LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYgICAgTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInBlX2ltYWdlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKCnN0YXRpYyB2b2lkIFBFX0luaXRETEwoUEVfTU9EUkVGKiBtb2RyZWYsIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkKTsKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodW5zaWduZWQgaW50KWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFMzIgaE1vZHVsZSApCnsgCiAgY2hhcgkJKk1vZHVsZTsKICBpbnQJCWksIGo7CiAgdV9zaG9ydAkqb3JkaW5hbDsKICB1X2xvbmcJKmZ1bmN0aW9uLCpmdW5jdGlvbnM7CiAgdV9jaGFyCSoqbmFtZTsKICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gaE1vZHVsZTsKCiAgRFdPUkQgcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CiAgRFdPUkQgcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0cyA9IChJTUFHRV9FWFBPUlRfRElSRUNUT1JZKilSVkEocnZhX3N0YXJ0KTsKCiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiXG4qKioqKioqRVhQT1JUIERBVEEqKioqKioqXG5Nb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKCSBNb2R1bGUsCgkgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsCgkgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiIE9yZCAgICBSVkEgICAgIEFkZHIgICBOYW1lXG4iICk7CiAgZm9yIChpPTA7aTxwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucztpKyssIGZ1bmN0aW9uKyspCiAgewogICAgICBpZiAoISpmdW5jdGlvbikgY29udGludWU7ICAvKiBObyBzdWNoIGZ1bmN0aW9uICovCiAgICAgIGRwcmludGZfd2luMzIoIHN0ZGRlYiwiJTRsZCAlMDhseCAlMDh4IiwKICAgICAgICAgICAgICAgICAgICAgaSArIHBlX2V4cG9ydHMtPkJhc2UsICpmdW5jdGlvbiwgUlZBKCpmdW5jdGlvbikgKTsKICAgICAgLyogQ2hlY2sgaWYgd2UgaGF2ZSBhIG5hbWUgZm9yIGl0ICovCiAgICAgIGZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQogICAgICAgICAgICAgIGRwcmludGZfd2luMzIoIHN0ZGRlYiwgIiAgJXMiLCAoY2hhciopUlZBKG5hbWVbal0pICk7CiAgICAgIGlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfZW5kKSkKCSAgZHByaW50Zl93aW4zMihzdGRkZWIsICIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKICAgICAgZHByaW50Zl93aW4zMiggc3RkZGViLCJcbiIgKTsKICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnRsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgTmFtZSBsaXN0LiAKICoJLSBsb29rIHVwIHRoZSBvcmRpbmFsIHdpdGggdGhhdCBpbmRleC4KICoJLSB1c2UgdGhlIG9yZGluYWwgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKiBJZiBpdCBpcyBhIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICovCkZBUlBST0MzMiBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggSE1PRFVMRTMyIGhNb2R1bGUsIExQQ1NUUiBmdW5jTmFtZSkKewoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAJCSpleHBvcnRzOwoJdW5zaWduZWQJCQlsb2FkX2FkZHI7Cgl1X3Nob3J0CQkJCSogb3JkaW5hbDsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZTsKCWludAkJCQlpOwoJUERCMzIJCQkJKnByb2Nlc3M9UFJPQ0VTU19DdXJyZW50KCk7CglQRV9NT0RSRUYJCQkqcGVtOwoJdV9sb25nCQkJCXJ2YV9zdGFydCwgcnZhX2VuZCwgYWRkcjsKCWNoYXIJCQkJKiBmb3J3YXJkOwoKCXBlbSA9IHByb2Nlc3MtPm1vZHJlZl9saXN0OwoJd2hpbGUgKHBlbSAmJiAocGVtLT5tb2R1bGUgIT0gaE1vZHVsZSkpCgkJcGVtPXBlbS0+bmV4dDsKCWlmICghcGVtKSB7CgkJZnByaW50ZihzdGRlcnIsIk5vIE1PRFJFRiBmb3VuZCBmb3IgUEVfTU9EVUxFICUwOHggaW4gcHJvY2VzcyAlcFxuIixoTW9kdWxlLHByb2Nlc3MpOwoJCXJldHVybiBOVUxMOwoJfQoJbG9hZF9hZGRyID0gaE1vZHVsZTsKCWV4cG9ydHMgICA9IHBlbS0+cGVfZXhwb3J0OwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpIHsKCQlmcHJpbnRmKHN0ZGVyciwiTW9kdWxlICUwOHgvTU9EUkVGICVwIGRvZXNuJ3QgaGF2ZSBhIGV4cG9ydHMgdGFibGUuXG4iLGhNb2R1bGUscGVtKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW9yZGluYWwJPSAodV9zaG9ydCopICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSAodV9sb25nKikgICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUJPSAodV9jaGFyICoqKSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yd2FyZCA9IE5VTEw7CglydmFfc3RhcnQgPSBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CglydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpIHsKCQlmb3IoaT0wOyBpPGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykgewoJCQllbmFtZT0oY2hhciopUlZBKCpuYW1lKTsKCQkJaWYoIXN0cmNtcChlbmFtZSxmdW5jTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHIgPSBmdW5jdGlvblsqb3JkaW5hbF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGFkZHIgPCBydmFfc3RhcnQpIHx8IChhZGRyID49IHJ2YV9lbmQpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoRkFSUFJPQzMyKVJWQShhZGRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcndhcmQgPSAoY2hhciAqKVJWQShhZGRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJCQl9CgkJCW9yZGluYWwrKzsKCQkJbmFtZSsrOwoJCX0KCX0gZWxzZSB7CgkJaWYgKExPV09SRChmdW5jTmFtZSktZXhwb3J0cy0+QmFzZSA+IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKSB7CgkJCWRwcmludGZfd2luMzIoc3RkZGViLCIJb3JkaW5hbCAlZCBvdXQgb2YgcmFuZ2UhXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPV09SRChmdW5jTmFtZSkpOwoJCQlyZXR1cm4gTlVMTDsKCQl9CgkJYWRkciA9IGZ1bmN0aW9uWyhpbnQpZnVuY05hbWUtZXhwb3J0cy0+QmFzZV07CgkJaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKCQkJcmV0dXJuIChGQVJQUk9DMzIpUlZBKGFkZHIpOwoJCWZvcndhcmQgPSAoY2hhciAqKVJWQShhZGRyKTsKCX0KCWlmIChmb3J3YXJkKQogICAgICAgIHsKCQljaGFyIG1vZHVsZVsyNTZdOwoJCWNoYXIgKmVuZCA9IHN0cmNocihmb3J3YXJkLCAnLicpOwoJCWlmICghZW5kKSByZXR1cm4gTlVMTDsKCQlzdHJuY3B5KG1vZHVsZSwgZm9yd2FyZCwgKGVuZCAtIGZvcndhcmQpKTsKCQltb2R1bGVbZW5kLWZvcndhcmRdID0gMDsKCQlyZXR1cm4gR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShtb2R1bGUpLCBlbmQgKyAxKTsKCX0KCXJldHVybiBOVUxMOwp9Cgp2b2lkIApmaXh1cF9pbXBvcnRzIChQREIzMiAqcHJvY2VzcyxQRV9NT0RSRUYgKnBlbSxITU9EVUxFMzIgaE1vZHVsZSkKewogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IJKnBlX2ltcDsKICAgIGludAlmaXh1cF9mYWlsZWQJCT0gMDsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIJPSBwZW0tPm1vZHVsZTsKICAgIGludAkJCQlpOwogICAgY2hhcgkJCSptb2RuYW1lOwogICAgCiAgICBpZiAocGVtLT5wZV9leHBvcnQpCiAgICAJbW9kbmFtZSA9IChjaGFyKikgUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKTsKICAgIGVsc2UKICAgICAgICBtb2RuYW1lID0gIjx1bmtub3duPiI7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiXG5EdW1waW5nIGltcG9ydHMgbGlzdFxuIik7CgogICAgLyogZmlyc3QsIGNvdW50IHRoZSBudW1iZXIgb2YgaW1wb3J0ZWQgbm9uLWludGVybmFsIG1vZHVsZXMgKi8KICAgIHBlX2ltcCA9IHBlbS0+cGVfaW1wb3J0OwogICAgaWYgKCFwZV9pbXApIAogICAgCWZwcmludGYoc3RkZXJyLCJubyBpbXBvcnQgZGlyZWN0b3J5Pz8/P1xuIik7CgogICAgLyogRklYTUU6IHNob3VsZCB0ZXJtaW5hdGUgb24gMCBDaGFyYWN0ZXJpc3RpY3MgKi8KICAgIGZvciAoaSA9IDA7IHBlX2ltcC0+TmFtZTsgcGVfaW1wKyspCglpKys7CgogICAgLyogbG9hZCB0aGUgaW1wb3J0ZWQgbW9kdWxlcy4gVGhleSBhcmUgYXV0b21hdGljYWxseSAKICAgICAqIGFkZGVkIHRvIHRoZSBtb2RyZWYgbGlzdCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwogCiAgICAvKiBGSVhNRTogc2hvdWxkIHRlcm1pbmF0ZSBvbiAwIENoYXJhY3RlcmlzdGljcyAqLwogICAgZm9yIChpID0gMCwgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7IHBlX2ltcC0+TmFtZTsgcGVfaW1wKyspIHsKICAgIAlITU9EVUxFMzIJcmVzOwoJUEVfTU9EUkVGCSp4cGVtLCoqeXBlbTsKCgogCWNoYXIgKm5hbWUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKCgkvKiBkb24ndCB1c2UgTU9EVUxFX0xvYWQsIFdpbjMyIGNyZWF0ZXMgbmV3IHRhc2sgZGlmZmVyZW50bHkgKi8KCXJlcyA9IFBFX0xvYWRMaWJyYXJ5RXgzMkEoIG5hbWUsIDAsIDAgKTsKCWlmIChyZXMgPD0gKEhNT0RVTEUzMikgMzIpIHsKCSAgICBjaGFyICpwLCBidWZmZXJbMTAyNF07CgoJICAgIC8qIFRyeSB3aXRoIHByZXBlbmRpbmcgdGhlIHBhdGggb2YgdGhlIGN1cnJlbnQgbW9kdWxlICovCgkgICAgR2V0TW9kdWxlRmlsZU5hbWUzMkEoIGhNb2R1bGUsIGJ1ZmZlciwgc2l6ZW9mIChidWZmZXIpKTsKCSAgICBpZiAoIShwID0gc3RycmNociAoYnVmZmVyLCAnXFwnKSkpCgkJcCA9IGJ1ZmZlcjsKCSAgICBzdHJjcHkgKHAgKyAxLCBuYW1lKTsKCSAgICByZXMgPSBQRV9Mb2FkTGlicmFyeUV4MzJBKCBidWZmZXIsIDAsIDAgKTsKCX0KCWlmIChyZXMgPD0gKEhNT0RVTEUzMikgMzIpIHsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJNb2R1bGUgJXMgbm90IGZvdW5kXG4iLCBuYW1lKTsKCSAgICBleGl0ICgwKTsKCX0KCXJlcyA9IE1PRFVMRV9IQU5ETEV0b0hNT0RVTEUzMihyZXMpOwoJeHBlbSA9IHBlbS0+bmV4dDsKCXdoaWxlICh4cGVtKSB7CgkJaWYgKHhwZW0tPm1vZHVsZSA9PSByZXMpCgkJCWJyZWFrOwoJCXhwZW0gPSB4cGVtLT5uZXh0OwoJfQoJaWYgKHhwZW0pIHsKCQkvKiBpdCBoYXMgYmVlbiBsb2FkZWQgKkJFRk9SRSogdXMsIHNvIHdlIGhhdmUgdG8gaW5pdAoJCSAqIGl0IGJlZm9yZSB1cy4gd2UganVzdCBzd2FwIHRoZSB0d28gbW9kdWxlcyB3aGljaCBzaG91bGQKCQkgKiB3b3JrLgoJCSAqLwoJCS8qIHVubGluayB4cGVtIGZyb20gY2hhaW4gKi8KCQl5cGVtID0gJihwcm9jZXNzLT5tb2RyZWZfbGlzdCk7CgkJd2hpbGUgKCp5cGVtKSB7CgkJCWlmICgoKnlwZW0pPT14cGVtKQoJCQkJYnJlYWs7CgkJCXlwZW0gPSAmKCgqeXBlbSktPm5leHQpOwoJCX0KCQkqeXBlbQkJPSB4cGVtLT5uZXh0OwoKCQkvKiBsaW5rIGl0IGRpcmVjdGx5IGJlZm9yZSBwZW0gKi8KCQl5cGVtCQk9ICYocHJvY2Vzcy0+bW9kcmVmX2xpc3QpOwoJCXdoaWxlICgqeXBlbSkgewoJCQlpZiAoKCp5cGVtKT09cGVtKQoJCQkJYnJlYWs7CgkJCXlwZW0gPSAmKCgqeXBlbSktPm5leHQpOwoJCX0KCQkqeXBlbQkJPSB4cGVtOwoJCXhwZW0tPm5leHQJPSBwZW07CgkJCgl9CglpKys7CiAgICB9CiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIHdoaWxlIChwZV9pbXAtPk5hbWUpIHsKCWNoYXIJCQkqTW9kdWxlOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglMUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKCglNb2R1bGUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKCWRwcmludGZfd2luMzIgKHN0ZGRlYiwgIiVzXG4iLCBNb2R1bGUpOwoKCS8qIEZJWE1FOiBmb3J3YXJkZXIgZW50cmllcyAuLi4gKi8KCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rKTsKCSAgICB0aHVua19saXN0ID0gKExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgoJICAgIHdoaWxlIChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICItLS0gT3JkaW5hbCAlcywlZFxuIiwgTW9kdWxlLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLChMUENTVFIpb3JkaW5hbCk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJZnByaW50ZihzdGRlcnIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBvcmRpbmFsKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9IGVsc2UgewkJLyogaW1wb3J0IGJ5IG5hbWUgKi8KCQkgICAgcGVfbmFtZSA9IChMUElNQUdFX0lNUE9SVF9CWV9OQU1FKVJWQShpbXBvcnRfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMigKCQkJCQkJTU9EVUxFX0ZpbmRNb2R1bGUgKE1vZHVsZSksCgkJCQkJCXBlX25hbWUtPk5hbWUpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9CgkJaW1wb3J0X2xpc3QrKzsKCQl0aHVua19saXN0Kys7CgkgICAgfQoJfSBlbHNlIHsJLyogQm9ybGFuZCBzdHlsZSAqLwoJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIkJvcmxhbmQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICB0aHVua19saXN0ID0gKExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgkgICAgd2hpbGUgKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIC8qIG5vdCBzdXJlIGFib3V0IHRoaXMgYnJhbmNoLCBidXQgaXQgc2VlbXMgdG8gd29yayAqLwoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiLS0tIE9yZGluYWwgJXMuJWRcbiIsTW9kdWxlLG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClHZXRQcm9jQWRkcmVzczMyKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSksCgkJCQkJCSAgICAgKExQQ1NUUikgb3JkaW5hbCk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJZnByaW50ZihzdGRlcnIsICJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSxvcmRpbmFsKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBwZV9uYW1lPShMUElNQUdFX0lNUE9SVF9CWV9OQU1FKSBSVkEodGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIGRwcmludGZfd2luMzIoc3RkZGViLCItLS0gJXMgJXMuJWRcbiIsCgkJICAgCQkgIHBlX25hbWUtPk5hbWUsTW9kdWxlLHBlX25hbWUtPkhpbnQpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClHZXRQcm9jQWRkcmVzczMyKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSkscGVfbmFtZS0+TmFtZSk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCWZwcmludGYoc3RkZXJyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwoJCSAgICAJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0KCXBlX2ltcCsrOwogICAgfQogICAgaWYgKGZpeHVwX2ZhaWxlZCkgZXhpdCgxKTsKfQoKc3RhdGljIGludCBjYWxjX3ZtYV9zaXplKCBITU9EVUxFMzIgaE1vZHVsZSApCnsKICAgIGludCBpLHZtYV9zaXplID0gMDsKICAgIElNQUdFX1NFQ1RJT05fSEVBREVSICpwZV9zZWcgPSBQRV9TRUNUSU9OUyhoTW9kdWxlKTsKCiAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIiAgIE5hbWUgICAgVlN6ICBWYWRkciAgICAgU3pSYXcgICBGaWxlYWRyICAqUmVsb2MgKkxpbmV1bSAjUmVsb2MgI0xpbnVtIENoYXJcbiIpOwogICAgZm9yIChpID0gMDsgaTwgUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKICAgIHsKICAgICAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIiU4czogJTQuNGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTQuNHggJTQuNHggJTguOGx4XG4iLCAKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk1pc2MuVmlydHVhbFNpemUsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlZpcnR1YWxBZGRyZXNzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5TaXplT2ZSYXdEYXRhLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9SYXdEYXRhLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9SZWxvY2F0aW9ucywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvTGluZW51bWJlcnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk51bWJlck9mUmVsb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk51bWJlck9mTGluZW51bWJlcnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPkNoYXJhY3RlcmlzdGljcyk7CiAgICAgICAgdm1hX3NpemUgPSBNQVgodm1hX3NpemUsIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MrcGVfc2VnLT5TaXplT2ZSYXdEYXRhKTsKICAgICAgICBwZV9zZWcrKzsKICAgIH0KICAgIHJldHVybiB2bWFfc2l6ZTsKfQoKc3RhdGljIHZvaWQgZG9fcmVsb2NhdGlvbnMoUEVfTU9EUkVGICpwZW0pCnsKICAgIGludCBkZWx0YSA9IHBlbS0+bW9kdWxlIC0gUEVfSEVBREVSKHBlbS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcj0gcGVtLT5tb2R1bGU7CglJTUFHRV9CQVNFX1JFTE9DQVRJT04JCSpyID0gcGVtLT5wZV9yZWxvYzsKCWludAkJCQloZGVsdGEgPSAoZGVsdGEgPj4gMTYpICYgMHhGRkZGOwoJaW50CQkJCWxkZWx0YSA9IGRlbHRhICYgMHhGRkZGOwoKCS8qIGludCByZWxvY19zaXplID0gKi8KCglpZihkZWx0YSA9PSAwKQoJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCQlyZXR1cm47Cgl3aGlsZShyLT5WaXJ0dWFsQWRkcmVzcykKCXsKCQljaGFyICpwYWdlID0gKGNoYXIqKSBSVkEoci0+VmlydHVhbEFkZHJlc3MpOwoJCWludCBjb3VudCA9IChyLT5TaXplT2ZCbG9jayAtIDgpLzI7CgkJaW50IGk7CgkJZHByaW50Zl9maXh1cChzdGRkZWIsICIleCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsCgkJCWNvdW50LCByLT5WaXJ0dWFsQWRkcmVzcyk7CgkJLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwoJCWZvcihpPTA7aTxjb3VudDtpKyspCgkJewoJCQlpbnQgb2Zmc2V0ID0gci0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwoJCQlpbnQgdHlwZSA9IHItPlR5cGVPZmZzZXRbaV0gPj4gMTI7CgkJCWRwcmludGZfZml4dXAoc3RkZGViLCJwYXRjaGluZyAleCB0eXBlICV4XG4iLCBvZmZzZXQsIHR5cGUpOwoJCQlzd2l0Y2godHlwZSkKCQkJewoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURTogYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0g6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGhkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGxkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgojaWYgMQoJCQkJKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CiNlbHNlCgkJCQl7IGludCBoPSoodW5zaWduZWQgc2hvcnQqKShwYWdlK29mZnNldCk7CgkJCQkgIGludCBsPXItPlR5cGVPZmZzZXRbKytpXTsKCQkJCSAgKih1bnNpZ25lZCBpbnQqKShwYWdlICsgb2Zmc2V0KSA9IChoPDwxNikgKyBsICsgZGVsdGE7CgkJCQl9CiNlbmRpZgoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hBREo6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIkRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9NSVBTX0pNUEFERFI6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIklzIHRoaXMgYSBNSVBTIG1hY2hpbmUgPz8/XG4iKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIGZpeHVwIHR5cGVcbiIpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJciA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04qKSgoY2hhciopciArIHItPlNpemVPZkJsb2NrKTsKCX0KfQoJCQoKCQoJCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCVBFX0xvYWRJbWFnZQogKiBMb2FkIG9uZSBQRSBmb3JtYXQgRExML0VYRSBpbnRvIG1lbW9yeQogKiAKICogVW5sdWNraWx5IHdlIGNhbid0IGp1c3QgbW1hcCB0aGUgc2VjdGlvbnMgd2hlcmUgd2Ugd2FudCB0aGVtLCBmb3IgCiAqIChhdCBsZWFzdCkgTGludXggZG9lcyBvbmx5IHN1cHBvcnQgb2Zmc2V0cyB3aGljaCBhcmUgcGFnZS1hbGlnbmVkLgogKgogKiBCVVQgd2UgaGF2ZSB0byBtYXAgdGhlIHdob2xlIGltYWdlIGFueXdheSwgZm9yIFdpbjMyIHByb2dyYW1zIHNvbWV0aW1lcwogKiB3YW50IHRvIGFjY2VzcyB0aGVtLiAoSE1PRFVMRTMyIHBvaW50IHRvIHRoZSBzdGFydCBvZiBpdCkKICovCnN0YXRpYyBITU9EVUxFMzIgUEVfTG9hZEltYWdlKCBIRklMRTMyIGhGaWxlICkKewogICAgSE1PRFVMRTMyIGhNb2R1bGU7CiAgICBIQU5ETEUzMiBtYXBwaW5nOwoKICAgIC8qIG1hcCB0aGUgUEUgZmlsZSBzb21ld2hlcmUgKi8KICAgIG1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZzMyQSggaEZpbGUsIE5VTEwsIFBBR0VfUkVBRE9OTFkgfCBTRUNfQ09NTUlULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCBOVUxMICk7CiAgICBpZiAoIW1hcHBpbmcpCiAgICB7CiAgICAgICAgZnByaW50Ziggc3RkZXJyLCAiUEVfTG9hZEltYWdlOiBDcmVhdGVGaWxlTWFwcGluZyBlcnJvciAlbGRcbiIsCiAgICAgICAgICAgICAgICAgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGhNb2R1bGUgPSAoSE1PRFVMRTMyKU1hcFZpZXdPZkZpbGUoIG1hcHBpbmcsIEZJTEVfTUFQX1JFQUQsIDAsIDAsIDAgKTsKICAgIENsb3NlSGFuZGxlKCBtYXBwaW5nICk7CiAgICBpZiAoIWhNb2R1bGUpCiAgICB7CiAgICAgICAgZnByaW50Ziggc3RkZXJyLCAiUEVfTG9hZEltYWdlOiBNYXBWaWV3T2ZGaWxlIGVycm9yICVsZFxuIiwKICAgICAgICAgICAgICAgICBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChQRV9IRUFERVIoaE1vZHVsZSktPlNpZ25hdHVyZSAhPSBJTUFHRV9OVF9TSUdOQVRVUkUpCiAgICB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsImltYWdlIGRvZXNuJ3QgaGF2ZSBQRSBzaWduYXR1cmUsIGJ1dCAweCUwOGx4XG4iLAogICAgICAgICAgICAgICAgUEVfSEVBREVSKGhNb2R1bGUpLT5TaWduYXR1cmUgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmIChQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTWFjaGluZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NikKICAgIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwidHJ5aW5nIHRvIGxvYWQgUEUgaW1hZ2UgZm9yIHVuc3VwcG9ydGVkIGFyY2hpdGVjdHVyZSAoIik7CiAgICAgICAgc3dpdGNoIChQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTWFjaGluZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfVU5LTk9XTjogZnByaW50ZihzdGRlcnIsIlVua25vd24iKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfSTg2MDogICAgZnByaW50ZihzdGRlcnIsIkk4NjAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjMwMDA6ICAgZnByaW50ZihzdGRlcnIsIlIzMDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1I0MDAwOiAgIGZwcmludGYoc3RkZXJyLCJSNDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMTAwMDA6ICBmcHJpbnRmKHN0ZGVyciwiUjEwMDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0FMUEhBOiAgIGZwcmludGYoc3RkZXJyLCJBbHBoYSIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9QT1dFUlBDOiBmcHJpbnRmKHN0ZGVyciwiUG93ZXJQQyIpOyBicmVhazsKICAgICAgICBkZWZhdWx0OiBmcHJpbnRmKHN0ZGVyciwiVW5rbm93bi0lMDR4IiwKICAgICAgICAgICAgICAgICAgICAgICAgIFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5NYWNoaW5lKTsgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGZwcmludGYoc3RkZXJyLCIpXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgcmV0dXJuIGhNb2R1bGU7CgplcnJvcjoKICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhpcyBtYXBzIGEgbG9hZGVkIFBFIGRsbCBpbnRvIHRoZSBhZGRyZXNzIHNwYWNlIG9mIHRoZSBzcGVjaWZpZWQgcHJvY2Vzcy4KICovCnN0YXRpYyBITU9EVUxFMzIgUEVfTWFwSW1hZ2UoIEhNT0RVTEUzMiBoTW9kdWxlLCBQREIzMiAqcHJvY2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0ZTVFJVQ1QgKm9mcywgRFdPUkQgZmxhZ3MgKQp7CglQRV9NT0RSRUYJCSpwZW07CglpbnQJCQlpLCByZXN1bHQ7CglEV09SRAkJCWxvYWRfYWRkcjsKCUlNQUdFX0RBVEFfRElSRUNUT1JZCWRpcjsKCWNoYXIJCQkqbW9kbmFtZTsKCWludAkJCXZtYV9zaXplOwoKICAgICAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VnOwogICAgICAgIElNQUdFX0RPU19IRUFERVIgKmRvc19oZWFkZXIgPSAoSU1BR0VfRE9TX0hFQURFUiAqKWhNb2R1bGU7CiAgICAgICAgSU1BR0VfTlRfSEVBREVSUyAqbnRfaGVhZGVyID0gUEVfSEVBREVSKGhNb2R1bGUpOwoJCglwZW0gPSAoUEVfTU9EUkVGKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoKnBlbSkpOwoJLyogTk9URTogZml4dXBfaW1wb3J0cyB0YWtlcyBjYXJlIG9mIHRoZSBjb3JyZWN0IG9yZGVyICovCglwZW0tPm5leHQJPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCXByb2Nlc3MtPm1vZHJlZl9saXN0ID0gcGVtOwoKCWlmICghKG50X2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICAgICAgewoJCWlmIChwcm9jZXNzLT5leGVfbW9kcmVmKQoJCQlmcHJpbnRmKHN0ZGVyciwib3ZlcndyaXRpbmcgb2xkIGV4ZV9tb2RyZWYuLi4gYXJyZ2hcbiIpOwoJCXByb2Nlc3MtPmV4ZV9tb2RyZWYgPSBwZW07Cgl9CgoJbG9hZF9hZGRyID0gbnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7Cgl2bWFfc2l6ZSA9IGNhbGNfdm1hX3NpemUoIGhNb2R1bGUgKTsKCWRwcmludGZfd2luMzIoc3RkZGViLCAiTG9hZCBhZGRyIGlzICVseFxuIixsb2FkX2FkZHIpOwoJbG9hZF9hZGRyID0gKERXT1JEKVZpcnR1YWxBbGxvYyggKHZvaWQqKWxvYWRfYWRkciwgdm1hX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKCWlmIChsb2FkX2FkZHIgPT0gMCkgewoJCWxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoIE5VTEwsIHZtYV9zaXplLAoJCQkJCQkgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAoJCQkJCQkgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwoJfQoJcGVtLT5tb2R1bGUgPSAoSE1PRFVMRTMyKWxvYWRfYWRkcjsKCglkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkxvYWQgYWRkciBpcyByZWFsbHkgJWx4LCByYW5nZSAleFxuIiwKICAgICAgICAgICAgICAgICAgICAgIGxvYWRfYWRkciwgdm1hX3NpemUpOwoJCiAgICAgICAgLyogU3RvcmUgdGhlIE5UIGhlYWRlciBhdCB0aGUgbG9hZCBhZGRyCiAgICAgICAgICogKEZJWE1FOiBzaG91bGQgcmVhbGx5IHVzZSBtbWFwKQogICAgICAgICAqLwogICAgICAgICooSU1BR0VfRE9TX0hFQURFUiAqKWxvYWRfYWRkciA9ICpkb3NfaGVhZGVyOwogICAgICAgICooSU1BR0VfTlRfSEVBREVSUyAqKShsb2FkX2FkZHIgKyBkb3NfaGVhZGVyLT5lX2xmYW5ldykgPSAqbnRfaGVhZGVyOwoKICAgICAgICBwZV9zZWcgPSBQRV9TRUNUSU9OUyhoTW9kdWxlKTsKCWZvciAoaSA9IDA7IGkgPCBudF9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBwZV9zZWcrKykKCXsKCQkvKiBtZW1jcHkgb25seSBub24tQlNTIHNlZ21lbnRzICovCgkJLyogRklYTUU6IHRoaXMgc2hvdWxkIGJlIGRvbmUgYnkgbW1hcCguLk1BUF9QUklWQVRFfE1BUF9GSVhFRC4uKQoJCSAqIGJ1dCBpdCBpcyBub3QgcG9zc2libGUgZm9yIChhdCBsZWFzdCkgTGludXggbmVlZHMKCQkgKiBhIHBhZ2UtYWxpZ25lZCBvZmZzZXQuCgkJICovCgkJaWYoIShwZV9zZWctPkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKSkKCQkgICAgbWVtY3B5KChjaGFyKilSVkEocGVfc2VnLT5WaXJ0dWFsQWRkcmVzcyksCgkJICAgIAkoY2hhciopKGhNb2R1bGUgKyBwZV9zZWctPlBvaW50ZXJUb1Jhd0RhdGEpLAoJCQlwZV9zZWctPlNpemVPZlJhd0RhdGEKCQkgICAgKTsKCgkJcmVzdWx0ID0gUlZBIChwZV9zZWctPlZpcnR1YWxBZGRyZXNzKTsKI2lmIDEKCQkvKiBub3QgbmVlZGVkLCBtZW1vcnkgaXMgemVybyAqLwoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIuYnNzIikgPT0gMCkKCQkgICAgbWVtc2V0KCh2b2lkICopcmVzdWx0LCAwLCAKCQkJICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplID8KCQkJICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplIDoKCQkJICAgcGVfc2VnLT5TaXplT2ZSYXdEYXRhKTsKI2VuZGlmCgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIuaWRhdGEiKSA9PSAwKQoJCQlwZW0tPnBlX2ltcG9ydCA9IChMUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIuZWRhdGEiKSA9PSAwKQoJCQlwZW0tPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5yc3JjIikgPT0gMCkKCQkJcGVtLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGVfc2VnLT5OYW1lLCAiLnJlbG9jIikgPT0gMCkKCQkJcGVtLT5wZV9yZWxvYyA9IChMUElNQUdFX0JBU0VfUkVMT0NBVElPTikgcmVzdWx0OwoJfQoKCS8qIFRoZXJlIGlzIHdvcmQgdGhhdCB0aGUgYWN0dWFsIGxvYWRlciBkb2VzIG5vdCBjYXJlIGFib3V0IHRoZQoJICAgc2VjdGlvbiBuYW1lcywgYW5kIG9ubHkgZ29lcyBmb3IgdGhlIERhdGFEaXJlY3RvcnkgKi8KCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX2V4cG9ydCAmJiAoaW50KXBlbS0+cGVfZXhwb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGV4cG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJLyogYWx3YXlzIHRydXN0IHRoZSBkaXJlY3RvcnkgKi8KCQlwZW0tPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQkvKiAKCQlpZihwZW0tPnBlX2ltcG9ydCAmJiAoaW50KXBlbS0+cGVfaW1wb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGltcG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJICovCgkJcGVtLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfUkVTT1VSQ0VdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGVtLT5wZV9yZXNvdXJjZSAmJiAoaW50KXBlbS0+cGVfcmVzb3VyY2UhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgcmVzb3VyY2UgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlbS0+cGVfcmVzb3VyY2UgPSAoTFBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCgoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlbS0+cGVfcmVsb2MgJiYgKGludClwZW0tPnBlX3JlbG9jIT0gUlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZWxvY2F0aW9uIGxpc3Q/P1xuIik7CgkJcGVtLT5wZV9yZWxvYyA9ICh2b2lkICopIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09QWVJJR0hUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiQ29weXJpZ2h0IHN0cmluZyBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUl0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMU10uU2l6ZSkKCQkgZnByaW50ZihzdGRuaW1wLCJUaHJlYWQgbG9jYWwgc3RvcmFnZSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0xPQURfQ09ORklHXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JQVRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJJbXBvcnQgQWRkcmVzcyBUYWJsZSBkaXJlY3RvcnkgaWdub3JlZFxuIik7CglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTNdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxMyBpZ25vcmVkXG4iKTsKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIpOwoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzE1XS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiVW5rbm93biBkaXJlY3RvcnkgMTUgaWdub3JlZFxuIik7CgoJaWYocGVtLT5wZV9yZWxvYykJZG9fcmVsb2NhdGlvbnMocGVtKTsKCWlmKHBlbS0+cGVfZXhwb3J0KQlkdW1wX2V4cG9ydHMocGVtLT5tb2R1bGUpOwoJaWYocGVtLT5wZV9pbXBvcnQpCWZpeHVwX2ltcG9ydHMocHJvY2VzcyxwZW0saE1vZHVsZSk7CiAgCQkKCWlmIChwZW0tPnBlX2V4cG9ydCkKCQltb2RuYW1lID0gKGNoYXIqKVJWQShwZW0tPnBlX2V4cG9ydC0+TmFtZSk7CgllbHNlIHsKCQljaGFyICpzOwoJCW1vZG5hbWUgPSBzID0gb2ZzLT5zelBhdGhOYW1lOwoJCXdoaWxlICgocz1zdHJjaHIobW9kbmFtZSwnXFwnKSkpCgkJCW1vZG5hbWUgPSBzKzE7CgkJaWYgKChzPXN0cmNocihtb2RuYW1lLCcuJykpKQoJCQkqcz0nXDAnOwoJfQoKICAgICAgICAvKiBOb3cgdGhhdCB3ZSBnb3QgZXZlcnl0aGluZyBhdCB0aGUgcmlnaHQgYWRkcmVzcywKICAgICAgICAgKiB3ZSBjYW4gdW5tYXAgdGhlIHByZXZpb3VzIG1vZHVsZSAqLwogICAgICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICAgICAgcmV0dXJuIChITU9EVUxFMzIpbG9hZF9hZGRyOwp9CgpISU5TVEFOQ0UxNiBNT0RVTEVfQ3JlYXRlSW5zdGFuY2UoSE1PRFVMRTE2IGhNb2R1bGUsTE9BRFBBUkFNUyAqcGFyYW1zKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIFBFIExpYnJhcnkgTG9hZGVyIGZyb250ZW5kLiAKICogRklYTUU6IGhhbmRsZSB0aGUgZmxhZ3MuCiAqICAgICAgICBpbnRlcm5hbCBtb2R1bGUgaGFuZGxpbmcgc2hvdWxkIGJlIG1hZGUgYmV0dGVyIGhlcmUgKGFuZCBpbiBidWlsdGluLmMpCiAqLwpITU9EVUxFMzIgUEVfTG9hZExpYnJhcnlFeDMyQSAoTFBDU1RSIG5hbWUsIEhGSUxFMzIgaEZpbGUsIERXT1JEIGZsYWdzKSB7CglPRlNUUlVDVAlvZnM7CglITU9EVUxFMzIJaE1vZHVsZTsKCU5FX01PRFVMRQkqcE1vZHVsZTsKCVBFX01PRFJFRgkqcGVtOwoKCWlmICgoaE1vZHVsZSA9IE1PRFVMRV9GaW5kTW9kdWxlKCBuYW1lICkpKSB7CgkJLyogdGhlIC5ETEwgaXMgZWl0aGVyIGxvYWRlZCBvciBpbnRlcm5hbCAqLwoJCWhNb2R1bGUgPSBNT0RVTEVfSEFORExFdG9ITU9EVUxFMzIoaE1vZHVsZSk7CgkJaWYgKCFISVdPUkQoaE1vZHVsZSkpIC8qIGludGVybmFsIChvciBiYWQpICovCgkJCXJldHVybiBoTW9kdWxlOwoJCS8qIGNoZWNrIGlmIHRoaXMgbW9kdWxlIGlzIGFscmVhZHkgbWFwcGVkICovCgkJcGVtIAk9IFBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdDsKCQl3aGlsZSAocGVtKSB7CgkJCWlmIChwZW0tPm1vZHVsZSA9PSBoTW9kdWxlKSByZXR1cm4gaE1vZHVsZTsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCX0KCQlwTW9kdWxlID0gTU9EVUxFX0dldFB0cihoTW9kdWxlKTsKCQlpZiAocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfQlVJTFRJTikgewoJCQlQREIzMgkqcHJvY2VzcyA9IFBST0NFU1NfQ3VycmVudCgpOwoJCQlJTUFHRV9ET1NfSEVBREVSCSpkaDsKCQkJSU1BR0VfTlRfSEVBREVSUwkqbmg7CgkJCUlNQUdFX1NFQ1RJT05fSEVBREVSCSpzaDsKCgkJCS8qIHdlIG9ubHkgY29tZSBoZXJlIGlmIHdlIGFscmVhZHkgaGF2ZSAnbG9hZGVkJyB0aGUKCQkJICogaW50ZXJuYWwgZGxsIGJ1dCBpbiBhbm90aGVyIHByb2Nlc3MuIEp1c3QgY3JlYXRlCgkJCSAqIGEgUEVfTU9EUkVGIGFuZCByZXR1cm4uCgkJCSAqLwoJCQlwZW0gPSAoUEVfTU9EUkVGKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKCQkJCUhFQVBfWkVST19NRU1PUlksc2l6ZW9mKCpwZW0pKTsKCQkJcGVtLT5tb2R1bGUgCSAgICAgPSBoTW9kdWxlOwoJCQlkaCA9IChJTUFHRV9ET1NfSEVBREVSKilwZW0tPm1vZHVsZTsKCQkJbmggPSAoSU1BR0VfTlRfSEVBREVSUyopKGRoKzEpOwoJCQlzaCA9IChJTUFHRV9TRUNUSU9OX0hFQURFUiopKG5oKzEpOwoJCQlwZW0tPnBlX2V4cG9ydAkgICAgID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkqKShzaCsyKTsKCQkJcGVtLT5uZXh0CSAgICAgPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCQkJcHJvY2Vzcy0+bW9kcmVmX2xpc3QgPSBwZW07CgkJCXJldHVybiBoTW9kdWxlOwoJCX0KCX0gZWxzZSB7CgoJCS8qIHRyeSB0byBsb2FkIGJ1aWx0aW4sIGVuYWJsZWQgbW9kdWxlcyBmaXJzdCAqLwoJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU5fTG9hZE1vZHVsZSggbmFtZSwgRkFMU0UgKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1PRFVMRV9IQU5ETEV0b0hNT0RVTEUzMiggaE1vZHVsZSApOwoKCQkvKiB0cnkgdG8gb3BlbiB0aGUgc3BlY2lmaWVkIGZpbGUgKi8KCQlpZiAoSEZJTEVfRVJST1IzMj09KGhGaWxlPU9wZW5GaWxlMzIobmFtZSwmb2ZzLE9GX1JFQUQpKSkgewoJCQkvKiBOb3cgdHJ5IHRoZSBidWlsdC1pbiBldmVuIGlmIGRpc2FibGVkICovCgkJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU5fTG9hZE1vZHVsZSggbmFtZSwgVFJVRSApKSkgewoJCQkJZnByaW50Ziggc3RkZXJyLCAiV2FybmluZzogY291bGQgbm90IGxvYWQgV2luZG93cyBETEwgJyVzJywgdXNpbmcgYnVpbHQtaW4gbW9kdWxlLlxuIiwgbmFtZSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBNT0RVTEVfSEFORExFdG9ITU9EVUxFMzIoIGhNb2R1bGUgKTsKCQkJfQoJCQlyZXR1cm4gMTsKCQl9CgkJaWYgKChoTW9kdWxlID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCAmb2ZzICkpIDwgMzIpIHsKCQkJX2xjbG9zZTMyKGhGaWxlKTsKCQkJcmV0dXJuIGhNb2R1bGU7CgkJfQoJCXBNb2R1bGUJCT0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZSApOwoJCXBNb2R1bGUtPmZsYWdzCT0gTkVfRkZMQUdTX1dJTjMyOwoJCXBNb2R1bGUtPm1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSApOwoJCUNsb3NlSGFuZGxlKCBoRmlsZSApOwoJCWlmIChwTW9kdWxlLT5tb2R1bGUzMiA8IDMyKSByZXR1cm4gMjE7Cgl9CgkvKiByZWN1cnNlICovCglwTW9kdWxlLT5tb2R1bGUzMiA9IFBFX01hcEltYWdlKCBwTW9kdWxlLT5tb2R1bGUzMiwgUFJPQ0VTU19DdXJyZW50KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm9mcyxmbGFncyk7CglyZXR1cm4gcE1vZHVsZS0+bW9kdWxlMzI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBMb2FkIHRoZSBQRSBtYWluIC5FWEUuIEFsbCBvdGhlciBsb2FkaW5nIGlzIGRvbmUgYnkgUEVfTG9hZExpYnJhcnlFeDMyQQogKiBGSVhNRTogdGhpcyBmdW5jdGlvbiBzaG91bGQgdXNlIFBFX0xvYWRMaWJyYXJ5RXgzMkEsIGJ1dCBjdXJyZW50bHkgY2FuJ3QKICogZHVlIHRvIHRoZSBUQVNLX0NyZWF0ZVRhc2sgc3R1ZmYuCiAqLwpISU5TVEFOQ0UxNiBQRV9Mb2FkTW9kdWxlKCBIRklMRTMyIGhGaWxlLCBPRlNUUlVDVCAqb2ZzLCBMT0FEUEFSQU1TKiBwYXJhbXMgKQp7CiAgICBITU9EVUxFMTYgaE1vZHVsZTE2OwogICAgSE1PRFVMRTMyIGhNb2R1bGUzMjsKICAgIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKCiAgICBpZiAoKGhNb2R1bGUxNiA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggb2ZzICkpIDwgMzIpIHJldHVybiBoTW9kdWxlMTY7CiAgICBwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZTE2ICk7CiAgICBwTW9kdWxlLT5mbGFncyA9IE5FX0ZGTEFHU19XSU4zMjsKCiAgICBwTW9kdWxlLT5tb2R1bGUzMiA9IGhNb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggaEZpbGUgKTsKICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwogICAgaWYgKGhNb2R1bGUzMiA8IDMyKSByZXR1cm4gMjE7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlMTYsIHBhcmFtcyApOwogICAgaWYgKCEoUEVfSEVBREVSKGhNb2R1bGUzMiktPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpKQogICAgewogICAgICAgIFRBU0tfQ3JlYXRlVGFzayggaE1vZHVsZTE2LCBoSW5zdGFuY2UsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmhFbnZpcm9ubWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgIChMUFNUUilQVFJfU0VHX1RPX0xJTiggcGFyYW1zLT5jbWRMaW5lICksCiAgICAgICAgICAgICAgICAgICAgICAgICAqKChXT1JEKilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPnNob3dDbWQpICsgMSkgKTsKICAgIH0KICAgIHBNb2R1bGUtPm1vZHVsZTMyID0gUEVfTWFwSW1hZ2UoIGhNb2R1bGUzMiwgUFJPQ0VTU19DdXJyZW50KCksIG9mcywgMCApOwogICAgcmV0dXJuIGhJbnN0YW5jZTsKfQoKaW50IFBFX1VubG9hZEltYWdlKCBITU9EVUxFMzIgaE1vZHVsZSApCnsKCXByaW50ZigiUEV1bmxvYWRJbWFnZSgpIGNhbGxlZCFcbiIpOwoJLyogZnJlZSByZXNvdXJjZXMsIGltYWdlLCB1bm1hcCAqLwoJcmV0dXJuIDE7Cn0KCi8qIENhbGxlZCBpZiB0aGUgbGlicmFyeSBpcyBsb2FkZWQgb3IgZnJlZWQuCiAqIE5PVEU6IGlmIGEgdGhyZWFkIGF0dGFjaGVzIGEgRExMLCB0aGUgY3VycmVudCB0aHJlYWQgd2lsbCBvbmx5IGRvCiAqIERMTF9QUk9DRVNTX0FUVEFDSC4gT25seSBuZXcgY3JlYXRlZCB0aHJlYWRzIGRvIERMTF9USFJFQURfQVRUQUNICiAqIChTREspCiAqLwpzdGF0aWMgdm9pZCBQRV9Jbml0RExMKFBFX01PRFJFRiAqcGVtLCBEV09SRCB0eXBlLExQVk9JRCBscFJlc2VydmVkKQp7CiAgICBpZiAodHlwZT09RExMX1BST0NFU1NfQVRUQUNIKQoJcGVtLT5mbGFncyB8PSBQRV9NT0RSRUZfUFJPQ0VTU19BVFRBQ0hFRDsKCiAgICAvKiAgRExMX0FUVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBmb3IgZHluYW1pYyBsb2Fkcywgbm90LU5VTEwgZm9yIHN0YXRpYyBsb2FkcwogICAgICogIERMTF9ERVRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgaWYgY2FsbGVkIGJ5IEZyZWVMaWJyYXJ5LCBub3QtTlVMTCBvdGhlcndpc2UKICAgICAqICB0aGUgU0RLIGRvZXNuJ3QgbWVudGlvbiBhbnl0aGluZyBmb3IgRExMX1RIUkVBRF8qCiAgICAgKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKChQRV9IRUFERVIocGVtLT5tb2R1bGUpLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSAmJgogICAgICAgIChQRV9IRUFERVIocGVtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KQogICAgKSB7CiAgICAgICAgRkFSUFJPQzMyIGVudHJ5ID0gKEZBUlBST0MzMilSVkFfUFRSKCBwZW0tPm1vZHVsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCApOwogICAgICAgIGRwcmludGZfcmVsYXkoIHN0ZGRlYiwgIkNhbGxUbzMyKGVudHJ5cHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApXG4iLAogICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LCBwZW0tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgICAgIGVudHJ5KCBwZW0tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgfQp9CgovKiBDYWxsIHRoZSBETExlbnRyeSBmdW5jdGlvbiBvZiBhbGwgZGxscyB1c2VkIGJ5IHRoYXQgcHJvY2Vzcy4KICogKE5PVEU6IHRoaXMgbWF5IHJlY3Vyc2l2ZWx5IGNhbGwgdGhpcyBmdW5jdGlvbiAoaWYgYSBsaWJyYXJ5IGNhbGxzCiAqIExvYWRMaWJyYXJ5KSAuLi4gYnV0IGl0IHdvbid0IG1hdHRlcikKICovCnZvaWQgUEVfSW5pdGlhbGl6ZURMTHMoUERCMzIgKnByb2Nlc3MsRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkgewoJUEVfTU9EUkVGCSpwZW07CgoJcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cgl3aGlsZSAocGVtKSB7CgkJaWYgKHBlbS0+ZmxhZ3MgJiBQRV9NT0RSRUZfTk9fRExMX0NBTExTKSB7CgkJCXBlbSA9IHBlbS0+bmV4dDsKCQkJY29udGludWU7CgkJfQoJCWlmICh0eXBlPT1ETExfUFJPQ0VTU19BVFRBQ0gpIHsKCQkJaWYgKHBlbS0+ZmxhZ3MgJiBQRV9NT0RSRUZfUFJPQ0VTU19BVFRBQ0hFRCkgewoJCQkJcGVtID0gcGVtLT5uZXh0OwoJCQkJY29udGludWU7CgkJCX0KCQl9CgkJUEVfSW5pdERMTCggcGVtLCB0eXBlLCBscFJlc2VydmVkICk7CgkJcGVtID0gcGVtLT5uZXh0OwoJfQp9Cgp2b2lkIFBFX0luaXRUbHMoUERCMzIgKnBkYikKewoJLyogRklYTUU6IHRscyBjYWxsYmFja3MgPz8/ICovCglQRV9NT0RSRUYJCSpwZW07CglJTUFHRV9OVF9IRUFERVJTCSpwZWg7CglEV09SRAkJCXNpemUsZGF0YXNpemUsaW5kZXg7CglMUFZPSUQJCQltZW07CglMUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKCglwZW0gPSBwZGItPm1vZHJlZl9saXN0OwoJd2hpbGUgKHBlbSkgewoJCXBlaCA9IFBFX0hFQURFUihwZW0tPm1vZHVsZSk7CgkJaWYgKCFwZWgtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpIHsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJcGRpciA9IChMUFZPSUQpKHBlbS0+bW9kdWxlICsgcGVoLT5PcHRpb25hbEhlYWRlci4KCQkJRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcyk7CgkJaW5kZXgJPSBUbHNBbGxvYygpOwoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLChMUFZPSUQpIHBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSwgZGF0YXNpemUpOwoJCVRsc1NldFZhbHVlKGluZGV4LG1lbSk7CgkJKihwZGlyLT5BZGRyZXNzT2ZJbmRleCk9aW5kZXg7ICAgCgkJcGVtPXBlbS0+bmV4dDsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMgKEtFUk5FTDMyLjc0KQogKiBEb24ndCBjYWxsIERsbEVudHJ5UG9pbnQgZm9yIERMTF9USFJFQURfe0FUVEFDSCxERVRBQ0h9IGlmIHNldC4KICovCkJPT0wzMiBXSU5BUEkgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhITU9EVUxFMzIgaE1vZHVsZSkKewoJUERCMzIJKnByb2Nlc3MgPSBQUk9DRVNTX0N1cnJlbnQoKTsKCVBFX01PRFJFRgkqcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7CgoJd2hpbGUgKHBlbSkgewoJCWlmIChwZW0tPm1vZHVsZSA9PSBoTW9kdWxlKQoJCQlwZW0tPmZsYWdzfD1QRV9NT0RSRUZfTk9fRExMX0NBTExTOwoJCXBlbSA9IHBlbS0+bmV4dDsKCX0KCXJldHVybiBUUlVFOwp9Cgo=