LyoKICogYWdlbnRfdHJhcC5jCiAqLwovKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb3B5cmlnaHQocykuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgqSAyMDAzIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIENPUFlJTkcgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoZSBOZXQtU05NUCBwYWNrYWdlLgogKi8KLyoqIEBkZWZncm91cCBhZ2VudF90cmFwIFRyYXAgZ2VuZXJhdGlvbiByb3V0aW5lcyBmb3IgbWliIG1vZHVsZXMgdG8gdXNlCiAqICBAaW5ncm91cCBhZ2VudAogKgogKiBAewogKi8KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaWZkZWYgV0lOMzIKIyAgaW5jbHVkZSA8c3lzL3RpbWViLmg+CiMgZWxzZQojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVuZGlmCiMgaW5jbHVkZSA8dGltZS5oPgojZWxzZQojIGlmIEhBVkVfU1lTX1RJTUVfSAojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVsc2UKIyAgaW5jbHVkZSA8dGltZS5oPgojIGVuZGlmCiNlbmRpZgojaWYgSEFWRV9TWVNfU09DS0VUX0gKI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2VsaWYgSEFWRV9XSU5TT0NLX0gKI2luY2x1ZGUgPHdpbnNvY2suaD4KI2VuZGlmCiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2luY2x1ZGUgPG5ldC1zbm1wL3V0aWxpdGllcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9hZ2VudF90cmFwLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9zbm1wX2FnZW50Lmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9hZ2VudF9jYWxsYmFja3MuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9hZ2VudF9tb2R1bGVfY29uZmlnLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9taWJfbW9kdWxlX2NvbmZpZy5oPgoKI2lmZGVmIFVTSU5HX0FHRU5UWF9QUk9UT0NPTF9NT0RVTEUKI2luY2x1ZGUgImFnZW50eC9wcm90b2NvbC5oIgojZW5kaWYKCnN0cnVjdCB0cmFwX3NpbmsgewogICAgbmV0c25tcF9zZXNzaW9uICpzZXNwOwogICAgc3RydWN0IHRyYXBfc2luayAqbmV4dDsKICAgIGludCAgICAgICAgICAgICBwZHV0eXBlOwogICAgaW50ICAgICAgICAgICAgIHZlcnNpb247Cn07CgpzdHJ1Y3QgdHJhcF9zaW5rICpzaW5rcyA9IE5VTEw7CgpleHRlcm4gc3RydWN0IHRpbWV2YWwgc3RhcnR0aW1lOwoKb2lkICAgICAgICAgICAgIG9iamlkX2VudGVycHJpc2V0cmFwW10gPSB7IE5FVFNOTVBfTk9USUZJQ0FUSU9OX01JQiB9OwpvaWQgICAgICAgICAgICAgdHJhcF92ZXJzaW9uX2lkW10gPSB7IE5FVFNOTVBfU1lTVEVNX01JQiB9OwppbnQgICAgICAgICAgICAgZW50ZXJwcmlzZXRyYXBfbGVuOwppbnQgICAgICAgICAgICAgdHJhcF92ZXJzaW9uX2lkX2xlbjsKCiNkZWZpbmUgU05NUFYyX1RSQVBTX1BSRUZJWAlTTk1QX09JRF9TTk1QTU9EVUxFUywxLDEsNQpvaWQgICAgICAgICAgICAgdHJhcF9wcmVmaXhbXSAgICA9IHsgU05NUFYyX1RSQVBTX1BSRUZJWCB9OwpvaWQgICAgICAgICAgICAgY29sZF9zdGFydF9vaWRbXSA9IHsgU05NUFYyX1RSQVBTX1BSRUZJWCwgMSB9OyAgLyogU05NUHYyLU1JQiAqLwpvaWQgICAgICAgICAgICAgd2FybV9zdGFydF9vaWRbXSA9IHsgU05NUFYyX1RSQVBTX1BSRUZJWCwgMiB9OyAgLyogU05NUHYyLU1JQiAqLwpvaWQgICAgICAgICAgICAgbGlua19kb3duX29pZFtdICA9IHsgU05NUFYyX1RSQVBTX1BSRUZJWCwgMyB9OyAgLyogSUYtTUlCICovCm9pZCAgICAgICAgICAgICBsaW5rX3VwX29pZFtdICAgID0geyBTTk1QVjJfVFJBUFNfUFJFRklYLCA0IH07ICAvKiBJRi1NSUIgKi8Kb2lkICAgICAgICAgICAgIGF1dGhfZmFpbF9vaWRbXSAgPSB7IFNOTVBWMl9UUkFQU19QUkVGSVgsIDUgfTsgIC8qIFNOTVB2Mi1NSUIgKi8Kb2lkICAgICAgICAgICAgIGVncF94eHhfb2lkW10gICAgPSB7IFNOTVBWMl9UUkFQU19QUkVGSVgsIDk5IH07IC8qID8/PyAqLwoKI2RlZmluZSBTTk1QVjJfVFJBUF9PQkpTX1BSRUZJWAlTTk1QX09JRF9TTk1QTU9EVUxFUywxLDEsNApvaWQgICAgICAgICAgICAgc25tcHRyYXBfb2lkW10gPSB7IFNOTVBWMl9UUkFQX09CSlNfUFJFRklYLCAxLCAwIH07Cm9pZCAgICAgICAgICAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkW10gPQogICAgeyBTTk1QVjJfVFJBUF9PQkpTX1BSRUZJWCwgMywgMCB9OwpvaWQgICAgICAgICAgICAgc3lzdXB0aW1lX29pZFtdID0geyBTTk1QX09JRF9NSUIyLCAxLCAzLCAwIH07CnNpemVfdCAgICAgICAgICBzbm1wdHJhcF9vaWRfbGVuOwpzaXplX3QgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW47CnNpemVfdCAgICAgICAgICBzeXN1cHRpbWVfb2lkX2xlbjsKCiNkZWZpbmUgU05NUFYyX0NPTU1fT0JKU19QUkVGSVgJU05NUF9PSURfU05NUE1PRFVMRVMsMTgsMQpvaWQgICAgICAgICAgICAgYWdlbnRhZGRyX29pZFtdID0geyBTTk1QVjJfQ09NTV9PQkpTX1BSRUZJWCwgMywgMCB9OwpzaXplX3QgICAgICAgICAgYWdlbnRhZGRyX29pZF9sZW47Cm9pZCAgICAgICAgICAgICBjb21tdW5pdHlfb2lkW10gPSB7IFNOTVBWMl9DT01NX09CSlNfUFJFRklYLCA0LCAwIH07CnNpemVfdCAgICAgICAgICBjb21tdW5pdHlfb2lkX2xlbjsKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQpjaGFyICAgICAgICAgICAqc25tcF90cmFwY29tbXVuaXR5ID0gTlVMTDsKI2VuZGlmCgoKI2RlZmluZSBTTk1QX0FVVEhFTlRJQ0FURURfVFJBUFNfRU5BQkxFRAkxCiNkZWZpbmUgU05NUF9BVVRIRU5USUNBVEVEX1RSQVBTX0RJU0FCTEVECTIKCmxvbmcgICAgICAgICAgICBzbm1wX2VuYWJsZWF1dGhlbnRyYXBzID0gU05NUF9BVVRIRU5USUNBVEVEX1RSQVBTX0RJU0FCTEVEOwppbnQgICAgICAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwc3NldCA9IDA7CgovKgogKiBQcm90b3R5cGVzIAogKi8KIC8qCiAgKiBzdGF0aWMgaW50IGNyZWF0ZV92MV90cmFwX3Nlc3Npb24gKGNvbnN0IGNoYXIgKiwgdV9zaG9ydCwgY29uc3QgY2hhciAqKTsKICAqIHN0YXRpYyBpbnQgY3JlYXRlX3YyX3RyYXBfc2Vzc2lvbiAoY29uc3QgY2hhciAqLCB1X3Nob3J0LCBjb25zdCBjaGFyICopOwogICogc3RhdGljIGludCBjcmVhdGVfdjJfaW5mb3JtX3Nlc3Npb24gKGNvbnN0IGNoYXIgKiwgdV9zaG9ydCwgY29uc3QgY2hhciAqKTsKICAqIHN0YXRpYyB2b2lkIGZyZWVfdHJhcF9zZXNzaW9uIChzdHJ1Y3QgdHJhcF9zaW5rICpzcCk7CiAgKiBzdGF0aWMgdm9pZCBzZW5kX3YxX3RyYXAgKG5ldHNubXBfc2Vzc2lvbiAqLCBpbnQsIGludCk7CiAgKiBzdGF0aWMgdm9pZCBzZW5kX3YyX3RyYXAgKG5ldHNubXBfc2Vzc2lvbiAqLCBpbnQsIGludCwgaW50KTsKICAqLwoKCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioKCSAqCgkgKiBUcmFwIHNlc3Npb24gaGFuZGxpbmcKCSAqCgkgKioqKioqKioqKioqKioqKioqKi8KCnZvaWQKaW5pdF90cmFwcyh2b2lkKQp7CiAgICBlbnRlcnByaXNldHJhcF9sZW4gID0gT0lEX0xFTkdUSChvYmppZF9lbnRlcnByaXNldHJhcCk7CiAgICB0cmFwX3ZlcnNpb25faWRfbGVuID0gT0lEX0xFTkdUSCh0cmFwX3ZlcnNpb25faWQpOwogICAgc25tcHRyYXBfb2lkX2xlbiAgICA9IE9JRF9MRU5HVEgoc25tcHRyYXBfb2lkKTsKICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWRfbGVuID0gT0lEX0xFTkdUSChzbm1wdHJhcGVudGVycHJpc2Vfb2lkKTsKICAgIHN5c3VwdGltZV9vaWRfbGVuICAgPSBPSURfTEVOR1RIKHN5c3VwdGltZV9vaWQpOwogICAgYWdlbnRhZGRyX29pZF9sZW4gICA9IE9JRF9MRU5HVEgoYWdlbnRhZGRyX29pZCk7CiAgICBjb21tdW5pdHlfb2lkX2xlbiAgID0gT0lEX0xFTkdUSChjb21tdW5pdHlfb2lkKTsKfQoKc3RhdGljIHZvaWQKZnJlZV90cmFwX3Nlc3Npb24oc3RydWN0IHRyYXBfc2luayAqc3ApCnsKICAgIHNubXBfY2xvc2Uoc3AtPnNlc3ApOwogICAgZnJlZShzcCk7Cn0KCmludAphZGRfdHJhcF9zZXNzaW9uKG5ldHNubXBfc2Vzc2lvbiAqIHNzLCBpbnQgcGR1dHlwZSwgaW50IGNvbmZpcm0sCiAgICAgICAgICAgICAgICAgaW50IHZlcnNpb24pCnsKICAgIGlmIChzbm1wX2NhbGxiYWNrX2F2YWlsYWJsZShTTk1QX0NBTExCQUNLX0FQUExJQ0FUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBEX0NBTExCQUNLX1JFR0lTVEVSX05PVElGSUNBVElPTlMpID09CiAgICAgICAgU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBzb21ldGhpbmcgZWxzZSB3YW50cyB0byBoYW5kbGUgbm90aWZpY2F0aW9uIHJlZ2lzdHJhdGlvbnMgCiAgICAgICAgICovCiAgICAgICAgc3RydWN0IGFnZW50X2FkZF90cmFwX2FyZ3MgYXJnczsKICAgICAgICBERUJVR01TR1RMKCgidHJhcCIsICJhZGRpbmcgY2FsbGJhY2sgdHJhcCBzaW5rXG4iKSk7CiAgICAgICAgYXJncy5zcyA9IHNzOwogICAgICAgIGFyZ3MuY29uZmlybSA9IGNvbmZpcm07CiAgICAgICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0FQUExJQ0FUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUERfQ0FMTEJBQ0tfUkVHSVNURVJfTk9USUZJQ0FUSU9OUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopICZhcmdzKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiBubyBvdGhlciBzdXBwb3J0IGV4aXN0cywgaGFuZGxlIGl0IG91cnNlbHZlcy4gCiAgICAgICAgICovCiAgICAgICAgc3RydWN0IHRyYXBfc2luayAqbmV3X3Npbms7CgogICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgImFkZGluZyBpbnRlcm5hbCB0cmFwIHNpbmtcbiIpKTsKICAgICAgICBuZXdfc2luayA9IChzdHJ1Y3QgdHJhcF9zaW5rICopIG1hbGxvYyhzaXplb2YoKm5ld19zaW5rKSk7CiAgICAgICAgaWYgKG5ld19zaW5rID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAwOwoKICAgICAgICBuZXdfc2luay0+c2VzcCA9IHNzOwogICAgICAgIG5ld19zaW5rLT5wZHV0eXBlID0gcGR1dHlwZTsKICAgICAgICBuZXdfc2luay0+dmVyc2lvbiA9IHZlcnNpb247CiAgICAgICAgbmV3X3NpbmstPm5leHQgPSBzaW5rczsKICAgICAgICBzaW5rcyA9IG5ld19zaW5rOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCmludApyZW1vdmVfdHJhcF9zZXNzaW9uKG5ldHNubXBfc2Vzc2lvbiAqIHNzKQp7CiAgICBzdHJ1Y3QgdHJhcF9zaW5rICpzcCA9IHNpbmtzLCAqcHJldiA9IDA7CgogICAgd2hpbGUgKHNwKSB7CiAgICAgICAgaWYgKHNwLT5zZXNwID09IHNzKSB7CiAgICAgICAgICAgIGlmIChwcmV2KSB7CiAgICAgICAgICAgICAgICBwcmV2LT5uZXh0ID0gc3AtPm5leHQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzaW5rcyA9IHNwLT5uZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEkgZG9uJ3QgYmVsaWV2ZSB5b3UgKnJlYWxseSogd2FudCB0byBjbG9zZSB0aGUgc2Vzc2lvbiBoZXJlOwogICAgICAgICAgICAgKiBpdCBtYXkgc3RpbGwgYmUgaW4gdXNlIGZvciBvdGhlciBwdXJwb3Nlcy4gIEluIHBhcnRpY3VsYXIgdGhpcwogICAgICAgICAgICAgKiBpcyBhd2t3YXJkIGZvciBBZ2VudFgsIHNpbmNlIHdlIHdhbnQgdG8gY2FsbCB0aGlzIGZ1bmN0aW9uCiAgICAgICAgICAgICAqIGZyb20gdGhlIHNlc3Npb24ncyBjYWxsYmFjay4gIExldCdzIGp1c3QgZnJlZSB0aGUgdHJhcHNpbmsKICAgICAgICAgICAgICogZGF0YSBzdHJ1Y3R1cmUuICBbamJwbl0gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZnJlZV90cmFwX3Nlc3Npb24oc3ApOyAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmcmVlKHNwKTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgICAgIHByZXYgPSBzcDsKICAgICAgICBzcCA9IHNwLT5uZXh0OwogICAgfQogICAgcmV0dXJuIDA7Cn0KCiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKc3RhdGljIGludApjcmVhdGVfdHJhcF9zZXNzaW9uMihjb25zdCBjaGFyICpzaW5rLCBjb25zdCBjaGFyKiBzaW5rcG9ydCwKCQkgICAgIGNoYXIgKmNvbSwgaW50IHZlcnNpb24sIGludCBwZHV0eXBlKQp7CiAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdDsKICAgIG5ldHNubXBfc2Vzc2lvbiBzZXNzaW9uLCAqc2VzcDsKCiAgICBtZW1zZXQoJnNlc3Npb24sIDAsIHNpemVvZihuZXRzbm1wX3Nlc3Npb24pKTsKICAgIHNlc3Npb24udmVyc2lvbiA9IHZlcnNpb247CiAgICBpZiAoY29tKSB7CiAgICAgICAgc2Vzc2lvbi5jb21tdW5pdHkgPSAodV9jaGFyICopIGNvbTsKICAgICAgICBzZXNzaW9uLmNvbW11bml0eV9sZW4gPSBzdHJsZW4oY29tKTsKICAgIH0KCiAgICAvKgogICAgICogZm9yIGluZm9ybXMsIHNldCByZXRyaWVzIHRvIGRlZmF1bHQKICAgICAqLwogICAgaWYgKFNOTVBfTVNHX0lORk9STSA9PSBwZHV0eXBlKSB7CiAgICAgICAgc2Vzc2lvbi50aW1lb3V0ID0gU05NUF9ERUZBVUxUX1RJTUVPVVQ7CiAgICAgICAgc2Vzc2lvbi5yZXRyaWVzID0gU05NUF9ERUZBVUxUX1JFVFJJRVM7CiAgICB9CgogICAgLyoKICAgICAqIGlmIHRoZSBzaW5rIGlzIGxvY2FsaG9zdCwgYmluZCB0byBsb2NhbGhvc3QsIHRvIHJlZHVjZSBvcGVuIHBvcnRzLgogICAgICovCiAgICBpZiAoKE5VTEwgPT0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfQ0xJRU5UX0FERFIpKSAmJiAKICAgICAgICAoKDAgPT0gc3RyY21wKCJsb2NhbGhvc3QiLHNpbmspKSB8fCAoMCA9PSBzdHJjbXAoIjEyNy4wLjAuMSIsc2luaykpKSkKICAgICAgICBzZXNzaW9uLmxvY2FsbmFtZSA9IHN0cmR1cCgibG9jYWxob3N0Iik7CgogICAgdCA9IG5ldHNubXBfdGRvbWFpbl90cmFuc3BvcnRfZnVsbCgic25tcHRyYXAiLCBzaW5rLCAwLCBOVUxMLCBzaW5rcG9ydCk7CiAgICBpZiAodCAhPSBOVUxMKSB7CglzZXNwID0gc25tcF9hZGQoJnNlc3Npb24sIHQsIE5VTEwsIE5VTEwpOwoKCWlmIChzZXNwKSB7CgkgICAgcmV0dXJuIGFkZF90cmFwX3Nlc3Npb24oc2VzcCwgcGR1dHlwZSwKCQkJCSAgICAocGR1dHlwZSA9PSBTTk1QX01TR19JTkZPUk0pLCB2ZXJzaW9uKTsKCX0KICAgIH0KICAgIC8qCiAgICAgKiBkaWFnbm9zZSBzbm1wX29wZW4gZXJyb3JzIHdpdGggdGhlIGlucHV0IG5ldHNubXBfc2Vzc2lvbiBwb2ludGVyIAogICAgICovCiAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wZDogY3JlYXRlX3RyYXBfc2Vzc2lvbiIsICZzZXNzaW9uKTsKICAgIHJldHVybiAwOwp9CgppbnQKY3JlYXRlX3RyYXBfc2Vzc2lvbihjaGFyICpzaW5rLCB1X3Nob3J0IHNpbmtwb3J0LAoJCSAgICBjaGFyICpjb20sIGludCB2ZXJzaW9uLCBpbnQgcGR1dHlwZSkKewogICAgY2hhciBidWZbc2l6ZW9mKHNpbmtwb3J0KSAqIDMgKyAyXTsKICAgIGlmIChzaW5rcG9ydCAhPSAwKSB7CglzcHJpbnRmKGJ1ZiwgIjolaHUiLCBzaW5rcG9ydCk7Cglzbm1wX2xvZyhMT0dfTk9USUNFLAoJCSAiVXNpbmcgYSBzZXBhcmF0ZSBwb3J0IG51bWJlciBpcyBkZXByZWNhdGVkLCBwbGVhc2UgY29ycmVjdCAiCgkJICJ0aGUgc2luayBzcGVjaWZpY2F0aW9uIGluc3RlYWQiKTsKICAgIH0KICAgIHJldHVybiBjcmVhdGVfdHJhcF9zZXNzaW9uMihzaW5rLCBzaW5rcG9ydCA/IGJ1ZiA6IE5VTEwsIGNvbSwgdmVyc2lvbiwKCQkJCXBkdXR5cGUpOwp9CgojZW5kaWYgLyogc3VwcG9ydCBmb3IgY29tbXVuaXR5IGJhc2VkIFNOTVAgKi8KCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQpzdGF0aWMgaW50CmNyZWF0ZV92MV90cmFwX3Nlc3Npb24oY2hhciAqc2luaywgY29uc3QgY2hhciAqc2lua3BvcnQsIGNoYXIgKmNvbSkKewogICAgcmV0dXJuIGNyZWF0ZV90cmFwX3Nlc3Npb24yKHNpbmssIHNpbmtwb3J0LCBjb20sCgkJCQlTTk1QX1ZFUlNJT05fMSwgU05NUF9NU0dfVFJBUCk7Cn0KI2VuZGlmCgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDCnN0YXRpYyBpbnQKY3JlYXRlX3YyX3RyYXBfc2Vzc2lvbihjb25zdCBjaGFyICpzaW5rLCBjb25zdCBjaGFyICpzaW5rcG9ydCwgY2hhciAqY29tKQp7CiAgICByZXR1cm4gY3JlYXRlX3RyYXBfc2Vzc2lvbjIoc2luaywgc2lua3BvcnQsIGNvbSwKCQkJCVNOTVBfVkVSU0lPTl8yYywgU05NUF9NU0dfVFJBUDIpOwp9CgpzdGF0aWMgaW50CmNyZWF0ZV92Ml9pbmZvcm1fc2Vzc2lvbihjb25zdCBjaGFyICpzaW5rLCBjb25zdCBjaGFyICpzaW5rcG9ydCwgY2hhciAqY29tKQp7CiAgICByZXR1cm4gY3JlYXRlX3RyYXBfc2Vzc2lvbjIoc2luaywgc2lua3BvcnQsIGNvbSwKCQkJCVNOTVBfVkVSU0lPTl8yYywgU05NUF9NU0dfSU5GT1JNKTsKfQojZW5kaWYKCnZvaWQKc25tcGRfZnJlZV90cmFwc2lua3Modm9pZCkKewogICAgc3RydWN0IHRyYXBfc2luayAqc3AgPSBzaW5rczsKICAgIHdoaWxlIChzcCkgewogICAgICAgIHNpbmtzID0gc2lua3MtPm5leHQ7CiAgICAgICAgZnJlZV90cmFwX3Nlc3Npb24oc3ApOwogICAgICAgIHNwID0gc2lua3M7CiAgICB9Cn0KCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioKCSAqCgkgKiBUcmFwIGhhbmRsaW5nCgkgKgoJICoqKioqKioqKioqKioqKioqKiovCgoKbmV0c25tcF9wZHUqCmNvbnZlcnRfdjJwZHVfdG9fdjEoIG5ldHNubXBfcGR1KiB0ZW1wbGF0ZV92MnBkdSApCnsKICAgIG5ldHNubXBfcGR1ICAgICAgICAgICAqdGVtcGxhdGVfdjFwZHU7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmZpcnN0X3ZiLCAqdmJsaXN0OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CiAgICBzaXplX3QgICAgICAgICAgICAgICAgIGxlbjsKCiAgICAvKgogICAgICogTWFrZSBhIGNvcHkgb2YgdGhlIHYyIFRyYXAgUERVCiAgICAgKiAgIGJlZm9yZSBzdGFydGluZyB0byBjb252ZXJ0IHRoaXMKICAgICAqICAgaW50byBhIHYxIFRyYXAgUERVLgogICAgICovCiAgICB0ZW1wbGF0ZV92MXBkdSA9IHNubXBfY2xvbmVfcGR1KCB0ZW1wbGF0ZV92MnBkdSk7CiAgICBpZiAoIXRlbXBsYXRlX3YxcGR1KSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvcHkgdjEgdGVtcGxhdGUgUERVXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHRlbXBsYXRlX3YxcGR1LT5jb21tYW5kID0gU05NUF9NU0dfVFJBUDsKICAgIGZpcnN0X3ZiID0gdGVtcGxhdGVfdjFwZHUtPnZhcmlhYmxlczsKICAgIHZibGlzdCAgID0gdGVtcGxhdGVfdjFwZHUtPnZhcmlhYmxlczsKCiAgICAvKgogICAgICogVGhlIGZpcnN0IHZhcmJpbmQgc2hvdWxkIGJlIHRoZSBzeXN0ZW0gdXB0aW1lLgogICAgICovCiAgICBpZiAoIXZibGlzdCB8fAogICAgICAgIHNubXBfb2lkX2NvbXBhcmUodmJsaXN0LT5uYW1lLCAgdmJsaXN0LT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3VwdGltZV9vaWQsIHN5c3VwdGltZV9vaWRfbGVuKSkgewogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IG5vIHYyIHN5c1VwdGltZSB2YXJiaW5kIHRvIHNldCBmcm9tXG4iKTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHRlbXBsYXRlX3YxcGR1LT50aW1lID0gKnZibGlzdC0+dmFsLmludGVnZXI7CiAgICB2Ymxpc3QgPSB2Ymxpc3QtPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgIAogICAgLyoKICAgICAqIFRoZSBzZWNvbmQgdmFyYmluZCBzaG91bGQgYmUgdGhlIHNubXBUcmFwT0lELgogICAgICovCiAgICBpZiAoIXZibGlzdCB8fAogICAgICAgIHNubXBfb2lkX2NvbXBhcmUodmJsaXN0LT5uYW1lLCB2Ymxpc3QtPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBfb2lkLCBzbm1wdHJhcF9vaWRfbGVuKSkgewogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IG5vIHYyIHRyYXBPSUQgdmFyYmluZCB0byBzZXQgZnJvbVxuIik7CiAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyoKICAgICAqIENoZWNrIHRoZSB2MiB2YXJiaW5kIGxpc3QgZm9yIGFueSB2YXJiaW5kcwogICAgICogIHRoYXQgYXJlIG5vdCB2YWxpZCBpbiBhbiBTTk1QdjEgdHJhcC4KICAgICAqICBUaGlzIGJhc2ljYWxseSBtZWFucyBDb3VudGVyNjQgdmFsdWVzLgogICAgICoKICAgICAqIFJGQyAyMDg5IHNhaWQgdG8gb21pdCBzdWNoIHZhcmJpbmRzIGZyb20gdGhlIGxpc3QuCiAgICAgKiBSRkMgMjU3Ni8zNTg0IHNheSB0byBkcm9wIHRoZSB0cmFwIGNvbXBsZXRlbHkuCiAgICAgKi8KICAgIGZvciAodmFyID0gdmJsaXN0LT5uZXh0X3ZhcmlhYmxlOyB2YXI7IHZhciA9IHZhci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgIGlmICggdmFyLT50eXBlID09IEFTTl9DT1VOVEVSNjQgKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiB2MSB0cmFwcyBjYW4ndCBjYXJyeSBDb3VudGVyNjQgdmFyYmluZHNcbiIpOwogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBTZXQgdGhlIGdlbmVyaWMgJiBzcGVjaWZpYyB0cmFwIHR5cGVzLAogICAgICogICAgYW5kIHRoZSBlbnRlcnByaXNlIGZpZWxkIGZyb20gdGhlIHYyIHZhcmJpbmQgbGlzdC4KICAgICAqIElmIHRoZXJlJ3MgYW4gYWdlbnRJUEFkZHJlc3MgdmFyYmluZCwgc2V0IHRoZSBhZ2VudF9hZGRyIHRvbwogICAgICovCiAgICBpZiAoIXNubXBfb2lkX2NvbXBhcmUodmJsaXN0LT52YWwub2JqaWQsIE9JRF9MRU5HVEgodHJhcF9wcmVmaXgpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHRyYXBfcHJlZml4LCAgICAgICBPSURfTEVOR1RIKHRyYXBfcHJlZml4KSkpIHsKICAgICAgICAvKgogICAgICAgICAqIEZvciAnc3RhbmRhcmQnIHRyYXBzLCBleHRyYWN0IHRoZSBnZW5lcmljIHRyYXAgdHlwZQogICAgICAgICAqICAgZnJvbSB0aGUgc25tcFRyYXBPSUQgdmFsdWUsIGFuZCB0YWtlIHRoZSBlbnRlcnByaXNlCiAgICAgICAgICogICB2YWx1ZSBmcm9tIHRoZSAnc25tcEVudGVycHJpc2UnIHZhcmJpbmQuCiAgICAgICAgICovCiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPnRyYXBfdHlwZSA9CiAgICAgICAgICAgIHZibGlzdC0+dmFsLm9iamlkW09JRF9MRU5HVEgodHJhcF9wcmVmaXgpXSAtIDE7CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPnNwZWNpZmljX3R5cGUgPSAwOwoKICAgICAgICB2YXIgPSBmaW5kX3ZhcmJpbmRfaW5fbGlzdCggdmJsaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4pOwogICAgICAgIGlmICh2YXIpIHsKICAgICAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UgPQogICAgICAgICAgICAgICAgbmV0c25tcF9tZW1kdXAodmFyLT52YWwub2JqaWQsIHZhci0+dmFsX2xlbik7CiAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9IHZhci0+dmFsX2xlbi9zaXplb2Yob2lkKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZSAgICAgICAgPSBOVUxMOwogICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGggPSAwOwkJLyogWFhYID8/PyAqLwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiBGb3IgZW50ZXJwcmlzZS1zcGVjaWZpYyB0cmFwcywgc3BsaXQgdGhlIHNubXBUcmFwT0lEIHZhbHVlCiAgICAgICAgICogICBpbnRvIGVudGVycHJpc2UgYW5kIHNwZWNpZmljIHRyYXAKICAgICAgICAgKi8KICAgICAgICBsZW4gPSB2Ymxpc3QtPnZhbF9sZW4gLyBzaXplb2Yob2lkKTsKICAgICAgICBpZiAoIGxlbiA8PSAyICkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogdjIgdHJhcE9JRCB0b28gc2hvcnQgKCVkKVxuIiwgKGludClsZW4pOwogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUgICAgID0gU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQzsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+c3BlY2lmaWNfdHlwZSA9IHZibGlzdC0+dmFsLm9iamlkW2xlbiAtIDFdOwogICAgICAgIGxlbi0tOwogICAgICAgIGlmICh2Ymxpc3QtPnZhbC5vYmppZFtsZW4tMV0gPT0gMCkKICAgICAgICAgICAgbGVuLS07CiAgICAgICAgU05NUF9GUkVFKHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlKTsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZSA9CiAgICAgICAgICAgIG5ldHNubXBfbWVtZHVwKHZibGlzdC0+dmFsLm9iamlkLCBsZW4qc2l6ZW9mKG9pZCkpOwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9IGxlbjsKICAgIH0KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB2Ymxpc3QsIGFnZW50YWRkcl9vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2VudGFkZHJfb2lkX2xlbik7CiAgICBpZiAodmFyKSB7CiAgICAgICAgbWVtY3B5KHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyLAogICAgICAgICAgICAgICB2YXItPnZhbC5zdHJpbmcsIDQpOwogICAgfQoKICAgIC8qCiAgICAgKiBUaGUgcmVtYWluZGVyIG9mIHRoZSB2MiB2YXJiaW5kIGxpc3QgaXMga2VwdAogICAgICogYXMgdGhlIHYyIHZhcmJpbmQgbGlzdC4gIFVwZGF0ZSB0aGUgUERVIGFuZAogICAgICogZnJlZSB0aGUgdHdvIHJlZHVuZGFudCB2YXJiaW5kcy4KICAgICAqLwogICAgdGVtcGxhdGVfdjFwZHUtPnZhcmlhYmxlcyA9IHZibGlzdC0+bmV4dF92YXJpYWJsZTsKICAgIHZibGlzdC0+bmV4dF92YXJpYWJsZSA9IE5VTEw7CiAgICBzbm1wX2ZyZWVfdmFyYmluZCggZmlyc3RfdmIgKTsKICAgICAgICAgICAgCiAgICByZXR1cm4gdGVtcGxhdGVfdjFwZHU7Cn0KCm5ldHNubXBfcGR1Kgpjb252ZXJ0X3YxcGR1X3RvX3YyKCBuZXRzbm1wX3BkdSogdGVtcGxhdGVfdjFwZHUgKQp7CiAgICBuZXRzbm1wX3BkdSAgICAgICAgICAgKnRlbXBsYXRlX3YycGR1OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CiAgICBvaWQgICAgICAgICAgICAgICAgICAgIGVudGVycHJpc2VbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgICAgICAgICBlbnRlcnByaXNlX2xlbjsKCiAgICAvKgogICAgICogTWFrZSBhIGNvcHkgb2YgdGhlIHYxIFRyYXAgUERVCiAgICAgKiAgIGJlZm9yZSBzdGFydGluZyB0byBjb252ZXJ0IHRoaXMKICAgICAqICAgaW50byBhIHYyIFRyYXAgUERVLgogICAgICovCiAgICB0ZW1wbGF0ZV92MnBkdSA9IHNubXBfY2xvbmVfcGR1KCB0ZW1wbGF0ZV92MXBkdSk7CiAgICBpZiAoIXRlbXBsYXRlX3YycGR1KSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvcHkgdjIgdGVtcGxhdGUgUERVXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHRlbXBsYXRlX3YycGR1LT5jb21tYW5kID0gU05NUF9NU0dfVFJBUDI7CgogICAgLyoKICAgICAqIEluc2VydCBhbiBzbm1wVHJhcE9JRCB2YXJiaW5kIGJlZm9yZSB0aGUgb3JpZ2luYWwgdjEgdmFyYmluZCBsaXN0CiAgICAgKiAgIGVpdGhlciB1c2luZyBvbmUgb2YgdGhlIHN0YW5kYXJkIGRlZmluZWQgdHJhcCBPSURzLAogICAgICogICBvciBjb25zdHJ1Y3RpbmcgdGhpcyBmcm9tIHRoZSBQRFUgZW50ZXJwcmlzZSAmIHNwZWNpZmljIHRyYXAgZmllbGRzCiAgICAgKi8KICAgIGlmICh0ZW1wbGF0ZV92MXBkdS0+dHJhcF90eXBlID09IFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMpIHsKICAgICAgICBtZW1jcHkoZW50ZXJwcmlzZSwgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCpzaXplb2Yob2lkKSk7CiAgICAgICAgZW50ZXJwcmlzZV9sZW4gICAgICAgICAgICAgICA9IHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aDsKICAgICAgICBlbnRlcnByaXNlW2VudGVycHJpc2VfbGVuKytdID0gMDsKICAgICAgICBlbnRlcnByaXNlW2VudGVycHJpc2VfbGVuKytdID0gdGVtcGxhdGVfdjFwZHUtPnNwZWNpZmljX3R5cGU7CiAgICB9IGVsc2UgewogICAgICAgIG1lbWNweShlbnRlcnByaXNlLCBjb2xkX3N0YXJ0X29pZCwgc2l6ZW9mKGNvbGRfc3RhcnRfb2lkKSk7CgllbnRlcnByaXNlWzldICA9IHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUrMTsKICAgICAgICBlbnRlcnByaXNlX2xlbiA9IHNpemVvZihjb2xkX3N0YXJ0X29pZCkvc2l6ZW9mKG9pZCk7CiAgICB9CgogICAgdmFyID0gTlVMTDsKICAgIGlmICghc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJnZhciwKICAgICAgICAgICAgIHNubXB0cmFwX29pZCwgc25tcHRyYXBfb2lkX2xlbiwKICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQsCiAgICAgICAgICAgICAodV9jaGFyKillbnRlcnByaXNlLCBlbnRlcnByaXNlX2xlbipzaXplb2Yob2lkKSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gaW5zZXJ0IGNvcGllZCBzbm1wVHJhcE9JRCB2YXJiaW5kXG4iKTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHZhci0+bmV4dF92YXJpYWJsZSAgICAgICAgPSB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzOwogICAgdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyA9IHZhcjsKCiAgICAvKgogICAgICogSW5zZXJ0IGEgc3lzVXB0aW1lIHZhcmJpbmQgYXQgdGhlIGhlYWQgb2YgdGhlIHYyIHZhcmJpbmQgbGlzdAogICAgICovCiAgICB2YXIgPSBOVUxMOwogICAgaWYgKCFzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCAmdmFyLAogICAgICAgICAgICAgc3lzdXB0aW1lX29pZCwgc3lzdXB0aW1lX29pZF9sZW4sCiAgICAgICAgICAgICBBU05fVElNRVRJQ0tTLAogICAgICAgICAgICAgKHVfY2hhciopJih0ZW1wbGF0ZV92MXBkdS0+dGltZSksIAogICAgICAgICAgICAgc2l6ZW9mKHRlbXBsYXRlX3YxcGR1LT50aW1lKSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gaW5zZXJ0IGNvcGllZCBzeXNVcHRpbWUgdmFyYmluZFxuIik7CiAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB2YXItPm5leHRfdmFyaWFibGUgICAgICAgID0gdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlczsKICAgIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMgPSB2YXI7CgogICAgLyoKICAgICAqIEFwcGVuZCB0aGUgb3RoZXIgdGhyZWUgY29udmVyc2lvbiB2YXJiaW5kcywKICAgICAqICAoc25tcFRyYXBBZ2VudEFkZHIsIHNubXBUcmFwQ29tbXVuaXR5ICYgc25tcFRyYXBFbnRlcnByaXNlKQogICAgICogIGlmIHRoZXkncmUgbm90IGFscmVhZHkgcHJlc2VudC4KICAgICAqICBCdXQgZG9uJ3QgYm9tYiBvdXQgY29tcGxldGVseSBpZiB0aGVyZSBhcmUgcHJvYmxlbXMuCiAgICAgKi8KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZW50YWRkcl9vaWQsIGFnZW50YWRkcl9vaWRfbGVuKTsKICAgIGlmICghdmFyICYmICh0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkclswXQogICAgICAgICAgICAgIHx8IHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyWzFdCiAgICAgICAgICAgICAgfHwgdGVtcGxhdGVfdjFwZHUtPmFnZW50X2FkZHJbMl0KICAgICAgICAgICAgICB8fCB0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkclszXSkpIHsKICAgICAgICBpZiAoIXNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICYodGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyksCiAgICAgICAgICAgICAgICAgYWdlbnRhZGRyX29pZCwgYWdlbnRhZGRyX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgQVNOX0lQQUREUkVTUywKICAgICAgICAgICAgICAgICAodV9jaGFyKikmKHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyKSwgCiAgICAgICAgICAgICAgICAgc2l6ZW9mKHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyKSkpCiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBhcHBlbmQgc25tcFRyYXBBZGRyIHZhcmJpbmRcbiIpOwogICAgfQogICAgdmFyID0gZmluZF92YXJiaW5kX2luX2xpc3QoIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbXVuaXR5X29pZCwgY29tbXVuaXR5X29pZF9sZW4pOwogICAgaWYgKCF2YXIgJiYgdGVtcGxhdGVfdjFwZHUtPmNvbW11bml0eSkgewogICAgICAgIGlmICghc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJih0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzKSwKICAgICAgICAgICAgICAgICBjb21tdW5pdHlfb2lkLCBjb21tdW5pdHlfb2lkX2xlbiwKICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSLAogICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5jb21tdW5pdHksIAogICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5jb21tdW5pdHlfbGVuKSkKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGFwcGVuZCBzbm1wVHJhcENvbW11bml0eSB2YXJiaW5kXG4iKTsKICAgIH0KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4pOwogICAgaWYgKCF2YXIpIHsKICAgICAgICBpZiAoIXNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICYodGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyksCiAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZCwgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgICAodV9jaGFyKil0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZSwgCiAgICAgICAgICAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2VfbGVuZ3RoKnNpemVvZihvaWQpKSkKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGFwcGVuZCBzbm1wRW50ZXJwcmlzZSB2YXJiaW5kXG4iKTsKICAgIH0KICAgIHJldHVybiB0ZW1wbGF0ZV92MnBkdTsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gYWxsb3dzIHlvdSB0byBtYWtlIGEgZGlzdGluY3Rpb24gYmV0d2VlbiBnZW5lcmljIAogKiB0cmFwcyBmcm9tIGRpZmZlcmVudCBjbGFzc2VzIG9mIGVxdWlwbWVudC4gRm9yIGV4YW1wbGUsIHlvdSBtYXkgd2FudCAKICogdG8gaGFuZGxlIGEgU05NUF9UUkFQX0xJTktET1dOIHRyYXAgZm9yIGEgcGFydGljdWxhciBkZXZpY2UgaW4gYSAKICogZGlmZmVyZW50IG1hbm5lciB0byBhIGdlbmVyaWMgc3lzdGVtIFNOTVBfVFJBUF9MSU5LRE9XTiB0cmFwLgogKiAgIAogKgogKiBAcGFyYW0gdHJhcCBpcyB0aGUgZ2VuZXJpYyB0cmFwIHR5cGUuICBUaGUgdHJhcCB0eXBlcyBhcmU6CiAqCQktIFNOTVBfVFJBUF9DT0xEU1RBUlQ6CiAqCQkJY29sZCBzdGFydAogKgkJLSBTTk1QX1RSQVBfV0FSTVNUQVJUOgogKgkJCXdhcm0gc3RhcnQKICoJCS0gU05NUF9UUkFQX0xJTktET1dOOgogKgkJCWxpbmsgZG93bgogKgkJLSBTTk1QX1RSQVBfTElOS1VQOgogKgkJCWxpbmsgdXAKICoJCS0gU05NUF9UUkFQX0FVVEhGQUlMOgogKgkJCWF1dGhlbnRpY2F0aW9uIGZhaWx1cmUKICoJCS0gU05NUF9UUkFQX0VHUE5FSUdIQk9STE9TUzoKICoJCQllZ3AgbmVpZ2hib3IgbG9zcwogKgkJLSBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDOgogKgkJCWVudGVycHJpc2Ugc3BlY2lmaWMKICoJCQkKICogQHBhcmFtIHNwZWNpZmljIGlzIHRoZSBzcGVjaWZpYyB0cmFwIHZhbHVlLgogKgogKiBAcGFyYW0gZW50ZXJwcmlzZSBpcyBhbiBlbnRlcnByaXNlIG9pZCBpbiB3aGljaCB5b3Ugd2FudCB0byBzZW5kIHNwZWNpZmljIAogKgl0cmFwcyBmcm9tLiAKICoKICogQHBhcmFtIGVudGVycHJpc2VfbGVuZ3RoIGlzIHRoZSBsZW5ndGggb2YgdGhlIGVudGVycHJpc2Ugb2lkLCB1c2UgbWFjcm8sCiAqCU9JRF9MRU5HVEgsIHRvIGNvbXB1dGUgbGVuZ3RoLgogKgogKiBAcGFyYW0gdmFycyBpcyB1c2VkIHRvIHN1cHBseSBsaXN0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIHRvIGZvcm0gYW4gU05NUHYyIAogKgl0cmFwLgogKgogKiBAcGFyYW0gY29udGV4dCBjdXJyZW50bHkgdW51c2VkIAogKgogKiBAcGFyYW0gZmxhZ3MgY3VycmVudGx5IHVudXNlZCAKICoKICogQHJldHVybiB2b2lkCiAqCiAqIEBzZWUgc2VuZF9lYXN5X3RyYXAKICogQHNlZSBzZW5kX3YydHJhcAogKi8KaW50Cm5ldHNubXBfc2VuZF90cmFwcyhpbnQgdHJhcCwgaW50IHNwZWNpZmljLAogICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqIGVudGVycHJpc2UsIGludCBlbnRlcnByaXNlX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiB2YXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKiBjb250ZXh0LCBpbnQgZmxhZ3MpCnsKICAgIG5ldHNubXBfcGR1ICAgICAgICAgICAqdGVtcGxhdGVfdjFwZHU7CiAgICBuZXRzbm1wX3BkdSAgICAgICAgICAgKnRlbXBsYXRlX3YycGR1OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2Ymxpc3QgPSBOVUxMOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp0cmFwX3ZiOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CiAgICBpbl9hZGRyX3QgICAgICAgICAgICAgKnBkdV9pbl9hZGRyX3Q7CiAgICB1X2xvbmcgICAgICAgICAgICAgICAgIHVwdGltZTsKICAgIHN0cnVjdCB0cmFwX3NpbmsgKnNpbms7CgogICAgREVCVUdNU0dUTCgoICJ0cmFwIiwgInNlbmRfdHJhcCAlZCAlZCAiLCB0cmFwLCBzcGVjaWZpYykpOwogICAgREVCVUdNU0dPSUQoKCJ0cmFwIiwgZW50ZXJwcmlzZSwgZW50ZXJwcmlzZV9sZW5ndGgpKTsKICAgIERFQlVHTVNHKCggInRyYXAiLCAiXG4iKSk7CgogICAgaWYgKHZhcnMpIHsKICAgICAgICB2Ymxpc3QgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoIHZhcnMgKTsKICAgICAgICBpZiAoIXZibGlzdCkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNsb25lIHZhcmJpbmQgbGlzdFxuIik7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCB0cmFwID09IC0xICkgewogICAgICAgIC8qCiAgICAgICAgICogQ29uc3RydWN0IHRoZSBTTk1QdjItc3R5bGUgbm90aWZpY2F0aW9uIFBEVQogICAgICAgICAqLwogICAgICAgIGlmICghdmJsaXN0KSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBjYWxsZWQgd2l0aCBOVUxMIHYyIGluZm9ybWF0aW9uXG4iKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICB0ZW1wbGF0ZV92MnBkdSA9IHNubXBfcGR1X2NyZWF0ZShTTk1QX01TR19UUkFQMik7CiAgICAgICAgaWYgKCF0ZW1wbGF0ZV92MnBkdSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvbnN0cnVjdCB2MiB0ZW1wbGF0ZSBQRFVcbiIpOwogICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2Ymxpc3QpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIENoZWNrIHRoZSB2YXJiaW5kIGxpc3Qgd2UndmUgYmVlbiBnaXZlbi4KICAgICAgICAgKiBJZiBpdCBzdGFydHMgd2l0aCBhICdzeXNVcHRpbWUuMCcgdmFyYmluZCwgdGhlbiB1c2UgdGhhdC4KICAgICAgICAgKiBPdGhlcndpc2UsIHByZXBlbmQgYSBzdWl0YWJsZSAnc3lzVXB0aW1lLjAnIHZhcmJpbmQuCiAgICAgICAgICovCiAgICAgICAgaWYgKCFzbm1wX29pZF9jb21wYXJlKCB2Ymxpc3QtPm5hbWUsICAgIHZibGlzdC0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN1cHRpbWVfb2lkLCBzeXN1cHRpbWVfb2lkX2xlbiApKSB7CiAgICAgICAgICAgIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMgPSB2Ymxpc3Q7CiAgICAgICAgICAgIHRyYXBfdmIgID0gdmJsaXN0LT5uZXh0X3ZhcmlhYmxlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHVwdGltZSAgID0gbmV0c25tcF9nZXRfYWdlbnRfdXB0aW1lKCk7CiAgICAgICAgICAgIHZhciA9IE5VTEw7CiAgICAgICAgICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICZ2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3VwdGltZV9vaWQsIHN5c3VwdGltZV9vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fVElNRVRJQ0tTLCAodV9jaGFyKikmdXB0aW1lLCBzaXplb2YodXB0aW1lKSk7CiAgICAgICAgICAgIGlmICghdmFyKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGluc2VydCBzeXNVcHRpbWUgdmFyYmluZFxuIik7CiAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHZibGlzdCk7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyA9IHZhcjsKICAgICAgICAgICAgdmFyLT5uZXh0X3ZhcmlhYmxlICAgICAgICA9IHZibGlzdDsKICAgICAgICAgICAgdHJhcF92YiAgPSB2Ymxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqICd0cmFwX3ZiJyBzaG91bGQgcG9pbnQgdG8gdGhlIHNubXBUcmFwT0lELjAgdmFyYmluZCwKICAgICAgICAgKiAgIGlkZW50aWZ5aW5nIHRoZSByZXF1ZXN0ZWQgdHJhcC4gIElmIG5vdCB0aGVuIGJvbWIgb3V0LgogICAgICAgICAqIElmIGl0J3MgYSAnc3RhbmRhcmQnIHRyYXAsIHRoZW4gd2UgbmVlZCB0byBhcHBlbmQgYW4KICAgICAgICAgKiAgIHNubXBFbnRlcnByaXNlIHZhcmJpbmQgKGlmIHRoZXJlIGlzbid0IGFscmVhZHkgb25lKS4KICAgICAgICAgKi8KICAgICAgICBpZiAoIXRyYXBfdmIgfHwKICAgICAgICAgICAgc25tcF9vaWRfY29tcGFyZSh0cmFwX3ZiLT5uYW1lLCB0cmFwX3ZiLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcF9vaWQsICBzbm1wdHJhcF9vaWRfbGVuKSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogbm8gdjIgdHJhcE9JRCB2YXJiaW5kIHByb3ZpZGVkXG4iKTsKICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzbm1wX29pZF9jb21wYXJlKHZibGlzdC0+dmFsLm9iamlkLCBPSURfTEVOR1RIKHRyYXBfcHJlZml4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhcF9wcmVmaXgsICAgICAgIE9JRF9MRU5HVEgodHJhcF9wcmVmaXgpKSkgewogICAgICAgICAgICB2YXIgPSBmaW5kX3ZhcmJpbmRfaW5fbGlzdCggdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkX2xlbik7CiAgICAgICAgICAgIGlmICghdmFyICYmCiAgICAgICAgICAgICAgICAhc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJih0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzKSwKICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZCwgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQsCiAgICAgICAgICAgICAgICAgICAgIChjaGFyKillbnRlcnByaXNlLCBlbnRlcnByaXNlX2xlbmd0aCpzaXplb2Yob2lkKSkpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gYWRkIHNubXBFbnRlcnByaXNlIHRvIHYyIHRyYXBcbiIpOwogICAgICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgIAoKICAgICAgICAvKgogICAgICAgICAqIElmIGV2ZXJ5dGhpbmcncyBPSywgY29udmVydCB0aGUgdjIgdGVtcGxhdGUgaW50byBhbiBTTk1QdjEgdHJhcCBQRFUuCiAgICAgICAgICovCiAgICAgICAgdGVtcGxhdGVfdjFwZHUgPSBjb252ZXJ0X3YycGR1X3RvX3YxKCB0ZW1wbGF0ZV92MnBkdSApOwogICAgICAgIGlmICghdGVtcGxhdGVfdjFwZHUpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBjb252ZXJ0IHYyLT52MSB0ZW1wbGF0ZSBQRFVcbiIpOwogICAgICAgIH0KCiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogQ29uc3RydWN0IHRoZSBTTk1QdjEgdHJhcCBQRFUuLi4uCiAgICAgICAgICovCiAgICAgICAgdGVtcGxhdGVfdjFwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfVFJBUCk7CiAgICAgICAgaWYgKCF0ZW1wbGF0ZV92MXBkdSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvbnN0cnVjdCB2MSB0ZW1wbGF0ZSBQRFVcbiIpOwogICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2Ymxpc3QpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUgICAgID0gdHJhcDsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+c3BlY2lmaWNfdHlwZSA9IHNwZWNpZmljOwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT50aW1lICAgICAgICAgID0gbmV0c25tcF9nZXRfYWdlbnRfdXB0aW1lKCk7CgogICAgICAgIGlmIChzbm1wX2Nsb25lX21lbSgodm9pZCAqKikgJnRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlLAogICAgICAgICAgICAgICAgICAgICAgIGVudGVycHJpc2UsIGVudGVycHJpc2VfbGVuZ3RoICogc2l6ZW9mKG9pZCkpKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gc2V0IHYxIGVudGVycHJpc2UgT0lEXG4iKTsKICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmJsaXN0KTsKICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2VfbGVuZ3RoID0gZW50ZXJwcmlzZV9sZW5ndGg7CgogICAgICAgIHRlbXBsYXRlX3YxcGR1LT5mbGFncyAgICB8PSBVQ0RfTVNHX0ZMQUdfRk9SQ0VfUERVX0NPUFk7CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPnZhcmlhYmxlcyA9IHZibGlzdDsKCiAgICAgICAgLyoKICAgICAgICAgKiAuLi4gYW5kIGNvbnZlcnQgaXQgaW50byBhbiBTTk1QdjItc3R5bGUgbm90aWZpY2F0aW9uIFBEVS4KICAgICAgICAgKi8KCiAgICAgICAgdGVtcGxhdGVfdjJwZHUgPSBjb252ZXJ0X3YxcGR1X3RvX3YyKCB0ZW1wbGF0ZV92MXBkdSApOwogICAgICAgIGlmICghdGVtcGxhdGVfdjJwZHUpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBjb252ZXJ0IHYxLT52MiB0ZW1wbGF0ZSBQRFVcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogQ2hlY2sgd2hldGhlciB3ZSdyZSBpZ25vcmluZyBhdXRoRmFpbCB0cmFwcwogICAgICovCiAgICBpZiAodGVtcGxhdGVfdjFwZHUpIHsKICAgICAgaWYgKHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUgPT0gU05NUF9UUkFQX0FVVEhGQUlMICYmCiAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwcyA9PSBTTk1QX0FVVEhFTlRJQ0FURURfVFJBUFNfRElTQUJMRUQpIHsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfQoKICAgIC8qCiAgICAgKiBFbnN1cmUgdGhhdCB0aGUgdjEgdHJhcCBQRFUgaW5jbHVkZXMgdGhlIGxvY2FsIElQIGFkZHJlc3MKICAgICAqLwogICAgICAgcGR1X2luX2FkZHJfdCA9IChpbl9hZGRyX3QgKikgdGVtcGxhdGVfdjFwZHUtPmFnZW50X2FkZHI7CiAgICAgICpwZHVfaW5fYWRkcl90ID0gZ2V0X215YWRkcigpOwogICAgfQoKCiAgICAvKgogICAgICogIE5vdyBsb29wIHRocm91Z2ggdGhlIGxpc3Qgb2YgdHJhcCBzaW5rcwogICAgICogICBhbmQgY2FsbCB0aGUgdHJhcCBjYWxsYmFjayByb3V0aW5lcywKICAgICAqICAgcHJvdmlkaW5nIGFuIGFwcHJvcHJpYXRlbHkgZm9ybWF0dGVkIFBEVSBpbiBlYWNoIGNhc2UKICAgICAqLwogICAgZm9yIChzaW5rID0gc2lua3M7IHNpbms7IHNpbmsgPSBzaW5rLT5uZXh0KSB7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgIGlmIChzaW5rLT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xKSB7CiAgICAgICAgICBpZiAodGVtcGxhdGVfdjFwZHUpIHsKICAgICAgICAgICAgc2VuZF90cmFwX3RvX3Nlc3Moc2luay0+c2VzcCwgdGVtcGxhdGVfdjFwZHUpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgaWYgKHRlbXBsYXRlX3YycGR1KSB7CiAgICAgICAgICAgIHRlbXBsYXRlX3YycGR1LT5jb21tYW5kID0gc2luay0+cGR1dHlwZTsKICAgICAgICAgICAgc2VuZF90cmFwX3RvX3Nlc3Moc2luay0+c2VzcCwgdGVtcGxhdGVfdjJwZHUpOwogICAgICAgICAgfQojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgICAgICB9CiNlbmRpZgogICAgfQogICAgaWYgKHRlbXBsYXRlX3YxcGR1KQogICAgICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19BUFBMSUNBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgU05NUERfQ0FMTEJBQ0tfU0VORF9UUkFQMSwgdGVtcGxhdGVfdjFwZHUpOwogICAgaWYgKHRlbXBsYXRlX3YycGR1KQogICAgICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19BUFBMSUNBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgU05NUERfQ0FMTEJBQ0tfU0VORF9UUkFQMiwgdGVtcGxhdGVfdjJwZHUpOwogICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgIHJldHVybiAwOwp9CgoKdm9pZApzZW5kX2VudGVycHJpc2VfdHJhcF92YXJzKGludCB0cmFwLAogICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzcGVjaWZpYywKICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiBlbnRlcnByaXNlLCBpbnQgZW50ZXJwcmlzZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICogdmFycykKewogICAgbmV0c25tcF9zZW5kX3RyYXBzKHRyYXAsIHNwZWNpZmljLAogICAgICAgICAgICAgICAgICAgICAgIGVudGVycHJpc2UsIGVudGVycHJpc2VfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgIHZhcnMsIE5VTEwsIDApOwogICAgcmV0dXJuOwp9CgovKioKICogQ2FwdHVyZXMgcmVzcG9uc2VzIG9yIHRoZSBsYWNrIHRoZXJlIG9mIGZyb20gSU5GT1JNcyB0aGF0IHdlcmUgc2VudAogKiAxKSBhIHJlc3BvbnNlIGlzIHJlY2VpdmVkIGZyb20gYW4gSU5GT1JNCiAqIDIpIG9uZSBpc24ndCByZWNlaXZlZCBhbmQgdGhlIHJldHJpZXMvdGltZW91dHMgaGF2ZSBmYWlsZWQKKi8KaW50CmhhbmRsZV9pbmZvcm1fcmVzcG9uc2UoaW50IG9wLCBuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLAogICAgICAgICAgICAgICAgICAgICAgIGludCByZXFpZCwgbmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgICAgICAgICAgICB2b2lkICptYWdpYykKewogICAgLyogWFhYOiBwb3NzaWJseSBzdGF0cyB1cGRhdGUgKi8KICAgIHN3aXRjaCAob3ApIHsKCiAgICBjYXNlIE5FVFNOTVBfQ0FMTEJBQ0tfT1BfUkVDRUlWRURfTUVTU0FHRToKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5QS1RTKTsKICAgICAgICBERUJVR01TR1RMKCgidHJhcCIsICJyZWNlaXZlZCB0aGUgaW5mb3JtIHJlc3BvbnNlIGZvciByZXFpZD0lZFxuIiwKICAgICAgICAgICAgICAgICAgICByZXFpZCkpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTkVUU05NUF9DQUxMQkFDS19PUF9USU1FRF9PVVQ6CiAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLAogICAgICAgICAgICAgICAgICAgICJyZWNlaXZlZCBhIHRpbWVvdXQgc2VuZGluZyBhbiBpbmZvcm0gZm9yIHJlcWlkPSVkXG4iLAogICAgICAgICAgICAgICAgICAgIHJlcWlkKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBORVRTTk1QX0NBTExCQUNLX09QX1NFTkRfRkFJTEVEOgogICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwKICAgICAgICAgICAgICAgICAgICAiZmFpbGVkIHRvIHNlbmQgYW4gaW5mb3JtIGZvciByZXFpZD0lZFxuIiwKICAgICAgICAgICAgICAgICAgICByZXFpZCkpOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLCAicmVjZWl2ZWQgb3A9JWQgZm9yIHJlcWlkPSVkIHdoZW4gdHJ5aW5nIHRvIHNlbmQgYW4gaW5mb3JtXG4iLCBvcCwgcmVxaWQpKTsKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKCi8qCiAqIHNlbmRfdHJhcF90b19zZXNzOiBzZW5kcyBhIHRyYXAgdG8gYSBzZXNzaW9uIGJ1dCBhc3N1bWVzIHRoYXQgdGhlCiAqIHBkdSBpcyBjb25zdHJ1Y3RlZCBjb3JyZWN0bHkgZm9yIHRoZSBzZXNzaW9uIHR5cGUuIAogKi8Kdm9pZApzZW5kX3RyYXBfdG9fc2VzcyhuZXRzbm1wX3Nlc3Npb24gKiBzZXNzLCBuZXRzbm1wX3BkdSAqdGVtcGxhdGVfcGR1KQp7CiAgICBuZXRzbm1wX3BkdSAgICAqcGR1OwogICAgaW50ICAgICAgICAgICAgcmVzdWx0OwogICAgY2hhciAgICAgICAgICAgdG1wW1NQUklOVF9NQVhfTEVOXTsKICAgIGludCAgICAgICAgICAgIGxlbjsKCgogICAgaWYgKCFzZXNzIHx8ICF0ZW1wbGF0ZV9wZHUpCiAgICAgICAgcmV0dXJuOwoKICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgInNlbmRpbmcgdHJhcCB0eXBlPSVkLCB2ZXJzaW9uPSVsZFxuIiwKICAgICAgICAgICAgICAgIHRlbXBsYXRlX3BkdS0+Y29tbWFuZCwgc2Vzcy0+dmVyc2lvbikpOwoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICBpZiAoc2Vzcy0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMSAmJgogICAgICAgICh0ZW1wbGF0ZV9wZHUtPmNvbW1hbmQgIT0gU05NUF9NU0dfVFJBUCkpCiAgICAgICAgcmV0dXJuOyAgICAgICAgICAgICAgICAgLyogU2tpcCB2MSBzaW5rcyBmb3IgdjIgb25seSB0cmFwcyAqLwogICAgaWYgKHNlc3MtPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzEgJiYKICAgICAgICAodGVtcGxhdGVfcGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1RSQVApKQogICAgICAgIHJldHVybjsgICAgICAgICAgICAgICAgIC8qIFNraXAgdjIrIHNpbmtzIGZvciB2MSBvbmx5IHRyYXBzICovCiNlbmRpZgogICAgdGVtcGxhdGVfcGR1LT52ZXJzaW9uID0gc2Vzcy0+dmVyc2lvbjsKICAgIHBkdSA9IHNubXBfY2xvbmVfcGR1KHRlbXBsYXRlX3BkdSk7CiAgICBwZHUtPnNlc3NpZCA9IHNlc3MtPnNlc3NpZDsgLyogQWdlbnRYIG9ubHkgPyAqLwoKICAgIGlmICggdGVtcGxhdGVfcGR1LT5jb21tYW5kID09IFNOTVBfTVNHX0lORk9STQojaWZkZWYgVVNJTkdfQUdFTlRYX1BST1RPQ09MX01PRFVMRQogICAgICAgICB8fCB0ZW1wbGF0ZV9wZHUtPmNvbW1hbmQgPT0gQUdFTlRYX01TR19OT1RJRlkKI2VuZGlmCiAgICAgICApIHsKICAgICAgICByZXN1bHQgPQogICAgICAgICAgICBzbm1wX2FzeW5jX3NlbmQoc2VzcywgcGR1LCAmaGFuZGxlX2luZm9ybV9yZXNwb25zZSwgTlVMTCk7CiAgICAgICAgCiAgICB9IGVsc2UgewogICAgICAgIGlmICgoc2Vzcy0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMykgJiYKICAgICAgICAgICAgICAgIChwZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfVFJBUDIpICYmCiAgICAgICAgICAgICAgICAoc2Vzcy0+c2VjdXJpdHlFbmdpbmVJRExlbiA9PSAwKSkgewogICAgICAgICAgICBsZW4gPSBzbm1wdjNfZ2V0X2VuZ2luZUlEKHRtcCwgc2l6ZW9mKHRtcCkpOwogICAgICAgICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSUQgPSBuZXRzbm1wX21lbWR1cCh0bXAsIGxlbik7CiAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbiA9IGxlbjsKICAgICAgICB9CgogICAgICAgIHJlc3VsdCA9IHNubXBfc2VuZChzZXNzLCBwZHUpOwogICAgfQoKICAgIGlmIChyZXN1bHQgPT0gMCkgewogICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXBkOiBzZW5kX3RyYXAiLCBzZXNzKTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgICB9IGVsc2UgewogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBPVVRUUkFQUyk7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVFBLVFMpOwogICAgfQp9Cgp2b2lkCnNlbmRfdHJhcF92YXJzKGludCB0cmFwLCBpbnQgc3BlY2lmaWMsIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIHZhcnMpCnsKICAgIGlmICh0cmFwID09IFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMpCiAgICAgICAgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycyh0cmFwLCBzcGVjaWZpYywgb2JqaWRfZW50ZXJwcmlzZXRyYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPSURfTEVOR1RIKG9iamlkX2VudGVycHJpc2V0cmFwKSwgdmFycyk7CiAgICBlbHNlCiAgICAgICAgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycyh0cmFwLCBzcGVjaWZpYywgdHJhcF92ZXJzaW9uX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0lEX0xFTkdUSCh0cmFwX3ZlcnNpb25faWQpLCB2YXJzKTsKfQoKLyoqCiAqIFNlbmRzIGFuIFNOTVB2MSB0cmFwIChvciB0aGUgU05NUHYyIGVxdWl2YWxlbnQpIHRvIHRoZSBsaXN0IG9mICAKICogY29uZmlndXJlZCB0cmFwIGRlc3RpbmF0aW9ucyAob3IgInNpbmtzIiksIHVzaW5nIHRoZSBwcm92aWRlZCAKICogdmFsdWVzIGZvciB0aGUgZ2VuZXJpYyB0cmFwIHR5cGUgYW5kIHNwZWNpZmljIHRyYXAgdmFsdWUuCiAqCiAqIFRoaXMgZnVuY3Rpb24gZXZlbnR1YWxseSBjYWxscyBzZW5kX2VudGVycHJpc2VfdHJhcF92YXJzLiAgSWYgdGhlCiAqIHRyYXAgdHlwZSBpcyBub3Qgc2V0IHRvIFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMgdGhlIGVudGVycHJpc2UgCiAqIGFuZCBlbnRlcnByaXNlX2xlbmd0aCBwYXJhbWF0ZXIgaXMgc2V0IHRvIHRoZSBwcmUgZGVmaW5lZCBORVRTTk1QX1NZU1RFTV9NSUIgCiAqIG9pZCBhbmQgbGVuZ3RoIHJlc3BlY3RpdmVseS4gIElmIHRoZSB0cmFwIHR5cGUgaXMgc2V0IHRvIAogKiBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDIHRoZSBlbnRlcnByaXNlIGFuZCBlbnRlcnByaXNlX2xlbmd0aCAKICogcGFyYW1ldGVycyBhcmUgc2V0IHRvIHRoZSBwcmUtZGVmaW5lZCBORVRTTk1QX05PVElGSUNBVElPTl9NSUIgb2lkIGFuZCBsZW5ndGggCiAqIHJlc3BlY3RpdmVseS4KICoKICogQHBhcmFtIHRyYXAgaXMgdGhlIGdlbmVyaWMgdHJhcCB0eXBlLgogKgogKiBAcGFyYW0gc3BlY2lmaWMgaXMgdGhlIHNwZWNpZmljIHRyYXAgdmFsdWUuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNlbmRfZW50ZXJwcmlzZV90cmFwX3ZhcnMKICogQHNlZSBzZW5kX3YydHJhcAogKi8KICAgICAgIAkKdm9pZApzZW5kX2Vhc3lfdHJhcChpbnQgdHJhcCwgaW50IHNwZWNpZmljKQp7CiAgICBzZW5kX3RyYXBfdmFycyh0cmFwLCBzcGVjaWZpYywgTlVMTCk7Cn0KCi8qKgogKiBVc2VzIHRoZSBzdXBwbGllZCBsaXN0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIHRvIGZvcm0gYW4gU05NUHYyIHRyYXAsIAogKiB3aGljaCBpcyBzZW50IHRvIFNOTVB2Mi1jYXBhYmxlIHNpbmtzICBvbiAgdGhlICBjb25maWd1cmVkICBsaXN0LiAgCiAqIEFuIGVxdWl2YWxlbnQgSU5GT1JNIGlzIHNlbnQgdG8gdGhlIGNvbmZpZ3VyZWQgbGlzdCBvZiBpbmZvcm0gc2lua3MuICAKICogU2lua3MgdGhhdCBjYW4gb25seSBoYW5kbGUgU05NUHYxIHRyYXBzIGFyZSBza2lwcGVkLgogKgogKiBUaGlzIGZ1bmN0aW9uIGV2ZW50dWFsbHkgY2FsbHMgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycy4gIElmIHRoZQogKiB0cmFwIHR5cGUgaXMgbm90IHNldCB0byBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDIHRoZSBlbnRlcnByaXNlIAogKiBhbmQgZW50ZXJwcmlzZV9sZW5ndGggcGFyYW1hdGVyIGlzIHNldCB0byB0aGUgcHJlIGRlZmluZWQgTkVUU05NUF9TWVNURU1fTUlCIAogKiBvaWQgYW5kIGxlbmd0aCByZXNwZWN0aXZlbHkuICBJZiB0aGUgdHJhcCB0eXBlIGlzIHNldCB0byAKICogU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQyB0aGUgZW50ZXJwcmlzZSBhbmQgZW50ZXJwcmlzZV9sZW5ndGggCiAqIHBhcmFtZXRlcnMgYXJlIHNldCB0byB0aGUgcHJlLWRlZmluZWQgTkVUU05NUF9OT1RJRklDQVRJT05fTUlCIG9pZCBhbmQgbGVuZ3RoIAogKiByZXNwZWN0aXZlbHkuCiAqCiAqIEBwYXJhbSB2YXJzIGlzIHVzZWQgdG8gc3VwcGx5IGxpc3Qgb2YgdmFyaWFibGUgYmluZGluZ3MgdG8gZm9ybSBhbiBTTk1QdjIgCiAqCXRyYXAuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNlbmRfZWFzeV90cmFwCiAqIEBzZWUgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycwogKi8KCnZvaWQKc2VuZF92MnRyYXAobmV0c25tcF92YXJpYWJsZV9saXN0ICogdmFycykKewogICAgc2VuZF90cmFwX3ZhcnMoLTEsIC0xLCB2YXJzKTsKfQoKdm9pZApzZW5kX3RyYXBfcGR1KG5ldHNubXBfcGR1ICpwZHUpCnsKICAgIHNlbmRfdHJhcF92YXJzKC0xLCAtMSwgcGR1LT52YXJpYWJsZXMpOwp9CgoKCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioKCSAqCgkgKiBDb25maWcgZmlsZSBoYW5kbGluZwoJICoKCSAqKioqKioqKioqKioqKioqKioqLwoKdm9pZApzbm1wZF9wYXJzZV9jb25maWdfYXV0aHRyYXAoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIGkgPSBhdG9pKGNwdHIpOwogICAgaWYgKGkgPT0gMCkgewogICAgICAgIGlmIChzdHJjbXAoY3B0ciwgImVuYWJsZSIpID09IDApIHsKICAgICAgICAgICAgaSA9IFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19FTkFCTEVEOwogICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKGNwdHIsICJkaXNhYmxlIikgPT0gMCkgewogICAgICAgICAgICBpID0gU05NUF9BVVRIRU5USUNBVEVEX1RSQVBTX0RJU0FCTEVEOwogICAgICAgIH0KICAgIH0KICAgIGlmIChpIDwgMSB8fCBpID4gMikgewogICAgICAgIGNvbmZpZ19wZXJyb3IoImF1dGh0cmFwZW5hYmxlIG11c3QgYmUgMSBvciAyIik7CiAgICB9IGVsc2UgewogICAgICAgIGlmIChzdHJjbXAodG9rZW4sICJwYXV0aHRyYXBlbmFibGUiKSA9PSAwKSB7CiAgICAgICAgICAgIGlmIChzbm1wX2VuYWJsZWF1dGhlbnRyYXBzc2V0IDwgMCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgYm9ndXMgKGFuZCBzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgLS0gdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgKiBvZiBzbm1wRW5hYmxlQXV0aGVuVHJhcHMuMCBpcyBhbHJlYWR5IGNvbmZpZ3VyZWQKICAgICAgICAgICAgICAgICAqIHJlYWQtb25seS4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICJpZ25vcmluZyBhdHRlbXB0ZWQgb3ZlcnJpZGUgb2YgcmVhZC1vbmx5IHNubXBFbmFibGVBdXRoZW5UcmFwcy4wXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNubXBfZW5hYmxlYXV0aGVudHJhcHNzZXQrKzsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChzbm1wX2VuYWJsZWF1dGhlbnRyYXBzc2V0ID4gMCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgYm9ndXMgKGFuZCBzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgLS0gd2UgYWxyZWFkeQogICAgICAgICAgICAgICAgICogcmVhZCBhIHBlcnNpc3RlbnQgdmFsdWUgb2Ygc25tcEVuYWJsZUF1dGhlblRyYXBzLjAsIHdoaWNoCiAgICAgICAgICAgICAgICAgKiB3ZSBzaG91bGQgaWdub3JlIGluIGZhdm91ciBvZiB0aGlzIG9uZS4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICJpZ25vcmluZyBhdHRlbXB0ZWQgb3ZlcnJpZGUgb2YgcmVhZC1vbmx5IHNubXBFbmFibGVBdXRoZW5UcmFwcy4wXG4iKTsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBGYWxsIHRocm91Z2ggYW5kIGNvcHkgaW4gdGhpcyB2YWx1ZS4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwc3NldCA9IC0xOwogICAgICAgIH0KICAgICAgICBzbm1wX2VuYWJsZWF1dGhlbnRyYXBzID0gaTsKICAgIH0KfQoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX3RyYXBzaW5rKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBjaGFyICAgICAgICAgICAgdG1wYnVmWzEwMjRdOwogICAgY2hhciAgICAgICAgICAgKnNwLCAqY3AsICpwcCA9IE5VTEw7CiAgICBjaGFyICAgICAgICAgICAgKnN0OwoKICAgIGlmICghc25tcF90cmFwY29tbXVuaXR5KQogICAgICAgIHNubXBfdHJhcGNvbW11bml0eSA9IHN0cmR1cCgicHVibGljIik7CiAgICBzcCA9IHN0cnRva19yKGNwdHIsICIgXHRcbiIsICZzdCk7CiAgICBjcCA9IHN0cnRva19yKE5VTEwsICIgXHRcbiIsICZzdCk7CiAgICBpZiAoY3ApCiAgICAgICAgcHAgPSBzdHJ0b2tfcihOVUxMLCAiIFx0XG4iLCAmc3QpOwogICAgaWYgKHBwKQoJY29uZmlnX3B3YXJuKCJUaGUgc2VwYXJhdGUgcG9ydCBhcmd1bWVudCB0byB0cmFwc2luayBpcyBkZXByZWNhdGVkIik7CiAgICBpZiAoY3JlYXRlX3YxX3RyYXBfc2Vzc2lvbihzcCwgcHAsIGNwID8gY3AgOiBzbm1wX3RyYXBjb21tdW5pdHkpID09IDApIHsKICAgICAgICBzbnByaW50Zih0bXBidWYsIHNpemVvZih0bXBidWYpLCAiY2Fubm90IGNyZWF0ZSB0cmFwc2luazogJXMiLCBjcHRyKTsKICAgICAgICB0bXBidWZbc2l6ZW9mKHRtcGJ1ZiktMV0gPSAnXDAnOwogICAgICAgIGNvbmZpZ19wZXJyb3IodG1wYnVmKTsKICAgIH0KfQojZW5kaWYKCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMKdm9pZApzbm1wZF9wYXJzZV9jb25maWdfdHJhcDJzaW5rKGNvbnN0IGNoYXIgKndvcmQsIGNoYXIgKmNwdHIpCnsKICAgIGNoYXIgICAgICAgICAgICB0bXBidWZbMTAyNF07CiAgICBjaGFyICAgICAgICAgICAqc3AsICpjcCwgKnBwID0gTlVMTDsKICAgIGNoYXIgICAgICAgICAgICAqc3Q7CgogICAgaWYgKCFzbm1wX3RyYXBjb21tdW5pdHkpCiAgICAgICAgc25tcF90cmFwY29tbXVuaXR5ID0gc3RyZHVwKCJwdWJsaWMiKTsKICAgIHNwID0gc3RydG9rX3IoY3B0ciwgIiBcdFxuIiwgJnN0KTsKICAgIGNwID0gc3RydG9rX3IoTlVMTCwgIiBcdFxuIiwgJnN0KTsKICAgIGlmIChjcCkKICAgICAgICBwcCA9IHN0cnRva19yKE5VTEwsICIgXHRcbiIsICZzdCk7CiAgICBpZiAocHApCgljb25maWdfcHdhcm4oIlRoZSBzZXBhcmF0ZSBwb3J0IGFyZ3VtZW50IHRvIHRyYXBzaW5rMiBpcyBkZXByZWNhdGVkIik7CiAgICBpZiAoY3JlYXRlX3YyX3RyYXBfc2Vzc2lvbihzcCwgcHAsIGNwID8gY3AgOiBzbm1wX3RyYXBjb21tdW5pdHkpID09IDApIHsKICAgICAgICBzbnByaW50Zih0bXBidWYsIHNpemVvZih0bXBidWYpLCAiY2Fubm90IGNyZWF0ZSB0cmFwMnNpbms6ICVzIiwgY3B0cik7CiAgICAgICAgdG1wYnVmW3NpemVvZih0bXBidWYpLTFdID0gJ1wwJzsKICAgICAgICBjb25maWdfcGVycm9yKHRtcGJ1Zik7CiAgICB9Cn0KCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX2luZm9ybXNpbmsoY29uc3QgY2hhciAqd29yZCwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgIHRtcGJ1ZlsxMDI0XTsKICAgIGNoYXIgICAgICAgICAgICpzcCwgKmNwLCAqcHAgPSBOVUxMOwogICAgY2hhciAgICAgICAgICAgICpzdDsKCiAgICBpZiAoIXNubXBfdHJhcGNvbW11bml0eSkKICAgICAgICBzbm1wX3RyYXBjb21tdW5pdHkgPSBzdHJkdXAoInB1YmxpYyIpOwogICAgc3AgPSBzdHJ0b2tfcihjcHRyLCAiIFx0XG4iLCAmc3QpOwogICAgY3AgPSBzdHJ0b2tfcihOVUxMLCAiIFx0XG4iLCAmc3QpOwogICAgaWYgKGNwKQogICAgICAgIHBwID0gc3RydG9rX3IoTlVMTCwgIiBcdFxuIiwgJnN0KTsKICAgIGlmIChwcCkKCWNvbmZpZ19wd2FybigiVGhlIHNlcGFyYXRlIHBvcnQgYXJndW1lbnQgdG8gaW5mb3Jtc2luayBpcyBkZXByZWNhdGVkIik7CiAgICBpZiAoY3JlYXRlX3YyX2luZm9ybV9zZXNzaW9uKHNwLCBwcCwgY3AgPyBjcCA6IHNubXBfdHJhcGNvbW11bml0eSkgPT0gMCkgewogICAgICAgIHNucHJpbnRmKHRtcGJ1Ziwgc2l6ZW9mKHRtcGJ1ZiksICJjYW5ub3QgY3JlYXRlIGluZm9ybXNpbms6ICVzIiwgY3B0cik7CiAgICAgICAgdG1wYnVmW3NpemVvZih0bXBidWYpLTFdID0gJ1wwJzsKICAgICAgICBjb25maWdfcGVycm9yKHRtcGJ1Zik7CiAgICB9Cn0KI2VuZGlmCgovKgogKiB0aGlzIG11c3QgYmUgc3RhbmRhcmRpemVkIHNvbWV3aGVyZSwgcmlnaHQ/IAogKi8KI2RlZmluZSBNQVhfQVJHUyAxMjgKCnN0YXRpYyBpbnQgICAgICB0cmFwdHlwZTsKCnN0YXRpYyB2b2lkCnRyYXBPcHRQcm9jKGludCBhcmdjLCBjaGFyICpjb25zdCAqYXJndiwgaW50IG9wdCkKewogICAgc3dpdGNoIChvcHQpIHsKICAgIGNhc2UgJ0MnOgogICAgICAgIHdoaWxlICgqb3B0YXJnKSB7CiAgICAgICAgICAgIHN3aXRjaCAoKm9wdGFyZysrKSB7CiAgICAgICAgICAgIGNhc2UgJ2knOgogICAgICAgICAgICAgICAgdHJhcHR5cGUgPSBTTk1QX01TR19JTkZPUk07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGNvbmZpZ19wZXJyb3IoInVua25vd24gYXJndW1lbnQgcGFzc2VkIHRvIC1DIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KfQoKCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX3RyYXBzZXNzKGNvbnN0IGNoYXIgKndvcmQsIGNoYXIgKmNwdHIpCnsKICAgIGNoYXIgICAgICAgICAgICphcmd2W01BWF9BUkdTXSwgKmNwID0gY3B0ciwgdG1wW1NQUklOVF9NQVhfTEVOXTsKICAgIGludCAgICAgICAgICAgICBhcmduOwogICAgbmV0c25tcF9zZXNzaW9uIHNlc3Npb24sICpzczsKICAgIHNpemVfdCAgICAgICAgICBsZW47CgogICAgLyoKICAgICAqIGluZm9ybSBvciB0cmFwPyAgZGVmYXVsdCB0byB0cmFwIAogICAgICovCiAgICB0cmFwdHlwZSA9IFNOTVBfTVNHX1RSQVAyOwoKICAgIC8qCiAgICAgKiBjcmVhdGUgdGhlIGFyZ3ZbXSBsaWtlIGFycmF5IAogICAgICovCiAgICBhcmd2WzBdID0gc3RyZHVwKCJzbm1wZC10cmFwc2VzcyIpOyAvKiBib2d1cyBlbnRyeSBmb3IgZ2V0b3B0KCkgKi8KICAgIGZvciAoYXJnbiA9IDE7IGNwICYmIGFyZ24gPCBNQVhfQVJHUzsgYXJnbisrKSB7CiAgICAgICAgY3AgPSBjb3B5X253b3JkKGNwLCB0bXAsIFNQUklOVF9NQVhfTEVOKTsKICAgICAgICBhcmd2W2FyZ25dID0gc3RyZHVwKHRtcCk7CiAgICB9CgogICAgc25tcF9wYXJzZV9hcmdzKGFyZ24sIGFyZ3YsICZzZXNzaW9uLCAiQzoiLCB0cmFwT3B0UHJvYyk7CgogICAgc3MgPSBzbm1wX2FkZCgmc2Vzc2lvbiwKCQkgIG5ldHNubXBfdHJhbnNwb3J0X29wZW5fY2xpZW50KCJzbm1wdHJhcCIsIHNlc3Npb24ucGVlcm5hbWUpLAoJCSAgTlVMTCwgTlVMTCk7CiAgICBmb3IgKDsgYXJnbiA+IDA7IGFyZ24tLSkgewogICAgICAgIGZyZWUoYXJndlthcmduIC0gMV0pOwogICAgfQoKICAgIGlmICghc3MpIHsKICAgICAgICBjb25maWdfcGVycm9yCiAgICAgICAgICAgICgic25tcGQ6IGZhaWxlZCB0byBwYXJzZSB0aGlzIGxpbmUgb3IgdGhlIHJlbW90ZSB0cmFwIHJlY2VpdmVyIGlzIGRvd24uICBQb3NzaWJsZSBjYXVzZToiKTsKICAgICAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wZDogc25tcGRfcGFyc2VfY29uZmlnX3RyYXBzZXNzKCkiLCAmc2Vzc2lvbik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qCiAgICAgKiBJZiB0aGlzIGlzIGFuIFNOTVB2MyBUUkFQIHNlc3Npb24sIHRoZW4gdGhlIGFnZW50IGlzCiAgICAgKiAgIHRoZSBhdXRob3JpdGF0aXZlIGVuZ2luZSwgc28gc2V0IHRoZSBlbmdpbmVJRCBhY2NvcmRpbmdseQogICAgICovCiAgICBpZiAoc3MtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzMgJiYKICAgICAgICB0cmFwdHlwZSAhPSBTTk1QX01TR19JTkZPUk0gICAmJgogICAgICAgIHNzLT5zZWN1cml0eUVuZ2luZUlETGVuID09IDApIHsKICAgICAgICAgICAgbGVuID0gc25tcHYzX2dldF9lbmdpbmVJRCggdG1wLCBzaXplb2YodG1wKSk7CiAgICAgICAgICAgIHNzLT5zZWN1cml0eUVuZ2luZUlEID0gbmV0c25tcF9tZW1kdXAodG1wLCBsZW4pOwogICAgICAgICAgICBzcy0+c2VjdXJpdHlFbmdpbmVJRExlbiA9IGxlbjsKICAgIH0KCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgaWYgKHNzLT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xKSB7CiAgICAgICAgYWRkX3RyYXBfc2Vzc2lvbihzcywgU05NUF9NU0dfVFJBUCwgMCwgU05NUF9WRVJTSU9OXzEpOwogICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgYWRkX3RyYXBfc2Vzc2lvbihzcywgdHJhcHR5cGUsICh0cmFwdHlwZSA9PSBTTk1QX01TR19JTkZPUk0pLAogICAgICAgICAgICAgICAgICAgICAgICAgc3MtPnZlcnNpb24pOwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgIH0KI2VuZGlmCn0KCiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKdm9pZApzbm1wZF9wYXJzZV9jb25maWdfdHJhcGNvbW11bml0eShjb25zdCBjaGFyICp3b3JkLCBjaGFyICpjcHRyKQp7CiAgICBpZiAoc25tcF90cmFwY29tbXVuaXR5ICE9IE5VTEwpIHsKICAgICAgICBmcmVlKHNubXBfdHJhcGNvbW11bml0eSk7CiAgICB9CiAgICBzbm1wX3RyYXBjb21tdW5pdHkgPSAoY2hhciAqKSBtYWxsb2Moc3RybGVuKGNwdHIpICsgMSk7CiAgICBpZiAoc25tcF90cmFwY29tbXVuaXR5ICE9IE5VTEwpIHsKICAgICAgICBjb3B5X253b3JkKGNwdHIsIHNubXBfdHJhcGNvbW11bml0eSwgc3RybGVuKGNwdHIpICsgMSk7CiAgICB9Cn0KCnZvaWQKc25tcGRfZnJlZV90cmFwY29tbXVuaXR5KHZvaWQpCnsKICAgIGlmIChzbm1wX3RyYXBjb21tdW5pdHkpIHsKICAgICAgICBmcmVlKHNubXBfdHJhcGNvbW11bml0eSk7CiAgICAgICAgc25tcF90cmFwY29tbXVuaXR5ID0gTlVMTDsKICAgIH0KfQojZW5kaWYKLyoqIEB9ICovCg==