LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAic2V0dXAuaCIKCiNpZm5kZWYgQ1VSTF9ESVNBQkxFX0ZUUAojaWYgZGVmaW5lZChIQVZFX0tSQjQpIHx8IGRlZmluZWQoSEFWRV9HU1NBUEkpCgojZGVmaW5lIF9NUFJJTlRGX1JFUExBQ0UgLyogd2Ugd2FudCBjdXJsLWZ1bmN0aW9ucyBpbnN0ZWFkIG9mIG5hdGl2ZSBvbmVzICovCiNpbmNsdWRlIDxjdXJsL21wcmludGYuaD4KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8bmV0ZGIuaD4KCiNpZmRlZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCgojaW5jbHVkZSAidXJsZGF0YS5oIgojaW5jbHVkZSAia3JiNC5oIgojaW5jbHVkZSAiYmFzZTY0LmgiCiNpbmNsdWRlICJzZW5kZi5oIgojaW5jbHVkZSAiZnRwLmgiCiNpbmNsdWRlICJtZW1vcnkuaCIKCi8qIFRoZSBsYXN0ICNpbmNsdWRlIGZpbGUgc2hvdWxkIGJlOiAqLwojaW5jbHVkZSAibWVtZGVidWcuaCIKCiNkZWZpbmUgbWluKGEsIGIpICAgKChhKSA8IChiKSA/IChhKSA6IChiKSkKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgewogICAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsOwogICAgY29uc3QgY2hhciAqbmFtZTsKfSBsZXZlbF9uYW1lc1tdID0gewogICAgeyBwcm90X2NsZWFyLCAiY2xlYXIiIH0sCiAgICB7IHByb3Rfc2FmZSwgInNhZmUiIH0sCiAgICB7IHByb3RfY29uZmlkZW50aWFsLCAiY29uZmlkZW50aWFsIiB9LAogICAgeyBwcm90X3ByaXZhdGUsICJwcml2YXRlIiB9Cn07CgpzdGF0aWMgZW51bSBwcm90ZWN0aW9uX2xldmVsCm5hbWVfdG9fbGV2ZWwoY29uc3QgY2hhciAqbmFtZSkKewogIGludCBpOwogIGZvcihpID0gMDsgaSA8IChpbnQpc2l6ZW9mKGxldmVsX25hbWVzKS8oaW50KXNpemVvZihsZXZlbF9uYW1lc1swXSk7IGkrKykKICAgIGlmKGN1cmxfc3RybmVxdWFsKGxldmVsX25hbWVzW2ldLm5hbWUsIG5hbWUsIHN0cmxlbihuYW1lKSkpCiAgICAgIHJldHVybiBsZXZlbF9uYW1lc1tpXS5sZXZlbDsKICByZXR1cm4gKGVudW0gcHJvdGVjdGlvbl9sZXZlbCktMTsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCAqIGNvbnN0IG1lY2hzW10gPSB7CiNpZmRlZiBIQVZFX0dTU0FQSQogICAgJkN1cmxfa3JiNV9jbGllbnRfbWVjaCwKI2VuZGlmCiNpZmRlZiBIQVZFX0tSQjQKICAgICZDdXJsX2tyYjRfY2xpZW50X21lY2gsCiNlbmRpZgogICAgTlVMTAp9OwoKaW50CkN1cmxfc2VjX2dldGMoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBGSUxFICpGKQp7CiAgaWYoY29ubi0+c2VjX2NvbXBsZXRlICYmIGNvbm4tPmRhdGFfcHJvdCkgewogICAgY2hhciBjOwogICAgaWYoQ3VybF9zZWNfcmVhZChjb25uLCBmaWxlbm8oRiksICZjLCAxKSA8PSAwKQogICAgICByZXR1cm4gRU9GOwogICAgcmV0dXJuIGM7CiAgfQogIGVsc2UKICAgIHJldHVybiBnZXRjKEYpOwp9CgpzdGF0aWMgaW50CmJsb2NrX3JlYWQoaW50IGZkLCB2b2lkICpidWYsIHNpemVfdCBsZW4pCnsKICB1bnNpZ25lZCBjaGFyICpwID0gYnVmOwogIGludCBiOwogIHdoaWxlKGxlbikgewogICAgYiA9IHJlYWQoZmQsIHAsIGxlbik7CiAgICBpZiAoYiA9PSAwKQogICAgICByZXR1cm4gMDsKICAgIGVsc2UgaWYgKGIgPCAwICYmIChlcnJubyA9PSBFSU5UUiB8fCBlcnJubyA9PSBFQUdBSU4pKQogICAgICBjb250aW51ZTsKICAgIGVsc2UgaWYgKGIgPCAwKQogICAgICByZXR1cm4gLTE7CiAgICBsZW4gLT0gYjsKICAgIHAgKz0gYjsKICB9CiAgcmV0dXJuIHAgLSAodW5zaWduZWQgY2hhciopYnVmOwp9CgpzdGF0aWMgaW50CmJsb2NrX3dyaXRlKGludCBmZCwgY29uc3Qgdm9pZCAqYnVmLCBzaXplX3QgbGVuKQp7CiAgY29uc3QgdW5zaWduZWQgY2hhciAqcCA9IGJ1ZjsKICBpbnQgYjsKICB3aGlsZShsZW4pIHsKICAgIGIgPSB3cml0ZShmZCwgcCwgbGVuKTsKICAgIGlmIChiIDwgMCAmJiAoZXJybm8gPT0gRUlOVFIgfHwgZXJybm8gPT0gRUFHQUlOKSkKICAgICAgY29udGludWU7CiAgICBlbHNlIGlmKGIgPCAwKQogICAgICByZXR1cm4gLTE7CiAgICBsZW4gLT0gYjsKICAgIHAgKz0gYjsKICB9CiAgcmV0dXJuIHAgLSAodW5zaWduZWQgY2hhciopYnVmOwp9CgpzdGF0aWMgaW50CnNlY19nZXRfZGF0YShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sCiAgICAgICAgICAgICBpbnQgZmQsIHN0cnVjdCBrcmI0YnVmZmVyICpidWYpCnsKICBpbnQgbGVuOwogIGludCBiOwoKICBiID0gYmxvY2tfcmVhZChmZCwgJmxlbiwgc2l6ZW9mKGxlbikpOwogIGlmIChiID09IDApCiAgICByZXR1cm4gMDsKICBlbHNlIGlmIChiIDwgMCkKICAgIHJldHVybiAtMTsKICBsZW4gPSBudG9obChsZW4pOwogIGJ1Zi0+ZGF0YSA9IHJlYWxsb2MoYnVmLT5kYXRhLCBsZW4pOwogIGIgPSBidWYtPmRhdGEgPyBibG9ja19yZWFkKGZkLCBidWYtPmRhdGEsIGxlbikgOiAtMTsKICBpZiAoYiA9PSAwKQogICAgcmV0dXJuIDA7CiAgZWxzZSBpZiAoYiA8IDApCiAgICByZXR1cm4gLTE7CiAgYnVmLT5zaXplID0gKGNvbm4tPm1lY2gtPmRlY29kZSkoY29ubi0+YXBwX2RhdGEsIGJ1Zi0+ZGF0YSwgbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4tPmRhdGFfcHJvdCwgY29ubik7CiAgYnVmLT5pbmRleCA9IDA7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBzaXplX3QKYnVmZmVyX3JlYWQoc3RydWN0IGtyYjRidWZmZXIgKmJ1Ziwgdm9pZCAqZGF0YSwgc2l6ZV90IGxlbikKewogICAgbGVuID0gbWluKGxlbiwgYnVmLT5zaXplIC0gYnVmLT5pbmRleCk7CiAgICBtZW1jcHkoZGF0YSwgKGNoYXIqKWJ1Zi0+ZGF0YSArIGJ1Zi0+aW5kZXgsIGxlbik7CiAgICBidWYtPmluZGV4ICs9IGxlbjsKICAgIHJldHVybiBsZW47Cn0KCnN0YXRpYyBzaXplX3QKYnVmZmVyX3dyaXRlKHN0cnVjdCBrcmI0YnVmZmVyICpidWYsIHZvaWQgKmRhdGEsIHNpemVfdCBsZW4pCnsKICAgIGlmKGJ1Zi0+aW5kZXggKyBsZW4gPiBidWYtPnNpemUpIHsKICAgICAgICB2b2lkICp0bXA7CiAgICAgICAgaWYoYnVmLT5kYXRhID09IE5VTEwpCiAgICAgICAgICAgIHRtcCA9IG1hbGxvYygxMDI0KTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHRtcCA9IHJlYWxsb2MoYnVmLT5kYXRhLCBidWYtPmluZGV4ICsgbGVuKTsKICAgICAgICBpZih0bXAgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIGJ1Zi0+ZGF0YSA9IHRtcDsKICAgICAgICBidWYtPnNpemUgPSBidWYtPmluZGV4ICsgbGVuOwogICAgfQogICAgbWVtY3B5KChjaGFyKilidWYtPmRhdGEgKyBidWYtPmluZGV4LCBkYXRhLCBsZW4pOwogICAgYnVmLT5pbmRleCArPSBsZW47CiAgICByZXR1cm4gbGVuOwp9CgppbnQKQ3VybF9zZWNfcmVhZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBmZCwgdm9pZCAqYnVmZmVyLCBpbnQgbGVuZ3RoKQp7CiAgICBzaXplX3QgbGVuOwogICAgaW50IHJ4ID0gMDsKCiAgICBpZihjb25uLT5zZWNfY29tcGxldGUgPT0gMCB8fCBjb25uLT5kYXRhX3Byb3QgPT0gMCkKICAgICAgcmV0dXJuIHJlYWQoZmQsIGJ1ZmZlciwgbGVuZ3RoKTsKCiAgICBpZihjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcpewogICAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAwOwogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBsZW4gPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbmd0aCk7CiAgICBsZW5ndGggLT0gbGVuOwogICAgcnggKz0gbGVuOwogICAgYnVmZmVyID0gKGNoYXIqKWJ1ZmZlciArIGxlbjsKCiAgICB3aGlsZShsZW5ndGgpIHsKICAgICAgaWYoc2VjX2dldF9kYXRhKGNvbm4sIGZkLCAmY29ubi0+aW5fYnVmZmVyKSA8IDApCiAgICAgICAgcmV0dXJuIC0xOwogICAgICBpZihjb25uLT5pbl9idWZmZXIuc2l6ZSA9PSAwKSB7CiAgICAgICAgaWYocngpCiAgICAgICAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAxOwogICAgICAgIHJldHVybiByeDsKICAgICAgfQogICAgICBsZW4gPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbmd0aCk7CiAgICAgIGxlbmd0aCAtPSBsZW47CiAgICAgIHJ4ICs9IGxlbjsKICAgICAgYnVmZmVyID0gKGNoYXIqKWJ1ZmZlciArIGxlbjsKICAgIH0KICAgIHJldHVybiByeDsKfQoKc3RhdGljIGludApzZWNfc2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBmZCwgY2hhciAqZnJvbSwgaW50IGxlbmd0aCkKewogIGludCBieXRlczsKICB2b2lkICpidWY7CiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIHByb3RsZXZlbCA9IGNvbm4tPmRhdGFfcHJvdDsKICBpbnQgaXNjbWQgPSBwcm90bGV2ZWwgPT0gcHJvdF9jbWQ7CgogIGlmKGlzY21kKSB7CiAgICBpZighc3RybmNtcChmcm9tLCAiUEFTUyAiLCA1KSB8fCAhc3RybmNtcChmcm9tLCAiQUNDVCAiLCA1KSkKICAgICAgcHJvdGxldmVsID0gcHJvdF9wcml2YXRlOwogICAgZWxzZQogICAgICBwcm90bGV2ZWwgPSBjb25uLT5jb21tYW5kX3Byb3Q7CiAgfQogIGJ5dGVzID0gKGNvbm4tPm1lY2gtPmVuY29kZSkoY29ubi0+YXBwX2RhdGEsIGZyb20sIGxlbmd0aCwgcHJvdGxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJ1ZiwgY29ubik7CiAgaWYoaXNjbWQpIHsKICAgIGNoYXIgKmNtZGJ1ZjsKCiAgICBieXRlcyA9IEN1cmxfYmFzZTY0X2VuY29kZShjb25uLT5kYXRhLCAoY2hhciAqKWJ1ZiwgYnl0ZXMsICZjbWRidWYpOwogICAgaWYoYnl0ZXMgPiAwKSB7CiAgICAgIGlmKHByb3RsZXZlbCA9PSBwcm90X3ByaXZhdGUpCglibG9ja193cml0ZShmZCwgIkVOQyAiLCA0KTsKICAgICAgZWxzZQoJYmxvY2tfd3JpdGUoZmQsICJNSUMgIiwgNCk7CiAgICAgIGJsb2NrX3dyaXRlKGZkLCBjbWRidWYsIGJ5dGVzKTsKICAgICAgYmxvY2tfd3JpdGUoZmQsICJcclxuIiwgMik7CiAgICAgIEN1cmxfaW5mb2YoY29ubi0+ZGF0YSwgIiVzICVzXG4iLCBwcm90bGV2ZWwgPT0gcHJvdF9wcml2YXRlID8gIkVOQyIgOiAiTUlDIiwgY21kYnVmKTsKICAgICAgZnJlZShjbWRidWYpOwogICAgfQogIH0gZWxzZSB7CiAgICBieXRlcyA9IGh0b25sKGJ5dGVzKTsKICAgIGJsb2NrX3dyaXRlKGZkLCAmYnl0ZXMsIHNpemVvZihieXRlcykpOwogICAgYmxvY2tfd3JpdGUoZmQsIGJ1ZiwgbnRvaGwoYnl0ZXMpKTsKICB9CiAgZnJlZShidWYpOwogIHJldHVybiBsZW5ndGg7Cn0KCmludApDdXJsX3NlY19mZmx1c2hfZmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgZmQpCnsKICBpZihjb25uLT5kYXRhX3Byb3QgIT0gcHJvdF9jbGVhcikgewogICAgaWYoY29ubi0+b3V0X2J1ZmZlci5pbmRleCA+IDApewogICAgICBDdXJsX3NlY193cml0ZShjb25uLCBmZCwKICAgICAgICAgICAgICAgIGNvbm4tPm91dF9idWZmZXIuZGF0YSwgY29ubi0+b3V0X2J1ZmZlci5pbmRleCk7CiAgICAgIGNvbm4tPm91dF9idWZmZXIuaW5kZXggPSAwOwogICAgfQogICAgc2VjX3NlbmQoY29ubiwgZmQsIE5VTEwsIDApOwogIH0KICByZXR1cm4gMDsKfQoKaW50CkN1cmxfc2VjX3dyaXRlKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IGZkLCBjaGFyICpidWZmZXIsIGludCBsZW5ndGgpCnsKICBpbnQgbGVuID0gY29ubi0+YnVmZmVyX3NpemU7CiAgaW50IHR4ID0gMDsKCiAgaWYoY29ubi0+ZGF0YV9wcm90ID09IHByb3RfY2xlYXIpCiAgICByZXR1cm4gd3JpdGUoZmQsIGJ1ZmZlciwgbGVuZ3RoKTsKCiAgbGVuIC09IChjb25uLT5tZWNoLT5vdmVyaGVhZCkoY29ubi0+YXBwX2RhdGEsIGNvbm4tPmRhdGFfcHJvdCwgbGVuKTsKICBpZihsZW4gPD0gMCkKICAgIGxlbiA9IGxlbmd0aDsKICB3aGlsZShsZW5ndGgpewogICAgaWYobGVuZ3RoIDwgbGVuKQogICAgICBsZW4gPSBsZW5ndGg7CiAgICBzZWNfc2VuZChjb25uLCBmZCwgYnVmZmVyLCBsZW4pOwogICAgbGVuZ3RoIC09IGxlbjsKICAgIGJ1ZmZlciArPSBsZW47CiAgICB0eCArPSBsZW47CiAgfQogIHJldHVybiB0eDsKfQoKc3NpemVfdApDdXJsX3NlY19zZW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IG51bSwgY2hhciAqYnVmZmVyLCBpbnQgbGVuZ3RoKQp7CiAgY3VybF9zb2NrZXRfdCBmZCA9IGNvbm4tPnNvY2tbbnVtXTsKICByZXR1cm4gKHNzaXplX3QpQ3VybF9zZWNfd3JpdGUoY29ubiwgZmQsIGJ1ZmZlciwgbGVuZ3RoKTsKfQoKaW50CkN1cmxfc2VjX3B1dGMoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgYywgRklMRSAqRikKewogIGNoYXIgY2ggPSBjOwogIGlmKGNvbm4tPmRhdGFfcHJvdCA9PSBwcm90X2NsZWFyKQogICAgcmV0dXJuIHB1dGMoYywgRik7CgogIGJ1ZmZlcl93cml0ZSgmY29ubi0+b3V0X2J1ZmZlciwgJmNoLCAxKTsKICBpZihjID09ICdcbicgfHwgY29ubi0+b3V0X2J1ZmZlci5pbmRleCA+PSAxMDI0IC8qIFhYWCAqLykgewogICAgQ3VybF9zZWNfd3JpdGUoY29ubiwgZmlsZW5vKEYpLCBjb25uLT5vdXRfYnVmZmVyLmRhdGEsCiAgICAgICAgICAgICAgICAgICBjb25uLT5vdXRfYnVmZmVyLmluZGV4KTsKICAgIGNvbm4tPm91dF9idWZmZXIuaW5kZXggPSAwOwogIH0KICByZXR1cm4gYzsKfQoKaW50CkN1cmxfc2VjX3JlYWRfbXNnKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY2hhciAqcywgaW50IGxldmVsKQp7CiAgaW50IGxlbjsKICB1bnNpZ25lZCBjaGFyICpidWY7CiAgaW50IGNvZGU7CgogIGxlbiA9IEN1cmxfYmFzZTY0X2RlY29kZShzICsgNCwgJmJ1Zik7IC8qIFhYWCAqLwogIGlmKGxlbiA+IDApCiAgICBsZW4gPSAoY29ubi0+bWVjaC0+ZGVjb2RlKShjb25uLT5hcHBfZGF0YSwgYnVmLCBsZW4sIGxldmVsLCBjb25uKTsKICBlbHNlCiAgICByZXR1cm4gLTE7CgogIGlmKGxlbiA8IDApIHsKICAgIGZyZWUoYnVmKTsKICAgIHJldHVybiAtMTsKICB9CgogIGlmKGNvbm4tPmRhdGEtPnNldC52ZXJib3NlKSB7CiAgICBidWZbbGVuXSA9ICdcbic7CiAgICBDdXJsX2RlYnVnKGNvbm4tPmRhdGEsIENVUkxJTkZPX0hFQURFUl9JTiwgKGNoYXIgKilidWYsIGxlbiArIDEsIGNvbm4pOwogIH0KCiAgYnVmW2xlbl0gPSAnXDAnOwoKICBpZihidWZbM10gPT0gJy0nKQogICAgY29kZSA9IDA7CiAgZWxzZQogICAgc3NjYW5mKChjaGFyICopYnVmLCAiJWQiLCAmY29kZSk7CiAgaWYoYnVmW2xlbi0xXSA9PSAnXG4nKQogICAgYnVmW2xlbi0xXSA9ICdcMCc7CiAgc3RyY3B5KHMsIChjaGFyICopYnVmKTsKICBmcmVlKGJ1Zik7CiAgcmV0dXJuIGNvZGU7Cn0KCmVudW0gcHJvdGVjdGlvbl9sZXZlbApDdXJsX3NldF9jb21tYW5kX3Byb3Qoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgbGV2ZWwpCnsKICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgb2xkID0gY29ubi0+Y29tbWFuZF9wcm90OwogIGNvbm4tPmNvbW1hbmRfcHJvdCA9IGxldmVsOwogIHJldHVybiBvbGQ7Cn0KCnN0YXRpYyBpbnQKc2VjX3Byb3RfaW50ZXJuYWwoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgbGV2ZWwpCnsKICBjaGFyICpwOwogIHVuc2lnbmVkIGludCBzID0gMTA0ODU3NjsKICBzc2l6ZV90IG5yZWFkOwoKICBpZighY29ubi0+c2VjX2NvbXBsZXRlKXsKICAgIGluZm9mKGNvbm4tPmRhdGEsICJObyBzZWN1cml0eSBkYXRhIGV4Y2hhbmdlIGhhcyB0YWtlbiBwbGFjZS5cbiIpOwogICAgcmV0dXJuIC0xOwogIH0KCiAgaWYobGV2ZWwpewogICAgaW50IGNvZGU7CiAgICBpZihDdXJsX2Z0cHNlbmRmKGNvbm4sICJQQlNaICV1IiwgcykpCiAgICAgIHJldHVybiAtMTsKCiAgICBpZihDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgJmNvZGUpKQogICAgICByZXR1cm4gLTE7CgogICAgaWYoY29kZS8xMDAgIT0gMil7CiAgICAgIGZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gc2V0IHByb3RlY3Rpb24gYnVmZmVyIHNpemUuIik7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gczsKCiAgICBwID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlBCU1o9Iik7CiAgICBpZihwKQogICAgICBzc2NhbmYocCwgIlBCU1o9JXUiLCAmcyk7CiAgICBpZihzIDwgY29ubi0+YnVmZmVyX3NpemUpCiAgICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gczsKICB9CgogIGlmKEN1cmxfZnRwc2VuZGYoY29ubiwgIlBST1QgJWMiLCBsZXZlbFsiQ1NFUCJdKSkKICAgIHJldHVybiAtMTsKCiAgaWYoQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sIE5VTEwpKQogICAgcmV0dXJuIC0xOwoKICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzInKXsKICAgIGZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gc2V0IHByb3RlY3Rpb24gbGV2ZWwuIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICBjb25uLT5kYXRhX3Byb3QgPSAoZW51bSBwcm90ZWN0aW9uX2xldmVsKWxldmVsOwogIGlmKGxldmVsID09IHByb3RfcHJpdmF0ZSkKICAgIGNvbm4tPmNvbW1hbmRfcHJvdCA9IChlbnVtIHByb3RlY3Rpb25fbGV2ZWwpbGV2ZWw7CiAgcmV0dXJuIDA7Cn0KCnZvaWQKQ3VybF9zZWNfc2V0X3Byb3RlY3Rpb25fbGV2ZWwoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaWYoY29ubi0+c2VjX2NvbXBsZXRlICYmIGNvbm4tPmRhdGFfcHJvdCAhPSBjb25uLT5yZXF1ZXN0X2RhdGFfcHJvdCkKICAgIHNlY19wcm90X2ludGVybmFsKGNvbm4sIGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90KTsKfQoKCmludApDdXJsX3NlY19yZXF1ZXN0X3Byb3Qoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjb25zdCBjaGFyICpsZXZlbCkKewogIGludCBsID0gbmFtZV90b19sZXZlbChsZXZlbCk7CiAgaWYobCA9PSAtMSkKICAgIHJldHVybiAtMTsKICBjb25uLT5yZXF1ZXN0X2RhdGFfcHJvdCA9IChlbnVtIHByb3RlY3Rpb25fbGV2ZWwpbDsKICByZXR1cm4gMDsKfQoKaW50CkN1cmxfc2VjX2xvZ2luKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGludCByZXQ7CiAgY29uc3Qgc3RydWN0IEN1cmxfc2VjX2NsaWVudF9tZWNoICogY29uc3QgKm07CiAgc3NpemVfdCBucmVhZDsKICBzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YT1jb25uLT5kYXRhOwogIGludCBmdHBjb2RlOwoKICBmb3IobSA9IG1lY2hzOyAqbSAmJiAoKm0pLT5uYW1lOyBtKyspIHsKICAgIHZvaWQgKnRtcDsKCiAgICB0bXAgPSByZWFsbG9jKGNvbm4tPmFwcF9kYXRhLCAoKm0pLT5zaXplKTsKICAgIGlmICh0bXAgPT0gTlVMTCkgewogICAgICBmYWlsZiAoZGF0YSwgInJlYWxsb2MgJXUgZmFpbGVkIiwgKCptKS0+c2l6ZSk7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGNvbm4tPmFwcF9kYXRhID0gdG1wOwoKICAgIGlmKCgqbSktPmluaXQgJiYgKCooKm0pLT5pbml0KShjb25uLT5hcHBfZGF0YSkgIT0gMCkgewogICAgICBpbmZvZihkYXRhLCAiU2tpcHBpbmcgJXMuLi5cbiIsICgqbSktPm5hbWUpOwogICAgICBjb250aW51ZTsKICAgIH0KICAgIGluZm9mKGRhdGEsICJUcnlpbmcgJXMuLi5cbiIsICgqbSktPm5hbWUpOwoKICAgIGlmKEN1cmxfZnRwc2VuZGYoY29ubiwgIkFVVEggJXMiLCAoKm0pLT5uYW1lKSkKICAgICAgcmV0dXJuIC0xOwoKICAgIGlmKEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCAmZnRwY29kZSkpCiAgICAgIHJldHVybiAtMTsKCiAgICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzMnKXsKICAgICAgc3dpdGNoKGZ0cGNvZGUpIHsKICAgICAgY2FzZSA1MDQ6CiAgICAgICAgaW5mb2YoZGF0YSwKICAgICAgICAgICAgICAiJXMgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgc2VydmVyLlxuIiwgKCptKS0+bmFtZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgNTM0OgogICAgICAgIGluZm9mKGRhdGEsICIlcyByZWplY3RlZCBhcyBzZWN1cml0eSBtZWNoYW5pc20uXG4iLCAoKm0pLT5uYW1lKTsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gPT0gJzUnKSB7CiAgICAgICAgICBpbmZvZihkYXRhLCAiVGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhlIEZUUCAiCiAgICAgICAgICAgICAgICAic2VjdXJpdHkgZXh0ZW5zaW9ucy5cbiIpOwogICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjb250aW51ZTsKICAgIH0KCiAgICByZXQgPSAoKigqbSktPmF1dGgpKGNvbm4tPmFwcF9kYXRhLCBjb25uKTsKCiAgICBpZihyZXQgPT0gQVVUSF9DT05USU5VRSkKICAgICAgY29udGludWU7CiAgICBlbHNlIGlmKHJldCAhPSBBVVRIX09LKXsKICAgICAgLyogbWVjaGFuaXNtIGlzIHN1cHBvc2VkIHRvIG91dHB1dCBlcnJvciBzdHJpbmcgKi8KICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgY29ubi0+bWVjaCA9ICptOwogICAgY29ubi0+c2VjX2NvbXBsZXRlID0gMTsKICAgIGNvbm4tPmNvbW1hbmRfcHJvdCA9IHByb3Rfc2FmZTsKICAgIC8qIFNldCB0aGUgcmVxdWVzdGVkIHByb3RlY3Rpb24gbGV2ZWwgKi8KICAgIC8qIEJMT0NLSU5HICovCiAgICBDdXJsX3NlY19zZXRfcHJvdGVjdGlvbl9sZXZlbChjb25uKTsKICAgIGJyZWFrOwogIH0KCiAgcmV0dXJuICptID09IE5VTEw7Cn0KCnZvaWQKQ3VybF9zZWNfZW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGlmIChjb25uLT5tZWNoICE9IE5VTEwpIHsKICAgIGlmKGNvbm4tPm1lY2gtPmVuZCkKICAgICAgKGNvbm4tPm1lY2gtPmVuZCkoY29ubi0+YXBwX2RhdGEpOwogICAgbWVtc2V0KGNvbm4tPmFwcF9kYXRhLCAwLCBjb25uLT5tZWNoLT5zaXplKTsKICAgIGZyZWUoY29ubi0+YXBwX2RhdGEpOwogICAgY29ubi0+YXBwX2RhdGEgPSBOVUxMOwogIH0KICBjb25uLT5zZWNfY29tcGxldGUgPSAwOwogIGNvbm4tPmRhdGFfcHJvdCA9IChlbnVtIHByb3RlY3Rpb25fbGV2ZWwpMDsKICBjb25uLT5tZWNoPU5VTEw7Cn0KCiNlbmRpZiAvKiBIQVZFX0tSQjQgKi8KI2VuZGlmIC8qIENVUkxfRElTQUJMRV9GVFAgKi8K