LyoqDQogKiBAZmlsZSBmbGFnc19hcGkuYw0KICogQGJyaWVmIGZsYWdzt9bH+L3Tv9rKtc/WDQogKg0KICogQ29weXJpZ2h0IChDKSAyMDIzIFNhbmVjaGlwcyBUZWNobm9sb2d5IENvLiwgTHRkLg0KICogQGF1dGhvciANCiAqIA0KICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkNCiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIGFzDQogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4go6ix2NGho7pHUEx2MiBMaWNlbmNlo6kNCiAqDQogKi8NCg0KDQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KICogICAgICAgICAgICAgICAgICAgICAgICAgICBJbmNsdWRlIGhlYWRlciBmaWxlcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovDQojaW5jbHVkZSA8c3RkaW8uaD4NCiNpbmNsdWRlIDxzdGRsaWIuaD4NCiNpbmNsdWRlIDx1bmlzdGQuaD4NCiNpbmNsdWRlIDxzdHJpbmcuaD4NCiNpbmNsdWRlIDxlcnJuby5oPg0KI2luY2x1ZGUgPHN5cy9pb2N0bC5oPg0KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+DQojaW5jbHVkZSA8ZmNudGwuaD4NCiNpbmNsdWRlIDxtdGQvbXRkLWFiaS5oPg0KDQojaW5jbHVkZSAicHViX2ZsYWdzLmgiDQoNCiNpbmNsdWRlICJmbGFnc19sb2cuaCINCiNpbmNsdWRlICJmbGFnc19hcGkuaCINCg0KDQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY3JvIGRlZmluaXRpb25zICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoNCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovDQojZGVmaW5lIE1BWF9QQVRIX0xFTiAoMjU2KQ0KDQojZGVmaW5lIFBBUlRJVElPTl9OQU1FX0ZMQUdTICJmbGFncyINCg0KI2RlZmluZSBGTEFHU19JTklUX1ZBTElEX0JMT0NLU19OVU0JKDgpDQoNCiNkZWZpbmUgR09PRF9CTE9DSyAoMCkNCiNkZWZpbmUgQkFEX0JMT0NLICgxKQ0KDQojZGVmaW5lIEZJTEVfUEFUSF9QUk9DX0NNRExJTkUgIi9wcm9jL2NtZGxpbmUiDQoNCiNkZWZpbmUgUFJPQ19DTURMSU5FX1NZU1RFTV9BX0ZMQUcgICAic3lzdGVtPXN5c3RlbV9hIg0KI2RlZmluZSBQUk9DX0NNRExJTkVfU1lTVEVNX0JfRkxBRyAgICJzeXN0ZW09c3lzdGVtX2IiDQoNCiNkZWZpbmUgU1lTVEVNX0lOREVYX1VOS05PV04gKC0xKQ0KI2RlZmluZSBTWVNURU1fSU5ERVhfMSAoMSkNCiNkZWZpbmUgU1lTVEVNX0lOREVYXzIgKDIpDQoNCiNkZWZpbmUgQ1JDX0xFX0JJVFMgNjQNCiNkZWZpbmUgQ1JDMzJfUE9MWV9MRSAweGVkYjg4MzIwDQojZGVmaW5lIExFX1RBQkxFX1JPV1MgKENSQ19MRV9CSVRTLzgpDQojZGVmaW5lIExFX1RBQkxFX1NJWkUgMjU2DQoNCg0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIGRlZmluaXRpb25zICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0KdHlwZWRlZiBzdHJ1Y3QNCnsNCiAgICB1bnNpZ25lZCBpbnQgbXRkX3RvdGFsc2l6ZTsJCQkJLy8gbXRkIGRldmljZSB0b3RhbCBzaXplDQogICAgdW5zaWduZWQgaW50IG10ZF9wYWdlcGVyYmxvY2s7CQkJLy8gbXRkIGRldmljZSBwYWdlIHBlciBibG9jaw0KICAgIHVuc2lnbmVkIGludCBtdGRfYmxvY2tzaXplOwkJCQkvLyBtdGQgZGV2aWNlIGJsb2NrIHNpemUNCiAgICB1bnNpZ25lZCBpbnQgbXRkX3BhZ2VzaXplOwkJCQkvLyBtdGQgZGV2aWNlIHBhZ2Ugc2l6ZQ0KICAgIHVuc2lnbmVkIGludCBtdGRfb29ic2l6ZTsJCQkJLy8gbXRkIGRldmljZSBvb2Igc2l6ZQ0KICAgIGludCBwYXJ0aV9maWxlX2Rlc2M7CQkJCQkvLyBwYXJ0aXRpb24gdXBkYXRlIGZpbGUgZGVzY3JpcHRpb24NCn0gcGFydGl0aW9uX210ZF9pbmZvX3Q7DQoNCg0KdHlwZWRlZiBlbnVtDQp7DQogICAgREVWSUNFX01URCA9IDAsDQogICAgREVWSUNFX1pGVEwgPSAxLA0KICAgIERFVklDRV9NVERfQkxPQ0ssDQp9IGRldmljZV90eXBlX3Q7DQoNCg0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAqCQkJCQkJICAgTG9jYWwgdmFyaWFibGUgZGVmaW5pdGlvbnMJCQkJCQkgICAqDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0KDQoNCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogKgkJCQkJCSAgR2xvYmFsIHZhcmlhYmxlIGRlZmluaXRpb25zCQkJCQkJICAgKg0KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCnN0YXRpYyB1bnNpZ25lZCBpbnQgY3JjMzJ0YWJsZV9sZVtMRV9UQUJMRV9ST1dTXVsyNTZdOw0KDQoNCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogKiAJCQkJCSAgIExvY2FsIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucwkJCQkJCQkgICAqDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0Kc3RhdGljIHZvaWQgY3JjMzJpbml0X2xlX2dlbmVyaWMoY29uc3QgdW5zaWduZWQgaW50IHBvbHlub21pYWwsIHVuc2lnbmVkIGludCAoKnRhYilbMjU2XSk7DQpzdGF0aWMgdW5zaWduZWQgaW50IGNyYzMyX2JvZHkodW5zaWduZWQgaW50IGNyYywgdW5zaWduZWQgY2hhciBjb25zdCAqYnVmLCBzaXplX3QgbGVuLCBjb25zdCB1bnNpZ25lZCBpbnQgKCp0YWIpWzI1Nl0pOw0Kc3RhdGljIHVuc2lnbmVkIGludCBjcmMzMl9sZV9nZW5lcmljKHVuc2lnbmVkIGludCBjcmMsIHVuc2lnbmVkIGNoYXIgY29uc3QgKnAsIHNpemVfdCBsZW4sIGNvbnN0IHVuc2lnbmVkIGludCAoKnRhYilbMjU2XSk7DQoNCnN0YXRpYyBpbnQgbXRkX2dldChjb25zdCBjaGFyICppX3BhcnRpX25hbWUsIGRldmljZV90eXBlX3QgZGV2aWNlX3R5cGUsIGNoYXIgKm9fbXRkX3BhdGgsIHVuc2lnbmVkIGludCBvX210ZF9wYXRoX2xlbik7DQpzdGF0aWMgaW50IHdyaXRlX2ZsYWdzX2luZm8ocGFydGl0aW9uX210ZF9pbmZvX3QgKnBfbXRkX2luZm8sIGludCBpbmRleCwgdW5zaWduZWQgY2hhciAqY29udGVudCwgaW50IGxlbik7DQoNCnN0YXRpYyBpbnQgZ2V0X2ZsYWdzX2luZm8oVF9GTEFHU19JTkZPICpwX21haW4sIGludCAqcF9tYWluX2luZGV4LCBUX0ZMQUdTX0lORk8gKnBfYmFja3VwLCBpbnQgKnBfYmFja3VwX2luZGV4KTsNCnN0YXRpYyBpbnQgc2V0X2ZsYWdzX2luZm8oVF9GTEFHU19JTkZPICpwX2ZsYWdzX2luZm8sIGludCAqcF9tYWluX2luZGV4LCBpbnQgKnBfYmFja3VwX2luZGV4KTsNCg0Kc3RhdGljIHZvaWQgY29weV9mbGFnc19pbmZvKFRfRkxBR1NfSU5GTyAqZHN0LCBUX0ZMQUdTX0lORk8gKnNyYyk7DQoNCnN0YXRpYyBpbnQgZ2V0X2N1cnJlbnRfc3lzdGVtKCk7DQoNCg0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAqIAkJCQkJIExvY2FsIGZ1bmN0aW9uIGltcGxlbWVudGF0aW9ucyAJCQkJCQkgICAqDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0Kc3RhdGljIHZvaWQgY3JjMzJpbml0X2xlX2dlbmVyaWMoY29uc3QgdW5zaWduZWQgaW50IHBvbHlub21pYWwsIHVuc2lnbmVkIGludCAoKnRhYilbMjU2XSkNCnsNCgl1bnNpZ25lZCBpLCBqOw0KCXVuc2lnbmVkIGludCBjcmMgPSAxOw0KDQoJdGFiWzBdWzBdID0gMDsNCg0KCWZvciAoaSA9IExFX1RBQkxFX1NJWkUgPj4gMTsgaTsgaSA+Pj0gMSkgew0KCQljcmMgPSAoY3JjID4+IDEpIF4gKChjcmMgJiAxKSA/IHBvbHlub21pYWwgOiAwKTsNCgkJZm9yIChqID0gMDsgaiA8IExFX1RBQkxFX1NJWkU7IGogKz0gMiAqIGkpDQoJCQl0YWJbMF1baSArIGpdID0gY3JjIF4gdGFiWzBdW2pdOw0KCX0NCglmb3IgKGkgPSAwOyBpIDwgTEVfVEFCTEVfU0laRTsgaSsrKSB7DQoJCWNyYyA9IHRhYlswXVtpXTsNCgkJZm9yIChqID0gMTsgaiA8IExFX1RBQkxFX1JPV1M7IGorKykgew0KCQkJY3JjID0gdGFiWzBdW2NyYyAmIDB4ZmZdIF4gKGNyYyA+PiA4KTsNCgkJCXRhYltqXVtpXSA9IGNyYzsNCgkJfQ0KCX0NCn0NCg0KDQpzdGF0aWMgdW5zaWduZWQgaW50IGNyYzMyX2JvZHkodW5zaWduZWQgaW50IGNyYywgdW5zaWduZWQgY2hhciBjb25zdCAqYnVmLCBzaXplX3QgbGVuLCBjb25zdCB1bnNpZ25lZCBpbnQgKCp0YWIpWzI1Nl0pDQp7DQojZGVmaW5lIERPX0NSQyh4KSBjcmMgPSB0MFsoY3JjIF4gKHgpKSAmIDI1NV0gXiAoY3JjID4+IDgpDQojZGVmaW5lIERPX0NSQzQgKHQzWyhxKSAmIDI1NV0gXiB0MlsocSA+PiA4KSAmIDI1NV0gXiBcDQoJCSAgIHQxWyhxID4+IDE2KSAmIDI1NV0gXiB0MFsocSA+PiAyNCkgJiAyNTVdKQ0KI2RlZmluZSBET19DUkM4ICh0N1socSkgJiAyNTVdIF4gdDZbKHEgPj4gOCkgJiAyNTVdIF4gXA0KCQkgICB0NVsocSA+PiAxNikgJiAyNTVdIF4gdDRbKHEgPj4gMjQpICYgMjU1XSkNCg0KCWNvbnN0IHVuc2lnbmVkIGludCAqYjsNCglzaXplX3QgICAgcmVtX2xlbjsNCg0KCWNvbnN0IHVuc2lnbmVkIGludCAqdDA9dGFiWzBdLCAqdDE9dGFiWzFdLCAqdDI9dGFiWzJdLCAqdDM9dGFiWzNdOw0KCWNvbnN0IHVuc2lnbmVkIGludCAqdDQgPSB0YWJbNF0sICp0NSA9IHRhYls1XSwgKnQ2ID0gdGFiWzZdLCAqdDcgPSB0YWJbN107DQoJdW5zaWduZWQgaW50IHE7DQoJDQoJaWYgKChsb25nKWJ1ZiAmIDMgJiYgbGVuKQ0KCXsNCgkJZG8NCgkJew0KCQkJRE9fQ1JDKCpidWYrKyk7DQoJCX0gd2hpbGUgKCgtLWxlbikgJiYgKChsb25nKWJ1ZikmMyk7DQoJfQ0KCQ0KCXJlbV9sZW4gPSBsZW4gJiA3Ow0KCWxlbiA9IGxlbiA+PiAzOw0KCWIgPSAoY29uc3QgdW5zaWduZWQgaW50ICopYnVmOw0KCQ0KCWZvciAoLS1iOyBsZW47IC0tbGVuKQ0KCXsNCgkJcSA9IGNyYyBeICorK2I7DQoJCWNyYyA9IERPX0NSQzg7DQoJCXEgPSAqKytiOw0KCQljcmMgXj0gRE9fQ1JDNDsNCgl9DQoJDQoJbGVuID0gcmVtX2xlbjsNCglpZiAobGVuKQ0KCXsNCgkJdW5zaWduZWQgY2hhciAqcCA9ICh1bnNpZ25lZCBjaGFyICopKGIgKyAxKSAtIDE7DQoJCWRvDQoJCXsNCgkJCURPX0NSQygqKytwKTsgLyogdXNlIHByZSBpbmNyZW1lbnQgZm9yIHNwZWVkICovDQoJCX0gd2hpbGUgKC0tbGVuKTsNCgl9DQoJDQoJcmV0dXJuIGNyYzsNCiN1bmRlZiBET19DUkMNCiN1bmRlZiBET19DUkM0DQojdW5kZWYgRE9fQ1JDOA0KfQ0KDQoNCnN0YXRpYyB1bnNpZ25lZCBpbnQgY3JjMzJfbGVfZ2VuZXJpYyh1bnNpZ25lZCBpbnQgY3JjLCB1bnNpZ25lZCBjaGFyIGNvbnN0ICpwLCBzaXplX3QgbGVuLCBjb25zdCB1bnNpZ25lZCBpbnQgKCp0YWIpWzI1Nl0pDQp7DQoJY3JjID0gY3JjMzJfYm9keShjcmMsIHAsIGxlbiwgdGFiKTsNCglyZXR1cm4gY3JjOw0KfQ0KDQoNCnN0YXRpYyBpbnQgbXRkX2dldChjb25zdCBjaGFyICppX3BhcnRpX25hbWUsIGRldmljZV90eXBlX3QgZGV2aWNlX3R5cGUsIGNoYXIgKm9fbXRkX3BhdGgsIHVuc2lnbmVkIGludCBvX210ZF9wYXRoX2xlbikNCnsNCiAgICBGSUxFICpmcF9tdGQgPSAwOw0KICAgIGNoYXIgYnVmWzEyOF07DQogICAgY2hhciAqbGluZV9zdHI7DQoNCiAgICBpZiAoIW9fbXRkX3BhdGhfbGVuKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuIC0xOw0KICAgIH0NCg0KICAgIGZwX210ZCA9IGZvcGVuKCIvcHJvYy9tdGQiLCAicisiKTsNCiAgICBpZiAoTlVMTCA9PSBmcF9tdGQpDQogICAgew0KICAgICAgICBmbGFnc19lcnIoIm9wZW4gZmlsZSBlcnJvcjogJXMiLCBzdHJlcnJvcihlcnJubykpOw0KICAgICAgICByZXR1cm4gLTE7DQogICAgfQ0KICAgIC8vIHByaW50ZigiW2xpYm10ZF06IHBhcnRpdGlvbiBuYW1lOiVzXG4iLCBpX3BhcnRpX25hbWUpOw0KDQogICAgd2hpbGUgKDEpDQogICAgew0KICAgICAgICBpbnQgbWF0Y2hlcyA9IDA7DQogICAgICAgIGNoYXIgbXRkbmFtZVs2NF0gPSB7MH07DQogICAgICAgIGludCBtdGRudW0gPSAwOw0KICAgICAgICB1bnNpZ25lZCBpbnQgbXRkc2l6ZSwgbXRkZXJhc2VzaXplOw0KICAgICAgICBtZW1zZXQoYnVmLCAwLCBzaXplb2YoYnVmKSk7DQogICAgICAgIGxpbmVfc3RyID0gZmdldHMoYnVmLCBzaXplb2YoYnVmKSAtIDEsIGZwX210ZCk7DQoNCiAgICAgICAgaWYgKE5VTEwgPT0gbGluZV9zdHIpDQogICAgICAgIHsNCiAgICAgICAgICAgIGZsYWdzX2VycigiZ2V0IGluZm8gZnJvbSBtdGQgZXJyb3I6ICVzIiwgc3RyZXJyb3IoZXJybm8pKTsNCiAgICAgICAgICAgIGZjbG9zZShmcF9tdGQpOw0KICAgICAgICAgICAgcmV0dXJuIC0xOw0KICAgICAgICB9DQogICAgICAgIC8vIG10ZDU6IDAwMTAwMDAwIDAwMDIwMDAwICJmb3RhZmxhZyINCiAgICAgICAgbWF0Y2hlcyA9IHNzY2FuZihidWYsICJtdGQlZDogJXggJXggXCIlNjNbXlwiXSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgJm10ZG51bSwgJm10ZHNpemUsICZtdGRlcmFzZXNpemUsIG10ZG5hbWUpOw0KICAgICAgICBtdGRuYW1lWzYzXSA9ICdcMCc7DQoNCiAgICAgICAgaWYgKChtYXRjaGVzID09IDQpICYmIChzdHJjbXAobXRkbmFtZSwgaV9wYXJ0aV9uYW1lKSA9PSAwKSkNCiAgICAgICAgew0KICAgICAgICAgICAgbWVtc2V0KG9fbXRkX3BhdGgsIDAsIG9fbXRkX3BhdGhfbGVuKTsNCiAgICAgICAgICAgIGlmIChkZXZpY2VfdHlwZSA9PSBERVZJQ0VfTVREX0JMT0NLKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHNucHJpbnRmKG9fbXRkX3BhdGgsIG9fbXRkX3BhdGhfbGVuLCAiL2Rldi9tdGRibG9jayVkIiwgbXRkbnVtKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UgaWYgKGRldmljZV90eXBlID09IERFVklDRV9NVEQpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgc25wcmludGYob19tdGRfcGF0aCwgb19tdGRfcGF0aF9sZW4sICIvZGV2L210ZCVkIiwgbXRkbnVtKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UgaWYgKGRldmljZV90eXBlID09IERFVklDRV9aRlRMKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHNucHJpbnRmKG9fbXRkX3BhdGgsIG9fbXRkX3BhdGhfbGVuLCAiL2Rldi96ZnRsJWQiLCBtdGRudW0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGZsYWdzX2VycigidW5rbm93biBkZXZpY2UgdHlwZSAlZCIsIGRldmljZV90eXBlKTsNCiAgICAgICAgICAgICAgICBmY2xvc2UoZnBfbXRkKTsNCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7DQogICAgICAgICAgICB9DQogICAgICAgICAgICAvLyBwcmludGYoIltsaWJtdGRdOiBvX210ZF9wYXRoPVslc11cbiIsIG9fbXRkX3BhdGgpOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICB9DQogICAgZmNsb3NlKGZwX210ZCk7DQogICAgcmV0dXJuIDA7DQp9DQoNCg0Kc3RhdGljIGludCB3cml0ZV9mbGFnc19pbmZvKHBhcnRpdGlvbl9tdGRfaW5mb190ICpwX210ZF9pbmZvLCBpbnQgaW5kZXgsIHVuc2lnbmVkIGNoYXIgKmNvbnRlbnQsIGludCBsZW4pDQp7DQogICAgc3RydWN0IGVyYXNlX2luZm9fdXNlciBlcmFzZV9pbmZvOw0KICAgIGludCB3cml0ZV9sZW4gPSAwOw0KICAgIGxvbmcgbG9uZyAgb2ZmcyA9IDA7DQoNCiAgICBlcmFzZV9pbmZvLnN0YXJ0ID0gaW5kZXggKiBwX210ZF9pbmZvLT5tdGRfYmxvY2tzaXplOw0KICAgIGVyYXNlX2luZm8ubGVuZ3RoID0gcF9tdGRfaW5mby0+bXRkX2Jsb2Nrc2l6ZTsNCg0KICAgIG9mZnMgPSAobG9uZyBsb25nKWluZGV4ICogcF9tdGRfaW5mby0+bXRkX2Jsb2Nrc2l6ZTsNCg0KICAgIGlmIChpb2N0bChwX210ZF9pbmZvLT5wYXJ0aV9maWxlX2Rlc2MsIFdSSVRFRU5BQkxFLCAwKSAhPSAwKQ0KICAgIHsNCiAgICAgICAgZmxhZ3NfZXJyKCJmYWlsZWQgdG8gZW5hYmxlIG10ZCB3cml0ZWFibGUsIGVycm5vPSVkLCBzdHJlcnJvcj0lcyIsIGVycm5vLCBzdHJlcnJvcihlcnJubykpOw0KCQkNCiAgICAgICAgcmV0dXJuIC0xOw0KICAgIH0NCg0KICAgIGlmIChpb2N0bChwX210ZF9pbmZvLT5wYXJ0aV9maWxlX2Rlc2MsIE1FTUdFVEJBREJMT0NLLCAmb2ZmcykgIT0gMCkNCiAgICB7DQogICAgICAgIGZsYWdzX2VycigiaW9jdGwgW01FTUdFVEJBREJMT0NLXSBibG9jazogJWQsIGNoYW5nZSB0byBiZSBiYWQgYmxvY2ssIGVycm5vPSVkLCBzdHJlcnJvcj1bJXNdIiwgaW5kZXgsIGVycm5vLCBzdHJlcnJvcihlcnJubykpOw0KCQkNCiAgICAgICAgcmV0dXJuIEJBRF9CTE9DSzsNCiAgICB9DQoNCiAgICBpZiAoaW9jdGwocF9tdGRfaW5mby0+cGFydGlfZmlsZV9kZXNjLCBNRU1FUkFTRSwgJmVyYXNlX2luZm8pIDwgMCkNCiAgICB7DQogICAgICAgIGZsYWdzX2VycigiaW9jdGwgW01FTUVSQVNFXSBibG9jazogJWQgZmFpbCwgZXJybm89JWQsIHN0cmVycm9yPVslc10iLCBpbmRleCwgZXJybm8sIHN0cmVycm9yKGVycm5vKSk7DQoJCQ0KICAgICAgICByZXR1cm4gLTE7DQogICAgfQ0KDQogICAgaWYgKGlvY3RsKHBfbXRkX2luZm8tPnBhcnRpX2ZpbGVfZGVzYywgTUVNR0VUQkFEQkxPQ0ssICZvZmZzKSAhPSAwKQ0KICAgIHsNCiAgICAgICAgZmxhZ3NfZXJyKCJpb2N0bCBbTUVNR0VUQkFEQkxPQ0tdIGJsb2NrOiVkICwgY2hhbmdlIHRvIGJlIGJhZCBibG9jaywgZXJybm89JWQsIHN0cmVycm9yPVslc10iLCBpbmRleCwgZXJybm8sIHN0cmVycm9yKGVycm5vKSk7DQoJCQ0KICAgICAgICByZXR1cm4gQkFEX0JMT0NLOw0KICAgIH0NCg0KICAgIGlmIChsc2VlayhwX210ZF9pbmZvLT5wYXJ0aV9maWxlX2Rlc2MsIGluZGV4ICogcF9tdGRfaW5mby0+bXRkX2Jsb2Nrc2l6ZSwgU0VFS19TRVQpIDwgMCkNCiAgICB7DQogICAgICAgIGZsYWdzX2VycigibHNlZWsgZmFpbCwgZXJybm89JWQsIHN0cmVycm9yPVslc10iLCBlcnJubywgc3RyZXJyb3IoZXJybm8pKTsNCgkJDQogICAgICAgIHJldHVybiAtMTsNCiAgICB9DQoNCiAgICB3cml0ZV9sZW4gPSB3cml0ZShwX210ZF9pbmZvLT5wYXJ0aV9maWxlX2Rlc2MsIGNvbnRlbnQsIHBfbXRkX2luZm8tPm10ZF9ibG9ja3NpemUpOw0KDQogICAgaWYgKHdyaXRlX2xlbiAhPSBwX210ZF9pbmZvLT5tdGRfYmxvY2tzaXplKQ0KICAgIHsNCiAgICAgICAgZmxhZ3NfZXJyKCJ3cml0ZSBmbGFzaCBmYWlsLCBlcnJubz0lZCwgc3RyZXJyb3I9WyVzXSIsIGVycm5vLCBzdHJlcnJvcihlcnJubykpOw0KCQkNCiAgICAgICAgcmV0dXJuIC0xOw0KICAgIH0NCg0KICAgIGlmIChpb2N0bChwX210ZF9pbmZvLT5wYXJ0aV9maWxlX2Rlc2MsIFdSSVRFRElTQUJMRSwgMCkgIT0gMCkNCiAgICB7DQogICAgICAgIGZsYWdzX2VycigiZmFpbGVkIHRvIGRpc2FibGUgbXRkIHdyaXRlYWJsZSwgZXJybm89JWQsIHN0cmVycm9yPSVzIiwgZXJybm8sIHN0cmVycm9yKGVycm5vKSk7DQogICAgfQ0KCQ0KICAgIHJldHVybiAwOw0KfQ0KDQoNCnN0YXRpYyBpbnQgZ2V0X2ZsYWdzX2luZm8oVF9GTEFHU19JTkZPICpwX21haW4sIGludCAqcF9tYWluX2luZGV4LCBUX0ZMQUdTX0lORk8gKnBfYmFja3VwLCBpbnQgKnBfYmFja3VwX2luZGV4KQ0Kew0KICAgIGludCByZXQgPSAtMTsNCiAgICBpbnQgZmRfZHN0ID0gLTE7DQogICAgY2hhciBtdGRfcGF0aFtNQVhfUEFUSF9MRU5dID0gezB9Ow0KICAgIHN0cnVjdCBtdGRfaW5mb191c2VyIG1lbWluZm8gPSB7MH07DQogICAgcGFydGl0aW9uX210ZF9pbmZvX3QgbXRkX2luZm8gPSB7MH07DQogICAgaW50IGluZGV4ICA9IDA7DQogICAgaW50IGJsb2NrX251bSA9IDA7DQogICAgaW50IGdvb2RfaW5kZXggPSAwOw0KICAgIGludCByZWFkX2xlbiAgPSAwOw0KDQogICAgbG9uZyBsb25nIG9mZnMgPSAwOw0KDQogICAgaW50IGJsb2NrX2ZsYWcgPSBHT09EX0JMT0NLOw0KDQogICAgcmV0ID0gbXRkX2dldChQQVJUSVRJT05fTkFNRV9GTEFHUywgREVWSUNFX01URCwgbXRkX3BhdGgsIE1BWF9QQVRIX0xFTik7DQogICAgaWYgKHJldCA8IDApDQogICAgew0KICAgICAgICBmbGFnc19lcnIoInBhcnRpdGlvbiBbJXNdIG5vdCBmaW5kIiwgUEFSVElUSU9OX05BTUVfRkxBR1MpOw0KICAgICAgICBnb3RvIGVycm9yOw0KICAgIH0NCg0KICAgIGlmICgoZmRfZHN0ID0gb3BlbihtdGRfcGF0aCwgT19SRFdSIHwgT19TWU5DKSkgPCAwKQ0KICAgIHsNCiAgICAgICAgZmxhZ3NfZXJyKCJvcGVuIGZsYXNoIGVycm9yLCBlcnJubz0lZCwgc3RyZXJyb3I9WyVzXSIsIGVycm5vLCBzdHJlcnJvcihlcnJubykpOw0KICAgICAgICBnb3RvIGVycm9yOw0KICAgIH0NCgkNCiAgICBtdGRfaW5mby5wYXJ0aV9maWxlX2Rlc2MgPSBmZF9kc3Q7DQoNCiAgICBpZiAoaW9jdGwoZmRfZHN0LCBNRU1HRVRJTkZPLCAmbWVtaW5mbykgIT0gMCkNCiAgICB7DQogICAgICAgIGZsYWdzX2VycigiZ2V0IGZsYXNoIGluZm8gZXJyb3IsIGVycm5vPSVkLCBzdHJlcnJvcj1bJXNdIiwgZXJybm8sIHN0cmVycm9yKGVycm5vKSk7DQogICAgICAgIGdvdG8gZXJyb3JfY2xvc2U7DQogICAgfQ0KDQogICAgbXRkX2luZm8ubXRkX2Jsb2Nrc2l6ZQkJPSBtZW1pbmZvLmVyYXNlc2l6ZTsNCiAgICBtdGRfaW5mby5tdGRfb29ic2l6ZQkJPSBtZW1pbmZvLm9vYnNpemU7DQogICAgbXRkX2luZm8ubXRkX3BhZ2VwZXJibG9jayAJPSBtZW1pbmZvLmVyYXNlc2l6ZSAvIG1lbWluZm8ud3JpdGVzaXplOw0KICAgIG10ZF9pbmZvLm10ZF9wYWdlc2l6ZSAJCT0gbWVtaW5mby53cml0ZXNpemU7DQogICAgbXRkX2luZm8ubXRkX3RvdGFsc2l6ZQkJPSBtZW1pbmZvLnNpemU7DQoNCiAgICBibG9ja19udW0gPSBtdGRfaW5mby5tdGRfdG90YWxzaXplIC8gbXRkX2luZm8ubXRkX2Jsb2Nrc2l6ZTsNCg0KICAgIGZvciAoaW5kZXggPSAwOyAoZ29vZF9pbmRleCA8IDIgJiYgaW5kZXggPCBibG9ja19udW0pOyBpbmRleCsrKQ0KICAgIHsNCg0KICAgICAgICBvZmZzID0gaW5kZXggKiBtdGRfaW5mby5tdGRfYmxvY2tzaXplOw0KICAgICAgICBpZiAoaW9jdGwobXRkX2luZm8ucGFydGlfZmlsZV9kZXNjLCBNRU1HRVRCQURCTE9DSywgJm9mZnMpID09IDApDQogICAgICAgIHsNCiAgICAgICAgICAgIGJsb2NrX2ZsYWcgPSBHT09EX0JMT0NLOw0KICAgICAgICB9DQogICAgICAgIGVsc2UNCiAgICAgICAgew0KICAgICAgICAgICAgZmxhZ3NfZXJyKCJmbGFncyBibG9jayBbJWRdIGlzIGJhZCwgZXJybm89JWQsIHN0cmVycm9yPVslc10iLCBpbmRleCwgZXJybm8sIHN0cmVycm9yKGVycm5vKSk7DQogICAgICAgICAgICBibG9ja19mbGFnID0gIEJBRF9CTE9DSzsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmIChibG9ja19mbGFnID09IEdPT0RfQkxPQ0spDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChsc2VlayhtdGRfaW5mby5wYXJ0aV9maWxlX2Rlc2MsIGluZGV4ICogbXRkX2luZm8ubXRkX2Jsb2Nrc2l6ZSwgU0VFS19TRVQpIDwgMCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBmbGFnc19lcnIoImxzZWVrIGVycm9yLCBlcnJubz0lZCwgc3RyZXJyb3I9WyVzXSIsIGVycm5vLCBzdHJlcnJvcihlcnJubykpOw0KICAgICAgICAgICAgICAgIGdvdG8gZXJyb3JfY2xvc2U7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGlmIChnb29kX2luZGV4ID09IDApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgcmVhZF9sZW4gPSByZWFkKG10ZF9pbmZvLnBhcnRpX2ZpbGVfZGVzYywgKHVuc2lnbmVkIGNoYXIqKXBfbWFpbiwgc2l6ZW9mKFRfRkxBR1NfSU5GTykpOw0KICAgICAgICAgICAgICAgICpwX21haW5faW5kZXggPSBpbmRleDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UgaWYgKGdvb2RfaW5kZXggPT0gMSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICByZWFkX2xlbiA9IHJlYWQobXRkX2luZm8ucGFydGlfZmlsZV9kZXNjLCAodW5zaWduZWQgY2hhciopcF9iYWNrdXAsIHNpemVvZihUX0ZMQUdTX0lORk8pKTsNCiAgICAgICAgICAgICAgICAqcF9iYWNrdXBfaW5kZXggPSBpbmRleDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgaWYgKHJlYWRfbGVuIDwgc2l6ZW9mKFRfRkxBR1NfSU5GTykpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgZmxhZ3NfZXJyKCJyZWFkIGxlbiAoJWQpIDwgbmVlZCBsZW4gKCVkKSIsIHJlYWRfbGVuLCBzaXplb2YoVF9GTEFHU19JTkZPKSk7DQogICAgICAgICAgICAgICAgZ290byBlcnJvcl9jbG9zZTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgZ29vZF9pbmRleCsrOw0KICAgICAgICB9DQoNCiAgICB9DQoNCiAgICBjbG9zZShmZF9kc3QpOw0KDQogICAgcmV0dXJuIDA7DQoNCmVycm9yX2Nsb3NlOg0KICAgIGNsb3NlKGZkX2RzdCk7DQoNCmVycm9yOg0KICAgIHJldHVybiAtMTsNCn0NCg0KDQpzdGF0aWMgaW50IHNldF9mbGFnc19pbmZvKFRfRkxBR1NfSU5GTyAqcF9mbGFnc19pbmZvLCBpbnQgKnBfbWFpbl9pbmRleCwgaW50ICpwX2JhY2t1cF9pbmRleCkNCnsNCiAgICBpbnQgcmV0ID0gLTE7DQogICAgaW50IGZkX2RzdCA9IC0xOw0KICAgIGNoYXIgbXRkX3BhdGhbTUFYX1BBVEhfTEVOXSA9IHswfTsNCiAgICBzdHJ1Y3QgbXRkX2luZm9fdXNlciBtZW1pbmZvID0gezB9Ow0KICAgIHBhcnRpdGlvbl9tdGRfaW5mb190IG10ZF9pbmZvID0gezB9Ow0KDQogICAgdW5zaWduZWQgY2hhciAqcmVhbF93cml0ZV9jb250ZW50ID0gTlVMTDsNCg0KICAgIGludCBpbmRleCAgPSAwOw0KICAgIGludCBibG9ja19udW0gPSAwOw0KICAgIGludCBtYWluX2luZGV4ID0gKnBfbWFpbl9pbmRleDsNCiAgICBpbnQgYmFja19pbmRleCA9ICpwX2JhY2t1cF9pbmRleDsNCg0KICAgIHJldCA9IG10ZF9nZXQoUEFSVElUSU9OX05BTUVfRkxBR1MsIERFVklDRV9NVEQsIG10ZF9wYXRoLCBNQVhfUEFUSF9MRU4pOw0KICAgIGlmIChyZXQgPCAwKQ0KICAgIHsNCiAgICAgICAgZmxhZ3NfZXJyKCJwYXJ0aXRpb24gWyVzXSBub3QgZm91bmQiLCBQQVJUSVRJT05fTkFNRV9GTEFHUyk7DQoJCQ0KICAgICAgICByZXR1cm4gLTE7DQogICAgfQ0KDQogICAgaWYgKChmZF9kc3QgPSBvcGVuKG10ZF9wYXRoLCBPX1JEV1IgfCBPX1NZTkMpKSA8IDApDQogICAgew0KICAgICAgICBmbGFnc19lcnIoIm9wZW4gZmxhc2ggZXJyb3IsIGVycm5vPSVkLCBzdHJlcnJvcj1bJXNdIiwgZXJybm8sIHN0cmVycm9yKGVycm5vKSk7DQogICAgICAgIHJldHVybiAtMTsNCiAgICB9DQoNCiAgICBpZiAoaW9jdGwoZmRfZHN0LCBNRU1HRVRJTkZPLCAmbWVtaW5mbykgIT0gMCkNCiAgICB7DQogICAgICAgIGZsYWdzX2VycigiZ2V0IGZsYXNoIGluZm8gZXJyb3IsIGVycm5vPSVkLCBzdHJlcnJvcj1bJXNdIiwgZXJybm8sIHN0cmVycm9yKGVycm5vKSk7DQogICAgICAgIGdvdG8gZXJyb3I7DQogICAgfQ0KDQogICAgbXRkX2luZm8ucGFydGlfZmlsZV9kZXNjIAk9IGZkX2RzdDsNCiAgICBtdGRfaW5mby5tdGRfYmxvY2tzaXplCQk9IG1lbWluZm8uZXJhc2VzaXplOw0KICAgIG10ZF9pbmZvLm10ZF9vb2JzaXplCQk9IG1lbWluZm8ub29ic2l6ZTsNCiAgICBtdGRfaW5mby5tdGRfcGFnZXBlcmJsb2NrIAk9IG1lbWluZm8uZXJhc2VzaXplIC8gbWVtaW5mby53cml0ZXNpemU7DQogICAgbXRkX2luZm8ubXRkX3BhZ2VzaXplIAkJPSBtZW1pbmZvLndyaXRlc2l6ZTsNCiAgICBtdGRfaW5mby5tdGRfdG90YWxzaXplCQk9IG1lbWluZm8uc2l6ZTsNCg0KICAgIGJsb2NrX251bSA9IG10ZF9pbmZvLm10ZF90b3RhbHNpemUgLyBtdGRfaW5mby5tdGRfYmxvY2tzaXplOw0KDQogICAgcmVhbF93cml0ZV9jb250ZW50ID0gKHVuc2lnbmVkIGNoYXIgKiltYWxsb2MobXRkX2luZm8ubXRkX2Jsb2Nrc2l6ZSk7DQogICAgaWYgKE5VTEwgPT0gcmVhbF93cml0ZV9jb250ZW50KQ0KICAgIHsNCiAgICAgICAgZmxhZ3NfZXJyKCJtYWxsb2MgYmxvY2sgZmFpbCIpOw0KICAgICAgICBnb3RvIGVycm9yOw0KICAgIH0NCg0KICAgIG1lbXNldChyZWFsX3dyaXRlX2NvbnRlbnQsIDB4RkYsIG10ZF9pbmZvLm10ZF9ibG9ja3NpemUpOw0KICAgIG1lbWNweShyZWFsX3dyaXRlX2NvbnRlbnQsIChjaGFyICopcF9mbGFnc19pbmZvLCBzaXplb2YoVF9GTEFHU19JTkZPKSk7DQoJDQogICAgZmxhZ3NfbG9nKCJiZWdpbiB0byB3cml0ZSBtYWluIGZsYWdzIik7DQoNCiAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBibG9ja19udW07IGluZGV4KyspDQogICAgew0KICAgICAgICBpZiAoaW5kZXggPT0gYmFja19pbmRleCkNCiAgICAgICAgew0KICAgICAgICAgICAgY29udGludWU7DQogICAgICAgIH0NCg0KICAgICAgICByZXQgPSB3cml0ZV9mbGFnc19pbmZvKCZtdGRfaW5mbywgaW5kZXgsIHJlYWxfd3JpdGVfY29udGVudCwgbXRkX2luZm8ubXRkX2Jsb2Nrc2l6ZSk7DQogICAgICAgIGlmIChyZXQgPT0gMCkNCiAgICAgICAgew0KICAgICAgICAgICAgLy8g0LSzybmmo6zNy7P2o6yyorj80MK12tK7v+nOu9bDDQogICAgICAgICAgICBmbGFnc19sb2coIm1haW4gZmxhZ3MgbG9jYXRpb246IFslZF0tPlslZF0iLCBtYWluX2luZGV4LCBpbmRleCk7DQogICAgICAgICAgICBtYWluX2luZGV4ID0gaW5kZXg7DQogICAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIGlmIChyZXQgPT0gQkFEX0JMT0NLKQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyDT9rW9u7W/6aOsz/K688z40ru/6Q0KICAgICAgICAgICAgZmxhZ3NfbG9nKCJmbGFncyBibG9jayBpbmRleCBbJWRdIGlzIGJhZCIsIGluZGV4KTsNCiAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICB9DQogICAgICAgIGVsc2UNCiAgICAgICAgew0KICAgICAgICAgICAgZmxhZ3NfZXJyKCJ3cml0ZSBtYWluIGZsYWdzIGZhaWwiKTsNCiAgICAgICAgICAgIG1haW5faW5kZXggPSAtMTsNCiAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgZmxhZ3NfbG9nKCJiZWdpbiB0byB3cml0ZSBiYWNrdXAgZmxhZ3MiKTsNCg0KICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IGJsb2NrX251bTsgaW5kZXgrKykNCiAgICB7DQogICAgICAgIGlmIChpbmRleCA9PSBtYWluX2luZGV4KQ0KICAgICAgICB7DQogICAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZsYWdzX2xvZygid3JpdGUgYmFja3VwIHRvIFslZF0gYmxvY2siLCBpbmRleCk7DQogICAgICAgIHJldCA9IHdyaXRlX2ZsYWdzX2luZm8oJm10ZF9pbmZvLCBpbmRleCwgcmVhbF93cml0ZV9jb250ZW50LCBtdGRfaW5mby5tdGRfYmxvY2tzaXplKTsNCiAgICAgICAgaWYgKHJldCA9PSAwKQ0KICAgICAgICB7DQogICAgICAgICAgICAvLyDQtLPJuaajrM3Ls/ajrLKiuPzQwrXa0ru/6c671sMNCiAgICAgICAgICAgIGZsYWdzX2xvZygiYmFja3VwIGZsYWdzIGxvY2F0aW9uOiBbJWRdLT5bJWRdIiwgYmFja19pbmRleCwgaW5kZXgpOw0KICAgICAgICAgICAgYmFja19pbmRleCA9IGluZGV4Ow0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICAgICAgZWxzZSBpZiAocmV0ID09IEJBRF9CTE9DSykNCiAgICAgICAgew0KICAgICAgICAgICAgLy8g0/a1vbu1v+mjrM/yuvPM+NK7v+kNCiAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICB9DQogICAgICAgIGVsc2UNCiAgICAgICAgew0KICAgICAgICAgICAgZmxhZ3NfZXJyKCJ3cml0ZSBiYWNrdXAgZmxhZ3MgZmFpbCIpOw0KICAgICAgICAgICAgYmFja19pbmRleCA9IC0xOw0KICAgICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICBpZiAobWFpbl9pbmRleCA9PSAtMSAmJiBiYWNrX2luZGV4ID09IC0xKQ0KICAgIHsNCiAgICAgICAgZ290byBlcnJvcjsNCiAgICB9DQogICAgZWxzZQ0KICAgIHsNCiAgICAgICAgcmV0ID0gMDsNCiAgICAgICAgZ290byBlbmQ7DQogICAgfQ0KDQplcnJvcjoNCiAgICByZXQgPSAtMTsNCg0KZW5kOg0KICAgIGNsb3NlKGZkX2RzdCk7DQoJDQoJaWYoTlVMTCAhPSByZWFsX3dyaXRlX2NvbnRlbnQpDQoJew0KCQlmcmVlKHJlYWxfd3JpdGVfY29udGVudCk7DQoJCXJlYWxfd3JpdGVfY29udGVudCA9IE5VTEw7DQoJfQ0KCQ0KICAgIHJldHVybiByZXQ7DQp9DQoNCg0Kc3RhdGljIHZvaWQgY29weV9mbGFnc19pbmZvKFRfRkxBR1NfSU5GTyAqZHN0LCBUX0ZMQUdTX0lORk8gKnNyYykNCnsNCgltZW1jcHkoZHN0LCBzcmMsIHNpemVvZihUX0ZMQUdTX0lORk8pKTsNCg0KCXJldHVybjsNCn0NCg0KDQpzdGF0aWMgaW50IGdldF9jdXJyZW50X3N5c3RlbSgpDQp7DQogICAgY2hhciBidWZbMTAyNF0gPSB7MH07DQoNCiAgICBjaGFyICpwYXJhID0gTlVMTDsNCiAgICBpbnQgbWF0Y2hlcyA9IDA7DQoNCiAgICBGSUxFICpmZF9jbWQgPSBOVUxMOw0KICAgIGNoYXIgKmxpbmVfc3RyID0gTlVMTDsNCg0KICAgIGludCBjdXJyZW50X3N5c3RlbSA9IC0xOw0KDQoNCiAgICBmZF9jbWQgPSBmb3BlbihGSUxFX1BBVEhfUFJPQ19DTURMSU5FLCAiciIpOw0KICAgIGlmICghZmRfY21kKQ0KICAgIHsNCiAgICAgICAgcHJpbnRmKCJPcGVuIGZpbGUgJXMgZXJyb3IsIGVycm9yOiVzIiwgRklMRV9QQVRIX1BST0NfQ01ETElORSwgc3RyZXJyb3IoZXJybm8pKTsNCiAgICAgICAgcmV0dXJuIFNZU1RFTV9JTkRFWF9VTktOT1dOOw0KICAgIH0NCg0KICAgIHdoaWxlICghZmVvZihmZF9jbWQpKQ0KICAgIHsNCiAgICAgICAgbWVtc2V0KGJ1ZiwgMCwgc2l6ZW9mKGJ1ZikpOw0KICAgICAgICBsaW5lX3N0ciA9IGZnZXRzKGJ1Ziwgc2l6ZW9mKGJ1ZiksIGZkX2NtZCk7DQoNCiAgICAgICAgaWYgKE5VTEwgPT0gbGluZV9zdHIpDQogICAgICAgIHsNCiAgICAgICAgICAgIHByaW50ZigiZ2V0IGluZm8gZnJvbSAvcHJvYy9jbWRsaW5lIGVycm9yOiVzIiwgc3RyZXJyb3IoZXJybm8pKTsNCiAgICAgICAgICAgIGdvdG8gZW5kOw0KICAgICAgICB9DQoNCiAgICAgICAgcHJpbnRmKCJidWZmOiVzIiwgYnVmKTsNCg0KICAgICAgICBwYXJhID0gc3RydG9rKGJ1ZiwgIiAiKTsNCiAgICAgICAgd2hpbGUgKHBhcmEpDQogICAgICAgIHsNCiAgICAgICAgICAgIHByaW50ZigicGFyYTolcyIsIHBhcmEpOw0KICAgICAgICAgICAgaWYgKHN0cm5jbXAocGFyYSwgUFJPQ19DTURMSU5FX1NZU1RFTV9BX0ZMQUcsIHN0cmxlbihQUk9DX0NNRExJTkVfU1lTVEVNX0FfRkxBRykpID09IDApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgY3VycmVudF9zeXN0ZW0gPSBTWVNURU1fSU5ERVhfMTsNCiAgICAgICAgICAgICAgICBnb3RvIGVuZDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UgaWYgKHN0cm5jbXAocGFyYSwgUFJPQ19DTURMSU5FX1NZU1RFTV9CX0ZMQUcsIHN0cmxlbihQUk9DX0NNRExJTkVfU1lTVEVNX0JfRkxBRykpID09IDApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgY3VycmVudF9zeXN0ZW0gPSBTWVNURU1fSU5ERVhfMjsNCiAgICAgICAgICAgICAgICBnb3RvIGVuZDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvLzoNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHBhcmEgPSBzdHJ0b2soTlVMTCwgIiAiKTsNCiAgICAgICAgfQ0KICAgIH0NCg0KZW5kOg0KICAgIGlmIChmZF9jbWQpDQogICAgew0KICAgICAgICBmY2xvc2UoZmRfY21kKTsNCiAgICB9DQoJDQogICAgcmV0dXJuIGN1cnJlbnRfc3lzdGVtOw0KfQ0KDQoNCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogKiAJCQkJCSBHbG9iYWwgZnVuY3Rpb24gaW1wbGVtZW50YXRpb25zCQkJCQkJICAgKg0KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCmludCBmbGFnc19pbml0KCkNCnsNCglUX0ZMQUdTX0lORk8gZmxhZ3NfaW5mbyA9IHswfTsNCglpbnQgbWFpbl9pbmRleCA9IDA7DQoJaW50IGJhY2tfaW5kZXggPSAxOw0KCWludCByZXQgPSAtMTsNCglpbnQgZmRfZHN0ID0gLTE7DQoJY2hhciBtdGRfcGF0aFtNQVhfUEFUSF9MRU5dID0gezB9Ow0KCXN0cnVjdCBtdGRfaW5mb191c2VyIG1lbWluZm8gPSB7MH07DQoJcGFydGl0aW9uX210ZF9pbmZvX3QgbXRkX2luZm8gPSB7MH07DQoNCgl1bnNpZ25lZCBjaGFyICpyZWFsX3dyaXRlX2NvbnRlbnQgPSBOVUxMOw0KCVRfRkxBR1NfSU5GTyAqcF93cml0ZSA9IE5VTEw7DQoNCglpbnQgaW5kZXggID0gMDsNCglpbnQgYmxvY2tfbnVtID0gMDsNCglpbnQgYWxyZWFkeV93cml0ZSA9IDA7DQoJDQoJdW5zaWduZWQgaW50IGNyY18zMiA9IDA7DQoJdW5zaWduZWQgaW50IGNyY18zMl8xID0gMDsNCg0KICAgIGZsYWdzX2luZm8ubWFnaWNfc3RhcnQgPSBGTEFHU19NQUdJQzsNCgkNCiAgICBmbGFnc19pbmZvLmJvb3RfZm90YV9mbGFnLmJvb3RfdG8gPSBEVUFMX1NZU1RFTTsNCiAgICBmbGFnc19pbmZvLmJvb3RfZm90YV9mbGFnLmZvdGFfc3RhdHVzID0gMDsNCiAgICBmbGFnc19pbmZvLmJvb3RfZm90YV9mbGFnLnN5c3RlbS5zdGF0dXMgPSBEVUFMU1lTVEVNX1NUQVRVU19CT09UQUJMRTsNCiAgICBmbGFnc19pbmZvLmJvb3RfZm90YV9mbGFnLnN5c3RlbS50cnlfY250ID0gMDsNCiAgICBmbGFnc19pbmZvLmJvb3RfZm90YV9mbGFnLnN5c3RlbTIuc3RhdHVzID0gRFVBTFNZU1RFTV9TVEFUVVNfQk9PVEFCTEU7DQogICAgZmxhZ3NfaW5mby5ib290X2ZvdGFfZmxhZy5zeXN0ZW0yLnRyeV9jbnQgPSAwOw0KDQogICAgZmxhZ3NfaW5mby5ib290X2Vudi5kdWFsc3lzX3R5cGUgPSBEVUFMU1lTVEVNX0FCOw0KDQoJZmxhZ3NfaW5mby51Ymlmc19zdGF0dXMuZnNfc3RhdHVzID0gMDsNCgkNCiAgICBmbGFnc19pbmZvLm1hZ2ljX2VuZCA9IEZMQUdTX01BR0lDOw0KDQoJY3JjMzJpbml0X2xlKCk7DQoJY3JjXzMyID0gY3JjMzJfbGUoMCwgKHVuc2lnbmVkIGNoYXIgY29uc3QgKikoJmZsYWdzX2luZm8pLCA1MTIpOw0KCWZsYWdzX2xvZygiaW5pdCBjcmNfMzI9JXUiLCBjcmNfMzIpOw0KDQoJZmxhZ3NfaW5mby5jcmMzMiA9IGNyY18zMjsNCgkNCgljcmMzMmluaXRfbGUoKTsNCgljcmNfMzJfMSA9IGNyYzMyX2xlKDAsICh1bnNpZ25lZCBjaGFyIGNvbnN0ICopKCZmbGFnc19pbmZvKSwgc2l6ZW9mKGZsYWdzX2luZm8pKTsNCglmbGFnc19sb2coImluaXQgY3JjXzMyXzE9JXUiLCBjcmNfMzJfMSk7DQoNCglmbGFnc19pbmZvLmNyYzMyXzEgPSBjcmNfMzJfMTsNCg0KCXJldCA9IG10ZF9nZXQoUEFSVElUSU9OX05BTUVfRkxBR1MsIERFVklDRV9NVEQsIG10ZF9wYXRoLCBNQVhfUEFUSF9MRU4pOw0KCWlmIChyZXQgPCAwKQ0KCXsNCgkJZmxhZ3NfZXJyKCJwYXJ0aXRpb24gWyVzXSBub3QgZm91bmQiLCBQQVJUSVRJT05fTkFNRV9GTEFHUyk7DQoJCQ0KCQlyZXR1cm4gLTE7DQoJfQ0KDQoJaWYgKChmZF9kc3QgPSBvcGVuKG10ZF9wYXRoLCBPX1JEV1IgfCBPX1NZTkMpKSA8IDApDQoJew0KCQlmbGFnc19lcnIoIm9wZW4gZmxhc2ggZXJyb3IsIGVycm5vPSVkLCBzdHJlcnJvcj1bJXNdIiwgZXJybm8sIHN0cmVycm9yKGVycm5vKSk7DQoJCQ0KCQlyZXR1cm4gLTE7DQoJfQ0KDQoJaWYgKGlvY3RsKGZkX2RzdCwgTUVNR0VUSU5GTywgJm1lbWluZm8pICE9IDApDQoJew0KCQlmbGFnc19lcnIoImdldCBmbGFzaCBpbmZvIGVycm9yLCBlcnJubz0lZCwgc3RyZXJyb3I9WyVzXSIsIGVycm5vLCBzdHJlcnJvcihlcnJubykpOw0KCQkNCgkJZ290byBlcnJvcjsNCgl9DQoNCgltdGRfaW5mby5wYXJ0aV9maWxlX2Rlc2MgCT0gZmRfZHN0Ow0KCW10ZF9pbmZvLm10ZF9ibG9ja3NpemUJCT0gbWVtaW5mby5lcmFzZXNpemU7DQoJbXRkX2luZm8ubXRkX29vYnNpemUJCT0gbWVtaW5mby5vb2JzaXplOw0KCW10ZF9pbmZvLm10ZF9wYWdlcGVyYmxvY2sJPSBtZW1pbmZvLmVyYXNlc2l6ZSAvIG1lbWluZm8ud3JpdGVzaXplOw0KCW10ZF9pbmZvLm10ZF9wYWdlc2l6ZQkJPSBtZW1pbmZvLndyaXRlc2l6ZTsNCgltdGRfaW5mby5tdGRfdG90YWxzaXplCQk9IG1lbWluZm8uc2l6ZTsNCg0KCWJsb2NrX251bSA9IG10ZF9pbmZvLm10ZF90b3RhbHNpemUgLyBtdGRfaW5mby5tdGRfYmxvY2tzaXplOw0KDQoJcmVhbF93cml0ZV9jb250ZW50ID0gKHVuc2lnbmVkIGNoYXIgKiltYWxsb2MobXRkX2luZm8ubXRkX2Jsb2Nrc2l6ZSk7DQoJaWYgKE5VTEwgPT0gcmVhbF93cml0ZV9jb250ZW50KQ0KCXsNCgkJZmxhZ3NfZXJyKCJtYWxsb2MgZm9yIGJsb2NrIGZhaWwiKTsNCgkJDQoJCWdvdG8gZXJyb3I7DQoJfQ0KDQoJbWVtc2V0KHJlYWxfd3JpdGVfY29udGVudCwgMHhGRiwgbXRkX2luZm8ubXRkX2Jsb2Nrc2l6ZSk7DQoJbWVtY3B5KHJlYWxfd3JpdGVfY29udGVudCwgKGNoYXIgKikoJmZsYWdzX2luZm8pLCBzaXplb2YoVF9GTEFHU19JTkZPKSk7DQoNCglmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBibG9ja19udW07IGluZGV4KyspDQoJew0KCQlpZiAoYWxyZWFkeV93cml0ZSA+PSBGTEFHU19JTklUX1ZBTElEX0JMT0NLU19OVU0pDQoJCXsNCgkJCWJyZWFrOw0KCQl9DQoNCgkJcmV0ID0gd3JpdGVfZmxhZ3NfaW5mbygmbXRkX2luZm8sIGluZGV4LCByZWFsX3dyaXRlX2NvbnRlbnQsIG10ZF9pbmZvLm10ZF9ibG9ja3NpemUpOw0KCQlpZiAocmV0ID09IDApDQoJCXsNCgkJCWFscmVhZHlfd3JpdGUrKzsNCgkJCWZsYWdzX2xvZygid3JpdGUgaW5pdCB2YWxpZCBibG9jayBudW06ICVkIiwgYWxyZWFkeV93cml0ZSk7DQoJCQkNCgkJCWNvbnRpbnVlOw0KCQl9DQoJCWVsc2UgaWYgKEJBRF9CTE9DSyA9PSByZXQpDQoJCXsNCgkJCWNvbnRpbnVlOw0KCQl9DQoJfQ0KDQoJaWYgKGFscmVhZHlfd3JpdGUgPj0gMikNCgl7DQoJCWZsYWdzX2xvZygiaW5pdCBzeXN0ZW0gc3RhdHVzIHN1Y2Nlc3MsIGFscmVhZCB3cml0ZSBibG9jazogJWQiLCBhbHJlYWR5X3dyaXRlKTsNCgkJcmV0ID0gMDsNCgl9DQoJZWxzZQ0KCXsNCgkJZmxhZ3NfbG9nKCJpbml0IHN5c3RlbSBzdGF0dXMgZmFpbCwgYWxyZWFkIHdyaXRlIGJsb2NrOiAlZCIsIGFscmVhZHlfd3JpdGUpOw0KCQlyZXQgPSAtMTsNCgl9DQoNCglnb3RvIGVuZDsNCg0KZXJyb3I6DQoJcmV0ID0gLTE7DQoNCmVuZDoNCgljbG9zZShmZF9kc3QpOw0KCQ0KCWlmKE5VTEwgIT0gcmVhbF93cml0ZV9jb250ZW50KQ0KCXsNCgkJZnJlZShyZWFsX3dyaXRlX2NvbnRlbnQpOw0KCQlyZWFsX3dyaXRlX2NvbnRlbnQgPSBOVUxMOw0KCX0NCgkNCglyZXR1cm4gcmV0Ow0KfQ0KDQoNCmludCBmbGFnc19nZXQoVF9GTEFHU19JTkZPICpwX2ZsYWdzX2luZm8pDQp7DQogICAgVF9GTEFHU19JTkZPIG1haW5fZmxhZyA9IHswfTsNCiAgICBUX0ZMQUdTX0lORk8gYmFja3VwX2ZsYWcgPSB7MH07DQoJVF9GTEFHU19JTkZPIHBfZmxhZ3NfaW5mb190bXAgPSB7MH07DQoJY2hhciBkZWx0YV9GW0lNR19OQU1FX0xFTl0gPSB7MH07DQoNCiAgICBpbnQgbWFpbl9pbmRleCA9IDA7DQogICAgaW50IGJhY2t1cF9pbmRleCA9IDE7DQoNCgl1bnNpZ25lZCBpbnQgY3JjMzJfbWFpbiA9IDA7DQoJdW5zaWduZWQgaW50IGNyYzMyX2JhY2t1cCA9IDA7DQoJDQoJdW5zaWduZWQgaW50IGNyYzMyX2xlX21haW4gPSAwOw0KCXVuc2lnbmVkIGludCBjcmMzMl9sZV9iYWNrdXAgPSAwOw0KDQoJaWYgKE5VTEwgPT0gcF9mbGFnc19pbmZvKQ0KCXsNCgkJZmxhZ3NfZXJyKCJpbnZhbGlkIHBhcmFtIE5VTEwiKTsNCgkJDQoJCXJldHVybiAtMTsNCgl9DQoNCiAgICBpZiAoZ2V0X2ZsYWdzX2luZm8oJm1haW5fZmxhZywgJm1haW5faW5kZXgsICZiYWNrdXBfZmxhZywgJmJhY2t1cF9pbmRleCkgIT0gMCkNCiAgICB7DQogICAgCWZsYWdzX2VycigiZ2V0IGZsYWdzIGluZm8gZmFpbCIpOw0KCQkNCiAgICAgICAgcmV0dXJuIC0xOw0KICAgIH0NCgkNCglmbGFnc19sb2coIm1haW5fZmxhZyBjcmMzMj0ldSwgY3JjMzJfMT0ldSIsIG1haW5fZmxhZy5jcmMzMiwgbWFpbl9mbGFnLmNyYzMyXzEpOw0KCWZsYWdzX2xvZygiYmFja3VwX2ZsYWcgY3JjMzI9JXUsIGNyYzMyXzE9JXUiLCBiYWNrdXBfZmxhZy5jcmMzMiwgYmFja3VwX2ZsYWcuY3JjMzJfMSk7DQoNCgltZW1zZXQoZGVsdGFfRiwgMHhGRiwgSU1HX05BTUVfTEVOKTsNCg0KCWlmICgoMCA9PSBtZW1jbXAobWFpbl9mbGFnLmltZ19zaXplWzBdLm5hbWUsIGRlbHRhX0YsIElNR19OQU1FX0xFTikpICYmICgwID09IG1lbWNtcChiYWNrdXBfZmxhZy5pbWdfc2l6ZVswXS5uYW1lLCBkZWx0YV9GLCBJTUdfTkFNRV9MRU4pKSkNCgl7DQoJCW1lbWNweSgmcF9mbGFnc19pbmZvX3RtcCwgJm1haW5fZmxhZywgc2l6ZW9mKFRfRkxBR1NfSU5GTykpOw0KCQltZW1zZXQocF9mbGFnc19pbmZvX3RtcC5pbWdfc2l6ZVswXS5uYW1lLCAwLCBzaXplb2YoVF9GTEFHU19JTkZPKS01MTIpOw0KDQoJCWNyYzMyaW5pdF9sZSgpOw0KCQlwX2ZsYWdzX2luZm9fdG1wLmNyYzMyXzEgPSBjcmMzMl9sZSgwLCAodW5zaWduZWQgY2hhciBjb25zdCAqKSgmcF9mbGFnc19pbmZvX3RtcCksIHNpemVvZihUX0ZMQUdTX0lORk8pKTsNCgkJZmxhZ3NfbG9nKCJmaXggb2xkLCBzZXQgY3JjMzJfMT0ldSIsIHBfZmxhZ3NfaW5mb190bXAuY3JjMzJfMSk7DQoJCQ0KCQlpZiAoc2V0X2ZsYWdzX2luZm8oJnBfZmxhZ3NfaW5mb190bXAsICZtYWluX2luZGV4LCAmYmFja3VwX2luZGV4KSAhPSAwKQ0KCQl7DQoJCQlmbGFnc19lcnIoImZpeCBvbGQsIHNldCBmbGFncyBpbmZvIGZhaWwiKTsNCgkJCXJldHVybiAtMTsNCgkJfQ0KCQkNCgkJY29weV9mbGFnc19pbmZvKHBfZmxhZ3NfaW5mbywgJm1haW5fZmxhZyk7DQoJCXJldHVybiAwOw0KCX0NCg0KCWNyYzMyX21haW4gPSBtYWluX2ZsYWcuY3JjMzJfMTsNCgljcmMzMl9iYWNrdXAgPSBiYWNrdXBfZmxhZy5jcmMzMl8xOw0KDQoJbWFpbl9mbGFnLmNyYzMyXzEgPSAwOw0KCWJhY2t1cF9mbGFnLmNyYzMyXzEgPSAwOw0KCQ0KCWNyYzMyaW5pdF9sZSgpOw0KCQ0KCWNyYzMyX2xlX21haW4gPSBjcmMzMl9sZSgwLCAodW5zaWduZWQgY2hhciBjb25zdCAqKSgmbWFpbl9mbGFnKSwgc2l6ZW9mKG1haW5fZmxhZykpOw0KCWZsYWdzX2xvZygiY3JjMzJfbGVfbWFpbiBjcmMzMj0ldSIsIGNyYzMyX2xlX21haW4pOw0KCQ0KCWNyYzMyX2xlX2JhY2t1cCA9IGNyYzMyX2xlKDAsICh1bnNpZ25lZCBjaGFyIGNvbnN0ICopKCZiYWNrdXBfZmxhZyksIHNpemVvZihiYWNrdXBfZmxhZykpOw0KCWZsYWdzX2xvZygiY3JjMzJfbGVfYmFja3VwIGNyYzMyPSV1IiwgY3JjMzJfbGVfYmFja3VwKTsNCg0KICAgIGlmIChjcmMzMl9tYWluID09IGNyYzMyX2xlX21haW4pDQogICAgew0KICAgICAgICBjb3B5X2ZsYWdzX2luZm8ocF9mbGFnc19pbmZvLCAmbWFpbl9mbGFnKTsNCgkJDQogICAgICAgIHJldHVybiAwOw0KICAgIH0NCgkNCiAgICBpZiAoY3JjMzJfYmFja3VwID09IGNyYzMyX2xlX2JhY2t1cCkNCiAgICB7DQogICAgICAgIGNvcHlfZmxhZ3NfaW5mbyhwX2ZsYWdzX2luZm8sICZiYWNrdXBfZmxhZyk7DQoJCQ0KICAgICAgICByZXR1cm4gMDsNCiAgICB9DQoNCiAgICBmbGFnc19lcnIoImRvIG5vdCBmaW5kIHZhbGlkIGZsYWdzIGluZm8iKTsNCgkNCiAgICByZXR1cm4gLTE7DQp9DQoNCg0KaW50IGZsYWdzX3NldChUX0ZMQUdTX0lORk8gKnBfZmxhZ3NfaW5mbykNCnsNCglUX0ZMQUdTX0lORk8gbWFpbl9mbGFnID0gezB9Ow0KICAgIFRfRkxBR1NfSU5GTyBiYWNrdXBfZmxhZyA9IHswfTsNCiAgICBpbnQgbWFpbl9pbmRleCA9IDA7DQogICAgaW50IGJhY2t1cF9pbmRleCA9IDE7DQoJDQoJaWYgKE5VTEwgPT0gcF9mbGFnc19pbmZvKQ0KCXsNCgkJZmxhZ3NfZXJyKCJpbnZhbGlkIHBhcmFtIE5VTEwiKTsNCgkJDQoJCXJldHVybiAtMTsNCgl9DQoNCglpZiAoKEZMQUdTX01BR0lDICE9IHBfZmxhZ3NfaW5mby0+bWFnaWNfc3RhcnQpIHx8IChGTEFHU19NQUdJQyAhPSBwX2ZsYWdzX2luZm8tPm1hZ2ljX2VuZCkpDQoJew0KCQlmbGFnc19lcnIoImludmFsaWQgbWFnaWMiKTsNCgkJDQoJCXJldHVybiAtMTsNCgl9DQoJDQogICAgaWYgKGdldF9mbGFnc19pbmZvKCZtYWluX2ZsYWcsICZtYWluX2luZGV4LCAmYmFja3VwX2ZsYWcsICZiYWNrdXBfaW5kZXgpICE9IDApDQogICAgew0KICAgIAlmbGFnc19lcnIoImdldCBmbGFncyBpbmZvIGZhaWwiKTsNCgkJDQogICAgICAgIHJldHVybiAtMTsNCiAgICB9DQoNCgljcmMzMmluaXRfbGUoKTsNCglwX2ZsYWdzX2luZm8tPmNyYzMyID0gMDsNCglwX2ZsYWdzX2luZm8tPmNyYzMyID0gY3JjMzJfbGUoMCwgKHVuc2lnbmVkIGNoYXIgY29uc3QgKilwX2ZsYWdzX2luZm8sIDUxMik7DQoJZmxhZ3NfbG9nKCJzZXQgY3JjMzI9JXUiLCBwX2ZsYWdzX2luZm8tPmNyYzMyKTsNCgkNCgljcmMzMmluaXRfbGUoKTsNCglwX2ZsYWdzX2luZm8tPmNyYzMyXzEgPSAwOw0KCXBfZmxhZ3NfaW5mby0+Y3JjMzJfMSA9IGNyYzMyX2xlKDAsICh1bnNpZ25lZCBjaGFyIGNvbnN0ICopcF9mbGFnc19pbmZvLCBzaXplb2YoVF9GTEFHU19JTkZPKSk7DQoJZmxhZ3NfbG9nKCJzZXQgY3JjMzJfMT0ldSIsIHBfZmxhZ3NfaW5mby0+Y3JjMzJfMSk7DQoNCiAgICBpZiAoc2V0X2ZsYWdzX2luZm8ocF9mbGFnc19pbmZvLCAmbWFpbl9pbmRleCwgJmJhY2t1cF9pbmRleCkgIT0gMCkNCiAgICB7DQogICAgICAgIGZsYWdzX2Vycigic2V0IHViaWZzIHN0YXR1cyBmYWlsIik7DQoJCQ0KICAgICAgICByZXR1cm4gLTE7DQogICAgfQ0KDQoJcmV0dXJuIDA7DQp9DQoNCg0KaW50IGZsYWdzX2dldF91Ymlmc19zdGF0dXMoVF9VQklGU19TVEFUVVMgKnBfdWJpZnNfc3RhdHVzKQ0Kew0KCVRfRkxBR1NfSU5GTyBwX2ZsYWdzX2luZm8gPSB7MH07DQoJDQoJaWYgKE5VTEwgPT0gcF91Ymlmc19zdGF0dXMpDQoJew0KCQlmbGFnc19lcnIoImludmFsaWQgcGFyYW0gTlVMTCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KDQoJaWYgKDAgPT0gZmxhZ3NfZ2V0KCZwX2ZsYWdzX2luZm8pKQ0KCXsNCgkJcF91Ymlmc19zdGF0dXMtPmZzX3N0YXR1cyA9IHBfZmxhZ3NfaW5mby51Ymlmc19zdGF0dXMuZnNfc3RhdHVzOw0KCQlzdHJuY3B5KHBfdWJpZnNfc3RhdHVzLT5mc19tdGRfbmFtZSwgcF9mbGFnc19pbmZvLnViaWZzX3N0YXR1cy5mc19tdGRfbmFtZSwgc2l6ZW9mKHBfdWJpZnNfc3RhdHVzLT5mc19tdGRfbmFtZSkpOw0KCQlzdHJuY3B5KHBfdWJpZnNfc3RhdHVzLT5mc191Ymlfdm9sX25hbWUsIHBfZmxhZ3NfaW5mby51Ymlmc19zdGF0dXMuZnNfdWJpX3ZvbF9uYW1lLCBzaXplb2YocF91Ymlmc19zdGF0dXMtPmZzX3ViaV92b2xfbmFtZSkpOw0KCQkNCgkJcmV0dXJuIDA7DQoJfQ0KCWVsc2UNCgl7DQoJICAgIGZsYWdzX2VycigiZG8gbm90IGZpbmQgdmFsaWQgZmxhZ3MgaW5mbyIpOw0KCSAgICByZXR1cm4gLTE7DQoJfQ0KfQ0KDQoNCmludCBmbGFnc19zZXRfdWJpZnNfc3RhdHVzKFRfVUJJRlNfU1RBVFVTICpwX3ViaWZzX3N0YXR1cykNCnsNCglUX0ZMQUdTX0lORk8gcF9mbGFnc19pbmZvID0gezB9Ow0KCQ0KCWlmIChOVUxMID09IHBfdWJpZnNfc3RhdHVzKQ0KCXsNCgkJZmxhZ3NfZXJyKCJpbnZhbGlkIHBhcmFtIE5VTEwiKTsNCgkJcmV0dXJuIC0xOw0KCX0NCg0KCWlmICgwICE9IGZsYWdzX2dldCgmcF9mbGFnc19pbmZvKSkNCgl7DQoJCWZsYWdzX2VycigiZ2V0IHViaWZzIHN0YXR1cyBpbnZhbGlkIik7DQoJCXJldHVybiAtMTsNCgl9DQoJDQoJbWVtY3B5KCYocF9mbGFnc19pbmZvLnViaWZzX3N0YXR1cyksIHBfdWJpZnNfc3RhdHVzLCBzaXplb2YoVF9VQklGU19TVEFUVVMpKTsNCg0KCWlmICgwICE9IGZsYWdzX3NldCgmcF9mbGFnc19pbmZvKSkNCgl7DQoJCWZsYWdzX2Vycigic2V0IHViaWZzIHN0YXR1cyBmYWlsIik7DQoJCXJldHVybiAtMTsNCgl9DQoJDQogICAgcmV0dXJuIDA7DQp9DQoNCg0KdW5zaWduZWQgaW50IGZsYWdzX2dldF9udnJvZmxhZyh2b2lkKQ0Kew0KCVRfRkxBR1NfSU5GTyB0X2ZsYWcgPSB7MH07DQoNCglpZiAoZmxhZ3NfZ2V0KCZ0X2ZsYWcpICE9IDApDQoJCXJldHVybiBOVlJPX0lOVkFMSUQ7DQoJcmV0dXJuIHRfZmxhZy5udnJvX2ZsYWc7DQp9DQoNCg0KaW50IGZsYWdzX3NldF9udnJvZmxhZyh1bnNpZ25lZCBpbnQgZmxhZykNCnsNCglUX0ZMQUdTX0lORk8gdF9mbGFnID0gezB9Ow0KDQoJaWYgKGZsYWdzX2dldCgmdF9mbGFnKSAhPSAwKQ0KCQlyZXR1cm4gLTE7DQoJaWYgKHRfZmxhZy5udnJvX2ZsYWcgPT0gZmxhZykNCgkJcmV0dXJuIDA7DQoJaWYgKGZsYWcgPT0gTlZST19SRVNUT1JJTkcpDQoJew0KCQlpZiAodF9mbGFnLm52cm9fZmxhZyAhPSBOVlJPX0JBQ0tFRF9VUCkNCgkJew0KCQkJcHJpbnRmKCJbZXJyb3JdZmxhZ3MgbnZybyBvbmx5IE5WUk9fQkFDS0VEX1VQIHN3aXRjaCB0byBOVlJPX1JFU1RPUklOR1xuIik7DQoJCQlyZXR1cm4gLTE7DQoJCX0NCgl9DQoJdF9mbGFnLm52cm9fZmxhZyA9IGZsYWc7DQoNCglyZXR1cm4gZmxhZ3Nfc2V0KCZ0X2ZsYWcpOw0KfQ0KDQoNCmludCBmbGFnc19nZXRfY3VycmVudF9zeXN0ZW0oKQ0Kew0KICAgIGludCBjdXJyZW50ID0gZ2V0X2N1cnJlbnRfc3lzdGVtKCk7DQoJDQogICAgaWYgKGN1cnJlbnQgPT0gMSkNCiAgICB7DQogICAgICAgIHJldHVybiBEVUFMX1NZU1RFTTsNCiAgICB9DQogICAgZWxzZSBpZiAoY3VycmVudCA9PSAyKQ0KICAgIHsNCiAgICAgICAgcmV0dXJuIERVQUxfU1lTVEVNMjsNCiAgICB9DQoNCiAgICByZXR1cm4gLTE7DQp9DQoNCg0KLyogtMtBUEm99tPD09q197Lio6zV/cq9tPrC67K7v8nKudPDICovDQppbnQgZmxhZ3NfZ2V0X25vY3JjKFRfRkxBR1NfSU5GTyAqcF9mbGFnc19pbmZvKQ0Kew0KICAgIFRfRkxBR1NfSU5GTyBtYWluX2ZsYWcgPSB7MH07DQogICAgVF9GTEFHU19JTkZPIGJhY2t1cF9mbGFnID0gezB9Ow0KICAgIGludCBtYWluX2luZGV4ID0gMDsNCiAgICBpbnQgYmFja3VwX2luZGV4ID0gMTsNCg0KCWlmIChOVUxMID09IHBfZmxhZ3NfaW5mbykNCgl7DQoJCWZsYWdzX2VycigiaW52YWxpZCBwYXJhbSBOVUxMIik7DQoJCXJldHVybiAtMTsNCgl9DQoNCiAgICBpZiAoZ2V0X2ZsYWdzX2luZm8oJm1haW5fZmxhZywgJm1haW5faW5kZXgsICZiYWNrdXBfZmxhZywgJmJhY2t1cF9pbmRleCkgIT0gMCkNCiAgICB7DQogICAgCWZsYWdzX2VycigiZ2V0IGZsYWdzIGluZm8gZmFpbCIpOw0KICAgICAgICByZXR1cm4gLTE7DQogICAgfQ0KCQ0KCWlmICgwICE9IG1lbWNtcCgmbWFpbl9mbGFnLCAmYmFja3VwX2ZsYWcsIHNpemVvZihUX0ZMQUdTX0lORk8pKSkNCgl7DQoJICAgIGZsYWdzX2VycigibWFpbiBmbGFnIGFuZCBiYWNrdXAgZmxhZyBhcmUgZGlmZmVyZW50Iik7DQogICAgICAgIHJldHVybiAtMTsNCgl9DQoJDQoJY29weV9mbGFnc19pbmZvKHBfZmxhZ3NfaW5mbywgJm1haW5fZmxhZyk7DQoJcF9mbGFnc19pbmZvLT5jcmMzMiA9IG1haW5fZmxhZy5jcmMzMjsNCg0KICAgIHJldHVybiAwOw0KfQ0KDQoNCi8qILTLQVBJvfbTw9Patfey4qOs1f3KvbT6wuuyu7/JyrnTwyAqLw0KaW50IGZsYWdzX3NldF9ub2NyYyhUX0ZMQUdTX0lORk8gKnBfZmxhZ3NfaW5mbykNCnsNCglUX0ZMQUdTX0lORk8gbWFpbl9mbGFnID0gezB9Ow0KICAgIFRfRkxBR1NfSU5GTyBiYWNrdXBfZmxhZyA9IHswfTsNCiAgICBpbnQgbWFpbl9pbmRleCA9IDA7DQogICAgaW50IGJhY2t1cF9pbmRleCA9IDE7DQoJDQoJaWYgKE5VTEwgPT0gcF9mbGFnc19pbmZvKQ0KCXsNCgkJZmxhZ3NfZXJyKCJpbnZhbGlkIHBhcmFtIE5VTEwiKTsNCgkJcmV0dXJuIC0xOw0KCX0NCg0KCWlmICgoRkxBR1NfTUFHSUMgIT0gcF9mbGFnc19pbmZvLT5tYWdpY19zdGFydCkgfHwgKEZMQUdTX01BR0lDICE9IHBfZmxhZ3NfaW5mby0+bWFnaWNfZW5kKSkNCgl7DQoJCWZsYWdzX2VycigiaW52YWxpZCBtYWdpYyIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KCQ0KICAgIGlmIChnZXRfZmxhZ3NfaW5mbygmbWFpbl9mbGFnLCAmbWFpbl9pbmRleCwgJmJhY2t1cF9mbGFnLCAmYmFja3VwX2luZGV4KSAhPSAwKQ0KICAgIHsNCiAgICAJZmxhZ3NfZXJyKCJnZXQgZmxhZ3MgaW5mbyBmYWlsIik7DQogICAgICAgIHJldHVybiAtMTsNCiAgICB9DQoNCiAgICBpZiAoc2V0X2ZsYWdzX2luZm8ocF9mbGFnc19pbmZvLCAmbWFpbl9pbmRleCwgJmJhY2t1cF9pbmRleCkgIT0gMCkNCiAgICB7DQogICAgICAgIGZsYWdzX2Vycigic2V0IHViaWZzIHN0YXR1cyBmYWlsIik7DQogICAgICAgIHJldHVybiAtMTsNCiAgICB9DQoNCglyZXR1cm4gMDsNCn0NCg0KDQp2b2lkIGNyYzMyaW5pdF9sZSh2b2lkKQ0Kew0KCWNyYzMyaW5pdF9sZV9nZW5lcmljKENSQzMyX1BPTFlfTEUsIGNyYzMydGFibGVfbGUpOw0KfQ0KDQoNCnVuc2lnbmVkIGludCBjcmMzMl9sZSh1bnNpZ25lZCBpbnQgY3JjLCB1bnNpZ25lZCBjaGFyIGNvbnN0ICpwLCBzaXplX3QgbGVuKQ0Kew0KCXJldHVybiBjcmMzMl9sZV9nZW5lcmljKGNyYywgcCwgbGVuLCAoY29uc3QgdW5zaWduZWQgaW50ICgqKVsyNTZdKWNyYzMydGFibGVfbGUpOw0KfQ0KDQo=