I2lmbmRlZiBXSU5FTElCCi8qIAogKiAgQ29weXJpZ2h0CTE5OTQJRXJpYyBZb3VuZGFsZSAmIEVyaWsgQm9zCiAqICBDb3B5cmlnaHQJMTk5NQlNYXJ0aW4gdm9uIEz2d2lzCiAqICBDb3B5cmlnaHQgICAxOTk2ICAgIE1hcmN1cyBNZWlzc25lcgogKgogKgliYXNlZCBvbiBFcmljIFlvdW5kYWxlJ3MgcGUtdGVzdCBhbmQ6CiAqCiAqCWZ0cC5taWNyb3NvZnQuY29tOi9wdWIvZGV2ZWxvcGVyL01TRE4vQ0Q4L1BFRklMRS5aSVAKICogbWFrZSB0aGF0OgogKglmdHAubWljcm9zb2Z0LmNvbTovZGV2ZWxvcHIvTVNETi9PY3RDRC9QRUZJTEUuWklQCiAqLwoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwZV9pbWFnZS5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJnbG9iYWwuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAic3RkZGVidWcuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJkZWJ1Z2dlci5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgoKc3RhdGljIHZvaWQgUEVfSW5pdERMTChITU9EVUxFMTYgaE1vZHVsZSwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQpOwoKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodW5zaWduZWQgaW50KWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkKCnZvaWQgZHVtcF9leHBvcnRzKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKiBwZV9leHBvcnRzLCB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyKQp7IAogIGNoYXIJCSpNb2R1bGUsKnM7CiAgaW50CQlpOwogIHVfc2hvcnQJKm9yZGluYWw7CiAgdV9sb25nCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIHVfY2hhcgkqKm5hbWUsKmVuYW1lOwogIGNoYXIJCWJ1ZmZlclsxMDAwXTsKICBEQkdfQUREUglkYWRkcjsKCiAgZGFkZHIuc2VnID0gMDsKICBkYWRkci50eXBlID0gTlVMTDsKICBNb2R1bGUgPSAoY2hhciopUlZBKHBlX2V4cG9ydHMtPk5hbWUpOwogIGRwcmludGZfd2luMzIoc3RkZGViLCJcbioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJIE1vZHVsZSwKCSBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywKCSBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKTsKCiAgb3JkaW5hbD0odV9zaG9ydCopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucz1mdW5jdGlvbj0odV9sb25nKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZT0odV9jaGFyKiopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyBPcmRpbmFsIFZpcnQgQWRkclxuIiwgIkZ1bmN0aW9uIE5hbWUiKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKykgewogICAgICBpZiAoaTxwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKSB7CgkgIGVuYW1lPShjaGFyKilSVkEoKm5hbWUrKyk7CgkgIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyAlNGQgICAgJTguOGx4ICglOC44bHgpXG4iLGVuYW1lLCpvcmRpbmFsLGZ1bmN0aW9uc1sqb3JkaW5hbF0sKmZ1bmN0aW9uKTsKCSAgc3ByaW50ZihidWZmZXIsIiVzXyVzIixNb2R1bGUsZW5hbWUpOwoJICBkYWRkci5vZmY9UlZBKGZ1bmN0aW9uc1sqb3JkaW5hbF0pOwoJICBvcmRpbmFsKys7CgkgIGZ1bmN0aW9uKys7CiAgICAgIH0gZWxzZSB7CiAgICAgIAkgIC8qIG9yZGluYWxzL25hbWVzIG5vIGxvbmdlciB2YWxpZCwgYnV0IHdlIHN0aWxsIGdvdCBmdW5jdGlvbnMgKi8KCSAgZHByaW50Zl93aW4zMihzdGRkZWIsIiUtMzJzICU0cyAgICAlOHMgJTguOGx4XG4iLCIiLCIiLCIiLCpmdW5jdGlvbik7CgkgIHNwcmludGYoYnVmZmVyLCIlc18lZCIsTW9kdWxlLGkpOwoJICBkYWRkci5vZmY9UlZBKCpmdW5jdGlvbnMpOwoJICBmdW5jdGlvbisrOwogICAgICB9CiAgICAgIHdoaWxlICgocz1zdHJjaHIoYnVmZmVyLCcuJykpKSAqcz0nXyc7CiAgICAgIERFQlVHX0FkZFN5bWJvbChidWZmZXIsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpGQVJQUk9DMzIgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oc3RydWN0IHBlX2RhdGEgKnBlLCBMUENTVFIgZnVuY05hbWUpCnsKCUlNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKiBleHBvcnRzID0gcGUtPnBlX2V4cG9ydDsKCXVuc2lnbmVkIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7Cgl1X3Nob3J0ICogb3JkaW5hbDsKCXVfbG9uZyAqIGZ1bmN0aW9uOwoJdV9jaGFyICoqIG5hbWUsICplbmFtZTsKCWludCBpOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCWRwcmludGZfd2luMzIoc3RkZGViLCJQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpCgkJcmV0dXJuIE5VTEw7CglvcmRpbmFsPSh1X3Nob3J0KikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0odV9sb25nKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lPSh1X2NoYXIgKiopIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CglpZiAoSElXT1JEKGZ1bmNOYW1lKSkgewoJCWZvcihpPTA7IGk8ZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKSB7CgkJCWVuYW1lPShjaGFyKikgUlZBKCpuYW1lKTsKCQkJaWYoIXN0cmNtcChlbmFtZSxmdW5jTmFtZSkpCgkJCQlyZXR1cm4gKEZBUlBST0MzMikgUlZBKGZ1bmN0aW9uWypvcmRpbmFsXSk7CgkJCW9yZGluYWwrKzsKCQkJbmFtZSsrOwoJCX0KCX0gZWxzZSB7CgkJaWYgKExPV09SRChmdW5jTmFtZSktZXhwb3J0cy0+QmFzZSA+IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKSB7CgkJCWRwcmludGZfd2luMzIoc3RkZGViLCIJb3JkaW5hbCAlZCBvdXQgb2YgcmFuZ2UhXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPV09SRChmdW5jTmFtZSkpOwoJCQlyZXR1cm4gTlVMTDsKCQl9CgkJcmV0dXJuIChGQVJQUk9DMzIpIFJWQShmdW5jdGlvblsoaW50KWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2VdKTsKCX0KCXJldHVybiBOVUxMOwp9Cgp2b2lkIApmaXh1cF9pbXBvcnRzIChzdHJ1Y3QgcGVfZGF0YSAqcGUsIEhNT0RVTEUxNiBoTW9kdWxlKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcGVfaW1wOwogICAgaW50CWZpeHVwX2ZhaWxlZCA9IDA7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gcGUtPmxvYWRfYWRkcjsKICAgIGludCBpOwogICAgTkVfTU9EVUxFICpuZV9tb2Q7CiAgICBITU9EVUxFMTYgKm1vZF9wdHI7CiAgICBjaGFyICptb2RuYW1lOwogICAgCiAgICBpZiAocGUtPnBlX2V4cG9ydCkKICAgIAltb2RuYW1lID0gKGNoYXIqKSBSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIlxuRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZS0+cGVfaW1wb3J0OwoKICAgIC8qIEZJWE1FOiBzaG91bGQgdGVybWluYXRlIG9uIDAgQ2hhcmFjdGVyaXN0aWNzICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKQoJaSsrOwoKICAgIC8qIE5vdywgYWxsb2NhdGUgbWVtb3J5IGZvciBkbGxzX3RvX2luaXQgKi8KICAgIG5lX21vZCA9IEdsb2JhbExvY2sxNiAoaE1vZHVsZSk7CiAgICBuZV9tb2QtPmRsbHNfdG9faW5pdCA9IEdMT0JBTF9BbGxvYyhHTUVNX1pFUk9JTklULCAoaSsxKSpzaXplb2YoSE1PRFVMRTE2KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhNb2R1bGUsIEZBTFNFLCBGQUxTRSwgRkFMU0UpOwogICAgbW9kX3B0ciA9IEdsb2JhbExvY2sxNiAobmVfbW9kLT5kbGxzX3RvX2luaXQpOwogICAgLyogbG9hZCB0aGUgbW9kdWxlcyBhbmQgcHV0IHRoZWlyIGhhbmRsZXMgaW50byB0aGUgbGlzdCAqLwogCiAgICAgLyogRklYTUU6IHNob3VsZCB0ZXJtaW5hdGUgb24gMCBDaGFyYWN0ZXJpc3RpY3MgKi8KICAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZS0+cGVfaW1wb3J0OyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKSB7CiAJY2hhciAqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoJbW9kX3B0cltpXSA9IE1PRFVMRV9Mb2FkKCBuYW1lLCAoTFBWT0lEKS0xLCBGQUxTRSApOwoJaWYgKG1vZF9wdHJbaV0gPD0gKEhNT0RVTEUxNikgMzIpIHsKCSAgICBjaGFyICpwLCBidWZmZXJbMjU2XTsKCgkgICAgLyogVHJ5IHdpdGggcHJlcGVuZGluZyB0aGUgcGF0aCBvZiB0aGUgY3VycmVudCBtb2R1bGUgKi8KCSAgICBHZXRNb2R1bGVGaWxlTmFtZTE2IChoTW9kdWxlLCBidWZmZXIsIHNpemVvZiAoYnVmZmVyKSk7CgkgICAgaWYgKCEocCA9IHN0cnJjaHIgKGJ1ZmZlciwgJ1xcJykpKQoJCXAgPSBidWZmZXI7CgkgICAgc3RyY3B5IChwICsgMSwgbmFtZSk7CgkgICAgbW9kX3B0cltpXSA9IE1PRFVMRV9Mb2FkKCBidWZmZXIsIChMUFZPSUQpLTEsIEZBTFNFICk7Cgl9CglpZiAobW9kX3B0cltpXSA8PSAoSE1PRFVMRTE2KSAzMikgewoJICAgIGZwcmludGYgKHN0ZGVyciwgIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsIG5hbWUpOwoJICAgIGV4aXQgKDApOwoJfQoJaSsrOwogICAgfQogICAgcGVfaW1wID0gcGUtPnBlX2ltcG9ydDsKICAgIHdoaWxlIChwZV9pbXAtPk5hbWUpIHsKCWNoYXIJCQkqTW9kdWxlOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglMUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKCWludAkJCW9yZGltcG9ydHdhcm5lZDsKCiAgICAgICAgb3JkaW1wb3J0d2FybmVkID0gMDsKCU1vZHVsZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoJZHByaW50Zl93aW4zMiAoc3RkZGViLCAiJXNcbiIsIE1vZHVsZSk7CgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayk7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgaWYoIWxzdHJuY21waTMyQShNb2R1bGUsImtlcm5lbDMyIiw4KSAmJiAhb3JkaW1wb3J0d2FybmVkKXsKCQkgICAgICAgZnByaW50ZihzdGRlcnIsIiVzIGltcG9ydHMga2VybmVsMzIuZGxsIGJ5IG9yZGluYWwuIE1heSBjcmFzaC5cbiIsbW9kbmFtZSk7CgkJICAgICAgIG9yZGltcG9ydHdhcm5lZCA9IDE7CgkJICAgIH0KCQkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiLS0tIE9yZGluYWwgJXMsJWRcbiIsIE1vZHVsZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSwoTFBDU1RSKW9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoTFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICItLS0gJXMgJXMuJWRcbiIsIHBlX25hbWUtPk5hbWUsIE1vZHVsZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoCgkJCQkJCU1PRFVMRV9GaW5kTW9kdWxlIChNb2R1bGUpLAoJCQkJCQlwZV9uYW1lLT5OYW1lKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCgkJICAgIGlmICghbHN0cm5jbXBpMzJBKE1vZHVsZSwia2VybmVsMzIiLDgpICYmIAoJCSAgICAJIW9yZGltcG9ydHdhcm5lZAoJCSAgICApIHsKCQkgICAgICAgZnByaW50ZihzdGRlcnIsIiVzIGltcG9ydHMga2VybmVsMzIuZGxsIGJ5IG9yZGluYWwuIE1heSBjcmFzaC5cbiIsbW9kbmFtZSk7CgkJICAgICAgIG9yZGltcG9ydHdhcm5lZCA9IDE7CgkJICAgIH0KCQkgICAgZHByaW50Zl93aW4zMihzdGRkZWIsIi0tLSBPcmRpbmFsICVzLiVkXG4iLE1vZHVsZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLAoJCQkJCQkgICAgIChMUENTVFIpIG9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oTFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLE1vZHVsZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLHBlX25hbWUtPk5hbWUpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJICAgIAlmcHJpbnRmKHN0ZGVyciwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CglwZV9pbXArKzsKICAgIH0KICAgIGlmIChmaXh1cF9mYWlsZWQpIGV4aXQoMSk7Cn0KCnN0YXRpYyB2b2lkIGNhbGNfdm1hX3NpemUoc3RydWN0IHBlX2RhdGEgKnBlKQp7CiAgaW50IGk7CgogIGRwcmludGZfd2luMzIoc3RkZGViLCAiRHVtcCBvZiBzZWdtZW50IHRhYmxlXG4iKTsKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIiAgIE5hbWUgICAgVlN6ICBWYWRkciAgICAgU3pSYXcgICBGaWxlYWRyICAqUmVsb2MgKkxpbmV1bSAjUmVsb2MgI0xpbnVtIENoYXJcbiIpOwogIGZvcihpPTA7IGk8IHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQogICAgewogICAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIiU4czogJTQuNGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTQuNHggJTQuNHggJTguOGx4XG4iLCAKCSAgICAgcGUtPnBlX3NlZ1tpXS5OYW1lLCAKCSAgICAgcGUtPnBlX3NlZ1tpXS5NaXNjLlZpcnR1YWxTaXplLAoJICAgICBwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzLAoJICAgICBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEsCgkgICAgIHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmF3RGF0YSwKCSAgICAgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SZWxvY2F0aW9ucywKCSAgICAgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9MaW5lbnVtYmVycywKCSAgICAgcGUtPnBlX3NlZ1tpXS5OdW1iZXJPZlJlbG9jYXRpb25zLAoJICAgICBwZS0+cGVfc2VnW2ldLk51bWJlck9mTGluZW51bWJlcnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uQ2hhcmFjdGVyaXN0aWNzKTsKCSAgcGUtPnZtYV9zaXplID0gTUFYKHBlLT52bWFfc2l6ZSwKCSAgCQlwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzICsgCgkJCXBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YSk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGRvX3JlbG9jYXRpb25zKHN0cnVjdCBwZV9kYXRhICpwZSkKewoJaW50IGRlbHRhID0gcGUtPmxvYWRfYWRkciAtIHBlLT5iYXNlX2FkZHI7Cgl1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gcGUtPmxvYWRfYWRkcjsKCUlNQUdFX0JBU0VfUkVMT0NBVElPTgkqciA9IHBlLT5wZV9yZWxvYzsKCWludCBoZGVsdGEgPSAoZGVsdGEgPj4gMTYpICYgMHhGRkZGOwoJaW50IGxkZWx0YSA9IGRlbHRhICYgMHhGRkZGOwoKCS8qIGludCByZWxvY19zaXplID0gKi8KCglpZihkZWx0YSA9PSAwKQoJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCQlyZXR1cm47Cgl3aGlsZShyLT5WaXJ0dWFsQWRkcmVzcykKCXsKCQljaGFyICpwYWdlID0gKGNoYXIqKSBSVkEoci0+VmlydHVhbEFkZHJlc3MpOwoJCWludCBjb3VudCA9IChyLT5TaXplT2ZCbG9jayAtIDgpLzI7CgkJaW50IGk7CgkJZHByaW50Zl9maXh1cChzdGRkZWIsICIleCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsCgkJCWNvdW50LCByLT5WaXJ0dWFsQWRkcmVzcyk7CgkJLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwoJCWZvcihpPTA7aTxjb3VudDtpKyspCgkJewoJCQlpbnQgb2Zmc2V0ID0gci0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwoJCQlpbnQgdHlwZSA9IHItPlR5cGVPZmZzZXRbaV0gPj4gMTI7CgkJCWRwcmludGZfZml4dXAoc3RkZGViLCJwYXRjaGluZyAleCB0eXBlICV4XG4iLCBvZmZzZXQsIHR5cGUpOwoJCQlzd2l0Y2godHlwZSkKCQkJewoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURTogYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0g6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGhkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGxkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgojaWYgMQoJCQkJKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CiNlbHNlCgkJCQl7IGludCBoPSoodW5zaWduZWQgc2hvcnQqKShwYWdlK29mZnNldCk7CgkJCQkgIGludCBsPXItPlR5cGVPZmZzZXRbKytpXTsKCQkJCSAgKih1bnNpZ25lZCBpbnQqKShwYWdlICsgb2Zmc2V0KSA9IChoPDwxNikgKyBsICsgZGVsdGE7CgkJCQl9CiNlbmRpZgoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hBREo6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIkRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9NSVBTX0pNUEFERFI6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIklzIHRoaXMgYSBNSVBTIG1hY2hpbmUgPz8/XG4iKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJZnByaW50ZihzdGRlcnIsICJVbmtub3duIGZpeHVwIHR5cGVcbiIpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJciA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04qKSgoY2hhciopciArIHItPlNpemVPZkJsb2NrKTsKCX0KfQoJCQoKCQoJCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCVBFX0xvYWRJbWFnZQogKiBMb2FkIG9uZSBQRSBmb3JtYXQgZXhlY3V0YWJsZSBpbnRvIG1lbW9yeQogKi8Kc3RhdGljIHN0cnVjdCBwZV9kYXRhICpQRV9Mb2FkSW1hZ2UoIGludCBmZCwgSE1PRFVMRTE2IGhNb2R1bGUsIFdPUkQgb2Zmc2V0ICkKewoJc3RydWN0IHBlX2RhdGEJCSpwZTsKCWludAkJCWksIHJlc3VsdDsKCWludAkJCWxvYWRfYWRkcjsKCUlNQUdFX0RBVEFfRElSRUNUT1JZCWRpcjsKCWNoYXIJCQlidWZmZXJbMjAwXTsKCURCR19BRERSCQlkYWRkcjsKCglkYWRkci5zZWc9MDsKCWRhZGRyLnR5cGUgPSBOVUxMOwoJcGUgPSB4bWFsbG9jKHNpemVvZihzdHJ1Y3QgcGVfZGF0YSkpOwoJbWVtc2V0KHBlLDAsc2l6ZW9mKHN0cnVjdCBwZV9kYXRhKSk7CglwZS0+cGVfaGVhZGVyID0geG1hbGxvYyhzaXplb2YoSU1BR0VfTlRfSEVBREVSUykpOwoKCS8qIHJlYWQgUEUgaGVhZGVyICovCglsc2VlayggZmQsIG9mZnNldCwgU0VFS19TRVQpOwoJcmVhZCggZmQsIHBlLT5wZV9oZWFkZXIsIHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSk7CgovKiBGSVhNRTogdGhpcyBpcyBhICpob3JyaWJsZSogaGFjayB0byBtYWtlIENPTURMRzMyLkRMTCBsb2FkIE9LLiBUaGUKcHJvYmxlbSBuZWVkcyB0byBiZSBmaXhlZCBwcm9wZXJseSBhdCBzb21lIHN0YWdlICovCgoJaWYgKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLk51bWJlck9mUnZhQW5kU2l6ZXMgIT0gMTYpIHsKCQlwcmludGYoIlNob3J0IFBFIEhlYWRlciEhIVxuIik7CgkJbHNlZWsoIGZkLCAtKDE2IC0gcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuTnVtYmVyT2ZSdmFBbmRTaXplcykgKiBzaXplb2YoSU1BR0VfREFUQV9ESVJFQ1RPUlkpLCBTRUVLX0NVUik7Cgl9CgovKiBob3JyaWJsZSBoYWNrIGVuZHMgISEhICovCgkvKiByZWFkIHNlY3Rpb25zICovCglwZS0+cGVfc2VnID0geG1hbGxvYyhzaXplb2YoSU1BR0VfU0VDVElPTl9IRUFERVIpICogCgkJCQkgICBwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnMpOwoJcmVhZCggZmQsIHBlLT5wZV9zZWcsIHNpemVvZihJTUFHRV9TRUNUSU9OX0hFQURFUikgKiAKCQkJcGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zKTsKCglsb2FkX2FkZHIgPSBwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CglwZS0+YmFzZV9hZGRyPWxvYWRfYWRkcjsKCXBlLT52bWFfc2l6ZT0wOwoJZHByaW50Zl93aW4zMihzdGRkZWIsICJMb2FkIGFkZHIgaXMgJXhcbiIsbG9hZF9hZGRyKTsKCWNhbGNfdm1hX3NpemUocGUpOwoKI2lmIDAKCS8qIFdlIHVzZSBtYWxsb2MgaGVyZSwgd2hpbGUgYSBodWdlIHBhcnQgb2YgdGhhdCBhZGRyZXNzIHNwYWNlIGRvZXMKCSAgIG5vdCBiZSBzdXBwb3J0ZWQgYnkgYWN0dWFsIG1lbW9yeS4gSXQgaGFzIHRvIGJlIGNvbnRpZ3VvdXMsIHRob3VnaC4KCSAgIEkgZG9uJ3Qga25vdyBpZiBtbWFwKCIvZGV2L251bGwiKTsgd291bGQgZG8gYW55IGJldHRlci4KCSAgIFdoYXQgSSdkIHJlYWxseSBsaWtlIHRvIGRvIGlzIGEgV2luMzIgc3R5bGUgVmlydHVhbEFsbG9jL01hcFZpZXdPZkZpbGUKCSAgIHNlcXVlbmNlICovCglsb2FkX2FkZHIgPSBwZS0+bG9hZF9hZGRyID0gKGludCl4bWFsbG9jKHBlLT52bWFfc2l6ZSk7CgltZW1zZXQoIGxvYWRfYWRkciwgMCwgcGUtPnZtYV9zaXplKTsKI2Vsc2UKCWxvYWRfYWRkciA9IChpbnQpIFZpcnR1YWxBbGxvYyggKHZvaWQqKXBlLT5iYXNlX2FkZHIsIHBlLT52bWFfc2l6ZSwgTUVNX1JFU0VSVkV8TUVNX0NPTU1JVCwgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwogICAgICAgIHBlLT5sb2FkX2FkZHIgPSBsb2FkX2FkZHI7CiNlbmRpZgoKCWRwcmludGZfd2luMzIoc3RkZGViLCAiTG9hZCBhZGRyIGlzIHJlYWxseSAleCwgcmFuZ2UgJXhcbiIsCgkJcGUtPmxvYWRfYWRkciwgcGUtPnZtYV9zaXplKTsKCQoKCWZvcihpPTA7IGkgPCBwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKCXsKCQkvKiBsb2FkIG9ubHkgbm9uLUJTUyBzZWdtZW50cyAqLwoJCWlmKCEocGUtPnBlX3NlZ1tpXS5DaGFyYWN0ZXJpc3RpY3MgJiAKCQkJSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmKGxzZWVrKGZkLHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmF3RGF0YSxTRUVLX1NFVCkgPT0gLTEKICAgICAgICAgICAgICAgICAgICAgICB8fCByZWFkKGZkLChjaGFyKilSVkEocGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpICE9IHBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YSkKICAgICAgICAgICAgICAgICAgICB7CgkJCWZwcmludGYoc3RkZXJyLCJGYWlsZWQgdG8gbG9hZCBzZWN0aW9uICV4XG4iLCBpKTsKCQkJZXhpdCgwKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgkJcmVzdWx0ID0gUlZBIChwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzKTsKI2lmIDEKCQkvKiBub3QgbmVlZGVkLCBtZW1vcnkgaXMgemVybyAqLwoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIuYnNzIikgPT0gMCkKCQkgICAgbWVtc2V0KCh2b2lkICopcmVzdWx0LCAwLCAKCQkJICAgcGUtPnBlX3NlZ1tpXS5NaXNjLlZpcnR1YWxTaXplID8KCQkJICAgcGUtPnBlX3NlZ1tpXS5NaXNjLlZpcnR1YWxTaXplIDoKCQkJICAgcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhKTsKI2VuZGlmCgoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIuaWRhdGEiKSA9PSAwKQoJCQlwZS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5lZGF0YSIpID09IDApCgkJCXBlLT5wZV9leHBvcnQgPSAoTFBJTUFHRV9FWFBPUlRfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIucnNyYyIpID09IDApCgkJCXBlLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLnJlbG9jIikgPT0gMCkKCQkJcGUtPnBlX3JlbG9jID0gKExQSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKSByZXN1bHQ7CgoJfQoKCS8qIFRoZXJlIGlzIHdvcmQgdGhhdCB0aGUgYWN0dWFsIGxvYWRlciBkb2VzIG5vdCBjYXJlIGFib3V0IHRoZQoJICAgc2VjdGlvbiBuYW1lcywgYW5kIG9ubHkgZ29lcyBmb3IgdGhlIERhdGFEaXJlY3RvcnkgKi8KCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGUtPnBlX2V4cG9ydCAmJiAoaW50KXBlLT5wZV9leHBvcnQhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgZXhwb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQkvKiBhbHdheXMgdHJ1c3QgdGhlIGRpcmVjdG9yeSAqLwoJCXBlLT5wZV9leHBvcnQgPSAoTFBJTUFHRV9FWFBPUlRfRElSRUNUT1JZKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglkaXI9cGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfSU1QT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9pbXBvcnQgJiYgKGludClwZS0+cGVfaW1wb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGltcG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJcGUtPnBlX2ltcG9ydCA9IChMUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglkaXI9cGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfUkVTT1VSQ0VdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGUtPnBlX3Jlc291cmNlICYmIChpbnQpcGUtPnBlX3Jlc291cmNlIT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIHJlc291cmNlIGRpcmVjdG9yeT8/XG4iKTsKCQlwZS0+cGVfcmVzb3VyY2UgPSAoTFBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYQ0VQVElPTl0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfU0VDVVJJVFldLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJTZWN1cml0eSBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoKCglkaXI9cGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9yZWxvYyAmJiAoaW50KXBlLT5wZV9yZWxvYyE9IFJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgcmVsb2NhdGlvbiBsaXN0Pz9cbiIpOwoJCXBlLT5wZV9yZWxvYyA9ICh2b2lkICopIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHXS5TaXplKQoJICB7CgkgICAgREVCVUdfUmVnaXN0ZXJEZWJ1Z0luZm8oZmQsIHBlLCBsb2FkX2FkZHIsIAoJCQlwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVR10uVmlydHVhbEFkZHJlc3MsCgkJCXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHXS5TaXplKTsKCSAgfQoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPUFlSSUdIVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkNvcHlyaWdodCBzdHJpbmcgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiR2xvYmFsIFBvaW50ZXIgKE1JUFMpIGlnbm9yZWRcbiIpOwoKI2lmZGVmIE5PVAkvKiB3ZSBpbml0aWFsaXplIHRoaXMgbGF0ZXIgKi8KCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMU10uU2l6ZSkKCQkgZHByaW50Zl93aW4zMihzdGRuaW1wLCJUaHJlYWQgbG9jYWwgc3RvcmFnZSBpZ25vcmVkXG4iKTsKI2VuZGlmCgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUddLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxM10uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDEzIGlnbm9yZWRcbiIpOwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIpOwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9yZWxvYykgZG9fcmVsb2NhdGlvbnMocGUpOwoJaWYocGUtPnBlX2ltcG9ydCkgZml4dXBfaW1wb3J0cyhwZSwgaE1vZHVsZSk7CglpZihwZS0+cGVfZXhwb3J0KSBkdW1wX2V4cG9ydHMocGUtPnBlX2V4cG9ydCxsb2FkX2FkZHIpOwogIAkJCglpZiAocGUtPnBlX2V4cG9ydCkgewoJCWNoYXIJKnM7CgoJCS8qIGFkZCBzdGFydCBvZiBzZWN0aW9ucyBhcyBkZWJ1Z3N5bWJvbHMgKi8KCQlmb3IoaT0wO2k8cGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zO2krKykgewoJCQlzcHJpbnRmKGJ1ZmZlciwiJXNfJXMiLAoJCQkJKGNoYXIqKVJWQShwZS0+cGVfZXhwb3J0LT5OYW1lKSwKCQkJCXBlLT5wZV9zZWdbaV0uTmFtZQoJCQkpOwoJCQlkYWRkci5vZmY9IFJWQShwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzKTsKICAgICAgCQkJd2hpbGUgKChzPXN0cmNocihidWZmZXIsJy4nKSkpICpzPSdfJzsKCQkJREVCVUdfQWRkU3ltYm9sKGJ1ZmZlciwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKCQl9CgkJLyogYWRkIGVudHJ5IHBvaW50ICovCgkJc3ByaW50ZihidWZmZXIsIiVzX0VudHJ5UG9pbnQiLChjaGFyKilSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSkpOwoJCWRhZGRyLm9mZj1SVkEocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCk7CiAgICAgIAkJd2hpbGUgKChzPXN0cmNocihidWZmZXIsJy4nKSkpICpzPSdfJzsKCQlERUJVR19BZGRTeW1ib2woYnVmZmVyLCZkYWRkciwgTlVMTCwgU1lNX1dJTjMyIHwgU1lNX0ZVTkMpOwoJCS8qIGFkZCBzdGFydCBvZiBETEwgKi8KCQlkYWRkci5vZmY9bG9hZF9hZGRyOwoJCURFQlVHX0FkZFN5bWJvbCgoY2hhciopIFJWQShwZS0+cGVfZXhwb3J0LT5OYW1lKSwmZGFkZHIsCgkJCQlOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7Cgl9CiAgICAgICAgcmV0dXJuIHBlOwp9CgpISU5TVEFOQ0UxNiBNT0RVTEVfQ3JlYXRlSW5zdGFuY2UoSE1PRFVMRTE2IGhNb2R1bGUsTE9BRFBBUkFNUyAqcGFyYW1zKTsKCkhJTlNUQU5DRTE2IFBFX0xvYWRNb2R1bGUoIEhGSUxFMzIgaEZpbGUsIE9GU1RSVUNUICpvZnMsIExPQURQQVJBTVMqIHBhcmFtcyApCnsKICAgIEhNT0RVTEUxNiBoTW9kdWxlOwogICAgSElOU1RBTkNFMTYgaEluc3RhbmNlOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgc3RydWN0IG16X2hlYWRlcl9zIG16X2hlYWRlcjsKICAgIGludCBmZDsKCiAgICBpZiAoKGhNb2R1bGUgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIG9mcyApKSA8IDMyKSByZXR1cm4gaE1vZHVsZTsKICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlICk7CiAgICBwTW9kdWxlLT5mbGFncyA9IE5FX0ZGTEFHU19XSU4zMjsKCiAgICAvKiBGSVhNRTogSGFjayBiZWNhdXNlIFBFX0xvYWRNb2R1bGUgaXMgcmVjdXJzaXZlICovCiAgICBmZCA9IGR1cCggRklMRV9HZXRVbml4SGFuZGxlKGhGaWxlKSApOwogICAgX2xjbG9zZTMyKCBoRmlsZSApOwogICAgbHNlZWsoIGZkLCAwLCBTRUVLX1NFVCApOwogICAgcmVhZCggZmQsICZtel9oZWFkZXIsIHNpemVvZihtel9oZWFkZXIpICk7CgogICAgcE1vZHVsZS0+cGVfbW9kdWxlID0gUEVfTG9hZEltYWdlKCBmZCwgaE1vZHVsZSwgbXpfaGVhZGVyLm5lX29mZnNldCApOwogICAgY2xvc2UoIGZkICk7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlLCBwYXJhbXMgKTsKCiAgICBpZiAoIShwTW9kdWxlLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgVEFTS19DcmVhdGVUYXNrKCBoTW9kdWxlLCBoSW5zdGFuY2UsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmhFbnZpcm9ubWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgIChMUFNUUilQVFJfU0VHX1RPX0xJTiggcGFyYW1zLT5jbWRMaW5lICksCiAgICAgICAgICAgICAgICAgICAgICAgICAqKChXT1JEKilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPnNob3dDbWQpICsgMSkgKTsKICAgIH0KICAgIHJldHVybiBoSW5zdGFuY2U7Cn0KCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRTE2IGhNb2R1bGUgKQp7CglwcmludGYoIlBFdW5sb2FkSW1hZ2UoKSBjYWxsZWQhXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8Kc3RhdGljIHZvaWQgUEVfSW5pdERMTChITU9EVUxFMTYgaE1vZHVsZSwgRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgUEVfTU9EVUxFICpwZTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHI7CgogICAgaE1vZHVsZSA9IEdldEV4ZVB0cihoTW9kdWxlKTsKICAgIGlmICghKHBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKGhNb2R1bGUpKSkgcmV0dXJuOwogICAgaWYgKCEocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfV0lOMzIpIHx8ICEocGUgPSBwTW9kdWxlLT5wZV9tb2R1bGUpKQogICAgICAgIHJldHVybjsKCiAgICAvKiAgRExMX0FUVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBmb3IgZHluYW1pYyBsb2Fkcywgbm90LU5VTEwgZm9yIHN0YXRpYyBsb2FkcwogICAgICogIERMTF9ERVRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgaWYgY2FsbGVkIGJ5IEZyZWVMaWJyYXJ5LCBub3QtTlVMTCBvdGhlcndpc2UKICAgICAqICB0aGUgU0RLIGRvZXNuJ3QgbWVudGlvbiBhbnl0aGluZyBmb3IgRExMX1RIUkVBRF8qCiAgICAgKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKAkocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKCQkocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7CglwcmludGYoIkluaXRQRURMTCgpIGNhbGxlZCFcbiIpOwoJQ2FsbERMTEVudHJ5UHJvYzMyKCAKCSAgICAoRkFSUFJPQzMyKVJWQShwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSwKCSAgICBoTW9kdWxlLAoJICAgIHR5cGUsCgkgICAgKERXT1JEKWxwUmVzZXJ2ZWQKCSk7CiAgICB9Cn0KCnZvaWQgUEVfSW5pdGlhbGl6ZURMTHMoSE1PRFVMRTE2IGhNb2R1bGUsRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewoJTkVfTU9EVUxFICpwTW9kdWxlOwoJSE1PRFVMRTE2ICpwRExMOwoJcE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoIEdldEV4ZVB0cihoTW9kdWxlKSApOwoJaWYgKHBNb2R1bGUtPmRsbHNfdG9faW5pdCkKCXsKCQlIR0xPQkFMMTYgdG9faW5pdCA9IHBNb2R1bGUtPmRsbHNfdG9faW5pdDsKCQlwTW9kdWxlLT5kbGxzX3RvX2luaXQgPSAwOwoJCgkJZm9yIChwRExMID0gKEhNT0RVTEUxNiAqKUdsb2JhbExvY2sxNiggdG9faW5pdCApOyAqcERMTDsgcERMTCsrKQoJCXsKICAgICAgICAgICAgICAgICAgICBQRV9Jbml0aWFsaXplRExMcyggKnBETEwsIHR5cGUsIGxwUmVzZXJ2ZWQpOwoJCX0KCQlHbG9iYWxGcmVlMTYoIHRvX2luaXQgKTsKCX0KCVBFX0luaXRETEwoIGhNb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKfQoKdm9pZCBQRV9Jbml0VGxzKCBQRV9NT0RVTEUgKm1vZHVsZSApCnsKICAgLyogRklYTUU6IHRscyBjYWxsYmFja3MgPz8/ICovCiAgIERXT1JEICBpbmRleDsKICAgRFdPUkQgIGRhdGFzaXplOwogICBEV09SRCAgc2l6ZTsKICAgTFBWT0lEIG1lbTsKICAgTFBJTUFHRV9UTFNfRElSRUNUT1JZIHBkaXI7CgogICAgaWYgKCFtb2R1bGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykKICAgICAgICByZXR1cm47CgogICAgcGRpciA9IChMUFZPSUQpKG1vZHVsZS0+bG9hZF9hZGRyICsgbW9kdWxlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLgogICAgICAgICAgICAgICBEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKICAgIGluZGV4ID0gVGxzQWxsb2MoKTsKICAgIGRhdGFzaXplID0gcGRpci0+RW5kQWRkcmVzc09mUmF3RGF0YS1wZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGE7CiAgICBzaXplICAgICA9IGRhdGFzaXplICsgcGRpci0+U2l6ZU9mWmVyb0ZpbGw7CiAgICAgICAgCiAgICBtZW0gPSBWaXJ0dWFsQWxsb2MoMCxzaXplLCBNRU1fUkVTRVJWRXxNRU1fQ09NTUlULCBQQUdFX1JFQURXUklURSApOwogICAgCiAgICBtZW1jcHkobWVtLChMUFZPSUQpIHBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSwgZGF0YXNpemUpOwogICAgVGxzU2V0VmFsdWUoaW5kZXgsbWVtKTsKICAgICoocGRpci0+QWRkcmVzc09mSW5kZXgpPWluZGV4OyAgIAp9CgojZW5kaWYgLyogV0lORUxJQiAqLwo=