LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgImRlYnVnZ2VyLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAidGxoZWxwMzIuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbmVkYmcpOwoKc3RhdGljIGludCAgICAgICAgICAgICAgICAgICAgICBuZnJhbWU7CnN0YXRpYyBJTUFHRUhMUF9TVEFDS19GUkFNRSogICAgZnJhbWVzID0gTlVMTDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgc3RhY2tfaW5mbwogKgogKiBEdW1wIHRoZSB0b3Agb2YgdGhlIHN0YWNrCiAqLwp2b2lkIHN0YWNrX2luZm8odm9pZCkKewogICAgc3RydWN0IGRiZ19sdmFsdWUgbHZhbHVlOwoKICAgIGx2YWx1ZS5jb29raWUgPSAwOwogICAgbHZhbHVlLnR5cGUuaWQgPSBkYmdfaXR5cGVfbm9uZTsKICAgIGx2YWx1ZS50eXBlLm1vZHVsZSA9IDA7CgogICAgLyogRklYTUU6IHdlIGFzc3VtZSBzdGFjayBncm93cyB0aGUgc2FtZSB3YXkgYXMgb24gaTM4NiAqLwogICAgaWYgKCFtZW1vcnlfZ2V0X2N1cnJlbnRfc3RhY2soJmx2YWx1ZS5hZGRyKSkKICAgICAgICBkYmdfcHJpbnRmKCJCYWQgc2VnbWVudCAoJWQpXG4iLCBsdmFsdWUuYWRkci5TZWdtZW50KTsKCiAgICBkYmdfcHJpbnRmKCJTdGFjayBkdW1wOlxuIik7CiAgICBzd2l0Y2ggKGx2YWx1ZS5hZGRyLk1vZGUpCiAgICB7CiAgICBjYXNlIEFkZHJNb2RlRmxhdDogLyogMzItYml0IG1vZGUgKi8KICAgIGNhc2UgQWRkck1vZGUxNjMyOiAvKiAzMi1iaXQgbW9kZSAqLwogICAgICAgIG1lbW9yeV9leGFtaW5lKCZsdmFsdWUsIDI0LCAneCcpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBZGRyTW9kZVJlYWw6ICAvKiAxNi1iaXQgbW9kZSAqLwogICAgY2FzZSBBZGRyTW9kZTE2MTY6CiAgICAgICAgbWVtb3J5X2V4YW1pbmUoJmx2YWx1ZSwgMjQsICd3Jyk7CglicmVhazsKICAgIH0KfQoKaW50IHN0YWNrX3NldF9mcmFtZShpbnQgbmV3ZnJhbWUpCnsKICAgIEFERFJFU1MgICAgIGFkZHI7CgogICAgZGJnX2N1cnJfZnJhbWUgPSBuZXdmcmFtZTsKICAgIGlmIChkYmdfY3Vycl9mcmFtZSA+PSBuZnJhbWUpIGRiZ19jdXJyX2ZyYW1lID0gbmZyYW1lIC0gMTsKICAgIGlmIChkYmdfY3Vycl9mcmFtZSA8IDApICAgICAgIGRiZ19jdXJyX2ZyYW1lID0gMDsKCiAgICBhZGRyLk1vZGUgPSBBZGRyTW9kZUZsYXQ7CiAgICBhZGRyLk9mZnNldCA9IGZyYW1lc1tkYmdfY3Vycl9mcmFtZV0uSW5zdHJ1Y3Rpb25PZmZzZXQ7CiAgICBzb3VyY2VfbGlzdF9mcm9tX2FkZHIoJmFkZHIsIDApOwogICAgcmV0dXJuIFRSVUU7Cn0KCkJPT0wgc3RhY2tfZ2V0X2ZyYW1lKFNZTUJPTF9JTkZPKiBzeW1ib2wsIElNQUdFSExQX1NUQUNLX0ZSQU1FKiBpaHNmKQp7CiAgICBEV09SRDY0ICAgICBkaXNwOwogICAgLyoKICAgICAqIElmIHdlIGRvbid0IGhhdmUgYSB2YWxpZCBiYWNrdHJhY2UsIHRoZW4ganVzdCByZXR1cm4uCiAgICAgKi8KICAgIGlmIChmcmFtZXMgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgIC8qCiAgICAgKiBJZiB3ZSBkb24ndCBrbm93IHdoYXQgdGhlIGN1cnJlbnQgZnVuY3Rpb24gaXMsIHRoZW4gd2UgYWxzbyBoYXZlCiAgICAgKiBub3RoaW5nIHRvIHJlcG9ydCBoZXJlLgogICAgICovCiAgICBpZiAoIVN5bUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgZnJhbWVzW2RiZ19jdXJyX2ZyYW1lXS5JbnN0cnVjdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgJmRpc3AsIHN5bWJvbCkpCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgaWYgKGloc2YpICppaHNmID0gZnJhbWVzW2RiZ19jdXJyX2ZyYW1lXTsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIHRoZSB0aGUgY3VycmVudCB0aHJlYWQKICovCnN0YXRpYyB1bnNpZ25lZCBiYWNrdHJhY2UoQk9PTCB3aXRoX2ZyYW1lcywgQk9PTCBub2lzeSkKewogICAgU1RBQ0tGUkFNRSAgc2Y7CiAgICB1bnNpZ25lZCAgICBuZiA9IDA7CgogICAgbWVtc2V0KCZzZiwgMCwgc2l6ZW9mKHNmKSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfZnJhbWUoJnNmLkFkZHJGcmFtZSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfcGMoJnNmLkFkZHJQQyk7CgogICAgLyogZG9uJ3QgY29uZnVzZSBTdGFja1dhbGsgYnkgcGFzc2luZyBpbiBpbmNvbnNpc3RlbnQgYWRkcmVzc2VzICovCiAgICBpZiAoKHNmLkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgJiYgKHNmLkFkZHJGcmFtZS5Nb2RlICE9IEFkZHJNb2RlRmxhdCkpCiAgICB7CiAgICAgICAgc2YuQWRkckZyYW1lLk9mZnNldCA9IChEV09SRCltZW1vcnlfdG9fbGluZWFyX2FkZHIoJnNmLkFkZHJGcmFtZSk7CiAgICAgICAgc2YuQWRkckZyYW1lLk1vZGUgPSBBZGRyTW9kZUZsYXQ7CiAgICB9CgogICAgaWYgKG5vaXN5KSBkYmdfcHJpbnRmKCJCYWNrdHJhY2U6XG4iKTsKICAgIHdoaWxlIChTdGFja1dhbGsoSU1BR0VfRklMRV9NQUNISU5FX0kzODYsIGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgCiAgICAgICAgICAgICAgICAgICAgIGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlLCAmc2YsICZkYmdfY29udGV4dCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgU3ltRnVuY3Rpb25UYWJsZUFjY2VzcywgU3ltR2V0TW9kdWxlQmFzZSwgTlVMTCkpCiAgICB7CiAgICAgICAgaWYgKHdpdGhfZnJhbWVzKQogICAgICAgIHsKICAgICAgICAgICAgZnJhbWVzID0gZGJnX2hlYXBfcmVhbGxvYyhmcmFtZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZiArIDEpICogc2l6ZW9mKElNQUdFSExQX1NUQUNLX0ZSQU1FKSk7CgogICAgICAgICAgICBmcmFtZXNbbmZdLkluc3RydWN0aW9uT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZzZi5BZGRyUEMpOwogICAgICAgICAgICBmcmFtZXNbbmZdLkZyYW1lT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZzZi5BZGRyRnJhbWUpOwogICAgICAgIH0KICAgICAgICBpZiAobm9pc3kpCiAgICAgICAgewogICAgICAgICAgICBkYmdfcHJpbnRmKCIlcyVkICIsIAogICAgICAgICAgICAgICAgICAgICAgICh3aXRoX2ZyYW1lcyAmJiBuZiA9PSBkYmdfY3Vycl9mcmFtZSA/ICI9PiIgOiAiICAiKSwKICAgICAgICAgICAgICAgICAgICAgICBuZiArIDEpOwogICAgICAgICAgICBwcmludF9hZGRyX2FuZF9hcmdzKCZzZi5BZGRyUEMsICZzZi5BZGRyRnJhbWUpOwogICAgICAgICAgICBkYmdfcHJpbnRmKCIgKCIpOwogICAgICAgICAgICBwcmludF9iYXJlX2FkZHJlc3MoJnNmLkFkZHJGcmFtZSk7CiAgICAgICAgICAgIGRiZ19wcmludGYoIilcbiIpOwogICAgICAgIH0KICAgICAgICBuZisrOwogICAgICAgIC8qIHdlJ3ZlIHByb2JhYmx5IGdvdHRlbiBvdXJzZWx2ZXMgaW50byBhbiBpbmZpbml0ZSBsb29wIHNvIGJhaWwgKi8KICAgICAgICBpZiAobmYgPiAyMDApCiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIG5mOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQliYWNrdHJhY2VfdGlkCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIGEgdGhyZWFkIGZyb20gaXRzIHByb2Nlc3MgYW5kIGl0cyBpZGVudGlmaWVyCiAqIChwcmVzZXJ2ZXMgY3VycmVudCB0aHJlYWQgYW5kIGNvbnRleHQgaW5mb3JtYXRpb24pCiAqLwpzdGF0aWMgdm9pZCBiYWNrdHJhY2VfdGlkKHN0cnVjdCBkYmdfcHJvY2VzcyogcGNzLCBEV09SRCB0aWQsIEJPT0wgbm9pc3kpCnsKICAgIHN0cnVjdCBkYmdfdGhyZWFkKiAgdGhyZWFkID0gZGJnX2N1cnJfdGhyZWFkOwoKICAgIGlmICghKGRiZ19jdXJyX3RocmVhZCA9IGRiZ19nZXRfdGhyZWFkKHBjcywgdGlkKSkpCiAgICAgICAgZGJnX3ByaW50ZigiVW5rbm93biB0aHJlYWQgaWQgKDB4JWx4KSBpbiBwcm9jZXNzICgweCVseClcbiIsIHRpZCwgcGNzLT5waWQpOwogICAgZWxzZQogICAgewogICAgICAgIENPTlRFWFQgc2F2ZWRfY3R4ID0gZGJnX2NvbnRleHQ7CgogICAgICAgIGRiZ19jdXJyX3RpZCA9IGRiZ19jdXJyX3RocmVhZC0+dGlkOwogICAgICAgIG1lbXNldCgmZGJnX2NvbnRleHQsIDAsIHNpemVvZihkYmdfY29udGV4dCkpOwogICAgICAgIGRiZ19jb250ZXh0LkNvbnRleHRGbGFncyA9IENPTlRFWFRfRlVMTDsKICAgICAgICBpZiAoU3VzcGVuZFRocmVhZChkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSkgIT0gLTEpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIUdldFRocmVhZENvbnRleHQoZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUsICZkYmdfY29udGV4dCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRiZ19wcmludGYoIkNhbid0IGdldCBjb250ZXh0IGZvciB0aHJlYWQgMHglbHggaW4gY3VycmVudCBwcm9jZXNzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICB0aWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgYmFja3RyYWNlKEZBTFNFLCBub2lzeSk7CiAgICAgICAgICAgIFJlc3VtZVRocmVhZChkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgZGJnX3ByaW50ZigiQ2FuJ3Qgc3VzcGVuZCB0aHJlYWQgMHglbHggaW4gY3VycmVudCBwcm9jZXNzXG4iLCB0aWQpOwogICAgICAgIGRiZ19jb250ZXh0ID0gc2F2ZWRfY3R4OwogICAgfQogICAgZGJnX2N1cnJfdGhyZWFkID0gdGhyZWFkOwogICAgZGJnX2N1cnJfdGlkID0gdGhyZWFkID8gdGhyZWFkLT50aWQgOiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQliYWNrdHJhY2VfYWxsCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIGV2ZXJ5IHJ1bm5pbmcgdGhyZWFkIGluIHRoZSBzeXN0ZW0gKGV4Y2VwdCB0aGUgZGVidWdnZXIpCiAqIChwcmVzZXJ2ZXMgY3VycmVudCBwcm9jZXNzIGluZm9ybWF0aW9uKQogKi8Kc3RhdGljIHZvaWQgYmFja3RyYWNlX2FsbCh2b2lkKQp7CiAgICBUSFJFQURFTlRSWTMyICAgICAgIGVudHJ5OwogICAgSEFORExFICAgICAgICAgICAgICBzbmFwc2hvdCA9IENyZWF0ZVRvb2xoZWxwMzJTbmFwc2hvdChUSDMyQ1NfU05BUFRIUkVBRCwgMCk7CgogICAgaWYgKHNuYXBzaG90ID09IElOVkFMSURfSEFORExFX1ZBTFVFKQogICAgewogICAgICAgIGRiZ19wcmludGYoIlVuYWJsZSB0byBjcmVhdGUgdG9vbGhlbHAgc25hcHNob3RcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBlbnRyeS5kd1NpemUgPSBzaXplb2YoZW50cnkpOwogICAgaWYgKFRocmVhZDMyRmlyc3Qoc25hcHNob3QsICZlbnRyeSkpCiAgICB7CiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQgPT0gR2V0Q3VycmVudFByb2Nlc3NJZCgpKSBjb250aW51ZTsKICAgICAgICAgICAgaWYgKGRiZ19jdXJyX3Byb2Nlc3MgJiYgZGJnX2N1cnJfcGlkICE9IGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCkKICAgICAgICAgICAgICAgIGRiZ19kZXRhY2hfZGVidWdnZWUoKTsKCiAgICAgICAgICAgIGlmIChlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQgIT0gZGJnX2N1cnJfcGlkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWRiZ19hdHRhY2hfZGVidWdnZWUoZW50cnkudGgzMk93bmVyUHJvY2Vzc0lELCBGQUxTRSwgVFJVRSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGJnX3ByaW50ZigiXG53YXJuaW5nOiBjb3VsZCBub3QgYXR0YWNoIHRvIDB4JWx4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRiZ19jdXJyX3BpZCA9IGRiZ19jdXJyX3Byb2Nlc3MtPnBpZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZGJnX3ByaW50ZigiXG5CYWNrdHJhY2luZyBmb3IgdGhyZWFkIDB4JWx4IGluIHByb2Nlc3MgMHglbHggKCVzKTpcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnkudGgzMlRocmVhZElELCBkYmdfY3Vycl9waWQsIGRiZ19jdXJyX3Byb2Nlc3MtPmltYWdlTmFtZSk7CiAgICAgICAgICAgIGJhY2t0cmFjZV90aWQoZGJnX2N1cnJfcHJvY2VzcywgZW50cnkudGgzMlRocmVhZElELCBUUlVFKTsKICAgICAgICB9CiAgICAgICAgd2hpbGUgKFRocmVhZDMyTmV4dChzbmFwc2hvdCwgJmVudHJ5KSk7CgogICAgICAgIGlmIChkYmdfY3Vycl9wcm9jZXNzKQogICAgICAgICAgICBkYmdfZGV0YWNoX2RlYnVnZ2VlKCk7CiAgICB9CiAgICBDbG9zZUhhbmRsZShzbmFwc2hvdCk7Cn0KCnZvaWQgc3RhY2tfYmFja3RyYWNlKERXT1JEIHRpZCwgQk9PTCBub2lzeSkKewogICAgLyogYmFja3RyYWNlIGV2ZXJ5IHRocmVhZCBpbiBldmVyeSBwcm9jZXNzIGV4Y2VwdCB0aGUgZGVidWdnZXIgaXRzZWxmLAogICAgICogaW52b2tpbmcgdmlhICJidCBhbGwiCiAgICAgKi8KICAgIGlmICh0aWQgPT0gLTEpIHJldHVybiBiYWNrdHJhY2VfYWxsKCk7CgogICAgaWYgKCFkYmdfY3Vycl9wcm9jZXNzKSAKICAgIHsKICAgICAgICBkYmdfcHJpbnRmKCJZb3UgbXVzdCBiZSBhdHRhY2hlZCB0byBhIHByb2Nlc3MgdG8gcnVuIHRoaXMgY29tbWFuZC5cbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIAogICAgaWYgKHRpZCA9PSBkYmdfY3Vycl90aWQpCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZnJhbWVzKTsKICAgICAgICBmcmFtZXMgPSBOVUxMOwogICAgICAgIG5mcmFtZSA9IGJhY2t0cmFjZShUUlVFLCBub2lzeSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgYmFja3RyYWNlX3RpZChkYmdfY3Vycl9wcm9jZXNzLCB0aWQsIG5vaXN5KTsKICAgIH0KfQo=