LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhd2F5IGxpa2UgYSBtYWRtYW4gYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAic2V0dXAuaCIKCiNpZm5kZWYgQ1VSTF9ESVNBQkxFX0ZUUAojaWZkZWYgSEFWRV9LUkI0CgojaW5jbHVkZSAic2VjdXJpdHkuaCIKI2luY2x1ZGUgImJhc2U2NC5oIgojaW5jbHVkZSA8c3RkbGliLmg+CiNpZmRlZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxrcmIuaD4KI2luY2x1ZGUgPGRlcy5oPgoKI2lmZGVmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPiAvKiBmb3IgZ2V0cGlkKCkgKi8KI2VuZGlmCgojaW5jbHVkZSAiZnRwLmgiCiNpbmNsdWRlICJzZW5kZi5oIgojaW5jbHVkZSAia3JiNC5oIgojaW5jbHVkZSAibWVtb3J5LmgiCgojaWYgZGVmaW5lZChIQVZFX0lORVRfTlRPQV9SKSAmJiAhZGVmaW5lZChIQVZFX0lORVRfTlRPQV9SX0RFQ0wpCiNpbmNsdWRlICJpbmV0X250b2Ffci5oIgojZW5kaWYKCi8qIFRoZSBsYXN0ICNpbmNsdWRlIGZpbGUgc2hvdWxkIGJlOiAqLwojaW5jbHVkZSAibWVtZGVidWcuaCIKCiNkZWZpbmUgTE9DQUxfQUREUiAoJmNvbm4tPmxvY2FsX2FkZHIpCiNkZWZpbmUgUkVNT1RFX0FERFIgY29ubi0+aXBfYWRkci0+YWlfYWRkcgojZGVmaW5lIG15Y3RsYWRkciBMT0NBTF9BRERSCiNkZWZpbmUgaGlzY3RsYWRkciBSRU1PVEVfQUREUgoKc3RydWN0IGtyYjRfZGF0YSB7CiAgZGVzX2NibG9jayBrZXk7CiAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICBjaGFyIG5hbWVbQU5BTUVfU1pdOwogIGNoYXIgaW5zdGFuY2VbSU5TVF9TWl07CiAgY2hhciByZWFsbVtSRUFMTV9TWl07Cn07CgojaWZuZGVmIEhBVkVfU1RSTENQWQovKiBpZiBpdCBldmVyIGdvZXMgbm9uLXN0YXRpYywgbWFrZSBpdCBDdXJsXyBwcmVmaXhlZCEgKi8Kc3RhdGljIHNpemVfdApzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeikKewogIHNpemVfdCBuOwogIGNoYXIgKnA7CgogIGZvciAocCA9IGRzdCwgbiA9IDA7CiAgICAgICBuICsgMSA8IGRzdF9zeiAmJiAqc3JjICE9ICdcMCc7CiAgICAgICArK3AsICsrc3JjLCArK24pCiAgICAqcCA9ICpzcmM7CiAgKnAgPSAnXDAnOwogIGlmICgqc3JjID09ICdcMCcpCiAgICByZXR1cm4gbjsKICBlbHNlCiAgICByZXR1cm4gbiArIHN0cmxlbiAoc3JjKTsKfQojZWxzZQpzaXplX3Qgc3RybGNweSAoY2hhciAqZHN0LCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCBkc3Rfc3opOwojZW5kaWYKCnN0YXRpYyBpbnQKa3JiNF9jaGVja19wcm90KHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwpCnsKICBhcHBfZGF0YSA9IE5VTEw7IC8qIHByZXZlbnQgY29tcGlsZXIgd2FybmluZyAqLwogIGlmKGxldmVsID09IHByb3RfY29uZmlkZW50aWFsKQogICAgcmV0dXJuIC0xOwogIHJldHVybiAwOwp9CgpzdGF0aWMgaW50CmtyYjRfZGVjb2RlKHZvaWQgKmFwcF9kYXRhLCB2b2lkICpidWYsIGludCBsZW4sIGludCBsZXZlbCwKICAgICAgICAgICAgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgTVNHX0RBVCBtOwogIGludCBlOwogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKCiAgaWYobGV2ZWwgPT0gcHJvdF9zYWZlKQogICAgZSA9IGtyYl9yZF9zYWZlKGJ1ZiwgbGVuLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUiwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwgJm0pOwogIGVsc2UKICAgIGUgPSBrcmJfcmRfcHJpdihidWYsIGxlbiwgZC0+c2NoZWR1bGUsICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLCAmbSk7CiAgaWYoZSkgewogICAgc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGEgPSBjb25uLT5kYXRhOwogICAgaW5mb2YoZGF0YSwgImtyYjRfZGVjb2RlOiAlc1xuIiwga3JiX2dldF9lcnJfdGV4dChlKSk7CiAgICByZXR1cm4gLTE7CiAgfQogIG1lbW1vdmUoYnVmLCBtLmFwcF9kYXRhLCBtLmFwcF9sZW5ndGgpOwogIHJldHVybiBtLmFwcF9sZW5ndGg7Cn0KCnN0YXRpYyBpbnQKa3JiNF9vdmVyaGVhZCh2b2lkICphcHBfZGF0YSwgaW50IGxldmVsLCBpbnQgbGVuKQp7CiAgLyogbm8gYXJndW1lbnRzIGFyZSB1c2VkLCBqdXN0IGluaXQgdGhlbSB0byBwcmV2ZW50IGNvbXBpbGVyIHdhcm5pbmdzICovCiAgYXBwX2RhdGEgPSBOVUxMOwogIGxldmVsID0gMDsKICBsZW4gPSAwOwogIHJldHVybiAzMTsKfQoKc3RhdGljIGludAprcmI0X2VuY29kZSh2b2lkICphcHBfZGF0YSwgdm9pZCAqZnJvbSwgaW50IGxlbmd0aCwgaW50IGxldmVsLCB2b2lkICoqdG8sCiAgICAgICAgICAgIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICAqdG8gPSBtYWxsb2MobGVuZ3RoICsgMzEpOwogIGlmKGxldmVsID09IHByb3Rfc2FmZSkKICAgIHJldHVybiBrcmJfbWtfc2FmZShmcm9tLCAqdG8sIGxlbmd0aCwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIpOwogIGVsc2UgaWYobGV2ZWwgPT0gcHJvdF9wcml2YXRlKQogICAgcmV0dXJuIGtyYl9ta19wcml2KGZyb20sICp0bywgbGVuZ3RoLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIpOwogIGVsc2UKICAgIHJldHVybiAtMTsKfQoKc3RhdGljIGludApta19hdXRoKHN0cnVjdCBrcmI0X2RhdGEgKmQsIEtURVhUIGFkYXQsCiAgICAgICAgY29uc3QgY2hhciAqc2VydmljZSwgY2hhciAqaG9zdCwgaW50IGNoZWNrc3VtKQp7CiAgaW50IHJldDsKICBDUkVERU5USUFMUyBjcmVkOwogIGNoYXIgc25hbWVbU05BTUVfU1pdLCBpbnN0W0lOU1RfU1pdLCByZWFsbVtSRUFMTV9TWl07CgogIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICBzdHJsY3B5KHJlYWxtLCBrcmJfcmVhbG1vZmhvc3QoaG9zdCksIHNpemVvZihyZWFsbSkpOwogIHJldCA9IGtyYl9ta19yZXEoYWRhdCwgc25hbWUsIGluc3QsIHJlYWxtLCBjaGVja3N1bSk7CiAgaWYocmV0KQogICAgcmV0dXJuIHJldDsKICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICBzdHJsY3B5KGluc3QsIGtyYl9nZXRfcGhvc3QoaG9zdCksIHNpemVvZihpbnN0KSk7CiAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICByZXQgPSBrcmJfZ2V0X2NyZWQoc25hbWUsIGluc3QsIHJlYWxtLCAmY3JlZCk7CiAgbWVtbW92ZSgmZC0+a2V5LCAmY3JlZC5zZXNzaW9uLCBzaXplb2YoZGVzX2NibG9jaykpOwogIGRlc19rZXlfc2NoZWQoJmQtPmtleSwgZC0+c2NoZWR1bGUpOwogIG1lbXNldCgmY3JlZCwgMCwgc2l6ZW9mKGNyZWQpKTsKICByZXR1cm4gcmV0Owp9CgojaWZkZWYgSEFWRV9LUkJfR0VUX09VUl9JUF9GT1JfUkVBTE0KaW50IGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShjaGFyICosIHN0cnVjdCBpbl9hZGRyICopOwojZW5kaWYKCnN0YXRpYyBpbnQKa3JiNF9hdXRoKHZvaWQgKmFwcF9kYXRhLCBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgcmV0OwogIGNoYXIgKnA7CiAgaW50IGxlbjsKICBLVEVYVF9TVCBhZGF0OwogIE1TR19EQVQgbXNnX2RhdGE7CiAgaW50IGNoZWNrc3VtOwogIHVfaW50MzJfdCBjczsKICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgY2hhciAqaG9zdCA9IGNvbm4tPmhvc3QubmFtZTsKICBzc2l6ZV90IG5yZWFkOwogIGludCBsID0gc2l6ZW9mKGNvbm4tPmxvY2FsX2FkZHIpOwogIHN0cnVjdCBTZXNzaW9uSGFuZGxlICpkYXRhID0gY29ubi0+ZGF0YTsKICBDVVJMY29kZSByZXN1bHQ7CgogIGlmKGdldHNvY2tuYW1lKGNvbm4tPnNvY2tbRklSU1RTT0NLRVRdLAogICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHIgKilMT0NBTF9BRERSLCAmbCkgPCAwKQogICAgcGVycm9yKCJnZXRzb2NrbmFtZSgpIik7CgogIGNoZWNrc3VtID0gZ2V0cGlkKCk7CiAgcmV0ID0gbWtfYXV0aChkLCAmYWRhdCwgImZ0cCIsIGhvc3QsIGNoZWNrc3VtKTsKICBpZihyZXQgPT0gS0RDX1BSX1VOS05PV04pCiAgICByZXQgPSBta19hdXRoKGQsICZhZGF0LCAicmNtZCIsIGhvc3QsIGNoZWNrc3VtKTsKICBpZihyZXQpIHsKICAgIGluZm9mKGRhdGEsICIlc1xuIiwga3JiX2dldF9lcnJfdGV4dChyZXQpKTsKICAgIHJldHVybiBBVVRIX0NPTlRJTlVFOwogIH0KCiNpZmRlZiBIQVZFX0tSQl9HRVRfT1VSX0lQX0ZPUl9SRUFMTQogIGlmIChrcmJfZ2V0X2NvbmZpZ19ib29sKCJuYXRfaW5fdXNlIikpIHsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiAqbG9jYWxhZGRyICA9IChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSOwogICAgc3RydWN0IGluX2FkZHIgbmF0QWRkcjsKCiAgICBpZiAoa3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKGtyYl9yZWFsbW9maG9zdChob3N0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm5hdEFkZHIpICE9IEtTVUNDRVNTCiAgICAgICAgJiYga3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKE5VTEwsICZuYXRBZGRyKSAhPSBLU1VDQ0VTUykKICAgICAgaW5mb2YoZGF0YSwgIkNhbid0IGdldCBhZGRyZXNzIGZvciByZWFsbSAlc1xuIiwKICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoaG9zdCkpOwogICAgZWxzZSB7CiAgICAgIGlmIChuYXRBZGRyLnNfYWRkciAhPSBsb2NhbGFkZHItPnNpbl9hZGRyLnNfYWRkcikgewojaWZkZWYgSEFWRV9JTkVUX05UT0FfUgogICAgICAgIGNoYXIgbnRvYV9idWZbNjRdOwogICAgICAgIGNoYXIgKmlwID0gKGNoYXIgKilpbmV0X250b2FfcihuYXRBZGRyLCBudG9hX2J1Ziwgc2l6ZW9mKG50b2FfYnVmKSk7CiNlbHNlCiAgICAgICAgY2hhciAqaXAgPSAoY2hhciAqKWluZXRfbnRvYShuYXRBZGRyKTsKI2VuZGlmCiAgICAgICAgaW5mb2YoZGF0YSwgIlVzaW5nIE5BVCBJUCBhZGRyZXNzICglcykgZm9yIGtlcmJlcm9zIDRcbiIsIGlwKTsKICAgICAgICBsb2NhbGFkZHItPnNpbl9hZGRyID0gbmF0QWRkcjsKICAgICAgfQogICAgfQogIH0KI2VuZGlmCgogIGlmKEN1cmxfYmFzZTY0X2VuY29kZSgoY2hhciAqKWFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJnApIDwgMSkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmciKTsKICAgIHJldHVybiBBVVRIX0NPTlRJTlVFOwogIH0KCiAgcmVzdWx0ID0gQ3VybF9mdHBzZW5kZihjb25uLCAiQURBVCAlcyIsIHApOwoKICBmcmVlKHApOwoKICBpZihyZXN1bHQpCiAgICByZXR1cm4gLTI7CgogIGlmKEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKSkKICAgIHJldHVybiAtMTsKCiAgaWYoZGF0YS0+c3RhdGUuYnVmZmVyWzBdICE9ICcyJyl7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJTZXJ2ZXIgZGlkbid0IGFjY2VwdCBhdXRoIGRhdGEiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KCiAgcCA9IHN0cnN0cihkYXRhLT5zdGF0ZS5idWZmZXIsICJBREFUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJSZW1vdGUgaG9zdCBkaWRuJ3Qgc2VuZCBhZGF0IHJlcGx5Iik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgcCArPSA1OwogIGxlbiA9IEN1cmxfYmFzZTY0X2RlY29kZShwLCAoY2hhciAqKWFkYXQuZGF0KTsKICBpZihsZW4gPCAwKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJGYWlsZWQgdG8gZGVjb2RlIGJhc2U2NCBmcm9tIHNlcnZlciIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIGFkYXQubGVuZ3RoID0gbGVuOwogIHJldCA9IGtyYl9yZF9zYWZlKGFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopaGlzY3RsYWRkciwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopbXljdGxhZGRyLCAmbXNnX2RhdGEpOwogIGlmKHJldCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiRXJyb3IgcmVhZGluZyByZXBseSBmcm9tIHNlcnZlcjogJXMiLAogICAgICAgICAgICAgICBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIGtyYl9nZXRfaW50KG1zZ19kYXRhLmFwcF9kYXRhLCAmY3MsIDQsIDApOwogIGlmKGNzIC0gY2hlY2tzdW0gIT0gMSkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiQmFkIGNoZWNrc3VtIHJldHVybmVkIGZyb20gc2VydmVyIik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgcmV0dXJuIEFVVEhfT0s7Cn0KCnN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCBDdXJsX2tyYjRfY2xpZW50X21lY2ggPSB7CiAgICAiS0VSQkVST1NfVjQiLAogICAgc2l6ZW9mKHN0cnVjdCBrcmI0X2RhdGEpLAogICAgTlVMTCwgLyogaW5pdCAqLwogICAga3JiNF9hdXRoLAogICAgTlVMTCwgLyogZW5kICovCiAgICBrcmI0X2NoZWNrX3Byb3QsCiAgICBrcmI0X292ZXJoZWFkLAogICAga3JiNF9lbmNvZGUsCiAgICBrcmI0X2RlY29kZQp9OwoKQ1VSTGNvZGUgQ3VybF9rcmJfa2F1dGgoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgZGVzX2NibG9jayBrZXk7CiAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICBLVEVYVF9TVCB0a3QsIHRrdGNvcHk7CiAgY2hhciAqbmFtZTsKICBjaGFyICpwOwogIGNoYXIgcGFzc3dkWzEwMF07CiAgaW50IHRtcDsKICBzc2l6ZV90IG5yZWFkOwogIGludCBzYXZlOwogIENVUkxjb2RlIHJlc3VsdDsKCiAgc2F2ZSA9IEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBwcm90X3ByaXZhdGUpOwoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzIiwgY29ubi0+dXNlcik7CgogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIHJlc3VsdCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzMnKXsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KCiAgcCA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJCYWQgcmVwbHkgZnJvbSBzZXJ2ZXIiKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KCiAgcCArPSAyOwogIHRtcCA9IEN1cmxfYmFzZTY0X2RlY29kZShwLCAoY2hhciAqKXRrdC5kYXQpOwogIGlmKHRtcCA8IDApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBkZWNvZGUgYmFzZTY0IGluIHJlcGx5LlxuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CiAgdGt0Lmxlbmd0aCA9IHRtcDsKICB0a3Rjb3B5Lmxlbmd0aCA9IHRrdC5sZW5ndGg7CgogIHAgPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiUD0iKTsKICBpZighcCkgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiQmFkIHJlcGx5IGZyb20gc2VydmVyIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CiAgbmFtZSA9IHAgKyAyOwogIGZvcig7ICpwICYmICpwICE9ICcgJyAmJiAqcCAhPSAnXHInICYmICpwICE9ICdcbic7IHArKyk7CiAgKnAgPSAwOwoKICBkZXNfc3RyaW5nX3RvX2tleSAoY29ubi0+cGFzc3dkLCAma2V5KTsKICBkZXNfa2V5X3NjaGVkKCZrZXksIHNjaGVkdWxlKTsKCiAgZGVzX3BjYmNfZW5jcnlwdCgodm9pZCAqKXRrdC5kYXQsICh2b2lkICopdGt0Y29weS5kYXQsCiAgICAgICAgICAgICAgICAgICB0a3QubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICBpZiAoc3RyY21wICgoY2hhciopdGt0Y29weS5kYXQgKyA4LAogICAgICAgICAgICAgIEtSQl9USUNLRVRfR1JBTlRJTkdfVElDS0VUKSAhPSAwKSB7CiAgICBhZnNfc3RyaW5nX3RvX2tleShwYXNzd2QsCiAgICAgICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoY29ubi0+aG9zdC5uYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICZrZXkpOwogICAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CiAgICBkZXNfcGNiY19lbmNyeXB0KCh2b2lkICopdGt0LmRhdCwgKHZvaWQgKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgICAgdGt0Lmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICB9CiAgbWVtc2V0KGtleSwgMCwgc2l6ZW9mKGtleSkpOwogIG1lbXNldChzY2hlZHVsZSwgMCwgc2l6ZW9mKHNjaGVkdWxlKSk7CiAgbWVtc2V0KHBhc3N3ZCwgMCwgc2l6ZW9mKHBhc3N3ZCkpOwogIGlmKEN1cmxfYmFzZTY0X2VuY29kZSgoY2hhciAqKXRrdGNvcHkuZGF0LCB0a3Rjb3B5Lmxlbmd0aCwgJnApIDwgMSkgewogICAgZmFpbGYoY29ubi0+ZGF0YSwgIk91dCBvZiBtZW1vcnkgYmFzZTY0LWVuY29kaW5nLiIpOwogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX09VVF9PRl9NRU1PUlk7CiAgfQogIG1lbXNldCAodGt0Y29weS5kYXQsIDAsIHRrdGNvcHkubGVuZ3RoKTsKCiAgcmVzdWx0ID0gQ3VybF9mdHBzZW5kZihjb25uLCAiU0lURSBLQVVUSCAlcyAlcyIsIG5hbWUsIHApOwogIGZyZWUocCk7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKCiAgcmVzdWx0ID0gQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sIE5VTEwpOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CiAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwoKICByZXR1cm4gQ1VSTEVfT0s7Cn0KCiNlbmRpZiAvKiBIQVZFX0tSQjQgKi8KI2VuZGlmIC8qIENVUkxfRElTQUJMRV9GVFAgKi8K