LyogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCiAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCiAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCiAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICovCgovKgogKiBtb2RfcHJveHlfc2NnaS5jCiAqIFByb3h5IGJhY2tlbmQgbW9kdWxlIGZvciB0aGUgU0NHSSBwcm90b2NvbAogKiAoaHR0cDovL3B5dGhvbi5jYS9zY2dpL3Byb3RvY29sLnR4dCkKICoKICogQW5kcukgTWFsbyAobmQvcGVybGlnLmRlKSwgQXVndXN0IDIwMDcKICovCgojZGVmaW5lIEFQUl9XQU5UX01FTUZVTkMKI2RlZmluZSBBUFJfV0FOVF9TVFJGVU5DCiNpbmNsdWRlICJhcHJfc3RyaW5ncy5oIgojaW5jbHVkZSAiYXBfaG9va3MuaCIKI2luY2x1ZGUgImFwcl9vcHRpb25hbF9ob29rcy5oIgojaW5jbHVkZSAiYXByX2J1Y2tldHMuaCIKCiNpbmNsdWRlICJodHRwZC5oIgojaW5jbHVkZSAiaHR0cF9jb25maWcuaCIKI2luY2x1ZGUgImh0dHBfbG9nLmgiCiNpbmNsdWRlICJodHRwX3Byb3RvY29sLmgiCiNpbmNsdWRlICJodHRwX3JlcXVlc3QuaCIKI2luY2x1ZGUgInV0aWxfc2NyaXB0LmgiCgojaW5jbHVkZSAibW9kX3Byb3h5LmgiCiNpbmNsdWRlICJzY2dpLmgiCgoKI2RlZmluZSBTQ0hFTUUgInNjZ2kiCiNkZWZpbmUgUFJPWFlfRlVOQ1RJT04gIlNDR0kiCiNkZWZpbmUgU0NHSV9NQUdJQyAiU0NHSSIKI2RlZmluZSBTQ0dJX1BST1RPQ09MX1ZFUlNJT04gIjEiCgovKiBqdXN0IHByb3RlY3QgZnJvbSB0eXBvcyAqLwojZGVmaW5lIENPTlRFTlRfTEVOR1RIICJDT05URU5UX0xFTkdUSCIKI2RlZmluZSBHQVRFV0FZX0lOVEVSRkFDRSAiR0FURVdBWV9JTlRFUkZBQ0UiCgptb2R1bGUgQVBfTU9EVUxFX0RFQ0xBUkVfREFUQSBwcm94eV9zY2dpX21vZHVsZTsKCgp0eXBlZGVmIGVudW0gewogICAgc2NnaV9pbnRlcm5hbF9yZWRpcmVjdCwKICAgIHNjZ2lfc2VuZGZpbGUKfSBzY2dpX3JlcXVlc3RfdHlwZTsKCnR5cGVkZWYgc3RydWN0IHsKICAgIGNvbnN0IGNoYXIgKmxvY2F0aW9uOyAgICAvKiB0YXJnZXQgVVJMICovCiAgICBzY2dpX3JlcXVlc3RfdHlwZSB0eXBlOyAgLyogdHlwZSBvZiByZXF1ZXN0ICovCn0gc2NnaV9yZXF1ZXN0X2NvbmZpZzsKCmNvbnN0IGNoYXIgKnNjZ2lfc2VuZGZpbGVfb2ZmID0gIm9mZiI7CmNvbnN0IGNoYXIgKnNjZ2lfc2VuZGZpbGVfb24gPSAiWC1TZW5kZmlsZSI7CmNvbnN0IGNoYXIgKnNjZ2lfaW50ZXJuYWxfcmVkaXJlY3Rfb2ZmID0gIm9mZiI7CmNvbnN0IGNoYXIgKnNjZ2lfaW50ZXJuYWxfcmVkaXJlY3Rfb24gPSAiTG9jYXRpb24iOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgY29uc3QgY2hhciAqc2VuZGZpbGU7CiAgICBjb25zdCBjaGFyICppbnRlcm5hbF9yZWRpcmVjdDsKfSBzY2dpX2NvbmZpZzsKCgovKgogKiBXZSBjcmVhdGUgb3VyIG93biBidWNrZXQgdHlwZSwgd2hpY2ggaXMgYWN0dWFsbHkgZGVyaXZlZCAoYyZwKSBmcm9tIHRoZQogKiBzb2NrZXQgYnVja2V0LgogKiBNYXliZSBzb21lIHRpbWUgdGhpcyBzaG91bGQgYmUgbWFkZSBtb3JlIGFic3RyYWN0IChsaWtlIHBhc3NpbmcgYW4KICogaW50ZXJjZXB0aW9uIGZ1bmN0aW9uIHRvIHJlYWQgb3Igc29tZXRoaW5nKSBhbmQgZ28gaW50byB0aGUgYXBfIG9yCiAqIGV2ZW4gYXByXyBuYW1lc3BhY2UuCiAqLwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgYXByX3NvY2tldF90ICpzb2NrOwogICAgYXByX29mZl90ICpjb3VudGVyOwp9IHNvY2tldF9leF9kYXRhOwoKc3RhdGljIGFwcl9idWNrZXQgKmJ1Y2tldF9zb2NrZXRfZXhfY3JlYXRlKHNvY2tldF9leF9kYXRhICpkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXByX2J1Y2tldF9hbGxvY190ICpsaXN0KTsKCgpzdGF0aWMgYXByX3N0YXR1c190IGJ1Y2tldF9zb2NrZXRfZXhfcmVhZChhcHJfYnVja2V0ICphLCBjb25zdCBjaGFyICoqc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHJfc2l6ZV90ICpsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcl9yZWFkX3R5cGVfZSBibG9jaykKewogICAgc29ja2V0X2V4X2RhdGEgKmRhdGEgPSBhLT5kYXRhOwogICAgYXByX3NvY2tldF90ICpwID0gZGF0YS0+c29jazsKICAgIGNoYXIgKmJ1ZjsKICAgIGFwcl9zdGF0dXNfdCBydjsKICAgIGFwcl9pbnRlcnZhbF90aW1lX3QgdGltZW91dDsKCiAgICBpZiAoYmxvY2sgPT0gQVBSX05PTkJMT0NLX1JFQUQpIHsKICAgICAgICBhcHJfc29ja2V0X3RpbWVvdXRfZ2V0KHAsICZ0aW1lb3V0KTsKICAgICAgICBhcHJfc29ja2V0X3RpbWVvdXRfc2V0KHAsIDApOwogICAgfQoKICAgICpzdHIgPSBOVUxMOwogICAgKmxlbiA9IEFQUl9CVUNLRVRfQlVGRl9TSVpFOwogICAgYnVmID0gYXByX2J1Y2tldF9hbGxvYygqbGVuLCBhLT5saXN0KTsKCiAgICBydiA9IGFwcl9zb2NrZXRfcmVjdihwLCBidWYsIGxlbik7CgogICAgaWYgKGJsb2NrID09IEFQUl9OT05CTE9DS19SRUFEKSB7CiAgICAgICAgYXByX3NvY2tldF90aW1lb3V0X3NldChwLCB0aW1lb3V0KTsKICAgIH0KCiAgICBpZiAocnYgIT0gQVBSX1NVQ0NFU1MgJiYgcnYgIT0gQVBSX0VPRikgewogICAgICAgIGFwcl9idWNrZXRfZnJlZShidWYpOwogICAgICAgIHJldHVybiBydjsKICAgIH0KCiAgICBpZiAoKmxlbiA+IDApIHsKICAgICAgICBhcHJfYnVja2V0X2hlYXAgKmg7CgogICAgICAgIC8qIGNvdW50IGZvciBzdGF0cyAqLwogICAgICAgICpkYXRhLT5jb3VudGVyICs9ICpsZW47CgogICAgICAgIC8qIENoYW5nZSB0aGUgY3VycmVudCBidWNrZXQgdG8gcmVmZXIgdG8gd2hhdCB3ZSByZWFkICovCiAgICAgICAgYSA9IGFwcl9idWNrZXRfaGVhcF9tYWtlKGEsIGJ1ZiwgKmxlbiwgYXByX2J1Y2tldF9mcmVlKTsKICAgICAgICBoID0gYS0+ZGF0YTsKICAgICAgICBoLT5hbGxvY19sZW4gPSBBUFJfQlVDS0VUX0JVRkZfU0laRTsgLyogbm90ZSB0aGUgcmVhbCBidWZmZXIgc2l6ZSAqLwogICAgICAgICpzdHIgPSBidWY7CiAgICAgICAgQVBSX0JVQ0tFVF9JTlNFUlRfQUZURVIoYSwgYnVja2V0X3NvY2tldF9leF9jcmVhdGUoZGF0YSwgYS0+bGlzdCkpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgYXByX2J1Y2tldF9mcmVlKGJ1Zik7CiAgICAgICAgYSA9IGFwcl9idWNrZXRfaW1tb3J0YWxfbWFrZShhLCAiIiwgMCk7CiAgICAgICAgKnN0ciA9IGEtPmRhdGE7CiAgICB9CiAgICByZXR1cm4gQVBSX1NVQ0NFU1M7Cn0KCnN0YXRpYyBjb25zdCBhcHJfYnVja2V0X3R5cGVfdCBidWNrZXRfdHlwZV9zb2NrZXRfZXggPSB7CiAgICAiU09DS0VUX0VYIiwgNSwgQVBSX0JVQ0tFVF9EQVRBLAogICAgYXByX2J1Y2tldF9kZXN0cm95X25vb3AsCiAgICBidWNrZXRfc29ja2V0X2V4X3JlYWQsCiAgICBhcHJfYnVja2V0X3NldGFzaWRlX25vdGltcGwsCiAgICBhcHJfYnVja2V0X3NwbGl0X25vdGltcGwsCiAgICBhcHJfYnVja2V0X2NvcHlfbm90aW1wbAp9OwoKc3RhdGljIGFwcl9idWNrZXQgKmJ1Y2tldF9zb2NrZXRfZXhfbWFrZShhcHJfYnVja2V0ICpiLCBzb2NrZXRfZXhfZGF0YSAqZGF0YSkKewogICAgYi0+dHlwZSAgICAgICAgPSAmYnVja2V0X3R5cGVfc29ja2V0X2V4OwogICAgYi0+bGVuZ3RoICAgICAgPSAoYXByX3NpemVfdCkoLTEpOwogICAgYi0+c3RhcnQgICAgICAgPSAtMTsKICAgIGItPmRhdGEgICAgICAgID0gZGF0YTsKICAgIHJldHVybiBiOwp9CgpzdGF0aWMgYXByX2J1Y2tldCAqYnVja2V0X3NvY2tldF9leF9jcmVhdGUoc29ja2V0X2V4X2RhdGEgKmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHJfYnVja2V0X2FsbG9jX3QgKmxpc3QpCnsKICAgIGFwcl9idWNrZXQgKmIgPSBhcHJfYnVja2V0X2FsbG9jKHNpemVvZigqYiksIGxpc3QpOwoKICAgIEFQUl9CVUNLRVRfSU5JVChiKTsKICAgIGItPmZyZWUgPSBhcHJfYnVja2V0X2ZyZWU7CiAgICBiLT5saXN0ID0gbGlzdDsKICAgIHJldHVybiBidWNrZXRfc29ja2V0X2V4X21ha2UoYiwgZGF0YSk7Cn0KCgovKgogKiBDYW5vbmljYWxpemUgc2NnaS1saWtlIFVSTHMuCiAqLwpzdGF0aWMgaW50IHNjZ2lfY2Fub24ocmVxdWVzdF9yZWMgKnIsIGNoYXIgKnVybCkKewogICAgY2hhciAqaG9zdCwgc3BvcnRbc2l6ZW9mKCI6NjU1MzUiKV07CiAgICBjb25zdCBjaGFyICplcnIsICpwYXRoOwogICAgYXByX3BvcnRfdCBwb3J0LCBkZWZfcG9ydDsKCiAgICBpZiAoc3RybmNhc2VjbXAodXJsLCBTQ0hFTUUgIjovLyIsIHNpemVvZihTQ0hFTUUpICsgMikpIHsKICAgICAgICByZXR1cm4gREVDTElORUQ7CiAgICB9CiAgICB1cmwgKz0gc2l6ZW9mKFNDSEVNRSk7IC8qIEtlZXAgc2xhc2hlcyAqLwoKICAgIHBvcnQgPSBkZWZfcG9ydCA9IFNDR0lfREVGX1BPUlQ7CgogICAgZXJyID0gYXBfcHJveHlfY2Fub25fbmV0bG9jKHItPnBvb2wsICZ1cmwsIE5VTEwsIE5VTEwsICZob3N0LCAmcG9ydCk7CiAgICBpZiAoZXJyKSB7CiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDA4NTcpCiAgICAgICAgICAgICAgICAgICAgICAiZXJyb3IgcGFyc2luZyBVUkwgJXM6ICVzIiwgdXJsLCBlcnIpOwogICAgICAgIHJldHVybiBIVFRQX0JBRF9SRVFVRVNUOwogICAgfQoKICAgIGlmIChwb3J0ICE9IGRlZl9wb3J0KSB7CiAgICAgICAgYXByX3NucHJpbnRmKHNwb3J0LCBzaXplb2Yoc3BvcnQpLCAiOiV1IiwgcG9ydCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBzcG9ydFswXSA9ICdcMCc7CiAgICB9CgogICAgaWYgKGFwX3N0cmNocihob3N0LCAnOicpKSB7IC8qIGlmIGxpdGVyYWwgSVB2NiBhZGRyZXNzICovCiAgICAgICAgaG9zdCA9IGFwcl9wc3RyY2F0KHItPnBvb2wsICJbIiwgaG9zdCwgIl0iLCBOVUxMKTsKICAgIH0KCiAgICBwYXRoID0gYXBfcHJveHlfY2Fub25lbmMoci0+cG9vbCwgdXJsLCBzdHJsZW4odXJsKSwgZW5jX3BhdGgsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0+cHJveHlyZXEpOwogICAgaWYgKCFwYXRoKSB7CiAgICAgICAgcmV0dXJuIEhUVFBfQkFEX1JFUVVFU1Q7CiAgICB9CgogICAgci0+ZmlsZW5hbWUgPSBhcHJfcHN0cmNhdChyLT5wb29sLCAicHJveHk6IiBTQ0hFTUUgIjovLyIsIGhvc3QsIHNwb3J0LCAiLyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGgsIE5VTEwpOwoKICAgIGlmIChhcHJfdGFibGVfZ2V0KHItPnN1YnByb2Nlc3NfZW52LCAicHJveHktc2NnaS1wYXRoaW5mbyIpKSB7CiAgICAgICAgci0+cGF0aF9pbmZvID0gYXByX3BzdHJjYXQoci0+cG9vbCwgIi8iLCBwYXRoLCBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gT0s7Cn0KCgovKgogKiBTZW5kIGEgYmxvY2sgb2YgZGF0YSwgZW5zdXJlLCBldmVyeXRoaW5nIGlzIHNlbnQKICovCnN0YXRpYyBpbnQgc2VuZGFsbChwcm94eV9jb25uX3JlYyAqY29ubiwgY29uc3QgY2hhciAqYnVmLCBhcHJfc2l6ZV90IGxlbmd0aCwKICAgICAgICAgICAgICAgICAgIHJlcXVlc3RfcmVjICpyKQp7CiAgICBhcHJfc3RhdHVzX3QgcnY7CiAgICBhcHJfc2l6ZV90IHdyaXR0ZW47CgogICAgd2hpbGUgKGxlbmd0aCA+IDApIHsKICAgICAgICB3cml0dGVuID0gbGVuZ3RoOwogICAgICAgIGlmICgocnYgPSBhcHJfc29ja2V0X3NlbmQoY29ubi0+c29jaywgYnVmLCAmd3JpdHRlbikpICE9IEFQUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCBydiwgciwgQVBMT0dOTygwMDg1OCkKICAgICAgICAgICAgICAgICAgICAgICAgICAic2VuZGluZyBkYXRhIHRvICVzOiV1IGZhaWxlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubi0+aG9zdG5hbWUsIGNvbm4tPnBvcnQpOwogICAgICAgICAgICByZXR1cm4gSFRUUF9TRVJWSUNFX1VOQVZBSUxBQkxFOwogICAgICAgIH0KCiAgICAgICAgLyogY291bnQgZm9yIHN0YXRzICovCiAgICAgICAgY29ubi0+d29ya2VyLT5zLT50cmFuc2ZlcnJlZCArPSB3cml0dGVuOwogICAgICAgIGJ1ZiArPSB3cml0dGVuOwogICAgICAgIGxlbmd0aCAtPSB3cml0dGVuOwogICAgfQoKICAgIHJldHVybiBPSzsKfQoKCi8qCiAqIFNlbmQgU0NHSSBoZWFkZXIgYmxvY2sKICovCnN0YXRpYyBpbnQgc2VuZF9oZWFkZXJzKHJlcXVlc3RfcmVjICpyLCBwcm94eV9jb25uX3JlYyAqY29ubikKewogICAgY2hhciAqYnVmLCAqY3AsICpib2R5bGVuOwogICAgY29uc3QgY2hhciAqbnNfbGVuOwogICAgY29uc3QgYXByX2FycmF5X2hlYWRlcl90ICplbnZfdGFibGU7CiAgICBjb25zdCBhcHJfdGFibGVfZW50cnlfdCAqZW52OwogICAgaW50IGo7CiAgICBhcHJfc2l6ZV90IGxlbiwgYm9keWxlbl9zaXplOwogICAgYXByX3NpemVfdCBoZWFkZXJsZW4gPSAgIHNpemVvZihDT05URU5UX0xFTkdUSCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzaXplb2YoU0NHSV9NQUdJQykKICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzaXplb2YoU0NHSV9QUk9UT0NPTF9WRVJTSU9OKTsKCiAgICBhcF9hZGRfY29tbW9uX3ZhcnMocik7CiAgICBhcF9hZGRfY2dpX3ZhcnMocik7CgogICAgLyoKICAgICAqIFRoZSBoZWFkZXIgYmxvYiBiYXNpY2FsbHkgdGFrZXMgdGhlIGVudmlyb25tZW50IGFuZCBjb25jYXRlbmF0ZXMKICAgICAqIGtleXMgYW5kIHZhbHVlcyB1c2luZyAwIGJ5dGVzLiBUaGVyZSBhcmUgc3BlY2lhbCB0cmVhdG1lbnRzIGhlcmU6CiAgICAgKiAgIC0gR0FURVdBWV9JTlRFUkZBQ0UgYW5kIFNDR0lfTUFHSUMgYXJlIGRyb3BwZWQKICAgICAqICAgLSBDT05URU5UX0xFTkdUSCBpcyBhbHdheXMgc2V0IGFuZCBtdXN0IGJlIHNlbnQgYXMgdGhlIHZlcnkgZmlyc3QKICAgICAqICAgICB2YXJpYWJsZQogICAgICoKICAgICAqIEFkZGl0aW9uYWxseSBpdCdzIHdyYXBwZWQgaW50byBhIHNvLWNhbGxlZCBuZXRzdHJpbmcgKHNlZSBTQ0dJIHNwZWMpCiAgICAgKi8KICAgIGVudl90YWJsZSA9IGFwcl90YWJsZV9lbHRzKHItPnN1YnByb2Nlc3NfZW52KTsKICAgIGVudiA9IChhcHJfdGFibGVfZW50cnlfdCAqKWVudl90YWJsZS0+ZWx0czsKICAgIGZvciAoaiA9IDA7IGogPCBlbnZfdGFibGUtPm5lbHRzOyArK2opIHsKICAgICAgICBpZiAoICAgKCFzdHJjbXAoZW52W2pdLmtleSwgR0FURVdBWV9JTlRFUkZBQ0UpKQogICAgICAgICAgICB8fCAoIXN0cmNtcChlbnZbal0ua2V5LCBDT05URU5UX0xFTkdUSCkpCiAgICAgICAgICAgIHx8ICghc3RyY21wKGVudltqXS5rZXksIFNDR0lfTUFHSUMpKSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaGVhZGVybGVuICs9IHN0cmxlbihlbnZbal0ua2V5KSArIHN0cmxlbihlbnZbal0udmFsKSArIDI7CiAgICB9CiAgICBib2R5bGVuID0gYXByX3BzcHJpbnRmKHItPnBvb2wsICIlIiBBUFJfT0ZGX1RfRk1ULCByLT5yZW1haW5pbmcpOwogICAgYm9keWxlbl9zaXplID0gc3RybGVuKGJvZHlsZW4pICsgMTsKICAgIGhlYWRlcmxlbiArPSBib2R5bGVuX3NpemU7CgogICAgbnNfbGVuID0gYXByX3BzcHJpbnRmKHItPnBvb2wsICIlIiBBUFJfU0laRV9UX0ZNVCAiOiIsIGhlYWRlcmxlbik7CiAgICBsZW4gPSBzdHJsZW4obnNfbGVuKTsKICAgIGhlYWRlcmxlbiArPSBsZW4gKyAxOyAvKiAxID09ICwgKi8KICAgIGNwID0gYnVmID0gYXByX3BhbGxvYyhyLT5wb29sLCBoZWFkZXJsZW4pOwogICAgbWVtY3B5KGNwLCBuc19sZW4sIGxlbik7CiAgICBjcCArPSBsZW47CgogICAgbWVtY3B5KGNwLCBDT05URU5UX0xFTkdUSCwgc2l6ZW9mKENPTlRFTlRfTEVOR1RIKSk7CiAgICBjcCArPSBzaXplb2YoQ09OVEVOVF9MRU5HVEgpOwogICAgbWVtY3B5KGNwLCBib2R5bGVuLCBib2R5bGVuX3NpemUpOwogICAgY3AgKz0gYm9keWxlbl9zaXplOwogICAgbWVtY3B5KGNwLCBTQ0dJX01BR0lDLCBzaXplb2YoU0NHSV9NQUdJQykpOwogICAgY3AgKz0gc2l6ZW9mKFNDR0lfTUFHSUMpOwogICAgbWVtY3B5KGNwLCBTQ0dJX1BST1RPQ09MX1ZFUlNJT04sIHNpemVvZihTQ0dJX1BST1RPQ09MX1ZFUlNJT04pKTsKICAgIGNwICs9IHNpemVvZihTQ0dJX1BST1RPQ09MX1ZFUlNJT04pOwoKICAgIGZvciAoaiA9IDA7IGogPCBlbnZfdGFibGUtPm5lbHRzOyArK2opIHsKICAgICAgICBpZiAoICAgKCFzdHJjbXAoZW52W2pdLmtleSwgR0FURVdBWV9JTlRFUkZBQ0UpKQogICAgICAgICAgICB8fCAoIXN0cmNtcChlbnZbal0ua2V5LCBDT05URU5UX0xFTkdUSCkpCiAgICAgICAgICAgIHx8ICghc3RyY21wKGVudltqXS5rZXksIFNDR0lfTUFHSUMpKSkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgbGVuID0gc3RybGVuKGVudltqXS5rZXkpICsgMTsKICAgICAgICBtZW1jcHkoY3AsIGVudltqXS5rZXksIGxlbik7CiAgICAgICAgY3AgKz0gbGVuOwogICAgICAgIGxlbiA9IHN0cmxlbihlbnZbal0udmFsKSArIDE7CiAgICAgICAgbWVtY3B5KGNwLCBlbnZbal0udmFsLCBsZW4pOwogICAgICAgIGNwICs9IGxlbjsKICAgIH0KICAgICpjcCsrID0gJywnOwoKICAgIHJldHVybiBzZW5kYWxsKGNvbm4sIGJ1ZiwgaGVhZGVybGVuLCByKTsKfQoKCi8qCiAqIFNlbmQgcmVxdWVzdCBib2R5IChpZiBhbnkpCiAqLwpzdGF0aWMgaW50IHNlbmRfcmVxdWVzdF9ib2R5KHJlcXVlc3RfcmVjICpyLCBwcm94eV9jb25uX3JlYyAqY29ubikKewogICAgaWYgKGFwX3Nob3VsZF9jbGllbnRfYmxvY2socikpIHsKICAgICAgICBjaGFyICpidWYgPSBhcHJfcGFsbG9jKHItPnBvb2wsIEFQX0lPQlVGU0laRSk7CiAgICAgICAgaW50IHN0YXR1czsKICAgICAgICBhcHJfc2l6ZV90IHJlYWRsZW47CgogICAgICAgIHJlYWRsZW4gPSBhcF9nZXRfY2xpZW50X2Jsb2NrKHIsIGJ1ZiwgQVBfSU9CVUZTSVpFKTsKICAgICAgICB3aGlsZSAocmVhZGxlbiA+IDApIHsKICAgICAgICAgICAgc3RhdHVzID0gc2VuZGFsbChjb25uLCBidWYsIHJlYWRsZW4sIHIpOwogICAgICAgICAgICBpZiAoc3RhdHVzICE9IE9LKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gSFRUUF9TRVJWSUNFX1VOQVZBSUxBQkxFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlYWRsZW4gPSBhcF9nZXRfY2xpZW50X2Jsb2NrKHIsIGJ1ZiwgQVBfSU9CVUZTSVpFKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlYWRsZW4gPT0gLTEpIHsKICAgICAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDA4NTkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgInJlY2VpdmluZyByZXF1ZXN0IGJvZHkgZmFpbGVkIik7CiAgICAgICAgICAgIHJldHVybiBIVFRQX0lOVEVSTkFMX1NFUlZFUl9FUlJPUjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIE9LOwp9CgoKLyoKICogRmV0Y2ggcmVzcG9uc2UgZnJvbSBiYWNrZW5kIGFuZCBwYXNzIGJhY2sgdG8gdGhlIGZyb250CiAqLwpzdGF0aWMgaW50IHBhc3NfcmVzcG9uc2UocmVxdWVzdF9yZWMgKnIsIHByb3h5X2Nvbm5fcmVjICpjb25uKQp7CiAgICBhcHJfYnVja2V0X2JyaWdhZGUgKmJiOwogICAgYXByX2J1Y2tldCAqYjsKICAgIGNvbnN0IGNoYXIgKmxvY2F0aW9uOwogICAgc2NnaV9jb25maWcgKmNvbmY7CiAgICBzb2NrZXRfZXhfZGF0YSAqc29ja19kYXRhOwogICAgaW50IHN0YXR1czsKCiAgICBzb2NrX2RhdGEgPSBhcHJfcGFsbG9jKHItPnBvb2wsIHNpemVvZigqc29ja19kYXRhKSk7CiAgICBzb2NrX2RhdGEtPnNvY2sgPSBjb25uLT5zb2NrOwogICAgc29ja19kYXRhLT5jb3VudGVyID0gJmNvbm4tPndvcmtlci0+cy0+cmVhZDsKCiAgICBiYiA9IGFwcl9icmlnYWRlX2NyZWF0ZShyLT5wb29sLCByLT5jb25uZWN0aW9uLT5idWNrZXRfYWxsb2MpOwogICAgYiA9IGJ1Y2tldF9zb2NrZXRfZXhfY3JlYXRlKHNvY2tfZGF0YSwgci0+Y29ubmVjdGlvbi0+YnVja2V0X2FsbG9jKTsKICAgIEFQUl9CUklHQURFX0lOU0VSVF9UQUlMKGJiLCBiKTsKICAgIGIgPSBhcHJfYnVja2V0X2Vvc19jcmVhdGUoci0+Y29ubmVjdGlvbi0+YnVja2V0X2FsbG9jKTsKICAgIEFQUl9CUklHQURFX0lOU0VSVF9UQUlMKGJiLCBiKTsKCiAgICBzdGF0dXMgPSBhcF9zY2FuX3NjcmlwdF9oZWFkZXJfZXJyX2JyaWdhZGVfZXgociwgYmIsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVBMT0dfTU9EVUxFX0lOREVYKTsKICAgIGlmIChzdGF0dXMgIT0gT0spIHsKICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0VSUiwgMCwgciwgQVBMT0dOTygwMDg2MCkKICAgICAgICAgICAgICAgICAgICAgICJlcnJvciByZWFkaW5nIHJlc3BvbnNlIGhlYWRlcnMgZnJvbSAlczoldSIsCiAgICAgICAgICAgICAgICAgICAgICBjb25uLT5ob3N0bmFtZSwgY29ubi0+cG9ydCk7CiAgICAgICAgci0+c3RhdHVzX2xpbmUgPSBOVUxMOwogICAgICAgIGFwcl9icmlnYWRlX2Rlc3Ryb3koYmIpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgogICAgY29uZiA9IGFwX2dldF9tb2R1bGVfY29uZmlnKHItPnBlcl9kaXJfY29uZmlnLCAmcHJveHlfc2NnaV9tb2R1bGUpOwogICAgaWYgKGNvbmYtPnNlbmRmaWxlICYmIGNvbmYtPnNlbmRmaWxlICE9IHNjZ2lfc2VuZGZpbGVfb2ZmKSB7CiAgICAgICAgc2hvcnQgZXJyID0gMTsKCiAgICAgICAgbG9jYXRpb24gPSBhcHJfdGFibGVfZ2V0KHItPmVycl9oZWFkZXJzX291dCwgY29uZi0+c2VuZGZpbGUpOwogICAgICAgIGlmICghbG9jYXRpb24pIHsKICAgICAgICAgICAgZXJyID0gMDsKICAgICAgICAgICAgbG9jYXRpb24gPSBhcHJfdGFibGVfZ2V0KHItPmhlYWRlcnNfb3V0LCBjb25mLT5zZW5kZmlsZSk7CiAgICAgICAgfQogICAgICAgIGlmIChsb2NhdGlvbikgewogICAgICAgICAgICBzY2dpX3JlcXVlc3RfY29uZmlnICpyZXFfY29uZiA9IGFwcl9wYWxsb2Moci0+cG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZigqcmVxX2NvbmYpKTsKICAgICAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19ERUJVRywgMCwgciwgQVBMT0dOTygwMDg2MSkKICAgICAgICAgICAgICAgICAgICAgICAgICAiRm91bmQgJXM6ICVzIC0gcHJlcGFyaW5nIHN1YnJlcXVlc3QuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25mLT5zZW5kZmlsZSwgbG9jYXRpb24pOwoKICAgICAgICAgICAgaWYgKGVycikgewogICAgICAgICAgICAgICAgYXByX3RhYmxlX3Vuc2V0KHItPmVycl9oZWFkZXJzX291dCwgY29uZi0+c2VuZGZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgYXByX3RhYmxlX3Vuc2V0KHItPmhlYWRlcnNfb3V0LCBjb25mLT5zZW5kZmlsZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVxX2NvbmYtPmxvY2F0aW9uID0gbG9jYXRpb247CiAgICAgICAgICAgIHJlcV9jb25mLT50eXBlID0gc2NnaV9zZW5kZmlsZTsKICAgICAgICAgICAgYXBfc2V0X21vZHVsZV9jb25maWcoci0+cmVxdWVzdF9jb25maWcsICZwcm94eV9zY2dpX21vZHVsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxX2NvbmYpOwogICAgICAgICAgICBhcHJfYnJpZ2FkZV9kZXN0cm95KGJiKTsKICAgICAgICAgICAgcmV0dXJuIE9LOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoci0+c3RhdHVzID09IEhUVFBfT0sgCiAgICAgICAgJiYgKCFjb25mLT5pbnRlcm5hbF9yZWRpcmVjdCAvKiBkZWZhdWx0ID09PSBPbiAqLwogICAgICAgICAgICB8fCBjb25mLT5pbnRlcm5hbF9yZWRpcmVjdCAhPSBzY2dpX2ludGVybmFsX3JlZGlyZWN0X29mZikpIHsKICAgICAgICBzaG9ydCBlcnIgPSAxOwogICAgICAgIGNvbnN0IGNoYXIgKmxvY2F0aW9uX2hlYWRlciA9IGNvbmYtPmludGVybmFsX3JlZGlyZWN0ID8gCiAgICAgICAgICAgIGNvbmYtPmludGVybmFsX3JlZGlyZWN0IDogc2NnaV9pbnRlcm5hbF9yZWRpcmVjdF9vbjsKCiAgICAgICAgbG9jYXRpb24gPSBhcHJfdGFibGVfZ2V0KHItPmVycl9oZWFkZXJzX291dCwgbG9jYXRpb25faGVhZGVyKTsKICAgICAgICBpZiAoIWxvY2F0aW9uKSB7CiAgICAgICAgICAgIGVyciA9IDA7CiAgICAgICAgICAgIGxvY2F0aW9uID0gYXByX3RhYmxlX2dldChyLT5oZWFkZXJzX291dCwgbG9jYXRpb25faGVhZGVyKTsKICAgICAgICB9CiAgICAgICAgaWYgKGxvY2F0aW9uICYmICpsb2NhdGlvbiA9PSAnLycpIHsKICAgICAgICAgICAgc2NnaV9yZXF1ZXN0X2NvbmZpZyAqcmVxX2NvbmYgPSBhcHJfcGFsbG9jKHItPnBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoKnJlcV9jb25mKSk7CiAgICAgICAgICAgIGlmIChzdHJjYXNlY21wKGxvY2F0aW9uX2hlYWRlciwgIkxvY2F0aW9uIikpIHsKICAgICAgICAgICAgICAgIGlmIChlcnIpIHsKICAgICAgICAgICAgICAgICAgICBhcHJfdGFibGVfdW5zZXQoci0+ZXJyX2hlYWRlcnNfb3V0LCBsb2NhdGlvbl9oZWFkZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYXByX3RhYmxlX3Vuc2V0KHItPmhlYWRlcnNfb3V0LCBsb2NhdGlvbl9oZWFkZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlcV9jb25mLT5sb2NhdGlvbiA9IGxvY2F0aW9uOwogICAgICAgICAgICByZXFfY29uZi0+dHlwZSA9IHNjZ2lfaW50ZXJuYWxfcmVkaXJlY3Q7CiAgICAgICAgICAgIGFwX3NldF9tb2R1bGVfY29uZmlnKHItPnJlcXVlc3RfY29uZmlnLCAmcHJveHlfc2NnaV9tb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcV9jb25mKTsKICAgICAgICAgICAgYXByX2JyaWdhZGVfZGVzdHJveShiYik7CiAgICAgICAgICAgIHJldHVybiBPSzsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGFwX3Bhc3NfYnJpZ2FkZShyLT5vdXRwdXRfZmlsdGVycywgYmIpKSB7CiAgICAgICAgcmV0dXJuIEFQX0ZJTFRFUl9FUlJPUjsKICAgIH0KCiAgICByZXR1cm4gT0s7Cn0KCi8qCiAqIEludGVybmFsIHJlZGlyZWN0IC8gc3VicmVxdWVzdCBoYW5kbGVyLCB3b3JraW5nIG9uIHJlcXVlc3Rfc3RhdHVzIGhvb2sKICovCnN0YXRpYyBpbnQgc2NnaV9yZXF1ZXN0X3N0YXR1cyhpbnQgKnN0YXR1cywgcmVxdWVzdF9yZWMgKnIpCnsKICAgIHNjZ2lfcmVxdWVzdF9jb25maWcgKnJlcV9jb25mOwoKICAgIGlmICggICAoKnN0YXR1cyA9PSBPSykKICAgICAgICAmJiAocmVxX2NvbmYgPSBhcF9nZXRfbW9kdWxlX2NvbmZpZyhyLT5yZXF1ZXN0X2NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHJveHlfc2NnaV9tb2R1bGUpKSkgewogICAgICAgIHN3aXRjaCAocmVxX2NvbmYtPnR5cGUpIHsKICAgICAgICBjYXNlIHNjZ2lfaW50ZXJuYWxfcmVkaXJlY3Q6CiAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfREVCVUcsIDAsIHIsIEFQTE9HTk8oMDA4NjIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkludGVybmFsIHJlZGlyZWN0IHRvICVzIiwgcmVxX2NvbmYtPmxvY2F0aW9uKTsKCiAgICAgICAgICAgIHItPnN0YXR1c19saW5lID0gTlVMTDsKICAgICAgICAgICAgaWYgKHItPm1ldGhvZF9udW1iZXIgIT0gTV9HRVQpIHsKICAgICAgICAgICAgICAgIC8qIGtlZXAgSEVBRCwgd2hpY2ggaXMgcGFzc2VkIGFyb3VuZCBhcyBNX0dFVCwgdG9vICovCiAgICAgICAgICAgICAgICByLT5tZXRob2QgPSAiR0VUIjsKICAgICAgICAgICAgICAgIHItPm1ldGhvZF9udW1iZXIgPSBNX0dFVDsKICAgICAgICAgICAgfQogICAgICAgICAgICBhcHJfdGFibGVfdW5zZXQoci0+aGVhZGVyc19pbiwgIkNvbnRlbnQtTGVuZ3RoIik7CiAgICAgICAgICAgIGFwX2ludGVybmFsX3JlZGlyZWN0X2hhbmRsZXIocmVxX2NvbmYtPmxvY2F0aW9uLCByKTsKICAgICAgICAgICAgcmV0dXJuIE9LOwogICAgICAgICAgICAvKiBicmVhazsgKi8KCiAgICAgICAgY2FzZSBzY2dpX3NlbmRmaWxlOgogICAgICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0RFQlVHLCAwLCByLCBBUExPR05PKDAwODYzKQogICAgICAgICAgICAgICAgICAgICAgICAgICJGaWxlIHN1YnJlcXVlc3QgdG8gJXMiLCByZXFfY29uZi0+bG9jYXRpb24pOwogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICByZXF1ZXN0X3JlYyAqcnI7CgogICAgICAgICAgICAgICAgcnIgPSBhcF9zdWJfcmVxX2xvb2t1cF9maWxlKHJlcV9jb25mLT5sb2NhdGlvbiwgciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByLT5vdXRwdXRfZmlsdGVycyk7CiAgICAgICAgICAgICAgICBpZiAocnItPnN0YXR1cyA9PSBIVFRQX09LICYmIHJyLT5maW5mby5maWxldHlwZSAhPSBBUFJfTk9GSUxFKSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBXZSBkb24ndCB0b3VjaCBDb250ZW50LUxlbmd0aCBoZXJlLiBJdCBtaWdodCBiZQogICAgICAgICAgICAgICAgICAgICAqIGJvcmtlZCAodGhlcmUncyBwbGVudHkgb2Ygcm9vbSBmb3IgYSByYWNlIGNvbmRpdGlvbikuCiAgICAgICAgICAgICAgICAgICAgICogRWl0aGVyIHRoZSBiYWNrZW5kIHNldHMgaXQgb3IgaXQncyBnb25uYSBiZSBjaHVua2VkLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGFwX3J1bl9zdWJfcmVxKHJyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGFwX2xvZ19yZXJyb3IoQVBMT0dfTUFSSywgQVBMT0dfRVJSLCAwLCByLCBBUExPR05PKDAwODY0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN1YnJlcXVlc3QgdG8gZmlsZSAnJXMnIG5vdCBwb3NzaWJsZS4gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihyci0+c3RhdHVzPSVkLCByci0+ZmluZm8uZmlsZXR5cGU9JWQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcV9jb25mLT5sb2NhdGlvbiwgcnItPnN0YXR1cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJyLT5maW5mby5maWxldHlwZSk7CiAgICAgICAgICAgICAgICAgICAgKnN0YXR1cyA9IEhUVFBfSU5URVJOQUxfU0VSVkVSX0VSUk9SOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAqc3RhdHVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IHdoaWxlICgwKTsKCiAgICAgICAgICAgIHJldHVybiBPSzsKICAgICAgICAgICAgLyogYnJlYWs7ICovCiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBERUNMSU5FRDsKfQoKCi8qCiAqIFRoaXMgaGFuZGxlcyBzY2dpOihkZXN0KSBVUkxzCiAqLwpzdGF0aWMgaW50IHNjZ2lfaGFuZGxlcihyZXF1ZXN0X3JlYyAqciwgcHJveHlfd29ya2VyICp3b3JrZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5X3NlcnZlcl9jb25mICpjb25mLCBjaGFyICp1cmwsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnByb3h5bmFtZSwgYXByX3BvcnRfdCBwcm94eXBvcnQpCnsKICAgIGludCBzdGF0dXM7CiAgICBwcm94eV9jb25uX3JlYyAqYmFja2VuZCA9IE5VTEw7CiAgICBhcHJfcG9vbF90ICpwID0gci0+cG9vbDsKICAgIGFwcl91cmlfdCAqdXJpOwogICAgY2hhciBkdW1teTsKCiAgICBpZiAoc3RybmNhc2VjbXAodXJsLCBTQ0hFTUUgIjovLyIsIHNpemVvZihTQ0hFTUUpICsgMikpIHsKICAgICAgICBhcF9sb2dfcmVycm9yKEFQTE9HX01BUkssIEFQTE9HX0RFQlVHLCAwLCByLCBBUExPR05PKDAwODY1KQogICAgICAgICAgICAgICAgICAgICAgImRlY2xpbmluZyBVUkwgJXMiLCB1cmwpOwogICAgICAgIHJldHVybiBERUNMSU5FRDsKICAgIH0KCiAgICAvKiBDcmVhdGUgc3BhY2UgZm9yIHN0YXRlIGluZm9ybWF0aW9uICovCiAgICBzdGF0dXMgPSBhcF9wcm94eV9hY3F1aXJlX2Nvbm5lY3Rpb24oUFJPWFlfRlVOQ1RJT04sICZiYWNrZW5kLCB3b3JrZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0+c2VydmVyKTsKICAgIGlmIChzdGF0dXMgIT0gT0spIHsKICAgICAgICBnb3RvIGNsZWFudXA7CiAgICB9CiAgICBiYWNrZW5kLT5pc19zc2wgPSAwOwoKICAgIC8qIFN0ZXAgT25lOiBEZXRlcm1pbmUgV2hvIFRvIENvbm5lY3QgVG8gKi8KICAgIHVyaSA9IGFwcl9wYWxsb2MocCwgc2l6ZW9mKCp1cmkpKTsKICAgIHN0YXR1cyA9IGFwX3Byb3h5X2RldGVybWluZV9jb25uZWN0aW9uKHAsIHIsIGNvbmYsIHdvcmtlciwgYmFja2VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVyaSwgJnVybCwgcHJveHluYW1lLCBwcm94eXBvcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZHVtbXksIDEpOwogICAgaWYgKHN0YXR1cyAhPSBPSykgewogICAgICAgIGdvdG8gY2xlYW51cDsKICAgIH0KCiAgICAvKiBTdGVwIFR3bzogTWFrZSB0aGUgQ29ubmVjdGlvbiAqLwogICAgaWYgKGFwX3Byb3h5X2Nvbm5lY3RfYmFja2VuZChQUk9YWV9GVU5DVElPTiwgYmFja2VuZCwgd29ya2VyLCByLT5zZXJ2ZXIpKSB7CiAgICAgICAgYXBfbG9nX3JlcnJvcihBUExPR19NQVJLLCBBUExPR19FUlIsIDAsIHIsIEFQTE9HTk8oMDA4NjYpCiAgICAgICAgICAgICAgICAgICAgICAiZmFpbGVkIHRvIG1ha2UgY29ubmVjdGlvbiB0byBiYWNrZW5kOiAlczoldSIsCiAgICAgICAgICAgICAgICAgICAgICBiYWNrZW5kLT5ob3N0bmFtZSwgYmFja2VuZC0+cG9ydCk7CiAgICAgICAgc3RhdHVzID0gSFRUUF9TRVJWSUNFX1VOQVZBSUxBQkxFOwogICAgICAgIGdvdG8gY2xlYW51cDsKICAgIH0KCiAgICAvKiBTdGVwIFRocmVlOiBQcm9jZXNzIHRoZSBSZXF1ZXN0ICovCiAgICBpZiAoICAgKChzdGF0dXMgPSBhcF9zZXR1cF9jbGllbnRfYmxvY2sociwgUkVRVUVTVF9DSFVOS0VEX0VSUk9SKSkgIT0gT0spCiAgICAgICAgfHwgKChzdGF0dXMgPSBzZW5kX2hlYWRlcnMociwgYmFja2VuZCkpICE9IE9LKQogICAgICAgIHx8ICgoc3RhdHVzID0gc2VuZF9yZXF1ZXN0X2JvZHkociwgYmFja2VuZCkpICE9IE9LKQogICAgICAgIHx8ICgoc3RhdHVzID0gcGFzc19yZXNwb25zZShyLCBiYWNrZW5kKSkgIT0gT0spKSB7CiAgICAgICAgZ290byBjbGVhbnVwOwogICAgfQoKY2xlYW51cDoKICAgIGlmIChiYWNrZW5kKSB7CiAgICAgICAgYmFja2VuZC0+Y2xvc2UgPSAxOyAvKiBhbHdheXMgY2xvc2UgdGhlIHNvY2tldCAqLwogICAgICAgIGFwX3Byb3h5X3JlbGVhc2VfY29ubmVjdGlvbihQUk9YWV9GVU5DVElPTiwgYmFja2VuZCwgci0+c2VydmVyKTsKICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KCgpzdGF0aWMgdm9pZCAqY3JlYXRlX3NjZ2lfY29uZmlnKGFwcl9wb29sX3QgKnAsIGNoYXIgKmR1bW15KQp7CiAgICBzY2dpX2NvbmZpZyAqY29uZj1hcHJfcGFsbG9jKHAsIHNpemVvZigqY29uZikpOwoKICAgIGNvbmYtPnNlbmRmaWxlID0gTlVMTDsgLyogPT09IGRlZmF1bHQgKG9mZikgKi8KICAgIGNvbmYtPmludGVybmFsX3JlZGlyZWN0ID0gTlVMTDsgLyogPT09IGRlZmF1bHQgKG9uKSAqLwoKICAgIHJldHVybiBjb25mOwp9CgoKc3RhdGljIHZvaWQgKm1lcmdlX3NjZ2lfY29uZmlnKGFwcl9wb29sX3QgKnAsIHZvaWQgKmJhc2VfLCB2b2lkICphZGRfKQp7CiAgICBzY2dpX2NvbmZpZyAqYmFzZT1iYXNlXywgKmFkZD1hZGRfLCAqY29uZj1hcHJfcGFsbG9jKHAsIHNpemVvZigqY29uZikpOwoKICAgIGNvbmYtPnNlbmRmaWxlID0gYWRkLT5zZW5kZmlsZSA/IGFkZC0+c2VuZGZpbGU6IGJhc2UtPnNlbmRmaWxlOwogICAgY29uZi0+aW50ZXJuYWxfcmVkaXJlY3QgPSBhZGQtPmludGVybmFsX3JlZGlyZWN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYWRkLT5pbnRlcm5hbF9yZWRpcmVjdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGJhc2UtPmludGVybmFsX3JlZGlyZWN0OwogICAgcmV0dXJuIGNvbmY7Cn0KCgpzdGF0aWMgY29uc3QgY2hhciAqc2NnaV9zZXRfc2VuZF9maWxlKGNtZF9wYXJtcyAqY21kLCB2b2lkICptY29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmFyZykKewogICAgc2NnaV9jb25maWcgKmNvbmY9bWNvbmZpZzsKCiAgICBpZiAoIXN0cmNhc2VjbXAoYXJnLCAiT2ZmIikpIHsKICAgICAgICBjb25mLT5zZW5kZmlsZSA9IHNjZ2lfc2VuZGZpbGVfb2ZmOwogICAgfQogICAgZWxzZSBpZiAoIXN0cmNhc2VjbXAoYXJnLCAiT24iKSkgewogICAgICAgIGNvbmYtPnNlbmRmaWxlID0gc2NnaV9zZW5kZmlsZV9vbjsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGNvbmYtPnNlbmRmaWxlID0gYXJnOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCgpzdGF0aWMgY29uc3QgY2hhciAqc2NnaV9zZXRfaW50ZXJuYWxfcmVkaXJlY3QoY21kX3Bhcm1zICpjbWQsIHZvaWQgKm1jb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICphcmcpCnsKICAgIHNjZ2lfY29uZmlnICpjb25mID0gbWNvbmZpZzsKCiAgICBpZiAoIXN0cmNhc2VjbXAoYXJnLCAiT2ZmIikpIHsKICAgICAgICBjb25mLT5pbnRlcm5hbF9yZWRpcmVjdCA9IHNjZ2lfaW50ZXJuYWxfcmVkaXJlY3Rfb2ZmOwogICAgfQogICAgZWxzZSBpZiAoIXN0cmNhc2VjbXAoYXJnLCAiT24iKSkgewogICAgICAgIGNvbmYtPmludGVybmFsX3JlZGlyZWN0ID0gc2NnaV9pbnRlcm5hbF9yZWRpcmVjdF9vbjsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGNvbmYtPmludGVybmFsX3JlZGlyZWN0ID0gYXJnOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCgpzdGF0aWMgY29uc3QgY29tbWFuZF9yZWMgc2NnaV9jbWRzW10gPQp7CiAgICBBUF9JTklUX1RBS0UxKCJQcm94eVNDR0lTZW5kZmlsZSIsIHNjZ2lfc2V0X3NlbmRfZmlsZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgUlNSQ19DT05GfEFDQ0VTU19DT05GLAogICAgICAgICAgICAgICAgICAiVGhlIG5hbWUgb2YgdGhlIFgtU2VuZGZpbGUgcHNldWRvIHJlc3BvbnNlIGhlYWRlciBvciAiCiAgICAgICAgICAgICAgICAgICJPbiBvciBPZmYiKSwKICAgIEFQX0lOSVRfVEFLRTEoIlByb3h5U0NHSUludGVybmFsUmVkaXJlY3QiLCBzY2dpX3NldF9pbnRlcm5hbF9yZWRpcmVjdCwgTlVMTCwKICAgICAgICAgICAgICAgICAgUlNSQ19DT05GfEFDQ0VTU19DT05GLAogICAgICAgICAgICAgICAgICAiVGhlIG5hbWUgb2YgdGhlIHBzZXVkbyByZXNwb25zZSBoZWFkZXIgb3IgT24gb3IgT2ZmIiksCiAgICB7TlVMTH0KfTsKCgpzdGF0aWMgdm9pZCByZWdpc3Rlcl9ob29rcyhhcHJfcG9vbF90ICpwKQp7CiAgICBwcm94eV9ob29rX3NjaGVtZV9oYW5kbGVyKHNjZ2lfaGFuZGxlciwgTlVMTCwgTlVMTCwgQVBSX0hPT0tfRklSU1QpOwogICAgcHJveHlfaG9va19jYW5vbl9oYW5kbGVyKHNjZ2lfY2Fub24sIE5VTEwsIE5VTEwsIEFQUl9IT09LX0ZJUlNUKTsKICAgIEFQUl9PUFRJT05BTF9IT09LKHByb3h5LCByZXF1ZXN0X3N0YXR1cywgc2NnaV9yZXF1ZXN0X3N0YXR1cywgTlVMTCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgIEFQUl9IT09LX01JRERMRSk7Cn0KCgpBUF9ERUNMQVJFX01PRFVMRShwcm94eV9zY2dpKSA9IHsKICAgIFNUQU5EQVJEMjBfTU9EVUxFX1NUVUZGLAogICAgY3JlYXRlX3NjZ2lfY29uZmlnLCAgLyogY3JlYXRlIHBlci1kaXJlY3RvcnkgY29uZmlnIHN0cnVjdHVyZSAqLwogICAgbWVyZ2Vfc2NnaV9jb25maWcsICAgLyogbWVyZ2UgcGVyLWRpcmVjdG9yeSBjb25maWcgc3RydWN0dXJlcyAqLwogICAgTlVMTCwgICAgICAgICAgICAgICAgLyogY3JlYXRlIHBlci1zZXJ2ZXIgY29uZmlnIHN0cnVjdHVyZSAqLwogICAgTlVMTCwgICAgICAgICAgICAgICAgLyogbWVyZ2UgcGVyLXNlcnZlciBjb25maWcgc3RydWN0dXJlcyAqLwogICAgc2NnaV9jbWRzLCAgICAgICAgICAgLyogY29tbWFuZCB0YWJsZSAqLwogICAgcmVnaXN0ZXJfaG9va3MgICAgICAgLyogcmVnaXN0ZXIgaG9va3MgKi8KfTsK