LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgImRlYnVnZ2VyLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAidGxoZWxwMzIuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbmVkYmcpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBzdGFja19pbmZvCiAqCiAqIER1bXAgdGhlIHRvcCBvZiB0aGUgc3RhY2sKICovCnZvaWQgc3RhY2tfaW5mbyh2b2lkKQp7CiAgICBzdHJ1Y3QgZGJnX2x2YWx1ZSBsdmFsdWU7CgogICAgbHZhbHVlLmNvb2tpZSA9IDA7CiAgICBsdmFsdWUudHlwZS5pZCA9IGRiZ19pdHlwZV9ub25lOwogICAgbHZhbHVlLnR5cGUubW9kdWxlID0gMDsKCiAgICAvKiBGSVhNRTogd2UgYXNzdW1lIHN0YWNrIGdyb3dzIHRoZSBzYW1lIHdheSBhcyBvbiBpMzg2ICovCiAgICBpZiAoIW1lbW9yeV9nZXRfY3VycmVudF9zdGFjaygmbHZhbHVlLmFkZHIpKQogICAgICAgIGRiZ19wcmludGYoIkJhZCBzZWdtZW50ICglZClcbiIsIGx2YWx1ZS5hZGRyLlNlZ21lbnQpOwoKICAgIGRiZ19wcmludGYoIlN0YWNrIGR1bXA6XG4iKTsKICAgIHN3aXRjaCAobHZhbHVlLmFkZHIuTW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OiAvKiAzMi1iaXQgbW9kZSAqLwogICAgY2FzZSBBZGRyTW9kZTE2MzI6IC8qIDMyLWJpdCBtb2RlICovCiAgICAgICAgbWVtb3J5X2V4YW1pbmUoJmx2YWx1ZSwgMjQsICd4Jyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDogIC8qIDE2LWJpdCBtb2RlICovCiAgICBjYXNlIEFkZHJNb2RlMTYxNjoKICAgICAgICBtZW1vcnlfZXhhbWluZSgmbHZhbHVlLCAyNCwgJ3cnKTsKCWJyZWFrOwogICAgfQp9CgpzdGF0aWMgQk9PTCBzdGFja19zZXRfZnJhbWVfaW50ZXJuYWwoaW50IG5ld2ZyYW1lKQp7CiAgICBpZiAobmV3ZnJhbWUgPj0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzKQogICAgICAgIG5ld2ZyYW1lID0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzIC0gMTsKICAgIGlmIChuZXdmcmFtZSA8IDApCiAgICAgICAgbmV3ZnJhbWUgPSAwOwoKICAgIGlmIChkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgIT0gbmV3ZnJhbWUpCiAgICB7CiAgICAgICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgaWhzZjsKCiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gbmV3ZnJhbWU7CiAgICAgICAgc3RhY2tfZ2V0X2N1cnJlbnRfZnJhbWUoJmloc2YpOwogICAgICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgc3RhY2tfZ2V0X2ZyYW1lKGludCBuZiwgSU1BR0VITFBfU1RBQ0tfRlJBTUUqIGloc2YpCnsKICAgIGloc2YtPkluc3RydWN0aW9uT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyk7CiAgICBpaHNmLT5GcmFtZU9mZnNldCA9ICh1bnNpZ25lZCBsb25nKW1lbW9yeV90b19saW5lYXJfYWRkcigmZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfZnJhbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KCkJPT0wgc3RhY2tfZ2V0X2N1cnJlbnRfZnJhbWUoSU1BR0VITFBfU1RBQ0tfRlJBTUUqIGloc2YpCnsKICAgIC8qCiAgICAgKiBJZiB3ZSBkb24ndCBoYXZlIGEgdmFsaWQgYmFja3RyYWNlLCB0aGVuIGp1c3QgcmV0dXJuLgogICAgICovCiAgICBpZiAoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIHN0YWNrX2dldF9mcmFtZShkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUsIGloc2YpOwp9CgpCT09MIHN0YWNrX3NldF9mcmFtZShpbnQgbmV3ZnJhbWUpCnsKICAgIEFERFJFU1MgICAgIGFkZHI7CiAgICBpZiAoIXN0YWNrX3NldF9mcmFtZV9pbnRlcm5hbChuZXdmcmFtZSkpIHJldHVybiBGQUxTRTsKICAgIGFkZHIuTW9kZSA9IEFkZHJNb2RlRmxhdDsKICAgIGFkZHIuT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWVdLmFkZHJfcGMpOwogICAgc291cmNlX2xpc3RfZnJvbV9hZGRyKCZhZGRyLCAwKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlzdGFja19nZXRfY3VycmVudF9zeW1ib2wKICoKICogUmV0cmlldmVzIHRoZSBzeW1ib2wgaW5mb3JtYXRpb24gZm9yIHRoZSBjdXJyZW50IGZyYW1lIGVsZW1lbnQKICovCkJPT0wgc3RhY2tfZ2V0X2N1cnJlbnRfc3ltYm9sKFNZTUJPTF9JTkZPKiBzeW1ib2wpCnsKICAgIElNQUdFSExQX1NUQUNLX0ZSQU1FICAgICAgICBpaHNmOwogICAgRFdPUkQ2NCAgICAgICAgICAgICAgICAgICAgIGRpc3A7CgogICAgaWYgKCFzdGFja19nZXRfY3VycmVudF9mcmFtZSgmaWhzZikpIHJldHVybiBGQUxTRTsKICAgIHJldHVybiBTeW1Gcm9tQWRkcihkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgJmRpc3AsIHN5bWJvbCk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJc3RhY2tfZmV0Y2hfZnJhbWVzCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIHRoZSB0aGUgY3VycmVudCB0aHJlYWQKICovCnVuc2lnbmVkIHN0YWNrX2ZldGNoX2ZyYW1lcyh2b2lkKQp7CiAgICBTVEFDS0ZSQU1FICBzZjsKICAgIHVuc2lnbmVkICAgIG5mID0gMDsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyk7CiAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9IE5VTEw7CgogICAgbWVtc2V0KCZzZiwgMCwgc2l6ZW9mKHNmKSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfZnJhbWUoJnNmLkFkZHJGcmFtZSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfcGMoJnNmLkFkZHJQQyk7CgogICAgLyogZG9uJ3QgY29uZnVzZSBTdGFja1dhbGsgYnkgcGFzc2luZyBpbiBpbmNvbnNpc3RlbnQgYWRkcmVzc2VzICovCiAgICBpZiAoKHNmLkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgJiYgKHNmLkFkZHJGcmFtZS5Nb2RlICE9IEFkZHJNb2RlRmxhdCkpCiAgICB7CiAgICAgICAgc2YuQWRkckZyYW1lLk9mZnNldCA9IChEV09SRCltZW1vcnlfdG9fbGluZWFyX2FkZHIoJnNmLkFkZHJGcmFtZSk7CiAgICAgICAgc2YuQWRkckZyYW1lLk1vZGUgPSBBZGRyTW9kZUZsYXQ7CiAgICB9CgogICAgd2hpbGUgKFN0YWNrV2FsayhJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NiwgZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAKICAgICAgICAgICAgICAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUsICZzZiwgJmRiZ19jb250ZXh0LCBOVUxMLAogICAgICAgICAgICAgICAgICAgICBTeW1GdW5jdGlvblRhYmxlQWNjZXNzLCBTeW1HZXRNb2R1bGVCYXNlLCBOVUxMKSkKICAgIHsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9IGRiZ19oZWFwX3JlYWxsb2MoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmYgKyAxKSAqIHNpemVvZihkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1swXSkpOwoKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyA9IHNmLkFkZHJQQzsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9mcmFtZSA9IHNmLkFkZHJGcmFtZTsKICAgICAgICBuZisrOwogICAgICAgIC8qIHdlJ3ZlIHByb2JhYmx5IGdvdHRlbiBvdXJzZWx2ZXMgaW50byBhbiBpbmZpbml0ZSBsb29wIHNvIGJhaWwgKi8KICAgICAgICBpZiAobmYgPiAyMDApIGJyZWFrOwogICAgfQogICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gLTE7CiAgICBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXMgPSBuZjsKICAgIHN0YWNrX3NldF9mcmFtZV9pbnRlcm5hbCgwKTsKICAgIHJldHVybiBuZjsKfQoKc3RydWN0IHN5bV9lbnVtCnsKICAgIGNoYXIqICAgICAgIHRtcDsKICAgIERXT1JEICAgICAgIGZyYW1lOwp9OwoKc3RhdGljIEJPT0wgV0lOQVBJIHN5bV9lbnVtX2NiKFNZTUJPTF9JTkZPKiBzeW1faW5mbywgVUxPTkcgc2l6ZSwgdm9pZCogdXNlcikKewogICAgc3RydWN0IHN5bV9lbnVtKiAgICBzZSA9IChzdHJ1Y3Qgc3ltX2VudW0qKXVzZXI7CiAgICBEV09SRCAgICAgICAgICAgICAgIGFkZHI7CiAgICB1bnNpZ25lZCAgICAgICAgICAgIHZhbDsKCiAgICBpZiAoKHN5bV9pbmZvLT5GbGFncyAmIChTWU1GTEFHX1BBUkFNRVRFUnxTWU1GTEFHX0ZSQU1FUkVMKSkgPT0gKFNZTUZMQUdfUEFSQU1FVEVSfFNZTUZMQUdfRlJBTUVSRUwpKQogICAgewogICAgICAgIGlmIChzZS0+dG1wWzBdKSBzdHJjYXQoc2UtPnRtcCwgIiwgIik7CiAgICAgICAgYWRkciA9IHNlLT5mcmFtZSArIHN5bV9pbmZvLT5BZGRyZXNzOwogICAgICAgIGlmIChkYmdfcmVhZF9tZW1vcnkoKGNoYXIqKWFkZHIsICZ2YWwsIHNpemVvZih2YWwpKSkKICAgICAgICAgICAgc3ByaW50ZihzZS0+dG1wICsgc3RybGVuKHNlLT50bXApLCAiJXM9MHgleCIsIHN5bV9pbmZvLT5OYW1lLCB2YWwpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc3ByaW50ZihzZS0+dG1wICsgc3RybGVuKHNlLT50bXApLCAiJXM9PFw/XD9cPz4iLCBzeW1faW5mby0+TmFtZSk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgc3RhY2tfcHJpbnRfYWRkcl9hbmRfYXJncyhpbnQgbmYpCnsKICAgIGNoYXIgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJbc2l6ZW9mKFNZTUJPTF9JTkZPKSArIDI1Nl07CiAgICBTWU1CT0xfSU5GTyogICAgICAgICAgICAgICAgc2kgPSAoU1lNQk9MX0lORk8qKWJ1ZmZlcjsKICAgIElNQUdFSExQX1NUQUNLX0ZSQU1FICAgICAgICBpaHNmOwogICAgSU1BR0VITFBfTElORSAgICAgICAgICAgICAgIGlsOwogICAgSU1BR0VITFBfTU9EVUxFICAgICAgICAgICAgIGltOwogICAgRFdPUkQ2NCAgICAgICAgICAgICAgICAgICAgIGRpc3A2NDsKCiAgICBwcmludF9iYXJlX2FkZHJlc3MoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5hZGRyX3BjKTsKCiAgICBzdGFja19nZXRfZnJhbWUobmYsICZpaHNmKTsKCiAgICAvKiBncmFiIG1vZHVsZSB3aGVyZSBzeW1ib2wgaXMuIElmIHdlIGRvbid0IGhhdmUgYSBtb2R1bGUsIHdlIGNhbm5vdCBwcmludCBtb3JlICovCiAgICBpbS5TaXplT2ZTdHJ1Y3QgPSBzaXplb2YoaW0pOwogICAgaWYgKCFTeW1HZXRNb2R1bGVJbmZvKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwgJmltKSkKICAgICAgICByZXR1cm47CgogICAgc2ktPlNpemVPZlN0cnVjdCA9IHNpemVvZigqc2kpOwogICAgc2ktPk1heE5hbWVMZW4gICA9IDI1NjsKICAgIGlmIChTeW1Gcm9tQWRkcihkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQsICZkaXNwNjQsIHNpKSkKICAgIHsKICAgICAgICBzdHJ1Y3Qgc3ltX2VudW0gc2U7CiAgICAgICAgY2hhciAgICAgICAgICAgIHRtcFsxMDI0XTsKICAgICAgICBEV09SRCAgICAgICAgICAgZGlzcDsKCiAgICAgICAgZGJnX3ByaW50ZigiICVzIiwgc2ktPk5hbWUpOwogICAgICAgIGlmIChkaXNwKSBkYmdfcHJpbnRmKCIrMHglbHgiLCAoRFdPUkRfUFRSKWRpc3A2NCk7CgogICAgICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7CiAgICAgICAgc2UudG1wID0gdG1wOwogICAgICAgIHNlLmZyYW1lID0gaWhzZi5GcmFtZU9mZnNldDsKICAgICAgICB0bXBbMF0gPSAnXDAnOwogICAgICAgIFN5bUVudW1TeW1ib2xzKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgMCwgTlVMTCwgc3ltX2VudW1fY2IsICZzZSk7CiAgICAgICAgaWYgKHRtcFswXSkgZGJnX3ByaW50ZigiKCVzKSIsIHRtcCk7CgogICAgICAgIGlsLlNpemVPZlN0cnVjdCA9IHNpemVvZihpbCk7CiAgICAgICAgaWYgKFN5bUdldExpbmVGcm9tQWRkcihkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGlzcCwgJmlsKSkKICAgICAgICAgICAgZGJnX3ByaW50ZigiIFslczolbHVdIiwgaWwuRmlsZU5hbWUsIGlsLkxpbmVOdW1iZXIpOwogICAgICAgIGRiZ19wcmludGYoIiBpbiAlcyIsIGltLk1vZHVsZU5hbWUpOwogICAgfQogICAgZWxzZSBkYmdfcHJpbnRmKCIgaW4gJXMgKCsweCVseCkiLCAKICAgICAgICAgICAgICAgICAgICBpbS5Nb2R1bGVOYW1lLCAoRFdPUkRfUFRSKShpaHNmLkluc3RydWN0aW9uT2Zmc2V0IC0gaW0uQmFzZU9mSW1hZ2UpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIHRoZSB0aGUgY3VycmVudCB0aHJlYWQKICovCnN0YXRpYyB1bnNpZ25lZCBiYWNrdHJhY2Uodm9pZCkKewogICAgdW5zaWduZWQgICAgICAgICAgICAgICAgICAgIG5mID0gMDsKICAgIElNQUdFSExQX1NUQUNLX0ZSQU1FICAgICAgICBpaHNmOwoKICAgIGRiZ19wcmludGYoIkJhY2t0cmFjZTpcbiIpOwogICAgZm9yIChuZiA9IDA7IG5mIDwgZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzOyBuZisrKQogICAgewogICAgICAgIGRiZ19wcmludGYoIiVzJWQgIiwgCiAgICAgICAgICAgICAgICAgICAobmYgPT0gZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID8gIj0+IiA6ICIgICIpLCBuZiArIDEpOwogICAgICAgIHN0YWNrX3ByaW50X2FkZHJfYW5kX2FyZ3MobmYpOwogICAgICAgIGRiZ19wcmludGYoIiAoIik7CiAgICAgICAgcHJpbnRfYmFyZV9hZGRyZXNzKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyk7CiAgICAgICAgZGJnX3ByaW50ZigiKVxuIik7CiAgICB9CiAgICAvKiByZXNldCBjb250ZXh0IHRvIGN1cnJlbnQgc3RhY2sgZnJhbWUgKi8KICAgIHN0YWNrX2dldF9mcmFtZShkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUsICZpaHNmKTsKICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7CiAgICByZXR1cm4gbmY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWJhY2t0cmFjZV90aWQKICoKICogRG8gYSBiYWNrdHJhY2Ugb24gYSB0aHJlYWQgZnJvbSBpdHMgcHJvY2VzcyBhbmQgaXRzIGlkZW50aWZpZXIKICogKHByZXNlcnZlcyBjdXJyZW50IHRocmVhZCBhbmQgY29udGV4dCBpbmZvcm1hdGlvbikKICovCnN0YXRpYyB2b2lkIGJhY2t0cmFjZV90aWQoc3RydWN0IGRiZ19wcm9jZXNzKiBwY3MsIERXT1JEIHRpZCkKewogICAgc3RydWN0IGRiZ190aHJlYWQqICB0aHJlYWQgPSBkYmdfY3Vycl90aHJlYWQ7CgogICAgaWYgKCEoZGJnX2N1cnJfdGhyZWFkID0gZGJnX2dldF90aHJlYWQocGNzLCB0aWQpKSkKICAgICAgICBkYmdfcHJpbnRmKCJVbmtub3duIHRocmVhZCBpZCAoMHglbHgpIGluIHByb2Nlc3MgKDB4JWx4KVxuIiwgdGlkLCBwY3MtPnBpZCk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgQ09OVEVYVCBzYXZlZF9jdHggPSBkYmdfY29udGV4dDsKCiAgICAgICAgZGJnX2N1cnJfdGlkID0gZGJnX2N1cnJfdGhyZWFkLT50aWQ7CiAgICAgICAgbWVtc2V0KCZkYmdfY29udGV4dCwgMCwgc2l6ZW9mKGRiZ19jb250ZXh0KSk7CiAgICAgICAgZGJnX2NvbnRleHQuQ29udGV4dEZsYWdzID0gQ09OVEVYVF9GVUxMOwogICAgICAgIGlmIChTdXNwZW5kVGhyZWFkKGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlKSAhPSAtMSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghR2V0VGhyZWFkQ29udGV4dChkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSwgJmRiZ19jb250ZXh0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGJnX3ByaW50ZigiQ2FuJ3QgZ2V0IGNvbnRleHQgZm9yIHRocmVhZCAweCVseCBpbiBjdXJyZW50IHByb2Nlc3NcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBiYWNrdHJhY2UoKTsKICAgICAgICAgICAgUmVzdW1lVGhyZWFkKGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBkYmdfcHJpbnRmKCJDYW4ndCBzdXNwZW5kIHRocmVhZCAweCVseCBpbiBjdXJyZW50IHByb2Nlc3NcbiIsIHRpZCk7CiAgICAgICAgZGJnX2NvbnRleHQgPSBzYXZlZF9jdHg7CiAgICB9CiAgICBkYmdfY3Vycl90aHJlYWQgPSB0aHJlYWQ7CiAgICBkYmdfY3Vycl90aWQgPSB0aHJlYWQgPyB0aHJlYWQtPnRpZCA6IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWJhY2t0cmFjZV9hbGwKICoKICogRG8gYSBiYWNrdHJhY2Ugb24gZXZlcnkgcnVubmluZyB0aHJlYWQgaW4gdGhlIHN5c3RlbSAoZXhjZXB0IHRoZSBkZWJ1Z2dlcikKICogKHByZXNlcnZlcyBjdXJyZW50IHByb2Nlc3MgaW5mb3JtYXRpb24pCiAqLwpzdGF0aWMgdm9pZCBiYWNrdHJhY2VfYWxsKHZvaWQpCnsKICAgIFRIUkVBREVOVFJZMzIgICAgICAgZW50cnk7CiAgICBIQU5ETEUgICAgICAgICAgICAgIHNuYXBzaG90ID0gQ3JlYXRlVG9vbGhlbHAzMlNuYXBzaG90KFRIMzJDU19TTkFQVEhSRUFELCAwKTsKCiAgICBpZiAoc25hcHNob3QgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCiAgICB7CiAgICAgICAgZGJnX3ByaW50ZigiVW5hYmxlIHRvIGNyZWF0ZSB0b29saGVscCBzbmFwc2hvdFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGVudHJ5LmR3U2l6ZSA9IHNpemVvZihlbnRyeSk7CiAgICBpZiAoVGhyZWFkMzJGaXJzdChzbmFwc2hvdCwgJmVudHJ5KSkKICAgIHsKICAgICAgICBkbwogICAgICAgIHsKICAgICAgICAgICAgaWYgKGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCA9PSBHZXRDdXJyZW50UHJvY2Vzc0lkKCkpIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAoZGJnX2N1cnJfcHJvY2VzcyAmJiBkYmdfY3Vycl9waWQgIT0gZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEKQogICAgICAgICAgICAgICAgZGJnX2RldGFjaF9kZWJ1Z2dlZSgpOwoKICAgICAgICAgICAgaWYgKGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCAhPSBkYmdfY3Vycl9waWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghZGJnX2F0dGFjaF9kZWJ1Z2dlZShlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQsIEZBTFNFLCBUUlVFKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkYmdfcHJpbnRmKCJcbndhcm5pbmc6IGNvdWxkIG5vdCBhdHRhY2ggdG8gMHglbHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGJnX2N1cnJfcGlkID0gZGJnX2N1cnJfcHJvY2Vzcy0+cGlkOwogICAgICAgICAgICB9CgogICAgICAgICAgICBkYmdfcHJpbnRmKCJcbkJhY2t0cmFjaW5nIGZvciB0aHJlYWQgMHglbHggaW4gcHJvY2VzcyAweCVseCAoJXMpOlxuIiwKICAgICAgICAgICAgICAgICAgICAgICBlbnRyeS50aDMyVGhyZWFkSUQsIGRiZ19jdXJyX3BpZCwgZGJnX2N1cnJfcHJvY2Vzcy0+aW1hZ2VOYW1lKTsKICAgICAgICAgICAgYmFja3RyYWNlX3RpZChkYmdfY3Vycl9wcm9jZXNzLCBlbnRyeS50aDMyVGhyZWFkSUQpOwogICAgICAgIH0KICAgICAgICB3aGlsZSAoVGhyZWFkMzJOZXh0KHNuYXBzaG90LCAmZW50cnkpKTsKCiAgICAgICAgaWYgKGRiZ19jdXJyX3Byb2Nlc3MpCiAgICAgICAgICAgIGRiZ19kZXRhY2hfZGVidWdnZWUoKTsKICAgIH0KICAgIENsb3NlSGFuZGxlKHNuYXBzaG90KTsKfQoKdm9pZCBzdGFja19iYWNrdHJhY2UoRFdPUkQgdGlkKQp7CiAgICAvKiBiYWNrdHJhY2UgZXZlcnkgdGhyZWFkIGluIGV2ZXJ5IHByb2Nlc3MgZXhjZXB0IHRoZSBkZWJ1Z2dlciBpdHNlbGYsCiAgICAgKiBpbnZva2luZyB2aWEgImJ0IGFsbCIKICAgICAqLwogICAgaWYgKHRpZCA9PSAtMSkgcmV0dXJuIGJhY2t0cmFjZV9hbGwoKTsKCiAgICBpZiAoIWRiZ19jdXJyX3Byb2Nlc3MpIAogICAgewogICAgICAgIGRiZ19wcmludGYoIllvdSBtdXN0IGJlIGF0dGFjaGVkIHRvIGEgcHJvY2VzcyB0byBydW4gdGhpcyBjb21tYW5kLlxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgCiAgICBpZiAodGlkID09IGRiZ19jdXJyX3RpZCkKICAgIHsKICAgICAgICBiYWNrdHJhY2UoKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBiYWNrdHJhY2VfdGlkKGRiZ19jdXJyX3Byb2Nlc3MsIHRpZCk7CiAgICB9Cn0K