LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKiAKICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogKiAKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAKICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgSW5zdGl0dXRlIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBJTlNUSVRVVEUgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBJTlNUSVRVVEUgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUwogKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKICogSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLiAgKi8KCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmZGVmIEtSQjQKCiNkZWZpbmUgX01QUklOVEZfUkVQTEFDRSAvKiB3ZSB3YW50IGN1cmwtZnVuY3Rpb25zIGluc3RlYWQgb2YgbmF0aXZlIG9uZXMgKi8KI2luY2x1ZGUgPGN1cmwvbXByaW50Zi5oPgoKI2luY2x1ZGUgInNlY3VyaXR5LmgiCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8bmV0ZGIuaD4KCiNpZmRlZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCgojaW5jbHVkZSAiYmFzZTY0LmgiCiNpbmNsdWRlICJzZW5kZi5oIgojaW5jbHVkZSAiZnRwLmgiCgovKiBUaGUgbGFzdCAjaW5jbHVkZSBmaWxlIHNob3VsZCBiZTogKi8KI2lmZGVmIE1BTExPQ0RFQlVHCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgojZW5kaWYKCiNkZWZpbmUgbWluKGEsIGIpICAgKChhKSA8IChiKSA/IChhKSA6IChiKSkKCnN0YXRpYyBzdHJ1Y3QgewogICAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsOwogICAgY29uc3QgY2hhciAqbmFtZTsKfSBsZXZlbF9uYW1lc1tdID0gewogICAgeyBwcm90X2NsZWFyLCAiY2xlYXIiIH0sCiAgICB7IHByb3Rfc2FmZSwgInNhZmUiIH0sCiAgICB7IHByb3RfY29uZmlkZW50aWFsLCAiY29uZmlkZW50aWFsIiB9LAogICAgeyBwcm90X3ByaXZhdGUsICJwcml2YXRlIiB9Cn07CgpzdGF0aWMgZW51bSBwcm90ZWN0aW9uX2xldmVsIApuYW1lX3RvX2xldmVsKGNvbnN0IGNoYXIgKm5hbWUpCnsKICBpbnQgaTsKICBmb3IoaSA9IDA7IGkgPCAoaW50KXNpemVvZihsZXZlbF9uYW1lcykvKGludClzaXplb2YobGV2ZWxfbmFtZXNbMF0pOyBpKyspCiAgICBpZighc3RybmNhc2VjbXAobGV2ZWxfbmFtZXNbaV0ubmFtZSwgbmFtZSwgc3RybGVuKG5hbWUpKSkKICAgICAgcmV0dXJuIGxldmVsX25hbWVzW2ldLmxldmVsOwogIHJldHVybiAoZW51bSBwcm90ZWN0aW9uX2xldmVsKS0xOwp9CgpzdGF0aWMgc3RydWN0IEN1cmxfc2VjX2NsaWVudF9tZWNoICptZWNoc1tdID0gewojaWZkZWYgS1JCNQogIC8qIG5vdCBzdXBwb3J0ZWQgKi8KI2VuZGlmCiNpZmRlZiBLUkI0CiAgICAmQ3VybF9rcmI0X2NsaWVudF9tZWNoLAojZW5kaWYKICAgIE5VTEwKfTsKCmludApDdXJsX3NlY19nZXRjKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgRklMRSAqRikKewogIGlmKGNvbm4tPnNlY19jb21wbGV0ZSAmJiBjb25uLT5kYXRhX3Byb3QpIHsKICAgIGNoYXIgYzsKICAgIGlmKEN1cmxfc2VjX3JlYWQoY29ubiwgZmlsZW5vKEYpLCAmYywgMSkgPD0gMCkKICAgICAgcmV0dXJuIEVPRjsKICAgIHJldHVybiBjOwogIH0KICBlbHNlCiAgICByZXR1cm4gZ2V0YyhGKTsKfQoKc3RhdGljIGludApibG9ja19yZWFkKGludCBmZCwgdm9pZCAqYnVmLCBzaXplX3QgbGVuKQp7CiAgdW5zaWduZWQgY2hhciAqcCA9IGJ1ZjsKICBpbnQgYjsKICB3aGlsZShsZW4pIHsKICAgIGIgPSByZWFkKGZkLCBwLCBsZW4pOwogICAgaWYgKGIgPT0gMCkKICAgICAgcmV0dXJuIDA7CiAgICBlbHNlIGlmIChiIDwgMCkKICAgICAgcmV0dXJuIC0xOwogICAgbGVuIC09IGI7CiAgICBwICs9IGI7CiAgfQogIHJldHVybiBwIC0gKHVuc2lnbmVkIGNoYXIqKWJ1ZjsKfQoKc3RhdGljIGludApibG9ja193cml0ZShpbnQgZmQsIHZvaWQgKmJ1Ziwgc2l6ZV90IGxlbikKewogIHVuc2lnbmVkIGNoYXIgKnAgPSBidWY7CiAgaW50IGI7CiAgd2hpbGUobGVuKSB7CiAgICBiID0gd3JpdGUoZmQsIHAsIGxlbik7CiAgICBpZihiIDwgMCkKICAgICAgcmV0dXJuIC0xOwogICAgbGVuIC09IGI7CiAgICBwICs9IGI7CiAgfQogIHJldHVybiBwIC0gKHVuc2lnbmVkIGNoYXIqKWJ1ZjsKfQoKc3RhdGljIGludApzZWNfZ2V0X2RhdGEoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLAogICAgICAgICAgICAgaW50IGZkLCBzdHJ1Y3Qga3JiNGJ1ZmZlciAqYnVmKQp7CiAgaW50IGxlbjsKICBpbnQgYjsKICAKICBiID0gYmxvY2tfcmVhZChmZCwgJmxlbiwgc2l6ZW9mKGxlbikpOwogIGlmIChiID09IDApCiAgICByZXR1cm4gMDsKICBlbHNlIGlmIChiIDwgMCkKICAgIHJldHVybiAtMTsKICBsZW4gPSBudG9obChsZW4pOwogIGJ1Zi0+ZGF0YSA9IHJlYWxsb2MoYnVmLT5kYXRhLCBsZW4pOwogIGIgPSBibG9ja19yZWFkKGZkLCBidWYtPmRhdGEsIGxlbik7CiAgaWYgKGIgPT0gMCkKICAgIHJldHVybiAwOwogIGVsc2UgaWYgKGIgPCAwKQogICAgcmV0dXJuIC0xOwogIGJ1Zi0+c2l6ZSA9IChjb25uLT5tZWNoLT5kZWNvZGUpKGNvbm4tPmFwcF9kYXRhLCBidWYtPmRhdGEsIGxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5kYXRhX3Byb3QsIGNvbm4pOwogIGJ1Zi0+aW5kZXggPSAwOwogIHJldHVybiAwOwp9CgpzdGF0aWMgc2l6ZV90CmJ1ZmZlcl9yZWFkKHN0cnVjdCBrcmI0YnVmZmVyICpidWYsIHZvaWQgKmRhdGEsIHNpemVfdCBsZW4pCnsKICAgIGxlbiA9IG1pbihsZW4sIGJ1Zi0+c2l6ZSAtIGJ1Zi0+aW5kZXgpOwogICAgbWVtY3B5KGRhdGEsIChjaGFyKilidWYtPmRhdGEgKyBidWYtPmluZGV4LCBsZW4pOwogICAgYnVmLT5pbmRleCArPSBsZW47CiAgICByZXR1cm4gbGVuOwp9CgpzdGF0aWMgc2l6ZV90CmJ1ZmZlcl93cml0ZShzdHJ1Y3Qga3JiNGJ1ZmZlciAqYnVmLCB2b2lkICpkYXRhLCBzaXplX3QgbGVuKQp7CiAgICBpZihidWYtPmluZGV4ICsgbGVuID4gYnVmLT5zaXplKSB7Cgl2b2lkICp0bXA7CglpZihidWYtPmRhdGEgPT0gTlVMTCkKCSAgICB0bXAgPSBtYWxsb2MoMTAyNCk7CgllbHNlCgkgICAgdG1wID0gcmVhbGxvYyhidWYtPmRhdGEsIGJ1Zi0+aW5kZXggKyBsZW4pOwoJaWYodG1wID09IE5VTEwpCgkgICAgcmV0dXJuIC0xOwoJYnVmLT5kYXRhID0gdG1wOwoJYnVmLT5zaXplID0gYnVmLT5pbmRleCArIGxlbjsKICAgIH0KICAgIG1lbWNweSgoY2hhciopYnVmLT5kYXRhICsgYnVmLT5pbmRleCwgZGF0YSwgbGVuKTsKICAgIGJ1Zi0+aW5kZXggKz0gbGVuOwogICAgcmV0dXJuIGxlbjsKfQoKaW50CkN1cmxfc2VjX3JlYWQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgZmQsIHZvaWQgKmJ1ZmZlciwgaW50IGxlbmd0aCkKewogICAgc2l6ZV90IGxlbjsKICAgIGludCByeCA9IDA7CgogICAgaWYoY29ubi0+c2VjX2NvbXBsZXRlID09IDAgfHwgY29ubi0+ZGF0YV9wcm90ID09IDApCiAgICAgIHJldHVybiByZWFkKGZkLCBidWZmZXIsIGxlbmd0aCk7CgogICAgaWYoY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnKXsKICAgICAgY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnID0gMDsKICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICAKICAgIGxlbiA9IGJ1ZmZlcl9yZWFkKCZjb25uLT5pbl9idWZmZXIsIGJ1ZmZlciwgbGVuZ3RoKTsKICAgIGxlbmd0aCAtPSBsZW47CiAgICByeCArPSBsZW47CiAgICBidWZmZXIgPSAoY2hhciopYnVmZmVyICsgbGVuOwogICAgCiAgICB3aGlsZShsZW5ndGgpIHsKICAgICAgaWYoc2VjX2dldF9kYXRhKGNvbm4sIGZkLCAmY29ubi0+aW5fYnVmZmVyKSA8IDApCiAgICAgICAgcmV0dXJuIC0xOwogICAgICBpZihjb25uLT5pbl9idWZmZXIuc2l6ZSA9PSAwKSB7CiAgICAgICAgaWYocngpCiAgICAgICAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAxOwogICAgICAgIHJldHVybiByeDsKICAgICAgfQogICAgICBsZW4gPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbmd0aCk7CiAgICAgIGxlbmd0aCAtPSBsZW47CiAgICAgIHJ4ICs9IGxlbjsKICAgICAgYnVmZmVyID0gKGNoYXIqKWJ1ZmZlciArIGxlbjsKICAgIH0KICAgIHJldHVybiByeDsKfQoKc3RhdGljIGludApzZWNfc2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBmZCwgY2hhciAqZnJvbSwgaW50IGxlbmd0aCkKewogIGludCBieXRlczsKICB2b2lkICpidWY7CiAgYnl0ZXMgPSAoY29ubi0+bWVjaC0+ZW5jb2RlKShjb25uLT5hcHBfZGF0YSwgZnJvbSwgbGVuZ3RoLCBjb25uLT5kYXRhX3Byb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYnVmLCBjb25uKTsKICBieXRlcyA9IGh0b25sKGJ5dGVzKTsKICBibG9ja193cml0ZShmZCwgJmJ5dGVzLCBzaXplb2YoYnl0ZXMpKTsKICBibG9ja193cml0ZShmZCwgYnVmLCBudG9obChieXRlcykpOwogIGZyZWUoYnVmKTsKICByZXR1cm4gbGVuZ3RoOwp9CgppbnQKQ3VybF9zZWNfZmZsdXNoX2ZkKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IGZkKQp7CiAgaWYoY29ubi0+ZGF0YV9wcm90ICE9IHByb3RfY2xlYXIpIHsKICAgIGlmKGNvbm4tPm91dF9idWZmZXIuaW5kZXggPiAwKXsKICAgICAgQ3VybF9zZWNfd3JpdGUoY29ubiwgZmQsCiAgICAgICAgICAgICAgICBjb25uLT5vdXRfYnVmZmVyLmRhdGEsIGNvbm4tPm91dF9idWZmZXIuaW5kZXgpOwogICAgICBjb25uLT5vdXRfYnVmZmVyLmluZGV4ID0gMDsKICAgIH0KICAgIHNlY19zZW5kKGNvbm4sIGZkLCBOVUxMLCAwKTsKICB9CiAgcmV0dXJuIDA7Cn0KCmludApDdXJsX3NlY193cml0ZShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBmZCwgY2hhciAqYnVmZmVyLCBpbnQgbGVuZ3RoKQp7CiAgaW50IGxlbiA9IGNvbm4tPmJ1ZmZlcl9zaXplOwogIGludCB0eCA9IDA7CiAgICAgIAogIGlmKGNvbm4tPmRhdGFfcHJvdCA9PSBwcm90X2NsZWFyKQogICAgcmV0dXJuIHdyaXRlKGZkLCBidWZmZXIsIGxlbmd0aCk7CgogIGxlbiAtPSAoY29ubi0+bWVjaC0+b3ZlcmhlYWQpKGNvbm4tPmFwcF9kYXRhLCBjb25uLT5kYXRhX3Byb3QsIGxlbik7CiAgd2hpbGUobGVuZ3RoKXsKICAgIGlmKGxlbmd0aCA8IGxlbikKICAgICAgbGVuID0gbGVuZ3RoOwogICAgc2VjX3NlbmQoY29ubiwgZmQsIGJ1ZmZlciwgbGVuKTsKICAgIGxlbmd0aCAtPSBsZW47CiAgICBidWZmZXIgKz0gbGVuOwogICAgdHggKz0gbGVuOwogIH0KICByZXR1cm4gdHg7Cn0KCmludApDdXJsX3NlY192ZnByaW50ZjIoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBGSUxFICpmLCBjb25zdCBjaGFyICpmbXQsIHZhX2xpc3QgYXApCnsKICBjaGFyICpidWY7CiAgaW50IHJldDsKICBpZihjb25uLT5kYXRhX3Byb3QgPT0gcHJvdF9jbGVhcikKICAgIHJldHVybiB2ZnByaW50ZihmLCBmbXQsIGFwKTsKICBlbHNlIHsKICAgIGJ1ZiA9IGFwcmludGYoZm10LCBhcCk7CiAgICByZXQgPSBidWZmZXJfd3JpdGUoJmNvbm4tPm91dF9idWZmZXIsIGJ1Ziwgc3RybGVuKGJ1ZikpOwogICAgZnJlZShidWYpOwogICAgcmV0dXJuIHJldDsKICB9Cn0KCmludApDdXJsX3NlY19mcHJpbnRmMihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIEZJTEUgKmYsIGNvbnN0IGNoYXIgKmZtdCwgLi4uKQp7CiAgICBpbnQgcmV0OwogICAgdmFfbGlzdCBhcDsKICAgIHZhX3N0YXJ0KGFwLCBmbXQpOwogICAgcmV0ID0gQ3VybF9zZWNfdmZwcmludGYyKGNvbm4sIGYsIGZtdCwgYXApOwogICAgdmFfZW5kKGFwKTsKICAgIHJldHVybiByZXQ7Cn0KCmludApDdXJsX3NlY19wdXRjKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IGMsIEZJTEUgKkYpCnsKICBjaGFyIGNoID0gYzsKICBpZihjb25uLT5kYXRhX3Byb3QgPT0gcHJvdF9jbGVhcikKICAgIHJldHVybiBwdXRjKGMsIEYpOwogICAgCiAgYnVmZmVyX3dyaXRlKCZjb25uLT5vdXRfYnVmZmVyLCAmY2gsIDEpOwogIGlmKGMgPT0gJ1xuJyB8fCBjb25uLT5vdXRfYnVmZmVyLmluZGV4ID49IDEwMjQgLyogWFhYICovKSB7CiAgICBDdXJsX3NlY193cml0ZShjb25uLCBmaWxlbm8oRiksIGNvbm4tPm91dF9idWZmZXIuZGF0YSwgY29ubi0+b3V0X2J1ZmZlci5pbmRleCk7CiAgICBjb25uLT5vdXRfYnVmZmVyLmluZGV4ID0gMDsKICB9CiAgcmV0dXJuIGM7Cn0KCmludApDdXJsX3NlY19yZWFkX21zZyhzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNoYXIgKnMsIGludCBsZXZlbCkKewogICAgaW50IGxlbjsKICAgIGNoYXIgKmJ1ZjsKICAgIGludCBjb2RlOwogICAgCiAgICBidWYgPSBtYWxsb2Moc3RybGVuKHMpKTsKICAgIGxlbiA9IEN1cmxfYmFzZTY0X2RlY29kZShzICsgNCwgYnVmKTsgLyogWFhYICovCiAgICAKICAgIGxlbiA9IChjb25uLT5tZWNoLT5kZWNvZGUpKGNvbm4tPmFwcF9kYXRhLCBidWYsIGxlbiwgbGV2ZWwsIGNvbm4pOwogICAgaWYobGVuIDwgMCkKCXJldHVybiAtMTsKICAgIAogICAgYnVmW2xlbl0gPSAnXDAnOwoKICAgIGlmKGJ1ZlszXSA9PSAnLScpCgljb2RlID0gMDsKICAgIGVsc2UKCXNzY2FuZihidWYsICIlZCIsICZjb2RlKTsKICAgIGlmKGJ1ZltsZW4tMV0gPT0gJ1xuJykKCWJ1ZltsZW4tMV0gPSAnXDAnOwogICAgc3RyY3B5KHMsIGJ1Zik7CiAgICBmcmVlKGJ1Zik7CiAgICByZXR1cm4gY29kZTsKfQoKLyogbW9kaWZpZWQgdG8gcmV0dXJuIGhvdyBtYW55IGJ5dGVzIHdyaXR0ZW4sIG9yIC0xIG9uIGVycm9yICoqKi8KaW50CkN1cmxfc2VjX3ZmcHJpbnRmKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgRklMRSAqZiwgY29uc3QgY2hhciAqZm10LCB2YV9saXN0IGFwKQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIGNoYXIgKmJ1ZjsKICAgIHZvaWQgKmVuYzsKICAgIGludCBsZW47CiAgICBpZighY29ubi0+c2VjX2NvbXBsZXRlKQoJcmV0dXJuIHZmcHJpbnRmKGYsIGZtdCwgYXApOwogICAgCiAgICBidWYgPSBhcHJpbnRmKGZtdCwgYXApOwogICAgbGVuID0gKGNvbm4tPm1lY2gtPmVuY29kZSkoY29ubi0+YXBwX2RhdGEsIGJ1Ziwgc3RybGVuKGJ1ZiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5jb21tYW5kX3Byb3QsICZlbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uKTsKICAgIGZyZWUoYnVmKTsKICAgIGlmKGxlbiA8IDApIHsKCWZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gZW5jb2RlIGNvbW1hbmQuXG4iKTsKCXJldHVybiAtMTsKICAgIH0KICAgIGlmKEN1cmxfYmFzZTY0X2VuY29kZShlbmMsIGxlbiwgJmJ1ZikgPCAwKXsKICAgICAgZmFpbGYoY29ubi0+ZGF0YSwgIk91dCBvZiBtZW1vcnkgYmFzZTY0LWVuY29kaW5nLlxuIik7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGlmKGNvbm4tPmNvbW1hbmRfcHJvdCA9PSBwcm90X3NhZmUpCglyZXQgPSBmcHJpbnRmKGYsICJNSUMgJXMiLCBidWYpOwogICAgZWxzZSBpZihjb25uLT5jb21tYW5kX3Byb3QgPT0gcHJvdF9wcml2YXRlKQoJcmV0ID0gZnByaW50ZihmLCAiRU5DICVzIiwgYnVmKTsKICAgIGVsc2UgaWYoY29ubi0+Y29tbWFuZF9wcm90ID09IHByb3RfY29uZmlkZW50aWFsKQoJcmV0ID0gZnByaW50ZihmLCAiQ09ORiAlcyIsIGJ1Zik7CgogICAgZnJlZShidWYpOwogICAgcmV0dXJuIHJldDsKfQoKaW50CkN1cmxfc2VjX2ZwcmludGYoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBGSUxFICpmLCBjb25zdCBjaGFyICpmbXQsIC4uLikKewogICAgdmFfbGlzdCBhcDsKICAgIGludCByZXQ7CiAgICB2YV9zdGFydChhcCwgZm10KTsKICAgIHJldCA9IEN1cmxfc2VjX3ZmcHJpbnRmKGNvbm4sIGYsIGZtdCwgYXApOwogICAgdmFfZW5kKGFwKTsKICAgIHJldHVybiByZXQ7Cn0KCgplbnVtIHByb3RlY3Rpb25fbGV2ZWwKQ3VybF9zZXRfY29tbWFuZF9wcm90KHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsKQp7CiAgICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgb2xkID0gY29ubi0+Y29tbWFuZF9wcm90OwogICAgY29ubi0+Y29tbWFuZF9wcm90ID0gbGV2ZWw7CiAgICByZXR1cm4gb2xkOwp9CgpzdGF0aWMgaW50CnNlY19wcm90X2ludGVybmFsKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IGxldmVsKQp7CiAgY2hhciAqcDsKICB1bnNpZ25lZCBpbnQgcyA9IDEwNDg1NzY7CiAgc3NpemVfdCBucmVhZDsKCiAgaWYoIWNvbm4tPnNlY19jb21wbGV0ZSl7CiAgICBpbmZvZihjb25uLT5kYXRhLCAiTm8gc2VjdXJpdHkgZGF0YSBleGNoYW5nZSBoYXMgdGFrZW4gcGxhY2UuXG4iKTsKICAgIHJldHVybiAtMTsKICB9CgogIGlmKGxldmVsKXsKICAgIEN1cmxfZnRwc2VuZGYoY29ubi0+Zmlyc3Rzb2NrZXQsIGNvbm4sCiAgICAgICAgICAgICAgICAgICJQQlNaICV1Iiwgcyk7CiAgICAvKiB3YWl0IGZvciBmZWVkYmFjayAqLwogICAgbnJlYWQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKGNvbm4tPmZpcnN0c29ja2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgY29ubiwgTlVMTCk7CiAgICBpZihucmVhZCA8IDApCiAgICAgIHJldHVybiAvKkNVUkxFX09QRVJBVElPTl9USU1FT1VURUQqLy0xOwogICAgaWYoLypyZXQgIT0gQ09NUExFVEUqL2Nvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMicpewogICAgICBmYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIHNldCBwcm90ZWN0aW9uIGJ1ZmZlciBzaXplLlxuIik7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gczsKICAgIHAgPSBzdHJzdHIoLypyZXBseV9zdHJpbmcqL2Nvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlBCU1o9Iik7CiAgICBpZihwKQogICAgICBzc2NhbmYocCwgIlBCU1o9JXUiLCAmcyk7CiAgICBpZihzIDwgY29ubi0+YnVmZmVyX3NpemUpCiAgICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gczsKICB9CgogIEN1cmxfZnRwc2VuZGYoY29ubi0+Zmlyc3Rzb2NrZXQsIGNvbm4sCiAgICAgICAgICAgICAgICAiUFJPVCAlYyIsIGxldmVsWyJDU0VQIl0pOwogIC8qIHdhaXQgZm9yIGZlZWRiYWNrICovCiAgbnJlYWQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKGNvbm4tPmZpcnN0c29ja2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsIGNvbm4sIE5VTEwpOwogIGlmKG5yZWFkIDwgMCkKICAgIHJldHVybiAvKkNVUkxFX09QRVJBVElPTl9USU1FT1VURUQqLy0xOwogIGlmKC8qcmV0ICE9IENPTVBMRVRFKi9jb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzInKXsKICAgIGZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gc2V0IHByb3RlY3Rpb24gbGV2ZWwuXG4iKTsKICAgIHJldHVybiAtMTsKICB9CiAgICAKICBjb25uLT5kYXRhX3Byb3QgPSAoZW51bSBwcm90ZWN0aW9uX2xldmVsKWxldmVsOwogIHJldHVybiAwOwp9Cgp2b2lkCkN1cmxfc2VjX3NldF9wcm90ZWN0aW9uX2xldmVsKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGlmKGNvbm4tPnNlY19jb21wbGV0ZSAmJiBjb25uLT5kYXRhX3Byb3QgIT0gY29ubi0+cmVxdWVzdF9kYXRhX3Byb3QpCiAgICBzZWNfcHJvdF9pbnRlcm5hbChjb25uLCBjb25uLT5yZXF1ZXN0X2RhdGFfcHJvdCk7Cn0KCgppbnQKQ3VybF9zZWNfcmVxdWVzdF9wcm90KHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY29uc3QgY2hhciAqbGV2ZWwpCnsKICBpbnQgbCA9IG5hbWVfdG9fbGV2ZWwobGV2ZWwpOwogIGlmKGwgPT0gLTEpCiAgICByZXR1cm4gLTE7CiAgY29ubi0+cmVxdWVzdF9kYXRhX3Byb3QgPSAoZW51bSBwcm90ZWN0aW9uX2xldmVsKWw7CiAgcmV0dXJuIDA7Cn0KCmludApDdXJsX3NlY19sb2dpbihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgcmV0OwogIHN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCAqKm07CiAgc3NpemVfdCBucmVhZDsKICBzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YT1jb25uLT5kYXRhOwoKICBmb3IobSA9IG1lY2hzOyAqbSAmJiAoKm0pLT5uYW1lOyBtKyspIHsKICAgIHZvaWQgKnRtcDsKCiAgICB0bXAgPSByZWFsbG9jKGNvbm4tPmFwcF9kYXRhLCAoKm0pLT5zaXplKTsKICAgIGlmICh0bXAgPT0gTlVMTCkgewogICAgICBmYWlsZiAoZGF0YSwgInJlYWxsb2MgJXUgZmFpbGVkIiwgKCptKS0+c2l6ZSk7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGNvbm4tPmFwcF9kYXRhID0gdG1wOwoJICAgIAogICAgaWYoKCptKS0+aW5pdCAmJiAoKigqbSktPmluaXQpKGNvbm4tPmFwcF9kYXRhKSAhPSAwKSB7CiAgICAgIGluZm9mKGRhdGEsICJTa2lwcGluZyAlcy4uLlxuIiwgKCptKS0+bmFtZSk7CiAgICAgIGNvbnRpbnVlOwogICAgfQogICAgaW5mb2YoZGF0YSwgIlRyeWluZyAlcy4uLlxuIiwgKCptKS0+bmFtZSk7CiAgICAvKnJldCA9IGNvbW1hbmQoIkFVVEggJXMiLCAoKm0pLT5uYW1lKTsqKiovCiAgICBDdXJsX2Z0cHNlbmRmKGNvbm4tPmZpcnN0c29ja2V0LCBjb25uLAogICAgICAgICAgICAgICAgICAiQVVUSCAlcyIsICgqbSktPm5hbWUpOwogICAgLyogd2FpdCBmb3IgZmVlZGJhY2sgKi8KICAgIG5yZWFkID0gQ3VybF9HZXRGVFBSZXNwb25zZShjb25uLT5maXJzdHNvY2tldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsIGNvbm4sIE5VTEwpOwogICAgaWYobnJlYWQgPCAwKQogICAgICByZXR1cm4gLypDVVJMRV9PUEVSQVRJT05fVElNRU9VVEVEKi8tMTsKICAgIGlmKC8qcmV0ICE9IENPTlRJTlVFKi9jb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzMnKXsKICAgICAgaWYoLypjb2RlID09IDUwNCovc3RybmNtcChjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsIjUwNCIsMykgPT0gMCkgewogICAgICAgIGluZm9mKGRhdGEsCiAgICAgICAgICAgICAgIiVzIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlci5cbiIsICgqbSktPm5hbWUpOwogICAgICB9CiAgICAgIGVsc2UgaWYoLypjb2RlID09IDUzNCovc3RybmNtcChjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsIjUzNCIsMykgPT0gMCkgewogICAgICAgIGluZm9mKGRhdGEsICIlcyByZWplY3RlZCBhcyBzZWN1cml0eSBtZWNoYW5pc20uXG4iLCAoKm0pLT5uYW1lKTsKICAgICAgfQogICAgICBlbHNlIGlmKC8qcmV0ID09IEVSUk9SKi9jb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gPT0gJzUnKSB7CiAgICAgICAgaW5mb2YoZGF0YSwgIlRoZSBzZXJ2ZXIgZG9lc24ndCBzdXBwb3J0IHRoZSBGVFAgIgogICAgICAgICAgICAgICJzZWN1cml0eSBleHRlbnNpb25zLlxuIik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgICB9CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIHJldCA9ICgqKCptKS0+YXV0aCkoY29ubi0+YXBwX2RhdGEsIC8qaG9zdCoqKi9jb25uKTsKCQogICAgaWYocmV0ID09IEFVVEhfQ09OVElOVUUpCiAgICAgIGNvbnRpbnVlOwogICAgZWxzZSBpZihyZXQgIT0gQVVUSF9PSyl7CiAgICAgIC8qIG1lY2hhbmlzbSBpcyBzdXBwb3NlZCB0byBvdXRwdXQgZXJyb3Igc3RyaW5nICovCiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGNvbm4tPm1lY2ggPSAqbTsKICAgIGNvbm4tPnNlY19jb21wbGV0ZSA9IDE7CiAgICBjb25uLT5jb21tYW5kX3Byb3QgPSBwcm90X3NhZmU7CiAgICBicmVhazsKICB9CiAgICAKICByZXR1cm4gKm0gPT0gTlVMTDsKfQoKdm9pZApDdXJsX3NlY19lbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaWYgKGNvbm4tPm1lY2ggIT0gTlVMTCkgewogICAgaWYoY29ubi0+bWVjaC0+ZW5kKQogICAgICAoY29ubi0+bWVjaC0+ZW5kKShjb25uLT5hcHBfZGF0YSk7CiAgICBtZW1zZXQoY29ubi0+YXBwX2RhdGEsIDAsIGNvbm4tPm1lY2gtPnNpemUpOwogICAgZnJlZShjb25uLT5hcHBfZGF0YSk7CiAgICBjb25uLT5hcHBfZGF0YSA9IE5VTEw7CiAgfQogIGNvbm4tPnNlY19jb21wbGV0ZSA9IDA7CiAgY29ubi0+ZGF0YV9wcm90ID0gKGVudW0gcHJvdGVjdGlvbl9sZXZlbCkwOwogIGNvbm4tPm1lY2g9TlVMTDsKfQoKI2VuZGlmIC8qIEtSQjQgKi8KCi8qCiAqIGxvY2FsIHZhcmlhYmxlczoKICogZXZhbDogKGxvYWQtZmlsZSAiLi4vY3VybC1tb2RlLmVsIikKICogZW5kOgogKiB2aW02MDA6IGV0IHN3PTIgdHM9MiBzdHM9MiB0dz03OCBmZG09bWFya2VyCiAqIHZpbTw2MDA6IGV0IHN3PTIgdHM9MiBzdHM9MiB0dz03OAogKi8K