LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTksIDIwMTMgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEgLSAyMDEzLCBEYW5pZWwgU3RlbmJlcmcsIDxkYW5pZWxAaGF4eC5zZT4sIGV0IGFsLgogKgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAiY3VybF9zZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBIQVZFX0dTU0FQSQoKI2lmZGVmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCgojaWZkZWYgSEFWRV9MSU1JVFNfSAojaW5jbHVkZSA8bGltaXRzLmg+CiNlbmRpZgoKI2luY2x1ZGUgInVybGRhdGEuaCIKI2luY2x1ZGUgImN1cmxfYmFzZTY0LmgiCiNpbmNsdWRlICJjdXJsX21lbW9yeS5oIgojaW5jbHVkZSAiY3VybF9zZWMuaCIKI2luY2x1ZGUgImZ0cC5oIgojaW5jbHVkZSAic2VuZGYuaCIKI2luY2x1ZGUgInJhd3N0ci5oIgojaW5jbHVkZSAid2Fybmxlc3MuaCIKCi8qIFRoZSBsYXN0ICNpbmNsdWRlIGZpbGUgc2hvdWxkIGJlOiAqLwojaW5jbHVkZSAibWVtZGVidWcuaCIKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgewogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbDsKICBjb25zdCBjaGFyICpuYW1lOwp9IGxldmVsX25hbWVzW10gPSB7CiAgeyBQUk9UX0NMRUFSLCAiY2xlYXIiIH0sCiAgeyBQUk9UX1NBRkUsICJzYWZlIiB9LAogIHsgUFJPVF9DT05GSURFTlRJQUwsICJjb25maWRlbnRpYWwiIH0sCiAgeyBQUk9UX1BSSVZBVEUsICJwcml2YXRlIiB9Cn07CgpzdGF0aWMgZW51bSBwcm90ZWN0aW9uX2xldmVsCm5hbWVfdG9fbGV2ZWwoY29uc3QgY2hhciAqbmFtZSkKewogIGludCBpOwogIGZvcihpID0gMDsgaSA8IChpbnQpc2l6ZW9mKGxldmVsX25hbWVzKS8oaW50KXNpemVvZihsZXZlbF9uYW1lc1swXSk7IGkrKykKICAgIGlmKGNoZWNrcHJlZml4KG5hbWUsIGxldmVsX25hbWVzW2ldLm5hbWUpKQogICAgICByZXR1cm4gbGV2ZWxfbmFtZXNbaV0ubGV2ZWw7CiAgcmV0dXJuIFBST1RfTk9ORTsKfQoKLyogQ29udmVydCBhIHByb3RvY29sIHxsZXZlbHwgdG8gaXRzIGNoYXIgcmVwcmVzZW50YXRpb24uCiAgIFdlIHRha2UgYW4gaW50IHRvIGNhdGNoIHByb2dyYW1taW5nIG1pc3Rha2VzLiAqLwpzdGF0aWMgY2hhciBsZXZlbF90b19jaGFyKGludCBsZXZlbCkgewogIHN3aXRjaChsZXZlbCkgewogIGNhc2UgUFJPVF9DTEVBUjoKICAgIHJldHVybiAnQyc7CiAgY2FzZSBQUk9UX1NBRkU6CiAgICByZXR1cm4gJ1MnOwogIGNhc2UgUFJPVF9DT05GSURFTlRJQUw6CiAgICByZXR1cm4gJ0UnOwogIGNhc2UgUFJPVF9QUklWQVRFOgogICAgcmV0dXJuICdQJzsKICBjYXNlIFBST1RfQ01EOgogICAgLyogRmFsbCB0aHJvdWdoICovCiAgZGVmYXVsdDoKICAgIC8qIFRob3NlIDIgY2FzZXMgc2hvdWxkIG5vdCBiZSByZWFjaGVkISAqLwogICAgYnJlYWs7CiAgfQogIERFQlVHQVNTRVJUKDApOwogIC8qIERlZmF1bHQgdG8gdGhlIG1vc3Qgc2VjdXJlIGFsdGVybmF0aXZlLiAqLwogIHJldHVybiAnUCc7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgQ3VybF9zZWNfY2xpZW50X21lY2ggKiBjb25zdCBtZWNoc1tdID0gewojaWZkZWYgSEFWRV9HU1NBUEkKICAmQ3VybF9rcmI1X2NsaWVudF9tZWNoLAojZW5kaWYKICBOVUxMCn07CgovKiBTZW5kIGFuIEZUUCBjb21tYW5kIGRlZmluZWQgYnkgfG1lc3NhZ2V8IGFuZCB0aGUgb3B0aW9uYWwgYXJndW1lbnRzLiBUaGUKICAgZnVuY3Rpb24gcmV0dXJucyB0aGUgZnRwX2NvZGUuIElmIGFuIGVycm9yIG9jY3VycywgLTEgaXMgcmV0dXJuZWQuICovCnN0YXRpYyBpbnQgZnRwX3NlbmRfY29tbWFuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNvbnN0IGNoYXIgKm1lc3NhZ2UsIC4uLikKewogIGludCBmdHBfY29kZTsKICBzc2l6ZV90IG5yZWFkOwogIHZhX2xpc3QgYXJnczsKICBjaGFyIHByaW50X2J1ZmZlcls1MF07CgogIHZhX3N0YXJ0KGFyZ3MsIG1lc3NhZ2UpOwogIHZzbnByaW50ZihwcmludF9idWZmZXIsIHNpemVvZihwcmludF9idWZmZXIpLCBtZXNzYWdlLCBhcmdzKTsKICB2YV9lbmQoYXJncyk7CgogIGlmKEN1cmxfZnRwc2VuZGYoY29ubiwgcHJpbnRfYnVmZmVyKSAhPSBDVVJMRV9PSykgewogICAgZnRwX2NvZGUgPSAtMTsKICB9CiAgZWxzZSB7CiAgICBpZihDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgJmZ0cF9jb2RlKSAhPSBDVVJMRV9PSykKICAgICAgZnRwX2NvZGUgPSAtMTsKICB9CgogICh2b2lkKW5yZWFkOyAvKiBVbnVzZWQgKi8KICByZXR1cm4gZnRwX2NvZGU7Cn0KCi8qIFJlYWQgfGxlbnwgZnJvbSB0aGUgc29ja2V0IHxmZHwgYW5kIHN0b3JlIGl0IGluIHx0b3wuIFJldHVybiBhIENVUkxjb2RlCiAgIHNheWluZyB3aGV0aGVyIGFuIGVycm9yIG9jY3VycmVkIG9yIENVUkxFX09LIGlmIHxsZW58IHdhcyByZWFkLiAqLwpzdGF0aWMgQ1VSTGNvZGUKc29ja2V0X3JlYWQoY3VybF9zb2NrZXRfdCBmZCwgdm9pZCAqdG8sIHNpemVfdCBsZW4pCnsKICBjaGFyICp0b19wID0gdG87CiAgQ1VSTGNvZGUgY29kZTsKICBzc2l6ZV90IG5yZWFkOwoKICB3aGlsZShsZW4gPiAwKSB7CiAgICBjb2RlID0gQ3VybF9yZWFkX3BsYWluKGZkLCB0b19wLCBsZW4sICZucmVhZCk7CiAgICBpZihjb2RlID09IENVUkxFX09LKSB7CiAgICAgIGxlbiAtPSBucmVhZDsKICAgICAgdG9fcCArPSBucmVhZDsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBGSVhNRTogV2UgYXJlIGRvaW5nIGEgYnVzeSB3YWl0ICovCiAgICAgIGlmKGNvZGUgPT0gQ1VSTEVfQUdBSU4pCiAgICAgICAgY29udGludWU7CiAgICAgIHJldHVybiBjb2RlOwogICAgfQogIH0KICByZXR1cm4gQ1VSTEVfT0s7Cn0KCgovKiBXcml0ZSB8bGVufCBieXRlcyBmcm9tIHRoZSBidWZmZXIgfHRvfCB0byB0aGUgc29ja2V0IHxmZHwuIFJldHVybiBhCiAgIENVUkxjb2RlIHNheWluZyB3aGV0aGVyIGFuIGVycm9yIG9jY3VycmVkIG9yIENVUkxFX09LIGlmIHxsZW58IHdhcwogICB3cml0dGVuLiAqLwpzdGF0aWMgQ1VSTGNvZGUKc29ja2V0X3dyaXRlKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY3VybF9zb2NrZXRfdCBmZCwgY29uc3Qgdm9pZCAqdG8sCiAgICAgICAgICAgICBzaXplX3QgbGVuKQp7CiAgY29uc3QgY2hhciAqdG9fcCA9IHRvOwogIENVUkxjb2RlIGNvZGU7CiAgc3NpemVfdCB3cml0dGVuOwoKICB3aGlsZShsZW4gPiAwKSB7CiAgICBjb2RlID0gQ3VybF93cml0ZV9wbGFpbihjb25uLCBmZCwgdG9fcCwgbGVuLCAmd3JpdHRlbik7CiAgICBpZihjb2RlID09IENVUkxFX09LKSB7CiAgICAgIGxlbiAtPSB3cml0dGVuOwogICAgICB0b19wICs9IHdyaXR0ZW47CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogRklYTUU6IFdlIGFyZSBkb2luZyBhIGJ1c3kgd2FpdCAqLwogICAgICBpZihjb2RlID09IENVUkxFX0FHQUlOKQogICAgICAgIGNvbnRpbnVlOwogICAgICByZXR1cm4gY29kZTsKICAgIH0KICB9CiAgcmV0dXJuIENVUkxFX09LOwp9CgpzdGF0aWMgQ1VSTGNvZGUgcmVhZF9kYXRhKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJsX3NvY2tldF90IGZkLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBrcmI1YnVmZmVyICpidWYpCnsKICBpbnQgbGVuOwogIHZvaWQqIHRtcDsKICBDVVJMY29kZSByZXQ7CgogIHJldCA9IHNvY2tldF9yZWFkKGZkLCAmbGVuLCBzaXplb2YobGVuKSk7CiAgaWYocmV0ICE9IENVUkxFX09LKQogICAgcmV0dXJuIHJldDsKCiAgbGVuID0gbnRvaGwobGVuKTsKICB0bXAgPSByZWFsbG9jKGJ1Zi0+ZGF0YSwgbGVuKTsKICBpZih0bXAgPT0gTlVMTCkKICAgIHJldHVybiBDVVJMRV9PVVRfT0ZfTUVNT1JZOwoKICBidWYtPmRhdGEgPSB0bXA7CiAgcmV0ID0gc29ja2V0X3JlYWQoZmQsIGJ1Zi0+ZGF0YSwgbGVuKTsKICBpZihyZXQgIT0gQ1VSTEVfT0spCiAgICByZXR1cm4gcmV0OwogIGJ1Zi0+c2l6ZSA9IGNvbm4tPm1lY2gtPmRlY29kZShjb25uLT5hcHBfZGF0YSwgYnVmLT5kYXRhLCBsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4tPmRhdGFfcHJvdCwgY29ubik7CiAgYnVmLT5pbmRleCA9IDA7CiAgcmV0dXJuIENVUkxFX09LOwp9CgpzdGF0aWMgc2l6ZV90CmJ1ZmZlcl9yZWFkKHN0cnVjdCBrcmI1YnVmZmVyICpidWYsIHZvaWQgKmRhdGEsIHNpemVfdCBsZW4pCnsKICBpZihidWYtPnNpemUgLSBidWYtPmluZGV4IDwgbGVuKQogICAgbGVuID0gYnVmLT5zaXplIC0gYnVmLT5pbmRleDsKICBtZW1jcHkoZGF0YSwgKGNoYXIqKWJ1Zi0+ZGF0YSArIGJ1Zi0+aW5kZXgsIGxlbik7CiAgYnVmLT5pbmRleCArPSBsZW47CiAgcmV0dXJuIGxlbjsKfQoKLyogTWF0Y2hlcyBDdXJsX3JlY3Ygc2lnbmF0dXJlICovCnN0YXRpYyBzc2l6ZV90IHNlY19yZWN2KHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IHNvY2tpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqYnVmZmVyLCBzaXplX3QgbGVuLCBDVVJMY29kZSAqZXJyKQp7CiAgc2l6ZV90IGJ5dGVzX3JlYWQ7CiAgc2l6ZV90IHRvdGFsX3JlYWQgPSAwOwogIGN1cmxfc29ja2V0X3QgZmQgPSBjb25uLT5zb2NrW3NvY2tpbmRleF07CgogICplcnIgPSBDVVJMRV9PSzsKCiAgLyogSGFuZGxlIGNsZWFyIHRleHQgcmVzcG9uc2UuICovCiAgaWYoY29ubi0+c2VjX2NvbXBsZXRlID09IDAgfHwgY29ubi0+ZGF0YV9wcm90ID09IFBST1RfQ0xFQVIpCiAgICAgIHJldHVybiByZWFkKGZkLCBidWZmZXIsIGxlbik7CgogIGlmKGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZykgewogICAgY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnID0gMDsKICAgIHJldHVybiAwOwogIH0KCiAgYnl0ZXNfcmVhZCA9IGJ1ZmZlcl9yZWFkKCZjb25uLT5pbl9idWZmZXIsIGJ1ZmZlciwgbGVuKTsKICBsZW4gLT0gYnl0ZXNfcmVhZDsKICB0b3RhbF9yZWFkICs9IGJ5dGVzX3JlYWQ7CiAgYnVmZmVyICs9IGJ5dGVzX3JlYWQ7CgogIHdoaWxlKGxlbiA+IDApIHsKICAgIGlmKHJlYWRfZGF0YShjb25uLCBmZCwgJmNvbm4tPmluX2J1ZmZlcikgIT0gQ1VSTEVfT0spCiAgICAgIHJldHVybiAtMTsKICAgIGlmKGNvbm4tPmluX2J1ZmZlci5zaXplID09IDApIHsKICAgICAgaWYoYnl0ZXNfcmVhZCA+IDApCiAgICAgICAgY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnID0gMTsKICAgICAgcmV0dXJuIGJ5dGVzX3JlYWQ7CiAgICB9CiAgICBieXRlc19yZWFkID0gYnVmZmVyX3JlYWQoJmNvbm4tPmluX2J1ZmZlciwgYnVmZmVyLCBsZW4pOwogICAgbGVuIC09IGJ5dGVzX3JlYWQ7CiAgICB0b3RhbF9yZWFkICs9IGJ5dGVzX3JlYWQ7CiAgICBidWZmZXIgKz0gYnl0ZXNfcmVhZDsKICB9CiAgLyogRklYTUU6IENoZWNrIGZvciBvdmVyZmxvdyAqLwogIHJldHVybiB0b3RhbF9yZWFkOwp9CgovKiBTZW5kIHxsZW5ndGh8IGJ5dGVzIGZyb20gfGZyb218IHRvIHRoZSB8ZmR8IHNvY2tldCB0YWtpbmcgY2FyZSBvZiBlbmNvZGluZwogICBhbmQgbmVnb2NpYXRpbmcgd2l0aCB0aGUgc2VydmVyLiB8ZnJvbXwgY2FuIGJlIE5VTEwuICovCi8qIEZJWE1FOiBXZSBkb24ndCBjaGVjayBmb3IgZXJyb3JzIG5vciByZXBvcnQgYW55ISAqLwpzdGF0aWMgdm9pZCBkb19zZWNfc2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGN1cmxfc29ja2V0X3QgZmQsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmZyb20sIGludCBsZW5ndGgpCnsKICBpbnQgYnl0ZXMsIGh0b25sX2J5dGVzOyAvKiAzMi1iaXQgaW50ZWdlcnMgZm9yIGh0b25sICovCiAgY2hhciAqYnVmZmVyID0gTlVMTDsKICBjaGFyICpjbWRfYnVmZmVyOwogIHNpemVfdCBjbWRfc2l6ZSA9IDA7CiAgQ1VSTGNvZGUgZXJyb3I7CiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIHByb3RfbGV2ZWwgPSBjb25uLT5kYXRhX3Byb3Q7CiAgYm9vbCBpc2NtZCA9IChwcm90X2xldmVsID09IFBST1RfQ01EKT9UUlVFOkZBTFNFOwoKICBERUJVR0FTU0VSVChwcm90X2xldmVsID4gUFJPVF9OT05FICYmIHByb3RfbGV2ZWwgPCBQUk9UX0xBU1QpOwoKICBpZihpc2NtZCkgewogICAgaWYoIXN0cm5jbXAoZnJvbSwgIlBBU1MgIiwgNSkgfHwgIXN0cm5jbXAoZnJvbSwgIkFDQ1QgIiwgNSkpCiAgICAgIHByb3RfbGV2ZWwgPSBQUk9UX1BSSVZBVEU7CiAgICBlbHNlCiAgICAgIHByb3RfbGV2ZWwgPSBjb25uLT5jb21tYW5kX3Byb3Q7CiAgfQogIGJ5dGVzID0gY29ubi0+bWVjaC0+ZW5jb2RlKGNvbm4tPmFwcF9kYXRhLCBmcm9tLCBsZW5ndGgsIHByb3RfbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmYnVmZmVyLCBjb25uKTsKICBpZighYnVmZmVyIHx8IGJ5dGVzIDw9IDApCiAgICByZXR1cm47IC8qIGVycm9yICovCgogIGlmKGlzY21kKSB7CiAgICBlcnJvciA9IEN1cmxfYmFzZTY0X2VuY29kZShjb25uLT5kYXRhLCBidWZmZXIsIGN1cmx4X3NpdG91eihieXRlcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY21kX2J1ZmZlciwgJmNtZF9zaXplKTsKICAgIGlmKGVycm9yKSB7CiAgICAgIGZyZWUoYnVmZmVyKTsKICAgICAgcmV0dXJuOyAvKiBlcnJvciAqLwogICAgfQogICAgaWYoY21kX3NpemUgPiAwKSB7CiAgICAgIHN0YXRpYyBjb25zdCBjaGFyICplbmMgPSAiRU5DICI7CiAgICAgIHN0YXRpYyBjb25zdCBjaGFyICptaWMgPSAiTUlDICI7CiAgICAgIGlmKHByb3RfbGV2ZWwgPT0gUFJPVF9QUklWQVRFKQogICAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgZW5jLCA0KTsKICAgICAgZWxzZQogICAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgbWljLCA0KTsKCiAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgY21kX2J1ZmZlciwgY21kX3NpemUpOwogICAgICBzb2NrZXRfd3JpdGUoY29ubiwgZmQsICJcclxuIiwgMik7CiAgICAgIGluZm9mKGNvbm4tPmRhdGEsICJTZW5kOiAlcyVzXG4iLCBwcm90X2xldmVsID09IFBST1RfUFJJVkFURT9lbmM6bWljLAogICAgICAgICAgICBjbWRfYnVmZmVyKTsKICAgICAgZnJlZShjbWRfYnVmZmVyKTsKICAgIH0KICB9CiAgZWxzZSB7CiAgICBodG9ubF9ieXRlcyA9IGh0b25sKGJ5dGVzKTsKICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgJmh0b25sX2J5dGVzLCBzaXplb2YoaHRvbmxfYnl0ZXMpKTsKICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgYnVmZmVyLCBjdXJseF9zaXRvdXooYnl0ZXMpKTsKICB9CiAgZnJlZShidWZmZXIpOwp9CgpzdGF0aWMgc3NpemVfdCBzZWNfd3JpdGUoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjdXJsX3NvY2tldF90IGZkLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYnVmZmVyLCBzaXplX3QgbGVuZ3RoKQp7CiAgLyogRklYTUU6IENoZWNrIGZvciBvdmVyZmxvdyAqLwogIHNzaXplX3QgdHggPSAwLCBsZW4gPSBjb25uLT5idWZmZXJfc2l6ZTsKCiAgbGVuIC09IGNvbm4tPm1lY2gtPm92ZXJoZWFkKGNvbm4tPmFwcF9kYXRhLCBjb25uLT5kYXRhX3Byb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cmx4X3N6dG9zaShsZW4pKTsKICBpZihsZW4gPD0gMCkKICAgIGxlbiA9IGxlbmd0aDsKICB3aGlsZShsZW5ndGgpIHsKICAgIGlmKGxlbiA+PSAwIHx8IGxlbmd0aCA8IChzaXplX3QpbGVuKSB7CiAgICAgIC8qIEZJWE1FOiBDaGVjayBmb3Igb3ZlcmZsb3cuICovCiAgICAgIGxlbiA9IGxlbmd0aDsKICAgIH0KICAgIGRvX3NlY19zZW5kKGNvbm4sIGZkLCBidWZmZXIsIGN1cmx4X3N6dG9zaShsZW4pKTsKICAgIGxlbmd0aCAtPSBsZW47CiAgICBidWZmZXIgKz0gbGVuOwogICAgdHggKz0gbGVuOwogIH0KICByZXR1cm4gdHg7Cn0KCi8qIE1hdGNoZXMgQ3VybF9zZW5kIHNpZ25hdHVyZSAqLwpzdGF0aWMgc3NpemVfdCBzZWNfc2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBzb2NraW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmJ1ZmZlciwgc2l6ZV90IGxlbiwgQ1VSTGNvZGUgKmVycikKewogIGN1cmxfc29ja2V0X3QgZmQgPSBjb25uLT5zb2NrW3NvY2tpbmRleF07CiAgKmVyciA9IENVUkxFX09LOwogIHJldHVybiBzZWNfd3JpdGUoY29ubiwgZmQsIGJ1ZmZlciwgbGVuKTsKfQoKaW50IEN1cmxfc2VjX3JlYWRfbXNnKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY2hhciAqYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsKQp7CiAgLyogZGVjb2RlZF9sZW4gc2hvdWxkIGJlIHNpemVfdCBvciBzc2l6ZV90IGJ1dCBjb25uLT5tZWNoLT5kZWNvZGUgcmV0dXJucyBhbgogICAgIGludCAqLwogIGludCBkZWNvZGVkX2xlbjsKICBjaGFyICpidWY7CiAgaW50IHJldF9jb2RlOwogIHNpemVfdCBkZWNvZGVkX3N6ID0gMDsKICBDVVJMY29kZSBlcnJvcjsKCiAgREVCVUdBU1NFUlQobGV2ZWwgPiBQUk9UX05PTkUgJiYgbGV2ZWwgPCBQUk9UX0xBU1QpOwoKICBlcnJvciA9IEN1cmxfYmFzZTY0X2RlY29kZShidWZmZXIgKyA0LCAodW5zaWduZWQgY2hhciAqKikmYnVmLCAmZGVjb2RlZF9zeik7CiAgaWYoZXJyb3IgfHwgZGVjb2RlZF9zeiA9PSAwKQogICAgcmV0dXJuIC0xOwoKICBpZihkZWNvZGVkX3N6ID4gKHNpemVfdClJTlRfTUFYKSB7CiAgICBmcmVlKGJ1Zik7CiAgICByZXR1cm4gLTE7CiAgfQogIGRlY29kZWRfbGVuID0gY3VybHhfdXp0b3NpKGRlY29kZWRfc3opOwoKICBkZWNvZGVkX2xlbiA9IGNvbm4tPm1lY2gtPmRlY29kZShjb25uLT5hcHBfZGF0YSwgYnVmLCBkZWNvZGVkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwgY29ubik7CiAgaWYoZGVjb2RlZF9sZW4gPD0gMCkgewogICAgZnJlZShidWYpOwogICAgcmV0dXJuIC0xOwogIH0KCiAgaWYoY29ubi0+ZGF0YS0+c2V0LnZlcmJvc2UpIHsKICAgIGJ1ZltkZWNvZGVkX2xlbl0gPSAnXG4nOwogICAgQ3VybF9kZWJ1Zyhjb25uLT5kYXRhLCBDVVJMSU5GT19IRUFERVJfSU4sIGJ1ZiwgZGVjb2RlZF9sZW4gKyAxLCBjb25uKTsKICB9CgogIGJ1ZltkZWNvZGVkX2xlbl0gPSAnXDAnOwogIERFQlVHQVNTRVJUKGRlY29kZWRfbGVuID4gMyk7CiAgaWYoYnVmWzNdID09ICctJykKICAgIHJldF9jb2RlID0gMDsKICBlbHNlIHsKICAgIC8qIENoZWNrIGZvciBlcnJvcj8gKi8KICAgIHNzY2FuZihidWYsICIlZCIsICZyZXRfY29kZSk7CiAgfQoKICBpZihidWZbZGVjb2RlZF9sZW4gLSAxXSA9PSAnXG4nKQogICAgYnVmW2RlY29kZWRfbGVuIC0gMV0gPSAnXDAnOwogIC8qIEZJWE1FOiBJcyB8YnVmZmVyfCBsZW5ndGggYWx3YXlzIGdyZWF0ZXIgdGhhbiB8ZGVjb2RlZF9sZW58PyAqLwogIHN0cmNweShidWZmZXIsIGJ1Zik7CiAgZnJlZShidWYpOwogIHJldHVybiByZXRfY29kZTsKfQoKLyogRklYTUU6IFRoZSBlcnJvciBjb2RlIHJldHVybmVkIGhlcmUgaXMgbmV2ZXIgY2hlY2tlZC4gKi8Kc3RhdGljIGludCBzZWNfc2V0X3Byb3RlY3Rpb25fbGV2ZWwoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IGNvZGU7CiAgY2hhciogcGJzejsKICBzdGF0aWMgdW5zaWduZWQgaW50IGJ1ZmZlcl9zaXplID0gMSA8PCAyMDsgLyogMTA0ODU3NiAqLwogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbCA9IGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90OwoKICBERUJVR0FTU0VSVChsZXZlbCA+IFBST1RfTk9ORSAmJiBsZXZlbCA8IFBST1RfTEFTVCk7CgogIGlmKCFjb25uLT5zZWNfY29tcGxldGUpIHsKICAgIGluZm9mKGNvbm4tPmRhdGEsICJUcnlpbmcgdG8gY2hhbmdlIHRoZSBwcm90ZWN0aW9uIGxldmVsIGFmdGVyIHRoZSIKICAgICAgICAgICAgICAgICAgICAgICJjb21wbGV0aW9uIG9mIHRoZSBkYXRhIGV4Y2hhbmdlLlxuIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICAvKiBCYWlsIG91dCBpZiB3ZSB0cnkgdG8gc2V0IHVwIHRoZSBzYW1lIGxldmVsICovCiAgaWYoY29ubi0+ZGF0YV9wcm90ID09IGxldmVsKQogICAgcmV0dXJuIDA7CgogIGlmKGxldmVsKSB7CiAgICBjb2RlID0gZnRwX3NlbmRfY29tbWFuZChjb25uLCAiUEJTWiAldSIsIGJ1ZmZlcl9zaXplKTsKICAgIGlmKGNvZGUgPCAwKQogICAgICByZXR1cm4gLTE7CgogICAgaWYoY29kZS8xMDAgIT0gMikgewogICAgICBmYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIHNldCB0aGUgcHJvdGVjdGlvbidzIGJ1ZmZlciBzaXplLiIpOwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBjb25uLT5idWZmZXJfc2l6ZSA9IGJ1ZmZlcl9zaXplOwoKICAgIHBic3ogPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiUEJTWj0iKTsKICAgIGlmKHBic3opIHsKICAgICAgLyogRklYTUU6IENoZWNrcyBmb3IgZXJyb3JzIGluIHNzY2FuZj8gKi8KICAgICAgc3NjYW5mKHBic3osICJQQlNaPSV1IiwgJmJ1ZmZlcl9zaXplKTsKICAgICAgaWYoYnVmZmVyX3NpemUgPCBjb25uLT5idWZmZXJfc2l6ZSkKICAgICAgICBjb25uLT5idWZmZXJfc2l6ZSA9IGJ1ZmZlcl9zaXplOwogICAgfQogIH0KCiAgLyogTm93IHRyeSB0byBuZWdpb2NpYXRlIHRoZSBwcm90ZWN0aW9uIGxldmVsLiAqLwogIGNvZGUgPSBmdHBfc2VuZF9jb21tYW5kKGNvbm4sICJQUk9UICVjIiwgbGV2ZWxfdG9fY2hhcihsZXZlbCkpOwoKICBpZihjb2RlIDwgMCkKICAgIHJldHVybiAtMTsKCiAgaWYoY29kZS8xMDAgIT0gMikgewogICAgZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBzZXQgdGhlIHByb3RlY3Rpb24gbGV2ZWwuIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICBjb25uLT5kYXRhX3Byb3QgPSBsZXZlbDsKICBpZihsZXZlbCA9PSBQUk9UX1BSSVZBVEUpCiAgICBjb25uLT5jb21tYW5kX3Byb3QgPSBsZXZlbDsKCiAgcmV0dXJuIDA7Cn0KCmludApDdXJsX3NlY19yZXF1ZXN0X3Byb3Qoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjb25zdCBjaGFyICpsZXZlbCkKewogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsID0gbmFtZV90b19sZXZlbChsZXZlbCk7CiAgaWYobCA9PSBQUk9UX05PTkUpCiAgICByZXR1cm4gLTE7CiAgREVCVUdBU1NFUlQobCA+IFBST1RfTk9ORSAmJiBsIDwgUFJPVF9MQVNUKTsKICBjb25uLT5yZXF1ZXN0X2RhdGFfcHJvdCA9IGw7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBDVVJMY29kZSBjaG9vc2VfbWVjaChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgcmV0OwogIHN0cnVjdCBTZXNzaW9uSGFuZGxlICpkYXRhID0gY29ubi0+ZGF0YTsKICBjb25zdCBzdHJ1Y3QgQ3VybF9zZWNfY2xpZW50X21lY2ggKiBjb25zdCAqbWVjaDsKICB2b2lkICp0bXBfYWxsb2NhdGlvbjsKICBjb25zdCBjaGFyICptZWNoX25hbWU7CgogIGZvcihtZWNoID0gbWVjaHM7ICgqbWVjaCk7ICsrbWVjaCkgewogICAgbWVjaF9uYW1lID0gKCptZWNoKS0+bmFtZTsKICAgIC8qIFdlIGhhdmUgbm8gbWVjaGFuaXNtIHdpdGggYSBOVUxMIG5hbWUgYnV0IGtlZXAgdGhpcyBjaGVjayAqLwogICAgREVCVUdBU1NFUlQobWVjaF9uYW1lICE9IE5VTEwpOwogICAgaWYobWVjaF9uYW1lID09IE5VTEwpIHsKICAgICAgaW5mb2YoZGF0YSwgIlNraXBwaW5nIG1lY2hhbmlzbSB3aXRoIGVtcHR5IG5hbWUgKCVwKVxuIiwgKHZvaWQgKiltZWNoKTsKICAgICAgY29udGludWU7CiAgICB9CiAgICB0bXBfYWxsb2NhdGlvbiA9IHJlYWxsb2MoY29ubi0+YXBwX2RhdGEsICgqbWVjaCktPnNpemUpOwogICAgaWYodG1wX2FsbG9jYXRpb24gPT0gTlVMTCkgewogICAgICBmYWlsZihkYXRhLCAiRmFpbGVkIHJlYWxsb2Mgb2Ygc2l6ZSAldSIsICgqbWVjaCktPnNpemUpOwogICAgICBtZWNoID0gTlVMTDsKICAgICAgcmV0dXJuIENVUkxFX09VVF9PRl9NRU1PUlk7CiAgICB9CiAgICBjb25uLT5hcHBfZGF0YSA9IHRtcF9hbGxvY2F0aW9uOwoKICAgIGlmKCgqbWVjaCktPmluaXQpIHsKICAgICAgcmV0ID0gKCptZWNoKS0+aW5pdChjb25uLT5hcHBfZGF0YSk7CiAgICAgIGlmKHJldCAhPSAwKSB7CiAgICAgICAgaW5mb2YoZGF0YSwgIkZhaWxlZCBpbml0aWFsaXphdGlvbiBmb3IgJXMuIFNraXBwaW5nIGl0LlxuIiwgbWVjaF9uYW1lKTsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgfQoKICAgIGluZm9mKGRhdGEsICJUcnlpbmcgbWVjaGFuaXNtICVzLi4uXG4iLCBtZWNoX25hbWUpOwogICAgcmV0ID0gZnRwX3NlbmRfY29tbWFuZChjb25uLCAiQVVUSCAlcyIsIG1lY2hfbmFtZSk7CiAgICBpZihyZXQgPCAwKQogICAgICAvKiBGSVhNRTogVGhpcyBlcnJvciBpcyB0b28gZ2VuZXJpYyBidXQgaXQgaXMgT0sgZm9yIG5vdy4gKi8KICAgICAgcmV0dXJuIENVUkxFX0NPVUxETlRfQ09OTkVDVDsKCiAgICBpZihyZXQvMTAwICE9IDMpIHsKICAgICAgc3dpdGNoKHJldCkgewogICAgICBjYXNlIDUwNDoKICAgICAgICBpbmZvZihkYXRhLCAiTWVjaGFuaXNtICVzIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIHNlcnZlciAoc2VydmVyICIKICAgICAgICAgICAgICAgICAgICAicmV0dXJuZWQgZnRwIGNvZGU6IDUwNCkuXG4iLCBtZWNoX25hbWUpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDUzNDoKICAgICAgICBpbmZvZihkYXRhLCAiTWVjaGFuaXNtICVzIHdhcyByZWplY3RlZCBieSB0aGUgc2VydmVyIChzZXJ2ZXIgcmV0dXJuZWQgIgogICAgICAgICAgICAgICAgICAgICJmdHAgY29kZTogNTM0KS5cbiIsIG1lY2hfbmFtZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgaWYocmV0LzEwMCA9PSA1KSB7CiAgICAgICAgICBpbmZvZihkYXRhLCAic2VydmVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHNlY3VyaXR5IGV4dGVuc2lvbnNcbiIpOwogICAgICAgICAgcmV0dXJuIENVUkxFX1VTRV9TU0xfRkFJTEVEOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjb250aW51ZTsKICAgIH0KCiAgICAvKiBBdXRoZW50aWNhdGUgKi8KICAgIHJldCA9ICgqbWVjaCktPmF1dGgoY29ubi0+YXBwX2RhdGEsIGNvbm4pOwoKICAgIGlmKHJldCA9PSBBVVRIX0NPTlRJTlVFKQogICAgICBjb250aW51ZTsKICAgIGVsc2UgaWYocmV0ICE9IEFVVEhfT0spIHsKICAgICAgLyogTWVjaGFuaXNtIGhhcyBkdW1wZWQgdGhlIGVycm9yIHRvIHN0ZGVyciwgZG9uJ3QgZXJyb3IgaGVyZS4gKi8KICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgREVCVUdBU1NFUlQocmV0ID09IEFVVEhfT0spOwoKICAgIGNvbm4tPm1lY2ggPSAqbWVjaDsKICAgIGNvbm4tPnNlY19jb21wbGV0ZSA9IDE7CiAgICBjb25uLT5yZWN2W0ZJUlNUU09DS0VUXSA9IHNlY19yZWN2OwogICAgY29ubi0+c2VuZFtGSVJTVFNPQ0tFVF0gPSBzZWNfc2VuZDsKICAgIGNvbm4tPnJlY3ZbU0VDT05EQVJZU09DS0VUXSA9IHNlY19yZWN2OwogICAgY29ubi0+c2VuZFtTRUNPTkRBUllTT0NLRVRdID0gc2VjX3NlbmQ7CiAgICBjb25uLT5jb21tYW5kX3Byb3QgPSBQUk9UX1NBRkU7CiAgICAvKiBTZXQgdGhlIHJlcXVlc3RlZCBwcm90ZWN0aW9uIGxldmVsICovCiAgICAvKiBCTE9DS0lORyAqLwogICAgKHZvaWQpc2VjX3NldF9wcm90ZWN0aW9uX2xldmVsKGNvbm4pOwogICAgYnJlYWs7CiAgfQoKICByZXR1cm4gbWVjaCAhPSBOVUxMID8gQ1VSTEVfT0sgOiBDVVJMRV9GQUlMRURfSU5JVDsKfQoKQ1VSTGNvZGUKQ3VybF9zZWNfbG9naW4oc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgcmV0dXJuIGNob29zZV9tZWNoKGNvbm4pOwp9CgoKdm9pZApDdXJsX3NlY19lbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaWYoY29ubi0+bWVjaCAhPSBOVUxMICYmIGNvbm4tPm1lY2gtPmVuZCkKICAgIGNvbm4tPm1lY2gtPmVuZChjb25uLT5hcHBfZGF0YSk7CiAgaWYoY29ubi0+YXBwX2RhdGEpIHsKICAgIGZyZWUoY29ubi0+YXBwX2RhdGEpOwogICAgY29ubi0+YXBwX2RhdGEgPSBOVUxMOwogIH0KICBpZihjb25uLT5pbl9idWZmZXIuZGF0YSkgewogICAgZnJlZShjb25uLT5pbl9idWZmZXIuZGF0YSk7CiAgICBjb25uLT5pbl9idWZmZXIuZGF0YSA9IE5VTEw7CiAgICBjb25uLT5pbl9idWZmZXIuc2l6ZSA9IDA7CiAgICBjb25uLT5pbl9idWZmZXIuaW5kZXggPSAwOwogICAgLyogRklYTUU6IElzIHRoaXMgcmVhbGx5IG5lZWRlZD8gKi8KICAgIGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyA9IDA7CiAgfQogIGNvbm4tPnNlY19jb21wbGV0ZSA9IDA7CiAgY29ubi0+ZGF0YV9wcm90ID0gUFJPVF9DTEVBUjsKICBjb25uLT5tZWNoID0gTlVMTDsKfQoKI2VuZGlmIC8qIEhBVkVfR1NTQVBJICovCgojZW5kaWYgLyogQ1VSTF9ESVNBQkxFX0ZUUCAqLwo=