LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhd2F5IGxpa2UgYSBtYWRtYW4gYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKiAKICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogKiAKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAKICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgSW5zdGl0dXRlIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBJTlNUSVRVVEUgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBJTlNUSVRVVEUgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUwogKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKICogSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLiAgKi8KCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBIQVZFX0tSQjQKCiNpbmNsdWRlICJzZWN1cml0eS5oIgojaW5jbHVkZSAiYmFzZTY0LmgiCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2lmZGVmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGtyYi5oPgojaW5jbHVkZSA8ZGVzLmg+CgojaWZkZWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+IC8qIGZvciBnZXRwaWQoKSAqLwojZW5kaWYKCiNpbmNsdWRlICJmdHAuaCIKI2luY2x1ZGUgInNlbmRmLmgiCiNpbmNsdWRlICJrcmI0LmgiCiNpbmNsdWRlICJtZW1vcnkuaCIKCiNpZiBkZWZpbmVkKEhBVkVfSU5FVF9OVE9BX1IpICYmICFkZWZpbmVkKEhBVkVfSU5FVF9OVE9BX1JfREVDTCkKI2luY2x1ZGUgImluZXRfbnRvYV9yLmgiCiNlbmRpZgoKLyogVGhlIGxhc3QgI2luY2x1ZGUgZmlsZSBzaG91bGQgYmU6ICovCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgoKI2RlZmluZSBMT0NBTF9BRERSICgmY29ubi0+bG9jYWxfYWRkcikKI2RlZmluZSBSRU1PVEVfQUREUiAoJmNvbm4tPnNlcnZfYWRkcikKI2RlZmluZSBteWN0bGFkZHIgTE9DQUxfQUREUgojZGVmaW5lIGhpc2N0bGFkZHIgUkVNT1RFX0FERFIKCnN0cnVjdCBrcmI0X2RhdGEgewogIGRlc19jYmxvY2sga2V5OwogIGRlc19rZXlfc2NoZWR1bGUgc2NoZWR1bGU7CiAgY2hhciBuYW1lW0FOQU1FX1NaXTsKICBjaGFyIGluc3RhbmNlW0lOU1RfU1pdOwogIGNoYXIgcmVhbG1bUkVBTE1fU1pdOwp9OwoKI2lmbmRlZiBIQVZFX1NUUkxDUFkKLyogaWYgaXQgZXZlciBnb2VzIG5vbi1zdGF0aWMsIG1ha2UgaXQgQ3VybF8gcHJlZml4ZWQhICovCnN0YXRpYyBzaXplX3QKc3RybGNweSAoY2hhciAqZHN0LCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCBkc3Rfc3opCnsKICBzaXplX3QgbjsKICBjaGFyICpwOwoKICBmb3IgKHAgPSBkc3QsIG4gPSAwOwogICAgICAgbiArIDEgPCBkc3Rfc3ogJiYgKnNyYyAhPSAnXDAnOwogICAgICAgKytwLCArK3NyYywgKytuKQogICAgKnAgPSAqc3JjOwogICpwID0gJ1wwJzsKICBpZiAoKnNyYyA9PSAnXDAnKQogICAgcmV0dXJuIG47CiAgZWxzZQogICAgcmV0dXJuIG4gKyBzdHJsZW4gKHNyYyk7Cn0KI2Vsc2UKc2l6ZV90IHN0cmxjcHkgKGNoYXIgKmRzdCwgY29uc3QgY2hhciAqc3JjLCBzaXplX3QgZHN0X3N6KTsKI2VuZGlmCgpzdGF0aWMgaW50CmtyYjRfY2hlY2tfcHJvdCh2b2lkICphcHBfZGF0YSwgaW50IGxldmVsKQp7CiAgYXBwX2RhdGEgPSBOVUxMOyAvKiBwcmV2ZW50IGNvbXBpbGVyIHdhcm5pbmcgKi8KICBpZihsZXZlbCA9PSBwcm90X2NvbmZpZGVudGlhbCkKICAgIHJldHVybiAtMTsKICByZXR1cm4gMDsKfQoKc3RhdGljIGludAprcmI0X2RlY29kZSh2b2lkICphcHBfZGF0YSwgdm9pZCAqYnVmLCBpbnQgbGVuLCBpbnQgbGV2ZWwsCgkgICAgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgTVNHX0RBVCBtOwogIGludCBlOwogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICAKICBpZihsZXZlbCA9PSBwcm90X3NhZmUpCiAgICBlID0ga3JiX3JkX3NhZmUoYnVmLCBsZW4sICZkLT5rZXksCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLCAmbSk7CiAgZWxzZQogICAgZSA9IGtyYl9yZF9wcml2KGJ1ZiwgbGVuLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLCAmbSk7CiAgaWYoZSkgewogICAgc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGEgPSBjb25uLT5kYXRhOwogICAgaW5mb2YoZGF0YSwgImtyYjRfZGVjb2RlOiAlc1xuIiwga3JiX2dldF9lcnJfdGV4dChlKSk7CiAgICByZXR1cm4gLTE7CiAgfQogIG1lbW1vdmUoYnVmLCBtLmFwcF9kYXRhLCBtLmFwcF9sZW5ndGgpOwogIHJldHVybiBtLmFwcF9sZW5ndGg7Cn0KCnN0YXRpYyBpbnQKa3JiNF9vdmVyaGVhZCh2b2lkICphcHBfZGF0YSwgaW50IGxldmVsLCBpbnQgbGVuKQp7CiAgLyogbm8gYXJndW1lbnRzIGFyZSB1c2VkLCBqdXN0IGluaXQgdGhlbSB0byBwcmV2ZW50IGNvbXBpbGVyIHdhcm5pbmdzICovCiAgYXBwX2RhdGEgPSBOVUxMOwogIGxldmVsID0gMDsKICBsZW4gPSAwOwogIHJldHVybiAzMTsKfQoKc3RhdGljIGludAprcmI0X2VuY29kZSh2b2lkICphcHBfZGF0YSwgdm9pZCAqZnJvbSwgaW50IGxlbmd0aCwgaW50IGxldmVsLCB2b2lkICoqdG8sCgkgICAgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwogICp0byA9IG1hbGxvYyhsZW5ndGggKyAzMSk7CiAgaWYobGV2ZWwgPT0gcHJvdF9zYWZlKQogICAgcmV0dXJuIGtyYl9ta19zYWZlKGZyb20sICp0bywgbGVuZ3RoLCAmZC0+a2V5LCAKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIpOwogIGVsc2UgaWYobGV2ZWwgPT0gcHJvdF9wcml2YXRlKQogICAgcmV0dXJuIGtyYl9ta19wcml2KGZyb20sICp0bywgbGVuZ3RoLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsCiAgICAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICBlbHNlCiAgICByZXR1cm4gLTE7Cn0KCnN0YXRpYyBpbnQKbWtfYXV0aChzdHJ1Y3Qga3JiNF9kYXRhICpkLCBLVEVYVCBhZGF0LCAKCWNvbnN0IGNoYXIgKnNlcnZpY2UsIGNoYXIgKmhvc3QsIGludCBjaGVja3N1bSkKewogIGludCByZXQ7CiAgQ1JFREVOVElBTFMgY3JlZDsKICBjaGFyIHNuYW1lW1NOQU1FX1NaXSwgaW5zdFtJTlNUX1NaXSwgcmVhbG1bUkVBTE1fU1pdOwoKICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICBzdHJsY3B5KGluc3QsIGtyYl9nZXRfcGhvc3QoaG9zdCksIHNpemVvZihpbnN0KSk7CiAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICByZXQgPSBrcmJfbWtfcmVxKGFkYXQsIHNuYW1lLCBpbnN0LCByZWFsbSwgY2hlY2tzdW0pOwogIGlmKHJldCkKICAgIHJldHVybiByZXQ7CiAgc3RybGNweShzbmFtZSwgc2VydmljZSwgc2l6ZW9mKHNuYW1lKSk7CiAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgcmV0ID0ga3JiX2dldF9jcmVkKHNuYW1lLCBpbnN0LCByZWFsbSwgJmNyZWQpOwogIG1lbW1vdmUoJmQtPmtleSwgJmNyZWQuc2Vzc2lvbiwgc2l6ZW9mKGRlc19jYmxvY2spKTsKICBkZXNfa2V5X3NjaGVkKCZkLT5rZXksIGQtPnNjaGVkdWxlKTsKICBtZW1zZXQoJmNyZWQsIDAsIHNpemVvZihjcmVkKSk7CiAgcmV0dXJuIHJldDsKfQoKI2lmZGVmIEhBVkVfS1JCX0dFVF9PVVJfSVBfRk9SX1JFQUxNCmludCBrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oY2hhciAqLCBzdHJ1Y3QgaW5fYWRkciAqKTsKI2VuZGlmCgpzdGF0aWMgaW50CmtyYjRfYXV0aCh2b2lkICphcHBfZGF0YSwgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IHJldDsKICBjaGFyICpwOwogIGludCBsZW47CiAgS1RFWFRfU1QgYWRhdDsKICBNU0dfREFUIG1zZ19kYXRhOwogIGludCBjaGVja3N1bTsKICB1X2ludDMyX3QgY3M7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwogIGNoYXIgKmhvc3QgPSBjb25uLT5ob3N0Lm5hbWU7CiAgc3NpemVfdCBucmVhZDsKICBpbnQgbCA9IHNpemVvZihjb25uLT5sb2NhbF9hZGRyKTsKICBzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YSA9IGNvbm4tPmRhdGE7CiAgQ1VSTGNvZGUgcmVzdWx0OwoKICBpZihnZXRzb2NrbmFtZShjb25uLT5zb2NrW0ZJUlNUU09DS0VUXSwKICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyICopTE9DQUxfQUREUiwgJmwpIDwgMCkKICAgIHBlcnJvcigiZ2V0c29ja25hbWUoKSIpOwoKICBjaGVja3N1bSA9IGdldHBpZCgpOwogIHJldCA9IG1rX2F1dGgoZCwgJmFkYXQsICJmdHAiLCBob3N0LCBjaGVja3N1bSk7CiAgaWYocmV0ID09IEtEQ19QUl9VTktOT1dOKQogICAgcmV0ID0gbWtfYXV0aChkLCAmYWRhdCwgInJjbWQiLCBob3N0LCBjaGVja3N1bSk7CiAgaWYocmV0KSB7CiAgICBDdXJsX2luZm9mKGRhdGEsICIlc1xuIiwga3JiX2dldF9lcnJfdGV4dChyZXQpKTsKICAgIHJldHVybiBBVVRIX0NPTlRJTlVFOwogIH0KICAKI2lmZGVmIEhBVkVfS1JCX0dFVF9PVVJfSVBfRk9SX1JFQUxNCiAgaWYgKGtyYl9nZXRfY29uZmlnX2Jvb2woIm5hdF9pbl91c2UiKSkgewogICAgc3RydWN0IHNvY2thZGRyX2luICpsb2NhbGFkZHIgID0gKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFI7CiAgICBzdHJ1Y3QgaW5fYWRkciBuYXRBZGRyOwoKICAgIGlmIChrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oa3JiX3JlYWxtb2Zob3N0KGhvc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbmF0QWRkcikgIT0gS1NVQ0NFU1MKICAgICAgICAmJiBrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oTlVMTCwgJm5hdEFkZHIpICE9IEtTVUNDRVNTKQogICAgICBDdXJsX2luZm9mKGRhdGEsICJDYW4ndCBnZXQgYWRkcmVzcyBmb3IgcmVhbG0gJXNcbiIsCiAgICAgICAgICAgICAgICAga3JiX3JlYWxtb2Zob3N0KGhvc3QpKTsKICAgIGVsc2UgewogICAgICBpZiAobmF0QWRkci5zX2FkZHIgIT0gbG9jYWxhZGRyLT5zaW5fYWRkci5zX2FkZHIpIHsKI2lmZGVmIEhBVkVfSU5FVF9OVE9BX1IKICAgICAgICBjaGFyIG50b2FfYnVmWzY0XTsKICAgICAgICBjaGFyICppcCA9IChjaGFyICopaW5ldF9udG9hX3IobmF0QWRkciwgbnRvYV9idWYsIHNpemVvZihudG9hX2J1ZikpOwojZWxzZQogICAgICAgIGNoYXIgKmlwID0gKGNoYXIgKilpbmV0X250b2EobmF0QWRkcik7CiNlbmRpZgogICAgICAgIEN1cmxfaW5mb2YoZGF0YSwgIlVzaW5nIE5BVCBJUCBhZGRyZXNzICglcykgZm9yIGtlcmJlcm9zIDRcbiIsIGlwKTsKICAgICAgICBsb2NhbGFkZHItPnNpbl9hZGRyID0gbmF0QWRkcjsKICAgICAgfQogICAgfQogIH0KI2VuZGlmCgogIGlmKEN1cmxfYmFzZTY0X2VuY29kZSgoY2hhciAqKWFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJnApIDwgMSkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmciKTsKICAgIHJldHVybiBBVVRIX0NPTlRJTlVFOwogIH0KCiAgcmVzdWx0ID0gQ3VybF9mdHBzZW5kZihjb25uLCAiQURBVCAlcyIsIHApOwoKICBmcmVlKHApOwoKICBpZihyZXN1bHQpCiAgICByZXR1cm4gLTI7CgogIGlmKEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKSkKICAgIHJldHVybiAtMTsKCiAgaWYoZGF0YS0+c3RhdGUuYnVmZmVyWzBdICE9ICcyJyl7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJTZXJ2ZXIgZGlkbid0IGFjY2VwdCBhdXRoIGRhdGEiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KCiAgcCA9IHN0cnN0cihkYXRhLT5zdGF0ZS5idWZmZXIsICJBREFUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJSZW1vdGUgaG9zdCBkaWRuJ3Qgc2VuZCBhZGF0IHJlcGx5Iik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgcCArPSA1OwogIGxlbiA9IEN1cmxfYmFzZTY0X2RlY29kZShwLCAoY2hhciAqKWFkYXQuZGF0KTsKICBpZihsZW4gPCAwKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJGYWlsZWQgdG8gZGVjb2RlIGJhc2U2NCBmcm9tIHNlcnZlciIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIGFkYXQubGVuZ3RoID0gbGVuOwogIHJldCA9IGtyYl9yZF9zYWZlKGFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJmQtPmtleSwgCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKWhpc2N0bGFkZHIsIAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilteWN0bGFkZHIsICZtc2dfZGF0YSk7CiAgaWYocmV0KSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJFcnJvciByZWFkaW5nIHJlcGx5IGZyb20gc2VydmVyOiAlcyIsIAogICAgICAgICAgICAgICBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIGtyYl9nZXRfaW50KG1zZ19kYXRhLmFwcF9kYXRhLCAmY3MsIDQsIDApOwogIGlmKGNzIC0gY2hlY2tzdW0gIT0gMSkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiQmFkIGNoZWNrc3VtIHJldHVybmVkIGZyb20gc2VydmVyIik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgcmV0dXJuIEFVVEhfT0s7Cn0KCnN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCBDdXJsX2tyYjRfY2xpZW50X21lY2ggPSB7CiAgICAiS0VSQkVST1NfVjQiLAogICAgc2l6ZW9mKHN0cnVjdCBrcmI0X2RhdGEpLAogICAgTlVMTCwgLyogaW5pdCAqLwogICAga3JiNF9hdXRoLAogICAgTlVMTCwgLyogZW5kICovCiAgICBrcmI0X2NoZWNrX3Byb3QsCiAgICBrcmI0X292ZXJoZWFkLAogICAga3JiNF9lbmNvZGUsCiAgICBrcmI0X2RlY29kZQp9OwoKQ1VSTGNvZGUgQ3VybF9rcmJfa2F1dGgoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgZGVzX2NibG9jayBrZXk7CiAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICBLVEVYVF9TVCB0a3QsIHRrdGNvcHk7CiAgY2hhciAqbmFtZTsKICBjaGFyICpwOwogIGNoYXIgcGFzc3dkWzEwMF07CiAgaW50IHRtcDsKICBzc2l6ZV90IG5yZWFkOwogIGludCBzYXZlOwogIENVUkxjb2RlIHJlc3VsdDsKCiAgc2F2ZSA9IEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBwcm90X3ByaXZhdGUpOwoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzIiwgY29ubi0+dXNlcik7CgogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIHJlc3VsdCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzMnKXsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KCiAgcCA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJCYWQgcmVwbHkgZnJvbSBzZXJ2ZXIiKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybiBDVVJMRV9GVFBfV0VJUkRfU0VSVkVSX1JFUExZOwogIH0KCiAgcCArPSAyOwogIHRtcCA9IEN1cmxfYmFzZTY0X2RlY29kZShwLCAoY2hhciAqKXRrdC5kYXQpOwogIGlmKHRtcCA8IDApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBkZWNvZGUgYmFzZTY0IGluIHJlcGx5LlxuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CiAgdGt0Lmxlbmd0aCA9IHRtcDsKICB0a3Rjb3B5Lmxlbmd0aCA9IHRrdC5sZW5ndGg7CiAgICAKICBwID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlA9Iik7CiAgaWYoIXApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkJhZCByZXBseSBmcm9tIHNlcnZlciIpOwogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQogIG5hbWUgPSBwICsgMjsKICBmb3IoOyAqcCAmJiAqcCAhPSAnICcgJiYgKnAgIT0gJ1xyJyAmJiAqcCAhPSAnXG4nOyBwKyspOwogICpwID0gMDsKCiAgZGVzX3N0cmluZ190b19rZXkgKGNvbm4tPnBhc3N3ZCwgJmtleSk7CiAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CiAgICAKICBkZXNfcGNiY19lbmNyeXB0KCh2b2lkICopdGt0LmRhdCwgKHZvaWQgKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgIHRrdC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogIGlmIChzdHJjbXAgKChjaGFyKil0a3Rjb3B5LmRhdCArIDgsCiAgICAgICAgICAgICAgS1JCX1RJQ0tFVF9HUkFOVElOR19USUNLRVQpICE9IDApIHsKICAgIGFmc19zdHJpbmdfdG9fa2V5KHBhc3N3ZCwKICAgICAgICAgICAgICAgICAgICAgIGtyYl9yZWFsbW9maG9zdChjb25uLT5ob3N0Lm5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgJmtleSk7CiAgICBkZXNfa2V5X3NjaGVkKCZrZXksIHNjaGVkdWxlKTsKICAgIGRlc19wY2JjX2VuY3J5cHQoKHZvaWQgKil0a3QuZGF0LCAodm9pZCAqKXRrdGNvcHkuZGF0LAogICAgICAgICAgICAgICAgICAgICB0a3QubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogIH0KICBtZW1zZXQoa2V5LCAwLCBzaXplb2Yoa2V5KSk7CiAgbWVtc2V0KHNjaGVkdWxlLCAwLCBzaXplb2Yoc2NoZWR1bGUpKTsKICBtZW1zZXQocGFzc3dkLCAwLCBzaXplb2YocGFzc3dkKSk7CiAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKChjaGFyICopdGt0Y29weS5kYXQsIHRrdGNvcHkubGVuZ3RoLCAmcCkgPCAxKSB7CiAgICBmYWlsZihjb25uLT5kYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmcuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfT1VUX09GX01FTU9SWTsKICB9CiAgbWVtc2V0ICh0a3Rjb3B5LmRhdCwgMCwgdGt0Y29weS5sZW5ndGgpOwoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzICVzIiwgbmFtZSwgcCk7CiAgZnJlZShwKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICByZXN1bHQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgTlVMTCk7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CgogIHJldHVybiBDVVJMRV9PSzsKfQoKI2VuZGlmIC8qIEhBVkVfS1JCNCAqLwojZW5kaWYgLyogQ1VSTF9ESVNBQkxFX0ZUUCAqLwo=