LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKiAKICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogKiAKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAKICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgSW5zdGl0dXRlIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBJTlNUSVRVVEUgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBJTlNUSVRVVEUgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUwogKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKICogSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLiAgKi8KCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmZGVmIEtSQjQKCiNkZWZpbmUgX01QUklOVEZfUkVQTEFDRSAvKiB3ZSB3YW50IGN1cmwtZnVuY3Rpb25zIGluc3RlYWQgb2YgbmF0aXZlIG9uZXMgKi8KI2luY2x1ZGUgPGN1cmwvbXByaW50Zi5oPgoKI2luY2x1ZGUgInNlY3VyaXR5LmgiCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8bmV0ZGIuaD4KCiNpZmRlZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCgojaW5jbHVkZSAiYmFzZTY0LmgiCiNpbmNsdWRlICJzZW5kZi5oIgojaW5jbHVkZSAiZnRwLmgiCgovKiBUaGUgbGFzdCAjaW5jbHVkZSBmaWxlIHNob3VsZCBiZTogKi8KI2lmZGVmIE1BTExPQ0RFQlVHCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgojZW5kaWYKCiNkZWZpbmUgbWluKGEsIGIpICAgKChhKSA8IChiKSA/IChhKSA6IChiKSkKCnN0YXRpYyBzdHJ1Y3QgewogICAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsOwogICAgY29uc3QgY2hhciAqbmFtZTsKfSBsZXZlbF9uYW1lc1tdID0gewogICAgeyBwcm90X2NsZWFyLCAiY2xlYXIiIH0sCiAgICB7IHByb3Rfc2FmZSwgInNhZmUiIH0sCiAgICB7IHByb3RfY29uZmlkZW50aWFsLCAiY29uZmlkZW50aWFsIiB9LAogICAgeyBwcm90X3ByaXZhdGUsICJwcml2YXRlIiB9Cn07CgpzdGF0aWMgZW51bSBwcm90ZWN0aW9uX2xldmVsIApuYW1lX3RvX2xldmVsKGNvbnN0IGNoYXIgKm5hbWUpCnsKICBpbnQgaTsKICBmb3IoaSA9IDA7IGkgPCAoaW50KXNpemVvZihsZXZlbF9uYW1lcykvKGludClzaXplb2YobGV2ZWxfbmFtZXNbMF0pOyBpKyspCiAgICBpZighc3RybmNhc2VjbXAobGV2ZWxfbmFtZXNbaV0ubmFtZSwgbmFtZSwgc3RybGVuKG5hbWUpKSkKICAgICAgcmV0dXJuIGxldmVsX25hbWVzW2ldLmxldmVsOwogIHJldHVybiAoZW51bSBwcm90ZWN0aW9uX2xldmVsKS0xOwp9CgpzdGF0aWMgc3RydWN0IEN1cmxfc2VjX2NsaWVudF9tZWNoICptZWNoc1tdID0gewojaWZkZWYgS1JCNQogIC8qIG5vdCBzdXBwb3J0ZWQgKi8KI2VuZGlmCiNpZmRlZiBLUkI0CiAgICAmQ3VybF9rcmI0X2NsaWVudF9tZWNoLAojZW5kaWYKICAgIE5VTEwKfTsKCmludApDdXJsX3NlY19nZXRjKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgRklMRSAqRikKewogIGlmKGNvbm4tPnNlY19jb21wbGV0ZSAmJiBjb25uLT5kYXRhX3Byb3QpIHsKICAgIGNoYXIgYzsKICAgIGlmKEN1cmxfc2VjX3JlYWQoY29ubiwgZmlsZW5vKEYpLCAmYywgMSkgPD0gMCkKICAgICAgcmV0dXJuIEVPRjsKICAgIHJldHVybiBjOwogIH0KICBlbHNlCiAgICByZXR1cm4gZ2V0YyhGKTsKfQoKc3RhdGljIGludApibG9ja19yZWFkKGludCBmZCwgdm9pZCAqYnVmLCBzaXplX3QgbGVuKQp7CiAgdW5zaWduZWQgY2hhciAqcCA9IGJ1ZjsKICBpbnQgYjsKICB3aGlsZShsZW4pIHsKICAgIGIgPSByZWFkKGZkLCBwLCBsZW4pOwogICAgaWYgKGIgPT0gMCkKICAgICAgcmV0dXJuIDA7CiAgICBlbHNlIGlmIChiIDwgMCkKICAgICAgcmV0dXJuIC0xOwogICAgbGVuIC09IGI7CiAgICBwICs9IGI7CiAgfQogIHJldHVybiBwIC0gKHVuc2lnbmVkIGNoYXIqKWJ1ZjsKfQoKc3RhdGljIGludApibG9ja193cml0ZShpbnQgZmQsIHZvaWQgKmJ1Ziwgc2l6ZV90IGxlbikKewogIHVuc2lnbmVkIGNoYXIgKnAgPSBidWY7CiAgaW50IGI7CiAgd2hpbGUobGVuKSB7CiAgICBiID0gd3JpdGUoZmQsIHAsIGxlbik7CiAgICBpZihiIDwgMCkKICAgICAgcmV0dXJuIC0xOwogICAgbGVuIC09IGI7CiAgICBwICs9IGI7CiAgfQogIHJldHVybiBwIC0gKHVuc2lnbmVkIGNoYXIqKWJ1ZjsKfQoKc3RhdGljIGludApzZWNfZ2V0X2RhdGEoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLAogICAgICAgICAgICAgaW50IGZkLCBzdHJ1Y3Qga3JiNGJ1ZmZlciAqYnVmKQp7CiAgaW50IGxlbjsKICBpbnQgYjsKICAKICBiID0gYmxvY2tfcmVhZChmZCwgJmxlbiwgc2l6ZW9mKGxlbikpOwogIGlmIChiID09IDApCiAgICByZXR1cm4gMDsKICBlbHNlIGlmIChiIDwgMCkKICAgIHJldHVybiAtMTsKICBsZW4gPSBudG9obChsZW4pOwogIGJ1Zi0+ZGF0YSA9IHJlYWxsb2MoYnVmLT5kYXRhLCBsZW4pOwogIGIgPSBibG9ja19yZWFkKGZkLCBidWYtPmRhdGEsIGxlbik7CiAgaWYgKGIgPT0gMCkKICAgIHJldHVybiAwOwogIGVsc2UgaWYgKGIgPCAwKQogICAgcmV0dXJuIC0xOwogIGJ1Zi0+c2l6ZSA9IChjb25uLT5tZWNoLT5kZWNvZGUpKGNvbm4tPmFwcF9kYXRhLCBidWYtPmRhdGEsIGxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5kYXRhX3Byb3QsIGNvbm4pOwogIGJ1Zi0+aW5kZXggPSAwOwogIHJldHVybiAwOwp9CgpzdGF0aWMgc2l6ZV90CmJ1ZmZlcl9yZWFkKHN0cnVjdCBrcmI0YnVmZmVyICpidWYsIHZvaWQgKmRhdGEsIHNpemVfdCBsZW4pCnsKICAgIGxlbiA9IG1pbihsZW4sIGJ1Zi0+c2l6ZSAtIGJ1Zi0+aW5kZXgpOwogICAgbWVtY3B5KGRhdGEsIChjaGFyKilidWYtPmRhdGEgKyBidWYtPmluZGV4LCBsZW4pOwogICAgYnVmLT5pbmRleCArPSBsZW47CiAgICByZXR1cm4gbGVuOwp9CgpzdGF0aWMgc2l6ZV90CmJ1ZmZlcl93cml0ZShzdHJ1Y3Qga3JiNGJ1ZmZlciAqYnVmLCB2b2lkICpkYXRhLCBzaXplX3QgbGVuKQp7CiAgICBpZihidWYtPmluZGV4ICsgbGVuID4gYnVmLT5zaXplKSB7Cgl2b2lkICp0bXA7CglpZihidWYtPmRhdGEgPT0gTlVMTCkKCSAgICB0bXAgPSBtYWxsb2MoMTAyNCk7CgllbHNlCgkgICAgdG1wID0gcmVhbGxvYyhidWYtPmRhdGEsIGJ1Zi0+aW5kZXggKyBsZW4pOwoJaWYodG1wID09IE5VTEwpCgkgICAgcmV0dXJuIC0xOwoJYnVmLT5kYXRhID0gdG1wOwoJYnVmLT5zaXplID0gYnVmLT5pbmRleCArIGxlbjsKICAgIH0KICAgIG1lbWNweSgoY2hhciopYnVmLT5kYXRhICsgYnVmLT5pbmRleCwgZGF0YSwgbGVuKTsKICAgIGJ1Zi0+aW5kZXggKz0gbGVuOwogICAgcmV0dXJuIGxlbjsKfQoKaW50CkN1cmxfc2VjX3JlYWQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgZmQsIHZvaWQgKmJ1ZmZlciwgaW50IGxlbmd0aCkKewogICAgc2l6ZV90IGxlbjsKICAgIGludCByeCA9IDA7CgogICAgaWYoY29ubi0+c2VjX2NvbXBsZXRlID09IDAgfHwgY29ubi0+ZGF0YV9wcm90ID09IDApCiAgICAgIHJldHVybiByZWFkKGZkLCBidWZmZXIsIGxlbmd0aCk7CgogICAgaWYoY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnKXsKICAgICAgY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnID0gMDsKICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICAKICAgIGxlbiA9IGJ1ZmZlcl9yZWFkKCZjb25uLT5pbl9idWZmZXIsIGJ1ZmZlciwgbGVuZ3RoKTsKICAgIGxlbmd0aCAtPSBsZW47CiAgICByeCArPSBsZW47CiAgICBidWZmZXIgPSAoY2hhciopYnVmZmVyICsgbGVuOwogICAgCiAgICB3aGlsZShsZW5ndGgpIHsKICAgICAgaWYoc2VjX2dldF9kYXRhKGNvbm4sIGZkLCAmY29ubi0+aW5fYnVmZmVyKSA8IDApCiAgICAgICAgcmV0dXJuIC0xOwogICAgICBpZihjb25uLT5pbl9idWZmZXIuc2l6ZSA9PSAwKSB7CiAgICAgICAgaWYocngpCiAgICAgICAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAxOwogICAgICAgIHJldHVybiByeDsKICAgICAgfQogICAgICBsZW4gPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbmd0aCk7CiAgICAgIGxlbmd0aCAtPSBsZW47CiAgICAgIHJ4ICs9IGxlbjsKICAgICAgYnVmZmVyID0gKGNoYXIqKWJ1ZmZlciArIGxlbjsKICAgIH0KICAgIHJldHVybiByeDsKfQoKc3RhdGljIGludApzZWNfc2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBmZCwgY2hhciAqZnJvbSwgaW50IGxlbmd0aCkKewogIGludCBieXRlczsKICB2b2lkICpidWY7CiAgYnl0ZXMgPSAoY29ubi0+bWVjaC0+ZW5jb2RlKShjb25uLT5hcHBfZGF0YSwgZnJvbSwgbGVuZ3RoLCBjb25uLT5kYXRhX3Byb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYnVmLCBjb25uKTsKICBieXRlcyA9IGh0b25sKGJ5dGVzKTsKICBibG9ja193cml0ZShmZCwgJmJ5dGVzLCBzaXplb2YoYnl0ZXMpKTsKICBibG9ja193cml0ZShmZCwgYnVmLCBudG9obChieXRlcykpOwogIGZyZWUoYnVmKTsKICByZXR1cm4gbGVuZ3RoOwp9CgppbnQKQ3VybF9zZWNfZmZsdXNoX2ZkKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IGZkKQp7CiAgaWYoY29ubi0+ZGF0YV9wcm90ICE9IHByb3RfY2xlYXIpIHsKICAgIGlmKGNvbm4tPm91dF9idWZmZXIuaW5kZXggPiAwKXsKICAgICAgQ3VybF9zZWNfd3JpdGUoY29ubiwgZmQsCiAgICAgICAgICAgICAgICBjb25uLT5vdXRfYnVmZmVyLmRhdGEsIGNvbm4tPm91dF9idWZmZXIuaW5kZXgpOwogICAgICBjb25uLT5vdXRfYnVmZmVyLmluZGV4ID0gMDsKICAgIH0KICAgIHNlY19zZW5kKGNvbm4sIGZkLCBOVUxMLCAwKTsKICB9CiAgcmV0dXJuIDA7Cn0KCmludApDdXJsX3NlY193cml0ZShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBmZCwgY2hhciAqYnVmZmVyLCBpbnQgbGVuZ3RoKQp7CiAgaW50IGxlbiA9IGNvbm4tPmJ1ZmZlcl9zaXplOwogIGludCB0eCA9IDA7CiAgICAgIAogIGlmKGNvbm4tPmRhdGFfcHJvdCA9PSBwcm90X2NsZWFyKQogICAgcmV0dXJuIHdyaXRlKGZkLCBidWZmZXIsIGxlbmd0aCk7CgogIGxlbiAtPSAoY29ubi0+bWVjaC0+b3ZlcmhlYWQpKGNvbm4tPmFwcF9kYXRhLCBjb25uLT5kYXRhX3Byb3QsIGxlbik7CiAgd2hpbGUobGVuZ3RoKXsKICAgIGlmKGxlbmd0aCA8IGxlbikKICAgICAgbGVuID0gbGVuZ3RoOwogICAgc2VjX3NlbmQoY29ubiwgZmQsIGJ1ZmZlciwgbGVuKTsKICAgIGxlbmd0aCAtPSBsZW47CiAgICBidWZmZXIgKz0gbGVuOwogICAgdHggKz0gbGVuOwogIH0KICByZXR1cm4gdHg7Cn0KCmludApDdXJsX3NlY192ZnByaW50ZjIoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBGSUxFICpmLCBjb25zdCBjaGFyICpmbXQsIHZhX2xpc3QgYXApCnsKICBjaGFyICpidWY7CiAgaW50IHJldDsKICBpZihjb25uLT5kYXRhX3Byb3QgPT0gcHJvdF9jbGVhcikKICAgIHJldHVybiB2ZnByaW50ZihmLCBmbXQsIGFwKTsKICBlbHNlIHsKICAgIGJ1ZiA9IGFwcmludGYoZm10LCBhcCk7CiAgICByZXQgPSBidWZmZXJfd3JpdGUoJmNvbm4tPm91dF9idWZmZXIsIGJ1Ziwgc3RybGVuKGJ1ZikpOwogICAgZnJlZShidWYpOwogICAgcmV0dXJuIHJldDsKICB9Cn0KCmludApDdXJsX3NlY19mcHJpbnRmMihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIEZJTEUgKmYsIGNvbnN0IGNoYXIgKmZtdCwgLi4uKQp7CiAgICBpbnQgcmV0OwogICAgdmFfbGlzdCBhcDsKICAgIHZhX3N0YXJ0KGFwLCBmbXQpOwogICAgcmV0ID0gQ3VybF9zZWNfdmZwcmludGYyKGNvbm4sIGYsIGZtdCwgYXApOwogICAgdmFfZW5kKGFwKTsKICAgIHJldHVybiByZXQ7Cn0KCmludApDdXJsX3NlY19wdXRjKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IGMsIEZJTEUgKkYpCnsKICBjaGFyIGNoID0gYzsKICBpZihjb25uLT5kYXRhX3Byb3QgPT0gcHJvdF9jbGVhcikKICAgIHJldHVybiBwdXRjKGMsIEYpOwogICAgCiAgYnVmZmVyX3dyaXRlKCZjb25uLT5vdXRfYnVmZmVyLCAmY2gsIDEpOwogIGlmKGMgPT0gJ1xuJyB8fCBjb25uLT5vdXRfYnVmZmVyLmluZGV4ID49IDEwMjQgLyogWFhYICovKSB7CiAgICBDdXJsX3NlY193cml0ZShjb25uLCBmaWxlbm8oRiksIGNvbm4tPm91dF9idWZmZXIuZGF0YSwgY29ubi0+b3V0X2J1ZmZlci5pbmRleCk7CiAgICBjb25uLT5vdXRfYnVmZmVyLmluZGV4ID0gMDsKICB9CiAgcmV0dXJuIGM7Cn0KCmludApDdXJsX3NlY19yZWFkX21zZyhzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNoYXIgKnMsIGludCBsZXZlbCkKewogICAgaW50IGxlbjsKICAgIGNoYXIgKmJ1ZjsKICAgIGludCBjb2RlOwogICAgCiAgICBidWYgPSBtYWxsb2Moc3RybGVuKHMpKTsKICAgIGxlbiA9IEN1cmxfYmFzZTY0X2RlY29kZShzICsgNCwgYnVmKTsgLyogWFhYICovCiAgICAKICAgIGxlbiA9IChjb25uLT5tZWNoLT5kZWNvZGUpKGNvbm4tPmFwcF9kYXRhLCBidWYsIGxlbiwgbGV2ZWwsIGNvbm4pOwogICAgaWYobGVuIDwgMCkKCXJldHVybiAtMTsKICAgIAogICAgYnVmW2xlbl0gPSAnXDAnOwoKICAgIGlmKGJ1ZlszXSA9PSAnLScpCgljb2RlID0gMDsKICAgIGVsc2UKCXNzY2FuZihidWYsICIlZCIsICZjb2RlKTsKICAgIGlmKGJ1ZltsZW4tMV0gPT0gJ1xuJykKCWJ1ZltsZW4tMV0gPSAnXDAnOwogICAgc3RyY3B5KHMsIGJ1Zik7CiAgICBmcmVlKGJ1Zik7CiAgICByZXR1cm4gY29kZTsKfQoKLyogbW9kaWZpZWQgdG8gcmV0dXJuIGhvdyBtYW55IGJ5dGVzIHdyaXR0ZW4sIG9yIC0xIG9uIGVycm9yICoqKi8KaW50CkN1cmxfc2VjX3ZmcHJpbnRmKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgRklMRSAqZiwgY29uc3QgY2hhciAqZm10LCB2YV9saXN0IGFwKQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIGNoYXIgKmJ1ZjsKICAgIHZvaWQgKmVuYzsKICAgIGludCBsZW47CiAgICBpZighY29ubi0+c2VjX2NvbXBsZXRlKQoJcmV0dXJuIHZmcHJpbnRmKGYsIGZtdCwgYXApOwogICAgCiAgICBidWYgPSBhcHJpbnRmKGZtdCwgYXApOwogICAgbGVuID0gKGNvbm4tPm1lY2gtPmVuY29kZSkoY29ubi0+YXBwX2RhdGEsIGJ1Ziwgc3RybGVuKGJ1ZiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5jb21tYW5kX3Byb3QsICZlbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uKTsKICAgIGZyZWUoYnVmKTsKICAgIGlmKGxlbiA8IDApIHsKCWZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gZW5jb2RlIGNvbW1hbmQuIik7CglyZXR1cm4gLTE7CiAgICB9CiAgICBpZihDdXJsX2Jhc2U2NF9lbmNvZGUoZW5jLCBsZW4sICZidWYpIDwgMCl7CiAgICAgIGZhaWxmKGNvbm4tPmRhdGEsICJPdXQgb2YgbWVtb3J5IGJhc2U2NC1lbmNvZGluZy4iKTsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgaWYoY29ubi0+Y29tbWFuZF9wcm90ID09IHByb3Rfc2FmZSkKCXJldCA9IGZwcmludGYoZiwgIk1JQyAlcyIsIGJ1Zik7CiAgICBlbHNlIGlmKGNvbm4tPmNvbW1hbmRfcHJvdCA9PSBwcm90X3ByaXZhdGUpCglyZXQgPSBmcHJpbnRmKGYsICJFTkMgJXMiLCBidWYpOwogICAgZWxzZSBpZihjb25uLT5jb21tYW5kX3Byb3QgPT0gcHJvdF9jb25maWRlbnRpYWwpCglyZXQgPSBmcHJpbnRmKGYsICJDT05GICVzIiwgYnVmKTsKCiAgICBmcmVlKGJ1Zik7CiAgICByZXR1cm4gcmV0Owp9CgppbnQKQ3VybF9zZWNfZnByaW50ZihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIEZJTEUgKmYsIGNvbnN0IGNoYXIgKmZtdCwgLi4uKQp7CiAgICB2YV9saXN0IGFwOwogICAgaW50IHJldDsKICAgIHZhX3N0YXJ0KGFwLCBmbXQpOwogICAgcmV0ID0gQ3VybF9zZWNfdmZwcmludGYoY29ubiwgZiwgZm10LCBhcCk7CiAgICB2YV9lbmQoYXApOwogICAgcmV0dXJuIHJldDsKfQoKCmVudW0gcHJvdGVjdGlvbl9sZXZlbApDdXJsX3NldF9jb21tYW5kX3Byb3Qoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgbGV2ZWwpCnsKICAgIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBvbGQgPSBjb25uLT5jb21tYW5kX3Byb3Q7CiAgICBjb25uLT5jb21tYW5kX3Byb3QgPSBsZXZlbDsKICAgIHJldHVybiBvbGQ7Cn0KCnN0YXRpYyBpbnQKc2VjX3Byb3RfaW50ZXJuYWwoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgbGV2ZWwpCnsKICBjaGFyICpwOwogIHVuc2lnbmVkIGludCBzID0gMTA0ODU3NjsKICBzc2l6ZV90IG5yZWFkOwoKICBpZighY29ubi0+c2VjX2NvbXBsZXRlKXsKICAgIGluZm9mKGNvbm4tPmRhdGEsICJObyBzZWN1cml0eSBkYXRhIGV4Y2hhbmdlIGhhcyB0YWtlbiBwbGFjZS5cbiIpOwogICAgcmV0dXJuIC0xOwogIH0KCiAgaWYobGV2ZWwpewogICAgaWYoQ3VybF9mdHBzZW5kZihjb25uLCAiUEJTWiAldSIsIHMpKQogICAgICByZXR1cm4gLTE7CgogICAgbnJlYWQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgY29ubiwgTlVMTCk7CiAgICBpZihucmVhZCA8IDApCiAgICAgIHJldHVybiAtMTsKCiAgICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzInKXsKICAgICAgZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBzZXQgcHJvdGVjdGlvbiBidWZmZXIgc2l6ZS4iKTsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgY29ubi0+YnVmZmVyX3NpemUgPSBzOwoKICAgIHAgPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiUEJTWj0iKTsKICAgIGlmKHApCiAgICAgIHNzY2FuZihwLCAiUEJTWj0ldSIsICZzKTsKICAgIGlmKHMgPCBjb25uLT5idWZmZXJfc2l6ZSkKICAgICAgY29ubi0+YnVmZmVyX3NpemUgPSBzOwogIH0KCiAgaWYoQ3VybF9mdHBzZW5kZihjb25uLCAiUFJPVCAlYyIsIGxldmVsWyJDU0VQIl0pKQogICAgcmV0dXJuIC0xOwoKICBucmVhZCA9IEN1cmxfR2V0RlRQUmVzcG9uc2UoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCBjb25uLCBOVUxMKTsKICBpZihucmVhZCA8IDApCiAgICByZXR1cm4gLTE7CgogIGlmKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMicpewogICAgZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBzZXQgcHJvdGVjdGlvbiBsZXZlbC4iKTsKICAgIHJldHVybiAtMTsKICB9CiAgICAKICBjb25uLT5kYXRhX3Byb3QgPSAoZW51bSBwcm90ZWN0aW9uX2xldmVsKWxldmVsOwogIHJldHVybiAwOwp9Cgp2b2lkCkN1cmxfc2VjX3NldF9wcm90ZWN0aW9uX2xldmVsKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGlmKGNvbm4tPnNlY19jb21wbGV0ZSAmJiBjb25uLT5kYXRhX3Byb3QgIT0gY29ubi0+cmVxdWVzdF9kYXRhX3Byb3QpCiAgICBzZWNfcHJvdF9pbnRlcm5hbChjb25uLCBjb25uLT5yZXF1ZXN0X2RhdGFfcHJvdCk7Cn0KCgppbnQKQ3VybF9zZWNfcmVxdWVzdF9wcm90KHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY29uc3QgY2hhciAqbGV2ZWwpCnsKICBpbnQgbCA9IG5hbWVfdG9fbGV2ZWwobGV2ZWwpOwogIGlmKGwgPT0gLTEpCiAgICByZXR1cm4gLTE7CiAgY29ubi0+cmVxdWVzdF9kYXRhX3Byb3QgPSAoZW51bSBwcm90ZWN0aW9uX2xldmVsKWw7CiAgcmV0dXJuIDA7Cn0KCmludApDdXJsX3NlY19sb2dpbihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgcmV0OwogIHN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCAqKm07CiAgc3NpemVfdCBucmVhZDsKICBzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YT1jb25uLT5kYXRhOwogIGludCBmdHBjb2RlOwoKICBmb3IobSA9IG1lY2hzOyAqbSAmJiAoKm0pLT5uYW1lOyBtKyspIHsKICAgIHZvaWQgKnRtcDsKCiAgICB0bXAgPSByZWFsbG9jKGNvbm4tPmFwcF9kYXRhLCAoKm0pLT5zaXplKTsKICAgIGlmICh0bXAgPT0gTlVMTCkgewogICAgICBmYWlsZiAoZGF0YSwgInJlYWxsb2MgJXUgZmFpbGVkIiwgKCptKS0+c2l6ZSk7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGNvbm4tPmFwcF9kYXRhID0gdG1wOwoJICAgIAogICAgaWYoKCptKS0+aW5pdCAmJiAoKigqbSktPmluaXQpKGNvbm4tPmFwcF9kYXRhKSAhPSAwKSB7CiAgICAgIGluZm9mKGRhdGEsICJTa2lwcGluZyAlcy4uLlxuIiwgKCptKS0+bmFtZSk7CiAgICAgIGNvbnRpbnVlOwogICAgfQogICAgaW5mb2YoZGF0YSwgIlRyeWluZyAlcy4uLlxuIiwgKCptKS0+bmFtZSk7CgogICAgaWYoQ3VybF9mdHBzZW5kZihjb25uLCAiQVVUSCAlcyIsICgqbSktPm5hbWUpKQogICAgICByZXR1cm4gLTE7CgogICAgbnJlYWQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgY29ubiwgJmZ0cGNvZGUpOwogICAgaWYobnJlYWQgPCAwKQogICAgICByZXR1cm4gLTE7CgogICAgaWYoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyWzBdICE9ICczJyl7CiAgICAgIHN3aXRjaChmdHBjb2RlKSB7CiAgICAgIGNhc2UgNTA0OgogICAgICAgIGluZm9mKGRhdGEsCiAgICAgICAgICAgICAgIiVzIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlci5cbiIsICgqbSktPm5hbWUpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDUzNDoKICAgICAgICBpbmZvZihkYXRhLCAiJXMgcmVqZWN0ZWQgYXMgc2VjdXJpdHkgbWVjaGFuaXNtLlxuIiwgKCptKS0+bmFtZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgaWYoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyWzBdID09ICc1JykgewogICAgICAgICAgaW5mb2YoZGF0YSwgIlRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZSBGVFAgIgogICAgICAgICAgICAgICAgInNlY3VyaXR5IGV4dGVuc2lvbnMuXG4iKTsKICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY29udGludWU7CiAgICB9CgogICAgcmV0ID0gKCooKm0pLT5hdXRoKShjb25uLT5hcHBfZGF0YSwgY29ubik7CgkKICAgIGlmKHJldCA9PSBBVVRIX0NPTlRJTlVFKQogICAgICBjb250aW51ZTsKICAgIGVsc2UgaWYocmV0ICE9IEFVVEhfT0spewogICAgICAvKiBtZWNoYW5pc20gaXMgc3VwcG9zZWQgdG8gb3V0cHV0IGVycm9yIHN0cmluZyAqLwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBjb25uLT5tZWNoID0gKm07CiAgICBjb25uLT5zZWNfY29tcGxldGUgPSAxOwogICAgY29ubi0+Y29tbWFuZF9wcm90ID0gcHJvdF9zYWZlOwogICAgYnJlYWs7CiAgfQogICAgCiAgcmV0dXJuICptID09IE5VTEw7Cn0KCnZvaWQKQ3VybF9zZWNfZW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGlmIChjb25uLT5tZWNoICE9IE5VTEwpIHsKICAgIGlmKGNvbm4tPm1lY2gtPmVuZCkKICAgICAgKGNvbm4tPm1lY2gtPmVuZCkoY29ubi0+YXBwX2RhdGEpOwogICAgbWVtc2V0KGNvbm4tPmFwcF9kYXRhLCAwLCBjb25uLT5tZWNoLT5zaXplKTsKICAgIGZyZWUoY29ubi0+YXBwX2RhdGEpOwogICAgY29ubi0+YXBwX2RhdGEgPSBOVUxMOwogIH0KICBjb25uLT5zZWNfY29tcGxldGUgPSAwOwogIGNvbm4tPmRhdGFfcHJvdCA9IChlbnVtIHByb3RlY3Rpb25fbGV2ZWwpMDsKICBjb25uLT5tZWNoPU5VTEw7Cn0KCiNlbmRpZiAvKiBLUkI0ICovCgovKgogKiBsb2NhbCB2YXJpYWJsZXM6CiAqIGV2YWw6IChsb2FkLWZpbGUgIi4uL2N1cmwtbW9kZS5lbCIpCiAqIGVuZDoKICogdmltNjAwOiBmZG09bWFya2VyCiAqIHZpbTogZXQgc3c9MiB0cz0yIHN0cz0yIHR3PTc4CiAqLwo=