LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTksIDIwMTcgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEgLSAyMDE5LCBEYW5pZWwgU3RlbmJlcmcsIDxkYW5pZWxAaGF4eC5zZT4sIGV0IGFsLgogKgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAiY3VybF9zZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBIQVZFX0dTU0FQSQoKI2lmZGVmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCgojaW5jbHVkZSA8bGltaXRzLmg+CgojaW5jbHVkZSAidXJsZGF0YS5oIgojaW5jbHVkZSAiY3VybF9iYXNlNjQuaCIKI2luY2x1ZGUgImN1cmxfbWVtb3J5LmgiCiNpbmNsdWRlICJjdXJsX3NlYy5oIgojaW5jbHVkZSAiZnRwLmgiCiNpbmNsdWRlICJzZW5kZi5oIgojaW5jbHVkZSAic3RyY2FzZS5oIgojaW5jbHVkZSAid2Fybmxlc3MuaCIKI2luY2x1ZGUgInN0cmR1cC5oIgovKiBUaGUgbGFzdCAzICNpbmNsdWRlIGZpbGVzIHNob3VsZCBiZSBpbiB0aGlzIG9yZGVyICovCiNpbmNsdWRlICJjdXJsX3ByaW50Zi5oIgojaW5jbHVkZSAiY3VybF9tZW1vcnkuaCIKI2luY2x1ZGUgIm1lbWRlYnVnLmgiCgpzdGF0aWMgY29uc3Qgc3RydWN0IHsKICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgbGV2ZWw7CiAgY29uc3QgY2hhciAqbmFtZTsKfSBsZXZlbF9uYW1lc1tdID0gewogIHsgUFJPVF9DTEVBUiwgImNsZWFyIiB9LAogIHsgUFJPVF9TQUZFLCAic2FmZSIgfSwKICB7IFBST1RfQ09ORklERU5USUFMLCAiY29uZmlkZW50aWFsIiB9LAogIHsgUFJPVF9QUklWQVRFLCAicHJpdmF0ZSIgfQp9OwoKc3RhdGljIGVudW0gcHJvdGVjdGlvbl9sZXZlbApuYW1lX3RvX2xldmVsKGNvbnN0IGNoYXIgKm5hbWUpCnsKICBpbnQgaTsKICBmb3IoaSA9IDA7IGkgPCAoaW50KXNpemVvZihsZXZlbF9uYW1lcykvKGludClzaXplb2YobGV2ZWxfbmFtZXNbMF0pOyBpKyspCiAgICBpZihjaGVja3ByZWZpeChuYW1lLCBsZXZlbF9uYW1lc1tpXS5uYW1lKSkKICAgICAgcmV0dXJuIGxldmVsX25hbWVzW2ldLmxldmVsOwogIHJldHVybiBQUk9UX05PTkU7Cn0KCi8qIENvbnZlcnQgYSBwcm90b2NvbCB8bGV2ZWx8IHRvIGl0cyBjaGFyIHJlcHJlc2VudGF0aW9uLgogICBXZSB0YWtlIGFuIGludCB0byBjYXRjaCBwcm9ncmFtbWluZyBtaXN0YWtlcy4gKi8Kc3RhdGljIGNoYXIgbGV2ZWxfdG9fY2hhcihpbnQgbGV2ZWwpCnsKICBzd2l0Y2gobGV2ZWwpIHsKICBjYXNlIFBST1RfQ0xFQVI6CiAgICByZXR1cm4gJ0MnOwogIGNhc2UgUFJPVF9TQUZFOgogICAgcmV0dXJuICdTJzsKICBjYXNlIFBST1RfQ09ORklERU5USUFMOgogICAgcmV0dXJuICdFJzsKICBjYXNlIFBST1RfUFJJVkFURToKICAgIHJldHVybiAnUCc7CiAgY2FzZSBQUk9UX0NNRDoKICAgIC8qIEZhbGwgdGhyb3VnaCAqLwogIGRlZmF1bHQ6CiAgICAvKiBUaG9zZSAyIGNhc2VzIHNob3VsZCBub3QgYmUgcmVhY2hlZCEgKi8KICAgIGJyZWFrOwogIH0KICBERUJVR0FTU0VSVCgwKTsKICAvKiBEZWZhdWx0IHRvIHRoZSBtb3N0IHNlY3VyZSBhbHRlcm5hdGl2ZS4gKi8KICByZXR1cm4gJ1AnOwp9CgovKiBTZW5kIGFuIEZUUCBjb21tYW5kIGRlZmluZWQgYnkgfG1lc3NhZ2V8IGFuZCB0aGUgb3B0aW9uYWwgYXJndW1lbnRzLiBUaGUKICAgZnVuY3Rpb24gcmV0dXJucyB0aGUgZnRwX2NvZGUuIElmIGFuIGVycm9yIG9jY3VycywgLTEgaXMgcmV0dXJuZWQuICovCnN0YXRpYyBpbnQgZnRwX3NlbmRfY29tbWFuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNvbnN0IGNoYXIgKm1lc3NhZ2UsIC4uLikKewogIGludCBmdHBfY29kZTsKICBzc2l6ZV90IG5yZWFkID0gMDsKICB2YV9saXN0IGFyZ3M7CiAgY2hhciBwcmludF9idWZmZXJbNTBdOwoKICB2YV9zdGFydChhcmdzLCBtZXNzYWdlKTsKICBtdnNucHJpbnRmKHByaW50X2J1ZmZlciwgc2l6ZW9mKHByaW50X2J1ZmZlciksIG1lc3NhZ2UsIGFyZ3MpOwogIHZhX2VuZChhcmdzKTsKCiAgaWYoQ3VybF9mdHBzZW5kKGNvbm4sIHByaW50X2J1ZmZlcikpIHsKICAgIGZ0cF9jb2RlID0gLTE7CiAgfQogIGVsc2UgewogICAgaWYoQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sICZmdHBfY29kZSkpCiAgICAgIGZ0cF9jb2RlID0gLTE7CiAgfQoKICAodm9pZClucmVhZDsgLyogVW51c2VkICovCiAgcmV0dXJuIGZ0cF9jb2RlOwp9CgovKiBSZWFkIHxsZW58IGZyb20gdGhlIHNvY2tldCB8ZmR8IGFuZCBzdG9yZSBpdCBpbiB8dG98LiBSZXR1cm4gYSBDVVJMY29kZQogICBzYXlpbmcgd2hldGhlciBhbiBlcnJvciBvY2N1cnJlZCBvciBDVVJMRV9PSyBpZiB8bGVufCB3YXMgcmVhZC4gKi8Kc3RhdGljIENVUkxjb2RlCnNvY2tldF9yZWFkKGN1cmxfc29ja2V0X3QgZmQsIHZvaWQgKnRvLCBzaXplX3QgbGVuKQp7CiAgY2hhciAqdG9fcCA9IHRvOwogIENVUkxjb2RlIHJlc3VsdDsKICBzc2l6ZV90IG5yZWFkID0gMDsKCiAgd2hpbGUobGVuID4gMCkgewogICAgcmVzdWx0ID0gQ3VybF9yZWFkX3BsYWluKGZkLCB0b19wLCBsZW4sICZucmVhZCk7CiAgICBpZighcmVzdWx0KSB7CiAgICAgIGxlbiAtPSBucmVhZDsKICAgICAgdG9fcCArPSBucmVhZDsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBGSVhNRTogV2UgYXJlIGRvaW5nIGEgYnVzeSB3YWl0ICovCiAgICAgIGlmKHJlc3VsdCA9PSBDVVJMRV9BR0FJTikKICAgICAgICBjb250aW51ZTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICB9CiAgcmV0dXJuIENVUkxFX09LOwp9CgoKLyogV3JpdGUgfGxlbnwgYnl0ZXMgZnJvbSB0aGUgYnVmZmVyIHx0b3wgdG8gdGhlIHNvY2tldCB8ZmR8LiBSZXR1cm4gYQogICBDVVJMY29kZSBzYXlpbmcgd2hldGhlciBhbiBlcnJvciBvY2N1cnJlZCBvciBDVVJMRV9PSyBpZiB8bGVufCB3YXMKICAgd3JpdHRlbi4gKi8Kc3RhdGljIENVUkxjb2RlCnNvY2tldF93cml0ZShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGN1cmxfc29ja2V0X3QgZmQsIGNvbnN0IHZvaWQgKnRvLAogICAgICAgICAgICAgc2l6ZV90IGxlbikKewogIGNvbnN0IGNoYXIgKnRvX3AgPSB0bzsKICBDVVJMY29kZSByZXN1bHQ7CiAgc3NpemVfdCB3cml0dGVuOwoKICB3aGlsZShsZW4gPiAwKSB7CiAgICByZXN1bHQgPSBDdXJsX3dyaXRlX3BsYWluKGNvbm4sIGZkLCB0b19wLCBsZW4sICZ3cml0dGVuKTsKICAgIGlmKCFyZXN1bHQpIHsKICAgICAgbGVuIC09IHdyaXR0ZW47CiAgICAgIHRvX3AgKz0gd3JpdHRlbjsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBGSVhNRTogV2UgYXJlIGRvaW5nIGEgYnVzeSB3YWl0ICovCiAgICAgIGlmKHJlc3VsdCA9PSBDVVJMRV9BR0FJTikKICAgICAgICBjb250aW51ZTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICB9CiAgcmV0dXJuIENVUkxFX09LOwp9CgpzdGF0aWMgQ1VSTGNvZGUgcmVhZF9kYXRhKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJsX3NvY2tldF90IGZkLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBrcmI1YnVmZmVyICpidWYpCnsKICBpbnQgbGVuOwogIHZvaWQgKnRtcCA9IE5VTEw7CiAgQ1VSTGNvZGUgcmVzdWx0OwoKICByZXN1bHQgPSBzb2NrZXRfcmVhZChmZCwgJmxlbiwgc2l6ZW9mKGxlbikpOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CgogIGlmKGxlbikgewogICAgLyogb25seSByZWFsbG9jIGlmIHRoZXJlIHdhcyBhIGxlbmd0aCAqLwogICAgbGVuID0gbnRvaGwobGVuKTsKICAgIHRtcCA9IEN1cmxfc2FmZXJlYWxsb2MoYnVmLT5kYXRhLCBsZW4pOwogIH0KICBpZih0bXAgPT0gTlVMTCkKICAgIHJldHVybiBDVVJMRV9PVVRfT0ZfTUVNT1JZOwoKICBidWYtPmRhdGEgPSB0bXA7CiAgcmVzdWx0ID0gc29ja2V0X3JlYWQoZmQsIGJ1Zi0+ZGF0YSwgbGVuKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwogIGJ1Zi0+c2l6ZSA9IGNvbm4tPm1lY2gtPmRlY29kZShjb25uLT5hcHBfZGF0YSwgYnVmLT5kYXRhLCBsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4tPmRhdGFfcHJvdCwgY29ubik7CiAgYnVmLT5pbmRleCA9IDA7CiAgcmV0dXJuIENVUkxFX09LOwp9CgpzdGF0aWMgc2l6ZV90CmJ1ZmZlcl9yZWFkKHN0cnVjdCBrcmI1YnVmZmVyICpidWYsIHZvaWQgKmRhdGEsIHNpemVfdCBsZW4pCnsKICBpZihidWYtPnNpemUgLSBidWYtPmluZGV4IDwgbGVuKQogICAgbGVuID0gYnVmLT5zaXplIC0gYnVmLT5pbmRleDsKICBtZW1jcHkoZGF0YSwgKGNoYXIgKilidWYtPmRhdGEgKyBidWYtPmluZGV4LCBsZW4pOwogIGJ1Zi0+aW5kZXggKz0gbGVuOwogIHJldHVybiBsZW47Cn0KCi8qIE1hdGNoZXMgQ3VybF9yZWN2IHNpZ25hdHVyZSAqLwpzdGF0aWMgc3NpemVfdCBzZWNfcmVjdihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBzb2NraW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKmJ1ZmZlciwgc2l6ZV90IGxlbiwgQ1VSTGNvZGUgKmVycikKewogIHNpemVfdCBieXRlc19yZWFkOwogIHNpemVfdCB0b3RhbF9yZWFkID0gMDsKICBjdXJsX3NvY2tldF90IGZkID0gY29ubi0+c29ja1tzb2NraW5kZXhdOwoKICAqZXJyID0gQ1VSTEVfT0s7CgogIC8qIEhhbmRsZSBjbGVhciB0ZXh0IHJlc3BvbnNlLiAqLwogIGlmKGNvbm4tPnNlY19jb21wbGV0ZSA9PSAwIHx8IGNvbm4tPmRhdGFfcHJvdCA9PSBQUk9UX0NMRUFSKQogICAgICByZXR1cm4gcmVhZChmZCwgYnVmZmVyLCBsZW4pOwoKICBpZihjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcpIHsKICAgIGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyA9IDA7CiAgICByZXR1cm4gMDsKICB9CgogIGJ5dGVzX3JlYWQgPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbik7CiAgbGVuIC09IGJ5dGVzX3JlYWQ7CiAgdG90YWxfcmVhZCArPSBieXRlc19yZWFkOwogIGJ1ZmZlciArPSBieXRlc19yZWFkOwoKICB3aGlsZShsZW4gPiAwKSB7CiAgICBpZihyZWFkX2RhdGEoY29ubiwgZmQsICZjb25uLT5pbl9idWZmZXIpKQogICAgICByZXR1cm4gLTE7CiAgICBpZihjb25uLT5pbl9idWZmZXIuc2l6ZSA9PSAwKSB7CiAgICAgIGlmKGJ5dGVzX3JlYWQgPiAwKQogICAgICAgIGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyA9IDE7CiAgICAgIHJldHVybiBieXRlc19yZWFkOwogICAgfQogICAgYnl0ZXNfcmVhZCA9IGJ1ZmZlcl9yZWFkKCZjb25uLT5pbl9idWZmZXIsIGJ1ZmZlciwgbGVuKTsKICAgIGxlbiAtPSBieXRlc19yZWFkOwogICAgdG90YWxfcmVhZCArPSBieXRlc19yZWFkOwogICAgYnVmZmVyICs9IGJ5dGVzX3JlYWQ7CiAgfQogIC8qIEZJWE1FOiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8KICByZXR1cm4gdG90YWxfcmVhZDsKfQoKLyogU2VuZCB8bGVuZ3RofCBieXRlcyBmcm9tIHxmcm9tfCB0byB0aGUgfGZkfCBzb2NrZXQgdGFraW5nIGNhcmUgb2YgZW5jb2RpbmcKICAgYW5kIG5lZ29jaWF0aW5nIHdpdGggdGhlIHNlcnZlci4gfGZyb218IGNhbiBiZSBOVUxMLiAqLwovKiBGSVhNRTogV2UgZG9uJ3QgY2hlY2sgZm9yIGVycm9ycyBub3IgcmVwb3J0IGFueSEgKi8Kc3RhdGljIHZvaWQgZG9fc2VjX3NlbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjdXJsX3NvY2tldF90IGZkLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpmcm9tLCBpbnQgbGVuZ3RoKQp7CiAgaW50IGJ5dGVzLCBodG9ubF9ieXRlczsgLyogMzItYml0IGludGVnZXJzIGZvciBodG9ubCAqLwogIGNoYXIgKmJ1ZmZlciA9IE5VTEw7CiAgY2hhciAqY21kX2J1ZmZlcjsKICBzaXplX3QgY21kX3NpemUgPSAwOwogIENVUkxjb2RlIGVycm9yOwogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBwcm90X2xldmVsID0gY29ubi0+ZGF0YV9wcm90OwogIGJvb2wgaXNjbWQgPSAocHJvdF9sZXZlbCA9PSBQUk9UX0NNRCk/VFJVRTpGQUxTRTsKCiAgREVCVUdBU1NFUlQocHJvdF9sZXZlbCA+IFBST1RfTk9ORSAmJiBwcm90X2xldmVsIDwgUFJPVF9MQVNUKTsKCiAgaWYoaXNjbWQpIHsKICAgIGlmKCFzdHJuY21wKGZyb20sICJQQVNTICIsIDUpIHx8ICFzdHJuY21wKGZyb20sICJBQ0NUICIsIDUpKQogICAgICBwcm90X2xldmVsID0gUFJPVF9QUklWQVRFOwogICAgZWxzZQogICAgICBwcm90X2xldmVsID0gY29ubi0+Y29tbWFuZF9wcm90OwogIH0KICBieXRlcyA9IGNvbm4tPm1lY2gtPmVuY29kZShjb25uLT5hcHBfZGF0YSwgZnJvbSwgbGVuZ3RoLCBwcm90X2xldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICoqKSZidWZmZXIpOwogIGlmKCFidWZmZXIgfHwgYnl0ZXMgPD0gMCkKICAgIHJldHVybjsgLyogZXJyb3IgKi8KCiAgaWYoaXNjbWQpIHsKICAgIGVycm9yID0gQ3VybF9iYXNlNjRfZW5jb2RlKGNvbm4tPmRhdGEsIGJ1ZmZlciwgY3VybHhfc2l0b3V6KGJ5dGVzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjbWRfYnVmZmVyLCAmY21kX3NpemUpOwogICAgaWYoZXJyb3IpIHsKICAgICAgZnJlZShidWZmZXIpOwogICAgICByZXR1cm47IC8qIGVycm9yICovCiAgICB9CiAgICBpZihjbWRfc2l6ZSA+IDApIHsKICAgICAgc3RhdGljIGNvbnN0IGNoYXIgKmVuYyA9ICJFTkMgIjsKICAgICAgc3RhdGljIGNvbnN0IGNoYXIgKm1pYyA9ICJNSUMgIjsKICAgICAgaWYocHJvdF9sZXZlbCA9PSBQUk9UX1BSSVZBVEUpCiAgICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBlbmMsIDQpOwogICAgICBlbHNlCiAgICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBtaWMsIDQpOwoKICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBjbWRfYnVmZmVyLCBjbWRfc2l6ZSk7CiAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgIlxyXG4iLCAyKTsKICAgICAgaW5mb2YoY29ubi0+ZGF0YSwgIlNlbmQ6ICVzJXNcbiIsIHByb3RfbGV2ZWwgPT0gUFJPVF9QUklWQVRFP2VuYzptaWMsCiAgICAgICAgICAgIGNtZF9idWZmZXIpOwogICAgICBmcmVlKGNtZF9idWZmZXIpOwogICAgfQogIH0KICBlbHNlIHsKICAgIGh0b25sX2J5dGVzID0gaHRvbmwoYnl0ZXMpOwogICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCAmaHRvbmxfYnl0ZXMsIHNpemVvZihodG9ubF9ieXRlcykpOwogICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBidWZmZXIsIGN1cmx4X3NpdG91eihieXRlcykpOwogIH0KICBmcmVlKGJ1ZmZlcik7Cn0KCnN0YXRpYyBzc2l6ZV90IHNlY193cml0ZShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGN1cmxfc29ja2V0X3QgZmQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpidWZmZXIsIHNpemVfdCBsZW5ndGgpCnsKICBzc2l6ZV90IHR4ID0gMCwgbGVuID0gY29ubi0+YnVmZmVyX3NpemU7CgogIGxlbiAtPSBjb25uLT5tZWNoLT5vdmVyaGVhZChjb25uLT5hcHBfZGF0YSwgY29ubi0+ZGF0YV9wcm90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJseF9zenRvc2kobGVuKSk7CiAgaWYobGVuIDw9IDApCiAgICBsZW4gPSBsZW5ndGg7CiAgd2hpbGUobGVuZ3RoKSB7CiAgICBpZihsZW5ndGggPCAoc2l6ZV90KWxlbikKICAgICAgbGVuID0gbGVuZ3RoOwoKICAgIGRvX3NlY19zZW5kKGNvbm4sIGZkLCBidWZmZXIsIGN1cmx4X3N6dG9zaShsZW4pKTsKICAgIGxlbmd0aCAtPSBsZW47CiAgICBidWZmZXIgKz0gbGVuOwogICAgdHggKz0gbGVuOwogIH0KICByZXR1cm4gdHg7Cn0KCi8qIE1hdGNoZXMgQ3VybF9zZW5kIHNpZ25hdHVyZSAqLwpzdGF0aWMgc3NpemVfdCBzZWNfc2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBzb2NraW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmJ1ZmZlciwgc2l6ZV90IGxlbiwgQ1VSTGNvZGUgKmVycikKewogIGN1cmxfc29ja2V0X3QgZmQgPSBjb25uLT5zb2NrW3NvY2tpbmRleF07CiAgKmVyciA9IENVUkxFX09LOwogIHJldHVybiBzZWNfd3JpdGUoY29ubiwgZmQsIGJ1ZmZlciwgbGVuKTsKfQoKaW50IEN1cmxfc2VjX3JlYWRfbXNnKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY2hhciAqYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsKQp7CiAgLyogZGVjb2RlZF9sZW4gc2hvdWxkIGJlIHNpemVfdCBvciBzc2l6ZV90IGJ1dCBjb25uLT5tZWNoLT5kZWNvZGUgcmV0dXJucyBhbgogICAgIGludCAqLwogIGludCBkZWNvZGVkX2xlbjsKICBjaGFyICpidWY7CiAgaW50IHJldF9jb2RlID0gMDsKICBzaXplX3QgZGVjb2RlZF9zeiA9IDA7CiAgQ1VSTGNvZGUgZXJyb3I7CgogIGlmKCFjb25uLT5tZWNoKQogICAgLyogbm90IGluaXRpdGFsaXplZCwgcmV0dXJuIGVycm9yICovCiAgICByZXR1cm4gLTE7CgogIERFQlVHQVNTRVJUKGxldmVsID4gUFJPVF9OT05FICYmIGxldmVsIDwgUFJPVF9MQVNUKTsKCiAgZXJyb3IgPSBDdXJsX2Jhc2U2NF9kZWNvZGUoYnVmZmVyICsgNCwgKHVuc2lnbmVkIGNoYXIgKiopJmJ1ZiwgJmRlY29kZWRfc3opOwogIGlmKGVycm9yIHx8IGRlY29kZWRfc3ogPT0gMCkKICAgIHJldHVybiAtMTsKCiAgaWYoZGVjb2RlZF9zeiA+IChzaXplX3QpSU5UX01BWCkgewogICAgZnJlZShidWYpOwogICAgcmV0dXJuIC0xOwogIH0KICBkZWNvZGVkX2xlbiA9IGN1cmx4X3V6dG9zaShkZWNvZGVkX3N6KTsKCiAgZGVjb2RlZF9sZW4gPSBjb25uLT5tZWNoLT5kZWNvZGUoY29ubi0+YXBwX2RhdGEsIGJ1ZiwgZGVjb2RlZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWwsIGNvbm4pOwogIGlmKGRlY29kZWRfbGVuIDw9IDApIHsKICAgIGZyZWUoYnVmKTsKICAgIHJldHVybiAtMTsKICB9CgogIGlmKGNvbm4tPmRhdGEtPnNldC52ZXJib3NlKSB7CiAgICBidWZbZGVjb2RlZF9sZW5dID0gJ1xuJzsKICAgIEN1cmxfZGVidWcoY29ubi0+ZGF0YSwgQ1VSTElORk9fSEVBREVSX0lOLCBidWYsIGRlY29kZWRfbGVuICsgMSk7CiAgfQoKICBidWZbZGVjb2RlZF9sZW5dID0gJ1wwJzsKICBpZihkZWNvZGVkX2xlbiA8PSAzKQogICAgLyogc3VzcGljaW91c2x5IHNob3J0ICovCiAgICByZXR1cm4gMDsKCiAgaWYoYnVmWzNdICE9ICctJykKICAgIC8qIHNhZmUgdG8gaWdub3JlIHJldHVybiBjb2RlICovCiAgICAodm9pZClzc2NhbmYoYnVmLCAiJWQiLCAmcmV0X2NvZGUpOwoKICBpZihidWZbZGVjb2RlZF9sZW4gLSAxXSA9PSAnXG4nKQogICAgYnVmW2RlY29kZWRfbGVuIC0gMV0gPSAnXDAnOwogIC8qIEZJWE1FOiBJcyB8YnVmZmVyfCBsZW5ndGggYWx3YXlzIGdyZWF0ZXIgdGhhbiB8ZGVjb2RlZF9sZW58PyAqLwogIHN0cmNweShidWZmZXIsIGJ1Zik7CiAgZnJlZShidWYpOwogIHJldHVybiByZXRfY29kZTsKfQoKLyogRklYTUU6IFRoZSBlcnJvciBjb2RlIHJldHVybmVkIGhlcmUgaXMgbmV2ZXIgY2hlY2tlZC4gKi8Kc3RhdGljIGludCBzZWNfc2V0X3Byb3RlY3Rpb25fbGV2ZWwoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IGNvZGU7CiAgY2hhciAqcGJzejsKICBzdGF0aWMgdW5zaWduZWQgaW50IGJ1ZmZlcl9zaXplID0gMSA8PCAyMDsgLyogMTA0ODU3NiAqLwogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbCA9IGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90OwoKICBERUJVR0FTU0VSVChsZXZlbCA+IFBST1RfTk9ORSAmJiBsZXZlbCA8IFBST1RfTEFTVCk7CgogIGlmKCFjb25uLT5zZWNfY29tcGxldGUpIHsKICAgIGluZm9mKGNvbm4tPmRhdGEsICJUcnlpbmcgdG8gY2hhbmdlIHRoZSBwcm90ZWN0aW9uIGxldmVsIGFmdGVyIHRoZSIKICAgICAgICAgICAgICAgICAgICAgICIgY29tcGxldGlvbiBvZiB0aGUgZGF0YSBleGNoYW5nZS5cbiIpOwogICAgcmV0dXJuIC0xOwogIH0KCiAgLyogQmFpbCBvdXQgaWYgd2UgdHJ5IHRvIHNldCB1cCB0aGUgc2FtZSBsZXZlbCAqLwogIGlmKGNvbm4tPmRhdGFfcHJvdCA9PSBsZXZlbCkKICAgIHJldHVybiAwOwoKICBpZihsZXZlbCkgewogICAgY29kZSA9IGZ0cF9zZW5kX2NvbW1hbmQoY29ubiwgIlBCU1ogJXUiLCBidWZmZXJfc2l6ZSk7CiAgICBpZihjb2RlIDwgMCkKICAgICAgcmV0dXJuIC0xOwoKICAgIGlmKGNvZGUvMTAwICE9IDIpIHsKICAgICAgZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBzZXQgdGhlIHByb3RlY3Rpb24ncyBidWZmZXIgc2l6ZS4iKTsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgY29ubi0+YnVmZmVyX3NpemUgPSBidWZmZXJfc2l6ZTsKCiAgICBwYnN6ID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlBCU1o9Iik7CiAgICBpZihwYnN6KSB7CiAgICAgIC8qIGlnbm9yZSByZXR1cm4gY29kZSwgdXNlIGRlZmF1bHQgdmFsdWUgaWYgaXQgZmFpbHMgKi8KICAgICAgKHZvaWQpc3NjYW5mKHBic3osICJQQlNaPSV1IiwgJmJ1ZmZlcl9zaXplKTsKICAgICAgaWYoYnVmZmVyX3NpemUgPCBjb25uLT5idWZmZXJfc2l6ZSkKICAgICAgICBjb25uLT5idWZmZXJfc2l6ZSA9IGJ1ZmZlcl9zaXplOwogICAgfQogIH0KCiAgLyogTm93IHRyeSB0byBuZWdpb2NpYXRlIHRoZSBwcm90ZWN0aW9uIGxldmVsLiAqLwogIGNvZGUgPSBmdHBfc2VuZF9jb21tYW5kKGNvbm4sICJQUk9UICVjIiwgbGV2ZWxfdG9fY2hhcihsZXZlbCkpOwoKICBpZihjb2RlIDwgMCkKICAgIHJldHVybiAtMTsKCiAgaWYoY29kZS8xMDAgIT0gMikgewogICAgZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBzZXQgdGhlIHByb3RlY3Rpb24gbGV2ZWwuIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICBjb25uLT5kYXRhX3Byb3QgPSBsZXZlbDsKICBpZihsZXZlbCA9PSBQUk9UX1BSSVZBVEUpCiAgICBjb25uLT5jb21tYW5kX3Byb3QgPSBsZXZlbDsKCiAgcmV0dXJuIDA7Cn0KCmludApDdXJsX3NlY19yZXF1ZXN0X3Byb3Qoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjb25zdCBjaGFyICpsZXZlbCkKewogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsID0gbmFtZV90b19sZXZlbChsZXZlbCk7CiAgaWYobCA9PSBQUk9UX05PTkUpCiAgICByZXR1cm4gLTE7CiAgREVCVUdBU1NFUlQobCA+IFBST1RfTk9ORSAmJiBsIDwgUFJPVF9MQVNUKTsKICBjb25uLT5yZXF1ZXN0X2RhdGFfcHJvdCA9IGw7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBDVVJMY29kZSBjaG9vc2VfbWVjaChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgcmV0OwogIHN0cnVjdCBDdXJsX2Vhc3kgKmRhdGEgPSBjb25uLT5kYXRhOwogIHZvaWQgKnRtcF9hbGxvY2F0aW9uOwogIGNvbnN0IHN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCAqbWVjaCA9ICZDdXJsX2tyYjVfY2xpZW50X21lY2g7CgogIHRtcF9hbGxvY2F0aW9uID0gcmVhbGxvYyhjb25uLT5hcHBfZGF0YSwgbWVjaC0+c2l6ZSk7CiAgaWYodG1wX2FsbG9jYXRpb24gPT0gTlVMTCkgewogICAgZmFpbGYoZGF0YSwgIkZhaWxlZCByZWFsbG9jIG9mIHNpemUgJXp1IiwgbWVjaC0+c2l6ZSk7CiAgICBtZWNoID0gTlVMTDsKICAgIHJldHVybiBDVVJMRV9PVVRfT0ZfTUVNT1JZOwogIH0KICBjb25uLT5hcHBfZGF0YSA9IHRtcF9hbGxvY2F0aW9uOwoKICBpZihtZWNoLT5pbml0KSB7CiAgICByZXQgPSBtZWNoLT5pbml0KGNvbm4tPmFwcF9kYXRhKTsKICAgIGlmKHJldCkgewogICAgICBpbmZvZihkYXRhLCAiRmFpbGVkIGluaXRpYWxpemF0aW9uIGZvciAlcy4gU2tpcHBpbmcgaXQuXG4iLAogICAgICAgICAgICBtZWNoLT5uYW1lKTsKICAgICAgcmV0dXJuIENVUkxFX0ZBSUxFRF9JTklUOwogICAgfQogIH0KCiAgaW5mb2YoZGF0YSwgIlRyeWluZyBtZWNoYW5pc20gJXMuLi5cbiIsIG1lY2gtPm5hbWUpOwogIHJldCA9IGZ0cF9zZW5kX2NvbW1hbmQoY29ubiwgIkFVVEggJXMiLCBtZWNoLT5uYW1lKTsKICBpZihyZXQgPCAwKQogICAgLyogRklYTUU6IFRoaXMgZXJyb3IgaXMgdG9vIGdlbmVyaWMgYnV0IGl0IGlzIE9LIGZvciBub3cuICovCiAgICByZXR1cm4gQ1VSTEVfQ09VTEROVF9DT05ORUNUOwoKICBpZihyZXQvMTAwICE9IDMpIHsKICAgIHN3aXRjaChyZXQpIHsKICAgIGNhc2UgNTA0OgogICAgICBpbmZvZihkYXRhLCAiTWVjaGFuaXNtICVzIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlciAoc2VydmVyICIKICAgICAgICAgICAgInJldHVybmVkIGZ0cCBjb2RlOiA1MDQpLlxuIiwgbWVjaC0+bmFtZSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSA1MzQ6CiAgICAgIGluZm9mKGRhdGEsICJNZWNoYW5pc20gJXMgd2FzIHJlamVjdGVkIGJ5IHRoZSBzZXJ2ZXIgKHNlcnZlciByZXR1cm5lZCAiCiAgICAgICAgICAgICJmdHAgY29kZTogNTM0KS5cbiIsIG1lY2gtPm5hbWUpOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGlmKHJldC8xMDAgPT0gNSkgewogICAgICAgIGluZm9mKGRhdGEsICJzZXJ2ZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUgc2VjdXJpdHkgZXh0ZW5zaW9uc1xuIik7CiAgICAgICAgcmV0dXJuIENVUkxFX1VTRV9TU0xfRkFJTEVEOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIENVUkxFX0xPR0lOX0RFTklFRDsKICB9CgogIC8qIEF1dGhlbnRpY2F0ZSAqLwogIHJldCA9IG1lY2gtPmF1dGgoY29ubi0+YXBwX2RhdGEsIGNvbm4pOwoKICBpZihyZXQgIT0gQVVUSF9DT05USU5VRSkgewogICAgaWYocmV0ICE9IEFVVEhfT0spIHsKICAgICAgLyogTWVjaGFuaXNtIGhhcyBkdW1wZWQgdGhlIGVycm9yIHRvIHN0ZGVyciwgZG9uJ3QgZXJyb3IgaGVyZS4gKi8KICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgREVCVUdBU1NFUlQocmV0ID09IEFVVEhfT0spOwoKICAgIGNvbm4tPm1lY2ggPSBtZWNoOwogICAgY29ubi0+c2VjX2NvbXBsZXRlID0gMTsKICAgIGNvbm4tPnJlY3ZbRklSU1RTT0NLRVRdID0gc2VjX3JlY3Y7CiAgICBjb25uLT5zZW5kW0ZJUlNUU09DS0VUXSA9IHNlY19zZW5kOwogICAgY29ubi0+cmVjdltTRUNPTkRBUllTT0NLRVRdID0gc2VjX3JlY3Y7CiAgICBjb25uLT5zZW5kW1NFQ09OREFSWVNPQ0tFVF0gPSBzZWNfc2VuZDsKICAgIGNvbm4tPmNvbW1hbmRfcHJvdCA9IFBST1RfU0FGRTsKICAgIC8qIFNldCB0aGUgcmVxdWVzdGVkIHByb3RlY3Rpb24gbGV2ZWwgKi8KICAgIC8qIEJMT0NLSU5HICovCiAgICAodm9pZClzZWNfc2V0X3Byb3RlY3Rpb25fbGV2ZWwoY29ubik7CiAgfQoKICByZXR1cm4gQ1VSTEVfT0s7Cn0KCkNVUkxjb2RlCkN1cmxfc2VjX2xvZ2luKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIHJldHVybiBjaG9vc2VfbWVjaChjb25uKTsKfQoKCnZvaWQKQ3VybF9zZWNfZW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGlmKGNvbm4tPm1lY2ggIT0gTlVMTCAmJiBjb25uLT5tZWNoLT5lbmQpCiAgICBjb25uLT5tZWNoLT5lbmQoY29ubi0+YXBwX2RhdGEpOwogIGZyZWUoY29ubi0+YXBwX2RhdGEpOwogIGNvbm4tPmFwcF9kYXRhID0gTlVMTDsKICBpZihjb25uLT5pbl9idWZmZXIuZGF0YSkgewogICAgZnJlZShjb25uLT5pbl9idWZmZXIuZGF0YSk7CiAgICBjb25uLT5pbl9idWZmZXIuZGF0YSA9IE5VTEw7CiAgICBjb25uLT5pbl9idWZmZXIuc2l6ZSA9IDA7CiAgICBjb25uLT5pbl9idWZmZXIuaW5kZXggPSAwOwogICAgLyogRklYTUU6IElzIHRoaXMgcmVhbGx5IG5lZWRlZD8gKi8KICAgIGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyA9IDA7CiAgfQogIGNvbm4tPnNlY19jb21wbGV0ZSA9IDA7CiAgY29ubi0+ZGF0YV9wcm90ID0gUFJPVF9DTEVBUjsKICBjb25uLT5tZWNoID0gTlVMTDsKfQoKI2VuZGlmIC8qIEhBVkVfR1NTQVBJICovCgojZW5kaWYgLyogQ1VSTF9ESVNBQkxFX0ZUUCAqLwo=