I2lmbmRlZiBXSU5FTElCCi8qIAogKiAgQ29weXJpZ2h0CTE5OTQJRXJpYyBZb3VuZGFsZSAmIEVyaWsgQm9zCiAqICBDb3B5cmlnaHQJMTk5NQlNYXJ0aW4gdm9uIEz2d2lzCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwZV9pbWFnZS5oIgojaW5jbHVkZSAicmVsYXkzMi5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJhbGlhcy5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJsZHQuaCIKI2luY2x1ZGUgInJlZ2lzdGVycy5oIgojaW5jbHVkZSAic3RkZGVidWcuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCgp2b2lkIG15X3djc3RvbWJzKGNoYXIgKiByZXN1bHQsIHVfc2hvcnQgKiBzb3VyY2UsIGludCBsZW4pCnsKICB3aGlsZShsZW4tLSkgewogICAgLyogdGhpcyB1c2VkIHRvIGJlIGlzYXNjaWksIGJ1dCBzZWUgaXNhc2NpaSBpbXBsZW1lbnRhdGlvbiBpbiBMaW51eCcKCSAgIGN0eXBlLmggKi8KICAgIGlmKCpzb3VyY2U8MjU1KSAqcmVzdWx0KysgPSAqc291cmNlKys7CiAgICBlbHNlIHsKICAgICAgcHJpbnRmKCJVbmFibGUgdG8gaGFuZGxlIHVuaWNvZGUgcmlnaHQgbm93XG4iKTsKICAgICAgZXhpdCgwKTsKICAgIH0KICB9Owp9CgojaWYgMApjaGFyICogeG1tYXAoY2hhciAqIHZhZGRyLCB1bnNpZ25lZCBpbnQgdl9zaXplLCB1bnNpZ25lZCBpbnQgcl9zaXplLAoJaW50IHByb3QsIGludCBmbGFncywgaW50IGZkLCB1bnNpZ25lZCBpbnQgZmlsZV9vZmZzZXQpCnsKICBjaGFyICogcmVzdWx0OwogIC8qIC5ic3MgaGFzIG5vIGFzc29jaWF0ZWQgc3RvcmFnZSBpbiB0aGUgUEUgZmlsZSAqLwogIGlmKHJfc2l6ZSkKICAgIHZfc2l6ZT1yX3NpemU7CiAgZWxzZQojaWYgZGVmaW5lZChfX3N2cjRfXykgfHwgZGVmaW5lZChfU0NPX0RTKQogICAgZnByaW50ZihzdGRlcnIsInhtbWFwOiAlcyBsaW5lICVkIGRvZXNuJ3Qgc3VwcG9ydCBNQVBfQU5PTlxuIixfX0ZJTEVfXywgX19MSU5FX18pOwojZWxzZQogICAgZmxhZ3MgfD0gTUFQX0FOT047CiNlbmRpZgogIHJlc3VsdCA9IG1tYXAodmFkZHIsIHZfc2l6ZSwgcHJvdCwgZmxhZ3MsIGZkLCBmaWxlX29mZnNldCk7CiAgaWYoKHVuc2lnbmVkIGludCkgcmVzdWx0ICE9IDB4ZmZmZmZmZmYpIHJldHVybiByZXN1bHQ7CgogIC8qIFNpZ2guICBBbGlnbm1lbnQgbXVzdCBiZSB3cm9uZyBmb3IgbW1hcC4gIERvIHRoaXMgdGhlIGhhcmQgd2F5LiAqLwogIGlmKCEoZmxhZ3MgJiBNQVBfRklYRUQpKSB7CiAgICB2YWRkciA9IChjaGFyICopMHg0MDAwMDAwMDsKICAgIGZsYWdzIHw9IE1BUF9GSVhFRDsKICB9OwoKICBtbWFwKHZhZGRyLCB2X3NpemUsIHByb3QsIE1BUF9BTk9OWU1PVVMgfCBmbGFncywgMCwgMCk7CiAgbHNlZWsoZmQsIGZpbGVfb2Zmc2V0LCBTRUVLX1NFVCk7CiAgcmVhZChmZCwgdmFkZHIsIHZfc2l6ZSk7CiAgcmV0dXJuIHZhZGRyOwp9OwojZW5kaWYKCnZvaWQgZHVtcF9leHBvcnRzKHN0cnVjdCBQRV9FeHBvcnRfRGlyZWN0b3J5ICogcGVfZXhwb3J0cywgdW5zaWduZWQgaW50IGxvYWRfYWRkcikKeyAKICBjaGFyICogTW9kdWxlOwogIGludCBpOwogIHVfc2hvcnQgKiBvcmRpbmFsOwogIHVfbG9uZyAqIGZ1bmN0aW9uOwogIHVfY2hhciAqKiBuYW1lLCAqZW5hbWU7CgogIE1vZHVsZSA9ICgoY2hhciAqKSBsb2FkX2FkZHIpICsgcGVfZXhwb3J0cy0+TmFtZTsKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiXG4qKioqKioqRVhQT1JUIERBVEEqKioqKioqXG5Nb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKCSBNb2R1bGUsCgkgcGVfZXhwb3J0cy0+TnVtYmVyX09mX0Z1bmN0aW9ucywKCSBwZV9leHBvcnRzLT5OdW1iZXJfT2ZfTmFtZXMpOwoKICBvcmRpbmFsID0gKHVfc2hvcnQgKikgKCgoY2hhciAqKSBsb2FkX2FkZHIpICsgKGludCkgcGVfZXhwb3J0cy0+QWRkcmVzc19PZl9OYW1lX09yZGluYWxzKTsKICBmdW5jdGlvbiA9ICh1X2xvbmcgKikgICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZSA9ICh1X2NoYXIgKiopICAoKChjaGFyICopIGxvYWRfYWRkcikgKyAoaW50KSBwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyBPcmRpbmFsIFZpcnQgQWRkclxuIiwgIkZ1bmN0aW9uIE5hbWUiKTsKICBmb3IoaT0wOyBpPCBwZV9leHBvcnRzLT5OdW1iZXJfT2ZfRnVuY3Rpb25zOyBpKyspCiAgICB7CiAgICAgIGVuYW1lID0gIChjaGFyICopICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpICpuYW1lKyspOwogICAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiJS0zMnMgJTRkICAgICU4LjhseFxuIiwgZW5hbWUsICpvcmRpbmFsKyssICpmdW5jdGlvbisrKTsKICAgIH0KfQoKc3RhdGljIERXT1JEIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKHN0cnVjdCBwZV9kYXRhICpwZSwgY2hhciogZnVuY05hbWUpCnsKCXN0cnVjdCBQRV9FeHBvcnRfRGlyZWN0b3J5ICogZXhwb3J0cyA9IHBlLT5wZV9leHBvcnQ7Cgl1bnNpZ25lZCBsb2FkX2FkZHIgPSBwZS0+bG9hZF9hZGRyOwoJdV9zaG9ydCAqIG9yZGluYWw7Cgl1X2xvbmcgKiBmdW5jdGlvbjsKCXVfY2hhciAqKiBuYW1lLCAqZW5hbWU7CglpbnQgaTsKCWlmKCFleHBvcnRzKXJldHVybiAwOwoJb3JkaW5hbCA9ICh1X3Nob3J0ICopICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIGV4cG9ydHMtPkFkZHJlc3NfT2ZfTmFtZV9PcmRpbmFscyk7CglmdW5jdGlvbiA9ICh1X2xvbmcgKikgICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lID0gKHVfY2hhciAqKikgICgoKGNoYXIgKikgbG9hZF9hZGRyKSArIChpbnQpIGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcihpPTA7IGk8ZXhwb3J0cy0+TnVtYmVyX09mX0Z1bmN0aW9uczsgaSsrKQoJewoJCWlmKEhJV09SRChmdW5jTmFtZSkpCgkJewoJCQllbmFtZSA9ICAoY2hhciAqKSAoKChjaGFyICopIGxvYWRfYWRkcikgKyAoaW50KSAqbmFtZSk7CgkJCWlmKHN0cmNtcChlbmFtZSxmdW5jTmFtZSk9PTApCgkJCQlyZXR1cm4gbG9hZF9hZGRyKypmdW5jdGlvbjsKCQl9ZWxzZXsKCQkJaWYoZnVuY05hbWUgPT0gKGludCkqb3JkaW5hbCArIGV4cG9ydHMtPkJhc2UpCgkJCQlyZXR1cm4gbG9hZF9hZGRyKypmdW5jdGlvbjsKCQl9CgkJZnVuY3Rpb24rKzsKCQlvcmRpbmFsKys7CgkJbmFtZSsrOwoJfQoJcmV0dXJuIDA7Cn0KCkRXT1JEIFBFX0dldFByb2NBZGRyZXNzKEhNT0RVTEUgaE1vZHVsZSwgY2hhciogZnVuY3Rpb24pCnsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKCiAgICBpZiAoIShwTW9kdWxlID0gTU9EVUxFX0dldFB0ciggaE1vZHVsZSApKSkgcmV0dXJuIDA7CiAgICBpZiAoIShwTW9kdWxlLT5mbGFncyAmIE5FX0ZGTEFHU19XSU4zMikgfHwgIXBNb2R1bGUtPnBlX21vZHVsZSkgcmV0dXJuIDA7CiAgICBpZiAocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfQlVJTFRJTikKICAgICAgICByZXR1cm4gQlVJTFRJTl9HZXRQcm9jQWRkcmVzczMyKCBwTW9kdWxlLCBmdW5jdGlvbiApOwogICAgcmV0dXJuIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCBwTW9kdWxlLT5wZV9tb2R1bGUsIGZ1bmN0aW9uICk7Cn0KCnZvaWQgZml4dXBfaW1wb3J0cyhzdHJ1Y3QgcGVfZGF0YSAqcGUsIEhNT0RVTEUgaE1vZHVsZSkKeyAKICBzdHJ1Y3QgUEVfSW1wb3J0X0RpcmVjdG9yeSAqIHBlX2ltcDsKICBpbnQgZml4dXBfZmFpbGVkPTA7CiAgdW5zaWduZWQgaW50IGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7CiAgaW50IGk7CiAgTkVfTU9EVUxFICpuZV9tb2Q7CiAgSE1PRFVMRSAqbW9kX3B0cjsKCiAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgZHByaW50Zl93aW4zMihzdGRkZWIsICJcbkR1bXBpbmcgaW1wb3J0cyBsaXN0XG4iKTsKCiAgLyogZmlyc3QsIGNvdW50IHRoZSBudW1iZXIgb2YgaW1wb3J0ZWQgbm9uLWludGVybmFsIG1vZHVsZXMgKi8KICBwZV9pbXAgPSBwZS0+cGVfaW1wb3J0OwogIGZvcihpPTA7cGVfaW1wLT5Nb2R1bGVOYW1lO3BlX2ltcCsrKQogIAlpKys7CgogIC8qIE5vdywgYWxsb2NhdGUgbWVtb3J5IGZvciBkbGxzX3RvX2luaXQgKi8KICBuZV9tb2QgPSBHbG9iYWxMb2NrMTYoaE1vZHVsZSk7CiAgbmVfbW9kLT5kbGxzX3RvX2luaXQgPSBHTE9CQUxfQWxsb2MoR01FTV9aRVJPSU5JVCwoaSsxKSAqIHNpemVvZihITU9EVUxFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoTW9kdWxlLCBGQUxTRSwgRkFMU0UsIEZBTFNFICk7CiAgbW9kX3B0ciA9IEdsb2JhbExvY2sxNihuZV9tb2QtPmRsbHNfdG9faW5pdCk7CiAgLyogbG9hZCB0aGUgbW9kdWxlcyBhbmQgcHV0IHRoZWlyIGhhbmRsZXMgaW50byB0aGUgbGlzdCAqLwogIGZvcihpPTAscGVfaW1wID0gcGUtPnBlX2ltcG9ydDtwZV9pbXAtPk1vZHVsZU5hbWU7cGVfaW1wKyspCiAgewogIAljaGFyICpuYW1lID0gKGNoYXIqKWxvYWRfYWRkcitwZV9pbXAtPk1vZHVsZU5hbWU7Cgltb2RfcHRyW2ldID0gTG9hZE1vZHVsZShuYW1lLChMUFZPSUQpLTEpOwoJaWYobW9kX3B0cltpXTw9KEhNT0RVTEUpMzIpCgl7CgkJZnByaW50ZihzdGRlcnIsIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsbmFtZSk7CgkJZXhpdCgwKTsKCX0KCWkrKzsKICB9CiAgcGVfaW1wID0gcGUtPnBlX2ltcG9ydDsKICB3aGlsZSAocGVfaW1wLT5Nb2R1bGVOYW1lKQogICAgewogICAgICBjaGFyICogTW9kdWxlOwogICAgICBzdHJ1Y3QgcGVfaW1wb3J0X25hbWUgKiBwZV9uYW1lOwogICAgICB1bnNpZ25lZCBpbnQgKiBpbXBvcnRfbGlzdCwgKnRodW5rX2xpc3Q7CgogICAgICBNb2R1bGUgPSAoKGNoYXIgKikgbG9hZF9hZGRyKSArIHBlX2ltcC0+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+cGVfcmVsb2MpIGRvX3JlbG9jYXRpb25zKHBlKTsKICAgICAgICByZXR1cm4gcGU7Cn0KCkhJTlNUQU5DRSBNT0RVTEVfQ3JlYXRlSW5zdGFuY2UoSE1PRFVMRSBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CnZvaWQgSW5pdFRhc2soc3RydWN0IHNpZ2NvbnRleHRfc3RydWN0IGNvbnRleHQpOwoKSElOU1RBTkNFIFBFX0xvYWRNb2R1bGUoIGludCBmZCwgT0ZTVFJVQ1QgKm9mcywgTE9BRFBBUkFNUyogcGFyYW1zICkKewogICAgICAgIFBFX01PRFVMRSAqcGU7CglpbnQgc2l6ZSwgb2Zfc2l6ZTsKCU5FX01PRFVMRSAqcE1vZHVsZTsKCVNFR1RBQkxFRU5UUlkgKnBTZWdtZW50OwoJY2hhciAqcFN0cjsKCURXT1JEIGN0czsKCUhNT0RVTEUgaE1vZHVsZTsKCUhJTlNUQU5DRSBoSW5zdGFuY2U7CiAgICAgICAgc3RydWN0IG16X2hlYWRlcl9zIG16X2hlYWRlcjsKCglBTElBU19Vc2VBbGlhc2VzPTE7CgoJbHNlZWsoZmQsMCxTRUVLX1NFVCk7CglyZWFkKCBmZCwgJm16X2hlYWRlciwgc2l6ZW9mKG16X2hlYWRlcikgKTsKCiAgICAgICAgb2Zfc2l6ZSA9IHNpemVvZihPRlNUUlVDVCkgLSBzaXplb2Yob2ZzLT5zelBhdGhOYW1lKQogICAgICAgICAgICAgICAgICArIHN0cmxlbihvZnMtPnN6UGF0aE5hbWUpICsgMTsKCXNpemUgPSBzaXplb2YoTkVfTU9EVUxFKSArCiAgICAgICAgICAgICAgIC8qIGxvYWRlZCBmaWxlIGluZm8gKi8KICAgICAgICAgICAgICAgb2Zfc2l6ZSArCiAgICAgICAgICAgICAgIC8qIHNlZ21lbnQgdGFibGU6IERTLENTICovCiAgICAgICAgICAgICAgIDIgKiBzaXplb2YoU0VHVEFCTEVFTlRSWSkgKwogICAgICAgICAgICAgICAvKiBuYW1lIHRhYmxlICovCiAgICAgICAgICAgICAgIDkgKwogICAgICAgICAgICAgICAvKiBzZXZlcmFsIGVtcHR5IHRhYmxlcyAqLwogICAgICAgICAgICAgICA4OwoKCWhNb2R1bGUgPSBHbG9iYWxBbGxvYzE2KCBHTUVNX01PVkVBQkxFIHwgR01FTV9aRVJPSU5JVCwgc2l6ZSApOwoJaWYgKCFoTW9kdWxlKSByZXR1cm4gKEhJTlNUQU5DRSkxMTsgIC8qIGludmFsaWQgZXhlICovCgoJRmFyU2V0T3duZXIoIGhNb2R1bGUsIGhNb2R1bGUgKTsKCQoJcE1vZHVsZSA9IChORV9NT0RVTEUqKUdsb2JhbExvY2sxNihoTW9kdWxlKTsKCgkvKiBTZXQgYWxsIHVzZWQgZW50cmllcyAqLwoJcE1vZHVsZS0+bWFnaWM9TkVfU0lHTkFUVVJFOwoJcE1vZHVsZS0+Y291bnQ9MTsKCXBNb2R1bGUtPm5leHQ9MDsKCXBNb2R1bGUtPmZsYWdzPU5FX0ZGTEFHU19XSU4zMjsKCXBNb2R1bGUtPmRncm91cD0xOwoJcE1vZHVsZS0+c3M9MTsKCXBNb2R1bGUtPmNzPTI7CgkvKiBXaG8gd2FudHMgdG8gTG9jYWxBbGxvYyBmb3IgYSBQRSBNb2R1bGU/ICovCglwTW9kdWxlLT5oZWFwX3NpemU9MHgxMDAwOwoJcE1vZHVsZS0+c3RhY2tfc2l6ZT0weEYwMDA7CglwTW9kdWxlLT5zZWdfY291bnQ9MTsKCXBNb2R1bGUtPm1vZHJlZl9jb3VudD0wOwoJcE1vZHVsZS0+bnJuYW1lX3NpemU9MDsKCXBNb2R1bGUtPmZpbGVpbmZvPXNpemVvZihORV9NT0RVTEUpOwoJcE1vZHVsZS0+b3NfZmxhZ3M9TkVfT1NGTEFHU19XSU5ET1dTOwoJcE1vZHVsZS0+ZXhwZWN0ZWRfdmVyc2lvbj0weDMwQTsKICAgICAgICBwTW9kdWxlLT5zZWxmID0gaE1vZHVsZTsKCiAgICAgICAgLyogU2V0IGxvYWRlZCBmaWxlIGluZm9ybWF0aW9uICovCiAgICAgICAgbWVtY3B5KCBwTW9kdWxlICsgMSwgb2ZzLCBvZl9zaXplICk7CiAgICAgICAgKChPRlNUUlVDVCAqKShwTW9kdWxlKzEpKS0+Y0J5dGVzID0gb2Zfc2l6ZSAtIDE7CgoJcFNlZ21lbnQ9KFNFR1RBQkxFRU5UUlkqKSgoY2hhciopKHBNb2R1bGUgKyAxKSArIG9mX3NpemUpOwoJcE1vZHVsZS0+c2VnX3RhYmxlPXBNb2R1bGUtPmRncm91cF9lbnRyeT0oaW50KXBTZWdtZW50LShpbnQpcE1vZHVsZTsKCXBTZWdtZW50LT5zaXplPTA7CglwU2VnbWVudC0+ZmxhZ3M9TkVfU0VHRkxBR1NfREFUQTsKCXBTZWdtZW50LT5taW5zaXplPTB4MTAwMDsKCXBTZWdtZW50Kys7CgoJY3RzPShEV09SRClNT0RVTEVfR2V0V25kUHJvY0VudHJ5MTYoIldpbjMyQ2FsbFRvU3RhcnQiKTsKI2lmZGVmIFdJTkVMSUIzMgoJcFNlZ21lbnQtPnNlbGVjdG9yPSh2b2lkKiljdHM7CglwTW9kdWxlLT5pcD0wOwojZWxzZQoJcFNlZ21lbnQtPnNlbGVjdG9yPWN0cz4+MTY7CglwTW9kdWxlLT5pcD1jdHMgJiAweEZGRkY7CiNlbmRpZgoJcFNlZ21lbnQrKzsKCglwU3RyPShjaGFyKilwU2VnbWVudDsKCXBNb2R1bGUtPm5hbWVfdGFibGU9KGludClwU3RyLShpbnQpcE1vZHVsZTsKCXN0cmNweShwU3RyLCJceDA4VzMyU1hYWFgiKTsKCXBTdHIrPTk7CgoJLyogQWxsIHRhYmxlcyB6ZXJvIHRlcm1pbmF0ZWQgKi8KCXBNb2R1bGUtPnJlc190YWJsZT1wTW9kdWxlLT5pbXBvcnRfdGFibGU9cE1vZHVsZS0+ZW50cnlfdGFibGU9CgkJKGludClwU3RyLShpbnQpcE1vZHVsZTsKCiAgICAgICAgTU9EVUxFX1JlZ2lzdGVyTW9kdWxlKCBwTW9kdWxlICk7CgoJcGUgPSBQRV9Mb2FkSW1hZ2UoIGZkLCBoTW9kdWxlLCBtel9oZWFkZXIubmVfb2Zmc2V0ICk7CgogICAgICAgIHBNb2R1bGUtPnBlX21vZHVsZSA9IHBlOwoJcE1vZHVsZS0+aGVhcF9zaXplPTB4MTAwMDsKCXBNb2R1bGUtPnN0YWNrX3NpemU9MHhFMDAwOwoKCS8qIENyZWF0ZUluc3RhbmNlIGFsbG9jYXRlcyBub3cgNjRLQiAqLwoJaEluc3RhbmNlPU1PRFVMRV9DcmVhdGVJbnN0YW5jZShoTW9kdWxlLE5VTEwgLyogRklYOiBOVUxMPyByZWFsbHk/ICovKTsKCiAgICAgICAgLyogRklYTUU6IElzIHRoaXMgcmVhbGx5IHRoZSBjb3JyZWN0IHBsYWNlIHRvIGluaXRpYWxpc2UgdGhlIERMTD8gKi8KCWlmICgocGUtPnBlX2hlYWRlci0+Y29mZi5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpIHsKLyogICAgICAgICAgICBQRV9Jbml0RExMKGhNb2R1bGUpOyAqLwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRBU0tfQ3JlYXRlVGFzayhoTW9kdWxlLGhJbnN0YW5jZSwwLAoJCXBhcmFtcy0+aEVudmlyb25tZW50LChMUFNUUilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPmNtZExpbmUpLAoJCSooKFdPUkQqKVBUUl9TRUdfVE9fTElOKHBhcmFtcy0+c2hvd0NtZCkrMSkpOwogICAgICAgICAgICBQRV9Jbml0aWFsaXplRExMcyhoTW9kdWxlKTsKCX0KCXJldHVybiBoSW5zdGFuY2U7Cn0KCmludCBVU0VSX0luaXRBcHAoSElOU1RBTkNFIGhJbnN0YW5jZSk7CnZvaWQgUEVfSW5pdFRFQihpbnQgaFRFQik7Cgp2b2lkIFBFX1dpbjMyQ2FsbFRvU3RhcnQoc3RydWN0IHNpZ2NvbnRleHRfc3RydWN0IGNvbnRleHQpCnsKICAgIGludCBmczsKICAgIEhNT0RVTEUgaE1vZHVsZTsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKCiAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiR29pbmcgdG8gc3RhcnQgV2luMzIgcHJvZ3JhbVxuIik7CQogICAgSW5pdFRhc2soY29udGV4dCk7CiAgICBoTW9kdWxlID0gR2V0RXhlUHRyKCBHZXRDdXJyZW50VGFzaygpICk7CiAgICBwTW9kdWxlID0gTU9EVUxFX0dldFB0ciggaE1vZHVsZSApOwogICAgVVNFUl9Jbml0QXBwKCBoTW9kdWxlICk7CiAgICBmcz0oaW50KUdsb2JhbEFsbG9jMTYoR0hORCwweDEwMDAwKTsKICAgIFBFX0luaXRURUIoZnMpOwogICAgX19hc21fXyBfX3ZvbGF0aWxlX18oIm1vdncgJXcwLCUlZnMiOjoiciIgKGZzKSk7CiAgICBDYWxsVGFza1N0YXJ0MzIoIChGQVJQUk9DKShwTW9kdWxlLT5wZV9tb2R1bGUtPmxvYWRfYWRkciArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1vZHVsZS0+cGVfbW9kdWxlLT5wZV9oZWFkZXItPm9wdF9jb2ZmLkFkZHJlc3NPZkVudHJ5UG9pbnQpICk7Cn0KCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRSBoTW9kdWxlICkKewoJcHJpbnRmKCJQRXVubG9hZEltYWdlKCkgY2FsbGVkIVxuIik7CgkvKiBmcmVlIHJlc291cmNlcywgaW1hZ2UsIHVubWFwICovCglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQgUEVfSW5pdERMTChITU9EVUxFIGhNb2R1bGUpCnsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKICAgIFBFX01PRFVMRSAqcGU7CgogICAgaE1vZHVsZSA9IEdldEV4ZVB0cihoTW9kdWxlKTsKICAgIGlmICghKHBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKGhNb2R1bGUpKSkgcmV0dXJuOwogICAgaWYgKCEocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfV0lOMzIpIHx8ICEocGUgPSBwTW9kdWxlLT5wZV9tb2R1bGUpKQogICAgICAgIHJldHVybjsKCiAgICAvKiBGSVhNRTogV2hhdCBhcmUgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBwYXJhbWV0ZXJzIDIgYW5kIDM/ICovCiAgICAgICAgCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gKi8KICAgIGlmIChwZS0+cGVfaGVhZGVyLT5jb2ZmLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKQogICAgewogICAgICAgIHByaW50ZigiSW5pdFBFRExMKCkgY2FsbGVkIVxuIik7CiAgICAgICAgQ2FsbERMTEVudHJ5UHJvYzMyKCAoRkFSUFJPQykocGUtPmxvYWRfYWRkciArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGUtPnBlX2hlYWRlci0+b3B0X2NvZmYuQWRkcmVzc09mRW50cnlQb2ludCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoTW9kdWxlLCAwLCAwICk7CiAgICB9Cn0KCgovKiBGSVhNRTogVGhpcyBzdHVmZiBpcyBhbGwgb24gYSAid2VsbCBpdCB3b3JrcyIgYmFzaXMuIEFuIGltcGxlbWVudGF0aW9uCmJhc2VkIG9uIHNvbWUga2luZCBvZiBkb2N1bWVudGF0aW9uIHdvdWxkIGJlIGdyZWF0bHkgYXBwcmVjaWF0ZWQgOi0pICovCgp0eXBlZGVmIHN0cnVjdAp7CiAgICB2b2lkICAgICAgICAqRXhjZXB0OwogICAgdm9pZCAgICAgICAgKnN0YWNrOwogICAgaW50CSAgICAgICAgZHVtbXkxWzRdOwogICAgc3RydWN0IFRFQiAgKlRFQkRTQWxpYXM7CiAgICBpbnQJICAgICAgICBkdW1teTJbMl07CiAgICBpbnQJICAgICAgICB0YXNraWQ7Cn0gVEVCOwoKdm9pZCBQRV9Jbml0VEVCKGludCBoVEVCKQp7CiAgICBUREIgKnBUYXNrOwogICAgVEVCICpwVEVCOwoKICAgIHBUYXNrID0gKFREQiAqKShHbG9iYWxMb2NrMTYoR2V0Q3VycmVudFRhc2soKSAmIDB4ZmZmZikpOwogICAgcFRFQiA9IChURUIgKikoUFRSX1NFR19PRkZfVE9fTElOKGhURUIsIDApKTsKICAgIHBURUItPnN0YWNrID0gKHZvaWQgKikoR2xvYmFsTG9jazE2KHBUYXNrLT5oU3RhY2szMikpOwogICAgcFRFQi0+RXhjZXB0ID0gKHZvaWQgKikoLTEpOyAKICAgIHBURUItPlRFQkRTQWxpYXMgPSBwVEVCOwogICAgcFRFQi0+dGFza2lkID0gZ2V0cGlkKCk7Cn0KCnZvaWQgUEVfSW5pdGlhbGl6ZURMTHMoSE1PRFVMRSBoTW9kdWxlKQp7CglORV9NT0RVTEUgKnBNb2R1bGU7CglITU9EVUxFICpwRExMOwoJcE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoIEdldEV4ZVB0cihoTW9kdWxlKSApOwoJaWYgKHBNb2R1bGUtPmRsbHNfdG9faW5pdCkKCXsKCQlIQU5ETEUgdG9faW5pdCA9IHBNb2R1bGUtPmRsbHNfdG9faW5pdDsKCQlwTW9kdWxlLT5kbGxzX3RvX2luaXQgPSAwOwoJCWZvciAocERMTCA9IChITU9EVUxFICopR2xvYmFsTG9jazE2KCB0b19pbml0ICk7ICpwRExMOyBwRExMKyspCgkJewoJCQlQRV9Jbml0aWFsaXplRExMcyggKnBETEwgKTsKCQkJUEVfSW5pdERMTCggKnBETEwgKTsKCQl9CgkJR2xvYmFsRnJlZTE2KCB0b19pbml0ICk7Cgl9CglQRV9Jbml0RExMKCBoTW9kdWxlICk7Cn0KI2VuZGlmIC8qIFdJTkVMSUIgKi8K