LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIE1hcnRpbidzIGxhdGVzdCBjaGFuZ2VzIHdlcmUgZG9uZSAyMDAwLTA5LTE4LgogKgogKiBJdCBoYXMgc2luY2UgYmVlbiBwYXRjaGVkIGF3YXkgbGlrZSBhIG1hZG1hbiBieSBEYW5pZWwgU3RlbmJlcmcgdG8gbWFrZSBpdAogKiBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZQogKiBuYW1lIHNwYWNlIGFuZCBtb3JlLgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBDb3B5cmlnaHQgKGMpIDIwMDQgLSAyMDA4IERhbmllbCBTdGVuYmVyZwogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICogJElkJAogKi8KCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBIQVZFX0tSQjQKCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2lmZGVmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGtyYi5oPgojaW5jbHVkZSA8ZGVzLmg+CgojaWZkZWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+IC8qIGZvciBnZXRwaWQoKSAqLwojZW5kaWYKCiNpbmNsdWRlICJ1cmxkYXRhLmgiCiNpbmNsdWRlICJiYXNlNjQuaCIKI2luY2x1ZGUgImZ0cC5oIgojaW5jbHVkZSAic2VuZGYuaCIKI2luY2x1ZGUgImtyYjQuaCIKI2luY2x1ZGUgIm1lbW9yeS5oIgoKI2lmIGRlZmluZWQoSEFWRV9JTkVUX05UT0FfUikgJiYgIWRlZmluZWQoSEFWRV9JTkVUX05UT0FfUl9ERUNMKQojaW5jbHVkZSAiaW5ldF9udG9hX3IuaCIKI2VuZGlmCgovKiBUaGUgbGFzdCAjaW5jbHVkZSBmaWxlIHNob3VsZCBiZTogKi8KI2luY2x1ZGUgIm1lbWRlYnVnLmgiCgojZGVmaW5lIExPQ0FMX0FERFIgKCZjb25uLT5sb2NhbF9hZGRyKQojZGVmaW5lIFJFTU9URV9BRERSIGNvbm4tPmlwX2FkZHItPmFpX2FkZHIKI2RlZmluZSBteWN0bGFkZHIgTE9DQUxfQUREUgojZGVmaW5lIGhpc2N0bGFkZHIgUkVNT1RFX0FERFIKCnN0cnVjdCBrcmI0X2RhdGEgewogIGRlc19jYmxvY2sga2V5OwogIGRlc19rZXlfc2NoZWR1bGUgc2NoZWR1bGU7CiAgY2hhciBuYW1lW0FOQU1FX1NaXTsKICBjaGFyIGluc3RhbmNlW0lOU1RfU1pdOwogIGNoYXIgcmVhbG1bUkVBTE1fU1pdOwp9OwoKI2lmbmRlZiBIQVZFX1NUUkxDUFkKLyogaWYgaXQgZXZlciBnb2VzIG5vbi1zdGF0aWMsIG1ha2UgaXQgQ3VybF8gcHJlZml4ZWQhICovCnN0YXRpYyBzaXplX3QKc3RybGNweSAoY2hhciAqZHN0LCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCBkc3Rfc3opCnsKICBzaXplX3QgbjsKICBjaGFyICpwOwoKICBmb3IgKHAgPSBkc3QsIG4gPSAwOwogICAgICAgbiArIDEgPCBkc3Rfc3ogJiYgKnNyYyAhPSAnXDAnOwogICAgICAgKytwLCArK3NyYywgKytuKQogICAgKnAgPSAqc3JjOwogICpwID0gJ1wwJzsKICBpZigqc3JjID09ICdcMCcpCiAgICByZXR1cm4gbjsKICBlbHNlCiAgICByZXR1cm4gbiArIHN0cmxlbiAoc3JjKTsKfQojZWxzZQpzaXplX3Qgc3RybGNweSAoY2hhciAqZHN0LCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCBkc3Rfc3opOwojZW5kaWYKCnN0YXRpYyBpbnQKa3JiNF9jaGVja19wcm90KHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwpCnsKICBhcHBfZGF0YSA9IE5VTEw7IC8qIHByZXZlbnQgY29tcGlsZXIgd2FybmluZyAqLwogIGlmKGxldmVsID09IHByb3RfY29uZmlkZW50aWFsKQogICAgcmV0dXJuIC0xOwogIHJldHVybiAwOwp9CgpzdGF0aWMgaW50CmtyYjRfZGVjb2RlKHZvaWQgKmFwcF9kYXRhLCB2b2lkICpidWYsIGludCBsZW4sIGludCBsZXZlbCwKICAgICAgICAgICAgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgTVNHX0RBVCBtOwogIGludCBlOwogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKCiAgaWYobGV2ZWwgPT0gcHJvdF9zYWZlKQogICAgZSA9IGtyYl9yZF9zYWZlKGJ1ZiwgbGVuLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUiwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwgJm0pOwogIGVsc2UKICAgIGUgPSBrcmJfcmRfcHJpdihidWYsIGxlbiwgZC0+c2NoZWR1bGUsICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLCAmbSk7CiAgaWYoZSkgewogICAgc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGEgPSBjb25uLT5kYXRhOwogICAgaW5mb2YoZGF0YSwgImtyYjRfZGVjb2RlOiAlc1xuIiwga3JiX2dldF9lcnJfdGV4dChlKSk7CiAgICByZXR1cm4gLTE7CiAgfQogIG1lbW1vdmUoYnVmLCBtLmFwcF9kYXRhLCBtLmFwcF9sZW5ndGgpOwogIHJldHVybiBtLmFwcF9sZW5ndGg7Cn0KCnN0YXRpYyBpbnQKa3JiNF9vdmVyaGVhZCh2b2lkICphcHBfZGF0YSwgaW50IGxldmVsLCBpbnQgbGVuKQp7CiAgLyogbm8gYXJndW1lbnRzIGFyZSB1c2VkLCBqdXN0IGluaXQgdGhlbSB0byBwcmV2ZW50IGNvbXBpbGVyIHdhcm5pbmdzICovCiAgYXBwX2RhdGEgPSBOVUxMOwogIGxldmVsID0gMDsKICBsZW4gPSAwOwogIHJldHVybiAzMTsKfQoKc3RhdGljIGludAprcmI0X2VuY29kZSh2b2lkICphcHBfZGF0YSwgY29uc3Qgdm9pZCAqZnJvbSwgaW50IGxlbmd0aCwgaW50IGxldmVsLCB2b2lkICoqdG8sCiAgICAgICAgICAgIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICAqdG8gPSBtYWxsb2MobGVuZ3RoICsgMzEpOwogIGlmKGxldmVsID09IHByb3Rfc2FmZSkKICAgIC8qIE5PVEUgdGhhdCB0aGUgdm9pZCogY2FzdCBpcyBzYWZlLCBrcmJfbWtfc2FmZS9wcml2IGRvbid0IG1vZGlmeSB0aGUKICAgICAqIGlucHV0IGJ1ZmZlcgogICAgICovCiAgICByZXR1cm4ga3JiX21rX3NhZmUoKHZvaWQqKWZyb20sICp0bywgbGVuZ3RoLCAmZC0+a2V5LAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLAogICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUik7CiAgZWxzZSBpZihsZXZlbCA9PSBwcm90X3ByaXZhdGUpCiAgICByZXR1cm4ga3JiX21rX3ByaXYoKHZvaWQqKWZyb20sICp0bywgbGVuZ3RoLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIpOwogIGVsc2UKICAgIHJldHVybiAtMTsKfQoKc3RhdGljIGludApta19hdXRoKHN0cnVjdCBrcmI0X2RhdGEgKmQsIEtURVhUIGFkYXQsCiAgICAgICAgY29uc3QgY2hhciAqc2VydmljZSwgY2hhciAqaG9zdCwgaW50IGNoZWNrc3VtKQp7CiAgaW50IHJldDsKICBDUkVERU5USUFMUyBjcmVkOwogIGNoYXIgc25hbWVbU05BTUVfU1pdLCBpbnN0W0lOU1RfU1pdLCByZWFsbVtSRUFMTV9TWl07CgogIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICBzdHJsY3B5KHJlYWxtLCBrcmJfcmVhbG1vZmhvc3QoaG9zdCksIHNpemVvZihyZWFsbSkpOwogIHJldCA9IGtyYl9ta19yZXEoYWRhdCwgc25hbWUsIGluc3QsIHJlYWxtLCBjaGVja3N1bSk7CiAgaWYocmV0KQogICAgcmV0dXJuIHJldDsKICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICBzdHJsY3B5KGluc3QsIGtyYl9nZXRfcGhvc3QoaG9zdCksIHNpemVvZihpbnN0KSk7CiAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICByZXQgPSBrcmJfZ2V0X2NyZWQoc25hbWUsIGluc3QsIHJlYWxtLCAmY3JlZCk7CiAgbWVtbW92ZSgmZC0+a2V5LCAmY3JlZC5zZXNzaW9uLCBzaXplb2YoZGVzX2NibG9jaykpOwogIGRlc19rZXlfc2NoZWQoJmQtPmtleSwgZC0+c2NoZWR1bGUpOwogIG1lbXNldCgmY3JlZCwgMCwgc2l6ZW9mKGNyZWQpKTsKICByZXR1cm4gcmV0Owp9CgojaWZkZWYgSEFWRV9LUkJfR0VUX09VUl9JUF9GT1JfUkVBTE0KaW50IGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShjaGFyICosIHN0cnVjdCBpbl9hZGRyICopOwojZW5kaWYKCnN0YXRpYyBpbnQKa3JiNF9hdXRoKHZvaWQgKmFwcF9kYXRhLCBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgcmV0OwogIGNoYXIgKnA7CiAgdW5zaWduZWQgY2hhciAqcHRyOwogIHNpemVfdCBsZW47CiAgS1RFWFRfU1QgYWRhdDsKICBNU0dfREFUIG1zZ19kYXRhOwogIGludCBjaGVja3N1bTsKICB1X2ludDMyX3QgY3M7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwogIGNoYXIgKmhvc3QgPSBjb25uLT5ob3N0Lm5hbWU7CiAgc3NpemVfdCBucmVhZDsKICBpbnQgbCA9IHNpemVvZihjb25uLT5sb2NhbF9hZGRyKTsKICBzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YSA9IGNvbm4tPmRhdGE7CiAgQ1VSTGNvZGUgcmVzdWx0OwoKICBpZihnZXRzb2NrbmFtZShjb25uLT5zb2NrW0ZJUlNUU09DS0VUXSwKICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyICopTE9DQUxfQUREUiwgJmwpIDwgMCkKICAgIHBlcnJvcigiZ2V0c29ja25hbWUoKSIpOwoKICBjaGVja3N1bSA9IGdldHBpZCgpOwogIHJldCA9IG1rX2F1dGgoZCwgJmFkYXQsICJmdHAiLCBob3N0LCBjaGVja3N1bSk7CiAgaWYocmV0ID09IEtEQ19QUl9VTktOT1dOKQogICAgcmV0ID0gbWtfYXV0aChkLCAmYWRhdCwgInJjbWQiLCBob3N0LCBjaGVja3N1bSk7CiAgaWYocmV0KSB7CiAgICBpbmZvZihkYXRhLCAiJXNcbiIsIGtyYl9nZXRfZXJyX3RleHQocmV0KSk7CiAgICByZXR1cm4gQVVUSF9DT05USU5VRTsKICB9CgojaWZkZWYgSEFWRV9LUkJfR0VUX09VUl9JUF9GT1JfUkVBTE0KICBpZihrcmJfZ2V0X2NvbmZpZ19ib29sKCJuYXRfaW5fdXNlIikpIHsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiAqbG9jYWxhZGRyICA9IChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSOwogICAgc3RydWN0IGluX2FkZHIgbmF0QWRkcjsKCiAgICBpZihrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oa3JiX3JlYWxtb2Zob3N0KGhvc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbmF0QWRkcikgIT0gS1NVQ0NFU1MKICAgICAgICAmJiBrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oTlVMTCwgJm5hdEFkZHIpICE9IEtTVUNDRVNTKQogICAgICBpbmZvZihkYXRhLCAiQ2FuJ3QgZ2V0IGFkZHJlc3MgZm9yIHJlYWxtICVzXG4iLAogICAgICAgICAgICAgICAgIGtyYl9yZWFsbW9maG9zdChob3N0KSk7CiAgICBlbHNlIHsKICAgICAgaWYobmF0QWRkci5zX2FkZHIgIT0gbG9jYWxhZGRyLT5zaW5fYWRkci5zX2FkZHIpIHsKI2lmZGVmIEhBVkVfSU5FVF9OVE9BX1IKICAgICAgICBjaGFyIG50b2FfYnVmWzY0XTsKICAgICAgICBjaGFyICppcCA9IChjaGFyICopaW5ldF9udG9hX3IobmF0QWRkciwgbnRvYV9idWYsIHNpemVvZihudG9hX2J1ZikpOwojZWxzZQogICAgICAgIGNoYXIgKmlwID0gKGNoYXIgKilpbmV0X250b2EobmF0QWRkcik7CiNlbmRpZgogICAgICAgIGluZm9mKGRhdGEsICJVc2luZyBOQVQgSVAgYWRkcmVzcyAoJXMpIGZvciBrZXJiZXJvcyA0XG4iLCBpcCk7CiAgICAgICAgbG9jYWxhZGRyLT5zaW5fYWRkciA9IG5hdEFkZHI7CiAgICAgIH0KICAgIH0KICB9CiNlbmRpZgoKICBpZihDdXJsX2Jhc2U2NF9lbmNvZGUoY29ubi0+ZGF0YSwgKGNoYXIgKilhZGF0LmRhdCwgYWRhdC5sZW5ndGgsICZwKSA8IDEpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIk91dCBvZiBtZW1vcnkgYmFzZTY0LWVuY29kaW5nIik7CiAgICByZXR1cm4gQVVUSF9DT05USU5VRTsKICB9CgogIHJlc3VsdCA9IEN1cmxfZnRwc2VuZGYoY29ubiwgIkFEQVQgJXMiLCBwKTsKCiAgZnJlZShwKTsKCiAgaWYocmVzdWx0KQogICAgcmV0dXJuIC0yOwoKICBpZihDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgTlVMTCkpCiAgICByZXR1cm4gLTE7CgogIGlmKGRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMicpewogICAgQ3VybF9mYWlsZihkYXRhLCAiU2VydmVyIGRpZG4ndCBhY2NlcHQgYXV0aCBkYXRhIik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CgogIHAgPSBzdHJzdHIoZGF0YS0+c3RhdGUuYnVmZmVyLCAiQURBVD0iKTsKICBpZighcCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiUmVtb3RlIGhvc3QgZGlkbid0IHNlbmQgYWRhdCByZXBseSIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIHAgKz0gNTsKICBsZW4gPSBDdXJsX2Jhc2U2NF9kZWNvZGUocCwgJnB0cik7CiAgaWYobGVuID4gc2l6ZW9mKGFkYXQuZGF0KS0xKSB7CiAgICBmcmVlKHB0cik7CiAgICBsZW49MDsKICB9CiAgaWYoIWxlbiB8fCAhcHRyKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJGYWlsZWQgdG8gZGVjb2RlIGJhc2U2NCBmcm9tIHNlcnZlciIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIG1lbWNweSgoY2hhciAqKWFkYXQuZGF0LCBwdHIsIGxlbik7CiAgZnJlZShwdHIpOwogIGFkYXQubGVuZ3RoID0gbGVuOwogIHJldCA9IGtyYl9yZF9zYWZlKGFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJmQtPmtleSwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopaGlzY3RsYWRkciwKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopbXljdGxhZGRyLCAmbXNnX2RhdGEpOwogIGlmKHJldCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiRXJyb3IgcmVhZGluZyByZXBseSBmcm9tIHNlcnZlcjogJXMiLAogICAgICAgICAgICAgICBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIGtyYl9nZXRfaW50KG1zZ19kYXRhLmFwcF9kYXRhLCAmY3MsIDQsIDApOwogIGlmKGNzIC0gY2hlY2tzdW0gIT0gMSkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiQmFkIGNoZWNrc3VtIHJldHVybmVkIGZyb20gc2VydmVyIik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgcmV0dXJuIEFVVEhfT0s7Cn0KCnN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCBDdXJsX2tyYjRfY2xpZW50X21lY2ggPSB7CiAgICAiS0VSQkVST1NfVjQiLAogICAgc2l6ZW9mKHN0cnVjdCBrcmI0X2RhdGEpLAogICAgTlVMTCwgLyogaW5pdCAqLwogICAga3JiNF9hdXRoLAogICAgTlVMTCwgLyogZW5kICovCiAgICBrcmI0X2NoZWNrX3Byb3QsCiAgICBrcmI0X292ZXJoZWFkLAogICAga3JiNF9lbmNvZGUsCiAgICBrcmI0X2RlY29kZQp9OwoKQ1VSTGNvZGUgQ3VybF9rcmJfa2F1dGgoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgZGVzX2NibG9jayBrZXk7CiAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICBLVEVYVF9TVCB0a3QsIHRrdGNvcHk7CiAgY2hhciAqbmFtZTsKICBjaGFyICpwOwogIGNoYXIgcGFzc3dkWzEwMF07CiAgc2l6ZV90IHRtcDsKICBzc2l6ZV90IG5yZWFkOwogIGludCBzYXZlOwogIENVUkxjb2RlIHJlc3VsdDsKICB1bnNpZ25lZCBjaGFyICpwdHI7CgogIHNhdmUgPSBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgcHJvdF9wcml2YXRlKTsKCiAgcmVzdWx0ID0gQ3VybF9mdHBzZW5kZihjb25uLCAiU0lURSBLQVVUSCAlcyIsIGNvbm4tPnVzZXIpOwoKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICByZXN1bHQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgTlVMTCk7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKCiAgaWYoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyWzBdICE9ICczJyl7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CgogIHAgPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiVD0iKTsKICBpZighcCkgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiQmFkIHJlcGx5IGZyb20gc2VydmVyIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CgogIHAgKz0gMjsKICB0bXAgPSBDdXJsX2Jhc2U2NF9kZWNvZGUocCwgJnB0cik7CiAgaWYodG1wID49IHNpemVvZih0a3QuZGF0KSkgewogICAgZnJlZShwdHIpOwogICAgdG1wPTA7CiAgfQogIGlmKCF0bXAgfHwgIXB0cikgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIGRlY29kZSBiYXNlNjQgaW4gcmVwbHkiKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KICBtZW1jcHkoKGNoYXIgKil0a3QuZGF0LCBwdHIsIHRtcCk7CiAgZnJlZShwdHIpOwogIHRrdC5sZW5ndGggPSB0bXA7CiAgdGt0Y29weS5sZW5ndGggPSB0a3QubGVuZ3RoOwoKICBwID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlA9Iik7CiAgaWYoIXApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkJhZCByZXBseSBmcm9tIHNlcnZlciIpOwogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQogIG5hbWUgPSBwICsgMjsKICBmb3IoOyAqcCAmJiAqcCAhPSAnICcgJiYgKnAgIT0gJ1xyJyAmJiAqcCAhPSAnXG4nOyBwKyspOwogICpwID0gMDsKCiAgZGVzX3N0cmluZ190b19rZXkgKGNvbm4tPnBhc3N3ZCwgJmtleSk7CiAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CgogIGRlc19wY2JjX2VuY3J5cHQoKHZvaWQgKil0a3QuZGF0LCAodm9pZCAqKXRrdGNvcHkuZGF0LAogICAgICAgICAgICAgICAgICAgdGt0Lmxlbmd0aCwKICAgICAgICAgICAgICAgICAgIHNjaGVkdWxlLCAma2V5LCBERVNfREVDUllQVCk7CiAgaWYoc3RyY21wICgoY2hhciopdGt0Y29weS5kYXQgKyA4LAogICAgICAgICAgICAgIEtSQl9USUNLRVRfR1JBTlRJTkdfVElDS0VUKSAhPSAwKSB7CiAgICBhZnNfc3RyaW5nX3RvX2tleShwYXNzd2QsCiAgICAgICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoY29ubi0+aG9zdC5uYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICZrZXkpOwogICAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CiAgICBkZXNfcGNiY19lbmNyeXB0KCh2b2lkICopdGt0LmRhdCwgKHZvaWQgKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgICAgdGt0Lmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICB9CiAgbWVtc2V0KGtleSwgMCwgc2l6ZW9mKGtleSkpOwogIG1lbXNldChzY2hlZHVsZSwgMCwgc2l6ZW9mKHNjaGVkdWxlKSk7CiAgbWVtc2V0KHBhc3N3ZCwgMCwgc2l6ZW9mKHBhc3N3ZCkpOwogIGlmKEN1cmxfYmFzZTY0X2VuY29kZShjb25uLT5kYXRhLCAoY2hhciAqKXRrdGNvcHkuZGF0LCB0a3Rjb3B5Lmxlbmd0aCwgJnApCiAgICAgPCAxKSB7CiAgICBmYWlsZihjb25uLT5kYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmcuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfT1VUX09GX01FTU9SWTsKICB9CiAgbWVtc2V0ICh0a3Rjb3B5LmRhdCwgMCwgdGt0Y29weS5sZW5ndGgpOwoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzICVzIiwgbmFtZSwgcCk7CiAgZnJlZShwKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICByZXN1bHQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgTlVMTCk7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CgogIHJldHVybiBDVVJMRV9PSzsKfQoKI2VuZGlmIC8qIEhBVkVfS1JCNCAqLwojZW5kaWYgLyogQ1VSTF9ESVNBQkxFX0ZUUCAqLwo=