LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiY2FsbGJhY2suaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAic2VydmVyLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luMzIpOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGVsYXlobHApOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwoZml4dXApOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKHJlbGF5KTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKHNlZ21lbnQpOwoKCnN0YXRpYyBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpnZXRfZXhwb3J0cyggSE1PRFVMRSBobW9kICkKewogICAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcmV0ID0gTlVMTDsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXIgPSBQRV9IRUFERVIoaG1vZCktPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplICYmIGRpci0+VmlydHVhbEFkZHJlc3MpCiAgICAgICAgcmV0ID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKikoKGNoYXIgKilobW9kICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKmdldF9pbXBvcnRzKCBITU9EVUxFIGhtb2QgKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcmV0ID0gTlVMTDsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXIgPSBQRV9IRUFERVIoaG1vZCktPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplICYmIGRpci0+VmlydHVhbEFkZHJlc3MpCiAgICAgICAgcmV0ID0gKElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICopKChjaGFyICopaG1vZCArIGRpci0+VmlydHVhbEFkZHJlc3MpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodm9pZCAqKSgoY2hhciAqKWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkpCgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFIGhNb2R1bGUgKQp7IAogIGNoYXIJCSpNb2R1bGU7CiAgaW50CQlpLCBqOwogIHVfc2hvcnQJKm9yZGluYWw7CiAgdV9sb25nCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIHVfY2hhcgkqKm5hbWU7CiAgdW5zaWduZWQgaW50IGxvYWRfYWRkciA9IGhNb2R1bGU7CgogIERXT1JEIHJ2YV9zdGFydCA9IFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwogIERXT1JEIHJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwogIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydHMgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSopUlZBKHJ2YV9zdGFydCk7CgogIE1vZHVsZSA9IChjaGFyKilSVkEocGVfZXhwb3J0cy0+TmFtZSk7CiAgVFJBQ0UoIioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbiIpOwogIFRSQUNFKCJNb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKICAgICAgICBNb2R1bGUsIHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zLCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKTsKCiAgb3JkaW5hbD0odV9zaG9ydCopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucz1mdW5jdGlvbj0odV9sb25nKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZT0odV9jaGFyKiopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIFRSQUNFKCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgaWYgKFRSQUNFX09OKHdpbjMyKSkKICAgICAgewoJRFBSSU5URiggIiU0bGQgJTA4bHggJXAiLCBpICsgcGVfZXhwb3J0cy0+QmFzZSwgKmZ1bmN0aW9uLCBSVkEoKmZ1bmN0aW9uKSApOwoJLyogQ2hlY2sgaWYgd2UgaGF2ZSBhIG5hbWUgZm9yIGl0ICovCglmb3IgKGogPSAwOyBqIDwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaisrKQogICAgICAgICAgaWYgKG9yZGluYWxbal0gPT0gaSkKICAgICAgICAgIHsKICAgICAgICAgICAgICBEUFJJTlRGKCAiICAlcyIsIChjaGFyKilSVkEobmFtZVtqXSkgKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KCWlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfZW5kKSkKCSAgRFBSSU5URigiIChmb3J3YXJkZWQgLT4gJXMpIiwgKGNoYXIgKilSVkEoKmZ1bmN0aW9uKSk7CglEUFJJTlRGKCJcbiIpOwogICAgICB9CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpzdGF0aWMgRkFSUFJPQyBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggCglXSU5FX01PRFJFRiAqd20sCS8qIFtpbl0gV0lORSBtb2RyZWZlcmVuY2UgKi8KCUxQQ1NUUiBmdW5jTmFtZSwJLyogW2luXSBmdW5jdGlvbiBuYW1lICovCiAgICAgICAgQk9PTCBzbm9vcCApCnsKCXVfc2hvcnQJCQkJKiBvcmRpbmFsczsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZSA9IE5VTEw7CglpbnQJCQkJaSwgb3JkaW5hbDsKCXVuc2lnbmVkIGludAkJCWxvYWRfYWRkciA9IHdtLT5tb2R1bGU7Cgl1X2xvbmcJCQkJcnZhX3N0YXJ0LCBydmFfZW5kLCBhZGRyOwoJY2hhcgkJCQkqIGZvcndhcmQ7CglJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpleHBvcnRzID0gZ2V0X2V4cG9ydHMod20tPm1vZHVsZSk7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJVFJBQ0UoIiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCVRSQUNFKCIoJWQpXG4iLChpbnQpZnVuY05hbWUpOwoJaWYgKCFleHBvcnRzKSB7CgkJLyogTm90IGEgZmF0YWwgcHJvYmxlbSwgc29tZSBhcHBzIGRvCgkJICogR2V0UHJvY0FkZHJlc3MoMCwiUmVnaXN0ZXJQZW5BcHAiKSB3aGljaCB0cmlnZ2VycyB0aGlzCgkJICogY2FzZS4KCQkgKi8KCQlXQVJOKCJNb2R1bGUgJTA4eCglcykvTU9EUkVGICVwIGRvZXNuJ3QgaGF2ZSBhIGV4cG9ydHMgdGFibGUuXG4iLHdtLT5tb2R1bGUsd20tPm1vZG5hbWUsd20pOwoJCXJldHVybiBOVUxMOwoJfQoJb3JkaW5hbHM9ICh1X3Nob3J0KikgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwoJZnVuY3Rpb249ICh1X2xvbmcqKSAgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwoJbmFtZQk9ICh1X2NoYXIgKiopIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7Cglmb3J3YXJkID0gTlVMTDsKCXJ2YV9zdGFydCA9IFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5WaXJ0dWFsQWRkcmVzczsKCXJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uU2l6ZTsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGZpcnN0IHRyeSBhIGJpbmFyeSBzZWFyY2ggKi8KICAgICAgICAgICAgaW50IG1pbiA9IDAsIG1heCA9IGV4cG9ydHMtPk51bWJlck9mTmFtZXMgLSAxOwogICAgICAgICAgICB3aGlsZSAobWluIDw9IG1heCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IHJlcywgcG9zID0gKG1pbiArIG1heCkgLyAyOwogICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtwb3NdKTsKICAgICAgICAgICAgICAgIGlmICghKHJlcyA9IHN0cmNtcCggZW5hbWUsIGZ1bmNOYW1lICkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG9yZGluYWwgPSBvcmRpbmFsc1twb3NdOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZm91bmQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocmVzID4gMCkgbWF4ID0gcG9zIC0gMTsKICAgICAgICAgICAgICAgIGVsc2UgbWluID0gcG9zICsgMTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBub3cgdHJ5IGEgbGluZWFyIHNlYXJjaCBpbiBjYXNlIHRoZSBuYW1lcyBhcmVuJ3Qgc29ydGVkIHByb3Blcmx5ICovCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGVuYW1lID0gUlZBKG5hbWVbaV0pOwogICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoIGVuYW1lLCBmdW5jTmFtZSApKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEVSUiggIiVzLiVzIHJlcXVpcmVkIGEgbGluZWFyIHNlYXJjaFxuIiwgd20tPm1vZG5hbWUsIGZ1bmNOYW1lICk7CiAgICAgICAgICAgICAgICAgICAgb3JkaW5hbCA9IG9yZGluYWxzW2ldOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZm91bmQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIE5VTEw7Cgl9CiAgICAgICAgZWxzZSAgLyogZmluZCBieSBvcmRpbmFsICovCiAgICAgICAgewogICAgICAgICAgICBvcmRpbmFsID0gTE9XT1JEKGZ1bmNOYW1lKSAtIGV4cG9ydHMtPkJhc2U7CiAgICAgICAgICAgIGlmIChzbm9vcCAmJiBuYW1lKSAgLyogbmVlZCB0byBmaW5kIGEgbmFtZSBmb3IgaXQgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykKICAgICAgICAgICAgICAgICAgICBpZiAob3JkaW5hbHNbaV0gPT0gb3JkaW5hbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVuYW1lID0gUlZBKG5hbWVbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCX0KCiBmb3VuZDoKICAgICAgICBpZiAob3JkaW5hbCA+PSBleHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucykKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIJb3JkaW5hbCAlbGQgb3V0IG9mIHJhbmdlIVxuIiwgb3JkaW5hbCArIGV4cG9ydHMtPkJhc2UgKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIGFkZHIgPSBmdW5jdGlvbltvcmRpbmFsXTsKICAgICAgICBpZiAoIWFkZHIpIHJldHVybiBOVUxMOwogICAgICAgIGlmICgoYWRkciA8IHJ2YV9zdGFydCkgfHwgKGFkZHIgPj0gcnZhX2VuZCkpCiAgICAgICAgewogICAgICAgICAgICBGQVJQUk9DIHByb2MgPSBSVkEoYWRkcik7CiAgICAgICAgICAgIGlmIChzbm9vcCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFlbmFtZSkgZW5hbWUgPSAiQCI7CiAgICAgICAgICAgICAgICBwcm9jID0gU05PT1BfR2V0UHJvY0FkZHJlc3Mod20tPm1vZHVsZSxlbmFtZSxvcmRpbmFsLHByb2MpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBwcm9jOwogICAgICAgIH0KICAgICAgICBlbHNlICAvKiBmb3J3YXJkIGVudHJ5IHBvaW50ICovCiAgICAgICAgewogICAgICAgICAgICAgICAgV0lORV9NT0RSRUYgKndtOwogICAgICAgICAgICAgICAgRkFSUFJPQyBwcm9jOwogICAgICAgICAgICAgICAgY2hhciAqZm9yd2FyZCA9IFJWQShhZGRyKTsKCQljaGFyIG1vZHVsZVsyNTZdOwoJCWNoYXIgKmVuZCA9IHN0cmNocihmb3J3YXJkLCAnLicpOwoKCQlpZiAoIWVuZCkgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICBpZiAoZW5kIC0gZm9yd2FyZCA+PSBzaXplb2YobW9kdWxlKSkgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICBtZW1jcHkoIG1vZHVsZSwgZm9yd2FyZCwgZW5kIC0gZm9yd2FyZCApOwoJCW1vZHVsZVtlbmQtZm9yd2FyZF0gPSAwOwogICAgICAgICAgICAgICAgaWYgKCEod20gPSBNT0RVTEVfRmluZE1vZHVsZSggbW9kdWxlICkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEVSUigibW9kdWxlIG5vdCBmb3VuZCBmb3IgZm9yd2FyZCAnJXMnXG4iLCBmb3J3YXJkICk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICB9CgkJaWYgKCEocHJvYyA9IE1PRFVMRV9HZXRQcm9jQWRkcmVzcyggd20tPm1vZHVsZSwgZW5kICsgMSwgc25vb3AgKSkpCiAgICAgICAgICAgICAgICAgICAgRVJSKCJmdW5jdGlvbiBub3QgZm91bmQgZm9yIGZvcndhcmQgJyVzJ1xuIiwgZm9yd2FyZCApOwoJCXJldHVybiBwcm9jOwoJfQp9CgpEV09SRCBmaXh1cF9pbXBvcnRzKCBXSU5FX01PRFJFRiAqd20gKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUgkqcGVfaW1wOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcgk9IHdtLT5tb2R1bGU7CiAgICBpbnQJCQkJaSxjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uPTE7CiAgICBjaGFyCQkJKm1vZG5hbWU7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpleHBvcnRzID0gZ2V0X2V4cG9ydHMod20tPm1vZHVsZSk7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqaW1wb3J0cyA9IGdldF9pbXBvcnRzKHdtLT5tb2R1bGUpOwogICAgCiAgICBpZiAoZXhwb3J0cykKICAgIAltb2RuYW1lID0gKGNoYXIqKSBSVkEoZXhwb3J0cy0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBpbXBvcnRzOwogICAgaWYgKCFwZV9pbXApIHJldHVybiAwOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIFRSQUNFKCJEdW1waW5nIGltcG9ydHMgbGlzdFxuIik7CgogICAgLyogV2UgYXNzdW1lIHRoYXQgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgaW1wb3J0IHdpdGggITAgY2hhcmFjdGVyaXN0aWNzIGFuZAogICAgICogZGV0ZWN0IGJyb2tlbiBpbXBvcnRzIHdpdGggYWxsIGNoYXJhY3RlcmlzdGljcyAwIChub3RhYmx5IEJvcmxhbmQpIGFuZAogICAgICogc3dpdGNoIHRoZSBkZXRlY3Rpb24gb2ZmIGZvciB0aGVtLgogICAgICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWUgOyBwZV9pbXArKykgewoJaWYgKCFpICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gPSAwOwoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CglpKys7CiAgICB9CiAgICBpZiAoIWkpIHJldHVybiAwOyAgLyogbm8gaW1wb3J0cyAqLwoKICAgIC8qIEFsbG9jYXRlIG1vZHVsZSBkZXBlbmRlbmN5IGxpc3QgKi8KICAgIHdtLT5uRGVwcyA9IGk7CiAgICB3bS0+ZGVwcyAgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGkqc2l6ZW9mKFdJTkVfTU9EUkVGICopICk7CgogICAgLyogbG9hZCB0aGUgaW1wb3J0ZWQgbW9kdWxlcy4gVGhleSBhcmUgYXV0b21hdGljYWxseSAKICAgICAqIGFkZGVkIHRvIHRoZSBtb2RyZWYgbGlzdCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwogCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBpbXBvcnRzOyBwZV9pbXAtPk5hbWUgOyBwZV9pbXArKykgewogICAgCVdJTkVfTU9EUkVGCQkqd21JbXA7CglJTUFHRV9JTVBPUlRfQllfTkFNRQkqcGVfbmFtZTsKCVBJTUFHRV9USFVOS19EQVRBCWltcG9ydF9saXN0LHRodW5rX2xpc3Q7CiAJY2hhcgkJCSpuYW1lID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CgoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CgoJd21JbXAgPSBNT0RVTEVfTG9hZExpYnJhcnlFeEEoIG5hbWUsIDAsIDAgKTsKCWlmICghd21JbXApIHsKCSAgICBFUlJfKG1vZHVsZSkoIk1vZHVsZSAoZmlsZSkgJXMgbmVlZGVkIGJ5ICVzIG5vdCBmb3VuZFxuIiwgbmFtZSwgd20tPmZpbGVuYW1lKTsKCSAgICByZXR1cm4gMTsKCX0KICAgICAgICB3bS0+ZGVwc1tpKytdID0gd21JbXA7CgoJLyogRklYTUU6IGZvcndhcmRlciBlbnRyaWVzIC4uLiAqLwoKCWlmIChwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rICE9IDApIHsgLyogb3JpZ2luYWwgTVMgc3R5bGUgKi8KCSAgICBUUkFDRSgiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBuYW1lLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKW9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSwgb3JkaW5hbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CQkvKiBpbXBvcnQgYnkgbmFtZSAqLwoJCSAgICBwZV9uYW1lID0gKFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBuYW1lLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQlpbXBvcnRfbGlzdCsrOwoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9IGVsc2UgewkvKiBCb3JsYW5kIHN0eWxlICovCgkgICAgVFJBQ0UoIkJvcmxhbmQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICB0aHVua19saXN0ID0gKFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCSAgICB3aGlsZSAodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgLyogbm90IHN1cmUgYWJvdXQgdGhpcyBicmFuY2gsIGJ1dCBpdCBzZWVtcyB0byB3b3JrICovCgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKCItLS0gT3JkaW5hbCAlcy4lZFxuIixuYW1lLG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpIG9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxvcmRpbmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oUElNQUdFX0lNUE9SVF9CWV9OQU1FKSBSVkEodGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKCItLS0gJXMgJXMuJWRcbiIsCgkJICAgCQkgIHBlX25hbWUtPk5hbWUsbmFtZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBwZV9uYW1lLT5IaW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBkb19yZWxvY2F0aW9ucwogKgogKiBBcHBseSB0aGUgcmVsb2NhdGlvbnMgdG8gYSBtYXBwZWQgUEUgaW1hZ2UKICovCnN0YXRpYyBpbnQgZG9fcmVsb2NhdGlvbnMoIGNoYXIgKmJhc2UsIGNvbnN0IElNQUdFX05UX0hFQURFUlMgKm50LCBjb25zdCBjaGFyICpmaWxlbmFtZSApCnsKICAgIGNvbnN0IElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBjb25zdCBJTUFHRV9CQVNFX1JFTE9DQVRJT04gKnJlbDsKICAgIGludCBkZWx0YSA9IGJhc2UgLSAoY2hhciAqKW50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CgogICAgZGlyID0gJm50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0NdOwogICAgcmVsID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiAqKShiYXNlICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgV0FSTigiSW5mbzogYmFzZSByZWxvY2F0aW9ucyBuZWVkZWQgZm9yICVzXG4iLCBmaWxlbmFtZSk7CiAgICBpZiAoIWRpci0+VmlydHVhbEFkZHJlc3MgfHwgIWRpci0+U2l6ZSkKICAgIHsKICAgICAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZSA9PSAweDQwMDAwMCkKICAgICAgICAgICAgRVJSKCJTdGFuZGFyZCBsb2FkIGFkZHJlc3MgZm9yIGEgV2luMzIgcHJvZ3JhbSBub3QgYXZhaWxhYmxlIC0gcGF0Y2hlZCBrZXJuZWwgP1xuIik7CiAgICAgICAgRVJSKCAiRkFUQUw6IE5lZWQgdG8gcmVsb2NhdGUgJXMsIGJ1dCBubyByZWxvY2F0aW9uIHJlY29yZHMgcHJlc2VudCAoJXMpLiBUcnkgdG8gcnVuIHRoYXQgZmlsZSBkaXJlY3RseSAhXG4iLAogICAgICAgICAgICAgZmlsZW5hbWUsCiAgICAgICAgICAgICAobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzJklNQUdFX0ZJTEVfUkVMT0NTX1NUUklQUEVEKT8KICAgICAgICAgICAgICJzdHJpcHBlZCBkdXJpbmcgbGluayIgOiAidW5rbm93biByZWFzb24iICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyogRklYTUU6IElmIHdlIG5lZWQgdG8gcmVsb2NhdGUgYSBzeXN0ZW0gRExMIChiYXNlID4gMkdCKSB3ZSBzaG91bGQKICAgICAqICAgICAgICByZWFsbHkgbWFrZSBzdXJlIHRoYXQgdGhlICpuZXcqIGJhc2UgYWRkcmVzcyBpcyBhbHNvID4gMkdCLgogICAgICogICAgICAgIFNvbWUgRExMcyByZWFsbHkgY2hlY2sgdGhlIE1TQiBvZiB0aGUgbW9kdWxlIGhhbmRsZSA6LS8KICAgICAqLwogICAgaWYgKChudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlICYgMHg4MDAwMDAwMCkgJiYgISgoRFdPUkQpYmFzZSAmIDB4ODAwMDAwMDApKQogICAgICAgIEVSUiggIkZvcmNlZCB0byByZWxvY2F0ZSBzeXN0ZW0gRExMIChiYXNlID4gMkdCKS4gVGhpcyBpcyBub3QgZ29vZC5cbiIgKTsKCiAgICBmb3IgKCA7ICgoY2hhciAqKXJlbCA8IGJhc2UgKyBkaXItPlZpcnR1YWxBZGRyZXNzICsgZGlyLT5TaXplKSAmJiByZWwtPlZpcnR1YWxBZGRyZXNzOwogICAgICAgICAgcmVsID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyZWwgKyByZWwtPlNpemVPZkJsb2NrKSkKICAgIHsKICAgICAgICBjaGFyICpwYWdlID0gYmFzZSArIHJlbC0+VmlydHVhbEFkZHJlc3M7CiAgICAgICAgaW50IGksIGNvdW50ID0gKHJlbC0+U2l6ZU9mQmxvY2sgLSA4KSAvIHNpemVvZihyZWwtPlR5cGVPZmZzZXQpOwoKICAgICAgICBpZiAoIWNvdW50KSBjb250aW51ZTsKCiAgICAgICAgLyogc2FuaXR5IGNoZWNrcyAqLwogICAgICAgIGlmICgoY2hhciAqKXJlbCArIHJlbC0+U2l6ZU9mQmxvY2sgPiBiYXNlICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyArIGRpci0+U2l6ZSB8fAogICAgICAgICAgICBwYWdlID4gYmFzZSArIG50LT5PcHRpb25hbEhlYWRlci5TaXplT2ZJbWFnZSkKICAgICAgICB7CiAgICAgICAgICAgIEVSUl8obW9kdWxlKSgiaW52YWxpZCByZWxvY2F0aW9uICVwLCVseCwlbGQgYXQgJXAsJWx4LCVseFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlbCwgcmVsLT5WaXJ0dWFsQWRkcmVzcywgcmVsLT5TaXplT2ZCbG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UsIGRpci0+VmlydHVhbEFkZHJlc3MsIGRpci0+U2l6ZSApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIFRSQUNFXyhtb2R1bGUpKCIlbGQgcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLCByZWwtPlNpemVPZkJsb2NrLCByZWwtPlZpcnR1YWxBZGRyZXNzKTsKCiAgICAgICAgLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwogICAgICAgIGZvciAoaSA9IDAgOyBpIDwgY291bnQ7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGludCBvZmZzZXQgPSByZWwtPlR5cGVPZmZzZXRbaV0gJiAweEZGRjsKICAgICAgICAgICAgaW50IHR5cGUgPSByZWwtPlR5cGVPZmZzZXRbaV0gPj4gMTI7CiAgICAgICAgICAgIHN3aXRjaCh0eXBlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0g6CiAgICAgICAgICAgICAgICAqKHNob3J0KikocGFnZStvZmZzZXQpICs9IEhJV09SRChkZWx0YSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfTE9XOgogICAgICAgICAgICAgICAgKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBMT1dPUkQoZGVsdGEpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CiAgICAgICAgICAgICAgICAqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBpZiB0aGlzIGlzIGFuIGV4cG9ydGVkIGFkZHJlc3MsIGZpcmUgdXAgZW5oYW5jZWQgbG9naWMgKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUVfKG1vZHVsZSkoIlVua25vd24vdW5zdXBwb3J0ZWQgZml4dXAgdHlwZSAlZC5cbiIsIHR5cGUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqIAogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvciAKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXRzIHdoaWNoIGFyZSBwYWdlLWFsaWduZWQuCiAqCiAqIEJVVCB3ZSBoYXZlIHRvIG1hcCB0aGUgd2hvbGUgaW1hZ2UgYW55d2F5LCBmb3IgV2luMzIgcHJvZ3JhbXMgc29tZXRpbWVzCiAqIHdhbnQgdG8gYWNjZXNzIHRoZW0uIChITU9EVUxFMzIgcG9pbnQgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8KSE1PRFVMRSBQRV9Mb2FkSW1hZ2UoIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncyApCnsKICAgIElNQUdFX05UX0hFQURFUlMgKm50OwogICAgSE1PRFVMRSBoTW9kdWxlOwogICAgSEFORExFIG1hcHBpbmc7CiAgICB2b2lkICpiYXNlOwoKICAgIFRSQUNFXyhtb2R1bGUpKCAibG9hZGluZyAlc1xuIiwgZmlsZW5hbWUgKTsKCiAgICBtYXBwaW5nID0gQ3JlYXRlRmlsZU1hcHBpbmdBKCBoRmlsZSwgTlVMTCwgU0VDX0lNQUdFLCAwLCAwLCBOVUxMICk7CiAgICBiYXNlID0gTWFwVmlld09mRmlsZSggbWFwcGluZywgRklMRV9NQVBfUkVBRCwgMCwgMCwgMCApOwogICAgQ2xvc2VIYW5kbGUoIG1hcHBpbmcgKTsKICAgIGlmICghYmFzZSkgcmV0dXJuIDA7CgogICAgaE1vZHVsZSA9IChITU9EVUxFKWJhc2U7CiAgICBpZiAoZmxhZ3MgJiBMT0FEX0xJQlJBUllfQVNfREFUQUZJTEUpIHJldHVybiBoTW9kdWxlOyAgLyogbm90aGluZyBlbHNlIHRvIGRvICovCgogICAgLyogcGVyZm9ybSBiYXNlIHJlbG9jYXRpb24sIGlmIG5lY2Vzc2FyeSAqLwoKICAgIG50ID0gUEVfSEVBREVSKCBoTW9kdWxlICk7CiAgICBpZiAoaE1vZHVsZSAhPSBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlKQogICAgewogICAgICAgIGlmICghZG9fcmVsb2NhdGlvbnMoIGJhc2UsIG50LCBmaWxlbmFtZSApKQogICAgICAgIHsKICAgICAgICAgICAgVW5tYXBWaWV3T2ZGaWxlKCBiYXNlICk7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQkFEX0VYRV9GT1JNQVQgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIC8qIHZpcnVzIGNoZWNrICovCgogICAgaWYgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KQogICAgewogICAgICAgIGludCBpOwogICAgICAgIElNQUdFX1NFQ1RJT05fSEVBREVSICpzZWMgPSAoSU1BR0VfU0VDVElPTl9IRUFERVIqKSgoY2hhciopJm50LT5PcHRpb25hbEhlYWRlciArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG50LT5GaWxlSGVhZGVyLlNpemVPZk9wdGlvbmFsSGVhZGVyKTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBzZWMrKykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCA8IHNlYy0+VmlydHVhbEFkZHJlc3MpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgaWYgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50IDwgc2VjLT5WaXJ0dWFsQWRkcmVzcytzZWMtPlNpemVPZlJhd0RhdGEpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKGkgPT0gbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucykKICAgICAgICAgICAgTUVTU0FHRSgiVklSVVMgV0FSTklORzogUEUgbW9kdWxlIGhhcyBhbiBpbnZhbGlkIGVudHJ5cG9pbnQgKDB4JTA4bHgpICIKICAgICAgICAgICAgICAgICAgICAib3V0c2lkZSBhbGwgc2VjdGlvbnMgKHBvc3NpYmx5IGluZmVjdGVkIGJ5IFRjaGVybm9ieWwvU3BhY2VGaWxsZXIgdmlydXMpIVxuIiwKICAgICAgICAgICAgICAgICAgICBudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCApOwogICAgfQoKICAgIHJldHVybiBoTW9kdWxlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAgUEVfQ3JlYXRlTW9kdWxlCiAqCiAqIENyZWF0ZSBXSU5FX01PRFJFRiBzdHJ1Y3R1cmUgZm9yIGxvYWRlZCBITU9EVUxFMzIsIGxpbmsgaXQgaW50bwogKiBwcm9jZXNzIG1vZHJlZl9saXN0LCBhbmQgZml4dXAgYWxsIGltcG9ydHMuCiAqCiAqIE5vdGU6IGhNb2R1bGUgbXVzdCBwb2ludCB0byBhIGNvcnJlY3RseSBhbGxvY2F0ZWQgUEUgaW1hZ2UsCiAqICAgICAgIHdpdGggYmFzZSByZWxvY2F0aW9ucyBhcHBsaWVkOyB0aGUgMTYtYml0IGR1bW15IG1vZHVsZQogKiAgICAgICBhc3NvY2lhdGVkIHRvIGhNb2R1bGUgbXVzdCBhbHJlYWR5IGV4aXN0LgogKgogKiBOb3RlOiBUaGlzIHJvdXRpbmUgbXVzdCBhbHdheXMgYmUgY2FsbGVkIGluIHRoZSBjb250ZXh0IG9mIHRoZQogKiAgICAgICBwcm9jZXNzIHRoYXQgaXMgdG8gb3duIHRoZSBtb2R1bGUgdG8gYmUgY3JlYXRlZC4KICoKICogTm90ZTogQXNzdW1lcyB0aGF0IHRoZSBwcm9jZXNzIGNyaXRpY2FsIHNlY3Rpb24gaXMgaGVsZAogKi8KV0lORV9NT0RSRUYgKlBFX0NyZWF0ZU1vZHVsZSggSE1PRFVMRSBoTW9kdWxlLCBMUENTVFIgZmlsZW5hbWUsIERXT1JEIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIRklMRSBoRmlsZSwgQk9PTCBidWlsdGluICkKewogICAgRFdPUkQgbG9hZF9hZGRyID0gKERXT1JEKWhNb2R1bGU7ICAvKiBmb3IgUlZBICovCiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihoTW9kdWxlKTsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnQgPSBOVUxMOwogICAgV0lORV9NT0RSRUYgKndtOwogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKCiAgICAvKiBSZXRyaWV2ZSBEYXRhRGlyZWN0b3J5IGVudHJpZXMgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9leHBvcnQgPSAoUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpUlZBKGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT047CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQyBoYW5kbGVkIGluIFBFX0xvYWRJbWFnZSAqLwogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHIGhhbmRsZWQgYnkgZGVidWdnZXIgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMUyBoYW5kbGVkIGluIFBFX1Rsc0luaXQgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUc7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFTEFZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICB7CgkJVFJBQ0UoIkRlbGF5ZWQgaW1wb3J0LCBzdHViIGNhbGxzIExvYWRMaWJyYXJ5XG4iICk7CgkJLyoKCQkgKiBOb3RoaW5nIHRvIGRvIGhlcmUuCgkJICovCgojaWZkZWYgSW1nRGVsYXlEZXNjcgoJCS8qCgkJICogVGhpcyBjb2RlIGlzIHVzZWZ1bCB0byBvYnNlcnZlIHdoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24uCgkJICovCgkJewoJCUltZ0RlbGF5RGVzY3IgKnBlX2RlbGF5ID0gTlVMTDsKICAgICAgICBwZV9kZWxheSA9IChQSW1nRGVsYXlEZXNjcilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPmdyQXR0cnMgPSAlMDh4XG4iLCBwZV9kZWxheS0+Z3JBdHRycyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnN6TmFtZSA9ICVzXG4iLCBwZV9kZWxheS0+c3pOYW1lKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSU5UID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJTlQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cFVubG9hZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wVW5sb2FkSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+ZHdUaW1lU3RhbXAgPSAlMDh4XG4iLCBwZV9kZWxheS0+ZHdUaW1lU3RhbXApOwogICAgICAgIH0KI2VuZGlmIC8qIEltZ0RlbGF5RGVzY3IgKi8KCX0KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09NX0RFU0NSSVBUT1I7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5KzE1OwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCiAgICAvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwoKICAgIGlmICgoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBmaWxlbmFtZSwgaE1vZHVsZSApKSA8IDMyKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggKERXT1JEKWhNb2R1bGUxNiApOwkvKiBUaGlzIHNob3VsZCBnaXZlIHRoZSBjb3JyZWN0IGVycm9yICovCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICBpZiAoISh3bSA9IE1PRFVMRV9BbGxvY01vZFJlZiggaE1vZHVsZSwgZmlsZW5hbWUgKSkpCiAgICB7CiAgICAgICAgRnJlZUxpYnJhcnkxNiggaE1vZHVsZTE2ICk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKCBidWlsdGluICkgCiAgICB7CiAgICAgICAgTkVfTU9EVUxFICpwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZTE2ICk7CiAgICAgICAgcE1vZHVsZS0+ZmxhZ3MgfD0gTkVfRkZMQUdTX0JVSUxUSU47CiAgICAgICAgd20tPmZsYWdzIHw9IFdJTkVfTU9EUkVGX0lOVEVSTkFMOwogICAgfQoKICAgIGlmICggZmxhZ3MgJiBET05UX1JFU09MVkVfRExMX1JFRkVSRU5DRVMgKQogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUzsKCiAgICB3bS0+ZmluZF9leHBvcnQgPSBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbjsKCiAgICAvKiBEdW1wIEV4cG9ydHMgKi8KCiAgICBpZiAoIHBlX2V4cG9ydCApCiAgICAgICAgZHVtcF9leHBvcnRzKCBoTW9kdWxlICk7CgogICAgLyogVGhlIGV4ZV9tb2RyZWYgbXVzdCBiZSBpbiBwbGFjZSwgYmVmb3JlIGltcGxpY2l0IGxpbmtlZCBETExzIGFyZSBsb2FkZWQgCiAgICAgICBieSBmaXh1cF9pbXBvcnRzLCBvdGhlcndoaXNlIEdldE1vZHVsZUZpbGVOYW1lIHdpbGwgbm90IHdvcmsgYW5kIG1vZHVsZXMgCiAgICAgICBpbiB0aGUgZXhlY3V0YWJsZXMgZGlyZWN0b3J5IGNhbiBub3QgYmUgZm91bmQgKi8KCiAgICBpZiAoIShudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgIGlmICggUFJPQ0VTU19DdXJyZW50KCktPmV4ZV9tb2RyZWYgKQoJRklYTUUoICJUcnlpbmcgdG8gbG9hZCBzZWNvbmQgLkVYRSBmaWxlOiAlc1xuIiwgZmlsZW5hbWUgKTsKICAgICAgZWxzZSAgCiAgICAgIHsKCVBST0NFU1NfQ3VycmVudCgpLT5leGVfbW9kcmVmID0gd207CiAgICAgICAgUFJPQ0VTU19DdXJyZW50KCktPm1vZHVsZSA9IHdtLT5tb2R1bGU7CiAgICAgIH0KICAgIH0KCiAgICAvKiBGaXh1cCBJbXBvcnRzICovCgogICAgaWYgKCEod20tPmZsYWdzICYgV0lORV9NT0RSRUZfRE9OVF9SRVNPTFZFX1JFRlMpICYmIGZpeHVwX2ltcG9ydHMoIHdtICkpCiAgICB7CiAgICAgICAgLyogcmVtb3ZlIGVudHJ5IGZyb20gbW9kcmVmIGNoYWluICovCgogICAgICAgIGlmICggIXdtLT5wcmV2ICkKICAgICAgICAgICAgUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0ID0gd20tPm5leHQ7CiAgICAgICAgZWxzZQogICAgICAgICAgICB3bS0+cHJldi0+bmV4dCA9IHdtLT5uZXh0OwoKICAgICAgICBpZiAoIHdtLT5uZXh0ICkgd20tPm5leHQtPnByZXYgPSB3bS0+cHJldjsKICAgICAgICB3bS0+bmV4dCA9IHdtLT5wcmV2ID0gTlVMTDsKCiAgICAgICAgLyogRklYTUU6IHRoZXJlIGFyZSBzZXZlcmFsIG1vcmUgZGFuZ2xpbmcgcmVmZXJlbmNlcwogICAgICAgICAqIGxlZnQuIEluY2x1ZGluZyBkbGxzIGxvYWRlZCBieSB0aGlzIGRsbCBiZWZvcmUgdGhlCiAgICAgICAgICogZmFpbGVkIG9uZS4gVW5yb2xsaW5nIGlzIHJhdGhlciBkaWZmaWN1bHQgd2l0aCB0aGUKICAgICAgICAgKiBjdXJyZW50IHN0cnVjdHVyZSBhbmQgd2UgY2FuIGxlYXZlIGl0IHRoZW0gbHlpbmcKICAgICAgICAgKiBhcm91bmQgd2l0aCBubyBwcm9ibGVtcywgc28gd2UgZG9uJ3QgY2FyZS4KICAgICAgICAgKiBBcyB0aGVzZSBtaWdodCByZWZlcmVuY2Ugb3VyIHdtLCB3ZSBkb24ndCBmcmVlIGl0LgogICAgICAgICAqLwogICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAocGVfZXhwb3J0KQogICAgICAgIFNOT09QX1JlZ2lzdGVyRExMKCBoTW9kdWxlLCB3bS0+bW9kbmFtZSwgcGVfZXhwb3J0LT5OdW1iZXJPZkZ1bmN0aW9ucyApOwoKICAgIC8qIFNlbmQgRExMIGxvYWQgZXZlbnQgKi8KICAgIC8qIHdlIGRvbid0IG5lZWQgdG8gc2VuZCBhIGRsbCBldmVudCBmb3IgdGhlIG1haW4gZXhlICovCgogICAgaWYgKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKQogICAgewogICAgICAgIHN0cnVjdCBsb2FkX2RsbF9yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwogICAgICAgIHJlcS0+aGFuZGxlICAgICA9IGhGaWxlOwogICAgICAgIHJlcS0+YmFzZSAgICAgICA9ICh2b2lkICopaE1vZHVsZTsKICAgICAgICByZXEtPmRiZ19vZmZzZXQgPSBudC0+RmlsZUhlYWRlci5Qb2ludGVyVG9TeW1ib2xUYWJsZTsKICAgICAgICByZXEtPmRiZ19zaXplICAgPSBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlN5bWJvbHM7CiAgICAgICAgcmVxLT5uYW1lICAgICAgID0gJndtLT5maWxlbmFtZTsKICAgICAgICBzZXJ2ZXJfY2FsbF9ub2VyciggUkVRX0xPQURfRExMICk7CiAgICB9CgogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKi8KV0lORV9NT0RSRUYgKlBFX0xvYWRMaWJyYXJ5RXhBIChMUENTVFIgbmFtZSwgRFdPUkQgZmxhZ3MpCnsKCUhNT0RVTEUJCWhNb2R1bGUzMjsKCVdJTkVfTU9EUkVGCSp3bTsKCWNoYXIgICAgICAgIAlmaWxlbmFtZVsyNTZdOwoJSEFORExFCQloRmlsZTsKCgkvKiBTZWFyY2ggZm9yIGFuZCBvcGVuIFBFIGZpbGUgKi8KCWlmICggU2VhcmNoUGF0aEEoIE5VTEwsIG5hbWUsICIuRExMIiwgCgkgICAgICAgICAgICAgICAgICBzaXplb2YoZmlsZW5hbWUpLCBmaWxlbmFtZSwgTlVMTCApID09IDAgKSByZXR1cm4gTlVMTDsKICAgICAgIAoJaEZpbGUgPSBDcmVhdGVGaWxlQSggZmlsZW5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIC0xICk7CglpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CgkKCS8qIExvYWQgUEUgbW9kdWxlICovCgloTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgZmxhZ3MgKTsKCWlmICghaE1vZHVsZTMyKQoJewogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLyogQ3JlYXRlIDMyLWJpdCBNT0RSRUYgKi8KCWlmICggISh3bSA9IFBFX0NyZWF0ZU1vZHVsZSggaE1vZHVsZTMyLCBmaWxlbmFtZSwgZmxhZ3MsIC0xLCBGQUxTRSApKSApCgl7CgkJRVJSKCAiY2FuJ3QgbG9hZCAlc1xuIiwgZmlsZW5hbWUgKTsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCVNldExhc3RFcnJvciggRVJST1JfT1VUT0ZNRU1PUlkgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCiAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CglyZXR1cm4gd207Cn0KCgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8KdHlwZWRlZiBEV09SRCBDQUxMQkFDSygqRExMRU5UUllQUk9DKShITU9EVUxFLERXT1JELExQVk9JRCk7CgpCT09MIFBFX0luaXRETEwoIEhNT0RVTEUgbW9kdWxlLCBEV09SRCB0eXBlLCBMUFZPSUQgbHBSZXNlcnZlZCApCnsKICAgIEJPT0wgcmV0diA9IFRSVUU7CiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihtb2R1bGUpOwoKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKICAgICAgICAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpKQogICAgewogICAgICAgIERMTEVOVFJZUFJPQyBlbnRyeSA9ICh2b2lkKikoKGNoYXIqKW1vZHVsZSArIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KTsKICAgICAgICBUUkFDRV8ocmVsYXkpKCJDYWxsVG8zMihlbnRyeXByb2M9JXAsbW9kdWxlPSUwOHgsdHlwZT0lbGQscmVzPSVwKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSwgbW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CgogICAgICAgIHJldHYgPSBlbnRyeSggbW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICB9CgogICAgcmV0dXJuIHJldHY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUEVfSW5pdFRscwkJCShpbnRlcm5hbCkKICoKICogSWYgaW5jbHVkZWQsIGluaXRpYWxpc2VzIHRoZSB0aHJlYWQgbG9jYWwgc3RvcmFnZXMgb2YgbW9kdWxlcy4KICogUG9pbnRlcnMgaW4gdGhvc2Ugc3RydWN0cyBhcmUgbm90IFJWQXMgYnV0IHJlYWwgcG9pbnRlcnMgd2hpY2ggaGF2ZSBiZWVuCiAqIHJlbG9jYXRlZCBieSBkb19yZWxvY2F0aW9ucygpIGFscmVhZHkuCiAqLwpzdGF0aWMgTFBWT0lECl9maXh1cF9hZGRyZXNzKFBJTUFHRV9PUFRJT05BTF9IRUFERVIgb3B0LGludCBkZWx0YSxMUFZPSUQgYWRkcikgewoJaWYgKAkoKERXT1JEKWFkZHI+b3B0LT5JbWFnZUJhc2UpICYmCgkJKChEV09SRClhZGRyPG9wdC0+SW1hZ2VCYXNlK29wdC0+U2l6ZU9mSW1hZ2UpCgkpCgkJLyogdGhlIGFkZHJlc3MgaGFzIG5vdCBiZWVuIHJlbG9jYXRlZCEgKi8KCQlyZXR1cm4gKExQVk9JRCkoKChEV09SRClhZGRyKStkZWx0YSk7CgllbHNlCgkJLyogdGhlIGFkZHJlc3MgaGFzIGJlZW4gcmVsb2NhdGVkIGFscmVhZHkgKi8KCQlyZXR1cm4gYWRkcjsKfQp2b2lkIFBFX0luaXRUbHMoIHZvaWQgKQp7CglXSU5FX01PRFJFRgkJKndtOwoJSU1BR0VfTlRfSEVBREVSUwkqcGVoOwoJRFdPUkQJCQlzaXplLGRhdGFzaXplOwoJTFBWT0lECQkJbWVtOwoJUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKICAgICAgICBpbnQgZGVsdGE7CgkKCWZvciAod20gPSBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3Q7d207d209d20tPm5leHQpIHsKCQlwZWggPSBQRV9IRUFERVIod20tPm1vZHVsZSk7CgkJZGVsdGEgPSB3bS0+bW9kdWxlIC0gcGVoLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CgkJaWYgKCFwZWgtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpCgkJCWNvbnRpbnVlOwoJCXBkaXIgPSAoTFBWT0lEKSh3bS0+bW9kdWxlICsgcGVoLT5PcHRpb25hbEhlYWRlci4KCQkJRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcyk7CgkJCgkJCgkJaWYgKCB3bS0+dGxzaW5kZXggPT0gLTEgKSB7CgkJCUxQRFdPUkQgeGFkZHI7CgkJCXdtLT50bHNpbmRleCA9IFRsc0FsbG9jKCk7CgkJCXhhZGRyID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwKCQkJCQlwZGlyLT5BZGRyZXNzT2ZJbmRleAoJCQkpOwoJCQkqeGFkZHI9d20tPnRsc2luZGV4OwoJCX0KCQlkYXRhc2l6ZT0gcGRpci0+RW5kQWRkcmVzc09mUmF3RGF0YS1wZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGE7CgkJc2l6ZQk9IGRhdGFzaXplICsgcGRpci0+U2l6ZU9mWmVyb0ZpbGw7CgkJbWVtPVZpcnR1YWxBbGxvYygwLHNpemUsTUVNX1JFU0VSVkV8TUVNX0NPTU1JVCxQQUdFX1JFQURXUklURSk7CgkJbWVtY3B5KG1lbSxfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLChMUFZPSUQpcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhKSxkYXRhc2l6ZSk7CgkJaWYgKHBkaXItPkFkZHJlc3NPZkNhbGxCYWNrcykgewoJCSAgICAgUElNQUdFX1RMU19DQUxMQkFDSyAqY2JzOyAKCgkJICAgICBjYnMgPSBfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLHBkaXItPkFkZHJlc3NPZkNhbGxCYWNrcyk7CgkJICAgICBpZiAoKmNicykKCQkgICAgICAgRklYTUUoIlRMUyBDYWxsYmFja3MgYXJlbid0IGdvaW5nIHRvIGJlIGNhbGxlZFxuIik7CgkJfQoKCQlUbHNTZXRWYWx1ZSggd20tPnRsc2luZGV4LCBtZW0gKTsKCX0KfQoK