I2lmbmRlZiBXSU5FTElCCi8qIAogKiAgQ29weXJpZ2h0CTE5OTQJRXJpYyBZb3VuZGFsZSAmIEVyaWsgQm9zCiAqICBDb3B5cmlnaHQJMTk5NQlNYXJ0aW4gdm9uIEz2d2lzCiAqICBDb3B5cmlnaHQgICAxOTk2ICAgIE1hcmN1cyBNZWlzc25lcgogKgogKgliYXNlZCBvbiBFcmljIFlvdW5kYWxlJ3MgcGUtdGVzdCBhbmQ6CiAqCiAqCWZ0cC5taWNyb3NvZnQuY29tOi9wdWIvZGV2ZWxvcGVyL01TRE4vQ0Q4L1BFRklMRS5aSVAKICogbWFrZSB0aGF0OgogKglmdHAubWljcm9zb2Z0LmNvbTovZGV2ZWxvcHIvTVNETi9PY3RDRC9QRUZJTEUuWklQCiAqLwoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwZV9pbWFnZS5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJnbG9iYWwuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAic3RkZGVidWcuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJkZWJ1Z2dlci5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgoKc3RhdGljIHZvaWQgUEVfSW5pdERMTChITU9EVUxFMTYgaE1vZHVsZSwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQpOwoKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodW5zaWduZWQgaW50KWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkKCnZvaWQgZHVtcF9leHBvcnRzKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKiBwZV9leHBvcnRzLCB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyKQp7IAogIGNoYXIJCSpNb2R1bGU7CiAgaW50CQlpOwogIHVfc2hvcnQJKm9yZGluYWw7CiAgdV9sb25nCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIHVfY2hhcgkqKm5hbWUsKmVuYW1lOwogIGNoYXIJCWJ1ZmZlclsxMDAwXTsKICBEQkdfQUREUglkYWRkcjsKCiAgZGFkZHIuc2VnID0gMDsKICBkYWRkci50eXBlID0gTlVMTDsKICBNb2R1bGUgPSAoY2hhciopUlZBKHBlX2V4cG9ydHMtPk5hbWUpOwogIGRwcmludGZfd2luMzIoc3RkZGViLCJcbioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJIE1vZHVsZSwKCSBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywKCSBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKTsKCiAgb3JkaW5hbD0odV9zaG9ydCopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucz1mdW5jdGlvbj0odV9sb25nKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZT0odV9jaGFyKiopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyBPcmRpbmFsIFZpcnQgQWRkclxuIiwgIkZ1bmN0aW9uIE5hbWUiKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKykgewogICAgICBpZiAoaTxwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKSB7CgkgIGVuYW1lPShjaGFyKilSVkEoKm5hbWUrKyk7CgkgIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyAlNGQgICAgJTguOGx4ICglOC44bHgpXG4iLGVuYW1lLCpvcmRpbmFsLGZ1bmN0aW9uc1sqb3JkaW5hbF0sKmZ1bmN0aW9uKTsKCSAgc3ByaW50ZihidWZmZXIsIiVzXyVzIixNb2R1bGUsZW5hbWUpOwoJICBkYWRkci5vZmY9UlZBKGZ1bmN0aW9uc1sqb3JkaW5hbF0pOwoJICBvcmRpbmFsKys7CgkgIGZ1bmN0aW9uKys7CiAgICAgIH0gZWxzZSB7CiAgICAgIAkgIC8qIG9yZGluYWxzL25hbWVzIG5vIGxvbmdlciB2YWxpZCwgYnV0IHdlIHN0aWxsIGdvdCBmdW5jdGlvbnMgKi8KCSAgZHByaW50Zl93aW4zMihzdGRkZWIsIiUtMzJzICU0cyAgICAlOHMgJTguOGx4XG4iLCIiLCIiLCIiLCpmdW5jdGlvbik7CgkgIHNwcmludGYoYnVmZmVyLCIlc18lZCIsTW9kdWxlLGkpOwoJICBkYWRkci5vZmY9UlZBKCpmdW5jdGlvbnMpOwoJICBmdW5jdGlvbisrOwogICAgICB9CiAgICAgIERFQlVHX0FkZFN5bWJvbChidWZmZXIsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpGQVJQUk9DMzIgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oc3RydWN0IHBlX2RhdGEgKnBlLCBMUENTVFIgZnVuY05hbWUpCnsKCUlNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKiBleHBvcnRzID0gcGUtPnBlX2V4cG9ydDsKCXVuc2lnbmVkIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7Cgl1X3Nob3J0ICogb3JkaW5hbDsKCXVfbG9uZyAqIGZ1bmN0aW9uOwoJdV9jaGFyICoqIG5hbWUsICplbmFtZTsKCWludCBpOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpCgkJcmV0dXJuIE5VTEw7CglvcmRpbmFsPSh1X3Nob3J0KikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0odV9sb25nKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lPSh1X2NoYXIgKiopIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CglpZiAoSElXT1JEKGZ1bmNOYW1lKSkgewoJCWZvcihpPTA7IGk8ZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKSB7CgkJCWVuYW1lPShjaGFyKikgUlZBKCpuYW1lKTsKCQkJaWYoIXN0cmNtcChlbmFtZSxmdW5jTmFtZSkpCgkJCQlyZXR1cm4gKEZBUlBST0MzMikgUlZBKGZ1bmN0aW9uWypvcmRpbmFsXSk7CgkJCW9yZGluYWwrKzsKCQkJbmFtZSsrOwoJCX0KCX0gZWxzZSB7CgkJaWYgKExPV09SRChmdW5jTmFtZSktZXhwb3J0cy0+QmFzZSA+IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKSB7CgkJCWRwcmludGZfd2luMzIoc3RkZGViLCIJb3JkaW5hbCAlZCBvdXQgb2YgcmFuZ2UhXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPV09SRChmdW5jTmFtZSkpOwoJCQlyZXR1cm4gTlVMTDsKCQl9CgkJcmV0dXJuIChGQVJQUk9DMzIpIFJWQShmdW5jdGlvblsoaW50KWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2VdKTsKCX0KCXJldHVybiBOVUxMOwp9Cgp2b2lkIApmaXh1cF9pbXBvcnRzIChzdHJ1Y3QgcGVfZGF0YSAqcGUsIEhNT0RVTEUxNiBoTW9kdWxlKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcGVfaW1wOwogICAgaW50CWZpeHVwX2ZhaWxlZCA9IDA7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gcGUtPmxvYWRfYWRkcjsKICAgIGludCBpOwogICAgTkVfTU9EVUxFICpuZV9tb2Q7CiAgICBITU9EVUxFMTYgKm1vZF9wdHI7CiAgICBjaGFyICptb2RuYW1lOwogICAgCiAgICBpZiAocGUtPnBlX2V4cG9ydCkKICAgIAltb2RuYW1lID0gKGNoYXIqKSBSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIlxuRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZS0+cGVfaW1wb3J0OwoKICAgIC8qIEZJWE1FOiBzaG91bGQgdGVybWluYXRlIG9uIDAgQ2hhcmFjdGVyaXN0aWNzICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKQoJaSsrOwoKICAgIC8qIE5vdywgYWxsb2NhdGUgbWVtb3J5IGZvciBkbGxzX3RvX2luaXQgKi8KICAgIG5lX21vZCA9IEdsb2JhbExvY2sxNiAoaE1vZHVsZSk7CiAgICBuZV9tb2QtPmRsbHNfdG9faW5pdCA9IEdMT0JBTF9BbGxvYyhHTUVNX1pFUk9JTklULCAoaSsxKSpzaXplb2YoSE1PRFVMRTE2KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhNb2R1bGUsIEZBTFNFLCBGQUxTRSwgRkFMU0UpOwogICAgbW9kX3B0ciA9IEdsb2JhbExvY2sxNiAobmVfbW9kLT5kbGxzX3RvX2luaXQpOwogICAgLyogbG9hZCB0aGUgbW9kdWxlcyBhbmQgcHV0IHRoZWlyIGhhbmRsZXMgaW50byB0aGUgbGlzdCAqLwogCiAgICAgLyogRklYTUU6IHNob3VsZCB0ZXJtaW5hdGUgb24gMCBDaGFyYWN0ZXJpc3RpY3MgKi8KICAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZS0+cGVfaW1wb3J0OyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKSB7CiAJY2hhciAqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoJbW9kX3B0cltpXSA9IE1PRFVMRV9Mb2FkKCBuYW1lLCAoTFBWT0lEKS0xLCBGQUxTRSApOwoJaWYgKG1vZF9wdHJbaV0gPD0gKEhNT0RVTEUxNikgMzIpIHsKCSAgICBjaGFyICpwLCBidWZmZXJbMjU2XTsKCgkgICAgLyogVHJ5IHdpdGggcHJlcGVuZGluZyB0aGUgcGF0aCBvZiB0aGUgY3VycmVudCBtb2R1bGUgKi8KCSAgICBHZXRNb2R1bGVGaWxlTmFtZTE2IChoTW9kdWxlLCBidWZmZXIsIHNpemVvZiAoYnVmZmVyKSk7CgkgICAgaWYgKCEocCA9IHN0cnJjaHIgKGJ1ZmZlciwgJ1xcJykpKQoJCXAgPSBidWZmZXI7CgkgICAgc3RyY3B5IChwICsgMSwgbmFtZSk7CgkgICAgbW9kX3B0cltpXSA9IE1PRFVMRV9Mb2FkKCBidWZmZXIsIChMUFZPSUQpLTEsIEZBTFNFICk7Cgl9CglpZiAobW9kX3B0cltpXSA8PSAoSE1PRFVMRTE2KSAzMikgewoJICAgIGZwcmludGYgKHN0ZGVyciwgIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsIG5hbWUpOwoJICAgIGV4aXQgKDApOwoJfQoJaSsrOwogICAgfQogICAgcGVfaW1wID0gcGUtPnBlX2ltcG9ydDsKICAgIHdoaWxlIChwZV9pbXAtPk5hbWUpIHsKCWNoYXIJCQkqTW9kdWxlOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglMUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKCWludAkJCW9yZGltcG9ydHdhcm5lZDsKCiAgICAgICAgb3JkaW1wb3J0d2FybmVkID0gMDsKCU1vZHVsZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoJZHByaW50Zl93aW4zMiAoc3RkZGViLCAiJXNcbiIsIE1vZHVsZSk7CgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayk7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgaWYoIWxzdHJuY21waTMyQShNb2R1bGUsImtlcm5lbDMyIiw4KSAmJiAhb3JkaW1wb3J0d2FybmVkKXsKCQkgICAgICAgZnByaW50ZihzdGRlcnIsIiVzIGltcG9ydHMga2VybmVsMzIuZGxsIGJ5IG9yZGluYWwuIE1heSBjcmFzaC5cbiIsbW9kbmFtZSk7CgkJICAgICAgIG9yZGltcG9ydHdhcm5lZCA9IDE7CgkJICAgIH0KCQkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiLS0tIE9yZGluYWwgJXMsJWRcbiIsIE1vZHVsZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSwoTFBDU1RSKW9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoTFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICItLS0gJXMgJXMuJWRcbiIsIHBlX25hbWUtPk5hbWUsIE1vZHVsZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoCgkJCQkJCU1PRFVMRV9GaW5kTW9kdWxlIChNb2R1bGUpLAoJCQkJCQlwZV9uYW1lLT5OYW1lKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCgkJICAgIGlmICghbHN0cm5jbXBpMzJBKE1vZHVsZSwia2VybmVsMzIiLDgpICYmIAoJCSAgICAJIW9yZGltcG9ydHdhcm5lZAoJCSAgICApIHsKCQkgICAgICAgZnByaW50ZihzdGRlcnIsIiVzIGltcG9ydHMga2VybmVsMzIuZGxsIGJ5IG9yZGluYWwuIE1heSBjcmFzaC5cbiIsbW9kbmFtZSk7CgkJICAgICAgIG9yZGltcG9ydHdhcm5lZCA9IDE7CgkJICAgIH0KCQkgICAgZHByaW50Zl93aW4zMihzdGRkZWIsIi0tLSBPcmRpbmFsICVzLiVkXG4iLE1vZHVsZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLAoJCQkJCQkgICAgIChMUENTVFIpIG9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oTFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLE1vZHVsZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLHBlX25hbWUtPk5hbWUpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJICAgIAlmcHJpbnRmKHN0ZGVyciwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CglwZV9pbXArKzsKICAgIH0KICAgIGlmIChmaXh1cF9mYWlsZWQpIGV4aXQoMSk7Cn0KCnN0YXRpYyB2b2lkIGNhbGNfdm1hX3NpemUoc3RydWN0IHBlX2RhdGEgKnBlKQp7CiAgaW50IGk7CgogIGRwcmludGZfd2luMzIoc3RkZGViLCAiRHVtcCBvZiBzZWdtZW50IHRhYmxlXG4iKTsKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIiAgIE5hbWUgICAgVlN6ICBWYWRkciAgICAgU3pSYXcgICBGaWxlYWRyICAqUmVsb2MgKkxpbmV1bSAjUmVsb2MgI0xpbnVtIENoYXJcbiIpOwogIGZvcihpPTA7IGk8IHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQogICAgewogICAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIiU4czogJTQuNGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTQuNHggJTQuNHggJTguOGx4XG4iLCAKCSAgICAgcGUtPnBlX3NlZ1tpXS5OYW1lLCAKCSAgICAgcGUtPnBlX3NlZ1tpXS5NaXNjLlZpcnR1YWxTaXplLAoJICAgICBwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzLAoJICAgICBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEsCgkgICAgIHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmF3RGF0YSwKCSAgICAgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SZWxvY2F0aW9ucywKCSAgICAgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9MaW5lbnVtYmVycywKCSAgICAgcGUtPnBlX3NlZ1tpXS5OdW1iZXJPZlJlbG9jYXRpb25zLAoJICAgICBwZS0+cGVfc2VnW2ldLk51bWJlck9mTGluZW51bWJlcnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uQ2hhcmFjdGVyaXN0aWNzKTsKCSAgcGUtPnZtYV9zaXplID0gTUFYKHBlLT52bWFfc2l6ZSwKCSAgCQlwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzICsgCgkJCXBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YSk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGRvX3JlbG9jYXRpb25zKHN0cnVjdCBwZV9kYXRhICpwZSkKewoJaW50IGRlbHRhID0gcGUtPmxvYWRfYWRkciAtIHBlLT5iYXNlX2FkZHI7Cgl1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gcGUtPmxvYWRfYWRkcjsKCUlNQUdFX0JBU0VfUkVMT0NBVElPTgkqciA9IHBlLT5wZV9yZWxvYzsKCWludCBoZGVsdGEgPSAoZGVsdGEgPj4gMTYpICYgMHhGRkZGOwoJaW50IGxkZWx0YSA9IGRlbHRhICYgMHhGRkZGOwoKCS8qIGludCByZWxvY19zaXplID0gKi8KCglpZihkZWx0YSA9PSAwKQoJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCQlyZXR1cm47Cgl3aGlsZShyLT5WaXJ0dWFsQWRkcmVzcykKCXsKCQljaGFyICpwYWdlID0gKGNoYXIqKSBSVkEoci0+VmlydHVhbEFkZHJlc3MpOwoJCWludCBjb3VudCA9IChyLT5TaXplT2ZCbG9jayAtIDgpLzI7CgkJaW50IGk7CgkJZHByaW50Zl9maXh1cChzdGRkZWIsICIleCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsCgkJCWNvdW50LCByLT5WaXJ0dWFsQWRkcmVzcyk7CgkJLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwoJCWZvcihpPTA7aTxjb3VudDtpKyspCgkJewoJCQlpbnQgb2Zmc2V0ID0gci0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwoJCQlpbnQgdHlwZSA9IHItPlR5cGVPZmZzZXRbaV0gPj4gMTI7CgkJCWRwcmludGZfZml4dXAoc3RkZGViLCJwYXRjaGluZyAleCB0eXBlICV4XG4iLCBvZmZzZXQsIHR5cGUpOwoJCQlzd2l0Y2godHlwZSkKCQkJewoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURTogYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0g6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGhkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGxkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgojaWYgMQoJCQkJKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CiNlbHNlCgkJCQl7IGludCBoPSoodW5zaWduZWQgc2hvcnQqKShwYWdlK29mZnNldCk7CgkJCQkgIGludCBsPXItPlR5cGVPZmZzZXRbKytpXTsKCQkJCSAgKih1bnNpZ25lZCBpbnQqKShwYWdlICsgb2Zmc2V0KSA9IChoPDwxNikgKyBsICsgZGVsdGE7CgkJCQl9CiNlbmRpZgoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hBREo6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIkRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9NSVBTX0pNUEFERFI6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIklzIHRoaXMgYSBNSVBTIG1hY2hpbmUgPz8/XG4iKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIGZpeHVwIHR5cGVcbiIpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJciA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04qKSgoY2hhciopciArIHItPlNpemVPZkJsb2NrKTsKCX0KfQoJCQoKCQoJCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCVBFX0xvYWRJbWFnZQogKiBMb2FkIG9uZSBQRSBmb3JtYXQgZXhlY3V0YWJsZSBpbnRvIG1lbW9yeQogKi8Kc3RhdGljIHZvaWQgUEVfTG9hZEltYWdlKCBzdHJ1Y3QgcHJfZGF0YSAqKnJldF9wZSwgaW50IGZkLCBITU9EVUxFMTYgaE1vZHVsZSwgV09SRCBvZmZzZXQsIE9GU1RSVUNUICpvZnMgKQp7CglzdHJ1Y3QgcGVfZGF0YQkJKnBlOwoJaW50CQkJaSwgcmVzdWx0OwoJaW50CQkJbG9hZF9hZGRyOwoJSU1BR0VfREFUQV9ESVJFQ1RPUlkJZGlyOwoJY2hhcgkJCWJ1ZmZlclsyMDBdOwoJREJHX0FERFIJCWRhZGRyOwoJY2hhcgkJCSptb2RuYW1lOwoKCWRhZGRyLnNlZz0wOwoJZGFkZHIudHlwZSA9IE5VTEw7CglwZSA9IHhtYWxsb2Moc2l6ZW9mKHN0cnVjdCBwZV9kYXRhKSk7CgltZW1zZXQocGUsMCxzaXplb2Yoc3RydWN0IHBlX2RhdGEpKTsKCXBlLT5wZV9oZWFkZXIgPSB4bWFsbG9jKHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSk7CgoJLyogcmVhZCBQRSBoZWFkZXIgKi8KCWxzZWVrKCBmZCwgb2Zmc2V0LCBTRUVLX1NFVCk7CglyZWFkKCBmZCwgcGUtPnBlX2hlYWRlciwgc2l6ZW9mKElNQUdFX05UX0hFQURFUlMpKTsKCglpZiAocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5NYWNoaW5lICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2KSB7CgkJZnByaW50ZihzdGRlcnIsInRyeWluZyB0byBsb2FkIFBFIGltYWdlIGZvciB1bnN1cHBvcnRlZCBhcmNoaXRlY3R1cmUgKCIpOwoJCXN3aXRjaCAocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5NYWNoaW5lKSB7CgkJY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfVU5LTk9XTjoKCQkJZnByaW50ZihzdGRlcnIsIlVua25vd24iKTticmVhazsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9JODYwOgoJCQlmcHJpbnRmKHN0ZGVyciwiSTg2MCIpO2JyZWFrOwoJCWNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IzMDAwOgoJCQlmcHJpbnRmKHN0ZGVyciwiUjMwMDAiKTticmVhazsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SNDAwMDoKCQkJZnByaW50ZihzdGRlcnIsIlI0MDAwIik7YnJlYWs7CgkJY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjEwMDAwOgoJCQlmcHJpbnRmKHN0ZGVyciwiUjEwMDAwIik7YnJlYWs7CgkJY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfQUxQSEE6CgkJCWZwcmludGYoc3RkZXJyLCJBbHBoYSIpO2JyZWFrOwoJCWNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1BPV0VSUEM6CgkJCWZwcmludGYoc3RkZXJyLCJQb3dlclBDIik7YnJlYWs7CgkJZGVmYXVsdDoKCQkJZnByaW50ZihzdGRlcnIsIlVua25vd24tJTA0eCIscGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5NYWNoaW5lKTticmVhazsKCQl9CgkJZnByaW50ZihzdGRlcnIsIilcbiIpOwoJCXJldHVybjsKCX0KCi8qIEZJWE1FOiB0aGlzIGlzIGEgKmhvcnJpYmxlKiBoYWNrIHRvIG1ha2UgQ09NRExHMzIuRExMIGxvYWQgT0suIFRoZQpwcm9ibGVtIG5lZWRzIHRvIGJlIGZpeGVkIHByb3Blcmx5IGF0IHNvbWUgc3RhZ2UgKi8KCglpZiAocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuTnVtYmVyT2ZSdmFBbmRTaXplcyAhPSAxNikgewoJCXByaW50ZigiU2hvcnQgUEUgSGVhZGVyISEhXG4iKTsKCQlsc2VlayggZmQsIC0oMTYgLSBwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5OdW1iZXJPZlJ2YUFuZFNpemVzKSAqIHNpemVvZihJTUFHRV9EQVRBX0RJUkVDVE9SWSksIFNFRUtfQ1VSKTsKCX0KCi8qIGhvcnJpYmxlIGhhY2sgZW5kcyAhISEgKi8KCS8qIHJlYWQgc2VjdGlvbnMgKi8KCXBlLT5wZV9zZWcgPSB4bWFsbG9jKHNpemVvZihJTUFHRV9TRUNUSU9OX0hFQURFUikgKiAKCQkJCSAgIHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucyk7CglyZWFkKCBmZCwgcGUtPnBlX3NlZywgc2l6ZW9mKElNQUdFX1NFQ1RJT05fSEVBREVSKSAqIAoJCQlwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnMpOwoKCWxvYWRfYWRkciA9IHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCXBlLT5iYXNlX2FkZHI9bG9hZF9hZGRyOwoJcGUtPnZtYV9zaXplPTA7CglkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkxvYWQgYWRkciBpcyAleFxuIixsb2FkX2FkZHIpOwoJY2FsY192bWFfc2l6ZShwZSk7CgojaWYgMAoJLyogV2UgdXNlIG1hbGxvYyBoZXJlLCB3aGlsZSBhIGh1Z2UgcGFydCBvZiB0aGF0IGFkZHJlc3Mgc3BhY2UgZG9lcwoJICAgbm90IGJlIHN1cHBvcnRlZCBieSBhY3R1YWwgbWVtb3J5LiBJdCBoYXMgdG8gYmUgY29udGlndW91cywgdGhvdWdoLgoJICAgSSBkb24ndCBrbm93IGlmIG1tYXAoIi9kZXYvbnVsbCIpOyB3b3VsZCBkbyBhbnkgYmV0dGVyLgoJICAgV2hhdCBJJ2QgcmVhbGx5IGxpa2UgdG8gZG8gaXMgYSBXaW4zMiBzdHlsZSBWaXJ0dWFsQWxsb2MvTWFwVmlld09mRmlsZQoJICAgc2VxdWVuY2UgKi8KCWxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHIgPSAoaW50KXhtYWxsb2MocGUtPnZtYV9zaXplKTsKCW1lbXNldCggbG9hZF9hZGRyLCAwLCBwZS0+dm1hX3NpemUpOwojZWxzZQoJbG9hZF9hZGRyID0gKGludCkgVmlydHVhbEFsbG9jKCAodm9pZCopcGUtPmJhc2VfYWRkciwgcGUtPnZtYV9zaXplLCBNRU1fUkVTRVJWRXxNRU1fQ09NTUlULCBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CiAgICAgICAgcGUtPmxvYWRfYWRkciA9IGxvYWRfYWRkcjsKI2VuZGlmCgoJZHByaW50Zl93aW4zMihzdGRkZWIsICJMb2FkIGFkZHIgaXMgcmVhbGx5ICV4LCByYW5nZSAleFxuIiwKCQlwZS0+bG9hZF9hZGRyLCBwZS0+dm1hX3NpemUpOwoJCgoJZm9yKGk9MDsgaSA8IHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQoJewoJCS8qIGxvYWQgb25seSBub24tQlNTIHNlZ21lbnRzICovCgkJaWYoIShwZS0+cGVfc2VnW2ldLkNoYXJhY3RlcmlzdGljcyAmIAoJCQlJTUFHRV9TQ05fQ05UX1VOSU5JVElBTElaRURfREFUQSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYobHNlZWsoZmQscGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SYXdEYXRhLFNFRUtfU0VUKSA9PSAtMQogICAgICAgICAgICAgICAgICAgICAgIHx8IHJlYWQoZmQsKGNoYXIqKVJWQShwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YSkgIT0gcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhKQogICAgICAgICAgICAgICAgICAgIHsKCQkJZnByaW50ZihzdGRlcnIsIkZhaWxlZCB0byBsb2FkIHNlY3Rpb24gJXhcbiIsIGkpOwoJCQlleGl0KDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCQlyZXN1bHQgPSBSVkEgKHBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MpOwojaWYgMQoJCS8qIG5vdCBuZWVkZWQsIG1lbW9yeSBpcyB6ZXJvICovCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5ic3MiKSA9PSAwKQoJCSAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgPwoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgOgoJCQkgICBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpOwojZW5kaWYKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5pZGF0YSIpID09IDApCgkJCXBlLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgcmVzdWx0OwoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmVkYXRhIikgPT0gMCkKCQkJcGUtPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5yc3JjIikgPT0gMCkKCQkJcGUtPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIucmVsb2MiKSA9PSAwKQoJCQlwZS0+cGVfcmVsb2MgPSAoTFBJTUFHRV9CQVNFX1JFTE9DQVRJT04pIHJlc3VsdDsKCgl9CgoJLyogVGhlcmUgaXMgd29yZCB0aGF0IHRoZSBhY3R1YWwgbG9hZGVyIGRvZXMgbm90IGNhcmUgYWJvdXQgdGhlCgkgICBzZWN0aW9uIG5hbWVzLCBhbmQgb25seSBnb2VzIGZvciB0aGUgRGF0YURpcmVjdG9yeSAqLwoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfZXhwb3J0ICYmIChpbnQpcGUtPnBlX2V4cG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBleHBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCS8qIGFsd2F5cyB0cnVzdCB0aGUgZGlyZWN0b3J5ICovCgkJcGUtPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlRdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGUtPnBlX2ltcG9ydCAmJiAoaW50KXBlLT5wZV9pbXBvcnQhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgaW1wb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQlwZS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9SRVNPVVJDRV07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfcmVzb3VyY2UgJiYgKGludClwZS0+cGVfcmVzb3VyY2UhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgcmVzb3VyY2UgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCgoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0NdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGUtPnBlX3JlbG9jICYmIChpbnQpcGUtPnBlX3JlbG9jIT0gUlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZWxvY2F0aW9uIGxpc3Q/P1xuIik7CgkJcGUtPnBlX3JlbG9jID0gKHZvaWQgKikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlNpemUpCgkgIHsKCSAgICBERUJVR19SZWdpc3RlckRlYnVnSW5mbyhmZCwgcGUsIGxvYWRfYWRkciwgCgkJCXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHXS5WaXJ0dWFsQWRkcmVzcywKCQkJcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlNpemUpOwoJICB9CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09QWVJJR0hUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiQ29weXJpZ2h0IHN0cmluZyBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9HTE9CQUxQVFJdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJHbG9iYWwgUG9pbnRlciAoTUlQUykgaWdub3JlZFxuIik7CgojaWZkZWYgTk9UCS8qIHdlIGluaXRpYWxpemUgdGhpcyBsYXRlciAqLwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfVExTXS5TaXplKQoJCSBkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlRocmVhZCBsb2NhbCBzdG9yYWdlIGlnbm9yZWRcbiIpOwojZW5kaWYKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJR10uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkxvYWQgQ29uZmlndXJhdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQk9VTkRfSU1QT1JUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiQm91bmQgSW1wb3J0IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JQVRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJJbXBvcnQgQWRkcmVzcyBUYWJsZSBkaXJlY3RvcnkgaWdub3JlZFxuIik7CglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzEzXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiVW5rbm93biBkaXJlY3RvcnkgMTMgaWdub3JlZFxuIik7CglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzE0XS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIik7CglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzE1XS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiVW5rbm93biBkaXJlY3RvcnkgMTUgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX3JlbG9jKSBkb19yZWxvY2F0aW9ucyhwZSk7CgoJLyogRG8gZXhwb3J0cyBiZWZvcmUgaW1wb3J0cyBiZWNhdXNlIGZpeHVwX2ltcG9ydHMKCSAqIG1heSBsb2FkIGEgbW9kdWxlIHRoYXQgcmVmZXJlbmNlcyB0aGlzIG1vZHVsZS4KCSAqLwoKCWlmKHBlLT5wZV9leHBvcnQpIGR1bXBfZXhwb3J0cyhwZS0+cGVfZXhwb3J0LGxvYWRfYWRkcik7CgkqcmV0X3BlID0gcGU7CS8qIG1ha2UgZXhwb3J0IGxpc3QgYXZhaWxhYmxlIGZvciBHZXRQcm9jQWRkcmVzcyAqLwoJaWYocGUtPnBlX2ltcG9ydCkgZml4dXBfaW1wb3J0cyhwZSwgaE1vZHVsZSk7CiAgCQkKCWlmIChwZS0+cGVfZXhwb3J0KQoJCW1vZG5hbWUgPSAoY2hhciopUlZBKHBlLT5wZV9leHBvcnQtPk5hbWUpOwoJZWxzZSB7CgkJY2hhciAqczsKCQltb2RuYW1lID0gcyA9IG9mcy0+c3pQYXRoTmFtZTsKCQl3aGlsZSAocz1zdHJjaHIobW9kbmFtZSwnXFwnKSkKCQkJbW9kbmFtZSA9IHMrMTsKCQlpZiAoKHM9c3RyY2hyKG1vZG5hbWUsJy4nKSkpCgkJCSpzPSdcMCc7Cgl9CgoJLyogYWRkIHN0YXJ0IG9mIHNlY3Rpb25zIGFzIGRlYnVnc3ltYm9scyAqLwoJZm9yKGk9MDtpPHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucztpKyspIHsKCQlzcHJpbnRmKGJ1ZmZlciwiJXNfJXMiLG1vZG5hbWUscGUtPnBlX3NlZ1tpXS5OYW1lKTsKCQlkYWRkci5vZmY9IFJWQShwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzKTsKCQlERUJVR19BZGRTeW1ib2woYnVmZmVyLCZkYWRkciwgTlVMTCwgU1lNX1dJTjMyIHwgU1lNX0ZVTkMpOwoJfQoJLyogYWRkIGVudHJ5IHBvaW50ICovCglzcHJpbnRmKGJ1ZmZlciwiJXNfRW50cnlQb2ludCIsbW9kbmFtZSk7CglkYWRkci5vZmY9UlZBKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpOwoJREVCVUdfQWRkU3ltYm9sKGJ1ZmZlciwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKCS8qIGFkZCBzdGFydCBvZiBETEwgKi8KCWRhZGRyLm9mZj1sb2FkX2FkZHI7CglERUJVR19BZGRTeW1ib2wobW9kbmFtZSwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKfQoKSElOU1RBTkNFMTYgTU9EVUxFX0NyZWF0ZUluc3RhbmNlKEhNT0RVTEUxNiBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CgpISU5TVEFOQ0UxNiBQRV9Mb2FkTW9kdWxlKCBIRklMRTMyIGhGaWxlLCBPRlNUUlVDVCAqb2ZzLCBMT0FEUEFSQU1TKiBwYXJhbXMgKQp7CiAgICBITU9EVUxFMTYgaE1vZHVsZTsKICAgIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKICAgIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogICAgaW50IGZkOwoKICAgIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggb2ZzICkpIDwgMzIpIHJldHVybiBoTW9kdWxlOwogICAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUgKTsKICAgIHBNb2R1bGUtPmZsYWdzID0gTkVfRkZMQUdTX1dJTjMyOwoKICAgIC8qIEZJWE1FOiBIYWNrIGJlY2F1c2UgUEVfTG9hZE1vZHVsZSBpcyByZWN1cnNpdmUgKi8KICAgIGZkID0gZHVwKCBGSUxFX0dldFVuaXhIYW5kbGUoaEZpbGUpICk7CiAgICBfbGNsb3NlMzIoIGhGaWxlICk7CiAgICBsc2VlayggZmQsIDAsIFNFRUtfU0VUICk7CiAgICByZWFkKCBmZCwgJm16X2hlYWRlciwgc2l6ZW9mKG16X2hlYWRlcikgKTsKCiAgICBQRV9Mb2FkSW1hZ2UoICZwTW9kdWxlLT5wZV9tb2R1bGUsIGZkLCBoTW9kdWxlLCBtel9oZWFkZXIuZV9sZmFuZXcsIG9mcyApOwogICAgaWYgKCFwTW9kdWxlLT5wZV9tb2R1bGUpCiAgICAJcmV0dXJuIDIxOwogICAgY2xvc2UoIGZkICk7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlLCBwYXJhbXMgKTsKCiAgICBpZiAoIShwTW9kdWxlLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgVEFTS19DcmVhdGVUYXNrKCBoTW9kdWxlLCBoSW5zdGFuY2UsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmhFbnZpcm9ubWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgIChMUFNUUilQVFJfU0VHX1RPX0xJTiggcGFyYW1zLT5jbWRMaW5lICksCiAgICAgICAgICAgICAgICAgICAgICAgICAqKChXT1JEKilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPnNob3dDbWQpICsgMSkgKTsKICAgIH0KICAgIHJldHVybiBoSW5zdGFuY2U7Cn0KCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRTE2IGhNb2R1bGUgKQp7CglwcmludGYoIlBFdW5sb2FkSW1hZ2UoKSBjYWxsZWQhXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8Kc3RhdGljIHZvaWQgUEVfSW5pdERMTChITU9EVUxFMTYgaE1vZHVsZSwgRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgUEVfTU9EVUxFICpwZTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHI7CgogICAgaE1vZHVsZSA9IEdldEV4ZVB0cihoTW9kdWxlKTsKICAgIGlmICghKHBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKGhNb2R1bGUpKSkgcmV0dXJuOwogICAgaWYgKCEocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfV0lOMzIpIHx8ICEocGUgPSBwTW9kdWxlLT5wZV9tb2R1bGUpKQogICAgICAgIHJldHVybjsKCiAgICAvKiAgRExMX0FUVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBmb3IgZHluYW1pYyBsb2Fkcywgbm90LU5VTEwgZm9yIHN0YXRpYyBsb2FkcwogICAgICogIERMTF9ERVRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgaWYgY2FsbGVkIGJ5IEZyZWVMaWJyYXJ5LCBub3QtTlVMTCBvdGhlcndpc2UKICAgICAqICB0aGUgU0RLIGRvZXNuJ3QgbWVudGlvbiBhbnl0aGluZyBmb3IgRExMX1RIUkVBRF8qCiAgICAgKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKAkocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKCQkocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7CglwcmludGYoIkluaXRQRURMTCgpIGNhbGxlZCFcbiIpOwoJQ2FsbERMTEVudHJ5UHJvYzMyKCAKCSAgICAoRkFSUFJPQzMyKVJWQShwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSwKCSAgICBoTW9kdWxlLAoJICAgIHR5cGUsCgkgICAgKERXT1JEKWxwUmVzZXJ2ZWQKCSk7CiAgICB9Cn0KCnZvaWQgUEVfSW5pdGlhbGl6ZURMTHMoSE1PRFVMRTE2IGhNb2R1bGUsRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewoJTkVfTU9EVUxFICpwTW9kdWxlOwoJSE1PRFVMRTE2ICpwRExMOwoJcE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoIEdldEV4ZVB0cihoTW9kdWxlKSApOwoJaWYgKHBNb2R1bGUtPmRsbHNfdG9faW5pdCkKCXsKCQlIR0xPQkFMMTYgdG9faW5pdCA9IHBNb2R1bGUtPmRsbHNfdG9faW5pdDsKCQlwTW9kdWxlLT5kbGxzX3RvX2luaXQgPSAwOwoJCgkJZm9yIChwRExMID0gKEhNT0RVTEUxNiAqKUdsb2JhbExvY2sxNiggdG9faW5pdCApOyAqcERMTDsgcERMTCsrKQoJCXsKICAgICAgICAgICAgICAgICAgICBQRV9Jbml0aWFsaXplRExMcyggKnBETEwsIHR5cGUsIGxwUmVzZXJ2ZWQpOwoJCX0KCQlHbG9iYWxGcmVlMTYoIHRvX2luaXQgKTsKCX0KCVBFX0luaXRETEwoIGhNb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKfQoKdm9pZCBQRV9Jbml0VGxzKCBQRV9NT0RVTEUgKm1vZHVsZSApCnsKICAgLyogRklYTUU6IHRscyBjYWxsYmFja3MgPz8/ICovCiAgIERXT1JEICBpbmRleDsKICAgRFdPUkQgIGRhdGFzaXplOwogICBEV09SRCAgc2l6ZTsKICAgTFBWT0lEIG1lbTsKICAgTFBJTUFHRV9UTFNfRElSRUNUT1JZIHBkaXI7CgogICAgaWYgKCFtb2R1bGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykKICAgICAgICByZXR1cm47CgogICAgcGRpciA9IChMUFZPSUQpKG1vZHVsZS0+bG9hZF9hZGRyICsgbW9kdWxlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLgogICAgICAgICAgICAgICBEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKICAgIGluZGV4ID0gVGxzQWxsb2MoKTsKICAgIGRhdGFzaXplID0gcGRpci0+RW5kQWRkcmVzc09mUmF3RGF0YS1wZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGE7CiAgICBzaXplICAgICA9IGRhdGFzaXplICsgcGRpci0+U2l6ZU9mWmVyb0ZpbGw7CiAgICAgICAgCiAgICBtZW0gPSBWaXJ0dWFsQWxsb2MoMCxzaXplLCBNRU1fUkVTRVJWRXxNRU1fQ09NTUlULCBQQUdFX1JFQURXUklURSApOwogICAgCiAgICBtZW1jcHkobWVtLChMUFZPSUQpIHBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSwgZGF0YXNpemUpOwogICAgVGxzU2V0VmFsdWUoaW5kZXgsbWVtKTsKICAgICoocGRpci0+QWRkcmVzc09mSW5kZXgpPWluZGV4OyAgIAp9CgojZW5kaWYgLyogV0lORUxJQiAqLwo=