LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEgLSAyMDE1LCBEYW5pZWwgU3RlbmJlcmcsIDxkYW5pZWxAaGF4eC5zZT4sIGV0IGFsLgogKgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAiY3VybF9zZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBIQVZFX0dTU0FQSQoKI2lmZGVmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCgojaWZkZWYgSEFWRV9MSU1JVFNfSAojaW5jbHVkZSA8bGltaXRzLmg+CiNlbmRpZgoKI2luY2x1ZGUgInVybGRhdGEuaCIKI2luY2x1ZGUgImN1cmxfYmFzZTY0LmgiCiNpbmNsdWRlICJjdXJsX21lbW9yeS5oIgojaW5jbHVkZSAiY3VybF9zZWMuaCIKI2luY2x1ZGUgImZ0cC5oIgojaW5jbHVkZSAic2VuZGYuaCIKI2luY2x1ZGUgInN0cmNhc2UuaCIKI2luY2x1ZGUgIndhcm5sZXNzLmgiCiNpbmNsdWRlICJzdHJkdXAuaCIKLyogVGhlIGxhc3QgI2luY2x1ZGUgZmlsZSBzaG91bGQgYmU6ICovCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgoKc3RhdGljIGNvbnN0IHN0cnVjdCB7CiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsOwogIGNvbnN0IGNoYXIgKm5hbWU7Cn0gbGV2ZWxfbmFtZXNbXSA9IHsKICB7IFBST1RfQ0xFQVIsICJjbGVhciIgfSwKICB7IFBST1RfU0FGRSwgInNhZmUiIH0sCiAgeyBQUk9UX0NPTkZJREVOVElBTCwgImNvbmZpZGVudGlhbCIgfSwKICB7IFBST1RfUFJJVkFURSwgInByaXZhdGUiIH0KfTsKCnN0YXRpYyBlbnVtIHByb3RlY3Rpb25fbGV2ZWwKbmFtZV90b19sZXZlbChjb25zdCBjaGFyICpuYW1lKQp7CiAgaW50IGk7CiAgZm9yKGkgPSAwOyBpIDwgKGludClzaXplb2YobGV2ZWxfbmFtZXMpLyhpbnQpc2l6ZW9mKGxldmVsX25hbWVzWzBdKTsgaSsrKQogICAgaWYoY2hlY2twcmVmaXgobmFtZSwgbGV2ZWxfbmFtZXNbaV0ubmFtZSkpCiAgICAgIHJldHVybiBsZXZlbF9uYW1lc1tpXS5sZXZlbDsKICByZXR1cm4gUFJPVF9OT05FOwp9CgovKiBDb252ZXJ0IGEgcHJvdG9jb2wgfGxldmVsfCB0byBpdHMgY2hhciByZXByZXNlbnRhdGlvbi4KICAgV2UgdGFrZSBhbiBpbnQgdG8gY2F0Y2ggcHJvZ3JhbW1pbmcgbWlzdGFrZXMuICovCnN0YXRpYyBjaGFyIGxldmVsX3RvX2NoYXIoaW50IGxldmVsKQp7CiAgc3dpdGNoKGxldmVsKSB7CiAgY2FzZSBQUk9UX0NMRUFSOgogICAgcmV0dXJuICdDJzsKICBjYXNlIFBST1RfU0FGRToKICAgIHJldHVybiAnUyc7CiAgY2FzZSBQUk9UX0NPTkZJREVOVElBTDoKICAgIHJldHVybiAnRSc7CiAgY2FzZSBQUk9UX1BSSVZBVEU6CiAgICByZXR1cm4gJ1AnOwogIGNhc2UgUFJPVF9DTUQ6CiAgICAvKiBGYWxsIHRocm91Z2ggKi8KICBkZWZhdWx0OgogICAgLyogVGhvc2UgMiBjYXNlcyBzaG91bGQgbm90IGJlIHJlYWNoZWQhICovCiAgICBicmVhazsKICB9CiAgREVCVUdBU1NFUlQoMCk7CiAgLyogRGVmYXVsdCB0byB0aGUgbW9zdCBzZWN1cmUgYWx0ZXJuYXRpdmUuICovCiAgcmV0dXJuICdQJzsKfQoKLyogU2VuZCBhbiBGVFAgY29tbWFuZCBkZWZpbmVkIGJ5IHxtZXNzYWdlfCBhbmQgdGhlIG9wdGlvbmFsIGFyZ3VtZW50cy4gVGhlCiAgIGZ1bmN0aW9uIHJldHVybnMgdGhlIGZ0cF9jb2RlLiBJZiBhbiBlcnJvciBvY2N1cnMsIC0xIGlzIHJldHVybmVkLiAqLwpzdGF0aWMgaW50IGZ0cF9zZW5kX2NvbW1hbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjb25zdCBjaGFyICptZXNzYWdlLCAuLi4pCnsKICBpbnQgZnRwX2NvZGU7CiAgc3NpemVfdCBucmVhZD0wOwogIHZhX2xpc3QgYXJnczsKICBjaGFyIHByaW50X2J1ZmZlcls1MF07CgogIHZhX3N0YXJ0KGFyZ3MsIG1lc3NhZ2UpOwogIHZzbnByaW50ZihwcmludF9idWZmZXIsIHNpemVvZihwcmludF9idWZmZXIpLCBtZXNzYWdlLCBhcmdzKTsKICB2YV9lbmQoYXJncyk7CgogIGlmKEN1cmxfZnRwc2VuZChjb25uLCBwcmludF9idWZmZXIpKSB7CiAgICBmdHBfY29kZSA9IC0xOwogIH0KICBlbHNlIHsKICAgIGlmKEN1cmxfR2V0RlRQUmVzcG9uc2UoJm5yZWFkLCBjb25uLCAmZnRwX2NvZGUpKQogICAgICBmdHBfY29kZSA9IC0xOwogIH0KCiAgKHZvaWQpbnJlYWQ7IC8qIFVudXNlZCAqLwogIHJldHVybiBmdHBfY29kZTsKfQoKLyogUmVhZCB8bGVufCBmcm9tIHRoZSBzb2NrZXQgfGZkfCBhbmQgc3RvcmUgaXQgaW4gfHRvfC4gUmV0dXJuIGEgQ1VSTGNvZGUKICAgc2F5aW5nIHdoZXRoZXIgYW4gZXJyb3Igb2NjdXJyZWQgb3IgQ1VSTEVfT0sgaWYgfGxlbnwgd2FzIHJlYWQuICovCnN0YXRpYyBDVVJMY29kZQpzb2NrZXRfcmVhZChjdXJsX3NvY2tldF90IGZkLCB2b2lkICp0bywgc2l6ZV90IGxlbikKewogIGNoYXIgKnRvX3AgPSB0bzsKICBDVVJMY29kZSByZXN1bHQ7CiAgc3NpemVfdCBucmVhZDsKCiAgd2hpbGUobGVuID4gMCkgewogICAgcmVzdWx0ID0gQ3VybF9yZWFkX3BsYWluKGZkLCB0b19wLCBsZW4sICZucmVhZCk7CiAgICBpZighcmVzdWx0KSB7CiAgICAgIGxlbiAtPSBucmVhZDsKICAgICAgdG9fcCArPSBucmVhZDsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBGSVhNRTogV2UgYXJlIGRvaW5nIGEgYnVzeSB3YWl0ICovCiAgICAgIGlmKHJlc3VsdCA9PSBDVVJMRV9BR0FJTikKICAgICAgICBjb250aW51ZTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICB9CiAgcmV0dXJuIENVUkxFX09LOwp9CgoKLyogV3JpdGUgfGxlbnwgYnl0ZXMgZnJvbSB0aGUgYnVmZmVyIHx0b3wgdG8gdGhlIHNvY2tldCB8ZmR8LiBSZXR1cm4gYQogICBDVVJMY29kZSBzYXlpbmcgd2hldGhlciBhbiBlcnJvciBvY2N1cnJlZCBvciBDVVJMRV9PSyBpZiB8bGVufCB3YXMKICAgd3JpdHRlbi4gKi8Kc3RhdGljIENVUkxjb2RlCnNvY2tldF93cml0ZShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGN1cmxfc29ja2V0X3QgZmQsIGNvbnN0IHZvaWQgKnRvLAogICAgICAgICAgICAgc2l6ZV90IGxlbikKewogIGNvbnN0IGNoYXIgKnRvX3AgPSB0bzsKICBDVVJMY29kZSByZXN1bHQ7CiAgc3NpemVfdCB3cml0dGVuOwoKICB3aGlsZShsZW4gPiAwKSB7CiAgICByZXN1bHQgPSBDdXJsX3dyaXRlX3BsYWluKGNvbm4sIGZkLCB0b19wLCBsZW4sICZ3cml0dGVuKTsKICAgIGlmKCFyZXN1bHQpIHsKICAgICAgbGVuIC09IHdyaXR0ZW47CiAgICAgIHRvX3AgKz0gd3JpdHRlbjsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBGSVhNRTogV2UgYXJlIGRvaW5nIGEgYnVzeSB3YWl0ICovCiAgICAgIGlmKHJlc3VsdCA9PSBDVVJMRV9BR0FJTikKICAgICAgICBjb250aW51ZTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICB9CiAgcmV0dXJuIENVUkxFX09LOwp9CgpzdGF0aWMgQ1VSTGNvZGUgcmVhZF9kYXRhKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJsX3NvY2tldF90IGZkLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBrcmI1YnVmZmVyICpidWYpCnsKICBpbnQgbGVuOwogIHZvaWQgKnRtcCA9IE5VTEw7CiAgQ1VSTGNvZGUgcmVzdWx0OwoKICByZXN1bHQgPSBzb2NrZXRfcmVhZChmZCwgJmxlbiwgc2l6ZW9mKGxlbikpOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIGlmKGxlbikgewogICAgLyogb25seSByZWFsbG9jIGlmIHRoZXJlIHdhcyBhIGxlbmd0aCAqLwogICAgbGVuID0gbnRvaGwobGVuKTsKICAgIHRtcCA9IEN1cmxfc2FmZXJlYWxsb2MoYnVmLT5kYXRhLCBsZW4pOwogIH0KICBpZih0bXAgPT0gTlVMTCkKICAgIHJldHVybiBDVVJMRV9PVVRfT0ZfTUVNT1JZOwoKICBidWYtPmRhdGEgPSB0bXA7CiAgcmVzdWx0ID0gc29ja2V0X3JlYWQoZmQsIGJ1Zi0+ZGF0YSwgbGVuKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwogIGJ1Zi0+c2l6ZSA9IGNvbm4tPm1lY2gtPmRlY29kZShjb25uLT5hcHBfZGF0YSwgYnVmLT5kYXRhLCBsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4tPmRhdGFfcHJvdCwgY29ubik7CiAgYnVmLT5pbmRleCA9IDA7CiAgcmV0dXJuIENVUkxFX09LOwp9CgpzdGF0aWMgc2l6ZV90CmJ1ZmZlcl9yZWFkKHN0cnVjdCBrcmI1YnVmZmVyICpidWYsIHZvaWQgKmRhdGEsIHNpemVfdCBsZW4pCnsKICBpZihidWYtPnNpemUgLSBidWYtPmluZGV4IDwgbGVuKQogICAgbGVuID0gYnVmLT5zaXplIC0gYnVmLT5pbmRleDsKICBtZW1jcHkoZGF0YSwgKGNoYXIgKilidWYtPmRhdGEgKyBidWYtPmluZGV4LCBsZW4pOwogIGJ1Zi0+aW5kZXggKz0gbGVuOwogIHJldHVybiBsZW47Cn0KCi8qIE1hdGNoZXMgQ3VybF9yZWN2IHNpZ25hdHVyZSAqLwpzdGF0aWMgc3NpemVfdCBzZWNfcmVjdihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBzb2NraW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKmJ1ZmZlciwgc2l6ZV90IGxlbiwgQ1VSTGNvZGUgKmVycikKewogIHNpemVfdCBieXRlc19yZWFkOwogIHNpemVfdCB0b3RhbF9yZWFkID0gMDsKICBjdXJsX3NvY2tldF90IGZkID0gY29ubi0+c29ja1tzb2NraW5kZXhdOwoKICAqZXJyID0gQ1VSTEVfT0s7CgogIC8qIEhhbmRsZSBjbGVhciB0ZXh0IHJlc3BvbnNlLiAqLwogIGlmKGNvbm4tPnNlY19jb21wbGV0ZSA9PSAwIHx8IGNvbm4tPmRhdGFfcHJvdCA9PSBQUk9UX0NMRUFSKQogICAgICByZXR1cm4gcmVhZChmZCwgYnVmZmVyLCBsZW4pOwoKICBpZihjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcpIHsKICAgIGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyA9IDA7CiAgICByZXR1cm4gMDsKICB9CgogIGJ5dGVzX3JlYWQgPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbik7CiAgbGVuIC09IGJ5dGVzX3JlYWQ7CiAgdG90YWxfcmVhZCArPSBieXRlc19yZWFkOwogIGJ1ZmZlciArPSBieXRlc19yZWFkOwoKICB3aGlsZShsZW4gPiAwKSB7CiAgICBpZihyZWFkX2RhdGEoY29ubiwgZmQsICZjb25uLT5pbl9idWZmZXIpKQogICAgICByZXR1cm4gLTE7CiAgICBpZihjb25uLT5pbl9idWZmZXIuc2l6ZSA9PSAwKSB7CiAgICAgIGlmKGJ5dGVzX3JlYWQgPiAwKQogICAgICAgIGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyA9IDE7CiAgICAgIHJldHVybiBieXRlc19yZWFkOwogICAgfQogICAgYnl0ZXNfcmVhZCA9IGJ1ZmZlcl9yZWFkKCZjb25uLT5pbl9idWZmZXIsIGJ1ZmZlciwgbGVuKTsKICAgIGxlbiAtPSBieXRlc19yZWFkOwogICAgdG90YWxfcmVhZCArPSBieXRlc19yZWFkOwogICAgYnVmZmVyICs9IGJ5dGVzX3JlYWQ7CiAgfQogIC8qIEZJWE1FOiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8KICByZXR1cm4gdG90YWxfcmVhZDsKfQoKLyogU2VuZCB8bGVuZ3RofCBieXRlcyBmcm9tIHxmcm9tfCB0byB0aGUgfGZkfCBzb2NrZXQgdGFraW5nIGNhcmUgb2YgZW5jb2RpbmcKICAgYW5kIG5lZ29jaWF0aW5nIHdpdGggdGhlIHNlcnZlci4gfGZyb218IGNhbiBiZSBOVUxMLiAqLwovKiBGSVhNRTogV2UgZG9uJ3QgY2hlY2sgZm9yIGVycm9ycyBub3IgcmVwb3J0IGFueSEgKi8Kc3RhdGljIHZvaWQgZG9fc2VjX3NlbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjdXJsX3NvY2tldF90IGZkLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpmcm9tLCBpbnQgbGVuZ3RoKQp7CiAgaW50IGJ5dGVzLCBodG9ubF9ieXRlczsgLyogMzItYml0IGludGVnZXJzIGZvciBodG9ubCAqLwogIGNoYXIgKmJ1ZmZlciA9IE5VTEw7CiAgY2hhciAqY21kX2J1ZmZlcjsKICBzaXplX3QgY21kX3NpemUgPSAwOwogIENVUkxjb2RlIGVycm9yOwogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBwcm90X2xldmVsID0gY29ubi0+ZGF0YV9wcm90OwogIGJvb2wgaXNjbWQgPSAocHJvdF9sZXZlbCA9PSBQUk9UX0NNRCk/VFJVRTpGQUxTRTsKCiAgREVCVUdBU1NFUlQocHJvdF9sZXZlbCA+IFBST1RfTk9ORSAmJiBwcm90X2xldmVsIDwgUFJPVF9MQVNUKTsKCiAgaWYoaXNjbWQpIHsKICAgIGlmKCFzdHJuY21wKGZyb20sICJQQVNTICIsIDUpIHx8ICFzdHJuY21wKGZyb20sICJBQ0NUICIsIDUpKQogICAgICBwcm90X2xldmVsID0gUFJPVF9QUklWQVRFOwogICAgZWxzZQogICAgICBwcm90X2xldmVsID0gY29ubi0+Y29tbWFuZF9wcm90OwogIH0KICBieXRlcyA9IGNvbm4tPm1lY2gtPmVuY29kZShjb25uLT5hcHBfZGF0YSwgZnJvbSwgbGVuZ3RoLCBwcm90X2xldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICoqKSZidWZmZXIpOwogIGlmKCFidWZmZXIgfHwgYnl0ZXMgPD0gMCkKICAgIHJldHVybjsgLyogZXJyb3IgKi8KCiAgaWYoaXNjbWQpIHsKICAgIGVycm9yID0gQ3VybF9iYXNlNjRfZW5jb2RlKGNvbm4tPmRhdGEsIGJ1ZmZlciwgY3VybHhfc2l0b3V6KGJ5dGVzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjbWRfYnVmZmVyLCAmY21kX3NpemUpOwogICAgaWYoZXJyb3IpIHsKICAgICAgZnJlZShidWZmZXIpOwogICAgICByZXR1cm47IC8qIGVycm9yICovCiAgICB9CiAgICBpZihjbWRfc2l6ZSA+IDApIHsKICAgICAgc3RhdGljIGNvbnN0IGNoYXIgKmVuYyA9ICJFTkMgIjsKICAgICAgc3RhdGljIGNvbnN0IGNoYXIgKm1pYyA9ICJNSUMgIjsKICAgICAgaWYocHJvdF9sZXZlbCA9PSBQUk9UX1BSSVZBVEUpCiAgICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBlbmMsIDQpOwogICAgICBlbHNlCiAgICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBtaWMsIDQpOwoKICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBjbWRfYnVmZmVyLCBjbWRfc2l6ZSk7CiAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgIlxyXG4iLCAyKTsKICAgICAgaW5mb2YoY29ubi0+ZGF0YSwgIlNlbmQ6ICVzJXNcbiIsIHByb3RfbGV2ZWwgPT0gUFJPVF9QUklWQVRFP2VuYzptaWMsCiAgICAgICAgICAgIGNtZF9idWZmZXIpOwogICAgICBmcmVlKGNtZF9idWZmZXIpOwogICAgfQogIH0KICBlbHNlIHsKICAgIGh0b25sX2J5dGVzID0gaHRvbmwoYnl0ZXMpOwogICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCAmaHRvbmxfYnl0ZXMsIHNpemVvZihodG9ubF9ieXRlcykpOwogICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBidWZmZXIsIGN1cmx4X3NpdG91eihieXRlcykpOwogIH0KICBmcmVlKGJ1ZmZlcik7Cn0KCnN0YXRpYyBzc2l6ZV90IHNlY193cml0ZShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGN1cmxfc29ja2V0X3QgZmQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpidWZmZXIsIHNpemVfdCBsZW5ndGgpCnsKICBzc2l6ZV90IHR4ID0gMCwgbGVuID0gY29ubi0+YnVmZmVyX3NpemU7CgogIGxlbiAtPSBjb25uLT5tZWNoLT5vdmVyaGVhZChjb25uLT5hcHBfZGF0YSwgY29ubi0+ZGF0YV9wcm90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJseF9zenRvc2kobGVuKSk7CiAgaWYobGVuIDw9IDApCiAgICBsZW4gPSBsZW5ndGg7CiAgd2hpbGUobGVuZ3RoKSB7CiAgICBpZihsZW5ndGggPCAoc2l6ZV90KWxlbikKICAgICAgbGVuID0gbGVuZ3RoOwoKICAgIGRvX3NlY19zZW5kKGNvbm4sIGZkLCBidWZmZXIsIGN1cmx4X3N6dG9zaShsZW4pKTsKICAgIGxlbmd0aCAtPSBsZW47CiAgICBidWZmZXIgKz0gbGVuOwogICAgdHggKz0gbGVuOwogIH0KICByZXR1cm4gdHg7Cn0KCi8qIE1hdGNoZXMgQ3VybF9zZW5kIHNpZ25hdHVyZSAqLwpzdGF0aWMgc3NpemVfdCBzZWNfc2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBzb2NraW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmJ1ZmZlciwgc2l6ZV90IGxlbiwgQ1VSTGNvZGUgKmVycikKewogIGN1cmxfc29ja2V0X3QgZmQgPSBjb25uLT5zb2NrW3NvY2tpbmRleF07CiAgKmVyciA9IENVUkxFX09LOwogIHJldHVybiBzZWNfd3JpdGUoY29ubiwgZmQsIGJ1ZmZlciwgbGVuKTsKfQoKaW50IEN1cmxfc2VjX3JlYWRfbXNnKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY2hhciAqYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsKQp7CiAgLyogZGVjb2RlZF9sZW4gc2hvdWxkIGJlIHNpemVfdCBvciBzc2l6ZV90IGJ1dCBjb25uLT5tZWNoLT5kZWNvZGUgcmV0dXJucyBhbgogICAgIGludCAqLwogIGludCBkZWNvZGVkX2xlbjsKICBjaGFyICpidWY7CiAgaW50IHJldF9jb2RlID0gMDsKICBzaXplX3QgZGVjb2RlZF9zeiA9IDA7CiAgQ1VSTGNvZGUgZXJyb3I7CgogIGlmKCFjb25uLT5tZWNoKQogICAgLyogbm90IGluaXRpdGFsaXplZCwgcmV0dXJuIGVycm9yICovCiAgICByZXR1cm4gLTE7CgogIERFQlVHQVNTRVJUKGxldmVsID4gUFJPVF9OT05FICYmIGxldmVsIDwgUFJPVF9MQVNUKTsKCiAgZXJyb3IgPSBDdXJsX2Jhc2U2NF9kZWNvZGUoYnVmZmVyICsgNCwgKHVuc2lnbmVkIGNoYXIgKiopJmJ1ZiwgJmRlY29kZWRfc3opOwogIGlmKGVycm9yIHx8IGRlY29kZWRfc3ogPT0gMCkKICAgIHJldHVybiAtMTsKCiAgaWYoZGVjb2RlZF9zeiA+IChzaXplX3QpSU5UX01BWCkgewogICAgZnJlZShidWYpOwogICAgcmV0dXJuIC0xOwogIH0KICBkZWNvZGVkX2xlbiA9IGN1cmx4X3V6dG9zaShkZWNvZGVkX3N6KTsKCiAgZGVjb2RlZF9sZW4gPSBjb25uLT5tZWNoLT5kZWNvZGUoY29ubi0+YXBwX2RhdGEsIGJ1ZiwgZGVjb2RlZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWwsIGNvbm4pOwogIGlmKGRlY29kZWRfbGVuIDw9IDApIHsKICAgIGZyZWUoYnVmKTsKICAgIHJldHVybiAtMTsKICB9CgogIGlmKGNvbm4tPmRhdGEtPnNldC52ZXJib3NlKSB7CiAgICBidWZbZGVjb2RlZF9sZW5dID0gJ1xuJzsKICAgIEN1cmxfZGVidWcoY29ubi0+ZGF0YSwgQ1VSTElORk9fSEVBREVSX0lOLCBidWYsIGRlY29kZWRfbGVuICsgMSwgY29ubik7CiAgfQoKICBidWZbZGVjb2RlZF9sZW5dID0gJ1wwJzsKICBpZihkZWNvZGVkX2xlbiA8PSAzKQogICAgLyogc3VzcGljaW91c2x5IHNob3J0ICovCiAgICByZXR1cm4gMDsKCiAgaWYoYnVmWzNdICE9ICctJykKICAgIC8qIHNhZmUgdG8gaWdub3JlIHJldHVybiBjb2RlICovCiAgICAodm9pZClzc2NhbmYoYnVmLCAiJWQiLCAmcmV0X2NvZGUpOwoKICBpZihidWZbZGVjb2RlZF9sZW4gLSAxXSA9PSAnXG4nKQogICAgYnVmW2RlY29kZWRfbGVuIC0gMV0gPSAnXDAnOwogIC8qIEZJWE1FOiBJcyB8YnVmZmVyfCBsZW5ndGggYWx3YXlzIGdyZWF0ZXIgdGhhbiB8ZGVjb2RlZF9sZW58PyAqLwogIHN0cmNweShidWZmZXIsIGJ1Zik7CiAgZnJlZShidWYpOwogIHJldHVybiByZXRfY29kZTsKfQoKLyogRklYTUU6IFRoZSBlcnJvciBjb2RlIHJldHVybmVkIGhlcmUgaXMgbmV2ZXIgY2hlY2tlZC4gKi8Kc3RhdGljIGludCBzZWNfc2V0X3Byb3RlY3Rpb25fbGV2ZWwoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IGNvZGU7CiAgY2hhciAqcGJzejsKICBzdGF0aWMgdW5zaWduZWQgaW50IGJ1ZmZlcl9zaXplID0gMSA8PCAyMDsgLyogMTA0ODU3NiAqLwogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbCA9IGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90OwoKICBERUJVR0FTU0VSVChsZXZlbCA+IFBST1RfTk9ORSAmJiBsZXZlbCA8IFBST1RfTEFTVCk7CgogIGlmKCFjb25uLT5zZWNfY29tcGxldGUpIHsKICAgIGluZm9mKGNvbm4tPmRhdGEsICJUcnlpbmcgdG8gY2hhbmdlIHRoZSBwcm90ZWN0aW9uIGxldmVsIGFmdGVyIHRoZSIKICAgICAgICAgICAgICAgICAgICAgICJjb21wbGV0aW9uIG9mIHRoZSBkYXRhIGV4Y2hhbmdlLlxuIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICAvKiBCYWlsIG91dCBpZiB3ZSB0cnkgdG8gc2V0IHVwIHRoZSBzYW1lIGxldmVsICovCiAgaWYoY29ubi0+ZGF0YV9wcm90ID09IGxldmVsKQogICAgcmV0dXJuIDA7CgogIGlmKGxldmVsKSB7CiAgICBjb2RlID0gZnRwX3NlbmRfY29tbWFuZChjb25uLCAiUEJTWiAldSIsIGJ1ZmZlcl9zaXplKTsKICAgIGlmKGNvZGUgPCAwKQogICAgICByZXR1cm4gLTE7CgogICAgaWYoY29kZS8xMDAgIT0gMikgewogICAgICBmYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIHNldCB0aGUgcHJvdGVjdGlvbidzIGJ1ZmZlciBzaXplLiIpOwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBjb25uLT5idWZmZXJfc2l6ZSA9IGJ1ZmZlcl9zaXplOwoKICAgIHBic3ogPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiUEJTWj0iKTsKICAgIGlmKHBic3opIHsKICAgICAgLyogaWdub3JlIHJldHVybiBjb2RlLCB1c2UgZGVmYXVsdCB2YWx1ZSBpZiBpdCBmYWlscyAqLwogICAgICAodm9pZClzc2NhbmYocGJzeiwgIlBCU1o9JXUiLCAmYnVmZmVyX3NpemUpOwogICAgICBpZihidWZmZXJfc2l6ZSA8IGNvbm4tPmJ1ZmZlcl9zaXplKQogICAgICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gYnVmZmVyX3NpemU7CiAgICB9CiAgfQoKICAvKiBOb3cgdHJ5IHRvIG5lZ2lvY2lhdGUgdGhlIHByb3RlY3Rpb24gbGV2ZWwuICovCiAgY29kZSA9IGZ0cF9zZW5kX2NvbW1hbmQoY29ubiwgIlBST1QgJWMiLCBsZXZlbF90b19jaGFyKGxldmVsKSk7CgogIGlmKGNvZGUgPCAwKQogICAgcmV0dXJuIC0xOwoKICBpZihjb2RlLzEwMCAhPSAyKSB7CiAgICBmYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIHNldCB0aGUgcHJvdGVjdGlvbiBsZXZlbC4iKTsKICAgIHJldHVybiAtMTsKICB9CgogIGNvbm4tPmRhdGFfcHJvdCA9IGxldmVsOwogIGlmKGxldmVsID09IFBST1RfUFJJVkFURSkKICAgIGNvbm4tPmNvbW1hbmRfcHJvdCA9IGxldmVsOwoKICByZXR1cm4gMDsKfQoKaW50CkN1cmxfc2VjX3JlcXVlc3RfcHJvdChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNvbnN0IGNoYXIgKmxldmVsKQp7CiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGwgPSBuYW1lX3RvX2xldmVsKGxldmVsKTsKICBpZihsID09IFBST1RfTk9ORSkKICAgIHJldHVybiAtMTsKICBERUJVR0FTU0VSVChsID4gUFJPVF9OT05FICYmIGwgPCBQUk9UX0xBU1QpOwogIGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90ID0gbDsKICByZXR1cm4gMDsKfQoKc3RhdGljIENVUkxjb2RlIGNob29zZV9tZWNoKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGludCByZXQ7CiAgc3RydWN0IEN1cmxfZWFzeSAqZGF0YSA9IGNvbm4tPmRhdGE7CiAgdm9pZCAqdG1wX2FsbG9jYXRpb247CiAgY29uc3Qgc3RydWN0IEN1cmxfc2VjX2NsaWVudF9tZWNoICptZWNoID0gJkN1cmxfa3JiNV9jbGllbnRfbWVjaDsKCiAgdG1wX2FsbG9jYXRpb24gPSByZWFsbG9jKGNvbm4tPmFwcF9kYXRhLCBtZWNoLT5zaXplKTsKICBpZih0bXBfYWxsb2NhdGlvbiA9PSBOVUxMKSB7CiAgICBmYWlsZihkYXRhLCAiRmFpbGVkIHJlYWxsb2Mgb2Ygc2l6ZSAldSIsIG1lY2gtPnNpemUpOwogICAgbWVjaCA9IE5VTEw7CiAgICByZXR1cm4gQ1VSTEVfT1VUX09GX01FTU9SWTsKICB9CiAgY29ubi0+YXBwX2RhdGEgPSB0bXBfYWxsb2NhdGlvbjsKCiAgaWYobWVjaC0+aW5pdCkgewogICAgcmV0ID0gbWVjaC0+aW5pdChjb25uLT5hcHBfZGF0YSk7CiAgICBpZihyZXQpIHsKICAgICAgaW5mb2YoZGF0YSwgIkZhaWxlZCBpbml0aWFsaXphdGlvbiBmb3IgJXMuIFNraXBwaW5nIGl0LlxuIiwKICAgICAgICAgICAgbWVjaC0+bmFtZSk7CiAgICAgIHJldHVybiBDVVJMRV9GQUlMRURfSU5JVDsKICAgIH0KICB9CgogIGluZm9mKGRhdGEsICJUcnlpbmcgbWVjaGFuaXNtICVzLi4uXG4iLCBtZWNoLT5uYW1lKTsKICByZXQgPSBmdHBfc2VuZF9jb21tYW5kKGNvbm4sICJBVVRIICVzIiwgbWVjaC0+bmFtZSk7CiAgaWYocmV0IDwgMCkKICAgIC8qIEZJWE1FOiBUaGlzIGVycm9yIGlzIHRvbyBnZW5lcmljIGJ1dCBpdCBpcyBPSyBmb3Igbm93LiAqLwogICAgcmV0dXJuIENVUkxFX0NPVUxETlRfQ09OTkVDVDsKCiAgaWYocmV0LzEwMCAhPSAzKSB7CiAgICBzd2l0Y2gocmV0KSB7CiAgICBjYXNlIDUwNDoKICAgICAgaW5mb2YoZGF0YSwgIk1lY2hhbmlzbSAlcyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2ZXIgKHNlcnZlciAiCiAgICAgICAgICAgICJyZXR1cm5lZCBmdHAgY29kZTogNTA0KS5cbiIsIG1lY2gtPm5hbWUpOwogICAgICBicmVhazsKICAgIGNhc2UgNTM0OgogICAgICBpbmZvZihkYXRhLCAiTWVjaGFuaXNtICVzIHdhcyByZWplY3RlZCBieSB0aGUgc2VydmVyIChzZXJ2ZXIgcmV0dXJuZWQgIgogICAgICAgICAgICAiZnRwIGNvZGU6IDUzNCkuXG4iLCBtZWNoLT5uYW1lKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBpZihyZXQvMTAwID09IDUpIHsKICAgICAgICBpbmZvZihkYXRhLCAic2VydmVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHNlY3VyaXR5IGV4dGVuc2lvbnNcbiIpOwogICAgICAgIHJldHVybiBDVVJMRV9VU0VfU1NMX0ZBSUxFRDsKICAgICAgfQogICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBDVVJMRV9MT0dJTl9ERU5JRUQ7CiAgfQoKICAvKiBBdXRoZW50aWNhdGUgKi8KICByZXQgPSBtZWNoLT5hdXRoKGNvbm4tPmFwcF9kYXRhLCBjb25uKTsKCiAgaWYocmV0ICE9IEFVVEhfQ09OVElOVUUpIHsKICAgIGlmKHJldCAhPSBBVVRIX09LKSB7CiAgICAgIC8qIE1lY2hhbmlzbSBoYXMgZHVtcGVkIHRoZSBlcnJvciB0byBzdGRlcnIsIGRvbid0IGVycm9yIGhlcmUuICovCiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIERFQlVHQVNTRVJUKHJldCA9PSBBVVRIX09LKTsKCiAgICBjb25uLT5tZWNoID0gbWVjaDsKICAgIGNvbm4tPnNlY19jb21wbGV0ZSA9IDE7CiAgICBjb25uLT5yZWN2W0ZJUlNUU09DS0VUXSA9IHNlY19yZWN2OwogICAgY29ubi0+c2VuZFtGSVJTVFNPQ0tFVF0gPSBzZWNfc2VuZDsKICAgIGNvbm4tPnJlY3ZbU0VDT05EQVJZU09DS0VUXSA9IHNlY19yZWN2OwogICAgY29ubi0+c2VuZFtTRUNPTkRBUllTT0NLRVRdID0gc2VjX3NlbmQ7CiAgICBjb25uLT5jb21tYW5kX3Byb3QgPSBQUk9UX1NBRkU7CiAgICAvKiBTZXQgdGhlIHJlcXVlc3RlZCBwcm90ZWN0aW9uIGxldmVsICovCiAgICAvKiBCTE9DS0lORyAqLwogICAgKHZvaWQpc2VjX3NldF9wcm90ZWN0aW9uX2xldmVsKGNvbm4pOwogIH0KCiAgcmV0dXJuIENVUkxFX09LOwp9CgpDVVJMY29kZQpDdXJsX3NlY19sb2dpbihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICByZXR1cm4gY2hvb3NlX21lY2goY29ubik7Cn0KCgp2b2lkCkN1cmxfc2VjX2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpZihjb25uLT5tZWNoICE9IE5VTEwgJiYgY29ubi0+bWVjaC0+ZW5kKQogICAgY29ubi0+bWVjaC0+ZW5kKGNvbm4tPmFwcF9kYXRhKTsKICBmcmVlKGNvbm4tPmFwcF9kYXRhKTsKICBjb25uLT5hcHBfZGF0YSA9IE5VTEw7CiAgaWYoY29ubi0+aW5fYnVmZmVyLmRhdGEpIHsKICAgIGZyZWUoY29ubi0+aW5fYnVmZmVyLmRhdGEpOwogICAgY29ubi0+aW5fYnVmZmVyLmRhdGEgPSBOVUxMOwogICAgY29ubi0+aW5fYnVmZmVyLnNpemUgPSAwOwogICAgY29ubi0+aW5fYnVmZmVyLmluZGV4ID0gMDsKICAgIC8qIEZJWE1FOiBJcyB0aGlzIHJlYWxseSBuZWVkZWQ/ICovCiAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAwOwogIH0KICBjb25uLT5zZWNfY29tcGxldGUgPSAwOwogIGNvbm4tPmRhdGFfcHJvdCA9IFBST1RfQ0xFQVI7CiAgY29ubi0+bWVjaCA9IE5VTEw7Cn0KCiNlbmRpZiAvKiBIQVZFX0dTU0FQSSAqLwoKI2VuZGlmIC8qIENVUkxfRElTQUJMRV9GVFAgKi8K