I2lmbmRlZiBXSU5FTElCCi8qIAogKiAgQ29weXJpZ2h0CTE5OTQJRXJpYyBZb3VuZGFsZSAmIEVyaWsgQm9zCiAqICBDb3B5cmlnaHQJMTk5NQlNYXJ0aW4gdm9uIEz2d2lzCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAiZGxscy5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwZV9pbWFnZS5oIgojaW5jbHVkZSAicmVsYXkzMi5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJhbGlhcy5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJsZHQuaCIKI2luY2x1ZGUgInJlZ2lzdGVycy5oIgojaW5jbHVkZSAic3RkZGVidWcuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCgpzdGF0aWMgSEFORExFMzIgUHJvY2Vzc0hlYXA7ICAvKiBGSVhNRTogc2hvdWxkIGJlIGluIHByb2Nlc3MgZGF0YWJhc2UgKi8KCnZvaWQgbXlfd2NzdG9tYnMoY2hhciAqIHJlc3VsdCwgdV9zaG9ydCAqIHNvdXJjZSwgaW50IGxlbikKewogIHdoaWxlKGxlbi0tKSB7CiAgICAvKiB0aGlzIHVzZWQgdG8gYmUgaXNhc2NpaSwgYnV0IHNlZSBpc2FzY2lpIGltcGxlbWVudGF0aW9uIGluIExpbnV4JwoJICAgY3R5cGUuaCAqLwogICAgaWYoKnNvdXJjZTwyNTUpICpyZXN1bHQrKyA9ICpzb3VyY2UrKzsKICAgIGVsc2UgewogICAgICBwcmludGYoIlVuYWJsZSB0byBoYW5kbGUgdW5pY29kZSByaWdodCBub3dcbiIpOwogICAgICBleGl0KDApOwogICAgfQogIH07Cn0KCiNpZiAwCmNoYXIgKiB4bW1hcChjaGFyICogdmFkZHIsIHVuc2lnbmVkIGludCB2X3NpemUsIHVuc2lnbmVkIGludCByX3NpemUsCglpbnQgcHJvdCwgaW50IGZsYWdzLCBpbnQgZmQsIHVuc2lnbmVkIGludCBmaWxlX29mZnNldCkKewogIGNoYXIgKiByZXN1bHQ7CiAgLyogLmJzcyBoYXMgbm8gYXNzb2NpYXRlZCBzdG9yYWdlIGluIHRoZSBQRSBmaWxlICovCiAgaWYocl9zaXplKQogICAgdl9zaXplPXJfc2l6ZTsKICBlbHNlCiNpZiBkZWZpbmVkKF9fc3ZyNF9fKSB8fCBkZWZpbmVkKF9TQ09fRFMpCiAgICBmcHJpbnRmKHN0ZGVyciwieG1tYXA6ICVzIGxpbmUgJWQgZG9lc24ndCBzdXBwb3J0IE1BUF9BTk9OXG4iLF9fRklMRV9fLCBfX0xJTkVfXyk7CiNlbHNlCiAgICBmbGFncyB8PSBNQVBfQU5PTjsKI2VuZGlmCiAgcmVzdWx0ID0gbW1hcCh2YWRkciwgdl9zaXplLCBwcm90LCBmbGFncywgZmQsIGZpbGVfb2Zmc2V0KTsKICBpZigodW5zaWduZWQgaW50KSByZXN1bHQgIT0gMHhmZmZmZmZmZikgcmV0dXJuIHJlc3VsdDsKCiAgLyogU2lnaC4gIEFsaWdubWVudCBtdXN0IGJlIHdyb25nIGZvciBtbWFwLiAgRG8gdGhpcyB0aGUgaGFyZCB3YXkuICovCiAgaWYoIShmbGFncyAmIE1BUF9GSVhFRCkpIHsKICAgIHZhZGRyID0gKGNoYXIgKikweDQwMDAwMDAwOwogICAgZmxhZ3MgfD0gTUFQX0ZJWEVEOwogIH07CgogIG1tYXAodmFkZHIsIHZfc2l6ZSwgcHJvdCwgTUFQX0FOT05ZTU9VUyB8IGZsYWdzLCAwLCAwKTsKICBsc2VlayhmZCwgZmlsZV9vZmZzZXQsIFNFRUtfU0VUKTsKICByZWFkKGZkLCB2YWRkciwgdl9zaXplKTsKICByZXR1cm4gdmFkZHI7Cn07CiNlbmRpZgoKdm9pZCBkdW1wX2V4cG9ydHMoc3RydWN0IFBFX0V4cG9ydF9EaXJlY3RvcnkgKiBwZV9leHBvcnRzLCB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyKQp7IAogIGNoYXIgKiBNb2R1bGU7CiAgaW50IGk7CiAgdV9zaG9ydCAqIG9yZGluYWw7CiAgdV9sb25nICogZnVuY3Rpb247CiAgdV9jaGFyICoqIG5hbWUsICplbmFtZTsKCiAgTW9kdWxlID0gKChjaGFyICopIGxvYWRfYWRkcikgKyBwZV9leHBvcnRzLT5OYW1lOwogIGRwcmludGZfd2luMzIoc3RkZGViLCJcbioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJIE1vZHVsZSwKCSBwZV9leHBvcnRzLT5OdW1iZXJfT2ZfRnVuY3Rpb25zLAoJIHBlX2V4cG9ydHMtPk51bWJlcl9PZl9OYW1lcyk7CgogIG9yZGluYWwgPSAodV9zaG9ydCAqKSAoKChjaGFyICopIGxvYWRfYWRkcikgKyAoaW50KSBwZV9leHBvcnRzLT5BZGRyZXNzX09mX05hbWVfT3JkaW5hbHMpOwogIGZ1bmN0aW9uID0gKHVfbG9uZyAqKSAgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgcGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lID0gKHVfY2hhciAqKikgICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgZHByaW50Zl93aW4zMihzdGRkZWIsIiUtMzJzIE9yZGluYWwgVmlydCBBZGRyXG4iLCAiRnVuY3Rpb24gTmFtZSIpOwogIGZvcihpPTA7IGk8IHBlX2V4cG9ydHMtPk51bWJlcl9PZl9GdW5jdGlvbnM7IGkrKykKICAgIHsKICAgICAgZW5hbWUgPSAgKGNoYXIgKikgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgKm5hbWUrKyk7CiAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyAlNGQgICAgJTguOGx4XG4iLCBlbmFtZSwgKm9yZGluYWwrKywgKmZ1bmN0aW9uKyspOwogICAgfQp9CgpzdGF0aWMgRFdPUkQgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oc3RydWN0IHBlX2RhdGEgKnBlLCBjaGFyKiBmdW5jTmFtZSkKewoJc3RydWN0IFBFX0V4cG9ydF9EaXJlY3RvcnkgKiBleHBvcnRzID0gcGUtPnBlX2V4cG9ydDsKCXVuc2lnbmVkIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7Cgl1X3Nob3J0ICogb3JkaW5hbDsKCXVfbG9uZyAqIGZ1bmN0aW9uOwoJdV9jaGFyICoqIG5hbWUsICplbmFtZTsKCWludCBpOwoJaWYoIWV4cG9ydHMpcmV0dXJuIDA7CglvcmRpbmFsID0gKHVfc2hvcnQgKikgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgZXhwb3J0cy0+QWRkcmVzc19PZl9OYW1lX09yZGluYWxzKTsKCWZ1bmN0aW9uID0gKHVfbG9uZyAqKSAgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUgPSAodV9jaGFyICoqKSAgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yKGk9MDsgaTxleHBvcnRzLT5OdW1iZXJfT2ZfRnVuY3Rpb25zOyBpKyspCgl7CgkJaWYoSElXT1JEKGZ1bmNOYW1lKSkKCQl7CgkJCWVuYW1lID0gIChjaGFyICopICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpICpuYW1lKTsKCQkJaWYoc3RyY21wKGVuYW1lLGZ1bmNOYW1lKT09MCkKCQkJCXJldHVybiBsb2FkX2FkZHIrKmZ1bmN0aW9uOwoJCX1lbHNlewoJCQlpZihmdW5jTmFtZSA9PSAoaW50KSpvcmRpbmFsICsgZXhwb3J0cy0+QmFzZSkKCQkJCXJldHVybiBsb2FkX2FkZHIrKmZ1bmN0aW9uOwoJCX0KCQlmdW5jdGlvbisrOwoJCW9yZGluYWwrKzsKCQluYW1lKys7Cgl9CglyZXR1cm4gMDsKfQoKRFdPUkQgUEVfR2V0UHJvY0FkZHJlc3MoSE1PRFVMRSBoTW9kdWxlLCBjaGFyKiBmdW5jdGlvbikKewogICAgTkVfTU9EVUxFICpwTW9kdWxlOwoKICAgIGlmICghKHBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKCBoTW9kdWxlICkpKSByZXR1cm4gMDsKICAgIGlmICghKHBNb2R1bGUtPmZsYWdzICYgTkVfRkZMQUdTX1dJTjMyKSkgcmV0dXJuIDA7CiAgICBpZiAocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfQlVJTFRJTikKICAgIHsKICAgICAgICBCVUlMVElOX0RMTCAqZGxsID0gKEJVSUxUSU5fRExMICopcE1vZHVsZS0+cGVfbW9kdWxlOwogICAgICAgIGlmKEhJV09SRChmdW5jdGlvbikpCiAgICAgICAgICAgIHJldHVybiBSRUxBWTMyX0dldEVudHJ5UG9pbnQoZGxsLGZ1bmN0aW9uLDApOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIFJFTEFZMzJfR2V0RW50cnlQb2ludChkbGwsMCwoaW50KWZ1bmN0aW9uKTsKICAgIH0KICAgIGlmICghcE1vZHVsZS0+cGVfbW9kdWxlKSByZXR1cm4gMDsKICAgIHJldHVybiBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggcE1vZHVsZS0+cGVfbW9kdWxlLCBmdW5jdGlvbiApOwp9Cgp2b2lkIGZpeHVwX2ltcG9ydHMoc3RydWN0IHBlX2RhdGEgKnBlLCBITU9EVUxFIGhNb2R1bGUpCnsgCiAgc3RydWN0IFBFX0ltcG9ydF9EaXJlY3RvcnkgKiBwZV9pbXA7CiAgaW50IGZpeHVwX2ZhaWxlZD0wOwogIHVuc2lnbmVkIGludCBsb2FkX2FkZHIgPSBwZS0+bG9hZF9hZGRyOwogIGludCBpOwogIE5FX01PRFVMRSAqbmVfbW9kOwogIEhNT0RVTEUgKm1vZF9wdHI7CgogLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogIGRwcmludGZfd2luMzIoc3RkZGViLCAiXG5EdW1waW5nIGltcG9ydHMgbGlzdFxuIik7CgogIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgcGVfaW1wID0gcGUtPnBlX2ltcG9ydDsKICBmb3IoaT0wO3BlX2ltcC0+TW9kdWxlTmFtZTtwZV9pbXArKykKICAJaSsrOwoKICAvKiBOb3csIGFsbG9jYXRlIG1lbW9yeSBmb3IgZGxsc190b19pbml0ICovCiAgbmVfbW9kID0gR2xvYmFsTG9jayhoTW9kdWxlKTsKICBuZV9tb2QtPmRsbHNfdG9faW5pdCA9IEdMT0JBTF9BbGxvYyhHTUVNX1pFUk9JTklULChpKzEpICogc2l6ZW9mKEhNT0RVTEUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhNb2R1bGUsIEZBTFNFLCBGQUxTRSwgRkFMU0UgKTsKICBtb2RfcHRyID0gR2xvYmFsTG9jayhuZV9tb2QtPmRsbHNfdG9faW5pdCk7CiAgLyogbG9hZCB0aGUgbW9kdWxlcyBhbmQgcHV0IHRoZWlyIGhhbmRsZXMgaW50byB0aGUgbGlzdCAqLwogIGZvcihpPTAscGVfaW1wID0gcGUtPnBlX2ltcG9ydDtwZV9pbXAtPk1vZHVsZU5hbWU7cGVfaW1wKyspCiAgewogIAljaGFyICpuYW1lID0gKGNoYXIqKWxvYWRfYWRkcitwZV9pbXAtPk1vZHVsZU5hbWU7Cgltb2RfcHRyW2ldID0gTG9hZE1vZHVsZShuYW1lLChMUFZPSUQpLTEpOwoJaWYobW9kX3B0cltpXTw9KEhNT0RVTEUpMzIpCgl7CgkJZnByaW50ZihzdGRlcnIsIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsbmFtZSk7CgkJZXhpdCgwKTsKCX0KCWkrKzsKICB9CiAgcGVfaW1wID0gcGUtPnBlX2ltcG9ydDsKICB3aGlsZSAocGVfaW1wLT5Nb2R1bGVOYW1lKQogICAgewogICAgICBjaGFyICogTW9kdWxlOwogICAgICBzdHJ1Y3QgcGVfaW1wb3J0X25hbWUgKiBwZV9uYW1lOwogICAgICB1bnNpZ25lZCBpbnQgKiBpbXBvcnRfbGlzdCwgKnRodW5rX2xpc3Q7CgogICAgICBNb2R1bGUgPSAoKGNoYXIgKikgbG9hZF9hZGRyKSArIHBlX2ltcC0+TW9kdWxlTmFtZTsKICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICIlc1xuIiwgTW9kdWxlKTsKCiAgIGlmKHBlX2ltcC0+SW1wb3J0X0xpc3QgIT0gMCkgeyAvKiBvcmlnaW5hbCBtaWNyb3NvZnQgc3R5bGUgKi8KICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICJNaWNyb3NvZnQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKICAgICAgaW1wb3J0X2xpc3QgPSAodW5zaWduZWQgaW50ICopIAoJKCgodW5zaWduZWQgaW50KSBsb2FkX2FkZHIpICsgcGVfaW1wLT5JbXBvcnRfTGlzdCk7CgkgIHRodW5rX2xpc3QgPSAodW5zaWduZWQgaW50ICopCgkgICgoKHVuc2lnbmVkIGludCkgbG9hZF9hZGRyKSArIHBlX2ltcC0+VGh1bmtfTGlzdCk7CgoKICAgIHdoaWxlKCppbXBvcnRfbGlzdCkKCXsKCSAgcGVfbmFtZSA9IChzdHJ1Y3QgcGVfaW1wb3J0X25hbWUgKikgKChpbnQpIGxvYWRfYWRkciArICgodW5zaWduZWQpKmltcG9ydF9saXN0ICYgfjB4ODAwMDAwMDApKTsKCSAgaWYoKHVuc2lnbmVkKSppbXBvcnRfbGlzdCAmIDB4ODAwMDAwMDApCgkgIHsKCQlpbnQgb3JkaW5hbD0qaW1wb3J0X2xpc3QgJiAoMHg4MDAwMDAwMC0xKTsKCQlkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiLS0tIE9yZGluYWwgJXMsJWRcbiIsIE1vZHVsZSwgb3JkaW5hbCk7CgkJKnRodW5rX2xpc3QgPSBXSU4zMl9HZXRQcm9jQWRkcmVzcyhNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLAoJCQlvcmRpbmFsKTsKCSAgfWVsc2V7IC8qIGltcG9ydCBieSBuYW1lICovCgkgIGRwcmludGZfd2luMzIoc3RkZGViLCAiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwojaWZuZGVmIFdJTkVMSUIgLyogRklYTUU6IEpCUDogU2hvdWxkIHRoaXMgaGFwcGVuIGluIGxpYndpbmUuYT8gKi8KCSAgCSp0aHVua19saXN0ID0gV0lOMzJfR2V0UHJvY0FkZHJlc3MoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSwKCQkJCXBlX25hbWUtPk5hbWUpOwoKI2Vsc2UKCSAgZnByaW50ZihzdGRlcnIsIkpCUDogQ2FsbCB0byBSRUxBWTMyX0dldEVudHJ5UG9pbnQgYmVpbmcgaWdub3JlZC5cbiIpOwojZW5kaWYKCQl9CgkgIGlmKCEqdGh1bmtfbGlzdCkKCSAgewoJICAJZnByaW50ZihzdGRlcnIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcylcbiIsTW9kdWxlLCAKCQkJcGVfbmFtZS0+SGludCwgcGVfbmFtZS0+TmFtZSk7CgkJZml4dXBfZmFpbGVkPTE7CgkgIH0KCgkgIGltcG9ydF9saXN0Kys7CgkgIHRodW5rX2xpc3QrKzsKCX0KICAgIH0gZWxzZSB7IC8qIEJvcmxhbmQgc3R5bGUgKi8KICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CiAgICAgIHRodW5rX2xpc3QgPSAodW5zaWduZWQgaW50ICopCiAgICAgICAgKCgodW5zaWduZWQgaW50KSBsb2FkX2FkZHIpICsgcGVfaW1wLT5UaHVua19MaXN0KTsKICAgICAgd2hpbGUoKnRodW5rX2xpc3QpIHsKICAgICAgICBwZV9uYW1lID0gKHN0cnVjdCBwZV9pbXBvcnRfbmFtZSAqKSAoKGludCkgbG9hZF9hZGRyICsgKnRodW5rX2xpc3QpOwogICAgICAgIGlmKCh1bnNpZ25lZClwZV9uYW1lICYgMHg4MDAwMDAwMCkgewogICAgICAgICAgZnByaW50ZihzdGRlcnIsIkltcG9ydCBieSBvcmRpbmFsIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgICAgZXhpdCgwKTsKICAgICAgICB9CiAgICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICItLS0gJXMgJXMuJWRcbiIsIHBlX25hbWUtPk5hbWUsIE1vZHVsZSwgcGVfbmFtZS0+SGludCk7CiNpZm5kZWYgV0lORUxJQiAvKiBGSVhNRTogSkJQOiBTaG91bGQgdGhpcyBoYXBwZW4gaW4gbGlid2luZS5hPyAqLwoJLyogRklYTUU6IEJvdGggY2FsbHMgc2hvdWxkIGJlIHVuaWZpZWQgaW50byBHZXRQcm9jQWRkcmVzcyAqLwojaWYgMAogICAgICAgICp0aHVua19saXN0PSh1bnNpZ25lZCBpbnQpUkVMQVkzMl9HZXRFbnRyeVBvaW50KE1vZHVsZSxwZV9uYW1lLT5OYW1lLHBlX25hbWUtPkhpbnQpOwoJaWYoKnRodW5rX2xpc3QgPT0gMCkKI2VuZGlmCgkgIAkqdGh1bmtfbGlzdCA9IFdJTjMyX0dldFByb2NBZGRyZXNzKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSksCgkJCQlwZV9uYW1lLT5OYW1lKTsKI2Vsc2UKICAgICAgICBmcHJpbnRmKHN0ZGVyciwiSkJQOiBDYWxsIHRvIFJFTEFZMzJfR2V0RW50cnlQb2ludCBiZWluZyBpZ25vcmVkLlxuIik7CiNlbmRpZgogICAgICAgIGlmKCEqdGh1bmtfbGlzdCkgewogICAgICAgICAgZnByaW50ZihzdGRlcnIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZFxuIixNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwogICAgICAgICAgZml4dXBfZmFpbGVkPTE7CiAgICAgICAgfQogICAgICAgIHRodW5rX2xpc3QrKzsKICAgICAgfQogICAgfQogICAgcGVfaW1wKys7CiAgfQogIGlmKGZpeHVwX2ZhaWxlZClleGl0KDEpOwp9CgpzdGF0aWMgdm9pZCBjYWxjX3ZtYV9zaXplKHN0cnVjdCBwZV9kYXRhICpwZSkKewogIGludCBpOwoKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgZHByaW50Zl93aW4zMihzdGRkZWIsICIgICBOYW1lICAgIFZTeiAgVmFkZHIgICAgIFN6UmF3ICAgRmlsZWFkciAgKlJlbG9jICpMaW5ldW0gI1JlbG9jICNMaW51bSBDaGFyXG4iKTsKICBmb3IoaT0wOyBpPCBwZS0+cGVfaGVhZGVyLT5jb2ZmLk51bWJlck9mU2VjdGlvbnM7IGkrKykKICAgIHsKICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICIlOHM6ICU0LjRseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU0LjR4ICU0LjR4ICU4LjhseFxuIiwgCgkgICAgIHBlLT5wZV9zZWdbaV0uTmFtZSwgCgkgICAgIHBlLT5wZV9zZWdbaV0uVmlydHVhbF9TaXplLAoJICAgICBwZS0+cGVfc2VnW2ldLlZpcnR1YWxfQWRkcmVzcywKCSAgICAgcGUtPnBlX3NlZ1tpXS5TaXplX09mX1Jhd19EYXRhLAoJICAgICBwZS0+cGVfc2VnW2ldLlBvaW50ZXJUb1Jhd0RhdGEsCgkgICAgIHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmVsb2NhdGlvbnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvTGluZW51bWJlcnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uTnVtYmVyT2ZSZWxvY2F0aW9ucywKCSAgICAgcGUtPnBlX3NlZ1tpXS5OdW1iZXJPZkxpbmVudW1iZXJzLAoJICAgICBwZS0+cGVfc2VnW2ldLkNoYXJhY3RlcmlzdGljcyk7CgkgIHBlLT52bWFfc2l6ZSA9IE1BWChwZS0+dm1hX3NpemUsCgkgIAkJcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX0FkZHJlc3MgKyAKCQkJcGUtPnBlX3NlZ1tpXS5TaXplX09mX1Jhd19EYXRhKTsKICAgIH0KfQoKc3RhdGljIHZvaWQgZG9fcmVsb2NhdGlvbnMoc3RydWN0IHBlX2RhdGEgKnBlKQp7CglpbnQgZGVsdGEgPSBwZS0+bG9hZF9hZGRyIC0gcGUtPmJhc2VfYWRkcjsKCXN0cnVjdCBQRV9SZWxvY19CbG9jayAqciA9IHBlLT5wZV9yZWxvYzsKCWludCBoZGVsdGEgPSAoZGVsdGEgPj4gMTYpICYgMHhGRkZGOwoJaW50IGxkZWx0YSA9IGRlbHRhICYgMHhGRkZGOwoJLyogaW50IHJlbG9jX3NpemUgPSAqLwoJaWYoZGVsdGEgPT0gMCkKCQkvKiBOb3RoaW5nIHRvIGRvICovCgkJcmV0dXJuOwoJd2hpbGUoci0+UGFnZVJWQSkKCXsKCQljaGFyICpwYWdlID0gKGNoYXIqKXBlLT5sb2FkX2FkZHIgKyByLT5QYWdlUlZBOwoJCWludCBjb3VudCA9IChyLT5CbG9ja1NpemUgLSA4KS8yOwoJCWludCBpOwoJCWRwcmludGZfZml4dXAoc3RkZGViLCAiJXggcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLAoJCQljb3VudCwgci0+UGFnZVJWQSk7CgkJLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwoJCWZvcihpPTA7aTxjb3VudDtpKyspCgkJewoJCQlpbnQgb2Zmc2V0ID0gci0+UmVsb2NhdGlvbnNbaV0gJiAweEZGRjsKCQkJaW50IHR5cGUgPSByLT5SZWxvY2F0aW9uc1tpXSA+PiAxMjsKCQkJZHByaW50Zl9maXh1cChzdGRkZWIsInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CiNpZiAxCgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKI2Vsc2UKCQkJCXsgaW50IGg9Kih1bnNpZ25lZCBzaG9ydCopKHBhZ2Urb2Zmc2V0KTsKCQkJCSAgaW50IGw9ci0+UmVsb2NhdGlvbnNbKytpXTsKCQkJCSAgKih1bnNpZ25lZCBpbnQqKShwYWdlICsgb2Zmc2V0KSA9IChoPDwxNikgKyBsICsgZGVsdGE7CgkJCQl9CiNlbmRpZgoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hBREo6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIkRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9NSVBTX0pNUEFERFI6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIklzIHRoaXMgYSBNSVBTIG1hY2hpbmUgPz8/XG4iKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIGZpeHVwIHR5cGVcbiIpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJciA9IChzdHJ1Y3QgUEVfUmVsb2NfQmxvY2sqKSgoY2hhciopciArIHItPkJsb2NrU2l6ZSk7Cgl9Cn0KCQkKCgkKCQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IGV4ZWN1dGFibGUgaW50byBtZW1vcnkKICovCnN0YXRpYyBzdHJ1Y3QgcGVfZGF0YSAqUEVfTG9hZEltYWdlKCBpbnQgZmQsIEhNT0RVTEUgaE1vZHVsZSwgV09SRCBvZmZzZXQgKQp7CiAgICBzdHJ1Y3QgcGVfZGF0YSAqcGU7CiAgICBpbnQgaSwgcmVzdWx0OwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcjsKICAgIHN0cnVjdCBEaXJlY3RvcnkgZGlyOwoKCXBlID0geG1hbGxvYyhzaXplb2Yoc3RydWN0IHBlX2RhdGEpKTsKCW1lbXNldChwZSwwLHNpemVvZihzdHJ1Y3QgcGVfZGF0YSkpOwoJcGUtPnBlX2hlYWRlciA9IHhtYWxsb2Moc2l6ZW9mKHN0cnVjdCBwZV9oZWFkZXJfcykpOwoKCS8qIHJlYWQgUEUgaGVhZGVyICovCglsc2VlayggZmQsIG9mZnNldCwgU0VFS19TRVQpOwoJcmVhZCggZmQsIHBlLT5wZV9oZWFkZXIsIHNpemVvZihzdHJ1Y3QgcGVfaGVhZGVyX3MpKTsKCgkvKiByZWFkIHNlY3Rpb25zICovCglwZS0+cGVfc2VnID0geG1hbGxvYyhzaXplb2Yoc3RydWN0IHBlX3NlZ21lbnRfdGFibGUpICogCgkJCQkgICBwZS0+cGVfaGVhZGVyLT5jb2ZmLk51bWJlck9mU2VjdGlvbnMpOwoJcmVhZCggZmQsIHBlLT5wZV9zZWcsIHNpemVvZihzdHJ1Y3QgcGVfc2VnbWVudF90YWJsZSkgKiAKCQkJcGUtPnBlX2hlYWRlci0+Y29mZi5OdW1iZXJPZlNlY3Rpb25zKTsKCglsb2FkX2FkZHIgPSBwZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5CYXNlT2ZJbWFnZTsKCXBlLT5iYXNlX2FkZHI9bG9hZF9hZGRyOwoJcGUtPnZtYV9zaXplPTA7CglkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkxvYWQgYWRkciBpcyAleFxuIixsb2FkX2FkZHIpOwoJY2FsY192bWFfc2l6ZShwZSk7CgoJLyogV2UgdXNlIG1hbGxvYyBoZXJlLCB3aGlsZSBhIGh1Z2UgcGFydCBvZiB0aGF0IGFkZHJlc3Mgc3BhY2UgZG9lcwoJICAgbm90IGJlIHN1cHBvcnRlZCBieSBhY3R1YWwgbWVtb3J5LiBJdCBoYXMgdG8gYmUgY29udGlndW91cywgdGhvdWdoLgoJICAgSSBkb24ndCBrbm93IGlmIG1tYXAoIi9kZXYvbnVsbCIpOyB3b3VsZCBkbyBhbnkgYmV0dGVyLgoJICAgV2hhdCBJJ2QgcmVhbGx5IGxpa2UgdG8gZG8gaXMgYSBXaW4zMiBzdHlsZSBWaXJ0dWFsQWxsb2MvTWFwVmlld09mRmlsZQoJICAgc2VxdWVuY2UgKi8KCWxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHIgPSBtYWxsb2MocGUtPnZtYV9zaXplKTsKCWRwcmludGZfd2luMzIoc3RkZGViLCAiTG9hZCBhZGRyIGlzIHJlYWxseSAleCwgcmFuZ2UgJXhcbiIsCgkJcGUtPmxvYWRfYWRkciwgcGUtPnZtYV9zaXplKTsKCgoJZm9yKGk9MDsgaSA8IHBlLT5wZV9oZWFkZXItPmNvZmYuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQoJewoJCS8qIGxvYWQgb25seSBub24tQlNTIHNlZ21lbnRzICovCgkJaWYocGUtPnBlX3NlZ1tpXS5DaGFyYWN0ZXJpc3RpY3MgJiAKCQkJfiBJTUFHRV9TQ05fVFlQRV9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKQoJCWlmKGxzZWVrKGZkLHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmF3RGF0YSxTRUVLX1NFVCkgPT0gLTEKCQl8fCByZWFkKGZkLGxvYWRfYWRkciArIHBlLT5wZV9zZWdbaV0uVmlydHVhbF9BZGRyZXNzLAoJCQkJcGUtPnBlX3NlZ1tpXS5TaXplX09mX1Jhd19EYXRhKSAKCQkJCSE9IHBlLT5wZV9zZWdbaV0uU2l6ZV9PZl9SYXdfRGF0YSkKCQl7CgkJCWZwcmludGYoc3RkZXJyLCJGYWlsZWQgdG8gbG9hZCBzZWN0aW9uICV4XG4iLCBpKTsKCQkJZXhpdCgwKTsKCQl9CgkJcmVzdWx0ID0gbG9hZF9hZGRyICsgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX0FkZHJlc3M7CiNpZiAwCglpZighbG9hZF9hZGRyKSB7CgkJCgkJcmVzdWx0ID0gKGludCl4bW1hcCgoY2hhciAqKTAsIHBlLT5wZV9zZWdbaV0uVmlydHVhbF9TaXplLAoJCQlwZS0+cGVfc2VnW2ldLlNpemVfT2ZfUmF3X0RhdGEsIDcsCgkJCU1BUF9QUklWQVRFLCBmZCwgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SYXdEYXRhKTsKCQlsb2FkX2FkZHIgPSAodW5zaWduZWQgaW50KSByZXN1bHQgLSAgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX0FkZHJlc3M7Cgl9IGVsc2UgewoJCXJlc3VsdCA9IChpbnQpeG1tYXAoKGNoYXIgKikgbG9hZF9hZGRyICsgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX0FkZHJlc3MsIAoJCQkgIHBlLT5wZV9zZWdbaV0uVmlydHVhbF9TaXplLAoJCSAgICAgIHBlLT5wZV9zZWdbaV0uU2l6ZV9PZl9SYXdfRGF0YSwgNywgTUFQX1BSSVZBVEUgfCBNQVBfRklYRUQsIAoJCSAgICAgIGZkLCBwZS0+cGVfc2VnW2ldLlBvaW50ZXJUb1Jhd0RhdGEpOwoJfQoJaWYocmVzdWx0PT0tMSl7CgkJZnByaW50ZihzdGRlcnIsIkNvdWxkIG5vdCBsb2FkIHNlY3Rpb24gJXggdG8gZGVzaXJlZCBhZGRyZXNzICVseFxuIiwKCQkJaSwgbG9hZF9hZGRyK3BlLT5wZV9zZWdbaV0uVmlydHVhbF9BZGRyZXNzKTsKCQlmcHJpbnRmKHN0ZGVyciwiTmVlZCB0byBpbXBsZW1lbnQgcmVsb2NhdGlvbnMgbm93XG4iKTsKCQlleGl0KDApOwoJfQojZW5kaWYKCiAgICAgICAgaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5ic3MiKSA9PSAwKQogICAgICAgICAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAogICAgICAgICAgICAgICAgICAgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX1NpemUgPwogICAgICAgICAgICAgICAgICAgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX1NpemUgOgogICAgICAgICAgICAgICAgICAgcGUtPnBlX3NlZ1tpXS5TaXplX09mX1Jhd19EYXRhKTsKCglpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmlkYXRhIikgPT0gMCkKCQlwZS0+cGVfaW1wb3J0ID0gKHN0cnVjdCBQRV9JbXBvcnRfRGlyZWN0b3J5ICopIHJlc3VsdDsKCglpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmVkYXRhIikgPT0gMCkKCQlwZS0+cGVfZXhwb3J0ID0gKHN0cnVjdCBQRV9FeHBvcnRfRGlyZWN0b3J5ICopIHJlc3VsdDsKCglpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLnJzcmMiKSA9PSAwKSB7CgkgICAgcGUtPnBlX3Jlc291cmNlID0gKHN0cnVjdCBQRV9SZXNvdXJjZV9EaXJlY3RvcnkgKikgcmVzdWx0OwojaWYgMAovKiBGSVhNRSBwZS0+cmVzb3VyY2Vfb2Zmc2V0IHNob3VsZCBiZSBkZWxldGVkIGZyb20gc3RydWN0dXJlIGlmIHRoaXMKIGlmZGVmIGRvZXNuJ3QgYnJlYWsgYW55dGhpbmcgKi8KCSAgICAvKiBzYXZlIG9mZnNldCBmb3IgUEVfRmluZFJlc291cmNlICovCgkgICAgcGUtPnJlc291cmNlX29mZnNldCA9IHBlLT5wZV9zZWdbaV0uVmlydHVhbF9BZGRyZXNzIC0gCgkJCQkJcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SYXdEYXRhOwojZW5kaWYJCgkgICAgfQoJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5yZWxvYyIpID09IDApCgkJcGUtPnBlX3JlbG9jID0gKHN0cnVjdCBQRV9SZWxvY19CbG9jayAqKSByZXN1bHQ7CgoJfQoKCS8qIFRoZXJlIGlzIHdvcmQgdGhhdCB0aGUgYWN0dWFsIGxvYWRlciBkb2VzIG5vdCBjYXJlIGFib3V0IHRoZQoJICAgc2VjdGlvbiBuYW1lcywgYW5kIG9ubHkgZ29lcyBmb3IgdGhlIERhdGFEaXJlY3RvcnkgKi8KCWRpcj1wZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfRVhQT1JUX0RJUkVDVE9SWV07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfZXhwb3J0ICYmIAoJCQlwZS0+cGVfZXhwb3J0IT1sb2FkX2FkZHIrZGlyLlZpcnR1YWxfYWRkcmVzcykKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGV4cG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJLyogYWx3YXlzIHRydXN0IHRoZSBkaXJlY3RvcnkgKi8KCQlwZS0+cGVfZXhwb3J0ID0gbG9hZF9hZGRyK2Rpci5WaXJ0dWFsX2FkZHJlc3M7Cgl9CgoJZGlyPXBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9JTVBPUlRfRElSRUNUT1JZXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9pbXBvcnQgJiYgCgkJCXBlLT5wZV9pbXBvcnQhPWxvYWRfYWRkcitkaXIuVmlydHVhbF9hZGRyZXNzKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgaW1wb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQlwZS0+cGVfaW1wb3J0ID0gbG9hZF9hZGRyK2Rpci5WaXJ0dWFsX2FkZHJlc3M7Cgl9CgoJZGlyPXBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9SRVNPVVJDRV9ESVJFQ1RPUlldOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGUtPnBlX3Jlc291cmNlICYmIAoJCQlwZS0+cGVfcmVzb3VyY2UhPWxvYWRfYWRkcitkaXIuVmlydHVhbF9hZGRyZXNzKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgcmVzb3VyY2UgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlLT5wZV9yZXNvdXJjZSA9IGxvYWRfYWRkcitkaXIuVmlydHVhbF9hZGRyZXNzOwoJfQoKCWRpcj1wZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfQkFTRV9SRUxPQ0FUSU9OX1RBQkxFXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9yZWxvYyAmJiAKCQkJcGUtPnBlX3JlbG9jIT1sb2FkX2FkZHIrZGlyLlZpcnR1YWxfYWRkcmVzcykKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIHJlbG9jYXRpb24gbGlzdD8/XG4iKTsKCQlwZS0+cGVfcmVsb2MgPSBsb2FkX2FkZHIrZGlyLlZpcnR1YWxfYWRkcmVzczsKCX0KCglpZihwZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0ZJTEVfRVhDRVBUSU9OX0RJUkVDVE9SWV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+b3B0X2NvZmYuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9GSUxFX1NFQ1VSSVRZX0RJUkVDVE9SWV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0ZJTEVfREVCVUdfRElSRUNUT1JZXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiRGVidWcgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRklMRV9ERVNDUklQVElPTl9TVFJJTkddLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJEZXNjcmlwdGlvbiBzdHJpbmcgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+b3B0X2NvZmYuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9GSUxFX01BQ0hJTkVfVkFMVUVdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJNYWNoaW5lIFZhbHVlIGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uU2l6ZSkKCQkgZHByaW50Zl93aW4zMihzdGRuaW1wLCJUaHJlYWQgbG9jYWwgc3RvcmFnZSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0ZJTEVfQ0FMTEJBQ0tfRElSRUNUT1JZXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiQ2FsbGJhY2sgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCglpZihwZS0+cGVfaW1wb3J0KSBmaXh1cF9pbXBvcnRzKHBlLCBoTW9kdWxlKTsKCWlmKHBlLT5wZV9leHBvcnQpIGR1bXBfZXhwb3J0cyhwZS0+cGVfZXhwb3J0LGxvYWRfYWRkcik7CglpZihwZS0+cGVfcmVsb2MpIGRvX3JlbG9jYXRpb25zKHBlKTsKICAgICAgICByZXR1cm4gcGU7Cn0KCkhJTlNUQU5DRSBNT0RVTEVfQ3JlYXRlSW5zdGFuY2UoSE1PRFVMRSBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CnZvaWQgSW5pdFRhc2soc3RydWN0IHNpZ2NvbnRleHRfc3RydWN0IGNvbnRleHQpOwoKSElOU1RBTkNFIFBFX0xvYWRNb2R1bGUoIGludCBmZCwgT0ZTVFJVQ1QgKm9mcywgTE9BRFBBUkFNUyogcGFyYW1zICkKewogICAgICAgIFBFX01PRFVMRSAqcGU7CglpbnQgc2l6ZSwgb2Zfc2l6ZTsKCU5FX01PRFVMRSAqcE1vZHVsZTsKCVNFR1RBQkxFRU5UUlkgKnBTZWdtZW50OwoJY2hhciAqcFN0cjsKCURXT1JEIGN0czsKCUhNT0RVTEUgaE1vZHVsZTsKCUhJTlNUQU5DRSBoSW5zdGFuY2U7CiAgICAgICAgc3RydWN0IG16X2hlYWRlcl9zIG16X2hlYWRlcjsKCglBTElBU19Vc2VBbGlhc2VzPTE7CgoJbHNlZWsoZmQsMCxTRUVLX1NFVCk7CglyZWFkKCBmZCwgJm16X2hlYWRlciwgc2l6ZW9mKG16X2hlYWRlcikgKTsKCiAgICAgICAgb2Zfc2l6ZSA9IHNpemVvZihPRlNUUlVDVCkgLSBzaXplb2Yob2ZzLT5zelBhdGhOYW1lKQogICAgICAgICAgICAgICAgICArIHN0cmxlbihvZnMtPnN6UGF0aE5hbWUpICsgMTsKCXNpemUgPSBzaXplb2YoTkVfTU9EVUxFKSArCiAgICAgICAgICAgICAgIC8qIGxvYWRlZCBmaWxlIGluZm8gKi8KICAgICAgICAgICAgICAgb2Zfc2l6ZSArCiAgICAgICAgICAgICAgIC8qIHNlZ21lbnQgdGFibGU6IERTLENTICovCiAgICAgICAgICAgICAgIDIgKiBzaXplb2YoU0VHVEFCTEVFTlRSWSkgKwogICAgICAgICAgICAgICAvKiBuYW1lIHRhYmxlICovCiAgICAgICAgICAgICAgIDkgKwogICAgICAgICAgICAgICAvKiBzZXZlcmFsIGVtcHR5IHRhYmxlcyAqLwogICAgICAgICAgICAgICA4OwoKCWhNb2R1bGUgPSBHbG9iYWxBbGxvYyggR01FTV9NT1ZFQUJMRSB8IEdNRU1fWkVST0lOSVQsIHNpemUgKTsKCWlmICghaE1vZHVsZSkgcmV0dXJuIChISU5TVEFOQ0UpMTE7ICAvKiBpbnZhbGlkIGV4ZSAqLwoKCUZhclNldE93bmVyKCBoTW9kdWxlLCBoTW9kdWxlICk7CgkKCXBNb2R1bGUgPSAoTkVfTU9EVUxFKilHbG9iYWxMb2NrKGhNb2R1bGUpOwoKCS8qIFNldCBhbGwgdXNlZCBlbnRyaWVzICovCglwTW9kdWxlLT5tYWdpYz1ORV9TSUdOQVRVUkU7CglwTW9kdWxlLT5jb3VudD0xOwoJcE1vZHVsZS0+bmV4dD0wOwoJcE1vZHVsZS0+ZmxhZ3M9TkVfRkZMQUdTX1dJTjMyOwoJcE1vZHVsZS0+ZGdyb3VwPTE7CglwTW9kdWxlLT5zcz0xOwoJcE1vZHVsZS0+Y3M9MjsKCS8qIFdobyB3YW50cyB0byBMb2NhbEFsbG9jIGZvciBhIFBFIE1vZHVsZT8gKi8KCXBNb2R1bGUtPmhlYXBfc2l6ZT0weDEwMDA7CglwTW9kdWxlLT5zdGFja19zaXplPTB4RjAwMDsKCXBNb2R1bGUtPnNlZ19jb3VudD0xOwoJcE1vZHVsZS0+bW9kcmVmX2NvdW50PTA7CglwTW9kdWxlLT5ucm5hbWVfc2l6ZT0wOwoJcE1vZHVsZS0+ZmlsZWluZm89c2l6ZW9mKE5FX01PRFVMRSk7CglwTW9kdWxlLT5vc19mbGFncz1ORV9PU0ZMQUdTX1dJTkRPV1M7CglwTW9kdWxlLT5leHBlY3RlZF92ZXJzaW9uPTB4MzBBOwogICAgICAgIHBNb2R1bGUtPnNlbGYgPSBoTW9kdWxlOwoKICAgICAgICAvKiBTZXQgbG9hZGVkIGZpbGUgaW5mb3JtYXRpb24gKi8KICAgICAgICBtZW1jcHkoIHBNb2R1bGUgKyAxLCBvZnMsIG9mX3NpemUgKTsKICAgICAgICAoKE9GU1RSVUNUICopKHBNb2R1bGUrMSkpLT5jQnl0ZXMgPSBvZl9zaXplIC0gMTsKCglwU2VnbWVudD0oU0VHVEFCTEVFTlRSWSopKChjaGFyKikocE1vZHVsZSArIDEpICsgb2Zfc2l6ZSk7CglwTW9kdWxlLT5zZWdfdGFibGU9cE1vZHVsZS0+ZGdyb3VwX2VudHJ5PShpbnQpcFNlZ21lbnQtKGludClwTW9kdWxlOwoJcFNlZ21lbnQtPnNpemU9MDsKCXBTZWdtZW50LT5mbGFncz1ORV9TRUdGTEFHU19EQVRBOwoJcFNlZ21lbnQtPm1pbnNpemU9MHgxMDAwOwoJcFNlZ21lbnQrKzsKCgljdHM9KERXT1JEKU1PRFVMRV9HZXRXbmRQcm9jRW50cnkxNigiV2luMzJDYWxsVG9TdGFydCIpOwojaWZkZWYgV0lORUxJQjMyCglwU2VnbWVudC0+c2VsZWN0b3I9KHZvaWQqKWN0czsKCXBNb2R1bGUtPmlwPTA7CiNlbHNlCglwU2VnbWVudC0+c2VsZWN0b3I9Y3RzPj4xNjsKCXBNb2R1bGUtPmlwPWN0cyAmIDB4RkZGRjsKI2VuZGlmCglwU2VnbWVudCsrOwoKCXBTdHI9KGNoYXIqKXBTZWdtZW50OwoJcE1vZHVsZS0+bmFtZV90YWJsZT0oaW50KXBTdHItKGludClwTW9kdWxlOwoJc3RyY3B5KHBTdHIsIlx4MDhXMzJTWFhYWCIpOwoJcFN0cis9OTsKCgkvKiBBbGwgdGFibGVzIHplcm8gdGVybWluYXRlZCAqLwoJcE1vZHVsZS0+cmVzX3RhYmxlPXBNb2R1bGUtPmltcG9ydF90YWJsZT1wTW9kdWxlLT5lbnRyeV90YWJsZT0KCQkoaW50KXBTdHItKGludClwTW9kdWxlOwoKICAgICAgICBNT0RVTEVfUmVnaXN0ZXJNb2R1bGUoaE1vZHVsZSk7CgoJcGUgPSBQRV9Mb2FkSW1hZ2UoIGZkLCBoTW9kdWxlLCBtel9oZWFkZXIubmVfb2Zmc2V0ICk7CgogICAgICAgIHBNb2R1bGUtPnBlX21vZHVsZSA9IHBlOwoJcE1vZHVsZS0+aGVhcF9zaXplPTB4MTAwMDsKCXBNb2R1bGUtPnN0YWNrX3NpemU9MHhFMDAwOwoKCS8qIENyZWF0ZUluc3RhbmNlIGFsbG9jYXRlcyBub3cgNjRLQiAqLwoJaEluc3RhbmNlPU1PRFVMRV9DcmVhdGVJbnN0YW5jZShoTW9kdWxlLE5VTEwgLyogRklYOiBOVUxMPyByZWFsbHk/ICovKTsKCiAgICAgICAgLyogRklYTUU6IElzIHRoaXMgcmVhbGx5IHRoZSBjb3JyZWN0IHBsYWNlIHRvIGluaXRpYWxpc2UgdGhlIERMTD8gKi8KCWlmICgocGUtPnBlX2hlYWRlci0+Y29mZi5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpIHsKLyogICAgICAgICAgICBQRV9Jbml0RExMKGhNb2R1bGUpOyAqLwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFByb2Nlc3NIZWFwID0gSGVhcENyZWF0ZSggMCwgMHgxMDAwMCwgMCApOwogICAgICAgICAgICBUQVNLX0NyZWF0ZVRhc2soaE1vZHVsZSxoSW5zdGFuY2UsMCwKCQlwYXJhbXMtPmhFbnZpcm9ubWVudCwoTFBTVFIpUFRSX1NFR19UT19MSU4ocGFyYW1zLT5jbWRMaW5lKSwKCQkqKChXT1JEKilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPnNob3dDbWQpKzEpKTsKICAgICAgICAgICAgUEVfSW5pdGlhbGl6ZURMTHMoaE1vZHVsZSk7Cgl9CglyZXR1cm4gaEluc3RhbmNlOwp9CgpIQU5ETEUzMiBHZXRQcm9jZXNzSGVhcCh2b2lkKQp7CiAgICByZXR1cm4gUHJvY2Vzc0hlYXA7Cn0KCmludCBVU0VSX0luaXRBcHAoSElOU1RBTkNFIGhJbnN0YW5jZSk7CnZvaWQgUEVfSW5pdFRFQihpbnQgaFRFQik7Cgp2b2lkIFBFX1dpbjMyQ2FsbFRvU3RhcnQoc3RydWN0IHNpZ2NvbnRleHRfc3RydWN0IGNvbnRleHQpCnsKICAgIGludCBmczsKICAgIEhNT0RVTEUgaE1vZHVsZTsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKICAgIHN0cnVjdCBwZV9kYXRhICpwZTsKCiAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiR29pbmcgdG8gc3RhcnQgV2luMzIgcHJvZ3JhbVxuIik7CQogICAgSW5pdFRhc2soY29udGV4dCk7CiAgICBoTW9kdWxlID0gR2V0RXhlUHRyKCBHZXRDdXJyZW50VGFzaygpICk7CiAgICBwTW9kdWxlID0gTU9EVUxFX0dldFB0ciggaE1vZHVsZSApOwogICAgVVNFUl9Jbml0QXBwKCBoTW9kdWxlICk7CiAgICBmcz0oaW50KUdsb2JhbEFsbG9jKEdITkQsMHgxMDAwMCk7CiAgICBQRV9Jbml0VEVCKGZzKTsKICAgIF9fYXNtX18gX192b2xhdGlsZV9fKCJtb3Z3ICV3MCwlJWZzIjo6InIiIChmcykpOwogICAgQ2FsbFRhc2tTdGFydDMyKCAoRkFSUFJPQykocE1vZHVsZS0+cGVfbW9kdWxlLT5sb2FkX2FkZHIgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNb2R1bGUtPnBlX21vZHVsZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5BZGRyZXNzT2ZFbnRyeVBvaW50KSApOwp9CgppbnQgUEVfVW5sb2FkSW1hZ2UoIEhNT0RVTEUgaE1vZHVsZSApCnsKCXByaW50ZigiUEV1bmxvYWRJbWFnZSgpIGNhbGxlZCFcbiIpOwoJLyogZnJlZSByZXNvdXJjZXMsIGltYWdlLCB1bm1hcCAqLwoJcmV0dXJuIDE7Cn0KCnN0YXRpYyB2b2lkIFBFX0luaXRETEwoSE1PRFVMRSBoTW9kdWxlKQp7CiAgICBORV9NT0RVTEUgKnBNb2R1bGU7CiAgICBQRV9NT0RVTEUgKnBlOwoKICAgIGhNb2R1bGUgPSBHZXRFeGVQdHIoaE1vZHVsZSk7CiAgICBpZiAoIShwTW9kdWxlID0gTU9EVUxFX0dldFB0cihoTW9kdWxlKSkpIHJldHVybjsKICAgIGlmICghKHBNb2R1bGUtPmZsYWdzICYgTkVfRkZMQUdTX1dJTjMyKSB8fCAhKHBlID0gcE1vZHVsZS0+cGVfbW9kdWxlKSkKICAgICAgICByZXR1cm47CgogICAgLyogRklYTUU6IFdoYXQgYXJlIHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgcGFyYW1ldGVycyAyIGFuZCAzPyAqLwogICAgICAgIAogICAgLyogSXMgdGhpcyBhIGxpYnJhcnk/ICovCiAgICBpZiAocGUtPnBlX2hlYWRlci0+Y29mZi5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkKICAgIHsKICAgICAgICBwcmludGYoIkluaXRQRURMTCgpIGNhbGxlZCFcbiIpOwogICAgICAgIENhbGxETExFbnRyeVByb2MzMiggKEZBUlBST0MpKHBlLT5sb2FkX2FkZHIgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkFkZHJlc3NPZkVudHJ5UG9pbnQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaE1vZHVsZSwgMCwgMCApOwogICAgfQp9CgoKLyogRklYTUU6IFRoaXMgc3R1ZmYgaXMgYWxsIG9uIGEgIndlbGwgaXQgd29ya3MiIGJhc2lzLiBBbiBpbXBsZW1lbnRhdGlvbgpiYXNlZCBvbiBzb21lIGtpbmQgb2YgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZSBncmVhdGx5IGFwcHJlY2lhdGVkIDotKSAqLwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgdm9pZCAgICAgICAgKkV4Y2VwdDsKICAgIHZvaWQgICAgICAgICpzdGFjazsKICAgIGludAkgICAgICAgIGR1bW15MVs0XTsKICAgIHN0cnVjdCBURUIgICpURUJEU0FsaWFzOwogICAgaW50CSAgICAgICAgZHVtbXkyWzJdOwogICAgaW50CSAgICAgICAgdGFza2lkOwp9IFRFQjsKCnZvaWQgUEVfSW5pdFRFQihpbnQgaFRFQikKewogICAgVERCICpwVGFzazsKICAgIFRFQiAqcFRFQjsKCiAgICBwVGFzayA9IChUREIgKikoR2xvYmFsTG9jayhHZXRDdXJyZW50VGFzaygpICYgMHhmZmZmKSk7CiAgICBwVEVCID0gKFRFQiAqKShQVFJfU0VHX09GRl9UT19MSU4oaFRFQiwgMCkpOwogICAgcFRFQi0+c3RhY2sgPSAodm9pZCAqKShHbG9iYWxMb2NrKHBUYXNrLT5oU3RhY2szMikpOwogICAgcFRFQi0+RXhjZXB0ID0gKHZvaWQgKikoLTEpOyAKICAgIHBURUItPlRFQkRTQWxpYXMgPSBwVEVCOwogICAgcFRFQi0+dGFza2lkID0gZ2V0cGlkKCk7Cn0KCnZvaWQgUEVfSW5pdGlhbGl6ZURMTHMoSE1PRFVMRSBoTW9kdWxlKQp7CglORV9NT0RVTEUgKnBNb2R1bGU7CglITU9EVUxFICpwRExMOwoJcE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoIEdldEV4ZVB0cihoTW9kdWxlKSApOwoJaWYgKHBNb2R1bGUtPmRsbHNfdG9faW5pdCkKCXsKCQlIQU5ETEUgdG9faW5pdCA9IHBNb2R1bGUtPmRsbHNfdG9faW5pdDsKCQlwTW9kdWxlLT5kbGxzX3RvX2luaXQgPSAwOwoJCWZvciAocERMTCA9IChITU9EVUxFICopR2xvYmFsTG9jayggdG9faW5pdCApOyAqcERMTDsgcERMTCsrKQoJCXsKCQkJUEVfSW5pdGlhbGl6ZURMTHMoICpwRExMICk7CgkJCVBFX0luaXRETEwoICpwRExMICk7CgkJfQoJCUdsb2JhbEZyZWUoIHRvX2luaXQgKTsKCX0KCVBFX0luaXRETEwoIGhNb2R1bGUgKTsKfQojZW5kaWYgLyogV0lORUxJQiAqLwo=