LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgImRlYnVnZ2VyLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAidGxoZWxwMzIuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbmVkYmcpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBzdGFja19pbmZvCiAqCiAqIER1bXAgdGhlIHRvcCBvZiB0aGUgc3RhY2sKICovCnZvaWQgc3RhY2tfaW5mbyh2b2lkKQp7CiAgICBzdHJ1Y3QgZGJnX2x2YWx1ZSBsdmFsdWU7CgogICAgbHZhbHVlLmNvb2tpZSA9IDA7CiAgICBsdmFsdWUudHlwZS5pZCA9IGRiZ19pdHlwZV9zZWdwdHI7CiAgICBsdmFsdWUudHlwZS5tb2R1bGUgPSAwOwoKICAgIC8qIEZJWE1FOiB3ZSBhc3N1bWUgc3RhY2sgZ3Jvd3MgdGhlIHNhbWUgd2F5IGFzIG9uIGkzODYgKi8KICAgIGlmICghbWVtb3J5X2dldF9jdXJyZW50X3N0YWNrKCZsdmFsdWUuYWRkcikpCiAgICAgICAgZGJnX3ByaW50ZigiQmFkIHNlZ21lbnQgKCVkKVxuIiwgbHZhbHVlLmFkZHIuU2VnbWVudCk7CgogICAgZGJnX3ByaW50ZigiU3RhY2sgZHVtcDpcbiIpOwogICAgc3dpdGNoIChsdmFsdWUuYWRkci5Nb2RlKQogICAgewogICAgY2FzZSBBZGRyTW9kZUZsYXQ6IC8qIDMyLWJpdCBtb2RlICovCiAgICBjYXNlIEFkZHJNb2RlMTYzMjogLyogMzItYml0IG1vZGUgKi8KICAgICAgICBtZW1vcnlfZXhhbWluZSgmbHZhbHVlLCAyNCwgJ3gnKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQWRkck1vZGVSZWFsOiAgLyogMTYtYml0IG1vZGUgKi8KICAgIGNhc2UgQWRkck1vZGUxNjE2OgogICAgICAgIG1lbW9yeV9leGFtaW5lKCZsdmFsdWUsIDI0LCAndycpOwoJYnJlYWs7CiAgICB9Cn0KCnN0YXRpYyBCT09MIHN0YWNrX3NldF9mcmFtZV9pbnRlcm5hbChpbnQgbmV3ZnJhbWUpCnsKICAgIGlmIChuZXdmcmFtZSA+PSBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXMpCiAgICAgICAgbmV3ZnJhbWUgPSBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXMgLSAxOwogICAgaWYgKG5ld2ZyYW1lIDwgMCkKICAgICAgICBuZXdmcmFtZSA9IDA7CgogICAgaWYgKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSAhPSBuZXdmcmFtZSkKICAgIHsKICAgICAgICBJTUFHRUhMUF9TVEFDS19GUkFNRSAgICBpaHNmOwoKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPSBuZXdmcmFtZTsKICAgICAgICBzdGFja19nZXRfY3VycmVudF9mcmFtZSgmaWhzZik7CiAgICAgICAgU3ltU2V0Q29udGV4dChkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsICZpaHNmLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBzdGFja19nZXRfZnJhbWUoaW50IG5mLCBJTUFHRUhMUF9TVEFDS19GUkFNRSogaWhzZikKewogICAgbWVtc2V0KGloc2YsIDAsIHNpemVvZigqaWhzZikpOwogICAgaWhzZi0+SW5zdHJ1Y3Rpb25PZmZzZXQgPSAodW5zaWduZWQgbG9uZyltZW1vcnlfdG9fbGluZWFyX2FkZHIoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5hZGRyX3BjKTsKICAgIGloc2YtPkZyYW1lT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9mcmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQoKQk9PTCBzdGFja19nZXRfY3VycmVudF9mcmFtZShJTUFHRUhMUF9TVEFDS19GUkFNRSogaWhzZikKewogICAgLyoKICAgICAqIElmIHdlIGRvbid0IGhhdmUgYSB2YWxpZCBiYWNrdHJhY2UsIHRoZW4ganVzdCByZXR1cm4uCiAgICAgKi8KICAgIGlmIChkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CiAgICByZXR1cm4gc3RhY2tfZ2V0X2ZyYW1lKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSwgaWhzZik7Cn0KCkJPT0wgc3RhY2tfc2V0X2ZyYW1lKGludCBuZXdmcmFtZSkKewogICAgQUREUkVTUzY0ICAgYWRkcjsKICAgIGlmICghc3RhY2tfc2V0X2ZyYW1lX2ludGVybmFsKG5ld2ZyYW1lKSkgcmV0dXJuIEZBTFNFOwogICAgYWRkci5Nb2RlID0gQWRkck1vZGVGbGF0OwogICAgYWRkci5PZmZzZXQgPSAodW5zaWduZWQgbG9uZyltZW1vcnlfdG9fbGluZWFyX2FkZHIoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW2RiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZV0uYWRkcl9wYyk7CiAgICBzb3VyY2VfbGlzdF9mcm9tX2FkZHIoJmFkZHIsIDApOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXN0YWNrX2dldF9jdXJyZW50X3N5bWJvbAogKgogKiBSZXRyaWV2ZXMgdGhlIHN5bWJvbCBpbmZvcm1hdGlvbiBmb3IgdGhlIGN1cnJlbnQgZnJhbWUgZWxlbWVudAogKi8KQk9PTCBzdGFja19nZXRfY3VycmVudF9zeW1ib2woU1lNQk9MX0lORk8qIHN5bWJvbCkKewogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CiAgICBEV09SRDY0ICAgICAgICAgICAgICAgICAgICAgZGlzcDsKCiAgICBpZiAoIXN0YWNrX2dldF9jdXJyZW50X2ZyYW1lKCZpaHNmKSkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIFN5bUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAmZGlzcCwgc3ltYm9sKTsKfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgc3RhY2tfcmVhZF9tZW0oSEFORExFIGhQcm9jLCBEV09SRDY0IGFkZHIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVk9JRCBidWZmZXIsIERXT1JEIHNpemUsIFBEV09SRCB3cml0dGVuKQp7CiAgICBTSVpFX1Qgc3o7CiAgICBCT09MIHJldDsKCiAgICBzdHJ1Y3QgZGJnX3Byb2Nlc3MqIHBjcyA9IGRiZ19nZXRfcHJvY2Vzc19oKGhQcm9jKTsKICAgIGlmICghcGNzKSByZXR1cm4gRkFMU0U7CiAgICByZXQgPSBwY3MtPnByb2Nlc3NfaW8tPnJlYWQoaFByb2MsIChjb25zdCB2b2lkKikoRFdPUkRfUFRSKWFkZHIsIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplLCAmc3opOwogICAgaWYgKHdyaXR0ZW4gIT0gTlVMTCkgKndyaXR0ZW4gPSBzejsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXN0YWNrX2ZldGNoX2ZyYW1lcwogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiB0aGUgdGhlIGN1cnJlbnQgdGhyZWFkCiAqLwp1bnNpZ25lZCBzdGFja19mZXRjaF9mcmFtZXModm9pZCkKewogICAgU1RBQ0tGUkFNRTY0IHNmOwogICAgdW5zaWduZWQgICAgIG5mID0gMDsKICAgIC8qIGFzIG5hdGl2ZSBzdGFja3dhbGsgY2FuIG1vZGlmeSB0aGUgY29udGV4dCBwYXNzZWQgdG8gaXQsIHNpbXBseSBjb3B5CiAgICAgKiBpdCB0byBhdm9pZCBhbnkgZGFtYWdlCiAgICAgKi8KICAgIENPTlRFWFQgICAgICBjdHggPSBkYmdfY29udGV4dDsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyk7CiAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9IE5VTEw7CgogICAgbWVtc2V0KCZzZiwgMCwgc2l6ZW9mKHNmKSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfZnJhbWUoJnNmLkFkZHJGcmFtZSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfcGMoJnNmLkFkZHJQQyk7CgogICAgLyogZG9uJ3QgY29uZnVzZSBTdGFja1dhbGsgYnkgcGFzc2luZyBpbiBpbmNvbnNpc3RlbnQgYWRkcmVzc2VzICovCiAgICBpZiAoKHNmLkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgJiYgKHNmLkFkZHJGcmFtZS5Nb2RlICE9IEFkZHJNb2RlRmxhdCkpCiAgICB7CiAgICAgICAgc2YuQWRkckZyYW1lLk9mZnNldCA9IChEV09SRCltZW1vcnlfdG9fbGluZWFyX2FkZHIoJnNmLkFkZHJGcmFtZSk7CiAgICAgICAgc2YuQWRkckZyYW1lLk1vZGUgPSBBZGRyTW9kZUZsYXQ7CiAgICB9CgogICAgd2hpbGUgKFN0YWNrV2FsazY0KElNQUdFX0ZJTEVfTUFDSElORV9JMzg2LCBkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIAogICAgICAgICAgICAgICAgICAgICAgIGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlLCAmc2YsICZjdHgsIHN0YWNrX3JlYWRfbWVtLAogICAgICAgICAgICAgICAgICAgICAgIFN5bUZ1bmN0aW9uVGFibGVBY2Nlc3M2NCwgU3ltR2V0TW9kdWxlQmFzZTY0LCBOVUxMKSkKICAgIHsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9IGRiZ19oZWFwX3JlYWxsb2MoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmYgKyAxKSAqIHNpemVvZihkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1swXSkpOwoKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyA9IHNmLkFkZHJQQzsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9mcmFtZSA9IHNmLkFkZHJGcmFtZTsKICAgICAgICBuZisrOwogICAgICAgIC8qIHdlJ3ZlIHByb2JhYmx5IGdvdHRlbiBvdXJzZWx2ZXMgaW50byBhbiBpbmZpbml0ZSBsb29wIHNvIGJhaWwgKi8KICAgICAgICBpZiAobmYgPiAyMDApIGJyZWFrOwogICAgfQogICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gLTE7CiAgICBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXMgPSBuZjsKICAgIHN0YWNrX3NldF9mcmFtZV9pbnRlcm5hbCgwKTsKICAgIHJldHVybiBuZjsKfQoKc3RydWN0IHN5bV9lbnVtCnsKICAgIGNoYXIqICAgICAgIHRtcDsKICAgIERXT1JEICAgICAgIGZyYW1lOwp9OwoKc3RhdGljIEJPT0wgV0lOQVBJIHN5bV9lbnVtX2NiKFNZTUJPTF9JTkZPKiBzeW1faW5mbywgVUxPTkcgc2l6ZSwgdm9pZCogdXNlcikKewogICAgc3RydWN0IHN5bV9lbnVtKiAgICBzZSA9IChzdHJ1Y3Qgc3ltX2VudW0qKXVzZXI7CiAgICBjaGFyICAgICAgICAgICAgICAgIHRtcFszMl07CgogICAgaWYgKHN5bV9pbmZvLT5GbGFncyAmIFNZTUZMQUdfUEFSQU1FVEVSKQogICAgewogICAgICAgIGlmIChzZS0+dG1wWzBdKSBzdHJjYXQoc2UtPnRtcCwgIiwgIik7CiAgICAKICAgICAgICBpZiAoc3ltX2luZm8tPkZsYWdzICYgU1lNRkxBR19SRUdSRUwpCiAgICAgICAgewogICAgICAgICAgICB1bnNpZ25lZCAgICB2YWw7CiAgICAgICAgICAgIERXT1JEICAgICAgIGFkZHIgPSBzZS0+ZnJhbWUgKyBzeW1faW5mby0+QWRkcmVzczsKCiAgICAgICAgICAgIGlmICghZGJnX3JlYWRfbWVtb3J5KChjaGFyKilhZGRyLCAmdmFsLCBzaXplb2YodmFsKSkpCiAgICAgICAgICAgICAgICBzbnByaW50Zih0bXAsIHNpemVvZih0bXApLCAiPCoqKiBjYW5ub3QgcmVhZCBhdCAweCVseCAqKio+IiwgYWRkcik7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHNucHJpbnRmKHRtcCwgc2l6ZW9mKHRtcCksICIweCV4IiwgdmFsKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoc3ltX2luZm8tPkZsYWdzICYgU1lNRkxBR19SRUdJU1RFUikKICAgICAgICB7CiAgICAgICAgICAgIERXT1JEKiBwdmFsOwoKICAgICAgICAgICAgaWYgKG1lbW9yeV9nZXRfcmVnaXN0ZXIoc3ltX2luZm8tPlJlZ2lzdGVyLCAmcHZhbCwgdG1wLCBzaXplb2YodG1wKSkpCiAgICAgICAgICAgICAgICBzbnByaW50Zih0bXAsIHNpemVvZih0bXApLCAiMHglbHgiLCAqcHZhbCk7CiAgICAgICAgfQogICAgICAgIHNwcmludGYoc2UtPnRtcCArIHN0cmxlbihzZS0+dG1wKSwgIiVzPSVzIiwgc3ltX2luZm8tPk5hbWUsIHRtcCk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgc3RhY2tfcHJpbnRfYWRkcl9hbmRfYXJncyhpbnQgbmYpCnsKICAgIGNoYXIgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJbc2l6ZW9mKFNZTUJPTF9JTkZPKSArIDI1Nl07CiAgICBTWU1CT0xfSU5GTyogICAgICAgICAgICAgICAgc2kgPSAoU1lNQk9MX0lORk8qKWJ1ZmZlcjsKICAgIElNQUdFSExQX1NUQUNLX0ZSQU1FICAgICAgICBpaHNmOwogICAgSU1BR0VITFBfTElORSAgICAgICAgICAgICAgIGlsOwogICAgSU1BR0VITFBfTU9EVUxFICAgICAgICAgICAgIGltOwogICAgRFdPUkQ2NCAgICAgICAgICAgICAgICAgICAgIGRpc3A2NDsKCiAgICBwcmludF9iYXJlX2FkZHJlc3MoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5hZGRyX3BjKTsKCiAgICBzdGFja19nZXRfZnJhbWUobmYsICZpaHNmKTsKCiAgICAvKiBncmFiIG1vZHVsZSB3aGVyZSBzeW1ib2wgaXMuIElmIHdlIGRvbid0IGhhdmUgYSBtb2R1bGUsIHdlIGNhbm5vdCBwcmludCBtb3JlICovCiAgICBpbS5TaXplT2ZTdHJ1Y3QgPSBzaXplb2YoaW0pOwogICAgaWYgKCFTeW1HZXRNb2R1bGVJbmZvKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwgJmltKSkKICAgICAgICByZXR1cm47CgogICAgc2ktPlNpemVPZlN0cnVjdCA9IHNpemVvZigqc2kpOwogICAgc2ktPk1heE5hbWVMZW4gICA9IDI1NjsKICAgIGlmIChTeW1Gcm9tQWRkcihkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQsICZkaXNwNjQsIHNpKSkKICAgIHsKICAgICAgICBzdHJ1Y3Qgc3ltX2VudW0gc2U7CiAgICAgICAgY2hhciAgICAgICAgICAgIHRtcFsxMDI0XTsKICAgICAgICBEV09SRCAgICAgICAgICAgZGlzcDsKCiAgICAgICAgZGJnX3ByaW50ZigiICVzIiwgc2ktPk5hbWUpOwogICAgICAgIGlmIChkaXNwNjQpIGRiZ19wcmludGYoIisweCVseCIsIChEV09SRF9QVFIpZGlzcDY0KTsKCiAgICAgICAgU3ltU2V0Q29udGV4dChkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsICZpaHNmLCBOVUxMKTsKICAgICAgICBzZS50bXAgPSB0bXA7CiAgICAgICAgc2UuZnJhbWUgPSBpaHNmLkZyYW1lT2Zmc2V0OwogICAgICAgIHRtcFswXSA9ICdcMCc7CiAgICAgICAgU3ltRW51bVN5bWJvbHMoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAwLCBOVUxMLCBzeW1fZW51bV9jYiwgJnNlKTsKICAgICAgICBpZiAodG1wWzBdKSBkYmdfcHJpbnRmKCIoJXMpIiwgdG1wKTsKCiAgICAgICAgaWwuU2l6ZU9mU3RydWN0ID0gc2l6ZW9mKGlsKTsKICAgICAgICBpZiAoU3ltR2V0TGluZUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkaXNwLCAmaWwpKQogICAgICAgICAgICBkYmdfcHJpbnRmKCIgWyVzOiVsdV0iLCBpbC5GaWxlTmFtZSwgaWwuTGluZU51bWJlcik7CiAgICAgICAgZGJnX3ByaW50ZigiIGluICVzIiwgaW0uTW9kdWxlTmFtZSk7CiAgICB9CiAgICBlbHNlIGRiZ19wcmludGYoIiBpbiAlcyAoKzB4JWx4KSIsIAogICAgICAgICAgICAgICAgICAgIGltLk1vZHVsZU5hbWUsIChEV09SRF9QVFIpKGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQgLSBpbS5CYXNlT2ZJbWFnZSkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQliYWNrdHJhY2UKICoKICogRG8gYSBiYWNrdHJhY2Ugb24gdGhlIHRoZSBjdXJyZW50IHRocmVhZAogKi8Kc3RhdGljIHZvaWQgYmFja3RyYWNlKHZvaWQpCnsKICAgIHVuc2lnbmVkICAgICAgICAgICAgICAgICAgICBjZiA9IGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZTsKICAgIElNQUdFSExQX1NUQUNLX0ZSQU1FICAgICAgICBpaHNmOwoKICAgIGRiZ19wcmludGYoIkJhY2t0cmFjZTpcbiIpOwogICAgZm9yIChkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPSAwOwogICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPCBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXM7CiAgICAgICAgIGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSsrKQogICAgewogICAgICAgIGRiZ19wcmludGYoIiVzJWQgIiwgCiAgICAgICAgICAgICAgICAgICAoY2YgPT0gZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID8gIj0+IiA6ICIgICIpLAogICAgICAgICAgICAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lICsgMSk7CiAgICAgICAgc3RhY2tfcHJpbnRfYWRkcl9hbmRfYXJncyhkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUpOwogICAgICAgIGRiZ19wcmludGYoIiAoIik7CiAgICAgICAgcHJpbnRfYmFyZV9hZGRyZXNzKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWVdLmFkZHJfcGMpOwogICAgICAgIGRiZ19wcmludGYoIilcbiIpOwogICAgfQogICAgLyogcmVzZXQgY29udGV4dCB0byBjdXJyZW50IHN0YWNrIGZyYW1lICovCiAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPSBjZjsKICAgIGlmICghZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMpIHJldHVybjsKICAgIHN0YWNrX2dldF9mcmFtZShkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUsICZpaHNmKTsKICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWJhY2t0cmFjZV90aWQKICoKICogRG8gYSBiYWNrdHJhY2Ugb24gYSB0aHJlYWQgZnJvbSBpdHMgcHJvY2VzcyBhbmQgaXRzIGlkZW50aWZpZXIKICogKHByZXNlcnZlcyBjdXJyZW50IHRocmVhZCBhbmQgY29udGV4dCBpbmZvcm1hdGlvbikKICovCnN0YXRpYyB2b2lkIGJhY2t0cmFjZV90aWQoc3RydWN0IGRiZ19wcm9jZXNzKiBwY3MsIERXT1JEIHRpZCkKewogICAgc3RydWN0IGRiZ190aHJlYWQqICB0aHJlYWQgPSBkYmdfY3Vycl90aHJlYWQ7CgogICAgaWYgKCEoZGJnX2N1cnJfdGhyZWFkID0gZGJnX2dldF90aHJlYWQocGNzLCB0aWQpKSkKICAgICAgICBkYmdfcHJpbnRmKCJVbmtub3duIHRocmVhZCBpZCAoMHglbHgpIGluIHByb2Nlc3MgKDB4JWx4KVxuIiwgdGlkLCBwY3MtPnBpZCk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgQ09OVEVYVCBzYXZlZF9jdHggPSBkYmdfY29udGV4dDsKCiAgICAgICAgZGJnX2N1cnJfdGlkID0gZGJnX2N1cnJfdGhyZWFkLT50aWQ7CiAgICAgICAgbWVtc2V0KCZkYmdfY29udGV4dCwgMCwgc2l6ZW9mKGRiZ19jb250ZXh0KSk7CiAgICAgICAgZGJnX2NvbnRleHQuQ29udGV4dEZsYWdzID0gQ09OVEVYVF9GVUxMOwogICAgICAgIGlmIChTdXNwZW5kVGhyZWFkKGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlKSAhPSAtMSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghR2V0VGhyZWFkQ29udGV4dChkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSwgJmRiZ19jb250ZXh0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGJnX3ByaW50ZigiQ2FuJ3QgZ2V0IGNvbnRleHQgZm9yIHRocmVhZCAweCVseCBpbiBjdXJyZW50IHByb2Nlc3NcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdGFja19mZXRjaF9mcmFtZXMoKTsKICAgICAgICAgICAgICAgIGJhY2t0cmFjZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFJlc3VtZVRocmVhZChkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgZGJnX3ByaW50ZigiQ2FuJ3Qgc3VzcGVuZCB0aHJlYWQgMHglbHggaW4gY3VycmVudCBwcm9jZXNzXG4iLCB0aWQpOwogICAgICAgIGRiZ19jb250ZXh0ID0gc2F2ZWRfY3R4OwogICAgfQogICAgZGJnX2N1cnJfdGhyZWFkID0gdGhyZWFkOwogICAgZGJnX2N1cnJfdGlkID0gdGhyZWFkID8gdGhyZWFkLT50aWQgOiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQliYWNrdHJhY2VfYWxsCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIGV2ZXJ5IHJ1bm5pbmcgdGhyZWFkIGluIHRoZSBzeXN0ZW0gKGV4Y2VwdCB0aGUgZGVidWdnZXIpCiAqIChwcmVzZXJ2ZXMgY3VycmVudCBwcm9jZXNzIGluZm9ybWF0aW9uKQogKi8Kc3RhdGljIHZvaWQgYmFja3RyYWNlX2FsbCh2b2lkKQp7CiAgICBzdHJ1Y3QgZGJnX3Byb2Nlc3MqIHByb2Nlc3MgPSBkYmdfY3Vycl9wcm9jZXNzOwogICAgVEhSRUFERU5UUlkzMiAgICAgICBlbnRyeTsKICAgIEhBTkRMRSAgICAgICAgICAgICAgc25hcHNob3QgPSBDcmVhdGVUb29saGVscDMyU25hcHNob3QoVEgzMkNTX1NOQVBUSFJFQUQsIDApOwoKICAgIGlmIChzbmFwc2hvdCA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgIHsKICAgICAgICBkYmdfcHJpbnRmKCJVbmFibGUgdG8gY3JlYXRlIHRvb2xoZWxwIHNuYXBzaG90XG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgZW50cnkuZHdTaXplID0gc2l6ZW9mKGVudHJ5KTsKICAgIGlmIChUaHJlYWQzMkZpcnN0KHNuYXBzaG90LCAmZW50cnkpKQogICAgewogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEID09IEdldEN1cnJlbnRQcm9jZXNzSWQoKSkgY29udGludWU7CiAgICAgICAgICAgIGlmIChkYmdfY3Vycl9wcm9jZXNzICYmIGRiZ19jdXJyX3BpZCAhPSBlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQpCiAgICAgICAgICAgICAgICBkYmdfY3Vycl9wcm9jZXNzLT5wcm9jZXNzX2lvLT5jbG9zZV9wcm9jZXNzKGRiZ19jdXJyX3Byb2Nlc3MsIEZBTFNFKTsKCiAgICAgICAgICAgIGlmIChlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQgIT0gZGJnX2N1cnJfcGlkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWRiZ19hdHRhY2hfZGVidWdnZWUoZW50cnkudGgzMk93bmVyUHJvY2Vzc0lELCBGQUxTRSwgVFJVRSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGJnX3ByaW50ZigiXG53YXJuaW5nOiBjb3VsZCBub3QgYXR0YWNoIHRvIDB4JWx4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRiZ19jdXJyX3BpZCA9IGRiZ19jdXJyX3Byb2Nlc3MtPnBpZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZGJnX3ByaW50ZigiXG5CYWNrdHJhY2luZyBmb3IgdGhyZWFkIDB4JWx4IGluIHByb2Nlc3MgMHglbHggKCVzKTpcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnkudGgzMlRocmVhZElELCBkYmdfY3Vycl9waWQsIGRiZ19jdXJyX3Byb2Nlc3MtPmltYWdlTmFtZSk7CiAgICAgICAgICAgIGJhY2t0cmFjZV90aWQoZGJnX2N1cnJfcHJvY2VzcywgZW50cnkudGgzMlRocmVhZElEKTsKICAgICAgICB9CiAgICAgICAgd2hpbGUgKFRocmVhZDMyTmV4dChzbmFwc2hvdCwgJmVudHJ5KSk7CgogICAgICAgIGlmIChkYmdfY3Vycl9wcm9jZXNzKQogICAgICAgICAgICBkYmdfY3Vycl9wcm9jZXNzLT5wcm9jZXNzX2lvLT5jbG9zZV9wcm9jZXNzKGRiZ19jdXJyX3Byb2Nlc3MsIEZBTFNFKTsKICAgIH0KICAgIENsb3NlSGFuZGxlKHNuYXBzaG90KTsKICAgIGRiZ19jdXJyX3Byb2Nlc3MgPSBwcm9jZXNzOwogICAgZGJnX2N1cnJfcGlkID0gcHJvY2VzcyA/IHByb2Nlc3MtPnBpZCA6IDA7Cn0KCnZvaWQgc3RhY2tfYmFja3RyYWNlKERXT1JEIHRpZCkKewogICAgLyogYmFja3RyYWNlIGV2ZXJ5IHRocmVhZCBpbiBldmVyeSBwcm9jZXNzIGV4Y2VwdCB0aGUgZGVidWdnZXIgaXRzZWxmLAogICAgICogaW52b2tpbmcgdmlhICJidCBhbGwiCiAgICAgKi8KICAgIGlmICh0aWQgPT0gLTEpIHJldHVybiBiYWNrdHJhY2VfYWxsKCk7CgogICAgaWYgKCFkYmdfY3Vycl9wcm9jZXNzKSAKICAgIHsKICAgICAgICBkYmdfcHJpbnRmKCJZb3UgbXVzdCBiZSBhdHRhY2hlZCB0byBhIHByb2Nlc3MgdG8gcnVuIHRoaXMgY29tbWFuZC5cbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIAogICAgaWYgKHRpZCA9PSBkYmdfY3Vycl90aWQpCiAgICB7CiAgICAgICAgYmFja3RyYWNlKCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgYmFja3RyYWNlX3RpZChkYmdfY3Vycl9wcm9jZXNzLCB0aWQpOwogICAgfQp9Cg==