LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhd2F5IGxpa2UgYSBtYWRtYW4gYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKiAKICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogKiAKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAKICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgSW5zdGl0dXRlIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBJTlNUSVRVVEUgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBJTlNUSVRVVEUgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUwogKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKICogSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLiAgKi8KCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmZGVmIEtSQjQKCiNpbmNsdWRlICJzZWN1cml0eS5oIgojaW5jbHVkZSAiYmFzZTY0LmgiCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPG5ldGRiLmg+CiNpbmNsdWRlIDxzeXNsb2cuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8a3JiLmg+CgojaWZkZWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+IC8qIGZvciBnZXRwaWQoKSAqLwojZW5kaWYKCiNpbmNsdWRlICJmdHAuaCIKI2luY2x1ZGUgInNlbmRmLmgiCgovKiBUaGUgbGFzdCAjaW5jbHVkZSBmaWxlIHNob3VsZCBiZTogKi8KI2lmZGVmIE1BTExPQ0RFQlVHCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgojZW5kaWYKCiNkZWZpbmUgTE9DQUxfQUREUiAoJmNvbm4tPmxvY2FsX2FkZHIpCiNkZWZpbmUgUkVNT1RFX0FERFIgKCZjb25uLT5zZXJ2X2FkZHIpCiNkZWZpbmUgbXljdGxhZGRyIExPQ0FMX0FERFIKI2RlZmluZSBoaXNjdGxhZGRyIFJFTU9URV9BRERSCgpzdHJ1Y3Qga3JiNF9kYXRhIHsKICAgIGRlc19jYmxvY2sga2V5OwogICAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICAgIGNoYXIgbmFtZVtBTkFNRV9TWl07CiAgICBjaGFyIGluc3RhbmNlW0lOU1RfU1pdOwogICAgY2hhciByZWFsbVtSRUFMTV9TWl07Cn07CgojaWZuZGVmIEhBVkVfU1RSTENQWQovKiBpZiBpdCBldmVyIGdvZXMgbm9uLXN0YXRpYywgbWFrZSBpdCBDdXJsXyBwcmVmaXhlZCEgKi8Kc3RhdGljIHNpemVfdApzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeikKewogICAgc2l6ZV90IG47CiAgICBjaGFyICpwOwoKICAgIGZvciAocCA9IGRzdCwgbiA9IDA7CgkgbiArIDEgPCBkc3Rfc3ogJiYgKnNyYyAhPSAnXDAnOwoJICsrcCwgKytzcmMsICsrbikKCSpwID0gKnNyYzsKICAgICpwID0gJ1wwJzsKICAgIGlmICgqc3JjID09ICdcMCcpCglyZXR1cm4gbjsKICAgIGVsc2UKCXJldHVybiBuICsgc3RybGVuIChzcmMpOwp9CiNlbHNlCnNpemVfdCBzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeik7CiNlbmRpZgoKc3RhdGljIGludAprcmI0X2NoZWNrX3Byb3Qodm9pZCAqYXBwX2RhdGEsIGludCBsZXZlbCkKewogIGFwcF9kYXRhID0gTlVMTDsgLyogcHJldmVudCBjb21waWxlciB3YXJuaW5nICovCiAgaWYobGV2ZWwgPT0gcHJvdF9jb25maWRlbnRpYWwpCiAgICByZXR1cm4gLTE7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKa3JiNF9kZWNvZGUodm9pZCAqYXBwX2RhdGEsIHZvaWQgKmJ1ZiwgaW50IGxlbiwgaW50IGxldmVsLAoJICAgIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogICAgTVNHX0RBVCBtOwogICAgaW50IGU7CiAgICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgICAKICAgIGlmKGxldmVsID09IHByb3Rfc2FmZSkKCWUgPSBrcmJfcmRfc2FmZShidWYsIGxlbiwgJmQtPmtleSwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAoJCQkoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwgJm0pOwogICAgZWxzZQoJZSA9IGtyYl9yZF9wcml2KGJ1ZiwgbGVuLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCgkJCShzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUiwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICAgIGlmKGUpewoJc3lzbG9nKExPR19FUlIsICJrcmI0X2RlY29kZTogJXMiLCBrcmJfZ2V0X2Vycl90ZXh0KGUpKTsKCXJldHVybiAtMTsKICAgIH0KICAgIG1lbW1vdmUoYnVmLCBtLmFwcF9kYXRhLCBtLmFwcF9sZW5ndGgpOwogICAgcmV0dXJuIG0uYXBwX2xlbmd0aDsKfQoKc3RhdGljIGludAprcmI0X292ZXJoZWFkKHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwsIGludCBsZW4pCnsKICAvKiBubyBhcmd1bWVudHMgYXJlIHVzZWQsIGp1c3QgaW5pdCB0aGVtIHRvIHByZXZlbnQgY29tcGlsZXIgd2FybmluZ3MgKi8KICBhcHBfZGF0YSA9IE5VTEw7CiAgbGV2ZWwgPSAwOwogIGxlbiA9IDA7CiAgcmV0dXJuIDMxOwp9CgpzdGF0aWMgaW50CmtyYjRfZW5jb2RlKHZvaWQgKmFwcF9kYXRhLCB2b2lkICpmcm9tLCBpbnQgbGVuZ3RoLCBpbnQgbGV2ZWwsIHZvaWQgKip0bywKCSAgICBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICAgIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICAgICp0byA9IG1hbGxvYyhsZW5ndGggKyAzMSk7CiAgICBpZihsZXZlbCA9PSBwcm90X3NhZmUpCglyZXR1cm4ga3JiX21rX3NhZmUoZnJvbSwgKnRvLCBsZW5ndGgsICZkLT5rZXksIAoJCQkgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKCQkJICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICAgIGVsc2UgaWYobGV2ZWwgPT0gcHJvdF9wcml2YXRlKQoJcmV0dXJuIGtyYl9ta19wcml2KGZyb20sICp0bywgbGVuZ3RoLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCgkJCSAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLAoJCQkgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIpOwogICAgZWxzZQoJcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50Cm1rX2F1dGgoc3RydWN0IGtyYjRfZGF0YSAqZCwgS1RFWFQgYWRhdCwgCgljb25zdCBjaGFyICpzZXJ2aWNlLCBjaGFyICpob3N0LCBpbnQgY2hlY2tzdW0pCnsKICAgIGludCByZXQ7CiAgICBDUkVERU5USUFMUyBjcmVkOwogICAgY2hhciBzbmFtZVtTTkFNRV9TWl0sIGluc3RbSU5TVF9TWl0sIHJlYWxtW1JFQUxNX1NaXTsKCiAgICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICAgIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICAgIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgICByZXQgPSBrcmJfbWtfcmVxKGFkYXQsIHNuYW1lLCBpbnN0LCByZWFsbSwgY2hlY2tzdW0pOwogICAgaWYocmV0KQoJcmV0dXJuIHJldDsKICAgIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogICAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogICAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICAgIHJldCA9IGtyYl9nZXRfY3JlZChzbmFtZSwgaW5zdCwgcmVhbG0sICZjcmVkKTsKICAgIG1lbW1vdmUoJmQtPmtleSwgJmNyZWQuc2Vzc2lvbiwgc2l6ZW9mKGRlc19jYmxvY2spKTsKICAgIGRlc19rZXlfc2NoZWQoJmQtPmtleSwgZC0+c2NoZWR1bGUpOwogICAgbWVtc2V0KCZjcmVkLCAwLCBzaXplb2YoY3JlZCkpOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIGludAprcmI0X2F1dGgodm9pZCAqYXBwX2RhdGEsIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGludCByZXQ7CiAgY2hhciAqcDsKICBpbnQgbGVuOwogIEtURVhUX1NUIGFkYXQ7CiAgTVNHX0RBVCBtc2dfZGF0YTsKICBpbnQgY2hlY2tzdW07CiAgdV9pbnQzMl90IGNzOwogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICBzdHJ1Y3Qgc29ja2FkZHJfaW4gKmxvY2FsYWRkciAgPSAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUjsKICBjaGFyICpob3N0ID0gY29ubi0+aHAtPmhfbmFtZTsKICBzc2l6ZV90IG5yZWFkOwogIGludCBsID0gc2l6ZW9mKGNvbm4tPmxvY2FsX2FkZHIpOwoKICBpZihnZXRzb2NrbmFtZShjb25uLT5maXJzdHNvY2tldCwKICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyICopTE9DQUxfQUREUiwgJmwpIDwgMCkKICAgIHBlcnJvcigiZ2V0c29ja25hbWUoKSIpOwoKICBjaGVja3N1bSA9IGdldHBpZCgpOwogIHJldCA9IG1rX2F1dGgoZCwgJmFkYXQsICJmdHAiLCBob3N0LCBjaGVja3N1bSk7CiAgaWYocmV0ID09IEtEQ19QUl9VTktOT1dOKQogICAgcmV0ID0gbWtfYXV0aChkLCAmYWRhdCwgInJjbWQiLCBob3N0LCBjaGVja3N1bSk7CiAgaWYocmV0KSB7CiAgICBwcmludGYoIiVzXG4iLCBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgfQogIAojaWZkZWYgSEFWRV9LUkJfR0VUX09VUl9JUF9GT1JfUkVBTE0KICBpZiAoa3JiX2dldF9jb25maWdfYm9vbCgibmF0X2luX3VzZSIpKSB7CiAgICBzdHJ1Y3QgaW5fYWRkciBuYXRBZGRyOwoKICAgIGlmIChrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oa3JiX3JlYWxtb2Zob3N0KGhvc3QpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbmF0QWRkcikgIT0gS1NVQ0NFU1MKICAgICAgICAmJiBrcmJfZ2V0X291cl9pcF9mb3JfcmVhbG0oTlVMTCwgJm5hdEFkZHIpICE9IEtTVUNDRVNTKQogICAgICBwcmludGYoIkNhbid0IGdldCBhZGRyZXNzIGZvciByZWFsbSAlc1xuIiwKICAgICAgICAgICAgIGtyYl9yZWFsbW9maG9zdChob3N0KSk7CiAgICBlbHNlIHsKICAgICAgaWYgKG5hdEFkZHIuc19hZGRyICE9IGxvY2FsYWRkci0+c2luX2FkZHIuc19hZGRyKSB7CiAgICAgICAgcHJpbnRmKCJVc2luZyBOQVQgSVAgYWRkcmVzcyAoJXMpIGZvciBrZXJiZXJvcyA0XG4iLAogICAgICAgICAgICAgICAoY2hhciAqKWluZXRfbnRvYShuYXRBZGRyKSk7CiAgICAgICAgbG9jYWxhZGRyLT5zaW5fYWRkciA9IG5hdEFkZHI7CiAgICAgICAgCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIG5vdCB0aGUgYmVzdCBwbGFjZSB0byBkbyB0aGlzLCBidXQgaXQgaXMgaGVyZSB3ZSBrbm93IHRoYXQKICAgICAgICAgKiAocHJvYmFibHkpIE5BVCBpcyBpbiB1c2UhICAqLwoKICAgICAgICAvKnBhc3NpdmVtb2RlID0gMTsqKiovCiAgICAgICAgLypwcmludGYoIlNldHRpbmc6IFBhc3NpdmUgbW9kZSBvbi5cbiIpOyoqKi8KICAgICAgfQogICAgfQogIH0KI2VuZGlmCgogIC8qcHJpbnRmKCJMb2NhbCBhZGRyZXNzIGlzICVzXG4iLCBpbmV0X250b2EobG9jYWxhZGRyLT5zaW5fYWRkcikpOyoqKi8KICAvKnByaW50ZigiUmVtb3RlIGFkZHJlc3MgaXMgJXNcbiIsIGluZXRfbnRvYShyZW1vdGVhZGRyLT5zaW5fYWRkcikpOyoqKi8KCiAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKGFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJnApIDwgMCkgewogICAgcHJpbnRmKCJPdXQgb2YgbWVtb3J5IGJhc2U2NC1lbmNvZGluZy5cbiIpOwogICAgcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgfQoKICBDdXJsX2Z0cHNlbmRmKGNvbm4tPmZpcnN0c29ja2V0LCBjb25uLCAiQURBVCAlcyIsIHApOwoKICBucmVhZCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoY29ubi0+Zmlyc3Rzb2NrZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgY29ubiwgTlVMTCk7CiAgaWYobnJlYWQgPCAwKQogICAgcmV0dXJuIC8qQ1VSTEVfT1BFUkFUSU9OX1RJTUVPVVRFRCovLTE7CiAgZnJlZShwKTsKCiAgaWYoLypyZXQgIT0gQ09NUExFVEUqL2Nvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMicpewogICAgcHJpbnRmKCJTZXJ2ZXIgZGlkbid0IGFjY2VwdCBhdXRoIGRhdGEuXG4iKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KCiAgcCA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJBREFUPSIpOwogIGlmKCFwKXsKICAgIHByaW50ZigiUmVtb3RlIGhvc3QgZGlkbid0IHNlbmQgYWRhdCByZXBseS5cbiIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIHAgKz0gNTsKICBsZW4gPSBDdXJsX2Jhc2U2NF9kZWNvZGUocCwgYWRhdC5kYXQpOwogIGlmKGxlbiA8IDApewogICAgcHJpbnRmKCJGYWlsZWQgdG8gZGVjb2RlIGJhc2U2NCBmcm9tIHNlcnZlci5cbiIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIGFkYXQubGVuZ3RoID0gbGVuOwogIHJldCA9IGtyYl9yZF9zYWZlKGFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJmQtPmtleSwgCiAgICAgICAgICAgICAgICAgICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKWhpc2N0bGFkZHIsIAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilteWN0bGFkZHIsICZtc2dfZGF0YSk7CiAgaWYocmV0KXsKICAgIHByaW50ZigiRXJyb3IgcmVhZGluZyByZXBseSBmcm9tIHNlcnZlcjogJXMuXG4iLCAKICAgICAgICAgICBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIGtyYl9nZXRfaW50KG1zZ19kYXRhLmFwcF9kYXRhLCAmY3MsIDQsIDApOwogIGlmKGNzIC0gY2hlY2tzdW0gIT0gMSl7CiAgICBwcmludGYoIkJhZCBjaGVja3N1bSByZXR1cm5lZCBmcm9tIHNlcnZlci5cbiIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIHJldHVybiBBVVRIX09LOwp9CgpzdHJ1Y3QgQ3VybF9zZWNfY2xpZW50X21lY2ggQ3VybF9rcmI0X2NsaWVudF9tZWNoID0gewogICAgIktFUkJFUk9TX1Y0IiwKICAgIHNpemVvZihzdHJ1Y3Qga3JiNF9kYXRhKSwKICAgIE5VTEwsIC8qIGluaXQgKi8KICAgIGtyYjRfYXV0aCwKICAgIE5VTEwsIC8qIGVuZCAqLwogICAga3JiNF9jaGVja19wcm90LAogICAga3JiNF9vdmVyaGVhZCwKICAgIGtyYjRfZW5jb2RlLAogICAga3JiNF9kZWNvZGUKfTsKCnZvaWQgQ3VybF9rcmJfa2F1dGgoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgZGVzX2NibG9jayBrZXk7CiAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICBLVEVYVF9TVCB0a3QsIHRrdGNvcHk7CiAgY2hhciAqbmFtZTsKICBjaGFyICpwOwogIGNoYXIgcGFzc3dkWzEwMF07CiAgaW50IHRtcDsKICBzc2l6ZV90IG5yZWFkOwoJCiAgaW50IHNhdmU7CgogIHNhdmUgPSBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgcHJvdF9wcml2YXRlKTsKCiAgQ3VybF9mdHBzZW5kZihjb25uLT5maXJzdHNvY2tldCwgY29ubiwKICAgICAgICAgICAgICAgICJTSVRFIEtBVVRIICVzIiwgY29ubi0+ZGF0YS0+c3RhdGUudXNlcik7CgogIG5yZWFkID0gQ3VybF9HZXRGVFBSZXNwb25zZShjb25uLT5maXJzdHNvY2tldCwgY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLCBOVUxMKTsKICBpZihucmVhZCA8IDApCiAgICByZXR1cm4gLypDVVJMRV9PUEVSQVRJT05fVElNRU9VVEVEKi87CgogIGlmKC8qcmV0ICE9IENPTlRJTlVFKi9jb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzMnKXsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIC8qY29kZSA9IC0xOyoqKi8KICAgIHJldHVybjsKICB9CgogIHAgPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiVD0iKTsKICBpZighcCkgewogICAgcHJpbnRmKCJCYWQgcmVwbHkgZnJvbSBzZXJ2ZXIuXG4iKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybjsKICB9CgogIHAgKz0gMjsKICB0bXAgPSBDdXJsX2Jhc2U2NF9kZWNvZGUocCwgJnRrdC5kYXQpOwogIGlmKHRtcCA8IDApIHsKICAgIHByaW50ZigiRmFpbGVkIHRvIGRlY29kZSBiYXNlNjQgaW4gcmVwbHkuXG4iKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybjsKICB9CiAgdGt0Lmxlbmd0aCA9IHRtcDsKICB0a3Rjb3B5Lmxlbmd0aCA9IHRrdC5sZW5ndGg7CiAgICAKICBwID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlA9Iik7CiAgaWYoIXApIHsKICAgIHByaW50ZigiQmFkIHJlcGx5IGZyb20gc2VydmVyLlxuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm47CiAgfQogIG5hbWUgPSBwICsgMjsKICBmb3IoOyAqcCAmJiAqcCAhPSAnICcgJiYgKnAgIT0gJ1xyJyAmJiAqcCAhPSAnXG4nOyBwKyspOwogICpwID0gMDsKCiAgZGVzX3N0cmluZ190b19rZXkgKGNvbm4tPmRhdGEtPnN0YXRlLnBhc3N3ZCwgJmtleSk7CiAgZGVzX2tleV9zY2hlZCgma2V5LCBzY2hlZHVsZSk7CiAgICAKICBkZXNfcGNiY19lbmNyeXB0KChkZXNfY2Jsb2NrKil0a3QuZGF0LCAoZGVzX2NibG9jayopdGt0Y29weS5kYXQsCiAgICAgICAgICAgICAgICAgICB0a3QubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICBpZiAoc3RyY21wICgoY2hhciopdGt0Y29weS5kYXQgKyA4LAogICAgICAgICAgICAgIEtSQl9USUNLRVRfR1JBTlRJTkdfVElDS0VUKSAhPSAwKSB7CiAgICBhZnNfc3RyaW5nX3RvX2tleSAocGFzc3dkLAogICAgICAgICAgICAgICAgICAgICAgIGtyYl9yZWFsbW9maG9zdCgvKmhvc3RuYW1lKi9jb25uLT5ocC0+aF9uYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAma2V5KTsKICAgIGRlc19rZXlfc2NoZWQgKCZrZXksIHNjaGVkdWxlKTsKICAgIGRlc19wY2JjX2VuY3J5cHQoKGRlc19jYmxvY2sqKXRrdC5kYXQsIChkZXNfY2Jsb2NrKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgICAgdGt0Lmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICB9CiAgbWVtc2V0KGtleSwgMCwgc2l6ZW9mKGtleSkpOwogIG1lbXNldChzY2hlZHVsZSwgMCwgc2l6ZW9mKHNjaGVkdWxlKSk7CiAgbWVtc2V0KHBhc3N3ZCwgMCwgc2l6ZW9mKHBhc3N3ZCkpOwogIGlmKEN1cmxfYmFzZTY0X2VuY29kZSh0a3Rjb3B5LmRhdCwgdGt0Y29weS5sZW5ndGgsICZwKSA8IDApIHsKICAgIGZhaWxmKGNvbm4tPmRhdGEsICJPdXQgb2YgbWVtb3J5IGJhc2U2NC1lbmNvZGluZy5cbiIpOwogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuOwogIH0KICBtZW1zZXQgKHRrdGNvcHkuZGF0LCAwLCB0a3Rjb3B5Lmxlbmd0aCk7CgogIEN1cmxfZnRwc2VuZGYoY29ubi0+Zmlyc3Rzb2NrZXQsIGNvbm4sCiAgICAgICAgICAgICAgICAiU0lURSBLQVVUSCAlcyAlcyIsIG5hbWUsIHApOwoKICBucmVhZCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoY29ubi0+Zmlyc3Rzb2NrZXQsIGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubiwgTlVMTCk7CiAgaWYobnJlYWQgPCAwKQogICAgcmV0dXJuIC8qQ1VSTEVfT1BFUkFUSU9OX1RJTUVPVVRFRCovOwogIGZyZWUocCk7CiAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwp9CgojZW5kaWYgLyogS1JCNCAqLwoKLyoKICogbG9jYWwgdmFyaWFibGVzOgogKiBldmFsOiAobG9hZC1maWxlICIuLi9jdXJsLW1vZGUuZWwiKQogKiBlbmQ6CiAqIHZpbTYwMDogZXQgc3c9MiB0cz0yIHN0cz0yIHR3PTc4IGZkbT1tYXJrZXIKICogdmltPDYwMDogZXQgc3c9MiB0cz0yIHN0cz0yIHR3PTc4CiAqLwo=