LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEgLSAyMDExLCBEYW5pZWwgU3RlbmJlcmcsIDxkYW5pZWxAaGF4eC5zZT4sIGV0IGFsLgogKgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBJbnN0aXR1dGUgbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzCiAqICAgIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZQogKiAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgSU5TVElUVVRFIEFORCBDT05UUklCVVRPUlMgYGBBUyBJUycnIEFORAogKiBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUKICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKICogQVJFIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgSU5TVElUVVRFIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4gICovCgojaW5jbHVkZSAic2V0dXAuaCIKCiNpZm5kZWYgQ1VSTF9ESVNBQkxFX0ZUUAojaWYgZGVmaW5lZChIQVZFX0tSQjQpIHx8IGRlZmluZWQoSEFWRV9HU1NBUEkpCgojaWZkZWYgSEFWRV9ORVREQl9ICiNpbmNsdWRlIDxuZXRkYi5oPgojZW5kaWYKCiNpZmRlZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCgojaWZkZWYgSEFWRV9MSU1JVFNfSAojaW5jbHVkZSA8bGltaXRzLmg+CiNlbmRpZgoKI2luY2x1ZGUgInVybGRhdGEuaCIKI2luY2x1ZGUgImN1cmxfYmFzZTY0LmgiCiNpbmNsdWRlICJjdXJsX21lbW9yeS5oIgojaW5jbHVkZSAia3JiNC5oIgojaW5jbHVkZSAiZnRwLmgiCiNpbmNsdWRlICJzZW5kZi5oIgojaW5jbHVkZSAicmF3c3RyLmgiCiNpbmNsdWRlICJ3YXJubGVzcy5oIgoKLyogVGhlIGxhc3QgI2luY2x1ZGUgZmlsZSBzaG91bGQgYmU6ICovCiNpbmNsdWRlICJtZW1kZWJ1Zy5oIgoKc3RhdGljIGNvbnN0IHN0cnVjdCB7CiAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsOwogIGNvbnN0IGNoYXIgKm5hbWU7Cn0gbGV2ZWxfbmFtZXNbXSA9IHsKICB7IFBST1RfQ0xFQVIsICJjbGVhciIgfSwKICB7IFBST1RfU0FGRSwgInNhZmUiIH0sCiAgeyBQUk9UX0NPTkZJREVOVElBTCwgImNvbmZpZGVudGlhbCIgfSwKICB7IFBST1RfUFJJVkFURSwgInByaXZhdGUiIH0KfTsKCnN0YXRpYyBlbnVtIHByb3RlY3Rpb25fbGV2ZWwKbmFtZV90b19sZXZlbChjb25zdCBjaGFyICpuYW1lKQp7CiAgaW50IGk7CiAgZm9yKGkgPSAwOyBpIDwgKGludClzaXplb2YobGV2ZWxfbmFtZXMpLyhpbnQpc2l6ZW9mKGxldmVsX25hbWVzWzBdKTsgaSsrKQogICAgaWYoY2hlY2twcmVmaXgobmFtZSwgbGV2ZWxfbmFtZXNbaV0ubmFtZSkpCiAgICAgIHJldHVybiBsZXZlbF9uYW1lc1tpXS5sZXZlbDsKICByZXR1cm4gUFJPVF9OT05FOwp9CgovKiBDb252ZXJ0IGEgcHJvdG9jb2wgfGxldmVsfCB0byBpdHMgY2hhciByZXByZXNlbnRhdGlvbi4KICAgV2UgdGFrZSBhbiBpbnQgdG8gY2F0Y2ggcHJvZ3JhbW1pbmcgbWlzdGFrZXMuICovCnN0YXRpYyBjaGFyIGxldmVsX3RvX2NoYXIoaW50IGxldmVsKSB7CiAgc3dpdGNoKGxldmVsKSB7CiAgY2FzZSBQUk9UX0NMRUFSOgogICAgcmV0dXJuICdDJzsKICBjYXNlIFBST1RfU0FGRToKICAgIHJldHVybiAnUyc7CiAgY2FzZSBQUk9UX0NPTkZJREVOVElBTDoKICAgIHJldHVybiAnRSc7CiAgY2FzZSBQUk9UX1BSSVZBVEU6CiAgICByZXR1cm4gJ1AnOwogIGNhc2UgUFJPVF9DTUQ6CiAgICAvKiBGYWxsIHRocm91Z2ggKi8KICBkZWZhdWx0OgogICAgLyogVGhvc2UgMiBjYXNlcyBzaG91bGQgbm90IGJlIHJlYWNoZWQhICovCiAgICBicmVhazsKICB9CiAgREVCVUdBU1NFUlQoMCk7CiAgLyogRGVmYXVsdCB0byB0aGUgbW9zdCBzZWN1cmUgYWx0ZXJuYXRpdmUuICovCiAgcmV0dXJuICdQJzsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCAqIGNvbnN0IG1lY2hzW10gPSB7CiNpZiBkZWZpbmVkKEhBVkVfR1NTQVBJKQogICZDdXJsX2tyYjVfY2xpZW50X21lY2gsCiNlbmRpZgojaWYgZGVmaW5lZChIQVZFX0tSQjQpCiAgJkN1cmxfa3JiNF9jbGllbnRfbWVjaCwKI2VuZGlmCiAgTlVMTAp9OwoKLyogU2VuZCBhbiBGVFAgY29tbWFuZCBkZWZpbmVkIGJ5IHxtZXNzYWdlfCBhbmQgdGhlIG9wdGlvbmFsIGFyZ3VtZW50cy4gVGhlCiAgIGZ1bmN0aW9uIHJldHVybnMgdGhlIGZ0cF9jb2RlLiBJZiBhbiBlcnJvciBvY2N1cnMsIC0xIGlzIHJldHVybmVkLiAqLwpzdGF0aWMgaW50IGZ0cF9zZW5kX2NvbW1hbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjb25zdCBjaGFyICptZXNzYWdlLCAuLi4pCnsKICBpbnQgZnRwX2NvZGU7CiAgc3NpemVfdCBucmVhZDsKICB2YV9saXN0IGFyZ3M7CiAgY2hhciBwcmludF9idWZmZXJbNTBdOwoKICB2YV9zdGFydChhcmdzLCBtZXNzYWdlKTsKICB2c25wcmludGYocHJpbnRfYnVmZmVyLCBzaXplb2YocHJpbnRfYnVmZmVyKSwgbWVzc2FnZSwgYXJncyk7CiAgdmFfZW5kKGFyZ3MpOwoKICBpZihDdXJsX2Z0cHNlbmRmKGNvbm4sIHByaW50X2J1ZmZlcikgIT0gQ1VSTEVfT0spIHsKICAgIGZ0cF9jb2RlID0gLTE7CiAgfQogIGVsc2UgewogICAgaWYoQ3VybF9HZXRGVFBSZXNwb25zZSgmbnJlYWQsIGNvbm4sICZmdHBfY29kZSkgIT0gQ1VSTEVfT0spCiAgICAgIGZ0cF9jb2RlID0gLTE7CiAgfQoKICAodm9pZClucmVhZDsgLyogVW51c2VkICovCiAgcmV0dXJuIGZ0cF9jb2RlOwp9CgovKiBSZWFkIHxsZW58IGZyb20gdGhlIHNvY2tldCB8ZmR8IGFuZCBzdG9yZSBpdCBpbiB8dG98LiBSZXR1cm4gYSBDVVJMY29kZQogICBzYXlpbmcgd2hldGhlciBhbiBlcnJvciBvY2N1cnJlZCBvciBDVVJMRV9PSyBpZiB8bGVufCB3YXMgcmVhZC4gKi8Kc3RhdGljIENVUkxjb2RlCnNvY2tldF9yZWFkKGN1cmxfc29ja2V0X3QgZmQsIHZvaWQgKnRvLCBzaXplX3QgbGVuKQp7CiAgY2hhciAqdG9fcCA9IHRvOwogIENVUkxjb2RlIGNvZGU7CiAgc3NpemVfdCBucmVhZDsKCiAgd2hpbGUobGVuID4gMCkgewogICAgY29kZSA9IEN1cmxfcmVhZF9wbGFpbihmZCwgdG9fcCwgbGVuLCAmbnJlYWQpOwogICAgaWYoY29kZSA9PSBDVVJMRV9PSykgewogICAgICBsZW4gLT0gbnJlYWQ7CiAgICAgIHRvX3AgKz0gbnJlYWQ7CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogRklYTUU6IFdlIGFyZSBkb2luZyBhIGJ1c3kgd2FpdCAqLwogICAgICBpZihjb2RlID09IENVUkxFX0FHQUlOKQogICAgICAgIGNvbnRpbnVlOwogICAgICByZXR1cm4gY29kZTsKICAgIH0KICB9CiAgcmV0dXJuIENVUkxFX09LOwp9CgoKLyogV3JpdGUgfGxlbnwgYnl0ZXMgZnJvbSB0aGUgYnVmZmVyIHx0b3wgdG8gdGhlIHNvY2tldCB8ZmR8LiBSZXR1cm4gYQogICBDVVJMY29kZSBzYXlpbmcgd2hldGhlciBhbiBlcnJvciBvY2N1cnJlZCBvciBDVVJMRV9PSyBpZiB8bGVufCB3YXMKICAgd3JpdHRlbi4gKi8Kc3RhdGljIENVUkxjb2RlCnNvY2tldF93cml0ZShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGN1cmxfc29ja2V0X3QgZmQsIGNvbnN0IHZvaWQgKnRvLAogICAgICAgICAgICAgc2l6ZV90IGxlbikKewogIGNvbnN0IGNoYXIgKnRvX3AgPSB0bzsKICBDVVJMY29kZSBjb2RlOwogIHNzaXplX3Qgd3JpdHRlbjsKCiAgd2hpbGUobGVuID4gMCkgewogICAgY29kZSA9IEN1cmxfd3JpdGVfcGxhaW4oY29ubiwgZmQsIHRvX3AsIGxlbiwgJndyaXR0ZW4pOwogICAgaWYoY29kZSA9PSBDVVJMRV9PSykgewogICAgICBsZW4gLT0gd3JpdHRlbjsKICAgICAgdG9fcCArPSB3cml0dGVuOwogICAgfQogICAgZWxzZSB7CiAgICAgIC8qIEZJWE1FOiBXZSBhcmUgZG9pbmcgYSBidXN5IHdhaXQgKi8KICAgICAgaWYoY29kZSA9PSBDVVJMRV9BR0FJTikKICAgICAgICBjb250aW51ZTsKICAgICAgcmV0dXJuIGNvZGU7CiAgICB9CiAgfQogIHJldHVybiBDVVJMRV9PSzsKfQoKc3RhdGljIENVUkxjb2RlIHJlYWRfZGF0YShzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3VybF9zb2NrZXRfdCBmZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qga3JiNGJ1ZmZlciAqYnVmKQp7CiAgaW50IGxlbjsKICB2b2lkKiB0bXA7CiAgQ1VSTGNvZGUgcmV0OwoKICByZXQgPSBzb2NrZXRfcmVhZChmZCwgJmxlbiwgc2l6ZW9mKGxlbikpOwogIGlmKHJldCAhPSBDVVJMRV9PSykKICAgIHJldHVybiByZXQ7CgogIGxlbiA9IG50b2hsKGxlbik7CiAgdG1wID0gcmVhbGxvYyhidWYtPmRhdGEsIGxlbik7CiAgaWYodG1wID09IE5VTEwpCiAgICByZXR1cm4gQ1VSTEVfT1VUX09GX01FTU9SWTsKCiAgYnVmLT5kYXRhID0gdG1wOwogIHJldCA9IHNvY2tldF9yZWFkKGZkLCBidWYtPmRhdGEsIGxlbik7CiAgaWYocmV0ICE9IENVUkxFX09LKQogICAgcmV0dXJuIHJldDsKICBidWYtPnNpemUgPSBjb25uLT5tZWNoLT5kZWNvZGUoY29ubi0+YXBwX2RhdGEsIGJ1Zi0+ZGF0YSwgbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5kYXRhX3Byb3QsIGNvbm4pOwogIGJ1Zi0+aW5kZXggPSAwOwogIHJldHVybiBDVVJMRV9PSzsKfQoKc3RhdGljIHNpemVfdApidWZmZXJfcmVhZChzdHJ1Y3Qga3JiNGJ1ZmZlciAqYnVmLCB2b2lkICpkYXRhLCBzaXplX3QgbGVuKQp7CiAgaWYoYnVmLT5zaXplIC0gYnVmLT5pbmRleCA8IGxlbikKICAgIGxlbiA9IGJ1Zi0+c2l6ZSAtIGJ1Zi0+aW5kZXg7CiAgbWVtY3B5KGRhdGEsIChjaGFyKilidWYtPmRhdGEgKyBidWYtPmluZGV4LCBsZW4pOwogIGJ1Zi0+aW5kZXggKz0gbGVuOwogIHJldHVybiBsZW47Cn0KCi8qIE1hdGNoZXMgQ3VybF9yZWN2IHNpZ25hdHVyZSAqLwpzdGF0aWMgc3NpemVfdCBzZWNfcmVjdihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBzb2NraW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKmJ1ZmZlciwgc2l6ZV90IGxlbiwgQ1VSTGNvZGUgKmVycikKewogIHNpemVfdCBieXRlc19yZWFkOwogIHNpemVfdCB0b3RhbF9yZWFkID0gMDsKICBjdXJsX3NvY2tldF90IGZkID0gY29ubi0+c29ja1tzb2NraW5kZXhdOwoKICAqZXJyID0gQ1VSTEVfT0s7CgogIC8qIEhhbmRsZSBjbGVhciB0ZXh0IHJlc3BvbnNlLiAqLwogIGlmKGNvbm4tPnNlY19jb21wbGV0ZSA9PSAwIHx8IGNvbm4tPmRhdGFfcHJvdCA9PSBQUk9UX0NMRUFSKQogICAgICByZXR1cm4gcmVhZChmZCwgYnVmZmVyLCBsZW4pOwoKICBpZihjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcpIHsKICAgIGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyA9IDA7CiAgICByZXR1cm4gMDsKICB9CgogIGJ5dGVzX3JlYWQgPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbik7CiAgbGVuIC09IGJ5dGVzX3JlYWQ7CiAgdG90YWxfcmVhZCArPSBieXRlc19yZWFkOwogIGJ1ZmZlciArPSBieXRlc19yZWFkOwoKICB3aGlsZShsZW4gPiAwKSB7CiAgICBpZihyZWFkX2RhdGEoY29ubiwgZmQsICZjb25uLT5pbl9idWZmZXIpICE9IENVUkxFX09LKQogICAgICByZXR1cm4gLTE7CiAgICBpZihjb25uLT5pbl9idWZmZXIuc2l6ZSA9PSAwKSB7CiAgICAgIGlmKGJ5dGVzX3JlYWQgPiAwKQogICAgICAgIGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyA9IDE7CiAgICAgIHJldHVybiBieXRlc19yZWFkOwogICAgfQogICAgYnl0ZXNfcmVhZCA9IGJ1ZmZlcl9yZWFkKCZjb25uLT5pbl9idWZmZXIsIGJ1ZmZlciwgbGVuKTsKICAgIGxlbiAtPSBieXRlc19yZWFkOwogICAgdG90YWxfcmVhZCArPSBieXRlc19yZWFkOwogICAgYnVmZmVyICs9IGJ5dGVzX3JlYWQ7CiAgfQogIC8qIEZJWE1FOiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8KICByZXR1cm4gdG90YWxfcmVhZDsKfQoKLyogU2VuZCB8bGVuZ3RofCBieXRlcyBmcm9tIHxmcm9tfCB0byB0aGUgfGZkfCBzb2NrZXQgdGFraW5nIGNhcmUgb2YgZW5jb2RpbmcKICAgYW5kIG5lZ29jaWF0aW5nIHdpdGggdGhlIHNlcnZlci4gfGZyb218IGNhbiBiZSBOVUxMLiAqLwovKiBGSVhNRTogV2UgZG9uJ3QgY2hlY2sgZm9yIGVycm9ycyBub3IgcmVwb3J0IGFueSEgKi8Kc3RhdGljIHZvaWQgZG9fc2VjX3NlbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjdXJsX3NvY2tldF90IGZkLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpmcm9tLCBpbnQgbGVuZ3RoKQp7CiAgaW50IGJ5dGVzLCBodG9ubF9ieXRlczsgLyogMzItYml0IGludGVnZXJzIGZvciBodG9ubCAqLwogIGNoYXIgKmJ1ZmZlciA9IE5VTEw7CiAgY2hhciAqY21kX2J1ZmZlcjsKICBzaXplX3QgY21kX3NpemUgPSAwOwogIENVUkxjb2RlIGVycm9yOwogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBwcm90X2xldmVsID0gY29ubi0+ZGF0YV9wcm90OwogIGJvb2wgaXNjbWQgPSAocHJvdF9sZXZlbCA9PSBQUk9UX0NNRCk/VFJVRTpGQUxTRTsKCiAgREVCVUdBU1NFUlQocHJvdF9sZXZlbCA+IFBST1RfTk9ORSAmJiBwcm90X2xldmVsIDwgUFJPVF9MQVNUKTsKCiAgaWYoaXNjbWQpIHsKICAgIGlmKCFzdHJuY21wKGZyb20sICJQQVNTICIsIDUpIHx8ICFzdHJuY21wKGZyb20sICJBQ0NUICIsIDUpKQogICAgICBwcm90X2xldmVsID0gUFJPVF9QUklWQVRFOwogICAgZWxzZQogICAgICBwcm90X2xldmVsID0gY29ubi0+Y29tbWFuZF9wcm90OwogIH0KICBieXRlcyA9IGNvbm4tPm1lY2gtPmVuY29kZShjb25uLT5hcHBfZGF0YSwgZnJvbSwgbGVuZ3RoLCBwcm90X2xldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmJ1ZmZlciwgY29ubik7CiAgaWYoIWJ1ZmZlciB8fCBieXRlcyA8PSAwKQogICAgcmV0dXJuOyAvKiBlcnJvciAqLwoKICBpZihpc2NtZCkgewogICAgZXJyb3IgPSBDdXJsX2Jhc2U2NF9lbmNvZGUoY29ubi0+ZGF0YSwgYnVmZmVyLCBjdXJseF9zaXRvdXooYnl0ZXMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNtZF9idWZmZXIsICZjbWRfc2l6ZSk7CiAgICBpZihlcnJvcikgewogICAgICBmcmVlKGJ1ZmZlcik7CiAgICAgIHJldHVybjsgLyogZXJyb3IgKi8KICAgIH0KICAgIGlmKGNtZF9zaXplID4gMCkgewogICAgICBzdGF0aWMgY29uc3QgY2hhciAqZW5jID0gIkVOQyAiOwogICAgICBzdGF0aWMgY29uc3QgY2hhciAqbWljID0gIk1JQyAiOwogICAgICBpZihwcm90X2xldmVsID09IFBST1RfUFJJVkFURSkKICAgICAgICBzb2NrZXRfd3JpdGUoY29ubiwgZmQsIGVuYywgNCk7CiAgICAgIGVsc2UKICAgICAgICBzb2NrZXRfd3JpdGUoY29ubiwgZmQsIG1pYywgNCk7CgogICAgICBzb2NrZXRfd3JpdGUoY29ubiwgZmQsIGNtZF9idWZmZXIsIGNtZF9zaXplKTsKICAgICAgc29ja2V0X3dyaXRlKGNvbm4sIGZkLCAiXHJcbiIsIDIpOwogICAgICBpbmZvZihjb25uLT5kYXRhLCAiU2VuZDogJXMlc1xuIiwgcHJvdF9sZXZlbCA9PSBQUk9UX1BSSVZBVEU/ZW5jOm1pYywKICAgICAgICAgICAgY21kX2J1ZmZlcik7CiAgICAgIGZyZWUoY21kX2J1ZmZlcik7CiAgICB9CiAgfQogIGVsc2UgewogICAgaHRvbmxfYnl0ZXMgPSBodG9ubChieXRlcyk7CiAgICBzb2NrZXRfd3JpdGUoY29ubiwgZmQsICZodG9ubF9ieXRlcywgc2l6ZW9mKGh0b25sX2J5dGVzKSk7CiAgICBzb2NrZXRfd3JpdGUoY29ubiwgZmQsIGJ1ZmZlciwgY3VybHhfc2l0b3V6KGJ5dGVzKSk7CiAgfQogIGZyZWUoYnVmZmVyKTsKfQoKc3RhdGljIHNzaXplX3Qgc2VjX3dyaXRlKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY3VybF9zb2NrZXRfdCBmZCwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmJ1ZmZlciwgc2l6ZV90IGxlbmd0aCkKewogIC8qIEZJWE1FOiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8KICBzc2l6ZV90IGxlbiA9IGNvbm4tPmJ1ZmZlcl9zaXplOwogIGludCB0eCA9IDA7CgogIGxlbiAtPSBjb25uLT5tZWNoLT5vdmVyaGVhZChjb25uLT5hcHBfZGF0YSwgY29ubi0+ZGF0YV9wcm90LCBsZW4pOwogIGlmKGxlbiA8PSAwKQogICAgbGVuID0gbGVuZ3RoOwogIHdoaWxlKGxlbmd0aCkgewogICAgaWYobGVuID49IDAgfHwgbGVuZ3RoIDwgKHNpemVfdClsZW4pIHsKICAgICAgLyogRklYTUU6IENoZWNrIGZvciBvdmVyZmxvdy4gKi8KICAgICAgbGVuID0gbGVuZ3RoOwogICAgfQogICAgZG9fc2VjX3NlbmQoY29ubiwgZmQsIGJ1ZmZlciwgbGVuKTsKICAgIGxlbmd0aCAtPSBsZW47CiAgICBidWZmZXIgKz0gbGVuOwogICAgdHggKz0gbGVuOwogIH0KICByZXR1cm4gdHg7Cn0KCi8qIE1hdGNoZXMgQ3VybF9zZW5kIHNpZ25hdHVyZSAqLwpzdGF0aWMgc3NpemVfdCBzZWNfc2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBzb2NraW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmJ1ZmZlciwgc2l6ZV90IGxlbiwgQ1VSTGNvZGUgKmVycikKewogIGN1cmxfc29ja2V0X3QgZmQgPSBjb25uLT5zb2NrW3NvY2tpbmRleF07CiAgKmVyciA9IENVUkxFX09LOwogIHJldHVybiBzZWNfd3JpdGUoY29ubiwgZmQsIGJ1ZmZlciwgbGVuKTsKfQoKaW50IEN1cmxfc2VjX3JlYWRfbXNnKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgY2hhciAqYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsKQp7CiAgLyogZGVjb2RlZF9sZW4gc2hvdWxkIGJlIHNpemVfdCBvciBzc2l6ZV90IGJ1dCBjb25uLT5tZWNoLT5kZWNvZGUgcmV0dXJucyBhbgogICAgIGludCAqLwogIGludCBkZWNvZGVkX2xlbjsKICBjaGFyICpidWY7CiAgaW50IHJldF9jb2RlOwogIHNpemVfdCBkZWNvZGVkX3N6ID0gMDsKICBDVVJMY29kZSBlcnJvcjsKCiAgREVCVUdBU1NFUlQobGV2ZWwgPiBQUk9UX05PTkUgJiYgbGV2ZWwgPCBQUk9UX0xBU1QpOwoKICBlcnJvciA9IEN1cmxfYmFzZTY0X2RlY29kZShidWZmZXIgKyA0LCAodW5zaWduZWQgY2hhciAqKikmYnVmLCAmZGVjb2RlZF9zeik7CiAgaWYoZXJyb3IgfHwgZGVjb2RlZF9zeiA9PSAwKQogICAgcmV0dXJuIC0xOwoKICBpZihkZWNvZGVkX3N6ID4gKHNpemVfdClJTlRfTUFYKSB7CiAgICBmcmVlKGJ1Zik7CiAgICByZXR1cm4gLTE7CiAgfQogIGRlY29kZWRfbGVuID0gY3VybHhfdXp0b3NpKGRlY29kZWRfc3opOwoKICBkZWNvZGVkX2xlbiA9IGNvbm4tPm1lY2gtPmRlY29kZShjb25uLT5hcHBfZGF0YSwgYnVmLCBkZWNvZGVkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwgY29ubik7CiAgaWYoZGVjb2RlZF9sZW4gPD0gMCkgewogICAgZnJlZShidWYpOwogICAgcmV0dXJuIC0xOwogIH0KCiAgaWYoY29ubi0+ZGF0YS0+c2V0LnZlcmJvc2UpIHsKICAgIGJ1ZltkZWNvZGVkX2xlbl0gPSAnXG4nOwogICAgQ3VybF9kZWJ1Zyhjb25uLT5kYXRhLCBDVVJMSU5GT19IRUFERVJfSU4sIGJ1ZiwgZGVjb2RlZF9sZW4gKyAxLCBjb25uKTsKICB9CgogIGJ1ZltkZWNvZGVkX2xlbl0gPSAnXDAnOwogIERFQlVHQVNTRVJUKGRlY29kZWRfbGVuID4gMyk7CiAgaWYoYnVmWzNdID09ICctJykKICAgIHJldF9jb2RlID0gMDsKICBlbHNlIHsKICAgIC8qIENoZWNrIGZvciBlcnJvcj8gKi8KICAgIHNzY2FuZihidWYsICIlZCIsICZyZXRfY29kZSk7CiAgfQoKICBpZihidWZbZGVjb2RlZF9sZW4gLSAxXSA9PSAnXG4nKQogICAgYnVmW2RlY29kZWRfbGVuIC0gMV0gPSAnXDAnOwogIC8qIEZJWE1FOiBJcyB8YnVmZmVyfCBsZW5ndGggYWx3YXlzIGdyZWF0ZXIgdGhhbiB8ZGVjb2RlZF9sZW58PyAqLwogIHN0cmNweShidWZmZXIsIGJ1Zik7CiAgZnJlZShidWYpOwogIHJldHVybiByZXRfY29kZTsKfQoKLyogRklYTUU6IFRoZSBlcnJvciBjb2RlIHJldHVybmVkIGhlcmUgaXMgbmV2ZXIgY2hlY2tlZC4gKi8Kc3RhdGljIGludCBzZWNfc2V0X3Byb3RlY3Rpb25fbGV2ZWwoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IGNvZGU7CiAgY2hhciogcGJzejsKICBzdGF0aWMgdW5zaWduZWQgaW50IGJ1ZmZlcl9zaXplID0gMSA8PCAyMDsgLyogMTA0ODU3NiAqLwogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbCA9IGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90OwoKICBERUJVR0FTU0VSVChsZXZlbCA+IFBST1RfTk9ORSAmJiBsZXZlbCA8IFBST1RfTEFTVCk7CgogIGlmKCFjb25uLT5zZWNfY29tcGxldGUpIHsKICAgIGluZm9mKGNvbm4tPmRhdGEsICJUcnlpbmcgdG8gY2hhbmdlIHRoZSBwcm90ZWN0aW9uIGxldmVsIGFmdGVyIHRoZSIKICAgICAgICAgICAgICAgICAgICAgICJjb21wbGV0aW9uIG9mIHRoZSBkYXRhIGV4Y2hhbmdlLlxuIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICAvKiBCYWlsIG91dCBpZiB3ZSB0cnkgdG8gc2V0IHVwIHRoZSBzYW1lIGxldmVsICovCiAgaWYoY29ubi0+ZGF0YV9wcm90ID09IGxldmVsKQogICAgcmV0dXJuIDA7CgogIGlmKGxldmVsKSB7CiAgICBjb2RlID0gZnRwX3NlbmRfY29tbWFuZChjb25uLCAiUEJTWiAldSIsIGJ1ZmZlcl9zaXplKTsKICAgIGlmKGNvZGUgPCAwKQogICAgICByZXR1cm4gLTE7CgogICAgaWYoY29kZS8xMDAgIT0gMikgewogICAgICBmYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIHNldCB0aGUgcHJvdGVjdGlvbidzIGJ1ZmZlciBzaXplLiIpOwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBjb25uLT5idWZmZXJfc2l6ZSA9IGJ1ZmZlcl9zaXplOwoKICAgIHBic3ogPSBzdHJzdHIoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyLCAiUEJTWj0iKTsKICAgIGlmKHBic3opIHsKICAgICAgLyogRklYTUU6IENoZWNrcyBmb3IgZXJyb3JzIGluIHNzY2FuZj8gKi8KICAgICAgc3NjYW5mKHBic3osICJQQlNaPSV1IiwgJmJ1ZmZlcl9zaXplKTsKICAgICAgaWYoYnVmZmVyX3NpemUgPCBjb25uLT5idWZmZXJfc2l6ZSkKICAgICAgICBjb25uLT5idWZmZXJfc2l6ZSA9IGJ1ZmZlcl9zaXplOwogICAgfQogIH0KCiAgLyogTm93IHRyeSB0byBuZWdpb2NpYXRlIHRoZSBwcm90ZWN0aW9uIGxldmVsLiAqLwogIGNvZGUgPSBmdHBfc2VuZF9jb21tYW5kKGNvbm4sICJQUk9UICVjIiwgbGV2ZWxfdG9fY2hhcihsZXZlbCkpOwoKICBpZihjb2RlIDwgMCkKICAgIHJldHVybiAtMTsKCiAgaWYoY29kZS8xMDAgIT0gMikgewogICAgZmFpbGYoY29ubi0+ZGF0YSwgIkZhaWxlZCB0byBzZXQgdGhlIHByb3RlY3Rpb24gbGV2ZWwuIik7CiAgICByZXR1cm4gLTE7CiAgfQoKICBjb25uLT5kYXRhX3Byb3QgPSBsZXZlbDsKICBpZihsZXZlbCA9PSBQUk9UX1BSSVZBVEUpCiAgICBjb25uLT5jb21tYW5kX3Byb3QgPSBsZXZlbDsKCiAgcmV0dXJuIDA7Cn0KCmludApDdXJsX3NlY19yZXF1ZXN0X3Byb3Qoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjb25zdCBjaGFyICpsZXZlbCkKewogIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsID0gbmFtZV90b19sZXZlbChsZXZlbCk7CiAgaWYobCA9PSBQUk9UX05PTkUpCiAgICByZXR1cm4gLTE7CiAgREVCVUdBU1NFUlQobCA+IFBST1RfTk9ORSAmJiBsIDwgUFJPVF9MQVNUKTsKICBjb25uLT5yZXF1ZXN0X2RhdGFfcHJvdCA9IGw7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBDVVJMY29kZSBjaG9vc2VfbWVjaChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpbnQgcmV0OwogIHN0cnVjdCBTZXNzaW9uSGFuZGxlICpkYXRhID0gY29ubi0+ZGF0YTsKICBjb25zdCBzdHJ1Y3QgQ3VybF9zZWNfY2xpZW50X21lY2ggKiBjb25zdCAqbWVjaDsKICB2b2lkICp0bXBfYWxsb2NhdGlvbjsKICBjb25zdCBjaGFyICptZWNoX25hbWU7CgogIGZvcihtZWNoID0gbWVjaHM7ICgqbWVjaCk7ICsrbWVjaCkgewogICAgbWVjaF9uYW1lID0gKCptZWNoKS0+bmFtZTsKICAgIC8qIFdlIGhhdmUgbm8gbWVjaGFuaXNtIHdpdGggYSBOVUxMIG5hbWUgYnV0IGtlZXAgdGhpcyBjaGVjayAqLwogICAgREVCVUdBU1NFUlQobWVjaF9uYW1lICE9IE5VTEwpOwogICAgaWYobWVjaF9uYW1lID09IE5VTEwpIHsKICAgICAgaW5mb2YoZGF0YSwgIlNraXBwaW5nIG1lY2hhbmlzbSB3aXRoIGVtcHR5IG5hbWUgKCVwKVxuIiwgbWVjaCk7CiAgICAgIGNvbnRpbnVlOwogICAgfQogICAgdG1wX2FsbG9jYXRpb24gPSByZWFsbG9jKGNvbm4tPmFwcF9kYXRhLCAoKm1lY2gpLT5zaXplKTsKICAgIGlmKHRtcF9hbGxvY2F0aW9uID09IE5VTEwpIHsKICAgICAgZmFpbGYoZGF0YSwgIkZhaWxlZCByZWFsbG9jIG9mIHNpemUgJXUiLCAoKm1lY2gpLT5zaXplKTsKICAgICAgbWVjaCA9IE5VTEw7CiAgICAgIHJldHVybiBDVVJMRV9PVVRfT0ZfTUVNT1JZOwogICAgfQogICAgY29ubi0+YXBwX2RhdGEgPSB0bXBfYWxsb2NhdGlvbjsKCiAgICBpZigoKm1lY2gpLT5pbml0KSB7CiAgICAgIHJldCA9ICgqbWVjaCktPmluaXQoY29ubi0+YXBwX2RhdGEpOwogICAgICBpZihyZXQgIT0gMCkgewogICAgICAgIGluZm9mKGRhdGEsICJGYWlsZWQgaW5pdGlhbGl6YXRpb24gZm9yICVzLiBTa2lwcGluZyBpdC5cbiIsIG1lY2hfbmFtZSk7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgIH0KCiAgICBpbmZvZihkYXRhLCAiVHJ5aW5nIG1lY2hhbmlzbSAlcy4uLlxuIiwgbWVjaF9uYW1lKTsKICAgIHJldCA9IGZ0cF9zZW5kX2NvbW1hbmQoY29ubiwgIkFVVEggJXMiLCBtZWNoX25hbWUpOwogICAgaWYocmV0IDwgMCkKICAgICAgLyogRklYTUU6IFRoaXMgZXJyb3IgaXMgdG9vIGdlbmVyaWMgYnV0IGl0IGlzIE9LIGZvciBub3cuICovCiAgICAgIHJldHVybiBDVVJMRV9DT1VMRE5UX0NPTk5FQ1Q7CgogICAgaWYocmV0LzEwMCAhPSAzKSB7CiAgICAgIHN3aXRjaChyZXQpIHsKICAgICAgY2FzZSA1MDQ6CiAgICAgICAgaW5mb2YoZGF0YSwgIk1lY2hhbmlzbSAlcyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2ZXIgKHNlcnZlciAiCiAgICAgICAgICAgICAgICAgICAgInJldHVybmVkIGZ0cCBjb2RlOiA1MDQpLlxuIiwgbWVjaF9uYW1lKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSA1MzQ6CiAgICAgICAgaW5mb2YoZGF0YSwgIk1lY2hhbmlzbSAlcyB3YXMgcmVqZWN0ZWQgYnkgdGhlIHNlcnZlciAoc2VydmVyIHJldHVybmVkICIKICAgICAgICAgICAgICAgICAgICAiZnRwIGNvZGU6IDUzNCkuXG4iLCBtZWNoX25hbWUpOwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIGlmKHJldC8xMDAgPT0gNSkgewogICAgICAgICAgaW5mb2YoZGF0YSwgInNlcnZlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBzZWN1cml0eSBleHRlbnNpb25zXG4iKTsKICAgICAgICAgIHJldHVybiBDVVJMRV9VU0VfU1NMX0ZBSUxFRDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY29udGludWU7CiAgICB9CgogICAgLyogQXV0aGVudGljYXRlICovCiAgICByZXQgPSAoKm1lY2gpLT5hdXRoKGNvbm4tPmFwcF9kYXRhLCBjb25uKTsKCiAgICBpZihyZXQgPT0gQVVUSF9DT05USU5VRSkKICAgICAgY29udGludWU7CiAgICBlbHNlIGlmKHJldCAhPSBBVVRIX09LKSB7CiAgICAgIC8qIE1lY2hhbmlzbSBoYXMgZHVtcGVkIHRoZSBlcnJvciB0byBzdGRlcnIsIGRvbid0IGVycm9yIGhlcmUuICovCiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIERFQlVHQVNTRVJUKHJldCA9PSBBVVRIX09LKTsKCiAgICBjb25uLT5tZWNoID0gKm1lY2g7CiAgICBjb25uLT5zZWNfY29tcGxldGUgPSAxOwogICAgY29ubi0+cmVjdltGSVJTVFNPQ0tFVF0gPSBzZWNfcmVjdjsKICAgIGNvbm4tPnNlbmRbRklSU1RTT0NLRVRdID0gc2VjX3NlbmQ7CiAgICBjb25uLT5yZWN2W1NFQ09OREFSWVNPQ0tFVF0gPSBzZWNfcmVjdjsKICAgIGNvbm4tPnNlbmRbU0VDT05EQVJZU09DS0VUXSA9IHNlY19zZW5kOwogICAgY29ubi0+Y29tbWFuZF9wcm90ID0gUFJPVF9TQUZFOwogICAgLyogU2V0IHRoZSByZXF1ZXN0ZWQgcHJvdGVjdGlvbiBsZXZlbCAqLwogICAgLyogQkxPQ0tJTkcgKi8KICAgICh2b2lkKXNlY19zZXRfcHJvdGVjdGlvbl9sZXZlbChjb25uKTsKICAgIGJyZWFrOwogIH0KCiAgcmV0dXJuIG1lY2ggIT0gTlVMTCA/IENVUkxFX09LIDogQ1VSTEVfRkFJTEVEX0lOSVQ7Cn0KCkNVUkxjb2RlCkN1cmxfc2VjX2xvZ2luKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIHJldHVybiBjaG9vc2VfbWVjaChjb25uKTsKfQoKCnZvaWQKQ3VybF9zZWNfZW5kKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubikKewogIGlmKGNvbm4tPm1lY2ggIT0gTlVMTCAmJiBjb25uLT5tZWNoLT5lbmQpCiAgICBjb25uLT5tZWNoLT5lbmQoY29ubi0+YXBwX2RhdGEpOwogIGlmKGNvbm4tPmFwcF9kYXRhKSB7CiAgICBmcmVlKGNvbm4tPmFwcF9kYXRhKTsKICAgIGNvbm4tPmFwcF9kYXRhID0gTlVMTDsKICB9CiAgaWYoY29ubi0+aW5fYnVmZmVyLmRhdGEpIHsKICAgIGZyZWUoY29ubi0+aW5fYnVmZmVyLmRhdGEpOwogICAgY29ubi0+aW5fYnVmZmVyLmRhdGEgPSBOVUxMOwogICAgY29ubi0+aW5fYnVmZmVyLnNpemUgPSAwOwogICAgY29ubi0+aW5fYnVmZmVyLmluZGV4ID0gMDsKICAgIC8qIEZJWE1FOiBJcyB0aGlzIHJlYWxseSBuZWVkZWQ/ICovCiAgICBjb25uLT5pbl9idWZmZXIuZW9mX2ZsYWcgPSAwOwogIH0KICBjb25uLT5zZWNfY29tcGxldGUgPSAwOwogIGNvbm4tPmRhdGFfcHJvdCA9IFBST1RfQ0xFQVI7CiAgY29ubi0+bWVjaCA9IE5VTEw7Cn0KCiNlbmRpZiAvKiBIQVZFX0tSQjQgfHwgSEFWRV9HU1NBUEkgKi8KCiNlbmRpZiAvKiBDVVJMX0RJU0FCTEVfRlRQICovCg==