LyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCiAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCiAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCiAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICovCgovKgogKiBtb2RfcHJveHlfc2NnaS5jCiAqIFByb3h5IGJhY2tlbmQgbW9kdWxlIGZvciB0aGUgU0NHSSBwcm90b2NvbAogKiAoaHR0cDovL3B5dGhvbi5jYS9zY2dpL3Byb3RvY29sLnR4dCkKICoKICogQW5kcukgTWFsbyAobmQvcGVybGlnLmRlKSwgQXVndXN0IDIwMDcKICovCgojZGVmaW5lIEFQUl9XQU5UX01FTUZVTkMKI2RlZmluZSBBUFJfV0FOVF9TVFJGVU5DCiNpbmNsdWRlICJhcHJfc3RyaW5ncy5oIgojaW5jbHVkZSAiYXBfaG9va3MuaCIKI2luY2x1ZGUgImFwcl9vcHRpb25hbF9ob29rcy5oIgojaW5jbHVkZSAiYXByX2J1Y2tldHMuaCIKCiNpbmNsdWRlICJodHRwZC5oIgojaW5jbHVkZSAiaHR0cF9jb25maWcuaCIKI2luY2x1ZGUgImh0dHBfbG9nLmgiCiNpbmNsdWRlICJodHRwX3Byb3RvY29sLmgiCiNpbmNsdWRlICJodHRwX3JlcXVlc3QuaCIKI2luY2x1ZGUgInV0aWxfc2NyaXB0LmgiCgojaW5jbHVkZSAibW9kX3Byb3h5LmgiCgoKI2RlZmluZSBTQ0hFTUUgInNjZ2kiCiNkZWZpbmUgUFJPWFlfRlVOQ1RJT04gIlNDR0kiCiNkZWZpbmUgU0NHSV9NQUdJQyAiU0NHSSIKI2RlZmluZSBTQ0dJX1BST1RPQ09MX1ZFUlNJT04gIjEiCiNkZWZpbmUgU0NHSV9ERUZBVUxUX1BPUlQgKDQwMDApCgovKiBqdXN0IHByb3RlY3QgZnJvbSB0eXBvcyAqLwojZGVmaW5lIENPTlRFTlRfTEVOR1RIICJDT05URU5UX0xFTkdUSCIKI2RlZmluZSBHQVRFV0FZX0lOVEVSRkFDRSAiR0FURVdBWV9JTlRFUkZBQ0UiCgptb2R1bGUgQVBfTU9EVUxFX0RFQ0xBUkVfREFUQSBwcm94eV9zY2dpX21vZHVsZTsKCgp0eXBlZGVmIGVudW0gewogICAgc2NnaV9pbnRlcm5hbF9yZWRpcmVjdCwKICAgIHNjZ2lfc2VuZGZpbGUKfSBzY2dpX3JlcXVlc3RfdHlwZTsKCnR5cGVkZWYgc3RydWN0IHsKICAgIGNvbnN0IGNoYXIgKmxvY2F0aW9uOyAgICAvKiB0YXJnZXQgVVJMICovCiAgICBzY2dpX3JlcXVlc3RfdHlwZSB0eXBlOyAgLyogdHlwZSBvZiByZXF1ZXN0ICovCn0gc2NnaV9yZXF1ZXN0X2NvbmZpZzsKCmNvbnN0IGNoYXIgKnNjZ2lfc2VuZGZpbGVfb2ZmID0gIm9mZiI7CmNvbnN0IGNoYXIgKnNjZ2lfc2VuZGZpbGVfb24gPSAiWC1TZW5kZmlsZSI7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBjb25zdCBjaGFyICpzZW5kZmlsZTsKICAgIGludCBpbnRlcm5hbF9yZWRpcmVjdDsKfSBzY2dpX2NvbmZpZzsKCgovKgogKiBXZSBjcmVhdGUgb3VyIG93biBidWNrZXQgdHlwZSwgd2hpY2ggaXMgYWN0dWFsbHkgZGVyaXZlZCAoYyZwKSBmcm9tIHRoZQogKiBzb2NrZXQgYnVja2V0LgogKiBNYXliZSBzb21lIHRpbWUgdGhpcyBzaG91bGQgYmUgbWFkZSBtb3JlIGFic3RyYWN0IChsaWtlIHBhc3NpbmcgYW4KICogaW50ZXJjZXB0aW9uIGZ1bmN0aW9uIHRvIHJlYWQgb3Igc29tZXRoaW5nKSBhbmQgZ28gaW50byB0aGUgYXBfIG9yCiAqIGV2ZW4gYXByXyBuYW1lc3BhY2UuCiAqLwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgYXByX3NvY2tldF90ICpzb2NrOwogICAgYXByX29mZl90ICpjb3VudGVyOwp9IHNvY2tldF9leF9kYXRhOwoKc3RhdGljIGFwcl9idWNrZXQgKmJ1Y2tldF9zb2NrZXRfZXhfY3JlYXRlKHNvY2tldF9leF9kYXRhICpkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXByX2J1Y2tldF9hbGxvY190ICpsaXN0KTsKCgpzdGF0aWMgYXByX3N0YXR1c190IGJ1Y2tldF9zb2NrZXRfZXhfcmVhZChhcHJfYnVja2V0ICphLCBjb25zdCBjaGFyICoqc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHJfc2l6ZV90ICpsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcl9yZWFkX3R5cGVfZSBibG9jaykKewogICAgc29ja2V0X2V4X2RhdGEgKmRhdGEgPSBhLT5kYXRhOwogICAgYXByX3NvY2tldF90ICpwID0gZGF0YS0+c29jazsKICAgIGNoYXIgKmJ1ZjsKICAgIGFwcl9zdGF0dXNfdCBydjsKICAgIGFwcl9pbnRlcnZhbF90aW1lX3QgdGltZW91dDsKCiAgICBpZiAoYmxvY2sgPT0gQVBSX05PTkJMT0NLX1JFQUQpIHsKICAgICAgICBhcHJfc29ja2V0X3RpbWVvdXRfZ2V0KHAsICZ0aW1lb3V0KTsKICAgICAgICBhcHJfc29ja2V0X3RpbWVvdXRfc2V0KHAsIDApOwogICAgfQoKICAgICpzdHIgPSBOVUxMOwogICAgKmxlbiA9IEFQUl9CVUNLRVRfQlVGRl9TSVpFOwogICAgYnVmID0gYXByX2J1Y2tldF9hbGxvYygqbGVuLCBhLT5saXN0KTsKCiAgICBydiA9IGFwcl9zb2NrZXRfcmVjdihwLCBidWYsIGxlbik7CgogICAgaWYgKGJsb2NrID09IEFQUl9OT05CTE9DS19SRUFEKSB7CiAgICAgICAgYXByX3NvY2tldF90aW1lb3V0X3NldChwLCB0aW1lb3V0KTsKICAgIH0KCiAgICBpZiAocnYgIT0gQVBSX1NVQ0NFU1MgJiYgcnYgIT0gQVBSX0VPRikgewogICAgICAgIGFwcl9idWNrZXRfZnJlZShidWYpOwogICAgICAgIHJldHVybiBydjsKICAgIH0KCiAgICBpZiAoKmxlbiA+IDApIHsKICAgICAgICBhcHJfYnVja2V0X2hlYXAgKmg7CgogICAgICAgIC8qIGNvdW50IGZvciBzdGF0cyAqLwogICAgICAgICpkYXRhLT5jb3VudGVyICs9ICpsZW47CgogICAgICAgIC8qIENoYW5nZSB0aGUgY3VycmVudCBidWNrZXQgdG8gcmVmZXIgdG8gd2hhdCB3ZSByZWFkICovCiAgICAgICAgYSA9IGFwcl9idWNrZXRfaGVhcF9tYWtlKGEsIGJ1ZiwgKmxlbiwgYXByX2J1Y2tldF9mcmVlKTsKICAgICAgICBoID0gYS0+ZGF0YTsKICAgICAgICBoLT5hbGxvY19sZW4gPSBBUFJfQlVDS0VUX0JVRkZfU0laRTsgLyogbm90ZSB0aGUgcmVhbCBidWZmZXIgc2l6ZSAqLwogICAgICAgICpzdHIgPSBidWY7CiAgICAgICAgQVBSX0JVQ0tFVF9JTlNFUlRfQUZURVIoYSwgYnVja2V0X3NvY2tldF9leF9jcmVhdGUoZGF0YSwgYS0+bGlzdCkpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgYXByX2J1Y2tldF9mcmVlKGJ1Zik7CiAgICAgICAgYSA9IGFwcl9idWNrZXRfaW1tb3J0YWxfbWFrZShhLCAiIiwgMCk7CiAgICAgICAgKnN0ciA9IGEtPmRhdGE7CiAgICB9CiAgICByZXR1cm4gQVBSX1NVQ0NFU1M7Cn0KCnN0YXRpYyBjb25zdCBhcHJfYnVja2V0X3R5cGVfdCBidWNrZXRfdHlwZV9zb2NrZXRfZXggPSB7CiAgICAiU09DS0VUX0VYIiwgNSwgQVBSX0JVQ0tFVF9EQVRBLAogICAgYXByX2J1Y2tldF9kZXN0cm95X25vb3AsCiAgICBidWNrZXRfc29ja2V0X2V4X3JlYWQsCiAgICBhcHJfYnVja2V0X3NldGFzaWRlX25vdGltcGwsCiAgICBhcHJfYnVja2V0X3NwbGl0X25vdGltcGwsCiAgICBhcHJfYnVja2V0X2NvcHlfbm90aW1wbAp9OwoKc3RhdGljIGFwcl9idWNrZXQgKmJ1Y2tldF9zb2NrZXRfZXhfbWFrZShhcHJfYnVja2V0ICpiLCBzb2NrZXRfZXhfZGF0YSAqZGF0YSkKewogICAgYi0+dHlwZSAgICAgICAgPSAmYnVja2V0X3R5cGVfc29ja2V0X2V4OwogICAgYi0+bGVuZ3RoICAgICAgPSAoYXByX3NpemVfdCkoLTEpOwogICAgYi0+c3RhcnQgICAgICAgPSAtMTsKICAgIGItPmRhdGEgICAgICAgID0gZGF0YTsKICAgIHJldHVybiBiOwp9CgpzdGF0aWMgYXByX2J1Y2tldCAqYnVja2V0X3NvY2tldF9leF9jcmVhdGUoc29ja2V0X2V4X2RhdGEgKmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHJfYnVja2V0X2FsbG9jX3QgKmxpc3QpCnsKICAgIGFwcl9idWNrZXQgKmIgPSBhcHJfYnVja2V0X2FsbG9jKHNpemVvZigqYiksIGxpc3QpOwoKICAgIEFQUl9CVUNLRVRfSU5JVChiKTsKICAgIGItPmZyZWUgPSBhcHJfYnVja2V0X2ZyZWU7CiAgICBiLT5saXN0ID0gbGlzdDsKICAgIHJldHVybiBidWNrZXRfc29ja2V0X2V4X21ha2UoYiwgZGF0YSk7Cn0KCgovKgogKiBDYW5vbmljYWxpemUgc2NnaS1saWtlIFVSTHMuCiAqLwpzdGF0aWMgaW50IHNjZ2lfY2Fub24ocmVxdWVzdF9yZWMgKnIsIGNoYXIgKnVybCkKewogICAgY2hhciAqaG9zdCwgc3BvcnRbc2l6ZW9mKCI6NjU1MzUiKV07CiAgICBjb25zdCBjaGFyICplcnIsICpwYXRoOwogICAgYXByX3BvcnRfdCBwb3J0ID0gU0NHSV9ERUZBVUxUX1BPUlQ7CgogICAgaWYgKHN0cm5jYXNlY21wKHVybCwgU0NIRU1FICI6Ly8iLCBzaXplb2YoU0NIRU1FKSArIDIpKSB7CiAgICAgICAgcmV0dXJuIERFQ0xJTkVEOwogICAgfQogICAgdXJsICs9IHNpemVvZihTQ0hFTUUpOyAvKiBLZWVwIHNsYXNoZXMgKi8KCiAgICBlcnIgPSBhcF9wcm94eV9jYW5vbl9uZXRsb2Moci0+cG9vbCwgJnVybCwgTlVMTCwgTlVMTCwgJmhvc3QsICZwb3J0KTsKICAgIGlmIChlcnIpIHsKICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0VSUiwgMCwgciwgQVBMT0dOTygwMDg1NykKICAgICAgICAgICAgICAgICAgICAgICJlcnJvciBwYXJzaW5nIFVSTCAlczogJXMiLCB1cmwsIGVycik7CiAgICAgICAgcmV0dXJuIEhUVFBfQkFEX1JFUVVFU1Q7CiAgICB9CgogICAgYXByX3NucHJpbnRmKHNwb3J0LCBzaXplb2Yoc3BvcnQpLCAiOiV1IiwgcG9ydCk7CgogICAgaWYgKGFwX3N0cmNocihob3N0LCAnOicpKSB7IC8qIGlmIGxpdGVyYWwgSVB2NiBhZGRyZXNzICovCiAgICAgICAgaG9zdCA9IGFwcl9wc3RyY2F0KHItPnBvb2wsICJbIiwgaG9zdCwgIl0iLCBOVUxMKTsKICAgIH0KCiAgICBwYXRoID0gYXBfcHJveHlfY2Fub25lbmMoci0+cG9vbCwgdXJsLCBzdHJsZW4odXJsKSwgZW5jX3BhdGgsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0+cHJveHlyZXEpOwogICAgaWYgKCFwYXRoKSB7CiAgICAgICAgcmV0dXJuIEhUVFBfQkFEX1JFUVVFU1Q7CiAgICB9CgogICAgci0+ZmlsZW5hbWUgPSBhcHJfcHN0cmNhdChyLT5wb29sLCAicHJveHk6IiBTQ0hFTUUgIjovLyIsIGhvc3QsIHNwb3J0LCAiLyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGgsIE5VTEwpOwoKICAgIGlmIChhcHJfdGFibGVfZ2V0KHItPnN1YnByb2Nlc3NfZW52LCAicHJveHktc2NnaS1wYXRoaW5mbyIpKSB7CiAgICAgICAgci0+cGF0aF9pbmZvID0gYXByX3BzdHJjYXQoci0+cG9vbCwgIi8iLCBwYXRoLCBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gT0s7Cn0KCgovKgogKiBTZW5kIGEgYmxvY2sgb2YgZGF0YSwgZW5zdXJlLCBldmVyeXRoaW5nIGlzIHNlbnQKICovCnN0YXRpYyBpbnQgc2VuZGFsbChwcm94eV9jb25uX3JlYyAqY29ubiwgY29uc3QgY2hhciAqYnVmLCBhcHJfc2l6ZV90IGxlbmd0aCwKICAgICAgICAgICAgICAgICAgIHJlcXVlc3RfcmVjICpyKQp7CiAgICBhcHJfc3RhdHVzX3QgcnY7CiAgICBhcHJfc2l6ZV90IHdyaXR0ZW47CgogICAgd2hpbGUgKGxlbmd0aCA+IDApIHsKICAgICAgICB3cml0dGVuID0gbGVuZ3RoOwogICAgICAgIGlmICgocnYgPSBhcHJfc29ja2V0X3NlbmQoY29ubi0+c29jaywgYnVmLCAmd3JpdHRlbikpICE9IEFQUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCBydiwgciwgQVBMT0dOTygwMDg1OCkKICAgICAgICAgICAgICAgICAgICAgICAgICAic2VuZGluZyBkYXRhIHRvICVzOiV1IGZhaWxlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubi0+aG9zdG5hbWUsIGNvbm4tPnBvcnQpOwogICAgICAgICAgICByZXR1cm4gSFRUUF9TRVJWSUNFX1VOQVZBSUxBQkxFOwogICAgICAgIH0KCiAgICAgICAgLyogY291bnQgZm9yIHN0YXRzICovCiAgICAgICAgY29ubi0+d29ya2VyLT5zLT50cmFuc2ZlcnJlZCArPSB3cml0dGVuOwogICAgICAgIGJ1ZiArPSB3cml0dGVuOwogICAgICAgIGxlbmd0aCAtPSB3cml0dGVuOwogICAgfQoKICAgIHJldHVybiBPSzsKfQoKCi8qCiAqIFNlbmQgU0NHSSBoZWFkZXIgYmxvY2sKICovCnN0YXRpYyBpbnQgc2VuZF9oZWFkZXJzKHJlcXVlc3RfcmVjICpyLCBwcm94eV9jb25uX3JlYyAqY29ubikKewogICAgY2hhciAqYnVmLCAqY3AsICpib2R5bGVuOwogICAgY29uc3QgY2hhciAqbnNfbGVuOwogICAgY29uc3QgYXByX2FycmF5X2hlYWRlcl90ICplbnZfdGFibGU7CiAgICBjb25zdCBhcHJfdGFibGVfZW50cnlfdCAqZW52OwogICAgaW50IGo7CiAgICBhcHJfc2l6ZV90IGxlbiwgYm9keWxlbl9zaXplOwogICAgYXByX3NpemVfdCBoZWFkZXJsZW4gPSAgIHNpemVvZihDT05URU5UX0xFTkdUSCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzaXplb2YoU0NHSV9NQUdJQykKICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzaXplb2YoU0NHSV9QUk9UT0NPTF9WRVJTSU9OKTsKCiAgICBhcF9hZGRfY29tbW9uX3ZhcnMocik7CiAgICBhcF9hZGRfY2dpX3ZhcnMocik7CgogICAgLyoKICAgICAqIFRoZSBoZWFkZXIgYmxvYiBiYXNpY2FsbHkgdGFrZXMgdGhlIGVudmlyb25tZW50IGFuZCBjb25jYXRlbmF0ZXMKICAgICAqIGtleXMgYW5kIHZhbHVlcyB1c2luZyAwIGJ5dGVzLiBUaGVyZSBhcmUgc3BlY2lhbCB0cmVhdG1lbnRzIGhlcmU6CiAgICAgKiAgIC0gR0FURVdBWV9JTlRFUkZBQ0UgYW5kIFNDR0lfTUFHSUMgYXJlIGRyb3BwZWQKICAgICAqICAgLSBDT05URU5UX0xFTkdUSCBpcyBhbHdheXMgc2V0IGFuZCBtdXN0IGJlIHNlbnQgYXMgdGhlIHZlcnkgZmlyc3QKICAgICAqICAgICB2YXJpYWJsZQogICAgICoKICAgICAqIEFkZGl0aW9uYWxseSBpdCdzIHdyYXBwZWQgaW50byBhIHNvLWNhbGxlZCBuZXRzdHJpbmcgKHNlZSBTQ0dJIHNwZWMpCiAgICAgKi8KICAgIGVudl90YWJsZSA9IGFwcl90YWJsZV9lbHRzKHItPnN1YnByb2Nlc3NfZW52KTsKICAgIGVudiA9IChhcHJfdGFibGVfZW50cnlfdCAqKWVudl90YWJsZS0+ZWx0czsKICAgIGZvciAoaiA9IDA7IGogPCBlbnZfdGFibGUtPm5lbHRzOyArK2opIHsKICAgICAgICBpZiAoICAgKCFzdHJjbXAoZW52W2pdLmtleSwgR0FURVdBWV9JTlRFUkZBQ0UpKQogICAgICAgICAgICB8fCAoIXN0cmNtcChlbnZbal0ua2V5LCBDT05URU5UX0xFTkdUSCkpCiAgICAgICAgICAgIHx8ICghc3RyY21wKGVudltqXS5rZXksIFNDR0lfTUFHSUMpKSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaGVhZGVybGVuICs9IHN0cmxlbihlbnZbal0ua2V5KSArIHN0cmxlbihlbnZbal0udmFsKSArIDI7CiAgICB9CiAgICBib2R5bGVuID0gYXByX3BzcHJpbnRmKHItPnBvb2wsICIlIiBBUFJfT0ZGX1RfRk1ULCByLT5yZW1haW5pbmcpOwogICAgYm9keWxlbl9zaXplID0gc3RybGVuKGJvZHlsZW4pICsgMTsKICAgIGhlYWRlcmxlbiArPSBib2R5bGVuX3NpemU7CgogICAgbnNfbGVuID0gYXByX3BzcHJpbnRmKHItPnBvb2wsICIlIiBBUFJfU0laRV9UX0ZNVCAiOiIsIGhlYWRlcmxlbik7CiAgICBsZW4gPSBzdHJsZW4obnNfbGVuKTsKICAgIGhlYWRlcmxlbiArPSBsZW4gKyAxOyAvKiAxID09ICwgKi8KICAgIGNwID0gYnVmID0gYXByX3BhbGxvYyhyLT5wb29sLCBoZWFkZXJsZW4pOwogICAgbWVtY3B5KGNwLCBuc19sZW4sIGxlbik7CiAgICBjcCArPSBsZW47CgogICAgbWVtY3B5KGNwLCBDT05URU5UX0xFTkdUSCwgc2l6ZW9mKENPTlRFTlRfTEVOR1RIKSk7CiAgICBjcCArPSBzaXplb2YoQ09OVEVOVF9MRU5HVEgpOwogICAgbWVtY3B5KGNwLCBib2R5bGVuLCBib2R5bGVuX3NpemUpOwogICAgY3AgKz0gYm9keWxlbl9zaXplOwogICAgbWVtY3B5KGNwLCBTQ0dJX01BR0lDLCBzaXplb2YoU0NHSV9NQUdJQykpOwogICAgY3AgKz0gc2l6ZW9mKFNDR0lfTUFHSUMpOwogICAgbWVtY3B5KGNwLCBTQ0dJX1BST1RPQ09MX1ZFUlNJT04sIHNpemVvZihTQ0dJX1BST1RPQ09MX1ZFUlNJT04pKTsKICAgIGNwICs9IHNpemVvZihTQ0dJX1BST1RPQ09MX1ZFUlNJT04pOwoKICAgIGZvciAoaiA9IDA7IGogPCBlbnZfdGFibGUtPm5lbHRzOyArK2opIHsKICAgICAgICBpZiAoICAgKCFzdHJjbXAoZW52W2pdLmtleSwgR0FURVdBWV9JTlRFUkZBQ0UpKQogICAgICAgICAgICB8fCAoIXN0cmNtcChlbnZbal0ua2V5LCBDT05URU5UX0xFTkdUSCkpCiAgICAgICAgICAgIHx8ICghc3RyY21wKGVudltqXS5rZXksIFNDR0lfTUFHSUMpKSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgbGVuID0gc3RybGVuKGVudltqXS5rZXkpICsgMTsKICAgICAgICBtZW1jcHkoY3AsIGVudltqXS5rZXksIGxlbik7CiAgICAgICAgY3AgKz0gbGVuOwogICAgICAgIGxlbiA9IHN0cmxlbihlbnZbal0udmFsKSArIDE7CiAgICAgICAgbWVtY3B5KGNwLCBlbnZbal0udmFsLCBsZW4pOwogICAgICAgIGNwICs9IGxlbjsKICAgIH0KICAgICpjcCsrID0gJywnOwoKICAgIHJldHVybiBzZW5kYWxsKGNvbm4sIGJ1ZiwgaGVhZGVybGVuLCByKTsKfQoKCi8qCiAqIFNlbmQgcmVxdWVzdCBib2R5IChpZiBhbnkpCiAqLwpzdGF0aWMgaW50IHNlbmRfcmVxdWVzdF9ib2R5KHJlcXVlc3RfcmVjICpyLCBwcm94eV9jb25uX3JlYyAqY29ubikKewogICAgaWYgKGFwX3Nob3VsZF9jbGllbnRfYmxvY2socikpIHsKICAgICAgICBjaGFyICpidWYgPSBhcHJfcGFsbG9jKHItPnBvb2wsIEFQX0lPQlVGU0laRSk7CiAgICAgICAgaW50IHN0YXR1czsKICAgICAgICBhcHJfc2l6ZV90IHJlYWRsZW47CgogICAgICAgIHJlYWRsZW4gPSBhcF9nZXRfY2xpZW50X2Jsb2NrKHIsIGJ1ZiwgQVBfSU9CVUZTSVpFKTsKICAgICAgICB3aGlsZSAocmVhZGxlbiA+IDApIHsKICAgICAgICAgICAgc3RhdHVzID0gc2VuZGFsbChjb25uLCBidWYsIHJlYWRsZW4sIHIpOwogICAgICAgICAgICBpZiAoc3RhdHVzICE9IE9LKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRUUF9TRVJWSUNFX1VOQVZBSUxBQkxFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlYWRsZW4gPSBhcF9nZXRfY2xpZW50X2Jsb2NrKHIsIGJ1ZiwgQVBfSU9CVUZTSVpFKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlYWRsZW4gPT0gLTEpIHsKICAgICAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDA4NTkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgInJlY2VpdmluZyByZXF1ZXN0IGJvZHkgZmFpbGVkIik7CiAgICAgICAgICAgIHJldHVybiBIVFRQX0lOVEVSTkFMX1NFUlZFUl9FUlJPUjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIE9LOwp9CgoKLyoKICogRmV0Y2ggcmVzcG9uc2UgZnJvbSBiYWNrZW5kIGFuZCBwYXNzIGJhY2sgdG8gdGhlIGZyb250CiAqLwpzdGF0aWMgaW50IHBhc3NfcmVzcG9uc2UocmVxdWVzdF9yZWMgKnIsIHByb3h5X2Nvbm5fcmVjICpjb25uKQp7CiAgICBhcHJfYnVja2V0X2JyaWdhZGUgKmJiOwogICAgYXByX2J1Y2tldCAqYjsKICAgIGNvbnN0IGNoYXIgKmxvY2F0aW9uOwogICAgc2NnaV9jb25maWcgKmNvbmY7CiAgICBzb2NrZXRfZXhfZGF0YSAqc29ja19kYXRhOwogICAgaW50IHN0YXR1czsKCiAgICBzb2NrX2RhdGEgPSBhcHJfcGFsbG9jKHItPnBvb2wsIHNpemVvZigqc29ja19kYXRhKSk7CiAgICBzb2NrX2RhdGEtPnNvY2sgPSBjb25uLT5zb2NrOwogICAgc29ja19kYXRhLT5jb3VudGVyID0gJmNvbm4tPndvcmtlci0+cy0+cmVhZDsKCiAgICBiYiA9IGFwcl9icmlnYWRlX2NyZWF0ZShyLT5wb29sLCByLT5jb25uZWN0aW9uLT5idWNrZXRfYWxsb2MpOwogICAgYiA9IGJ1Y2tldF9zb2NrZXRfZXhfY3JlYXRlKHNvY2tfZGF0YSwgci0+Y29ubmVjdGlvbi0+YnVja2V0X2FsbG9jKTsKICAgIEFQUl9CUklHQURFX0lOU0VSVF9UQUlMKGJiLCBiKTsKICAgIGIgPSBhcHJfYnVja2V0X2Vvc19jcmVhdGUoci0+Y29ubmVjdGlvbi0+YnVja2V0X2FsbG9jKTsKICAgIEFQUl9CUklHQURFX0lOU0VSVF9UQUlMKGJiLCBiKTsKCiAgICBzdGF0dXMgPSBhcF9zY2FuX3NjcmlwdF9oZWFkZXJfZXJyX2JyaWdhZGVfZXgociwgYmIsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVBMT0dfTU9EVUxFX0lOREVYKTsKICAgIGlmIChzdGF0dXMgIT0gT0spIHsKICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0VSUiwgMCwgciwgQVBMT0dOTygwMDg2MCkKICAgICAgICAgICAgICAgICAgICAgICJlcnJvciByZWFkaW5nIHJlc3BvbnNlIGhlYWRlcnMgZnJvbSAlczoldSIsCiAgICAgICAgICAgICAgICAgICAgICBjb25uLT5ob3N0bmFtZSwgY29ubi0+cG9ydCk7CiAgICAgICAgci0+c3RhdHVzX2xpbmUgPSBOVUxMOwogICAgICAgIGFwcl9icmlnYWRlX2Rlc3Ryb3koYmIpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgogICAgY29uZiA9IGFwX2dldF9tb2R1bGVfY29uZmlnKHItPnBlcl9kaXJfY29uZmlnLCAmcHJveHlfc2NnaV9tb2R1bGUpOwogICAgaWYgKGNvbmYtPnNlbmRmaWxlICYmIGNvbmYtPnNlbmRmaWxlICE9IHNjZ2lfc2VuZGZpbGVfb2ZmKSB7CiAgICAgICAgc2hvcnQgZXJyID0gMTsKCiAgICAgICAgbG9jYXRpb24gPSBhcHJfdGFibGVfZ2V0KHItPmVycl9oZWFkZXJzX291dCwgY29uZi0+c2VuZGZpbGUpOwogICAgICAgIGlmICghbG9jYXRpb24pIHsKICAgICAgICAgICAgZXJyID0gMDsKICAgICAgICAgICAgbG9jYXRpb24gPSBhcHJfdGFibGVfZ2V0KHItPmhlYWRlcnNfb3V0LCBjb25mLT5zZW5kZmlsZSk7CiAgICAgICAgfQogICAgICAgIGlmIChsb2NhdGlvbikgewogICAgICAgICAgICBzY2dpX3JlcXVlc3RfY29uZmlnICpyZXFfY29uZiA9IGFwcl9wYWxsb2Moci0+cG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZigqcmVxX2NvbmYpKTsKICAgICAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19ERUJVRywgMCwgciwgQVBMT0dOTygwMDg2MSkKICAgICAgICAgICAgICAgICAgICAgICAgICAiRm91bmQgJXM6ICVzIC0gcHJlcGFyaW5nIHN1YnJlcXVlc3QuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25mLT5zZW5kZmlsZSwgbG9jYXRpb24pOwoKICAgICAgICAgICAgaWYgKGVycikgewogICAgICAgICAgICAgICAgYXByX3RhYmxlX3Vuc2V0KHItPmVycl9oZWFkZXJzX291dCwgY29uZi0+c2VuZGZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgYXByX3RhYmxlX3Vuc2V0KHItPmhlYWRlcnNfb3V0LCBjb25mLT5zZW5kZmlsZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVxX2NvbmYtPmxvY2F0aW9uID0gbG9jYXRpb247CiAgICAgICAgICAgIHJlcV9jb25mLT50eXBlID0gc2NnaV9zZW5kZmlsZTsKICAgICAgICAgICAgYXBfc2V0X21vZHVsZV9jb25maWcoci0+cmVxdWVzdF9jb25maWcsICZwcm94eV9zY2dpX21vZHVsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxX2NvbmYpOwogICAgICAgICAgICBhcHJfYnJpZ2FkZV9kZXN0cm95KGJiKTsKICAgICAgICAgICAgcmV0dXJuIE9LOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY29uZi0+aW50ZXJuYWxfcmVkaXJlY3QgJiYgci0+c3RhdHVzID09IEhUVFBfT0spIHsKICAgICAgICBsb2NhdGlvbiA9IGFwcl90YWJsZV9nZXQoci0+aGVhZGVyc19vdXQsICJMb2NhdGlvbiIpOwogICAgICAgIGlmIChsb2NhdGlvbiAmJiAqbG9jYXRpb24gPT0gJy8nKSB7CiAgICAgICAgICAgIHNjZ2lfcmVxdWVzdF9jb25maWcgKnJlcV9jb25mID0gYXByX3BhbGxvYyhyLT5wb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKCpyZXFfY29uZikpOwogICAgICAgICAgICByZXFfY29uZi0+bG9jYXRpb24gPSBsb2NhdGlvbjsKICAgICAgICAgICAgcmVxX2NvbmYtPnR5cGUgPSBzY2dpX2ludGVybmFsX3JlZGlyZWN0OwogICAgICAgICAgICBhcF9zZXRfbW9kdWxlX2NvbmZpZyhyLT5yZXF1ZXN0X2NvbmZpZywgJnByb3h5X3NjZ2lfbW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXFfY29uZik7CiAgICAgICAgICAgIGFwcl9icmlnYWRlX2Rlc3Ryb3koYmIpOwogICAgICAgICAgICByZXR1cm4gT0s7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFhYWDogV2hhdCBjb3VsZCB3ZSBkbyB3aXRoIHRoYXQgcmV0dXJuIGNvZGU/ICovCiAgICAodm9pZClhcF9wYXNzX2JyaWdhZGUoci0+b3V0cHV0X2ZpbHRlcnMsIGJiKTsKCiAgICByZXR1cm4gT0s7Cn0KCi8qCiAqIEludGVybmFsIHJlZGlyZWN0IC8gc3VicmVxdWVzdCBoYW5kbGVyLCB3b3JraW5nIG9uIHJlcXVlc3Rfc3RhdHVzIGhvb2sKICovCnN0YXRpYyBpbnQgc2NnaV9yZXF1ZXN0X3N0YXR1cyhpbnQgKnN0YXR1cywgcmVxdWVzdF9yZWMgKnIpCnsKICAgIHNjZ2lfcmVxdWVzdF9jb25maWcgKnJlcV9jb25mOwoKICAgIGlmICggICAoKnN0YXR1cyA9PSBPSykKICAgICAgICAmJiAocmVxX2NvbmYgPSBhcF9nZXRfbW9kdWxlX2NvbmZpZyhyLT5yZXF1ZXN0X2NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHJveHlfc2NnaV9tb2R1bGUpKSkgewogICAgICAgIHN3aXRjaCAocmVxX2NvbmYtPnR5cGUpIHsKICAgICAgICBjYXNlIHNjZ2lfaW50ZXJuYWxfcmVkaXJlY3Q6CiAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfREVCVUcsIDAsIHIsIEFQTE9HTk8oMDA4NjIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkludGVybmFsIHJlZGlyZWN0IHRvICVzIiwgcmVxX2NvbmYtPmxvY2F0aW9uKTsKCiAgICAgICAgICAgIHItPnN0YXR1c19saW5lID0gTlVMTDsKICAgICAgICAgICAgaWYgKHItPm1ldGhvZF9udW1iZXIgIT0gTV9HRVQpIHsKICAgICAgICAgICAgICAgIC8qIGtlZXAgSEVBRCwgd2hpY2ggaXMgcGFzc2VkIGFyb3VuZCBhcyBNX0dFVCwgdG9vICovCiAgICAgICAgICAgICAgICByLT5tZXRob2QgPSAiR0VUIjsKICAgICAgICAgICAgICAgIHItPm1ldGhvZF9udW1iZXIgPSBNX0dFVDsKICAgICAgICAgICAgfQogICAgICAgICAgICBhcHJfdGFibGVfdW5zZXQoci0+aGVhZGVyc19pbiwgIkNvbnRlbnQtTGVuZ3RoIik7CiAgICAgICAgICAgIGFwX2ludGVybmFsX3JlZGlyZWN0X2hhbmRsZXIocmVxX2NvbmYtPmxvY2F0aW9uLCByKTsKICAgICAgICAgICAgcmV0dXJuIE9LOwogICAgICAgICAgICAvKiBicmVhazsgKi8KCiAgICAgICAgY2FzZSBzY2dpX3NlbmRmaWxlOgogICAgICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0RFQlVHLCAwLCByLCBBUExPR05PKDAwODYzKQogICAgICAgICAgICAgICAgICAgICAgICAgICJGaWxlIHN1YnJlcXVlc3QgdG8gJXMiLCByZXFfY29uZi0+bG9jYXRpb24pOwogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICByZXF1ZXN0X3JlYyAqcnI7CgogICAgICAgICAgICAgICAgcnIgPSBhcF9zdWJfcmVxX2xvb2t1cF9maWxlKHJlcV9jb25mLT5sb2NhdGlvbiwgciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByLT5vdXRwdXRfZmlsdGVycyk7CiAgICAgICAgICAgICAgICBpZiAocnItPnN0YXR1cyA9PSBIVFRQX09LICYmIHJyLT5maW5mby5maWxldHlwZSAhPSBBUFJfTk9GSUxFKSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBXZSBkb24ndCB0b3VjaCBDb250ZW50LUxlbmd0aCBoZXJlLiBJdCBtaWdodCBiZQogICAgICAgICAgICAgICAgICAgICAqIGJvcmtlZCAodGhlcmUncyBwbGVudHkgb2Ygcm9vbSBmb3IgYSByYWNlIGNvbmRpdGlvbikuCiAgICAgICAgICAgICAgICAgICAgICogRWl0aGVyIHRoZSBiYWNrZW5kIHNldHMgaXQgb3IgaXQncyBnb25uYSBiZSBjaHVua2VkLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGFwX3J1bl9zdWJfcmVxKHJyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAwODY0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN1YnJlcXVlc3QgdG8gZmlsZSAnJXMnIG5vdCBwb3NzaWJsZS4gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihyci0+c3RhdHVzPSVkLCByci0+ZmluZm8uZmlsZXR5cGU9JWQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcV9jb25mLT5sb2NhdGlvbiwgcnItPnN0YXR1cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJyLT5maW5mby5maWxldHlwZSk7CiAgICAgICAgICAgICAgICAgICAgKnN0YXR1cyA9IEhUVFBfSU5URVJOQUxfU0VSVkVSX0VSUk9SOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAqc3RhdHVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IHdoaWxlKDApOwoKICAgICAgICAgICAgcmV0dXJuIE9LOwogICAgICAgICAgICAvKiBicmVhazsgKi8KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIERFQ0xJTkVEOwp9CgoKLyoKICogVGhpcyBoYW5kbGVzIHNjZ2k6KGRlc3QpIFVSTHMKICovCnN0YXRpYyBpbnQgc2NnaV9oYW5kbGVyKHJlcXVlc3RfcmVjICpyLCBwcm94eV93b3JrZXIgKndvcmtlciwKICAgICAgICAgICAgICAgICAgICAgICAgcHJveHlfc2VydmVyX2NvbmYgKmNvbmYsIGNoYXIgKnVybCwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqcHJveHluYW1lLCBhcHJfcG9ydF90IHByb3h5cG9ydCkKewogICAgaW50IHN0YXR1czsKICAgIHByb3h5X2Nvbm5fcmVjICpiYWNrZW5kID0gTlVMTDsKICAgIGFwcl9wb29sX3QgKnAgPSByLT5wb29sOwogICAgYXByX3VyaV90ICp1cmkgPSBhcHJfcGFsbG9jKHItPnBvb2wsIHNpemVvZigqdXJpKSk7CiAgICBjaGFyIGR1bW15OwoKICAgIGlmIChzdHJuY2FzZWNtcCh1cmwsIFNDSEVNRSAiOi8vIiwgc2l6ZW9mKFNDSEVNRSkgKyAyKSkgewogICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfREVCVUcsIDAsIHIsIEFQTE9HTk8oMDA4NjUpCiAgICAgICAgICAgICAgICAgICAgICAiZGVjbGluaW5nIFVSTCAlcyIsIHVybCk7CiAgICAgICAgcmV0dXJuIERFQ0xJTkVEOwogICAgfQoKICAgIC8qIENyZWF0ZSBzcGFjZSBmb3Igc3RhdGUgaW5mb3JtYXRpb24gKi8KICAgIHN0YXR1cyA9IGFwX3Byb3h5X2FjcXVpcmVfY29ubmVjdGlvbihQUk9YWV9GVU5DVElPTiwgJmJhY2tlbmQsIHdvcmtlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByLT5zZXJ2ZXIpOwogICAgaWYgKHN0YXR1cyAhPSBPSykgewogICAgICAgIGdvdG8gY2xlYW51cDsKICAgIH0KICAgIGJhY2tlbmQtPmlzX3NzbCA9IDA7CgogICAgLyogU3RlcCBPbmU6IERldGVybWluZSBXaG8gVG8gQ29ubmVjdCBUbyAqLwogICAgc3RhdHVzID0gYXBfcHJveHlfZGV0ZXJtaW5lX2Nvbm5lY3Rpb24ocCwgciwgY29uZiwgd29ya2VyLCBiYWNrZW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJpLCAmdXJsLCBwcm94eW5hbWUsIHByb3h5cG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkdW1teSwgMSk7CiAgICBpZiAoc3RhdHVzICE9IE9LKSB7CiAgICAgICAgZ290byBjbGVhbnVwOwogICAgfQoKICAgIC8qIFN0ZXAgVHdvOiBNYWtlIHRoZSBDb25uZWN0aW9uICovCiAgICBpZiAoYXBfcHJveHlfY29ubmVjdF9iYWNrZW5kKFBST1hZX0ZVTkNUSU9OLCBiYWNrZW5kLCB3b3JrZXIsIHItPnNlcnZlcikpIHsKICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0VSUiwgMCwgciwgQVBMT0dOTygwMDg2NikKICAgICAgICAgICAgICAgICAgICAgICJmYWlsZWQgdG8gbWFrZSBjb25uZWN0aW9uIHRvIGJhY2tlbmQ6ICVzOiV1IiwKICAgICAgICAgICAgICAgICAgICAgIGJhY2tlbmQtPmhvc3RuYW1lLCBiYWNrZW5kLT5wb3J0KTsKICAgICAgICBzdGF0dXMgPSBIVFRQX1NFUlZJQ0VfVU5BVkFJTEFCTEU7CiAgICAgICAgZ290byBjbGVhbnVwOwogICAgfQoKICAgIC8qIFN0ZXAgVGhyZWU6IFByb2Nlc3MgdGhlIFJlcXVlc3QgKi8KICAgIGlmICggICAoKHN0YXR1cyA9IGFwX3NldHVwX2NsaWVudF9ibG9jayhyLCBSRVFVRVNUX0NIVU5LRURfRVJST1IpKSAhPSBPSykKICAgICAgICB8fCAoKHN0YXR1cyA9IHNlbmRfaGVhZGVycyhyLCBiYWNrZW5kKSkgIT0gT0spCiAgICAgICAgfHwgKChzdGF0dXMgPSBzZW5kX3JlcXVlc3RfYm9keShyLCBiYWNrZW5kKSkgIT0gT0spCiAgICAgICAgfHwgKChzdGF0dXMgPSBwYXNzX3Jlc3BvbnNlKHIsIGJhY2tlbmQpKSAhPSBPSykpIHsKICAgICAgICBnb3RvIGNsZWFudXA7CiAgICB9CgpjbGVhbnVwOgogICAgaWYgKGJhY2tlbmQpIHsKICAgICAgICBiYWNrZW5kLT5jbG9zZSA9IDE7IC8qIGFsd2F5cyBjbG9zZSB0aGUgc29ja2V0ICovCiAgICAgICAgYXBfcHJveHlfcmVsZWFzZV9jb25uZWN0aW9uKFBST1hZX0ZVTkNUSU9OLCBiYWNrZW5kLCByLT5zZXJ2ZXIpOwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKCnN0YXRpYyB2b2lkICpjcmVhdGVfc2NnaV9jb25maWcoYXByX3Bvb2xfdCAqcCwgY2hhciAqZHVtbXkpCnsKICAgIHNjZ2lfY29uZmlnICpjb25mPWFwcl9wYWxsb2MocCwgc2l6ZW9mKCpjb25mKSk7CgogICAgY29uZi0+c2VuZGZpbGUgPSBOVUxMOwogICAgY29uZi0+aW50ZXJuYWxfcmVkaXJlY3QgPSAtMTsKCiAgICByZXR1cm4gY29uZjsKfQoKCnN0YXRpYyB2b2lkICptZXJnZV9zY2dpX2NvbmZpZyhhcHJfcG9vbF90ICpwLCB2b2lkICpiYXNlXywgdm9pZCAqYWRkXykKewogICAgc2NnaV9jb25maWcgKmJhc2U9YmFzZV8sICphZGQ9YWRkXywgKmNvbmY9YXByX3BhbGxvYyhwLCBzaXplb2YoKmNvbmYpKTsKCiAgICBjb25mLT5zZW5kZmlsZSA9IGFkZC0+c2VuZGZpbGUgPyBhZGQtPnNlbmRmaWxlOiBiYXNlLT5zZW5kZmlsZTsKICAgIGNvbmYtPmludGVybmFsX3JlZGlyZWN0ID0gICAoYWRkLT5pbnRlcm5hbF9yZWRpcmVjdCAhPSAtMSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhZGQtPmludGVybmFsX3JlZGlyZWN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogYmFzZS0+aW50ZXJuYWxfcmVkaXJlY3Q7CiAgICByZXR1cm4gY29uZjsKfQoKCnN0YXRpYyBjb25zdCBjaGFyICpzY2dpX3NldF9zZW5kX2ZpbGUoY21kX3Bhcm1zICpjbWQsIHZvaWQgKm1jb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYXJnKQp7CiAgICBzY2dpX2NvbmZpZyAqY29uZj1tY29uZmlnOwoKICAgIGlmICghc3RyY2FzZWNtcChhcmcsICJPZmYiKSkgewogICAgICAgIGNvbmYtPnNlbmRmaWxlID0gc2NnaV9zZW5kZmlsZV9vZmY7CiAgICB9CiAgICBlbHNlIGlmICghc3RyY2FzZWNtcChhcmcsICJPbiIpKSB7CiAgICAgICAgY29uZi0+c2VuZGZpbGUgPSBzY2dpX3NlbmRmaWxlX29uOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgY29uZi0+c2VuZGZpbGUgPSBhcmc7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKCnN0YXRpYyBjb25zdCBjb21tYW5kX3JlYyBzY2dpX2NtZHNbXSA9CnsKICAgIEFQX0lOSVRfVEFLRTEoIlByb3h5U0NHSVNlbmRmaWxlIiwgc2NnaV9zZXRfc2VuZF9maWxlLCBOVUxMLAogICAgICAgICAgICAgICAgICBSU1JDX0NPTkZ8QUNDRVNTX0NPTkYsCiAgICAgICAgICAgICAgICAgICJUaGUgbmFtZSBvZiB0aGUgWC1TZW5kZmlsZSBwZXVkbyByZXNwb25zZSBoZWFkZXIgb3IgIgogICAgICAgICAgICAgICAgICAiT24gb3IgT2ZmIiksCiAgICBBUF9JTklUX0ZMQUcoIlByb3h5U0NHSUludGVybmFsUmVkaXJlY3QiLCBhcF9zZXRfZmxhZ19zbG90LAogICAgICAgICAgICAgICAgICh2b2lkKilBUFJfT0ZGU0VUT0Yoc2NnaV9jb25maWcsIGludGVybmFsX3JlZGlyZWN0KSwKICAgICAgICAgICAgICAgICBSU1JDX0NPTkZ8QUNDRVNTX0NPTkYsCiAgICAgICAgICAgICAgICAgIk9mZiBpZiBpbnRlcm5hbCByZWRpcmVjdCByZXNwb25zZXMgc2hvdWxkIG5vdCBiZSBhY2NlcHRlZCIpLAogICAge05VTEx9Cn07CgoKc3RhdGljIHZvaWQgcmVnaXN0ZXJfaG9va3MoYXByX3Bvb2xfdCAqcCkKewogICAgcHJveHlfaG9va19zY2hlbWVfaGFuZGxlcihzY2dpX2hhbmRsZXIsIE5VTEwsIE5VTEwsIEFQUl9IT09LX0ZJUlNUKTsKICAgIHByb3h5X2hvb2tfY2Fub25faGFuZGxlcihzY2dpX2Nhbm9uLCBOVUxMLCBOVUxMLCBBUFJfSE9PS19GSVJTVCk7CiAgICBBUFJfT1BUSU9OQUxfSE9PSyhwcm94eSwgcmVxdWVzdF9zdGF0dXMsIHNjZ2lfcmVxdWVzdF9zdGF0dXMsIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICBBUFJfSE9PS19NSURETEUpOwp9CgoKQVBfREVDTEFSRV9NT0RVTEUocHJveHlfc2NnaSkgPSB7CiAgICBTVEFOREFSRDIwX01PRFVMRV9TVFVGRiwKICAgIGNyZWF0ZV9zY2dpX2NvbmZpZywgIC8qIGNyZWF0ZSBwZXItZGlyZWN0b3J5IGNvbmZpZyBzdHJ1Y3R1cmUgKi8KICAgIG1lcmdlX3NjZ2lfY29uZmlnLCAgIC8qIG1lcmdlIHBlci1kaXJlY3RvcnkgY29uZmlnIHN0cnVjdHVyZXMgKi8KICAgIE5VTEwsICAgICAgICAgICAgICAgIC8qIGNyZWF0ZSBwZXItc2VydmVyIGNvbmZpZyBzdHJ1Y3R1cmUgKi8KICAgIE5VTEwsICAgICAgICAgICAgICAgIC8qIG1lcmdlIHBlci1zZXJ2ZXIgY29uZmlnIHN0cnVjdHVyZXMgKi8KICAgIHNjZ2lfY21kcywgICAgICAgICAgIC8qIGNvbW1hbmQgdGFibGUgKi8KICAgIHJlZ2lzdGVyX2hvb2tzICAgICAgIC8qIHJlZ2lzdGVyIGhvb2tzICovCn07Cg==