LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgImRlYnVnZ2VyLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAidGxoZWxwMzIuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbmVkYmcpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBzdGFja19pbmZvCiAqCiAqIER1bXAgdGhlIHRvcCBvZiB0aGUgc3RhY2sKICovCnZvaWQgc3RhY2tfaW5mbyh2b2lkKQp7CiAgICBzdHJ1Y3QgZGJnX2x2YWx1ZSBsdmFsdWU7CgogICAgbHZhbHVlLmNvb2tpZSA9IDA7CiAgICBsdmFsdWUudHlwZS5pZCA9IGRiZ19pdHlwZV9zZWdwdHI7CiAgICBsdmFsdWUudHlwZS5tb2R1bGUgPSAwOwoKICAgIC8qIEZJWE1FOiB3ZSBhc3N1bWUgc3RhY2sgZ3Jvd3MgdGhlIHNhbWUgd2F5IGFzIG9uIGkzODYgKi8KICAgIGlmICghbWVtb3J5X2dldF9jdXJyZW50X3N0YWNrKCZsdmFsdWUuYWRkcikpCiAgICAgICAgZGJnX3ByaW50ZigiQmFkIHNlZ21lbnQgKCVkKVxuIiwgbHZhbHVlLmFkZHIuU2VnbWVudCk7CgogICAgZGJnX3ByaW50ZigiU3RhY2sgZHVtcDpcbiIpOwogICAgc3dpdGNoIChsdmFsdWUuYWRkci5Nb2RlKQogICAgewogICAgY2FzZSBBZGRyTW9kZUZsYXQ6IC8qIDMyLWJpdCBtb2RlICovCiAgICBjYXNlIEFkZHJNb2RlMTYzMjogLyogMzItYml0IG1vZGUgKi8KICAgICAgICBtZW1vcnlfZXhhbWluZSgmbHZhbHVlLCAyNCwgJ3gnKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQWRkck1vZGVSZWFsOiAgLyogMTYtYml0IG1vZGUgKi8KICAgIGNhc2UgQWRkck1vZGUxNjE2OgogICAgICAgIG1lbW9yeV9leGFtaW5lKCZsdmFsdWUsIDI0LCAndycpOwoJYnJlYWs7CiAgICB9Cn0KCnN0YXRpYyBCT09MIHN0YWNrX3NldF9mcmFtZV9pbnRlcm5hbChpbnQgbmV3ZnJhbWUpCnsKICAgIGlmIChuZXdmcmFtZSA+PSBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXMpCiAgICAgICAgbmV3ZnJhbWUgPSBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXMgLSAxOwogICAgaWYgKG5ld2ZyYW1lIDwgMCkKICAgICAgICBuZXdmcmFtZSA9IDA7CgogICAgaWYgKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSAhPSBuZXdmcmFtZSkKICAgIHsKICAgICAgICBJTUFHRUhMUF9TVEFDS19GUkFNRSAgICBpaHNmOwoKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPSBuZXdmcmFtZTsKICAgICAgICBzdGFja19nZXRfY3VycmVudF9mcmFtZSgmaWhzZik7CiAgICAgICAgU3ltU2V0Q29udGV4dChkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsICZpaHNmLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBzdGFja19nZXRfZnJhbWUoaW50IG5mLCBJTUFHRUhMUF9TVEFDS19GUkFNRSogaWhzZikKewogICAgbWVtc2V0KGloc2YsIDAsIHNpemVvZigqaWhzZikpOwogICAgaWhzZi0+SW5zdHJ1Y3Rpb25PZmZzZXQgPSAodW5zaWduZWQgbG9uZyltZW1vcnlfdG9fbGluZWFyX2FkZHIoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5hZGRyX3BjKTsKICAgIGloc2YtPkZyYW1lT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9mcmFtZSk7CiAgICByZXR1cm4gVFJVRTsKfQoKQk9PTCBzdGFja19nZXRfY3VycmVudF9mcmFtZShJTUFHRUhMUF9TVEFDS19GUkFNRSogaWhzZikKewogICAgLyoKICAgICAqIElmIHdlIGRvbid0IGhhdmUgYSB2YWxpZCBiYWNrdHJhY2UsIHRoZW4ganVzdCByZXR1cm4uCiAgICAgKi8KICAgIGlmIChkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CiAgICByZXR1cm4gc3RhY2tfZ2V0X2ZyYW1lKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSwgaWhzZik7Cn0KCkJPT0wgc3RhY2tfc2V0X2ZyYW1lKGludCBuZXdmcmFtZSkKewogICAgQUREUkVTUyAgICAgYWRkcjsKICAgIGlmICghc3RhY2tfc2V0X2ZyYW1lX2ludGVybmFsKG5ld2ZyYW1lKSkgcmV0dXJuIEZBTFNFOwogICAgYWRkci5Nb2RlID0gQWRkck1vZGVGbGF0OwogICAgYWRkci5PZmZzZXQgPSAodW5zaWduZWQgbG9uZyltZW1vcnlfdG9fbGluZWFyX2FkZHIoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW2RiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZV0uYWRkcl9wYyk7CiAgICBzb3VyY2VfbGlzdF9mcm9tX2FkZHIoJmFkZHIsIDApOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXN0YWNrX2dldF9jdXJyZW50X3N5bWJvbAogKgogKiBSZXRyaWV2ZXMgdGhlIHN5bWJvbCBpbmZvcm1hdGlvbiBmb3IgdGhlIGN1cnJlbnQgZnJhbWUgZWxlbWVudAogKi8KQk9PTCBzdGFja19nZXRfY3VycmVudF9zeW1ib2woU1lNQk9MX0lORk8qIHN5bWJvbCkKewogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CiAgICBEV09SRDY0ICAgICAgICAgICAgICAgICAgICAgZGlzcDsKCiAgICBpZiAoIXN0YWNrX2dldF9jdXJyZW50X2ZyYW1lKCZpaHNmKSkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIFN5bUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAmZGlzcCwgc3ltYm9sKTsKfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgc3RhY2tfcmVhZF9tZW0oSEFORExFIGhQcm9jLCBEV09SRCBhZGRyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFZPSUQgYnVmZmVyLCBEV09SRCBzaXplLCBQRFdPUkQgd3JpdHRlbikKewogICAgc3RydWN0IGRiZ19wcm9jZXNzKiBwY3MgPSBkYmdfZ2V0X3Byb2Nlc3NfaChoUHJvYyk7CiAgICBpZiAoIXBjcykgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIHBjcy0+cHJvY2Vzc19pby0+cmVhZChoUHJvYywgKGNvbnN0IHZvaWQqKWFkZHIsIGJ1ZmZlciwgc2l6ZSwgd3JpdHRlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXN0YWNrX2ZldGNoX2ZyYW1lcwogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiB0aGUgdGhlIGN1cnJlbnQgdGhyZWFkCiAqLwp1bnNpZ25lZCBzdGFja19mZXRjaF9mcmFtZXModm9pZCkKewogICAgU1RBQ0tGUkFNRSAgc2Y7CiAgICB1bnNpZ25lZCAgICBuZiA9IDA7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMpOwogICAgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMgPSBOVUxMOwoKICAgIG1lbXNldCgmc2YsIDAsIHNpemVvZihzZikpOwogICAgbWVtb3J5X2dldF9jdXJyZW50X2ZyYW1lKCZzZi5BZGRyRnJhbWUpOwogICAgbWVtb3J5X2dldF9jdXJyZW50X3BjKCZzZi5BZGRyUEMpOwoKICAgIC8qIGRvbid0IGNvbmZ1c2UgU3RhY2tXYWxrIGJ5IHBhc3NpbmcgaW4gaW5jb25zaXN0ZW50IGFkZHJlc3NlcyAqLwogICAgaWYgKChzZi5BZGRyUEMuTW9kZSA9PSBBZGRyTW9kZUZsYXQpICYmIChzZi5BZGRyRnJhbWUuTW9kZSAhPSBBZGRyTW9kZUZsYXQpKQogICAgewogICAgICAgIHNmLkFkZHJGcmFtZS5PZmZzZXQgPSAoRFdPUkQpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZzZi5BZGRyRnJhbWUpOwogICAgICAgIHNmLkFkZHJGcmFtZS5Nb2RlID0gQWRkck1vZGVGbGF0OwogICAgfQoKICAgIHdoaWxlIChTdGFja1dhbGsoSU1BR0VfRklMRV9NQUNISU5FX0kzODYsIGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgCiAgICAgICAgICAgICAgICAgICAgIGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlLCAmc2YsICZkYmdfY29udGV4dCwgc3RhY2tfcmVhZF9tZW0sCiAgICAgICAgICAgICAgICAgICAgIFN5bUZ1bmN0aW9uVGFibGVBY2Nlc3MsIFN5bUdldE1vZHVsZUJhc2UsIE5VTEwpKQogICAgewogICAgICAgIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzID0gZGJnX2hlYXBfcmVhbGxvYyhkYmdfY3Vycl90aHJlYWQtPmZyYW1lcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZiArIDEpICogc2l6ZW9mKGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzWzBdKSk7CgogICAgICAgIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5hZGRyX3BjID0gc2YuQWRkclBDOwogICAgICAgIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5hZGRyX2ZyYW1lID0gc2YuQWRkckZyYW1lOwogICAgICAgIG5mKys7CiAgICAgICAgLyogd2UndmUgcHJvYmFibHkgZ290dGVuIG91cnNlbHZlcyBpbnRvIGFuIGluZmluaXRlIGxvb3Agc28gYmFpbCAqLwogICAgICAgIGlmIChuZiA+IDIwMCkgYnJlYWs7CiAgICB9CiAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPSAtMTsKICAgIGRiZ19jdXJyX3RocmVhZC0+bnVtX2ZyYW1lcyA9IG5mOwogICAgc3RhY2tfc2V0X2ZyYW1lX2ludGVybmFsKDApOwogICAgcmV0dXJuIG5mOwp9CgpzdHJ1Y3Qgc3ltX2VudW0KewogICAgY2hhciogICAgICAgdG1wOwogICAgRFdPUkQgICAgICAgZnJhbWU7Cn07CgpzdGF0aWMgQk9PTCBXSU5BUEkgc3ltX2VudW1fY2IoU1lNQk9MX0lORk8qIHN5bV9pbmZvLCBVTE9ORyBzaXplLCB2b2lkKiB1c2VyKQp7CiAgICBzdHJ1Y3Qgc3ltX2VudW0qICAgIHNlID0gKHN0cnVjdCBzeW1fZW51bSopdXNlcjsKICAgIGNoYXIgICAgICAgICAgICAgICAgdG1wWzMyXTsKCiAgICBpZiAoc3ltX2luZm8tPkZsYWdzICYgU1lNRkxBR19QQVJBTUVURVIpCiAgICB7CiAgICAgICAgaWYgKHNlLT50bXBbMF0pIHN0cmNhdChzZS0+dG1wLCAiLCAiKTsKICAgIAogICAgICAgIGlmIChzeW1faW5mby0+RmxhZ3MgJiBTWU1GTEFHX1JFR1JFTCkKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkICAgIHZhbDsKICAgICAgICAgICAgRFdPUkQgICAgICAgYWRkciA9IHNlLT5mcmFtZSArIHN5bV9pbmZvLT5BZGRyZXNzOwoKICAgICAgICAgICAgaWYgKCFkYmdfcmVhZF9tZW1vcnkoKGNoYXIqKWFkZHIsICZ2YWwsIHNpemVvZih2YWwpKSkKICAgICAgICAgICAgICAgIHNucHJpbnRmKHRtcCwgc2l6ZW9mKHRtcCksICI8KioqIGNhbm5vdCByZWFkIGF0IDB4JWx4ICoqKj4iLCBhZGRyKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgc25wcmludGYodG1wLCBzaXplb2YodG1wKSwgIjB4JXgiLCB2YWwpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzeW1faW5mby0+RmxhZ3MgJiBTWU1GTEFHX1JFR0lTVEVSKQogICAgICAgIHsKICAgICAgICAgICAgRFdPUkQqIHB2YWw7CgogICAgICAgICAgICBpZiAobWVtb3J5X2dldF9yZWdpc3RlcihzeW1faW5mby0+UmVnaXN0ZXIsICZwdmFsLCB0bXAsIHNpemVvZih0bXApKSkKICAgICAgICAgICAgICAgIHNucHJpbnRmKHRtcCwgc2l6ZW9mKHRtcCksICIweCVseCIsICpwdmFsKTsKICAgICAgICB9CiAgICAgICAgc3ByaW50ZihzZS0+dG1wICsgc3RybGVuKHNlLT50bXApLCAiJXM9JXMiLCBzeW1faW5mby0+TmFtZSwgdG1wKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBzdGFja19wcmludF9hZGRyX2FuZF9hcmdzKGludCBuZikKewogICAgY2hhciAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlcltzaXplb2YoU1lNQk9MX0lORk8pICsgMjU2XTsKICAgIFNZTUJPTF9JTkZPKiAgICAgICAgICAgICAgICBzaSA9IChTWU1CT0xfSU5GTyopYnVmZmVyOwogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CiAgICBJTUFHRUhMUF9MSU5FICAgICAgICAgICAgICAgaWw7CiAgICBJTUFHRUhMUF9NT0RVTEUgICAgICAgICAgICAgaW07CiAgICBEV09SRDY0ICAgICAgICAgICAgICAgICAgICAgZGlzcDY0OwoKICAgIHByaW50X2JhcmVfYWRkcmVzcygmZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfcGMpOwoKICAgIHN0YWNrX2dldF9mcmFtZShuZiwgJmloc2YpOwoKICAgIC8qIGdyYWIgbW9kdWxlIHdoZXJlIHN5bWJvbCBpcy4gSWYgd2UgZG9uJ3QgaGF2ZSBhIG1vZHVsZSwgd2UgY2Fubm90IHByaW50IG1vcmUgKi8KICAgIGltLlNpemVPZlN0cnVjdCA9IHNpemVvZihpbSk7CiAgICBpZiAoIVN5bUdldE1vZHVsZUluZm8oZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCBpaHNmLkluc3RydWN0aW9uT2Zmc2V0LCAmaW0pKQogICAgICAgIHJldHVybjsKCiAgICBzaS0+U2l6ZU9mU3RydWN0ID0gc2l6ZW9mKCpzaSk7CiAgICBzaS0+TWF4TmFtZUxlbiAgID0gMjU2OwogICAgaWYgKFN5bUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwgJmRpc3A2NCwgc2kpKQogICAgewogICAgICAgIHN0cnVjdCBzeW1fZW51bSBzZTsKICAgICAgICBjaGFyICAgICAgICAgICAgdG1wWzEwMjRdOwogICAgICAgIERXT1JEICAgICAgICAgICBkaXNwOwoKICAgICAgICBkYmdfcHJpbnRmKCIgJXMiLCBzaS0+TmFtZSk7CiAgICAgICAgaWYgKGRpc3A2NCkgZGJnX3ByaW50ZigiKzB4JWx4IiwgKERXT1JEX1BUUilkaXNwNjQpOwoKICAgICAgICBTeW1TZXRDb250ZXh0KGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgJmloc2YsIE5VTEwpOwogICAgICAgIHNlLnRtcCA9IHRtcDsKICAgICAgICBzZS5mcmFtZSA9IGloc2YuRnJhbWVPZmZzZXQ7CiAgICAgICAgdG1wWzBdID0gJ1wwJzsKICAgICAgICBTeW1FbnVtU3ltYm9scyhkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIDAsIE5VTEwsIHN5bV9lbnVtX2NiLCAmc2UpOwogICAgICAgIGlmICh0bXBbMF0pIGRiZ19wcmludGYoIiglcykiLCB0bXApOwoKICAgICAgICBpbC5TaXplT2ZTdHJ1Y3QgPSBzaXplb2YoaWwpOwogICAgICAgIGlmIChTeW1HZXRMaW5lRnJvbUFkZHIoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCBpaHNmLkluc3RydWN0aW9uT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRpc3AsICZpbCkpCiAgICAgICAgICAgIGRiZ19wcmludGYoIiBbJXM6JWx1XSIsIGlsLkZpbGVOYW1lLCBpbC5MaW5lTnVtYmVyKTsKICAgICAgICBkYmdfcHJpbnRmKCIgaW4gJXMiLCBpbS5Nb2R1bGVOYW1lKTsKICAgIH0KICAgIGVsc2UgZGJnX3ByaW50ZigiIGluICVzICgrMHglbHgpIiwgCiAgICAgICAgICAgICAgICAgICAgaW0uTW9kdWxlTmFtZSwgKERXT1JEX1BUUikoaWhzZi5JbnN0cnVjdGlvbk9mZnNldCAtIGltLkJhc2VPZkltYWdlKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWJhY2t0cmFjZQogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiB0aGUgdGhlIGN1cnJlbnQgdGhyZWFkCiAqLwpzdGF0aWMgdm9pZCBiYWNrdHJhY2Uodm9pZCkKewogICAgdW5zaWduZWQgICAgICAgICAgICAgICAgICAgIGNmID0gZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lOwogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CgogICAgZGJnX3ByaW50ZigiQmFja3RyYWNlOlxuIik7CiAgICBmb3IgKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSA9IDA7CiAgICAgICAgIGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSA8IGRiZ19jdXJyX3RocmVhZC0+bnVtX2ZyYW1lczsKICAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lKyspCiAgICB7CiAgICAgICAgZGJnX3ByaW50ZigiJXMlZCAiLCAKICAgICAgICAgICAgICAgICAgIChjZiA9PSBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPyAiPT4iIDogIiAgIiksCiAgICAgICAgICAgICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgKyAxKTsKICAgICAgICBzdGFja19wcmludF9hZGRyX2FuZF9hcmdzKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSk7CiAgICAgICAgZGJnX3ByaW50ZigiICgiKTsKICAgICAgICBwcmludF9iYXJlX2FkZHJlc3MoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW2RiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZV0uYWRkcl9wYyk7CiAgICAgICAgZGJnX3ByaW50ZigiKVxuIik7CiAgICB9CiAgICAvKiByZXNldCBjb250ZXh0IHRvIGN1cnJlbnQgc3RhY2sgZnJhbWUgKi8KICAgIGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSA9IGNmOwogICAgc3RhY2tfZ2V0X2ZyYW1lKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSwgJmloc2YpOwogICAgU3ltU2V0Q29udGV4dChkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsICZpaHNmLCBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlX3RpZAogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiBhIHRocmVhZCBmcm9tIGl0cyBwcm9jZXNzIGFuZCBpdHMgaWRlbnRpZmllcgogKiAocHJlc2VydmVzIGN1cnJlbnQgdGhyZWFkIGFuZCBjb250ZXh0IGluZm9ybWF0aW9uKQogKi8Kc3RhdGljIHZvaWQgYmFja3RyYWNlX3RpZChzdHJ1Y3QgZGJnX3Byb2Nlc3MqIHBjcywgRFdPUkQgdGlkKQp7CiAgICBzdHJ1Y3QgZGJnX3RocmVhZCogIHRocmVhZCA9IGRiZ19jdXJyX3RocmVhZDsKCiAgICBpZiAoIShkYmdfY3Vycl90aHJlYWQgPSBkYmdfZ2V0X3RocmVhZChwY3MsIHRpZCkpKQogICAgICAgIGRiZ19wcmludGYoIlVua25vd24gdGhyZWFkIGlkICgweCVseCkgaW4gcHJvY2VzcyAoMHglbHgpXG4iLCB0aWQsIHBjcy0+cGlkKTsKICAgIGVsc2UKICAgIHsKICAgICAgICBDT05URVhUIHNhdmVkX2N0eCA9IGRiZ19jb250ZXh0OwoKICAgICAgICBkYmdfY3Vycl90aWQgPSBkYmdfY3Vycl90aHJlYWQtPnRpZDsKICAgICAgICBtZW1zZXQoJmRiZ19jb250ZXh0LCAwLCBzaXplb2YoZGJnX2NvbnRleHQpKTsKICAgICAgICBkYmdfY29udGV4dC5Db250ZXh0RmxhZ3MgPSBDT05URVhUX0ZVTEw7CiAgICAgICAgaWYgKFN1c3BlbmRUaHJlYWQoZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUpICE9IC0xKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFHZXRUaHJlYWRDb250ZXh0KGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlLCAmZGJnX2NvbnRleHQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkYmdfcHJpbnRmKCJDYW4ndCBnZXQgY29udGV4dCBmb3IgdGhyZWFkIDB4JWx4IGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGJhY2t0cmFjZSgpOwogICAgICAgICAgICBSZXN1bWVUaHJlYWQoZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUpOwogICAgICAgIH0KICAgICAgICBlbHNlIGRiZ19wcmludGYoIkNhbid0IHN1c3BlbmQgdGhyZWFkIDB4JWx4IGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwgdGlkKTsKICAgICAgICBkYmdfY29udGV4dCA9IHNhdmVkX2N0eDsKICAgIH0KICAgIGRiZ19jdXJyX3RocmVhZCA9IHRocmVhZDsKICAgIGRiZ19jdXJyX3RpZCA9IHRocmVhZCA/IHRocmVhZC0+dGlkIDogMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlX2FsbAogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiBldmVyeSBydW5uaW5nIHRocmVhZCBpbiB0aGUgc3lzdGVtIChleGNlcHQgdGhlIGRlYnVnZ2VyKQogKiAocHJlc2VydmVzIGN1cnJlbnQgcHJvY2VzcyBpbmZvcm1hdGlvbikKICovCnN0YXRpYyB2b2lkIGJhY2t0cmFjZV9hbGwodm9pZCkKewogICAgVEhSRUFERU5UUlkzMiAgICAgICBlbnRyeTsKICAgIEhBTkRMRSAgICAgICAgICAgICAgc25hcHNob3QgPSBDcmVhdGVUb29saGVscDMyU25hcHNob3QoVEgzMkNTX1NOQVBUSFJFQUQsIDApOwoKICAgIGlmIChzbmFwc2hvdCA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgIHsKICAgICAgICBkYmdfcHJpbnRmKCJVbmFibGUgdG8gY3JlYXRlIHRvb2xoZWxwIHNuYXBzaG90XG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgZW50cnkuZHdTaXplID0gc2l6ZW9mKGVudHJ5KTsKICAgIGlmIChUaHJlYWQzMkZpcnN0KHNuYXBzaG90LCAmZW50cnkpKQogICAgewogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEID09IEdldEN1cnJlbnRQcm9jZXNzSWQoKSkgY29udGludWU7CiAgICAgICAgICAgIGlmIChkYmdfY3Vycl9wcm9jZXNzICYmIGRiZ19jdXJyX3BpZCAhPSBlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQpCiAgICAgICAgICAgICAgICBkYmdfY3Vycl9wcm9jZXNzLT5wcm9jZXNzX2lvLT5jbG9zZV9wcm9jZXNzKGRiZ19jdXJyX3Byb2Nlc3MsIEZBTFNFKTsKCiAgICAgICAgICAgIGlmIChlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQgIT0gZGJnX2N1cnJfcGlkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWRiZ19hdHRhY2hfZGVidWdnZWUoZW50cnkudGgzMk93bmVyUHJvY2Vzc0lELCBGQUxTRSwgVFJVRSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGJnX3ByaW50ZigiXG53YXJuaW5nOiBjb3VsZCBub3QgYXR0YWNoIHRvIDB4JWx4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRiZ19jdXJyX3BpZCA9IGRiZ19jdXJyX3Byb2Nlc3MtPnBpZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZGJnX3ByaW50ZigiXG5CYWNrdHJhY2luZyBmb3IgdGhyZWFkIDB4JWx4IGluIHByb2Nlc3MgMHglbHggKCVzKTpcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnkudGgzMlRocmVhZElELCBkYmdfY3Vycl9waWQsIGRiZ19jdXJyX3Byb2Nlc3MtPmltYWdlTmFtZSk7CiAgICAgICAgICAgIGJhY2t0cmFjZV90aWQoZGJnX2N1cnJfcHJvY2VzcywgZW50cnkudGgzMlRocmVhZElEKTsKICAgICAgICB9CiAgICAgICAgd2hpbGUgKFRocmVhZDMyTmV4dChzbmFwc2hvdCwgJmVudHJ5KSk7CgogICAgICAgIGlmIChkYmdfY3Vycl9wcm9jZXNzKQogICAgICAgICAgICBkYmdfY3Vycl9wcm9jZXNzLT5wcm9jZXNzX2lvLT5jbG9zZV9wcm9jZXNzKGRiZ19jdXJyX3Byb2Nlc3MsIEZBTFNFKTsKICAgIH0KICAgIENsb3NlSGFuZGxlKHNuYXBzaG90KTsKfQoKdm9pZCBzdGFja19iYWNrdHJhY2UoRFdPUkQgdGlkKQp7CiAgICAvKiBiYWNrdHJhY2UgZXZlcnkgdGhyZWFkIGluIGV2ZXJ5IHByb2Nlc3MgZXhjZXB0IHRoZSBkZWJ1Z2dlciBpdHNlbGYsCiAgICAgKiBpbnZva2luZyB2aWEgImJ0IGFsbCIKICAgICAqLwogICAgaWYgKHRpZCA9PSAtMSkgcmV0dXJuIGJhY2t0cmFjZV9hbGwoKTsKCiAgICBpZiAoIWRiZ19jdXJyX3Byb2Nlc3MpIAogICAgewogICAgICAgIGRiZ19wcmludGYoIllvdSBtdXN0IGJlIGF0dGFjaGVkIHRvIGEgcHJvY2VzcyB0byBydW4gdGhpcyBjb21tYW5kLlxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgCiAgICBpZiAodGlkID09IGRiZ19jdXJyX3RpZCkKICAgIHsKICAgICAgICBiYWNrdHJhY2UoKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBiYWNrdHJhY2VfdGlkKGRiZ19jdXJyX3Byb2Nlc3MsIHRpZCk7CiAgICB9Cn0K