LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgImRlYnVnZ2VyLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAidGxoZWxwMzIuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbmVkYmcpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBzdGFja19pbmZvCiAqCiAqIER1bXAgdGhlIHRvcCBvZiB0aGUgc3RhY2sKICovCnZvaWQgc3RhY2tfaW5mbyh2b2lkKQp7CiAgICBzdHJ1Y3QgZGJnX2x2YWx1ZSBsdmFsdWU7CgogICAgbHZhbHVlLmNvb2tpZSA9IDA7CiAgICBsdmFsdWUudHlwZS5pZCA9IGRiZ19pdHlwZV9ub25lOwogICAgbHZhbHVlLnR5cGUubW9kdWxlID0gMDsKCiAgICAvKiBGSVhNRTogd2UgYXNzdW1lIHN0YWNrIGdyb3dzIHRoZSBzYW1lIHdheSBhcyBvbiBpMzg2ICovCiAgICBpZiAoIW1lbW9yeV9nZXRfY3VycmVudF9zdGFjaygmbHZhbHVlLmFkZHIpKQogICAgICAgIGRiZ19wcmludGYoIkJhZCBzZWdtZW50ICglZClcbiIsIGx2YWx1ZS5hZGRyLlNlZ21lbnQpOwoKICAgIGRiZ19wcmludGYoIlN0YWNrIGR1bXA6XG4iKTsKICAgIHN3aXRjaCAobHZhbHVlLmFkZHIuTW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OiAvKiAzMi1iaXQgbW9kZSAqLwogICAgY2FzZSBBZGRyTW9kZTE2MzI6IC8qIDMyLWJpdCBtb2RlICovCiAgICAgICAgbWVtb3J5X2V4YW1pbmUoJmx2YWx1ZSwgMjQsICd4Jyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDogIC8qIDE2LWJpdCBtb2RlICovCiAgICBjYXNlIEFkZHJNb2RlMTYxNjoKICAgICAgICBtZW1vcnlfZXhhbWluZSgmbHZhbHVlLCAyNCwgJ3cnKTsKCWJyZWFrOwogICAgfQp9CgpzdGF0aWMgQk9PTCBzdGFja19zZXRfZnJhbWVfaW50ZXJuYWwoaW50IG5ld2ZyYW1lKQp7CiAgICBpZiAobmV3ZnJhbWUgPj0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzKQogICAgICAgIG5ld2ZyYW1lID0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzIC0gMTsKICAgIGlmIChuZXdmcmFtZSA8IDApCiAgICAgICAgbmV3ZnJhbWUgPSAwOwoKICAgIGlmIChkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgIT0gbmV3ZnJhbWUpCiAgICB7CiAgICAgICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgaWhzZjsKCiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gbmV3ZnJhbWU7CiAgICAgICAgc3RhY2tfZ2V0X2N1cnJlbnRfZnJhbWUoJmloc2YpOwogICAgICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgc3RhY2tfZ2V0X2ZyYW1lKGludCBuZiwgSU1BR0VITFBfU1RBQ0tfRlJBTUUqIGloc2YpCnsKICAgIGloc2YtPkluc3RydWN0aW9uT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyk7CiAgICBpaHNmLT5GcmFtZU9mZnNldCA9ICh1bnNpZ25lZCBsb25nKW1lbW9yeV90b19saW5lYXJfYWRkcigmZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfZnJhbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KCkJPT0wgc3RhY2tfZ2V0X2N1cnJlbnRfZnJhbWUoSU1BR0VITFBfU1RBQ0tfRlJBTUUqIGloc2YpCnsKICAgIC8qCiAgICAgKiBJZiB3ZSBkb24ndCBoYXZlIGEgdmFsaWQgYmFja3RyYWNlLCB0aGVuIGp1c3QgcmV0dXJuLgogICAgICovCiAgICBpZiAoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIHN0YWNrX2dldF9mcmFtZShkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUsIGloc2YpOwp9CgpCT09MIHN0YWNrX3NldF9mcmFtZShpbnQgbmV3ZnJhbWUpCnsKICAgIEFERFJFU1MgICAgIGFkZHI7CiAgICBpZiAoIXN0YWNrX3NldF9mcmFtZV9pbnRlcm5hbChuZXdmcmFtZSkpIHJldHVybiBGQUxTRTsKICAgIGFkZHIuTW9kZSA9IEFkZHJNb2RlRmxhdDsKICAgIGFkZHIuT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWVdLmFkZHJfcGMpOwogICAgc291cmNlX2xpc3RfZnJvbV9hZGRyKCZhZGRyLCAwKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlzdGFja19nZXRfY3VycmVudF9zeW1ib2wKICoKICogUmV0cmlldmVzIHRoZSBzeW1ib2wgaW5mb3JtYXRpb24gZm9yIHRoZSBjdXJyZW50IGZyYW1lIGVsZW1lbnQKICovCkJPT0wgc3RhY2tfZ2V0X2N1cnJlbnRfc3ltYm9sKFNZTUJPTF9JTkZPKiBzeW1ib2wpCnsKICAgIElNQUdFSExQX1NUQUNLX0ZSQU1FICAgICAgICBpaHNmOwogICAgRFdPUkQ2NCAgICAgICAgICAgICAgICAgICAgIGRpc3A7CgogICAgaWYgKCFzdGFja19nZXRfY3VycmVudF9mcmFtZSgmaWhzZikpIHJldHVybiBGQUxTRTsKICAgIHJldHVybiBTeW1Gcm9tQWRkcihkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgJmRpc3AsIHN5bWJvbCk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJc3RhY2tfZmV0Y2hfZnJhbWVzCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIHRoZSB0aGUgY3VycmVudCB0aHJlYWQKICovCnVuc2lnbmVkIHN0YWNrX2ZldGNoX2ZyYW1lcyh2b2lkKQp7CiAgICBTVEFDS0ZSQU1FICBzZjsKICAgIHVuc2lnbmVkICAgIG5mID0gMDsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyk7CiAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9IE5VTEw7CgogICAgbWVtc2V0KCZzZiwgMCwgc2l6ZW9mKHNmKSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfZnJhbWUoJnNmLkFkZHJGcmFtZSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfcGMoJnNmLkFkZHJQQyk7CgogICAgLyogZG9uJ3QgY29uZnVzZSBTdGFja1dhbGsgYnkgcGFzc2luZyBpbiBpbmNvbnNpc3RlbnQgYWRkcmVzc2VzICovCiAgICBpZiAoKHNmLkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgJiYgKHNmLkFkZHJGcmFtZS5Nb2RlICE9IEFkZHJNb2RlRmxhdCkpCiAgICB7CiAgICAgICAgc2YuQWRkckZyYW1lLk9mZnNldCA9IChEV09SRCltZW1vcnlfdG9fbGluZWFyX2FkZHIoJnNmLkFkZHJGcmFtZSk7CiAgICAgICAgc2YuQWRkckZyYW1lLk1vZGUgPSBBZGRyTW9kZUZsYXQ7CiAgICB9CgogICAgd2hpbGUgKFN0YWNrV2FsayhJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NiwgZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAKICAgICAgICAgICAgICAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUsICZzZiwgJmRiZ19jb250ZXh0LCBOVUxMLAogICAgICAgICAgICAgICAgICAgICBTeW1GdW5jdGlvblRhYmxlQWNjZXNzLCBTeW1HZXRNb2R1bGVCYXNlLCBOVUxMKSkKICAgIHsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9IGRiZ19oZWFwX3JlYWxsb2MoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmYgKyAxKSAqIHNpemVvZihkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1swXSkpOwoKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyA9IHNmLkFkZHJQQzsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9mcmFtZSA9IHNmLkFkZHJGcmFtZTsKICAgICAgICBuZisrOwogICAgICAgIC8qIHdlJ3ZlIHByb2JhYmx5IGdvdHRlbiBvdXJzZWx2ZXMgaW50byBhbiBpbmZpbml0ZSBsb29wIHNvIGJhaWwgKi8KICAgICAgICBpZiAobmYgPiAyMDApIGJyZWFrOwogICAgfQogICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gLTE7CiAgICBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXMgPSBuZjsKICAgIHN0YWNrX3NldF9mcmFtZV9pbnRlcm5hbCgwKTsKICAgIHJldHVybiBuZjsKfQoKc3RydWN0IHN5bV9lbnVtCnsKICAgIGNoYXIqICAgICAgIHRtcDsKICAgIERXT1JEICAgICAgIGZyYW1lOwp9OwoKc3RhdGljIEJPT0wgV0lOQVBJIHN5bV9lbnVtX2NiKFNZTUJPTF9JTkZPKiBzeW1faW5mbywgVUxPTkcgc2l6ZSwgdm9pZCogdXNlcikKewogICAgc3RydWN0IHN5bV9lbnVtKiAgICBzZSA9IChzdHJ1Y3Qgc3ltX2VudW0qKXVzZXI7CiAgICBEV09SRCAgICAgICAgICAgICAgIGFkZHI7CiAgICB1bnNpZ25lZCAgICAgICAgICAgIHZhbDsKCiAgICBpZiAoKHN5bV9pbmZvLT5GbGFncyAmIChTWU1GTEFHX1BBUkFNRVRFUnxTWU1GTEFHX1JFR1JFTCkpID09IChTWU1GTEFHX1BBUkFNRVRFUnxTWU1GTEFHX1JFR1JFTCkpCiAgICB7CiAgICAgICAgaWYgKHNlLT50bXBbMF0pIHN0cmNhdChzZS0+dG1wLCAiLCAiKTsKICAgICAgICBhZGRyID0gc2UtPmZyYW1lICsgc3ltX2luZm8tPkFkZHJlc3M7CiAgICAgICAgaWYgKGRiZ19yZWFkX21lbW9yeSgoY2hhciopYWRkciwgJnZhbCwgc2l6ZW9mKHZhbCkpKQogICAgICAgICAgICBzcHJpbnRmKHNlLT50bXAgKyBzdHJsZW4oc2UtPnRtcCksICIlcz0weCV4Iiwgc3ltX2luZm8tPk5hbWUsIHZhbCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBzcHJpbnRmKHNlLT50bXAgKyBzdHJsZW4oc2UtPnRtcCksICIlcz08XD9cP1w/PiIsIHN5bV9pbmZvLT5OYW1lKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBzdGFja19wcmludF9hZGRyX2FuZF9hcmdzKGludCBuZikKewogICAgY2hhciAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlcltzaXplb2YoU1lNQk9MX0lORk8pICsgMjU2XTsKICAgIFNZTUJPTF9JTkZPKiAgICAgICAgICAgICAgICBzaSA9IChTWU1CT0xfSU5GTyopYnVmZmVyOwogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CiAgICBJTUFHRUhMUF9MSU5FICAgICAgICAgICAgICAgaWw7CiAgICBJTUFHRUhMUF9NT0RVTEUgICAgICAgICAgICAgaW07CiAgICBEV09SRDY0ICAgICAgICAgICAgICAgICAgICAgZGlzcDY0OwoKICAgIHByaW50X2JhcmVfYWRkcmVzcygmZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfcGMpOwoKICAgIHN0YWNrX2dldF9mcmFtZShuZiwgJmloc2YpOwoKICAgIC8qIGdyYWIgbW9kdWxlIHdoZXJlIHN5bWJvbCBpcy4gSWYgd2UgZG9uJ3QgaGF2ZSBhIG1vZHVsZSwgd2UgY2Fubm90IHByaW50IG1vcmUgKi8KICAgIGltLlNpemVPZlN0cnVjdCA9IHNpemVvZihpbSk7CiAgICBpZiAoIVN5bUdldE1vZHVsZUluZm8oZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCBpaHNmLkluc3RydWN0aW9uT2Zmc2V0LCAmaW0pKQogICAgICAgIHJldHVybjsKCiAgICBzaS0+U2l6ZU9mU3RydWN0ID0gc2l6ZW9mKCpzaSk7CiAgICBzaS0+TWF4TmFtZUxlbiAgID0gMjU2OwogICAgaWYgKFN5bUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwgJmRpc3A2NCwgc2kpKQogICAgewogICAgICAgIHN0cnVjdCBzeW1fZW51bSBzZTsKICAgICAgICBjaGFyICAgICAgICAgICAgdG1wWzEwMjRdOwogICAgICAgIERXT1JEICAgICAgICAgICBkaXNwOwoKICAgICAgICBkYmdfcHJpbnRmKCIgJXMiLCBzaS0+TmFtZSk7CiAgICAgICAgaWYgKGRpc3ApIGRiZ19wcmludGYoIisweCVseCIsIChEV09SRF9QVFIpZGlzcDY0KTsKCiAgICAgICAgU3ltU2V0Q29udGV4dChkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsICZpaHNmLCBOVUxMKTsKICAgICAgICBzZS50bXAgPSB0bXA7CiAgICAgICAgc2UuZnJhbWUgPSBpaHNmLkZyYW1lT2Zmc2V0OwogICAgICAgIHRtcFswXSA9ICdcMCc7CiAgICAgICAgU3ltRW51bVN5bWJvbHMoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAwLCBOVUxMLCBzeW1fZW51bV9jYiwgJnNlKTsKICAgICAgICBpZiAodG1wWzBdKSBkYmdfcHJpbnRmKCIoJXMpIiwgdG1wKTsKCiAgICAgICAgaWwuU2l6ZU9mU3RydWN0ID0gc2l6ZW9mKGlsKTsKICAgICAgICBpZiAoU3ltR2V0TGluZUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkaXNwLCAmaWwpKQogICAgICAgICAgICBkYmdfcHJpbnRmKCIgWyVzOiVsdV0iLCBpbC5GaWxlTmFtZSwgaWwuTGluZU51bWJlcik7CiAgICAgICAgZGJnX3ByaW50ZigiIGluICVzIiwgaW0uTW9kdWxlTmFtZSk7CiAgICB9CiAgICBlbHNlIGRiZ19wcmludGYoIiBpbiAlcyAoKzB4JWx4KSIsIAogICAgICAgICAgICAgICAgICAgIGltLk1vZHVsZU5hbWUsIChEV09SRF9QVFIpKGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQgLSBpbS5CYXNlT2ZJbWFnZSkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQliYWNrdHJhY2UKICoKICogRG8gYSBiYWNrdHJhY2Ugb24gdGhlIHRoZSBjdXJyZW50IHRocmVhZAogKi8Kc3RhdGljIHVuc2lnbmVkIGJhY2t0cmFjZSh2b2lkKQp7CiAgICB1bnNpZ25lZCAgICAgICAgICAgICAgICAgICAgbmYgPSAwOwogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CgogICAgZGJnX3ByaW50ZigiQmFja3RyYWNlOlxuIik7CiAgICBmb3IgKG5mID0gMDsgbmYgPCBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXM7IG5mKyspCiAgICB7CiAgICAgICAgZGJnX3ByaW50ZigiJXMlZCAiLCAKICAgICAgICAgICAgICAgICAgIChuZiA9PSBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPyAiPT4iIDogIiAgIiksIG5mICsgMSk7CiAgICAgICAgc3RhY2tfcHJpbnRfYWRkcl9hbmRfYXJncyhuZik7CiAgICAgICAgZGJnX3ByaW50ZigiICgiKTsKICAgICAgICBwcmludF9iYXJlX2FkZHJlc3MoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5hZGRyX3BjKTsKICAgICAgICBkYmdfcHJpbnRmKCIpXG4iKTsKICAgIH0KICAgIC8qIHJlc2V0IGNvbnRleHQgdG8gY3VycmVudCBzdGFjayBmcmFtZSAqLwogICAgc3RhY2tfZ2V0X2ZyYW1lKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSwgJmloc2YpOwogICAgU3ltU2V0Q29udGV4dChkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsICZpaHNmLCBOVUxMKTsKICAgIHJldHVybiBuZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlX3RpZAogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiBhIHRocmVhZCBmcm9tIGl0cyBwcm9jZXNzIGFuZCBpdHMgaWRlbnRpZmllcgogKiAocHJlc2VydmVzIGN1cnJlbnQgdGhyZWFkIGFuZCBjb250ZXh0IGluZm9ybWF0aW9uKQogKi8Kc3RhdGljIHZvaWQgYmFja3RyYWNlX3RpZChzdHJ1Y3QgZGJnX3Byb2Nlc3MqIHBjcywgRFdPUkQgdGlkKQp7CiAgICBzdHJ1Y3QgZGJnX3RocmVhZCogIHRocmVhZCA9IGRiZ19jdXJyX3RocmVhZDsKCiAgICBpZiAoIShkYmdfY3Vycl90aHJlYWQgPSBkYmdfZ2V0X3RocmVhZChwY3MsIHRpZCkpKQogICAgICAgIGRiZ19wcmludGYoIlVua25vd24gdGhyZWFkIGlkICgweCVseCkgaW4gcHJvY2VzcyAoMHglbHgpXG4iLCB0aWQsIHBjcy0+cGlkKTsKICAgIGVsc2UKICAgIHsKICAgICAgICBDT05URVhUIHNhdmVkX2N0eCA9IGRiZ19jb250ZXh0OwoKICAgICAgICBkYmdfY3Vycl90aWQgPSBkYmdfY3Vycl90aHJlYWQtPnRpZDsKICAgICAgICBtZW1zZXQoJmRiZ19jb250ZXh0LCAwLCBzaXplb2YoZGJnX2NvbnRleHQpKTsKICAgICAgICBkYmdfY29udGV4dC5Db250ZXh0RmxhZ3MgPSBDT05URVhUX0ZVTEw7CiAgICAgICAgaWYgKFN1c3BlbmRUaHJlYWQoZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUpICE9IC0xKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFHZXRUaHJlYWRDb250ZXh0KGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlLCAmZGJnX2NvbnRleHQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkYmdfcHJpbnRmKCJDYW4ndCBnZXQgY29udGV4dCBmb3IgdGhyZWFkIDB4JWx4IGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGJhY2t0cmFjZSgpOwogICAgICAgICAgICBSZXN1bWVUaHJlYWQoZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUpOwogICAgICAgIH0KICAgICAgICBlbHNlIGRiZ19wcmludGYoIkNhbid0IHN1c3BlbmQgdGhyZWFkIDB4JWx4IGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwgdGlkKTsKICAgICAgICBkYmdfY29udGV4dCA9IHNhdmVkX2N0eDsKICAgIH0KICAgIGRiZ19jdXJyX3RocmVhZCA9IHRocmVhZDsKICAgIGRiZ19jdXJyX3RpZCA9IHRocmVhZCA/IHRocmVhZC0+dGlkIDogMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlX2FsbAogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiBldmVyeSBydW5uaW5nIHRocmVhZCBpbiB0aGUgc3lzdGVtIChleGNlcHQgdGhlIGRlYnVnZ2VyKQogKiAocHJlc2VydmVzIGN1cnJlbnQgcHJvY2VzcyBpbmZvcm1hdGlvbikKICovCnN0YXRpYyB2b2lkIGJhY2t0cmFjZV9hbGwodm9pZCkKewogICAgVEhSRUFERU5UUlkzMiAgICAgICBlbnRyeTsKICAgIEhBTkRMRSAgICAgICAgICAgICAgc25hcHNob3QgPSBDcmVhdGVUb29saGVscDMyU25hcHNob3QoVEgzMkNTX1NOQVBUSFJFQUQsIDApOwoKICAgIGlmIChzbmFwc2hvdCA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgIHsKICAgICAgICBkYmdfcHJpbnRmKCJVbmFibGUgdG8gY3JlYXRlIHRvb2xoZWxwIHNuYXBzaG90XG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgZW50cnkuZHdTaXplID0gc2l6ZW9mKGVudHJ5KTsKICAgIGlmIChUaHJlYWQzMkZpcnN0KHNuYXBzaG90LCAmZW50cnkpKQogICAgewogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEID09IEdldEN1cnJlbnRQcm9jZXNzSWQoKSkgY29udGludWU7CiAgICAgICAgICAgIGlmIChkYmdfY3Vycl9wcm9jZXNzICYmIGRiZ19jdXJyX3BpZCAhPSBlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQpCiAgICAgICAgICAgICAgICBkYmdfZGV0YWNoX2RlYnVnZ2VlKCk7CgogICAgICAgICAgICBpZiAoZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEICE9IGRiZ19jdXJyX3BpZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFkYmdfYXR0YWNoX2RlYnVnZ2VlKGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCwgRkFMU0UsIFRSVUUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRiZ19wcmludGYoIlxud2FybmluZzogY291bGQgbm90IGF0dGFjaCB0byAweCVseFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkYmdfY3Vycl9waWQgPSBkYmdfY3Vycl9wcm9jZXNzLT5waWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRiZ19wcmludGYoIlxuQmFja3RyYWNpbmcgZm9yIHRocmVhZCAweCVseCBpbiBwcm9jZXNzIDB4JWx4ICglcyk6XG4iLAogICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LnRoMzJUaHJlYWRJRCwgZGJnX2N1cnJfcGlkLCBkYmdfY3Vycl9wcm9jZXNzLT5pbWFnZU5hbWUpOwogICAgICAgICAgICBiYWNrdHJhY2VfdGlkKGRiZ19jdXJyX3Byb2Nlc3MsIGVudHJ5LnRoMzJUaHJlYWRJRCk7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChUaHJlYWQzMk5leHQoc25hcHNob3QsICZlbnRyeSkpOwoKICAgICAgICBpZiAoZGJnX2N1cnJfcHJvY2VzcykKICAgICAgICAgICAgZGJnX2RldGFjaF9kZWJ1Z2dlZSgpOwogICAgfQogICAgQ2xvc2VIYW5kbGUoc25hcHNob3QpOwp9Cgp2b2lkIHN0YWNrX2JhY2t0cmFjZShEV09SRCB0aWQpCnsKICAgIC8qIGJhY2t0cmFjZSBldmVyeSB0aHJlYWQgaW4gZXZlcnkgcHJvY2VzcyBleGNlcHQgdGhlIGRlYnVnZ2VyIGl0c2VsZiwKICAgICAqIGludm9raW5nIHZpYSAiYnQgYWxsIgogICAgICovCiAgICBpZiAodGlkID09IC0xKSByZXR1cm4gYmFja3RyYWNlX2FsbCgpOwoKICAgIGlmICghZGJnX2N1cnJfcHJvY2VzcykgCiAgICB7CiAgICAgICAgZGJnX3ByaW50ZigiWW91IG11c3QgYmUgYXR0YWNoZWQgdG8gYSBwcm9jZXNzIHRvIHJ1biB0aGlzIGNvbW1hbmQuXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAKICAgIGlmICh0aWQgPT0gZGJnX2N1cnJfdGlkKQogICAgewogICAgICAgIGJhY2t0cmFjZSgpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGJhY2t0cmFjZV90aWQoZGJnX2N1cnJfcHJvY2VzcywgdGlkKTsKICAgIH0KfQo=