LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gTm8sIHlvdSAodXN1YWxseSkgY2Fubm90IHVzZSBMaW51eCBtbWFwKCkgdG8gbW1hcCgpIHRoZSBpbWFnZXMgZGlyZWN0bHkuCiAqCiAqICAgVGhlIHByb2JsZW0gaXMsIHRoYXQgdGhlcmUgaXMgbm90IGRpcmVjdCAxOjEgbWFwcGluZyBmcm9tIGEgZGlza2ltYWdlIGFuZAogKiAgIGEgbWVtb3J5aW1hZ2UuIFRoZSBoZWFkZXJzIGF0IHRoZSBzdGFydCBhcmUgbWFwcGVkIGxpbmVhciwgYnV0IHRoZSBzZWN0aW9ucwogKiAgIGFyZSBub3QuIEZvciB4ODYgdGhlIHNlY3Rpb25zIGFyZSA1MTIgYnl0ZSBhbGlnbmVkIGluIGZpbGUgYW5kIDQwOTYgYnl0ZQogKiAgIGFsaWduZWQgaW4gbWVtb3J5LiBMaW51eCBsaWtlcyB0aGVtIDQwOTYgYnl0ZSBhbGlnbmVkIGluIG1lbW9yeSAoZHVlIHRvCiAqICAgeDg2IHBhZ2VzaXplLCB0aGlzIGNhbm5vdCBiZSBmaXhlZCB3aXRob3V0IGEgcmF0aGVyIGxhcmdlIGtlcm5lbCByZXdyaXRlKQogKiAgIGFuZCAnYmxvY2tzaXplJyBmaWxlLWFsaWduZWQgKG9mZnNldHMpLiBTaW5jZSB3ZSBoYXZlIDUxMi8xMDI0LzIwNDggKENEUk9NKQogKiAgIGFuZCBvdGhlciBieXRlIGJsb2Nrc2l6ZXMsIHdlIGNhbid0IGRvIHRoaXMuIEhvd2V2ZXIsIHRoaXMgY291bGQgYmUgbGVzcwogKiAgIGRpZmZpY3VsdCB0byBzdXBwb3J0Li4uIChTZWUgbW0vZmlsZW1hcC5jKS4KICogLSBBbGwgdGhvc2UgZnVuY3Rpb24gbWFwIHRoaW5ncyBpbnRvIGEgbmV3IGFkZHJlc3NwYWNlLiBGcm9tIHRoZSB3cm9uZwogKiAgIHByb2Nlc3MgYW5kIHRoZSB3cm9uZyB0aHJlYWQuIFNvIGNhbGxpbmcgb3RoZXIgQVBJIGZ1bmN0aW9ucyB3aWxsIG1lc3MgCiAqICAgdGhpbmdzIHVwIGJhZGx5IHNvbWV0aW1lcy4KICovCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAicGVfaW1hZ2UuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgoKc3RhdGljIHZvaWQgUEVfSW5pdERMTChXSU5FX01PRFJFRiAqd20sIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkKTsKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodW5zaWduZWQgaW50KWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkKCiNkZWZpbmUgQWRqdXN0UHRyKHB0cixkZWx0YSkgKChjaGFyICopKHB0cikgKyAoZGVsdGEpKQoKdm9pZCBkdW1wX2V4cG9ydHMoIEhNT0RVTEUzMiBoTW9kdWxlICkKeyAKICBjaGFyCQkqTW9kdWxlOwogIGludAkJaSwgajsKICB1X3Nob3J0CSpvcmRpbmFsOwogIHVfbG9uZwkqZnVuY3Rpb24sKmZ1bmN0aW9uczsKICB1X2NoYXIJKipuYW1lOwogIHVuc2lnbmVkIGludCBsb2FkX2FkZHIgPSBoTW9kdWxlOwoKICBEV09SRCBydmFfc3RhcnQgPSBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5WaXJ0dWFsQWRkcmVzczsKICBEV09SRCBydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uU2l6ZTsKICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnRzID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkqKVJWQShydmFfc3RhcnQpOwoKICBNb2R1bGUgPSAoY2hhciopUlZBKHBlX2V4cG9ydHMtPk5hbWUpOwogIFRSQUNFKHdpbjMyLCIqKioqKioqRVhQT1JUIERBVEEqKioqKioqXG4iKTsKICBUUkFDRSh3aW4zMiwiTW9kdWxlIG5hbWUgaXMgJXMsICVsZCBmdW5jdGlvbnMsICVsZCBuYW1lc1xuIiwgCgkgICAgICAgTW9kdWxlLCBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBUUkFDRSh3aW4zMiwiIE9yZCAgICBSVkEgICAgIEFkZHIgICBOYW1lXG4iICk7CiAgZm9yIChpPTA7aTxwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucztpKyssIGZ1bmN0aW9uKyspCiAgewogICAgICBpZiAoISpmdW5jdGlvbikgY29udGludWU7ICAvKiBObyBzdWNoIGZ1bmN0aW9uICovCiAgICAgIGlmIChUUkFDRV9PTih3aW4zMikpewoJZGJnX2RlY2xfc3RyKHdpbjMyLCAxMDI0KTsKCglkc3ByaW50Zih3aW4zMiwiJTRsZCAlMDhseCAlMDh4IiwKCQkgaSArIHBlX2V4cG9ydHMtPkJhc2UsICpmdW5jdGlvbiwgUlZBKCpmdW5jdGlvbikgKTsKCS8qIENoZWNrIGlmIHdlIGhhdmUgYSBuYW1lIGZvciBpdCAqLwoJZm9yIChqID0gMDsgaiA8IHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXM7IGorKykKICAgICAgICAgIGlmIChvcmRpbmFsW2pdID09IGkpCgkgICAgZHNwcmludGYod2luMzIsICIgICVzIiwgKGNoYXIqKVJWQShuYW1lW2pdKSApOwoJaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9lbmQpKQoJICBkc3ByaW50Zih3aW4zMiwgIiAoZm9yd2FyZGVkIC0+ICVzKSIsIChjaGFyICopUlZBKCpmdW5jdGlvbikpOwoJVFJBQ0Uod2luMzIsIiVzXG4iLCBkYmdfc3RyKHdpbjMyKSk7CiAgICAgIH0KICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnRsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgTmFtZSBsaXN0LiAKICoJLSBsb29rIHVwIHRoZSBvcmRpbmFsIHdpdGggdGhhdCBpbmRleC4KICoJLSB1c2UgdGhlIG9yZGluYWwgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKiBJZiBpdCBpcyBhIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICovCkZBUlBST0MzMiBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggCglQREIzMiAqcHJvY2VzcywJCS8qIFtpbl0gcHJvY2VzcyBjb250ZXh0ICovCglXSU5FX01PRFJFRiAqd20sCS8qIFtpbl0gV0lORSBtb2RyZWZlcmVuY2UgKi8KCUxQQ1NUUiBmdW5jTmFtZSApCS8qIFtpbl0gZnVuY3Rpb24gbmFtZSAqLwp7Cgl1X3Nob3J0CQkJCSogb3JkaW5hbDsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZTsKCWludAkJCQlpOwoJUEVfTU9EUkVGCQkJKnBlbSA9ICYod20tPmJpbmZtdC5wZSk7CglJTUFHRV9FWFBPUlRfRElSRUNUT1JZIAkJKmV4cG9ydHMgPSBwZW0tPnBlX2V4cG9ydDsKCXVuc2lnbmVkIGludAkJCWxvYWRfYWRkciA9IHdtLT5tb2R1bGU7Cgl1X2xvbmcJCQkJcnZhX3N0YXJ0LCBydmFfZW5kLCBhZGRyOwoJY2hhcgkJCQkqIGZvcndhcmQ7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJVFJBQ0Uod2luMzIsIiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCVRSQUNFKHdpbjMyLCIoJWQpXG4iLChpbnQpZnVuY05hbWUpOwoJaWYgKCFleHBvcnRzKSB7CgkJLyogTm90IGEgZmF0YWwgcHJvYmxlbSwgc29tZSBhcHBzIGRvCgkJICogR2V0UHJvY0FkZHJlc3MoMCwiUmVnaXN0ZXJQZW5BcHAiKSB3aGljaCB0cmlnZ2VycyB0aGlzCgkJICogY2FzZS4KCQkgKi8KCQlXQVJOKHdpbjMyLCJNb2R1bGUgJTA4eCglcykvTU9EUkVGICVwIGRvZXNuJ3QgaGF2ZSBhIGV4cG9ydHMgdGFibGUuXG4iLHdtLT5tb2R1bGUsd20tPm1vZG5hbWUscGVtKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW9yZGluYWwJPSAodV9zaG9ydCopICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSAodV9sb25nKikgICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUJPSAodV9jaGFyICoqKSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yd2FyZCA9IE5VTEw7CglydmFfc3RhcnQgPSBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CglydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpIHsKCQlmb3IoaT0wOyBpPGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykgewoJCQllbmFtZT0oY2hhciopUlZBKCpuYW1lKTsKCQkJaWYoIXN0cmNtcChlbmFtZSxmdW5jTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHIgPSBmdW5jdGlvblsqb3JkaW5hbF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFkZHIpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKEZBUlBST0MzMilSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3J3YXJkID0gKGNoYXIgKilSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCQkJfQoJCQlvcmRpbmFsKys7CgkJCW5hbWUrKzsKCQl9Cgl9IGVsc2UgewoJCWlmIChMT1dPUkQoZnVuY05hbWUpLWV4cG9ydHMtPkJhc2UgPiBleHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucykgewoJCQlUUkFDRSh3aW4zMiwiCW9yZGluYWwgJWQgb3V0IG9mIHJhbmdlIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT1dPUkQoZnVuY05hbWUpKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoJCWFkZHIgPSBmdW5jdGlvblsoaW50KWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2VdOwogICAgICAgICAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKCQlpZiAoKGFkZHIgPCBydmFfc3RhcnQpIHx8IChhZGRyID49IHJ2YV9lbmQpKQoJCQlyZXR1cm4gKEZBUlBST0MzMilSVkEoYWRkcik7CgkJZm9yd2FyZCA9IChjaGFyICopUlZBKGFkZHIpOwoJfQoJaWYgKGZvcndhcmQpCiAgICAgICAgewogICAgICAgICAgICAgICAgSE1PRFVMRTMyIGhNb2Q7CgkJY2hhciBtb2R1bGVbMjU2XTsKCQljaGFyICplbmQgPSBzdHJjaHIoZm9yd2FyZCwgJy4nKTsKCgkJaWYgKCFlbmQpIHJldHVybiBOVUxMOwoJCWFzc2VydChlbmQtZm9yd2FyZDwyNTYpOwoJCXN0cm5jcHkobW9kdWxlLCBmb3J3YXJkLCAoZW5kIC0gZm9yd2FyZCkpOwoJCW1vZHVsZVtlbmQtZm9yd2FyZF0gPSAwOwogICAgICAgICAgICAgICAgaE1vZCA9IE1PRFVMRV9GaW5kTW9kdWxlMzIocHJvY2Vzcyxtb2R1bGUpOwoJCWFzc2VydChoTW9kKTsKCQlyZXR1cm4gTU9EVUxFX0dldFByb2NBZGRyZXNzMzIoIHByb2Nlc3MsIGhNb2QsIGVuZCArIDEpOwoJfQoJcmV0dXJuIE5VTEw7Cn0KCkRXT1JEIGZpeHVwX2ltcG9ydHMgKFBEQjMyICpwcm9jZXNzLFdJTkVfTU9EUkVGICp3bSkKewogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IJKnBlX2ltcDsKICAgIFdJTkVfTU9EUkVGCQkJKnh3bTsKICAgIFBFX01PRFJFRgkJCSpwZW07CiAgICBpbnQJZml4dXBfZmFpbGVkCQk9IDA7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyCT0gd20tPm1vZHVsZTsKICAgIGludAkJCQlpOwogICAgY2hhcgkJCSptb2RuYW1lOwogICAgCiAgICBhc3NlcnQod20tPnR5cGU9PU1PRFVMRTMyX1BFKTsKICAgIHBlbSA9ICYod20tPmJpbmZtdC5wZSk7CiAgICBpZiAocGVtLT5wZV9leHBvcnQpCiAgICAJbW9kbmFtZSA9IChjaGFyKikgUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKTsKICAgIGVsc2UKICAgICAgICBtb2RuYW1lID0gIjx1bmtub3duPiI7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgVFJBQ0Uod2luMzIsICJEdW1waW5nIGltcG9ydHMgbGlzdFxuIik7CgogICAgLyogZmlyc3QsIGNvdW50IHRoZSBudW1iZXIgb2YgaW1wb3J0ZWQgbm9uLWludGVybmFsIG1vZHVsZXMgKi8KICAgIHBlX2ltcCA9IHBlbS0+cGVfaW1wb3J0OwogICAgaWYgKCFwZV9pbXApIAogICAgCUVSUih3aW4zMiwgIm5vIGltcG9ydCBkaXJlY3Rvcnk/Pz8/XG4iKTsKCiAgICAvKiBGSVhNRTogc2hvdWxkIHRlcm1pbmF0ZSBvbiAwIENoYXJhY3RlcmlzdGljcyAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lOyBwZV9pbXArKykKCWkrKzsKCiAgICAvKiBsb2FkIHRoZSBpbXBvcnRlZCBtb2R1bGVzLiBUaGV5IGFyZSBhdXRvbWF0aWNhbGx5IAogICAgICogYWRkZWQgdG8gdGhlIG1vZHJlZiBsaXN0IG9mIHRoZSBwcm9jZXNzLgogICAgICovCiAKICAgIC8qIEZJWE1FOiBzaG91bGQgdGVybWluYXRlIG9uIDAgQ2hhcmFjdGVyaXN0aWNzICovCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsgcGVfaW1wLT5OYW1lOyBwZV9pbXArKykgewogICAgCUhNT0RVTEUzMglyZXM7CglXSU5FX01PRFJFRgkqKnl3bTsKIAljaGFyCQkqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoKCS8qIGRvbid0IHVzZSBNT0RVTEVfTG9hZCwgV2luMzIgY3JlYXRlcyBuZXcgdGFzayBkaWZmZXJlbnRseSAqLwoJcmVzID0gUEVfTG9hZExpYnJhcnlFeDMyQSggbmFtZSwgcHJvY2VzcywgMCwgMCApOwoJaWYgKHJlcyA8PSAoSE1PRFVMRTMyKSAzMikgewoJICAgIGNoYXIgKnAsYnVmZmVyWzIwMDBdOwoJICAgIAoJICAgIC8qIEdldE1vZHVsZUZpbGVOYW1lIHdvdWxkIHVzZSB0aGUgd3JvbmcgcHJvY2Vzcywgc28gZG9uJ3QgdXNlIGl0ICovCgkgICAgc3RyY3B5KGJ1ZmZlcix3bS0+c2hvcnRuYW1lKTsKCSAgICBpZiAoIShwID0gc3RycmNociAoYnVmZmVyLCAnXFwnKSkpCgkJcCA9IGJ1ZmZlcjsKCSAgICBzdHJjcHkgKHAgKyAxLCBuYW1lKTsKCSAgICByZXMgPSBQRV9Mb2FkTGlicmFyeUV4MzJBKCBidWZmZXIsIHByb2Nlc3MsIDAsIDAgKTsKCX0KCWlmIChyZXMgPD0gKEhNT0RVTEUzMikgMzIpIHsKCSAgICBFUlIgKG1vZHVsZSwgIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsIG5hbWUpOwoJICAgIHJldHVybiByZXM7Cgl9Cgl4d20gPSB3bS0+bmV4dDsKCXdoaWxlICh4d20pIHsKCQlpZiAoeHdtLT5tb2R1bGUgPT0gcmVzKQoJCQlicmVhazsKCQl4d20gPSB4d20tPm5leHQ7Cgl9CglpZiAoeHdtKSB7CgkJLyogSXQgaGFzIGJlZW4gbG9hZGVkICpCRUZPUkUqIHVzLCBzbyB3ZSBoYXZlIHRvIGluaXRpYWxpemUKCQkgKiBpdCBiZWZvcmUgdXMuIFdlIGNhbm5vdCBqdXN0IGxpbmsgaW4gdGhlIHh3bSBiZWZvcmUgd20sCgkJICogc2luY2UgeHdtIG1pZ2h0IHJlZmVyZW5jZSBtb3JlIGRsbHMgd2hpY2ggd291bGQgYmUgaW4gdGhlCgkJICogd3Jvbmcgb3JkZXIgYWZ0ZXIgdGhhdC4KCQkgKiBJbnN0ZWFkIHdlIGxpbmsgaW4gd20gcmlnaHQgQUZURVIgeHdtLCB3aGljaCBzaG91bGQga2VlcAoJCSAqIHRoZSBjb3JyZWN0IG9yZGVyLiAoSSBhbSBub3QgMTAwJSBzdXJlIGFib3V0IHRoYXQuKQoJCSAqLwoJCS8qIHVubGluayB3bSBmcm9tIGNoYWluICovCgkJeXdtID0gJihwcm9jZXNzLT5tb2RyZWZfbGlzdCk7CgkJd2hpbGUgKCp5d20pIHsKCQkJaWYgKCgqeXdtKT09d20pCgkJCQlicmVhazsKCQkJeXdtID0gJigoKnl3bSktPm5leHQpOwoJCX0KCQkqeXdtCQk9IHdtLT5uZXh0OwoKCQkvKiBsaW5rIHdtIGRpcmVjdGx5IEFGVEVSIHh3bSAqLwoJCXdtLT5uZXh0CT0geHdtLT5uZXh0OwoJCXh3bS0+bmV4dAk9IHdtOwoJCQoJfQoJaSsrOwogICAgfQogICAgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7CiAgICB3aGlsZSAocGVfaW1wLT5OYW1lKSB7CgljaGFyCQkJKk1vZHVsZTsKCUlNQUdFX0lNUE9SVF9CWV9OQU1FCSpwZV9uYW1lOwoJTFBJTUFHRV9USFVOS19EQVRBCWltcG9ydF9saXN0LHRodW5rX2xpc3Q7CiAgICAgICAgSE1PRFVMRTMyIGhJbXBNb2R1bGU7CgoJTW9kdWxlID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CiAgICAgICAgaEltcE1vZHVsZSA9IE1PRFVMRV9GaW5kTW9kdWxlMzIocHJvY2VzcyxNb2R1bGUpOwoJYXNzZXJ0KGhJbXBNb2R1bGUpOyAvKiB3ZSBoYXZlIGltcG9ydGVkIGl0LCBzbyBpdCBNVVNUIGJlIHRoZXJlICovCglUUkFDRSh3aW4zMiwgIiVzXG4iLCBNb2R1bGUpOwoKCS8qIEZJWE1FOiBmb3J3YXJkZXIgZW50cmllcyAuLi4gKi8KCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgVFJBQ0Uod2luMzIsICJNaWNyb3NvZnQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICBpbXBvcnRfbGlzdCA9KExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCgkgICAgd2hpbGUgKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKHdpbjMyLCAiLS0tIE9yZGluYWwgJXMsJWRcbiIsIE1vZHVsZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKU1PRFVMRV9HZXRQcm9jQWRkcmVzczMyKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCAoTFBDU1RSKW9yZGluYWwKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlXQVJOKHdpbjMyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoTFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSh3aW4zMiwgIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzMzIoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MsIGhJbXBNb2R1bGUsIHBlX25hbWUtPk5hbWUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlXQVJOKHdpbjMyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9CgkJaW1wb3J0X2xpc3QrKzsKCQl0aHVua19saXN0Kys7CgkgICAgfQoJfSBlbHNlIHsJLyogQm9ybGFuZCBzdHlsZSAqLwoJICAgIFRSQUNFKHdpbjMyLCAiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSAoTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCSAgICB3aGlsZSAodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgLyogbm90IHN1cmUgYWJvdXQgdGhpcyBicmFuY2gsIGJ1dCBpdCBzZWVtcyB0byB3b3JrICovCgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKHdpbjMyLCItLS0gT3JkaW5hbCAlcy4lZFxuIixNb2R1bGUsb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKU1PRFVMRV9HZXRQcm9jQWRkcmVzczMyKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCAoTFBDU1RSKSBvcmRpbmFsCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJV0FSTih3aW4zMiwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLG9yZGluYWwpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9KExQSU1BR0VfSU1QT1JUX0JZX05BTUUpIFJWQSh0aHVua19saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0Uod2luMzIsIi0tLSAlcyAlcy4lZFxuIiwKCQkgICAJCSAgcGVfbmFtZS0+TmFtZSxNb2R1bGUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKU1PRFVMRV9HZXRQcm9jQWRkcmVzczMyKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCBwZV9uYW1lLT5OYW1lCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCVdBUk4od2luMzIsICJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIAkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0KCQl0aHVua19saXN0Kys7CgkgICAgfQoJfQoJcGVfaW1wKys7CiAgICB9CiAgICBpZiAoZml4dXBfZmFpbGVkKSByZXR1cm4gMjI7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludCBjYWxjX3ZtYV9zaXplKCBITU9EVUxFMzIgaE1vZHVsZSApCnsKICAgIGludCBpLHZtYV9zaXplID0gMDsKICAgIElNQUdFX1NFQ1RJT05fSEVBREVSICpwZV9zZWcgPSBQRV9TRUNUSU9OUyhoTW9kdWxlKTsKCiAgICBUUkFDRSh3aW4zMiwgIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgICBUUkFDRSh3aW4zMiwgIiAgIE5hbWUgICAgVlN6ICBWYWRkciAgICAgU3pSYXcgICBGaWxlYWRyICAqUmVsb2MgKkxpbmV1bSAjUmVsb2MgI0xpbnVtIENoYXJcbiIpOwogICAgZm9yIChpID0gMDsgaTwgUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKICAgIHsKICAgICAgICBUUkFDRSh3aW4zMiwgIiU4czogJTQuNGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTQuNHggJTQuNHggJTguOGx4XG4iLCAKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk1pc2MuVmlydHVhbFNpemUsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlZpcnR1YWxBZGRyZXNzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5TaXplT2ZSYXdEYXRhLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9SYXdEYXRhLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9SZWxvY2F0aW9ucywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvTGluZW51bWJlcnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk51bWJlck9mUmVsb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk51bWJlck9mTGluZW51bWJlcnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPkNoYXJhY3RlcmlzdGljcyk7CiAgICAgICAgdm1hX3NpemUgPSBNQVgodm1hX3NpemUsIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MrcGVfc2VnLT5TaXplT2ZSYXdEYXRhKTsKICAgICAgICBwZV9zZWcrKzsKICAgIH0KICAgIHJldHVybiB2bWFfc2l6ZTsKfQoKc3RhdGljIHZvaWQgZG9fcmVsb2NhdGlvbnMoV0lORV9NT0RSRUYgKndtKQp7CiAgICBQRV9NT0RSRUYJKnBlbSA9ICYod20tPmJpbmZtdC5wZSk7CiAgICBpbnQgZGVsdGEgPSB3bS0+bW9kdWxlIC0gUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyPSB3bS0+bW9kdWxlOwoKCUlNQUdFX0JBU0VfUkVMT0NBVElPTgkJKnIgPSBwZW0tPnBlX3JlbG9jOwoJaW50CQkJCWhkZWx0YSA9IChkZWx0YSA+PiAxNikgJiAweEZGRkY7CglpbnQJCQkJbGRlbHRhID0gZGVsdGEgJiAweEZGRkY7CgoJLyogaW50IHJlbG9jX3NpemUgPSAqLwoKCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlZpcnR1YWxBZGRyZXNzKQoJewoJCWNoYXIgKnBhZ2UgPSAoY2hhciopIFJWQShyLT5WaXJ0dWFsQWRkcmVzcyk7CgkJaW50IGNvdW50ID0gKHItPlNpemVPZkJsb2NrIC0gOCkvMjsKCQlpbnQgaTsKCQlUUkFDRShmaXh1cCwgIiV4IHJlbG9jYXRpb25zIGZvciBwYWdlICVseFxuIiwKCQkJY291bnQsIHItPlZpcnR1YWxBZGRyZXNzKTsKCQkvKiBwYXRjaGluZyBpbiByZXZlcnNlIG9yZGVyICovCgkJZm9yKGk9MDtpPGNvdW50O2krKykKCQl7CgkJCWludCBvZmZzZXQgPSByLT5UeXBlT2Zmc2V0W2ldICYgMHhGRkY7CgkJCWludCB0eXBlID0gci0+VHlwZU9mZnNldFtpXSA+PiAxMjsKCQkJVFJBQ0UoZml4dXAsInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CiNpZiAxCgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKI2Vsc2UKCQkJCXsgaW50IGg9Kih1bnNpZ25lZCBzaG9ydCopKHBhZ2Urb2Zmc2V0KTsKCQkJCSAgaW50IGw9ci0+VHlwZU9mZnNldFsrK2ldOwoJCQkJICAqKHVuc2lnbmVkIGludCopKHBhZ2UgKyBvZmZzZXQpID0gKGg8PDE2KSArIGwgKyBkZWx0YTsKCQkJCX0KI2VuZGlmCgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSEFESjoKCQkJCVdBUk4od2luMzIsICJEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBJTUFHRV9SRUxfQkFTRURfSElHSEFESlxuIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTUlQU19KTVBBRERSOgoJCQkJV0FSTih3aW4zMiwgIklzIHRoaXMgYSBNSVBTIG1hY2hpbmUgPz8/XG4iKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJV0FSTih3aW4zMiwgIlVua25vd24gZml4dXAgdHlwZVxuIik7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyICsgci0+U2l6ZU9mQmxvY2spOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqIAogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvciAKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXRzIHdoaWNoIGFyZSBwYWdlLWFsaWduZWQuCiAqCiAqIEJVVCB3ZSBoYXZlIHRvIG1hcCB0aGUgd2hvbGUgaW1hZ2UgYW55d2F5LCBmb3IgV2luMzIgcHJvZ3JhbXMgc29tZXRpbWVzCiAqIHdhbnQgdG8gYWNjZXNzIHRoZW0uIChITU9EVUxFMzIgcG9pbnQgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8Kc3RhdGljIEhNT0RVTEUzMiBQRV9Mb2FkSW1hZ2UoIEhGSUxFMzIgaEZpbGUgKQp7CiAgICBITU9EVUxFMzIgaE1vZHVsZTsKICAgIEhBTkRMRTMyIG1hcHBpbmc7CgogICAgLyogbWFwIHRoZSBQRSBmaWxlIHNvbWV3aGVyZSAqLwogICAgbWFwcGluZyA9IENyZWF0ZUZpbGVNYXBwaW5nMzJBKCBoRmlsZSwgTlVMTCwgUEFHRV9SRUFET05MWSB8IFNFQ19DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIE5VTEwgKTsKICAgIGlmICghbWFwcGluZykKICAgIHsKICAgICAgICBXQVJOKCB3aW4zMiwgIkNyZWF0ZUZpbGVNYXBwaW5nIGVycm9yICVsZFxuIiwKICAgICAgICAgICAgICAgICBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaE1vZHVsZSA9IChITU9EVUxFMzIpTWFwVmlld09mRmlsZSggbWFwcGluZywgRklMRV9NQVBfUkVBRCwgMCwgMCwgMCApOwogICAgQ2xvc2VIYW5kbGUoIG1hcHBpbmcgKTsKICAgIGlmICghaE1vZHVsZSkKICAgIHsKICAgICAgICBXQVJOKCB3aW4zMiwgIlBFX0xvYWRJbWFnZTogTWFwVmlld09mRmlsZSBlcnJvciAlbGRcbiIsCiAgICAgICAgICAgICAgICAgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoUEVfSEVBREVSKGhNb2R1bGUpLT5TaWduYXR1cmUgIT0gSU1BR0VfTlRfU0lHTkFUVVJFKQogICAgewogICAgICAgIFdBUk4od2luMzIsImltYWdlIGRvZXNuJ3QgaGF2ZSBQRSBzaWduYXR1cmUsIGJ1dCAweCUwOGx4XG4iLAogICAgICAgICAgICAgICAgUEVfSEVBREVSKGhNb2R1bGUpLT5TaWduYXR1cmUgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmIChQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTWFjaGluZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NikKICAgIHsKICAgICAgICBNU0coIlRyeWluZyB0byBsb2FkIFBFIGltYWdlIGZvciB1bnN1cHBvcnRlZCBhcmNoaXRlY3R1cmUgKCIpOwogICAgICAgIHN3aXRjaCAoUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk1hY2hpbmUpCiAgICAgICAgewogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1VOS05PV046IE1TRygiVW5rbm93blxuIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0k4NjA6ICAgIE1TRygiSTg2MFxuIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IzMDAwOiAgIE1TRygiUjMwMDBcbiIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SNDAwMDogICBNU0coIlI0MDAwXG4iKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjEwMDAwOiAgTVNHKCJSMTAwMDBcbiIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9BTFBIQTogICBNU0coIkFscGhhXG4iKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUE9XRVJQQzogTVNHKCJQb3dlclBDXG4iKTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogTVNHKCJVbmtub3duLSUwNHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTWFjaGluZSk7IGJyZWFrOwogICAgICAgIH0KICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgcmV0dXJuIGhNb2R1bGU7CgplcnJvcjoKICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhpcyBtYXBzIGEgbG9hZGVkIFBFIGRsbCBpbnRvIHRoZSBhZGRyZXNzIHNwYWNlIG9mIHRoZSBzcGVjaWZpZWQgcHJvY2Vzcy4KICovCnN0YXRpYyBCT09MMzIgUEVfTWFwSW1hZ2UoIFBEQjMyICpwcm9jZXNzLFdJTkVfTU9EUkVGICp3bSwgT0ZTVFJVQ1QgKm9mcywgRFdPUkQgZmxhZ3MgKQp7CglQRV9NT0RSRUYJCSpwZW07CglpbnQJCQlpLCByZXN1bHQ7CglEV09SRAkJCWxvYWRfYWRkcjsKCUlNQUdFX0RBVEFfRElSRUNUT1JZCWRpcjsKCWNoYXIJCQkqbW9kbmFtZTsKCWludAkJCXZtYV9zaXplOwoJSE1PRFVMRTMyCQloTW9kdWxlID0gd20tPm1vZHVsZTsKCiAgICAgICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlZzsKICAgICAgICBJTUFHRV9ET1NfSEVBREVSICpkb3NfaGVhZGVyID0gKElNQUdFX0RPU19IRUFERVIgKiloTW9kdWxlOwogICAgICAgIElNQUdFX05UX0hFQURFUlMgKm50X2hlYWRlciA9IFBFX0hFQURFUihoTW9kdWxlKTsKCQoJcGVtIAk9ICYod20tPmJpbmZtdC5wZSk7CgoJcmVzdWx0ID0gR2V0TG9uZ1BhdGhOYW1lMzJBKG9mcy0+c3pQYXRoTmFtZSxOVUxMLDApOwoJd20tPmxvbmduYW1lID0gKGNoYXIqKUhlYXBBbGxvYyhwcm9jZXNzLT5oZWFwLDAscmVzdWx0KzEpOwoJR2V0TG9uZ1BhdGhOYW1lMzJBKG9mcy0+c3pQYXRoTmFtZSx3bS0+bG9uZ25hbWUscmVzdWx0KzEpOwoKCXdtLT5zaG9ydG5hbWUgPSBIRUFQX3N0cmR1cEEocHJvY2Vzcy0+aGVhcCwwLG9mcy0+c3pQYXRoTmFtZSk7CgoJaWYgKCEobnRfaGVhZGVyLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSkKICAgICAgICB7CgkJaWYgKHByb2Nlc3MtPmV4ZV9tb2RyZWYpCgkJCUZJWE1FKHdpbjMyLCJvdmVyd3JpdGluZyBvbGQgZXhlX21vZHJlZi4uLiBhcnJnaFxuIik7CgkJcHJvY2Vzcy0+ZXhlX21vZHJlZiA9IHdtOwoJfQoKCWxvYWRfYWRkciA9IG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJdm1hX3NpemUgPSBjYWxjX3ZtYV9zaXplKCBoTW9kdWxlICk7CglUUkFDRSh3aW4zMiwgIkxvYWQgYWRkciBpcyAlbHhcbiIsbG9hZF9hZGRyKTsKCWxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoICh2b2lkKilsb2FkX2FkZHIsIHZtYV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CglpZiAobG9hZF9hZGRyID09IDApIHsKCQlsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCBOVUxMLCB2bWFfc2l6ZSwKCQkJCQkJIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKCQkJCQkJIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKCX0KCS8qIE5PVEU6IHRoaXMgY2hhbmdlcyBhIHZhbHVlIGluIHRoZSBwcm9jZXNzIG1vZHJlZiBjaGFpbiwgd2hpY2ggY2FuCgkgKiBiZSBhY2Nlc3NlZCBpbmRlcGVuZGVudGx5IGZyb20gdGhpcyBmdW5jdGlvbgoJICovCgl3bS0+bW9kdWxlID0gKEhNT0RVTEUzMilsb2FkX2FkZHI7CgoJVFJBQ0Uod2luMzIsICJMb2FkIGFkZHIgaXMgcmVhbGx5ICVseCwgcmFuZ2UgJXhcbiIsCiAgICAgICAgICAgICAgICAgICAgICBsb2FkX2FkZHIsIHZtYV9zaXplKTsKCglUUkFDRShzZWdtZW50LCAiTG9hZGluZyAlcyBhdCAlbHgsIHJhbmdlICV4XG4iLAogICAgICAgICAgICAgIG9mcy0+c3pQYXRoTmFtZSwgbG9hZF9hZGRyLCB2bWFfc2l6ZSApOwoJCiAgICAgICAgLyogU3RvcmUgdGhlIE5UIGhlYWRlciBhdCB0aGUgbG9hZCBhZGRyCiAgICAgICAgICogKEZJWE1FOiBzaG91bGQgcmVhbGx5IHVzZSBtbWFwKQogICAgICAgICAqLwogICAgICAgICooSU1BR0VfRE9TX0hFQURFUiAqKWxvYWRfYWRkciA9ICpkb3NfaGVhZGVyOwogICAgICAgICooSU1BR0VfTlRfSEVBREVSUyAqKShsb2FkX2FkZHIgKyBkb3NfaGVhZGVyLT5lX2xmYW5ldykgPSAqbnRfaGVhZGVyOwoKICAgICAgICBwZV9zZWcgPSBQRV9TRUNUSU9OUyhoTW9kdWxlKTsKCWZvciAoaSA9IDA7IGkgPCBudF9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBwZV9zZWcrKykKCXsKCQkvKiBtZW1jcHkgb25seSBub24tQlNTIHNlZ21lbnRzICovCgkJLyogRklYTUU6IHRoaXMgc2hvdWxkIGJlIGRvbmUgYnkgbW1hcCguLk1BUF9QUklWQVRFfE1BUF9GSVhFRC4uKQoJCSAqIGJ1dCBpdCBpcyBub3QgcG9zc2libGUgZm9yIChhdCBsZWFzdCkgTGludXggbmVlZHMKCQkgKiBhIHBhZ2UtYWxpZ25lZCBvZmZzZXQuCgkJICovCgkJaWYoIShwZV9zZWctPkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKSkKCQkgICAgbWVtY3B5KChjaGFyKilSVkEocGVfc2VnLT5WaXJ0dWFsQWRkcmVzcyksCgkJICAgIAkoY2hhciopKGhNb2R1bGUgKyBwZV9zZWctPlBvaW50ZXJUb1Jhd0RhdGEpLAoJCQlwZV9zZWctPlNpemVPZlJhd0RhdGEKCQkgICAgKTsKCgkJcmVzdWx0ID0gUlZBIChwZV9zZWctPlZpcnR1YWxBZGRyZXNzKTsKI2lmIDEKCQkvKiBub3QgbmVlZGVkLCBtZW1vcnkgaXMgemVybyAqLwoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIuYnNzIikgPT0gMCkKCQkgICAgbWVtc2V0KCh2b2lkICopcmVzdWx0LCAwLCAKCQkJICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplID8KCQkJICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplIDoKCQkJICAgcGVfc2VnLT5TaXplT2ZSYXdEYXRhKTsKI2VuZGlmCgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIuaWRhdGEiKSA9PSAwKQoJCQlwZW0tPnBlX2ltcG9ydCA9IChMUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIuZWRhdGEiKSA9PSAwKQoJCQlwZW0tPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5yc3JjIikgPT0gMCkKCQkJcGVtLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGVfc2VnLT5OYW1lLCAiLnJlbG9jIikgPT0gMCkKCQkJcGVtLT5wZV9yZWxvYyA9IChMUElNQUdFX0JBU0VfUkVMT0NBVElPTikgcmVzdWx0OwoJfQoKCS8qIFRoZXJlIGlzIHdvcmQgdGhhdCB0aGUgYWN0dWFsIGxvYWRlciBkb2VzIG5vdCBjYXJlIGFib3V0IHRoZQoJICAgc2VjdGlvbiBuYW1lcywgYW5kIG9ubHkgZ29lcyBmb3IgdGhlIERhdGFEaXJlY3RvcnkgKi8KCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX2V4cG9ydCAmJiAoaW50KXBlbS0+cGVfZXhwb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJV0FSTih3aW4zMiwid3JvbmcgZXhwb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQkvKiBhbHdheXMgdHJ1c3QgdGhlIGRpcmVjdG9yeSAqLwoJCXBlbS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfSU1QT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCS8qIAoJCWlmKHBlbS0+cGVfaW1wb3J0ICYmIChpbnQpcGVtLT5wZV9pbXBvcnQhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlXQVJOKHdpbjMyLCJ3cm9uZyBpbXBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCSAqLwoJCXBlbS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1JFU09VUkNFXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlbS0+cGVfcmVzb3VyY2UgJiYgKGludClwZW0tPnBlX3Jlc291cmNlIT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJV0FSTih3aW4zMiwid3JvbmcgcmVzb3VyY2UgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlbS0+cGVfcmVzb3VyY2UgPSAoTFBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfU0VDVVJJVFldLlNpemUpCgkJRklYTUUod2luMzIsIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCgoKCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQ107CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX3JlbG9jICYmIChpbnQpcGVtLT5wZV9yZWxvYyE9IFJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlXQVJOKHdpbjMyLCJ3cm9uZyByZWxvY2F0aW9uIGxpc3Q/P1xuIik7CgkJcGVtLT5wZV9yZWxvYyA9ICh2b2lkICopIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09QWVJJR0hUXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJHbG9iYWwgUG9pbnRlciAoTUlQUykgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJR10uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVF0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiQm91bmQgSW1wb3J0IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVF0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzEzXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJVbmtub3duIGRpcmVjdG9yeSAxMyBpZ25vcmVkXG4iKTsKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNF0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIik7CglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTVdLlNpemUpCgkJRklYTUUod2luMzIsIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIpOwoKCWlmKHBlbS0+cGVfcmVsb2MpCWRvX3JlbG9jYXRpb25zKHdtKTsKCWlmKHBlbS0+cGVfZXhwb3J0KSB7CgkJZHVtcF9leHBvcnRzKHdtLT5tb2R1bGUpOwoKCQl3bS0+bW9kbmFtZSA9IEhFQVBfc3RyZHVwQShwcm9jZXNzLT5oZWFwLDAsKGNoYXIqKVJWQShwZW0tPnBlX2V4cG9ydC0+TmFtZSkpOwoJfSBlbHNlIHsKCQkvKiB0cnkgdG8gZmluZCBvdXQgdGhlIG5hbWUgZnJvbSB0aGUgT0ZTVFJVQ1QgKi8KCQljaGFyICpzOwoJCW1vZG5hbWUgPSBzID0gb2ZzLT5zelBhdGhOYW1lOwoJCXdoaWxlICgocz1zdHJjaHIobW9kbmFtZSwnXFwnKSkpCgkJCW1vZG5hbWUgPSBzKzE7CgkJd20tPm1vZG5hbWUgPSBIRUFQX3N0cmR1cEEocHJvY2Vzcy0+aGVhcCwwLG1vZG5hbWUpOwoJfQoJaWYocGVtLT5wZV9pbXBvcnQpCXsKCQlpZiAoZml4dXBfaW1wb3J0cyhwcm9jZXNzLHdtKSkgewoJCQlXSU5FX01PRFJFRgkqKnh3bTsKCgkJCS8qIHJlbW92ZSBlbnRyeSBmcm9tIG1vZHJlZiBjaGFpbiAqLwoJCQl4d20gPSAmKHByb2Nlc3MtPm1vZHJlZl9saXN0KTsKCQkJd2hpbGUgKCp4d20pIHsKCQkJCWlmICgqeHdtPT13bSkgewoJCQkJCSp4d20gPSB3bS0+bmV4dDsKCQkJCQlicmVhazsKCQkJCX0KCQkJCXh3bSA9ICYoKCp4d20pLT5uZXh0KTsKCQkJfQoJCQkvKiBGSVhNRTogdGhlcmUgYXJlIHNldmVyYWwgbW9yZSBkYW5nbGluZyByZWZlcmVuY2VzCgkJCSAqIGxlZnQuIEluY2x1ZGluZyBkbGxzIGxvYWRlZCBieSB0aGlzIGRsbCBiZWZvcmUgdGhlCgkJCSAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCgkJCSAqIGN1cnJlbnQgc3RydWN0dXJlIGFuZCB3ZSBjYW4gbGVhdmUgaXQgdGhlbSBseWluZwoJCQkgKiBhcm91bmQgd2l0aCBubyBwcm9ibGVtcywgc28gd2UgZG9uJ3QgY2FyZQoJCQkgKi8KCQkJcmV0dXJuIDA7CgkJfQoJfQogIAkJCiAgICAgICAgLyogTm93IHRoYXQgd2UgZ290IGV2ZXJ5dGhpbmcgYXQgdGhlIHJpZ2h0IGFkZHJlc3MsCiAgICAgICAgICogd2UgY2FuIHVubWFwIHRoZSBwcmV2aW91cyBtb2R1bGUgKi8KICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKiAgICAgICAgaW50ZXJuYWwgbW9kdWxlIGhhbmRsaW5nIHNob3VsZCBiZSBtYWRlIGJldHRlciBoZXJlIChhbmQgaW4gYnVpbHRpbi5jKQogKi8KSE1PRFVMRTMyIFBFX0xvYWRMaWJyYXJ5RXgzMkEgKExQQ1NUUiBuYW1lLCBQREIzMiAqcHJvY2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhGSUxFMzIgaEZpbGUsIERXT1JEIGZsYWdzKQp7CglPRlNUUlVDVAlvZnM7CglITU9EVUxFMzIJaE1vZHVsZTsKCU5FX01PRFVMRQkqcE1vZHVsZTsKCVdJTkVfTU9EUkVGCSp3bTsKCglpZiAoKGhNb2R1bGUgPSBNT0RVTEVfRmluZE1vZHVsZTMyKCBwcm9jZXNzLCBuYW1lICkpKSB7CgkJZm9yICh3bT0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7d207d209d20tPm5leHQpCgkJCWlmICh3bS0+bW9kdWxlID09IGhNb2R1bGUpCgkJCQlyZXR1cm4gaE1vZHVsZTsKCQkvKiBTaW5jZSBNT0RVTEVfRmluZE1vZHVsZTMyIHVzZXMgdGhlIG1vZHJlZiBjaGFpbiB0b28sIHRoZQoJCSAqIG1vZHVsZSBNVVNUIGhhdmUgYmVlbiBmb3VuZCBhYm92ZS4gSWYgbm90LCBzb21ldGhpbmcgaGFzIGdvbmUKCQkgKiB0ZXJyaWJseSB3cm9uZy4KCQkgKi8KCQlhc3NlcnQoMCk7Cgl9CgkvKiB0cnkgdG8gbG9hZCBidWlsdGluLCBlbmFibGVkIG1vZHVsZXMgZmlyc3QgKi8KCWlmICgoaE1vZHVsZSA9IEJVSUxUSU4zMl9Mb2FkTW9kdWxlKCBuYW1lLCBGQUxTRSwgcHJvY2VzcyApKSkKCSAgICByZXR1cm4gaE1vZHVsZTsKCgkvKiB0cnkgdG8gbG9hZCB0aGUgc3BlY2lmaWVkIGRsbC9leGUgKi8KCWlmIChIRklMRV9FUlJPUjMyPT0oaEZpbGU9T3BlbkZpbGUzMihuYW1lLCZvZnMsT0ZfUkVBRCkpKSB7CgkJLyogTm93IHRyeSB0aGUgYnVpbHQtaW4gZXZlbiBpZiBkaXNhYmxlZCAqLwoJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU4zMl9Mb2FkTW9kdWxlKCBuYW1lLCBUUlVFLCBwcm9jZXNzICkpKSB7CgkJICAgIFdBUk4oIG1vZHVsZSwgIkNvdWxkIG5vdCBsb2FkIGV4dGVybmFsIERMTCAnJXMnLCB1c2luZyBidWlsdC1pbiBtb2R1bGUuXG4iLCBuYW1lICk7CgkJICAgIHJldHVybiBoTW9kdWxlOwoJCX0KCQlyZXR1cm4gMTsKCX0KCS8qIHdpbGwgZ28gYXdheSAuLi4gKi8KCWlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggJm9mcyApKSA8IDMyKSB7CgkJX2xjbG9zZTMyKGhGaWxlKTsKCQlyZXR1cm4gaE1vZHVsZTsKCX0KCXBNb2R1bGUgICAgICAgICA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUgKTsKCXBNb2R1bGUtPmZsYWdzICA9IE5FX0ZGTEFHU19XSU4zMjsKCS8qIC4uICovCgoJd209KFdJTkVfTU9EUkVGKilIZWFwQWxsb2MocHJvY2Vzcy0+aGVhcCxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZigqd20pKTsKCXdtLT50eXBlID0gTU9EVUxFMzJfUEU7CgkvKiBOT1RFOiBmaXh1cF9pbXBvcnRzIHRha2VzIGNhcmUgb2YgdGhlIGNvcnJlY3Qgb3JkZXIgKi8KCXdtLT5uZXh0ID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cglwcm9jZXNzLT5tb2RyZWZfbGlzdCA9IHdtOwoKCXdtLT5tb2R1bGUgPSBwTW9kdWxlLT5tb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggaEZpbGUgKTsKCglDbG9zZUhhbmRsZSggaEZpbGUgKTsKICAgICAgICBpZiAod20tPm1vZHVsZSA8IDMyKSAKICAgICAgICB7CgkgICAgcHJvY2Vzcy0+bW9kcmVmX2xpc3QgPSB3bS0+bmV4dDsKCSAgICBGcmVlTGlicmFyeTE2KCBoTW9kdWxlKTsKCSAgICBIZWFwRnJlZShwcm9jZXNzLT5oZWFwLDAsd20pOwoJICAgIEVSUih3aW4zMiwiY2FuJ3QgbG9hZCAlc1xuIixvZnMuc3pQYXRoTmFtZSk7CiAgICAgICAgICAgIHJldHVybiAyMTsgLyogRklYTUU6IHByb2JhYmx5IDAgKi8KICAgICAgICB9CgoJLyogKHBvc3NpYmxlKSByZWN1cnNpb24gKi8KCWlmICghUEVfTWFwSW1hZ2UocHJvY2Vzcyx3bSwmb2ZzLGZsYWdzKSkgewoJICAgIC8qIEVSUk9SIGNsZWFudXAgLi4uICovCgkgICAgV0lORV9NT0RSRUYJKip4d207CgoJICAgIEVSUih3aW4zMiwiY291bGRuJ3QgbG9hZCAlc1xuIixvZnMuc3pQYXRoTmFtZSk7CgkgICAgLyogdW5saW5rIGZyb20gcHJvY2VzcyBtb2RyZWYgY2hhaW4gKi8KCSAgICBmb3IgKCAgICB4d209Jihwcm9jZXNzLT5tb2RyZWZfbGlzdCk7CgkJICAgICAqeHdtICYmICgqeHdtIT13bSk7CgkJICAgICB4d209JigoKnh3bSktPm5leHQpCgkgICAgKSAvKiBFTVBUWSAqLzsKCSAgICBpZiAoKnh3bSkKCSAgICAJKnh3bT0oKnh3bSktPm5leHQ7CgkgICAgCQoJICAgIHJldHVybiAwOwoJfQogICAgICAgIHBNb2R1bGUtPm1vZHVsZTMyID0gd20tPm1vZHVsZTsKCXJldHVybiB3bS0+bW9kdWxlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTG9hZCB0aGUgUEUgbWFpbiAuRVhFLiBBbGwgb3RoZXIgbG9hZGluZyBpcyBkb25lIGJ5IFBFX0xvYWRMaWJyYXJ5RXgzMkEKICogRklYTUU6IHRoaXMgZnVuY3Rpb24gc2hvdWxkIHVzZSBQRV9Mb2FkTGlicmFyeUV4MzJBLCBidXQgY3VycmVudGx5IGNhbid0CiAqIGR1ZSB0byB0aGUgUFJPQ0VTU19DcmVhdGUgc3R1ZmYuCiAqLwpISU5TVEFOQ0UxNiBQRV9Mb2FkTW9kdWxlKCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZF9saW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgZW52LCBVSU5UMTYgc2hvd19jbWQgKQp7CiAgICBITU9EVUxFMTYgaE1vZHVsZTE2OwogICAgSE1PRFVMRTMyIGhNb2R1bGUzMjsKICAgIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKICAgIEhGSUxFMzIgaEZpbGU7CiAgICBPRlNUUlVDVCBvZnM7CiAgICBUSERCICp0aGRiID0gVEhSRUFEX0N1cnJlbnQoKTsKICAgIFBEQjMyICpwcm9jZXNzOwogICAgV0lORV9NT0RSRUYJKndtOwoKICAgIGlmICgoaEZpbGUgPSBPcGVuRmlsZTMyKCBuYW1lLCAmb2ZzLCBPRl9SRUFEICkpID09IEhGSUxFX0VSUk9SMzIpCiAgICAgICAgcmV0dXJuIDI7ICAvKiBGaWxlIG5vdCBmb3VuZCAqLwoKICAgIGlmICgoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCAmb2ZzICkpIDwgMzIpIHJldHVybiBoTW9kdWxlMTY7CiAgICBwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZTE2ICk7CiAgICBwTW9kdWxlLT5mbGFncyA9IE5FX0ZGTEFHU19XSU4zMjsKCiAgICBwTW9kdWxlLT5tb2R1bGUzMiA9IGhNb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggaEZpbGUgKTsKICAgIGlmIChoTW9kdWxlMzIgPCAzMikgcmV0dXJuIDIxOwoKICAgIGhJbnN0YW5jZSA9IE5FX0NyZWF0ZUluc3RhbmNlKCBwTW9kdWxlLCBOVUxMLCAoY21kX2xpbmUgPT0gTlVMTCkgKTsKICAgIGlmIChjbWRfbGluZSAmJgogICAgICAgICEoUEVfSEVBREVSKGhNb2R1bGUzMiktPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpKQogICAgewogICAgICAgIFBEQjMyICpwZGIgPSBQUk9DRVNTX0NyZWF0ZSggcE1vZHVsZSwgY21kX2xpbmUsIGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhJbnN0YW5jZSwgMCwgc2hvd19jbWQgKTsKICAgICAgICBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggcGRiLT50YXNrICk7CiAgICAgICAgdGhkYiA9IHBUYXNrLT50aGRiOwogICAgfQoKICAgIHByb2Nlc3MgPSB0aGRiLT5wcm9jZXNzOwoKICAgIHdtPShXSU5FX01PRFJFRiopSGVhcEFsbG9jKHByb2Nlc3MtPmhlYXAsSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoKndtKSk7CiAgICB3bS0+dHlwZSA9IE1PRFVMRTMyX1BFOwogICAgLyogTk9URTogZml4dXBfaW1wb3J0cyB0YWtlcyBjYXJlIG9mIHRoZSBjb3JyZWN0IG9yZGVyICovCiAgICB3bS0+bmV4dCA9IHByb2Nlc3MtPm1vZHJlZl9saXN0OwogICAgd20tPm1vZHVsZSA9IGhNb2R1bGUzMjsKICAgIHByb2Nlc3MtPm1vZHJlZl9saXN0ID0gd207CiAgICBpZiAoIVBFX01hcEltYWdlKCBwcm9jZXNzLCB3bSwgJm9mcywgMCApKQogICAgewogICAgIAkvKiBGSVhNRTogc2hvdWxkIGRlc3Ryb3kgdGhlIHRhc2sgY3JlYXRlZCBhbmQgZnJlZSByZWZlcmVuY2VkIHN0dWZmICovCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBwTW9kdWxlLT5tb2R1bGUzMiA9IHdtLT5tb2R1bGU7CiAgICAvKiBGSVhNRTogWXVjay4gSXMgdGhlcmUgbm8gb3RoZXIgZ29vZCBwbGFjZSB0byBkbyB0aGF0PyAqLwogICAgUEVfSW5pdFRscyggdGhkYiApOwogICAgcmV0dXJuIGhJbnN0YW5jZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQRV9VbmxvYWRJbWFnZSBbaW50ZXJuYWxdCiAqLwppbnQgUEVfVW5sb2FkSW1hZ2UoIEhNT0RVTEUzMiBoTW9kdWxlICkKewoJRklYTUUod2luMzIsInN0dWIuXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8Kc3RhdGljIHZvaWQgUEVfSW5pdERMTChXSU5FX01PRFJFRiAqd20sIERXT1JEIHR5cGUsTFBWT0lEIGxwUmVzZXJ2ZWQpCnsKICAgIGlmICh3bS0+dHlwZSE9TU9EVUxFMzJfUEUpCiAgICAJcmV0dXJuOwogICAgaWYgKHR5cGU9PURMTF9QUk9DRVNTX0FUVEFDSCkKCXdtLT5iaW5mbXQucGUuZmxhZ3MgfD0gUEVfTU9EUkVGX1BST0NFU1NfQVRUQUNIRUQ7CgogICAgLyogIERMTF9BVFRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgZm9yIGR5bmFtaWMgbG9hZHMsIG5vdC1OVUxMIGZvciBzdGF0aWMgbG9hZHMKICAgICAqICBETExfREVUQUNIX1BST0NFU1M6CiAgICAgKgkJbHByZXNlcnZlZCBpcyBOVUxMIGlmIGNhbGxlZCBieSBGcmVlTGlicmFyeSwgbm90LU5VTEwgb3RoZXJ3aXNlCiAgICAgKiAgdGhlIFNESyBkb2Vzbid0IG1lbnRpb24gYW55dGhpbmcgZm9yIERMTF9USFJFQURfKgogICAgICovCiAgICAgICAgCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgoUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSAmJgogICAgICAgIChQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICApIHsKICAgICAgICBGQVJQUk9DMzIgZW50cnkgPSAoRkFSUFJPQzMyKVJWQV9QVFIoIHdtLT5tb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgKTsKICAgICAgICBUUkFDRShyZWxheSwgIkNhbGxUbzMyKGVudHJ5cHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApXG4iLAogICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LCB3bS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICAgICAgZW50cnkoIHdtLT5tb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgIH0KfQoKLyogQ2FsbCB0aGUgRExMZW50cnkgZnVuY3Rpb24gb2YgYWxsIGRsbHMgdXNlZCBieSB0aGF0IHByb2Nlc3MuCiAqIChOT1RFOiB0aGlzIG1heSByZWN1cnNpdmVseSBjYWxsIHRoaXMgZnVuY3Rpb24gKGlmIGEgbGlicmFyeSBjYWxscwogKiBMb2FkTGlicmFyeSkgLi4uIGJ1dCBpdCB3b24ndCBtYXR0ZXIpCiAqLwp2b2lkIFBFX0luaXRpYWxpemVETExzKFBEQjMyICpwcm9jZXNzLERXT1JEIHR5cGUsTFBWT0lEIGxwUmVzZXJ2ZWQpIHsKCVdJTkVfTU9EUkVGCSp3bTsKCglmb3IgKHdtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7d207d209d20tPm5leHQpIHsKCQlQRV9NT0RSRUYJKnBlbSA9IE5VTEw7CgkJaWYgKHdtLT50eXBlIT1NT0RVTEUzMl9QRSkKCQkJY29udGludWU7CgkJcGVtID0gJih3bS0+YmluZm10LnBlKTsKCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9OT19ETExfQ0FMTFMpCgkJCWNvbnRpbnVlOwoJCWlmICh0eXBlPT1ETExfUFJPQ0VTU19BVFRBQ0gpIHsKCQkJaWYgKHBlbS0+ZmxhZ3MgJiBQRV9NT0RSRUZfUFJPQ0VTU19BVFRBQ0hFRCkKCQkJCWNvbnRpbnVlOwoJCX0KCQlQRV9Jbml0RExMKCB3bSwgdHlwZSwgbHBSZXNlcnZlZCApOwoJfQp9Cgp2b2lkIFBFX0luaXRUbHMoVEhEQiAqdGhkYikKewoJV0lORV9NT0RSRUYJCSp3bTsKCVBFX01PRFJFRgkJKnBlbTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZTsKCUxQVk9JRAkJCW1lbTsKCUxQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwoJUERCMzIJCQkqcGRiID0gdGhkYi0+cHJvY2VzczsKICAgICAgICBpbnQgZGVsdGE7CgkKCWZvciAod20gPSBwZGItPm1vZHJlZl9saXN0O3dtO3dtPXdtLT5uZXh0KSB7CgkJaWYgKHdtLT50eXBlIT1NT0RVTEUzMl9QRSkKCQkJY29udGludWU7CgkJcGVtID0gJih3bS0+YmluZm10LnBlKTsKCQlwZWggPSBQRV9IRUFERVIod20tPm1vZHVsZSk7CgkJZGVsdGEgPSB3bS0+bW9kdWxlIC0gcGVoLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CgkJaWYgKCFwZWgtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpCgkJCWNvbnRpbnVlOwoJCXBkaXIgPSAoTFBWT0lEKSh3bS0+bW9kdWxlICsgcGVoLT5PcHRpb25hbEhlYWRlci4KCQkJRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcyk7CgkJCgkJCgkJaWYgKCEocGVtLT5mbGFncyAmIFBFX01PRFJFRl9UTFNfQUxMT0NFRCkpIHsKCQkJcGVtLT50bHNpbmRleCA9IFRIUkVBRF9UbHNBbGxvYyh0aGRiKTsKCQkJKihMUERXT1JEKUFkanVzdFB0cihwZGlyLT5BZGRyZXNzT2ZJbmRleCxkZWx0YSkKCQkJICA9cGVtLT50bHNpbmRleDsgICAKCQl9CgkJcGVtLT5mbGFncyB8PSBQRV9NT0RSRUZfVExTX0FMTE9DRUQ7CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sCgkJICAgICAgIEFkanVzdFB0cihwZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGEsZGVsdGEpLCAKCQkgICAgICAgZGF0YXNpemUpOwoKCQkvKiBkb24ndCB1c2UgVGxzU2V0VmFsdWUsIHdlIGFyZSBpbiB0aGUgd3JvbmcgdGhyZWFkICovCgkJaWYgKHBkaXItPkFkZHJlc3NPZkNhbGxCYWNrcykgewoJCSAgICAgTFBJTUFHRV9UTFNfQ0FMTEJBQ0sgKmNicyA9IAoJCSAgICAgICAoTFBJTUFHRV9UTFNfQ0FMTEJBQ0sgKikKCQkgICAgICAgQWRqdXN0UHRyKHBkaXItPkFkZHJlc3NPZkNhbGxCYWNrcywgZGVsdGEpOwoKCQkgICAgIGlmICgqY2JzKSB7CgkJICAgICAgIEZJWE1FKHdpbjMyLCAiVExTIENhbGxiYWNrcyBhcmVuJ3QgZ29pbmcgdG8gYmUgY2FsbGVkXG4iKTsKCQkgICAgIH0KCQl9CgkJdGhkYi0+dGxzX2FycmF5W3BlbS0+dGxzaW5kZXhdID0gbWVtOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyAoS0VSTkVMMzIuNzQpCiAqIERvbid0IGNhbGwgRGxsRW50cnlQb2ludCBmb3IgRExMX1RIUkVBRF97QVRUQUNILERFVEFDSH0gaWYgc2V0LgogKi8KQk9PTDMyIFdJTkFQSSBEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzKEhNT0RVTEUzMiBoTW9kdWxlKQp7CglXSU5FX01PRFJFRgkqd207CgoJZm9yICh3bT1QUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3Q7d207d209d20tPm5leHQpCgkJaWYgKCh3bS0+bW9kdWxlID09IGhNb2R1bGUpICYmICh3bS0+dHlwZT09TU9EVUxFMzJfUEUpKQoJCQl3bS0+YmluZm10LnBlLmZsYWdzfD1QRV9NT0RSRUZfTk9fRExMX0NBTExTOwoJcmV0dXJuIFRSVUU7Cn0K