LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYgICAgTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInBlX2ltYWdlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2lmbmRlZiBXSU5FTElCCiNpbmNsdWRlICJkZWJ1Z2dlci5oIgojZW5kaWYKCnN0YXRpYyB2b2lkIFBFX0luaXRETEwoUEVfTU9EUkVGKiBtb2RyZWYsIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkKTsKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodW5zaWduZWQgaW50KWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkKCnZvaWQgZHVtcF9leHBvcnRzKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKiBwZV9leHBvcnRzLCB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyKQp7IAojaWZuZGVmIFdJTkVMSUIKICBjaGFyCQkqTW9kdWxlOwogIGludAkJaTsKICB1X3Nob3J0CSpvcmRpbmFsOwogIHVfbG9uZwkqZnVuY3Rpb24sKmZ1bmN0aW9uczsKICB1X2NoYXIJKipuYW1lLCplbmFtZTsKICBjaGFyCQlidWZmZXJbMTAwMF07CiAgREJHX0FERFIJZGFkZHI7CgogIGRhZGRyLnNlZyA9IDA7CiAgZGFkZHIudHlwZSA9IE5VTEw7CiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiXG4qKioqKioqRVhQT1JUIERBVEEqKioqKioqXG5Nb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKCSBNb2R1bGUsCgkgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsCgkgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiJS0zMnMgT3JkaW5hbCBWaXJ0IEFkZHJcbiIsICJGdW5jdGlvbiBOYW1lIik7CiAgZm9yIChpPTA7aTxwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucztpKyspIHsKICAgICAgaWYgKGk8cGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcykgewoJICBlbmFtZT0oY2hhciopUlZBKCpuYW1lKyspOwoJICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiJS0zMnMgJTRkICAgICU4LjhseCAoJTguOGx4KVxuIixlbmFtZSwqb3JkaW5hbCxmdW5jdGlvbnNbKm9yZGluYWxdLCpmdW5jdGlvbik7CgkgIHNwcmludGYoYnVmZmVyLCIlc18lcyIsTW9kdWxlLGVuYW1lKTsKCSAgZGFkZHIub2ZmPVJWQShmdW5jdGlvbnNbKm9yZGluYWxdKTsKCSAgb3JkaW5hbCsrOwoJICBmdW5jdGlvbisrOwogICAgICB9IGVsc2UgewogICAgICAJICAvKiBvcmRpbmFscy9uYW1lcyBubyBsb25nZXIgdmFsaWQsIGJ1dCB3ZSBzdGlsbCBnb3QgZnVuY3Rpb25zICovCgkgIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyAlNHMgICAgJThzICU4LjhseFxuIiwiIiwiIiwiIiwqZnVuY3Rpb24pOwoJICBzcHJpbnRmKGJ1ZmZlciwiJXNfJWQiLE1vZHVsZSxpKTsKCSAgZGFkZHIub2ZmPVJWQSgqZnVuY3Rpb25zKTsKCSAgZnVuY3Rpb24rKzsKICAgICAgfQogICAgICBERUJVR19BZGRTeW1ib2woYnVmZmVyLCZkYWRkciwgTlVMTCwgU1lNX1dJTjMyIHwgU1lNX0ZVTkMpOwogIH0KI2VuZGlmCn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnRsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgTmFtZSBsaXN0LiAKICoJLSBsb29rIHVwIHRoZSBvcmRpbmFsIHdpdGggdGhhdCBpbmRleC4KICoJLSB1c2UgdGhlIG9yZGluYWwgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKiBJZiBpdCBpcyBhIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICovCkZBUlBST0MzMiBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbihzdHJ1Y3QgcGVfZGF0YSAqcGUsIExQQ1NUUiBmdW5jTmFtZSkKewoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAJCSpleHBvcnRzOwoJdW5zaWduZWQJCQlsb2FkX2FkZHI7Cgl1X3Nob3J0CQkJCSogb3JkaW5hbDsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZTsKCWludAkJCQlpOwoJUERCMzIJCQkJKnByb2Nlc3M9KFBEQjMyKilHZXRDdXJyZW50UHJvY2Vzc0lkKCk7CglQRV9NT0RSRUYJCQkqcGVtOwoKCXBlbSA9IHByb2Nlc3MtPm1vZHJlZl9saXN0OwoJd2hpbGUgKHBlbSAmJiAocGVtLT5wZV9tb2R1bGUgIT0gcGUpKQoJCXBlbT1wZW0tPm5leHQ7CglpZiAoIXBlbSkgewoJCWZwcmludGYoc3RkZXJyLCJObyBNT0RSRUYgZm91bmQgZm9yIFBFX01PRFVMRSAlcCBpbiBwcm9jZXNzICVwXG4iLHBlLHByb2Nlc3MpOwoJCXJldHVybiBOVUxMOwoJfQoJbG9hZF9hZGRyCT0gcGVtLT5sb2FkX2FkZHI7CglleHBvcnRzCQk9IHBlbS0+cGVfZXhwb3J0OwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpIHsKCQlmcHJpbnRmKHN0ZGVyciwiTW9kdWxlICVwL01PRFJFRiAlcCBkb2Vzbid0IGhhdmUgYSBleHBvcnRzIHRhYmxlLlxuIixwZSxwZW0pOwoJCXJldHVybiBOVUxMOwoJfQoJb3JkaW5hbAk9ICh1X3Nob3J0KikgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwoJZnVuY3Rpb249ICh1X2xvbmcqKSAgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwoJbmFtZQk9ICh1X2NoYXIgKiopIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpIHsKCQlmb3IoaT0wOyBpPGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykgewoJCQllbmFtZT0oY2hhciopUlZBKCpuYW1lKTsKCQkJaWYoIXN0cmNtcChlbmFtZSxmdW5jTmFtZSkpCgkJCQlyZXR1cm4gKEZBUlBST0MzMikgUlZBKGZ1bmN0aW9uWypvcmRpbmFsXSk7CgkJCW9yZGluYWwrKzsKCQkJbmFtZSsrOwoJCX0KCX0gZWxzZSB7CgkJaWYgKExPV09SRChmdW5jTmFtZSktZXhwb3J0cy0+QmFzZSA+IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKSB7CgkJCWRwcmludGZfd2luMzIoc3RkZGViLCIJb3JkaW5hbCAlZCBvdXQgb2YgcmFuZ2UhXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPV09SRChmdW5jTmFtZSkpOwoJCQlyZXR1cm4gTlVMTDsKCQl9CgkJcmV0dXJuIChGQVJQUk9DMzIpIFJWQShmdW5jdGlvblsoaW50KWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2VdKTsKCX0KCXJldHVybiBOVUxMOwp9Cgp2b2lkIApmaXh1cF9pbXBvcnRzIChQREIzMiAqcHJvY2VzcyxQRV9NT0RSRUYgKnBlbSkKewogICAgUEVfTU9EVUxFCQkJKnBlID0gcGVtLT5wZV9tb2R1bGU7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUgkqcGVfaW1wOwogICAgaW50CWZpeHVwX2ZhaWxlZAkJPSAwOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcgk9IHBlbS0+bG9hZF9hZGRyOwogICAgaW50CQkJCWk7CiAgICBjaGFyCQkJKm1vZG5hbWU7CiAgICAKICAgIGlmIChwZW0tPnBlX2V4cG9ydCkKICAgIAltb2RuYW1lID0gKGNoYXIqKSBSVkEocGVtLT5wZV9leHBvcnQtPk5hbWUpOwogICAgZWxzZQogICAgICAgIG1vZG5hbWUgPSAiPHVua25vd24+IjsKCiAgICAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICJcbkR1bXBpbmcgaW1wb3J0cyBsaXN0XG4iKTsKCiAgICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogICAgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7CiAgICBpZiAoIXBlX2ltcCkgCiAgICAJZnByaW50ZihzdGRlcnIsIm5vIGltcG9ydCBkaXJlY3Rvcnk/Pz8/XG4iKTsKCiAgICAvKiBGSVhNRTogc2hvdWxkIHRlcm1pbmF0ZSBvbiAwIENoYXJhY3RlcmlzdGljcyAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lOyBwZV9pbXArKykKCWkrKzsKCiAgICAvKiBsb2FkIHRoZSBpbXBvcnRlZCBtb2R1bGVzLiBUaGV5IGFyZSBhdXRvbWF0aWNhbGx5IAogICAgICogYWRkZWQgdG8gdGhlIG1vZHJlZiBsaXN0IG9mIHRoZSBwcm9jZXNzLgogICAgICovCiAKICAgIC8qIEZJWE1FOiBzaG91bGQgdGVybWluYXRlIG9uIDAgQ2hhcmFjdGVyaXN0aWNzICovCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsgcGVfaW1wLT5OYW1lOyBwZV9pbXArKykgewogICAgCUhNT0RVTEUzMglyZXM7CglQRV9NT0RSRUYJKnhwZW0sKip5cGVtOwoKCiAJY2hhciAqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoKCS8qIGRvbid0IHVzZSBNT0RVTEVfTG9hZCwgV2luMzIgY3JlYXRlcyBuZXcgdGFzayBkaWZmZXJlbnRseSAqLwoJcmVzID0gUEVfTG9hZExpYnJhcnlFeDMyQSggbmFtZSwgMCwgMCApOwoJaWYgKHJlcyA8PSAoSE1PRFVMRTMyKSAzMikgewoJICAgIGNoYXIgKnAsIGJ1ZmZlclsyNTZdOwoKCSAgICAvKiBUcnkgd2l0aCBwcmVwZW5kaW5nIHRoZSBwYXRoIG9mIHRoZSBjdXJyZW50IG1vZHVsZSAqLwoJICAgIEdldE1vZHVsZUZpbGVOYW1lMzJBIChwZS0+bWFwcGVkZGxsLCBidWZmZXIsIHNpemVvZiAoYnVmZmVyKSk7CgkgICAgaWYgKCEocCA9IHN0cnJjaHIgKGJ1ZmZlciwgJ1xcJykpKQoJCXAgPSBidWZmZXI7CgkgICAgc3RyY3B5IChwICsgMSwgbmFtZSk7CgkgICAgcmVzID0gUEVfTG9hZExpYnJhcnlFeDMyQSggYnVmZmVyLCAwLCAwICk7Cgl9CglpZiAocmVzIDw9IChITU9EVUxFMzIpIDMyKSB7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiTW9kdWxlICVzIG5vdCBmb3VuZFxuIiwgbmFtZSk7CgkgICAgZXhpdCAoMCk7Cgl9CglyZXMgPSBNT0RVTEVfSEFORExFdG9ITU9EVUxFMzIocmVzKTsKCXhwZW0gPSBwZW0tPm5leHQ7Cgl3aGlsZSAoeHBlbSkgewoJCWlmICh4cGVtLT5wZV9tb2R1bGUtPm1hcHBlZGRsbCA9PSByZXMpCgkJCWJyZWFrOwoJCXhwZW0gPSB4cGVtLT5uZXh0OwoJfQoJaWYgKHhwZW0pIHsKCQkvKiBpdCBoYXMgYmVlbiBsb2FkZWQgKkJFRk9SRSogdXMsIHNvIHdlIGhhdmUgdG8gaW5pdAoJCSAqIGl0IGJlZm9yZSB1cy4gd2UganVzdCBzd2FwIHRoZSB0d28gbW9kdWxlcyB3aGljaCBzaG91bGQKCQkgKiB3b3JrLgoJCSAqLwoJCS8qIHVubGluayB4cGVtIGZyb20gY2hhaW4gKi8KCQl5cGVtID0gJihwcm9jZXNzLT5tb2RyZWZfbGlzdCk7CgkJd2hpbGUgKCp5cGVtKSB7CgkJCWlmICgoKnlwZW0pPT14cGVtKQoJCQkJYnJlYWs7CgkJCXlwZW0gPSAmKCgqeXBlbSktPm5leHQpOwoJCX0KCQkqeXBlbQkJPSB4cGVtLT5uZXh0OwoKCQkvKiBsaW5rIGl0IGRpcmVjdGx5IGJlZm9yZSBwZW0gKi8KCQl5cGVtCQk9ICYocHJvY2Vzcy0+bW9kcmVmX2xpc3QpOwoJCXdoaWxlICgqeXBlbSkgewoJCQlpZiAoKCp5cGVtKT09cGVtKQoJCQkJYnJlYWs7CgkJCXlwZW0gPSAmKCgqeXBlbSktPm5leHQpOwoJCX0KCQkqeXBlbQkJPSB4cGVtOwoJCXhwZW0tPm5leHQJPSBwZW07CgkJCgl9CglpKys7CiAgICB9CiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIHdoaWxlIChwZV9pbXAtPk5hbWUpIHsKCWNoYXIJCQkqTW9kdWxlOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglMUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKCWludAkJCW9yZGltcG9ydHdhcm5lZDsKCiAgICAgICAgb3JkaW1wb3J0d2FybmVkID0gMDsKCU1vZHVsZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoJZHByaW50Zl93aW4zMiAoc3RkZGViLCAiJXNcbiIsIE1vZHVsZSk7CgoJLyogRklYTUU6IGZvcndhcmRlciBlbnRyaWVzIC4uLiAqLwoKCWlmIChwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rICE9IDApIHsgLyogb3JpZ2luYWwgTVMgc3R5bGUgKi8KCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICJNaWNyb3NvZnQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICBpbXBvcnRfbGlzdCA9KExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCgkgICAgd2hpbGUgKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIGlmKCFsc3RybmNtcGkzMkEoTW9kdWxlLCJrZXJuZWwzMiIsOCkgJiYgIW9yZGltcG9ydHdhcm5lZCl7CgkJICAgICAgIGZwcmludGYoc3RkZXJyLCIlcyBpbXBvcnRzIGtlcm5lbDMyLmRsbCBieSBvcmRpbmFsLiBNYXkgY3Jhc2guXG4iLG1vZG5hbWUpOwoJCSAgICAgICBvcmRpbXBvcnR3YXJuZWQgPSAxOwoJCSAgICB9CgkJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBNb2R1bGUsIG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClHZXRQcm9jQWRkcmVzczMyKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSksKExQQ1NUUilvcmRpbmFsKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsIG9yZGluYWwpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0gZWxzZSB7CQkvKiBpbXBvcnQgYnkgbmFtZSAqLwoJCSAgICBwZV9uYW1lID0gKExQSU1BR0VfSU1QT1JUX0JZX05BTUUpUlZBKGltcG9ydF9saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClHZXRQcm9jQWRkcmVzczMyKAoJCQkJCQlNT0RVTEVfRmluZE1vZHVsZSAoTW9kdWxlKSwKCQkJCQkJcGVfbmFtZS0+TmFtZSk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJZnByaW50ZihzdGRlcnIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcyksIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSxwZV9uYW1lLT5IaW50LHBlX25hbWUtPk5hbWUpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0KCQlpbXBvcnRfbGlzdCsrOwoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9IGVsc2UgewkvKiBCb3JsYW5kIHN0eWxlICovCgkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSAoTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCSAgICB3aGlsZSAodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgLyogbm90IHN1cmUgYWJvdXQgdGhpcyBicmFuY2gsIGJ1dCBpdCBzZWVtcyB0byB3b3JrICovCgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKTsKCgoJCSAgICBpZiAoIWxzdHJuY21waTMyQShNb2R1bGUsImtlcm5lbDMyIiw4KSAmJiAKCQkgICAgCSFvcmRpbXBvcnR3YXJuZWQKCQkgICAgKSB7CgkJICAgICAgIGZwcmludGYoc3RkZXJyLCIlcyBpbXBvcnRzIGtlcm5lbDMyLmRsbCBieSBvcmRpbmFsLiBNYXkgY3Jhc2guXG4iLG1vZG5hbWUpOwoJCSAgICAgICBvcmRpbXBvcnR3YXJuZWQgPSAxOwoJCSAgICB9CgkJICAgIGRwcmludGZfd2luMzIoc3RkZGViLCItLS0gT3JkaW5hbCAlcy4lZFxuIixNb2R1bGUsb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSwKCQkJCQkJICAgICAoTFBDU1RSKSBvcmRpbmFsKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLG9yZGluYWwpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9KExQSU1BR0VfSU1QT1JUX0JZX05BTUUpIFJWQSh0aHVua19saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgZHByaW50Zl93aW4zMihzdGRkZWIsIi0tLSAlcyAlcy4lZFxuIiwKCQkgICAJCSAgcGVfbmFtZS0+TmFtZSxNb2R1bGUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSxwZV9uYW1lLT5OYW1lKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCSAgICAJZnByaW50ZihzdGRlcnIsICJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIAkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0KCQl0aHVua19saXN0Kys7CgkgICAgfQoJfQoJcGVfaW1wKys7CiAgICB9CiAgICBpZiAoZml4dXBfZmFpbGVkKSBleGl0KDEpOwp9CgpzdGF0aWMgaW50IGNhbGNfdm1hX3NpemUoc3RydWN0IHBlX2RhdGEgKnBlKQp7CiAgaW50IGksdm1hX3NpemUgPSAwOwoKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgZHByaW50Zl93aW4zMihzdGRkZWIsICIgICBOYW1lICAgIFZTeiAgVmFkZHIgICAgIFN6UmF3ICAgRmlsZWFkciAgKlJlbG9jICpMaW5ldW0gI1JlbG9jICNMaW51bSBDaGFyXG4iKTsKICBmb3IoaT0wOyBpPCBwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKICAgIHsKICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICIlOHM6ICU0LjRseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU0LjR4ICU0LjR4ICU4LjhseFxuIiwgCgkgICAgIHBlLT5wZV9zZWdbaV0uTmFtZSwgCgkgICAgIHBlLT5wZV9zZWdbaV0uTWlzYy5WaXJ0dWFsU2l6ZSwKCSAgICAgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcywKCSAgICAgcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhLAoJICAgICBwZS0+cGVfc2VnW2ldLlBvaW50ZXJUb1Jhd0RhdGEsCgkgICAgIHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmVsb2NhdGlvbnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvTGluZW51bWJlcnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uTnVtYmVyT2ZSZWxvY2F0aW9ucywKCSAgICAgcGUtPnBlX3NlZ1tpXS5OdW1iZXJPZkxpbmVudW1iZXJzLAoJICAgICBwZS0+cGVfc2VnW2ldLkNoYXJhY3RlcmlzdGljcyk7CgkgIHZtYV9zaXplID0gTUFYKHZtYV9zaXplLAoJICAJCXBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MgKyAKCQkJcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhKTsKICAgIH0KICAgIHJldHVybiB2bWFfc2l6ZTsKfQoKc3RhdGljIHZvaWQgZG9fcmVsb2NhdGlvbnMoUEVfTU9EUkVGICpwZW0pCnsKCWludCBkZWx0YSA9IHBlbS0+bG9hZF9hZGRyIC0gcGVtLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoKCXVuc2lnbmVkIGludAkJCWxvYWRfYWRkcj0gcGVtLT5sb2FkX2FkZHI7CglJTUFHRV9CQVNFX1JFTE9DQVRJT04JCSpyID0gcGVtLT5wZV9yZWxvYzsKCWludAkJCQloZGVsdGEgPSAoZGVsdGEgPj4gMTYpICYgMHhGRkZGOwoJaW50CQkJCWxkZWx0YSA9IGRlbHRhICYgMHhGRkZGOwoKCS8qIGludCByZWxvY19zaXplID0gKi8KCglpZihkZWx0YSA9PSAwKQoJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCQlyZXR1cm47Cgl3aGlsZShyLT5WaXJ0dWFsQWRkcmVzcykKCXsKCQljaGFyICpwYWdlID0gKGNoYXIqKSBSVkEoci0+VmlydHVhbEFkZHJlc3MpOwoJCWludCBjb3VudCA9IChyLT5TaXplT2ZCbG9jayAtIDgpLzI7CgkJaW50IGk7CgkJZHByaW50Zl9maXh1cChzdGRkZWIsICIleCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsCgkJCWNvdW50LCByLT5WaXJ0dWFsQWRkcmVzcyk7CgkJLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwoJCWZvcihpPTA7aTxjb3VudDtpKyspCgkJewoJCQlpbnQgb2Zmc2V0ID0gci0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwoJCQlpbnQgdHlwZSA9IHItPlR5cGVPZmZzZXRbaV0gPj4gMTI7CgkJCWRwcmludGZfZml4dXAoc3RkZGViLCJwYXRjaGluZyAleCB0eXBlICV4XG4iLCBvZmZzZXQsIHR5cGUpOwoJCQlzd2l0Y2godHlwZSkKCQkJewoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURTogYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0g6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGhkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGxkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgojaWYgMQoJCQkJKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CiNlbHNlCgkJCQl7IGludCBoPSoodW5zaWduZWQgc2hvcnQqKShwYWdlK29mZnNldCk7CgkJCQkgIGludCBsPXItPlR5cGVPZmZzZXRbKytpXTsKCQkJCSAgKih1bnNpZ25lZCBpbnQqKShwYWdlICsgb2Zmc2V0KSA9IChoPDwxNikgKyBsICsgZGVsdGE7CgkJCQl9CiNlbmRpZgoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hBREo6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIkRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9NSVBTX0pNUEFERFI6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIklzIHRoaXMgYSBNSVBTIG1hY2hpbmUgPz8/XG4iKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIGZpeHVwIHR5cGVcbiIpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJciA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04qKSgoY2hhciopciArIHItPlNpemVPZkJsb2NrKTsKCX0KfQoJCQoKCQoJCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCVBFX0xvYWRJbWFnZQogKiBMb2FkIG9uZSBQRSBmb3JtYXQgRExML0VYRSBpbnRvIG1lbW9yeQogKiAKICogVW5sdWNraWx5IHdlIGNhbid0IGp1c3QgbW1hcCB0aGUgc2VjdGlvbnMgd2hlcmUgd2Ugd2FudCB0aGVtLCBmb3IgCiAqIChhdCBsZWFzdCkgTGludXggZG9lcyBvbmx5IHN1cHBvcnQgb2Zmc2V0IHdpdGggYXJlIG11bHRpcGxlcyBvZiB0aGUKICogdW5kZXJseWluZyBmaWxlc3lzdGVtYmxvY2tzaXplLCBidXQgUEUgRExMcyB1c3VhbGx5IGhhdmUgYWxpZ25tZW50cyBvZiA1MTIKICogYnl0ZS4gVGhpcyBmYWlscyBmb3IgaW5zdGFuY2Ugd2hlbiB5b3UgdHJ5IHRvIG1hcCBmcm9tIENEUk9NIChic2l6ZSAyMDQ4KS4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUzMiBwb2ludCB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpzdGF0aWMgUEVfTU9EVUxFICpQRV9Mb2FkSW1hZ2UoIGludCBmZCApCnsKCXN0cnVjdCBwZV9kYXRhCQkqcGU7CglzdHJ1Y3Qgc3RhdAkJc3RidWY7CgoJaWYgKC0xPT1mc3RhdChmZCwmc3RidWYpKSB7CgkJcGVycm9yKCJQRV9Mb2FkSW1hZ2U6ZnN0YXQiKTsKCQlyZXR1cm4gTlVMTDsKCX0KCXBlID0geG1hbGxvYyhzaXplb2Yoc3RydWN0IHBlX2RhdGEpKTsKCW1lbXNldChwZSwwLHNpemVvZihzdHJ1Y3QgcGVfZGF0YSkpOwoKCS8qIG1hcCB0aGUgUEUgaW1hZ2Ugc29tZXdoZXJlICovCglwZS0+bWFwcGVkZGxsID0gKEhNT0RVTEUzMiltbWFwKE5VTEwsc3RidWYuc3Rfc2l6ZSxQUk9UX1JFQUQsTUFQX1NIQVJFRCxmZCwwKTsKCWlmICghcGUtPm1hcHBlZGRsbCB8fCBwZS0+bWFwcGVkZGxsPT0tMSkgewoJCWlmIChlcnJubz09RU5PRVhFQykgewoJCQlpbnQJcmVzPTAsY3VycmVhZCA9IDA7CgoJCQlsc2VlayhmZCwwLFNFRUtfU0VUKTsKCQkJLyogbGludXg6IHNvbWUgZmlsZXN5c3RlbXMgZG9uJ3Qgc3VwcG9ydCBtbWFwIChzYW1iYSwKCQkJICogbnRmcyBhcHBhcmVudGx5KSBzbyB3ZSBoYXZlIHRvIHJlYWQgdGhlIGltYWdlIHRoZQoJCQkgKiBoYXJkIHdheQoJCQkgKi8KCQkJcGUtPm1hcHBlZGRsbCA9IHhtYWxsb2Moc3RidWYuc3Rfc2l6ZSk7CgkJCXdoaWxlIChjdXJyZWFkIDwgc3RidWYuc3Rfc2l6ZSkgewoJCQkJcmVzID0gcmVhZChmZCxwZS0+bWFwcGVkZGxsK2N1cnJlYWQsc3RidWYuc3Rfc2l6ZS1jdXJyZWFkKTsKCQkJCWlmIChyZXM8PTApIAoJCQkJCWJyZWFrOwoJCQkJY3VycmVhZCs9cmVzOwoJCQl9CgkJCWlmIChyZXMgPT0gLTEpIHsKCQkJCXBlcnJvcigiUEVfTG9hZEltYWdlOm1tYXAgY29tcGF0IHJlYWQiKTsKCQkJCWZyZWUocGUtPm1hcHBlZGRsbCk7CgkJCQlmcmVlKHBlKTsKCQkJCXJldHVybiBOVUxMOwoJCQl9CgoJCX0gZWxzZSB7CgkJCXBlcnJvcigiUEVfTG9hZEltYWdlOm1tYXAiKTsKCQkJZnJlZShwZSk7CgkJCXJldHVybiBOVUxMOwoJCX0KCX0KCS8qIGxpbmsgUEUgaGVhZGVyICovCglwZS0+cGVfaGVhZGVyID0gKElNQUdFX05UX0hFQURFUlMqKShwZS0+bWFwcGVkZGxsKygoKElNQUdFX0RPU19IRUFERVIqKXBlLT5tYXBwZWRkbGwpLT5lX2xmYW5ldykpOwoJaWYgKHBlLT5wZV9oZWFkZXItPlNpZ25hdHVyZSE9SU1BR0VfTlRfU0lHTkFUVVJFKSB7CgkJZnByaW50ZihzdGRlcnIsImltYWdlIGRvZXNuJ3QgaGF2ZSBQRSBzaWduYXR1cmUsIGJ1dCAweCUwOGx4XG4iLAoJCQlwZS0+cGVfaGVhZGVyLT5TaWduYXR1cmUKCQkpOwoJCWZyZWUocGUpOwoJCXJldHVybiBOVUxMOwoJfQoKCWlmIChwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk1hY2hpbmUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYpIHsKCQlmcHJpbnRmKHN0ZGVyciwidHJ5aW5nIHRvIGxvYWQgUEUgaW1hZ2UgZm9yIHVuc3VwcG9ydGVkIGFyY2hpdGVjdHVyZSAoIik7CgkJc3dpdGNoIChwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk1hY2hpbmUpIHsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9VTktOT1dOOgoJCQlmcHJpbnRmKHN0ZGVyciwiVW5rbm93biIpO2JyZWFrOwoJCWNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0k4NjA6CgkJCWZwcmludGYoc3RkZXJyLCJJODYwIik7YnJlYWs7CgkJY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjMwMDA6CgkJCWZwcmludGYoc3RkZXJyLCJSMzAwMCIpO2JyZWFrOwoJCWNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1I0MDAwOgoJCQlmcHJpbnRmKHN0ZGVyciwiUjQwMDAiKTticmVhazsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMTAwMDA6CgkJCWZwcmludGYoc3RkZXJyLCJSMTAwMDAiKTticmVhazsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9BTFBIQToKCQkJZnByaW50ZihzdGRlcnIsIkFscGhhIik7YnJlYWs7CgkJY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUE9XRVJQQzoKCQkJZnByaW50ZihzdGRlcnIsIlBvd2VyUEMiKTticmVhazsKCQlkZWZhdWx0OgoJCQlmcHJpbnRmKHN0ZGVyciwiVW5rbm93bi0lMDR4IixwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk1hY2hpbmUpO2JyZWFrOwoJCX0KCQlmcHJpbnRmKHN0ZGVyciwiKVxuIik7CgkJcmV0dXJuIE5VTEw7Cgl9CglwZS0+cGVfc2VnID0gKElNQUdFX1NFQ1RJT05fSEVBREVSKikoKChMUEJZVEUpKHBlLT5wZV9oZWFkZXIrMSkpLQoJCSAoMTYgLSBwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5OdW1iZXJPZlJ2YUFuZFNpemVzKSAqIHNpemVvZihJTUFHRV9EQVRBX0RJUkVDVE9SWSkpOwoKLyogRklYTUU6IHRoZSAoMTYtLi4uKSBpcyBhICpob3JyaWJsZSogaGFjayB0byBtYWtlIENPTURMRzMyLkRMTCBsb2FkIE9LLiBUaGUKICogcHJvYmxlbSBuZWVkcyB0byBiZSBmaXhlZCBwcm9wZXJseSBhdCBzb21lIHN0YWdlLgogKi8KIAlyZXR1cm4gcGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoaXMgbWFwcyBhIGxvYWRlZCBQRSBkbGwgaW50byB0aGUgYWRkcmVzcyBzcGFjZSBvZiB0aGUgc3BlY2lmaWVkIHByb2Nlc3MuCiAqLwp2b2lkClBFX01hcEltYWdlKFBFX01PRFVMRSAqcGUsUERCMzIgKnByb2Nlc3MsIE9GU1RSVUNUICpvZnMsIERXT1JEIGZsYWdzKSB7CglQRV9NT0RSRUYJCSpwZW07CglpbnQJCQlpLCByZXN1bHQ7CglpbnQJCQlsb2FkX2FkZHI7CglJTUFHRV9EQVRBX0RJUkVDVE9SWQlkaXI7CgljaGFyCQkJYnVmZmVyWzIwMF07CgljaGFyCQkJKm1vZG5hbWU7CglpbnQJCQl2bWFfc2l6ZTsKCQoJcGVtCQk9IChQRV9NT0RSRUYqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKCpwZW0pKTsKCS8qIE5PVEU6IGZpeHVwX2ltcG9ydHMgdGFrZXMgY2FyZSBvZiB0aGUgY29ycmVjdCBvcmRlciAqLwoJcGVtLT5uZXh0CT0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cglwcm9jZXNzLT5tb2RyZWZfbGlzdCA9IHBlbTsKCglwZW0tPnBlX21vZHVsZQk9IHBlOwoJaWYgKCEocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpIHsKCQlpZiAocHJvY2Vzcy0+ZXhlX21vZHJlZikKCQkJZnByaW50ZihzdGRlcnIsIm92ZXJ3cml0aW5nIG9sZCBleGVfbW9kcmVmLi4uIGFycmdoXG4iKTsKCQlwcm9jZXNzLT5leGVfbW9kcmVmID0gcGVtOwoJfQoKCWxvYWRfYWRkciAJPSBwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CglkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkxvYWQgYWRkciBpcyAleFxuIixsb2FkX2FkZHIpOwoJdm1hX3NpemUgPSBjYWxjX3ZtYV9zaXplKHBlKTsKCWxvYWRfYWRkciAJPSAoaW50KSBWaXJ0dWFsQWxsb2MoICh2b2lkKilsb2FkX2FkZHIsIHZtYV9zaXplLCBNRU1fUkVTRVJWRXxNRU1fQ09NTUlULCBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CiAgICAgICAgcGVtLT5sb2FkX2FkZHIJPSBsb2FkX2FkZHI7CgoJZHByaW50Zl93aW4zMihzdGRkZWIsICJMb2FkIGFkZHIgaXMgcmVhbGx5ICVseCwgcmFuZ2UgJXhcbiIsCgkJcGVtLT5sb2FkX2FkZHIsIHZtYV9zaXplKTsKCQoKCWZvcihpPTA7IGkgPCBwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKCXsKCQkvKiBtZW1jcHkgb25seSBub24tQlNTIHNlZ21lbnRzICovCgkJLyogRklYTUU6IHRoaXMgc2hvdWxkIGJlIGRvbmUgYnkgbW1hcCguLk1BUF9QUklWQVRFfE1BUF9GSVhFRC4uKQoJCSAqIGJ1dCBpdCBpcyBub3QgcG9zc2libGUgZm9yIChhdCBsZWFzdCkgTGludXggbmVlZHMgYW4gb2Zmc2V0CgkJICogYWxpZ25lZCB0byBhIGJsb2NrIG9uIHRoZSBmaWxlc3lzdGVtLgoJCSAqLwoJCWlmKCEocGUtPnBlX3NlZ1tpXS5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9TQ05fQ05UX1VOSU5JVElBTElaRURfREFUQSkpCgkJICAgIG1lbWNweSgoY2hhciopUlZBKHBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MpLAoJCSAgICAJKGNoYXIqKShwZS0+bWFwcGVkZGxsK3BlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmF3RGF0YSksCgkJCXBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YQoJCSAgICApOwoKCQlyZXN1bHQgPSBSVkEgKHBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MpOwojaWYgMQoJCS8qIG5vdCBuZWVkZWQsIG1lbW9yeSBpcyB6ZXJvICovCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5ic3MiKSA9PSAwKQoJCSAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgPwoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgOgoJCQkgICBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpOwojZW5kaWYKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5pZGF0YSIpID09IDApCgkJCXBlbS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5lZGF0YSIpID09IDApCgkJCXBlbS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLnJzcmMiKSA9PSAwKQoJCQlwZW0tPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIucmVsb2MiKSA9PSAwKQoJCQlwZW0tPnBlX3JlbG9jID0gKExQSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKSByZXN1bHQ7Cgl9CgoJLyogVGhlcmUgaXMgd29yZCB0aGF0IHRoZSBhY3R1YWwgbG9hZGVyIGRvZXMgbm90IGNhcmUgYWJvdXQgdGhlCgkgICBzZWN0aW9uIG5hbWVzLCBhbmQgb25seSBnb2VzIGZvciB0aGUgRGF0YURpcmVjdG9yeSAqLwoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX2V4cG9ydCAmJiAoaW50KXBlbS0+cGVfZXhwb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGV4cG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJLyogYWx3YXlzIHRydXN0IHRoZSBkaXJlY3RvcnkgKi8KCQlwZW0tPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlRdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGVtLT5wZV9pbXBvcnQgJiYgKGludClwZW0tPnBlX2ltcG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBpbXBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlbS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9SRVNPVVJDRV07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX3Jlc291cmNlICYmIChpbnQpcGVtLT5wZV9yZXNvdXJjZSE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZXNvdXJjZSBkaXJlY3Rvcnk/P1xuIik7CgkJcGVtLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCgoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0NdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGVtLT5wZV9yZWxvYyAmJiAoaW50KXBlbS0+cGVfcmVsb2MhPSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIHJlbG9jYXRpb24gbGlzdD8/XG4iKTsKCQlwZW0tPnBlX3JlbG9jID0gKHZvaWQgKikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgojaWZuZGVmIFdJTkVMSUIKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHXS5TaXplKQoJICB7CgkgICAgREVCVUdfUmVnaXN0ZXJEZWJ1Z0luZm8ocGUsIGxvYWRfYWRkciwgCgkJCXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHXS5WaXJ0dWFsQWRkcmVzcywKCQkJcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlNpemUpOwoJICB9CiNlbmRpZgoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPUFlSSUdIVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkNvcHlyaWdodCBzdHJpbmcgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiR2xvYmFsIFBvaW50ZXIgKE1JUFMpIGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMU10uU2l6ZSkKCQkgZnByaW50ZihzdGRuaW1wLCJUaHJlYWQgbG9jYWwgc3RvcmFnZSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJR10uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkxvYWQgQ29uZmlndXJhdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQk9VTkRfSU1QT1JUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiQm91bmQgSW1wb3J0IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JQVRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJJbXBvcnQgQWRkcmVzcyBUYWJsZSBkaXJlY3RvcnkgaWdub3JlZFxuIik7CglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzEzXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiVW5rbm93biBkaXJlY3RvcnkgMTMgaWdub3JlZFxuIik7CglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzE0XS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIik7CglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzE1XS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiVW5rbm93biBkaXJlY3RvcnkgMTUgaWdub3JlZFxuIik7CgoJaWYocGVtLT5wZV9yZWxvYykJZG9fcmVsb2NhdGlvbnMocGVtKTsKCWlmKHBlbS0+cGVfZXhwb3J0KQlkdW1wX2V4cG9ydHMocGVtLT5wZV9leHBvcnQsbG9hZF9hZGRyKTsKCWlmKHBlbS0+cGVfaW1wb3J0KQlmaXh1cF9pbXBvcnRzKHByb2Nlc3MscGVtKTsKICAJCQoJaWYgKHBlbS0+cGVfZXhwb3J0KQoJCW1vZG5hbWUgPSAoY2hhciopUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKTsKCWVsc2UgewoJCWNoYXIgKnM7CgkJbW9kbmFtZSA9IHMgPSBvZnMtPnN6UGF0aE5hbWU7CgkJd2hpbGUgKChzPXN0cmNocihtb2RuYW1lLCdcXCcpKSkKCQkJbW9kbmFtZSA9IHMrMTsKCQlpZiAoKHM9c3RyY2hyKG1vZG5hbWUsJy4nKSkpCgkJCSpzPSdcMCc7Cgl9CgojaWZuZGVmIFdJTkVMSUIKICAgICAgICB7CiAgICAgICAgICAgIERCR19BRERSIGRhZGRyID0geyBOVUxMLCAwLCAwIH07CiAgICAgICAgICAgIC8qIGFkZCBzdGFydCBvZiBzZWN0aW9ucyBhcyBkZWJ1Z3N5bWJvbHMgKi8KICAgICAgICAgICAgZm9yKGk9MDtpPHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucztpKyspIHsKCQlzcHJpbnRmKGJ1ZmZlciwiJXNfJXMiLG1vZG5hbWUscGUtPnBlX3NlZ1tpXS5OYW1lKTsKCQlkYWRkci5vZmY9IFJWQShwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzKTsKCQlERUJVR19BZGRTeW1ib2woYnVmZmVyLCZkYWRkciwgTlVMTCwgU1lNX1dJTjMyIHwgU1lNX0ZVTkMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGFkZCBlbnRyeSBwb2ludCAqLwogICAgICAgICAgICBzcHJpbnRmKGJ1ZmZlciwiJXNfRW50cnlQb2ludCIsbW9kbmFtZSk7CiAgICAgICAgICAgIGRhZGRyLm9mZj1SVkEocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCk7CiAgICAgICAgICAgIERFQlVHX0FkZFN5bWJvbChidWZmZXIsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7CiAgICAgICAgICAgIC8qIGFkZCBzdGFydCBvZiBETEwgKi8KICAgICAgICAgICAgZGFkZHIub2ZmPWxvYWRfYWRkcjsKICAgICAgICAgICAgREVCVUdfQWRkU3ltYm9sKG1vZG5hbWUsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7CiAgICAgICAgfQojZW5kaWYKfQoKSElOU1RBTkNFMTYgTU9EVUxFX0NyZWF0ZUluc3RhbmNlKEhNT0RVTEUxNiBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKi8KSE1PRFVMRTMyIFBFX0xvYWRMaWJyYXJ5RXgzMkEgKExQQ1NUUiBuYW1lLCBIRklMRTMyIGhGaWxlLCBEV09SRCBmbGFncykgewoJT0ZTVFJVQ1QJb2ZzOwoJSE1PRFVMRTMyCWhNb2R1bGU7CglORV9NT0RVTEUJKnBNb2R1bGU7CglQRV9NT0RSRUYJKnBlbTsKCglpZiAoKGhNb2R1bGUgPSBNT0RVTEVfRmluZE1vZHVsZSggbmFtZSApKSkgewoJCS8qIHRoZSAuRExMIGlzIGVpdGhlciBsb2FkZWQgb3IgaW50ZXJuYWwgKi8KCQloTW9kdWxlID0gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKGhNb2R1bGUpOwoJCWlmICghSElXT1JEKGhNb2R1bGUpKSAvKiBpbnRlcm5hbCAob3IgYmFkKSAqLwoJCQlyZXR1cm4gaE1vZHVsZTsKCQkvKiBjaGVjayBpZiB0aGlzIG1vZHVsZSBpcyBhbHJlYWR5IG1hcHBlZCAqLwoJCXBlbSAJPSAoKFBEQjMyKilHZXRDdXJyZW50UHJvY2Vzc0lkKCkpLT5tb2RyZWZfbGlzdDsKCQl3aGlsZSAocGVtKSB7CgkJCWlmIChwZW0tPnBlX21vZHVsZS0+bWFwcGVkZGxsID09IGhNb2R1bGUpCgkJCQlyZXR1cm4gaE1vZHVsZTsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCX0KCQlwTW9kdWxlID0gTU9EVUxFX0dldFB0cihoTW9kdWxlKTsKCX0gZWxzZSB7CgoJCS8qIHRyeSB0byBsb2FkIGJ1aWx0aW4sIGVuYWJsZWQgbW9kdWxlcyBmaXJzdCAqLwoJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU5fTG9hZE1vZHVsZSggbmFtZSwgRkFMU0UgKSkpCgkJCXJldHVybiBoTW9kdWxlOwoKCQkvKiB0cnkgdG8gb3BlbiB0aGUgc3BlY2lmaWVkIGZpbGUgKi8KCQlpZiAoSEZJTEVfRVJST1IzMj09KGhGaWxlPU9wZW5GaWxlMzIobmFtZSwmb2ZzLE9GX1JFQUQpKSkgewoJCQkvKiBOb3cgdHJ5IHRoZSBidWlsdC1pbiBldmVuIGlmIGRpc2FibGVkICovCgkJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU5fTG9hZE1vZHVsZSggbmFtZSwgVFJVRSApKSkgewoJCQkJZnByaW50Ziggc3RkZXJyLCAiV2FybmluZzogY291bGQgbm90IGxvYWQgV2luZG93cyBETEwgJyVzJywgdXNpbmcgYnVpbHQtaW4gbW9kdWxlLlxuIiwgbmFtZSApOwoJCQkJcmV0dXJuIGhNb2R1bGU7CgkJCX0KCQkJcmV0dXJuIDE7CgkJfQoJCWlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggJm9mcyApKSA8IDMyKSB7CgkJCV9sY2xvc2UzMihoRmlsZSk7CgkJCXJldHVybiBoTW9kdWxlOwoJCX0KCQlwTW9kdWxlCQk9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUgKTsKCQlwTW9kdWxlLT5mbGFncwk9IE5FX0ZGTEFHU19XSU4zMjsKCQlwTW9kdWxlLT5wZV9tb2R1bGUgPSBQRV9Mb2FkSW1hZ2UoIEZJTEVfR2V0VW5peEhhbmRsZShoRmlsZSkgKTsKCQlfbGNsb3NlMzIoaEZpbGUpOwoJCWlmICghcE1vZHVsZS0+cGVfbW9kdWxlKQoJCQlyZXR1cm4gMjE7Cgl9CgkvKiByZWN1cnNlICovCglQRV9NYXBJbWFnZShwTW9kdWxlLT5wZV9tb2R1bGUsKFBEQjMyKilHZXRDdXJyZW50UHJvY2Vzc0lkKCksJm9mcyxmbGFncyk7CglyZXR1cm4gcE1vZHVsZS0+cGVfbW9kdWxlLT5tYXBwZWRkbGw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBMb2FkIHRoZSBQRSBtYWluIC5FWEUuIEFsbCBvdGhlciBsb2FkaW5nIGlzIGRvbmUgYnkgUEVfTG9hZExpYnJhcnlFeDMyQQogKiBGSVhNRTogdGhpcyBmdW5jdGlvbiBzaG91bGQgdXNlIFBFX0xvYWRMaWJyYXJ5RXgzMkEsIGJ1dCBjdXJyZW50bHkgY2FuJ3QKICogZHVlIHRvIHRoZSBUQVNLX0NyZWF0ZVRhc2sgc3R1ZmYuCiAqLwpISU5TVEFOQ0UxNiBQRV9Mb2FkTW9kdWxlKCBIRklMRTMyIGhGaWxlLCBPRlNUUlVDVCAqb2ZzLCBMT0FEUEFSQU1TKiBwYXJhbXMgKQp7CiAgICBITU9EVUxFMTYgaE1vZHVsZTsKICAgIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKCiAgICBpZiAoKGhNb2R1bGUgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIG9mcyApKSA8IDMyKSByZXR1cm4gaE1vZHVsZTsKICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlICk7CiAgICBwTW9kdWxlLT5mbGFncyA9IE5FX0ZGTEFHU19XSU4zMjsKCiAgICBwTW9kdWxlLT5wZV9tb2R1bGUgPSBQRV9Mb2FkSW1hZ2UoIEZJTEVfR2V0VW5peEhhbmRsZShoRmlsZSkgKTsKICAgIF9sY2xvc2UzMihoRmlsZSk7CiAgICBpZiAoIXBNb2R1bGUtPnBlX21vZHVsZSkKICAgIAlyZXR1cm4gMjE7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlLCBwYXJhbXMgKTsKICAgIGlmICghKHBNb2R1bGUtPnBlX21vZHVsZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSkKICAgIHsKICAgICAgICBUQVNLX0NyZWF0ZVRhc2soIGhNb2R1bGUsIGhJbnN0YW5jZSwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy0+aEVudmlyb25tZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgKExQU1RSKVBUUl9TRUdfVE9fTElOKCBwYXJhbXMtPmNtZExpbmUgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICooKFdPUkQqKVBUUl9TRUdfVE9fTElOKHBhcmFtcy0+c2hvd0NtZCkgKyAxKSApOwogICAgfQogICAgUEVfTWFwSW1hZ2UocE1vZHVsZS0+cGVfbW9kdWxlLChQREIzMiopR2V0Q3VycmVudFByb2Nlc3NJZCgpLG9mcywwKTsKICAgIHJldHVybiBoSW5zdGFuY2U7Cn0KCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRTMyIGhNb2R1bGUgKQp7CglwcmludGYoIlBFdW5sb2FkSW1hZ2UoKSBjYWxsZWQhXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8Kc3RhdGljIHZvaWQgUEVfSW5pdERMTChQRV9NT0RSRUYgKnBlbSwgRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewogICAgUEVfTU9EVUxFCQkqcGUgPSBwZW0tPnBlX21vZHVsZTsKICAgIHVuc2lnbmVkIGludAlsb2FkX2FkZHIgPSBwZW0tPmxvYWRfYWRkcjsKCiAgICBpZiAodHlwZT09RExMX1BST0NFU1NfQVRUQUNIKQoJcGVtLT5mbGFncyB8PSBQRV9NT0RSRUZfUFJPQ0VTU19BVFRBQ0hFRDsKI2lmbmRlZiBXSU5FTElCCiAgICBpZiAoT3B0aW9ucy5kZWJ1ZykgewogICAgICAgICAgICBEQkdfQUREUiBhZGRyID0geyBOVUxMLCAwLCBSVkEocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkgfTsKICAgICAgICAgICAgREVCVUdfQWRkQnJlYWtwb2ludCggJmFkZHIgKTsKCSAgICBERUJVR19TZXRCcmVha3BvaW50cyhUUlVFKTsKICAgIH0KI2VuZGlmCgogICAgLyogIERMTF9BVFRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgZm9yIGR5bmFtaWMgbG9hZHMsIG5vdC1OVUxMIGZvciBzdGF0aWMgbG9hZHMKICAgICAqICBETExfREVUQUNIX1BST0NFU1M6CiAgICAgKgkJbHByZXNlcnZlZCBpcyBOVUxMIGlmIGNhbGxlZCBieSBGcmVlTGlicmFyeSwgbm90LU5VTEwgb3RoZXJ3aXNlCiAgICAgKiAgdGhlIFNESyBkb2Vzbid0IG1lbnRpb24gYW55dGhpbmcgZm9yIERMTF9USFJFQURfKgogICAgICovCiAgICAgICAgCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgJKHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCgkJKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICApIHsKICAgICAgICBGQVJQUk9DMzIgZW50cnkgPSAoRkFSUFJPQzMyKVJWQShwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KTsKICAgICAgICBkcHJpbnRmX3JlbGF5KCBzdGRkZWIsICJDYWxsVG8zMihlbnRyeXByb2M9JXAsbW9kdWxlPSVkLHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIHBlLT5tYXBwZWRkbGwsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgICAgICBlbnRyeSggcGUtPm1hcHBlZGRsbCwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgfQp9CgovKiBDYWxsIHRoZSBETExlbnRyeSBmdW5jdGlvbiBvZiBhbGwgZGxscyB1c2VkIGJ5IHRoYXQgcHJvY2Vzcy4KICogKE5PVEU6IHRoaXMgbWF5IHJlY3Vyc2l2ZWx5IGNhbGwgdGhpcyBmdW5jdGlvbiAoaWYgYSBsaWJyYXJ5IGNhbGxzCiAqIExvYWRMaWJyYXJ5KSAuLi4gYnV0IGl0IHdvbid0IG1hdHRlcikKICovCnZvaWQgUEVfSW5pdGlhbGl6ZURMTHMoUERCMzIgKnByb2Nlc3MsRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkgewoJUEVfTU9EUkVGCSpwZW07CgoJcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cgl3aGlsZSAocGVtKSB7CgkJaWYgKHBlbS0+ZmxhZ3MgJiBQRV9NT0RSRUZfTk9fRExMX0NBTExTKSB7CgkJCXBlbSA9IHBlbS0+bmV4dDsKCQkJY29udGludWU7CgkJfQoJCWlmICh0eXBlPT1ETExfUFJPQ0VTU19BVFRBQ0gpIHsKCQkJaWYgKHBlbS0+ZmxhZ3MgJiBQRV9NT0RSRUZfUFJPQ0VTU19BVFRBQ0hFRCkgewoJCQkJcGVtID0gcGVtLT5uZXh0OwoJCQkJY29udGludWU7CgkJCX0KCQl9CgkJUEVfSW5pdERMTCggcGVtLCB0eXBlLCBscFJlc2VydmVkICk7CgkJcGVtID0gcGVtLT5uZXh0OwoJfQp9Cgp2b2lkIFBFX0luaXRUbHMoUERCMzIgKnBkYikKewoJLyogRklYTUU6IHRscyBjYWxsYmFja3MgPz8/ICovCglQRV9NT0RSRUYJCSpwZW07CglJTUFHRV9OVF9IRUFERVJTCSpwZWg7CglEV09SRAkJCXNpemUsZGF0YXNpemUsaW5kZXg7CglMUFZPSUQJCQltZW07CglMUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKCglwZW0gPSBwZGItPm1vZHJlZl9saXN0OwoJd2hpbGUgKHBlbSkgewoJCXBlaCA9IHBlbS0+cGVfbW9kdWxlLT5wZV9oZWFkZXI7CgkJaWYgKCFwZWgtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpIHsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJcGRpciA9IChMUFZPSUQpKHBlbS0+bG9hZF9hZGRyICsgcGVoLT5PcHRpb25hbEhlYWRlci4KCQkJRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcyk7CgkJaW5kZXgJPSBUbHNBbGxvYygpOwoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLChMUFZPSUQpIHBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSwgZGF0YXNpemUpOwoJCVRsc1NldFZhbHVlKGluZGV4LG1lbSk7CgkJKihwZGlyLT5BZGRyZXNzT2ZJbmRleCk9aW5kZXg7ICAgCgkJcGVtPXBlbS0+bmV4dDsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMgKEtFUk5FTDMyLjc0KQogKiBEb24ndCBjYWxsIERsbEVudHJ5UG9pbnQgZm9yIERMTF9USFJFQURfe0FUVEFDSCxERVRBQ0h9IGlmIHNldC4KICovCkJPT0wzMiBXSU5BUEkgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhITU9EVUxFMzIgaE1vZHVsZSkKewoJUERCMzIJKnByb2Nlc3MgPSAoUERCMzIqKUdldEN1cnJlbnRQcm9jZXNzSWQoKTsKCVBFX01PRFJFRgkqcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7CgoJd2hpbGUgKHBlbSkgewoJCWlmIChwZW0tPnBlX21vZHVsZS0+bWFwcGVkZGxsID09IGhNb2R1bGUpCgkJCXBlbS0+ZmxhZ3N8PVBFX01PRFJFRl9OT19ETExfQ0FMTFM7CgkJcGVtID0gcGVtLT5uZXh0OwoJfQoJcmV0dXJuIFRSVUU7Cn0KCg==