LyoKICogYWdlbnRfdHJhcC5jCiAqLwovKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb3B5cmlnaHQocykuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgqSAyMDAzIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIENPUFlJTkcgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoZSBOZXQtU05NUCBwYWNrYWdlLgogKi8KLyoqIEBkZWZncm91cCBhZ2VudF90cmFwIFRyYXAgZ2VuZXJhdGlvbiByb3V0aW5lcyBmb3IgbWliIG1vZHVsZXMgdG8gdXNlCiAqICBAaW5ncm91cCBhZ2VudAogKgogKiBAewogKi8KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaWZkZWYgV0lOMzIKIyAgaW5jbHVkZSA8c3lzL3RpbWViLmg+CiMgZWxzZQojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVuZGlmCiMgaW5jbHVkZSA8dGltZS5oPgojZWxzZQojIGlmIEhBVkVfU1lTX1RJTUVfSAojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVsc2UKIyAgaW5jbHVkZSA8dGltZS5oPgojIGVuZGlmCiNlbmRpZgojaWYgSEFWRV9TWVNfU09DS0VUX0gKI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2VsaWYgSEFWRV9XSU5TT0NLX0gKI2luY2x1ZGUgPHdpbnNvY2suaD4KI2VuZGlmCiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2luY2x1ZGUgPG5ldC1zbm1wL3V0aWxpdGllcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYWdlbnRfdHJhcC5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvc25tcF9hZ2VudC5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYWdlbnRfY2FsbGJhY2tzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYWdlbnRfbW9kdWxlX2NvbmZpZy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbWliX21vZHVsZV9jb25maWcuaD4KCiNpZmRlZiBVU0lOR19BR0VOVFhfUFJPVE9DT0xfTU9EVUxFCiNpbmNsdWRlICJhZ2VudHgvcHJvdG9jb2wuaCIKI2VuZGlmCgpzdHJ1Y3QgdHJhcF9zaW5rIHsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc2VzcDsKICAgIHN0cnVjdCB0cmFwX3NpbmsgKm5leHQ7CiAgICBpbnQgICAgICAgICAgICAgcGR1dHlwZTsKICAgIGludCAgICAgICAgICAgICB2ZXJzaW9uOwp9OwoKc3RydWN0IHRyYXBfc2luayAqc2lua3MgPSBOVUxMOwoKZXh0ZXJuIHN0cnVjdCB0aW1ldmFsIHN0YXJ0dGltZTsKCm9pZCAgICAgICAgICAgICBvYmppZF9lbnRlcnByaXNldHJhcFtdID0geyBORVRTTk1QX05PVElGSUNBVElPTl9NSUIgfTsKb2lkICAgICAgICAgICAgIHRyYXBfdmVyc2lvbl9pZFtdID0geyBORVRTTk1QX1NZU1RFTV9NSUIgfTsKaW50ICAgICAgICAgICAgIGVudGVycHJpc2V0cmFwX2xlbjsKaW50ICAgICAgICAgICAgIHRyYXBfdmVyc2lvbl9pZF9sZW47CgojZGVmaW5lIFNOTVBWMl9UUkFQU19QUkVGSVgJU05NUF9PSURfU05NUE1PRFVMRVMsMSwxLDUKb2lkICAgICAgICAgICAgIHRyYXBfcHJlZml4W10gICAgPSB7IFNOTVBWMl9UUkFQU19QUkVGSVggfTsKb2lkICAgICAgICAgICAgIGNvbGRfc3RhcnRfb2lkW10gPSB7IFNOTVBWMl9UUkFQU19QUkVGSVgsIDEgfTsgIC8qIFNOTVB2Mi1NSUIgKi8Kb2lkICAgICAgICAgICAgIHdhcm1fc3RhcnRfb2lkW10gPSB7IFNOTVBWMl9UUkFQU19QUkVGSVgsIDIgfTsgIC8qIFNOTVB2Mi1NSUIgKi8Kb2lkICAgICAgICAgICAgIGxpbmtfZG93bl9vaWRbXSAgPSB7IFNOTVBWMl9UUkFQU19QUkVGSVgsIDMgfTsgIC8qIElGLU1JQiAqLwpvaWQgICAgICAgICAgICAgbGlua191cF9vaWRbXSAgICA9IHsgU05NUFYyX1RSQVBTX1BSRUZJWCwgNCB9OyAgLyogSUYtTUlCICovCm9pZCAgICAgICAgICAgICBhdXRoX2ZhaWxfb2lkW10gID0geyBTTk1QVjJfVFJBUFNfUFJFRklYLCA1IH07ICAvKiBTTk1QdjItTUlCICovCm9pZCAgICAgICAgICAgICBlZ3BfeHh4X29pZFtdICAgID0geyBTTk1QVjJfVFJBUFNfUFJFRklYLCA5OSB9OyAvKiA/Pz8gKi8KCiNkZWZpbmUgU05NUFYyX1RSQVBfT0JKU19QUkVGSVgJU05NUF9PSURfU05NUE1PRFVMRVMsMSwxLDQKb2lkICAgICAgICAgICAgIHNubXB0cmFwX29pZFtdID0geyBTTk1QVjJfVFJBUF9PQkpTX1BSRUZJWCwgMSwgMCB9OwpvaWQgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZFtdID0KICAgIHsgU05NUFYyX1RSQVBfT0JKU19QUkVGSVgsIDMsIDAgfTsKb2lkICAgICAgICAgICAgIHN5c3VwdGltZV9vaWRbXSA9IHsgU05NUF9PSURfTUlCMiwgMSwgMywgMCB9OwpzaXplX3QgICAgICAgICAgc25tcHRyYXBfb2lkX2xlbjsKc2l6ZV90ICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWRfbGVuOwpzaXplX3QgICAgICAgICAgc3lzdXB0aW1lX29pZF9sZW47CgojZGVmaW5lIFNOTVBWMl9DT01NX09CSlNfUFJFRklYCVNOTVBfT0lEX1NOTVBNT0RVTEVTLDE4LDEKb2lkICAgICAgICAgICAgIGFnZW50YWRkcl9vaWRbXSA9IHsgU05NUFYyX0NPTU1fT0JKU19QUkVGSVgsIDMsIDAgfTsKc2l6ZV90ICAgICAgICAgIGFnZW50YWRkcl9vaWRfbGVuOwpvaWQgICAgICAgICAgICAgY29tbXVuaXR5X29pZFtdID0geyBTTk1QVjJfQ09NTV9PQkpTX1BSRUZJWCwgNCwgMCB9OwpzaXplX3QgICAgICAgICAgY29tbXVuaXR5X29pZF9sZW47CiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKY2hhciAgICAgICAgICAgKnNubXBfdHJhcGNvbW11bml0eSA9IE5VTEw7CiNlbmRpZgoKCiNkZWZpbmUgU05NUF9BVVRIRU5USUNBVEVEX1RSQVBTX0VOQUJMRUQJMQojZGVmaW5lIFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19ESVNBQkxFRAkyCgpsb25nICAgICAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwcyA9IFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19ESVNBQkxFRDsKaW50ICAgICAgICAgICAgIHNubXBfZW5hYmxlYXV0aGVudHJhcHNzZXQgPSAwOwoKLyoKICogUHJvdG90eXBlcyAKICovCiAvKgogICogc3RhdGljIGludCBjcmVhdGVfdjFfdHJhcF9zZXNzaW9uIChjb25zdCBjaGFyICosIHVfc2hvcnQsIGNvbnN0IGNoYXIgKik7CiAgKiBzdGF0aWMgaW50IGNyZWF0ZV92Ml90cmFwX3Nlc3Npb24gKGNvbnN0IGNoYXIgKiwgdV9zaG9ydCwgY29uc3QgY2hhciAqKTsKICAqIHN0YXRpYyBpbnQgY3JlYXRlX3YyX2luZm9ybV9zZXNzaW9uIChjb25zdCBjaGFyICosIHVfc2hvcnQsIGNvbnN0IGNoYXIgKik7CiAgKiBzdGF0aWMgdm9pZCBmcmVlX3RyYXBfc2Vzc2lvbiAoc3RydWN0IHRyYXBfc2luayAqc3ApOwogICogc3RhdGljIHZvaWQgc2VuZF92MV90cmFwIChuZXRzbm1wX3Nlc3Npb24gKiwgaW50LCBpbnQpOwogICogc3RhdGljIHZvaWQgc2VuZF92Ml90cmFwIChuZXRzbm1wX3Nlc3Npb24gKiwgaW50LCBpbnQsIGludCk7CiAgKi8KCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqCgkgKgoJICogVHJhcCBzZXNzaW9uIGhhbmRsaW5nCgkgKgoJICoqKioqKioqKioqKioqKioqKiovCgp2b2lkCmluaXRfdHJhcHModm9pZCkKewogICAgZW50ZXJwcmlzZXRyYXBfbGVuICA9IE9JRF9MRU5HVEgob2JqaWRfZW50ZXJwcmlzZXRyYXApOwogICAgdHJhcF92ZXJzaW9uX2lkX2xlbiA9IE9JRF9MRU5HVEgodHJhcF92ZXJzaW9uX2lkKTsKICAgIHNubXB0cmFwX29pZF9sZW4gICAgPSBPSURfTEVOR1RIKHNubXB0cmFwX29pZCk7CiAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkX2xlbiA9IE9JRF9MRU5HVEgoc25tcHRyYXBlbnRlcnByaXNlX29pZCk7CiAgICBzeXN1cHRpbWVfb2lkX2xlbiAgID0gT0lEX0xFTkdUSChzeXN1cHRpbWVfb2lkKTsKICAgIGFnZW50YWRkcl9vaWRfbGVuICAgPSBPSURfTEVOR1RIKGFnZW50YWRkcl9vaWQpOwogICAgY29tbXVuaXR5X29pZF9sZW4gICA9IE9JRF9MRU5HVEgoY29tbXVuaXR5X29pZCk7Cn0KCnN0YXRpYyB2b2lkCmZyZWVfdHJhcF9zZXNzaW9uKHN0cnVjdCB0cmFwX3NpbmsgKnNwKQp7CiAgICBERUJVR01TR1RMKCgidHJhcCIsICJmcmVlaW5nIGNhbGxiYWNrIHRyYXAgc2Vzc2lvbiAoJXAsICVwKVxuIiwgc3AsIHNwLT5zZXNwKSk7CiAgICBzbm1wX2Nsb3NlKHNwLT5zZXNwKTsKICAgIGZyZWUoc3ApOwp9CgppbnQKYWRkX3RyYXBfc2Vzc2lvbihuZXRzbm1wX3Nlc3Npb24gKiBzcywgaW50IHBkdXR5cGUsIGludCBjb25maXJtLAogICAgICAgICAgICAgICAgIGludCB2ZXJzaW9uKQp7CiAgICBpZiAoc25tcF9jYWxsYmFja19hdmFpbGFibGUoU05NUF9DQUxMQkFDS19BUFBMSUNBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QRF9DQUxMQkFDS19SRUdJU1RFUl9OT1RJRklDQVRJT05TKSA9PQogICAgICAgIFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIC8qCiAgICAgICAgICogc29tZXRoaW5nIGVsc2Ugd2FudHMgdG8gaGFuZGxlIG5vdGlmaWNhdGlvbiByZWdpc3RyYXRpb25zIAogICAgICAgICAqLwogICAgICAgIHN0cnVjdCBhZ2VudF9hZGRfdHJhcF9hcmdzIGFyZ3M7CiAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLCAiYWRkaW5nIGNhbGxiYWNrIHRyYXAgc2luayAoJXApXG4iLCBzcykpOwogICAgICAgIGFyZ3Muc3MgPSBzczsKICAgICAgICBhcmdzLmNvbmZpcm0gPSBjb25maXJtOwogICAgICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19BUFBMSUNBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBEX0NBTExCQUNLX1JFR0lTVEVSX05PVElGSUNBVElPTlMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSAmYXJncyk7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogbm8gb3RoZXIgc3VwcG9ydCBleGlzdHMsIGhhbmRsZSBpdCBvdXJzZWx2ZXMuIAogICAgICAgICAqLwogICAgICAgIHN0cnVjdCB0cmFwX3NpbmsgKm5ld19zaW5rOwoKICAgICAgICBERUJVR01TR1RMKCgidHJhcCIsICJhZGRpbmcgaW50ZXJuYWwgdHJhcCBzaW5rXG4iKSk7CiAgICAgICAgbmV3X3NpbmsgPSAoc3RydWN0IHRyYXBfc2luayAqKSBtYWxsb2Moc2l6ZW9mKCpuZXdfc2luaykpOwogICAgICAgIGlmIChuZXdfc2luayA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gMDsKCiAgICAgICAgbmV3X3NpbmstPnNlc3AgPSBzczsKICAgICAgICBuZXdfc2luay0+cGR1dHlwZSA9IHBkdXR5cGU7CiAgICAgICAgbmV3X3NpbmstPnZlcnNpb24gPSB2ZXJzaW9uOwogICAgICAgIG5ld19zaW5rLT5uZXh0ID0gc2lua3M7CiAgICAgICAgc2lua3MgPSBuZXdfc2luazsKICAgIH0KICAgIHJldHVybiAxOwp9CgppbnQKcmVtb3ZlX3RyYXBfc2Vzc2lvbihuZXRzbm1wX3Nlc3Npb24gKiBzcykKewogICAgc3RydWN0IHRyYXBfc2luayAqc3AgPSBzaW5rcywgKnByZXYgPSBOVUxMOwoKICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgInJlbW92aW5nIHRyYXAgc2Vzc2lvbnNcbiIpKTsKICAgIHdoaWxlIChzcCkgewogICAgICAgIGlmIChzcC0+c2VzcCA9PSBzcykgewogICAgICAgICAgICBpZiAocHJldikgewogICAgICAgICAgICAgICAgcHJldi0+bmV4dCA9IHNwLT5uZXh0OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2lua3MgPSBzcC0+bmV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJIGRvbid0IGJlbGlldmUgeW91ICpyZWFsbHkqIHdhbnQgdG8gY2xvc2UgdGhlIHNlc3Npb24gaGVyZTsKICAgICAgICAgICAgICogaXQgbWF5IHN0aWxsIGJlIGluIHVzZSBmb3Igb3RoZXIgcHVycG9zZXMuICBJbiBwYXJ0aWN1bGFyIHRoaXMKICAgICAgICAgICAgICogaXMgYXdrd2FyZCBmb3IgQWdlbnRYLCBzaW5jZSB3ZSB3YW50IHRvIGNhbGwgdGhpcyBmdW5jdGlvbgogICAgICAgICAgICAgKiBmcm9tIHRoZSBzZXNzaW9uJ3MgY2FsbGJhY2suICBMZXQncyBqdXN0IGZyZWUgdGhlIHRyYXBzaW5rCiAgICAgICAgICAgICAqIGRhdGEgc3RydWN0dXJlLiAgW2picG5dICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGZyZWVfdHJhcF9zZXNzaW9uKHNwKTsgIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLCAicmVtb3ZpbmcgdHJhcCBzZXNzaW9uICglcCwgJXApXG4iLCBzcCwgc3AtPnNlc3ApKTsKICAgICAgICAgICAgZnJlZShzcCk7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBwcmV2ID0gc3A7CiAgICAgICAgc3AgPSBzcC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAwOwp9CgojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCnN0YXRpYyBpbnQKY3JlYXRlX3RyYXBfc2Vzc2lvbjIoY29uc3QgY2hhciAqc2luaywgY29uc3QgY2hhciogc2lua3BvcnQsCgkJICAgICBjaGFyICpjb20sIGludCB2ZXJzaW9uLCBpbnQgcGR1dHlwZSkKewogICAgbmV0c25tcF90cmFuc3BvcnQgKnQ7CiAgICBuZXRzbm1wX3Nlc3Npb24gc2Vzc2lvbiwgKnNlc3A7CgogICAgbWVtc2V0KCZzZXNzaW9uLCAwLCBzaXplb2YobmV0c25tcF9zZXNzaW9uKSk7CiAgICBzZXNzaW9uLnZlcnNpb24gPSB2ZXJzaW9uOwogICAgaWYgKGNvbSkgewogICAgICAgIHNlc3Npb24uY29tbXVuaXR5ID0gKHVfY2hhciAqKSBjb207CiAgICAgICAgc2Vzc2lvbi5jb21tdW5pdHlfbGVuID0gc3RybGVuKGNvbSk7CiAgICB9CgogICAgLyoKICAgICAqIGZvciBpbmZvcm1zLCBzZXQgcmV0cmllcyB0byBkZWZhdWx0CiAgICAgKi8KICAgIGlmIChTTk1QX01TR19JTkZPUk0gPT0gcGR1dHlwZSkgewogICAgICAgIHNlc3Npb24udGltZW91dCA9IFNOTVBfREVGQVVMVF9USU1FT1VUOwogICAgICAgIHNlc3Npb24ucmV0cmllcyA9IFNOTVBfREVGQVVMVF9SRVRSSUVTOwogICAgfQoKICAgIC8qCiAgICAgKiBpZiB0aGUgc2luayBpcyBsb2NhbGhvc3QsIGJpbmQgdG8gbG9jYWxob3N0LCB0byByZWR1Y2Ugb3BlbiBwb3J0cy4KICAgICAqLwogICAgaWYgKChOVUxMID09IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0NMSUVOVF9BRERSKSkgJiYgCiAgICAgICAgKCgwID09IHN0cmNtcCgibG9jYWxob3N0IixzaW5rKSkgfHwgKDAgPT0gc3RyY21wKCIxMjcuMC4wLjEiLHNpbmspKSkpCiAgICAgICAgc2Vzc2lvbi5sb2NhbG5hbWUgPSBzdHJkdXAoImxvY2FsaG9zdCIpOwoKICAgIHQgPSBuZXRzbm1wX3Rkb21haW5fdHJhbnNwb3J0X2Z1bGwoInNubXB0cmFwIiwgc2luaywgMCwgTlVMTCwgc2lua3BvcnQpOwogICAgaWYgKHQgIT0gTlVMTCkgewoJc2VzcCA9IHNubXBfYWRkKCZzZXNzaW9uLCB0LCBOVUxMLCBOVUxMKTsKCglpZiAoc2VzcCkgewoJICAgIHJldHVybiBhZGRfdHJhcF9zZXNzaW9uKHNlc3AsIHBkdXR5cGUsCgkJCQkgICAgKHBkdXR5cGUgPT0gU05NUF9NU0dfSU5GT1JNKSwgdmVyc2lvbik7Cgl9CiAgICB9CiAgICAvKgogICAgICogZGlhZ25vc2Ugc25tcF9vcGVuIGVycm9ycyB3aXRoIHRoZSBpbnB1dCBuZXRzbm1wX3Nlc3Npb24gcG9pbnRlciAKICAgICAqLwogICAgc25tcF9zZXNzX3BlcnJvcigic25tcGQ6IGNyZWF0ZV90cmFwX3Nlc3Npb24iLCAmc2Vzc2lvbik7CiAgICByZXR1cm4gMDsKfQoKaW50CmNyZWF0ZV90cmFwX3Nlc3Npb24oY2hhciAqc2luaywgdV9zaG9ydCBzaW5rcG9ydCwKCQkgICAgY2hhciAqY29tLCBpbnQgdmVyc2lvbiwgaW50IHBkdXR5cGUpCnsKICAgIGNoYXIgYnVmW3NpemVvZihzaW5rcG9ydCkgKiAzICsgMl07CiAgICBpZiAoc2lua3BvcnQgIT0gMCkgewoJc3ByaW50ZihidWYsICI6JWh1Iiwgc2lua3BvcnQpOwoJc25tcF9sb2coTE9HX05PVElDRSwKCQkgIlVzaW5nIGEgc2VwYXJhdGUgcG9ydCBudW1iZXIgaXMgZGVwcmVjYXRlZCwgcGxlYXNlIGNvcnJlY3QgIgoJCSAidGhlIHNpbmsgc3BlY2lmaWNhdGlvbiBpbnN0ZWFkIik7CiAgICB9CiAgICByZXR1cm4gY3JlYXRlX3RyYXBfc2Vzc2lvbjIoc2luaywgc2lua3BvcnQgPyBidWYgOiBOVUxMLCBjb20sIHZlcnNpb24sCgkJCQlwZHV0eXBlKTsKfQoKI2VuZGlmIC8qIHN1cHBvcnQgZm9yIGNvbW11bml0eSBiYXNlZCBTTk1QICovCgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKc3RhdGljIGludApjcmVhdGVfdjFfdHJhcF9zZXNzaW9uKGNoYXIgKnNpbmssIGNvbnN0IGNoYXIgKnNpbmtwb3J0LCBjaGFyICpjb20pCnsKICAgIHJldHVybiBjcmVhdGVfdHJhcF9zZXNzaW9uMihzaW5rLCBzaW5rcG9ydCwgY29tLAoJCQkJU05NUF9WRVJTSU9OXzEsIFNOTVBfTVNHX1RSQVApOwp9CiNlbmRpZgoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYyQwpzdGF0aWMgaW50CmNyZWF0ZV92Ml90cmFwX3Nlc3Npb24oY29uc3QgY2hhciAqc2luaywgY29uc3QgY2hhciAqc2lua3BvcnQsIGNoYXIgKmNvbSkKewogICAgcmV0dXJuIGNyZWF0ZV90cmFwX3Nlc3Npb24yKHNpbmssIHNpbmtwb3J0LCBjb20sCgkJCQlTTk1QX1ZFUlNJT05fMmMsIFNOTVBfTVNHX1RSQVAyKTsKfQoKc3RhdGljIGludApjcmVhdGVfdjJfaW5mb3JtX3Nlc3Npb24oY29uc3QgY2hhciAqc2luaywgY29uc3QgY2hhciAqc2lua3BvcnQsIGNoYXIgKmNvbSkKewogICAgcmV0dXJuIGNyZWF0ZV90cmFwX3Nlc3Npb24yKHNpbmssIHNpbmtwb3J0LCBjb20sCgkJCQlTTk1QX1ZFUlNJT05fMmMsIFNOTVBfTVNHX0lORk9STSk7Cn0KI2VuZGlmCgp2b2lkCnNubXBkX2ZyZWVfdHJhcHNpbmtzKHZvaWQpCnsKICAgIHN0cnVjdCB0cmFwX3NpbmsgKnNwID0gc2lua3M7CiAgICBERUJVR01TR1RMKCgidHJhcCIsICJmcmVlaW5nIHRyYXAgc2Vzc2lvbnNcbiIpKTsKICAgIHdoaWxlIChzcCkgewogICAgICAgIHNpbmtzID0gc2lua3MtPm5leHQ7CiAgICAgICAgZnJlZV90cmFwX3Nlc3Npb24oc3ApOwogICAgICAgIHNwID0gc2lua3M7CiAgICB9Cn0KCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioKCSAqCgkgKiBUcmFwIGhhbmRsaW5nCgkgKgoJICoqKioqKioqKioqKioqKioqKiovCgoKbmV0c25tcF9wZHUqCmNvbnZlcnRfdjJwZHVfdG9fdjEoIG5ldHNubXBfcGR1KiB0ZW1wbGF0ZV92MnBkdSApCnsKICAgIG5ldHNubXBfcGR1ICAgICAgICAgICAqdGVtcGxhdGVfdjFwZHU7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmZpcnN0X3ZiLCAqdmJsaXN0OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CgogICAgLyoKICAgICAqIE1ha2UgYSBjb3B5IG9mIHRoZSB2MiBUcmFwIFBEVQogICAgICogICBiZWZvcmUgc3RhcnRpbmcgdG8gY29udmVydCB0aGlzCiAgICAgKiAgIGludG8gYSB2MSBUcmFwIFBEVS4KICAgICAqLwogICAgdGVtcGxhdGVfdjFwZHUgPSBzbm1wX2Nsb25lX3BkdSggdGVtcGxhdGVfdjJwZHUpOwogICAgaWYgKCF0ZW1wbGF0ZV92MXBkdSkgewogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBjb3B5IHYxIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB0ZW1wbGF0ZV92MXBkdS0+Y29tbWFuZCA9IFNOTVBfTVNHX1RSQVA7CiAgICBmaXJzdF92YiA9IHRlbXBsYXRlX3YxcGR1LT52YXJpYWJsZXM7CiAgICB2Ymxpc3QgICA9IHRlbXBsYXRlX3YxcGR1LT52YXJpYWJsZXM7CgogICAgLyoKICAgICAqIFRoZSBmaXJzdCB2YXJiaW5kIHNob3VsZCBiZSB0aGUgc3lzdGVtIHVwdGltZS4KICAgICAqLwogICAgaWYgKCF2Ymxpc3QgfHwKICAgICAgICBzbm1wX29pZF9jb21wYXJlKHZibGlzdC0+bmFtZSwgIHZibGlzdC0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICBzeXN1cHRpbWVfb2lkLCBzeXN1cHRpbWVfb2lkX2xlbikpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBubyB2MiBzeXNVcHRpbWUgdmFyYmluZCB0byBzZXQgZnJvbVxuIik7CiAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB0ZW1wbGF0ZV92MXBkdS0+dGltZSA9ICp2Ymxpc3QtPnZhbC5pbnRlZ2VyOwogICAgdmJsaXN0ID0gdmJsaXN0LT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICAKICAgIC8qCiAgICAgKiBUaGUgc2Vjb25kIHZhcmJpbmQgc2hvdWxkIGJlIHRoZSBzbm1wVHJhcE9JRC4KICAgICAqLwogICAgaWYgKCF2Ymxpc3QgfHwKICAgICAgICBzbm1wX29pZF9jb21wYXJlKHZibGlzdC0+bmFtZSwgdmJsaXN0LT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwX29pZCwgc25tcHRyYXBfb2lkX2xlbikpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBubyB2MiB0cmFwT0lEIHZhcmJpbmQgdG8gc2V0IGZyb21cbiIpOwogICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjFwZHUpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qCiAgICAgKiBDaGVjayB0aGUgdjIgdmFyYmluZCBsaXN0IGZvciBhbnkgdmFyYmluZHMKICAgICAqICB0aGF0IGFyZSBub3QgdmFsaWQgaW4gYW4gU05NUHYxIHRyYXAuCiAgICAgKiAgVGhpcyBiYXNpY2FsbHkgbWVhbnMgQ291bnRlcjY0IHZhbHVlcy4KICAgICAqCiAgICAgKiBSRkMgMjA4OSBzYWlkIHRvIG9taXQgc3VjaCB2YXJiaW5kcyBmcm9tIHRoZSBsaXN0LgogICAgICogUkZDIDI1NzYvMzU4NCBzYXkgdG8gZHJvcCB0aGUgdHJhcCBjb21wbGV0ZWx5LgogICAgICovCiAgICBmb3IgKHZhciA9IHZibGlzdC0+bmV4dF92YXJpYWJsZTsgdmFyOyB2YXIgPSB2YXItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICBpZiAoIHZhci0+dHlwZSA9PSBBU05fQ09VTlRFUjY0ICkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogdjEgdHJhcHMgY2FuJ3QgY2FycnkgQ291bnRlcjY0IHZhcmJpbmRzXG4iKTsKICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogU2V0IHRoZSBnZW5lcmljICYgc3BlY2lmaWMgdHJhcCB0eXBlcywKICAgICAqICAgIGFuZCB0aGUgZW50ZXJwcmlzZSBmaWVsZCBmcm9tIHRoZSB2MiB2YXJiaW5kIGxpc3QuCiAgICAgKiBJZiB0aGVyZSdzIGFuIGFnZW50SVBBZGRyZXNzIHZhcmJpbmQsIHNldCB0aGUgYWdlbnRfYWRkciB0b28KICAgICAqLwogICAgaWYgKCFzbm1wX29pZF9jb21wYXJlKHZibGlzdC0+dmFsLm9iamlkLCBPSURfTEVOR1RIKHRyYXBfcHJlZml4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFwX3ByZWZpeCwgICAgICAgT0lEX0xFTkdUSCh0cmFwX3ByZWZpeCkpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBGb3IgJ3N0YW5kYXJkJyB0cmFwcywgZXh0cmFjdCB0aGUgZ2VuZXJpYyB0cmFwIHR5cGUKICAgICAgICAgKiAgIGZyb20gdGhlIHNubXBUcmFwT0lEIHZhbHVlLCBhbmQgdGFrZSB0aGUgZW50ZXJwcmlzZQogICAgICAgICAqICAgdmFsdWUgZnJvbSB0aGUgJ3NubXBFbnRlcnByaXNlJyB2YXJiaW5kLgogICAgICAgICAqLwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUgPQogICAgICAgICAgICB2Ymxpc3QtPnZhbC5vYmppZFtPSURfTEVOR1RIKHRyYXBfcHJlZml4KV0gLSAxOwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT5zcGVjaWZpY190eXBlID0gMDsKCiAgICAgICAgdmFyID0gZmluZF92YXJiaW5kX2luX2xpc3QoIHZibGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWRfbGVuKTsKICAgICAgICBpZiAodmFyKSB7CiAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9IHZhci0+dmFsX2xlbi9zaXplb2Yob2lkKTsKICAgICAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UgPQogICAgICAgICAgICAgICAgc25tcF9kdXBsaWNhdGVfb2JqaWQodmFyLT52YWwub2JqaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlICAgICAgICA9IE5VTEw7CiAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9IDA7CQkvKiBYWFggPz8/ICovCiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIEZvciBlbnRlcnByaXNlLXNwZWNpZmljIHRyYXBzLCBzcGxpdCB0aGUgc25tcFRyYXBPSUQgdmFsdWUKICAgICAgICAgKiAgIGludG8gZW50ZXJwcmlzZSBhbmQgc3BlY2lmaWMgdHJhcAogICAgICAgICAqLwogICAgICAgIHNpemVfdCBsZW4gPSB2Ymxpc3QtPnZhbF9sZW4gLyBzaXplb2Yob2lkKTsKICAgICAgICBpZiAoIGxlbiA8PSAyICkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogdjIgdHJhcE9JRCB0b28gc2hvcnQgKCVkKVxuIiwgKGludClsZW4pOwogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUgICAgID0gU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQzsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+c3BlY2lmaWNfdHlwZSA9IHZibGlzdC0+dmFsLm9iamlkW2xlbiAtIDFdOwogICAgICAgIGxlbi0tOwogICAgICAgIGlmICh2Ymxpc3QtPnZhbC5vYmppZFtsZW4tMV0gPT0gMCkKICAgICAgICAgICAgbGVuLS07CiAgICAgICAgU05NUF9GUkVFKHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlKTsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZSA9CiAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKHZibGlzdC0+dmFsLm9iamlkLCBsZW4pOwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9IGxlbjsKICAgIH0KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB2Ymxpc3QsIGFnZW50YWRkcl9vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2VudGFkZHJfb2lkX2xlbik7CiAgICBpZiAodmFyKSB7CiAgICAgICAgbWVtY3B5KHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyLAogICAgICAgICAgICAgICB2YXItPnZhbC5zdHJpbmcsIDQpOwogICAgfQoKICAgIC8qCiAgICAgKiBUaGUgcmVtYWluZGVyIG9mIHRoZSB2MiB2YXJiaW5kIGxpc3QgaXMga2VwdAogICAgICogYXMgdGhlIHYyIHZhcmJpbmQgbGlzdC4gIFVwZGF0ZSB0aGUgUERVIGFuZAogICAgICogZnJlZSB0aGUgdHdvIHJlZHVuZGFudCB2YXJiaW5kcy4KICAgICAqLwogICAgdGVtcGxhdGVfdjFwZHUtPnZhcmlhYmxlcyA9IHZibGlzdC0+bmV4dF92YXJpYWJsZTsKICAgIHZibGlzdC0+bmV4dF92YXJpYWJsZSA9IE5VTEw7CiAgICBzbm1wX2ZyZWVfdmFyYmluZCggZmlyc3RfdmIgKTsKICAgICAgICAgICAgCiAgICByZXR1cm4gdGVtcGxhdGVfdjFwZHU7Cn0KCm5ldHNubXBfcGR1Kgpjb252ZXJ0X3YxcGR1X3RvX3YyKCBuZXRzbm1wX3BkdSogdGVtcGxhdGVfdjFwZHUgKQp7CiAgICBuZXRzbm1wX3BkdSAgICAgICAgICAgKnRlbXBsYXRlX3YycGR1OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CiAgICBvaWQgICAgICAgICAgICAgICAgICAgIGVudGVycHJpc2VbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgICAgICAgICBlbnRlcnByaXNlX2xlbjsKCiAgICAvKgogICAgICogTWFrZSBhIGNvcHkgb2YgdGhlIHYxIFRyYXAgUERVCiAgICAgKiAgIGJlZm9yZSBzdGFydGluZyB0byBjb252ZXJ0IHRoaXMKICAgICAqICAgaW50byBhIHYyIFRyYXAgUERVLgogICAgICovCiAgICB0ZW1wbGF0ZV92MnBkdSA9IHNubXBfY2xvbmVfcGR1KCB0ZW1wbGF0ZV92MXBkdSk7CiAgICBpZiAoIXRlbXBsYXRlX3YycGR1KSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvcHkgdjIgdGVtcGxhdGUgUERVXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHRlbXBsYXRlX3YycGR1LT5jb21tYW5kID0gU05NUF9NU0dfVFJBUDI7CgogICAgLyoKICAgICAqIEluc2VydCBhbiBzbm1wVHJhcE9JRCB2YXJiaW5kIGJlZm9yZSB0aGUgb3JpZ2luYWwgdjEgdmFyYmluZCBsaXN0CiAgICAgKiAgIGVpdGhlciB1c2luZyBvbmUgb2YgdGhlIHN0YW5kYXJkIGRlZmluZWQgdHJhcCBPSURzLAogICAgICogICBvciBjb25zdHJ1Y3RpbmcgdGhpcyBmcm9tIHRoZSBQRFUgZW50ZXJwcmlzZSAmIHNwZWNpZmljIHRyYXAgZmllbGRzCiAgICAgKi8KICAgIGlmICh0ZW1wbGF0ZV92MXBkdS0+dHJhcF90eXBlID09IFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMpIHsKICAgICAgICBtZW1jcHkoZW50ZXJwcmlzZSwgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCpzaXplb2Yob2lkKSk7CiAgICAgICAgZW50ZXJwcmlzZV9sZW4gICAgICAgICAgICAgICA9IHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aDsKICAgICAgICBlbnRlcnByaXNlW2VudGVycHJpc2VfbGVuKytdID0gMDsKICAgICAgICBlbnRlcnByaXNlW2VudGVycHJpc2VfbGVuKytdID0gdGVtcGxhdGVfdjFwZHUtPnNwZWNpZmljX3R5cGU7CiAgICB9IGVsc2UgewogICAgICAgIG1lbWNweShlbnRlcnByaXNlLCBjb2xkX3N0YXJ0X29pZCwgc2l6ZW9mKGNvbGRfc3RhcnRfb2lkKSk7CgllbnRlcnByaXNlWzldICA9IHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUrMTsKICAgICAgICBlbnRlcnByaXNlX2xlbiA9IHNpemVvZihjb2xkX3N0YXJ0X29pZCkvc2l6ZW9mKG9pZCk7CiAgICB9CgogICAgdmFyID0gTlVMTDsKICAgIGlmICghc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJnZhciwKICAgICAgICAgICAgIHNubXB0cmFwX29pZCwgc25tcHRyYXBfb2lkX2xlbiwKICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQsCiAgICAgICAgICAgICAodV9jaGFyKillbnRlcnByaXNlLCBlbnRlcnByaXNlX2xlbipzaXplb2Yob2lkKSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gaW5zZXJ0IGNvcGllZCBzbm1wVHJhcE9JRCB2YXJiaW5kXG4iKTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHZhci0+bmV4dF92YXJpYWJsZSAgICAgICAgPSB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzOwogICAgdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyA9IHZhcjsKCiAgICAvKgogICAgICogSW5zZXJ0IGEgc3lzVXB0aW1lIHZhcmJpbmQgYXQgdGhlIGhlYWQgb2YgdGhlIHYyIHZhcmJpbmQgbGlzdAogICAgICovCiAgICB2YXIgPSBOVUxMOwogICAgaWYgKCFzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCAmdmFyLAogICAgICAgICAgICAgc3lzdXB0aW1lX29pZCwgc3lzdXB0aW1lX29pZF9sZW4sCiAgICAgICAgICAgICBBU05fVElNRVRJQ0tTLAogICAgICAgICAgICAgKHVfY2hhciopJih0ZW1wbGF0ZV92MXBkdS0+dGltZSksIAogICAgICAgICAgICAgc2l6ZW9mKHRlbXBsYXRlX3YxcGR1LT50aW1lKSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gaW5zZXJ0IGNvcGllZCBzeXNVcHRpbWUgdmFyYmluZFxuIik7CiAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB2YXItPm5leHRfdmFyaWFibGUgICAgICAgID0gdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlczsKICAgIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMgPSB2YXI7CgogICAgLyoKICAgICAqIEFwcGVuZCB0aGUgb3RoZXIgdGhyZWUgY29udmVyc2lvbiB2YXJiaW5kcywKICAgICAqICAoc25tcFRyYXBBZ2VudEFkZHIsIHNubXBUcmFwQ29tbXVuaXR5ICYgc25tcFRyYXBFbnRlcnByaXNlKQogICAgICogIGlmIHRoZXkncmUgbm90IGFscmVhZHkgcHJlc2VudC4KICAgICAqICBCdXQgZG9uJ3QgYm9tYiBvdXQgY29tcGxldGVseSBpZiB0aGVyZSBhcmUgcHJvYmxlbXMuCiAgICAgKi8KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZW50YWRkcl9vaWQsIGFnZW50YWRkcl9vaWRfbGVuKTsKICAgIGlmICghdmFyICYmICh0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkclswXQogICAgICAgICAgICAgIHx8IHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyWzFdCiAgICAgICAgICAgICAgfHwgdGVtcGxhdGVfdjFwZHUtPmFnZW50X2FkZHJbMl0KICAgICAgICAgICAgICB8fCB0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkclszXSkpIHsKICAgICAgICBpZiAoIXNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICYodGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyksCiAgICAgICAgICAgICAgICAgYWdlbnRhZGRyX29pZCwgYWdlbnRhZGRyX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgQVNOX0lQQUREUkVTUywKICAgICAgICAgICAgICAgICAodV9jaGFyKikmKHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyKSwgCiAgICAgICAgICAgICAgICAgc2l6ZW9mKHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyKSkpCiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBhcHBlbmQgc25tcFRyYXBBZGRyIHZhcmJpbmRcbiIpOwogICAgfQogICAgdmFyID0gZmluZF92YXJiaW5kX2luX2xpc3QoIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbXVuaXR5X29pZCwgY29tbXVuaXR5X29pZF9sZW4pOwogICAgaWYgKCF2YXIgJiYgdGVtcGxhdGVfdjFwZHUtPmNvbW11bml0eSkgewogICAgICAgIGlmICghc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJih0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzKSwKICAgICAgICAgICAgICAgICBjb21tdW5pdHlfb2lkLCBjb21tdW5pdHlfb2lkX2xlbiwKICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSLAogICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5jb21tdW5pdHksIAogICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5jb21tdW5pdHlfbGVuKSkKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGFwcGVuZCBzbm1wVHJhcENvbW11bml0eSB2YXJiaW5kXG4iKTsKICAgIH0KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4pOwogICAgaWYgKCF2YXIpIHsKICAgICAgICBpZiAoIXNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICYodGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyksCiAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZCwgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgICAodV9jaGFyKil0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZSwgCiAgICAgICAgICAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2VfbGVuZ3RoKnNpemVvZihvaWQpKSkKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGFwcGVuZCBzbm1wRW50ZXJwcmlzZSB2YXJiaW5kXG4iKTsKICAgIH0KICAgIHJldHVybiB0ZW1wbGF0ZV92MnBkdTsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gYWxsb3dzIHlvdSB0byBtYWtlIGEgZGlzdGluY3Rpb24gYmV0d2VlbiBnZW5lcmljIAogKiB0cmFwcyBmcm9tIGRpZmZlcmVudCBjbGFzc2VzIG9mIGVxdWlwbWVudC4gRm9yIGV4YW1wbGUsIHlvdSBtYXkgd2FudCAKICogdG8gaGFuZGxlIGEgU05NUF9UUkFQX0xJTktET1dOIHRyYXAgZm9yIGEgcGFydGljdWxhciBkZXZpY2UgaW4gYSAKICogZGlmZmVyZW50IG1hbm5lciB0byBhIGdlbmVyaWMgc3lzdGVtIFNOTVBfVFJBUF9MSU5LRE9XTiB0cmFwLgogKiAgIAogKgogKiBAcGFyYW0gdHJhcCBpcyB0aGUgZ2VuZXJpYyB0cmFwIHR5cGUuICBUaGUgdHJhcCB0eXBlcyBhcmU6CiAqCQktIFNOTVBfVFJBUF9DT0xEU1RBUlQ6CiAqCQkJY29sZCBzdGFydAogKgkJLSBTTk1QX1RSQVBfV0FSTVNUQVJUOgogKgkJCXdhcm0gc3RhcnQKICoJCS0gU05NUF9UUkFQX0xJTktET1dOOgogKgkJCWxpbmsgZG93bgogKgkJLSBTTk1QX1RSQVBfTElOS1VQOgogKgkJCWxpbmsgdXAKICoJCS0gU05NUF9UUkFQX0FVVEhGQUlMOgogKgkJCWF1dGhlbnRpY2F0aW9uIGZhaWx1cmUKICoJCS0gU05NUF9UUkFQX0VHUE5FSUdIQk9STE9TUzoKICoJCQllZ3AgbmVpZ2hib3IgbG9zcwogKgkJLSBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDOgogKgkJCWVudGVycHJpc2Ugc3BlY2lmaWMKICoJCQkKICogQHBhcmFtIHNwZWNpZmljIGlzIHRoZSBzcGVjaWZpYyB0cmFwIHZhbHVlLgogKgogKiBAcGFyYW0gZW50ZXJwcmlzZSBpcyBhbiBlbnRlcnByaXNlIG9pZCBpbiB3aGljaCB5b3Ugd2FudCB0byBzZW5kIHNwZWNpZmljIAogKgl0cmFwcyBmcm9tLiAKICoKICogQHBhcmFtIGVudGVycHJpc2VfbGVuZ3RoIGlzIHRoZSBsZW5ndGggb2YgdGhlIGVudGVycHJpc2Ugb2lkLCB1c2UgbWFjcm8sCiAqCU9JRF9MRU5HVEgsIHRvIGNvbXB1dGUgbGVuZ3RoLgogKgogKiBAcGFyYW0gdmFycyBpcyB1c2VkIHRvIHN1cHBseSBsaXN0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIHRvIGZvcm0gYW4gU05NUHYyIAogKgl0cmFwLgogKgogKiBAcGFyYW0gY29udGV4dCBjdXJyZW50bHkgdW51c2VkIAogKgogKiBAcGFyYW0gZmxhZ3MgY3VycmVudGx5IHVudXNlZCAKICoKICogQHJldHVybiB2b2lkCiAqCiAqIEBzZWUgc2VuZF9lYXN5X3RyYXAKICogQHNlZSBzZW5kX3YydHJhcAogKi8KaW50Cm5ldHNubXBfc2VuZF90cmFwcyhpbnQgdHJhcCwgaW50IHNwZWNpZmljLAogICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqIGVudGVycHJpc2UsIGludCBlbnRlcnByaXNlX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiB2YXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKiBjb250ZXh0LCBpbnQgZmxhZ3MpCnsKICAgIG5ldHNubXBfcGR1ICAgICAgICAgICAqdGVtcGxhdGVfdjFwZHU7CiAgICBuZXRzbm1wX3BkdSAgICAgICAgICAgKnRlbXBsYXRlX3YycGR1OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2Ymxpc3QgPSBOVUxMOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp0cmFwX3ZiOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CiAgICBpbl9hZGRyX3QgICAgICAgICAgICAgKnBkdV9pbl9hZGRyX3Q7CiAgICB1X2xvbmcgICAgICAgICAgICAgICAgIHVwdGltZTsKICAgIHN0cnVjdCB0cmFwX3NpbmsgKnNpbms7CiAgICBjb25zdCBjaGFyICAgICAgICAgICAgKnYxdHJhcGFkZHJlc3M7CiAgICBpbnQgICAgICAgICAgICAgICAgICAgIHJlczsKCiAgICBERUJVR01TR1RMKCggInRyYXAiLCAic2VuZF90cmFwICVkICVkICIsIHRyYXAsIHNwZWNpZmljKSk7CiAgICBERUJVR01TR09JRCgoInRyYXAiLCBlbnRlcnByaXNlLCBlbnRlcnByaXNlX2xlbmd0aCkpOwogICAgREVCVUdNU0coKCAidHJhcCIsICJcbiIpKTsKCiAgICBpZiAodmFycykgewogICAgICAgIHZibGlzdCA9IHNubXBfY2xvbmVfdmFyYmluZCggdmFycyApOwogICAgICAgIGlmICghdmJsaXN0KSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gY2xvbmUgdmFyYmluZCBsaXN0XG4iKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoIHRyYXAgPT0gLTEgKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBDb25zdHJ1Y3QgdGhlIFNOTVB2Mi1zdHlsZSBub3RpZmljYXRpb24gUERVCiAgICAgICAgICovCiAgICAgICAgaWYgKCF2Ymxpc3QpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGNhbGxlZCB3aXRoIE5VTEwgdjIgaW5mb3JtYXRpb25cbiIpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIHRlbXBsYXRlX3YycGR1ID0gc25tcF9wZHVfY3JlYXRlKFNOTVBfTVNHX1RSQVAyKTsKICAgICAgICBpZiAoIXRlbXBsYXRlX3YycGR1KSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gY29uc3RydWN0IHYyIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHZibGlzdCk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogQ2hlY2sgdGhlIHZhcmJpbmQgbGlzdCB3ZSd2ZSBiZWVuIGdpdmVuLgogICAgICAgICAqIElmIGl0IHN0YXJ0cyB3aXRoIGEgJ3N5c1VwdGltZS4wJyB2YXJiaW5kLCB0aGVuIHVzZSB0aGF0LgogICAgICAgICAqIE90aGVyd2lzZSwgcHJlcGVuZCBhIHN1aXRhYmxlICdzeXNVcHRpbWUuMCcgdmFyYmluZC4KICAgICAgICAgKi8KICAgICAgICBpZiAoIXNubXBfb2lkX2NvbXBhcmUoIHZibGlzdC0+bmFtZSwgICAgdmJsaXN0LT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3VwdGltZV9vaWQsIHN5c3VwdGltZV9vaWRfbGVuICkpIHsKICAgICAgICAgICAgdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyA9IHZibGlzdDsKICAgICAgICAgICAgdHJhcF92YiAgPSB2Ymxpc3QtPm5leHRfdmFyaWFibGU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdXB0aW1lICAgPSBuZXRzbm1wX2dldF9hZ2VudF91cHRpbWUoKTsKICAgICAgICAgICAgdmFyID0gTlVMTDsKICAgICAgICAgICAgc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJnZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdXB0aW1lX29pZCwgc3lzdXB0aW1lX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9USU1FVElDS1MsICh1X2NoYXIqKSZ1cHRpbWUsIHNpemVvZih1cHRpbWUpKTsKICAgICAgICAgICAgaWYgKCF2YXIpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gaW5zZXJ0IHN5c1VwdGltZSB2YXJiaW5kXG4iKTsKICAgICAgICAgICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjJwZHUpOwogICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmJsaXN0KTsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzID0gdmFyOwogICAgICAgICAgICB2YXItPm5leHRfdmFyaWFibGUgICAgICAgID0gdmJsaXN0OwogICAgICAgICAgICB0cmFwX3ZiICA9IHZibGlzdDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogJ3RyYXBfdmInIHNob3VsZCBwb2ludCB0byB0aGUgc25tcFRyYXBPSUQuMCB2YXJiaW5kLAogICAgICAgICAqICAgaWRlbnRpZnlpbmcgdGhlIHJlcXVlc3RlZCB0cmFwLiAgSWYgbm90IHRoZW4gYm9tYiBvdXQuCiAgICAgICAgICogSWYgaXQncyBhICdzdGFuZGFyZCcgdHJhcCwgdGhlbiB3ZSBuZWVkIHRvIGFwcGVuZCBhbgogICAgICAgICAqICAgc25tcEVudGVycHJpc2UgdmFyYmluZCAoaWYgdGhlcmUgaXNuJ3QgYWxyZWFkeSBvbmUpLgogICAgICAgICAqLwogICAgICAgIGlmICghdHJhcF92YiB8fAogICAgICAgICAgICBzbm1wX29pZF9jb21wYXJlKHRyYXBfdmItPm5hbWUsIHRyYXBfdmItPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwX29pZCwgIHNubXB0cmFwX29pZF9sZW4pKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBubyB2MiB0cmFwT0lEIHZhcmJpbmQgcHJvdmlkZWRcbiIpOwogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBpZiAoIXNubXBfb2lkX2NvbXBhcmUodmJsaXN0LT52YWwub2JqaWQsIE9JRF9MRU5HVEgodHJhcF9wcmVmaXgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFwX3ByZWZpeCwgICAgICAgT0lEX0xFTkdUSCh0cmFwX3ByZWZpeCkpKSB7CiAgICAgICAgICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWRfbGVuKTsKICAgICAgICAgICAgaWYgKCF2YXIgJiYKICAgICAgICAgICAgICAgICFzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCAmKHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMpLAogICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkLCBzbm1wdHJhcGVudGVycHJpc2Vfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgICAgICAgKGNoYXIqKWVudGVycHJpc2UsIGVudGVycHJpc2VfbGVuZ3RoKnNpemVvZihvaWQpKSkgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBhZGQgc25tcEVudGVycHJpc2UgdG8gdjIgdHJhcFxuIik7CiAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAgICAgCgogICAgICAgIC8qCiAgICAgICAgICogSWYgZXZlcnl0aGluZydzIE9LLCBjb252ZXJ0IHRoZSB2MiB0ZW1wbGF0ZSBpbnRvIGFuIFNOTVB2MSB0cmFwIFBEVS4KICAgICAgICAgKi8KICAgICAgICB0ZW1wbGF0ZV92MXBkdSA9IGNvbnZlcnRfdjJwZHVfdG9fdjEoIHRlbXBsYXRlX3YycGR1ICk7CiAgICAgICAgaWYgKCF0ZW1wbGF0ZV92MXBkdSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvbnZlcnQgdjItPnYxIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiBDb25zdHJ1Y3QgdGhlIFNOTVB2MSB0cmFwIFBEVS4uLi4KICAgICAgICAgKi8KICAgICAgICB0ZW1wbGF0ZV92MXBkdSA9IHNubXBfcGR1X2NyZWF0ZShTTk1QX01TR19UUkFQKTsKICAgICAgICBpZiAoIXRlbXBsYXRlX3YxcGR1KSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gY29uc3RydWN0IHYxIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHZibGlzdCk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPnRyYXBfdHlwZSAgICAgPSB0cmFwOwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT5zcGVjaWZpY190eXBlID0gc3BlY2lmaWM7CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPnRpbWUgICAgICAgICAgPSBuZXRzbm1wX2dldF9hZ2VudF91cHRpbWUoKTsKCiAgICAgICAgaWYgKHNubXBfY2xvbmVfbWVtKCh2b2lkICoqKSAmdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UsCiAgICAgICAgICAgICAgICAgICAgICAgZW50ZXJwcmlzZSwgZW50ZXJwcmlzZV9sZW5ndGggKiBzaXplb2Yob2lkKSkpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBzZXQgdjEgZW50ZXJwcmlzZSBPSURcbiIpOwogICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2Ymxpc3QpOwogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGggPSBlbnRlcnByaXNlX2xlbmd0aDsKCiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmZsYWdzICAgIHw9IFVDRF9NU0dfRkxBR19GT1JDRV9QRFVfQ09QWTsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+dmFyaWFibGVzID0gdmJsaXN0OwoKICAgICAgICAvKgogICAgICAgICAqIC4uLiBhbmQgY29udmVydCBpdCBpbnRvIGFuIFNOTVB2Mi1zdHlsZSBub3RpZmljYXRpb24gUERVLgogICAgICAgICAqLwoKICAgICAgICB0ZW1wbGF0ZV92MnBkdSA9IGNvbnZlcnRfdjFwZHVfdG9fdjIoIHRlbXBsYXRlX3YxcGR1ICk7CiAgICAgICAgaWYgKCF0ZW1wbGF0ZV92MnBkdSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvbnZlcnQgdjEtPnYyIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBDaGVjayB3aGV0aGVyIHdlJ3JlIGlnbm9yaW5nIGF1dGhGYWlsIHRyYXBzCiAgICAgKi8KICAgIGlmICh0ZW1wbGF0ZV92MXBkdSkgewogICAgICBpZiAodGVtcGxhdGVfdjFwZHUtPnRyYXBfdHlwZSA9PSBTTk1QX1RSQVBfQVVUSEZBSUwgJiYKICAgICAgICBzbm1wX2VuYWJsZWF1dGhlbnRyYXBzID09IFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19ESVNBQkxFRCkgewogICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjFwZHUpOwogICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjJwZHUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9CgogICAgLyoKICAgICAqIEVuc3VyZSB0aGF0IHRoZSB2MSB0cmFwIFBEVSBpbmNsdWRlcyB0aGUgbG9jYWwgSVAgYWRkcmVzcwogICAgICovCiAgICAgICBwZHVfaW5fYWRkcl90ID0gKGluX2FkZHJfdCAqKSB0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkcjsKICAgICAgIHYxdHJhcGFkZHJlc3MgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX1RSQVBfQUREUik7CiAgICAgICBpZiAodjF0cmFwYWRkcmVzcyAhPSBOVUxMKSB7CiAgICAgICAgICAgLyogInYxdHJhcGFkZHJlc3MiIHdhcyBzcGVjaWZpZWQgaW4gY29uZmlnLCB0cnkgdG8gcmVzb2x2ZSBpdCAqLwogICAgICAgICAgIHJlcyA9IG5ldHNubXBfZ2V0aG9zdGJ5bmFtZV92NCh2MXRyYXBhZGRyZXNzLCBwZHVfaW5fYWRkcl90KTsKICAgICAgIH0KICAgICAgIGlmICh2MXRyYXBhZGRyZXNzID09IE5VTEwgfHwgcmVzIDwgMCkgewogICAgICAgICAgIC8qICJ2MXRyYXBhZGRyZXNzIiB3YXMgbm90IHNwZWNpZmllZCBpbiBjb25maWcgb3IgdGhlIHJlc29sdXRpb24gZmFpbGVkLAogICAgICAgICAgICAqIHRyeSBhbnkgbG9jYWwgYWRkcmVzcyAqLwogICAgICAgICAgICpwZHVfaW5fYWRkcl90ID0gZ2V0X215YWRkcigpOwogICAgICAgfQoKICAgIH0KCiAgICBpZiAodGVtcGxhdGVfdjJwZHUpIHsKCS8qIEEgY29udGV4dCBuYW1lIHdhcyBwcm92aWRlZCwgc28gY29weSBpdCBhbmQgaXRzIGxlbmd0aCB0byB0aGUgdjIgcGR1CgkgKiB0ZW1wbGF0ZS4gKi8KCWlmIChjb250ZXh0ICE9IE5VTEwpCgl7CgkJdGVtcGxhdGVfdjJwZHUtPmNvbnRleHROYW1lICAgID0gc3RyZHVwKGNvbnRleHQpOwoJCXRlbXBsYXRlX3YycGR1LT5jb250ZXh0TmFtZUxlbiA9IHN0cmxlbihjb250ZXh0KTsKCX0KICAgIH0KCiAgICAvKgogICAgICogIE5vdyBsb29wIHRocm91Z2ggdGhlIGxpc3Qgb2YgdHJhcCBzaW5rcwogICAgICogICBhbmQgY2FsbCB0aGUgdHJhcCBjYWxsYmFjayByb3V0aW5lcywKICAgICAqICAgcHJvdmlkaW5nIGFuIGFwcHJvcHJpYXRlbHkgZm9ybWF0dGVkIFBEVSBpbiBlYWNoIGNhc2UKICAgICAqLwogICAgZm9yIChzaW5rID0gc2lua3M7IHNpbms7IHNpbmsgPSBzaW5rLT5uZXh0KSB7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgIGlmIChzaW5rLT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xKSB7CiAgICAgICAgICBpZiAodGVtcGxhdGVfdjFwZHUpIHsKICAgICAgICAgICAgc2VuZF90cmFwX3RvX3Nlc3Moc2luay0+c2VzcCwgdGVtcGxhdGVfdjFwZHUpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgaWYgKHRlbXBsYXRlX3YycGR1KSB7CiAgICAgICAgICAgIHRlbXBsYXRlX3YycGR1LT5jb21tYW5kID0gc2luay0+cGR1dHlwZTsKICAgICAgICAgICAgc2VuZF90cmFwX3RvX3Nlc3Moc2luay0+c2VzcCwgdGVtcGxhdGVfdjJwZHUpOwogICAgICAgICAgfQojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgICAgICB9CiNlbmRpZgogICAgfQogICAgaWYgKHRlbXBsYXRlX3YxcGR1KQogICAgICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19BUFBMSUNBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgU05NUERfQ0FMTEJBQ0tfU0VORF9UUkFQMSwgdGVtcGxhdGVfdjFwZHUpOwogICAgaWYgKHRlbXBsYXRlX3YycGR1KQogICAgICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19BUFBMSUNBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgU05NUERfQ0FMTEJBQ0tfU0VORF9UUkFQMiwgdGVtcGxhdGVfdjJwZHUpOwogICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgIHJldHVybiAwOwp9CgoKdm9pZApzZW5kX2VudGVycHJpc2VfdHJhcF92YXJzKGludCB0cmFwLAogICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzcGVjaWZpYywKICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiBlbnRlcnByaXNlLCBpbnQgZW50ZXJwcmlzZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICogdmFycykKewogICAgbmV0c25tcF9zZW5kX3RyYXBzKHRyYXAsIHNwZWNpZmljLAogICAgICAgICAgICAgICAgICAgICAgIGVudGVycHJpc2UsIGVudGVycHJpc2VfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgIHZhcnMsIE5VTEwsIDApOwogICAgcmV0dXJuOwp9CgovKioKICogQ2FwdHVyZXMgcmVzcG9uc2VzIG9yIHRoZSBsYWNrIHRoZXJlIG9mIGZyb20gSU5GT1JNcyB0aGF0IHdlcmUgc2VudAogKiAxKSBhIHJlc3BvbnNlIGlzIHJlY2VpdmVkIGZyb20gYW4gSU5GT1JNCiAqIDIpIG9uZSBpc24ndCByZWNlaXZlZCBhbmQgdGhlIHJldHJpZXMvdGltZW91dHMgaGF2ZSBmYWlsZWQKKi8KaW50CmhhbmRsZV9pbmZvcm1fcmVzcG9uc2UoaW50IG9wLCBuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLAogICAgICAgICAgICAgICAgICAgICAgIGludCByZXFpZCwgbmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgICAgICAgICAgICB2b2lkICptYWdpYykKewogICAgLyogWFhYOiBwb3NzaWJseSBzdGF0cyB1cGRhdGUgKi8KICAgIHN3aXRjaCAob3ApIHsKCiAgICBjYXNlIE5FVFNOTVBfQ0FMTEJBQ0tfT1BfUkVDRUlWRURfTUVTU0FHRToKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5QS1RTKTsKICAgICAgICBERUJVR01TR1RMKCgidHJhcCIsICJyZWNlaXZlZCB0aGUgaW5mb3JtIHJlc3BvbnNlIGZvciByZXFpZD0lZFxuIiwKICAgICAgICAgICAgICAgICAgICByZXFpZCkpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTkVUU05NUF9DQUxMQkFDS19PUF9USU1FRF9PVVQ6CiAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLAogICAgICAgICAgICAgICAgICAgICJyZWNlaXZlZCBhIHRpbWVvdXQgc2VuZGluZyBhbiBpbmZvcm0gZm9yIHJlcWlkPSVkXG4iLAogICAgICAgICAgICAgICAgICAgIHJlcWlkKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBORVRTTk1QX0NBTExCQUNLX09QX1NFTkRfRkFJTEVEOgogICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwKICAgICAgICAgICAgICAgICAgICAiZmFpbGVkIHRvIHNlbmQgYW4gaW5mb3JtIGZvciByZXFpZD0lZFxuIiwKICAgICAgICAgICAgICAgICAgICByZXFpZCkpOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLCAicmVjZWl2ZWQgb3A9JWQgZm9yIHJlcWlkPSVkIHdoZW4gdHJ5aW5nIHRvIHNlbmQgYW4gaW5mb3JtXG4iLCBvcCwgcmVxaWQpKTsKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKCi8qCiAqIHNlbmRfdHJhcF90b19zZXNzOiBzZW5kcyBhIHRyYXAgdG8gYSBzZXNzaW9uIGJ1dCBhc3N1bWVzIHRoYXQgdGhlCiAqIHBkdSBpcyBjb25zdHJ1Y3RlZCBjb3JyZWN0bHkgZm9yIHRoZSBzZXNzaW9uIHR5cGUuIAogKi8Kdm9pZApzZW5kX3RyYXBfdG9fc2VzcyhuZXRzbm1wX3Nlc3Npb24gKiBzZXNzLCBuZXRzbm1wX3BkdSAqdGVtcGxhdGVfcGR1KQp7CiAgICBuZXRzbm1wX3BkdSAgICAqcGR1OwogICAgaW50ICAgICAgICAgICAgcmVzdWx0OwogICAgY2hhciAgICAgICAgICAgdG1wW1NQUklOVF9NQVhfTEVOXTsKICAgIGludCAgICAgICAgICAgIGxlbjsKCgogICAgaWYgKCFzZXNzIHx8ICF0ZW1wbGF0ZV9wZHUpCiAgICAgICAgcmV0dXJuOwoKICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgInNlbmRpbmcgdHJhcCB0eXBlPSVkLCB2ZXJzaW9uPSVsZFxuIiwKICAgICAgICAgICAgICAgIHRlbXBsYXRlX3BkdS0+Y29tbWFuZCwgc2Vzcy0+dmVyc2lvbikpOwoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICBpZiAoc2Vzcy0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMSAmJgogICAgICAgICh0ZW1wbGF0ZV9wZHUtPmNvbW1hbmQgIT0gU05NUF9NU0dfVFJBUCkpCiAgICAgICAgcmV0dXJuOyAgICAgICAgICAgICAgICAgLyogU2tpcCB2MSBzaW5rcyBmb3IgdjIgb25seSB0cmFwcyAqLwogICAgaWYgKHNlc3MtPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzEgJiYKICAgICAgICAodGVtcGxhdGVfcGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1RSQVApKQogICAgICAgIHJldHVybjsgICAgICAgICAgICAgICAgIC8qIFNraXAgdjIrIHNpbmtzIGZvciB2MSBvbmx5IHRyYXBzICovCiNlbmRpZgogICAgdGVtcGxhdGVfcGR1LT52ZXJzaW9uID0gc2Vzcy0+dmVyc2lvbjsKICAgIHBkdSA9IHNubXBfY2xvbmVfcGR1KHRlbXBsYXRlX3BkdSk7CiAgICBwZHUtPnNlc3NpZCA9IHNlc3MtPnNlc3NpZDsgLyogQWdlbnRYIG9ubHkgPyAqLwoKICAgIGlmICggdGVtcGxhdGVfcGR1LT5jb21tYW5kID09IFNOTVBfTVNHX0lORk9STQojaWZkZWYgVVNJTkdfQUdFTlRYX1BST1RPQ09MX01PRFVMRQogICAgICAgICB8fCB0ZW1wbGF0ZV9wZHUtPmNvbW1hbmQgPT0gQUdFTlRYX01TR19OT1RJRlkKI2VuZGlmCiAgICAgICApIHsKICAgICAgICByZXN1bHQgPQogICAgICAgICAgICBzbm1wX2FzeW5jX3NlbmQoc2VzcywgcGR1LCAmaGFuZGxlX2luZm9ybV9yZXNwb25zZSwgTlVMTCk7CiAgICAgICAgCiAgICB9IGVsc2UgewogICAgICAgIGlmICgoc2Vzcy0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMykgJiYKICAgICAgICAgICAgICAgIChwZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfVFJBUDIpICYmCiAgICAgICAgICAgICAgICAoc2Vzcy0+c2VjdXJpdHlFbmdpbmVJRExlbiA9PSAwKSkgewogICAgICAgICAgICBsZW4gPSBzbm1wdjNfZ2V0X2VuZ2luZUlEKHRtcCwgc2l6ZW9mKHRtcCkpOwogICAgICAgICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSUQgPSBuZXRzbm1wX21lbWR1cCh0bXAsIGxlbik7CiAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbiA9IGxlbjsKICAgICAgICB9CgogICAgICAgIHJlc3VsdCA9IHNubXBfc2VuZChzZXNzLCBwZHUpOwogICAgfQoKICAgIGlmIChyZXN1bHQgPT0gMCkgewogICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXBkOiBzZW5kX3RyYXAiLCBzZXNzKTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgICB9IGVsc2UgewogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBPVVRUUkFQUyk7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVFBLVFMpOwogICAgfQp9Cgp2b2lkCnNlbmRfdHJhcF92YXJzKGludCB0cmFwLCBpbnQgc3BlY2lmaWMsIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIHZhcnMpCnsKICAgIGlmICh0cmFwID09IFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMpCiAgICAgICAgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycyh0cmFwLCBzcGVjaWZpYywgb2JqaWRfZW50ZXJwcmlzZXRyYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPSURfTEVOR1RIKG9iamlkX2VudGVycHJpc2V0cmFwKSwgdmFycyk7CiAgICBlbHNlCiAgICAgICAgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycyh0cmFwLCBzcGVjaWZpYywgdHJhcF92ZXJzaW9uX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0lEX0xFTkdUSCh0cmFwX3ZlcnNpb25faWQpLCB2YXJzKTsKfQoKLyogU2VuZCBhIHRyYXAgdW5kZXIgYSBjb250ZXh0ICovCnZvaWQgc2VuZF90cmFwX3ZhcnNfd2l0aF9jb250ZXh0KGludCB0cmFwLCBpbnQgc3BlY2lmaWMsIAogICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFycywgY2hhciAqY29udGV4dCkKewogICAgaWYgKHRyYXAgPT0gU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQykKICAgICAgICBuZXRzbm1wX3NlbmRfdHJhcHModHJhcCwgc3BlY2lmaWMsIG9iamlkX2VudGVycHJpc2V0cmFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0lEX0xFTkdUSChvYmppZF9lbnRlcnByaXNldHJhcCksIHZhcnMsCgkJCQkJCQkJICBjb250ZXh0LCAwKTsKICAgIGVsc2UKICAgICAgICBuZXRzbm1wX3NlbmRfdHJhcHModHJhcCwgc3BlY2lmaWMsIHRyYXBfdmVyc2lvbl9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9JRF9MRU5HVEgodHJhcF92ZXJzaW9uX2lkKSwgdmFycywgCgkJCQkJCQkJICBjb250ZXh0LCAwKTsKICAgIAkKfQoKLyoqCiAqIFNlbmRzIGFuIFNOTVB2MSB0cmFwIChvciB0aGUgU05NUHYyIGVxdWl2YWxlbnQpIHRvIHRoZSBsaXN0IG9mICAKICogY29uZmlndXJlZCB0cmFwIGRlc3RpbmF0aW9ucyAob3IgInNpbmtzIiksIHVzaW5nIHRoZSBwcm92aWRlZCAKICogdmFsdWVzIGZvciB0aGUgZ2VuZXJpYyB0cmFwIHR5cGUgYW5kIHNwZWNpZmljIHRyYXAgdmFsdWUuCiAqCiAqIFRoaXMgZnVuY3Rpb24gZXZlbnR1YWxseSBjYWxscyBzZW5kX2VudGVycHJpc2VfdHJhcF92YXJzLiAgSWYgdGhlCiAqIHRyYXAgdHlwZSBpcyBub3Qgc2V0IHRvIFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMgdGhlIGVudGVycHJpc2UgCiAqIGFuZCBlbnRlcnByaXNlX2xlbmd0aCBwYXJhbWF0ZXIgaXMgc2V0IHRvIHRoZSBwcmUgZGVmaW5lZCBORVRTTk1QX1NZU1RFTV9NSUIgCiAqIG9pZCBhbmQgbGVuZ3RoIHJlc3BlY3RpdmVseS4gIElmIHRoZSB0cmFwIHR5cGUgaXMgc2V0IHRvIAogKiBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDIHRoZSBlbnRlcnByaXNlIGFuZCBlbnRlcnByaXNlX2xlbmd0aCAKICogcGFyYW1ldGVycyBhcmUgc2V0IHRvIHRoZSBwcmUtZGVmaW5lZCBORVRTTk1QX05PVElGSUNBVElPTl9NSUIgb2lkIGFuZCBsZW5ndGggCiAqIHJlc3BlY3RpdmVseS4KICoKICogQHBhcmFtIHRyYXAgaXMgdGhlIGdlbmVyaWMgdHJhcCB0eXBlLgogKgogKiBAcGFyYW0gc3BlY2lmaWMgaXMgdGhlIHNwZWNpZmljIHRyYXAgdmFsdWUuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNlbmRfZW50ZXJwcmlzZV90cmFwX3ZhcnMKICogQHNlZSBzZW5kX3YydHJhcAogKi8KICAgICAgIAkKdm9pZApzZW5kX2Vhc3lfdHJhcChpbnQgdHJhcCwgaW50IHNwZWNpZmljKQp7CiAgICBzZW5kX3RyYXBfdmFycyh0cmFwLCBzcGVjaWZpYywgTlVMTCk7Cn0KCi8qKgogKiBVc2VzIHRoZSBzdXBwbGllZCBsaXN0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIHRvIGZvcm0gYW4gU05NUHYyIHRyYXAsIAogKiB3aGljaCBpcyBzZW50IHRvIFNOTVB2Mi1jYXBhYmxlIHNpbmtzICBvbiAgdGhlICBjb25maWd1cmVkICBsaXN0LiAgCiAqIEFuIGVxdWl2YWxlbnQgSU5GT1JNIGlzIHNlbnQgdG8gdGhlIGNvbmZpZ3VyZWQgbGlzdCBvZiBpbmZvcm0gc2lua3MuICAKICogU2lua3MgdGhhdCBjYW4gb25seSBoYW5kbGUgU05NUHYxIHRyYXBzIGFyZSBza2lwcGVkLgogKgogKiBUaGlzIGZ1bmN0aW9uIGV2ZW50dWFsbHkgY2FsbHMgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycy4gIElmIHRoZQogKiB0cmFwIHR5cGUgaXMgbm90IHNldCB0byBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDIHRoZSBlbnRlcnByaXNlIAogKiBhbmQgZW50ZXJwcmlzZV9sZW5ndGggcGFyYW1hdGVyIGlzIHNldCB0byB0aGUgcHJlIGRlZmluZWQgTkVUU05NUF9TWVNURU1fTUlCIAogKiBvaWQgYW5kIGxlbmd0aCByZXNwZWN0aXZlbHkuICBJZiB0aGUgdHJhcCB0eXBlIGlzIHNldCB0byAKICogU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQyB0aGUgZW50ZXJwcmlzZSBhbmQgZW50ZXJwcmlzZV9sZW5ndGggCiAqIHBhcmFtZXRlcnMgYXJlIHNldCB0byB0aGUgcHJlLWRlZmluZWQgTkVUU05NUF9OT1RJRklDQVRJT05fTUlCIG9pZCBhbmQgbGVuZ3RoIAogKiByZXNwZWN0aXZlbHkuCiAqCiAqIEBwYXJhbSB2YXJzIGlzIHVzZWQgdG8gc3VwcGx5IGxpc3Qgb2YgdmFyaWFibGUgYmluZGluZ3MgdG8gZm9ybSBhbiBTTk1QdjIgCiAqCXRyYXAuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNlbmRfZWFzeV90cmFwCiAqIEBzZWUgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycwogKi8KCnZvaWQKc2VuZF92MnRyYXAobmV0c25tcF92YXJpYWJsZV9saXN0ICogdmFycykKewogICAgc2VuZF90cmFwX3ZhcnMoLTEsIC0xLCB2YXJzKTsKfQoKLyoqCiAqIFNpbWlsYXIgdG8gc2VuZF92MnRyYXAoKSwgd2l0aCB0aGUgYWRkZWQgYWJpbGl0eSB0byBzcGVjaWZ5IGEgY29udGV4dC4gIElmCiAqIHRoZSBsYXN0IHBhcmFtZXRlciBpcyBOVUxMLCB0aGVuIHRoaXMgY2FsbCBpcyBlcXVpdmFsZW50IHRvIHNlbmRfdjJ0cmFwKCkuCiAqCiAqIEBwYXJhbSB2YXJzIGlzIHVzZWQgdG8gc3VwcGx5IHRoZSBsaXN0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIGZvciB0aGUgdHJhcC4KICogCiAqIEBwYXJhbSBjb250ZXh0IGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUgY29udGV4dCBvZiB0aGUgdHJhcC4KICoKICogQHJldHVybiB2b2lkCiAqCiAqIEBzZWUgc2VuZF92MnRyYXAKICovCnZvaWQgc2VuZF92M3RyYXAobmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJzLCBjaGFyICpjb250ZXh0KQp7CiAgICBuZXRzbm1wX3NlbmRfdHJhcHMoLTEsIC0xLCAKCQkJCQl0cmFwX3ZlcnNpb25faWQsIE9JRF9MRU5HVEgodHJhcF92ZXJzaW9uX2lkKSwKICAgICAgICAgICAgICAgICAgICB2YXJzLCBjb250ZXh0LCAwKTsKfQoKdm9pZApzZW5kX3RyYXBfcGR1KG5ldHNubXBfcGR1ICpwZHUpCnsKICAgIHNlbmRfdHJhcF92YXJzKC0xLCAtMSwgcGR1LT52YXJpYWJsZXMpOwp9CgoKCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioKCSAqCgkgKiBDb25maWcgZmlsZSBoYW5kbGluZwoJICoKCSAqKioqKioqKioqKioqKioqKioqLwoKdm9pZApzbm1wZF9wYXJzZV9jb25maWdfYXV0aHRyYXAoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIGkgPSBhdG9pKGNwdHIpOwogICAgaWYgKGkgPT0gMCkgewogICAgICAgIGlmIChzdHJjbXAoY3B0ciwgImVuYWJsZSIpID09IDApIHsKICAgICAgICAgICAgaSA9IFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19FTkFCTEVEOwogICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKGNwdHIsICJkaXNhYmxlIikgPT0gMCkgewogICAgICAgICAgICBpID0gU05NUF9BVVRIRU5USUNBVEVEX1RSQVBTX0RJU0FCTEVEOwogICAgICAgIH0KICAgIH0KICAgIGlmIChpIDwgMSB8fCBpID4gMikgewogICAgICAgIGNvbmZpZ19wZXJyb3IoImF1dGh0cmFwZW5hYmxlIG11c3QgYmUgMSBvciAyIik7CiAgICB9IGVsc2UgewogICAgICAgIGlmIChzdHJjbXAodG9rZW4sICJwYXV0aHRyYXBlbmFibGUiKSA9PSAwKSB7CiAgICAgICAgICAgIGlmIChzbm1wX2VuYWJsZWF1dGhlbnRyYXBzc2V0IDwgMCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgYm9ndXMgKGFuZCBzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgLS0gdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgKiBvZiBzbm1wRW5hYmxlQXV0aGVuVHJhcHMuMCBpcyBhbHJlYWR5IGNvbmZpZ3VyZWQKICAgICAgICAgICAgICAgICAqIHJlYWQtb25seS4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICJpZ25vcmluZyBhdHRlbXB0ZWQgb3ZlcnJpZGUgb2YgcmVhZC1vbmx5IHNubXBFbmFibGVBdXRoZW5UcmFwcy4wXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNubXBfZW5hYmxlYXV0aGVudHJhcHNzZXQrKzsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChzbm1wX2VuYWJsZWF1dGhlbnRyYXBzc2V0ID4gMCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgYm9ndXMgKGFuZCBzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgLS0gd2UgYWxyZWFkeQogICAgICAgICAgICAgICAgICogcmVhZCBhIHBlcnNpc3RlbnQgdmFsdWUgb2Ygc25tcEVuYWJsZUF1dGhlblRyYXBzLjAsIHdoaWNoCiAgICAgICAgICAgICAgICAgKiB3ZSBzaG91bGQgaWdub3JlIGluIGZhdm91ciBvZiB0aGlzIG9uZS4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICJpZ25vcmluZyBhdHRlbXB0ZWQgb3ZlcnJpZGUgb2YgcmVhZC1vbmx5IHNubXBFbmFibGVBdXRoZW5UcmFwcy4wXG4iKTsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBGYWxsIHRocm91Z2ggYW5kIGNvcHkgaW4gdGhpcyB2YWx1ZS4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwc3NldCA9IC0xOwogICAgICAgIH0KICAgICAgICBzbm1wX2VuYWJsZWF1dGhlbnRyYXBzID0gaTsKICAgIH0KfQoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX3RyYXBzaW5rKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBjaGFyICAgICAgICAgICAqc3AsICpjcCwgKnBwID0gTlVMTDsKICAgIGNoYXIgICAgICAgICAgICAqc3Q7CgogICAgaWYgKCFzbm1wX3RyYXBjb21tdW5pdHkpCiAgICAgICAgc25tcF90cmFwY29tbXVuaXR5ID0gc3RyZHVwKCJwdWJsaWMiKTsKICAgIHNwID0gc3RydG9rX3IoY3B0ciwgIiBcdFxuIiwgJnN0KTsKICAgIGNwID0gc3RydG9rX3IoTlVMTCwgIiBcdFxuIiwgJnN0KTsKICAgIGlmIChjcCkKICAgICAgICBwcCA9IHN0cnRva19yKE5VTEwsICIgXHRcbiIsICZzdCk7CiAgICBpZiAocHApCgljb25maWdfcHdhcm4oIlRoZSBzZXBhcmF0ZSBwb3J0IGFyZ3VtZW50IHRvIHRyYXBzaW5rIGlzIGRlcHJlY2F0ZWQiKTsKICAgIGlmIChjcmVhdGVfdjFfdHJhcF9zZXNzaW9uKHNwLCBwcCwgY3AgPyBjcCA6IHNubXBfdHJhcGNvbW11bml0eSkgPT0gMCkgewoJbmV0c25tcF9jb25maWdfZXJyb3IoImNhbm5vdCBjcmVhdGUgdHJhcHNpbms6ICVzIiwgY3B0cik7CiAgICB9Cn0KI2VuZGlmCgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX3RyYXAyc2luayhjb25zdCBjaGFyICp3b3JkLCBjaGFyICpjcHRyKQp7CiAgICBjaGFyICAgICAgICAgICAqc3QsICpzcCwgKmNwLCAqcHAgPSBOVUxMOwoKICAgIGlmICghc25tcF90cmFwY29tbXVuaXR5KQogICAgICAgIHNubXBfdHJhcGNvbW11bml0eSA9IHN0cmR1cCgicHVibGljIik7CiAgICBzcCA9IHN0cnRva19yKGNwdHIsICIgXHRcbiIsICZzdCk7CiAgICBjcCA9IHN0cnRva19yKE5VTEwsICIgXHRcbiIsICZzdCk7CiAgICBpZiAoY3ApCiAgICAgICAgcHAgPSBzdHJ0b2tfcihOVUxMLCAiIFx0XG4iLCAmc3QpOwogICAgaWYgKHBwKQoJY29uZmlnX3B3YXJuKCJUaGUgc2VwYXJhdGUgcG9ydCBhcmd1bWVudCB0byB0cmFwc2luazIgaXMgZGVwcmVjYXRlZCIpOwogICAgaWYgKGNyZWF0ZV92Ml90cmFwX3Nlc3Npb24oc3AsIHBwLCBjcCA/IGNwIDogc25tcF90cmFwY29tbXVuaXR5KSA9PSAwKSB7CgluZXRzbm1wX2NvbmZpZ19lcnJvcigiY2Fubm90IGNyZWF0ZSB0cmFwMnNpbms6ICVzIiwgY3B0cik7CiAgICB9Cn0KCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX2luZm9ybXNpbmsoY29uc3QgY2hhciAqd29yZCwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgKnN0LCAqc3AsICpjcCwgKnBwID0gTlVMTDsKCiAgICBpZiAoIXNubXBfdHJhcGNvbW11bml0eSkKICAgICAgICBzbm1wX3RyYXBjb21tdW5pdHkgPSBzdHJkdXAoInB1YmxpYyIpOwogICAgc3AgPSBzdHJ0b2tfcihjcHRyLCAiIFx0XG4iLCAmc3QpOwogICAgY3AgPSBzdHJ0b2tfcihOVUxMLCAiIFx0XG4iLCAmc3QpOwogICAgaWYgKGNwKQogICAgICAgIHBwID0gc3RydG9rX3IoTlVMTCwgIiBcdFxuIiwgJnN0KTsKICAgIGlmIChwcCkKCWNvbmZpZ19wd2FybigiVGhlIHNlcGFyYXRlIHBvcnQgYXJndW1lbnQgdG8gaW5mb3Jtc2luayBpcyBkZXByZWNhdGVkIik7CiAgICBpZiAoY3JlYXRlX3YyX2luZm9ybV9zZXNzaW9uKHNwLCBwcCwgY3AgPyBjcCA6IHNubXBfdHJhcGNvbW11bml0eSkgPT0gMCkgewoJbmV0c25tcF9jb25maWdfZXJyb3IoImNhbm5vdCBjcmVhdGUgaW5mb3Jtc2luazogJXMiLCBjcHRyKTsKICAgIH0KfQojZW5kaWYKCi8qCiAqIHRoaXMgbXVzdCBiZSBzdGFuZGFyZGl6ZWQgc29tZXdoZXJlLCByaWdodD8gCiAqLwojZGVmaW5lIE1BWF9BUkdTIDEyOAoKc3RhdGljIGludCAgICAgIHRyYXB0eXBlOwoKc3RhdGljIHZvaWQKdHJhcE9wdFByb2MoaW50IGFyZ2MsIGNoYXIgKmNvbnN0ICphcmd2LCBpbnQgb3B0KQp7CiAgICBzd2l0Y2ggKG9wdCkgewogICAgY2FzZSAnQyc6CiAgICAgICAgd2hpbGUgKCpvcHRhcmcpIHsKICAgICAgICAgICAgc3dpdGNoICgqb3B0YXJnKyspIHsKICAgICAgICAgICAgY2FzZSAnaSc6CiAgICAgICAgICAgICAgICB0cmFwdHlwZSA9IFNOTVBfTVNHX0lORk9STTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgY29uZmlnX3BlcnJvcigidW5rbm93biBhcmd1bWVudCBwYXNzZWQgdG8gLUMiKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQp9CgoKdm9pZApzbm1wZF9wYXJzZV9jb25maWdfdHJhcHNlc3MoY29uc3QgY2hhciAqd29yZCwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgKmFyZ3ZbTUFYX0FSR1NdLCAqY3AgPSBjcHRyLCB0bXBbU1BSSU5UX01BWF9MRU5dOwogICAgaW50ICAgICAgICAgICAgIGFyZ247CiAgICBuZXRzbm1wX3Nlc3Npb24gc2Vzc2lvbiwgKnNzOwogICAgc2l6ZV90ICAgICAgICAgIGxlbjsKCiAgICAvKgogICAgICogaW5mb3JtIG9yIHRyYXA/ICBkZWZhdWx0IHRvIHRyYXAgCiAgICAgKi8KICAgIHRyYXB0eXBlID0gU05NUF9NU0dfVFJBUDI7CgogICAgLyoKICAgICAqIGNyZWF0ZSB0aGUgYXJndltdIGxpa2UgYXJyYXkgCiAgICAgKi8KICAgIGFyZ3ZbMF0gPSBzdHJkdXAoInNubXBkLXRyYXBzZXNzIik7IC8qIGJvZ3VzIGVudHJ5IGZvciBnZXRvcHQoKSAqLwogICAgZm9yIChhcmduID0gMTsgY3AgJiYgYXJnbiA8IE1BWF9BUkdTOyBhcmduKyspIHsKICAgICAgICBjcCA9IGNvcHlfbndvcmQoY3AsIHRtcCwgU1BSSU5UX01BWF9MRU4pOwogICAgICAgIGFyZ3ZbYXJnbl0gPSBzdHJkdXAodG1wKTsKICAgIH0KCiAgICBzbm1wX3BhcnNlX2FyZ3MoYXJnbiwgYXJndiwgJnNlc3Npb24sICJDOiIsIHRyYXBPcHRQcm9jKTsKCiAgICBzcyA9IHNubXBfYWRkKCZzZXNzaW9uLAoJCSAgbmV0c25tcF90cmFuc3BvcnRfb3Blbl9jbGllbnQoInNubXB0cmFwIiwgc2Vzc2lvbi5wZWVybmFtZSksCgkJICBOVUxMLCBOVUxMKTsKICAgIGZvciAoOyBhcmduID4gMDsgYXJnbi0tKSB7CiAgICAgICAgZnJlZShhcmd2W2FyZ24gLSAxXSk7CiAgICB9CgogICAgaWYgKCFzcykgewogICAgICAgIGNvbmZpZ19wZXJyb3IKICAgICAgICAgICAgKCJzbm1wZDogZmFpbGVkIHRvIHBhcnNlIHRoaXMgbGluZSBvciB0aGUgcmVtb3RlIHRyYXAgcmVjZWl2ZXIgaXMgZG93bi4gIFBvc3NpYmxlIGNhdXNlOiIpOwogICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXBkOiBzbm1wZF9wYXJzZV9jb25maWdfdHJhcHNlc3MoKSIsICZzZXNzaW9uKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyoKICAgICAqIElmIHRoaXMgaXMgYW4gU05NUHYzIFRSQVAgc2Vzc2lvbiwgdGhlbiB0aGUgYWdlbnQgaXMKICAgICAqICAgdGhlIGF1dGhvcml0YXRpdmUgZW5naW5lLCBzbyBzZXQgdGhlIGVuZ2luZUlEIGFjY29yZGluZ2x5CiAgICAgKi8KICAgIGlmIChzcy0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMyAmJgogICAgICAgIHRyYXB0eXBlICE9IFNOTVBfTVNHX0lORk9STSAgICYmCiAgICAgICAgc3MtPnNlY3VyaXR5RW5naW5lSURMZW4gPT0gMCkgewogICAgICAgICAgICBsZW4gPSBzbm1wdjNfZ2V0X2VuZ2luZUlEKCB0bXAsIHNpemVvZih0bXApKTsKICAgICAgICAgICAgc3MtPnNlY3VyaXR5RW5naW5lSUQgPSBuZXRzbm1wX21lbWR1cCh0bXAsIGxlbik7CiAgICAgICAgICAgIHNzLT5zZWN1cml0eUVuZ2luZUlETGVuID0gbGVuOwogICAgfQoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICBpZiAoc3MtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpIHsKICAgICAgICBhZGRfdHJhcF9zZXNzaW9uKHNzLCBTTk1QX01TR19UUkFQLCAwLCBTTk1QX1ZFUlNJT05fMSk7CiAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICBhZGRfdHJhcF9zZXNzaW9uKHNzLCB0cmFwdHlwZSwgKHRyYXB0eXBlID09IFNOTVBfTVNHX0lORk9STSksCiAgICAgICAgICAgICAgICAgICAgICAgICBzcy0+dmVyc2lvbik7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgfQojZW5kaWYKfQoKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQp2b2lkCnNubXBkX3BhcnNlX2NvbmZpZ190cmFwY29tbXVuaXR5KGNvbnN0IGNoYXIgKndvcmQsIGNoYXIgKmNwdHIpCnsKICAgIGlmIChzbm1wX3RyYXBjb21tdW5pdHkgIT0gTlVMTCkgewogICAgICAgIGZyZWUoc25tcF90cmFwY29tbXVuaXR5KTsKICAgIH0KICAgIHNubXBfdHJhcGNvbW11bml0eSA9IChjaGFyICopIG1hbGxvYyhzdHJsZW4oY3B0cikgKyAxKTsKICAgIGlmIChzbm1wX3RyYXBjb21tdW5pdHkgIT0gTlVMTCkgewogICAgICAgIGNvcHlfbndvcmQoY3B0ciwgc25tcF90cmFwY29tbXVuaXR5LCBzdHJsZW4oY3B0cikgKyAxKTsKICAgIH0KfQoKdm9pZApzbm1wZF9mcmVlX3RyYXBjb21tdW5pdHkodm9pZCkKewogICAgaWYgKHNubXBfdHJhcGNvbW11bml0eSkgewogICAgICAgIGZyZWUoc25tcF90cmFwY29tbXVuaXR5KTsKICAgICAgICBzbm1wX3RyYXBjb21tdW5pdHkgPSBOVUxMOwogICAgfQp9CiNlbmRpZgovKiogQH0gKi8K