LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgImRlYnVnZ2VyLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAidGxoZWxwMzIuaCIKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgc3RhY2tfaW5mbwogKgogKiBEdW1wIHRoZSB0b3Agb2YgdGhlIHN0YWNrCiAqLwp2b2lkIHN0YWNrX2luZm8odm9pZCkKewogICAgc3RydWN0IGRiZ19sdmFsdWUgbHZhbHVlOwoKICAgIGx2YWx1ZS5jb29raWUgPSAwOwogICAgbHZhbHVlLnR5cGUuaWQgPSBkYmdfaXR5cGVfc2VncHRyOwogICAgbHZhbHVlLnR5cGUubW9kdWxlID0gMDsKCiAgICAvKiBGSVhNRTogd2UgYXNzdW1lIHN0YWNrIGdyb3dzIHRoZSBzYW1lIHdheSBhcyBvbiBpMzg2ICovCiAgICBpZiAoIW1lbW9yeV9nZXRfY3VycmVudF9zdGFjaygmbHZhbHVlLmFkZHIpKQogICAgICAgIGRiZ19wcmludGYoIkJhZCBzZWdtZW50ICglZClcbiIsIGx2YWx1ZS5hZGRyLlNlZ21lbnQpOwoKICAgIGRiZ19wcmludGYoIlN0YWNrIGR1bXA6XG4iKTsKICAgIHN3aXRjaCAobHZhbHVlLmFkZHIuTW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OiAvKiAzMi1iaXQgbW9kZSAqLwogICAgY2FzZSBBZGRyTW9kZTE2MzI6IC8qIDMyLWJpdCBtb2RlICovCiAgICAgICAgbWVtb3J5X2V4YW1pbmUoJmx2YWx1ZSwgMjQsICd4Jyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDogIC8qIDE2LWJpdCBtb2RlICovCiAgICBjYXNlIEFkZHJNb2RlMTYxNjoKICAgICAgICBtZW1vcnlfZXhhbWluZSgmbHZhbHVlLCAyNCwgJ3cnKTsKCWJyZWFrOwogICAgfQp9CgpzdGF0aWMgQk9PTCBzdGFja19zZXRfZnJhbWVfaW50ZXJuYWwoaW50IG5ld2ZyYW1lKQp7CiAgICBpZiAobmV3ZnJhbWUgPj0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzKQogICAgICAgIG5ld2ZyYW1lID0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzIC0gMTsKICAgIGlmIChuZXdmcmFtZSA8IDApCiAgICAgICAgbmV3ZnJhbWUgPSAwOwoKICAgIGlmIChkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgIT0gbmV3ZnJhbWUpCiAgICB7CiAgICAgICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgaWhzZjsKCiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gbmV3ZnJhbWU7CiAgICAgICAgc3RhY2tfZ2V0X2N1cnJlbnRfZnJhbWUoJmloc2YpOwogICAgICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgc3RhY2tfZ2V0X2ZyYW1lKGludCBuZiwgSU1BR0VITFBfU1RBQ0tfRlJBTUUqIGloc2YpCnsKICAgIG1lbXNldChpaHNmLCAwLCBzaXplb2YoKmloc2YpKTsKICAgIGloc2YtPkluc3RydWN0aW9uT2Zmc2V0ID0gZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmxpbmVhcl9wYzsKICAgIGloc2YtPkZyYW1lT2Zmc2V0ID0gZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmxpbmVhcl9mcmFtZTsKICAgIHJldHVybiBUUlVFOwp9CgpCT09MIHN0YWNrX2dldF9jdXJyZW50X2ZyYW1lKElNQUdFSExQX1NUQUNLX0ZSQU1FKiBpaHNmKQp7CiAgICAvKgogICAgICogSWYgd2UgZG9uJ3QgaGF2ZSBhIHZhbGlkIGJhY2t0cmFjZSwgdGhlbiBqdXN0IHJldHVybi4KICAgICAqLwogICAgaWYgKGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzID09IE5VTEwpIHJldHVybiBGQUxTRTsKICAgIHJldHVybiBzdGFja19nZXRfZnJhbWUoZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lLCBpaHNmKTsKfQoKQk9PTCBzdGFja19nZXRfcmVnaXN0ZXJfY3VycmVudF9mcmFtZSh1bnNpZ25lZCByZWdubywgRFdPUkQqKiBwdmFsKQp7CiAgICBlbnVtIGJlX2NwdV9hZGRyICAgICAgICAgICAga2luZDsKCiAgICBpZiAoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghYmVfY3B1LT5nZXRfcmVnaXN0ZXJfaW5mbyhyZWdubywgJmtpbmQpKSByZXR1cm4gRkFMU0U7CgogICAgc3dpdGNoIChraW5kKQogICAgewogICAgY2FzZSBiZV9jcHVfYWRkcl9wYzoKICAgICAgICAqcHZhbCA9ICZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWVdLmxpbmVhcl9wYzsKICAgICAgICBicmVhazsKICAgIGNhc2UgYmVfY3B1X2FkZHJfc3RhY2s6CiAgICAgICAgKnB2YWwgPSAmZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lXS5saW5lYXJfc3RhY2s7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIGJlX2NwdV9hZGRyX2ZyYW1lOgogICAgICAgICpwdmFsID0gJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW2RiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZV0ubGluZWFyX2ZyYW1lOwogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCkJPT0wgc3RhY2tfc2V0X2ZyYW1lKGludCBuZXdmcmFtZSkKewogICAgQUREUkVTUzY0ICAgYWRkcjsKICAgIGlmICghc3RhY2tfc2V0X2ZyYW1lX2ludGVybmFsKG5ld2ZyYW1lKSkgcmV0dXJuIEZBTFNFOwogICAgYWRkci5Nb2RlID0gQWRkck1vZGVGbGF0OwogICAgYWRkci5PZmZzZXQgPSAodW5zaWduZWQgbG9uZyltZW1vcnlfdG9fbGluZWFyX2FkZHIoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW2RiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZV0uYWRkcl9wYyk7CiAgICBzb3VyY2VfbGlzdF9mcm9tX2FkZHIoJmFkZHIsIDApOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXN0YWNrX2dldF9jdXJyZW50X3N5bWJvbAogKgogKiBSZXRyaWV2ZXMgdGhlIHN5bWJvbCBpbmZvcm1hdGlvbiBmb3IgdGhlIGN1cnJlbnQgZnJhbWUgZWxlbWVudAogKi8KQk9PTCBzdGFja19nZXRfY3VycmVudF9zeW1ib2woU1lNQk9MX0lORk8qIHN5bWJvbCkKewogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CiAgICBEV09SRDY0ICAgICAgICAgICAgICAgICAgICAgZGlzcDsKCiAgICBpZiAoIXN0YWNrX2dldF9jdXJyZW50X2ZyYW1lKCZpaHNmKSkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIFN5bUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAmZGlzcCwgc3ltYm9sKTsKfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgc3RhY2tfcmVhZF9tZW0oSEFORExFIGhQcm9jLCBEV09SRDY0IGFkZHIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVk9JRCBidWZmZXIsIERXT1JEIHNpemUsIFBEV09SRCB3cml0dGVuKQp7CiAgICBTSVpFX1Qgc3o7CiAgICBCT09MIHJldDsKCiAgICBzdHJ1Y3QgZGJnX3Byb2Nlc3MqIHBjcyA9IGRiZ19nZXRfcHJvY2Vzc19oKGhQcm9jKTsKICAgIGlmICghcGNzKSByZXR1cm4gRkFMU0U7CiAgICByZXQgPSBwY3MtPnByb2Nlc3NfaW8tPnJlYWQoaFByb2MsIChjb25zdCB2b2lkKikoRFdPUkRfUFRSKWFkZHIsIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplLCAmc3opOwogICAgaWYgKHdyaXR0ZW4gIT0gTlVMTCkgKndyaXR0ZW4gPSBzejsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXN0YWNrX2ZldGNoX2ZyYW1lcwogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiB0aGUgY3VycmVudCB0aHJlYWQKICovCnVuc2lnbmVkIHN0YWNrX2ZldGNoX2ZyYW1lcyh2b2lkKQp7CiAgICBTVEFDS0ZSQU1FNjQgc2Y7CiAgICB1bnNpZ25lZCAgICAgbmYgPSAwOwogICAgLyogYXMgbmF0aXZlIHN0YWNrd2FsayBjYW4gbW9kaWZ5IHRoZSBjb250ZXh0IHBhc3NlZCB0byBpdCwgc2ltcGx5IGNvcHkKICAgICAqIGl0IHRvIGF2b2lkIGFueSBkYW1hZ2UKICAgICAqLwogICAgQ09OVEVYVCAgICAgIGN0eCA9IGRiZ19jb250ZXh0OwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzKTsKICAgIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzID0gTlVMTDsKCiAgICBtZW1zZXQoJnNmLCAwLCBzaXplb2Yoc2YpKTsKICAgIG1lbW9yeV9nZXRfY3VycmVudF9mcmFtZSgmc2YuQWRkckZyYW1lKTsKICAgIG1lbW9yeV9nZXRfY3VycmVudF9wYygmc2YuQWRkclBDKTsKCiAgICAvKiBkb24ndCBjb25mdXNlIFN0YWNrV2FsayBieSBwYXNzaW5nIGluIGluY29uc2lzdGVudCBhZGRyZXNzZXMgKi8KICAgIGlmICgoc2YuQWRkclBDLk1vZGUgPT0gQWRkck1vZGVGbGF0KSAmJiAoc2YuQWRkckZyYW1lLk1vZGUgIT0gQWRkck1vZGVGbGF0KSkKICAgIHsKICAgICAgICBzZi5BZGRyRnJhbWUuT2Zmc2V0ID0gKERXT1JEKW1lbW9yeV90b19saW5lYXJfYWRkcigmc2YuQWRkckZyYW1lKTsKICAgICAgICBzZi5BZGRyRnJhbWUuTW9kZSA9IEFkZHJNb2RlRmxhdDsKICAgIH0KCiAgICB3aGlsZSAoU3RhY2tXYWxrNjQoSU1BR0VfRklMRV9NQUNISU5FX0kzODYsIGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUsICZzZiwgJmN0eCwgc3RhY2tfcmVhZF9tZW0sCiAgICAgICAgICAgICAgICAgICAgICAgU3ltRnVuY3Rpb25UYWJsZUFjY2VzczY0LCBTeW1HZXRNb2R1bGVCYXNlNjQsIE5VTEwpKQogICAgewogICAgICAgIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzID0gZGJnX2hlYXBfcmVhbGxvYyhkYmdfY3Vycl90aHJlYWQtPmZyYW1lcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZiArIDEpICogc2l6ZW9mKGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzWzBdKSk7CgogICAgICAgIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5hZGRyX3BjICAgICAgPSBzZi5BZGRyUEM7CiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmxpbmVhcl9wYyAgICA9IChEV09SRCltZW1vcnlfdG9fbGluZWFyX2FkZHIoJnNmLkFkZHJQQyk7CiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfZnJhbWUgICA9IHNmLkFkZHJGcmFtZTsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0ubGluZWFyX2ZyYW1lID0gKERXT1JEKW1lbW9yeV90b19saW5lYXJfYWRkcigmc2YuQWRkckZyYW1lKTsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9zdGFjayAgID0gc2YuQWRkclN0YWNrOwogICAgICAgIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5saW5lYXJfc3RhY2sgPSAoRFdPUkQpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZzZi5BZGRyU3RhY2spOwogICAgICAgIG5mKys7CiAgICAgICAgLyogd2UndmUgcHJvYmFibHkgZ290dGVuIG91cnNlbHZlcyBpbnRvIGFuIGluZmluaXRlIGxvb3Agc28gYmFpbCAqLwogICAgICAgIGlmIChuZiA+IDIwMCkgYnJlYWs7CiAgICB9CiAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPSAtMTsKICAgIGRiZ19jdXJyX3RocmVhZC0+bnVtX2ZyYW1lcyA9IG5mOwogICAgc3RhY2tfc2V0X2ZyYW1lX2ludGVybmFsKDApOwogICAgcmV0dXJuIG5mOwp9CgpzdHJ1Y3Qgc3ltX2VudW0KewogICAgRFdPUkQgICAgICAgZnJhbWU7CiAgICBCT09MICAgICAgICBmaXJzdDsKfTsKCnN0YXRpYyBCT09MIFdJTkFQSSBzeW1fZW51bV9jYihQU1lNQk9MX0lORk8gc3ltX2luZm8sIFVMT05HIHNpemUsIFBWT0lEIHVzZXIpCnsKICAgIHN0cnVjdCBzeW1fZW51bSogICAgc2UgPSAoc3RydWN0IHN5bV9lbnVtKil1c2VyOwoKICAgIGlmIChzeW1faW5mby0+RmxhZ3MgJiBTWU1GTEFHX1BBUkFNRVRFUikKICAgIHsKICAgICAgICBpZiAoIXNlLT5maXJzdCkgZGJnX3ByaW50ZigiLCAiKTsgZWxzZSBzZS0+Zmlyc3QgPSBGQUxTRTsKICAgICAgICBzeW1ib2xfcHJpbnRfbG9jYWwoc3ltX2luZm8sIHNlLT5mcmFtZSwgRkFMU0UpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIHN0YWNrX3ByaW50X2FkZHJfYW5kX2FyZ3MoaW50IG5mKQp7CiAgICBjaGFyICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyW3NpemVvZihTWU1CT0xfSU5GTykgKyAyNTZdOwogICAgU1lNQk9MX0lORk8qICAgICAgICAgICAgICAgIHNpID0gKFNZTUJPTF9JTkZPKilidWZmZXI7CiAgICBJTUFHRUhMUF9TVEFDS19GUkFNRSAgICAgICAgaWhzZjsKICAgIElNQUdFSExQX0xJTkUgICAgICAgICAgICAgICBpbDsKICAgIElNQUdFSExQX01PRFVMRSAgICAgICAgICAgICBpbTsKICAgIERXT1JENjQgICAgICAgICAgICAgICAgICAgICBkaXNwNjQ7CgogICAgcHJpbnRfYmFyZV9hZGRyZXNzKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyk7CgogICAgc3RhY2tfZ2V0X2ZyYW1lKG5mLCAmaWhzZik7CgogICAgLyogZ3JhYiBtb2R1bGUgd2hlcmUgc3ltYm9sIGlzLiBJZiB3ZSBkb24ndCBoYXZlIGEgbW9kdWxlLCB3ZSBjYW5ub3QgcHJpbnQgbW9yZSAqLwogICAgaW0uU2l6ZU9mU3RydWN0ID0gc2l6ZW9mKGltKTsKICAgIGlmICghU3ltR2V0TW9kdWxlSW5mbyhkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIGloc2YuSW5zdHJ1Y3Rpb25PZmZzZXQsICZpbSkpCiAgICAgICAgcmV0dXJuOwoKICAgIHNpLT5TaXplT2ZTdHJ1Y3QgPSBzaXplb2YoKnNpKTsKICAgIHNpLT5NYXhOYW1lTGVuICAgPSAyNTY7CiAgICBpZiAoU3ltRnJvbUFkZHIoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCBpaHNmLkluc3RydWN0aW9uT2Zmc2V0LCAmZGlzcDY0LCBzaSkpCiAgICB7CiAgICAgICAgc3RydWN0IHN5bV9lbnVtIHNlOwogICAgICAgIERXT1JEICAgICAgICAgICBkaXNwOwoKICAgICAgICBkYmdfcHJpbnRmKCIgJXMiLCBzaS0+TmFtZSk7CiAgICAgICAgaWYgKGRpc3A2NCkgZGJnX3ByaW50ZigiKzB4JWx4IiwgKERXT1JEX1BUUilkaXNwNjQpOwoKICAgICAgICBTeW1TZXRDb250ZXh0KGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgJmloc2YsIE5VTEwpOwogICAgICAgIHNlLmZpcnN0ID0gVFJVRTsKICAgICAgICBzZS5mcmFtZSA9IGloc2YuRnJhbWVPZmZzZXQ7CiAgICAgICAgZGJnX3ByaW50ZigiKCIpOwogICAgICAgIFN5bUVudW1TeW1ib2xzKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgMCwgTlVMTCwgc3ltX2VudW1fY2IsICZzZSk7CiAgICAgICAgZGJnX3ByaW50ZigiKSIpOwoKICAgICAgICBpbC5TaXplT2ZTdHJ1Y3QgPSBzaXplb2YoaWwpOwogICAgICAgIGlmIChTeW1HZXRMaW5lRnJvbUFkZHIoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCBpaHNmLkluc3RydWN0aW9uT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRpc3AsICZpbCkpCiAgICAgICAgICAgIGRiZ19wcmludGYoIiBbJXM6JXVdIiwgaWwuRmlsZU5hbWUsIGlsLkxpbmVOdW1iZXIpOwogICAgICAgIGRiZ19wcmludGYoIiBpbiAlcyIsIGltLk1vZHVsZU5hbWUpOwogICAgfQogICAgZWxzZSBkYmdfcHJpbnRmKCIgaW4gJXMgKCsweCVseCkiLCAKICAgICAgICAgICAgICAgICAgICBpbS5Nb2R1bGVOYW1lLCAoRFdPUkRfUFRSKShpaHNmLkluc3RydWN0aW9uT2Zmc2V0IC0gaW0uQmFzZU9mSW1hZ2UpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlCiAqCiAqIERvIGEgYmFja3RyYWNlIG9uIHRoZSBjdXJyZW50IHRocmVhZAogKi8Kc3RhdGljIHZvaWQgYmFja3RyYWNlKHZvaWQpCnsKICAgIHVuc2lnbmVkICAgICAgICAgICAgICAgICAgICBjZiA9IGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZTsKICAgIElNQUdFSExQX1NUQUNLX0ZSQU1FICAgICAgICBpaHNmOwoKICAgIGRiZ19wcmludGYoIkJhY2t0cmFjZTpcbiIpOwogICAgZm9yIChkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPSAwOwogICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPCBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXM7CiAgICAgICAgIGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSsrKQogICAgewogICAgICAgIGRiZ19wcmludGYoIiVzJWQgIiwgCiAgICAgICAgICAgICAgICAgICAoY2YgPT0gZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID8gIj0+IiA6ICIgICIpLAogICAgICAgICAgICAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lICsgMSk7CiAgICAgICAgc3RhY2tfcHJpbnRfYWRkcl9hbmRfYXJncyhkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUpOwogICAgICAgIGRiZ19wcmludGYoIiAoIik7CiAgICAgICAgcHJpbnRfYmFyZV9hZGRyZXNzKCZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWVdLmFkZHJfZnJhbWUpOwogICAgICAgIGRiZ19wcmludGYoIilcbiIpOwogICAgfQogICAgLyogcmVzZXQgY29udGV4dCB0byBjdXJyZW50IHN0YWNrIGZyYW1lICovCiAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPSBjZjsKICAgIGlmICghZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMpIHJldHVybjsKICAgIHN0YWNrX2dldF9mcmFtZShkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUsICZpaHNmKTsKICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWJhY2t0cmFjZV90aWQKICoKICogRG8gYSBiYWNrdHJhY2Ugb24gYSB0aHJlYWQgZnJvbSBpdHMgcHJvY2VzcyBhbmQgaXRzIGlkZW50aWZpZXIKICogKHByZXNlcnZlcyBjdXJyZW50IHRocmVhZCBhbmQgY29udGV4dCBpbmZvcm1hdGlvbikKICovCnN0YXRpYyB2b2lkIGJhY2t0cmFjZV90aWQoc3RydWN0IGRiZ19wcm9jZXNzKiBwY3MsIERXT1JEIHRpZCkKewogICAgc3RydWN0IGRiZ190aHJlYWQqICB0aHJlYWQgPSBkYmdfY3Vycl90aHJlYWQ7CgogICAgaWYgKCEoZGJnX2N1cnJfdGhyZWFkID0gZGJnX2dldF90aHJlYWQocGNzLCB0aWQpKSkKICAgICAgICBkYmdfcHJpbnRmKCJVbmtub3duIHRocmVhZCBpZCAoJTA0eCkgaW4gcHJvY2VzcyAoJTA0eClcbiIsIHRpZCwgcGNzLT5waWQpOwogICAgZWxzZQogICAgewogICAgICAgIENPTlRFWFQgc2F2ZWRfY3R4ID0gZGJnX2NvbnRleHQ7CgogICAgICAgIGRiZ19jdXJyX3RpZCA9IGRiZ19jdXJyX3RocmVhZC0+dGlkOwogICAgICAgIG1lbXNldCgmZGJnX2NvbnRleHQsIDAsIHNpemVvZihkYmdfY29udGV4dCkpOwogICAgICAgIGRiZ19jb250ZXh0LkNvbnRleHRGbGFncyA9IENPTlRFWFRfRlVMTDsKICAgICAgICBpZiAoU3VzcGVuZFRocmVhZChkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSkgIT0gLTEpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIUdldFRocmVhZENvbnRleHQoZGJnX2N1cnJfdGhyZWFkLT5oYW5kbGUsICZkYmdfY29udGV4dCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRiZ19wcmludGYoIkNhbid0IGdldCBjb250ZXh0IGZvciB0aHJlYWQgJTA0eCBpbiBjdXJyZW50IHByb2Nlc3NcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdGFja19mZXRjaF9mcmFtZXMoKTsKICAgICAgICAgICAgICAgIGJhY2t0cmFjZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFJlc3VtZVRocmVhZChkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgZGJnX3ByaW50ZigiQ2FuJ3Qgc3VzcGVuZCB0aHJlYWQgJTA0eCBpbiBjdXJyZW50IHByb2Nlc3NcbiIsIHRpZCk7CiAgICAgICAgZGJnX2NvbnRleHQgPSBzYXZlZF9jdHg7CiAgICB9CiAgICBkYmdfY3Vycl90aHJlYWQgPSB0aHJlYWQ7CiAgICBkYmdfY3Vycl90aWQgPSB0aHJlYWQgPyB0aHJlYWQtPnRpZCA6IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWJhY2t0cmFjZV9hbGwKICoKICogRG8gYSBiYWNrdHJhY2Ugb24gZXZlcnkgcnVubmluZyB0aHJlYWQgaW4gdGhlIHN5c3RlbSAoZXhjZXB0IHRoZSBkZWJ1Z2dlcikKICogKHByZXNlcnZlcyBjdXJyZW50IHByb2Nlc3MgaW5mb3JtYXRpb24pCiAqLwpzdGF0aWMgdm9pZCBiYWNrdHJhY2VfYWxsKHZvaWQpCnsKICAgIHN0cnVjdCBkYmdfcHJvY2VzcyogcHJvY2VzcyA9IGRiZ19jdXJyX3Byb2Nlc3M7CiAgICBUSFJFQURFTlRSWTMyICAgICAgIGVudHJ5OwogICAgSEFORExFICAgICAgICAgICAgICBzbmFwc2hvdCA9IENyZWF0ZVRvb2xoZWxwMzJTbmFwc2hvdChUSDMyQ1NfU05BUFRIUkVBRCwgMCk7CgogICAgaWYgKHNuYXBzaG90ID09IElOVkFMSURfSEFORExFX1ZBTFVFKQogICAgewogICAgICAgIGRiZ19wcmludGYoIlVuYWJsZSB0byBjcmVhdGUgdG9vbGhlbHAgc25hcHNob3RcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBlbnRyeS5kd1NpemUgPSBzaXplb2YoZW50cnkpOwogICAgaWYgKFRocmVhZDMyRmlyc3Qoc25hcHNob3QsICZlbnRyeSkpCiAgICB7CiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQgPT0gR2V0Q3VycmVudFByb2Nlc3NJZCgpKSBjb250aW51ZTsKICAgICAgICAgICAgaWYgKGRiZ19jdXJyX3Byb2Nlc3MgJiYgZGJnX2N1cnJfcGlkICE9IGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCkKICAgICAgICAgICAgICAgIGRiZ19jdXJyX3Byb2Nlc3MtPnByb2Nlc3NfaW8tPmNsb3NlX3Byb2Nlc3MoZGJnX2N1cnJfcHJvY2VzcywgRkFMU0UpOwoKICAgICAgICAgICAgaWYgKGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCAhPSBkYmdfY3Vycl9waWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghZGJnX2F0dGFjaF9kZWJ1Z2dlZShlbnRyeS50aDMyT3duZXJQcm9jZXNzSUQsIEZBTFNFKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkYmdfcHJpbnRmKCJcbndhcm5pbmc6IGNvdWxkIG5vdCBhdHRhY2ggdG8gJTA0eFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkYmdfY3Vycl9waWQgPSBkYmdfY3Vycl9wcm9jZXNzLT5waWQ7CiAgICAgICAgICAgICAgICBkYmdfYWN0aXZlX3dhaXRfZm9yX2ZpcnN0X2V4Y2VwdGlvbigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBkYmdfcHJpbnRmKCJcbkJhY2t0cmFjaW5nIGZvciB0aHJlYWQgJTA0eCBpbiBwcm9jZXNzICUwNHggKCVzKTpcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnkudGgzMlRocmVhZElELCBkYmdfY3Vycl9waWQsIGRiZ19jdXJyX3Byb2Nlc3MtPmltYWdlTmFtZSk7CiAgICAgICAgICAgIGJhY2t0cmFjZV90aWQoZGJnX2N1cnJfcHJvY2VzcywgZW50cnkudGgzMlRocmVhZElEKTsKICAgICAgICB9CiAgICAgICAgd2hpbGUgKFRocmVhZDMyTmV4dChzbmFwc2hvdCwgJmVudHJ5KSk7CgogICAgICAgIGlmIChkYmdfY3Vycl9wcm9jZXNzKQogICAgICAgICAgICBkYmdfY3Vycl9wcm9jZXNzLT5wcm9jZXNzX2lvLT5jbG9zZV9wcm9jZXNzKGRiZ19jdXJyX3Byb2Nlc3MsIEZBTFNFKTsKICAgIH0KICAgIENsb3NlSGFuZGxlKHNuYXBzaG90KTsKICAgIGRiZ19jdXJyX3Byb2Nlc3MgPSBwcm9jZXNzOwogICAgZGJnX2N1cnJfcGlkID0gcHJvY2VzcyA/IHByb2Nlc3MtPnBpZCA6IDA7Cn0KCnZvaWQgc3RhY2tfYmFja3RyYWNlKERXT1JEIHRpZCkKewogICAgLyogYmFja3RyYWNlIGV2ZXJ5IHRocmVhZCBpbiBldmVyeSBwcm9jZXNzIGV4Y2VwdCB0aGUgZGVidWdnZXIgaXRzZWxmLAogICAgICogaW52b2tpbmcgdmlhICJidCBhbGwiCiAgICAgKi8KICAgIGlmICh0aWQgPT0gLTEpIHJldHVybiBiYWNrdHJhY2VfYWxsKCk7CgogICAgaWYgKCFkYmdfY3Vycl9wcm9jZXNzKSAKICAgIHsKICAgICAgICBkYmdfcHJpbnRmKCJZb3UgbXVzdCBiZSBhdHRhY2hlZCB0byBhIHByb2Nlc3MgdG8gcnVuIHRoaXMgY29tbWFuZC5cbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIAogICAgaWYgKHRpZCA9PSBkYmdfY3Vycl90aWQpCiAgICB7CiAgICAgICAgYmFja3RyYWNlKCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgYmFja3RyYWNlX3RpZChkYmdfY3Vycl9wcm9jZXNzLCB0aWQpOwogICAgfQp9Cg==