LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTksIDIwMTcgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEgLSAyMDE1LCBEYW5pZWwgU3RlbmJlcmcsIDxkYW5pZWxAaGF4eC5zZT4sIGV0IGFsLgogKgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAiY3VybF9zZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBIQVZFX0dTU0FQSQoKI2lmZGVmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCgojaW5jbHVkZSA8bGltaXRzLmg+CgojaW5jbHVkZSAidXJsZGF0YS5oIgojaW5jbHVkZSAiY3VybF9iYXNlNjQuaCIKI2luY2x1ZGUgImN1cmxfbWVtb3J5LmgiCiNpbmNsdWRlICJjdXJsX3NlYy5oIgojaW5jbHVkZSAiZnRwLmgiCiNpbmNsdWRlICJzZW5kZi5oIgojaW5jbHVkZSAic3RyY2FzZS5oIgojaW5jbHVkZSAid2Fybmxlc3MuaCIKI2luY2x1ZGUgInN0cmR1cC5oIgovKiBUaGUgbGFzdCAjaW5jbHVkZSBmaWxlIHNob3VsZCBiZTogKi8KI2luY2x1ZGUgIm1lbWRlYnVnLmgiCgpzdGF0aWMgY29uc3Qgc3RydWN0IHsKICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgbGV2ZWw7CiAgY29uc3QgY2hhciAqbmFtZTsKfSBsZXZlbF9uYW1lc1tdID0gewogIHsgUFJPVF9DTEVBUiwgImNsZWFyIiB9LAogIHsgUFJPVF9TQUZFLCAic2FmZSIgfSwKICB7IFBST1RfQ09ORklERU5USUFMLCAiY29uZmlkZW50aWFsIiB9LAogIHsgUFJPVF9QUklWQVRFLCAicHJpdmF0ZSIgfQp9OwoKc3RhdGljIGVudW0gcHJvdGVjdGlvbl9sZXZlbApuYW1lX3RvX2xldmVsKGNvbnN0IGNoYXIgKm5hbWUpCnsKICBpbnQgaTsKICBmb3IoaSA9IDA7IGkgPCAoaW50KXNpemVvZihsZXZlbF9uYW1lcykvKGludClzaXplb2YobGV2ZWxfbmFtZXNbMF0pOyBpKyspCiAgICBpZihjaGVja3ByZWZpeChuYW1lLCBsZXZlbF9uYW1lc1tpXS5uYW1lKSkKICAgICAgcmV0dXJuIGxldmVsX25hbWVzW2ldLmxldmVsOwogIHJldHVybiBQUk9UX05PTkU7Cn0KCi8qIENvbnZlcnQgYSBwcm90b2NvbCB8bGV2ZWx8IHRvIGl0cyBjaGFyIHJlcHJlc2VudGF0aW9uLgogICBXZSB0YWtlIGFuIGludCB0byBjYXRjaCBwcm9ncmFtbWluZyBtaXN0YWtlcy4gKi8Kc3RhdGljIGNoYXIgbGV2ZWxfdG9fY2hhcihpbnQgbGV2ZWwpCnsKICBzd2l0Y2gobGV2ZWwpIHsKICBjYXNlIFBST1RfQ0xFQVI6CiAgICByZXR1cm4gJ0MnOwogIGNhc2UgUFJPVF9TQUZFOgogICAgcmV0dXJuICdTJzsKICBjYXNlIFBST1RfQ09ORklERU5USUFMOgogICAgcmV0dXJuICdFJzsKICBjYXNlIFBST1RfUFJJVkFURToKICAgIHJldHVybiAnUCc7CiAgY2FzZSBQUk9UX0NNRDoKICAgIC8qIEZhbGwgdGhyb3VnaCAqLwogIGRlZmF1bHQ6CiAgICAvKiBUaG9zZSAyIGNhc2VzIHNob3VsZCBub3QgYmUgcmVhY2hlZCEgKi8KICAgIGJyZWFrOwogIH0KICBERUJVR0FTU0VSVCgwKTsKICAvKiBEZWZhdWx0IHRvIHRoZSBtb3N0IHNlY3VyZSBhbHRlcm5hdGl2ZS4gKi8KICByZXR1cm4gJ1AnOwp9CgovKiBTZW5kIGFuIEZUUCBjb21tYW5kIGRlZmluZWQgYnkgfG1lc3NhZ2V8IGFuZCB0aGUgb3B0aW9uYWwgYXJndW1lbnRzLiBUaGUKICAgZnVuY3Rpb24gcmV0dXJucyB0aGUgZnRwX2NvZGUuIElmIGFuIGVycm9yIG9jY3VycywgLTEgaXMgcmV0dXJuZWQuICovCnN0YXRpYyBpbnQgZnRwX3NlbmRfY29tbWFuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNvbnN0IGNoYXIgKm1lc3NhZ2UsIC4uLikKewogIGludCBmdHBfY29kZTsKICBzc2l6ZV90IG5yZWFkID0gMDsKICB2YV9saXN0IGFyZ3M7CiAgY2hhciBwcmludF9idWZmZXJbNTBdOwoKICB2YV9zdGFydChhcmdzLCBtZXNzYWdlKTsKICB2c25wcmludGYocHJpbnRfYnVmZmVyLCBzaXplb2YocHJpbnRfYnVmZmVyKSwgbWVzc2FnZSwgYXJncyk7CiAgdmFfZW5kKGFyZ3MpOwoKICBpZihDdXJsX2Z0cHNlbmQoY29ubiwgcHJpbnRfYnVmZmVyKSkgewogICAgZnRwX2NvZGUgPSAtMTsKICB9CiAgZWxzZSB7CiAgICBpZihDdXJsX0dldEZUUFJlc3BvbnNlKCZucmVhZCwgY29ubiwgJmZ0cF9jb2RlKSkKICAgICAgZnRwX2NvZGUgPSAtMTsKICB9CgogICh2b2lkKW5yZWFkOyAvKiBVbnVzZWQgKi8KICByZXR1cm4gZnRwX2NvZGU7Cn0KCi8qIFJlYWQgfGxlbnwgZnJvbSB0aGUgc29ja2V0IHxmZHwgYW5kIHN0b3JlIGl0IGluIHx0b3wuIFJldHVybiBhIENVUkxjb2RlCiAgIHNheWluZyB3aGV0aGVyIGFuIGVycm9yIG9jY3VycmVkIG9yIENVUkxFX09LIGlmIHxsZW58IHdhcyByZWFkLiAqLwpzdGF0aWMgQ1VSTGNvZGUKc29ja2V0X3JlYWQoY3VybF9zb2NrZXRfdCBmZCwgdm9pZCAqdG8sIHNpemVfdCBsZW4pCnsKICBjaGFyICp0b19wID0gdG87CiAgQ1VSTGNvZGUgcmVzdWx0OwogIHNzaXplX3QgbnJlYWQ7CgogIHdoaWxlKGxlbiA+IDApIHsKICAgIHJlc3VsdCA9IEN1cmxfcmVhZF9wbGFpbihmZCwgdG9fcCwgbGVuLCAmbnJlYWQpOwogICAgaWYoIXJlc3VsdCkgewogICAgICBsZW4gLT0gbnJlYWQ7CiAgICAgIHRvX3AgKz0gbnJlYWQ7CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogRklYTUU6IFdlIGFyZSBkb2luZyBhIGJ1c3kgd2FpdCAqLwogICAgICBpZihyZXN1bHQgPT0gQ1VSTEVfQUdBSU4pCiAgICAgICAgY29udGludWU7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgfQogIHJldHVybiBDVVJMRV9PSzsKfQoKCi8qIFdyaXRlIHxsZW58IGJ5dGVzIGZyb20gdGhlIGJ1ZmZlciB8dG98IHRvIHRoZSBzb2NrZXQgfGZkfC4gUmV0dXJuIGEKICAgQ1VSTGNvZGUgc2F5aW5nIHdoZXRoZXIgYW4gZXJyb3Igb2NjdXJyZWQgb3IgQ1VSTEVfT0sgaWYgfGxlbnwgd2FzCiAgIHdyaXR0ZW4uICovCnN0YXRpYyBDVVJMY29kZQpzb2NrZXRfd3JpdGUoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjdXJsX3NvY2tldF90IGZkLCBjb25zdCB2b2lkICp0bywKICAgICAgICAgICAgIHNpemVfdCBsZW4pCnsKICBjb25zdCBjaGFyICp0b19wID0gdG87CiAgQ1VSTGNvZGUgcmVzdWx0OwogIHNzaXplX3Qgd3JpdHRlbjsKCiAgd2hpbGUobGVuID4gMCkgewogICAgcmVzdWx0ID0gQ3VybF93cml0ZV9wbGFpbihjb25uLCBmZCwgdG9fcCwgbGVuLCAmd3JpdHRlbik7CiAgICBpZighcmVzdWx0KSB7CiAgICAgIGxlbiAtPSB3cml0dGVuOwogICAgICB0b19wICs9IHdyaXR0ZW47CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogRklYTUU6IFdlIGFyZSBkb2luZyBhIGJ1c3kgd2FpdCAqLwogICAgICBpZihyZXN1bHQgPT0gQ1VSTEVfQUdBSU4pCiAgICAgICAgY29udGludWU7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgfQogIHJldHVybiBDVVJMRV9PSzsKfQoKc3RhdGljIENVUkxjb2RlIHJlYWRfZGF0YShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3VybF9zb2NrZXRfdCBmZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qga3JiNWJ1ZmZlciAqYnVmKQp7CiAgaW50IGxlbjsKICB2b2lkICp0bXAgPSBOVUxMOwogIENVUkxjb2RlIHJlc3VsdDsKCiAgcmVzdWx0ID0gc29ja2V0X3JlYWQoZmQsICZsZW4sIHNpemVvZihsZW4pKTsKICBpZihyZXN1bHQpCiAgICByZXR1cm4gcmVzdWx0OwoKICBpZihsZW4pIHsKICAgIC8qIG9ubHkgcmVhbGxvYyBpZiB0aGVyZSB3YXMgYSBsZW5ndGggKi8KICAgIGxlbiA9IG50b2hsKGxlbik7CiAgICB0bXAgPSBDdXJsX3NhZmVyZWFsbG9jKGJ1Zi0+ZGF0YSwgbGVuKTsKICB9CiAgaWYodG1wID09IE5VTEwpCiAgICByZXR1cm4gQ1VSTEVfT1VUX09GX01FTU9SWTsKCiAgYnVmLT5kYXRhID0gdG1wOwogIHJlc3VsdCA9IHNvY2tldF9yZWFkKGZkLCBidWYtPmRhdGEsIGxlbik7CiAgaWYocmVzdWx0KQogICAgcmV0dXJuIHJlc3VsdDsKICBidWYtPnNpemUgPSBjb25uLT5tZWNoLT5kZWNvZGUoY29ubi0+YXBwX2RhdGEsIGJ1Zi0+ZGF0YSwgbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5kYXRhX3Byb3QsIGNvbm4pOwogIGJ1Zi0+aW5kZXggPSAwOwogIHJldHVybiBDVVJMRV9PSzsKfQoKc3RhdGljIHNpemVfdApidWZmZXJfcmVhZChzdHJ1Y3Qga3JiNWJ1ZmZlciAqYnVmLCB2b2lkICpkYXRhLCBzaXplX3QgbGVuKQp7CiAgaWYoYnVmLT5zaXplIC0gYnVmLT5pbmRleCA8IGxlbikKICAgIGxlbiA9IGJ1Zi0+c2l6ZSAtIGJ1Zi0+aW5kZXg7CiAgbWVtY3B5KGRhdGEsIChjaGFyICopYnVmLT5kYXRhICsgYnVmLT5pbmRleCwgbGVuKTsKICBidWYtPmluZGV4ICs9IGxlbjsKICByZXR1cm4gbGVuOwp9CgovKiBNYXRjaGVzIEN1cmxfcmVjdiBzaWduYXR1cmUgKi8Kc3RhdGljIHNzaXplX3Qgc2VjX3JlY3Yoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgc29ja2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpidWZmZXIsIHNpemVfdCBsZW4sIENVUkxjb2RlICplcnIpCnsKICBzaXplX3QgYnl0ZXNfcmVhZDsKICBzaXplX3QgdG90YWxfcmVhZCA9IDA7CiAgY3VybF9zb2NrZXRfdCBmZCA9IGNvbm4tPnNvY2tbc29ja2luZGV4XTsKCiAgKmVyciA9IENVUkxFX09LOwoKICAvKiBIYW5kbGUgY2xlYXIgdGV4dCByZXNwb25zZS4gKi8KICBpZihjb25uLT5zZWNfY29tcGxldGUgPT0gMCB8fCBjb25uLT5kYXRhX3Byb3QgPT0gUFJPVF9DTEVBUikKICAgICAgcmV0dXJuIHJlYWQoZmQsIGJ1ZmZlciwgbGVuKTsKCiAgaWYoY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnKSB7CiAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAwOwogICAgcmV0dXJuIDA7CiAgfQoKICBieXRlc19yZWFkID0gYnVmZmVyX3JlYWQoJmNvbm4tPmluX2J1ZmZlciwgYnVmZmVyLCBsZW4pOwogIGxlbiAtPSBieXRlc19yZWFkOwogIHRvdGFsX3JlYWQgKz0gYnl0ZXNfcmVhZDsKICBidWZmZXIgKz0gYnl0ZXNfcmVhZDsKCiAgd2hpbGUobGVuID4gMCkgewogICAgaWYocmVhZF9kYXRhKGNvbm4sIGZkLCAmY29ubi0+aW5fYnVmZmVyKSkKICAgICAgcmV0dXJuIC0xOwogICAgaWYoY29ubi0+aW5fYnVmZmVyLnNpemUgPT0gMCkgewogICAgICBpZihieXRlc19yZWFkID4gMCkKICAgICAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAxOwogICAgICByZXR1cm4gYnl0ZXNfcmVhZDsKICAgIH0KICAgIGJ5dGVzX3JlYWQgPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbik7CiAgICBsZW4gLT0gYnl0ZXNfcmVhZDsKICAgIHRvdGFsX3JlYWQgKz0gYnl0ZXNfcmVhZDsKICAgIGJ1ZmZlciArPSBieXRlc19yZWFkOwogIH0KICAvKiBGSVhNRTogQ2hlY2sgZm9yIG92ZXJmbG93ICovCiAgcmV0dXJuIHRvdGFsX3JlYWQ7Cn0KCi8qIFNlbmQgfGxlbmd0aHwgYnl0ZXMgZnJvbSB8ZnJvbXwgdG8gdGhlIHxmZHwgc29ja2V0IHRha2luZyBjYXJlIG9mIGVuY29kaW5nCiAgIGFuZCBuZWdvY2lhdGluZyB3aXRoIHRoZSBzZXJ2ZXIuIHxmcm9tfCBjYW4gYmUgTlVMTC4gKi8KLyogRklYTUU6IFdlIGRvbid0IGNoZWNrIGZvciBlcnJvcnMgbm9yIHJlcG9ydCBhbnkhICovCnN0YXRpYyB2b2lkIGRvX3NlY19zZW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY3VybF9zb2NrZXRfdCBmZCwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZnJvbSwgaW50IGxlbmd0aCkKewogIGludCBieXRlcywgaHRvbmxfYnl0ZXM7IC8qIDMyLWJpdCBpbnRlZ2VycyBmb3IgaHRvbmwgKi8KICBjaGFyICpidWZmZXIgPSBOVUxMOwogIGNoYXIgKmNtZF9idWZmZXI7CiAgc2l6ZV90IGNtZF9zaXplID0gMDsKICBDVVJMY29kZSBlcnJvcjsKICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgcHJvdF9sZXZlbCA9IGNvbm4tPmRhdGFfcHJvdDsKICBib29sIGlzY21kID0gKHByb3RfbGV2ZWwgPT0gUFJPVF9DTUQpP1RSVUU6RkFMU0U7CgogIERFQlVHQVNTRVJUKHByb3RfbGV2ZWwgPiBQUk9UX05PTkUgJiYgcHJvdF9sZXZlbCA8IFBST1RfTEFTVCk7CgogIGlmKGlzY21kKSB7CiAgICBpZighc3RybmNtcChmcm9tLCAiUEFTUyAiLCA1KSB8fCAhc3RybmNtcChmcm9tLCAiQUNDVCAiLCA1KSkKICAgICAgcHJvdF9sZXZlbCA9IFBST1RfUFJJVkFURTsKICAgIGVsc2UKICAgICAgcHJvdF9sZXZlbCA9IGNvbm4tPmNvbW1hbmRfcHJvdDsKICB9CiAgYnl0ZXMgPSBjb25uLT5tZWNoLT5lbmNvZGUoY29ubi0+YXBwX2RhdGEsIGZyb20sIGxlbmd0aCwgcHJvdF9sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKikmYnVmZmVyKTsKICBpZighYnVmZmVyIHx8IGJ5dGVzIDw9IDApCiAgICByZXR1cm47IC8qIGVycm9yICovCgogIGlmKGlzY21kKSB7CiAgICBlcnJvciA9IEN1cmxfYmFzZTY0X2VuY29kZShjb25uLT5kYXRhLCBidWZmZXIsIGN1cmx4X3NpdG91eihieXRlcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY21kX2J1ZmZlciwgJmNtZF9zaXplKTsKICAgIGlmKGVycm9yKSB7CiAgICAgIGZyZWUoYnVmZmVyKTsKICAgICAgcmV0dXJuOyAvKiBlcnJvciAqLwogICAgfQogICAgaWYoY21kX3NpemUgPiAwKSB7CiAgICAgIHN0YXRpYyBjb25zdCBjaGFyICplbmMgPSAiRU5DICI7CiAgICAgIHN0YXRpYyBjb25zdCBjaGFyICptaWMgPSAiTUlDICI7CiAgICAgIGlmKHByb3RfbGV2ZWwgPT0gUFJPVF9QUklWQVRFKQogICAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgZW5jLCA0KTsKICAgICAgZWxzZQogICAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgbWljLCA0KTsKCiAgICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgY21kX2J1ZmZlciwgY21kX3NpemUpOwogICAgICBzb2NrZXRfd3JpdGUoY29ubiwgZmQsICJcclxuIiwgMik7CiAgICAgIGluZm9mKGNvbm4tPmRhdGEsICJTZW5kOiAlcyVzXG4iLCBwcm90X2xldmVsID09IFBST1RfUFJJVkFURT9lbmM6bWljLAogICAgICAgICAgICBjbWRfYnVmZmVyKTsKICAgICAgZnJlZShjbWRfYnVmZmVyKTsKICAgIH0KICB9CiAgZWxzZSB7CiAgICBodG9ubF9ieXRlcyA9IGh0b25sKGJ5dGVzKTsKICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgJmh0b25sX2J5dGVzLCBzaXplb2YoaHRvbmxfYnl0ZXMpKTsKICAgIHNvY2tldF93cml0ZShjb25uLCBmZCwgYnVmZmVyLCBjdXJseF9zaXRvdXooYnl0ZXMpKTsKICB9CiAgZnJlZShidWZmZXIpOwp9CgpzdGF0aWMgc3NpemVfdCBzZWNfd3JpdGUoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjdXJsX3NvY2tldF90IGZkLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYnVmZmVyLCBzaXplX3QgbGVuZ3RoKQp7CiAgc3NpemVfdCB0eCA9IDAsIGxlbiA9IGNvbm4tPmJ1ZmZlcl9zaXplOwoKICBsZW4gLT0gY29ubi0+bWVjaC0+b3ZlcmhlYWQoY29ubi0+YXBwX2RhdGEsIGNvbm4tPmRhdGFfcHJvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VybHhfc3p0b3NpKGxlbikpOwogIGlmKGxlbiA8PSAwKQogICAgbGVuID0gbGVuZ3RoOwogIHdoaWxlKGxlbmd0aCkgewogICAgaWYobGVuZ3RoIDwgKHNpemVfdClsZW4pCiAgICAgIGxlbiA9IGxlbmd0aDsKCiAgICBkb19zZWNfc2VuZChjb25uLCBmZCwgYnVmZmVyLCBjdXJseF9zenRvc2kobGVuKSk7CiAgICBsZW5ndGggLT0gbGVuOwogICAgYnVmZmVyICs9IGxlbjsKICAgIHR4ICs9IGxlbjsKICB9CiAgcmV0dXJuIHR4Owp9CgovKiBNYXRjaGVzIEN1cmxfc2VuZCBzaWduYXR1cmUgKi8Kc3RhdGljIHNzaXplX3Qgc2VjX3NlbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgc29ja2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpidWZmZXIsIHNpemVfdCBsZW4sIENVUkxjb2RlICplcnIpCnsKICBjdXJsX3NvY2tldF90IGZkID0gY29ubi0+c29ja1tzb2NraW5kZXhdOwogICplcnIgPSBDVVJMRV9PSzsKICByZXR1cm4gc2VjX3dyaXRlKGNvbm4sIGZkLCBidWZmZXIsIGxlbik7Cn0KCmludCBDdXJsX3NlY19yZWFkX21zZyhzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNoYXIgKmJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbCkKewogIC8qIGRlY29kZWRfbGVuIHNob3VsZCBiZSBzaXplX3Qgb3Igc3NpemVfdCBidXQgY29ubi0+bWVjaC0+ZGVjb2RlIHJldHVybnMgYW4KICAgICBpbnQgKi8KICBpbnQgZGVjb2RlZF9sZW47CiAgY2hhciAqYnVmOwogIGludCByZXRfY29kZSA9IDA7CiAgc2l6ZV90IGRlY29kZWRfc3ogPSAwOwogIENVUkxjb2RlIGVycm9yOwoKICBpZighY29ubi0+bWVjaCkKICAgIC8qIG5vdCBpbml0aXRhbGl6ZWQsIHJldHVybiBlcnJvciAqLwogICAgcmV0dXJuIC0xOwoKICBERUJVR0FTU0VSVChsZXZlbCA+IFBST1RfTk9ORSAmJiBsZXZlbCA8IFBST1RfTEFTVCk7CgogIGVycm9yID0gQ3VybF9iYXNlNjRfZGVjb2RlKGJ1ZmZlciArIDQsICh1bnNpZ25lZCBjaGFyICoqKSZidWYsICZkZWNvZGVkX3N6KTsKICBpZihlcnJvciB8fCBkZWNvZGVkX3N6ID09IDApCiAgICByZXR1cm4gLTE7CgogIGlmKGRlY29kZWRfc3ogPiAoc2l6ZV90KUlOVF9NQVgpIHsKICAgIGZyZWUoYnVmKTsKICAgIHJldHVybiAtMTsKICB9CiAgZGVjb2RlZF9sZW4gPSBjdXJseF91enRvc2koZGVjb2RlZF9zeik7CgogIGRlY29kZWRfbGVuID0gY29ubi0+bWVjaC0+ZGVjb2RlKGNvbm4tPmFwcF9kYXRhLCBidWYsIGRlY29kZWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsLCBjb25uKTsKICBpZihkZWNvZGVkX2xlbiA8PSAwKSB7CiAgICBmcmVlKGJ1Zik7CiAgICByZXR1cm4gLTE7CiAgfQoKICBpZihjb25uLT5kYXRhLT5zZXQudmVyYm9zZSkgewogICAgYnVmW2RlY29kZWRfbGVuXSA9ICdcbic7CiAgICBDdXJsX2RlYnVnKGNvbm4tPmRhdGEsIENVUkxJTkZPX0hFQURFUl9JTiwgYnVmLCBkZWNvZGVkX2xlbiArIDEsIGNvbm4pOwogIH0KCiAgYnVmW2RlY29kZWRfbGVuXSA9ICdcMCc7CiAgaWYoZGVjb2RlZF9sZW4gPD0gMykKICAgIC8qIHN1c3BpY2lvdXNseSBzaG9ydCAqLwogICAgcmV0dXJuIDA7CgogIGlmKGJ1ZlszXSAhPSAnLScpCiAgICAvKiBzYWZlIHRvIGlnbm9yZSByZXR1cm4gY29kZSAqLwogICAgKHZvaWQpc3NjYW5mKGJ1ZiwgIiVkIiwgJnJldF9jb2RlKTsKCiAgaWYoYnVmW2RlY29kZWRfbGVuIC0gMV0gPT0gJ1xuJykKICAgIGJ1ZltkZWNvZGVkX2xlbiAtIDFdID0gJ1wwJzsKICAvKiBGSVhNRTogSXMgfGJ1ZmZlcnwgbGVuZ3RoIGFsd2F5cyBncmVhdGVyIHRoYW4gfGRlY29kZWRfbGVufD8gKi8KICBzdHJjcHkoYnVmZmVyLCBidWYpOwogIGZyZWUoYnVmKTsKICByZXR1cm4gcmV0X2NvZGU7Cn0KCi8qIEZJWE1FOiBUaGUgZXJyb3IgY29kZSByZXR1cm5lZCBoZXJlIGlzIG5ldmVyIGNoZWNrZWQuICovCnN0YXRpYyBpbnQgc2VjX3NldF9wcm90ZWN0aW9uX2xldmVsKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGludCBjb2RlOwogIGNoYXIgKnBic3o7CiAgc3RhdGljIHVuc2lnbmVkIGludCBidWZmZXJfc2l6ZSA9IDEgPDwgMjA7IC8qIDEwNDg1NzYgKi8KICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgbGV2ZWwgPSBjb25uLT5yZXF1ZXN0X2RhdGFfcHJvdDsKCiAgREVCVUdBU1NFUlQobGV2ZWwgPiBQUk9UX05PTkUgJiYgbGV2ZWwgPCBQUk9UX0xBU1QpOwoKICBpZighY29ubi0+c2VjX2NvbXBsZXRlKSB7CiAgICBpbmZvZihjb25uLT5kYXRhLCAiVHJ5aW5nIHRvIGNoYW5nZSB0aGUgcHJvdGVjdGlvbiBsZXZlbCBhZnRlciB0aGUiCiAgICAgICAgICAgICAgICAgICAgICAiY29tcGxldGlvbiBvZiB0aGUgZGF0YSBleGNoYW5nZS5cbiIpOwogICAgcmV0dXJuIC0xOwogIH0KCiAgLyogQmFpbCBvdXQgaWYgd2UgdHJ5IHRvIHNldCB1cCB0aGUgc2FtZSBsZXZlbCAqLwogIGlmKGNvbm4tPmRhdGFfcHJvdCA9PSBsZXZlbCkKICAgIHJldHVybiAwOwoKICBpZihsZXZlbCkgewogICAgY29kZSA9IGZ0cF9zZW5kX2NvbW1hbmQoY29ubiwgIlBCU1ogJXUiLCBidWZmZXJfc2l6ZSk7CiAgICBpZihjb2RlIDwgMCkKICAgICAgcmV0dXJuIC0xOwoKICAgIGlmKGNvZGUvMTAwICE9IDIpIHsKICAgICAgZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBzZXQgdGhlIHByb3RlY3Rpb24ncyBidWZmZXIgc2l6ZS4iKTsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgY29ubi0+YnVmZmVyX3NpemUgPSBidWZmZXJfc2l6ZTsKCiAgICBwYnN6ID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlBCU1o9Iik7CiAgICBpZihwYnN6KSB7CiAgICAgIC8qIGlnbm9yZSByZXR1cm4gY29kZSwgdXNlIGRlZmF1bHQgdmFsdWUgaWYgaXQgZmFpbHMgKi8KICAgICAgKHZvaWQpc3NjYW5mKHBic3osICJQQlNaPSV1IiwgJmJ1ZmZlcl9zaXplKTsKICAgICAgaWYoYnVmZmVyX3NpemUgPCBjb25uLT5idWZmZXJfc2l6ZSkKICAgICAgICBjb25uLT5idWZmZXJfc2l6ZSA9IGJ1ZmZlcl9zaXplOwogICAgfQogIH0KCiAgLyogTm93IHRyeSB0byBuZWdpb2NpYXRlIHRoZSBwcm90ZWN0aW9uIGxldmVsLiAqLwogIGNvZGUgPSBmdHBfc2VuZF9jb21tYW5kKGNvbm4sICJQUk9UICVjIiwgbGV2ZWxfdG9fY2hhcihsZXZlbCkpOwoKICBpZihjb2RlIDwgMCkKICAgIHJldHVybiAtMTsKCiAgaWYoY29kZS8xMDAgIT0gMikgewogICAgZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBzZXQgdGhlIHByb3RlY3Rpb24gbGV2ZWwuIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICBjb25uLT5kYXRhX3Byb3QgPSBsZXZlbDsKICBpZihsZXZlbCA9PSBQUk9UX1BSSVZBVEUpCiAgICBjb25uLT5jb21tYW5kX3Byb3QgPSBsZXZlbDsKCiAgcmV0dXJuIDA7Cn0KCmludApDdXJsX3NlY19yZXF1ZXN0X3Byb3Qoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjb25zdCBjaGFyICpsZXZlbCkKewogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsID0gbmFtZV90b19sZXZlbChsZXZlbCk7CiAgaWYobCA9PSBQUk9UX05PTkUpCiAgICByZXR1cm4gLTE7CiAgREVCVUdBU1NFUlQobCA+IFBST1RfTk9ORSAmJiBsIDwgUFJPVF9MQVNUKTsKICBjb25uLT5yZXF1ZXN0X2RhdGFfcHJvdCA9IGw7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBDVVJMY29kZSBjaG9vc2VfbWVjaChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgcmV0OwogIHN0cnVjdCBDdXJsX2Vhc3kgKmRhdGEgPSBjb25uLT5kYXRhOwogIHZvaWQgKnRtcF9hbGxvY2F0aW9uOwogIGNvbnN0IHN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCAqbWVjaCA9ICZDdXJsX2tyYjVfY2xpZW50X21lY2g7CgogIHRtcF9hbGxvY2F0aW9uID0gcmVhbGxvYyhjb25uLT5hcHBfZGF0YSwgbWVjaC0+c2l6ZSk7CiAgaWYodG1wX2FsbG9jYXRpb24gPT0gTlVMTCkgewogICAgZmFpbGYoZGF0YSwgIkZhaWxlZCByZWFsbG9jIG9mIHNpemUgJXUiLCBtZWNoLT5zaXplKTsKICAgIG1lY2ggPSBOVUxMOwogICAgcmV0dXJuIENVUkxFX09VVF9PRl9NRU1PUlk7CiAgfQogIGNvbm4tPmFwcF9kYXRhID0gdG1wX2FsbG9jYXRpb247CgogIGlmKG1lY2gtPmluaXQpIHsKICAgIHJldCA9IG1lY2gtPmluaXQoY29ubi0+YXBwX2RhdGEpOwogICAgaWYocmV0KSB7CiAgICAgIGluZm9mKGRhdGEsICJGYWlsZWQgaW5pdGlhbGl6YXRpb24gZm9yICVzLiBTa2lwcGluZyBpdC5cbiIsCiAgICAgICAgICAgIG1lY2gtPm5hbWUpOwogICAgICByZXR1cm4gQ1VSTEVfRkFJTEVEX0lOSVQ7CiAgICB9CiAgfQoKICBpbmZvZihkYXRhLCAiVHJ5aW5nIG1lY2hhbmlzbSAlcy4uLlxuIiwgbWVjaC0+bmFtZSk7CiAgcmV0ID0gZnRwX3NlbmRfY29tbWFuZChjb25uLCAiQVVUSCAlcyIsIG1lY2gtPm5hbWUpOwogIGlmKHJldCA8IDApCiAgICAvKiBGSVhNRTogVGhpcyBlcnJvciBpcyB0b28gZ2VuZXJpYyBidXQgaXQgaXMgT0sgZm9yIG5vdy4gKi8KICAgIHJldHVybiBDVVJMRV9DT1VMRE5UX0NPTk5FQ1Q7CgogIGlmKHJldC8xMDAgIT0gMykgewogICAgc3dpdGNoKHJldCkgewogICAgY2FzZSA1MDQ6CiAgICAgIGluZm9mKGRhdGEsICJNZWNoYW5pc20gJXMgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgc2VydmVyIChzZXJ2ZXIgIgogICAgICAgICAgICAicmV0dXJuZWQgZnRwIGNvZGU6IDUwNCkuXG4iLCBtZWNoLT5uYW1lKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDUzNDoKICAgICAgaW5mb2YoZGF0YSwgIk1lY2hhbmlzbSAlcyB3YXMgcmVqZWN0ZWQgYnkgdGhlIHNlcnZlciAoc2VydmVyIHJldHVybmVkICIKICAgICAgICAgICAgImZ0cCBjb2RlOiA1MzQpLlxuIiwgbWVjaC0+bmFtZSk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgaWYocmV0LzEwMCA9PSA1KSB7CiAgICAgICAgaW5mb2YoZGF0YSwgInNlcnZlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzZWN1cml0eSBleHRlbnNpb25zXG4iKTsKICAgICAgICByZXR1cm4gQ1VSTEVfVVNFX1NTTF9GQUlMRUQ7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gQ1VSTEVfTE9HSU5fREVOSUVEOwogIH0KCiAgLyogQXV0aGVudGljYXRlICovCiAgcmV0ID0gbWVjaC0+YXV0aChjb25uLT5hcHBfZGF0YSwgY29ubik7CgogIGlmKHJldCAhPSBBVVRIX0NPTlRJTlVFKSB7CiAgICBpZihyZXQgIT0gQVVUSF9PSykgewogICAgICAvKiBNZWNoYW5pc20gaGFzIGR1bXBlZCB0aGUgZXJyb3IgdG8gc3RkZXJyLCBkb24ndCBlcnJvciBoZXJlLiAqLwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBERUJVR0FTU0VSVChyZXQgPT0gQVVUSF9PSyk7CgogICAgY29ubi0+bWVjaCA9IG1lY2g7CiAgICBjb25uLT5zZWNfY29tcGxldGUgPSAxOwogICAgY29ubi0+cmVjdltGSVJTVFNPQ0tFVF0gPSBzZWNfcmVjdjsKICAgIGNvbm4tPnNlbmRbRklSU1RTT0NLRVRdID0gc2VjX3NlbmQ7CiAgICBjb25uLT5yZWN2W1NFQ09OREFSWVNPQ0tFVF0gPSBzZWNfcmVjdjsKICAgIGNvbm4tPnNlbmRbU0VDT05EQVJZU09DS0VUXSA9IHNlY19zZW5kOwogICAgY29ubi0+Y29tbWFuZF9wcm90ID0gUFJPVF9TQUZFOwogICAgLyogU2V0IHRoZSByZXF1ZXN0ZWQgcHJvdGVjdGlvbiBsZXZlbCAqLwogICAgLyogQkxPQ0tJTkcgKi8KICAgICh2b2lkKXNlY19zZXRfcHJvdGVjdGlvbl9sZXZlbChjb25uKTsKICB9CgogIHJldHVybiBDVVJMRV9PSzsKfQoKQ1VSTGNvZGUKQ3VybF9zZWNfbG9naW4oc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgcmV0dXJuIGNob29zZV9tZWNoKGNvbm4pOwp9CgoKdm9pZApDdXJsX3NlY19lbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaWYoY29ubi0+bWVjaCAhPSBOVUxMICYmIGNvbm4tPm1lY2gtPmVuZCkKICAgIGNvbm4tPm1lY2gtPmVuZChjb25uLT5hcHBfZGF0YSk7CiAgZnJlZShjb25uLT5hcHBfZGF0YSk7CiAgY29ubi0+YXBwX2RhdGEgPSBOVUxMOwogIGlmKGNvbm4tPmluX2J1ZmZlci5kYXRhKSB7CiAgICBmcmVlKGNvbm4tPmluX2J1ZmZlci5kYXRhKTsKICAgIGNvbm4tPmluX2J1ZmZlci5kYXRhID0gTlVMTDsKICAgIGNvbm4tPmluX2J1ZmZlci5zaXplID0gMDsKICAgIGNvbm4tPmluX2J1ZmZlci5pbmRleCA9IDA7CiAgICAvKiBGSVhNRTogSXMgdGhpcyByZWFsbHkgbmVlZGVkPyAqLwogICAgY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnID0gMDsKICB9CiAgY29ubi0+c2VjX2NvbXBsZXRlID0gMDsKICBjb25uLT5kYXRhX3Byb3QgPSBQUk9UX0NMRUFSOwogIGNvbm4tPm1lY2ggPSBOVUxMOwp9CgojZW5kaWYgLyogSEFWRV9HU1NBUEkgKi8KCiNlbmRpZiAvKiBDVVJMX0RJU0FCTEVfRlRQICovCg==