LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYgICAgTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInBlX2ltYWdlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKCnN0YXRpYyB2b2lkIFBFX0luaXRETEwoUEVfTU9EUkVGKiBtb2RyZWYsIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkKTsKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodW5zaWduZWQgaW50KWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFMzIgaE1vZHVsZSApCnsgCiAgY2hhcgkJKk1vZHVsZTsKICBpbnQJCWksIGo7CiAgdV9zaG9ydAkqb3JkaW5hbDsKICB1X2xvbmcJKmZ1bmN0aW9uLCpmdW5jdGlvbnM7CiAgdV9jaGFyCSoqbmFtZTsKICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gaE1vZHVsZTsKCiAgRFdPUkQgcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CiAgRFdPUkQgcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0cyA9IChJTUFHRV9FWFBPUlRfRElSRUNUT1JZKilSVkEocnZhX3N0YXJ0KTsKCiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiXG4qKioqKioqRVhQT1JUIERBVEEqKioqKioqXG5Nb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKCSBNb2R1bGUsCgkgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsCgkgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiIE9yZCAgICBSVkEgICAgIEFkZHIgICBOYW1lXG4iICk7CiAgZm9yIChpPTA7aTxwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucztpKyssIGZ1bmN0aW9uKyspCiAgewogICAgICBpZiAoISpmdW5jdGlvbikgY29udGludWU7ICAvKiBObyBzdWNoIGZ1bmN0aW9uICovCiAgICAgIGRwcmludGZfd2luMzIoIHN0ZGRlYiwiJTRsZCAlMDhseCAlMDh4IiwKICAgICAgICAgICAgICAgICAgICAgaSArIHBlX2V4cG9ydHMtPkJhc2UsICpmdW5jdGlvbiwgUlZBKCpmdW5jdGlvbikgKTsKICAgICAgLyogQ2hlY2sgaWYgd2UgaGF2ZSBhIG5hbWUgZm9yIGl0ICovCiAgICAgIGZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQogICAgICAgICAgICAgIGRwcmludGZfd2luMzIoIHN0ZGRlYiwgIiAgJXMiLCAoY2hhciopUlZBKG5hbWVbal0pICk7CiAgICAgIGlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfZW5kKSkKCSAgZHByaW50Zl93aW4zMihzdGRkZWIsICIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKICAgICAgZHByaW50Zl93aW4zMiggc3RkZGViLCJcbiIgKTsKICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnRsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgTmFtZSBsaXN0LiAKICoJLSBsb29rIHVwIHRoZSBvcmRpbmFsIHdpdGggdGhhdCBpbmRleC4KICoJLSB1c2UgdGhlIG9yZGluYWwgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKiBJZiBpdCBpcyBhIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICovCkZBUlBST0MzMiBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggSE1PRFVMRTMyIGhNb2R1bGUsIExQQ1NUUiBmdW5jTmFtZSkKewoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAJCSpleHBvcnRzOwoJdW5zaWduZWQJCQlsb2FkX2FkZHI7Cgl1X3Nob3J0CQkJCSogb3JkaW5hbDsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZTsKCWludAkJCQlpOwoJUERCMzIJCQkJKnByb2Nlc3M9cEN1cnJlbnRQcm9jZXNzOwoJUEVfTU9EUkVGCQkJKnBlbTsKCXVfbG9uZwkJCQlydmFfc3RhcnQsIHJ2YV9lbmQsIGFkZHI7CgljaGFyCQkJCSogZm9yd2FyZDsKCglwZW0gPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCXdoaWxlIChwZW0gJiYgKHBlbS0+bW9kdWxlICE9IGhNb2R1bGUpKQoJCXBlbT1wZW0tPm5leHQ7CglpZiAoIXBlbSkgewoJCWZwcmludGYoc3RkZXJyLCJObyBNT0RSRUYgZm91bmQgZm9yIFBFX01PRFVMRSAlMDh4IGluIHByb2Nlc3MgJXBcbiIsaE1vZHVsZSxwcm9jZXNzKTsKCQlyZXR1cm4gTlVMTDsKCX0KCWxvYWRfYWRkciA9IGhNb2R1bGU7CglleHBvcnRzICAgPSBwZW0tPnBlX2V4cG9ydDsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkKCQlkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oJXMpXG4iLGZ1bmNOYW1lKTsKCWVsc2UKCQlkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oJWQpXG4iLChpbnQpZnVuY05hbWUpOwoJaWYgKCFleHBvcnRzKSB7CgkJZnByaW50ZihzdGRlcnIsIk1vZHVsZSAlMDh4L01PRFJFRiAlcCBkb2Vzbid0IGhhdmUgYSBleHBvcnRzIHRhYmxlLlxuIixoTW9kdWxlLHBlbSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglvcmRpbmFsCT0gKHVfc2hvcnQqKSAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gKHVfbG9uZyopICAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lCT0gKHVfY2hhciAqKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcndhcmQgPSBOVUxMOwoJcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwoJcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKSB7CgkJZm9yKGk9MDsgaTxleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspIHsKCQkJZW5hbWU9KGNoYXIqKVJWQSgqbmFtZSk7CgkJCWlmKCFzdHJjbXAoZW5hbWUsZnVuY05hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRyID0gZnVuY3Rpb25bKm9yZGluYWxdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKEZBUlBST0MzMilSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3J3YXJkID0gKGNoYXIgKilSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCQkJfQoJCQlvcmRpbmFsKys7CgkJCW5hbWUrKzsKCQl9Cgl9IGVsc2UgewoJCWlmIChMT1dPUkQoZnVuY05hbWUpLWV4cG9ydHMtPkJhc2UgPiBleHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucykgewoJCQlkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiCW9yZGluYWwgJWQgb3V0IG9mIHJhbmdlIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT1dPUkQoZnVuY05hbWUpKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoJCWFkZHIgPSBmdW5jdGlvblsoaW50KWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2VdOwoJCWlmICgoYWRkciA8IHJ2YV9zdGFydCkgfHwgKGFkZHIgPj0gcnZhX2VuZCkpCgkJCXJldHVybiAoRkFSUFJPQzMyKVJWQShhZGRyKTsKCQlmb3J3YXJkID0gKGNoYXIgKilSVkEoYWRkcik7Cgl9CglpZiAoZm9yd2FyZCkKICAgICAgICB7CgkJY2hhciBtb2R1bGVbMjU2XTsKCQljaGFyICplbmQgPSBzdHJjaHIoZm9yd2FyZCwgJy4nKTsKCQlpZiAoIWVuZCkgcmV0dXJuIE5VTEw7CgkJc3RybmNweShtb2R1bGUsIGZvcndhcmQsIChlbmQgLSBmb3J3YXJkKSk7CgkJbW9kdWxlW2VuZC1mb3J3YXJkXSA9IDA7CgkJcmV0dXJuIEdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUobW9kdWxlKSwgZW5kICsgMSk7Cgl9CglyZXR1cm4gTlVMTDsKfQoKdm9pZCAKZml4dXBfaW1wb3J0cyAoUERCMzIgKnByb2Nlc3MsUEVfTU9EUkVGICpwZW0sSE1PRFVMRTMyIGhNb2R1bGUpCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SCSpwZV9pbXA7CiAgICBpbnQJZml4dXBfZmFpbGVkCQk9IDA7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyCT0gcGVtLT5tb2R1bGU7CiAgICBpbnQJCQkJaTsKICAgIGNoYXIJCQkqbW9kbmFtZTsKICAgIAogICAgaWYgKHBlbS0+cGVfZXhwb3J0KQogICAgCW1vZG5hbWUgPSAoY2hhciopIFJWQShwZW0tPnBlX2V4cG9ydC0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIlxuRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIGlmICghcGVfaW1wKSAKICAgIAlmcHJpbnRmKHN0ZGVyciwibm8gaW1wb3J0IGRpcmVjdG9yeT8/Pz9cbiIpOwoKICAgIC8qIEZJWE1FOiBzaG91bGQgdGVybWluYXRlIG9uIDAgQ2hhcmFjdGVyaXN0aWNzICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKQoJaSsrOwoKICAgIC8qIGxvYWQgdGhlIGltcG9ydGVkIG1vZHVsZXMuIFRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgCiAgICAgKiBhZGRlZCB0byB0aGUgbW9kcmVmIGxpc3Qgb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KIAogICAgLyogRklYTUU6IHNob3VsZCB0ZXJtaW5hdGUgb24gMCBDaGFyYWN0ZXJpc3RpY3MgKi8KICAgIGZvciAoaSA9IDAsIHBlX2ltcCA9IHBlbS0+cGVfaW1wb3J0OyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKSB7CiAgICAJSE1PRFVMRTMyCXJlczsKCVBFX01PRFJFRgkqeHBlbSwqKnlwZW07CgoKIAljaGFyICpuYW1lID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CgoJLyogZG9uJ3QgdXNlIE1PRFVMRV9Mb2FkLCBXaW4zMiBjcmVhdGVzIG5ldyB0YXNrIGRpZmZlcmVudGx5ICovCglyZXMgPSBQRV9Mb2FkTGlicmFyeUV4MzJBKCBuYW1lLCAwLCAwICk7CglpZiAocmVzIDw9IChITU9EVUxFMzIpIDMyKSB7CgkgICAgY2hhciAqcCwgYnVmZmVyWzEwMjRdOwoKCSAgICAvKiBUcnkgd2l0aCBwcmVwZW5kaW5nIHRoZSBwYXRoIG9mIHRoZSBjdXJyZW50IG1vZHVsZSAqLwoJICAgIEdldE1vZHVsZUZpbGVOYW1lMzJBKCBoTW9kdWxlLCBidWZmZXIsIHNpemVvZiAoYnVmZmVyKSk7CgkgICAgaWYgKCEocCA9IHN0cnJjaHIgKGJ1ZmZlciwgJ1xcJykpKQoJCXAgPSBidWZmZXI7CgkgICAgc3RyY3B5IChwICsgMSwgbmFtZSk7CgkgICAgcmVzID0gUEVfTG9hZExpYnJhcnlFeDMyQSggYnVmZmVyLCAwLCAwICk7Cgl9CglpZiAocmVzIDw9IChITU9EVUxFMzIpIDMyKSB7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiTW9kdWxlICVzIG5vdCBmb3VuZFxuIiwgbmFtZSk7CgkgICAgZXhpdCAoMCk7Cgl9CglyZXMgPSBNT0RVTEVfSEFORExFdG9ITU9EVUxFMzIocmVzKTsKCXhwZW0gPSBwZW0tPm5leHQ7Cgl3aGlsZSAoeHBlbSkgewoJCWlmICh4cGVtLT5tb2R1bGUgPT0gcmVzKQoJCQlicmVhazsKCQl4cGVtID0geHBlbS0+bmV4dDsKCX0KCWlmICh4cGVtKSB7CgkJLyogaXQgaGFzIGJlZW4gbG9hZGVkICpCRUZPUkUqIHVzLCBzbyB3ZSBoYXZlIHRvIGluaXQKCQkgKiBpdCBiZWZvcmUgdXMuIHdlIGp1c3Qgc3dhcCB0aGUgdHdvIG1vZHVsZXMgd2hpY2ggc2hvdWxkCgkJICogd29yay4KCQkgKi8KCQkvKiB1bmxpbmsgeHBlbSBmcm9tIGNoYWluICovCgkJeXBlbSA9ICYocHJvY2Vzcy0+bW9kcmVmX2xpc3QpOwoJCXdoaWxlICgqeXBlbSkgewoJCQlpZiAoKCp5cGVtKT09eHBlbSkKCQkJCWJyZWFrOwoJCQl5cGVtID0gJigoKnlwZW0pLT5uZXh0KTsKCQl9CgkJKnlwZW0JCT0geHBlbS0+bmV4dDsKCgkJLyogbGluayBpdCBkaXJlY3RseSBiZWZvcmUgcGVtICovCgkJeXBlbQkJPSAmKHByb2Nlc3MtPm1vZHJlZl9saXN0KTsKCQl3aGlsZSAoKnlwZW0pIHsKCQkJaWYgKCgqeXBlbSk9PXBlbSkKCQkJCWJyZWFrOwoJCQl5cGVtID0gJigoKnlwZW0pLT5uZXh0KTsKCQl9CgkJKnlwZW0JCT0geHBlbTsKCQl4cGVtLT5uZXh0CT0gcGVtOwoJCQoJfQoJaSsrOwogICAgfQogICAgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7CiAgICB3aGlsZSAocGVfaW1wLT5OYW1lKSB7CgljaGFyCQkJKk1vZHVsZTsKCUlNQUdFX0lNUE9SVF9CWV9OQU1FCSpwZV9uYW1lOwoJTFBJTUFHRV9USFVOS19EQVRBCWltcG9ydF9saXN0LHRodW5rX2xpc3Q7CgoJTW9kdWxlID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CglkcHJpbnRmX3dpbjMyIChzdGRkZWIsICIlc1xuIiwgTW9kdWxlKTsKCgkvKiBGSVhNRTogZm9yd2FyZGVyIGVudHJpZXMgLi4uICovCgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayk7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiLS0tIE9yZGluYWwgJXMsJWRcbiIsIE1vZHVsZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSwoTFBDU1RSKW9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoTFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICItLS0gJXMgJXMuJWRcbiIsIHBlX25hbWUtPk5hbWUsIE1vZHVsZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoCgkJCQkJCU1PRFVMRV9GaW5kTW9kdWxlIChNb2R1bGUpLAoJCQkJCQlwZV9uYW1lLT5OYW1lKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgZHByaW50Zl93aW4zMihzdGRkZWIsIi0tLSBPcmRpbmFsICVzLiVkXG4iLE1vZHVsZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLAoJCQkJCQkgICAgIChMUENTVFIpIG9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oTFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLE1vZHVsZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLHBlX25hbWUtPk5hbWUpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJICAgIAlmcHJpbnRmKHN0ZGVyciwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CglwZV9pbXArKzsKICAgIH0KICAgIGlmIChmaXh1cF9mYWlsZWQpIGV4aXQoMSk7Cn0KCnN0YXRpYyBpbnQgY2FsY192bWFfc2l6ZSggSE1PRFVMRTMyIGhNb2R1bGUgKQp7CiAgICBpbnQgaSx2bWFfc2l6ZSA9IDA7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VnID0gUEVfU0VDVElPTlMoaE1vZHVsZSk7CgogICAgZHByaW50Zl93aW4zMihzdGRkZWIsICJEdW1wIG9mIHNlZ21lbnQgdGFibGVcbiIpOwogICAgZHByaW50Zl93aW4zMihzdGRkZWIsICIgICBOYW1lICAgIFZTeiAgVmFkZHIgICAgIFN6UmF3ICAgRmlsZWFkciAgKlJlbG9jICpMaW5ldW0gI1JlbG9jICNMaW51bSBDaGFyXG4iKTsKICAgIGZvciAoaSA9IDA7IGk8IFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyspCiAgICB7CiAgICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICIlOHM6ICU0LjRseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU0LjR4ICU0LjR4ICU4LjhseFxuIiwgCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+U2l6ZU9mUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmVsb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb0xpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZlJlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZkxpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5DaGFyYWN0ZXJpc3RpY3MpOwogICAgICAgIHZtYV9zaXplID0gTUFYKHZtYV9zaXplLCBwZV9zZWctPlZpcnR1YWxBZGRyZXNzK3BlX3NlZy0+U2l6ZU9mUmF3RGF0YSk7CiAgICAgICAgcGVfc2VnKys7CiAgICB9CiAgICByZXR1cm4gdm1hX3NpemU7Cn0KCnN0YXRpYyB2b2lkIGRvX3JlbG9jYXRpb25zKFBFX01PRFJFRiAqcGVtKQp7CiAgICBpbnQgZGVsdGEgPSBwZW0tPm1vZHVsZSAtIFBFX0hFQURFUihwZW0tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHI9IHBlbS0+bW9kdWxlOwoJSU1BR0VfQkFTRV9SRUxPQ0FUSU9OCQkqciA9IHBlbS0+cGVfcmVsb2M7CglpbnQJCQkJaGRlbHRhID0gKGRlbHRhID4+IDE2KSAmIDB4RkZGRjsKCWludAkJCQlsZGVsdGEgPSBkZWx0YSAmIDB4RkZGRjsKCgkvKiBpbnQgcmVsb2Nfc2l6ZSA9ICovCgoJaWYoZGVsdGEgPT0gMCkKCQkvKiBOb3RoaW5nIHRvIGRvICovCgkJcmV0dXJuOwoJd2hpbGUoci0+VmlydHVhbEFkZHJlc3MpCgl7CgkJY2hhciAqcGFnZSA9IChjaGFyKikgUlZBKHItPlZpcnR1YWxBZGRyZXNzKTsKCQlpbnQgY291bnQgPSAoci0+U2l6ZU9mQmxvY2sgLSA4KS8yOwoJCWludCBpOwoJCWRwcmludGZfZml4dXAoc3RkZGViLCAiJXggcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLAoJCQljb3VudCwgci0+VmlydHVhbEFkZHJlc3MpOwoJCS8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KCQlmb3IoaT0wO2k8Y291bnQ7aSsrKQoJCXsKCQkJaW50IG9mZnNldCA9IHItPlR5cGVPZmZzZXRbaV0gJiAweEZGRjsKCQkJaW50IHR5cGUgPSByLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwoJCQlkcHJpbnRmX2ZpeHVwKHN0ZGRlYiwicGF0Y2hpbmcgJXggdHlwZSAleFxuIiwgb2Zmc2V0LCB0eXBlKTsKCQkJc3dpdGNoKHR5cGUpCgkJCXsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfQUJTT0xVVEU6IGJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBoZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTE9XOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBsZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSExPVzoKI2lmIDEKCQkJCSooaW50KikocGFnZStvZmZzZXQpICs9IGRlbHRhOwojZWxzZQoJCQkJeyBpbnQgaD0qKHVuc2lnbmVkIHNob3J0KikocGFnZStvZmZzZXQpOwoJCQkJICBpbnQgbD1yLT5UeXBlT2Zmc2V0WysraV07CgkJCQkgICoodW5zaWduZWQgaW50KikocGFnZSArIG9mZnNldCkgPSAoaDw8MTYpICsgbCArIGRlbHRhOwoJCQkJfQojZW5kaWYKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJZnByaW50ZihzdGRlcnIsICJEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBJTUFHRV9SRUxfQkFTRURfSElHSEFESlxuIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTUlQU19KTVBBRERSOgoJCQkJZnByaW50ZihzdGRlcnIsICJJcyB0aGlzIGEgTUlQUyBtYWNoaW5lID8/P1xuIik7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBmaXh1cCB0eXBlXG4iKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXIgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKikoKGNoYXIqKXIgKyByLT5TaXplT2ZCbG9jayk7Cgl9Cn0KCQkKCgkKCQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICogCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yIAogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUzMiBwb2ludCB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpzdGF0aWMgSE1PRFVMRTMyIFBFX0xvYWRJbWFnZSggSEZJTEUzMiBoRmlsZSApCnsKICAgIEhNT0RVTEUzMiBoTW9kdWxlOwogICAgSEFORExFMzIgbWFwcGluZzsKCiAgICAvKiBtYXAgdGhlIFBFIGZpbGUgc29tZXdoZXJlICovCiAgICBtYXBwaW5nID0gQ3JlYXRlRmlsZU1hcHBpbmczMkEoIGhGaWxlLCBOVUxMLCBQQUdFX1JFQURPTkxZIHwgU0VDX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgTlVMTCApOwogICAgaWYgKCFtYXBwaW5nKQogICAgewogICAgICAgIGZwcmludGYoIHN0ZGVyciwgIlBFX0xvYWRJbWFnZTogQ3JlYXRlRmlsZU1hcHBpbmcgZXJyb3IgJWxkXG4iLAogICAgICAgICAgICAgICAgIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBoTW9kdWxlID0gKEhNT0RVTEUzMilNYXBWaWV3T2ZGaWxlKCBtYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggbWFwcGluZyApOwogICAgaWYgKCFoTW9kdWxlKQogICAgewogICAgICAgIGZwcmludGYoIHN0ZGVyciwgIlBFX0xvYWRJbWFnZTogTWFwVmlld09mRmlsZSBlcnJvciAlbGRcbiIsCiAgICAgICAgICAgICAgICAgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoUEVfSEVBREVSKGhNb2R1bGUpLT5TaWduYXR1cmUgIT0gSU1BR0VfTlRfU0lHTkFUVVJFKQogICAgewogICAgICAgIGZwcmludGYoc3RkZXJyLCJpbWFnZSBkb2Vzbid0IGhhdmUgUEUgc2lnbmF0dXJlLCBidXQgMHglMDhseFxuIiwKICAgICAgICAgICAgICAgIFBFX0hFQURFUihoTW9kdWxlKS0+U2lnbmF0dXJlICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk1hY2hpbmUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYpCiAgICB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsInRyeWluZyB0byBsb2FkIFBFIGltYWdlIGZvciB1bnN1cHBvcnRlZCBhcmNoaXRlY3R1cmUgKCIpOwogICAgICAgIHN3aXRjaCAoUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk1hY2hpbmUpCiAgICAgICAgewogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1VOS05PV046IGZwcmludGYoc3RkZXJyLCJVbmtub3duIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0k4NjA6ICAgIGZwcmludGYoc3RkZXJyLCJJODYwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IzMDAwOiAgIGZwcmludGYoc3RkZXJyLCJSMzAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SNDAwMDogICBmcHJpbnRmKHN0ZGVyciwiUjQwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjEwMDAwOiAgZnByaW50ZihzdGRlcnIsIlIxMDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9BTFBIQTogICBmcHJpbnRmKHN0ZGVyciwiQWxwaGEiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUE9XRVJQQzogZnByaW50ZihzdGRlcnIsIlBvd2VyUEMiKTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogZnByaW50ZihzdGRlcnIsIlVua25vd24tJTA0eCIsCiAgICAgICAgICAgICAgICAgICAgICAgICBQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTWFjaGluZSk7IGJyZWFrOwogICAgICAgIH0KICAgICAgICBmcHJpbnRmKHN0ZGVyciwiKVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIHJldHVybiBoTW9kdWxlOwoKZXJyb3I6CiAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoaXMgbWFwcyBhIGxvYWRlZCBQRSBkbGwgaW50byB0aGUgYWRkcmVzcyBzcGFjZSBvZiB0aGUgc3BlY2lmaWVkIHByb2Nlc3MuCiAqLwpzdGF0aWMgSE1PRFVMRTMyIFBFX01hcEltYWdlKCBITU9EVUxFMzIgaE1vZHVsZSwgUERCMzIgKnByb2Nlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9GU1RSVUNUICpvZnMsIERXT1JEIGZsYWdzICkKewoJUEVfTU9EUkVGCQkqcGVtOwoJaW50CQkJaSwgcmVzdWx0OwoJRFdPUkQJCQlsb2FkX2FkZHI7CglJTUFHRV9EQVRBX0RJUkVDVE9SWQlkaXI7CgljaGFyCQkJKm1vZG5hbWU7CglpbnQJCQl2bWFfc2l6ZTsKCiAgICAgICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlZzsKICAgICAgICBJTUFHRV9ET1NfSEVBREVSICpkb3NfaGVhZGVyID0gKElNQUdFX0RPU19IRUFERVIgKiloTW9kdWxlOwogICAgICAgIElNQUdFX05UX0hFQURFUlMgKm50X2hlYWRlciA9IFBFX0hFQURFUihoTW9kdWxlKTsKCQoJcGVtID0gKFBFX01PRFJFRiopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKCpwZW0pKTsKCS8qIE5PVEU6IGZpeHVwX2ltcG9ydHMgdGFrZXMgY2FyZSBvZiB0aGUgY29ycmVjdCBvcmRlciAqLwoJcGVtLT5uZXh0CT0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cglwcm9jZXNzLT5tb2RyZWZfbGlzdCA9IHBlbTsKCglpZiAoIShudF9oZWFkZXItPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpKQogICAgICAgIHsKCQlpZiAocHJvY2Vzcy0+ZXhlX21vZHJlZikKCQkJZnByaW50ZihzdGRlcnIsIm92ZXJ3cml0aW5nIG9sZCBleGVfbW9kcmVmLi4uIGFycmdoXG4iKTsKCQlwcm9jZXNzLT5leGVfbW9kcmVmID0gcGVtOwoJfQoKCWxvYWRfYWRkciA9IG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJdm1hX3NpemUgPSBjYWxjX3ZtYV9zaXplKCBoTW9kdWxlICk7CglkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkxvYWQgYWRkciBpcyAlbHhcbiIsbG9hZF9hZGRyKTsKCWxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoICh2b2lkKilsb2FkX2FkZHIsIHZtYV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CglpZiAobG9hZF9hZGRyID09IDApIHsKCQlsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCBOVUxMLCB2bWFfc2l6ZSwKCQkJCQkJIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKCQkJCQkJIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKCX0KCXBlbS0+bW9kdWxlID0gKEhNT0RVTEUzMilsb2FkX2FkZHI7CgoJZHByaW50Zl93aW4zMihzdGRkZWIsICJMb2FkIGFkZHIgaXMgcmVhbGx5ICVseCwgcmFuZ2UgJXhcbiIsCiAgICAgICAgICAgICAgICAgICAgICBsb2FkX2FkZHIsIHZtYV9zaXplKTsKCQogICAgICAgIC8qIFN0b3JlIHRoZSBOVCBoZWFkZXIgYXQgdGhlIGxvYWQgYWRkcgogICAgICAgICAqIChGSVhNRTogc2hvdWxkIHJlYWxseSB1c2UgbW1hcCkKICAgICAgICAgKi8KICAgICAgICAqKElNQUdFX0RPU19IRUFERVIgKilsb2FkX2FkZHIgPSAqZG9zX2hlYWRlcjsKICAgICAgICAqKElNQUdFX05UX0hFQURFUlMgKikobG9hZF9hZGRyICsgZG9zX2hlYWRlci0+ZV9sZmFuZXcpID0gKm50X2hlYWRlcjsKCiAgICAgICAgcGVfc2VnID0gUEVfU0VDVElPTlMoaE1vZHVsZSk7Cglmb3IgKGkgPSAwOyBpIDwgbnRfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKywgcGVfc2VnKyspCgl7CgkJLyogbWVtY3B5IG9ubHkgbm9uLUJTUyBzZWdtZW50cyAqLwoJCS8qIEZJWE1FOiB0aGlzIHNob3VsZCBiZSBkb25lIGJ5IG1tYXAoLi5NQVBfUFJJVkFURXxNQVBfRklYRUQuLikKCQkgKiBidXQgaXQgaXMgbm90IHBvc3NpYmxlIGZvciAoYXQgbGVhc3QpIExpbnV4IG5lZWRzCgkJICogYSBwYWdlLWFsaWduZWQgb2Zmc2V0LgoJCSAqLwoJCWlmKCEocGVfc2VnLT5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9TQ05fQ05UX1VOSU5JVElBTElaRURfREFUQSkpCgkJICAgIG1lbWNweSgoY2hhciopUlZBKHBlX3NlZy0+VmlydHVhbEFkZHJlc3MpLAoJCSAgICAJKGNoYXIqKShoTW9kdWxlICsgcGVfc2VnLT5Qb2ludGVyVG9SYXdEYXRhKSwKCQkJcGVfc2VnLT5TaXplT2ZSYXdEYXRhCgkJICAgICk7CgoJCXJlc3VsdCA9IFJWQSAocGVfc2VnLT5WaXJ0dWFsQWRkcmVzcyk7CiNpZiAxCgkJLyogbm90IG5lZWRlZCwgbWVtb3J5IGlzIHplcm8gKi8KCQlpZihzdHJjbXAocGVfc2VnLT5OYW1lLCAiLmJzcyIpID09IDApCgkJICAgIG1lbXNldCgodm9pZCAqKXJlc3VsdCwgMCwgCgkJCSAgIHBlX3NlZy0+TWlzYy5WaXJ0dWFsU2l6ZSA/CgkJCSAgIHBlX3NlZy0+TWlzYy5WaXJ0dWFsU2l6ZSA6CgkJCSAgIHBlX3NlZy0+U2l6ZU9mUmF3RGF0YSk7CiNlbmRpZgoKCQlpZihzdHJjbXAocGVfc2VnLT5OYW1lLCAiLmlkYXRhIikgPT0gMCkKCQkJcGVtLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgcmVzdWx0OwoKCQlpZihzdHJjbXAocGVfc2VnLT5OYW1lLCAiLmVkYXRhIikgPT0gMCkKCQkJcGVtLT5wZV9leHBvcnQgPSAoTFBJTUFHRV9FWFBPUlRfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIucnNyYyIpID09IDApCgkJCXBlbS0+cGVfcmVzb3VyY2UgPSAoTFBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5yZWxvYyIpID09IDApCgkJCXBlbS0+cGVfcmVsb2MgPSAoTFBJTUFHRV9CQVNFX1JFTE9DQVRJT04pIHJlc3VsdDsKCX0KCgkvKiBUaGVyZSBpcyB3b3JkIHRoYXQgdGhlIGFjdHVhbCBsb2FkZXIgZG9lcyBub3QgY2FyZSBhYm91dCB0aGUKCSAgIHNlY3Rpb24gbmFtZXMsIGFuZCBvbmx5IGdvZXMgZm9yIHRoZSBEYXRhRGlyZWN0b3J5ICovCglkaXI9bnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGVtLT5wZV9leHBvcnQgJiYgKGludClwZW0tPnBlX2V4cG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBleHBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCS8qIGFsd2F5cyB0cnVzdCB0aGUgZGlyZWN0b3J5ICovCgkJcGVtLT5wZV9leHBvcnQgPSAoTFBJTUFHRV9FWFBPUlRfRElSRUNUT1JZKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglkaXI9bnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlRdOwoJaWYoZGlyLlNpemUpCgl7CgkJLyogCgkJaWYocGVtLT5wZV9pbXBvcnQgJiYgKGludClwZW0tPnBlX2ltcG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBpbXBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCSAqLwoJCXBlbS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1JFU09VUkNFXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlbS0+cGVfcmVzb3VyY2UgJiYgKGludClwZW0tPnBlX3Jlc291cmNlIT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIHJlc291cmNlIGRpcmVjdG9yeT8/XG4iKTsKCQlwZW0tPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYQ0VQVElPTl0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCgoKCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQ107CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX3JlbG9jICYmIChpbnQpcGVtLT5wZV9yZWxvYyE9IFJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgcmVsb2NhdGlvbiBsaXN0Pz9cbiIpOwoJCXBlbS0+cGVfcmVsb2MgPSAodm9pZCAqKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPUFlSSUdIVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkNvcHlyaWdodCBzdHJpbmcgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9HTE9CQUxQVFJdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJHbG9iYWwgUG9pbnRlciAoTUlQUykgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFNdLlNpemUpCgkJIGZwcmludGYoc3RkbmltcCwiVGhyZWFkIGxvY2FsIHN0b3JhZ2UgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJR10uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkxvYWQgQ29uZmlndXJhdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CT1VORF9JTVBPUlRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzEzXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiVW5rbm93biBkaXJlY3RvcnkgMTMgaWdub3JlZFxuIik7CglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxNCBpZ25vcmVkXG4iKTsKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIpOwoKCWlmKHBlbS0+cGVfcmVsb2MpCWRvX3JlbG9jYXRpb25zKHBlbSk7CglpZihwZW0tPnBlX2V4cG9ydCkJZHVtcF9leHBvcnRzKHBlbS0+bW9kdWxlKTsKCWlmKHBlbS0+cGVfaW1wb3J0KQlmaXh1cF9pbXBvcnRzKHByb2Nlc3MscGVtLGhNb2R1bGUpOwogIAkJCglpZiAocGVtLT5wZV9leHBvcnQpCgkJbW9kbmFtZSA9IChjaGFyKilSVkEocGVtLT5wZV9leHBvcnQtPk5hbWUpOwoJZWxzZSB7CgkJY2hhciAqczsKCQltb2RuYW1lID0gcyA9IG9mcy0+c3pQYXRoTmFtZTsKCQl3aGlsZSAoKHM9c3RyY2hyKG1vZG5hbWUsJ1xcJykpKQoJCQltb2RuYW1lID0gcysxOwoJCWlmICgocz1zdHJjaHIobW9kbmFtZSwnLicpKSkKCQkJKnM9J1wwJzsKCX0KCiAgICAgICAgLyogTm93IHRoYXQgd2UgZ290IGV2ZXJ5dGhpbmcgYXQgdGhlIHJpZ2h0IGFkZHJlc3MsCiAgICAgICAgICogd2UgY2FuIHVubWFwIHRoZSBwcmV2aW91cyBtb2R1bGUgKi8KICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgICAgIHJldHVybiAoSE1PRFVMRTMyKWxvYWRfYWRkcjsKfQoKSElOU1RBTkNFMTYgTU9EVUxFX0NyZWF0ZUluc3RhbmNlKEhNT0RVTEUxNiBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKiAgICAgICAgaW50ZXJuYWwgbW9kdWxlIGhhbmRsaW5nIHNob3VsZCBiZSBtYWRlIGJldHRlciBoZXJlIChhbmQgaW4gYnVpbHRpbi5jKQogKi8KSE1PRFVMRTMyIFBFX0xvYWRMaWJyYXJ5RXgzMkEgKExQQ1NUUiBuYW1lLCBIRklMRTMyIGhGaWxlLCBEV09SRCBmbGFncykgewoJT0ZTVFJVQ1QJb2ZzOwoJSE1PRFVMRTMyCWhNb2R1bGU7CglORV9NT0RVTEUJKnBNb2R1bGU7CglQRV9NT0RSRUYJKnBlbTsKCglpZiAoKGhNb2R1bGUgPSBNT0RVTEVfRmluZE1vZHVsZSggbmFtZSApKSkgewoJCS8qIHRoZSAuRExMIGlzIGVpdGhlciBsb2FkZWQgb3IgaW50ZXJuYWwgKi8KCQloTW9kdWxlID0gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKGhNb2R1bGUpOwoJCWlmICghSElXT1JEKGhNb2R1bGUpKSAvKiBpbnRlcm5hbCAob3IgYmFkKSAqLwoJCQlyZXR1cm4gaE1vZHVsZTsKCQkvKiBjaGVjayBpZiB0aGlzIG1vZHVsZSBpcyBhbHJlYWR5IG1hcHBlZCAqLwoJCXBlbSAJPSBwQ3VycmVudFByb2Nlc3MtPm1vZHJlZl9saXN0OwoJCXdoaWxlIChwZW0pIHsKCQkJaWYgKHBlbS0+bW9kdWxlID09IGhNb2R1bGUpIHJldHVybiBoTW9kdWxlOwoJCQlwZW0gPSBwZW0tPm5leHQ7CgkJfQoJCXBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKGhNb2R1bGUpOwoJCWlmIChwTW9kdWxlLT5mbGFncyAmIE5FX0ZGTEFHU19CVUlMVElOKSB7CgkJCVBEQjMyCSpwcm9jZXNzID0gcEN1cnJlbnRQcm9jZXNzOwoJCQlJTUFHRV9ET1NfSEVBREVSCSpkaDsKCQkJSU1BR0VfTlRfSEVBREVSUwkqbmg7CgkJCUlNQUdFX1NFQ1RJT05fSEVBREVSCSpzaDsKCgkJCS8qIHdlIG9ubHkgY29tZSBoZXJlIGlmIHdlIGFscmVhZHkgaGF2ZSAnbG9hZGVkJyB0aGUKCQkJICogaW50ZXJuYWwgZGxsIGJ1dCBpbiBhbm90aGVyIHByb2Nlc3MuIEp1c3QgY3JlYXRlCgkJCSAqIGEgUEVfTU9EUkVGIGFuZCByZXR1cm4uCgkJCSAqLwoJCQlwZW0gPSAoUEVfTU9EUkVGKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKCQkJCUhFQVBfWkVST19NRU1PUlksc2l6ZW9mKCpwZW0pKTsKCQkJcGVtLT5tb2R1bGUgCSAgICAgPSBoTW9kdWxlOwoJCQlkaCA9IChJTUFHRV9ET1NfSEVBREVSKilwZW0tPm1vZHVsZTsKCQkJbmggPSAoSU1BR0VfTlRfSEVBREVSUyopKGRoKzEpOwoJCQlzaCA9IChJTUFHRV9TRUNUSU9OX0hFQURFUiopKG5oKzEpOwoJCQlwZW0tPnBlX2V4cG9ydAkgICAgID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkqKShzaCsyKTsKCQkJcGVtLT5uZXh0CSAgICAgPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCQkJcHJvY2Vzcy0+bW9kcmVmX2xpc3QgPSBwZW07CgkJCXJldHVybiBoTW9kdWxlOwoJCX0KCX0gZWxzZSB7CgoJCS8qIHRyeSB0byBsb2FkIGJ1aWx0aW4sIGVuYWJsZWQgbW9kdWxlcyBmaXJzdCAqLwoJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU5fTG9hZE1vZHVsZSggbmFtZSwgRkFMU0UgKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1PRFVMRV9IQU5ETEV0b0hNT0RVTEUzMiggaE1vZHVsZSApOwoKCQkvKiB0cnkgdG8gb3BlbiB0aGUgc3BlY2lmaWVkIGZpbGUgKi8KCQlpZiAoSEZJTEVfRVJST1IzMj09KGhGaWxlPU9wZW5GaWxlMzIobmFtZSwmb2ZzLE9GX1JFQUQpKSkgewoJCQkvKiBOb3cgdHJ5IHRoZSBidWlsdC1pbiBldmVuIGlmIGRpc2FibGVkICovCgkJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU5fTG9hZE1vZHVsZSggbmFtZSwgVFJVRSApKSkgewoJCQkJZnByaW50Ziggc3RkZXJyLCAiV2FybmluZzogY291bGQgbm90IGxvYWQgV2luZG93cyBETEwgJyVzJywgdXNpbmcgYnVpbHQtaW4gbW9kdWxlLlxuIiwgbmFtZSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBNT0RVTEVfSEFORExFdG9ITU9EVUxFMzIoIGhNb2R1bGUgKTsKCQkJfQoJCQlyZXR1cm4gMTsKCQl9CgkJaWYgKChoTW9kdWxlID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCAmb2ZzICkpIDwgMzIpIHsKCQkJX2xjbG9zZTMyKGhGaWxlKTsKCQkJcmV0dXJuIGhNb2R1bGU7CgkJfQoJCXBNb2R1bGUJCT0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZSApOwoJCXBNb2R1bGUtPmZsYWdzCT0gTkVfRkZMQUdTX1dJTjMyOwoJCXBNb2R1bGUtPm1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSApOwoJCUNsb3NlSGFuZGxlKCBoRmlsZSApOwoJCWlmIChwTW9kdWxlLT5tb2R1bGUzMiA8IDMyKSByZXR1cm4gMjE7Cgl9CgkvKiByZWN1cnNlICovCglwTW9kdWxlLT5tb2R1bGUzMiA9IFBFX01hcEltYWdlKCBwTW9kdWxlLT5tb2R1bGUzMiwgcEN1cnJlbnRQcm9jZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvZnMsZmxhZ3MpOwoJcmV0dXJuIHBNb2R1bGUtPm1vZHVsZTMyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTG9hZCB0aGUgUEUgbWFpbiAuRVhFLiBBbGwgb3RoZXIgbG9hZGluZyBpcyBkb25lIGJ5IFBFX0xvYWRMaWJyYXJ5RXgzMkEKICogRklYTUU6IHRoaXMgZnVuY3Rpb24gc2hvdWxkIHVzZSBQRV9Mb2FkTGlicmFyeUV4MzJBLCBidXQgY3VycmVudGx5IGNhbid0CiAqIGR1ZSB0byB0aGUgVEFTS19DcmVhdGVUYXNrIHN0dWZmLgogKi8KSElOU1RBTkNFMTYgUEVfTG9hZE1vZHVsZSggSEZJTEUzMiBoRmlsZSwgT0ZTVFJVQ1QgKm9mcywgTE9BRFBBUkFNUyogcGFyYW1zICkKewogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKICAgIEhNT0RVTEUzMiBoTW9kdWxlMzI7CiAgICBISU5TVEFOQ0UxNiBoSW5zdGFuY2U7CiAgICBORV9NT0RVTEUgKnBNb2R1bGU7CgogICAgaWYgKChoTW9kdWxlMTYgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIG9mcyApKSA8IDMyKSByZXR1cm4gaE1vZHVsZTE2OwogICAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwogICAgcE1vZHVsZS0+ZmxhZ3MgPSBORV9GRkxBR1NfV0lOMzI7CgogICAgcE1vZHVsZS0+bW9kdWxlMzIgPSBoTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlICk7CiAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKICAgIGlmIChoTW9kdWxlMzIgPCAzMikgcmV0dXJuIDIxOwoKICAgIGhJbnN0YW5jZSA9IE1PRFVMRV9DcmVhdGVJbnN0YW5jZSggaE1vZHVsZTE2LCBwYXJhbXMgKTsKICAgIGlmICghKFBFX0hFQURFUihoTW9kdWxlMzIpLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSkKICAgIHsKICAgICAgICBUQVNLX0NyZWF0ZVRhc2soIGhNb2R1bGUxNiwgaEluc3RhbmNlLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT5oRW52aXJvbm1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAoTFBTVFIpUFRSX1NFR19UT19MSU4oIHBhcmFtcy0+Y21kTGluZSApLAogICAgICAgICAgICAgICAgICAgICAgICAgKigoV09SRCopUFRSX1NFR19UT19MSU4ocGFyYW1zLT5zaG93Q21kKSArIDEpICk7CiAgICB9CiAgICBwTW9kdWxlLT5tb2R1bGUzMiA9IFBFX01hcEltYWdlKCBoTW9kdWxlMzIsIHBDdXJyZW50UHJvY2Vzcywgb2ZzLCAwICk7CiAgICByZXR1cm4gaEluc3RhbmNlOwp9CgppbnQgUEVfVW5sb2FkSW1hZ2UoIEhNT0RVTEUzMiBoTW9kdWxlICkKewoJcHJpbnRmKCJQRXVubG9hZEltYWdlKCkgY2FsbGVkIVxuIik7CgkvKiBmcmVlIHJlc291cmNlcywgaW1hZ2UsIHVubWFwICovCglyZXR1cm4gMTsKfQoKLyogQ2FsbGVkIGlmIHRoZSBsaWJyYXJ5IGlzIGxvYWRlZCBvciBmcmVlZC4KICogTk9URTogaWYgYSB0aHJlYWQgYXR0YWNoZXMgYSBETEwsIHRoZSBjdXJyZW50IHRocmVhZCB3aWxsIG9ubHkgZG8KICogRExMX1BST0NFU1NfQVRUQUNILiBPbmx5IG5ldyBjcmVhdGVkIHRocmVhZHMgZG8gRExMX1RIUkVBRF9BVFRBQ0gKICogKFNESykKICovCnN0YXRpYyB2b2lkIFBFX0luaXRETEwoUEVfTU9EUkVGICpwZW0sIERXT1JEIHR5cGUsTFBWT0lEIGxwUmVzZXJ2ZWQpCnsKICAgIGlmICh0eXBlPT1ETExfUFJPQ0VTU19BVFRBQ0gpCglwZW0tPmZsYWdzIHw9IFBFX01PRFJFRl9QUk9DRVNTX0FUVEFDSEVEOwoKICAgIC8qICBETExfQVRUQUNIX1BST0NFU1M6CiAgICAgKgkJbHByZXNlcnZlZCBpcyBOVUxMIGZvciBkeW5hbWljIGxvYWRzLCBub3QtTlVMTCBmb3Igc3RhdGljIGxvYWRzCiAgICAgKiAgRExMX0RFVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBpZiBjYWxsZWQgYnkgRnJlZUxpYnJhcnksIG5vdC1OVUxMIG90aGVyd2lzZQogICAgICogIHRoZSBTREsgZG9lc24ndCBtZW50aW9uIGFueXRoaW5nIGZvciBETExfVEhSRUFEXyoKICAgICAqLwogICAgICAgIAogICAgLyogSXMgdGhpcyBhIGxpYnJhcnk/IEFuZCBoYXMgaXQgZ290IGFuIGVudHJ5cG9pbnQ/ICovCiAgICBpZiAoKFBFX0hFQURFUihwZW0tPm1vZHVsZSktPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCiAgICAgICAgKFBFX0hFQURFUihwZW0tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICApIHsKICAgICAgICBGQVJQUk9DMzIgZW50cnkgPSAoRkFSUFJPQzMyKVJWQV9QVFIoIHBlbS0+bW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICk7CiAgICAgICAgZHByaW50Zl9yZWxheSggc3RkZGViLCAiQ2FsbFRvMzIoZW50cnlwcm9jPSVwLG1vZHVsZT0lMDh4LHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIHBlbS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICAgICAgZW50cnkoIHBlbS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICB9Cn0KCi8qIENhbGwgdGhlIERMTGVudHJ5IGZ1bmN0aW9uIG9mIGFsbCBkbGxzIHVzZWQgYnkgdGhhdCBwcm9jZXNzLgogKiAoTk9URTogdGhpcyBtYXkgcmVjdXJzaXZlbHkgY2FsbCB0aGlzIGZ1bmN0aW9uIChpZiBhIGxpYnJhcnkgY2FsbHMKICogTG9hZExpYnJhcnkpIC4uLiBidXQgaXQgd29uJ3QgbWF0dGVyKQogKi8Kdm9pZCBQRV9Jbml0aWFsaXplRExMcyhQREIzMiAqcHJvY2VzcyxEV09SRCB0eXBlLExQVk9JRCBscFJlc2VydmVkKSB7CglQRV9NT0RSRUYJKnBlbTsKCglwZW0gPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCXdoaWxlIChwZW0pIHsKCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9OT19ETExfQ0FMTFMpIHsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHR5cGU9PURMTF9QUk9DRVNTX0FUVEFDSCkgewoJCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9QUk9DRVNTX0FUVEFDSEVEKSB7CgkJCQlwZW0gPSBwZW0tPm5leHQ7CgkJCQljb250aW51ZTsKCQkJfQoJCX0KCQlQRV9Jbml0RExMKCBwZW0sIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKCQlwZW0gPSBwZW0tPm5leHQ7Cgl9Cn0KCnZvaWQgUEVfSW5pdFRscyhQREIzMiAqcGRiKQp7CgkvKiBGSVhNRTogdGxzIGNhbGxiYWNrcyA/Pz8gKi8KCVBFX01PRFJFRgkJKnBlbTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZSxpbmRleDsKCUxQVk9JRAkJCW1lbTsKCUxQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwoKCXBlbSA9IHBkYi0+bW9kcmVmX2xpc3Q7Cgl3aGlsZSAocGVtKSB7CgkJcGVoID0gUEVfSEVBREVSKHBlbS0+bW9kdWxlKTsKCQlpZiAoIXBlaC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykgewoJCQlwZW0gPSBwZW0tPm5leHQ7CgkJCWNvbnRpbnVlOwoJCX0KCQlwZGlyID0gKExQVk9JRCkocGVtLT5tb2R1bGUgKyBwZWgtPk9wdGlvbmFsSGVhZGVyLgoJCQlEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKCQlpbmRleAk9IFRsc0FsbG9jKCk7CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sKExQVk9JRCkgcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhLCBkYXRhc2l6ZSk7CgkJVGxzU2V0VmFsdWUoaW5kZXgsbWVtKTsKCQkqKHBkaXItPkFkZHJlc3NPZkluZGV4KT1pbmRleDsgICAKCQlwZW09cGVtLT5uZXh0OwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyAoS0VSTkVMMzIuNzQpCiAqIERvbid0IGNhbGwgRGxsRW50cnlQb2ludCBmb3IgRExMX1RIUkVBRF97QVRUQUNILERFVEFDSH0gaWYgc2V0LgogKi8KQk9PTDMyIFdJTkFQSSBEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzKEhNT0RVTEUzMiBoTW9kdWxlKQp7CglQREIzMgkqcHJvY2VzcyA9IHBDdXJyZW50UHJvY2VzczsKCVBFX01PRFJFRgkqcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7CgoJd2hpbGUgKHBlbSkgewoJCWlmIChwZW0tPm1vZHVsZSA9PSBoTW9kdWxlKQoJCQlwZW0tPmZsYWdzfD1QRV9NT0RSRUZfTk9fRExMX0NBTExTOwoJCXBlbSA9IHBlbS0+bmV4dDsKCX0KCXJldHVybiBUUlVFOwp9Cgo=