LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgImRlYnVnZ2VyLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAidGxoZWxwMzIuaCIKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgc3RhY2tfaW5mbwogKgogKiBEdW1wIHRoZSB0b3Agb2YgdGhlIHN0YWNrCiAqLwp2b2lkIHN0YWNrX2luZm8odm9pZCkKewogICAgc3RydWN0IGRiZ19sdmFsdWUgbHZhbHVlOwoKICAgIGx2YWx1ZS5jb29raWUgPSAwOwogICAgbHZhbHVlLnR5cGUuaWQgPSBkYmdfaXR5cGVfc2VncHRyOwogICAgbHZhbHVlLnR5cGUubW9kdWxlID0gMDsKCiAgICAvKiBGSVhNRTogd2UgYXNzdW1lIHN0YWNrIGdyb3dzIHRoZSBzYW1lIHdheSBhcyBvbiBpMzg2ICovCiAgICBpZiAoIW1lbW9yeV9nZXRfY3VycmVudF9zdGFjaygmbHZhbHVlLmFkZHIpKQogICAgICAgIGRiZ19wcmludGYoIkJhZCBzZWdtZW50ICglZClcbiIsIGx2YWx1ZS5hZGRyLlNlZ21lbnQpOwoKICAgIGRiZ19wcmludGYoIlN0YWNrIGR1bXA6XG4iKTsKICAgIHN3aXRjaCAobHZhbHVlLmFkZHIuTW9kZSkKICAgIHsKICAgIGNhc2UgQWRkck1vZGVGbGF0OiAvKiAzMi1iaXQgbW9kZSAqLwogICAgY2FzZSBBZGRyTW9kZTE2MzI6IC8qIDMyLWJpdCBtb2RlICovCiAgICAgICAgbWVtb3J5X2V4YW1pbmUoJmx2YWx1ZSwgMjQsICd4Jyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFkZHJNb2RlUmVhbDogIC8qIDE2LWJpdCBtb2RlICovCiAgICBjYXNlIEFkZHJNb2RlMTYxNjoKICAgICAgICBtZW1vcnlfZXhhbWluZSgmbHZhbHVlLCAyNCwgJ3cnKTsKCWJyZWFrOwogICAgfQp9CgpzdGF0aWMgQk9PTCBzdGFja19zZXRfZnJhbWVfaW50ZXJuYWwoaW50IG5ld2ZyYW1lKQp7CiAgICBpZiAobmV3ZnJhbWUgPj0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzKQogICAgICAgIG5ld2ZyYW1lID0gZGJnX2N1cnJfdGhyZWFkLT5udW1fZnJhbWVzIC0gMTsKICAgIGlmIChuZXdmcmFtZSA8IDApCiAgICAgICAgbmV3ZnJhbWUgPSAwOwoKICAgIGlmIChkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgIT0gbmV3ZnJhbWUpCiAgICB7CiAgICAgICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgaWhzZjsKCiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gbmV3ZnJhbWU7CiAgICAgICAgc3RhY2tfZ2V0X2N1cnJlbnRfZnJhbWUoJmloc2YpOwogICAgICAgIFN5bVNldENvbnRleHQoZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCAmaWhzZiwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgc3RhY2tfZ2V0X2ZyYW1lKGludCBuZiwgSU1BR0VITFBfU1RBQ0tfRlJBTUUqIGloc2YpCnsKICAgIG1lbXNldChpaHNmLCAwLCBzaXplb2YoKmloc2YpKTsKICAgIGloc2YtPkluc3RydWN0aW9uT2Zmc2V0ID0gZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmxpbmVhcl9wYzsKICAgIGloc2YtPkZyYW1lT2Zmc2V0ID0gZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmxpbmVhcl9mcmFtZTsKICAgIHJldHVybiBUUlVFOwp9CgpCT09MIHN0YWNrX2dldF9jdXJyZW50X2ZyYW1lKElNQUdFSExQX1NUQUNLX0ZSQU1FKiBpaHNmKQp7CiAgICAvKgogICAgICogSWYgd2UgZG9uJ3QgaGF2ZSBhIHZhbGlkIGJhY2t0cmFjZSwgdGhlbiBqdXN0IHJldHVybi4KICAgICAqLwogICAgaWYgKGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzID09IE5VTEwpIHJldHVybiBGQUxTRTsKICAgIHJldHVybiBzdGFja19nZXRfZnJhbWUoZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lLCBpaHNmKTsKfQoKQk9PTCBzdGFja19nZXRfcmVnaXN0ZXJfY3VycmVudF9mcmFtZSh1bnNpZ25lZCByZWdubywgRFdPUkQqKiBwdmFsKQp7CiAgICBlbnVtIGJlX2NwdV9hZGRyICAgICAgICAgICAga2luZDsKCiAgICBpZiAoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghYmVfY3B1LT5nZXRfcmVnaXN0ZXJfaW5mbyhyZWdubywgJmtpbmQpKSByZXR1cm4gRkFMU0U7CgogICAgc3dpdGNoIChraW5kKQogICAgewogICAgY2FzZSBiZV9jcHVfYWRkcl9wYzoKICAgICAgICAqcHZhbCA9ICZkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWVdLmxpbmVhcl9wYzsKICAgICAgICBicmVhazsKICAgIGNhc2UgYmVfY3B1X2FkZHJfc3RhY2s6CiAgICAgICAgKnB2YWwgPSAmZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lXS5saW5lYXJfc3RhY2s7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIGJlX2NwdV9hZGRyX2ZyYW1lOgogICAgICAgICpwdmFsID0gJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW2RiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZV0ubGluZWFyX2ZyYW1lOwogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCkJPT0wgc3RhY2tfc2V0X2ZyYW1lKGludCBuZXdmcmFtZSkKewogICAgQUREUkVTUzY0ICAgYWRkcjsKICAgIGlmICghc3RhY2tfc2V0X2ZyYW1lX2ludGVybmFsKG5ld2ZyYW1lKSkgcmV0dXJuIEZBTFNFOwogICAgYWRkci5Nb2RlID0gQWRkck1vZGVGbGF0OwogICAgYWRkci5PZmZzZXQgPSAodW5zaWduZWQgbG9uZyltZW1vcnlfdG9fbGluZWFyX2FkZHIoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW2RiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZV0uYWRkcl9wYyk7CiAgICBzb3VyY2VfbGlzdF9mcm9tX2FkZHIoJmFkZHIsIDApOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXN0YWNrX2dldF9jdXJyZW50X3N5bWJvbAogKgogKiBSZXRyaWV2ZXMgdGhlIHN5bWJvbCBpbmZvcm1hdGlvbiBmb3IgdGhlIGN1cnJlbnQgZnJhbWUgZWxlbWVudAogKi8KQk9PTCBzdGFja19nZXRfY3VycmVudF9zeW1ib2woU1lNQk9MX0lORk8qIHN5bWJvbCkKewogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CiAgICBEV09SRDY0ICAgICAgICAgICAgICAgICAgICAgZGlzcDsKCiAgICBpZiAoIXN0YWNrX2dldF9jdXJyZW50X2ZyYW1lKCZpaHNmKSkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIFN5bUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAmZGlzcCwgc3ltYm9sKTsKfQoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sgc3RhY2tfcmVhZF9tZW0oSEFORExFIGhQcm9jLCBEV09SRDY0IGFkZHIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVk9JRCBidWZmZXIsIERXT1JEIHNpemUsIFBEV09SRCB3cml0dGVuKQp7CiAgICBTSVpFX1Qgc3o7CiAgICBCT09MIHJldDsKCiAgICBzdHJ1Y3QgZGJnX3Byb2Nlc3MqIHBjcyA9IGRiZ19nZXRfcHJvY2Vzc19oKGhQcm9jKTsKICAgIGlmICghcGNzKSByZXR1cm4gRkFMU0U7CiAgICByZXQgPSBwY3MtPnByb2Nlc3NfaW8tPnJlYWQoaFByb2MsIChjb25zdCB2b2lkKikoRFdPUkRfUFRSKWFkZHIsIGJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplLCAmc3opOwogICAgaWYgKHdyaXR0ZW4gIT0gTlVMTCkgKndyaXR0ZW4gPSBzejsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXN0YWNrX2ZldGNoX2ZyYW1lcwogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiB0aGUgdGhlIGN1cnJlbnQgdGhyZWFkCiAqLwp1bnNpZ25lZCBzdGFja19mZXRjaF9mcmFtZXModm9pZCkKewogICAgU1RBQ0tGUkFNRTY0IHNmOwogICAgdW5zaWduZWQgICAgIG5mID0gMDsKICAgIC8qIGFzIG5hdGl2ZSBzdGFja3dhbGsgY2FuIG1vZGlmeSB0aGUgY29udGV4dCBwYXNzZWQgdG8gaXQsIHNpbXBseSBjb3B5CiAgICAgKiBpdCB0byBhdm9pZCBhbnkgZGFtYWdlCiAgICAgKi8KICAgIENPTlRFWFQgICAgICBjdHggPSBkYmdfY29udGV4dDsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyk7CiAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9IE5VTEw7CgogICAgbWVtc2V0KCZzZiwgMCwgc2l6ZW9mKHNmKSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfZnJhbWUoJnNmLkFkZHJGcmFtZSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfcGMoJnNmLkFkZHJQQyk7CgogICAgLyogZG9uJ3QgY29uZnVzZSBTdGFja1dhbGsgYnkgcGFzc2luZyBpbiBpbmNvbnNpc3RlbnQgYWRkcmVzc2VzICovCiAgICBpZiAoKHNmLkFkZHJQQy5Nb2RlID09IEFkZHJNb2RlRmxhdCkgJiYgKHNmLkFkZHJGcmFtZS5Nb2RlICE9IEFkZHJNb2RlRmxhdCkpCiAgICB7CiAgICAgICAgc2YuQWRkckZyYW1lLk9mZnNldCA9IChEV09SRCltZW1vcnlfdG9fbGluZWFyX2FkZHIoJnNmLkFkZHJGcmFtZSk7CiAgICAgICAgc2YuQWRkckZyYW1lLk1vZGUgPSBBZGRyTW9kZUZsYXQ7CiAgICB9CgogICAgd2hpbGUgKFN0YWNrV2FsazY0KElNQUdFX0ZJTEVfTUFDSElORV9JMzg2LCBkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIAogICAgICAgICAgICAgICAgICAgICAgIGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlLCAmc2YsICZjdHgsIHN0YWNrX3JlYWRfbWVtLAogICAgICAgICAgICAgICAgICAgICAgIFN5bUZ1bmN0aW9uVGFibGVBY2Nlc3M2NCwgU3ltR2V0TW9kdWxlQmFzZTY0LCBOVUxMKSkKICAgIHsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lcyA9IGRiZ19oZWFwX3JlYWxsb2MoZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmYgKyAxKSAqIHNpemVvZihkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1swXSkpOwoKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0uYWRkcl9wYyAgICAgID0gc2YuQWRkclBDOwogICAgICAgIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5saW5lYXJfcGMgICAgPSAoRFdPUkQpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZzZi5BZGRyUEMpOwogICAgICAgIGRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW25mXS5hZGRyX2ZyYW1lICAgPSBzZi5BZGRyRnJhbWU7CiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmxpbmVhcl9mcmFtZSA9IChEV09SRCltZW1vcnlfdG9fbGluZWFyX2FkZHIoJnNmLkFkZHJGcmFtZSk7CiAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfc3RhY2sgICA9IHNmLkFkZHJTdGFjazsKICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmZyYW1lc1tuZl0ubGluZWFyX3N0YWNrID0gKERXT1JEKW1lbW9yeV90b19saW5lYXJfYWRkcigmc2YuQWRkclN0YWNrKTsKICAgICAgICBuZisrOwogICAgICAgIC8qIHdlJ3ZlIHByb2JhYmx5IGdvdHRlbiBvdXJzZWx2ZXMgaW50byBhbiBpbmZpbml0ZSBsb29wIHNvIGJhaWwgKi8KICAgICAgICBpZiAobmYgPiAyMDApIGJyZWFrOwogICAgfQogICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lID0gLTE7CiAgICBkYmdfY3Vycl90aHJlYWQtPm51bV9mcmFtZXMgPSBuZjsKICAgIHN0YWNrX3NldF9mcmFtZV9pbnRlcm5hbCgwKTsKICAgIHJldHVybiBuZjsKfQoKc3RydWN0IHN5bV9lbnVtCnsKICAgIERXT1JEICAgICAgIGZyYW1lOwogICAgQk9PTCAgICAgICAgZmlyc3Q7Cn07CgpzdGF0aWMgQk9PTCBXSU5BUEkgc3ltX2VudW1fY2IoU1lNQk9MX0lORk8qIHN5bV9pbmZvLCBVTE9ORyBzaXplLCB2b2lkKiB1c2VyKQp7CiAgICBzdHJ1Y3Qgc3ltX2VudW0qICAgIHNlID0gKHN0cnVjdCBzeW1fZW51bSopdXNlcjsKCiAgICBpZiAoc3ltX2luZm8tPkZsYWdzICYgU1lNRkxBR19QQVJBTUVURVIpCiAgICB7CiAgICAgICAgaWYgKCFzZS0+Zmlyc3QpIGRiZ19wcmludGYoIiwgIik7IGVsc2Ugc2UtPmZpcnN0ID0gRkFMU0U7CiAgICAgICAgc3ltYm9sX3ByaW50X2xvY2FsKHN5bV9pbmZvLCBzZS0+ZnJhbWUsIEZBTFNFKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBzdGFja19wcmludF9hZGRyX2FuZF9hcmdzKGludCBuZikKewogICAgY2hhciAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlcltzaXplb2YoU1lNQk9MX0lORk8pICsgMjU2XTsKICAgIFNZTUJPTF9JTkZPKiAgICAgICAgICAgICAgICBzaSA9IChTWU1CT0xfSU5GTyopYnVmZmVyOwogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CiAgICBJTUFHRUhMUF9MSU5FICAgICAgICAgICAgICAgaWw7CiAgICBJTUFHRUhMUF9NT0RVTEUgICAgICAgICAgICAgaW07CiAgICBEV09SRDY0ICAgICAgICAgICAgICAgICAgICAgZGlzcDY0OwoKICAgIHByaW50X2JhcmVfYWRkcmVzcygmZGJnX2N1cnJfdGhyZWFkLT5mcmFtZXNbbmZdLmFkZHJfcGMpOwoKICAgIHN0YWNrX2dldF9mcmFtZShuZiwgJmloc2YpOwoKICAgIC8qIGdyYWIgbW9kdWxlIHdoZXJlIHN5bWJvbCBpcy4gSWYgd2UgZG9uJ3QgaGF2ZSBhIG1vZHVsZSwgd2UgY2Fubm90IHByaW50IG1vcmUgKi8KICAgIGltLlNpemVPZlN0cnVjdCA9IHNpemVvZihpbSk7CiAgICBpZiAoIVN5bUdldE1vZHVsZUluZm8oZGJnX2N1cnJfcHJvY2Vzcy0+aGFuZGxlLCBpaHNmLkluc3RydWN0aW9uT2Zmc2V0LCAmaW0pKQogICAgICAgIHJldHVybjsKCiAgICBzaS0+U2l6ZU9mU3RydWN0ID0gc2l6ZW9mKCpzaSk7CiAgICBzaS0+TWF4TmFtZUxlbiAgID0gMjU2OwogICAgaWYgKFN5bUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwgJmRpc3A2NCwgc2kpKQogICAgewogICAgICAgIHN0cnVjdCBzeW1fZW51bSBzZTsKICAgICAgICBEV09SRCAgICAgICAgICAgZGlzcDsKCiAgICAgICAgZGJnX3ByaW50ZigiICVzIiwgc2ktPk5hbWUpOwogICAgICAgIGlmIChkaXNwNjQpIGRiZ19wcmludGYoIisweCVseCIsIChEV09SRF9QVFIpZGlzcDY0KTsKCiAgICAgICAgU3ltU2V0Q29udGV4dChkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsICZpaHNmLCBOVUxMKTsKICAgICAgICBzZS5maXJzdCA9IFRSVUU7CiAgICAgICAgc2UuZnJhbWUgPSBpaHNmLkZyYW1lT2Zmc2V0OwogICAgICAgIGRiZ19wcmludGYoIigiKTsKICAgICAgICBTeW1FbnVtU3ltYm9scyhkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsIDAsIE5VTEwsIHN5bV9lbnVtX2NiLCAmc2UpOwogICAgICAgIGRiZ19wcmludGYoIikiKTsKCiAgICAgICAgaWwuU2l6ZU9mU3RydWN0ID0gc2l6ZW9mKGlsKTsKICAgICAgICBpZiAoU3ltR2V0TGluZUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgaWhzZi5JbnN0cnVjdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkaXNwLCAmaWwpKQogICAgICAgICAgICBkYmdfcHJpbnRmKCIgWyVzOiV1XSIsIGlsLkZpbGVOYW1lLCBpbC5MaW5lTnVtYmVyKTsKICAgICAgICBkYmdfcHJpbnRmKCIgaW4gJXMiLCBpbS5Nb2R1bGVOYW1lKTsKICAgIH0KICAgIGVsc2UgZGJnX3ByaW50ZigiIGluICVzICgrMHglbHgpIiwgCiAgICAgICAgICAgICAgICAgICAgaW0uTW9kdWxlTmFtZSwgKERXT1JEX1BUUikoaWhzZi5JbnN0cnVjdGlvbk9mZnNldCAtIGltLkJhc2VPZkltYWdlKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCWJhY2t0cmFjZQogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiB0aGUgdGhlIGN1cnJlbnQgdGhyZWFkCiAqLwpzdGF0aWMgdm9pZCBiYWNrdHJhY2Uodm9pZCkKewogICAgdW5zaWduZWQgICAgICAgICAgICAgICAgICAgIGNmID0gZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lOwogICAgSU1BR0VITFBfU1RBQ0tfRlJBTUUgICAgICAgIGloc2Y7CgogICAgZGJnX3ByaW50ZigiQmFja3RyYWNlOlxuIik7CiAgICBmb3IgKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSA9IDA7CiAgICAgICAgIGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSA8IGRiZ19jdXJyX3RocmVhZC0+bnVtX2ZyYW1lczsKICAgICAgICAgZGJnX2N1cnJfdGhyZWFkLT5jdXJyX2ZyYW1lKyspCiAgICB7CiAgICAgICAgZGJnX3ByaW50ZigiJXMlZCAiLCAKICAgICAgICAgICAgICAgICAgIChjZiA9PSBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgPyAiPT4iIDogIiAgIiksCiAgICAgICAgICAgICAgICAgICBkYmdfY3Vycl90aHJlYWQtPmN1cnJfZnJhbWUgKyAxKTsKICAgICAgICBzdGFja19wcmludF9hZGRyX2FuZF9hcmdzKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSk7CiAgICAgICAgZGJnX3ByaW50ZigiICgiKTsKICAgICAgICBwcmludF9iYXJlX2FkZHJlc3MoJmRiZ19jdXJyX3RocmVhZC0+ZnJhbWVzW2RiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZV0uYWRkcl9mcmFtZSk7CiAgICAgICAgZGJnX3ByaW50ZigiKVxuIik7CiAgICB9CiAgICAvKiByZXNldCBjb250ZXh0IHRvIGN1cnJlbnQgc3RhY2sgZnJhbWUgKi8KICAgIGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSA9IGNmOwogICAgaWYgKCFkYmdfY3Vycl90aHJlYWQtPmZyYW1lcykgcmV0dXJuOwogICAgc3RhY2tfZ2V0X2ZyYW1lKGRiZ19jdXJyX3RocmVhZC0+Y3Vycl9mcmFtZSwgJmloc2YpOwogICAgU3ltU2V0Q29udGV4dChkYmdfY3Vycl9wcm9jZXNzLT5oYW5kbGUsICZpaHNmLCBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlX3RpZAogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiBhIHRocmVhZCBmcm9tIGl0cyBwcm9jZXNzIGFuZCBpdHMgaWRlbnRpZmllcgogKiAocHJlc2VydmVzIGN1cnJlbnQgdGhyZWFkIGFuZCBjb250ZXh0IGluZm9ybWF0aW9uKQogKi8Kc3RhdGljIHZvaWQgYmFja3RyYWNlX3RpZChzdHJ1Y3QgZGJnX3Byb2Nlc3MqIHBjcywgRFdPUkQgdGlkKQp7CiAgICBzdHJ1Y3QgZGJnX3RocmVhZCogIHRocmVhZCA9IGRiZ19jdXJyX3RocmVhZDsKCiAgICBpZiAoIShkYmdfY3Vycl90aHJlYWQgPSBkYmdfZ2V0X3RocmVhZChwY3MsIHRpZCkpKQogICAgICAgIGRiZ19wcmludGYoIlVua25vd24gdGhyZWFkIGlkICglMDR4KSBpbiBwcm9jZXNzICglMDR4KVxuIiwgdGlkLCBwY3MtPnBpZCk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgQ09OVEVYVCBzYXZlZF9jdHggPSBkYmdfY29udGV4dDsKCiAgICAgICAgZGJnX2N1cnJfdGlkID0gZGJnX2N1cnJfdGhyZWFkLT50aWQ7CiAgICAgICAgbWVtc2V0KCZkYmdfY29udGV4dCwgMCwgc2l6ZW9mKGRiZ19jb250ZXh0KSk7CiAgICAgICAgZGJnX2NvbnRleHQuQ29udGV4dEZsYWdzID0gQ09OVEVYVF9GVUxMOwogICAgICAgIGlmIChTdXNwZW5kVGhyZWFkKGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlKSAhPSAtMSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghR2V0VGhyZWFkQ29udGV4dChkYmdfY3Vycl90aHJlYWQtPmhhbmRsZSwgJmRiZ19jb250ZXh0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGJnX3ByaW50ZigiQ2FuJ3QgZ2V0IGNvbnRleHQgZm9yIHRocmVhZCAlMDR4IGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0YWNrX2ZldGNoX2ZyYW1lcygpOwogICAgICAgICAgICAgICAgYmFja3RyYWNlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgUmVzdW1lVGhyZWFkKGRiZ19jdXJyX3RocmVhZC0+aGFuZGxlKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBkYmdfcHJpbnRmKCJDYW4ndCBzdXNwZW5kIHRocmVhZCAlMDR4IGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwgdGlkKTsKICAgICAgICBkYmdfY29udGV4dCA9IHNhdmVkX2N0eDsKICAgIH0KICAgIGRiZ19jdXJyX3RocmVhZCA9IHRocmVhZDsKICAgIGRiZ19jdXJyX3RpZCA9IHRocmVhZCA/IHRocmVhZC0+dGlkIDogMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJYmFja3RyYWNlX2FsbAogKgogKiBEbyBhIGJhY2t0cmFjZSBvbiBldmVyeSBydW5uaW5nIHRocmVhZCBpbiB0aGUgc3lzdGVtIChleGNlcHQgdGhlIGRlYnVnZ2VyKQogKiAocHJlc2VydmVzIGN1cnJlbnQgcHJvY2VzcyBpbmZvcm1hdGlvbikKICovCnN0YXRpYyB2b2lkIGJhY2t0cmFjZV9hbGwodm9pZCkKewogICAgc3RydWN0IGRiZ19wcm9jZXNzKiBwcm9jZXNzID0gZGJnX2N1cnJfcHJvY2VzczsKICAgIFRIUkVBREVOVFJZMzIgICAgICAgZW50cnk7CiAgICBIQU5ETEUgICAgICAgICAgICAgIHNuYXBzaG90ID0gQ3JlYXRlVG9vbGhlbHAzMlNuYXBzaG90KFRIMzJDU19TTkFQVEhSRUFELCAwKTsKCiAgICBpZiAoc25hcHNob3QgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCiAgICB7CiAgICAgICAgZGJnX3ByaW50ZigiVW5hYmxlIHRvIGNyZWF0ZSB0b29saGVscCBzbmFwc2hvdFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGVudHJ5LmR3U2l6ZSA9IHNpemVvZihlbnRyeSk7CiAgICBpZiAoVGhyZWFkMzJGaXJzdChzbmFwc2hvdCwgJmVudHJ5KSkKICAgIHsKICAgICAgICBkbwogICAgICAgIHsKICAgICAgICAgICAgaWYgKGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCA9PSBHZXRDdXJyZW50UHJvY2Vzc0lkKCkpIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAoZGJnX2N1cnJfcHJvY2VzcyAmJiBkYmdfY3Vycl9waWQgIT0gZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEKQogICAgICAgICAgICAgICAgZGJnX2N1cnJfcHJvY2Vzcy0+cHJvY2Vzc19pby0+Y2xvc2VfcHJvY2VzcyhkYmdfY3Vycl9wcm9jZXNzLCBGQUxTRSk7CgogICAgICAgICAgICBpZiAoZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEICE9IGRiZ19jdXJyX3BpZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFkYmdfYXR0YWNoX2RlYnVnZ2VlKGVudHJ5LnRoMzJPd25lclByb2Nlc3NJRCwgRkFMU0UpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRiZ19wcmludGYoIlxud2FybmluZzogY291bGQgbm90IGF0dGFjaCB0byAlMDR4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnkudGgzMk93bmVyUHJvY2Vzc0lEKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRiZ19jdXJyX3BpZCA9IGRiZ19jdXJyX3Byb2Nlc3MtPnBpZDsKICAgICAgICAgICAgICAgIGRiZ19hY3RpdmVfd2FpdF9mb3JfZmlyc3RfZXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRiZ19wcmludGYoIlxuQmFja3RyYWNpbmcgZm9yIHRocmVhZCAlMDR4IGluIHByb2Nlc3MgJTA0eCAoJXMpOlxuIiwKICAgICAgICAgICAgICAgICAgICAgICBlbnRyeS50aDMyVGhyZWFkSUQsIGRiZ19jdXJyX3BpZCwgZGJnX2N1cnJfcHJvY2Vzcy0+aW1hZ2VOYW1lKTsKICAgICAgICAgICAgYmFja3RyYWNlX3RpZChkYmdfY3Vycl9wcm9jZXNzLCBlbnRyeS50aDMyVGhyZWFkSUQpOwogICAgICAgIH0KICAgICAgICB3aGlsZSAoVGhyZWFkMzJOZXh0KHNuYXBzaG90LCAmZW50cnkpKTsKCiAgICAgICAgaWYgKGRiZ19jdXJyX3Byb2Nlc3MpCiAgICAgICAgICAgIGRiZ19jdXJyX3Byb2Nlc3MtPnByb2Nlc3NfaW8tPmNsb3NlX3Byb2Nlc3MoZGJnX2N1cnJfcHJvY2VzcywgRkFMU0UpOwogICAgfQogICAgQ2xvc2VIYW5kbGUoc25hcHNob3QpOwogICAgZGJnX2N1cnJfcHJvY2VzcyA9IHByb2Nlc3M7CiAgICBkYmdfY3Vycl9waWQgPSBwcm9jZXNzID8gcHJvY2Vzcy0+cGlkIDogMDsKfQoKdm9pZCBzdGFja19iYWNrdHJhY2UoRFdPUkQgdGlkKQp7CiAgICAvKiBiYWNrdHJhY2UgZXZlcnkgdGhyZWFkIGluIGV2ZXJ5IHByb2Nlc3MgZXhjZXB0IHRoZSBkZWJ1Z2dlciBpdHNlbGYsCiAgICAgKiBpbnZva2luZyB2aWEgImJ0IGFsbCIKICAgICAqLwogICAgaWYgKHRpZCA9PSAtMSkgcmV0dXJuIGJhY2t0cmFjZV9hbGwoKTsKCiAgICBpZiAoIWRiZ19jdXJyX3Byb2Nlc3MpIAogICAgewogICAgICAgIGRiZ19wcmludGYoIllvdSBtdXN0IGJlIGF0dGFjaGVkIHRvIGEgcHJvY2VzcyB0byBydW4gdGhpcyBjb21tYW5kLlxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgCiAgICBpZiAodGlkID09IGRiZ19jdXJyX3RpZCkKICAgIHsKICAgICAgICBiYWNrdHJhY2UoKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBiYWNrdHJhY2VfdGlkKGRiZ19jdXJyX3Byb2Nlc3MsIHRpZCk7CiAgICB9Cn0K