LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIE1hcnRpbidzIGxhdGVzdCBjaGFuZ2VzIHdlcmUgZG9uZSAyMDAwLTA5LTE4LgogKgogKiBJdCBoYXMgc2luY2UgYmVlbiBwYXRjaGVkIGF3YXkgbGlrZSBhIG1hZG1hbiBieSBEYW5pZWwgU3RlbmJlcmcgdG8gbWFrZSBpdAogKiBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZQogKiBuYW1lIHNwYWNlIGFuZCBtb3JlLgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBDb3B5cmlnaHQgKGMpIDIwMDQgLSAyMDExIERhbmllbCBTdGVuYmVyZwogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICovCgojaW5jbHVkZSAic2V0dXAuaCIKCiNpZm5kZWYgQ1VSTF9ESVNBQkxFX0ZUUAojaWZkZWYgSEFWRV9LUkI0CgojaWZkZWYgSEFWRV9ORVREQl9ICiNpbmNsdWRlIDxuZXRkYi5oPgojZW5kaWYKI2luY2x1ZGUgPGtyYi5oPgojaW5jbHVkZSA8ZGVzLmg+CgojaWZkZWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+IC8qIGZvciBnZXRwaWQoKSAqLwojZW5kaWYKCiNpbmNsdWRlICJ1cmxkYXRhLmgiCiNpbmNsdWRlICJjdXJsX2Jhc2U2NC5oIgojaW5jbHVkZSAiZnRwLmgiCiNpbmNsdWRlICJzZW5kZi5oIgojaW5jbHVkZSAia3JiNC5oIgojaW5jbHVkZSAiaW5ldF9udG9wLmgiCiNpbmNsdWRlICJjdXJsX21lbW9yeS5oIgoKLyogVGhlIGxhc3QgI2luY2x1ZGUgZmlsZSBzaG91bGQgYmU6ICovCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgoKI2RlZmluZSBMT0NBTF9BRERSICgmY29ubi0+bG9jYWxfYWRkcikKI2RlZmluZSBSRU1PVEVfQUREUiBjb25uLT5pcF9hZGRyLT5haV9hZGRyCiNkZWZpbmUgbXljdGxhZGRyIExPQ0FMX0FERFIKI2RlZmluZSBoaXNjdGxhZGRyIFJFTU9URV9BRERSCgpzdHJ1Y3Qga3JiNF9kYXRhIHsKICBkZXNfY2Jsb2NrIGtleTsKICBkZXNfa2V5X3NjaGVkdWxlIHNjaGVkdWxlOwogIGNoYXIgbmFtZVtBTkFNRV9TWl07CiAgY2hhciBpbnN0YW5jZVtJTlNUX1NaXTsKICBjaGFyIHJlYWxtW1JFQUxNX1NaXTsKfTsKCiNpZm5kZWYgSEFWRV9TVFJMQ1BZCi8qIGlmIGl0IGV2ZXIgZ29lcyBub24tc3RhdGljLCBtYWtlIGl0IEN1cmxfIHByZWZpeGVkISAqLwpzdGF0aWMgc2l6ZV90CnN0cmxjcHkgKGNoYXIgKmRzdCwgY29uc3QgY2hhciAqc3JjLCBzaXplX3QgZHN0X3N6KQp7CiAgc2l6ZV90IG47CiAgY2hhciAqcDsKCiAgZm9yKHAgPSBkc3QsIG4gPSAwOwogICAgICBuICsgMSA8IGRzdF9zeiAmJiAqc3JjICE9ICdcMCc7CiAgICAgICsrcCwgKytzcmMsICsrbikKICAgICpwID0gKnNyYzsKICAqcCA9ICdcMCc7CiAgaWYoKnNyYyA9PSAnXDAnKQogICAgcmV0dXJuIG47CiAgZWxzZQogICAgcmV0dXJuIG4gKyBzdHJsZW4gKHNyYyk7Cn0KI2Vsc2UKc2l6ZV90IHN0cmxjcHkgKGNoYXIgKmRzdCwgY29uc3QgY2hhciAqc3JjLCBzaXplX3QgZHN0X3N6KTsKI2VuZGlmCgpzdGF0aWMgaW50CmtyYjRfY2hlY2tfcHJvdCh2b2lkICphcHBfZGF0YSwgaW50IGxldmVsKQp7CiAgYXBwX2RhdGEgPSBOVUxMOyAvKiBwcmV2ZW50IGNvbXBpbGVyIHdhcm5pbmcgKi8KICBpZihsZXZlbCA9PSBQUk9UX0NPTkZJREVOVElBTCkKICAgIHJldHVybiAtMTsKICByZXR1cm4gMDsKfQoKc3RhdGljIGludAprcmI0X2RlY29kZSh2b2lkICphcHBfZGF0YSwgdm9pZCAqYnVmLCBpbnQgbGVuLCBpbnQgbGV2ZWwsCiAgICAgICAgICAgIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIE1TR19EQVQgbTsKICBpbnQgZTsKICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CgogIGlmKGxldmVsID09IFBST1RfU0FGRSkKICAgIGUgPSBrcmJfcmRfc2FmZShidWYsIGxlbiwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIsCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICBlbHNlCiAgICBlID0ga3JiX3JkX3ByaXYoYnVmLCBsZW4sIGQtPnNjaGVkdWxlLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUiwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwgJm0pOwogIGlmKGUpIHsKICAgIHN0cnVjdCBTZXNzaW9uSGFuZGxlICpkYXRhID0gY29ubi0+ZGF0YTsKICAgIGluZm9mKGRhdGEsICJrcmI0X2RlY29kZTogJXNcbiIsIGtyYl9nZXRfZXJyX3RleHQoZSkpOwogICAgcmV0dXJuIC0xOwogIH0KICBtZW1tb3ZlKGJ1ZiwgbS5hcHBfZGF0YSwgbS5hcHBfbGVuZ3RoKTsKICByZXR1cm4gbS5hcHBfbGVuZ3RoOwp9CgpzdGF0aWMgaW50CmtyYjRfb3ZlcmhlYWQodm9pZCAqYXBwX2RhdGEsIGludCBsZXZlbCwgaW50IGxlbikKewogIC8qIG5vIGFyZ3VtZW50cyBhcmUgdXNlZCwganVzdCBpbml0IHRoZW0gdG8gcHJldmVudCBjb21waWxlciB3YXJuaW5ncyAqLwogIGFwcF9kYXRhID0gTlVMTDsKICBsZXZlbCA9IDA7CiAgbGVuID0gMDsKICByZXR1cm4gMzE7Cn0KCnN0YXRpYyBpbnQKa3JiNF9lbmNvZGUodm9pZCAqYXBwX2RhdGEsIGNvbnN0IHZvaWQgKmZyb20sIGludCBsZW5ndGgsIGludCBsZXZlbCwgdm9pZCAqKnRvLAogICAgICAgICAgICBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgKnRvID0gbWFsbG9jKGxlbmd0aCArIDMxKTsKICBpZighKnRvKQogICAgcmV0dXJuIC0xOwogIGlmKGxldmVsID09IFBST1RfU0FGRSkKICAgIC8qIE5PVEUgdGhhdCB0aGUgdm9pZCogY2FzdCBpcyBzYWZlLCBrcmJfbWtfc2FmZS9wcml2IGRvbid0IG1vZGlmeSB0aGUKICAgICAqIGlucHV0IGJ1ZmZlcgogICAgICovCiAgICByZXR1cm4ga3JiX21rX3NhZmUoKHZvaWQqKWZyb20sICp0bywgbGVuZ3RoLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUik7CiAgZWxzZSBpZihsZXZlbCA9PSBQUk9UX1BSSVZBVEUpCiAgICByZXR1cm4ga3JiX21rX3ByaXYoKHZvaWQqKWZyb20sICp0bywgbGVuZ3RoLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIpOwogIGVsc2UKICAgIHJldHVybiAtMTsKfQoKc3RhdGljIGludApta19hdXRoKHN0cnVjdCBrcmI0X2RhdGEgKmQsIEtURVhUIGFkYXQsCiAgICAgICAgY29uc3QgY2hhciAqc2VydmljZSwgY2hhciAqaG9zdCwgaW50IGNoZWNrc3VtKQp7CiAgaW50IHJldDsKICBDUkVERU5USUFMUyBjcmVkOwogIGNoYXIgc25hbWVbU05BTUVfU1pdLCBpbnN0W0lOU1RfU1pdLCByZWFsbVtSRUFMTV9TWl07CgogIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICBzdHJsY3B5KHJlYWxtLCBrcmJfcmVhbG1vZmhvc3QoaG9zdCksIHNpemVvZihyZWFsbSkpOwogIHJldCA9IGtyYl9ta19yZXEoYWRhdCwgc25hbWUsIGluc3QsIHJlYWxtLCBjaGVja3N1bSk7CiAgaWYocmV0KQogICAgcmV0dXJuIHJldDsKICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICBzdHJsY3B5KGluc3QsIGtyYl9nZXRfcGhvc3QoaG9zdCksIHNpemVvZihpbnN0KSk7CiAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICByZXQgPSBrcmJfZ2V0X2NyZWQoc25hbWUsIGluc3QsIHJlYWxtLCAmY3JlZCk7CiAgbWVtbW92ZSgmZC0+a2V5LCAmY3JlZC5zZXNzaW9uLCBzaXplb2YoZGVzX2NibG9jaykpOwogIGRlc19rZXlfc2NoZWQoJmQtPmtleSwgZC0+c2NoZWR1bGUpOwogIG1lbXNldCgmY3JlZCwgMCwgc2l6ZW9mKGNyZWQpKTsKICByZXR1cm4gcmV0Owp9CgojaWZkZWYgSEFWRV9LUkJfR0VUX09VUl9JUF9GT1JfUkVBTE0KaW50IGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShjaGFyICosIHN0cnVjdCBpbl9hZGRyICopOwojZW5kaWYKCnN0YXRpYyBpbnQKa3JiNF9hdXRoKHZvaWQgKmFwcF9kYXRhLCBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgcmV0OwogIGNoYXIgKnA7CiAgdW5zaWduZWQgY2hhciAqcHRyOwogIHNpemVfdCBsZW4gPSAwOwogIEtURVhUX1NUIGFkYXQ7CiAgTVNHX0RBVCBtc2dfZGF0YTsKICBpbnQgY2hlY2tzdW07CiAgdV9pbnQzMl90IGNzOwogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICBjaGFyICpob3N0ID0gY29ubi0+aG9zdC5uYW1lOwogIHNzaXplX3QgbnJlYWQ7CiAgaW50IGwgPSBzaXplb2YoY29ubi0+bG9jYWxfYWRkcik7CiAgc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGEgPSBjb25uLT5kYXRhOwogIENVUkxjb2RlIHJlc3VsdDsKICBzaXplX3QgYmFzZTY0X3N6ID0gMDsKCiAgaWYoZ2V0c29ja25hbWUoY29ubi0+c29ja1tGSVJTVFNPQ0tFVF0sCiAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkciAqKUxPQ0FMX0FERFIsICZsKSA8IDApCiAgICBwZXJyb3IoImdldHNvY2tuYW1lKCkiKTsKCiAgY2hlY2tzdW0gPSBnZXRwaWQoKTsKICByZXQgPSBta19hdXRoKGQsICZhZGF0LCAiZnRwIiwgaG9zdCwgY2hlY2tzdW0pOwogIGlmKHJldCA9PSBLRENfUFJfVU5LTk9XTikKICAgIHJldCA9IG1rX2F1dGgoZCwgJmFkYXQsICJyY21kIiwgaG9zdCwgY2hlY2tzdW0pOwogIGlmKHJldCkgewogICAgaW5mb2YoZGF0YSwgIiVzXG4iLCBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgfQoKI2lmZGVmIEhBVkVfS1JCX0dFVF9PVVJfSVBfRk9SX1JFQUxNCiAgaWYoa3JiX2dldF9jb25maWdfYm9vbCgibmF0X2luX3VzZSIpKSB7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gKmxvY2FsYWRkciAgPSAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUjsKICAgIHN0cnVjdCBpbl9hZGRyIG5hdEFkZHI7CgogICAgaWYoa3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKGtyYl9yZWFsbW9maG9zdChob3N0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm5hdEFkZHIpICE9IEtTVUNDRVNTCiAgICAgICAgJiYga3JiX2dldF9vdXJfaXBfZm9yX3JlYWxtKE5VTEwsICZuYXRBZGRyKSAhPSBLU1VDQ0VTUykKICAgICAgaW5mb2YoZGF0YSwgIkNhbid0IGdldCBhZGRyZXNzIGZvciByZWFsbSAlc1xuIiwKICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoaG9zdCkpOwogICAgZWxzZSB7CiAgICAgIGlmKG5hdEFkZHIuc19hZGRyICE9IGxvY2FsYWRkci0+c2luX2FkZHIuc19hZGRyKSB7CiAgICAgICAgY2hhciBhZGRyX2J1ZlsxMjhdOwogICAgICAgIGlmKEN1cmxfaW5ldF9udG9wKEFGX0lORVQsIG5hdEFkZHIsIGFkZHJfYnVmLCBzaXplb2YoYWRkcl9idWYpKSkKICAgICAgICAgIGluZm9mKGRhdGEsICJVc2luZyBOQVQgSVAgYWRkcmVzcyAoJXMpIGZvciBrZXJiZXJvcyA0XG4iLCBhZGRyX2J1Zik7CiAgICAgICAgbG9jYWxhZGRyLT5zaW5fYWRkciA9IG5hdEFkZHI7CiAgICAgIH0KICAgIH0KICB9CiNlbmRpZgoKICByZXN1bHQgPSBDdXJsX2Jhc2U2NF9lbmNvZGUoY29ubi0+ZGF0YSwgKGNoYXIgKilhZGF0LmRhdCwgYWRhdC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwLCAmYmFzZTY0X3N6KTsKICBpZihyZXN1bHQpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgImJhc2U2NC1lbmNvZGluZzogJXMiLCBjdXJsX2Vhc3lfc3RyZXJyb3IocmVzdWx0KSk7CiAgICByZXR1cm4gQVVUSF9DT05USU5VRTsKICB9CgogIHJlc3VsdCA9IEN1cmxfZnRwc2VuZGYoY29ubiwgIkFEQVQgJXMiLCBwKTsKCiAgZnJlZShwKTsKCiAgaWYocmVzdWx0KQogICAgcmV0dXJuIC0yOwoKICBpZihDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgTlVMTCkpCiAgICByZXR1cm4gLTE7CgogIGlmKGRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMicpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIlNlcnZlciBkaWRuJ3QgYWNjZXB0IGF1dGggZGF0YSIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQoKICBwID0gc3Ryc3RyKGRhdGEtPnN0YXRlLmJ1ZmZlciwgIkFEQVQ9Iik7CiAgaWYoIXApIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIlJlbW90ZSBob3N0IGRpZG4ndCBzZW5kIGFkYXQgcmVwbHkiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBwICs9IDU7CiAgcmVzdWx0ID0gQ3VybF9iYXNlNjRfZGVjb2RlKHAsICZwdHIsICZsZW4pOwogIGlmKHJlc3VsdCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiYmFzZTY0LWRlY29kaW5nOiAlcyIsIGN1cmxfZWFzeV9zdHJlcnJvcihyZXN1bHQpKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBpZihsZW4gPiBzaXplb2YoYWRhdC5kYXQpLTEpIHsKICAgIGZyZWUocHRyKTsKICAgIHB0ciA9IE5VTEw7CiAgICBsZW4gPSAwOwogIH0KICBpZighbGVuIHx8ICFwdHIpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIkZhaWxlZCB0byBkZWNvZGUgYmFzZTY0IGZyb20gc2VydmVyIik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgbWVtY3B5KChjaGFyICopYWRhdC5kYXQsIHB0ciwgbGVuKTsKICBmcmVlKHB0cik7CiAgYWRhdC5sZW5ndGggPSBsZW47CiAgcmV0ID0ga3JiX3JkX3NhZmUoYWRhdC5kYXQsIGFkYXQubGVuZ3RoLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKiloaXNjdGxhZGRyLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilteWN0bGFkZHIsICZtc2dfZGF0YSk7CiAgaWYocmV0KSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJFcnJvciByZWFkaW5nIHJlcGx5IGZyb20gc2VydmVyOiAlcyIsCiAgICAgICAgICAgICAgIGtyYl9nZXRfZXJyX3RleHQocmV0KSk7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAga3JiX2dldF9pbnQobXNnX2RhdGEuYXBwX2RhdGEsICZjcywgNCwgMCk7CiAgaWYoY3MgLSBjaGVja3N1bSAhPSAxKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJCYWQgY2hlY2tzdW0gcmV0dXJuZWQgZnJvbSBzZXJ2ZXIiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICByZXR1cm4gQVVUSF9PSzsKfQoKc3RydWN0IEN1cmxfc2VjX2NsaWVudF9tZWNoIEN1cmxfa3JiNF9jbGllbnRfbWVjaCA9IHsKICAgICJLRVJCRVJPU19WNCIsCiAgICBzaXplb2Yoc3RydWN0IGtyYjRfZGF0YSksCiAgICBOVUxMLCAvKiBpbml0ICovCiAgICBrcmI0X2F1dGgsCiAgICBOVUxMLCAvKiBlbmQgKi8KICAgIGtyYjRfY2hlY2tfcHJvdCwKICAgIGtyYjRfb3ZlcmhlYWQsCiAgICBrcmI0X2VuY29kZSwKICAgIGtyYjRfZGVjb2RlCn07CgpzdGF0aWMgZW51bSBwcm90ZWN0aW9uX2xldmVsCmtyYjRfc2V0X2NvbW1hbmRfcHJvdChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbCkKewogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBvbGQgPSBjb25uLT5jb21tYW5kX3Byb3Q7CiAgREVCVUdBU1NFUlQobGV2ZWwgPiBQUk9UX05PTkUgJiYgbGV2ZWwgPCBQUk9UX0xBU1QpOwogIGNvbm4tPmNvbW1hbmRfcHJvdCA9IGxldmVsOwogIHJldHVybiBvbGQ7Cn0KCkNVUkxjb2RlIEN1cmxfa3JiX2thdXRoKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGRlc19jYmxvY2sga2V5OwogIGRlc19rZXlfc2NoZWR1bGUgc2NoZWR1bGU7CiAgS1RFWFRfU1QgdGt0LCB0a3Rjb3B5OwogIGNoYXIgKm5hbWU7CiAgY2hhciAqcDsKICBjaGFyIHBhc3N3ZFsxMDBdOwogIHNpemVfdCB0bXAgPSAwOwogIHNzaXplX3QgbnJlYWQ7CiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIHNhdmU7CiAgQ1VSTGNvZGUgcmVzdWx0OwogIHVuc2lnbmVkIGNoYXIgKnB0cjsKICBzaXplX3QgYmFzZTY0X3N6ID0gMDsKCiAgc2F2ZSA9IGtyYjRfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBQUk9UX1BSSVZBVEUpOwoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzIiwgY29ubi0+dXNlcik7CgogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIHJlc3VsdCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzMnKSB7CiAgICBrcmI0X3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CgogIHAgPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiVD0iKTsKICBpZighcCkgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiQmFkIHJlcGx5IGZyb20gc2VydmVyIik7CiAgICBrcmI0X3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CgogIHAgKz0gMjsKICByZXN1bHQgPSBDdXJsX2Jhc2U2NF9kZWNvZGUocCwgJnB0ciwgJnRtcCk7CiAgaWYocmVzdWx0KSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJiYXNlNjQtZGVjb2Rpbmc6ICVzIiwgY3VybF9lYXN5X3N0cmVycm9yKHJlc3VsdCkpOwogICAgcmV0dXJuIHJlc3VsdDsKICB9CiAgaWYodG1wID49IHNpemVvZih0a3QuZGF0KSkgewogICAgZnJlZShwdHIpOwogICAgcHRyID0gTlVMTDsKICAgIHRtcCA9IDA7CiAgfQogIGlmKCF0bXAgfHwgIXB0cikgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIGRlY29kZSBiYXNlNjQgaW4gcmVwbHkiKTsKICAgIGtyYjRfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KICBtZW1jcHkoKGNoYXIgKil0a3QuZGF0LCBwdHIsIHRtcCk7CiAgZnJlZShwdHIpOwogIHRrdC5sZW5ndGggPSB0bXA7CiAgdGt0Y29weS5sZW5ndGggPSB0a3QubGVuZ3RoOwoKICBwID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlA9Iik7CiAgaWYoIXApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkJhZCByZXBseSBmcm9tIHNlcnZlciIpOwogICAga3JiNF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQogIG5hbWUgPSBwICsgMjsKICBmb3IoOyAqcCAmJiAqcCAhPSAnICcgJiYgKnAgIT0gJ1xyJyAmJiAqcCAhPSAnXG4nOyBwKyspOwogICpwID0gMDsKCiAgZGVzX3N0cmluZ190b19rZXkgKGNvbm4tPnBhc3N3ZCwgJmtleSk7CiAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CgogIGRlc19wY2JjX2VuY3J5cHQoKHZvaWQgKil0a3QuZGF0LCAodm9pZCAqKXRrdGNvcHkuZGF0LAogICAgICAgICAgICAgICAgICAgdGt0Lmxlbmd0aCwKICAgICAgICAgICAgICAgICAgIHNjaGVkdWxlLCAma2V5LCBERVNfREVDUllQVCk7CiAgaWYoc3RyY21wICgoY2hhciopdGt0Y29weS5kYXQgKyA4LAogICAgICAgICAgICAgIEtSQl9USUNLRVRfR1JBTlRJTkdfVElDS0VUKSAhPSAwKSB7CiAgICBhZnNfc3RyaW5nX3RvX2tleShwYXNzd2QsCiAgICAgICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoY29ubi0+aG9zdC5uYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICZrZXkpOwogICAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CiAgICBkZXNfcGNiY19lbmNyeXB0KCh2b2lkICopdGt0LmRhdCwgKHZvaWQgKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgICAgdGt0Lmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICB9CiAgbWVtc2V0KGtleSwgMCwgc2l6ZW9mKGtleSkpOwogIG1lbXNldChzY2hlZHVsZSwgMCwgc2l6ZW9mKHNjaGVkdWxlKSk7CiAgbWVtc2V0KHBhc3N3ZCwgMCwgc2l6ZW9mKHBhc3N3ZCkpOwogIHJlc3VsdCA9IEN1cmxfYmFzZTY0X2VuY29kZShjb25uLT5kYXRhLCAoY2hhciAqKXRrdGNvcHkuZGF0LCB0a3Rjb3B5Lmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnAsICZiYXNlNjRfc3opOwogIGlmKHJlc3VsdCkgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiYmFzZTY0LWVuY29kaW5nOiAlcyIsIGN1cmxfZWFzeV9zdHJlcnJvcihyZXN1bHQpKTsKICAgIGtyYjRfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiByZXN1bHQ7CiAgfQogIG1lbXNldCAodGt0Y29weS5kYXQsIDAsIHRrdGNvcHkubGVuZ3RoKTsKCiAgcmVzdWx0ID0gQ3VybF9mdHBzZW5kZihjb25uLCAiU0lURSBLQVVUSCAlcyAlcyIsIG5hbWUsIHApOwogIGZyZWUocCk7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKCiAgcmVzdWx0ID0gQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sIE5VTEwpOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CiAga3JiNF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwoKICByZXR1cm4gQ1VSTEVfT0s7Cn0KCiNlbmRpZiAvKiBIQVZFX0tSQjQgKi8KI2VuZGlmIC8qIENVUkxfRElTQUJMRV9GVFAgKi8K