LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gTm8sIHlvdSAodXN1YWxseSkgY2Fubm90IHVzZSBMaW51eCBtbWFwKCkgdG8gbW1hcCgpIHRoZSBpbWFnZXMgZGlyZWN0bHkuCiAqCiAqICAgVGhlIHByb2JsZW0gaXMsIHRoYXQgdGhlcmUgaXMgbm90IGRpcmVjdCAxOjEgbWFwcGluZyBmcm9tIGEgZGlza2ltYWdlIGFuZAogKiAgIGEgbWVtb3J5aW1hZ2UuIFRoZSBoZWFkZXJzIGF0IHRoZSBzdGFydCBhcmUgbWFwcGVkIGxpbmVhciwgYnV0IHRoZSBzZWN0aW9ucwogKiAgIGFyZSBub3QuIEZvciB4ODYgdGhlIHNlY3Rpb25zIGFyZSA1MTIgYnl0ZSBhbGlnbmVkIGluIGZpbGUgYW5kIDQwOTYgYnl0ZQogKiAgIGFsaWduZWQgaW4gbWVtb3J5LiBMaW51eCBsaWtlcyB0aGVtIDQwOTYgYnl0ZSBhbGlnbmVkIGluIG1lbW9yeSAoZHVlIHRvCiAqICAgeDg2IHBhZ2VzaXplLCB0aGlzIGNhbm5vdCBiZSBmaXhlZCB3aXRob3V0IGEgcmF0aGVyIGxhcmdlIGtlcm5lbCByZXdyaXRlKQogKiAgIGFuZCAnYmxvY2tzaXplJyBmaWxlLWFsaWduZWQgKG9mZnNldHMpLiBTaW5jZSB3ZSBoYXZlIDUxMi8xMDI0LzIwNDggKENEUk9NKQogKiAgIGFuZCBvdGhlciBieXRlIGJsb2Nrc2l6ZXMsIHdlIGNhbid0IGRvIHRoaXMuIEhvd2V2ZXIsIHRoaXMgY291bGQgYmUgbGVzcwogKiAgIGRpZmZpY3VsdCB0byBzdXBwb3J0Li4uIChTZWUgbW0vZmlsZW1hcC5jKS4KICogLSBBbGwgdGhvc2UgZnVuY3Rpb24gbWFwIHRoaW5ncyBpbnRvIGEgbmV3IGFkZHJlc3NwYWNlLiBGcm9tIHRoZSB3cm9uZwogKiAgIHByb2Nlc3MgYW5kIHRoZSB3cm9uZyB0aHJlYWQuIFNvIGNhbGxpbmcgb3RoZXIgQVBJIGZ1bmN0aW9ucyB3aWxsIG1lc3MgCiAqICAgdGhpbmdzIHVwIGJhZGx5IHNvbWV0aW1lcy4KICovCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgInBlX2ltYWdlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAiZGVidWcuaCIKCnN0YXRpYyB2b2lkIFBFX0luaXRETEwoV0lORV9NT0RSRUYgKndtLCBEV09SRCB0eXBlLCBMUFZPSUQgbHBSZXNlcnZlZCk7CgovKiBjb252ZXJ0IFBFIGltYWdlIFZpcnR1YWxBZGRyZXNzIHRvIFJlYWwgQWRkcmVzcyAqLwojZGVmaW5lIFJWQSh4KSAoKHVuc2lnbmVkIGludClsb2FkX2FkZHIrKHVuc2lnbmVkIGludCkoeCkpCgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFMzIgaE1vZHVsZSApCnsgCiAgY2hhcgkJKk1vZHVsZTsKICBpbnQJCWksIGo7CiAgdV9zaG9ydAkqb3JkaW5hbDsKICB1X2xvbmcJKmZ1bmN0aW9uLCpmdW5jdGlvbnM7CiAgdV9jaGFyCSoqbmFtZTsKICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gaE1vZHVsZTsKCiAgRFdPUkQgcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CiAgRFdPUkQgcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0cyA9IChJTUFHRV9FWFBPUlRfRElSRUNUT1JZKilSVkEocnZhX3N0YXJ0KTsKCiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBUUkFDRSh3aW4zMiwiKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuIik7CiAgVFJBQ0Uod2luMzIsIk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJICAgICAgIE1vZHVsZSwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsIHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXMpOwoKICBvcmRpbmFsPSh1X3Nob3J0KikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CiAgZnVuY3Rpb25zPWZ1bmN0aW9uPSh1X2xvbmcqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lPSh1X2NoYXIqKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgVFJBQ0Uod2luMzIsIiBPcmQgICAgUlZBICAgICBBZGRyICAgTmFtZVxuIiApOwogIGZvciAoaT0wO2k8cGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnM7aSsrLCBmdW5jdGlvbisrKQogIHsKICAgICAgaWYgKCEqZnVuY3Rpb24pIGNvbnRpbnVlOyAgLyogTm8gc3VjaCBmdW5jdGlvbiAqLwogICAgICBpZiAoVFJBQ0VfT04od2luMzIpKXsKCWRiZ19kZWNsX3N0cih3aW4zMiwgMTAyNCk7CgoJZHNwcmludGYod2luMzIsIiU0bGQgJTA4bHggJTA4eCIsCgkJIGkgKyBwZV9leHBvcnRzLT5CYXNlLCAqZnVuY3Rpb24sIFJWQSgqZnVuY3Rpb24pICk7CgkvKiBDaGVjayBpZiB3ZSBoYXZlIGEgbmFtZSBmb3IgaXQgKi8KCWZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQoJICAgIGRzcHJpbnRmKHdpbjMyLCAiICAlcyIsIChjaGFyKilSVkEobmFtZVtqXSkgKTsKCWlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfZW5kKSkKCSAgZHNwcmludGYod2luMzIsICIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKCVRSQUNFKHdpbjMyLCIlc1xuIiwgZGJnX3N0cih3aW4zMikpOwogICAgICB9CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpGQVJQUk9DMzIgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oIAoJUERCMzIgKnByb2Nlc3MsCQkvKiBbaW5dIHByb2Nlc3MgY29udGV4dCAqLwoJV0lORV9NT0RSRUYgKndtLAkvKiBbaW5dIFdJTkUgbW9kcmVmZXJlbmNlICovCglMUENTVFIgZnVuY05hbWUgKQkvKiBbaW5dIGZ1bmN0aW9uIG5hbWUgKi8KewoJdV9zaG9ydAkJCQkqIG9yZGluYWw7Cgl1X2xvbmcJCQkJKiBmdW5jdGlvbjsKCXVfY2hhcgkJCQkqKiBuYW1lLCAqZW5hbWU7CglpbnQJCQkJaTsKCVBFX01PRFJFRgkJCSpwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAJCSpleHBvcnRzID0gcGVtLT5wZV9leHBvcnQ7Cgl1bnNpZ25lZCBpbnQJCQlsb2FkX2FkZHIgPSB3bS0+bW9kdWxlOwoJdV9sb25nCQkJCXJ2YV9zdGFydCwgcnZhX2VuZCwgYWRkcjsKCWNoYXIJCQkJKiBmb3J3YXJkOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCVRSQUNFKHdpbjMyLCIoJXMpXG4iLGZ1bmNOYW1lKTsKCWVsc2UKCQlUUkFDRSh3aW4zMiwiKCVkKVxuIiwoaW50KWZ1bmNOYW1lKTsKCWlmICghZXhwb3J0cykgewoJCS8qIE5vdCBhIGZhdGFsIHByb2JsZW0sIHNvbWUgYXBwcyBkbwoJCSAqIEdldFByb2NBZGRyZXNzKDAsIlJlZ2lzdGVyUGVuQXBwIikgd2hpY2ggdHJpZ2dlcnMgdGhpcwoJCSAqIGNhc2UuCgkJICovCgkJV0FSTih3aW4zMiwiTW9kdWxlICUwOHgoJXMpL01PRFJFRiAlcCBkb2Vzbid0IGhhdmUgYSBleHBvcnRzIHRhYmxlLlxuIix3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHBlbSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglvcmRpbmFsCT0gKHVfc2hvcnQqKSAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gKHVfbG9uZyopICAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lCT0gKHVfY2hhciAqKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcndhcmQgPSBOVUxMOwoJcnZhX3N0YXJ0ID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwoJcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKSB7CgkJZm9yKGk9MDsgaTxleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspIHsKCQkJZW5hbWU9KGNoYXIqKVJWQSgqbmFtZSk7CgkJCWlmKCFzdHJjbXAoZW5hbWUsZnVuY05hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRyID0gZnVuY3Rpb25bKm9yZGluYWxdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoYWRkciA8IHJ2YV9zdGFydCkgfHwgKGFkZHIgPj0gcnZhX2VuZCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChGQVJQUk9DMzIpUlZBKGFkZHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yd2FyZCA9IChjaGFyICopUlZBKGFkZHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJCX0KCQkJb3JkaW5hbCsrOwoJCQluYW1lKys7CgkJfQoJfSBlbHNlIHsKCQlpZiAoTE9XT1JEKGZ1bmNOYW1lKS1leHBvcnRzLT5CYXNlID4gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpIHsKCQkJVFJBQ0Uod2luMzIsIglvcmRpbmFsICVkIG91dCBvZiByYW5nZSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9XT1JEKGZ1bmNOYW1lKSk7CgkJCXJldHVybiBOVUxMOwoJCX0KCQlhZGRyID0gZnVuY3Rpb25bKGludClmdW5jTmFtZS1leHBvcnRzLT5CYXNlXTsKICAgICAgICAgICAgICAgIGlmICghYWRkcikgcmV0dXJuIE5VTEw7CgkJaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKCQkJcmV0dXJuIChGQVJQUk9DMzIpUlZBKGFkZHIpOwoJCWZvcndhcmQgPSAoY2hhciAqKVJWQShhZGRyKTsKCX0KCWlmIChmb3J3YXJkKQogICAgICAgIHsKICAgICAgICAgICAgICAgIEhNT0RVTEUzMiBoTW9kOwoJCWNoYXIgbW9kdWxlWzI1Nl07CgkJY2hhciAqZW5kID0gc3RyY2hyKGZvcndhcmQsICcuJyk7CgoJCWlmICghZW5kKSByZXR1cm4gTlVMTDsKCQlhc3NlcnQoZW5kLWZvcndhcmQ8MjU2KTsKCQlzdHJuY3B5KG1vZHVsZSwgZm9yd2FyZCwgKGVuZCAtIGZvcndhcmQpKTsKCQltb2R1bGVbZW5kLWZvcndhcmRdID0gMDsKICAgICAgICAgICAgICAgIGhNb2QgPSBNT0RVTEVfRmluZE1vZHVsZTMyKHByb2Nlc3MsbW9kdWxlKTsKCQlhc3NlcnQoaE1vZCk7CgkJcmV0dXJuIE1PRFVMRV9HZXRQcm9jQWRkcmVzczMyKCBwcm9jZXNzLCBoTW9kLCBlbmQgKyAxKTsKCX0KCXJldHVybiBOVUxMOwp9CgpEV09SRCBmaXh1cF9pbXBvcnRzIChQREIzMiAqcHJvY2VzcyxXSU5FX01PRFJFRiAqd20pCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SCSpwZV9pbXA7CiAgICBXSU5FX01PRFJFRgkJCSp4d207CiAgICBQRV9NT0RSRUYJCQkqcGVtOwogICAgaW50CWZpeHVwX2ZhaWxlZAkJPSAwOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcgk9IHdtLT5tb2R1bGU7CiAgICBpbnQJCQkJaTsKICAgIGNoYXIJCQkqbW9kbmFtZTsKICAgIAogICAgYXNzZXJ0KHdtLT50eXBlPT1NT0RVTEUzMl9QRSk7CiAgICBwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwogICAgaWYgKHBlbS0+cGVfZXhwb3J0KQogICAgCW1vZG5hbWUgPSAoY2hhciopIFJWQShwZW0tPnBlX2V4cG9ydC0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIFRSQUNFKHdpbjMyLCAiRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIGlmICghcGVfaW1wKSAKICAgIAlFUlIod2luMzIsICJubyBpbXBvcnQgZGlyZWN0b3J5Pz8/P1xuIik7CgogICAgLyogRklYTUU6IHNob3VsZCB0ZXJtaW5hdGUgb24gMCBDaGFyYWN0ZXJpc3RpY3MgKi8KICAgIGZvciAoaSA9IDA7IHBlX2ltcC0+TmFtZTsgcGVfaW1wKyspCglpKys7CgogICAgLyogbG9hZCB0aGUgaW1wb3J0ZWQgbW9kdWxlcy4gVGhleSBhcmUgYXV0b21hdGljYWxseSAKICAgICAqIGFkZGVkIHRvIHRoZSBtb2RyZWYgbGlzdCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwogCiAgICAvKiBGSVhNRTogc2hvdWxkIHRlcm1pbmF0ZSBvbiAwIENoYXJhY3RlcmlzdGljcyAqLwogICAgZm9yIChpID0gMCwgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7IHBlX2ltcC0+TmFtZTsgcGVfaW1wKyspIHsKICAgIAlITU9EVUxFMzIJcmVzOwoJV0lORV9NT0RSRUYJKip5d207CiAJY2hhcgkJKm5hbWUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKCgkvKiBkb24ndCB1c2UgTU9EVUxFX0xvYWQsIFdpbjMyIGNyZWF0ZXMgbmV3IHRhc2sgZGlmZmVyZW50bHkgKi8KCXJlcyA9IFBFX0xvYWRMaWJyYXJ5RXgzMkEoIG5hbWUsIHByb2Nlc3MsIDAsIDAgKTsKCWlmIChyZXMgPD0gKEhNT0RVTEUzMikgMzIpIHsKCSAgICBjaGFyICpwLGJ1ZmZlclsyMDAwXTsKCSAgICAKCSAgICAvKiBHZXRNb2R1bGVGaWxlTmFtZSB3b3VsZCB1c2UgdGhlIHdyb25nIHByb2Nlc3MsIHNvIGRvbid0IHVzZSBpdCAqLwoJICAgIHN0cmNweShidWZmZXIsd20tPnNob3J0bmFtZSk7CgkgICAgaWYgKCEocCA9IHN0cnJjaHIgKGJ1ZmZlciwgJ1xcJykpKQoJCXAgPSBidWZmZXI7CgkgICAgc3RyY3B5IChwICsgMSwgbmFtZSk7CgkgICAgcmVzID0gUEVfTG9hZExpYnJhcnlFeDMyQSggYnVmZmVyLCBwcm9jZXNzLCAwLCAwICk7Cgl9CglpZiAocmVzIDw9IChITU9EVUxFMzIpIDMyKSB7CgkgICAgV0FSTiAobW9kdWxlLCAiTW9kdWxlICVzIG5vdCBmb3VuZFxuIiwgbmFtZSk7CgkgICAgcmV0dXJuIHJlczsKCX0KCXh3bSA9IHdtLT5uZXh0OwoJd2hpbGUgKHh3bSkgewoJCWlmICh4d20tPm1vZHVsZSA9PSByZXMpCgkJCWJyZWFrOwoJCXh3bSA9IHh3bS0+bmV4dDsKCX0KCWlmICh4d20pIHsKCQkvKiBJdCBoYXMgYmVlbiBsb2FkZWQgKkJFRk9SRSogdXMsIHNvIHdlIGhhdmUgdG8gaW5pdGlhbGl6ZQoJCSAqIGl0IGJlZm9yZSB1cy4gV2UgY2Fubm90IGp1c3QgbGluayBpbiB0aGUgeHdtIGJlZm9yZSB3bSwKCQkgKiBzaW5jZSB4d20gbWlnaHQgcmVmZXJlbmNlIG1vcmUgZGxscyB3aGljaCB3b3VsZCBiZSBpbiB0aGUKCQkgKiB3cm9uZyBvcmRlciBhZnRlciB0aGF0LgoJCSAqIEluc3RlYWQgd2UgbGluayBpbiB3bSByaWdodCBBRlRFUiB4d20sIHdoaWNoIHNob3VsZCBrZWVwCgkJICogdGhlIGNvcnJlY3Qgb3JkZXIuIChJIGFtIG5vdCAxMDAlIHN1cmUgYWJvdXQgdGhhdC4pCgkJICovCgkJLyogdW5saW5rIHdtIGZyb20gY2hhaW4gKi8KCQl5d20gPSAmKHByb2Nlc3MtPm1vZHJlZl9saXN0KTsKCQl3aGlsZSAoKnl3bSkgewoJCQlpZiAoKCp5d20pPT13bSkKCQkJCWJyZWFrOwoJCQl5d20gPSAmKCgqeXdtKS0+bmV4dCk7CgkJfQoJCSp5d20JCT0gd20tPm5leHQ7CgoJCS8qIGxpbmsgd20gZGlyZWN0bHkgQUZURVIgeHdtICovCgkJd20tPm5leHQJPSB4d20tPm5leHQ7CgkJeHdtLT5uZXh0CT0gd207CgkJCgl9CglpKys7CiAgICB9CiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIHdoaWxlIChwZV9pbXAtPk5hbWUpIHsKCWNoYXIJCQkqTW9kdWxlOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglMUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKICAgICAgICBITU9EVUxFMzIgaEltcE1vZHVsZTsKCglNb2R1bGUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKICAgICAgICBoSW1wTW9kdWxlID0gTU9EVUxFX0ZpbmRNb2R1bGUzMihwcm9jZXNzLE1vZHVsZSk7Cglhc3NlcnQoaEltcE1vZHVsZSk7IC8qIHdlIGhhdmUgaW1wb3J0ZWQgaXQsIHNvIGl0IE1VU1QgYmUgdGhlcmUgKi8KCVRSQUNFKHdpbjMyLCAiJXNcbiIsIE1vZHVsZSk7CgoJLyogRklYTUU6IGZvcndhcmRlciBlbnRyaWVzIC4uLiAqLwoKCWlmIChwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rICE9IDApIHsgLyogb3JpZ2luYWwgTVMgc3R5bGUgKi8KCSAgICBUUkFDRSh3aW4zMiwgIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayk7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0Uod2luMzIsICItLS0gT3JkaW5hbCAlcywlZFxuIiwgTW9kdWxlLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzMzIoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MsIGhJbXBNb2R1bGUsIChMUENTVFIpb3JkaW5hbAoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCVdBUk4od2luMzIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBvcmRpbmFsKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9IGVsc2UgewkJLyogaW1wb3J0IGJ5IG5hbWUgKi8KCQkgICAgcGVfbmFtZSA9IChMUElNQUdFX0lNUE9SVF9CWV9OQU1FKVJWQShpbXBvcnRfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKHdpbjMyLCAiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClNT0RVTEVfR2V0UHJvY0FkZHJlc3MzMigKICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2VzcywgaEltcE1vZHVsZSwgcGVfbmFtZS0+TmFtZQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCVdBUk4od2luMzIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcyksIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSxwZV9uYW1lLT5IaW50LHBlX25hbWUtPk5hbWUpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0KCQlpbXBvcnRfbGlzdCsrOwoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9IGVsc2UgewkvKiBCb3JsYW5kIHN0eWxlICovCgkgICAgVFJBQ0Uod2luMzIsICJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0Uod2luMzIsIi0tLSBPcmRpbmFsICVzLiVkXG4iLE1vZHVsZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzMzIoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MsIGhJbXBNb2R1bGUsIChMUENTVFIpIG9yZGluYWwKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlXQVJOKHdpbjMyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oTFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSh3aW4zMiwiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLE1vZHVsZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzMzIoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MsIGhJbXBNb2R1bGUsIHBlX25hbWUtPk5hbWUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCSAgICAJV0FSTih3aW4zMiwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CglwZV9pbXArKzsKICAgIH0KICAgIGlmIChmaXh1cF9mYWlsZWQpIHJldHVybiAyMjsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50IGNhbGNfdm1hX3NpemUoIEhNT0RVTEUzMiBoTW9kdWxlICkKewogICAgaW50IGksdm1hX3NpemUgPSAwOwogICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlZyA9IFBFX1NFQ1RJT05TKGhNb2R1bGUpOwoKICAgIFRSQUNFKHdpbjMyLCAiRHVtcCBvZiBzZWdtZW50IHRhYmxlXG4iKTsKICAgIFRSQUNFKHdpbjMyLCAiICAgTmFtZSAgICBWU3ogIFZhZGRyICAgICBTelJhdyAgIEZpbGVhZHIgICpSZWxvYyAqTGluZXVtICNSZWxvYyAjTGludW0gQ2hhclxuIik7CiAgICBmb3IgKGkgPSAwOyBpPCBQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQogICAgewogICAgICAgIFRSQUNFKHdpbjMyLCAiJThzOiAlNC40bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlNC40eCAlNC40eCAlOC44bHhcbiIsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OYW1lLCAKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TWlzYy5WaXJ0dWFsU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlNpemVPZlJhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1Jhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1JlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9MaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZSZWxvY2F0aW9ucywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZMaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+Q2hhcmFjdGVyaXN0aWNzKTsKICAgICAgICB2bWFfc2l6ZSA9IE1BWCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPlNpemVPZlJhd0RhdGEpOwogICAgICAgIHBlX3NlZysrOwogICAgfQogICAgcmV0dXJuIHZtYV9zaXplOwp9CgpzdGF0aWMgdm9pZCBkb19yZWxvY2F0aW9ucyhXSU5FX01PRFJFRiAqd20pCnsKICAgIFBFX01PRFJFRgkqcGVtID0gJih3bS0+YmluZm10LnBlKTsKICAgIGludCBkZWx0YSA9IHdtLT5tb2R1bGUgLSBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHI9IHdtLT5tb2R1bGU7CgoJSU1BR0VfQkFTRV9SRUxPQ0FUSU9OCQkqciA9IHBlbS0+cGVfcmVsb2M7CglpbnQJCQkJaGRlbHRhID0gKGRlbHRhID4+IDE2KSAmIDB4RkZGRjsKCWludAkJCQlsZGVsdGEgPSBkZWx0YSAmIDB4RkZGRjsKCgkvKiBpbnQgcmVsb2Nfc2l6ZSA9ICovCgoJaWYoZGVsdGEgPT0gMCkKCQkvKiBOb3RoaW5nIHRvIGRvICovCgkJcmV0dXJuOwoJd2hpbGUoci0+VmlydHVhbEFkZHJlc3MpCgl7CgkJY2hhciAqcGFnZSA9IChjaGFyKikgUlZBKHItPlZpcnR1YWxBZGRyZXNzKTsKCQlpbnQgY291bnQgPSAoci0+U2l6ZU9mQmxvY2sgLSA4KS8yOwoJCWludCBpOwoJCVRSQUNFKGZpeHVwLCAiJXggcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLAoJCQljb3VudCwgci0+VmlydHVhbEFkZHJlc3MpOwoJCS8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KCQlmb3IoaT0wO2k8Y291bnQ7aSsrKQoJCXsKCQkJaW50IG9mZnNldCA9IHItPlR5cGVPZmZzZXRbaV0gJiAweEZGRjsKCQkJaW50IHR5cGUgPSByLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwoJCQlUUkFDRShmaXh1cCwicGF0Y2hpbmcgJXggdHlwZSAleFxuIiwgb2Zmc2V0LCB0eXBlKTsKCQkJc3dpdGNoKHR5cGUpCgkJCXsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfQUJTT0xVVEU6IGJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBoZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTE9XOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBsZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSExPVzoKI2lmIDEKCQkJCSooaW50KikocGFnZStvZmZzZXQpICs9IGRlbHRhOwojZWxzZQoJCQkJeyBpbnQgaD0qKHVuc2lnbmVkIHNob3J0KikocGFnZStvZmZzZXQpOwoJCQkJICBpbnQgbD1yLT5UeXBlT2Zmc2V0WysraV07CgkJCQkgICoodW5zaWduZWQgaW50KikocGFnZSArIG9mZnNldCkgPSAoaDw8MTYpICsgbCArIGRlbHRhOwoJCQkJfQojZW5kaWYKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJV0FSTih3aW4zMiwgIkRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9NSVBTX0pNUEFERFI6CgkJCQlXQVJOKHdpbjMyLCAiSXMgdGhpcyBhIE1JUFMgbWFjaGluZSA/Pz9cbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlXQVJOKHdpbjMyLCAiVW5rbm93biBmaXh1cCB0eXBlXG4iKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXIgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKikoKGNoYXIqKXIgKyByLT5TaXplT2ZCbG9jayk7Cgl9Cn0KCQkKCgkKCQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICogCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yIAogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUzMiBwb2ludCB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpzdGF0aWMgSE1PRFVMRTMyIFBFX0xvYWRJbWFnZSggSEZJTEUzMiBoRmlsZSApCnsKICAgIEhNT0RVTEUzMiBoTW9kdWxlOwogICAgSEFORExFMzIgbWFwcGluZzsKCiAgICAvKiBtYXAgdGhlIFBFIGZpbGUgc29tZXdoZXJlICovCiAgICBtYXBwaW5nID0gQ3JlYXRlRmlsZU1hcHBpbmczMkEoIGhGaWxlLCBOVUxMLCBQQUdFX1JFQURPTkxZIHwgU0VDX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgTlVMTCApOwogICAgaWYgKCFtYXBwaW5nKQogICAgewogICAgICAgIFdBUk4oIHdpbjMyLCAiQ3JlYXRlRmlsZU1hcHBpbmcgZXJyb3IgJWxkXG4iLAogICAgICAgICAgICAgICAgIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBoTW9kdWxlID0gKEhNT0RVTEUzMilNYXBWaWV3T2ZGaWxlKCBtYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggbWFwcGluZyApOwogICAgaWYgKCFoTW9kdWxlKQogICAgewogICAgICAgIFdBUk4oIHdpbjMyLCAiUEVfTG9hZEltYWdlOiBNYXBWaWV3T2ZGaWxlIGVycm9yICVsZFxuIiwKICAgICAgICAgICAgICAgICBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChQRV9IRUFERVIoaE1vZHVsZSktPlNpZ25hdHVyZSAhPSBJTUFHRV9OVF9TSUdOQVRVUkUpCiAgICB7CiAgICAgICAgV0FSTih3aW4zMiwiaW1hZ2UgZG9lc24ndCBoYXZlIFBFIHNpZ25hdHVyZSwgYnV0IDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICBQRV9IRUFERVIoaE1vZHVsZSktPlNpZ25hdHVyZSApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5NYWNoaW5lICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2KQogICAgewogICAgICAgIE1TRygiVHJ5aW5nIHRvIGxvYWQgUEUgaW1hZ2UgZm9yIHVuc3VwcG9ydGVkIGFyY2hpdGVjdHVyZSAoIik7CiAgICAgICAgc3dpdGNoIChQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTWFjaGluZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfVU5LTk9XTjogTVNHKCJVbmtub3duXG4iKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfSTg2MDogICAgTVNHKCJJODYwXG4iKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjMwMDA6ICAgTVNHKCJSMzAwMFxuIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1I0MDAwOiAgIE1TRygiUjQwMDBcbiIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMTAwMDA6ICBNU0coIlIxMDAwMFxuIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0FMUEhBOiAgIE1TRygiQWxwaGFcbiIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9QT1dFUlBDOiBNU0coIlBvd2VyUENcbiIpOyBicmVhazsKICAgICAgICBkZWZhdWx0OiBNU0coIlVua25vd24tJTA0eFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5NYWNoaW5lKTsgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICByZXR1cm4gaE1vZHVsZTsKCmVycm9yOgogICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGlzIG1hcHMgYSBsb2FkZWQgUEUgZGxsIGludG8gdGhlIGFkZHJlc3Mgc3BhY2Ugb2YgdGhlIHNwZWNpZmllZCBwcm9jZXNzLgogKi8Kc3RhdGljIEJPT0wzMiBQRV9NYXBJbWFnZSggUERCMzIgKnByb2Nlc3MsV0lORV9NT0RSRUYgKndtLCBPRlNUUlVDVCAqb2ZzLCBEV09SRCBmbGFncyApCnsKCVBFX01PRFJFRgkJKnBlbTsKCWludAkJCWksIHJlc3VsdDsKCURXT1JECQkJbG9hZF9hZGRyOwoJSU1BR0VfREFUQV9ESVJFQ1RPUlkJZGlyOwoJY2hhcgkJCSptb2RuYW1lOwoJaW50CQkJdm1hX3NpemU7CglITU9EVUxFMzIJCWhNb2R1bGUgPSB3bS0+bW9kdWxlOwoKICAgICAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VnOwogICAgICAgIElNQUdFX0RPU19IRUFERVIgKmRvc19oZWFkZXIgPSAoSU1BR0VfRE9TX0hFQURFUiAqKWhNb2R1bGU7CiAgICAgICAgSU1BR0VfTlRfSEVBREVSUyAqbnRfaGVhZGVyID0gUEVfSEVBREVSKGhNb2R1bGUpOwoJCglwZW0gCT0gJih3bS0+YmluZm10LnBlKTsKCglyZXN1bHQgPSBHZXRMb25nUGF0aE5hbWUzMkEob2ZzLT5zelBhdGhOYW1lLE5VTEwsMCk7Cgl3bS0+bG9uZ25hbWUgPSAoY2hhciopSGVhcEFsbG9jKHByb2Nlc3MtPmhlYXAsMCxyZXN1bHQrMSk7CglHZXRMb25nUGF0aE5hbWUzMkEob2ZzLT5zelBhdGhOYW1lLHdtLT5sb25nbmFtZSxyZXN1bHQrMSk7CgoJd20tPnNob3J0bmFtZSA9IEhFQVBfc3RyZHVwQShwcm9jZXNzLT5oZWFwLDAsb2ZzLT5zelBhdGhOYW1lKTsKCglpZiAoIShudF9oZWFkZXItPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpKQogICAgICAgIHsKCQlpZiAocHJvY2Vzcy0+ZXhlX21vZHJlZikKCQkJRklYTUUod2luMzIsIm92ZXJ3cml0aW5nIG9sZCBleGVfbW9kcmVmLi4uIGFycmdoXG4iKTsKCQlwcm9jZXNzLT5leGVfbW9kcmVmID0gd207Cgl9CgoJbG9hZF9hZGRyID0gbnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7Cgl2bWFfc2l6ZSA9IGNhbGNfdm1hX3NpemUoIGhNb2R1bGUgKTsKCVRSQUNFKHdpbjMyLCAiTG9hZCBhZGRyIGlzICVseFxuIixsb2FkX2FkZHIpOwoJbG9hZF9hZGRyID0gKERXT1JEKVZpcnR1YWxBbGxvYyggKHZvaWQqKWxvYWRfYWRkciwgdm1hX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKCWlmIChsb2FkX2FkZHIgPT0gMCkgewoJCWxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoIE5VTEwsIHZtYV9zaXplLAoJCQkJCQkgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAoJCQkJCQkgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwoJfQoJLyogTk9URTogdGhpcyBjaGFuZ2VzIGEgdmFsdWUgaW4gdGhlIHByb2Nlc3MgbW9kcmVmIGNoYWluLCB3aGljaCBjYW4KCSAqIGJlIGFjY2Vzc2VkIGluZGVwZW5kZW50bHkgZnJvbSB0aGlzIGZ1bmN0aW9uCgkgKi8KCXdtLT5tb2R1bGUgPSAoSE1PRFVMRTMyKWxvYWRfYWRkcjsKCglUUkFDRSh3aW4zMiwgIkxvYWQgYWRkciBpcyByZWFsbHkgJWx4LCByYW5nZSAleFxuIiwKICAgICAgICAgICAgICAgICAgICAgIGxvYWRfYWRkciwgdm1hX3NpemUpOwoKCVRSQUNFKHNlZ21lbnQsICJMb2FkaW5nICVzIGF0ICVseCwgcmFuZ2UgJXhcbiIsCiAgICAgICAgICAgICAgb2ZzLT5zelBhdGhOYW1lLCBsb2FkX2FkZHIsIHZtYV9zaXplICk7CgkKICAgICAgICAvKiBTdG9yZSB0aGUgTlQgaGVhZGVyIGF0IHRoZSBsb2FkIGFkZHIKICAgICAgICAgKiAoRklYTUU6IHNob3VsZCByZWFsbHkgdXNlIG1tYXApCiAgICAgICAgICovCiAgICAgICAgKihJTUFHRV9ET1NfSEVBREVSICopbG9hZF9hZGRyID0gKmRvc19oZWFkZXI7CiAgICAgICAgKihJTUFHRV9OVF9IRUFERVJTICopKGxvYWRfYWRkciArIGRvc19oZWFkZXItPmVfbGZhbmV3KSA9ICpudF9oZWFkZXI7CgogICAgICAgIHBlX3NlZyA9IFBFX1NFQ1RJT05TKGhNb2R1bGUpOwoJZm9yIChpID0gMDsgaSA8IG50X2hlYWRlci0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyssIHBlX3NlZysrKQoJewoJCS8qIG1lbWNweSBvbmx5IG5vbi1CU1Mgc2VnbWVudHMgKi8KCQkvKiBGSVhNRTogdGhpcyBzaG91bGQgYmUgZG9uZSBieSBtbWFwKC4uTUFQX1BSSVZBVEV8TUFQX0ZJWEVELi4pCgkJICogYnV0IGl0IGlzIG5vdCBwb3NzaWJsZSBmb3IgKGF0IGxlYXN0KSBMaW51eCBuZWVkcwoJCSAqIGEgcGFnZS1hbGlnbmVkIG9mZnNldC4KCQkgKi8KCQlpZighKHBlX3NlZy0+Q2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpKQoJCSAgICBtZW1jcHkoKGNoYXIqKVJWQShwZV9zZWctPlZpcnR1YWxBZGRyZXNzKSwKCQkgICAgCShjaGFyKikoaE1vZHVsZSArIHBlX3NlZy0+UG9pbnRlclRvUmF3RGF0YSksCgkJCXBlX3NlZy0+U2l6ZU9mUmF3RGF0YQoJCSAgICApOwoKCQlyZXN1bHQgPSBSVkEgKHBlX3NlZy0+VmlydHVhbEFkZHJlc3MpOwojaWYgMQoJCS8qIG5vdCBuZWVkZWQsIG1lbW9yeSBpcyB6ZXJvICovCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5ic3MiKSA9PSAwKQoJCSAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAoJCQkgICBwZV9zZWctPk1pc2MuVmlydHVhbFNpemUgPwoJCQkgICBwZV9zZWctPk1pc2MuVmlydHVhbFNpemUgOgoJCQkgICBwZV9zZWctPlNpemVPZlJhd0RhdGEpOwojZW5kaWYKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5pZGF0YSIpID09IDApCgkJCXBlbS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5lZGF0YSIpID09IDApCgkJCXBlbS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGVfc2VnLT5OYW1lLCAiLnJzcmMiKSA9PSAwKQoJCQlwZW0tPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIucmVsb2MiKSA9PSAwKQoJCQlwZW0tPnBlX3JlbG9jID0gKExQSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKSByZXN1bHQ7Cgl9CgoJLyogVGhlcmUgaXMgd29yZCB0aGF0IHRoZSBhY3R1YWwgbG9hZGVyIGRvZXMgbm90IGNhcmUgYWJvdXQgdGhlCgkgICBzZWN0aW9uIG5hbWVzLCBhbmQgb25seSBnb2VzIGZvciB0aGUgRGF0YURpcmVjdG9yeSAqLwoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlbS0+cGVfZXhwb3J0ICYmIChpbnQpcGVtLT5wZV9leHBvcnQhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlXQVJOKHdpbjMyLCJ3cm9uZyBleHBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCS8qIGFsd2F5cyB0cnVzdCB0aGUgZGlyZWN0b3J5ICovCgkJcGVtLT5wZV9leHBvcnQgPSAoTFBJTUFHRV9FWFBPUlRfRElSRUNUT1JZKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglkaXI9bnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlRdOwoJaWYoZGlyLlNpemUpCgl7CgkJLyogCgkJaWYocGVtLT5wZV9pbXBvcnQgJiYgKGludClwZW0tPnBlX2ltcG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCVdBUk4od2luMzIsIndyb25nIGltcG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJICovCgkJcGVtLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfUkVTT1VSQ0VdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGVtLT5wZV9yZXNvdXJjZSAmJiAoaW50KXBlbS0+cGVfcmVzb3VyY2UhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlXQVJOKHdpbjMyLCJ3cm9uZyByZXNvdXJjZSBkaXJlY3Rvcnk/P1xuIik7CgkJcGVtLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT05dLlNpemUpCgkJRklYTUUod2luMzIsIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWV0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCgoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlbS0+cGVfcmVsb2MgJiYgKGludClwZW0tPnBlX3JlbG9jIT0gUlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCVdBUk4od2luMzIsIndyb25nIHJlbG9jYXRpb24gbGlzdD8/XG4iKTsKCQlwZW0tPnBlX3JlbG9jID0gKHZvaWQgKikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT1BZUklHSFRdLlNpemUpCgkJRklYTUUod2luMzIsIkNvcHlyaWdodCBzdHJpbmcgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9HTE9CQUxQVFJdLlNpemUpCgkJRklYTUUod2luMzIsIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0xPQURfQ09ORklHXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQk9VTkRfSU1QT1JUXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJJbXBvcnQgQWRkcmVzcyBUYWJsZSBkaXJlY3RvcnkgaWdub3JlZFxuIik7CglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTNdLlNpemUpCgkJRklYTUUod2luMzIsIlVua25vd24gZGlyZWN0b3J5IDEzIGlnbm9yZWRcbiIpOwoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzE0XS5TaXplKQoJCUZJWE1FKHdpbjMyLCJVbmtub3duIGRpcmVjdG9yeSAxNCBpZ25vcmVkXG4iKTsKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNV0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiVW5rbm93biBkaXJlY3RvcnkgMTUgaWdub3JlZFxuIik7CgoJaWYocGVtLT5wZV9yZWxvYykJZG9fcmVsb2NhdGlvbnMod20pOwoJaWYocGVtLT5wZV9leHBvcnQpIHsKCQlkdW1wX2V4cG9ydHMod20tPm1vZHVsZSk7CgoJCXdtLT5tb2RuYW1lID0gSEVBUF9zdHJkdXBBKHByb2Nlc3MtPmhlYXAsMCwoY2hhciopUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKSk7Cgl9IGVsc2UgewoJCS8qIHRyeSB0byBmaW5kIG91dCB0aGUgbmFtZSBmcm9tIHRoZSBPRlNUUlVDVCAqLwoJCWNoYXIgKnM7CgkJbW9kbmFtZSA9IHMgPSBvZnMtPnN6UGF0aE5hbWU7CgkJd2hpbGUgKChzPXN0cmNocihtb2RuYW1lLCdcXCcpKSkKCQkJbW9kbmFtZSA9IHMrMTsKCQl3bS0+bW9kbmFtZSA9IEhFQVBfc3RyZHVwQShwcm9jZXNzLT5oZWFwLDAsbW9kbmFtZSk7Cgl9CglpZihwZW0tPnBlX2ltcG9ydCkJewoJCWlmIChmaXh1cF9pbXBvcnRzKHByb2Nlc3Msd20pKSB7CgkJCVdJTkVfTU9EUkVGCSoqeHdtOwoKCQkJLyogcmVtb3ZlIGVudHJ5IGZyb20gbW9kcmVmIGNoYWluICovCgkJCXh3bSA9ICYocHJvY2Vzcy0+bW9kcmVmX2xpc3QpOwoJCQl3aGlsZSAoKnh3bSkgewoJCQkJaWYgKCp4d209PXdtKSB7CgkJCQkJKnh3bSA9IHdtLT5uZXh0OwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJeHdtID0gJigoKnh3bSktPm5leHQpOwoJCQl9CgkJCS8qIEZJWE1FOiB0aGVyZSBhcmUgc2V2ZXJhbCBtb3JlIGRhbmdsaW5nIHJlZmVyZW5jZXMKCQkJICogbGVmdC4gSW5jbHVkaW5nIGRsbHMgbG9hZGVkIGJ5IHRoaXMgZGxsIGJlZm9yZSB0aGUKCQkJICogZmFpbGVkIG9uZS4gVW5yb2xsaW5nIGlzIHJhdGhlciBkaWZmaWN1bHQgd2l0aCB0aGUKCQkJICogY3VycmVudCBzdHJ1Y3R1cmUgYW5kIHdlIGNhbiBsZWF2ZSBpdCB0aGVtIGx5aW5nCgkJCSAqIGFyb3VuZCB3aXRoIG5vIHByb2JsZW1zLCBzbyB3ZSBkb24ndCBjYXJlCgkJCSAqLwoJCQlyZXR1cm4gMDsKCQl9Cgl9CiAgCQkKICAgICAgICAvKiBOb3cgdGhhdCB3ZSBnb3QgZXZlcnl0aGluZyBhdCB0aGUgcmlnaHQgYWRkcmVzcywKICAgICAgICAgKiB3ZSBjYW4gdW5tYXAgdGhlIHByZXZpb3VzIG1vZHVsZSAqLwogICAgICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICAgICAgcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIFBFIExpYnJhcnkgTG9hZGVyIGZyb250ZW5kLiAKICogRklYTUU6IGhhbmRsZSB0aGUgZmxhZ3MuCiAqICAgICAgICBpbnRlcm5hbCBtb2R1bGUgaGFuZGxpbmcgc2hvdWxkIGJlIG1hZGUgYmV0dGVyIGhlcmUgKGFuZCBpbiBidWlsdGluLmMpCiAqLwpITU9EVUxFMzIgUEVfTG9hZExpYnJhcnlFeDMyQSAoTFBDU1RSIG5hbWUsIFBEQjMyICpwcm9jZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEZJTEUzMiBoRmlsZSwgRFdPUkQgZmxhZ3MpCnsKCU9GU1RSVUNUCW9mczsKCUhNT0RVTEUzMgloTW9kdWxlOwoJTkVfTU9EVUxFCSpwTW9kdWxlOwoJV0lORV9NT0RSRUYJKndtOwoKCWlmICgoaE1vZHVsZSA9IE1PRFVMRV9GaW5kTW9kdWxlMzIoIHByb2Nlc3MsIG5hbWUgKSkpIHsKCQlmb3IgKHdtPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkKCQkJaWYgKHdtLT5tb2R1bGUgPT0gaE1vZHVsZSkKCQkJCXJldHVybiBoTW9kdWxlOwoJCS8qIFNpbmNlIE1PRFVMRV9GaW5kTW9kdWxlMzIgdXNlcyB0aGUgbW9kcmVmIGNoYWluIHRvbywgdGhlCgkJICogbW9kdWxlIE1VU1QgaGF2ZSBiZWVuIGZvdW5kIGFib3ZlLiBJZiBub3QsIHNvbWV0aGluZyBoYXMgZ29uZQoJCSAqIHRlcnJpYmx5IHdyb25nLgoJCSAqLwoJCWFzc2VydCgwKTsKCX0KCS8qIHRyeSB0byBsb2FkIGJ1aWx0aW4sIGVuYWJsZWQgbW9kdWxlcyBmaXJzdCAqLwoJaWYgKChoTW9kdWxlID0gQlVJTFRJTjMyX0xvYWRNb2R1bGUoIG5hbWUsIEZBTFNFLCBwcm9jZXNzICkpKQoJICAgIHJldHVybiBoTW9kdWxlOwoKCS8qIHRyeSB0byBsb2FkIHRoZSBzcGVjaWZpZWQgZGxsL2V4ZSAqLwoJaWYgKEhGSUxFX0VSUk9SMzI9PShoRmlsZT1PcGVuRmlsZTMyKG5hbWUsJm9mcyxPRl9SRUFEKSkpIHsKCQkvKiBOb3cgdHJ5IHRoZSBidWlsdC1pbiBldmVuIGlmIGRpc2FibGVkICovCgkJaWYgKChoTW9kdWxlID0gQlVJTFRJTjMyX0xvYWRNb2R1bGUoIG5hbWUsIFRSVUUsIHByb2Nlc3MgKSkpIHsKCQkgICAgV0FSTiggbW9kdWxlLCAiQ291bGQgbm90IGxvYWQgZXh0ZXJuYWwgRExMICclcycsIHVzaW5nIGJ1aWx0LWluIG1vZHVsZS5cbiIsIG5hbWUgKTsKCQkgICAgcmV0dXJuIGhNb2R1bGU7CgkJfQoJCXJldHVybiAxOwoJfQoJLyogd2lsbCBnbyBhd2F5IC4uLiAqLwoJaWYgKChoTW9kdWxlID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCAmb2ZzICkpIDwgMzIpIHsKCQlfbGNsb3NlMzIoaEZpbGUpOwoJCXJldHVybiBoTW9kdWxlOwoJfQoJcE1vZHVsZSAgICAgICAgID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZSApOwoJcE1vZHVsZS0+ZmxhZ3MgID0gTkVfRkZMQUdTX1dJTjMyOwoJLyogLi4gKi8KCgl3bT0oV0lORV9NT0RSRUYqKUhlYXBBbGxvYyhwcm9jZXNzLT5oZWFwLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKCp3bSkpOwoJd20tPnR5cGUgPSBNT0RVTEUzMl9QRTsKCS8qIE5PVEU6IGZpeHVwX2ltcG9ydHMgdGFrZXMgY2FyZSBvZiB0aGUgY29ycmVjdCBvcmRlciAqLwoJd20tPm5leHQgPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCXByb2Nlc3MtPm1vZHJlZl9saXN0ID0gd207CgoJd20tPm1vZHVsZSA9IHBNb2R1bGUtPm1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSApOwoKCUNsb3NlSGFuZGxlKCBoRmlsZSApOwogICAgICAgIGlmICh3bS0+bW9kdWxlIDwgMzIpIAogICAgICAgIHsKCSAgICBwcm9jZXNzLT5tb2RyZWZfbGlzdCA9IHdtLT5uZXh0OwoJICAgIEhlYXBGcmVlKHByb2Nlc3MtPmhlYXAsMCx3bSk7CgkgICAgRVJSKHdpbjMyLCJjYW4ndCBsb2FkICVzXG4iLG9mcy5zelBhdGhOYW1lKTsKICAgICAgICAgICAgcmV0dXJuIDIxOyAvKiBGSVhNRTogcHJvYmFibHkgMCAqLwogICAgICAgIH0KCgkvKiAocG9zc2libGUpIHJlY3Vyc2lvbiAqLwoJaWYgKCFQRV9NYXBJbWFnZShwcm9jZXNzLHdtLCZvZnMsZmxhZ3MpKSB7CgkgICAgLyogRVJST1IgY2xlYW51cCAuLi4gKi8KCSAgICBXSU5FX01PRFJFRgkqKnh3bTsKCgkgICAgRVJSKHdpbjMyLCJjb3VsZG4ndCBsb2FkICVzXG4iLG9mcy5zelBhdGhOYW1lKTsKCSAgICAvKiB1bmxpbmsgZnJvbSBwcm9jZXNzIG1vZHJlZiBjaGFpbiAqLwoJICAgIGZvciAoICAgIHh3bT0mKHByb2Nlc3MtPm1vZHJlZl9saXN0KTsKCQkgICAgICp4d20gJiYgKCp4d20hPXdtKTsKCQkgICAgIHh3bT0mKCgqeHdtKS0+bmV4dCkKCSAgICApIC8qIEVNUFRZICovOwoJICAgIGlmICgqeHdtKQoJICAgIAkqeHdtPSgqeHdtKS0+bmV4dDsKCSAgICAJCgkgICAgcmV0dXJuIDA7Cgl9CiAgICAgICAgcE1vZHVsZS0+bW9kdWxlMzIgPSB3bS0+bW9kdWxlOwoJcmV0dXJuIHdtLT5tb2R1bGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBMb2FkIHRoZSBQRSBtYWluIC5FWEUuIEFsbCBvdGhlciBsb2FkaW5nIGlzIGRvbmUgYnkgUEVfTG9hZExpYnJhcnlFeDMyQQogKiBGSVhNRTogdGhpcyBmdW5jdGlvbiBzaG91bGQgdXNlIFBFX0xvYWRMaWJyYXJ5RXgzMkEsIGJ1dCBjdXJyZW50bHkgY2FuJ3QKICogZHVlIHRvIHRoZSBQUk9DRVNTX0NyZWF0ZSBzdHVmZi4KICovCkhJTlNUQU5DRTE2IFBFX0xvYWRNb2R1bGUoIExQQ1NUUiBuYW1lLCBMUENTVFIgY21kX2xpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBlbnYsIFVJTlQxNiBzaG93X2NtZCApCnsKICAgIEhNT0RVTEUxNiBoTW9kdWxlMTY7CiAgICBITU9EVUxFMzIgaE1vZHVsZTMyOwogICAgSElOU1RBTkNFMTYgaEluc3RhbmNlOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgSEZJTEUzMiBoRmlsZTsKICAgIE9GU1RSVUNUIG9mczsKICAgIFRIREIgKnRoZGIgPSBUSFJFQURfQ3VycmVudCgpOwogICAgUERCMzIgKnByb2Nlc3M7CiAgICBXSU5FX01PRFJFRgkqd207CgogICAgaWYgKChoRmlsZSA9IE9wZW5GaWxlMzIoIG5hbWUsICZvZnMsIE9GX1JFQUQgKSkgPT0gSEZJTEVfRVJST1IzMikKICAgICAgICByZXR1cm4gMjsgIC8qIEZpbGUgbm90IGZvdW5kICovCgogICAgaWYgKChoTW9kdWxlMTYgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoICZvZnMgKSkgPCAzMikgcmV0dXJuIGhNb2R1bGUxNjsKICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlMTYgKTsKICAgIHBNb2R1bGUtPmZsYWdzID0gTkVfRkZMQUdTX1dJTjMyOwoKICAgIHBNb2R1bGUtPm1vZHVsZTMyID0gaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSApOwogICAgaWYgKGhNb2R1bGUzMiA8IDMyKSByZXR1cm4gMjE7CgogICAgaEluc3RhbmNlID0gTkVfQ3JlYXRlSW5zdGFuY2UoIHBNb2R1bGUsIE5VTEwsIChjbWRfbGluZSA9PSBOVUxMKSApOwogICAgaWYgKGNtZF9saW5lICYmCiAgICAgICAgIShQRV9IRUFERVIoaE1vZHVsZTMyKS0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgUERCMzIgKnBkYiA9IFBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRfbGluZSwgZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEluc3RhbmNlLCAwLCBzaG93X2NtZCApOwogICAgICAgIFREQiAqcFRhc2sgPSAoVERCICopR2xvYmFsTG9jazE2KCBwZGItPnRhc2sgKTsKICAgICAgICB0aGRiID0gcFRhc2stPnRoZGI7CiAgICB9CgogICAgcHJvY2VzcyA9IHRoZGItPnByb2Nlc3M7CgogICAgd209KFdJTkVfTU9EUkVGKilIZWFwQWxsb2MocHJvY2Vzcy0+aGVhcCxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZigqd20pKTsKICAgIHdtLT50eXBlID0gTU9EVUxFMzJfUEU7CiAgICAvKiBOT1RFOiBmaXh1cF9pbXBvcnRzIHRha2VzIGNhcmUgb2YgdGhlIGNvcnJlY3Qgb3JkZXIgKi8KICAgIHdtLT5uZXh0ID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7CiAgICB3bS0+bW9kdWxlID0gaE1vZHVsZTMyOwogICAgcHJvY2Vzcy0+bW9kcmVmX2xpc3QgPSB3bTsKICAgIGlmICghUEVfTWFwSW1hZ2UoIHByb2Nlc3MsIHdtLCAmb2ZzLCAwICkpCiAgICB7CiAgICAgCS8qIEZJWE1FOiBzaG91bGQgZGVzdHJveSB0aGUgdGFzayBjcmVhdGVkIGFuZCBmcmVlIHJlZmVyZW5jZWQgc3R1ZmYgKi8KICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIHBNb2R1bGUtPm1vZHVsZTMyID0gd20tPm1vZHVsZTsKICAgIC8qIEZJWE1FOiBZdWNrLiBJcyB0aGVyZSBubyBvdGhlciBnb29kIHBsYWNlIHRvIGRvIHRoYXQ/ICovCiAgICBQRV9Jbml0VGxzKCB0aGRiICk7CiAgICByZXR1cm4gaEluc3RhbmNlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBFX1VubG9hZEltYWdlIFtpbnRlcm5hbF0KICovCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRTMyIGhNb2R1bGUgKQp7CglGSVhNRSh3aW4zMiwic3R1Yi5cbiIpOwoJLyogZnJlZSByZXNvdXJjZXMsIGltYWdlLCB1bm1hcCAqLwoJcmV0dXJuIDE7Cn0KCi8qIENhbGxlZCBpZiB0aGUgbGlicmFyeSBpcyBsb2FkZWQgb3IgZnJlZWQuCiAqIE5PVEU6IGlmIGEgdGhyZWFkIGF0dGFjaGVzIGEgRExMLCB0aGUgY3VycmVudCB0aHJlYWQgd2lsbCBvbmx5IGRvCiAqIERMTF9QUk9DRVNTX0FUVEFDSC4gT25seSBuZXcgY3JlYXRlZCB0aHJlYWRzIGRvIERMTF9USFJFQURfQVRUQUNICiAqIChTREspCiAqLwpzdGF0aWMgdm9pZCBQRV9Jbml0RExMKFdJTkVfTU9EUkVGICp3bSwgRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewogICAgaWYgKHdtLT50eXBlIT1NT0RVTEUzMl9QRSkKICAgIAlyZXR1cm47CiAgICBpZiAodHlwZT09RExMX1BST0NFU1NfQVRUQUNIKQoJd20tPmJpbmZtdC5wZS5mbGFncyB8PSBQRV9NT0RSRUZfUFJPQ0VTU19BVFRBQ0hFRDsKCiAgICAvKiAgRExMX0FUVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBmb3IgZHluYW1pYyBsb2Fkcywgbm90LU5VTEwgZm9yIHN0YXRpYyBsb2FkcwogICAgICogIERMTF9ERVRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgaWYgY2FsbGVkIGJ5IEZyZWVMaWJyYXJ5LCBub3QtTlVMTCBvdGhlcndpc2UKICAgICAqICB0aGUgU0RLIGRvZXNuJ3QgbWVudGlvbiBhbnl0aGluZyBmb3IgRExMX1RIUkVBRF8qCiAgICAgKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKChQRV9IRUFERVIod20tPm1vZHVsZSktPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCiAgICAgICAgKFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIEZBUlBST0MzMiBlbnRyeSA9IChGQVJQUk9DMzIpUlZBX1BUUiggd20tPm1vZHVsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCApOwogICAgICAgIFRSQUNFKHJlbGF5LCAiQ2FsbFRvMzIoZW50cnlwcm9jPSVwLG1vZHVsZT0lMDh4LHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIHdtLT5tb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgICAgICBlbnRyeSggd20tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgfQp9CgovKiBDYWxsIHRoZSBETExlbnRyeSBmdW5jdGlvbiBvZiBhbGwgZGxscyB1c2VkIGJ5IHRoYXQgcHJvY2Vzcy4KICogKE5PVEU6IHRoaXMgbWF5IHJlY3Vyc2l2ZWx5IGNhbGwgdGhpcyBmdW5jdGlvbiAoaWYgYSBsaWJyYXJ5IGNhbGxzCiAqIExvYWRMaWJyYXJ5KSAuLi4gYnV0IGl0IHdvbid0IG1hdHRlcikKICovCnZvaWQgUEVfSW5pdGlhbGl6ZURMTHMoUERCMzIgKnByb2Nlc3MsRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkgewoJV0lORV9NT0RSRUYJKndtOwoKCWZvciAod20gPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkgewoJCVBFX01PRFJFRgkqcGVtID0gTlVMTDsKCQlpZiAod20tPnR5cGUhPU1PRFVMRTMyX1BFKQoJCQljb250aW51ZTsKCQlwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwoJCWlmIChwZW0tPmZsYWdzICYgUEVfTU9EUkVGX05PX0RMTF9DQUxMUykKCQkJY29udGludWU7CgkJaWYgKHR5cGU9PURMTF9QUk9DRVNTX0FUVEFDSCkgewoJCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9QUk9DRVNTX0FUVEFDSEVEKQoJCQkJY29udGludWU7CgkJfQoJCVBFX0luaXRETEwoIHdtLCB0eXBlLCBscFJlc2VydmVkICk7Cgl9Cn0KCnZvaWQgUEVfSW5pdFRscyhUSERCICp0aGRiKQp7CglXSU5FX01PRFJFRgkJKndtOwoJUEVfTU9EUkVGCQkqcGVtOwoJSU1BR0VfTlRfSEVBREVSUwkqcGVoOwoJRFdPUkQJCQlzaXplLGRhdGFzaXplOwoJTFBWT0lECQkJbWVtOwoJTFBJTUFHRV9UTFNfRElSRUNUT1JZCXBkaXI7CglQREIzMgkJCSpwZGIgPSB0aGRiLT5wcm9jZXNzOwogICAgICAgIGludCBkZWx0YTsKCQoJZm9yICh3bSA9IHBkYi0+bW9kcmVmX2xpc3Q7d207d209d20tPm5leHQpIHsKCQlpZiAod20tPnR5cGUhPU1PRFVMRTMyX1BFKQoJCQljb250aW51ZTsKCQlwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwoJCXBlaCA9IFBFX0hFQURFUih3bS0+bW9kdWxlKTsKCQlkZWx0YSA9IHdtLT5tb2R1bGUgLSBwZWgtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCQlpZiAoIXBlaC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykKCQkJY29udGludWU7CgkJcGRpciA9IChMUFZPSUQpKHdtLT5tb2R1bGUgKyBwZWgtPk9wdGlvbmFsSGVhZGVyLgoJCQlEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKCQkKCQkKCQlpZiAoIShwZW0tPmZsYWdzICYgUEVfTU9EUkVGX1RMU19BTExPQ0VEKSkgewoJCQlwZW0tPnRsc2luZGV4ID0gVEhSRUFEX1Rsc0FsbG9jKHRoZGIpOwoJCQkqKExQRFdPUkQpQWRqdXN0UHRyKHBkaXItPkFkZHJlc3NPZkluZGV4LGRlbHRhKQoJCQkgID1wZW0tPnRsc2luZGV4OyAgIAoJCX0KCQlwZW0tPmZsYWdzIHw9IFBFX01PRFJFRl9UTFNfQUxMT0NFRDsKCQlkYXRhc2l6ZT0gcGRpci0+RW5kQWRkcmVzc09mUmF3RGF0YS1wZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGE7CgkJc2l6ZQk9IGRhdGFzaXplICsgcGRpci0+U2l6ZU9mWmVyb0ZpbGw7CgkJbWVtPVZpcnR1YWxBbGxvYygwLHNpemUsTUVNX1JFU0VSVkV8TUVNX0NPTU1JVCxQQUdFX1JFQURXUklURSk7CgkJbWVtY3B5KG1lbSwKCQkgICAgICAgQWRqdXN0UHRyKHBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSxkZWx0YSksIAoJCSAgICAgICBkYXRhc2l6ZSk7CgoJCS8qIGRvbid0IHVzZSBUbHNTZXRWYWx1ZSwgd2UgYXJlIGluIHRoZSB3cm9uZyB0aHJlYWQgKi8KCQlpZiAocGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKSB7CgkJICAgICBMUElNQUdFX1RMU19DQUxMQkFDSyAqY2JzID0gCgkJICAgICAgIChMUElNQUdFX1RMU19DQUxMQkFDSyAqKQoJCSAgICAgICBBZGp1c3RQdHIocGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzLCBkZWx0YSk7CgoJCSAgICAgaWYgKCpjYnMpIHsKCQkgICAgICAgRklYTUUod2luMzIsICJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCSAgICAgfQoJCX0KCQl0aGRiLT50bHNfYXJyYXlbcGVtLT50bHNpbmRleF0gPSBtZW07Cgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzIChLRVJORUwzMi43NCkKICogRG9uJ3QgY2FsbCBEbGxFbnRyeVBvaW50IGZvciBETExfVEhSRUFEX3tBVFRBQ0gsREVUQUNIfSBpZiBzZXQuCiAqLwpCT09MMzIgV0lOQVBJIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoSE1PRFVMRTMyIGhNb2R1bGUpCnsKCVdJTkVfTU9EUkVGCSp3bTsKCglmb3IgKHdtPVBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkKCQlpZiAoKHdtLT5tb2R1bGUgPT0gaE1vZHVsZSkgJiYgKHdtLT50eXBlPT1NT0RVTEUzMl9QRSkpCgkJCXdtLT5iaW5mbXQucGUuZmxhZ3N8PVBFX01PRFJFRl9OT19ETExfQ0FMTFM7CglyZXR1cm4gVFJVRTsKfQo=