LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEgLSAyMDE1LCBEYW5pZWwgU3RlbmJlcmcsIDxkYW5pZWxAaGF4eC5zZT4sIGV0IGFsLgogKgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAiY3VybF9zZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBIQVZFX0dTU0FQSQoKI2lmZGVmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCgojaWZkZWYgSEFWRV9MSU1JVFNfSAojaW5jbHVkZSA8bGltaXRzLmg+CiNlbmRpZgoKI2luY2x1ZGUgInVybGRhdGEuaCIKI2luY2x1ZGUgImN1cmxfYmFzZTY0LmgiCiNpbmNsdWRlICJjdXJsX21lbW9yeS5oIgojaW5jbHVkZSAiY3VybF9zZWMuaCIKI2luY2x1ZGUgImZ0cC5oIgojaW5jbHVkZSAic2VuZGYuaCIKI2luY2x1ZGUgInJhd3N0ci5oIgojaW5jbHVkZSAid2Fybmxlc3MuaCIKCi8qIFRoZSBsYXN0ICNpbmNsdWRlIGZpbGUgc2hvdWxkIGJlOiAqLwojaW5jbHVkZSAibWVtZGVidWcuaCIKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgewogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbDsKICBjb25zdCBjaGFyICpuYW1lOwp9IGxldmVsX25hbWVzW10gPSB7CiAgeyBQUk9UX0NMRUFSLCAiY2xlYXIiIH0sCiAgeyBQUk9UX1NBRkUsICJzYWZlIiB9LAogIHsgUFJPVF9DT05GSURFTlRJQUwsICJjb25maWRlbnRpYWwiIH0sCiAgeyBQUk9UX1BSSVZBVEUsICJwcml2YXRlIiB9Cn07CgpzdGF0aWMgZW51bSBwcm90ZWN0aW9uX2xldmVsCm5hbWVfdG9fbGV2ZWwoY29uc3QgY2hhciAqbmFtZSkKewogIGludCBpOwogIGZvcihpID0gMDsgaSA8IChpbnQpc2l6ZW9mKGxldmVsX25hbWVzKS8oaW50KXNpemVvZihsZXZlbF9uYW1lc1swXSk7IGkrKykKICAgIGlmKGNoZWNrcHJlZml4KG5hbWUsIGxldmVsX25hbWVzW2ldLm5hbWUpKQogICAgICByZXR1cm4gbGV2ZWxfbmFtZXNbaV0ubGV2ZWw7CiAgcmV0dXJuIFBST1RfTk9ORTsKfQoKLyogQ29udmVydCBhIHByb3RvY29sIHxsZXZlbHwgdG8gaXRzIGNoYXIgcmVwcmVzZW50YXRpb24uCiAgIFdlIHRha2UgYW4gaW50IHRvIGNhdGNoIHByb2dyYW1taW5nIG1pc3Rha2VzLiAqLwpzdGF0aWMgY2hhciBsZXZlbF90b19jaGFyKGludCBsZXZlbCkgewogIHN3aXRjaChsZXZlbCkgewogIGNhc2UgUFJPVF9DTEVBUjoKICAgIHJldHVybiAnQyc7CiAgY2FzZSBQUk9UX1NBRkU6CiAgICByZXR1cm4gJ1MnOwogIGNhc2UgUFJPVF9DT05GSURFTlRJQUw6CiAgICByZXR1cm4gJ0UnOwogIGNhc2UgUFJPVF9QUklWQVRFOgogICAgcmV0dXJuICdQJzsKICBjYXNlIFBST1RfQ01EOgogICAgLyogRmFsbCB0aHJvdWdoICovCiAgZGVmYXVsdDoKICAgIC8qIFRob3NlIDIgY2FzZXMgc2hvdWxkIG5vdCBiZSByZWFjaGVkISAqLwogICAgYnJlYWs7CiAgfQogIERFQlVHQVNTRVJUKDApOwogIC8qIERlZmF1bHQgdG8gdGhlIG1vc3Qgc2VjdXJlIGFsdGVybmF0aXZlLiAqLwogIHJldHVybiAnUCc7Cn0KCi8qIFNlbmQgYW4gRlRQIGNvbW1hbmQgZGVmaW5lZCBieSB8bWVzc2FnZXwgYW5kIHRoZSBvcHRpb25hbCBhcmd1bWVudHMuIFRoZQogICBmdW5jdGlvbiByZXR1cm5zIHRoZSBmdHBfY29kZS4gSWYgYW4gZXJyb3Igb2NjdXJzLCAtMSBpcyByZXR1cm5lZC4gKi8Kc3RhdGljIGludCBmdHBfc2VuZF9jb21tYW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY29uc3QgY2hhciAqbWVzc2FnZSwgLi4uKQp7CiAgaW50IGZ0cF9jb2RlOwogIHNzaXplX3QgbnJlYWQ9MDsKICB2YV9saXN0IGFyZ3M7CiAgY2hhciBwcmludF9idWZmZXJbNTBdOwoKICB2YV9zdGFydChhcmdzLCBtZXNzYWdlKTsKICB2c25wcmludGYocHJpbnRfYnVmZmVyLCBzaXplb2YocHJpbnRfYnVmZmVyKSwgbWVzc2FnZSwgYXJncyk7CiAgdmFfZW5kKGFyZ3MpOwoKICBpZihDdXJsX2Z0cHNlbmRmKGNvbm4sIHByaW50X2J1ZmZlcikpIHsKICAgIGZ0cF9jb2RlID0gLTE7CiAgfQogIGVsc2UgewogICAgaWYoQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sICZmdHBfY29kZSkpCiAgICAgIGZ0cF9jb2RlID0gLTE7CiAgfQoKICAodm9pZClucmVhZDsgLyogVW51c2VkICovCiAgcmV0dXJuIGZ0cF9jb2RlOwp9CgovKiBSZWFkIHxsZW58IGZyb20gdGhlIHNvY2tldCB8ZmR8IGFuZCBzdG9yZSBpdCBpbiB8dG98LiBSZXR1cm4gYSBDVVJMY29kZQogICBzYXlpbmcgd2hldGhlciBhbiBlcnJvciBvY2N1cnJlZCBvciBDVVJMRV9PSyBpZiB8bGVufCB3YXMgcmVhZC4gKi8Kc3RhdGljIENVUkxjb2RlCnNvY2tldF9yZWFkKGN1cmxfc29ja2V0X3QgZmQsIHZvaWQgKnRvLCBzaXplX3QgbGVuKQp7CiAgY2hhciAqdG9fcCA9IHRvOwogIENVUkxjb2RlIHJlc3VsdDsKICBzc2l6ZV90IG5yZWFkOwoKICB3aGlsZShsZW4gPiAwKSB7CiAgICByZXN1bHQgPSBDdXJsX3JlYWRfcGxhaW4oZmQsIHRvX3AsIGxlbiwgJm5yZWFkKTsKICAgIGlmKCFyZXN1bHQpIHsKICAgICAgbGVuIC09IG5yZWFkOwogICAgICB0b19wICs9IG5yZWFkOwogICAgfQogICAgZWxzZSB7CiAgICAgIC8qIEZJWE1FOiBXZSBhcmUgZG9pbmcgYSBidXN5IHdhaXQgKi8KICAgICAgaWYocmVzdWx0ID09IENVUkxFX0FHQUlOKQogICAgICAgIGNvbnRpbnVlOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQogIH0KICByZXR1cm4gQ1VSTEVfT0s7Cn0KCgovKiBXcml0ZSB8bGVufCBieXRlcyBmcm9tIHRoZSBidWZmZXIgfHRvfCB0byB0aGUgc29ja2V0IHxmZHwuIFJldHVybiBhCiAgIENVUkxjb2RlIHNheWluZyB3aGV0aGVyIGFuIGVycm9yIG9jY3VycmVkIG9yIENVUkxFX09LIGlmIHxsZW58IHdhcwogICB3cml0dGVuLiAqLwpzdGF0aWMgQ1VSTGNvZGUKc29ja2V0X3dyaXRlKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY3VybF9zb2NrZXRfdCBmZCwgY29uc3Qgdm9pZCAqdG8sCiAgICAgICAgICAgICBzaXplX3QgbGVuKQp7CiAgY29uc3QgY2hhciAqdG9fcCA9IHRvOwogIENVUkxjb2RlIHJlc3VsdDsKICBzc2l6ZV90IHdyaXR0ZW47CgogIHdoaWxlKGxlbiA+IDApIHsKICAgIHJlc3VsdCA9IEN1cmxfd3JpdGVfcGxhaW4oY29ubiwgZmQsIHRvX3AsIGxlbiwgJndyaXR0ZW4pOwogICAgaWYoIXJlc3VsdCkgewogICAgICBsZW4gLT0gd3JpdHRlbjsKICAgICAgdG9fcCArPSB3cml0dGVuOwogICAgfQogICAgZWxzZSB7CiAgICAgIC8qIEZJWE1FOiBXZSBhcmUgZG9pbmcgYSBidXN5IHdhaXQgKi8KICAgICAgaWYocmVzdWx0ID09IENVUkxFX0FHQUlOKQogICAgICAgIGNvbnRpbnVlOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQogIH0KICByZXR1cm4gQ1VSTEVfT0s7Cn0KCnN0YXRpYyBDVVJMY29kZSByZWFkX2RhdGEoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLAogICAgICAgICAgICAgICAgICAgICAgICAgIGN1cmxfc29ja2V0X3QgZmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGtyYjVidWZmZXIgKmJ1ZikKewogIGludCBsZW47CiAgdm9pZCogdG1wOwogIENVUkxjb2RlIHJlc3VsdDsKCiAgcmVzdWx0ID0gc29ja2V0X3JlYWQoZmQsICZsZW4sIHNpemVvZihsZW4pKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICBsZW4gPSBudG9obChsZW4pOwogIHRtcCA9IHJlYWxsb2MoYnVmLT5kYXRhLCBsZW4pOwogIGlmKHRtcCA9PSBOVUxMKQogICAgcmV0dXJuIENVUkxFX09VVF9PRl9NRU1PUlk7CgogIGJ1Zi0+ZGF0YSA9IHRtcDsKICByZXN1bHQgPSBzb2NrZXRfcmVhZChmZCwgYnVmLT5kYXRhLCBsZW4pOwogIGlmKHJlc3VsdCkKICAgIHJldHVybiByZXN1bHQ7CiAgYnVmLT5zaXplID0gY29ubi0+bWVjaC0+ZGVjb2RlKGNvbm4tPmFwcF9kYXRhLCBidWYtPmRhdGEsIGxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubi0+ZGF0YV9wcm90LCBjb25uKTsKICBidWYtPmluZGV4ID0gMDsKICByZXR1cm4gQ1VSTEVfT0s7Cn0KCnN0YXRpYyBzaXplX3QKYnVmZmVyX3JlYWQoc3RydWN0IGtyYjVidWZmZXIgKmJ1Ziwgdm9pZCAqZGF0YSwgc2l6ZV90IGxlbikKewogIGlmKGJ1Zi0+c2l6ZSAtIGJ1Zi0+aW5kZXggPCBsZW4pCiAgICBsZW4gPSBidWYtPnNpemUgLSBidWYtPmluZGV4OwogIG1lbWNweShkYXRhLCAoY2hhciopYnVmLT5kYXRhICsgYnVmLT5pbmRleCwgbGVuKTsKICBidWYtPmluZGV4ICs9IGxlbjsKICByZXR1cm4gbGVuOwp9CgovKiBNYXRjaGVzIEN1cmxfcmVjdiBzaWduYXR1cmUgKi8Kc3RhdGljIHNzaXplX3Qgc2VjX3JlY3Yoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgc29ja2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpidWZmZXIsIHNpemVfdCBsZW4sIENVUkxjb2RlICplcnIpCnsKICBzaXplX3QgYnl0ZXNfcmVhZDsKICBzaXplX3QgdG90YWxfcmVhZCA9IDA7CiAgY3VybF9zb2NrZXRfdCBmZCA9IGNvbm4tPnNvY2tbc29ja2luZGV4XTsKCiAgKmVyciA9IENVUkxFX09LOwoKICAvKiBIYW5kbGUgY2xlYXIgdGV4dCByZXNwb25zZS4gKi8KICBpZihjb25uLT5zZWNfY29tcGxldGUgPT0gMCB8fCBjb25uLT5kYXRhX3Byb3QgPT0gUFJPVF9DTEVBUikKICAgICAgcmV0dXJuIHJlYWQoZmQsIGJ1ZmZlciwgbGVuKTsKCiAgaWYoY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnKSB7CiAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAwOwogICAgcmV0dXJuIDA7CiAgfQoKICBieXRlc19yZWFkID0gYnVmZmVyX3JlYWQoJmNvbm4tPmluX2J1ZmZlciwgYnVmZmVyLCBsZW4pOwogIGxlbiAtPSBieXRlc19yZWFkOwogIHRvdGFsX3JlYWQgKz0gYnl0ZXNfcmVhZDsKICBidWZmZXIgKz0gYnl0ZXNfcmVhZDsKCiAgd2hpbGUobGVuID4gMCkgewogICAgaWYocmVhZF9kYXRhKGNvbm4sIGZkLCAmY29ubi0+aW5fYnVmZmVyKSkKICAgICAgcmV0dXJuIC0xOwogICAgaWYoY29ubi0+aW5fYnVmZmVyLnNpemUgPT0gMCkgewogICAgICBpZihieXRlc19yZWFkID4gMCkKICAgICAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAxOwogICAgICByZXR1cm4gYnl0ZXNfcmVhZDsKICAgIH0KICAgIGJ5dGVzX3JlYWQgPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbik7CiAgICBsZW4gLT0gYnl0ZXNfcmVhZDsKICAgIHRvdGFsX3JlYWQgKz0gYnl0ZXNfcmVhZDsKICAgIGJ1ZmZlciArPSBieXRlc19yZWFkOwogIH0KICAvKiBGSVhNRTogQ2hlY2sgZm9yIG92ZXJmbG93ICovCiAgcmV0dXJuIHRvdGFsX3JlYWQ7Cn0KCi8qIFNlbmQgfGxlbmd0aHwgYnl0ZXMgZnJvbSB8ZnJvbXwgdG8gdGhlIHxmZHwgc29ja2V0IHRha2luZyBjYXJlIG9mIGVuY29kaW5nCiAgIGFuZCBuZWdvY2lhdGluZyB3aXRoIHRoZSBzZXJ2ZXIuIHxmcm9tfCBjYW4gYmUgTlVMTC4gKi8KLyogRklYTUU6IFdlIGRvbid0IGNoZWNrIGZvciBlcnJvcnMgbm9yIHJlcG9ydCBhbnkhICovCnN0YXRpYyB2b2lkIGRvX3NlY19zZW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY3VybF9zb2NrZXRfdCBmZCwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZnJvbSwgaW50IGxlbmd0aCkKewogIGludCBieXRlcywgaHRvbmxfYnl0ZXM7IC8qIDMyLWJpdCBpbnRlZ2VycyBmb3IgaHRvbmwgKi8KICBjaGFyICpidWZmZXIgPSBOVUxMOwogIGNoYXIgKmNtZF9idWZmZXI7CiAgc2l6ZV90IGNtZF9zaXplID0gMDsKICBDVVJMY29kZSBlcnJvcjsKICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgcHJvdF9sZXZlbCA9IGNvbm4tPmRhdGFfcHJvdDsKICBib29sIGlzY21kID0gKHByb3RfbGV2ZWwgPT0gUFJPVF9DTUQpP1RSVUU6RkFMU0U7CgogIERFQlVHQVNTRVJUKHByb3RfbGV2ZWwgPiBQUk9UX05PTkUgJiYgcHJvdF9sZXZlbCA8IFBST1RfTEFTVCk7CgogIGlmKGlzY21kKSB7CiAgICBpZighc3RybmNtcChmcm9tLCAiUEFTUyAiLCA1KSB8fCAhc3RybmNtcChmcm9tLCAiQUNDVCAiLCA1KSkKICAgICAgcHJvdF9sZXZlbCA9IFBST1RfUFJJVkFURTsKICAgIGVsc2UKICAgICAgcHJvdF9sZXZlbCA9IGNvbm4tPmNvbW1hbmRfcHJvdDsKICB9CiAgYnl0ZXMgPSBjb25uLT5tZWNoLT5lbmNvZGUoY29ubi0+YXBwX2RhdGEsIGZyb20sIGxlbmd0aCwgcHJvdF9sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZidWZmZXIpOwogIGlmKCFidWZmZXIgfHwgYnl0ZXMgPD0gMCkKICAgIHJldHVybjsgLyogZXJyb3IgKi8KCiAgaWYoaXNjbWQpIHsKICAgIGVycm9yID0gQ3VybF9iYXNlNjRfZW5jb2RlKGNvbm4tPmRhdGEsIGJ1ZmZlciwgY3VybHhfc2l0b3V6KGJ5dGVzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjbWRfYnVmZmVyLCAmY21kX3NpemUpOwogICAgaWYoZXJyb3IpIHsKICAgICAgZnJlZShidWZmZXIpOwogICAgICByZXR1cm47IC8qIGVycm9yICovCiAgICB9CiAgICBpZihjbWRfc2l6ZSA+IDApIHsKICAgICAgc3RhdGljIGNvbnN0IGNoYXIgKmVuYyA9ICJFTkMgIjsKICAgICAgc3RhdGljIGNvbnN0IGNoYXIgKm1pYyA9ICJNSUMgIjsKICAgICAgaWYocHJvdF9sZXZlbCA9PSBQUk9UX1BSSVZBVEUpCiAgICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBlbmMsIDQpOwogICAgICBlbHNlCiAgICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBtaWMsIDQpOwoKICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBjbWRfYnVmZmVyLCBjbWRfc2l6ZSk7CiAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgIlxyXG4iLCAyKTsKICAgICAgaW5mb2YoY29ubi0+ZGF0YSwgIlNlbmQ6ICVzJXNcbiIsIHByb3RfbGV2ZWwgPT0gUFJPVF9QUklWQVRFP2VuYzptaWMsCiAgICAgICAgICAgIGNtZF9idWZmZXIpOwogICAgICBmcmVlKGNtZF9idWZmZXIpOwogICAgfQogIH0KICBlbHNlIHsKICAgIGh0b25sX2J5dGVzID0gaHRvbmwoYnl0ZXMpOwogICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCAmaHRvbmxfYnl0ZXMsIHNpemVvZihodG9ubF9ieXRlcykpOwogICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCBidWZmZXIsIGN1cmx4X3NpdG91eihieXRlcykpOwogIH0KICBmcmVlKGJ1ZmZlcik7Cn0KCnN0YXRpYyBzc2l6ZV90IHNlY193cml0ZShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGN1cmxfc29ja2V0X3QgZmQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpidWZmZXIsIHNpemVfdCBsZW5ndGgpCnsKICBzc2l6ZV90IHR4ID0gMCwgbGVuID0gY29ubi0+YnVmZmVyX3NpemU7CgogIGxlbiAtPSBjb25uLT5tZWNoLT5vdmVyaGVhZChjb25uLT5hcHBfZGF0YSwgY29ubi0+ZGF0YV9wcm90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJseF9zenRvc2kobGVuKSk7CiAgaWYobGVuIDw9IDApCiAgICBsZW4gPSBsZW5ndGg7CiAgd2hpbGUobGVuZ3RoKSB7CiAgICBpZihsZW5ndGggPCAoc2l6ZV90KWxlbikKICAgICAgbGVuID0gbGVuZ3RoOwoKICAgIGRvX3NlY19zZW5kKGNvbm4sIGZkLCBidWZmZXIsIGN1cmx4X3N6dG9zaShsZW4pKTsKICAgIGxlbmd0aCAtPSBsZW47CiAgICBidWZmZXIgKz0gbGVuOwogICAgdHggKz0gbGVuOwogIH0KICByZXR1cm4gdHg7Cn0KCi8qIE1hdGNoZXMgQ3VybF9zZW5kIHNpZ25hdHVyZSAqLwpzdGF0aWMgc3NpemVfdCBzZWNfc2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBzb2NraW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmJ1ZmZlciwgc2l6ZV90IGxlbiwgQ1VSTGNvZGUgKmVycikKewogIGN1cmxfc29ja2V0X3QgZmQgPSBjb25uLT5zb2NrW3NvY2tpbmRleF07CiAgKmVyciA9IENVUkxFX09LOwogIHJldHVybiBzZWNfd3JpdGUoY29ubiwgZmQsIGJ1ZmZlciwgbGVuKTsKfQoKaW50IEN1cmxfc2VjX3JlYWRfbXNnKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY2hhciAqYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsKQp7CiAgLyogZGVjb2RlZF9sZW4gc2hvdWxkIGJlIHNpemVfdCBvciBzc2l6ZV90IGJ1dCBjb25uLT5tZWNoLT5kZWNvZGUgcmV0dXJucyBhbgogICAgIGludCAqLwogIGludCBkZWNvZGVkX2xlbjsKICBjaGFyICpidWY7CiAgaW50IHJldF9jb2RlID0gMDsKICBzaXplX3QgZGVjb2RlZF9zeiA9IDA7CiAgQ1VSTGNvZGUgZXJyb3I7CgogIERFQlVHQVNTRVJUKGxldmVsID4gUFJPVF9OT05FICYmIGxldmVsIDwgUFJPVF9MQVNUKTsKCiAgZXJyb3IgPSBDdXJsX2Jhc2U2NF9kZWNvZGUoYnVmZmVyICsgNCwgKHVuc2lnbmVkIGNoYXIgKiopJmJ1ZiwgJmRlY29kZWRfc3opOwogIGlmKGVycm9yIHx8IGRlY29kZWRfc3ogPT0gMCkKICAgIHJldHVybiAtMTsKCiAgaWYoZGVjb2RlZF9zeiA+IChzaXplX3QpSU5UX01BWCkgewogICAgZnJlZShidWYpOwogICAgcmV0dXJuIC0xOwogIH0KICBkZWNvZGVkX2xlbiA9IGN1cmx4X3V6dG9zaShkZWNvZGVkX3N6KTsKCiAgZGVjb2RlZF9sZW4gPSBjb25uLT5tZWNoLT5kZWNvZGUoY29ubi0+YXBwX2RhdGEsIGJ1ZiwgZGVjb2RlZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWwsIGNvbm4pOwogIGlmKGRlY29kZWRfbGVuIDw9IDApIHsKICAgIGZyZWUoYnVmKTsKICAgIHJldHVybiAtMTsKICB9CgogIGlmKGNvbm4tPmRhdGEtPnNldC52ZXJib3NlKSB7CiAgICBidWZbZGVjb2RlZF9sZW5dID0gJ1xuJzsKICAgIEN1cmxfZGVidWcoY29ubi0+ZGF0YSwgQ1VSTElORk9fSEVBREVSX0lOLCBidWYsIGRlY29kZWRfbGVuICsgMSwgY29ubik7CiAgfQoKICBidWZbZGVjb2RlZF9sZW5dID0gJ1wwJzsKICBpZihkZWNvZGVkX2xlbiA8PSAzKQogICAgLyogc3VzcGljaW91c2x5IHNob3J0ICovCiAgICByZXR1cm4gMDsKCiAgaWYoYnVmWzNdICE9ICctJykKICAgIC8qIHNhZmUgdG8gaWdub3JlIHJldHVybiBjb2RlICovCiAgICAodm9pZClzc2NhbmYoYnVmLCAiJWQiLCAmcmV0X2NvZGUpOwoKICBpZihidWZbZGVjb2RlZF9sZW4gLSAxXSA9PSAnXG4nKQogICAgYnVmW2RlY29kZWRfbGVuIC0gMV0gPSAnXDAnOwogIC8qIEZJWE1FOiBJcyB8YnVmZmVyfCBsZW5ndGggYWx3YXlzIGdyZWF0ZXIgdGhhbiB8ZGVjb2RlZF9sZW58PyAqLwogIHN0cmNweShidWZmZXIsIGJ1Zik7CiAgZnJlZShidWYpOwogIHJldHVybiByZXRfY29kZTsKfQoKLyogRklYTUU6IFRoZSBlcnJvciBjb2RlIHJldHVybmVkIGhlcmUgaXMgbmV2ZXIgY2hlY2tlZC4gKi8Kc3RhdGljIGludCBzZWNfc2V0X3Byb3RlY3Rpb25fbGV2ZWwoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IGNvZGU7CiAgY2hhciogcGJzejsKICBzdGF0aWMgdW5zaWduZWQgaW50IGJ1ZmZlcl9zaXplID0gMSA8PCAyMDsgLyogMTA0ODU3NiAqLwogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbCA9IGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90OwoKICBERUJVR0FTU0VSVChsZXZlbCA+IFBST1RfTk9ORSAmJiBsZXZlbCA8IFBST1RfTEFTVCk7CgogIGlmKCFjb25uLT5zZWNfY29tcGxldGUpIHsKICAgIGluZm9mKGNvbm4tPmRhdGEsICJUcnlpbmcgdG8gY2hhbmdlIHRoZSBwcm90ZWN0aW9uIGxldmVsIGFmdGVyIHRoZSIKICAgICAgICAgICAgICAgICAgICAgICJjb21wbGV0aW9uIG9mIHRoZSBkYXRhIGV4Y2hhbmdlLlxuIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICAvKiBCYWlsIG91dCBpZiB3ZSB0cnkgdG8gc2V0IHVwIHRoZSBzYW1lIGxldmVsICovCiAgaWYoY29ubi0+ZGF0YV9wcm90ID09IGxldmVsKQogICAgcmV0dXJuIDA7CgogIGlmKGxldmVsKSB7CiAgICBjb2RlID0gZnRwX3NlbmRfY29tbWFuZChjb25uLCAiUEJTWiAldSIsIGJ1ZmZlcl9zaXplKTsKICAgIGlmKGNvZGUgPCAwKQogICAgICByZXR1cm4gLTE7CgogICAgaWYoY29kZS8xMDAgIT0gMikgewogICAgICBmYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIHNldCB0aGUgcHJvdGVjdGlvbidzIGJ1ZmZlciBzaXplLiIpOwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBjb25uLT5idWZmZXJfc2l6ZSA9IGJ1ZmZlcl9zaXplOwoKICAgIHBic3ogPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiUEJTWj0iKTsKICAgIGlmKHBic3opIHsKICAgICAgLyogaWdub3JlIHJldHVybiBjb2RlLCB1c2UgZGVmYXVsdCB2YWx1ZSBpZiBpdCBmYWlscyAqLwogICAgICAodm9pZClzc2NhbmYocGJzeiwgIlBCU1o9JXUiLCAmYnVmZmVyX3NpemUpOwogICAgICBpZihidWZmZXJfc2l6ZSA8IGNvbm4tPmJ1ZmZlcl9zaXplKQogICAgICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gYnVmZmVyX3NpemU7CiAgICB9CiAgfQoKICAvKiBOb3cgdHJ5IHRvIG5lZ2lvY2lhdGUgdGhlIHByb3RlY3Rpb24gbGV2ZWwuICovCiAgY29kZSA9IGZ0cF9zZW5kX2NvbW1hbmQoY29ubiwgIlBST1QgJWMiLCBsZXZlbF90b19jaGFyKGxldmVsKSk7CgogIGlmKGNvZGUgPCAwKQogICAgcmV0dXJuIC0xOwoKICBpZihjb2RlLzEwMCAhPSAyKSB7CiAgICBmYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIHNldCB0aGUgcHJvdGVjdGlvbiBsZXZlbC4iKTsKICAgIHJldHVybiAtMTsKICB9CgogIGNvbm4tPmRhdGFfcHJvdCA9IGxldmVsOwogIGlmKGxldmVsID09IFBST1RfUFJJVkFURSkKICAgIGNvbm4tPmNvbW1hbmRfcHJvdCA9IGxldmVsOwoKICByZXR1cm4gMDsKfQoKaW50CkN1cmxfc2VjX3JlcXVlc3RfcHJvdChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNvbnN0IGNoYXIgKmxldmVsKQp7CiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGwgPSBuYW1lX3RvX2xldmVsKGxldmVsKTsKICBpZihsID09IFBST1RfTk9ORSkKICAgIHJldHVybiAtMTsKICBERUJVR0FTU0VSVChsID4gUFJPVF9OT05FICYmIGwgPCBQUk9UX0xBU1QpOwogIGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90ID0gbDsKICByZXR1cm4gMDsKfQoKc3RhdGljIENVUkxjb2RlIGNob29zZV9tZWNoKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGludCByZXQ7CiAgc3RydWN0IEN1cmxfZWFzeSAqZGF0YSA9IGNvbm4tPmRhdGE7CiAgdm9pZCAqdG1wX2FsbG9jYXRpb247CiAgY29uc3Qgc3RydWN0IEN1cmxfc2VjX2NsaWVudF9tZWNoICptZWNoID0gJkN1cmxfa3JiNV9jbGllbnRfbWVjaDsKCiAgdG1wX2FsbG9jYXRpb24gPSByZWFsbG9jKGNvbm4tPmFwcF9kYXRhLCBtZWNoLT5zaXplKTsKICBpZih0bXBfYWxsb2NhdGlvbiA9PSBOVUxMKSB7CiAgICBmYWlsZihkYXRhLCAiRmFpbGVkIHJlYWxsb2Mgb2Ygc2l6ZSAldSIsIG1lY2gtPnNpemUpOwogICAgbWVjaCA9IE5VTEw7CiAgICByZXR1cm4gQ1VSTEVfT1VUX09GX01FTU9SWTsKICB9CiAgY29ubi0+YXBwX2RhdGEgPSB0bXBfYWxsb2NhdGlvbjsKCiAgaWYobWVjaC0+aW5pdCkgewogICAgcmV0ID0gbWVjaC0+aW5pdChjb25uLT5hcHBfZGF0YSk7CiAgICBpZihyZXQpIHsKICAgICAgaW5mb2YoZGF0YSwgIkZhaWxlZCBpbml0aWFsaXphdGlvbiBmb3IgJXMuIFNraXBwaW5nIGl0LlxuIiwKICAgICAgICAgICAgbWVjaC0+bmFtZSk7CiAgICAgIHJldHVybiBDVVJMRV9GQUlMRURfSU5JVDsKICAgIH0KICB9CgogIGluZm9mKGRhdGEsICJUcnlpbmcgbWVjaGFuaXNtICVzLi4uXG4iLCBtZWNoLT5uYW1lKTsKICByZXQgPSBmdHBfc2VuZF9jb21tYW5kKGNvbm4sICJBVVRIICVzIiwgbWVjaC0+bmFtZSk7CiAgaWYocmV0IDwgMCkKICAgIC8qIEZJWE1FOiBUaGlzIGVycm9yIGlzIHRvbyBnZW5lcmljIGJ1dCBpdCBpcyBPSyBmb3Igbm93LiAqLwogICAgcmV0dXJuIENVUkxFX0NPVUxETlRfQ09OTkVDVDsKCiAgaWYocmV0LzEwMCAhPSAzKSB7CiAgICBzd2l0Y2gocmV0KSB7CiAgICBjYXNlIDUwNDoKICAgICAgaW5mb2YoZGF0YSwgIk1lY2hhbmlzbSAlcyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2ZXIgKHNlcnZlciAiCiAgICAgICAgICAgICJyZXR1cm5lZCBmdHAgY29kZTogNTA0KS5cbiIsIG1lY2gtPm5hbWUpOwogICAgICBicmVhazsKICAgIGNhc2UgNTM0OgogICAgICBpbmZvZihkYXRhLCAiTWVjaGFuaXNtICVzIHdhcyByZWplY3RlZCBieSB0aGUgc2VydmVyIChzZXJ2ZXIgcmV0dXJuZWQgIgogICAgICAgICAgICAiZnRwIGNvZGU6IDUzNCkuXG4iLCBtZWNoLT5uYW1lKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBpZihyZXQvMTAwID09IDUpIHsKICAgICAgICBpbmZvZihkYXRhLCAic2VydmVyIGRvZXMgbm90IHN1cHBvcnQgdGhlIHNlY3VyaXR5IGV4dGVuc2lvbnNcbiIpOwogICAgICAgIHJldHVybiBDVVJMRV9VU0VfU1NMX0ZBSUxFRDsKICAgICAgfQogICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBDVVJMRV9MT0dJTl9ERU5JRUQ7CiAgfQoKICAvKiBBdXRoZW50aWNhdGUgKi8KICByZXQgPSBtZWNoLT5hdXRoKGNvbm4tPmFwcF9kYXRhLCBjb25uKTsKCiAgaWYocmV0ICE9IEFVVEhfQ09OVElOVUUpIHsKICAgIGlmKHJldCAhPSBBVVRIX09LKSB7CiAgICAgIC8qIE1lY2hhbmlzbSBoYXMgZHVtcGVkIHRoZSBlcnJvciB0byBzdGRlcnIsIGRvbid0IGVycm9yIGhlcmUuICovCiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIERFQlVHQVNTRVJUKHJldCA9PSBBVVRIX09LKTsKCiAgICBjb25uLT5tZWNoID0gbWVjaDsKICAgIGNvbm4tPnNlY19jb21wbGV0ZSA9IDE7CiAgICBjb25uLT5yZWN2W0ZJUlNUU09DS0VUXSA9IHNlY19yZWN2OwogICAgY29ubi0+c2VuZFtGSVJTVFNPQ0tFVF0gPSBzZWNfc2VuZDsKICAgIGNvbm4tPnJlY3ZbU0VDT05EQVJZU09DS0VUXSA9IHNlY19yZWN2OwogICAgY29ubi0+c2VuZFtTRUNPTkRBUllTT0NLRVRdID0gc2VjX3NlbmQ7CiAgICBjb25uLT5jb21tYW5kX3Byb3QgPSBQUk9UX1NBRkU7CiAgICAvKiBTZXQgdGhlIHJlcXVlc3RlZCBwcm90ZWN0aW9uIGxldmVsICovCiAgICAvKiBCTE9DS0lORyAqLwogICAgKHZvaWQpc2VjX3NldF9wcm90ZWN0aW9uX2xldmVsKGNvbm4pOwogIH0KCiAgcmV0dXJuIENVUkxFX09LOwp9CgpDVVJMY29kZQpDdXJsX3NlY19sb2dpbihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICByZXR1cm4gY2hvb3NlX21lY2goY29ubik7Cn0KCgp2b2lkCkN1cmxfc2VjX2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpZihjb25uLT5tZWNoICE9IE5VTEwgJiYgY29ubi0+bWVjaC0+ZW5kKQogICAgY29ubi0+bWVjaC0+ZW5kKGNvbm4tPmFwcF9kYXRhKTsKICBmcmVlKGNvbm4tPmFwcF9kYXRhKTsKICBjb25uLT5hcHBfZGF0YSA9IE5VTEw7CiAgaWYoY29ubi0+aW5fYnVmZmVyLmRhdGEpIHsKICAgIGZyZWUoY29ubi0+aW5fYnVmZmVyLmRhdGEpOwogICAgY29ubi0+aW5fYnVmZmVyLmRhdGEgPSBOVUxMOwogICAgY29ubi0+aW5fYnVmZmVyLnNpemUgPSAwOwogICAgY29ubi0+aW5fYnVmZmVyLmluZGV4ID0gMDsKICAgIC8qIEZJWE1FOiBJcyB0aGlzIHJlYWxseSBuZWVkZWQ/ICovCiAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAwOwogIH0KICBjb25uLT5zZWNfY29tcGxldGUgPSAwOwogIGNvbm4tPmRhdGFfcHJvdCA9IFBST1RfQ0xFQVI7CiAgY29ubi0+bWVjaCA9IE5VTEw7Cn0KCiNlbmRpZiAvKiBIQVZFX0dTU0FQSSAqLwoKI2VuZGlmIC8qIENVUkxfRElTQUJMRV9GVFAgKi8K