I2lmbmRlZiBXSU5FTElCCi8qIAogKiAgQ29weXJpZ2h0CTE5OTQJRXJpYyBZb3VuZGFsZSAmIEVyaWsgQm9zCiAqICBDb3B5cmlnaHQJMTk5NQlNYXJ0aW4gdm9uIEz2d2lzCiAqICBDb3B5cmlnaHQgICAxOTk2ICAgIE1hcmN1cyBNZWlzc25lcgogKgogKgliYXNlZCBvbiBFcmljIFlvdW5kYWxlJ3MgcGUtdGVzdCBhbmQ6CiAqCiAqCWZ0cC5taWNyb3NvZnQuY29tOi9wdWIvZGV2ZWxvcGVyL01TRE4vQ0Q4L1BFRklMRS5aSVAKICogbWFrZSB0aGF0OgogKglmdHAubWljcm9zb2Z0LmNvbTovZGV2ZWxvcHIvTVNETi9PY3RDRC9QRUZJTEUuWklQCiAqLwoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwZV9pbWFnZS5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJnbG9iYWwuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAic3RkZGVidWcuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJkZWJ1Z2dlci5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgoKLyogY29udmVydCBQRSBpbWFnZSBWaXJ0dWFsQWRkcmVzcyB0byBSZWFsIEFkZHJlc3MgKi8KI2RlZmluZSBSVkEoeCkgKCh1bnNpZ25lZCBpbnQpbG9hZF9hZGRyKyh1bnNpZ25lZCBpbnQpKHgpKQoKdm9pZCBkdW1wX2V4cG9ydHMoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqIHBlX2V4cG9ydHMsIHVuc2lnbmVkIGludCBsb2FkX2FkZHIpCnsgCiAgY2hhcgkJKk1vZHVsZSwqczsKICBpbnQJCWk7CiAgdV9zaG9ydAkqb3JkaW5hbDsKICB1X2xvbmcJKmZ1bmN0aW9uLCpmdW5jdGlvbnM7CiAgdV9jaGFyCSoqbmFtZSwqZW5hbWU7CiAgY2hhcgkJYnVmZmVyWzEwMDBdOwogIERCR19BRERSCWRhZGRyOwoKICBkYWRkci5zZWcgPSAwOwogIGRhZGRyLnR5cGUgPSBOVUxMOwogIE1vZHVsZSA9IChjaGFyKilSVkEocGVfZXhwb3J0cy0+TmFtZSk7CiAgZHByaW50Zl93aW4zMihzdGRkZWIsIlxuKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuTW9kdWxlIG5hbWUgaXMgJXMsICVsZCBmdW5jdGlvbnMsICVsZCBuYW1lc1xuIiwgCgkgTW9kdWxlLAoJIHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zLAoJIHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXMpOwoKICBvcmRpbmFsPSh1X3Nob3J0KikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CiAgZnVuY3Rpb25zPWZ1bmN0aW9uPSh1X2xvbmcqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lPSh1X2NoYXIqKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgZHByaW50Zl93aW4zMihzdGRkZWIsIiUtMzJzIE9yZGluYWwgVmlydCBBZGRyXG4iLCAiRnVuY3Rpb24gTmFtZSIpOwogIGZvciAoaT0wO2k8cGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnM7aSsrKSB7CiAgICAgIGlmIChpPHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXMpIHsKCSAgZW5hbWU9KGNoYXIqKVJWQSgqbmFtZSsrKTsKCSAgZHByaW50Zl93aW4zMihzdGRkZWIsIiUtMzJzICU0ZCAgICAlOC44bHggKCU4LjhseClcbiIsZW5hbWUsKm9yZGluYWwsZnVuY3Rpb25zWypvcmRpbmFsXSwqZnVuY3Rpb24pOwoJICBzcHJpbnRmKGJ1ZmZlciwiJXNfJXMiLE1vZHVsZSxlbmFtZSk7CgkgIGRhZGRyLm9mZj1SVkEoZnVuY3Rpb25zWypvcmRpbmFsXSk7CgkgIG9yZGluYWwrKzsKCSAgZnVuY3Rpb24rKzsKICAgICAgfSBlbHNlIHsKICAgICAgCSAgLyogb3JkaW5hbHMvbmFtZXMgbm8gbG9uZ2VyIHZhbGlkLCBidXQgd2Ugc3RpbGwgZ290IGZ1bmN0aW9ucyAqLwoJICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiJS0zMnMgJTRzICAgICU4cyAlOC44bHhcbiIsIiIsIiIsIiIsKmZ1bmN0aW9uKTsKCSAgc3ByaW50ZihidWZmZXIsIiVzXyVkIixNb2R1bGUsaSk7CgkgIGRhZGRyLm9mZj1SVkEoKmZ1bmN0aW9ucyk7CgkgIGZ1bmN0aW9uKys7CiAgICAgIH0KICAgICAgd2hpbGUgKChzPXN0cmNocihidWZmZXIsJy4nKSkpICpzPSdfJzsKICAgICAgREVCVUdfQWRkU3ltYm9sKGJ1ZmZlciwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnRsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgTmFtZSBsaXN0LiAKICoJLSBsb29rIHVwIHRoZSBvcmRpbmFsIHdpdGggdGhhdCBpbmRleC4KICoJLSB1c2UgdGhlIG9yZGluYWwgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKiBJZiBpdCBpcyBhIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICovCkZBUlBST0MzMiBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbihzdHJ1Y3QgcGVfZGF0YSAqcGUsIExQQ1NUUiBmdW5jTmFtZSkKewoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqIGV4cG9ydHMgPSBwZS0+cGVfZXhwb3J0OwoJdW5zaWduZWQgbG9hZF9hZGRyID0gcGUtPmxvYWRfYWRkcjsKCXVfc2hvcnQgKiBvcmRpbmFsOwoJdV9sb25nICogZnVuY3Rpb247Cgl1X2NoYXIgKiogbmFtZSwgKmVuYW1lOwoJaW50IGk7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJZHByaW50Zl93aW4zMihzdGRkZWIsIlBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCVzKVxuIixmdW5jTmFtZSk7CgllbHNlCgkJZHByaW50Zl93aW4zMihzdGRkZWIsIlBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCVkKVxuIiwoaW50KWZ1bmNOYW1lKTsKCWlmICghZXhwb3J0cykKCQlyZXR1cm4gTlVMTDsKCW9yZGluYWw9KHVfc2hvcnQqKSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSh1X2xvbmcqKSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWU9KHVfY2hhciAqKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWlmIChISVdPUkQoZnVuY05hbWUpKSB7CgkJZm9yKGk9MDsgaTxleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspIHsKCQkJZW5hbWU9KGNoYXIqKSBSVkEoKm5hbWUpOwoJCQlpZighc3RyY21wKGVuYW1lLGZ1bmNOYW1lKSkKCQkJCXJldHVybiAoRkFSUFJPQzMyKSBSVkEoZnVuY3Rpb25bKm9yZGluYWxdKTsKCQkJb3JkaW5hbCsrOwoJCQluYW1lKys7CgkJfQoJfSBlbHNlIHsKCQlpZiAoTE9XT1JEKGZ1bmNOYW1lKS1leHBvcnRzLT5CYXNlID4gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpIHsKCQkJZHByaW50Zl93aW4zMihzdGRkZWIsIglvcmRpbmFsICVkIG91dCBvZiByYW5nZSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9XT1JEKGZ1bmNOYW1lKSk7CgkJCXJldHVybiBOVUxMOwoJCX0KCQlyZXR1cm4gKEZBUlBST0MzMikgUlZBKGZ1bmN0aW9uWyhpbnQpZnVuY05hbWUtZXhwb3J0cy0+QmFzZV0pOwoJfQoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgCmZpeHVwX2ltcG9ydHMgKHN0cnVjdCBwZV9kYXRhICpwZSwgSE1PRFVMRTE2IGhNb2R1bGUpCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICpwZV9pbXA7CiAgICBpbnQJZml4dXBfZmFpbGVkID0gMDsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIgPSBwZS0+bG9hZF9hZGRyOwogICAgaW50IGk7CiAgICBORV9NT0RVTEUgKm5lX21vZDsKICAgIEhNT0RVTEUxNiAqbW9kX3B0cjsKICAgIGNoYXIgKm1vZG5hbWU7CiAgICAKICAgIGlmIChwZS0+cGVfZXhwb3J0KQogICAgCW1vZG5hbWUgPSAoY2hhciopIFJWQShwZS0+cGVfZXhwb3J0LT5OYW1lKTsKICAgIGVsc2UKICAgICAgICBtb2RuYW1lID0gIjx1bmtub3duPiI7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiXG5EdW1waW5nIGltcG9ydHMgbGlzdFxuIik7CgogICAgLyogZmlyc3QsIGNvdW50IHRoZSBudW1iZXIgb2YgaW1wb3J0ZWQgbm9uLWludGVybmFsIG1vZHVsZXMgKi8KICAgIHBlX2ltcCA9IHBlLT5wZV9pbXBvcnQ7CgogICAgLyogRklYTUU6IHNob3VsZCB0ZXJtaW5hdGUgb24gMCBDaGFyYWN0ZXJpc3RpY3MgKi8KICAgIGZvciAoaSA9IDA7IHBlX2ltcC0+TmFtZTsgcGVfaW1wKyspCglpKys7CgogICAgLyogTm93LCBhbGxvY2F0ZSBtZW1vcnkgZm9yIGRsbHNfdG9faW5pdCAqLwogICAgbmVfbW9kID0gR2xvYmFsTG9jazE2IChoTW9kdWxlKTsKICAgIG5lX21vZC0+ZGxsc190b19pbml0ID0gR0xPQkFMX0FsbG9jKEdNRU1fWkVST0lOSVQsIChpKzEpKnNpemVvZihITU9EVUxFMTYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaE1vZHVsZSwgRkFMU0UsIEZBTFNFLCBGQUxTRSk7CiAgICBtb2RfcHRyID0gR2xvYmFsTG9jazE2IChuZV9tb2QtPmRsbHNfdG9faW5pdCk7CiAgICAvKiBsb2FkIHRoZSBtb2R1bGVzIGFuZCBwdXQgdGhlaXIgaGFuZGxlcyBpbnRvIHRoZSBsaXN0ICovCiAKICAgICAvKiBGSVhNRTogc2hvdWxkIHRlcm1pbmF0ZSBvbiAwIENoYXJhY3RlcmlzdGljcyAqLwogICAgIGZvciAoaSA9IDAsIHBlX2ltcCA9IHBlLT5wZV9pbXBvcnQ7IHBlX2ltcC0+TmFtZTsgcGVfaW1wKyspIHsKIAljaGFyICpuYW1lID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7Cgltb2RfcHRyW2ldID0gTU9EVUxFX0xvYWQoIG5hbWUsIChMUFZPSUQpLTEsIEZBTFNFICk7CglpZiAobW9kX3B0cltpXSA8PSAoSE1PRFVMRTE2KSAzMikgewoJICAgIGNoYXIgKnAsIGJ1ZmZlclsyNTZdOwoKCSAgICAvKiBUcnkgd2l0aCBwcmVwZW5kaW5nIHRoZSBwYXRoIG9mIHRoZSBjdXJyZW50IG1vZHVsZSAqLwoJICAgIEdldE1vZHVsZUZpbGVOYW1lMTYgKGhNb2R1bGUsIGJ1ZmZlciwgc2l6ZW9mIChidWZmZXIpKTsKCSAgICBpZiAoIShwID0gc3RycmNociAoYnVmZmVyLCAnXFwnKSkpCgkJcCA9IGJ1ZmZlcjsKCSAgICBzdHJjcHkgKHAgKyAxLCBuYW1lKTsKCSAgICBtb2RfcHRyW2ldID0gTU9EVUxFX0xvYWQoIGJ1ZmZlciwgKExQVk9JRCktMSwgRkFMU0UgKTsKCX0KCWlmIChtb2RfcHRyW2ldIDw9IChITU9EVUxFMTYpIDMyKSB7CgkgICAgZnByaW50ZiAoc3RkZXJyLCAiTW9kdWxlICVzIG5vdCBmb3VuZFxuIiwgbmFtZSk7CgkgICAgZXhpdCAoMCk7Cgl9CglpKys7CiAgICB9CiAgICBwZV9pbXAgPSBwZS0+cGVfaW1wb3J0OwogICAgd2hpbGUgKHBlX2ltcC0+TmFtZSkgewoJY2hhcgkJCSpNb2R1bGU7CglJTUFHRV9JTVBPUlRfQllfTkFNRQkqcGVfbmFtZTsKCUxQSU1BR0VfVEhVTktfREFUQQlpbXBvcnRfbGlzdCx0aHVua19saXN0OwoJaW50CQkJb3JkaW1wb3J0d2FybmVkOwoKICAgICAgICBvcmRpbXBvcnR3YXJuZWQgPSAwOwoJTW9kdWxlID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CglkcHJpbnRmX3dpbjMyIChzdGRkZWIsICIlc1xuIiwgTW9kdWxlKTsKCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rKTsKCSAgICB0aHVua19saXN0ID0gKExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgoJICAgIHdoaWxlIChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBpZighbHN0cm5jbXBpMzJBKE1vZHVsZSwia2VybmVsMzIiLDgpICYmICFvcmRpbXBvcnR3YXJuZWQpewoJCSAgICAgICBmcHJpbnRmKHN0ZGVyciwiJXMgaW1wb3J0cyBrZXJuZWwzMi5kbGwgYnkgb3JkaW5hbC4gTWF5IGNyYXNoLlxuIixtb2RuYW1lKTsKCQkgICAgICAgb3JkaW1wb3J0d2FybmVkID0gMTsKCQkgICAgfQoJCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICItLS0gT3JkaW5hbCAlcywlZFxuIiwgTW9kdWxlLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLChMUENTVFIpb3JkaW5hbCk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJZnByaW50ZihzdGRlcnIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBvcmRpbmFsKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9IGVsc2UgewkJLyogaW1wb3J0IGJ5IG5hbWUgKi8KCQkgICAgcGVfbmFtZSA9IChMUElNQUdFX0lNUE9SVF9CWV9OQU1FKVJWQShpbXBvcnRfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMigKCQkJCQkJTU9EVUxFX0ZpbmRNb2R1bGUgKE1vZHVsZSksCgkJCQkJCXBlX25hbWUtPk5hbWUpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9CgkJaW1wb3J0X2xpc3QrKzsKCQl0aHVua19saXN0Kys7CgkgICAgfQoJfSBlbHNlIHsJLyogQm9ybGFuZCBzdHlsZSAqLwoJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIkJvcmxhbmQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICB0aHVua19saXN0ID0gKExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgkgICAgd2hpbGUgKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIC8qIG5vdCBzdXJlIGFib3V0IHRoaXMgYnJhbmNoLCBidXQgaXQgc2VlbXMgdG8gd29yayAqLwoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCk7CgoKCQkgICAgaWYgKCFsc3RybmNtcGkzMkEoTW9kdWxlLCJrZXJuZWwzMiIsOCkgJiYgCgkJICAgIAkhb3JkaW1wb3J0d2FybmVkCgkJICAgICkgewoJCSAgICAgICBmcHJpbnRmKHN0ZGVyciwiJXMgaW1wb3J0cyBrZXJuZWwzMi5kbGwgYnkgb3JkaW5hbC4gTWF5IGNyYXNoLlxuIixtb2RuYW1lKTsKCQkgICAgICAgb3JkaW1wb3J0d2FybmVkID0gMTsKCQkgICAgfQoJCSAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiLS0tIE9yZGluYWwgJXMuJWRcbiIsTW9kdWxlLG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClHZXRQcm9jQWRkcmVzczMyKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSksCgkJCQkJCSAgICAgKExQQ1NUUikgb3JkaW5hbCk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJZnByaW50ZihzdGRlcnIsICJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSxvcmRpbmFsKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBwZV9uYW1lPShMUElNQUdFX0lNUE9SVF9CWV9OQU1FKSBSVkEodGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIGRwcmludGZfd2luMzIoc3RkZGViLCItLS0gJXMgJXMuJWRcbiIsCgkJICAgCQkgIHBlX25hbWUtPk5hbWUsTW9kdWxlLHBlX25hbWUtPkhpbnQpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClHZXRQcm9jQWRkcmVzczMyKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSkscGVfbmFtZS0+TmFtZSk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCWZwcmludGYoc3RkZXJyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwoJCSAgICAJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0KCXBlX2ltcCsrOwogICAgfQogICAgaWYgKGZpeHVwX2ZhaWxlZCkgZXhpdCgxKTsKfQoKc3RhdGljIHZvaWQgY2FsY192bWFfc2l6ZShzdHJ1Y3QgcGVfZGF0YSAqcGUpCnsKICBpbnQgaTsKCiAgZHByaW50Zl93aW4zMihzdGRkZWIsICJEdW1wIG9mIHNlZ21lbnQgdGFibGVcbiIpOwogIGRwcmludGZfd2luMzIoc3RkZGViLCAiICAgTmFtZSAgICBWU3ogIFZhZGRyICAgICBTelJhdyAgIEZpbGVhZHIgICpSZWxvYyAqTGluZXVtICNSZWxvYyAjTGludW0gQ2hhclxuIik7CiAgZm9yKGk9MDsgaTwgcGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyspCiAgICB7CiAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiJThzOiAlNC40bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlNC40eCAlNC40eCAlOC44bHhcbiIsIAoJICAgICBwZS0+cGVfc2VnW2ldLk5hbWUsIAoJICAgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUsCgkgICAgIHBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MsCgkgICAgIHBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YSwKCSAgICAgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SYXdEYXRhLAoJICAgICBwZS0+cGVfc2VnW2ldLlBvaW50ZXJUb1JlbG9jYXRpb25zLAoJICAgICBwZS0+cGVfc2VnW2ldLlBvaW50ZXJUb0xpbmVudW1iZXJzLAoJICAgICBwZS0+cGVfc2VnW2ldLk51bWJlck9mUmVsb2NhdGlvbnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uTnVtYmVyT2ZMaW5lbnVtYmVycywKCSAgICAgcGUtPnBlX3NlZ1tpXS5DaGFyYWN0ZXJpc3RpY3MpOwoJICBwZS0+dm1hX3NpemUgPSBNQVgocGUtPnZtYV9zaXplLAoJICAJCXBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MgKyAKCQkJcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhKTsKICAgIH0KfQoKc3RhdGljIHZvaWQgZG9fcmVsb2NhdGlvbnMoc3RydWN0IHBlX2RhdGEgKnBlKQp7CglpbnQgZGVsdGEgPSBwZS0+bG9hZF9hZGRyIC0gcGUtPmJhc2VfYWRkcjsKCXVuc2lnbmVkIGludCBsb2FkX2FkZHIgPSBwZS0+bG9hZF9hZGRyOwoJSU1BR0VfQkFTRV9SRUxPQ0FUSU9OCSpyID0gcGUtPnBlX3JlbG9jOwoJaW50IGhkZWx0YSA9IChkZWx0YSA+PiAxNikgJiAweEZGRkY7CglpbnQgbGRlbHRhID0gZGVsdGEgJiAweEZGRkY7CgoJLyogaW50IHJlbG9jX3NpemUgPSAqLwoKCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlZpcnR1YWxBZGRyZXNzKQoJewoJCWNoYXIgKnBhZ2UgPSAoY2hhciopIFJWQShyLT5WaXJ0dWFsQWRkcmVzcyk7CgkJaW50IGNvdW50ID0gKHItPlNpemVPZkJsb2NrIC0gOCkvMjsKCQlpbnQgaTsKCQlkcHJpbnRmX2ZpeHVwKHN0ZGRlYiwgIiV4IHJlbG9jYXRpb25zIGZvciBwYWdlICVseFxuIiwKCQkJY291bnQsIHItPlZpcnR1YWxBZGRyZXNzKTsKCQkvKiBwYXRjaGluZyBpbiByZXZlcnNlIG9yZGVyICovCgkJZm9yKGk9MDtpPGNvdW50O2krKykKCQl7CgkJCWludCBvZmZzZXQgPSByLT5UeXBlT2Zmc2V0W2ldICYgMHhGRkY7CgkJCWludCB0eXBlID0gci0+VHlwZU9mZnNldFtpXSA+PiAxMjsKCQkJZHByaW50Zl9maXh1cChzdGRkZWIsInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CiNpZiAxCgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKI2Vsc2UKCQkJCXsgaW50IGg9Kih1bnNpZ25lZCBzaG9ydCopKHBhZ2Urb2Zmc2V0KTsKCQkJCSAgaW50IGw9ci0+VHlwZU9mZnNldFsrK2ldOwoJCQkJICAqKHVuc2lnbmVkIGludCopKHBhZ2UgKyBvZmZzZXQpID0gKGg8PDE2KSArIGwgKyBkZWx0YTsKCQkJCX0KI2VuZGlmCgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSEFESjoKCQkJCWZwcmludGYoc3RkZXJyLCAiRG9uJ3Qga25vdyB3aGF0IHRvIGRvIHdpdGggSU1BR0VfUkVMX0JBU0VEX0hJR0hBREpcbiIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX01JUFNfSk1QQUREUjoKCQkJCWZwcmludGYoc3RkZXJyLCAiSXMgdGhpcyBhIE1JUFMgbWFjaGluZSA/Pz9cbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gZml4dXAgdHlwZVxuIik7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyICsgci0+U2l6ZU9mQmxvY2spOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBleGVjdXRhYmxlIGludG8gbWVtb3J5CiAqLwpzdGF0aWMgc3RydWN0IHBlX2RhdGEgKlBFX0xvYWRJbWFnZSggaW50IGZkLCBITU9EVUxFMTYgaE1vZHVsZSwgV09SRCBvZmZzZXQgKQp7CglzdHJ1Y3QgcGVfZGF0YQkJKnBlOwoJaW50CQkJaSwgcmVzdWx0OwoJaW50CQkJbG9hZF9hZGRyOwoJSU1BR0VfREFUQV9ESVJFQ1RPUlkJZGlyOwoJY2hhcgkJCWJ1ZmZlclsyMDBdOwoJREJHX0FERFIJCWRhZGRyOwoKCWRhZGRyLnNlZz0wOwoJZGFkZHIudHlwZSA9IE5VTEw7CglwZSA9IHhtYWxsb2Moc2l6ZW9mKHN0cnVjdCBwZV9kYXRhKSk7CgltZW1zZXQocGUsMCxzaXplb2Yoc3RydWN0IHBlX2RhdGEpKTsKCXBlLT5wZV9oZWFkZXIgPSB4bWFsbG9jKHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSk7CgoJLyogcmVhZCBQRSBoZWFkZXIgKi8KCWxzZWVrKCBmZCwgb2Zmc2V0LCBTRUVLX1NFVCk7CglyZWFkKCBmZCwgcGUtPnBlX2hlYWRlciwgc2l6ZW9mKElNQUdFX05UX0hFQURFUlMpKTsKCi8qIEZJWE1FOiB0aGlzIGlzIGEgKmhvcnJpYmxlKiBoYWNrIHRvIG1ha2UgQ09NRExHMzIuRExMIGxvYWQgT0suIFRoZQpwcm9ibGVtIG5lZWRzIHRvIGJlIGZpeGVkIHByb3Blcmx5IGF0IHNvbWUgc3RhZ2UgKi8KCglpZiAocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuTnVtYmVyT2ZSdmFBbmRTaXplcyAhPSAxNikgewoJCXByaW50ZigiU2hvcnQgUEUgSGVhZGVyISEhXG4iKTsKCQlsc2VlayggZmQsIC0oMTYgLSBwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5OdW1iZXJPZlJ2YUFuZFNpemVzKSAqIHNpemVvZihJTUFHRV9EQVRBX0RJUkVDVE9SWSksIFNFRUtfQ1VSKTsKCX0KCi8qIGhvcnJpYmxlIGhhY2sgZW5kcyAhISEgKi8KCS8qIHJlYWQgc2VjdGlvbnMgKi8KCXBlLT5wZV9zZWcgPSB4bWFsbG9jKHNpemVvZihJTUFHRV9TRUNUSU9OX0hFQURFUikgKiAKCQkJCSAgIHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucyk7CglyZWFkKCBmZCwgcGUtPnBlX3NlZywgc2l6ZW9mKElNQUdFX1NFQ1RJT05fSEVBREVSKSAqIAoJCQlwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnMpOwoKCWxvYWRfYWRkciA9IHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCXBlLT5iYXNlX2FkZHI9bG9hZF9hZGRyOwoJcGUtPnZtYV9zaXplPTA7CglkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkxvYWQgYWRkciBpcyAleFxuIixsb2FkX2FkZHIpOwoJY2FsY192bWFfc2l6ZShwZSk7CgojaWYgMAoJLyogV2UgdXNlIG1hbGxvYyBoZXJlLCB3aGlsZSBhIGh1Z2UgcGFydCBvZiB0aGF0IGFkZHJlc3Mgc3BhY2UgZG9lcwoJICAgbm90IGJlIHN1cHBvcnRlZCBieSBhY3R1YWwgbWVtb3J5LiBJdCBoYXMgdG8gYmUgY29udGlndW91cywgdGhvdWdoLgoJICAgSSBkb24ndCBrbm93IGlmIG1tYXAoIi9kZXYvbnVsbCIpOyB3b3VsZCBkbyBhbnkgYmV0dGVyLgoJICAgV2hhdCBJJ2QgcmVhbGx5IGxpa2UgdG8gZG8gaXMgYSBXaW4zMiBzdHlsZSBWaXJ0dWFsQWxsb2MvTWFwVmlld09mRmlsZQoJICAgc2VxdWVuY2UgKi8KCWxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHIgPSAoaW50KXhtYWxsb2MocGUtPnZtYV9zaXplKTsKCW1lbXNldCggbG9hZF9hZGRyLCAwLCBwZS0+dm1hX3NpemUpOwojZWxzZQoJbG9hZF9hZGRyID0gIHBlLT5sb2FkX2FkZHIgPSBWaXJ0dWFsQWxsb2MoIE5VTEwsIHBlLT52bWFfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUVNX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwojZW5kaWYKCglkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkxvYWQgYWRkciBpcyByZWFsbHkgJXgsIHJhbmdlICV4XG4iLAoJCXBlLT5sb2FkX2FkZHIsIHBlLT52bWFfc2l6ZSk7CgkKCglmb3IoaT0wOyBpIDwgcGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyspCgl7CgkJLyogbG9hZCBvbmx5IG5vbi1CU1Mgc2VnbWVudHMgKi8KCQlpZihwZS0+cGVfc2VnW2ldLkNoYXJhY3RlcmlzdGljcyAmIAoJCQl+IElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKQoJCWlmKGxzZWVrKGZkLHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmF3RGF0YSxTRUVLX1NFVCkgPT0gLTEKCQl8fCByZWFkKGZkLChjaGFyKilSVkEocGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyksCgkJCSAgIHBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YSkgIT0gcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhKQoJCXsKCQkJZnByaW50ZihzdGRlcnIsIkZhaWxlZCB0byBsb2FkIHNlY3Rpb24gJXhcbiIsIGkpOwoJCQlleGl0KDApOwoJCX0KCQlyZXN1bHQgPSBSVkEgKHBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MpOwojaWYgMQoJCS8qIG5vdCBuZWVkZWQsIG1lbW9yeSBpcyB6ZXJvICovCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5ic3MiKSA9PSAwKQoJCSAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgPwoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgOgoJCQkgICBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpOwojZW5kaWYKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5pZGF0YSIpID09IDApCgkJCXBlLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgcmVzdWx0OwoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmVkYXRhIikgPT0gMCkKCQkJcGUtPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5yc3JjIikgPT0gMCkKCQkJcGUtPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIucmVsb2MiKSA9PSAwKQoJCQlwZS0+cGVfcmVsb2MgPSAoTFBJTUFHRV9CQVNFX1JFTE9DQVRJT04pIHJlc3VsdDsKCgl9CgoJLyogVGhlcmUgaXMgd29yZCB0aGF0IHRoZSBhY3R1YWwgbG9hZGVyIGRvZXMgbm90IGNhcmUgYWJvdXQgdGhlCgkgICBzZWN0aW9uIG5hbWVzLCBhbmQgb25seSBnb2VzIGZvciB0aGUgRGF0YURpcmVjdG9yeSAqLwoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfZXhwb3J0ICYmIChpbnQpcGUtPnBlX2V4cG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBleHBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCS8qIGFsd2F5cyB0cnVzdCB0aGUgZGlyZWN0b3J5ICovCgkJcGUtPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlRdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGUtPnBlX2ltcG9ydCAmJiAoaW50KXBlLT5wZV9pbXBvcnQhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgaW1wb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQlwZS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9SRVNPVVJDRV07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfcmVzb3VyY2UgJiYgKGludClwZS0+cGVfcmVzb3VyY2UhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgcmVzb3VyY2UgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCgoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0NdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGUtPnBlX3JlbG9jICYmIChpbnQpcGUtPnBlX3JlbG9jIT0gUlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZWxvY2F0aW9uIGxpc3Q/P1xuIik7CgkJcGUtPnBlX3JlbG9jID0gKHZvaWQgKikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlNpemUpCgkgIHsKCSAgICBERUJVR19SZWdpc3RlckRlYnVnSW5mbyhmZCwgcGUsIGxvYWRfYWRkciwgCgkJCXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHXS5WaXJ0dWFsQWRkcmVzcywKCQkJcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlNpemUpOwoJICB9CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09QWVJJR0hUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiQ29weXJpZ2h0IHN0cmluZyBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9HTE9CQUxQVFJdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJHbG9iYWwgUG9pbnRlciAoTUlQUykgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfVExTXS5TaXplKQoJCSBkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlRocmVhZCBsb2NhbCBzdG9yYWdlIGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0xPQURfQ09ORklHXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CT1VORF9JTVBPUlRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTNdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxMyBpZ25vcmVkXG4iKTsKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxNCBpZ25vcmVkXG4iKTsKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTVdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxNSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfcmVsb2MpIGRvX3JlbG9jYXRpb25zKHBlKTsKCWlmKHBlLT5wZV9pbXBvcnQpIGZpeHVwX2ltcG9ydHMocGUsIGhNb2R1bGUpOwoJaWYocGUtPnBlX2V4cG9ydCkgZHVtcF9leHBvcnRzKHBlLT5wZV9leHBvcnQsbG9hZF9hZGRyKTsKICAJCQoJaWYgKHBlLT5wZV9leHBvcnQpIHsKCQljaGFyCSpzOwoKCQkvKiBhZGQgc3RhcnQgb2Ygc2VjdGlvbnMgYXMgZGVidWdzeW1ib2xzICovCgkJZm9yKGk9MDtpPHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucztpKyspIHsKCQkJc3ByaW50ZihidWZmZXIsIiVzXyVzIiwKCQkJCShjaGFyKilSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSksCgkJCQlwZS0+cGVfc2VnW2ldLk5hbWUKCQkJKTsKCQkJZGFkZHIub2ZmPSBSVkEocGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgIAkJCXdoaWxlICgocz1zdHJjaHIoYnVmZmVyLCcuJykpKSAqcz0nXyc7CgkJCURFQlVHX0FkZFN5bWJvbChidWZmZXIsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7CgkJfQoJCS8qIGFkZCBlbnRyeSBwb2ludCAqLwoJCXNwcmludGYoYnVmZmVyLCIlc19FbnRyeVBvaW50IiwoY2hhciopUlZBKHBlLT5wZV9leHBvcnQtPk5hbWUpKTsKCQlkYWRkci5vZmY9UlZBKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpOwogICAgICAJCXdoaWxlICgocz1zdHJjaHIoYnVmZmVyLCcuJykpKSAqcz0nXyc7CgkJREVCVUdfQWRkU3ltYm9sKGJ1ZmZlciwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKCQkvKiBhZGQgc3RhcnQgb2YgRExMICovCgkJZGFkZHIub2ZmPWxvYWRfYWRkcjsKCQlERUJVR19BZGRTeW1ib2woKGNoYXIqKSBSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSksJmRhZGRyLAoJCQkJTlVMTCwgU1lNX1dJTjMyIHwgU1lNX0ZVTkMpOwoJfQogICAgICAgIHJldHVybiBwZTsKfQoKSElOU1RBTkNFMTYgTU9EVUxFX0NyZWF0ZUluc3RhbmNlKEhNT0RVTEUxNiBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CgpISU5TVEFOQ0UxNiBQRV9Mb2FkTW9kdWxlKCBpbnQgZmQsIE9GU1RSVUNUICpvZnMsIExPQURQQVJBTVMqIHBhcmFtcyApCnsKICAgIEhNT0RVTEUxNiBoTW9kdWxlOwogICAgSElOU1RBTkNFMTYgaEluc3RhbmNlOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgc3RydWN0IG16X2hlYWRlcl9zIG16X2hlYWRlcjsKCiAgICBpZiAoKGhNb2R1bGUgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIG9mcyApKSA8IDMyKSByZXR1cm4gaE1vZHVsZTsKICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlICk7CiAgICBwTW9kdWxlLT5mbGFncyA9IE5FX0ZGTEFHU19XSU4zMjsKCiAgICBsc2VlayggZmQsIDAsIFNFRUtfU0VUICk7CiAgICByZWFkKCBmZCwgJm16X2hlYWRlciwgc2l6ZW9mKG16X2hlYWRlcikgKTsKCiAgICBwTW9kdWxlLT5wZV9tb2R1bGUgPSBQRV9Mb2FkSW1hZ2UoIGZkLCBoTW9kdWxlLCBtel9oZWFkZXIubmVfb2Zmc2V0ICk7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlLCBwYXJhbXMgKTsKCiAgICBpZiAoIShwTW9kdWxlLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgVEFTS19DcmVhdGVUYXNrKCBoTW9kdWxlLCBoSW5zdGFuY2UsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmhFbnZpcm9ubWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgIChMUFNUUilQVFJfU0VHX1RPX0xJTiggcGFyYW1zLT5jbWRMaW5lICksCiAgICAgICAgICAgICAgICAgICAgICAgICAqKChXT1JEKilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPnNob3dDbWQpICsgMSkgKTsKICAgIH0KICAgIHJldHVybiBoSW5zdGFuY2U7Cn0KCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRTE2IGhNb2R1bGUgKQp7CglwcmludGYoIlBFdW5sb2FkSW1hZ2UoKSBjYWxsZWQhXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgpzdGF0aWMgdm9pZCBQRV9Jbml0RExMKEhNT0RVTEUxNiBoTW9kdWxlKQp7CiAgICBORV9NT0RVTEUgKnBNb2R1bGU7CiAgICBQRV9NT0RVTEUgKnBlOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcjsKCiAgICBoTW9kdWxlID0gR2V0RXhlUHRyKGhNb2R1bGUpOwogICAgaWYgKCEocE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoaE1vZHVsZSkpKSByZXR1cm47CiAgICBpZiAoIShwTW9kdWxlLT5mbGFncyAmIE5FX0ZGTEFHU19XSU4zMikgfHwgIShwZSA9IHBNb2R1bGUtPnBlX21vZHVsZSkpCiAgICAgICAgcmV0dXJuOwoKICAgIC8qIEZJWE1FOiBXaGF0IGlzIHRoZSBjb3JyZWN0IHZhbHVlIGZvciBwYXJhbWV0ZXIgMz8gCiAgICAgKgkgICAgICAodGhlIE1TRE4gbGlicmFyeSBKQU45NiBzYXlzICdyZXNlcnZlZCBmb3IgZnV0dXJlIHVzZScpCiAgICAgKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKAkocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKCQkocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7CglwcmludGYoIkluaXRQRURMTCgpIGNhbGxlZCFcbiIpOwoJQ2FsbERMTEVudHJ5UHJvYzMyKCAKCSAgICAoRkFSUFJPQzMyKVJWQShwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSwKCSAgICBoTW9kdWxlLAoJICAgIERMTF9QUk9DRVNTX0FUVEFDSCwKCSAgICAtMQoJKTsKICAgIH0KfQoKdm9pZCBQRV9Jbml0aWFsaXplRExMcyhITU9EVUxFMTYgaE1vZHVsZSkKewoJTkVfTU9EVUxFICpwTW9kdWxlOwoJSE1PRFVMRTE2ICpwRExMOwoJcE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoIEdldEV4ZVB0cihoTW9kdWxlKSApOwoJaWYgKHBNb2R1bGUtPmRsbHNfdG9faW5pdCkKCXsKCQlIR0xPQkFMMTYgdG9faW5pdCA9IHBNb2R1bGUtPmRsbHNfdG9faW5pdDsKCQlwTW9kdWxlLT5kbGxzX3RvX2luaXQgPSAwOwoJCWZvciAocERMTCA9IChITU9EVUxFMTYgKilHbG9iYWxMb2NrMTYoIHRvX2luaXQgKTsgKnBETEw7IHBETEwrKykKCQl7CgkJCVBFX0luaXRpYWxpemVETExzKCAqcERMTCApOwoJCQlQRV9Jbml0RExMKCAqcERMTCApOwoJCX0KCQlHbG9iYWxGcmVlMTYoIHRvX2luaXQgKTsKCX0KCVBFX0luaXRETEwoIGhNb2R1bGUgKTsKfQojZW5kaWYgLyogV0lORUxJQiAqLwo=