I2lmbmRlZiBXSU5FTElCCi8qIAogKiAgQ29weXJpZ2h0CTE5OTQJRXJpYyBZb3VuZGFsZSAmIEVyaWsgQm9zCiAqICBDb3B5cmlnaHQJMTk5NQlNYXJ0aW4gdm9uIEz2d2lzCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwZV9pbWFnZS5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJnbG9iYWwuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAicmVnaXN0ZXJzLmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKCnZvaWQgbXlfd2NzdG9tYnMoY2hhciAqIHJlc3VsdCwgdV9zaG9ydCAqIHNvdXJjZSwgaW50IGxlbikKewogIHdoaWxlKGxlbi0tKSB7CiAgICAvKiB0aGlzIHVzZWQgdG8gYmUgaXNhc2NpaSwgYnV0IHNlZSBpc2FzY2lpIGltcGxlbWVudGF0aW9uIGluIExpbnV4JwoJICAgY3R5cGUuaCAqLwogICAgaWYoKnNvdXJjZTwyNTUpICpyZXN1bHQrKyA9ICpzb3VyY2UrKzsKICAgIGVsc2UgewogICAgICBwcmludGYoIlVuYWJsZSB0byBoYW5kbGUgdW5pY29kZSByaWdodCBub3dcbiIpOwogICAgICBleGl0KDApOwogICAgfQogIH07Cn0KCiNpZiAwCmNoYXIgKiB4bW1hcChjaGFyICogdmFkZHIsIHVuc2lnbmVkIGludCB2X3NpemUsIHVuc2lnbmVkIGludCByX3NpemUsCglpbnQgcHJvdCwgaW50IGZsYWdzLCBpbnQgZmQsIHVuc2lnbmVkIGludCBmaWxlX29mZnNldCkKewogIGNoYXIgKiByZXN1bHQ7CiAgLyogLmJzcyBoYXMgbm8gYXNzb2NpYXRlZCBzdG9yYWdlIGluIHRoZSBQRSBmaWxlICovCiAgaWYocl9zaXplKQogICAgdl9zaXplPXJfc2l6ZTsKICBlbHNlCiNpZiBkZWZpbmVkKF9fc3ZyNF9fKSB8fCBkZWZpbmVkKF9TQ09fRFMpCiAgICBmcHJpbnRmKHN0ZGVyciwieG1tYXA6ICVzIGxpbmUgJWQgZG9lc24ndCBzdXBwb3J0IE1BUF9BTk9OXG4iLF9fRklMRV9fLCBfX0xJTkVfXyk7CiNlbHNlCiAgICBmbGFncyB8PSBNQVBfQU5PTjsKI2VuZGlmCiAgcmVzdWx0ID0gbW1hcCh2YWRkciwgdl9zaXplLCBwcm90LCBmbGFncywgZmQsIGZpbGVfb2Zmc2V0KTsKICBpZigodW5zaWduZWQgaW50KSByZXN1bHQgIT0gMHhmZmZmZmZmZikgcmV0dXJuIHJlc3VsdDsKCiAgLyogU2lnaC4gIEFsaWdubWVudCBtdXN0IGJlIHdyb25nIGZvciBtbWFwLiAgRG8gdGhpcyB0aGUgaGFyZCB3YXkuICovCiAgaWYoIShmbGFncyAmIE1BUF9GSVhFRCkpIHsKICAgIHZhZGRyID0gKGNoYXIgKikweDQwMDAwMDAwOwogICAgZmxhZ3MgfD0gTUFQX0ZJWEVEOwogIH07CgogIG1tYXAodmFkZHIsIHZfc2l6ZSwgcHJvdCwgTUFQX0FOT05ZTU9VUyB8IGZsYWdzLCAwLCAwKTsKICBsc2VlayhmZCwgZmlsZV9vZmZzZXQsIFNFRUtfU0VUKTsKICByZWFkKGZkLCB2YWRkciwgdl9zaXplKTsKICByZXR1cm4gdmFkZHI7Cn07CiNlbmRpZgoKdm9pZCBkdW1wX2V4cG9ydHMoc3RydWN0IFBFX0V4cG9ydF9EaXJlY3RvcnkgKiBwZV9leHBvcnRzLCB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyKQp7IAogIGNoYXIgKiBNb2R1bGU7CiAgaW50IGk7CiAgdV9zaG9ydCAqIG9yZGluYWw7CiAgdV9sb25nICogZnVuY3Rpb247CiAgdV9jaGFyICoqIG5hbWUsICplbmFtZTsKCiAgTW9kdWxlID0gKChjaGFyICopIGxvYWRfYWRkcikgKyBwZV9leHBvcnRzLT5OYW1lOwogIGRwcmludGZfd2luMzIoc3RkZGViLCJcbioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJIE1vZHVsZSwKCSBwZV9leHBvcnRzLT5OdW1iZXJfT2ZfRnVuY3Rpb25zLAoJIHBlX2V4cG9ydHMtPk51bWJlcl9PZl9OYW1lcyk7CgogIG9yZGluYWwgPSAodV9zaG9ydCAqKSAoKChjaGFyICopIGxvYWRfYWRkcikgKyAoaW50KSBwZV9leHBvcnRzLT5BZGRyZXNzX09mX05hbWVfT3JkaW5hbHMpOwogIGZ1bmN0aW9uID0gKHVfbG9uZyAqKSAgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgcGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lID0gKHVfY2hhciAqKikgICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgZHByaW50Zl93aW4zMihzdGRkZWIsIiUtMzJzIE9yZGluYWwgVmlydCBBZGRyXG4iLCAiRnVuY3Rpb24gTmFtZSIpOwogIGZvcihpPTA7IGk8IHBlX2V4cG9ydHMtPk51bWJlcl9PZl9GdW5jdGlvbnM7IGkrKykKICAgIHsKICAgICAgZW5hbWUgPSAgKGNoYXIgKikgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgKm5hbWUrKyk7CiAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyAlNGQgICAgJTguOGx4XG4iLCBlbmFtZSwgKm9yZGluYWwrKywgKmZ1bmN0aW9uKyspOwogICAgfQp9CgpzdGF0aWMgRFdPUkQgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oc3RydWN0IHBlX2RhdGEgKnBlLCBjaGFyKiBmdW5jTmFtZSkKewoJc3RydWN0IFBFX0V4cG9ydF9EaXJlY3RvcnkgKiBleHBvcnRzID0gcGUtPnBlX2V4cG9ydDsKCXVuc2lnbmVkIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7Cgl1X3Nob3J0ICogb3JkaW5hbDsKCXVfbG9uZyAqIGZ1bmN0aW9uOwoJdV9jaGFyICoqIG5hbWUsICplbmFtZTsKCWludCBpOwoJaWYoIWV4cG9ydHMpcmV0dXJuIDA7CglvcmRpbmFsID0gKHVfc2hvcnQgKikgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgZXhwb3J0cy0+QWRkcmVzc19PZl9OYW1lX09yZGluYWxzKTsKCWZ1bmN0aW9uID0gKHVfbG9uZyAqKSAgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUgPSAodV9jaGFyICoqKSAgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yKGk9MDsgaTxleHBvcnRzLT5OdW1iZXJfT2ZfRnVuY3Rpb25zOyBpKyspCgl7CgkJaWYoSElXT1JEKGZ1bmNOYW1lKSkKCQl7CgkJCWVuYW1lID0gIChjaGFyICopICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpICpuYW1lKTsKCQkJaWYoc3RyY21wKGVuYW1lLGZ1bmNOYW1lKT09MCkKCQkJCXJldHVybiBsb2FkX2FkZHIrKmZ1bmN0aW9uOwoJCX1lbHNlewoJCQlpZihmdW5jTmFtZSA9PSAoaW50KSpvcmRpbmFsICsgZXhwb3J0cy0+QmFzZSkKCQkJCXJldHVybiBsb2FkX2FkZHIrKmZ1bmN0aW9uOwoJCX0KCQlmdW5jdGlvbisrOwoJCW9yZGluYWwrKzsKCQluYW1lKys7Cgl9CglyZXR1cm4gMDsKfQoKRFdPUkQgUEVfR2V0UHJvY0FkZHJlc3MoSE1PRFVMRSBoTW9kdWxlLCBjaGFyKiBmdW5jdGlvbikKewogICAgTkVfTU9EVUxFICpwTW9kdWxlOwoKICAgIGlmICghKHBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKCBoTW9kdWxlICkpKSByZXR1cm4gMDsKICAgIGlmICghKHBNb2R1bGUtPmZsYWdzICYgTkVfRkZMQUdTX1dJTjMyKSB8fCAhcE1vZHVsZS0+cGVfbW9kdWxlKSByZXR1cm4gMDsKICAgIGlmIChwTW9kdWxlLT5mbGFncyAmIE5FX0ZGTEFHU19CVUlMVElOKQogICAgICAgIHJldHVybiBCVUlMVElOX0dldFByb2NBZGRyZXNzMzIoIHBNb2R1bGUsIGZ1bmN0aW9uICk7CiAgICByZXR1cm4gUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oIHBNb2R1bGUtPnBlX21vZHVsZSwgZnVuY3Rpb24gKTsKfQoKdm9pZCBmaXh1cF9pbXBvcnRzKHN0cnVjdCBwZV9kYXRhICpwZSwgSE1PRFVMRSBoTW9kdWxlKQp7IAogIHN0cnVjdCBQRV9JbXBvcnRfRGlyZWN0b3J5ICogcGVfaW1wOwogIGludCBmaXh1cF9mYWlsZWQ9MDsKICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gcGUtPmxvYWRfYWRkcjsKICBpbnQgaTsKICBORV9NT0RVTEUgKm5lX21vZDsKICBITU9EVUxFICptb2RfcHRyOwoKIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIlxuRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogIHBlX2ltcCA9IHBlLT5wZV9pbXBvcnQ7CiAgZm9yKGk9MDtwZV9pbXAtPk1vZHVsZU5hbWU7cGVfaW1wKyspCiAgCWkrKzsKCiAgLyogTm93LCBhbGxvY2F0ZSBtZW1vcnkgZm9yIGRsbHNfdG9faW5pdCAqLwogIG5lX21vZCA9IEdsb2JhbExvY2sxNihoTW9kdWxlKTsKICBuZV9tb2QtPmRsbHNfdG9faW5pdCA9IEdMT0JBTF9BbGxvYyhHTUVNX1pFUk9JTklULChpKzEpICogc2l6ZW9mKEhNT0RVTEUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhNb2R1bGUsIEZBTFNFLCBGQUxTRSwgRkFMU0UgKTsKICBtb2RfcHRyID0gR2xvYmFsTG9jazE2KG5lX21vZC0+ZGxsc190b19pbml0KTsKICAvKiBsb2FkIHRoZSBtb2R1bGVzIGFuZCBwdXQgdGhlaXIgaGFuZGxlcyBpbnRvIHRoZSBsaXN0ICovCiAgZm9yKGk9MCxwZV9pbXAgPSBwZS0+cGVfaW1wb3J0O3BlX2ltcC0+TW9kdWxlTmFtZTtwZV9pbXArKykKICB7CiAgCWNoYXIgKm5hbWUgPSAoY2hhciopbG9hZF9hZGRyK3BlX2ltcC0+TW9kdWxlTmFtZTsKCW1vZF9wdHJbaV0gPSBMb2FkTW9kdWxlKG5hbWUsKExQVk9JRCktMSk7CglpZihtb2RfcHRyW2ldPD0oSE1PRFVMRSkzMikKICAgICAgICB7CiAgICAgICAgICAgIGNoYXIgKnAsIGJ1ZmZlclsyNTZdOwoKICAgICAgICAgICAgLyogVHJ5IHdpdGggcHJlcGVuZGluZyB0aGUgcGF0aCBvZiB0aGUgY3VycmVudCBtb2R1bGUgKi8KICAgICAgICAgICAgR2V0TW9kdWxlRmlsZU5hbWUoIGhNb2R1bGUsIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlcikgKTsKICAgICAgICAgICAgaWYgKCEocCA9IHN0cnJjaHIoIGJ1ZmZlciwgJ1xcJyApKSkgcCA9IGJ1ZmZlcjsKICAgICAgICAgICAgc3RyY3B5KCBwICsgMSwgbmFtZSApOwogICAgICAgICAgICBtb2RfcHRyW2ldID0gTG9hZE1vZHVsZSggYnVmZmVyLCAoTFBWT0lEKS0xICk7CiAgICAgICAgfQoJaWYobW9kX3B0cltpXTw9KEhNT0RVTEUpMzIpCgl7CgkJZnByaW50ZihzdGRlcnIsIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsbmFtZSk7CgkJZXhpdCgwKTsKCX0KCWkrKzsKICB9CiAgcGVfaW1wID0gcGUtPnBlX2ltcG9ydDsKICB3aGlsZSAocGVfaW1wLT5Nb2R1bGVOYW1lKQogICAgewogICAgICBjaGFyICogTW9kdWxlOwogICAgICBzdHJ1Y3QgcGVfaW1wb3J0X25hbWUgKiBwZV9uYW1lOwogICAgICB1bnNpZ25lZCBpbnQgKiBpbXBvcnRfbGlzdCwgKnRodW5rX2xpc3Q7CgogICAgICBNb2R1bGUgPSAoKGNoYXIgKikgbG9hZF9hZGRyKSArIHBlX2ltcC0+TW9kdWxlTmFtZTsKICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICIlc1xuIiwgTW9kdWxlKTsKCiAgIGlmKHBlX2ltcC0+SW1wb3J0X0xpc3QgIT0gMCkgeyAvKiBvcmlnaW5hbCBtaWNyb3NvZnQgc3R5bGUgKi8KICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICJNaWNyb3NvZnQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKICAgICAgaW1wb3J0X2xpc3QgPSAodW5zaWduZWQgaW50ICopIAoJKCgodW5zaWduZWQgaW50KSBsb2FkX2FkZHIpICsgcGVfaW1wLT5JbXBvcnRfTGlzdCk7CgkgIHRodW5rX2xpc3QgPSAodW5zaWduZWQgaW50ICopCgkgICgoKHVuc2lnbmVkIGludCkgbG9hZF9hZGRyKSArIHBlX2ltcC0+VGh1bmtfTGlzdCk7CgoKICAgIHdoaWxlKCppbXBvcnRfbGlzdCkKCXsKCSAgcGVfbmFtZSA9IChzdHJ1Y3QgcGVfaW1wb3J0X25hbWUgKikgKChpbnQpIGxvYWRfYWRkciArICgodW5zaWduZWQpKmltcG9ydF9saXN0ICYgfjB4ODAwMDAwMDApKTsKCSAgaWYoKHVuc2lnbmVkKSppbXBvcnRfbGlzdCAmIDB4ODAwMDAwMDApCgkgIHsKCQlpbnQgb3JkaW5hbD0qaW1wb3J0X2xpc3QgJiAoMHg4MDAwMDAwMC0xKTsKCQlkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiLS0tIE9yZGluYWwgJXMsJWRcbiIsIE1vZHVsZSwgb3JkaW5hbCk7CgkJKnRodW5rX2xpc3QgPSBXSU4zMl9HZXRQcm9jQWRkcmVzcyhNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLAoJCQlvcmRpbmFsKTsKCSAgCWlmKCEqdGh1bmtfbGlzdCkKCSAgCXsKCSAgCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkXG4iLE1vZHVsZSwgCgkJCQlvcmRpbmFsKTsKCQkJZml4dXBfZmFpbGVkPTE7CgkgIAl9CgkgIH1lbHNleyAvKiBpbXBvcnQgYnkgbmFtZSAqLwoJICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKI2lmbmRlZiBXSU5FTElCIC8qIEZJWE1FOiBKQlA6IFNob3VsZCB0aGlzIGhhcHBlbiBpbiBsaWJ3aW5lLmE/ICovCgkgIAkqdGh1bmtfbGlzdCA9IFdJTjMyX0dldFByb2NBZGRyZXNzKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSksCgkJCQlwZV9uYW1lLT5OYW1lKTsKCSAgaWYoISp0aHVua19saXN0KQoJICB7CgkgIAlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKVxuIixNb2R1bGUsIAoJCQlwZV9uYW1lLT5IaW50LCBwZV9uYW1lLT5OYW1lKTsKCQlmaXh1cF9mYWlsZWQ9MTsKCSAgfQoKI2Vsc2UKCSAgZnByaW50ZihzdGRlcnIsIkpCUDogQ2FsbCB0byBSRUxBWTMyX0dldEVudHJ5UG9pbnQgYmVpbmcgaWdub3JlZC5cbiIpOwojZW5kaWYKCQl9CgoJICBpbXBvcnRfbGlzdCsrOwoJICB0aHVua19saXN0Kys7Cgl9CiAgICB9IGVsc2UgeyAvKiBCb3JsYW5kIHN0eWxlICovCiAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwogICAgICB0aHVua19saXN0ID0gKHVuc2lnbmVkIGludCAqKQogICAgICAgICgoKHVuc2lnbmVkIGludCkgbG9hZF9hZGRyKSArIHBlX2ltcC0+VGh1bmtfTGlzdCk7CiAgICAgIHdoaWxlKCp0aHVua19saXN0KSB7CiAgICAgICAgcGVfbmFtZSA9IChzdHJ1Y3QgcGVfaW1wb3J0X25hbWUgKikgKChpbnQpIGxvYWRfYWRkciArICp0aHVua19saXN0KTsKICAgICAgICBpZigodW5zaWduZWQpcGVfbmFtZSAmIDB4ODAwMDAwMDApIHsKICAgICAgICAgIGZwcmludGYoc3RkZXJyLCJJbXBvcnQgYnkgb3JkaW5hbCBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICAgIGV4aXQoMCk7CiAgICAgICAgfQogICAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwojaWZuZGVmIFdJTkVMSUIgLyogRklYTUU6IEpCUDogU2hvdWxkIHRoaXMgaGFwcGVuIGluIGxpYndpbmUuYT8gKi8KCS8qIEZJWE1FOiBCb3RoIGNhbGxzIHNob3VsZCBiZSB1bmlmaWVkIGludG8gR2V0UHJvY0FkZHJlc3MgKi8KICAgICAgICAqdGh1bmtfbGlzdCA9IFdJTjMyX0dldFByb2NBZGRyZXNzKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZV9uYW1lLT5OYW1lKTsKI2Vsc2UKICAgICAgICBmcHJpbnRmKHN0ZGVyciwiSkJQOiBDYWxsIHRvIFJFTEFZMzJfR2V0RW50cnlQb2ludCBiZWluZyBpZ25vcmVkLlxuIik7CiNlbmRpZgogICAgICAgIGlmKCEqdGh1bmtfbGlzdCkgewogICAgICAgICAgZnByaW50ZihzdGRlcnIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZFxuIixNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwogICAgICAgICAgZml4dXBfZmFpbGVkPTE7CiAgICAgICAgfQogICAgICAgIHRodW5rX2xpc3QrKzsKICAgICAgfQogICAgfQogICAgcGVfaW1wKys7CiAgfQogIGlmKGZpeHVwX2ZhaWxlZClleGl0KDEpOwp9CgpzdGF0aWMgdm9pZCBjYWxjX3ZtYV9zaXplKHN0cnVjdCBwZV9kYXRhICpwZSkKewogIGludCBpOwoKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgZHByaW50Zl93aW4zMihzdGRkZWIsICIgICBOYW1lICAgIFZTeiAgVmFkZHIgICAgIFN6UmF3ICAgRmlsZWFkciAgKlJlbG9jICpMaW5ldW0gI1JlbG9jICNMaW51bSBDaGFyXG4iKTsKICBmb3IoaT0wOyBpPCBwZS0+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+cGVfcmVsb2MpIGRvX3JlbG9jYXRpb25zKHBlKTsKICAgICAgICByZXR1cm4gcGU7Cn0KCkhJTlNUQU5DRSBNT0RVTEVfQ3JlYXRlSW5zdGFuY2UoSE1PRFVMRSBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CnZvaWQgSW5pdFRhc2soc3RydWN0IHNpZ2NvbnRleHRfc3RydWN0IGNvbnRleHQpOwoKSElOU1RBTkNFIFBFX0xvYWRNb2R1bGUoIGludCBmZCwgT0ZTVFJVQ1QgKm9mcywgTE9BRFBBUkFNUyogcGFyYW1zICkKewogICAgICAgIFBFX01PRFVMRSAqcGU7CglpbnQgc2l6ZSwgb2Zfc2l6ZTsKCU5FX01PRFVMRSAqcE1vZHVsZTsKCVNFR1RBQkxFRU5UUlkgKnBTZWdtZW50OwoJY2hhciAqcFN0cjsKCURXT1JEIGN0czsKCUhNT0RVTEUgaE1vZHVsZTsKCUhJTlNUQU5DRSBoSW5zdGFuY2U7CiAgICAgICAgc3RydWN0IG16X2hlYWRlcl9zIG16X2hlYWRlcjsKCglsc2VlayhmZCwwLFNFRUtfU0VUKTsKCXJlYWQoIGZkLCAmbXpfaGVhZGVyLCBzaXplb2YobXpfaGVhZGVyKSApOwoKICAgICAgICBvZl9zaXplID0gc2l6ZW9mKE9GU1RSVUNUKSAtIHNpemVvZihvZnMtPnN6UGF0aE5hbWUpCiAgICAgICAgICAgICAgICAgICsgc3RybGVuKG9mcy0+c3pQYXRoTmFtZSkgKyAxOwoJc2l6ZSA9IHNpemVvZihORV9NT0RVTEUpICsKICAgICAgICAgICAgICAgLyogbG9hZGVkIGZpbGUgaW5mbyAqLwogICAgICAgICAgICAgICBvZl9zaXplICsKICAgICAgICAgICAgICAgLyogc2VnbWVudCB0YWJsZTogRFMsQ1MgKi8KICAgICAgICAgICAgICAgMiAqIHNpemVvZihTRUdUQUJMRUVOVFJZKSArCiAgICAgICAgICAgICAgIC8qIG5hbWUgdGFibGUgKi8KICAgICAgICAgICAgICAgOSArCiAgICAgICAgICAgICAgIC8qIHNldmVyYWwgZW1wdHkgdGFibGVzICovCiAgICAgICAgICAgICAgIDg7CgoJaE1vZHVsZSA9IEdsb2JhbEFsbG9jMTYoIEdNRU1fTU9WRUFCTEUgfCBHTUVNX1pFUk9JTklULCBzaXplICk7CglpZiAoIWhNb2R1bGUpIHJldHVybiAoSElOU1RBTkNFKTExOyAgLyogaW52YWxpZCBleGUgKi8KCglGYXJTZXRPd25lciggaE1vZHVsZSwgaE1vZHVsZSApOwoJCglwTW9kdWxlID0gKE5FX01PRFVMRSopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwoKCS8qIFNldCBhbGwgdXNlZCBlbnRyaWVzICovCglwTW9kdWxlLT5tYWdpYz1ORV9TSUdOQVRVUkU7CglwTW9kdWxlLT5jb3VudD0xOwoJcE1vZHVsZS0+bmV4dD0wOwoJcE1vZHVsZS0+ZmxhZ3M9TkVfRkZMQUdTX1dJTjMyOwoJcE1vZHVsZS0+ZGdyb3VwPTE7CglwTW9kdWxlLT5zcz0xOwoJcE1vZHVsZS0+Y3M9MjsKCS8qIFdobyB3YW50cyB0byBMb2NhbEFsbG9jIGZvciBhIFBFIE1vZHVsZT8gKi8KCXBNb2R1bGUtPmhlYXBfc2l6ZT0weDEwMDA7CglwTW9kdWxlLT5zdGFja19zaXplPTB4RjAwMDsKCXBNb2R1bGUtPnNlZ19jb3VudD0xOwoJcE1vZHVsZS0+bW9kcmVmX2NvdW50PTA7CglwTW9kdWxlLT5ucm5hbWVfc2l6ZT0wOwoJcE1vZHVsZS0+ZmlsZWluZm89c2l6ZW9mKE5FX01PRFVMRSk7CglwTW9kdWxlLT5vc19mbGFncz1ORV9PU0ZMQUdTX1dJTkRPV1M7CglwTW9kdWxlLT5leHBlY3RlZF92ZXJzaW9uPTB4MzBBOwogICAgICAgIHBNb2R1bGUtPnNlbGYgPSBoTW9kdWxlOwoKICAgICAgICAvKiBTZXQgbG9hZGVkIGZpbGUgaW5mb3JtYXRpb24gKi8KICAgICAgICBtZW1jcHkoIHBNb2R1bGUgKyAxLCBvZnMsIG9mX3NpemUgKTsKICAgICAgICAoKE9GU1RSVUNUICopKHBNb2R1bGUrMSkpLT5jQnl0ZXMgPSBvZl9zaXplIC0gMTsKCglwU2VnbWVudD0oU0VHVEFCTEVFTlRSWSopKChjaGFyKikocE1vZHVsZSArIDEpICsgb2Zfc2l6ZSk7CglwTW9kdWxlLT5zZWdfdGFibGU9cE1vZHVsZS0+ZGdyb3VwX2VudHJ5PShpbnQpcFNlZ21lbnQtKGludClwTW9kdWxlOwoJcFNlZ21lbnQtPnNpemU9MDsKCXBTZWdtZW50LT5mbGFncz1ORV9TRUdGTEFHU19EQVRBOwoJcFNlZ21lbnQtPm1pbnNpemU9MHgxMDAwOwoJcFNlZ21lbnQrKzsKCgljdHM9KERXT1JEKU1PRFVMRV9HZXRXbmRQcm9jRW50cnkxNigiV2luMzJDYWxsVG9TdGFydCIpOwojaWZkZWYgV0lORUxJQjMyCglwU2VnbWVudC0+c2VsZWN0b3I9KHZvaWQqKWN0czsKCXBNb2R1bGUtPmlwPTA7CiNlbHNlCglwU2VnbWVudC0+c2VsZWN0b3I9Y3RzPj4xNjsKCXBNb2R1bGUtPmlwPWN0cyAmIDB4RkZGRjsKI2VuZGlmCglwU2VnbWVudCsrOwoKCXBTdHI9KGNoYXIqKXBTZWdtZW50OwoJcE1vZHVsZS0+bmFtZV90YWJsZT0oaW50KXBTdHItKGludClwTW9kdWxlOwoJc3RyY3B5KHBTdHIsIlx4MDhXMzJTWFhYWCIpOwoJcFN0cis9OTsKCgkvKiBBbGwgdGFibGVzIHplcm8gdGVybWluYXRlZCAqLwoJcE1vZHVsZS0+cmVzX3RhYmxlPXBNb2R1bGUtPmltcG9ydF90YWJsZT1wTW9kdWxlLT5lbnRyeV90YWJsZT0KCQkoaW50KXBTdHItKGludClwTW9kdWxlOwoKICAgICAgICBNT0RVTEVfUmVnaXN0ZXJNb2R1bGUoIHBNb2R1bGUgKTsKCglwZSA9IFBFX0xvYWRJbWFnZSggZmQsIGhNb2R1bGUsIG16X2hlYWRlci5uZV9vZmZzZXQgKTsKCiAgICAgICAgcE1vZHVsZS0+cGVfbW9kdWxlID0gcGU7CglwTW9kdWxlLT5oZWFwX3NpemU9MHgxMDAwOwoJcE1vZHVsZS0+c3RhY2tfc2l6ZT0weEUwMDA7CgoJLyogQ3JlYXRlSW5zdGFuY2UgYWxsb2NhdGVzIG5vdyA2NEtCICovCgloSW5zdGFuY2U9TU9EVUxFX0NyZWF0ZUluc3RhbmNlKGhNb2R1bGUsTlVMTCAvKiBGSVg6IE5VTEw/IHJlYWxseT8gKi8pOwoKICAgICAgICAvKiBGSVhNRTogSXMgdGhpcyByZWFsbHkgdGhlIGNvcnJlY3QgcGxhY2UgdG8gaW5pdGlhbGlzZSB0aGUgRExMPyAqLwoJaWYgKChwZS0+cGVfaGVhZGVyLT5jb2ZmLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSkgewovKiAgICAgICAgICAgIFBFX0luaXRETEwoaE1vZHVsZSk7ICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVEFTS19DcmVhdGVUYXNrKGhNb2R1bGUsaEluc3RhbmNlLDAsCgkJcGFyYW1zLT5oRW52aXJvbm1lbnQsKExQU1RSKVBUUl9TRUdfVE9fTElOKHBhcmFtcy0+Y21kTGluZSksCgkJKigoV09SRCopUFRSX1NFR19UT19MSU4ocGFyYW1zLT5zaG93Q21kKSsxKSk7CiAgICAgICAgICAgIFBFX0luaXRpYWxpemVETExzKGhNb2R1bGUpOwoJfQoJcmV0dXJuIGhJbnN0YW5jZTsKfQoKaW50IFVTRVJfSW5pdEFwcChISU5TVEFOQ0UgaEluc3RhbmNlKTsKdm9pZCBQRV9Jbml0VEVCKGludCBoVEVCKTsKCnZvaWQgUEVfV2luMzJDYWxsVG9TdGFydChzdHJ1Y3Qgc2lnY29udGV4dF9zdHJ1Y3QgY29udGV4dCkKewogICAgaW50IGZzOwogICAgSE1PRFVMRSBoTW9kdWxlOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwoKICAgIGRwcmludGZfd2luMzIoc3RkZGViLCJHb2luZyB0byBzdGFydCBXaW4zMiBwcm9ncmFtXG4iKTsJCiAgICBJbml0VGFzayhjb250ZXh0KTsKICAgIGhNb2R1bGUgPSBHZXRFeGVQdHIoIEdldEN1cnJlbnRUYXNrKCkgKTsKICAgIHBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKCBoTW9kdWxlICk7CiAgICBVU0VSX0luaXRBcHAoIGhNb2R1bGUgKTsKICAgIGZzPShpbnQpR2xvYmFsQWxsb2MxNihHSE5ELDB4MTAwMDApOwogICAgUEVfSW5pdFRFQihmcyk7CiAgICBfX2FzbV9fIF9fdm9sYXRpbGVfXygibW92dyAldzAsJSVmcyI6OiJyIiAoZnMpKTsKICAgIENhbGxUYXNrU3RhcnQzMiggKEZBUlBST0MpKHBNb2R1bGUtPnBlX21vZHVsZS0+bG9hZF9hZGRyICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTW9kdWxlLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+b3B0X2NvZmYuQWRkcmVzc09mRW50cnlQb2ludCkgKTsKfQoKaW50IFBFX1VubG9hZEltYWdlKCBITU9EVUxFIGhNb2R1bGUgKQp7CglwcmludGYoIlBFdW5sb2FkSW1hZ2UoKSBjYWxsZWQhXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgpzdGF0aWMgdm9pZCBQRV9Jbml0RExMKEhNT0RVTEUgaE1vZHVsZSkKewogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgUEVfTU9EVUxFICpwZTsKCiAgICBoTW9kdWxlID0gR2V0RXhlUHRyKGhNb2R1bGUpOwogICAgaWYgKCEocE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoaE1vZHVsZSkpKSByZXR1cm47CiAgICBpZiAoIShwTW9kdWxlLT5mbGFncyAmIE5FX0ZGTEFHU19XSU4zMikgfHwgIShwZSA9IHBNb2R1bGUtPnBlX21vZHVsZSkpCiAgICAgICAgcmV0dXJuOwoKICAgIC8qIEZJWE1FOiBXaGF0IGFyZSB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIHBhcmFtZXRlcnMgMiBhbmQgMz8gKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyAqLwogICAgaWYgKHBlLT5wZV9oZWFkZXItPmNvZmYuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpCiAgICB7CiAgICAgICAgcHJpbnRmKCJJbml0UEVETEwoKSBjYWxsZWQhXG4iKTsKICAgICAgICBDYWxsRExMRW50cnlQcm9jMzIoIChGQVJQUk9DKShwZS0+bG9hZF9hZGRyICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5BZGRyZXNzT2ZFbnRyeVBvaW50KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhNb2R1bGUsIDAsIDAgKTsKICAgIH0KfQoKCi8qIEZJWE1FOiBUaGlzIHN0dWZmIGlzIGFsbCBvbiBhICJ3ZWxsIGl0IHdvcmtzIiBiYXNpcy4gQW4gaW1wbGVtZW50YXRpb24KYmFzZWQgb24gc29tZSBraW5kIG9mIGRvY3VtZW50YXRpb24gd291bGQgYmUgZ3JlYXRseSBhcHByZWNpYXRlZCA6LSkgKi8KCnR5cGVkZWYgc3RydWN0CnsKICAgIHZvaWQgICAgICAgICpFeGNlcHQ7CiAgICB2b2lkICAgICAgICAqc3RhY2s7CiAgICBpbnQJICAgICAgICBkdW1teTFbNF07CiAgICBzdHJ1Y3QgVEVCICAqVEVCRFNBbGlhczsKICAgIGludAkgICAgICAgIGR1bW15MlsyXTsKICAgIGludAkgICAgICAgIHRhc2tpZDsKfSBURUI7Cgp2b2lkIFBFX0luaXRURUIoaW50IGhURUIpCnsKICAgIFREQiAqcFRhc2s7CiAgICBURUIgKnBURUI7CgogICAgcFRhc2sgPSAoVERCICopKEdsb2JhbExvY2sxNihHZXRDdXJyZW50VGFzaygpICYgMHhmZmZmKSk7CiAgICBwVEVCID0gKFRFQiAqKShQVFJfU0VHX09GRl9UT19MSU4oaFRFQiwgMCkpOwogICAgcFRFQi0+c3RhY2sgPSAodm9pZCAqKShHbG9iYWxMb2NrMTYocFRhc2stPmhTdGFjazMyKSk7CiAgICBwVEVCLT5FeGNlcHQgPSAodm9pZCAqKSgtMSk7IAogICAgcFRFQi0+VEVCRFNBbGlhcyA9IHBURUI7CiAgICBwVEVCLT50YXNraWQgPSBnZXRwaWQoKTsKfQoKdm9pZCBQRV9Jbml0aWFsaXplRExMcyhITU9EVUxFIGhNb2R1bGUpCnsKCU5FX01PRFVMRSAqcE1vZHVsZTsKCUhNT0RVTEUgKnBETEw7CglwTW9kdWxlID0gTU9EVUxFX0dldFB0ciggR2V0RXhlUHRyKGhNb2R1bGUpICk7CglpZiAocE1vZHVsZS0+ZGxsc190b19pbml0KQoJewoJCUhBTkRMRSB0b19pbml0ID0gcE1vZHVsZS0+ZGxsc190b19pbml0OwoJCXBNb2R1bGUtPmRsbHNfdG9faW5pdCA9IDA7CgkJZm9yIChwRExMID0gKEhNT0RVTEUgKilHbG9iYWxMb2NrMTYoIHRvX2luaXQgKTsgKnBETEw7IHBETEwrKykKCQl7CgkJCVBFX0luaXRpYWxpemVETExzKCAqcERMTCApOwoJCQlQRV9Jbml0RExMKCAqcERMTCApOwoJCX0KCQlHbG9iYWxGcmVlMTYoIHRvX2luaXQgKTsKCX0KCVBFX0luaXRETEwoIGhNb2R1bGUgKTsKfQojZW5kaWYgLyogV0lORUxJQiAqLwo=