LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgImRlYnVnZ2VyLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAidGxoZWxwMzIuaCIKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgc3RhY2tfaW5mbwogKgogKiBEdW1wIHRoZSB0b3Agb2YgdGhlIHN0YWNrCiAqLwp2b2lkIHN0YWNrX2luZm8odm9pZCkKewogICAgc3RydWN0IGRiZ19sdmFsdWUgbHZhbHVlOwoKICAgIGx2YWx1ZS5jb29raWUgPSAwOwogICAgbHZhbHVlLnR5cGUuaWQgPSBkYmdfaXR5cGVfc2VncHRyOwogICAgbHZhbHVlLnR5cGUubW9kdWxlID0gMDsKCiAgICAvKiBGSVhNRTogd2UgYXNzdW1lIHN0YWNrIGdyb3dzIHRoZSBzYW1lIHdheSBhcyBvbiBpMzg2ICovCiAgICBpZiAoIW1lbW9yeV9nZXRfY3VycmVudF9zdGFjaygmbHZhbHVlLmFkZHIpKQogICAgICAgIGRiZ19wcmludGYoIkJhZCBzZWdtZW50ICglZClcbiIsIGx2YWx1ZS5hZGRyLlNlZ21lbnQpOwoKICAgIGRiZ19wcmludGYoIlN0YWNrIGR1bXA6XG4iKTsKICAgIHN3aXRjaCAobHZhbHVlLmFkZHIuTW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OiAvKiAzMi1iaXQgbW9kZSAqLwogICAgY2FzZSBBZGRyTW9kZTE2MzI6IC8qIDMyLWJpdCBtb2RlICovCiAgICAgICAgbWVtb3J5X2V4YW1pbmUoJmx2YWx1ZSwgMjQsICd4Jyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDogIC8qIDE2LWJpdCBtb2RlICovCiAgICBjYXNlIEFkZHJNb2RlMTYxNjoKICAgICAgICBtZW1vcnlfZXhhbWluZSgmbHZhbHVlLCAyNCwgJ3cnKTsKCWJyZWFrOwogICAgfQp9CgpzdGF0aWMgQk9PTCBzdGFja19zZXRfZnJhbWVfaW50ZXJuYWwoaW50IG5ld2ZyYW1lKQp7CiAgICBpZiAobmV3ZnJhbWUgPj0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzKQogICAgICAgIG5ld2ZyYW1lID0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzIC0gMTsKICAgIGlmIChuZXdmcmFtZSA8IDApCiAgICAgICAgbmV3ZnJhbWUgPSAwOwoKICAgIGlmIChkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgIT0gbmV3ZnJhbWUpCiAgICB7CiAgICAgICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgaWhzZjsKCiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gbmV3ZnJhbWU7CiAgICAgICAgc3RhY2tfZ2V0X2N1cnJlbnRfZnJhbWUoJmloc2YpOwogICAgICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgc3RhY2tfZ2V0X2ZyYW1lKGludCBuZiwgSU1BR0VITFBfU1RBQ0tfRlJBTUUqIGloc2YpCnsKICAgIG1lbXNldChpaHNmLCAwLCBzaXplb2YoKmloc2YpKTsKICAgIGloc2YtPkluc3RydWN0aW9uT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyk7CiAgICBpaHNmLT5GcmFtZU9mZnNldCA9ICh1bnNpZ25lZCBsb25nKW1lbW9yeV90b19saW5lYXJfYWRkcigmZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfZnJhbWUpOwogICAgcmV0dXJuIFRSVUU7Cn0KCkJPT0wgc3RhY2tfZ2V0X2N1cnJlbnRfZnJhbWUoSU1BR0VITFBfU1RBQ0tfRlJBTUUqIGloc2YpCnsKICAgIC8qCiAgICAgKiBJZiB3ZSBkb24ndCBoYXZlIGEgdmFsaWQgYmFja3RyYWNlLCB0aGVuIGp1c3QgcmV0dXJuLgogICAgICovCiAgICBpZiAoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIHN0YWNrX2dldF9mcmFtZShkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUsIGloc2YpOwp9CgpCT09MIHN0YWNrX3NldF9mcmFtZShpbnQgbmV3ZnJhbWUpCnsKICAgIEFERFJFU1M2NCAgIGFkZHI7CiAgICBpZiAoIXN0YWNrX3NldF9mcmFtZV9pbnRlcm5hbChuZXdmcmFtZSkpIHJldHVybiBGQUxTRTsKICAgIGFkZHIuTW9kZSA9IEFkZHJNb2RlRmxhdDsKICAgIGFkZHIuT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWVdLmFkZHJfcGMpOwogICAgc291cmNlX2xpc3RfZnJvbV9hZGRyKCZhZGRyLCAwKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlzdGFja19nZXRfY3VycmVudF9zeW1ib2wKICoKICogUmV0cmlldmVzIHRoZSBzeW1ib2wgaW5mb3JtYXRpb24gZm9yIHRoZSBjdXJyZW50IGZyYW1lIGVsZW1lbnQKICovCkJPT0wgc3RhY2tfZ2V0X2N1cnJlbnRfc3ltYm9sKFNZTUJPTF9JTkZPKiBzeW1ib2wpCnsKICAgIElNQUdFSExQX1NUQUNLX0ZSQU1FICAgICAgICBpaHNmOwogICAgRFdPUkQ2NCAgICAgICAgICAgICAgICAgICAgIGRpc3A7CgogICAgaWYgKCFzdGFja19nZXRfY3VycmVudF9mcmFtZSgmaWhzZikpIHJldHVybiBGQUxTRTsKICAgIHJldHVybiBTeW1Gcm9tQWRkcihkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgJmRpc3AsIHN5bWJvbCk7Cn0KCnN0YXRpYyBCT09MIENBTExCQUNLIHN0YWNrX3JlYWRfbWVtKEhBTkRMRSBoUHJvYywgRFdPUkQ2NCBhZGRyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFZPSUQgYnVmZmVyLCBEV09SRCBzaXplLCBQRFdPUkQgd3JpdHRlbikKewogICAgU0laRV9UIHN6OwogICAgQk9PTCByZXQ7CgogICAgc3RydWN0IGRiZ19wcm9jZXNzKiBwY3MgPSBkYmdfZ2V0X3Byb2Nlc3NfaChoUHJvYyk7CiAgICBpZiAoIXBjcykgcmV0dXJuIEZBTFNFOwogICAgcmV0ID0gcGNzLT5wcm9jZXNzX2lvLT5yZWFkKGhQcm9jLCAoY29uc3Qgdm9pZCopKERXT1JEX1BUUilhZGRyLCBidWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSwgJnN6KTsKICAgIGlmICh3cml0dGVuICE9IE5VTEwpICp3cml0dGVuID0gc3o7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlzdGFja19mZXRjaF9mcmFtZXMKICoKICogRG8gYSBiYWNrdHJhY2Ugb24gdGhlIHRoZSBjdXJyZW50IHRocmVhZAogKi8KdW5zaWduZWQgc3RhY2tfZmV0Y2hfZnJhbWVzKHZvaWQpCnsKICAgIFNUQUNLRlJBTUU2NCBzZjsKICAgIHVuc2lnbmVkICAgICBuZiA9IDA7CiAgICAvKiBhcyBuYXRpdmUgc3RhY2t3YWxrIGNhbiBtb2RpZnkgdGhlIGNvbnRleHQgcGFzc2VkIHRvIGl0LCBzaW1wbHkgY29weQogICAgICogaXQgdG8gYXZvaWQgYW55IGRhbWFnZQogICAgICovCiAgICBDT05URVhUICAgICAgY3R4ID0gZGJnX2NvbnRleHQ7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMpOwogICAgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMgPSBOVUxMOwoKICAgIG1lbXNldCgmc2YsIDAsIHNpemVvZihzZikpOwogICAgbWVtb3J5X2dldF9jdXJyZW50X2ZyYW1lKCZzZi5BZGRyRnJhbWUpOwogICAgbWVtb3J5X2dldF9jdXJyZW50X3BjKCZzZi5BZGRyUEMpOwoKICAgIC8qIGRvbid0IGNvbmZ1c2UgU3RhY2tXYWxrIGJ5IHBhc3NpbmcgaW4gaW5jb25zaXN0ZW50IGFkZHJlc3NlcyAqLwogICAgaWYgKChzZi5BZGRyUEMuTW9kZSA9PSBBZGRyTW9kZUZsYXQpICYmIChzZi5BZGRyRnJhbWUuTW9kZSAhPSBBZGRyTW9kZUZsYXQpKQogICAgewogICAgICAgIHNmLkFkZHJGcmFtZS5PZmZzZXQgPSAoRFdPUkQpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZzZi5BZGRyRnJhbWUpOwogICAgICAgIHNmLkFkZHJGcmFtZS5Nb2RlID0gQWRkck1vZGVGbGF0OwogICAgfQoKICAgIHdoaWxlIChTdGFja1dhbGs2NChJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NiwgZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAKICAgICAgICAgICAgICAgICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSwgJnNmLCAmY3R4LCBzdGFja19yZWFkX21lbSwKICAgICAgICAgICAgICAgICAgICAgICBTeW1GdW5jdGlvblRhYmxlQWNjZXNzNjQsIFN5bUdldE1vZHVsZUJhc2U2NCwgTlVMTCkpCiAgICB7CiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMgPSBkYmdfaGVhcF9yZWFsbG9jKGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5mICsgMSkgKiBzaXplb2YoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbMF0pKTsKCiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfcGMgPSBzZi5BZGRyUEM7CiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfZnJhbWUgPSBzZi5BZGRyRnJhbWU7CiAgICAgICAgbmYrKzsKICAgICAgICAvKiB3ZSd2ZSBwcm9iYWJseSBnb3R0ZW4gb3Vyc2VsdmVzIGludG8gYW4gaW5maW5pdGUgbG9vcCBzbyBiYWlsICovCiAgICAgICAgaWYgKG5mID4gMjAwKSBicmVhazsKICAgIH0KICAgIGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSA9IC0xOwogICAgZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzID0gbmY7CiAgICBzdGFja19zZXRfZnJhbWVfaW50ZXJuYWwoMCk7CiAgICByZXR1cm4gbmY7Cn0KCnN0cnVjdCBzeW1fZW51bQp7CiAgICBjaGFyKiAgICAgICB0bXA7CiAgICBEV09SRCAgICAgICBmcmFtZTsKfTsKCnN0YXRpYyBCT09MIFdJTkFQSSBzeW1fZW51bV9jYihTWU1CT0xfSU5GTyogc3ltX2luZm8sIFVMT05HIHNpemUsIHZvaWQqIHVzZXIpCnsKICAgIHN0cnVjdCBzeW1fZW51bSogICAgc2UgPSAoc3RydWN0IHN5bV9lbnVtKil1c2VyOwogICAgY2hhciAgICAgICAgICAgICAgICB0bXBbMzJdOwoKICAgIGlmIChzeW1faW5mby0+RmxhZ3MgJiBTWU1GTEFHX1BBUkFNRVRFUikKICAgIHsKICAgICAgICBpZiAoc2UtPnRtcFswXSkgc3RyY2F0KHNlLT50bXAsICIsICIpOwogICAgCiAgICAgICAgaWYgKHN5bV9pbmZvLT5GbGFncyAmIFNZTUZMQUdfUkVHUkVMKQogICAgICAgIHsKICAgICAgICAgICAgdW5zaWduZWQgICAgdmFsOwogICAgICAgICAgICBEV09SRCAgICAgICBhZGRyID0gc2UtPmZyYW1lICsgc3ltX2luZm8tPkFkZHJlc3M7CgogICAgICAgICAgICBpZiAoIWRiZ19yZWFkX21lbW9yeSgoY2hhciopYWRkciwgJnZhbCwgc2l6ZW9mKHZhbCkpKQogICAgICAgICAgICAgICAgc25wcmludGYodG1wLCBzaXplb2YodG1wKSwgIjwqKiogY2Fubm90IHJlYWQgYXQgMHglbHggKioqPiIsIGFkZHIpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBzbnByaW50Zih0bXAsIHNpemVvZih0bXApLCAiMHgleCIsIHZhbCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHN5bV9pbmZvLT5GbGFncyAmIFNZTUZMQUdfUkVHSVNURVIpCiAgICAgICAgewogICAgICAgICAgICBEV09SRCogcHZhbDsKCiAgICAgICAgICAgIGlmIChtZW1vcnlfZ2V0X3JlZ2lzdGVyKHN5bV9pbmZvLT5SZWdpc3RlciwgJnB2YWwsIHRtcCwgc2l6ZW9mKHRtcCkpKQogICAgICAgICAgICAgICAgc25wcmludGYodG1wLCBzaXplb2YodG1wKSwgIjB4JWx4IiwgKnB2YWwpOwogICAgICAgIH0KICAgICAgICBzcHJpbnRmKHNlLT50bXAgKyBzdHJsZW4oc2UtPnRtcCksICIlcz0lcyIsIHN5bV9pbmZvLT5OYW1lLCB0bXApOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIHN0YWNrX3ByaW50X2FkZHJfYW5kX2FyZ3MoaW50IG5mKQp7CiAgICBjaGFyICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyW3NpemVvZihTWU1CT0xfSU5GTykgKyAyNTZdOwogICAgU1lNQk9MX0lORk8qICAgICAgICAgICAgICAgIHNpID0gKFNZTUJPTF9JTkZPKilidWZmZXI7CiAgICBJTUFHRUhMUF9TVEFDS19GUkFNRSAgICAgICAgaWhzZjsKICAgIElNQUdFSExQX0xJTkUgICAgICAgICAgICAgICBpbDsKICAgIElNQUdFSExQX01PRFVMRSAgICAgICAgICAgICBpbTsKICAgIERXT1JENjQgICAgICAgICAgICAgICAgICAgICBkaXNwNjQ7CgogICAgcHJpbnRfYmFyZV9hZGRyZXNzKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyk7CgogICAgc3RhY2tfZ2V0X2ZyYW1lKG5mLCAmaWhzZik7CgogICAgLyogZ3JhYiBtb2R1bGUgd2hlcmUgc3ltYm9sIGlzLiBJZiB3ZSBkb24ndCBoYXZlIGEgbW9kdWxlLCB3ZSBjYW5ub3QgcHJpbnQgbW9yZSAqLwogICAgaW0uU2l6ZU9mU3RydWN0ID0gc2l6ZW9mKGltKTsKICAgIGlmICghU3ltR2V0TW9kdWxlSW5mbyhkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQsICZpbSkpCiAgICAgICAgcmV0dXJuOwoKICAgIHNpLT5TaXplT2ZTdHJ1Y3QgPSBzaXplb2YoKnNpKTsKICAgIHNpLT5NYXhOYW1lTGVuICAgPSAyNTY7CiAgICBpZiAoU3ltRnJvbUFkZHIoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCBpaHNmLkluc3RydWN0aW9uT2Zmc2V0LCAmZGlzcDY0LCBzaSkpCiAgICB7CiAgICAgICAgc3RydWN0IHN5bV9lbnVtIHNlOwogICAgICAgIGNoYXIgICAgICAgICAgICB0bXBbMTAyNF07CiAgICAgICAgRFdPUkQgICAgICAgICAgIGRpc3A7CgogICAgICAgIGRiZ19wcmludGYoIiAlcyIsIHNpLT5OYW1lKTsKICAgICAgICBpZiAoZGlzcDY0KSBkYmdfcHJpbnRmKCIrMHglbHgiLCAoRFdPUkRfUFRSKWRpc3A2NCk7CgogICAgICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7CiAgICAgICAgc2UudG1wID0gdG1wOwogICAgICAgIHNlLmZyYW1lID0gaWhzZi5GcmFtZU9mZnNldDsKICAgICAgICB0bXBbMF0gPSAnXDAnOwogICAgICAgIFN5bUVudW1TeW1ib2xzKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgMCwgTlVMTCwgc3ltX2VudW1fY2IsICZzZSk7CiAgICAgICAgaWYgKHRtcFswXSkgZGJnX3ByaW50ZigiKCVzKSIsIHRtcCk7CgogICAgICAgIGlsLlNpemVPZlN0cnVjdCA9IHNpemVvZihpbCk7CiAgICAgICAgaWYgKFN5bUdldExpbmVGcm9tQWRkcihkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGlzcCwgJmlsKSkKICAgICAgICAgICAgZGJnX3ByaW50ZigiIFslczolbHVdIiwgaWwuRmlsZU5hbWUsIGlsLkxpbmVOdW1iZXIpOwogICAgICAgIGRiZ19wcmludGYoIiBpbiAlcyIsIGltLk1vZHVsZU5hbWUpOwogICAgfQogICAgZWxzZSBkYmdfcHJpbnRmKCIgaW4gJXMgKCsweCVseCkiLCAKICAgICAgICAgICAgICAgICAgICBpbS5Nb2R1bGVOYW1lLCAoRFdPUkRfUFRSKShpaHNmLkluc3RydWN0aW9uT2Zmc2V0IC0gaW0uQmFzZU9mSW1hZ2UpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIHRoZSB0aGUgY3VycmVudCB0aHJlYWQKICovCnN0YXRpYyB2b2lkIGJhY2t0cmFjZSh2b2lkKQp7CiAgICB1bnNpZ25lZCAgICAgICAgICAgICAgICAgICAgY2YgPSBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWU7CiAgICBJTUFHRUhMUF9TVEFDS19GUkFNRSAgICAgICAgaWhzZjsKCiAgICBkYmdfcHJpbnRmKCJCYWNrdHJhY2U6XG4iKTsKICAgIGZvciAoZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gMDsKICAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lIDwgZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzOwogICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUrKykKICAgIHsKICAgICAgICBkYmdfcHJpbnRmKCIlcyVkICIsIAogICAgICAgICAgICAgICAgICAgKGNmID09IGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSA/ICI9PiIgOiAiICAiKSwKICAgICAgICAgICAgICAgICAgIGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSArIDEpOwogICAgICAgIHN0YWNrX3ByaW50X2FkZHJfYW5kX2FyZ3MoZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lKTsKICAgICAgICBkYmdfcHJpbnRmKCIgKCIpOwogICAgICAgIHByaW50X2JhcmVfYWRkcmVzcygmZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lXS5hZGRyX3BjKTsKICAgICAgICBkYmdfcHJpbnRmKCIpXG4iKTsKICAgIH0KICAgIC8qIHJlc2V0IGNvbnRleHQgdG8gY3VycmVudCBzdGFjayBmcmFtZSAqLwogICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gY2Y7CiAgICBpZiAoIWRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzKSByZXR1cm47CiAgICBzdGFja19nZXRfZnJhbWUoZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lLCAmaWhzZik7CiAgICBTeW1TZXRDb250ZXh0KGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgJmloc2YsIE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQliYWNrdHJhY2VfdGlkCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIGEgdGhyZWFkIGZyb20gaXRzIHByb2Nlc3MgYW5kIGl0cyBpZGVudGlmaWVyCiAqIChwcmVzZXJ2ZXMgY3VycmVudCB0aHJlYWQgYW5kIGNvbnRleHQgaW5mb3JtYXRpb24pCiAqLwpzdGF0aWMgdm9pZCBiYWNrdHJhY2VfdGlkKHN0cnVjdCBkYmdfcHJvY2VzcyogcGNzLCBEV09SRCB0aWQpCnsKICAgIHN0cnVjdCBkYmdfdGhyZWFkKiAgdGhyZWFkID0gZGJnX2N1cnJfdGhyZWFkOwoKICAgIGlmICghKGRiZ19jdXJyX3RocmVhZCA9IGRiZ19nZXRfdGhyZWFkKHBjcywgdGlkKSkpCiAgICAgICAgZGJnX3ByaW50ZigiVW5rbm93biB0aHJlYWQgaWQgKDB4JWx4KSBpbiBwcm9jZXNzICgweCVseClcbiIsIHRpZCwgcGNzLT5waWQpOwogICAgZWxzZQogICAgewogICAgICAgIENPTlRFWFQgc2F2ZWRfY3R4ID0gZGJnX2NvbnRleHQ7CgogICAgICAgIGRiZ19jdXJyX3RpZCA9IGRiZ19jdXJyX3RocmVhZC0+dGlkOwogICAgICAgIG1lbXNldCgmZGJnX2NvbnRleHQsIDAsIHNpemVvZihkYmdfY29udGV4dCkpOwogICAgICAgIGRiZ19jb250ZXh0LkNvbnRleHRGbGFncyA9IENPTlRFWFRfRlVMTDsKICAgICAgICBpZiAoU3VzcGVuZFRocmVhZChkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSkgIT0gLTEpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIUdldFRocmVhZENvbnRleHQoZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUsICZkYmdfY29udGV4dCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRiZ19wcmludGYoIkNhbid0IGdldCBjb250ZXh0IGZvciB0aHJlYWQgMHglbHggaW4gY3VycmVudCBwcm9jZXNzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICB0aWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RhY2tfZmV0Y2hfZnJhbWVzKCk7CiAgICAgICAgICAgICAgICBiYWNrdHJhY2UoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBSZXN1bWVUaHJlYWQoZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUpOwogICAgICAgIH0KICAgICAgICBlbHNlIGRiZ19wcmludGYoIkNhbid0IHN1c3BlbmQgdGhyZWFkIDB4JWx4IGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwgdGlkKTsKICAgICAgICBkYmdfY29udGV4dCA9IHNhdmVkX2N0eDsKICAgIH0KICAgIGRiZ19jdXJyX3RocmVhZCA9IHRocmVhZDsKICAgIGRiZ19jdXJyX3RpZCA9IHRocmVhZCA/IHRocmVhZC0+dGlkIDogMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlX2FsbAogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiBldmVyeSBydW5uaW5nIHRocmVhZCBpbiB0aGUgc3lzdGVtIChleGNlcHQgdGhlIGRlYnVnZ2VyKQogKiAocHJlc2VydmVzIGN1cnJlbnQgcHJvY2VzcyBpbmZvcm1hdGlvbikKICovCnN0YXRpYyB2b2lkIGJhY2t0cmFjZV9hbGwodm9pZCkKewogICAgc3RydWN0IGRiZ19wcm9jZXNzKiBwcm9jZXNzID0gZGJnX2N1cnJfcHJvY2VzczsKICAgIFRIUkVBREVOVFJZMzIgICAgICAgZW50cnk7CiAgICBIQU5ETEUgICAgICAgICAgICAgIHNuYXBzaG90ID0gQ3JlYXRlVG9vbGhlbHAzMlNuYXBzaG90KFRIMzJDU19TTkFQVEhSRUFELCAwKTsKCiAgICBpZiAoc25hcHNob3QgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCiAgICB7CiAgICAgICAgZGJnX3ByaW50ZigiVW5hYmxlIHRvIGNyZWF0ZSB0b29saGVscCBzbmFwc2hvdFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGVudHJ5LmR3U2l6ZSA9IHNpemVvZihlbnRyeSk7CiAgICBpZiAoVGhyZWFkMzJGaXJzdChzbmFwc2hvdCwgJmVudHJ5KSkKICAgIHsKICAgICAgICBkbwogICAgICAgIHsKICAgICAgICAgICAgaWYgKGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCA9PSBHZXRDdXJyZW50UHJvY2Vzc0lkKCkpIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAoZGJnX2N1cnJfcHJvY2VzcyAmJiBkYmdfY3Vycl9waWQgIT0gZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEKQogICAgICAgICAgICAgICAgZGJnX2N1cnJfcHJvY2Vzcy0+cHJvY2Vzc19pby0+Y2xvc2VfcHJvY2VzcyhkYmdfY3Vycl9wcm9jZXNzLCBGQUxTRSk7CgogICAgICAgICAgICBpZiAoZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEICE9IGRiZ19jdXJyX3BpZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFkYmdfYXR0YWNoX2RlYnVnZ2VlKGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCwgRkFMU0UsIFRSVUUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRiZ19wcmludGYoIlxud2FybmluZzogY291bGQgbm90IGF0dGFjaCB0byAweCVseFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkYmdfY3Vycl9waWQgPSBkYmdfY3Vycl9wcm9jZXNzLT5waWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRiZ19wcmludGYoIlxuQmFja3RyYWNpbmcgZm9yIHRocmVhZCAweCVseCBpbiBwcm9jZXNzIDB4JWx4ICglcyk6XG4iLAogICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LnRoMzJUaHJlYWRJRCwgZGJnX2N1cnJfcGlkLCBkYmdfY3Vycl9wcm9jZXNzLT5pbWFnZU5hbWUpOwogICAgICAgICAgICBiYWNrdHJhY2VfdGlkKGRiZ19jdXJyX3Byb2Nlc3MsIGVudHJ5LnRoMzJUaHJlYWRJRCk7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChUaHJlYWQzMk5leHQoc25hcHNob3QsICZlbnRyeSkpOwoKICAgICAgICBpZiAoZGJnX2N1cnJfcHJvY2VzcykKICAgICAgICAgICAgZGJnX2N1cnJfcHJvY2Vzcy0+cHJvY2Vzc19pby0+Y2xvc2VfcHJvY2VzcyhkYmdfY3Vycl9wcm9jZXNzLCBGQUxTRSk7CiAgICB9CiAgICBDbG9zZUhhbmRsZShzbmFwc2hvdCk7CiAgICBkYmdfY3Vycl9wcm9jZXNzID0gcHJvY2VzczsKICAgIGRiZ19jdXJyX3BpZCA9IHByb2Nlc3MgPyBwcm9jZXNzLT5waWQgOiAwOwp9Cgp2b2lkIHN0YWNrX2JhY2t0cmFjZShEV09SRCB0aWQpCnsKICAgIC8qIGJhY2t0cmFjZSBldmVyeSB0aHJlYWQgaW4gZXZlcnkgcHJvY2VzcyBleGNlcHQgdGhlIGRlYnVnZ2VyIGl0c2VsZiwKICAgICAqIGludm9raW5nIHZpYSAiYnQgYWxsIgogICAgICovCiAgICBpZiAodGlkID09IC0xKSByZXR1cm4gYmFja3RyYWNlX2FsbCgpOwoKICAgIGlmICghZGJnX2N1cnJfcHJvY2VzcykgCiAgICB7CiAgICAgICAgZGJnX3ByaW50ZigiWW91IG11c3QgYmUgYXR0YWNoZWQgdG8gYSBwcm9jZXNzIHRvIHJ1biB0aGlzIGNvbW1hbmQuXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAKICAgIGlmICh0aWQgPT0gZGJnX2N1cnJfdGlkKQogICAgewogICAgICAgIGJhY2t0cmFjZSgpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGJhY2t0cmFjZV90aWQoZGJnX2N1cnJfcHJvY2VzcywgdGlkKTsKICAgIH0KfQo=