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+dm1hX3NpemUpOwojZWxzZQoJbG9hZF9hZGRyID0gKGludCkgVmlydHVhbEFsbG9jKCBOVUxMLCBwZS0+dm1hX3NpemUsIE1FTV9DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwogICAgICAgIHBlLT5sb2FkX2FkZHIgPSBsb2FkX2FkZHI7CiNlbmRpZgoKCWRwcmludGZfd2luMzIoc3RkZGViLCAiTG9hZCBhZGRyIGlzIHJlYWxseSAleCwgcmFuZ2UgJXhcbiIsCgkJcGUtPmxvYWRfYWRkciwgcGUtPnZtYV9zaXplKTsKCQoKCWZvcihpPTA7IGkgPCBwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKCXsKCQkvKiBsb2FkIG9ubHkgbm9uLUJTUyBzZWdtZW50cyAqLwoJCWlmKHBlLT5wZV9zZWdbaV0uQ2hhcmFjdGVyaXN0aWNzICYgCgkJCX4gSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpCgkJaWYobHNlZWsoZmQscGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SYXdEYXRhLFNFRUtfU0VUKSA9PSAtMQoJCXx8IHJlYWQoZmQsKGNoYXIqKVJWQShwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzKSwKCQkJICAgcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhKSAhPSBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpCgkJewoJCQlmcHJpbnRmKHN0ZGVyciwiRmFpbGVkIHRvIGxvYWQgc2VjdGlvbiAleFxuIiwgaSk7CgkJCWV4aXQoMCk7CgkJfQoJCXJlc3VsdCA9IFJWQSAocGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyk7CiNpZiAxCgkJLyogbm90IG5lZWRlZCwgbWVtb3J5IGlzIHplcm8gKi8KCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmJzcyIpID09IDApCgkJICAgIG1lbXNldCgodm9pZCAqKXJlc3VsdCwgMCwgCgkJCSAgIHBlLT5wZV9zZWdbaV0uTWlzYy5WaXJ0dWFsU2l6ZSA/CgkJCSAgIHBlLT5wZV9zZWdbaV0uTWlzYy5WaXJ0dWFsU2l6ZSA6CgkJCSAgIHBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YSk7CiNlbmRpZgoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmlkYXRhIikgPT0gMCkKCQkJcGUtPnBlX2ltcG9ydCA9IChMUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIuZWRhdGEiKSA9PSAwKQoJCQlwZS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLnJzcmMiKSA9PSAwKQoJCQlwZS0+cGVfcmVzb3VyY2UgPSAoTFBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5yZWxvYyIpID09IDApCgkJCXBlLT5wZV9yZWxvYyA9IChMUElNQUdFX0JBU0VfUkVMT0NBVElPTikgcmVzdWx0OwoKCX0KCgkvKiBUaGVyZSBpcyB3b3JkIHRoYXQgdGhlIGFjdHVhbCBsb2FkZXIgZG9lcyBub3QgY2FyZSBhYm91dCB0aGUKCSAgIHNlY3Rpb24gbmFtZXMsIGFuZCBvbmx5IGdvZXMgZm9yIHRoZSBEYXRhRGlyZWN0b3J5ICovCglkaXI9cGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9leHBvcnQgJiYgKGludClwZS0+cGVfZXhwb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGV4cG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJLyogYWx3YXlzIHRydXN0IHRoZSBkaXJlY3RvcnkgKi8KCQlwZS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfaW1wb3J0ICYmIChpbnQpcGUtPnBlX2ltcG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBpbXBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1JFU09VUkNFXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9yZXNvdXJjZSAmJiAoaW50KXBlLT5wZV9yZXNvdXJjZSE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZXNvdXJjZSBkaXJlY3Rvcnk/P1xuIik7CgkJcGUtPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT05dLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCgoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQ107CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfcmVsb2MgJiYgKGludClwZS0+cGVfcmVsb2MhPSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIHJlbG9jYXRpb24gbGlzdD8/XG4iKTsKCQlwZS0+cGVfcmVsb2MgPSAodm9pZCAqKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVR10uU2l6ZSkKCSAgewoJICAgIERFQlVHX1JlZ2lzdGVyRGVidWdJbmZvKGZkLCBwZSwgbG9hZF9hZGRyLCAKCQkJcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlZpcnR1YWxBZGRyZXNzLAoJCQlwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVR10uU2l6ZSk7CgkgIH0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT1BZUklHSFRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUl0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iKTsKCiNpZmRlZiBOT1QJLyogd2UgaW5pdGlhbGl6ZSB0aGlzIGxhdGVyICovCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFNdLlNpemUpCgkJIGRwcmludGZfd2luMzIoc3RkbmltcCwiVGhyZWFkIGxvY2FsIHN0b3JhZ2UgaWdub3JlZFxuIik7CiNlbmRpZgoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0xPQURfQ09ORklHXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CT1VORF9JTVBPUlRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTNdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxMyBpZ25vcmVkXG4iKTsKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxNCBpZ25vcmVkXG4iKTsKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTVdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxNSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfcmVsb2MpIGRvX3JlbG9jYXRpb25zKHBlKTsKCWlmKHBlLT5wZV9pbXBvcnQpIGZpeHVwX2ltcG9ydHMocGUsIGhNb2R1bGUpOwoJaWYocGUtPnBlX2V4cG9ydCkgZHVtcF9leHBvcnRzKHBlLT5wZV9leHBvcnQsbG9hZF9hZGRyKTsKICAJCQoJaWYgKHBlLT5wZV9leHBvcnQpIHsKCQljaGFyCSpzOwoKCQkvKiBhZGQgc3RhcnQgb2Ygc2VjdGlvbnMgYXMgZGVidWdzeW1ib2xzICovCgkJZm9yKGk9MDtpPHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucztpKyspIHsKCQkJc3ByaW50ZihidWZmZXIsIiVzXyVzIiwKCQkJCShjaGFyKilSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSksCgkJCQlwZS0+cGVfc2VnW2ldLk5hbWUKCQkJKTsKCQkJZGFkZHIub2ZmPSBSVkEocGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgIAkJCXdoaWxlICgocz1zdHJjaHIoYnVmZmVyLCcuJykpKSAqcz0nXyc7CgkJCURFQlVHX0FkZFN5bWJvbChidWZmZXIsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7CgkJfQoJCS8qIGFkZCBlbnRyeSBwb2ludCAqLwoJCXNwcmludGYoYnVmZmVyLCIlc19FbnRyeVBvaW50IiwoY2hhciopUlZBKHBlLT5wZV9leHBvcnQtPk5hbWUpKTsKCQlkYWRkci5vZmY9UlZBKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpOwogICAgICAJCXdoaWxlICgocz1zdHJjaHIoYnVmZmVyLCcuJykpKSAqcz0nXyc7CgkJREVCVUdfQWRkU3ltYm9sKGJ1ZmZlciwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKCQkvKiBhZGQgc3RhcnQgb2YgRExMICovCgkJZGFkZHIub2ZmPWxvYWRfYWRkcjsKCQlERUJVR19BZGRTeW1ib2woKGNoYXIqKSBSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSksJmRhZGRyLAoJCQkJTlVMTCwgU1lNX1dJTjMyIHwgU1lNX0ZVTkMpOwoJfQogICAgICAgIHJldHVybiBwZTsKfQoKSElOU1RBTkNFMTYgTU9EVUxFX0NyZWF0ZUluc3RhbmNlKEhNT0RVTEUxNiBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CgpISU5TVEFOQ0UxNiBQRV9Mb2FkTW9kdWxlKCBpbnQgZmQsIE9GU1RSVUNUICpvZnMsIExPQURQQVJBTVMqIHBhcmFtcyApCnsKICAgIEhNT0RVTEUxNiBoTW9kdWxlOwogICAgSElOU1RBTkNFMTYgaEluc3RhbmNlOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgc3RydWN0IG16X2hlYWRlcl9zIG16X2hlYWRlcjsKCiAgICBpZiAoKGhNb2R1bGUgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIG9mcyApKSA8IDMyKSByZXR1cm4gaE1vZHVsZTsKICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlICk7CiAgICBwTW9kdWxlLT5mbGFncyA9IE5FX0ZGTEFHU19XSU4zMjsKCiAgICBsc2VlayggZmQsIDAsIFNFRUtfU0VUICk7CiAgICByZWFkKCBmZCwgJm16X2hlYWRlciwgc2l6ZW9mKG16X2hlYWRlcikgKTsKCiAgICBwTW9kdWxlLT5wZV9tb2R1bGUgPSBQRV9Mb2FkSW1hZ2UoIGZkLCBoTW9kdWxlLCBtel9oZWFkZXIubmVfb2Zmc2V0ICk7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlLCBwYXJhbXMgKTsKCiAgICBpZiAoIShwTW9kdWxlLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgVEFTS19DcmVhdGVUYXNrKCBoTW9kdWxlLCBoSW5zdGFuY2UsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmhFbnZpcm9ubWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgIChMUFNUUilQVFJfU0VHX1RPX0xJTiggcGFyYW1zLT5jbWRMaW5lICksCiAgICAgICAgICAgICAgICAgICAgICAgICAqKChXT1JEKilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPnNob3dDbWQpICsgMSkgKTsKICAgIH0KICAgIHJldHVybiBoSW5zdGFuY2U7Cn0KCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRTE2IGhNb2R1bGUgKQp7CglwcmludGYoIlBFdW5sb2FkSW1hZ2UoKSBjYWxsZWQhXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgpzdGF0aWMgdm9pZCBQRV9Jbml0RExMKEhNT0RVTEUxNiBoTW9kdWxlKQp7CiAgICBORV9NT0RVTEUgKnBNb2R1bGU7CiAgICBQRV9NT0RVTEUgKnBlOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcjsKCiAgICBoTW9kdWxlID0gR2V0RXhlUHRyKGhNb2R1bGUpOwogICAgaWYgKCEocE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoaE1vZHVsZSkpKSByZXR1cm47CiAgICBpZiAoIShwTW9kdWxlLT5mbGFncyAmIE5FX0ZGTEFHU19XSU4zMikgfHwgIShwZSA9IHBNb2R1bGUtPnBlX21vZHVsZSkpCiAgICAgICAgcmV0dXJuOwoKICAgIC8qIEZJWE1FOiBXaGF0IGlzIHRoZSBjb3JyZWN0IHZhbHVlIGZvciBwYXJhbWV0ZXIgMz8gCiAgICAgKgkgICAgICAodGhlIE1TRE4gbGlicmFyeSBKQU45NiBzYXlzICdyZXNlcnZlZCBmb3IgZnV0dXJlIHVzZScpCiAgICAgKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKAkocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKCQkocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7CglwcmludGYoIkluaXRQRURMTCgpIGNhbGxlZCFcbiIpOwoJQ2FsbERMTEVudHJ5UHJvYzMyKCAKCSAgICAoRkFSUFJPQzMyKVJWQShwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSwKCSAgICBoTW9kdWxlLAoJICAgIERMTF9QUk9DRVNTX0FUVEFDSCwKCSAgICAtMQoJKTsKICAgIH0KfQoKdm9pZCBQRV9Jbml0aWFsaXplRExMcyhITU9EVUxFMTYgaE1vZHVsZSkKewoJTkVfTU9EVUxFICpwTW9kdWxlOwoJSE1PRFVMRTE2ICpwRExMOwoJcE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoIEdldEV4ZVB0cihoTW9kdWxlKSApOwoJaWYgKHBNb2R1bGUtPmRsbHNfdG9faW5pdCkKCXsKCQlIR0xPQkFMMTYgdG9faW5pdCA9IHBNb2R1bGUtPmRsbHNfdG9faW5pdDsKCQlwTW9kdWxlLT5kbGxzX3RvX2luaXQgPSAwOwoJCWZvciAocERMTCA9IChITU9EVUxFMTYgKilHbG9iYWxMb2NrMTYoIHRvX2luaXQgKTsgKnBETEw7IHBETEwrKykKCQl7CgkJCVBFX0luaXRpYWxpemVETExzKCAqcERMTCApOwoJCQlQRV9Jbml0RExMKCAqcERMTCApOwoJCX0KCQlHbG9iYWxGcmVlMTYoIHRvX2luaXQgKTsKCX0KCVBFX0luaXRETEwoIGhNb2R1bGUgKTsKfQoKdm9pZCBQRV9Jbml0VGxzKCBQRV9NT0RVTEUgKm1vZHVsZSApCnsKICAgLyogRklYTUU6IHRscyBjYWxsYmFja3MgPz8/ICovCiAgIERXT1JEICBpbmRleDsKICAgRFdPUkQgIGRhdGFzaXplOwogICBEV09SRCAgc2l6ZTsKICAgTFBWT0lEIG1lbTsKICAgTFBJTUFHRV9UTFNfRElSRUNUT1JZIHBkaXI7CgogICAgaWYgKCFtb2R1bGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykKICAgICAgICByZXR1cm47CgogICAgcGRpciA9IChMUFZPSUQpKG1vZHVsZS0+bG9hZF9hZGRyICsgbW9kdWxlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLgogICAgICAgICAgICAgICBEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKICAgIGluZGV4ID0gVGxzQWxsb2MoKTsKICAgIGRhdGFzaXplID0gcGRpci0+RW5kQWRkcmVzc09mUmF3RGF0YS1wZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGE7CiAgICBzaXplICAgICA9IGRhdGFzaXplICsgcGRpci0+U2l6ZU9mWmVyb0ZpbGw7CiAgICAgICAgCiAgICBtZW0gPSBWaXJ0dWFsQWxsb2MoMCxzaXplLCBNRU1fUkVTRVJWRXxNRU1fQ09NTUlULCBQQUdFX1JFQURXUklURSApOwogICAgCiAgICBtZW1jcHkobWVtLChMUFZPSUQpIHBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSwgZGF0YXNpemUpOwogICAgVGxzU2V0VmFsdWUoaW5kZXgsbWVtKTsKICAgICoocGRpci0+QWRkcmVzc09mSW5kZXgpPWluZGV4OyAgIAp9CgojZW5kaWYgLyogV0lORUxJQiAqLwo=