I2lmbmRlZiBXSU5FTElCCi8qIAogKiAgQ29weXJpZ2h0CTE5OTQJRXJpYyBZb3VuZGFsZSAmIEVyaWsgQm9zCiAqICBDb3B5cmlnaHQJMTk5NQlNYXJ0aW4gdm9uIEz2d2lzCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwZV9pbWFnZS5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJnbG9iYWwuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAicmVnaXN0ZXJzLmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKCnZvaWQgbXlfd2NzdG9tYnMoY2hhciAqIHJlc3VsdCwgdV9zaG9ydCAqIHNvdXJjZSwgaW50IGxlbikKewogIHdoaWxlKGxlbi0tKSB7CiAgICAvKiB0aGlzIHVzZWQgdG8gYmUgaXNhc2NpaSwgYnV0IHNlZSBpc2FzY2lpIGltcGxlbWVudGF0aW9uIGluIExpbnV4JwoJICAgY3R5cGUuaCAqLwogICAgaWYoKnNvdXJjZTwyNTUpICpyZXN1bHQrKyA9ICpzb3VyY2UrKzsKICAgIGVsc2UgewogICAgICBwcmludGYoIlVuYWJsZSB0byBoYW5kbGUgdW5pY29kZSByaWdodCBub3dcbiIpOwogICAgICBleGl0KDApOwogICAgfQogIH07Cn0KCiNpZiAwCmNoYXIgKiB4bW1hcChjaGFyICogdmFkZHIsIHVuc2lnbmVkIGludCB2X3NpemUsIHVuc2lnbmVkIGludCByX3NpemUsCglpbnQgcHJvdCwgaW50IGZsYWdzLCBpbnQgZmQsIHVuc2lnbmVkIGludCBmaWxlX29mZnNldCkKewogIGNoYXIgKiByZXN1bHQ7CiAgLyogLmJzcyBoYXMgbm8gYXNzb2NpYXRlZCBzdG9yYWdlIGluIHRoZSBQRSBmaWxlICovCiAgaWYocl9zaXplKQogICAgdl9zaXplPXJfc2l6ZTsKICBlbHNlCiNpZiBkZWZpbmVkKF9fc3ZyNF9fKSB8fCBkZWZpbmVkKF9TQ09fRFMpCiAgICBmcHJpbnRmKHN0ZGVyciwieG1tYXA6ICVzIGxpbmUgJWQgZG9lc24ndCBzdXBwb3J0IE1BUF9BTk9OXG4iLF9fRklMRV9fLCBfX0xJTkVfXyk7CiNlbHNlCiAgICBmbGFncyB8PSBNQVBfQU5PTjsKI2VuZGlmCiAgcmVzdWx0ID0gbW1hcCh2YWRkciwgdl9zaXplLCBwcm90LCBmbGFncywgZmQsIGZpbGVfb2Zmc2V0KTsKICBpZigodW5zaWduZWQgaW50KSByZXN1bHQgIT0gMHhmZmZmZmZmZikgcmV0dXJuIHJlc3VsdDsKCiAgLyogU2lnaC4gIEFsaWdubWVudCBtdXN0IGJlIHdyb25nIGZvciBtbWFwLiAgRG8gdGhpcyB0aGUgaGFyZCB3YXkuICovCiAgaWYoIShmbGFncyAmIE1BUF9GSVhFRCkpIHsKICAgIHZhZGRyID0gKGNoYXIgKikweDQwMDAwMDAwOwogICAgZmxhZ3MgfD0gTUFQX0ZJWEVEOwogIH07CgogIG1tYXAodmFkZHIsIHZfc2l6ZSwgcHJvdCwgTUFQX0FOT05ZTU9VUyB8IGZsYWdzLCAwLCAwKTsKICBsc2VlayhmZCwgZmlsZV9vZmZzZXQsIFNFRUtfU0VUKTsKICByZWFkKGZkLCB2YWRkciwgdl9zaXplKTsKICByZXR1cm4gdmFkZHI7Cn07CiNlbmRpZgoKdm9pZCBkdW1wX2V4cG9ydHMoc3RydWN0IFBFX0V4cG9ydF9EaXJlY3RvcnkgKiBwZV9leHBvcnRzLCB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyKQp7IAogIGNoYXIgKiBNb2R1bGU7CiAgaW50IGk7CiAgdV9zaG9ydCAqIG9yZGluYWw7CiAgdV9sb25nICogZnVuY3Rpb247CiAgdV9jaGFyICoqIG5hbWUsICplbmFtZTsKCiAgTW9kdWxlID0gKChjaGFyICopIGxvYWRfYWRkcikgKyBwZV9leHBvcnRzLT5OYW1lOwogIGRwcmludGZfd2luMzIoc3RkZGViLCJcbioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJIE1vZHVsZSwKCSBwZV9leHBvcnRzLT5OdW1iZXJfT2ZfRnVuY3Rpb25zLAoJIHBlX2V4cG9ydHMtPk51bWJlcl9PZl9OYW1lcyk7CgogIG9yZGluYWwgPSAodV9zaG9ydCAqKSAoKChjaGFyICopIGxvYWRfYWRkcikgKyAoaW50KSBwZV9leHBvcnRzLT5BZGRyZXNzX09mX05hbWVfT3JkaW5hbHMpOwogIGZ1bmN0aW9uID0gKHVfbG9uZyAqKSAgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgcGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lID0gKHVfY2hhciAqKikgICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgZHByaW50Zl93aW4zMihzdGRkZWIsIiUtMzJzIE9yZGluYWwgVmlydCBBZGRyXG4iLCAiRnVuY3Rpb24gTmFtZSIpOwogIGZvcihpPTA7IGk8IHBlX2V4cG9ydHMtPk51bWJlcl9PZl9GdW5jdGlvbnM7IGkrKykKICAgIHsKICAgICAgZW5hbWUgPSAgKGNoYXIgKikgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgKm5hbWUrKyk7CiAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyAlNGQgICAgJTguOGx4XG4iLCBlbmFtZSwgKm9yZGluYWwrKywgKmZ1bmN0aW9uKyspOwogICAgfQp9CgpGQVJQUk9DMzIgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oc3RydWN0IHBlX2RhdGEgKnBlLCBMUENTVFIgZnVuY05hbWUpCnsKCXN0cnVjdCBQRV9FeHBvcnRfRGlyZWN0b3J5ICogZXhwb3J0cyA9IHBlLT5wZV9leHBvcnQ7Cgl1bnNpZ25lZCBsb2FkX2FkZHIgPSBwZS0+bG9hZF9hZGRyOwoJdV9zaG9ydCAqIG9yZGluYWw7Cgl1X2xvbmcgKiBmdW5jdGlvbjsKCXVfY2hhciAqKiBuYW1lLCAqZW5hbWU7CglpbnQgaTsKCglpZiAoIWV4cG9ydHMpIHJldHVybiBOVUxMOwoJb3JkaW5hbCA9ICh1X3Nob3J0ICopICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIGV4cG9ydHMtPkFkZHJlc3NfT2ZfTmFtZV9PcmRpbmFscyk7CglmdW5jdGlvbiA9ICh1X2xvbmcgKikgICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lID0gKHVfY2hhciAqKikgICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcihpPTA7IGk8ZXhwb3J0cy0+TnVtYmVyX09mX0Z1bmN0aW9uczsgaSsrKQoJewoJCWlmKEhJV09SRChmdW5jTmFtZSkpCgkJewoJCQllbmFtZSA9ICAoY2hhciAqKSAoKChjaGFyICopIGxvYWRfYWRkcikgKyAoaW50KSAqbmFtZSk7CgkJCWlmKHN0cmNtcChlbmFtZSxmdW5jTmFtZSk9PTApCgkJCQlyZXR1cm4gKEZBUlBST0MzMikobG9hZF9hZGRyICsgKmZ1bmN0aW9uKTsKCQl9ZWxzZXsKCQkJaWYoKGludClmdW5jTmFtZSA9PSAoaW50KSpvcmRpbmFsICsgZXhwb3J0cy0+QmFzZSkKCQkJCXJldHVybiAoRkFSUFJPQzMyKShsb2FkX2FkZHIgKyAqZnVuY3Rpb24pOwoJCX0KCQlmdW5jdGlvbisrOwoJCW9yZGluYWwrKzsKCQluYW1lKys7Cgl9CglyZXR1cm4gTlVMTDsKfQoKdm9pZCBmaXh1cF9pbXBvcnRzKHN0cnVjdCBwZV9kYXRhICpwZSwgSE1PRFVMRTE2IGhNb2R1bGUpCnsgCiAgc3RydWN0IFBFX0ltcG9ydF9EaXJlY3RvcnkgKiBwZV9pbXA7CiAgaW50IGZpeHVwX2ZhaWxlZD0wOwogIHVuc2lnbmVkIGludCBsb2FkX2FkZHIgPSBwZS0+bG9hZF9hZGRyOwogIGludCBpOwogIE5FX01PRFVMRSAqbmVfbW9kOwogIEhNT0RVTEUxNiAqbW9kX3B0cjsKCiAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgZHByaW50Zl93aW4zMihzdGRkZWIsICJcbkR1bXBpbmcgaW1wb3J0cyBsaXN0XG4iKTsKCiAgLyogZmlyc3QsIGNvdW50IHRoZSBudW1iZXIgb2YgaW1wb3J0ZWQgbm9uLWludGVybmFsIG1vZHVsZXMgKi8KICBwZV9pbXAgPSBwZS0+cGVfaW1wb3J0OwogIGZvcihpPTA7cGVfaW1wLT5Nb2R1bGVOYW1lO3BlX2ltcCsrKQogIAlpKys7CgogIC8qIE5vdywgYWxsb2NhdGUgbWVtb3J5IGZvciBkbGxzX3RvX2luaXQgKi8KICBuZV9tb2QgPSBHbG9iYWxMb2NrMTYoaE1vZHVsZSk7CiAgbmVfbW9kLT5kbGxzX3RvX2luaXQgPSBHTE9CQUxfQWxsb2MoR01FTV9aRVJPSU5JVCwoaSsxKSAqIHNpemVvZihITU9EVUxFMTYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhNb2R1bGUsIEZBTFNFLCBGQUxTRSwgRkFMU0UgKTsKICBtb2RfcHRyID0gR2xvYmFsTG9jazE2KG5lX21vZC0+ZGxsc190b19pbml0KTsKICAvKiBsb2FkIHRoZSBtb2R1bGVzIGFuZCBwdXQgdGhlaXIgaGFuZGxlcyBpbnRvIHRoZSBsaXN0ICovCiAgZm9yKGk9MCxwZV9pbXAgPSBwZS0+cGVfaW1wb3J0O3BlX2ltcC0+TW9kdWxlTmFtZTtwZV9pbXArKykKICB7CiAgCWNoYXIgKm5hbWUgPSAoY2hhciopbG9hZF9hZGRyK3BlX2ltcC0+TW9kdWxlTmFtZTsKCW1vZF9wdHJbaV0gPSBMb2FkTW9kdWxlKG5hbWUsKExQVk9JRCktMSk7CglpZihtb2RfcHRyW2ldPD0oSE1PRFVMRTE2KTMyKQogICAgICAgIHsKICAgICAgICAgICAgY2hhciAqcCwgYnVmZmVyWzI1Nl07CgogICAgICAgICAgICAvKiBUcnkgd2l0aCBwcmVwZW5kaW5nIHRoZSBwYXRoIG9mIHRoZSBjdXJyZW50IG1vZHVsZSAqLwogICAgICAgICAgICBHZXRNb2R1bGVGaWxlTmFtZSggaE1vZHVsZSwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSApOwogICAgICAgICAgICBpZiAoIShwID0gc3RycmNociggYnVmZmVyLCAnXFwnICkpKSBwID0gYnVmZmVyOwogICAgICAgICAgICBzdHJjcHkoIHAgKyAxLCBuYW1lICk7CiAgICAgICAgICAgIG1vZF9wdHJbaV0gPSBMb2FkTW9kdWxlKCBidWZmZXIsIChMUFZPSUQpLTEgKTsKICAgICAgICB9CglpZihtb2RfcHRyW2ldPD0oSE1PRFVMRTE2KTMyKQoJewoJCWZwcmludGYoc3RkZXJyLCJNb2R1bGUgJXMgbm90IGZvdW5kXG4iLG5hbWUpOwoJCWV4aXQoMCk7Cgl9CglpKys7CiAgfQogIHBlX2ltcCA9IHBlLT5wZV9pbXBvcnQ7CiAgd2hpbGUgKHBlX2ltcC0+TW9kdWxlTmFtZSkKICAgIHsKICAgICAgY2hhciAqIE1vZHVsZTsKICAgICAgc3RydWN0IHBlX2ltcG9ydF9uYW1lICogcGVfbmFtZTsKICAgICAgdW5zaWduZWQgaW50ICogaW1wb3J0X2xpc3QsICp0aHVua19saXN0OwoKICAgICAgTW9kdWxlID0gKChjaGFyICopIGxvYWRfYWRkcikgKyBwZV9pbXAtPk1vZHVsZU5hbWU7CiAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiJXNcbiIsIE1vZHVsZSk7CgogICBpZihwZV9pbXAtPkltcG9ydF9MaXN0ICE9IDApIHsgLyogb3JpZ2luYWwgbWljcm9zb2Z0IHN0eWxlICovCiAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CiAgICAgIGltcG9ydF9saXN0ID0gKHVuc2lnbmVkIGludCAqKSAKCSgoKHVuc2lnbmVkIGludCkgbG9hZF9hZGRyKSArIHBlX2ltcC0+SW1wb3J0X0xpc3QpOwoJICB0aHVua19saXN0ID0gKHVuc2lnbmVkIGludCAqKQoJICAoKCh1bnNpZ25lZCBpbnQpIGxvYWRfYWRkcikgKyBwZV9pbXAtPlRodW5rX0xpc3QpOwoKCiAgICB3aGlsZSgqaW1wb3J0X2xpc3QpCgl7CgkgIHBlX25hbWUgPSAoc3RydWN0IHBlX2ltcG9ydF9uYW1lICopICgoaW50KSBsb2FkX2FkZHIgKyAoKHVuc2lnbmVkKSppbXBvcnRfbGlzdCAmIH4weDgwMDAwMDAwKSk7CgkgIGlmKCh1bnNpZ25lZCkqaW1wb3J0X2xpc3QgJiAweDgwMDAwMDAwKQoJICB7CgkJaW50IG9yZGluYWw9KmltcG9ydF9saXN0ICYgKDB4ODAwMDAwMDAtMSk7CgkJZHByaW50Zl93aW4zMihzdGRkZWIsIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBNb2R1bGUsIG9yZGluYWwpOwoJCSp0aHVua19saXN0ID0gR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUENTVFIpb3JkaW5hbCk7CgkgIAlpZighKnRodW5rX2xpc3QpCgkgIAl7CgkgIAkJZnByaW50ZihzdGRlcnIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1vZHVsZSwgb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJICAJfQoJICB9ZWxzZXsgLyogaW1wb3J0IGJ5IG5hbWUgKi8KCSAgZHByaW50Zl93aW4zMihzdGRkZWIsICItLS0gJXMgJXMuJWRcbiIsIHBlX25hbWUtPk5hbWUsIE1vZHVsZSwgcGVfbmFtZS0+SGludCk7CiNpZm5kZWYgV0lORUxJQiAvKiBGSVhNRTogSkJQOiBTaG91bGQgdGhpcyBoYXBwZW4gaW4gbGlid2luZS5hPyAqLwoJICAJKnRodW5rX2xpc3QgPSBHZXRQcm9jQWRkcmVzczMyKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVfbmFtZS0+TmFtZSk7CgkgIGlmKCEqdGh1bmtfbGlzdCkKCSAgewoJICAJZnByaW50ZihzdGRlcnIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcyksIHNldHRpbmcgdG8gTlVMTFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgTW9kdWxlLCBwZV9uYW1lLT5IaW50LCBwZV9uYW1lLT5OYW1lKTsKCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCSAgfQoKI2Vsc2UKCSAgZnByaW50ZihzdGRlcnIsIkpCUDogQ2FsbCB0byBSRUxBWTMyX0dldEVudHJ5UG9pbnQgYmVpbmcgaWdub3JlZC5cbiIpOwojZW5kaWYKCQl9CgoJICBpbXBvcnRfbGlzdCsrOwoJICB0aHVua19saXN0Kys7Cgl9CiAgICB9IGVsc2UgeyAvKiBCb3JsYW5kIHN0eWxlICovCiAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwogICAgICB0aHVua19saXN0ID0gKHVuc2lnbmVkIGludCAqKQogICAgICAgICgoKHVuc2lnbmVkIGludCkgbG9hZF9hZGRyKSArIHBlX2ltcC0+VGh1bmtfTGlzdCk7CiAgICAgIHdoaWxlKCp0aHVua19saXN0KSB7CiAgICAgICAgcGVfbmFtZSA9IChzdHJ1Y3QgcGVfaW1wb3J0X25hbWUgKikgKChpbnQpIGxvYWRfYWRkciArICp0aHVua19saXN0KTsKICAgICAgICBpZigodW5zaWduZWQpcGVfbmFtZSAmIDB4ODAwMDAwMDApIHsKICAgICAgICAgIGZwcmludGYoc3RkZXJyLCJJbXBvcnQgYnkgb3JkaW5hbCBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICAgIGV4aXQoMCk7CiAgICAgICAgfQogICAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwojaWZuZGVmIFdJTkVMSUIgLyogRklYTUU6IEpCUDogU2hvdWxkIHRoaXMgaGFwcGVuIGluIGxpYndpbmUuYT8gKi8KICAgICAgICAqdGh1bmtfbGlzdCA9IEdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVfbmFtZS0+TmFtZSk7CiNlbHNlCiAgICAgICAgZnByaW50ZihzdGRlcnIsIkpCUDogQ2FsbCB0byBSRUxBWTMyX0dldEVudHJ5UG9pbnQgYmVpbmcgaWdub3JlZC5cbiIpOwojZW5kaWYKICAgICAgICBpZighKnRodW5rX2xpc3QpIHsKICAgICAgICAgIGZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKICAgICAgICAgICAgICAgICAgTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKICAgICAgICAgIC8qIGZpeHVwX2ZhaWxlZD0xOyAqLwogICAgICAgIH0KICAgICAgICB0aHVua19saXN0Kys7CiAgICAgIH0KICAgIH0KICAgIHBlX2ltcCsrOwogIH0KICBpZihmaXh1cF9mYWlsZWQpZXhpdCgxKTsKfQoKc3RhdGljIHZvaWQgY2FsY192bWFfc2l6ZShzdHJ1Y3QgcGVfZGF0YSAqcGUpCnsKICBpbnQgaTsKCiAgZHByaW50Zl93aW4zMihzdGRkZWIsICJEdW1wIG9mIHNlZ21lbnQgdGFibGVcbiIpOwogIGRwcmludGZfd2luMzIoc3RkZGViLCAiICAgTmFtZSAgICBWU3ogIFZhZGRyICAgICBTelJhdyAgIEZpbGVhZHIgICpSZWxvYyAqTGluZXVtICNSZWxvYyAjTGludW0gQ2hhclxuIik7CiAgZm9yKGk9MDsgaTwgcGUtPnBlX2hlYWRlci0+Y29mZi5OdW1iZXJPZlNlY3Rpb25zOyBpKyspCiAgICB7CiAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiJThzOiAlNC40bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlNC40eCAlNC40eCAlOC44bHhcbiIsIAoJICAgICBwZS0+cGVfc2VnW2ldLk5hbWUsIAoJICAgICBwZS0+cGVfc2VnW2ldLlZpcnR1YWxfU2l6ZSwKCSAgICAgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX0FkZHJlc3MsCgkgICAgIHBlLT5wZV9zZWdbaV0uU2l6ZV9PZl9SYXdfRGF0YSwKCSAgICAgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SYXdEYXRhLAoJICAgICBwZS0+cGVfc2VnW2ldLlBvaW50ZXJUb1JlbG9jYXRpb25zLAoJICAgICBwZS0+cGVfc2VnW2ldLlBvaW50ZXJUb0xpbmVudW1iZXJzLAoJICAgICBwZS0+cGVfc2VnW2ldLk51bWJlck9mUmVsb2NhdGlvbnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uTnVtYmVyT2ZMaW5lbnVtYmVycywKCSAgICAgcGUtPnBlX3NlZ1tpXS5DaGFyYWN0ZXJpc3RpY3MpOwoJICBwZS0+dm1hX3NpemUgPSBNQVgocGUtPnZtYV9zaXplLAoJICAJCXBlLT5wZV9zZWdbaV0uVmlydHVhbF9BZGRyZXNzICsgCgkJCXBlLT5wZV9zZWdbaV0uU2l6ZV9PZl9SYXdfRGF0YSk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGRvX3JlbG9jYXRpb25zKHN0cnVjdCBwZV9kYXRhICpwZSkKewoJaW50IGRlbHRhID0gcGUtPmxvYWRfYWRkciAtIHBlLT5iYXNlX2FkZHI7CglzdHJ1Y3QgUEVfUmVsb2NfQmxvY2sgKnIgPSBwZS0+cGVfcmVsb2M7CglpbnQgaGRlbHRhID0gKGRlbHRhID4+IDE2KSAmIDB4RkZGRjsKCWludCBsZGVsdGEgPSBkZWx0YSAmIDB4RkZGRjsKCS8qIGludCByZWxvY19zaXplID0gKi8KCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlBhZ2VSVkEpCgl7CgkJY2hhciAqcGFnZSA9IChjaGFyKilwZS0+bG9hZF9hZGRyICsgci0+UGFnZVJWQTsKCQlpbnQgY291bnQgPSAoci0+QmxvY2tTaXplIC0gOCkvMjsKCQlpbnQgaTsKCQlkcHJpbnRmX2ZpeHVwKHN0ZGRlYiwgIiV4IHJlbG9jYXRpb25zIGZvciBwYWdlICVseFxuIiwKCQkJY291bnQsIHItPlBhZ2VSVkEpOwoJCS8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KCQlmb3IoaT0wO2k8Y291bnQ7aSsrKQoJCXsKCQkJaW50IG9mZnNldCA9IHItPlJlbG9jYXRpb25zW2ldICYgMHhGRkY7CgkJCWludCB0eXBlID0gci0+UmVsb2NhdGlvbnNbaV0gPj4gMTI7CgkJCWRwcmludGZfZml4dXAoc3RkZGViLCJwYXRjaGluZyAleCB0eXBlICV4XG4iLCBvZmZzZXQsIHR5cGUpOwoJCQlzd2l0Y2godHlwZSkKCQkJewoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURTogYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0g6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGhkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGxkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgojaWYgMQoJCQkJKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CiNlbHNlCgkJCQl7IGludCBoPSoodW5zaWduZWQgc2hvcnQqKShwYWdlK29mZnNldCk7CgkJCQkgIGludCBsPXItPlJlbG9jYXRpb25zWysraV07CgkJCQkgICoodW5zaWduZWQgaW50KikocGFnZSArIG9mZnNldCkgPSAoaDw8MTYpICsgbCArIGRlbHRhOwoJCQkJfQojZW5kaWYKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJZnByaW50ZihzdGRlcnIsICJEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBJTUFHRV9SRUxfQkFTRURfSElHSEFESlxuIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTUlQU19KTVBBRERSOgoJCQkJZnByaW50ZihzdGRlcnIsICJJcyB0aGlzIGEgTUlQUyBtYWNoaW5lID8/P1xuIik7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBmaXh1cCB0eXBlXG4iKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXIgPSAoc3RydWN0IFBFX1JlbG9jX0Jsb2NrKikoKGNoYXIqKXIgKyByLT5CbG9ja1NpemUpOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBleGVjdXRhYmxlIGludG8gbWVtb3J5CiAqLwpzdGF0aWMgc3RydWN0IHBlX2RhdGEgKlBFX0xvYWRJbWFnZSggaW50IGZkLCBITU9EVUxFMTYgaE1vZHVsZSwgV09SRCBvZmZzZXQgKQp7CiAgICBzdHJ1Y3QgcGVfZGF0YSAqcGU7CiAgICBpbnQgaSwgcmVzdWx0OwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcjsKICAgIHN0cnVjdCBEaXJlY3RvcnkgZGlyOwoKCXBlID0geG1hbGxvYyhzaXplb2Yoc3RydWN0IHBlX2RhdGEpKTsKCW1lbXNldChwZSwwLHNpemVvZihzdHJ1Y3QgcGVfZGF0YSkpOwoJcGUtPnBlX2hlYWRlciA9IHhtYWxsb2Moc2l6ZW9mKHN0cnVjdCBwZV9oZWFkZXJfcykpOwoKCS8qIHJlYWQgUEUgaGVhZGVyICovCglsc2VlayggZmQsIG9mZnNldCwgU0VFS19TRVQpOwoJcmVhZCggZmQsIHBlLT5wZV9oZWFkZXIsIHNpemVvZihzdHJ1Y3QgcGVfaGVhZGVyX3MpKTsKCgkvKiByZWFkIHNlY3Rpb25zICovCglwZS0+cGVfc2VnID0geG1hbGxvYyhzaXplb2Yoc3RydWN0IHBlX3NlZ21lbnRfdGFibGUpICogCgkJCQkgICBwZS0+cGVfaGVhZGVyLT5jb2ZmLk51bWJlck9mU2VjdGlvbnMpOwoJcmVhZCggZmQsIHBlLT5wZV9zZWcsIHNpemVvZihzdHJ1Y3QgcGVfc2VnbWVudF90YWJsZSkgKiAKCQkJcGUtPnBlX2hlYWRlci0+Y29mZi5OdW1iZXJPZlNlY3Rpb25zKTsKCglsb2FkX2FkZHIgPSBwZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5CYXNlT2ZJbWFnZTsKCXBlLT5iYXNlX2FkZHI9bG9hZF9hZGRyOwoJcGUtPnZtYV9zaXplPTA7CglkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkxvYWQgYWRkciBpcyAleFxuIixsb2FkX2FkZHIpOwoJY2FsY192bWFfc2l6ZShwZSk7CgoJLyogV2UgdXNlIG1hbGxvYyBoZXJlLCB3aGlsZSBhIGh1Z2UgcGFydCBvZiB0aGF0IGFkZHJlc3Mgc3BhY2UgZG9lcwoJICAgbm90IGJlIHN1cHBvcnRlZCBieSBhY3R1YWwgbWVtb3J5LiBJdCBoYXMgdG8gYmUgY29udGlndW91cywgdGhvdWdoLgoJICAgSSBkb24ndCBrbm93IGlmIG1tYXAoIi9kZXYvbnVsbCIpOyB3b3VsZCBkbyBhbnkgYmV0dGVyLgoJICAgV2hhdCBJJ2QgcmVhbGx5IGxpa2UgdG8gZG8gaXMgYSBXaW4zMiBzdHlsZSBWaXJ0dWFsQWxsb2MvTWFwVmlld09mRmlsZQoJICAgc2VxdWVuY2UgKi8KCWxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHIgPSBtYWxsb2MocGUtPnZtYV9zaXplKTsKCWRwcmludGZfd2luMzIoc3RkZGViLCAiTG9hZCBhZGRyIGlzIHJlYWxseSAleCwgcmFuZ2UgJXhcbiIsCgkJcGUtPmxvYWRfYWRkciwgcGUtPnZtYV9zaXplKTsKCgoJZm9yKGk9MDsgaSA8IHBlLT5wZV9oZWFkZXItPmNvZmYuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQoJewoJCS8qIGxvYWQgb25seSBub24tQlNTIHNlZ21lbnRzICovCgkJaWYocGUtPnBlX3NlZ1tpXS5DaGFyYWN0ZXJpc3RpY3MgJiAKCQkJfiBJTUFHRV9TQ05fVFlQRV9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKQoJCWlmKGxzZWVrKGZkLHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmF3RGF0YSxTRUVLX1NFVCkgPT0gLTEKCQl8fCByZWFkKGZkLGxvYWRfYWRkciArIHBlLT5wZV9zZWdbaV0uVmlydHVhbF9BZGRyZXNzLAoJCQkJcGUtPnBlX3NlZ1tpXS5TaXplX09mX1Jhd19EYXRhKSAKCQkJCSE9IHBlLT5wZV9zZWdbaV0uU2l6ZV9PZl9SYXdfRGF0YSkKCQl7CgkJCWZwcmludGYoc3RkZXJyLCJGYWlsZWQgdG8gbG9hZCBzZWN0aW9uICV4XG4iLCBpKTsKCQkJZXhpdCgwKTsKCQl9CgkJcmVzdWx0ID0gbG9hZF9hZGRyICsgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX0FkZHJlc3M7CiNpZiAwCglpZighbG9hZF9hZGRyKSB7CgkJCgkJcmVzdWx0ID0gKGludCl4bW1hcCgoY2hhciAqKTAsIHBlLT5wZV9zZWdbaV0uVmlydHVhbF9TaXplLAoJCQlwZS0+cGVfc2VnW2ldLlNpemVfT2ZfUmF3X0RhdGEsIDcsCgkJCU1BUF9QUklWQVRFLCBmZCwgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SYXdEYXRhKTsKCQlsb2FkX2FkZHIgPSAodW5zaWduZWQgaW50KSByZXN1bHQgLSAgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX0FkZHJlc3M7Cgl9IGVsc2UgewoJCXJlc3VsdCA9IChpbnQpeG1tYXAoKGNoYXIgKikgbG9hZF9hZGRyICsgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX0FkZHJlc3MsIAoJCQkgIHBlLT5wZV9zZWdbaV0uVmlydHVhbF9TaXplLAoJCSAgICAgIHBlLT5wZV9zZWdbaV0uU2l6ZV9PZl9SYXdfRGF0YSwgNywgTUFQX1BSSVZBVEUgfCBNQVBfRklYRUQsIAoJCSAgICAgIGZkLCBwZS0+cGVfc2VnW2ldLlBvaW50ZXJUb1Jhd0RhdGEpOwoJfQoJaWYocmVzdWx0PT0tMSl7CgkJZnByaW50ZihzdGRlcnIsIkNvdWxkIG5vdCBsb2FkIHNlY3Rpb24gJXggdG8gZGVzaXJlZCBhZGRyZXNzICVseFxuIiwKCQkJaSwgbG9hZF9hZGRyK3BlLT5wZV9zZWdbaV0uVmlydHVhbF9BZGRyZXNzKTsKCQlmcHJpbnRmKHN0ZGVyciwiTmVlZCB0byBpbXBsZW1lbnQgcmVsb2NhdGlvbnMgbm93XG4iKTsKCQlleGl0KDApOwoJfQojZW5kaWYKCiAgICAgICAgaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5ic3MiKSA9PSAwKQogICAgICAgICAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAogICAgICAgICAgICAgICAgICAgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX1NpemUgPwogICAgICAgICAgICAgICAgICAgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsX1NpemUgOgogICAgICAgICAgICAgICAgICAgcGUtPnBlX3NlZ1tpXS5TaXplX09mX1Jhd19EYXRhKTsKCglpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmlkYXRhIikgPT0gMCkKCQlwZS0+cGVfaW1wb3J0ID0gKHN0cnVjdCBQRV9JbXBvcnRfRGlyZWN0b3J5ICopIHJlc3VsdDsKCglpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmVkYXRhIikgPT0gMCkKCQlwZS0+cGVfZXhwb3J0ID0gKHN0cnVjdCBQRV9FeHBvcnRfRGlyZWN0b3J5ICopIHJlc3VsdDsKCglpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLnJzcmMiKSA9PSAwKQoJICAgIHBlLT5wZV9yZXNvdXJjZSA9IChzdHJ1Y3QgUEVfUmVzb3VyY2VfRGlyZWN0b3J5ICopIHJlc3VsdDsKCglpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLnJlbG9jIikgPT0gMCkKCQlwZS0+cGVfcmVsb2MgPSAoc3RydWN0IFBFX1JlbG9jX0Jsb2NrICopIHJlc3VsdDsKCgl9CgoJLyogVGhlcmUgaXMgd29yZCB0aGF0IHRoZSBhY3R1YWwgbG9hZGVyIGRvZXMgbm90IGNhcmUgYWJvdXQgdGhlCgkgICBzZWN0aW9uIG5hbWVzLCBhbmQgb25seSBnb2VzIGZvciB0aGUgRGF0YURpcmVjdG9yeSAqLwoJZGlyPXBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9FWFBPUlRfRElSRUNUT1JZXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9leHBvcnQgJiYgCgkJCXBlLT5wZV9leHBvcnQhPWxvYWRfYWRkcitkaXIuVmlydHVhbF9hZGRyZXNzKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgZXhwb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQkvKiBhbHdheXMgdHJ1c3QgdGhlIGRpcmVjdG9yeSAqLwoJCXBlLT5wZV9leHBvcnQgPSBsb2FkX2FkZHIrZGlyLlZpcnR1YWxfYWRkcmVzczsKCX0KCglkaXI9cGUtPnBlX2hlYWRlci0+b3B0X2NvZmYuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX0lNUE9SVF9ESVJFQ1RPUlldOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGUtPnBlX2ltcG9ydCAmJiAKCQkJcGUtPnBlX2ltcG9ydCE9bG9hZF9hZGRyK2Rpci5WaXJ0dWFsX2FkZHJlc3MpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBpbXBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlLT5wZV9pbXBvcnQgPSBsb2FkX2FkZHIrZGlyLlZpcnR1YWxfYWRkcmVzczsKCX0KCglkaXI9cGUtPnBlX2hlYWRlci0+b3B0X2NvZmYuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1JFU09VUkNFX0RJUkVDVE9SWV07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfcmVzb3VyY2UgJiYgCgkJCXBlLT5wZV9yZXNvdXJjZSE9bG9hZF9hZGRyK2Rpci5WaXJ0dWFsX2FkZHJlc3MpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZXNvdXJjZSBkaXJlY3Rvcnk/P1xuIik7CgkJcGUtPnBlX3Jlc291cmNlID0gbG9hZF9hZGRyK2Rpci5WaXJ0dWFsX2FkZHJlc3M7Cgl9CgoJZGlyPXBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9CQVNFX1JFTE9DQVRJT05fVEFCTEVdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGUtPnBlX3JlbG9jICYmIAoJCQlwZS0+cGVfcmVsb2MhPWxvYWRfYWRkcitkaXIuVmlydHVhbF9hZGRyZXNzKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgcmVsb2NhdGlvbiBsaXN0Pz9cbiIpOwoJCXBlLT5wZV9yZWxvYyA9IGxvYWRfYWRkcitkaXIuVmlydHVhbF9hZGRyZXNzOwoJfQoKCWlmKHBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRklMRV9FWENFUFRJT05fRElSRUNUT1JZXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0ZJTEVfU0VDVVJJVFlfRElSRUNUT1JZXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRklMRV9ERUJVR19ESVJFQ1RPUlldLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJEZWJ1ZyBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+b3B0X2NvZmYuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9GSUxFX0RFU0NSSVBUSU9OX1NUUklOR10uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkRlc2NyaXB0aW9uIHN0cmluZyBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0ZJTEVfTUFDSElORV9WQUxVRV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIk1hY2hpbmUgVmFsdWUgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+b3B0X2NvZmYuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5TaXplKQoJCSBkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlRocmVhZCBsb2NhbCBzdG9yYWdlIGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRklMRV9DQUxMQkFDS19ESVJFQ1RPUlldLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJDYWxsYmFjayBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoKCWlmKHBlLT5wZV9pbXBvcnQpIGZpeHVwX2ltcG9ydHMocGUsIGhNb2R1bGUpOwoJaWYocGUtPnBlX2V4cG9ydCkgZHVtcF9leHBvcnRzKHBlLT5wZV9leHBvcnQsbG9hZF9hZGRyKTsKCWlmKHBlLT5wZV9yZWxvYykgZG9fcmVsb2NhdGlvbnMocGUpOwogICAgICAgIHJldHVybiBwZTsKfQoKSElOU1RBTkNFIE1PRFVMRV9DcmVhdGVJbnN0YW5jZShITU9EVUxFMTYgaE1vZHVsZSxMT0FEUEFSQU1TICpwYXJhbXMpOwp2b2lkIEluaXRUYXNrKCBTSUdDT05URVhUICpjb250ZXh0ICk7CgpISU5TVEFOQ0UgUEVfTG9hZE1vZHVsZSggaW50IGZkLCBPRlNUUlVDVCAqb2ZzLCBMT0FEUEFSQU1TKiBwYXJhbXMgKQp7CiAgICBITU9EVUxFMTYgaE1vZHVsZTsKICAgIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKICAgIFNFR1RBQkxFRU5UUlkgKnBTZWdtZW50OwogICAgRkFSUFJPQzE2IHN0YXJ0dXA7CiAgICBzdHJ1Y3QgbXpfaGVhZGVyX3MgbXpfaGVhZGVyOwoKICAgIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggb2ZzICkpIDwgMzIpIHJldHVybiBoTW9kdWxlOwogICAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUgKTsKICAgIHBNb2R1bGUtPmZsYWdzID0gTkVfRkZMQUdTX1dJTjMyOwoKICAgIGxzZWVrKCBmZCwgMCwgU0VFS19TRVQgKTsKICAgIHJlYWQoIGZkLCAmbXpfaGVhZGVyLCBzaXplb2YobXpfaGVhZGVyKSApOwoKICAgIC8qIFNldCB0aGUgc3RhcnR1cCBhZGRyZXNzICovCgogICAgc3RhcnR1cCA9IE1PRFVMRV9HZXRXbmRQcm9jRW50cnkxNigiV2luMzJDYWxsVG9TdGFydCIpOwogICAgcFNlZ21lbnQgPSBORV9TRUdfVEFCTEUocE1vZHVsZSkgKyBwTW9kdWxlLT5jcyAtIDE7CiAgICBwU2VnbWVudC0+c2VsZWN0b3IgPSBTRUxFQ1RPUk9GKHN0YXJ0dXApOyAvKiBGSVhNRSAqLwogICAgcE1vZHVsZS0+aXAgPSBPRkZTRVRPRihzdGFydHVwKTsKCiAgICBwTW9kdWxlLT5wZV9tb2R1bGUgPSBQRV9Mb2FkSW1hZ2UoIGZkLCBoTW9kdWxlLCBtel9oZWFkZXIubmVfb2Zmc2V0ICk7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlLCBwYXJhbXMgKTsKCiAgICBpZiAoIShwTW9kdWxlLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+Y29mZi5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgaW50IGZzOwogICAgICAgIFRBU0tfQ3JlYXRlVGFzayggaE1vZHVsZSwgaEluc3RhbmNlLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT5oRW52aXJvbm1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAoTFBTVFIpUFRSX1NFR19UT19MSU4oIHBhcmFtcy0+Y21kTGluZSApLAogICAgICAgICAgICAgICAgICAgICAgICAgKigoV09SRCopUFRSX1NFR19UT19MSU4ocGFyYW1zLT5zaG93Q21kKSArIDEpICk7CiAgICAgICAgZnM9KGludClHbG9iYWxBbGxvYzE2KCBHTUVNX0ZJWEVEIHwgR01FTV9aRVJPSU5JVCwgMHgxMDAwMCApOwogICAgICAgIFBFX0luaXRURUIoZnMpOwogICAgICAgIC8qIEZJWE1FOiB0aGlzIHNob3VsZCBiZSBkb25lIGluIHRoZSBjb250ZXh0IG9mIHRoZSBuZXcgdGFzayAqLwogICAgICAgIF9fYXNtX18gX192b2xhdGlsZV9fKCJtb3Z3ICV3MCwlJWZzIjo6InIiIChmcykpOwogICAgICAgIFBFX0luaXRpYWxpemVETExzKCBoTW9kdWxlICk7CiAgICB9CiAgICByZXR1cm4gaEluc3RhbmNlOwp9CgppbnQgVVNFUl9Jbml0QXBwKEhJTlNUQU5DRSBoSW5zdGFuY2UpOwp2b2lkIFBFX0luaXRURUIoaW50IGhURUIpOwoKdm9pZCBQRV9XaW4zMkNhbGxUb1N0YXJ0KCBTSUdDT05URVhUICpjb250ZXh0ICkKewogICAgSE1PRFVMRTE2IGhNb2R1bGU7CiAgICBORV9NT0RVTEUgKnBNb2R1bGU7CgogICAgZHByaW50Zl93aW4zMihzdGRkZWIsIkdvaW5nIHRvIHN0YXJ0IFdpbjMyIHByb2dyYW1cbiIpOwkKICAgIEluaXRUYXNrKCBjb250ZXh0ICk7CiAgICBoTW9kdWxlID0gR2V0RXhlUHRyKCBHZXRDdXJyZW50VGFzaygpICk7CiAgICBwTW9kdWxlID0gTU9EVUxFX0dldFB0ciggaE1vZHVsZSApOwogICAgVVNFUl9Jbml0QXBwKCBoTW9kdWxlICk7CiAgICBDYWxsVGFza1N0YXJ0MzIoIChGQVJQUk9DMzIpKHBNb2R1bGUtPnBlX21vZHVsZS0+bG9hZF9hZGRyICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTW9kdWxlLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+b3B0X2NvZmYuQWRkcmVzc09mRW50cnlQb2ludCkgKTsKfQoKaW50IFBFX1VubG9hZEltYWdlKCBITU9EVUxFMTYgaE1vZHVsZSApCnsKCXByaW50ZigiUEV1bmxvYWRJbWFnZSgpIGNhbGxlZCFcbiIpOwoJLyogZnJlZSByZXNvdXJjZXMsIGltYWdlLCB1bm1hcCAqLwoJcmV0dXJuIDE7Cn0KCnN0YXRpYyB2b2lkIFBFX0luaXRETEwoSE1PRFVMRTE2IGhNb2R1bGUpCnsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKICAgIFBFX01PRFVMRSAqcGU7CgogICAgaE1vZHVsZSA9IEdldEV4ZVB0cihoTW9kdWxlKTsKICAgIGlmICghKHBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKGhNb2R1bGUpKSkgcmV0dXJuOwogICAgaWYgKCEocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfV0lOMzIpIHx8ICEocGUgPSBwTW9kdWxlLT5wZV9tb2R1bGUpKQogICAgICAgIHJldHVybjsKCiAgICAvKiBGSVhNRTogV2hhdCBhcmUgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBwYXJhbWV0ZXJzIDIgYW5kIDM/ICovCiAgICAgICAgCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gKi8KICAgIGlmIChwZS0+cGVfaGVhZGVyLT5jb2ZmLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKQogICAgewogICAgICAgIHByaW50ZigiSW5pdFBFRExMKCkgY2FsbGVkIVxuIik7CiAgICAgICAgQ2FsbERMTEVudHJ5UHJvYzMyKCAoRkFSUFJPQzMyKShwZS0+bG9hZF9hZGRyICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZS0+cGVfaGVhZGVyLT5vcHRfY29mZi5BZGRyZXNzT2ZFbnRyeVBvaW50KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhNb2R1bGUsIDAsIDAgKTsKICAgIH0KfQoKCi8qIEZJWE1FOiBUaGlzIHN0dWZmIGlzIGFsbCBvbiBhICJ3ZWxsIGl0IHdvcmtzIiBiYXNpcy4gQW4gaW1wbGVtZW50YXRpb24KYmFzZWQgb24gc29tZSBraW5kIG9mIGRvY3VtZW50YXRpb24gd291bGQgYmUgZ3JlYXRseSBhcHByZWNpYXRlZCA6LSkgKi8KCnR5cGVkZWYgc3RydWN0CnsKICAgIHZvaWQgICAgICAgICpFeGNlcHQ7CiAgICB2b2lkICAgICAgICAqc3RhY2s7CiAgICBpbnQJICAgICAgICBkdW1teTFbNF07CiAgICBzdHJ1Y3QgVEVCICAqVEVCRFNBbGlhczsKICAgIGludAkgICAgICAgIGR1bW15MlsyXTsKICAgIGludAkgICAgICAgIHRhc2tpZDsKfSBURUI7Cgp2b2lkIFBFX0luaXRURUIoaW50IGhURUIpCnsKICAgIFREQiAqcFRhc2s7CiAgICBURUIgKnBURUI7CgogICAgcFRhc2sgPSAoVERCICopKEdsb2JhbExvY2sxNihHZXRDdXJyZW50VGFzaygpICYgMHhmZmZmKSk7CiAgICBwVEVCID0gKFRFQiAqKShQVFJfU0VHX09GRl9UT19MSU4oaFRFQiwgMCkpOwogICAgcFRFQi0+c3RhY2sgPSAodm9pZCAqKShHbG9iYWxMb2NrMTYocFRhc2stPmhTdGFjazMyKSk7CiAgICBwVEVCLT5FeGNlcHQgPSAodm9pZCAqKSgtMSk7IAogICAgcFRFQi0+VEVCRFNBbGlhcyA9IHBURUI7CiAgICBwVEVCLT50YXNraWQgPSBnZXRwaWQoKTsKfQoKdm9pZCBQRV9Jbml0aWFsaXplRExMcyhITU9EVUxFMTYgaE1vZHVsZSkKewoJTkVfTU9EVUxFICpwTW9kdWxlOwoJSE1PRFVMRTE2ICpwRExMOwoJcE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoIEdldEV4ZVB0cihoTW9kdWxlKSApOwoJaWYgKHBNb2R1bGUtPmRsbHNfdG9faW5pdCkKCXsKCQlIQU5ETEUgdG9faW5pdCA9IHBNb2R1bGUtPmRsbHNfdG9faW5pdDsKCQlwTW9kdWxlLT5kbGxzX3RvX2luaXQgPSAwOwoJCWZvciAocERMTCA9IChITU9EVUxFMTYgKilHbG9iYWxMb2NrMTYoIHRvX2luaXQgKTsgKnBETEw7IHBETEwrKykKCQl7CgkJCVBFX0luaXRpYWxpemVETExzKCAqcERMTCApOwoJCQlQRV9Jbml0RExMKCAqcERMTCApOwoJCX0KCQlHbG9iYWxGcmVlMTYoIHRvX2luaXQgKTsKCX0KCVBFX0luaXRETEwoIGhNb2R1bGUgKTsKfQojZW5kaWYgLyogV0lORUxJQiAqLwo=