LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhd2F5IGxpa2UgYSBtYWRtYW4gYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKiAKICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogKiAKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAKICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgSW5zdGl0dXRlIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBJTlNUSVRVVEUgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBJTlNUSVRVVEUgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUwogKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKICogSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLiAgKi8KCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBLUkI0CgojaW5jbHVkZSAic2VjdXJpdHkuaCIKI2luY2x1ZGUgImJhc2U2NC5oIgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxuZXRkYi5oPgojaW5jbHVkZSA8c3lzbG9nLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGtyYi5oPgojaW5jbHVkZSA8ZGVzLmg+CgojaWZkZWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+IC8qIGZvciBnZXRwaWQoKSAqLwojZW5kaWYKCiNpbmNsdWRlICJmdHAuaCIKI2luY2x1ZGUgInNlbmRmLmgiCgojaWYgZGVmaW5lZChIQVZFX0lORVRfTlRPQV9SKSAmJiAhZGVmaW5lZChIQVZFX0lORVRfTlRPQV9SX0RFQ0wpCiNpbmNsdWRlICJpbmV0X250b2Ffci5oIgojZW5kaWYKCi8qIFRoZSBsYXN0ICNpbmNsdWRlIGZpbGUgc2hvdWxkIGJlOiAqLwojaWZkZWYgQ1VSTERFQlVHCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgojZW5kaWYKCiNkZWZpbmUgTE9DQUxfQUREUiAoJmNvbm4tPmxvY2FsX2FkZHIpCiNkZWZpbmUgUkVNT1RFX0FERFIgKCZjb25uLT5zZXJ2X2FkZHIpCiNkZWZpbmUgbXljdGxhZGRyIExPQ0FMX0FERFIKI2RlZmluZSBoaXNjdGxhZGRyIFJFTU9URV9BRERSCgpzdHJ1Y3Qga3JiNF9kYXRhIHsKICAgIGRlc19jYmxvY2sga2V5OwogICAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICAgIGNoYXIgbmFtZVtBTkFNRV9TWl07CiAgICBjaGFyIGluc3RhbmNlW0lOU1RfU1pdOwogICAgY2hhciByZWFsbVtSRUFMTV9TWl07Cn07CgojaWZuZGVmIEhBVkVfU1RSTENQWQovKiBpZiBpdCBldmVyIGdvZXMgbm9uLXN0YXRpYywgbWFrZSBpdCBDdXJsXyBwcmVmaXhlZCEgKi8Kc3RhdGljIHNpemVfdApzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeikKewogICAgc2l6ZV90IG47CiAgICBjaGFyICpwOwoKICAgIGZvciAocCA9IGRzdCwgbiA9IDA7CgkgbiArIDEgPCBkc3Rfc3ogJiYgKnNyYyAhPSAnXDAnOwoJICsrcCwgKytzcmMsICsrbikKCSpwID0gKnNyYzsKICAgICpwID0gJ1wwJzsKICAgIGlmICgqc3JjID09ICdcMCcpCglyZXR1cm4gbjsKICAgIGVsc2UKCXJldHVybiBuICsgc3RybGVuIChzcmMpOwp9CiNlbHNlCnNpemVfdCBzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeik7CiNlbmRpZgoKc3RhdGljIGludAprcmI0X2NoZWNrX3Byb3Qodm9pZCAqYXBwX2RhdGEsIGludCBsZXZlbCkKewogIGFwcF9kYXRhID0gTlVMTDsgLyogcHJldmVudCBjb21waWxlciB3YXJuaW5nICovCiAgaWYobGV2ZWwgPT0gcHJvdF9jb25maWRlbnRpYWwpCiAgICByZXR1cm4gLTE7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKa3JiNF9kZWNvZGUodm9pZCAqYXBwX2RhdGEsIHZvaWQgKmJ1ZiwgaW50IGxlbiwgaW50IGxldmVsLAoJICAgIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogICAgTVNHX0RBVCBtOwogICAgaW50IGU7CiAgICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgICAKICAgIGlmKGxldmVsID09IHByb3Rfc2FmZSkKCWUgPSBrcmJfcmRfc2FmZShidWYsIGxlbiwgJmQtPmtleSwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAoJCQkoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwgJm0pOwogICAgZWxzZQoJZSA9IGtyYl9yZF9wcml2KGJ1ZiwgbGVuLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCgkJCShzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUiwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICAgIGlmKGUpewoJc3lzbG9nKExPR19FUlIsICJrcmI0X2RlY29kZTogJXMiLCBrcmJfZ2V0X2Vycl90ZXh0KGUpKTsKCXJldHVybiAtMTsKICAgIH0KICAgIG1lbW1vdmUoYnVmLCBtLmFwcF9kYXRhLCBtLmFwcF9sZW5ndGgpOwogICAgcmV0dXJuIG0uYXBwX2xlbmd0aDsKfQoKc3RhdGljIGludAprcmI0X292ZXJoZWFkKHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwsIGludCBsZW4pCnsKICAvKiBubyBhcmd1bWVudHMgYXJlIHVzZWQsIGp1c3QgaW5pdCB0aGVtIHRvIHByZXZlbnQgY29tcGlsZXIgd2FybmluZ3MgKi8KICBhcHBfZGF0YSA9IE5VTEw7CiAgbGV2ZWwgPSAwOwogIGxlbiA9IDA7CiAgcmV0dXJuIDMxOwp9CgpzdGF0aWMgaW50CmtyYjRfZW5jb2RlKHZvaWQgKmFwcF9kYXRhLCB2b2lkICpmcm9tLCBpbnQgbGVuZ3RoLCBpbnQgbGV2ZWwsIHZvaWQgKip0bywKCSAgICBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICAgIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICAgICp0byA9IG1hbGxvYyhsZW5ndGggKyAzMSk7CiAgICBpZihsZXZlbCA9PSBwcm90X3NhZmUpCglyZXR1cm4ga3JiX21rX3NhZmUoZnJvbSwgKnRvLCBsZW5ndGgsICZkLT5rZXksIAoJCQkgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKCQkJICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICAgIGVsc2UgaWYobGV2ZWwgPT0gcHJvdF9wcml2YXRlKQoJcmV0dXJuIGtyYl9ta19wcml2KGZyb20sICp0bywgbGVuZ3RoLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCgkJCSAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLAoJCQkgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIpOwogICAgZWxzZQoJcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50Cm1rX2F1dGgoc3RydWN0IGtyYjRfZGF0YSAqZCwgS1RFWFQgYWRhdCwgCgljb25zdCBjaGFyICpzZXJ2aWNlLCBjaGFyICpob3N0LCBpbnQgY2hlY2tzdW0pCnsKICAgIGludCByZXQ7CiAgICBDUkVERU5USUFMUyBjcmVkOwogICAgY2hhciBzbmFtZVtTTkFNRV9TWl0sIGluc3RbSU5TVF9TWl0sIHJlYWxtW1JFQUxNX1NaXTsKCiAgICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICAgIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICAgIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgICByZXQgPSBrcmJfbWtfcmVxKGFkYXQsIHNuYW1lLCBpbnN0LCByZWFsbSwgY2hlY2tzdW0pOwogICAgaWYocmV0KQoJcmV0dXJuIHJldDsKICAgIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogICAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogICAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICAgIHJldCA9IGtyYl9nZXRfY3JlZChzbmFtZSwgaW5zdCwgcmVhbG0sICZjcmVkKTsKICAgIG1lbW1vdmUoJmQtPmtleSwgJmNyZWQuc2Vzc2lvbiwgc2l6ZW9mKGRlc19jYmxvY2spKTsKICAgIGRlc19rZXlfc2NoZWQoJmQtPmtleSwgZC0+c2NoZWR1bGUpOwogICAgbWVtc2V0KCZjcmVkLCAwLCBzaXplb2YoY3JlZCkpOwogICAgcmV0dXJuIHJldDsKfQoKI2lmZGVmIEhBVkVfS1JCX0dFVF9PVVJfSVBfRk9SX1JFQUxNCmludCBrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oY2hhciAqLCBzdHJ1Y3QgaW5fYWRkciAqKTsKI2VuZGlmCgpzdGF0aWMgaW50CmtyYjRfYXV0aCh2b2lkICphcHBfZGF0YSwgc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IHJldDsKICBjaGFyICpwOwogIGludCBsZW47CiAgS1RFWFRfU1QgYWRhdDsKICBNU0dfREFUIG1zZ19kYXRhOwogIGludCBjaGVja3N1bTsKICB1X2ludDMyX3QgY3M7CiAgc3RydWN0IGtyYjRfZGF0YSAqZCA9IGFwcF9kYXRhOwogIGNoYXIgKmhvc3QgPSBjb25uLT5ob3N0bmFtZTsKICBzc2l6ZV90IG5yZWFkOwogIGludCBsID0gc2l6ZW9mKGNvbm4tPmxvY2FsX2FkZHIpOwogIHN0cnVjdCBTZXNzaW9uSGFuZGxlICpkYXRhID0gY29ubi0+ZGF0YTsKICBDVVJMY29kZSByZXN1bHQ7CgogIGlmKGdldHNvY2tuYW1lKGNvbm4tPmZpcnN0c29ja2V0LAogICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHIgKilMT0NBTF9BRERSLCAmbCkgPCAwKQogICAgcGVycm9yKCJnZXRzb2NrbmFtZSgpIik7CgogIGNoZWNrc3VtID0gZ2V0cGlkKCk7CiAgcmV0ID0gbWtfYXV0aChkLCAmYWRhdCwgImZ0cCIsIGhvc3QsIGNoZWNrc3VtKTsKICBpZihyZXQgPT0gS0RDX1BSX1VOS05PV04pCiAgICByZXQgPSBta19hdXRoKGQsICZhZGF0LCAicmNtZCIsIGhvc3QsIGNoZWNrc3VtKTsKICBpZihyZXQpIHsKICAgIEN1cmxfaW5mb2YoZGF0YSwgIiVzXG4iLCBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgfQogIAojaWZkZWYgSEFWRV9LUkJfR0VUX09VUl9JUF9GT1JfUkVBTE0KICBpZiAoa3JiX2dldF9jb25maWdfYm9vbCgibmF0X2luX3VzZSIpKSB7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gKmxvY2FsYWRkciAgPSAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUjsKICAgIHN0cnVjdCBpbl9hZGRyIG5hdEFkZHI7CgogICAgaWYgKGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShrcmJfcmVhbG1vZmhvc3QoaG9zdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZuYXRBZGRyKSAhPSBLU1VDQ0VTUwogICAgICAgICYmIGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShOVUxMLCAmbmF0QWRkcikgIT0gS1NVQ0NFU1MpCiAgICAgIEN1cmxfaW5mb2YoZGF0YSwgIkNhbid0IGdldCBhZGRyZXNzIGZvciByZWFsbSAlc1xuIiwKICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoaG9zdCkpOwogICAgZWxzZSB7CiAgICAgIGlmIChuYXRBZGRyLnNfYWRkciAhPSBsb2NhbGFkZHItPnNpbl9hZGRyLnNfYWRkcikgewojaWZkZWYgSEFWRV9JTkVUX05UT0FfUgogICAgICAgIGNoYXIgbnRvYV9idWZbNjRdOwogICAgICAgIGNoYXIgKmlwID0gKGNoYXIgKilpbmV0X250b2FfcihuYXRBZGRyLCBudG9hX2J1Ziwgc2l6ZW9mKG50b2FfYnVmKSk7CiNlbHNlCiAgICAgICAgY2hhciAqaXAgPSAoY2hhciAqKWluZXRfbnRvYShuYXRBZGRyKTsKI2VuZGlmCiAgICAgICAgQ3VybF9pbmZvZihkYXRhLCAiVXNpbmcgTkFUIElQIGFkZHJlc3MgKCVzKSBmb3Iga2VyYmVyb3MgNFxuIiwgaXApOwogICAgICAgIGxvY2FsYWRkci0+c2luX2FkZHIgPSBuYXRBZGRyOwogICAgICB9CiAgICB9CiAgfQojZW5kaWYKCiAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKGFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJnApIDwgMCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmciKTsKICAgIHJldHVybiBBVVRIX0NPTlRJTlVFOwogIH0KCiAgcmVzdWx0ID0gQ3VybF9mdHBzZW5kZihjb25uLCAiQURBVCAlcyIsIHApOwoKICBmcmVlKHApOwoKICBpZihyZXN1bHQpCiAgICByZXR1cm4gLTI7CgogIGlmKEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCBOVUxMKSkKICAgIHJldHVybiAtMTsKCiAgaWYoZGF0YS0+c3RhdGUuYnVmZmVyWzBdICE9ICcyJyl7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJTZXJ2ZXIgZGlkbid0IGFjY2VwdCBhdXRoIGRhdGEiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KCiAgcCA9IHN0cnN0cihkYXRhLT5zdGF0ZS5idWZmZXIsICJBREFUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJSZW1vdGUgaG9zdCBkaWRuJ3Qgc2VuZCBhZGF0IHJlcGx5Iik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgcCArPSA1OwogIGxlbiA9IEN1cmxfYmFzZTY0X2RlY29kZShwLCBhZGF0LmRhdCk7CiAgaWYobGVuIDwgMCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiRmFpbGVkIHRvIGRlY29kZSBiYXNlNjQgZnJvbSBzZXJ2ZXIiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBhZGF0Lmxlbmd0aCA9IGxlbjsKICByZXQgPSBrcmJfcmRfc2FmZShhZGF0LmRhdCwgYWRhdC5sZW5ndGgsICZkLT5rZXksIAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKiloaXNjdGxhZGRyLCAKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopbXljdGxhZGRyLCAmbXNnX2RhdGEpOwogIGlmKHJldCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiRXJyb3IgcmVhZGluZyByZXBseSBmcm9tIHNlcnZlcjogJXMiLCAKICAgICAgICAgICAgICAga3JiX2dldF9lcnJfdGV4dChyZXQpKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBrcmJfZ2V0X2ludChtc2dfZGF0YS5hcHBfZGF0YSwgJmNzLCA0LCAwKTsKICBpZihjcyAtIGNoZWNrc3VtICE9IDEpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIkJhZCBjaGVja3N1bSByZXR1cm5lZCBmcm9tIHNlcnZlciIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIHJldHVybiBBVVRIX09LOwp9CgpzdHJ1Y3QgQ3VybF9zZWNfY2xpZW50X21lY2ggQ3VybF9rcmI0X2NsaWVudF9tZWNoID0gewogICAgIktFUkJFUk9TX1Y0IiwKICAgIHNpemVvZihzdHJ1Y3Qga3JiNF9kYXRhKSwKICAgIE5VTEwsIC8qIGluaXQgKi8KICAgIGtyYjRfYXV0aCwKICAgIE5VTEwsIC8qIGVuZCAqLwogICAga3JiNF9jaGVja19wcm90LAogICAga3JiNF9vdmVyaGVhZCwKICAgIGtyYjRfZW5jb2RlLAogICAga3JiNF9kZWNvZGUKfTsKCkNVUkxjb2RlIEN1cmxfa3JiX2thdXRoKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGRlc19jYmxvY2sga2V5OwogIGRlc19rZXlfc2NoZWR1bGUgc2NoZWR1bGU7CiAgS1RFWFRfU1QgdGt0LCB0a3Rjb3B5OwogIGNoYXIgKm5hbWU7CiAgY2hhciAqcDsKICBjaGFyIHBhc3N3ZFsxMDBdOwogIGludCB0bXA7CiAgc3NpemVfdCBucmVhZDsKICBpbnQgc2F2ZTsKICBDVVJMY29kZSByZXN1bHQ7CgogIHNhdmUgPSBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgcHJvdF9wcml2YXRlKTsKCiAgcmVzdWx0ID0gQ3VybF9mdHBzZW5kZihjb25uLCAiU0lURSBLQVVUSCAlcyIsIGNvbm4tPnVzZXIpOwoKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICByZXN1bHQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgTlVMTCk7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKCiAgaWYoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyWzBdICE9ICczJyl7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CgogIHAgPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiVD0iKTsKICBpZighcCkgewogICAgQ3VybF9mYWlsZihjb25uLT5kYXRhLCAiQmFkIHJlcGx5IGZyb20gc2VydmVyIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CgogIHAgKz0gMjsKICB0bXAgPSBDdXJsX2Jhc2U2NF9kZWNvZGUocCwgJnRrdC5kYXQpOwogIGlmKHRtcCA8IDApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBkZWNvZGUgYmFzZTY0IGluIHJlcGx5LlxuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfRlRQX1dFSVJEX1NFUlZFUl9SRVBMWTsKICB9CiAgdGt0Lmxlbmd0aCA9IHRtcDsKICB0a3Rjb3B5Lmxlbmd0aCA9IHRrdC5sZW5ndGg7CiAgICAKICBwID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlA9Iik7CiAgaWYoIXApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkJhZCByZXBseSBmcm9tIHNlcnZlciIpOwogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuIENVUkxFX0ZUUF9XRUlSRF9TRVJWRVJfUkVQTFk7CiAgfQogIG5hbWUgPSBwICsgMjsKICBmb3IoOyAqcCAmJiAqcCAhPSAnICcgJiYgKnAgIT0gJ1xyJyAmJiAqcCAhPSAnXG4nOyBwKyspOwogICpwID0gMDsKCiAgZGVzX3N0cmluZ190b19rZXkgKGNvbm4tPnBhc3N3ZCwgJmtleSk7CiAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CiAgICAKICBkZXNfcGNiY19lbmNyeXB0KCh2b2lkICopdGt0LmRhdCwgKHZvaWQgKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgIHRrdC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogIGlmIChzdHJjbXAgKChjaGFyKil0a3Rjb3B5LmRhdCArIDgsCiAgICAgICAgICAgICAgS1JCX1RJQ0tFVF9HUkFOVElOR19USUNLRVQpICE9IDApIHsKICAgIGFmc19zdHJpbmdfdG9fa2V5KHBhc3N3ZCwKICAgICAgICAgICAgICAgICAgICAgIGtyYl9yZWFsbW9maG9zdChjb25uLT5ob3N0bmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAma2V5KTsKICAgIGRlc19rZXlfc2NoZWQoJmtleSwgc2NoZWR1bGUpOwogICAgZGVzX3BjYmNfZW5jcnlwdCgodm9pZCAqKXRrdC5kYXQsICh2b2lkICopdGt0Y29weS5kYXQsCiAgICAgICAgICAgICAgICAgICAgIHRrdC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgIHNjaGVkdWxlLCAma2V5LCBERVNfREVDUllQVCk7CiAgfQogIG1lbXNldChrZXksIDAsIHNpemVvZihrZXkpKTsKICBtZW1zZXQoc2NoZWR1bGUsIDAsIHNpemVvZihzY2hlZHVsZSkpOwogIG1lbXNldChwYXNzd2QsIDAsIHNpemVvZihwYXNzd2QpKTsKICBpZihDdXJsX2Jhc2U2NF9lbmNvZGUodGt0Y29weS5kYXQsIHRrdGNvcHkubGVuZ3RoLCAmcCkgPCAwKSB7CiAgICBmYWlsZihjb25uLT5kYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmcuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm4gQ1VSTEVfT1VUX09GX01FTU9SWTsKICB9CiAgbWVtc2V0ICh0a3Rjb3B5LmRhdCwgMCwgdGt0Y29weS5sZW5ndGgpOwoKICByZXN1bHQgPSBDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzICVzIiwgbmFtZSwgcCk7CiAgZnJlZShwKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICByZXN1bHQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgTlVMTCk7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CgogIHJldHVybiBDVVJMRV9PSzsKfQoKI2VuZGlmIC8qIEtSQjQgKi8KI2VuZGlmIC8qIENVUkxfRElTQUJMRV9GVFAgKi8K