LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhd2F5IGxpa2UgYSBtYWRtYW4gYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKiAKICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogKiAKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAKICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgSW5zdGl0dXRlIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBJTlNUSVRVVEUgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBJTlNUSVRVVEUgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUwogKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKICogSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLiAgKi8KCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBLUkI0CgojaW5jbHVkZSAic2VjdXJpdHkuaCIKI2luY2x1ZGUgImJhc2U2NC5oIgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxuZXRkYi5oPgojaW5jbHVkZSA8c3lzbG9nLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGtyYi5oPgoKI2lmZGVmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPiAvKiBmb3IgZ2V0cGlkKCkgKi8KI2VuZGlmCgojaW5jbHVkZSAiZnRwLmgiCiNpbmNsdWRlICJzZW5kZi5oIgoKI2lmIGRlZmluZWQoSEFWRV9JTkVUX05UT0FfUikgJiYgIWRlZmluZWQoSEFWRV9JTkVUX05UT0FfUl9ERUNMKQojaW5jbHVkZSAiaW5ldF9udG9hX3IuaCIKI2VuZGlmCgovKiBUaGUgbGFzdCAjaW5jbHVkZSBmaWxlIHNob3VsZCBiZTogKi8KI2lmZGVmIE1BTExPQ0RFQlVHCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgojZW5kaWYKCiNkZWZpbmUgTE9DQUxfQUREUiAoJmNvbm4tPmxvY2FsX2FkZHIpCiNkZWZpbmUgUkVNT1RFX0FERFIgKCZjb25uLT5zZXJ2X2FkZHIpCiNkZWZpbmUgbXljdGxhZGRyIExPQ0FMX0FERFIKI2RlZmluZSBoaXNjdGxhZGRyIFJFTU9URV9BRERSCgpzdHJ1Y3Qga3JiNF9kYXRhIHsKICAgIGRlc19jYmxvY2sga2V5OwogICAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICAgIGNoYXIgbmFtZVtBTkFNRV9TWl07CiAgICBjaGFyIGluc3RhbmNlW0lOU1RfU1pdOwogICAgY2hhciByZWFsbVtSRUFMTV9TWl07Cn07CgojaWZuZGVmIEhBVkVfU1RSTENQWQovKiBpZiBpdCBldmVyIGdvZXMgbm9uLXN0YXRpYywgbWFrZSBpdCBDdXJsXyBwcmVmaXhlZCEgKi8Kc3RhdGljIHNpemVfdApzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeikKewogICAgc2l6ZV90IG47CiAgICBjaGFyICpwOwoKICAgIGZvciAocCA9IGRzdCwgbiA9IDA7CgkgbiArIDEgPCBkc3Rfc3ogJiYgKnNyYyAhPSAnXDAnOwoJICsrcCwgKytzcmMsICsrbikKCSpwID0gKnNyYzsKICAgICpwID0gJ1wwJzsKICAgIGlmICgqc3JjID09ICdcMCcpCglyZXR1cm4gbjsKICAgIGVsc2UKCXJldHVybiBuICsgc3RybGVuIChzcmMpOwp9CiNlbHNlCnNpemVfdCBzdHJsY3B5IChjaGFyICpkc3QsIGNvbnN0IGNoYXIgKnNyYywgc2l6ZV90IGRzdF9zeik7CiNlbmRpZgoKc3RhdGljIGludAprcmI0X2NoZWNrX3Byb3Qodm9pZCAqYXBwX2RhdGEsIGludCBsZXZlbCkKewogIGFwcF9kYXRhID0gTlVMTDsgLyogcHJldmVudCBjb21waWxlciB3YXJuaW5nICovCiAgaWYobGV2ZWwgPT0gcHJvdF9jb25maWRlbnRpYWwpCiAgICByZXR1cm4gLTE7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKa3JiNF9kZWNvZGUodm9pZCAqYXBwX2RhdGEsIHZvaWQgKmJ1ZiwgaW50IGxlbiwgaW50IGxldmVsLAoJICAgIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogICAgTVNHX0RBVCBtOwogICAgaW50IGU7CiAgICBzdHJ1Y3Qga3JiNF9kYXRhICpkID0gYXBwX2RhdGE7CiAgICAKICAgIGlmKGxldmVsID09IHByb3Rfc2FmZSkKCWUgPSBrcmJfcmRfc2FmZShidWYsIGxlbiwgJmQtPmtleSwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSLAoJCQkoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwgJm0pOwogICAgZWxzZQoJZSA9IGtyYl9yZF9wcml2KGJ1ZiwgbGVuLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCgkJCShzdHJ1Y3Qgc29ja2FkZHJfaW4gKilSRU1PVEVfQUREUiwKCQkJKHN0cnVjdCBzb2NrYWRkcl9pbiAqKUxPQ0FMX0FERFIsICZtKTsKICAgIGlmKGUpewoJc3lzbG9nKExPR19FUlIsICJrcmI0X2RlY29kZTogJXMiLCBrcmJfZ2V0X2Vycl90ZXh0KGUpKTsKCXJldHVybiAtMTsKICAgIH0KICAgIG1lbW1vdmUoYnVmLCBtLmFwcF9kYXRhLCBtLmFwcF9sZW5ndGgpOwogICAgcmV0dXJuIG0uYXBwX2xlbmd0aDsKfQoKc3RhdGljIGludAprcmI0X292ZXJoZWFkKHZvaWQgKmFwcF9kYXRhLCBpbnQgbGV2ZWwsIGludCBsZW4pCnsKICAvKiBubyBhcmd1bWVudHMgYXJlIHVzZWQsIGp1c3QgaW5pdCB0aGVtIHRvIHByZXZlbnQgY29tcGlsZXIgd2FybmluZ3MgKi8KICBhcHBfZGF0YSA9IE5VTEw7CiAgbGV2ZWwgPSAwOwogIGxlbiA9IDA7CiAgcmV0dXJuIDMxOwp9CgpzdGF0aWMgaW50CmtyYjRfZW5jb2RlKHZvaWQgKmFwcF9kYXRhLCB2b2lkICpmcm9tLCBpbnQgbGVuZ3RoLCBpbnQgbGV2ZWwsIHZvaWQgKip0bywKCSAgICBzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICAgIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICAgICp0byA9IG1hbGxvYyhsZW5ndGggKyAzMSk7CiAgICBpZihsZXZlbCA9PSBwcm90X3NhZmUpCglyZXR1cm4ga3JiX21rX3NhZmUoZnJvbSwgKnRvLCBsZW5ndGgsICZkLT5rZXksIAoJCQkgICAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUiwKCQkJICAgKHN0cnVjdCBzb2NrYWRkcl9pbiAqKVJFTU9URV9BRERSKTsKICAgIGVsc2UgaWYobGV2ZWwgPT0gcHJvdF9wcml2YXRlKQoJcmV0dXJuIGtyYl9ta19wcml2KGZyb20sICp0bywgbGVuZ3RoLCBkLT5zY2hlZHVsZSwgJmQtPmtleSwgCgkJCSAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKilMT0NBTF9BRERSLAoJCQkgICAoc3RydWN0IHNvY2thZGRyX2luICopUkVNT1RFX0FERFIpOwogICAgZWxzZQoJcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50Cm1rX2F1dGgoc3RydWN0IGtyYjRfZGF0YSAqZCwgS1RFWFQgYWRhdCwgCgljb25zdCBjaGFyICpzZXJ2aWNlLCBjaGFyICpob3N0LCBpbnQgY2hlY2tzdW0pCnsKICAgIGludCByZXQ7CiAgICBDUkVERU5USUFMUyBjcmVkOwogICAgY2hhciBzbmFtZVtTTkFNRV9TWl0sIGluc3RbSU5TVF9TWl0sIHJlYWxtW1JFQUxNX1NaXTsKCiAgICBzdHJsY3B5KHNuYW1lLCBzZXJ2aWNlLCBzaXplb2Yoc25hbWUpKTsKICAgIHN0cmxjcHkoaW5zdCwga3JiX2dldF9waG9zdChob3N0KSwgc2l6ZW9mKGluc3QpKTsKICAgIHN0cmxjcHkocmVhbG0sIGtyYl9yZWFsbW9maG9zdChob3N0KSwgc2l6ZW9mKHJlYWxtKSk7CiAgICByZXQgPSBrcmJfbWtfcmVxKGFkYXQsIHNuYW1lLCBpbnN0LCByZWFsbSwgY2hlY2tzdW0pOwogICAgaWYocmV0KQoJcmV0dXJuIHJldDsKICAgIHN0cmxjcHkoc25hbWUsIHNlcnZpY2UsIHNpemVvZihzbmFtZSkpOwogICAgc3RybGNweShpbnN0LCBrcmJfZ2V0X3Bob3N0KGhvc3QpLCBzaXplb2YoaW5zdCkpOwogICAgc3RybGNweShyZWFsbSwga3JiX3JlYWxtb2Zob3N0KGhvc3QpLCBzaXplb2YocmVhbG0pKTsKICAgIHJldCA9IGtyYl9nZXRfY3JlZChzbmFtZSwgaW5zdCwgcmVhbG0sICZjcmVkKTsKICAgIG1lbW1vdmUoJmQtPmtleSwgJmNyZWQuc2Vzc2lvbiwgc2l6ZW9mKGRlc19jYmxvY2spKTsKICAgIGRlc19rZXlfc2NoZWQoJmQtPmtleSwgZC0+c2NoZWR1bGUpOwogICAgbWVtc2V0KCZjcmVkLCAwLCBzaXplb2YoY3JlZCkpOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIGludAprcmI0X2F1dGgodm9pZCAqYXBwX2RhdGEsIHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGludCByZXQ7CiAgY2hhciAqcDsKICBpbnQgbGVuOwogIEtURVhUX1NUIGFkYXQ7CiAgTVNHX0RBVCBtc2dfZGF0YTsKICBpbnQgY2hlY2tzdW07CiAgdV9pbnQzMl90IGNzOwogIHN0cnVjdCBrcmI0X2RhdGEgKmQgPSBhcHBfZGF0YTsKICBjaGFyICpob3N0ID0gY29ubi0+aG9zdG5hbWU7CiAgc3NpemVfdCBucmVhZDsKICBpbnQgbCA9IHNpemVvZihjb25uLT5sb2NhbF9hZGRyKTsKICBzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YSA9IGNvbm4tPmRhdGE7CgogIGlmKGdldHNvY2tuYW1lKGNvbm4tPmZpcnN0c29ja2V0LAogICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHIgKilMT0NBTF9BRERSLCAmbCkgPCAwKQogICAgcGVycm9yKCJnZXRzb2NrbmFtZSgpIik7CgogIGNoZWNrc3VtID0gZ2V0cGlkKCk7CiAgcmV0ID0gbWtfYXV0aChkLCAmYWRhdCwgImZ0cCIsIGhvc3QsIGNoZWNrc3VtKTsKICBpZihyZXQgPT0gS0RDX1BSX1VOS05PV04pCiAgICByZXQgPSBta19hdXRoKGQsICZhZGF0LCAicmNtZCIsIGhvc3QsIGNoZWNrc3VtKTsKICBpZihyZXQpIHsKICAgIEN1cmxfaW5mb2YoZGF0YSwgIiVzXG4iLCBrcmJfZ2V0X2Vycl90ZXh0KHJldCkpOwogICAgcmV0dXJuIEFVVEhfQ09OVElOVUU7CiAgfQogIAojaWZkZWYgSEFWRV9LUkJfR0VUX09VUl9JUF9GT1JfUkVBTE0KICBpZiAoa3JiX2dldF9jb25maWdfYm9vbCgibmF0X2luX3VzZSIpKSB7CiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gKmxvY2FsYWRkciAgPSAoc3RydWN0IHNvY2thZGRyX2luICopTE9DQUxfQUREUjsKICAgIHN0cnVjdCBpbl9hZGRyIG5hdEFkZHI7CgogICAgaWYgKGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShrcmJfcmVhbG1vZmhvc3QoaG9zdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZuYXRBZGRyKSAhPSBLU1VDQ0VTUwogICAgICAgICYmIGtyYl9nZXRfb3VyX2lwX2Zvcl9yZWFsbShOVUxMLCAmbmF0QWRkcikgIT0gS1NVQ0NFU1MpCiAgICAgIEN1cmxfaW5mb2YoZGF0YSwgIkNhbid0IGdldCBhZGRyZXNzIGZvciByZWFsbSAlc1xuIiwKICAgICAgICAgICAgICAgICBrcmJfcmVhbG1vZmhvc3QoaG9zdCkpOwogICAgZWxzZSB7CiAgICAgIGlmIChuYXRBZGRyLnNfYWRkciAhPSBsb2NhbGFkZHItPnNpbl9hZGRyLnNfYWRkcikgewojaWZkZWYgSEFWRV9JTkVUX05UT0FfUgogICAgICAgIGNoYXIgbnRvYV9idWZbNjRdOwogICAgICAgIGNoYXIgKmlwID0gKGNoYXIgKilpbmV0X250b2FfcihuYXRBZGRyLCBudG9hX2J1Ziwgc2l6ZW9mKG50b2FfYnVmKSk7CiNlbHNlCiAgICAgICAgY2hhciAqaXAgPSAoY2hhciAqKWluZXRfbnRvYShuYXRBZGRyKTsKI2VuZGlmCiAgICAgICAgQ3VybF9pbmZvZihkYXRhLCAiVXNpbmcgTkFUIElQIGFkZHJlc3MgKCVzKSBmb3Iga2VyYmVyb3MgNFxuIiwgaXApOwogICAgICAgIGxvY2FsYWRkci0+c2luX2FkZHIgPSBuYXRBZGRyOwogICAgICB9CiAgICB9CiAgfQojZW5kaWYKCiAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKGFkYXQuZGF0LCBhZGF0Lmxlbmd0aCwgJnApIDwgMCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmciKTsKICAgIHJldHVybiBBVVRIX0NPTlRJTlVFOwogIH0KCiAgaWYoQ3VybF9mdHBzZW5kZihjb25uLCAiQURBVCAlcyIsIHApKQogICAgcmV0dXJuIC0yOwoKICBucmVhZCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoZGF0YS0+c3RhdGUuYnVmZmVyLCBjb25uLCBOVUxMKTsKICBpZihucmVhZCA8IDApCiAgICByZXR1cm4gLTE7CiAgZnJlZShwKTsKCiAgaWYoZGF0YS0+c3RhdGUuYnVmZmVyWzBdICE9ICcyJyl7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJTZXJ2ZXIgZGlkbid0IGFjY2VwdCBhdXRoIGRhdGEiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KCiAgcCA9IHN0cnN0cihkYXRhLT5zdGF0ZS5idWZmZXIsICJBREFUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGRhdGEsICJSZW1vdGUgaG9zdCBkaWRuJ3Qgc2VuZCBhZGF0IHJlcGx5Iik7CiAgICByZXR1cm4gQVVUSF9FUlJPUjsKICB9CiAgcCArPSA1OwogIGxlbiA9IEN1cmxfYmFzZTY0X2RlY29kZShwLCBhZGF0LmRhdCk7CiAgaWYobGVuIDwgMCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiRmFpbGVkIHRvIGRlY29kZSBiYXNlNjQgZnJvbSBzZXJ2ZXIiKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBhZGF0Lmxlbmd0aCA9IGxlbjsKICByZXQgPSBrcmJfcmRfc2FmZShhZGF0LmRhdCwgYWRhdC5sZW5ndGgsICZkLT5rZXksIAogICAgICAgICAgICAgICAgICAgIChzdHJ1Y3Qgc29ja2FkZHJfaW4gKiloaXNjdGxhZGRyLCAKICAgICAgICAgICAgICAgICAgICAoc3RydWN0IHNvY2thZGRyX2luICopbXljdGxhZGRyLCAmbXNnX2RhdGEpOwogIGlmKHJldCkgewogICAgQ3VybF9mYWlsZihkYXRhLCAiRXJyb3IgcmVhZGluZyByZXBseSBmcm9tIHNlcnZlcjogJXMiLCAKICAgICAgICAgICAgICAga3JiX2dldF9lcnJfdGV4dChyZXQpKTsKICAgIHJldHVybiBBVVRIX0VSUk9SOwogIH0KICBrcmJfZ2V0X2ludChtc2dfZGF0YS5hcHBfZGF0YSwgJmNzLCA0LCAwKTsKICBpZihjcyAtIGNoZWNrc3VtICE9IDEpIHsKICAgIEN1cmxfZmFpbGYoZGF0YSwgIkJhZCBjaGVja3N1bSByZXR1cm5lZCBmcm9tIHNlcnZlciIpOwogICAgcmV0dXJuIEFVVEhfRVJST1I7CiAgfQogIHJldHVybiBBVVRIX09LOwp9CgpzdHJ1Y3QgQ3VybF9zZWNfY2xpZW50X21lY2ggQ3VybF9rcmI0X2NsaWVudF9tZWNoID0gewogICAgIktFUkJFUk9TX1Y0IiwKICAgIHNpemVvZihzdHJ1Y3Qga3JiNF9kYXRhKSwKICAgIE5VTEwsIC8qIGluaXQgKi8KICAgIGtyYjRfYXV0aCwKICAgIE5VTEwsIC8qIGVuZCAqLwogICAga3JiNF9jaGVja19wcm90LAogICAga3JiNF9vdmVyaGVhZCwKICAgIGtyYjRfZW5jb2RlLAogICAga3JiNF9kZWNvZGUKfTsKCnZvaWQgQ3VybF9rcmJfa2F1dGgoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgZGVzX2NibG9jayBrZXk7CiAgZGVzX2tleV9zY2hlZHVsZSBzY2hlZHVsZTsKICBLVEVYVF9TVCB0a3QsIHRrdGNvcHk7CiAgY2hhciAqbmFtZTsKICBjaGFyICpwOwogIGNoYXIgcGFzc3dkWzEwMF07CiAgaW50IHRtcDsKICBzc2l6ZV90IG5yZWFkOwoJCiAgaW50IHNhdmU7CgogIHNhdmUgPSBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgcHJvdF9wcml2YXRlKTsKCiAgaWYoQ3VybF9mdHBzZW5kZihjb25uLCAiU0lURSBLQVVUSCAlcyIsIGNvbm4tPmRhdGEtPnN0YXRlLnVzZXIpKQogICAgcmV0dXJuOwoKICBucmVhZCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLCBOVUxMKTsKICBpZihucmVhZCA8IDApCiAgICByZXR1cm4gLypDVVJMRV9PUEVSQVRJT05fVElNRU9VVEVEKi87CgogIGlmKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMycpewogICAgQ3VybF9zZXRfY29tbWFuZF9wcm90KGNvbm4sIHNhdmUpOwogICAgcmV0dXJuOwogIH0KCiAgcCA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJUPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJCYWQgcmVwbHkgZnJvbSBzZXJ2ZXIiKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybjsKICB9CgogIHAgKz0gMjsKICB0bXAgPSBDdXJsX2Jhc2U2NF9kZWNvZGUocCwgJnRrdC5kYXQpOwogIGlmKHRtcCA8IDApIHsKICAgIEN1cmxfZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBkZWNvZGUgYmFzZTY0IGluIHJlcGx5LlxuIik7CiAgICBDdXJsX3NldF9jb21tYW5kX3Byb3QoY29ubiwgc2F2ZSk7CiAgICByZXR1cm47CiAgfQogIHRrdC5sZW5ndGggPSB0bXA7CiAgdGt0Y29weS5sZW5ndGggPSB0a3QubGVuZ3RoOwogICAgCiAgcCA9IHN0cnN0cihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsICJQPSIpOwogIGlmKCFwKSB7CiAgICBDdXJsX2ZhaWxmKGNvbm4tPmRhdGEsICJCYWQgcmVwbHkgZnJvbSBzZXJ2ZXIiKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybjsKICB9CiAgbmFtZSA9IHAgKyAyOwogIGZvcig7ICpwICYmICpwICE9ICcgJyAmJiAqcCAhPSAnXHInICYmICpwICE9ICdcbic7IHArKyk7CiAgKnAgPSAwOwoKICBkZXNfc3RyaW5nX3RvX2tleSAoY29ubi0+ZGF0YS0+c3RhdGUucGFzc3dkLCAma2V5KTsKICBkZXNfa2V5X3NjaGVkKCZrZXksIHNjaGVkdWxlKTsKICAgIAogIGRlc19wY2JjX2VuY3J5cHQoKGRlc19jYmxvY2sqKXRrdC5kYXQsIChkZXNfY2Jsb2NrKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgIHRrdC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICBzY2hlZHVsZSwgJmtleSwgREVTX0RFQ1JZUFQpOwogIGlmIChzdHJjbXAgKChjaGFyKil0a3Rjb3B5LmRhdCArIDgsCiAgICAgICAgICAgICAgS1JCX1RJQ0tFVF9HUkFOVElOR19USUNLRVQpICE9IDApIHsKICAgIGFmc19zdHJpbmdfdG9fa2V5IChwYXNzd2QsCiAgICAgICAgICAgICAgICAgICAgICAga3JiX3JlYWxtb2Zob3N0KGNvbm4tPmhvc3RuYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAma2V5KTsKICAgIGRlc19rZXlfc2NoZWQgKCZrZXksIHNjaGVkdWxlKTsKICAgIGRlc19wY2JjX2VuY3J5cHQoKGRlc19jYmxvY2sqKXRrdC5kYXQsIChkZXNfY2Jsb2NrKil0a3Rjb3B5LmRhdCwKICAgICAgICAgICAgICAgICAgICAgdGt0Lmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGUsICZrZXksIERFU19ERUNSWVBUKTsKICB9CiAgbWVtc2V0KGtleSwgMCwgc2l6ZW9mKGtleSkpOwogIG1lbXNldChzY2hlZHVsZSwgMCwgc2l6ZW9mKHNjaGVkdWxlKSk7CiAgbWVtc2V0KHBhc3N3ZCwgMCwgc2l6ZW9mKHBhc3N3ZCkpOwogIGlmKEN1cmxfYmFzZTY0X2VuY29kZSh0a3Rjb3B5LmRhdCwgdGt0Y29weS5sZW5ndGgsICZwKSA8IDApIHsKICAgIGZhaWxmKGNvbm4tPmRhdGEsICJPdXQgb2YgbWVtb3J5IGJhc2U2NC1lbmNvZGluZy4iKTsKICAgIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKICAgIHJldHVybjsKICB9CiAgbWVtc2V0ICh0a3Rjb3B5LmRhdCwgMCwgdGt0Y29weS5sZW5ndGgpOwoKICBpZihDdXJsX2Z0cHNlbmRmKGNvbm4sICJTSVRFIEtBVVRIICVzICVzIiwgbmFtZSwgcCkpCiAgICByZXR1cm47CgogIG5yZWFkID0gQ3VybF9HZXRGVFBSZXNwb25zZShjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4sIE5VTEwpOwogIGlmKG5yZWFkIDwgMCkKICAgIHJldHVybiAvKkNVUkxFX09QRVJBVElPTl9USU1FT1VURUQqLzsKICBmcmVlKHApOwogIEN1cmxfc2V0X2NvbW1hbmRfcHJvdChjb25uLCBzYXZlKTsKfQoKI2VuZGlmIC8qIEtSQjQgKi8KI2VuZGlmIC8qIENVUkxfRElTQUJMRV9GVFAgKi8KCi8qCiAqIGxvY2FsIHZhcmlhYmxlczoKICogZXZhbDogKGxvYWQtZmlsZSAiLi4vY3VybC1tb2RlLmVsIikKICogZW5kOgogKiB2aW02MDA6IGZkbT1tYXJrZXIKICogdmltOiBldCBzdz0yIHRzPTIgc3RzPTIgdHc9NzgKICovCg==