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+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKCXsKCQkvKiBsb2FkIG9ubHkgbm9uLUJTUyBzZWdtZW50cyAqLwoJCWlmKHBlLT5wZV9zZWdbaV0uQ2hhcmFjdGVyaXN0aWNzICYgCgkJCX4gSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpCgkJaWYobHNlZWsoZmQscGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SYXdEYXRhLFNFRUtfU0VUKSA9PSAtMQoJCXx8IHJlYWQoZmQsKGNoYXIqKVJWQShwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzKSwKCQkJICAgcGUtPnBlX3NlZ1tpXS5TaXplT2ZSYXdEYXRhKSAhPSBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpCgkJewoJCQlmcHJpbnRmKHN0ZGVyciwiRmFpbGVkIHRvIGxvYWQgc2VjdGlvbiAleFxuIiwgaSk7CgkJCWV4aXQoMCk7CgkJfQoJCXJlc3VsdCA9IFJWQSAocGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyk7CiNpZiAxCgkJLyogbm90IG5lZWRlZCwgbWVtb3J5IGlzIHplcm8gKi8KCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmJzcyIpID09IDApCgkJICAgIG1lbXNldCgodm9pZCAqKXJlc3VsdCwgMCwgCgkJCSAgIHBlLT5wZV9zZWdbaV0uTWlzYy5WaXJ0dWFsU2l6ZSA/CgkJCSAgIHBlLT5wZV9zZWdbaV0uTWlzYy5WaXJ0dWFsU2l6ZSA6CgkJCSAgIHBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YSk7CiNlbmRpZgoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLmlkYXRhIikgPT0gMCkKCQkJcGUtPnBlX2ltcG9ydCA9IChMUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIuZWRhdGEiKSA9PSAwKQoJCQlwZS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLnJzcmMiKSA9PSAwKQoJCQlwZS0+cGVfcmVzb3VyY2UgPSAoTFBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5yZWxvYyIpID09IDApCgkJCXBlLT5wZV9yZWxvYyA9IChMUElNQUdFX0JBU0VfUkVMT0NBVElPTikgcmVzdWx0OwoKCX0KCgkvKiBUaGVyZSBpcyB3b3JkIHRoYXQgdGhlIGFjdHVhbCBsb2FkZXIgZG9lcyBub3QgY2FyZSBhYm91dCB0aGUKCSAgIHNlY3Rpb24gbmFtZXMsIGFuZCBvbmx5IGdvZXMgZm9yIHRoZSBEYXRhRGlyZWN0b3J5ICovCglkaXI9cGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9leHBvcnQgJiYgKGludClwZS0+cGVfZXhwb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGV4cG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJLyogYWx3YXlzIHRydXN0IHRoZSBkaXJlY3RvcnkgKi8KCQlwZS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfaW1wb3J0ICYmIChpbnQpcGUtPnBlX2ltcG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBpbXBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1JFU09VUkNFXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlLT5wZV9yZXNvdXJjZSAmJiAoaW50KXBlLT5wZV9yZXNvdXJjZSE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZXNvdXJjZSBkaXJlY3Rvcnk/P1xuIik7CgkJcGUtPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT05dLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCgoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQ107CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZS0+cGVfcmVsb2MgJiYgKGludClwZS0+cGVfcmVsb2MhPSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIHJlbG9jYXRpb24gbGlzdD8/XG4iKTsKCQlwZS0+cGVfcmVsb2MgPSAodm9pZCAqKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVR10uU2l6ZSkKCSAgewoJICAgIERFQlVHX1JlZ2lzdGVyRGVidWdJbmZvKGZkLCBwZSwgbG9hZF9hZGRyLCAKCQkJcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlZpcnR1YWxBZGRyZXNzLAoJCQlwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVR10uU2l6ZSk7CgkgIH0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT1BZUklHSFRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUl0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iKTsKCiNpZmRlZiBOT1QJLyogd2UgaW5pdGlhbGl6ZSB0aGlzIGxhdGVyICovCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFNdLlNpemUpCgkJIGRwcmludGZfd2luMzIoc3RkbmltcCwiVGhyZWFkIGxvY2FsIHN0b3JhZ2UgaWdub3JlZFxuIik7CiNlbmRpZgoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0xPQURfQ09ORklHXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CT1VORF9JTVBPUlRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTNdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxMyBpZ25vcmVkXG4iKTsKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxNCBpZ25vcmVkXG4iKTsKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTVdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxNSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfcmVsb2MpIGRvX3JlbG9jYXRpb25zKHBlKTsKCWlmKHBlLT5wZV9pbXBvcnQpIGZpeHVwX2ltcG9ydHMocGUsIGhNb2R1bGUpOwoJaWYocGUtPnBlX2V4cG9ydCkgZHVtcF9leHBvcnRzKHBlLT5wZV9leHBvcnQsbG9hZF9hZGRyKTsKICAJCQoJaWYgKHBlLT5wZV9leHBvcnQpIHsKCQljaGFyCSpzOwoKCQkvKiBhZGQgc3RhcnQgb2Ygc2VjdGlvbnMgYXMgZGVidWdzeW1ib2xzICovCgkJZm9yKGk9MDtpPHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucztpKyspIHsKCQkJc3ByaW50ZihidWZmZXIsIiVzXyVzIiwKCQkJCShjaGFyKilSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSksCgkJCQlwZS0+cGVfc2VnW2ldLk5hbWUKCQkJKTsKCQkJZGFkZHIub2ZmPSBSVkEocGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgIAkJCXdoaWxlICgocz1zdHJjaHIoYnVmZmVyLCcuJykpKSAqcz0nXyc7CgkJCURFQlVHX0FkZFN5bWJvbChidWZmZXIsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7CgkJfQoJCS8qIGFkZCBlbnRyeSBwb2ludCAqLwoJCXNwcmludGYoYnVmZmVyLCIlc19FbnRyeVBvaW50IiwoY2hhciopUlZBKHBlLT5wZV9leHBvcnQtPk5hbWUpKTsKCQlkYWRkci5vZmY9UlZBKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpOwogICAgICAJCXdoaWxlICgocz1zdHJjaHIoYnVmZmVyLCcuJykpKSAqcz0nXyc7CgkJREVCVUdfQWRkU3ltYm9sKGJ1ZmZlciwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKCQkvKiBhZGQgc3RhcnQgb2YgRExMICovCgkJZGFkZHIub2ZmPWxvYWRfYWRkcjsKCQlERUJVR19BZGRTeW1ib2woKGNoYXIqKSBSVkEocGUtPnBlX2V4cG9ydC0+TmFtZSksJmRhZGRyLAoJCQkJTlVMTCwgU1lNX1dJTjMyIHwgU1lNX0ZVTkMpOwoJfQogICAgICAgIHJldHVybiBwZTsKfQoKSElOU1RBTkNFMTYgTU9EVUxFX0NyZWF0ZUluc3RhbmNlKEhNT0RVTEUxNiBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CgpISU5TVEFOQ0UxNiBQRV9Mb2FkTW9kdWxlKCBpbnQgZmQsIE9GU1RSVUNUICpvZnMsIExPQURQQVJBTVMqIHBhcmFtcyApCnsKICAgIEhNT0RVTEUxNiBoTW9kdWxlOwogICAgSElOU1RBTkNFMTYgaEluc3RhbmNlOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgc3RydWN0IG16X2hlYWRlcl9zIG16X2hlYWRlcjsKCiAgICBpZiAoKGhNb2R1bGUgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIG9mcyApKSA8IDMyKSByZXR1cm4gaE1vZHVsZTsKICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlICk7CiAgICBwTW9kdWxlLT5mbGFncyA9IE5FX0ZGTEFHU19XSU4zMjsKCiAgICBsc2VlayggZmQsIDAsIFNFRUtfU0VUICk7CiAgICByZWFkKCBmZCwgJm16X2hlYWRlciwgc2l6ZW9mKG16X2hlYWRlcikgKTsKCiAgICBwTW9kdWxlLT5wZV9tb2R1bGUgPSBQRV9Mb2FkSW1hZ2UoIGZkLCBoTW9kdWxlLCBtel9oZWFkZXIubmVfb2Zmc2V0ICk7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlLCBwYXJhbXMgKTsKCiAgICBpZiAoIShwTW9kdWxlLT5wZV9tb2R1bGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgVEFTS19DcmVhdGVUYXNrKCBoTW9kdWxlLCBoSW5zdGFuY2UsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMtPmhFbnZpcm9ubWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgIChMUFNUUilQVFJfU0VHX1RPX0xJTiggcGFyYW1zLT5jbWRMaW5lICksCiAgICAgICAgICAgICAgICAgICAgICAgICAqKChXT1JEKilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPnNob3dDbWQpICsgMSkgKTsKICAgIH0KICAgIHJldHVybiBoSW5zdGFuY2U7Cn0KCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRTE2IGhNb2R1bGUgKQp7CglwcmludGYoIlBFdW5sb2FkSW1hZ2UoKSBjYWxsZWQhXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8Kc3RhdGljIHZvaWQgUEVfSW5pdERMTChITU9EVUxFMTYgaE1vZHVsZSwgRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgUEVfTU9EVUxFICpwZTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHI7CgogICAgaE1vZHVsZSA9IEdldEV4ZVB0cihoTW9kdWxlKTsKICAgIGlmICghKHBNb2R1bGUgPSBNT0RVTEVfR2V0UHRyKGhNb2R1bGUpKSkgcmV0dXJuOwogICAgaWYgKCEocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfV0lOMzIpIHx8ICEocGUgPSBwTW9kdWxlLT5wZV9tb2R1bGUpKQogICAgICAgIHJldHVybjsKCiAgICAvKiAgRExMX0FUVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBmb3IgZHluYW1pYyBsb2Fkcywgbm90LU5VTEwgZm9yIHN0YXRpYyBsb2FkcwogICAgICogIERMTF9ERVRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgaWYgY2FsbGVkIGJ5IEZyZWVMaWJyYXJ5LCBub3QtTlVMTCBvdGhlcndpc2UKICAgICAqICB0aGUgU0RLIGRvZXNuJ3QgbWVudGlvbiBhbnl0aGluZyBmb3IgRExMX1RIUkVBRF8qCiAgICAgKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKAkocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKCQkocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIGxvYWRfYWRkciA9IHBlLT5sb2FkX2FkZHI7CglwcmludGYoIkluaXRQRURMTCgpIGNhbGxlZCFcbiIpOwoJQ2FsbERMTEVudHJ5UHJvYzMyKCAKCSAgICAoRkFSUFJPQzMyKVJWQShwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSwKCSAgICBoTW9kdWxlLAoJICAgIHR5cGUsCgkgICAgKERXT1JEKWxwUmVzZXJ2ZWQKCSk7CiAgICB9Cn0KCnZvaWQgUEVfSW5pdGlhbGl6ZURMTHMoSE1PRFVMRTE2IGhNb2R1bGUsRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewoJTkVfTU9EVUxFICpwTW9kdWxlOwoJSE1PRFVMRTE2ICpwRExMOwoJcE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoIEdldEV4ZVB0cihoTW9kdWxlKSApOwoJaWYgKHBNb2R1bGUtPmRsbHNfdG9faW5pdCkKCXsKCQlIR0xPQkFMMTYgdG9faW5pdCA9IHBNb2R1bGUtPmRsbHNfdG9faW5pdDsKCQlwTW9kdWxlLT5kbGxzX3RvX2luaXQgPSAwOwoJCgkJZm9yIChwRExMID0gKEhNT0RVTEUxNiAqKUdsb2JhbExvY2sxNiggdG9faW5pdCApOyAqcERMTDsgcERMTCsrKQoJCXsKCQkJUEVfSW5pdGlhbGl6ZURMTHMoICpwRExMLCB0eXBlLCBscFJlc2VydmVkKTsKCQkJUEVfSW5pdERMTCggKnBETEwsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKCQl9CgkJR2xvYmFsRnJlZTE2KCB0b19pbml0ICk7Cgl9CglQRV9Jbml0RExMKCBoTW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7Cn0KCnZvaWQgUEVfSW5pdFRscyggUEVfTU9EVUxFICptb2R1bGUgKQp7CiAgIC8qIEZJWE1FOiB0bHMgY2FsbGJhY2tzID8/PyAqLwogICBEV09SRCAgaW5kZXg7CiAgIERXT1JEICBkYXRhc2l6ZTsKICAgRFdPUkQgIHNpemU7CiAgIExQVk9JRCBtZW07CiAgIExQSU1BR0VfVExTX0RJUkVDVE9SWSBwZGlyOwoKICAgIGlmICghbW9kdWxlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpCiAgICAgICAgcmV0dXJuOwoKICAgIHBkaXIgPSAoTFBWT0lEKShtb2R1bGUtPmxvYWRfYWRkciArIG1vZHVsZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci4KICAgICAgICAgICAgICAgRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcyk7CiAgICBpbmRleCA9IFRsc0FsbG9jKCk7CiAgICBkYXRhc2l6ZSA9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwogICAgc2l6ZSAgICAgPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwogICAgICAgIAogICAgbWVtID0gVmlydHVhbEFsbG9jKDAsc2l6ZSwgTUVNX1JFU0VSVkV8TUVNX0NPTU1JVCwgUEFHRV9SRUFEV1JJVEUgKTsKICAgIAogICAgbWVtY3B5KG1lbSwoTFBWT0lEKSBwZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGEsIGRhdGFzaXplKTsKICAgIFRsc1NldFZhbHVlKGluZGV4LG1lbSk7CiAgICAqKHBkaXItPkFkZHJlc3NPZkluZGV4KT1pbmRleDsgICAKfQoKI2VuZGlmIC8qIFdJTkVMSUIgKi8K