I2lmbmRlZiBXSU5FTElCCi8qIAogKiAgQ29weXJpZ2h0CTE5OTQJRXJpYyBZb3VuZGFsZSAmIEVyaWsgQm9zCiAqICBDb3B5cmlnaHQJMTk5NQlNYXJ0aW4gdm9uIEz2d2lzCiAqICBDb3B5cmlnaHQgICAxOTk2ICAgIE1hcmN1cyBNZWlzc25lcgogKgogKgliYXNlZCBvbiBFcmljIFlvdW5kYWxlJ3MgcGUtdGVzdCBhbmQ6CiAqCiAqCWZ0cC5taWNyb3NvZnQuY29tOi9wdWIvZGV2ZWxvcGVyL01TRE4vQ0Q4L1BFRklMRS5aSVAKICogbWFrZSB0aGF0OgogKglmdHAubWljcm9zb2Z0LmNvbTovZGV2ZWxvcHIvTVNETi9PY3RDRC9QRUZJTEUuWklQCiAqLwoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwZV9pbWFnZS5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJnbG9iYWwuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAic3RkZGVidWcuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJkZWJ1Z2dlci5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgoKc3RhdGljIHZvaWQgUEVfSW5pdERMTChITU9EVUxFMTYgaE1vZHVsZSwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQpOwoKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodW5zaWduZWQgaW50KWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkKCnZvaWQgZHVtcF9leHBvcnRzKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKiBwZV9leHBvcnRzLCB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyKQp7IAogIGNoYXIJCSpNb2R1bGU7CiAgaW50CQlpOwogIHVfc2hvcnQJKm9yZGluYWw7CiAgdV9sb25nCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIHVfY2hhcgkqKm5hbWUsKmVuYW1lOwogIGNoYXIJCWJ1ZmZlclsxMDAwXTsKICBEQkdfQUREUglkYWRkcjsKCiAgZGFkZHIuc2VnID0gMDsKICBkYWRkci50eXBlID0gTlVMTDsKICBNb2R1bGUgPSAoY2hhciopUlZBKHBlX2V4cG9ydHMtPk5hbWUpOwogIGRwcmludGZfd2luMzIoc3RkZGViLCJcbioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJIE1vZHVsZSwKCSBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywKCSBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKTsKCiAgb3JkaW5hbD0odV9zaG9ydCopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucz1mdW5jdGlvbj0odV9sb25nKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZT0odV9jaGFyKiopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyBPcmRpbmFsIFZpcnQgQWRkclxuIiwgIkZ1bmN0aW9uIE5hbWUiKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKykgewogICAgICBpZiAoaTxwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKSB7CgkgIGVuYW1lPShjaGFyKilSVkEoKm5hbWUrKyk7CgkgIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyAlNGQgICAgJTguOGx4ICglOC44bHgpXG4iLGVuYW1lLCpvcmRpbmFsLGZ1bmN0aW9uc1sqb3JkaW5hbF0sKmZ1bmN0aW9uKTsKCSAgc3ByaW50ZihidWZmZXIsIiVzXyVzIixNb2R1bGUsZW5hbWUpOwoJICBkYWRkci5vZmY9UlZBKGZ1bmN0aW9uc1sqb3JkaW5hbF0pOwoJICBvcmRpbmFsKys7CgkgIGZ1bmN0aW9uKys7CiAgICAgIH0gZWxzZSB7CiAgICAgIAkgIC8qIG9yZGluYWxzL25hbWVzIG5vIGxvbmdlciB2YWxpZCwgYnV0IHdlIHN0aWxsIGdvdCBmdW5jdGlvbnMgKi8KCSAgZHByaW50Zl93aW4zMihzdGRkZWIsIiUtMzJzICU0cyAgICAlOHMgJTguOGx4XG4iLCIiLCIiLCIiLCpmdW5jdGlvbik7CgkgIHNwcmludGYoYnVmZmVyLCIlc18lZCIsTW9kdWxlLGkpOwoJICBkYWRkci5vZmY9UlZBKCpmdW5jdGlvbnMpOwoJICBmdW5jdGlvbisrOwogICAgICB9CiAgICAgIERFQlVHX0FkZFN5bWJvbChidWZmZXIsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpGQVJQUk9DMzIgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oc3RydWN0IHBlX2RhdGEgKnBlLCBMUENTVFIgZnVuY05hbWUpCnsKCUlNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKiBleHBvcnRzID0gcGUtPnBlX2V4cG9ydDsKCXVuc2lnbmVkIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7Cgl1X3Nob3J0ICogb3JkaW5hbDsKCXVfbG9uZyAqIGZ1bmN0aW9uOwoJdV9jaGFyICoqIG5hbWUsICplbmFtZTsKCWludCBpOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpCgkJcmV0dXJuIE5VTEw7CglvcmRpbmFsPSh1X3Nob3J0KikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0odV9sb25nKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lPSh1X2NoYXIgKiopIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CglpZiAoSElXT1JEKGZ1bmNOYW1lKSkgewoJCWZvcihpPTA7IGk8ZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKSB7CgkJCWVuYW1lPShjaGFyKikgUlZBKCpuYW1lKTsKCQkJaWYoIXN0cmNtcChlbmFtZSxmdW5jTmFtZSkpCgkJCQlyZXR1cm4gKEZBUlBST0MzMikgUlZBKGZ1bmN0aW9uWypvcmRpbmFsXSk7CgkJCW9yZGluYWwrKzsKCQkJbmFtZSsrOwoJCX0KCX0gZWxzZSB7CgkJaWYgKExPV09SRChmdW5jTmFtZSktZXhwb3J0cy0+QmFzZSA+IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKSB7CgkJCWRwcmludGZfd2luMzIoc3RkZGViLCIJb3JkaW5hbCAlZCBvdXQgb2YgcmFuZ2UhXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPV09SRChmdW5jTmFtZSkpOwoJCQlyZXR1cm4gTlVMTDsKCQl9CgkJcmV0dXJuIChGQVJQUk9DMzIpIFJWQShmdW5jdGlvblsoaW50KWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2VdKTsKCX0KCXJldHVybiBOVUxMOwp9Cgp2b2lkIApmaXh1cF9pbXBvcnRzIChzdHJ1Y3QgcGVfZGF0YSAqcGUsIEhNT0RVTEUxNiBoTW9kdWxlKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcGVfaW1wOwogICAgaW50CWZpeHVwX2ZhaWxlZCA9IDA7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gcGUtPmxvYWRfYWRkcjsKICAgIGludCBpOwogICAgTkVfTU9EVUxFICpuZV9tb2Q7CiAgICBITU9EVUxFMTYgKm1vZF9wdHI7CiAgICBjaGFyICptb2RuYW1lOwogICAgCiAgICBpZiAocGUtPnBlX2V4cG9ydCkKICAgIAltb2RuYW1lID0gKGNoYXIqKSBSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIlxuRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZS0+cGVfaW1wb3J0OwoKICAgIC8qIEZJWE1FOiBzaG91bGQgdGVybWluYXRlIG9uIDAgQ2hhcmFjdGVyaXN0aWNzICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKQoJaSsrOwoKICAgIC8qIE5vdywgYWxsb2NhdGUgbWVtb3J5IGZvciBkbGxzX3RvX2luaXQgKi8KICAgIG5lX21vZCA9IEdsb2JhbExvY2sxNiAoaE1vZHVsZSk7CiAgICBuZV9tb2QtPmRsbHNfdG9faW5pdCA9IEdMT0JBTF9BbGxvYyhHTUVNX1pFUk9JTklULCAoaSsxKSpzaXplb2YoSE1PRFVMRTE2KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhNb2R1bGUsIEZBTFNFLCBGQUxTRSwgRkFMU0UpOwogICAgbW9kX3B0ciA9IEdsb2JhbExvY2sxNiAobmVfbW9kLT5kbGxzX3RvX2luaXQpOwogICAgLyogbG9hZCB0aGUgbW9kdWxlcyBhbmQgcHV0IHRoZWlyIGhhbmRsZXMgaW50byB0aGUgbGlzdCAqLwogCiAgICAgLyogRklYTUU6IHNob3VsZCB0ZXJtaW5hdGUgb24gMCBDaGFyYWN0ZXJpc3RpY3MgKi8KICAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZS0+cGVfaW1wb3J0OyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKSB7CiAJY2hhciAqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoJbW9kX3B0cltpXSA9IE1PRFVMRV9Mb2FkKCBuYW1lLCAoTFBWT0lEKS0xLCBGQUxTRSApOwoJaWYgKG1vZF9wdHJbaV0gPD0gKEhNT0RVTEUxNikgMzIpIHsKCSAgICBjaGFyICpwLCBidWZmZXJbMjU2XTsKCgkgICAgLyogVHJ5IHdpdGggcHJlcGVuZGluZyB0aGUgcGF0aCBvZiB0aGUgY3VycmVudCBtb2R1bGUgKi8KCSAgICBHZXRNb2R1bGVGaWxlTmFtZTE2IChoTW9kdWxlLCBidWZmZXIsIHNpemVvZiAoYnVmZmVyKSk7CgkgICAgaWYgKCEocCA9IHN0cnJjaHIgKGJ1ZmZlciwgJ1xcJykpKQoJCXAgPSBidWZmZXI7CgkgICAgc3RyY3B5IChwICsgMSwgbmFtZSk7CgkgICAgbW9kX3B0cltpXSA9IE1PRFVMRV9Mb2FkKCBidWZmZXIsIChMUFZPSUQpLTEsIEZBTFNFICk7Cgl9CglpZiAobW9kX3B0cltpXSA8PSAoSE1PRFVMRTE2KSAzMikgewoJICAgIGZwcmludGYgKHN0ZGVyciwgIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsIG5hbWUpOwoJICAgIGV4aXQgKDApOwoJfQoJaSsrOwogICAgfQogICAgcGVfaW1wID0gcGUtPnBlX2ltcG9ydDsKICAgIHdoaWxlIChwZV9pbXAtPk5hbWUpIHsKCWNoYXIJCQkqTW9kdWxlOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglMUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKCWludAkJCW9yZGltcG9ydHdhcm5lZDsKCiAgICAgICAgb3JkaW1wb3J0d2FybmVkID0gMDsKCU1vZHVsZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoJZHByaW50Zl93aW4zMiAoc3RkZGViLCAiJXNcbiIsIE1vZHVsZSk7CgoJLyogRklYTUU6IGZvcndhcmRlciBlbnRyaWVzIC4uLiAqLwoKCWlmIChwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rICE9IDApIHsgLyogb3JpZ2luYWwgTVMgc3R5bGUgKi8KCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICJNaWNyb3NvZnQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICBpbXBvcnRfbGlzdCA9KExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCgkgICAgd2hpbGUgKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIGlmKCFsc3RybmNtcGkzMkEoTW9kdWxlLCJrZXJuZWwzMiIsOCkgJiYgIW9yZGltcG9ydHdhcm5lZCl7CgkJICAgICAgIGZwcmludGYoc3RkZXJyLCIlcyBpbXBvcnRzIGtlcm5lbDMyLmRsbCBieSBvcmRpbmFsLiBNYXkgY3Jhc2guXG4iLG1vZG5hbWUpOwoJCSAgICAgICBvcmRpbXBvcnR3YXJuZWQgPSAxOwoJCSAgICB9CgkJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBNb2R1bGUsIG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClHZXRQcm9jQWRkcmVzczMyKE1PRFVMRV9GaW5kTW9kdWxlKE1vZHVsZSksKExQQ1NUUilvcmRpbmFsKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsIG9yZGluYWwpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0gZWxzZSB7CQkvKiBpbXBvcnQgYnkgbmFtZSAqLwoJCSAgICBwZV9uYW1lID0gKExQSU1BR0VfSU1QT1JUX0JZX05BTUUpUlZBKGltcG9ydF9saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClHZXRQcm9jQWRkcmVzczMyKAoJCQkJCQlNT0RVTEVfRmluZE1vZHVsZSAoTW9kdWxlKSwKCQkJCQkJcGVfbmFtZS0+TmFtZSk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJZnByaW50ZihzdGRlcnIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcyksIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSxwZV9uYW1lLT5IaW50LHBlX25hbWUtPk5hbWUpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0KCQlpbXBvcnRfbGlzdCsrOwoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9IGVsc2UgewkvKiBCb3JsYW5kIHN0eWxlICovCgkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSAoTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCSAgICB3aGlsZSAodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgLyogbm90IHN1cmUgYWJvdXQgdGhpcyBicmFuY2gsIGJ1dCBpdCBzZWVtcyB0byB3b3JrICovCgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKTsKCgoJCSAgICBpZiAoIWxzdHJuY21waTMyQShNb2R1bGUsImtlcm5lbDMyIiw4KSAmJiAKCQkgICAgCSFvcmRpbXBvcnR3YXJuZWQKCQkgICAgKSB7CgkJICAgICAgIGZwcmludGYoc3RkZXJyLCIlcyBpbXBvcnRzIGtlcm5lbDMyLmRsbCBieSBvcmRpbmFsLiBNYXkgY3Jhc2guXG4iLG1vZG5hbWUpOwoJCSAgICAgICBvcmRpbXBvcnR3YXJuZWQgPSAxOwoJCSAgICB9CgkJICAgIGRwcmludGZfd2luMzIoc3RkZGViLCItLS0gT3JkaW5hbCAlcy4lZFxuIixNb2R1bGUsb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSwKCQkJCQkJICAgICAoTFBDU1RSKSBvcmRpbmFsKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLG9yZGluYWwpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9KExQSU1BR0VfSU1QT1JUX0JZX05BTUUpIFJWQSh0aHVua19saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgZHByaW50Zl93aW4zMihzdGRkZWIsIi0tLSAlcyAlcy4lZFxuIiwKCQkgICAJCSAgcGVfbmFtZS0+TmFtZSxNb2R1bGUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSxwZV9uYW1lLT5OYW1lKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCSAgICAJZnByaW50ZihzdGRlcnIsICJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIAkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0KCQl0aHVua19saXN0Kys7CgkgICAgfQoJfQoJcGVfaW1wKys7CiAgICB9CiAgICBpZiAoZml4dXBfZmFpbGVkKSBleGl0KDEpOwp9CgpzdGF0aWMgdm9pZCBjYWxjX3ZtYV9zaXplKHN0cnVjdCBwZV9kYXRhICpwZSkKewogIGludCBpOwoKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgZHByaW50Zl93aW4zMihzdGRkZWIsICIgICBOYW1lICAgIFZTeiAgVmFkZHIgICAgIFN6UmF3ICAgRmlsZWFkciAgKlJlbG9jICpMaW5ldW0gI1JlbG9jICNMaW51bSBDaGFyXG4iKTsKICBmb3IoaT0wOyBpPCBwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKICAgIHsKICAgICAgZHByaW50Zl93aW4zMihzdGRkZWIsICIlOHM6ICU0LjRseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU0LjR4ICU0LjR4ICU4LjhseFxuIiwgCgkgICAgIHBlLT5wZV9zZWdbaV0uTmFtZSwgCgkgICAgIHBlLT5wZV9zZWdbaV0uTWlzYy5WaXJ0dWFsU2l6ZSwKCSAgICAgcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcywKCSAgICAgcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhLAoJICAgICBwZS0+cGVfc2VnW2ldLlBvaW50ZXJUb1Jhd0RhdGEsCgkgICAgIHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmVsb2NhdGlvbnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvTGluZW51bWJlcnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uTnVtYmVyT2ZSZWxvY2F0aW9ucywKCSAgICAgcGUtPnBlX3NlZ1tpXS5OdW1iZXJPZkxpbmVudW1iZXJzLAoJICAgICBwZS0+cGVfc2VnW2ldLkNoYXJhY3RlcmlzdGljcyk7CgkgIHBlLT52bWFfc2l6ZSA9IE1BWChwZS0+dm1hX3NpemUsCgkgIAkJcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyArIAoJCQlwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBkb19yZWxvY2F0aW9ucyhzdHJ1Y3QgcGVfZGF0YSAqcGUpCnsKCWludCBkZWx0YSA9IHBlLT5sb2FkX2FkZHIgLSBwZS0+YmFzZV9hZGRyOwoJdW5zaWduZWQgaW50IGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7CglJTUFHRV9CQVNFX1JFTE9DQVRJT04JKnIgPSBwZS0+cGVfcmVsb2M7CglpbnQgaGRlbHRhID0gKGRlbHRhID4+IDE2KSAmIDB4RkZGRjsKCWludCBsZGVsdGEgPSBkZWx0YSAmIDB4RkZGRjsKCgkvKiBpbnQgcmVsb2Nfc2l6ZSA9ICovCgoJaWYoZGVsdGEgPT0gMCkKCQkvKiBOb3RoaW5nIHRvIGRvICovCgkJcmV0dXJuOwoJd2hpbGUoci0+VmlydHVhbEFkZHJlc3MpCgl7CgkJY2hhciAqcGFnZSA9IChjaGFyKikgUlZBKHItPlZpcnR1YWxBZGRyZXNzKTsKCQlpbnQgY291bnQgPSAoci0+U2l6ZU9mQmxvY2sgLSA4KS8yOwoJCWludCBpOwoJCWRwcmludGZfZml4dXAoc3RkZGViLCAiJXggcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLAoJCQljb3VudCwgci0+VmlydHVhbEFkZHJlc3MpOwoJCS8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KCQlmb3IoaT0wO2k8Y291bnQ7aSsrKQoJCXsKCQkJaW50IG9mZnNldCA9IHItPlR5cGVPZmZzZXRbaV0gJiAweEZGRjsKCQkJaW50IHR5cGUgPSByLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwoJCQlkcHJpbnRmX2ZpeHVwKHN0ZGRlYiwicGF0Y2hpbmcgJXggdHlwZSAleFxuIiwgb2Zmc2V0LCB0eXBlKTsKCQkJc3dpdGNoKHR5cGUpCgkJCXsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfQUJTT0xVVEU6IGJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBoZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTE9XOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBsZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSExPVzoKI2lmIDEKCQkJCSooaW50KikocGFnZStvZmZzZXQpICs9IGRlbHRhOwojZWxzZQoJCQkJeyBpbnQgaD0qKHVuc2lnbmVkIHNob3J0KikocGFnZStvZmZzZXQpOwoJCQkJICBpbnQgbD1yLT5UeXBlT2Zmc2V0WysraV07CgkJCQkgICoodW5zaWduZWQgaW50KikocGFnZSArIG9mZnNldCkgPSAoaDw8MTYpICsgbCArIGRlbHRhOwoJCQkJfQojZW5kaWYKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJZnByaW50ZihzdGRlcnIsICJEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBJTUFHRV9SRUxfQkFTRURfSElHSEFESlxuIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTUlQU19KTVBBRERSOgoJCQkJZnByaW50ZihzdGRlcnIsICJJcyB0aGlzIGEgTUlQUyBtYWNoaW5lID8/P1xuIik7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBmaXh1cCB0eXBlXG4iKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXIgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKikoKGNoYXIqKXIgKyByLT5TaXplT2ZCbG9jayk7Cgl9Cn0KCQkKCgkKCQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IGV4ZWN1dGFibGUgaW50byBtZW1vcnkKICovCnN0YXRpYyB2b2lkIFBFX0xvYWRJbWFnZSggc3RydWN0IHBlX2RhdGEgKipyZXRfcGUsIGludCBmZCwgSE1PRFVMRTE2IGhNb2R1bGUsIFdPUkQgb2Zmc2V0LCBPRlNUUlVDVCAqb2ZzICkKewoJc3RydWN0IHBlX2RhdGEJCSpwZTsKCWludAkJCWksIHJlc3VsdDsKCWludAkJCWxvYWRfYWRkcjsKCUlNQUdFX0RBVEFfRElSRUNUT1JZCWRpcjsKCWNoYXIJCQlidWZmZXJbMjAwXTsKCURCR19BRERSCQlkYWRkcjsKCWNoYXIJCQkqbW9kbmFtZTsKCglkYWRkci5zZWc9MDsKCWRhZGRyLnR5cGUgPSBOVUxMOwoJcGUgPSB4bWFsbG9jKHNpemVvZihzdHJ1Y3QgcGVfZGF0YSkpOwoJbWVtc2V0KHBlLDAsc2l6ZW9mKHN0cnVjdCBwZV9kYXRhKSk7CglwZS0+cGVfaGVhZGVyID0geG1hbGxvYyhzaXplb2YoSU1BR0VfTlRfSEVBREVSUykpOwoKCS8qIHJlYWQgUEUgaGVhZGVyICovCglsc2VlayggZmQsIG9mZnNldCwgU0VFS19TRVQpOwoJcmVhZCggZmQsIHBlLT5wZV9oZWFkZXIsIHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSk7CgoJaWYgKHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTWFjaGluZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NikgewoJCWZwcmludGYoc3RkZXJyLCJ0cnlpbmcgdG8gbG9hZCBQRSBpbWFnZSBmb3IgdW5zdXBwb3J0ZWQgYXJjaGl0ZWN0dXJlICgiKTsKCQlzd2l0Y2ggKHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTWFjaGluZSkgewoJCWNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1VOS05PV046CgkJCWZwcmludGYoc3RkZXJyLCJVbmtub3duIik7YnJlYWs7CgkJY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfSTg2MDoKCQkJZnByaW50ZihzdGRlcnIsIkk4NjAiKTticmVhazsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMzAwMDoKCQkJZnByaW50ZihzdGRlcnIsIlIzMDAwIik7YnJlYWs7CgkJY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjQwMDA6CgkJCWZwcmludGYoc3RkZXJyLCJSNDAwMCIpO2JyZWFrOwoJCWNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IxMDAwMDoKCQkJZnByaW50ZihzdGRlcnIsIlIxMDAwMCIpO2JyZWFrOwoJCWNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0FMUEhBOgoJCQlmcHJpbnRmKHN0ZGVyciwiQWxwaGEiKTticmVhazsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9QT1dFUlBDOgoJCQlmcHJpbnRmKHN0ZGVyciwiUG93ZXJQQyIpO2JyZWFrOwoJCWRlZmF1bHQ6CgkJCWZwcmludGYoc3RkZXJyLCJVbmtub3duLSUwNHgiLHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTWFjaGluZSk7YnJlYWs7CgkJfQoJCWZwcmludGYoc3RkZXJyLCIpXG4iKTsKCQlyZXR1cm47Cgl9Ci8qIEZJWE1FOiB0aGlzIGlzIGEgKmhvcnJpYmxlKiBoYWNrIHRvIG1ha2UgQ09NRExHMzIuRExMIGxvYWQgT0suIFRoZQogKiBwcm9ibGVtIG5lZWRzIHRvIGJlIGZpeGVkIHByb3Blcmx5IGF0IHNvbWUgc3RhZ2UgCiAqLwoJaWYgKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLk51bWJlck9mUnZhQW5kU2l6ZXMgIT0gMTYpIHsKCQlwcmludGYoIlNob3J0IFBFIEhlYWRlciEhIVxuIik7CgkJbHNlZWsoIGZkLCAtKDE2IC0gcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuTnVtYmVyT2ZSdmFBbmRTaXplcykgKiBzaXplb2YoSU1BR0VfREFUQV9ESVJFQ1RPUlkpLCBTRUVLX0NVUik7Cgl9CgoJLyogcmVhZCBzZWN0aW9ucyAqLwoJcGUtPnBlX3NlZyA9IHhtYWxsb2Moc2l6ZW9mKElNQUdFX1NFQ1RJT05fSEVBREVSKSAqIAoJCQkJICAgcGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zKTsKCXJlYWQoIGZkLCBwZS0+cGVfc2VnLCBzaXplb2YoSU1BR0VfU0VDVElPTl9IRUFERVIpICogCgkJCXBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucyk7CgoJbG9hZF9hZGRyID0gcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJcGUtPmJhc2VfYWRkcj1sb2FkX2FkZHI7CglwZS0+dm1hX3NpemU9MDsKCWRwcmludGZfd2luMzIoc3RkZGViLCAiTG9hZCBhZGRyIGlzICV4XG4iLGxvYWRfYWRkcik7CgljYWxjX3ZtYV9zaXplKHBlKTsKCWxvYWRfYWRkciA9IChpbnQpIFZpcnR1YWxBbGxvYyggKHZvaWQqKXBlLT5iYXNlX2FkZHIsIHBlLT52bWFfc2l6ZSwgTUVNX1JFU0VSVkV8TUVNX0NPTU1JVCwgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwogICAgICAgIHBlLT5sb2FkX2FkZHIgPSBsb2FkX2FkZHI7CgoJZHByaW50Zl93aW4zMihzdGRkZWIsICJMb2FkIGFkZHIgaXMgcmVhbGx5ICV4LCByYW5nZSAleFxuIiwKCQlwZS0+bG9hZF9hZGRyLCBwZS0+dm1hX3NpemUpOwoJCgoJZm9yKGk9MDsgaSA8IHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQoJewoJCS8qIGxvYWQgb25seSBub24tQlNTIHNlZ21lbnRzICovCgkJaWYoIShwZS0+cGVfc2VnW2ldLkNoYXJhY3RlcmlzdGljcyAmIAoJCQlJTUFHRV9TQ05fQ05UX1VOSU5JVElBTElaRURfREFUQSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYobHNlZWsoZmQscGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SYXdEYXRhLFNFRUtfU0VUKSA9PSAtMQogICAgICAgICAgICAgICAgICAgICAgIHx8IHJlYWQoZmQsKGNoYXIqKVJWQShwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YSkgIT0gcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhKQogICAgICAgICAgICAgICAgICAgIHsKCQkJZnByaW50ZihzdGRlcnIsIkZhaWxlZCB0byBsb2FkIHNlY3Rpb24gJXhcbiIsIGkpOwoJCQlleGl0KDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCQlyZXN1bHQgPSBSVkEgKHBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MpOwojaWYgMQoJCS8qIG5vdCBuZWVkZWQsIG1lbW9yeSBpcyB6ZXJvICovCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5ic3MiKSA9PSAwKQoJCSAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgPwoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgOgoJCQkgICBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpOwojZW5kaWYKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5pZGF0YSIpID09IDApCgkJCXBlLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgcmVzdWx0OwoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmVkYXRhIikgPT0gMCkKCQkJcGUtPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5yc3JjIikgPT0gMCkKCQkJcGUtPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIucmVsb2MiKSA9PSAwKQoJCQlwZS0+cGVfcmVsb2MgPSAoTFBJTUFHRV9CQVNFX1JFTE9DQVRJT04pIHJlc3VsdDsKCX0KCgkvKiBUaGVyZSBpcyB3b3JkIHRoYXQgdGhlIGFjdHVhbCBsb2FkZXIgZG9lcyBub3QgY2FyZSBhYm91dCB0aGUKCSAgIHNlY3Rpb24gbmFtZXMsIGFuZCBvbmx5IGdvZXMgZm9yIHRoZSBEYXRhRGlyZWN0b3J5ICovCglkaXI9cGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9leHBvcnQgJiYgKGludClwZS0+cGVfZXhwb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGV4cG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJLyogYWx3YXlzIHRydXN0IHRoZSBkaXJlY3RvcnkgKi8KCQlwZS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfaW1wb3J0ICYmIChpbnQpcGUtPnBlX2ltcG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBpbXBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1JFU09VUkNFXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9yZXNvdXJjZSAmJiAoaW50KXBlLT5wZV9yZXNvdXJjZSE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZXNvdXJjZSBkaXJlY3Rvcnk/P1xuIik7CgkJcGUtPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT05dLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCgoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQ107CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfcmVsb2MgJiYgKGludClwZS0+cGVfcmVsb2MhPSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIHJlbG9jYXRpb24gbGlzdD8/XG4iKTsKCQlwZS0+cGVfcmVsb2MgPSAodm9pZCAqKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVR10uU2l6ZSkKCSAgewoJICAgIERFQlVHX1JlZ2lzdGVyRGVidWdJbmZvKGZkLCBwZSwgbG9hZF9hZGRyLCAKCQkJcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlZpcnR1YWxBZGRyZXNzLAoJCQlwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVR10uU2l6ZSk7CgkgIH0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT1BZUklHSFRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUl0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFNdLlNpemUpCgkJIGZwcmludGYoc3RkbmltcCwiVGhyZWFkIGxvY2FsIHN0b3JhZ2UgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUddLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxM10uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDEzIGlnbm9yZWRcbiIpOwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIpOwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9yZWxvYykgZG9fcmVsb2NhdGlvbnMocGUpOwoKCS8qIERvIGV4cG9ydHMgYmVmb3JlIGltcG9ydHMgYmVjYXVzZSBmaXh1cF9pbXBvcnRzCgkgKiBtYXkgbG9hZCBhIG1vZHVsZSB0aGF0IHJlZmVyZW5jZXMgdGhpcyBtb2R1bGUuCgkgKi8KCglpZihwZS0+cGVfZXhwb3J0KSBkdW1wX2V4cG9ydHMocGUtPnBlX2V4cG9ydCxsb2FkX2FkZHIpOwoJKnJldF9wZSA9IHBlOwkvKiBtYWtlIGV4cG9ydCBsaXN0IGF2YWlsYWJsZSBmb3IgR2V0UHJvY0FkZHJlc3MgKi8KCWlmKHBlLT5wZV9pbXBvcnQpIGZpeHVwX2ltcG9ydHMocGUsIGhNb2R1bGUpOwogIAkJCglpZiAocGUtPnBlX2V4cG9ydCkKCQltb2RuYW1lID0gKGNoYXIqKVJWQShwZS0+cGVfZXhwb3J0LT5OYW1lKTsKCWVsc2UgewoJCWNoYXIgKnM7CgkJbW9kbmFtZSA9IHMgPSBvZnMtPnN6UGF0aE5hbWU7CgkJd2hpbGUgKChzPXN0cmNocihtb2RuYW1lLCdcXCcpKSkKCQkJbW9kbmFtZSA9IHMrMTsKCQlpZiAoKHM9c3RyY2hyKG1vZG5hbWUsJy4nKSkpCgkJCSpzPSdcMCc7Cgl9CgoJLyogYWRkIHN0YXJ0IG9mIHNlY3Rpb25zIGFzIGRlYnVnc3ltYm9scyAqLwoJZm9yKGk9MDtpPHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucztpKyspIHsKCQlzcHJpbnRmKGJ1ZmZlciwiJXNfJXMiLG1vZG5hbWUscGUtPnBlX3NlZ1tpXS5OYW1lKTsKCQlkYWRkci5vZmY9IFJWQShwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzKTsKCQlERUJVR19BZGRTeW1ib2woYnVmZmVyLCZkYWRkciwgTlVMTCwgU1lNX1dJTjMyIHwgU1lNX0ZVTkMpOwoJfQoJLyogYWRkIGVudHJ5IHBvaW50ICovCglzcHJpbnRmKGJ1ZmZlciwiJXNfRW50cnlQb2ludCIsbW9kbmFtZSk7CglkYWRkci5vZmY9UlZBKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpOwoJREVCVUdfQWRkU3ltYm9sKGJ1ZmZlciwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKCS8qIGFkZCBzdGFydCBvZiBETEwgKi8KCWRhZGRyLm9mZj1sb2FkX2FkZHI7CglERUJVR19BZGRTeW1ib2wobW9kbmFtZSwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKfQoKSElOU1RBTkNFMTYgTU9EVUxFX0NyZWF0ZUluc3RhbmNlKEhNT0RVTEUxNiBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CgpISU5TVEFOQ0UxNiBQRV9Mb2FkTW9kdWxlKCBIRklMRTMyIGhGaWxlLCBPRlNUUlVDVCAqb2ZzLCBMT0FEUEFSQU1TKiBwYXJhbXMgKQp7CiAgICBITU9EVUxFMTYgaE1vZHVsZTsKICAgIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKICAgIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogICAgaW50IGZkOwoKICAgIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggb2ZzICkpIDwgMzIpIHJldHVybiBoTW9kdWxlOwogICAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUgKTsKICAgIHBNb2R1bGUtPmZsYWdzID0gTkVfRkZMQUdTX1dJTjMyOwoKICAgIC8qIEZJWE1FOiBIYWNrIGJlY2F1c2UgUEVfTG9hZE1vZHVsZSBpcyByZWN1cnNpdmUgKi8KICAgIGZkID0gZHVwKCBGSUxFX0dldFVuaXhIYW5kbGUoaEZpbGUpICk7CiAgICBfbGNsb3NlMzIoIGhGaWxlICk7CiAgICBsc2VlayggZmQsIDAsIFNFRUtfU0VUICk7CiAgICByZWFkKCBmZCwgJm16X2hlYWRlciwgc2l6ZW9mKG16X2hlYWRlcikgKTsKCiAgICBQRV9Mb2FkSW1hZ2UoICZwTW9kdWxlLT5wZV9tb2R1bGUsIGZkLCBoTW9kdWxlLCBtel9oZWFkZXIuZV9sZmFuZXcsIG9mcyApOwogICAgaWYgKCFwTW9kdWxlLT5wZV9tb2R1bGUpCiAgICAJcmV0dXJuIDIxOwogICAgY2xvc2UoIGZkICk7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlLCBwYXJhbXMgKTsKCiAgICBpZiAoIShwTW9kdWxlLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgVEFTS19DcmVhdGVUYXNrKCBoTW9kdWxlLCBoSW5zdGFuY2UsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmhFbnZpcm9ubWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgIChMUFNUUilQVFJfU0VHX1RPX0xJTiggcGFyYW1zLT5jbWRMaW5lICksCiAgICAgICAgICAgICAgICAgICAgICAgICAqKChXT1JEKilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPnNob3dDbWQpICsgMSkgKTsKICAgIH0KICAgIHJldHVybiBoSW5zdGFuY2U7Cn0KCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRTE2IGhNb2R1bGUgKQp7CglwcmludGYoIlBFdW5sb2FkSW1hZ2UoKSBjYWxsZWQhXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8Kc3RhdGljIHZvaWQgUEVfSW5pdERMTChITU9EVUxFMTYgaE1vZHVsZSwgRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgUEVfTU9EVUxFICpwZTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHI7CgogICAgaE1vZHVsZSA9IEdldEV4ZVB0cihoTW9kdWxlKTsKICAgIGlmICghKHBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKGhNb2R1bGUpKSkgcmV0dXJuOwogICAgaWYgKCEocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfV0lOMzIpIHx8ICEocGUgPSBwTW9kdWxlLT5wZV9tb2R1bGUpKQogICAgICAgIHJldHVybjsKCiAgICBsb2FkX2FkZHIgPSBwZS0+bG9hZF9hZGRyOwoKI2lmbmRlZiBXSU5FTElCCiAgICBpZiAoT3B0aW9ucy5kZWJ1ZykgewogICAgICAgICAgICBEQkdfQUREUiBhZGRyID0geyBOVUxMLCAwLCBSVkEocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkgfTsKICAgICAgICAgICAgREVCVUdfQWRkQnJlYWtwb2ludCggJmFkZHIgKTsKCSAgICBERUJVR19TZXRCcmVha3BvaW50cyhUUlVFKTsKICAgIH0KI2VuZGlmCgogICAgLyogIERMTF9BVFRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgZm9yIGR5bmFtaWMgbG9hZHMsIG5vdC1OVUxMIGZvciBzdGF0aWMgbG9hZHMKICAgICAqICBETExfREVUQUNIX1BST0NFU1M6CiAgICAgKgkJbHByZXNlcnZlZCBpcyBOVUxMIGlmIGNhbGxlZCBieSBGcmVlTGlicmFyeSwgbm90LU5VTEwgb3RoZXJ3aXNlCiAgICAgKiAgdGhlIFNESyBkb2Vzbid0IG1lbnRpb24gYW55dGhpbmcgZm9yIERMTF9USFJFQURfKgogICAgICovCiAgICAgICAgCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgJKHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCgkJKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICApIHsKCXByaW50ZigiSW5pdFBFRExMKCkgY2FsbGVkIVxuIik7CglDYWxsRExMRW50cnlQcm9jMzIoIAoJICAgIChGQVJQUk9DMzIpUlZBKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpLAoJICAgIGhNb2R1bGUsCgkgICAgdHlwZSwKCSAgICAoRFdPUkQpbHBSZXNlcnZlZAoJKTsKICAgIH0KfQoKdm9pZCBQRV9Jbml0aWFsaXplRExMcyhITU9EVUxFMTYgaE1vZHVsZSxEV09SRCB0eXBlLExQVk9JRCBscFJlc2VydmVkKQp7CglORV9NT0RVTEUgKnBNb2R1bGU7CglITU9EVUxFMTYgKnBETEw7CglwTW9kdWxlID0gTU9EVUxFX0dldFB0ciggR2V0RXhlUHRyKGhNb2R1bGUpICk7CglpZiAocE1vZHVsZS0+ZGxsc190b19pbml0KQoJewoJCUhHTE9CQUwxNiB0b19pbml0ID0gcE1vZHVsZS0+ZGxsc190b19pbml0OwoJCXBNb2R1bGUtPmRsbHNfdG9faW5pdCA9IDA7CgkKCQlmb3IgKHBETEwgPSAoSE1PRFVMRTE2ICopR2xvYmFsTG9jazE2KCB0b19pbml0ICk7ICpwRExMOyBwRExMKyspCgkJewogICAgICAgICAgICAgICAgICAgIFBFX0luaXRpYWxpemVETExzKCAqcERMTCwgdHlwZSwgbHBSZXNlcnZlZCk7CgkJfQoJCUdsb2JhbEZyZWUxNiggdG9faW5pdCApOwoJfQoJUEVfSW5pdERMTCggaE1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwp9Cgp2b2lkIFBFX0luaXRUbHMoIFBFX01PRFVMRSAqbW9kdWxlICkKewogICAvKiBGSVhNRTogdGxzIGNhbGxiYWNrcyA/Pz8gKi8KICAgRFdPUkQgIGluZGV4OwogICBEV09SRCAgZGF0YXNpemU7CiAgIERXT1JEICBzaXplOwogICBMUFZPSUQgbWVtOwogICBMUElNQUdFX1RMU19ESVJFQ1RPUlkgcGRpcjsKCiAgICBpZiAoIW1vZHVsZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKQogICAgICAgIHJldHVybjsKCiAgICBwZGlyID0gKExQVk9JRCkobW9kdWxlLT5sb2FkX2FkZHIgKyBtb2R1bGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuCiAgICAgICAgICAgICAgIERhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpOwogICAgaW5kZXggPSBUbHNBbGxvYygpOwogICAgZGF0YXNpemUgPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKICAgIHNpemUgICAgID0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKICAgICAgICAKICAgIG1lbSA9IFZpcnR1YWxBbGxvYygwLHNpemUsIE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsIFBBR0VfUkVBRFdSSVRFICk7CiAgICAKICAgIG1lbWNweShtZW0sKExQVk9JRCkgcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhLCBkYXRhc2l6ZSk7CiAgICBUbHNTZXRWYWx1ZShpbmRleCxtZW0pOwogICAgKihwZGlyLT5BZGRyZXNzT2ZJbmRleCk9aW5kZXg7ICAgCn0KCiNlbmRpZiAvKiBXSU5FTElCICovCg==