Lyogdmk6c2V0IHRzPTggc3RzPTQgc3c9NDoKICoKICogVklNIC0gVmkgSU1wcm92ZWQJCWJ5IEJyYW0gTW9vbGVuYWFyCiAqCQkJCUdVSS9Nb3RpZiBzdXBwb3J0IGJ5IFJvYmVydCBXZWJiCiAqCiAqIERvICI6aGVscCB1Z2FuZGEiICBpbiBWaW0gdG8gcmVhZCBjb3B5aW5nIGFuZCB1c2FnZSBjb25kaXRpb25zLgogKiBEbyAiOmhlbHAgY3JlZGl0cyIgaW4gVmltIHRvIHNlZSBhIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZC4KICogU2VlIFJFQURNRS50eHQgZm9yIGFuIG92ZXJ2aWV3IG9mIHRoZSBWaW0gc291cmNlIGNvZGUuCiAqLwoKI2luY2x1ZGUgPFhtL0Zvcm0uaD4KI2luY2x1ZGUgPFhtL1Jvd0NvbHVtbi5oPgojaW5jbHVkZSA8WG0vUHVzaEIuaD4KI2luY2x1ZGUgPFhtL1RleHQuaD4KI2luY2x1ZGUgPFhtL1RleHRGLmg+CiNpbmNsdWRlIDxYbS9TZXBhcmF0b3IuaD4KI2luY2x1ZGUgPFhtL0xhYmVsLmg+CiNpbmNsdWRlIDxYbS9DYXNjYWRlQi5oPgojaW5jbHVkZSA8WG0vU2Nyb2xsQmFyLmg+CiNpbmNsdWRlIDxYbS9NZW51U2hlbGwuaD4KI2luY2x1ZGUgPFhtL0RyYXdpbmdBLmg+CiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCiMgaW5jbHVkZSA8WG0vUmVwVHlwZS5oPgojZW5kaWYKI2luY2x1ZGUgPFhtL0ZyYW1lLmg+CiNpbmNsdWRlIDxYbS9MYWJlbEcuaD4KI2luY2x1ZGUgPFhtL1RvZ2dsZUJHLmg+CiNpbmNsdWRlIDxYbS9TZXBhcmF0b0cuaD4KI2luY2x1ZGUgPFhtL1htUC5oPgoKI2luY2x1ZGUgPFgxMS9rZXlzeW0uaD4KI2luY2x1ZGUgPFgxMS9YYXRvbS5oPgojaW5jbHVkZSA8WDExL1N0cmluZ0RlZnMuaD4KI2luY2x1ZGUgPFgxMS9JbnRyaW5zaWMuaD4KCiNpbmNsdWRlICJ2aW0uaCIKCiNpZmRlZiBIQVZFX1gxMV9YUE1fSAojIGluY2x1ZGUgPFgxMS94cG0uaD4KI2Vsc2UKIyBpZmRlZiBIQVZFX1hNX1hQTVBfSAojICBpbmNsdWRlIDxYbS9YcG1QLmg+CiMgZW5kaWYKI2VuZGlmCiNpZmRlZiBIQVZFX1hNX05PVEVCT09LX0gKIyBpbmNsdWRlIDxYbS9Ob3RlYm9vay5oPgojZW5kaWYKCiNpbmNsdWRlICJndWlfeG1lYncuaCIJLyogZm9yIG91ciBFbmhhbmNlZCBCdXR0b24gV2lkZ2V0ICovCgojaWYgZGVmaW5lZChGRUFUX0dVSV9ESUFMT0cpICYmIGRlZmluZWQoSEFWRV9YUE0pCiMgaW5jbHVkZSAiLi4vcGl4bWFwcy9hbGVydC54cG0iCiMgaW5jbHVkZSAiLi4vcGl4bWFwcy9lcnJvci54cG0iCiMgaW5jbHVkZSAiLi4vcGl4bWFwcy9nZW5lcmljLnhwbSIKIyBpbmNsdWRlICIuLi9waXhtYXBzL2luZm8ueHBtIgojIGluY2x1ZGUgIi4uL3BpeG1hcHMvcXVlc3QueHBtIgojZW5kaWYKCiNkZWZpbmUgTU9USUZfUE9QVVAKCmV4dGVybiBXaWRnZXQgdmltU2hlbGw7CgpzdGF0aWMgV2lkZ2V0IHZpbUZvcm07CnN0YXRpYyBXaWRnZXQgdGV4dEFyZWFGb3JtOwpXaWRnZXQgdGV4dEFyZWE7CiNpZmRlZiBGRUFUX1RPT0xCQVIKc3RhdGljIFdpZGdldCB0b29sQmFyRnJhbWU7CnN0YXRpYyBXaWRnZXQgdG9vbEJhcjsKI2VuZGlmCiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCnN0YXRpYyBXaWRnZXQJdGFiTGluZTsKc3RhdGljIFdpZGdldAl0YWJMaW5lX21lbnUgPSAwOwpzdGF0aWMgaW50CXNob3dpbmdfdGFibGluZSA9IDA7CiNlbmRpZgojaWZkZWYgRkVBVF9GT09URVIKc3RhdGljIFdpZGdldCBmb290ZXI7CiNlbmRpZgojaWZkZWYgRkVBVF9NRU5VCiMgaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQovKiByZW1lbWJlciB0aGUgbGFzdCBzZXQgdmFsdWUgZm9yIHRoZSB0ZWFyb2ZmIGl0ZW0gKi8Kc3RhdGljIGludCB0ZWFyb2ZmX3ZhbCA9IChpbnQpWG1URUFSX09GRl9FTkFCTEVEOwojIGVuZGlmCnN0YXRpYyBXaWRnZXQgbWVudUJhcjsKI2VuZGlmCgpzdGF0aWMgdm9pZCBzY3JvbGxfY2IgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYdFBvaW50ZXIgY2FsbF9kYXRhKSk7CiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCnN0YXRpYyB2b2lkIHRhYmxpbmVfY2IgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYdFBvaW50ZXIgY2FsbF9kYXRhKSk7CnN0YXRpYyB2b2lkIHRhYmxpbmVfYnV0dG9uX2NiIF9fQVJHUygoV2lkZ2V0IHcsIFh0UG9pbnRlciBjbGllbnRfZGF0YSwgWHRQb2ludGVyIGNhbGxfZGF0YSkpOwpzdGF0aWMgdm9pZCB0YWJsaW5lX21lbnVfY2IgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyCWNsb3N1cmUsIFhFdmVudAkqZSwgQm9vbGVhbiAqY29udGludWVfZGlzcGF0Y2gpKTsKc3RhdGljIHZvaWQgdGFibGluZV9iYWxsb29uX2NiIF9fQVJHUygoQmFsbG9vbkV2YWwgKmJldmFsLCBpbnQgc3RhdGUpKTsKI2VuZGlmCiNpZmRlZiBGRUFUX1RPT0xCQVIKIyBpZmRlZiBGRUFUX0ZPT1RFUgpzdGF0aWMgdm9pZCB0b29sYmFyYnV0dG9uX2VudGVyX2NiIF9fQVJHUygoV2lkZ2V0LCBYdFBvaW50ZXIsIFhFdmVudCAqLCBCb29sZWFuICopKTsKc3RhdGljIHZvaWQgdG9vbGJhcmJ1dHRvbl9sZWF2ZV9jYiBfX0FSR1MoKFdpZGdldCwgWHRQb2ludGVyLCBYRXZlbnQgKiwgQm9vbGVhbiAqKSk7CiMgZW5kaWYKc3RhdGljIHZvaWQgcmVzZXRfZm9jdXMgX19BUkdTKCh2b2lkKSk7CiNlbmRpZgojaWZkZWYgRkVBVF9GT09URVIKc3RhdGljIGludCBndWlfbWNoX2NvbXB1dGVfZm9vdGVyX2hlaWdodCBfX0FSR1MoKHZvaWQpKTsKI2VuZGlmCiNpZmRlZiBXU0RFQlVHCnN0YXRpYyB2b2lkIGF0dGFjaER1bXAoV2lkZ2V0LCBjaGFyICopOwojZW5kaWYKCnN0YXRpYyB2b2lkIGd1aV9tb3RpZl9tZW51X2NvbG9ycyBfX0FSR1MoKFdpZGdldCBpZCkpOwpzdGF0aWMgdm9pZCBndWlfbW90aWZfc2Nyb2xsX2NvbG9ycyBfX0FSR1MoKFdpZGdldCBpZCkpOwoKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKIyBkZWZpbmUgU1RSSU5HX1RBRyAgWG1GT05UTElTVF9ERUZBVUxUX1RBRwojZWxzZQojIGRlZmluZSBTVFJJTkdfVEFHICBYbVNUUklOR19ERUZBVUxUX0NIQVJTRVQKI2VuZGlmCgovKgogKiBDYWxsLWJhY2sgcm91dGluZXMuCiAqLwoKICAgIHN0YXRpYyB2b2lkCnNjcm9sbF9jYih3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXcgVU5VU0VEOwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhLCBjYWxsX2RhdGE7CnsKICAgIHNjcm9sbGJhcl9UICpzYjsKICAgIGxvbmcJdmFsdWU7CiAgICBpbnQJCWRyYWdnaW5nOwoKICAgIHNiID0gZ3VpX2ZpbmRfc2Nyb2xsYmFyKChsb25nKWNsaWVudF9kYXRhKTsKCiAgICB2YWx1ZSA9ICgoWG1TY3JvbGxCYXJDYWxsYmFja1N0cnVjdCAqKWNhbGxfZGF0YSktPnZhbHVlOwogICAgZHJhZ2dpbmcgPSAoKChYbVNjcm9sbEJhckNhbGxiYWNrU3RydWN0ICopY2FsbF9kYXRhKS0+cmVhc29uID09CgkJCQkJCQkgICAgICAoaW50KVhtQ1JfRFJBRyk7CiAgICBndWlfZHJhZ19zY3JvbGxiYXIoc2IsIHZhbHVlLCBkcmFnZ2luZyk7Cn0KCiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCiAgICBzdGF0aWMgdm9pZAp0YWJsaW5lX2NiKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdyBVTlVTRUQ7CiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGEgVU5VU0VEOwogICAgWHRQb2ludGVyCWNhbGxfZGF0YTsKewogICAgWG1Ob3RlYm9va0NhbGxiYWNrU3RydWN0ICpucHRyOwoKICAgIG5wdHIgPSAoWG1Ob3RlYm9va0NhbGxiYWNrU3RydWN0ICopY2FsbF9kYXRhOwogICAgaWYgKG5wdHItPnJlYXNvbiAhPSAoaW50KVhtQ1JfTk9ORSkKCXNlbmRfdGFibGluZV9ldmVudChucHRyLT5wYWdlX251bWJlcik7Cn0KCiAgICBzdGF0aWMgdm9pZAp0YWJsaW5lX2J1dHRvbl9jYih3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXc7CiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGEgVU5VU0VEOwogICAgWHRQb2ludGVyCWNhbGxfZGF0YSBVTlVTRUQ7CnsKICAgIGludAkJY21kLCB0YWJfaWR4OwoKICAgIFh0VmFHZXRWYWx1ZXModywgWG1OdXNlckRhdGEsICZjbWQsIE5VTEwpOwogICAgWHRWYUdldFZhbHVlcyh0YWJMaW5lX21lbnUsIFhtTnVzZXJEYXRhLCAmdGFiX2lkeCwgTlVMTCk7CgogICAgc2VuZF90YWJsaW5lX21lbnVfZXZlbnQodGFiX2lkeCwgY21kKTsKfQoKLyoKICogVGFibGluZSBzaW5nbGUgbW91c2UgY2xpY2sgdGltZW91dCBoYW5kbGVyCiAqLwogICAgc3RhdGljIHZvaWQKbW90aWZfdGFibGluZV90aW1lcl9jYiAodGltZWRfb3V0LCBpbnRlcnZhbF9pZCkKICAgIFh0UG9pbnRlcgkJdGltZWRfb3V0OwogICAgWHRJbnRlcnZhbElkCSppbnRlcnZhbF9pZCBVTlVTRUQ7CnsKICAgICooKGludCAqKXRpbWVkX291dCkgPSBUUlVFOwp9CgovKgogKiBjaGVjayBpZiB0aGUgdGFibGluZSB0YWIgc2Nyb2xsZXIgaXMgY2xpY2tlZAogKi8KICAgIHN0YXRpYyBpbnQKdGFibGluZV9zY3JvbGxlcl9jbGlja2VkKHNjcm9sbGVyX25hbWUsIGV2ZW50KQogICAgY2hhcgkJKnNjcm9sbGVyX25hbWU7CiAgICBYQnV0dG9uUHJlc3NlZEV2ZW50ICpldmVudDsKewogICAgV2lkZ2V0CXRhYl9zY3JvbGxfdzsKICAgIFBvc2l0aW9uCXBvc194LCBwb3NfeTsKICAgIERpbWVuc2lvbgl3aWR0aCwgaGVpZ2h0OwoKICAgIHRhYl9zY3JvbGxfdyA9IFh0TmFtZVRvV2lkZ2V0KHRhYkxpbmUsIHNjcm9sbGVyX25hbWUpOwogICAgaWYgKHRhYl9zY3JvbGxfdyAhPSAoV2lkZ2V0KTApIHsKCVh0VmFHZXRWYWx1ZXModGFiX3Njcm9sbF93LCBYbU54LCAmcG9zX3gsIFhtTnksICZwb3NfeSwgWG1Od2lkdGgsCgkJICAgICAgJndpZHRoLCBYbU5oZWlnaHQsICZoZWlnaHQsIE5VTEwpOwoJaWYgKHBvc194ID49IDApIHsKCSAgICAvKiBUYWIgc2Nyb2xsZXIgKG5leHQpIGlzIHZpc2libGUgKi8KCSAgICBpZiAoKGV2ZW50LT54ID49IHBvc194KSAmJiAoZXZlbnQtPnggPD0gcG9zX3ggKyB3aWR0aCkgJiYKCQkoZXZlbnQtPnkgPj0gcG9zX3kpICYmIChldmVudC0+eSA8PSBwb3NfeSArIGhlaWdodCkpIHsKCQkvKiBDbGlja2VkIG9uIHRoZSBzY3JvbGxlciAqLwoJCXJldHVybiBUUlVFOwoJICAgIH0KCX0KICAgIH0KICAgIHJldHVybiBGQUxTRTsKfQoKICAgIHN0YXRpYyB2b2lkCnRhYmxpbmVfbWVudV9jYih3LCBjbG9zdXJlLCBlLCBjb250aW51ZV9kaXNwYXRjaCkKICAgIFdpZGdldAl3OwogICAgWHRQb2ludGVyCWNsb3N1cmUgVU5VU0VEOwogICAgWEV2ZW50CSplOwogICAgQm9vbGVhbgkqY29udGludWVfZGlzcGF0Y2ggVU5VU0VEOwp7CiAgICBXaWRnZXQJCQl0YWJfdzsKICAgIFhCdXR0b25QcmVzc2VkRXZlbnQJCSpldmVudDsKICAgIGludAkJCQl0YWJfaWR4ID0gMDsKICAgIFdpZGdldExpc3QJCQljaGlsZHJlbjsKICAgIENhcmRpbmFsCQkJbnVtQ2hpbGRyZW47CiAgICBzdGF0aWMgWHRJbnRlcnZhbElkCQl0aW1lciA9IChYdEludGVydmFsSWQpMDsKICAgIHN0YXRpYyBpbnQJCQl0aW1lZF9vdXQgPSBUUlVFOwoKICAgIGV2ZW50ID0gKFhCdXR0b25QcmVzc2VkRXZlbnQgKillOwoKICAgIGlmIChldmVudC0+YnV0dG9uID09IEJ1dHRvbjEpCiAgICB7CglpZiAodGFibGluZV9zY3JvbGxlcl9jbGlja2VkKCJNYWpvclRhYlNjcm9sbGVyTmV4dCIsIGV2ZW50KQoJICAgIHx8IHRhYmxpbmVfc2Nyb2xsZXJfY2xpY2tlZCgiTWFqb3JUYWJTY3JvbGxlclByZXZpb3VzIiwgZXZlbnQpKQoJICAgIHJldHVybjsKCglpZiAoIXRpbWVkX291dCkKCXsKCSAgICBYdFJlbW92ZVRpbWVPdXQodGltZXIpOwoJICAgIHRpbWVkX291dCA9IFRSVUU7CgoJICAgIC8qCgkgICAgICogRG91YmxlIGNsaWNrIG9uIHRoZSB0YWJsaW5lIGd1dHRlciwgYWRkIGEgbmV3IHRhYgoJICAgICAqLwoJICAgIHNlbmRfdGFibGluZV9tZW51X2V2ZW50KDAsIFRBQkxJTkVfTUVOVV9ORVcpOwoJfQoJZWxzZQoJewoJICAgIC8qCgkgICAgICogU2luZ2xlIGNsaWNrIG9uIHRoZSB0YWJsaW5lIGd1dHRlciwgc3RhcnQgYSB0aW1lciB0byBjaGVjawoJICAgICAqIGZvciBkb3VibGUgY2xpY2tzCgkgICAgICovCgkgICAgdGltZXIgPSBYdEFwcEFkZFRpbWVPdXQoYXBwX2NvbnRleHQsIChsb25nX3UpcF9tb3VzZXQsCgkJCQkgICAgbW90aWZfdGFibGluZV90aW1lcl9jYiwgJnRpbWVkX291dCk7CgkgICAgdGltZWRfb3V0ID0gRkFMU0U7Cgl9CglyZXR1cm47CiAgICB9CgogICAgaWYgKGV2ZW50LT5idXR0b24gIT0gQnV0dG9uMykKCXJldHVybjsKCiAgICAvKiBXaGVuIGlnbm9yaW5nIGV2ZW50cyBkb24ndCBzaG93IHRoZSBtZW51LiAqLwogICAgaWYgKGhvbGRfZ3VpX2V2ZW50cwojIGlmZGVmIEZFQVRfQ01EV0lOCgkgICAgfHwgY21kd2luX3R5cGUgIT0gMAojIGVuZGlmCiAgICAgICApCglyZXR1cm47CgogICAgaWYgKGV2ZW50LT5zdWJ3aW5kb3cgIT0gTm9uZSkKICAgIHsKCXRhYl93ID0gWHRXaW5kb3dUb1dpZGdldChYdERpc3BsYXkodyksIGV2ZW50LT5zdWJ3aW5kb3cpOwoJLyogTElOVEVEOiBhdm9pZCB3YXJuaW5nOiBkdWJpb3VzIG9wZXJhdGlvbiBvbiBlbnVtICovCglpZiAodGFiX3cgIT0gKFdpZGdldCkwICYmIFhtSXNQdXNoQnV0dG9uKHRhYl93KSkKCSAgICBYdFZhR2V0VmFsdWVzKHRhYl93LCBYbU5wYWdlTnVtYmVyLCAmdGFiX2lkeCwgTlVMTCk7CiAgICB9CgogICAgWHRWYVNldFZhbHVlcyh0YWJMaW5lX21lbnUsIFhtTnVzZXJEYXRhLCB0YWJfaWR4LCBOVUxMKTsKICAgIFh0VmFHZXRWYWx1ZXModGFiTGluZV9tZW51LCBYbU5jaGlsZHJlbiwgJmNoaWxkcmVuLCBYbU5udW1DaGlsZHJlbiwKCQkgICZudW1DaGlsZHJlbiwgTlVMTCk7CiAgICBYdE1hbmFnZUNoaWxkcmVuKGNoaWxkcmVuLCBudW1DaGlsZHJlbik7CiAgICBYbU1lbnVQb3NpdGlvbih0YWJMaW5lX21lbnUsIChYQnV0dG9uUHJlc3NlZEV2ZW50ICopZSkgOwogICAgWHRNYW5hZ2VDaGlsZCh0YWJMaW5lX21lbnUpOwp9CgogICAgc3RhdGljIHZvaWQKdGFibGluZV9iYWxsb29uX2NiKGJldmFsLCBzdGF0ZSkKICAgIEJhbGxvb25FdmFsCSpiZXZhbDsKICAgIGludAkJc3RhdGUgVU5VU0VEOwp7CiAgICBpbnQJCW5yOwogICAgdGFicGFnZV9UCSp0cDsKCiAgICBpZiAoYmV2YWwtPnRhcmdldCA9PSAoV2lkZ2V0KTApCglyZXR1cm47CgogICAgWHRWYUdldFZhbHVlcyhiZXZhbC0+dGFyZ2V0LCBYbU5wYWdlTnVtYmVyLCAmbnIsIE5VTEwpOwogICAgdHAgPSBmaW5kX3RhYnBhZ2UobnIpOwogICAgaWYgKHRwID09IE5VTEwpCglyZXR1cm47CgogICAgZ2V0X3RhYmxpbmVfbGFiZWwodHAsIFRSVUUpOwogICAgZ3VpX21jaF9wb3N0X2JhbGxvb24oYmV2YWwsIE5hbWVCdWZmKTsKfQoKI2VuZGlmCgovKgogKiBFbmQgb2YgY2FsbC1iYWNrIHJvdXRpbmVzCiAqLwoKLyoKICogSW1wbGVtZW50IHRocmVlIGRpbWVuc2lvbmFsIHNoYWRpbmcgb2YgaW5zZW5zaXRpdmUgbGFiZWxzLgogKiBCeSBNYXJjaW4gRGFsZWNraS4KICovCgojaW5jbHVkZSA8WG0vWG1QLmg+CiNpbmNsdWRlIDxYbS9MYWJlbFAuaD4KCnN0YXRpYyBYdEV4cG9zZVByb2Mgb2xkX2xhYmVsX2V4cG9zZSA9IE5VTEw7CgpzdGF0aWMgdm9pZCBsYWJlbF9leHBvc2UgX19BUkdTKChXaWRnZXQgX3csIFhFdmVudCAqX2V2ZW50LCBSZWdpb24gX3JlZ2lvbikpOwoKICAgIHN0YXRpYyB2b2lkCmxhYmVsX2V4cG9zZShfdywgX2V2ZW50LCBfcmVnaW9uKQogICAgV2lkZ2V0CV93OwogICAgWEV2ZW50CSpfZXZlbnQ7CiAgICBSZWdpb24JX3JlZ2lvbjsKewogICAgR0MJCSAgICBpbnNlbnNpdGl2ZUdDOwogICAgWG1MYWJlbFdpZGdldCAgIGx3ID0gKFhtTGFiZWxXaWRnZXQpX3c7CiAgICB1bnNpZ25lZCBjaGFyICAgbGFiZWxfdHlwZSA9IChpbnQpWG1TVFJJTkc7CgogICAgWHRWYUdldFZhbHVlcyhfdywgWG1ObGFiZWxUeXBlLCAmbGFiZWxfdHlwZSwgKFh0UG9pbnRlcikwKTsKCiAgICBpZiAoWHRJc1NlbnNpdGl2ZShfdykgfHwgbGFiZWxfdHlwZSAhPSAoaW50KVhtU1RSSU5HKQoJKCpvbGRfbGFiZWxfZXhwb3NlKShfdywgX2V2ZW50LCBfcmVnaW9uKTsKICAgIGVsc2UKICAgIHsKCVhHQ1ZhbHVlcyAgIHZhbHVlczsKCVh0R0NNYXNrICAgIG1hc2s7CglYdEdDTWFzayAgICBkeW5hbWljOwoJWEZvbnRTdHJ1Y3QgKmZzOwoKCV9YbUZvbnRMaXN0R2V0RGVmYXVsdEZvbnQobHctPmxhYmVsLmZvbnQsICZmcyk7CgoJLyogRklYTUU6IHdlIHNob3VsZCBiZSBkb2luZyB0aGUgd2hvbGUgZHJhd2luZyBvdXJzZWxmIGhlcmUuICovCglpbnNlbnNpdGl2ZUdDID0gbHctPmxhYmVsLmluc2Vuc2l0aXZlX0dDOwoKCW1hc2sgPSBHQ0ZvcmVncm91bmQgfCBHQ0JhY2tncm91bmQgfCBHQ0dyYXBoaWNzRXhwb3N1cmVzOwoJZHluYW1pYyA9IEdDQ2xpcE1hc2sgfCBHQ0NsaXBYT3JpZ2luIHwgR0NDbGlwWU9yaWdpbjsKCXZhbHVlcy5ncmFwaGljc19leHBvc3VyZXMgPSBGYWxzZTsKCglpZiAoZnMgIT0gMCkKCXsKCSAgICBtYXNrIHw9IEdDRm9udDsKCSAgICB2YWx1ZXMuZm9udCA9IGZzLT5maWQ7Cgl9CgoJaWYgKGx3LT5wcmltaXRpdmUudG9wX3NoYWRvd19waXhtYXAgIT0gTm9uZQoJCSYmIGx3LT5wcmltaXRpdmUudG9wX3NoYWRvd19waXhtYXAgIT0gWG1VTlNQRUNJRklFRF9QSVhNQVApCgl7CgkgICAgbWFzayB8PSBHQ0ZpbGxTdHlsZSB8IEdDVGlsZTsKCSAgICB2YWx1ZXMuZmlsbF9zdHlsZSA9IEZpbGxUaWxlZDsKCSAgICB2YWx1ZXMudGlsZSA9IGx3LT5wcmltaXRpdmUudG9wX3NoYWRvd19waXhtYXA7Cgl9CgoJbHctPmxhYmVsLlRleHRSZWN0LnggKz0gMTsKCWx3LT5sYWJlbC5UZXh0UmVjdC55ICs9IDE7CglpZiAobHctPmxhYmVsLl9hY2NfdGV4dCAhPSAwKQoJewoJICAgIGx3LT5sYWJlbC5hY2NfVGV4dFJlY3QueCArPSAxOwoJICAgIGx3LT5sYWJlbC5hY2NfVGV4dFJlY3QueSArPSAxOwoJfQoKCXZhbHVlcy5mb3JlZ3JvdW5kID0gbHctPnByaW1pdGl2ZS50b3Bfc2hhZG93X2NvbG9yOwoJdmFsdWVzLmJhY2tncm91bmQgPSBsdy0+Y29yZS5iYWNrZ3JvdW5kX3BpeGVsOwoKCWx3LT5sYWJlbC5pbnNlbnNpdGl2ZV9HQyA9IFh0QWxsb2NhdGVHQygoV2lkZ2V0KWx3LCAwLCBtYXNrLAoJCQkJCSAgICAgICAmdmFsdWVzLCBkeW5hbWljLCAoWHRHQ01hc2spMCk7CgkoKm9sZF9sYWJlbF9leHBvc2UpKF93LCBfZXZlbnQsIF9yZWdpb24pOwoJWHRSZWxlYXNlR0MoX3csIGx3LT5sYWJlbC5pbnNlbnNpdGl2ZV9HQyk7CgoJbHctPmxhYmVsLlRleHRSZWN0LnggLT0gMTsKCWx3LT5sYWJlbC5UZXh0UmVjdC55IC09IDE7CglpZiAobHctPmxhYmVsLl9hY2NfdGV4dCAhPSAwKQoJewoJICAgIGx3LT5sYWJlbC5hY2NfVGV4dFJlY3QueCAtPSAxOwoJICAgIGx3LT5sYWJlbC5hY2NfVGV4dFJlY3QueSAtPSAxOwoJfQoKCXZhbHVlcy5mb3JlZ3JvdW5kID0gbHctPnByaW1pdGl2ZS5ib3R0b21fc2hhZG93X2NvbG9yOwoJdmFsdWVzLmJhY2tncm91bmQgPSBsdy0+Y29yZS5iYWNrZ3JvdW5kX3BpeGVsOwoKCWx3LT5sYWJlbC5pbnNlbnNpdGl2ZV9HQyA9IFh0QWxsb2NhdGVHQygoV2lkZ2V0KSBsdywgMCwgbWFzaywKCQkJCQkgICAgICAgJnZhbHVlcywgZHluYW1pYywgKFh0R0NNYXNrKTApOwoJKCpvbGRfbGFiZWxfZXhwb3NlKShfdywgX2V2ZW50LCBfcmVnaW9uKTsKCVh0UmVsZWFzZUdDKF93LCBsdy0+bGFiZWwuaW5zZW5zaXRpdmVfR0MpOwoKCWx3LT5sYWJlbC5pbnNlbnNpdGl2ZV9HQyA9IGluc2Vuc2l0aXZlR0M7CiAgICB9Cn0KCi8qCiAqIENyZWF0ZSBhbGwgdGhlIG1vdGlmIHdpZGdldHMgbmVjZXNzYXJ5LgogKi8KICAgIHZvaWQKZ3VpX3gxMV9jcmVhdGVfd2lkZ2V0cygpCnsKI2lmZGVmIEZFQVRfR1VJX1RBQkxJTkUKICAgIFdpZGdldAlidXR0b24sIHNjcm9sbGVyOwogICAgQXJnCQlhcmdzWzEwXTsKICAgIGludAkJbjsKICAgIFhtU3RyaW5nCXhtczsKI2VuZGlmCgogICAgLyoKICAgICAqIEluc3RhbGwgdGhlIDNEIHNoYWRlIGVmZmVjdCBkcmF3aW5nIHJvdXRpbmVzLgogICAgICovCiAgICBpZiAob2xkX2xhYmVsX2V4cG9zZSA9PSBOVUxMKQogICAgewoJb2xkX2xhYmVsX2V4cG9zZSA9IHhtTGFiZWxXaWRnZXRDbGFzcy0+Y29yZV9jbGFzcy5leHBvc2U7Cgl4bUxhYmVsV2lkZ2V0Q2xhc3MtPmNvcmVfY2xhc3MuZXhwb3NlID0gbGFiZWxfZXhwb3NlOwogICAgfQoKICAgIC8qCiAgICAgKiBTdGFydCBvdXQgYnkgYWRkaW5nIHRoZSBjb25maWd1cmVkIGJvcmRlciB3aWR0aCBpbnRvIHRoZSBib3JkZXIgb2Zmc2V0CiAgICAgKi8KICAgIGd1aS5ib3JkZXJfb2Zmc2V0ID0gZ3VpLmJvcmRlcl93aWR0aDsKCiAgICAvKgogICAgICogSW5zdGFsbCB0aGUgdGVhck9mZk1vZGVsIHJlc291cmNlIGNvbnZlcnRlci4KICAgICAqLwojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQogICAgWG1SZXBUeXBlSW5zdGFsbFRlYXJPZmZNb2RlbENvbnZlcnRlcigpOwojZW5kaWYKCiAgICAvKiBNYWtlIHN1cmUgdGhlICJRdWl0IiBtZW51IGVudHJ5IG9mIHRoZSB3aW5kb3cgbWFuYWdlciBpcyBpZ25vcmVkICovCiAgICBYdFZhU2V0VmFsdWVzKHZpbVNoZWxsLCBYbU5kZWxldGVSZXNwb25zZSwgWG1ET19OT1RISU5HLCBOVUxMKTsKCiAgICB2aW1Gb3JtID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInZpbUZvcm0iLAoJeG1Gb3JtV2lkZ2V0Q2xhc3MsIHZpbVNoZWxsLAoJWG1OYm9yZGVyV2lkdGgsIDAsCglYbU5oaWdobGlnaHRUaGlja25lc3MsIDAsCglYbU5zaGFkb3dUaGlja25lc3MsIDAsCglYbU5tYXJnaW5XaWR0aCwgMCwKCVhtTm1hcmdpbkhlaWdodCwgMCwKCVhtTnJlc2l6ZVBvbGljeSwgWG1SRVNJWkVfQU5ZLAoJTlVMTCk7CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnModmltRm9ybSk7CgojaWZkZWYgRkVBVF9NRU5VCiAgICB7CglBcmcgYWxbN107IC8qIE1ha2Ugc3VyZSB0aGVyZSBpcyBlbm91Z2ggcm9vbSBmb3IgYXJndW1lbnRzISAqLwoJaW50IGFjID0gMDsKCiMgaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJWHRTZXRBcmcoYWxbYWNdLCBYbU50ZWFyT2ZmTW9kZWwsIHRlYXJvZmZfdmFsKTsgYWMrKzsKIyBlbmRpZgoJWHRTZXRBcmcoYWxbYWNdLCBYbU5sZWZ0QXR0YWNobWVudCwgIFhtQVRUQUNIX0ZPUk0pOyBhYysrOwoJWHRTZXRBcmcoYWxbYWNdLCBYbU50b3BBdHRhY2htZW50LCAgIFhtQVRUQUNIX0ZPUk0pOyBhYysrOwoJWHRTZXRBcmcoYWxbYWNdLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBhYysrOwojIGlmbmRlZiBGRUFUX1RPT0xCQVIKCS8qIEFsd2F5cyBzdGljayB0byByaWdodCBoYW5kIHNpZGUuICovCglYdFNldEFyZyhhbFthY10sIFhtTnJpZ2h0T2Zmc2V0LCAwKTsgYWMrKzsKIyBlbmRpZgoJWHRTZXRBcmcoYWxbYWNdLCBYbU5tYXJnaW5IZWlnaHQsIDApOyBhYysrOwoJbWVudUJhciA9IFhtQ3JlYXRlTWVudUJhcih2aW1Gb3JtLCAibWVudUJhciIsIGFsLCBhYyk7CglYdE1hbmFnZUNoaWxkKG1lbnVCYXIpOwoKCS8qIFJlbWVtYmVyIHRoZSBkZWZhdWx0IGNvbG9ycywgbmVlZGVkIGZvciAiOmhpIGNsZWFyIi4gKi8KCVh0VmFHZXRWYWx1ZXMobWVudUJhciwKCSAgICBYbU5iYWNrZ3JvdW5kLCAmZ3VpLm1lbnVfZGVmX2JnX3BpeGVsLAoJICAgIFhtTmZvcmVncm91bmQsICZndWkubWVudV9kZWZfZmdfcGl4ZWwsCgkgICAgTlVMTCk7CglndWlfbW90aWZfbWVudV9jb2xvcnMobWVudUJhcik7CiAgICB9CiNlbmRpZgoKI2lmZGVmIEZFQVRfVE9PTEJBUgogICAgLyoKICAgICAqIENyZWF0ZSBhbiBlbXB0eSBUb29sQmFyLiBXZSBzaG91bGQgZ2V0IGJ1dHRvbnMgZGVmaW5lZCBmcm9tIG1lbnUudmltLgogICAgICovCiAgICB0b29sQmFyRnJhbWUgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJ0b29sQmFyRnJhbWUiLAoJeG1GcmFtZVdpZGdldENsYXNzLCB2aW1Gb3JtLAoJWG1Oc2hhZG93VGhpY2tuZXNzLCAwLAoJWG1ObWFyZ2luSGVpZ2h0LCAwLAoJWG1ObWFyZ2luV2lkdGgsIDAsCglYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCU5VTEwpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHRvb2xCYXJGcmFtZSk7CgogICAgdG9vbEJhciA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJ0b29sQmFyIiwKCXhtUm93Q29sdW1uV2lkZ2V0Q2xhc3MsIHRvb2xCYXJGcmFtZSwKCVhtTmNoaWxkVHlwZSwgWG1GUkFNRV9XT1JLQVJFQV9DSElMRCwKCVhtTnJvd0NvbHVtblR5cGUsIFhtV09SS19BUkVBLAoJWG1Ob3JpZW50YXRpb24sIFhtSE9SSVpPTlRBTCwKCVhtTnRyYXZlcnNhbE9uLCBGYWxzZSwKCVhtTmlzSG9tb2dlbmVvdXMsIEZhbHNlLAoJWG1OcGFja2luZywgWG1QQUNLX1RJR0hULAoJWG1Oc3BhY2luZywgMCwKCVhtTnNoYWRvd1RoaWNrbmVzcywgMCwKCVhtTmhpZ2hsaWdodFRoaWNrbmVzcywgMCwKCVhtTm1hcmdpbkhlaWdodCwgMCwKCVhtTm1hcmdpbldpZHRoLCAwLAoJWG1OYWRqdXN0TGFzdCwgVHJ1ZSwKCU5VTEwpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHRvb2xCYXIpOwoKI2VuZGlmCgojaWZkZWYgRkVBVF9HVUlfVEFCTElORQogICAgLyogQ3JlYXRlIHRoZSBWaW0gR1VJIHRhYmxpbmUgKi8KICAgIG4gPSAwOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYmluZGluZ1R5cGUsIFhtTk9ORSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm9yaWVudGF0aW9uLCBYbVZFUlRJQ0FMKTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYmFja1BhZ2VTaXplLCBYbU5PTkUpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5iYWNrUGFnZU51bWJlciwgMCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJhY2tQYWdlUGxhY2VtZW50LCBYbVRPUF9SSUdIVCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm1ham9yVGFiU3BhY2luZywgMCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnNoYWRvd1RoaWNrbmVzcywgMCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwogICAgdGFiTGluZSA9IFhtQ3JlYXRlTm90ZWJvb2sodmltRm9ybSwgIlZpbSB0YWJsaW5lIiwgYXJncywgbik7CgogICAgWHRBZGRDYWxsYmFjayh0YWJMaW5lLCBYbU5wYWdlQ2hhbmdlZENhbGxiYWNrLCAoWHRDYWxsYmFja1Byb2MpdGFibGluZV9jYiwKCQkJTlVMTCk7CiAgICBYdEFkZEV2ZW50SGFuZGxlcih0YWJMaW5lLCBCdXR0b25QcmVzc01hc2ssIEZhbHNlLAoJCQkoWHRFdmVudEhhbmRsZXIpdGFibGluZV9tZW51X2NiLCBOVUxMKTsKCiAgICBndWkudGFibGluZV9oZWlnaHQgPSBUQUJMSU5FX0hFSUdIVDsKCiAgICAvKgogICAgICogU2V0IHRoZSBzaXplIG9mIHRoZSBtaW5vciBuZXh0L3ByZXYgc2Nyb2xsZXJzIHRvIHplcm8sIHNvCiAgICAgKiB0aGF0IHRoZXkgYXJlIG5vdCBkaXNwbGF5ZWQuIER1ZSB0byBhIGJ1ZyBpbiBPcGVuTW90aWYgMi4zLAogICAgICogZXZlbiBpZiB0aGVzZSBjaGlsZHJlbiB3aWRnZXQgYXJlIHVubWFuYWdlZCwgdGhleSBhcmUgYWdhaW4KICAgICAqIG1hbmFnZWQgYnkgdGhlIE5vdGVib29rIHdpZGdldCBhbmQgdGhlIG5vdGVib29rIHdpZGdldCBnZW9tZXRyeQogICAgICogaXMgYWRqdXN0ZWQgdG8gYWNjb3VudCBmb3IgdGhlIG1pbm9yIHNjcm9sbGVyIHdpZGdldHMuCiAgICAgKi8KICAgIHNjcm9sbGVyID0gWHROYW1lVG9XaWRnZXQodGFiTGluZSwgIk1pbm9yVGFiU2Nyb2xsZXJOZXh0Iik7CiAgICBYdFZhU2V0VmFsdWVzKHNjcm9sbGVyLCBYbU53aWR0aCwgMCwgWG1OcmVzaXphYmxlLCBGYWxzZSwKCQkgIFhtTnRyYXZlcnNhbE9uLCBGYWxzZSwgTlVMTCk7CiAgICBzY3JvbGxlciA9IFh0TmFtZVRvV2lkZ2V0KHRhYkxpbmUsICJNaW5vclRhYlNjcm9sbGVyUHJldmlvdXMiKTsKICAgIFh0VmFTZXRWYWx1ZXMoc2Nyb2xsZXIsIFhtTndpZHRoLCAwLCBYbU5yZXNpemFibGUsIEZhbHNlLAoJCSAgWG1OdHJhdmVyc2FsT24sIEZhbHNlLCBOVUxMKTsKCiAgICAvKiBDcmVhdGUgdGhlIHRhYmxpbmUgcG9wdXAgbWVudSAqLwogICAgdGFiTGluZV9tZW51ID0gWG1DcmVhdGVQb3B1cE1lbnUodGFiTGluZSwgInRhYmxpbmUgcG9wdXAiLCBOVUxMLCAwKTsKCiAgICAvKiBBZGQgdGhlIGJ1dHRvbnMgdG8gdGhlIG1lbnUgKi8KICAgIGlmIChmaXJzdF90YWJwYWdlLT50cF9uZXh0ICE9IE5VTEwpCiAgICB7CgluID0gMDsKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnVzZXJEYXRhLCBUQUJMSU5FX01FTlVfQ0xPU0UpOyBuKys7Cgl4bXMgPSBYbVN0cmluZ0NyZWF0ZSgoY2hhciAqKSJDbG9zZSB0YWIiLCBTVFJJTkdfVEFHKTsKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxhYmVsU3RyaW5nLCB4bXMpOyBuKys7CglidXR0b24gPSBYbUNyZWF0ZVB1c2hCdXR0b24odGFiTGluZV9tZW51LCAiQ2xvc2UiLCBhcmdzLCBuKTsKCVh0QWRkQ2FsbGJhY2soYnV0dG9uLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCSAgICAgIChYdENhbGxiYWNrUHJvYyl0YWJsaW5lX2J1dHRvbl9jYiwgTlVMTCk7CglYbVN0cmluZ0ZyZWUoeG1zKTsKICAgIH0KCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnVzZXJEYXRhLCBUQUJMSU5FX01FTlVfTkVXKTsgbisrOwogICAgeG1zID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKikiTmV3IFRhYiIsIFNUUklOR19UQUcpOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGFiZWxTdHJpbmcsIHhtcyk7IG4rKzsKICAgIGJ1dHRvbiA9IFhtQ3JlYXRlUHVzaEJ1dHRvbih0YWJMaW5lX21lbnUsICJOZXcgVGFiIiwgYXJncywgbik7CiAgICBYdEFkZENhbGxiYWNrKGJ1dHRvbiwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCQkgIChYdENhbGxiYWNrUHJvYyl0YWJsaW5lX2J1dHRvbl9jYiwgTlVMTCk7CiAgICBYbVN0cmluZ0ZyZWUoeG1zKTsKCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnVzZXJEYXRhLCBUQUJMSU5FX01FTlVfT1BFTik7IG4rKzsKICAgIHhtcyA9IFhtU3RyaW5nQ3JlYXRlKChjaGFyICopIk9wZW4gdGFiLi4uIiwgU1RSSU5HX1RBRyk7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sYWJlbFN0cmluZywgeG1zKTsgbisrOwogICAgYnV0dG9uID0gWG1DcmVhdGVQdXNoQnV0dG9uKHRhYkxpbmVfbWVudSwgIk9wZW4gdGFiLi4uIiwgYXJncywgbik7CiAgICBYdEFkZENhbGxiYWNrKGJ1dHRvbiwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCQkgIChYdENhbGxiYWNrUHJvYyl0YWJsaW5lX2J1dHRvbl9jYiwgTlVMTCk7CiAgICBYbVN0cmluZ0ZyZWUoeG1zKTsKI2VuZGlmCgogICAgdGV4dEFyZWFGb3JtID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInRleHRBcmVhRm9ybSIsCgl4bUZvcm1XaWRnZXRDbGFzcywgdmltRm9ybSwKCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglYbU5tYXJnaW5XaWR0aCwgMCwKCVhtTm1hcmdpbkhlaWdodCwgMCwKCVhtTnJlc2l6ZVBvbGljeSwgWG1SRVNJWkVfQU5ZLAoJTlVMTCk7CiAgICBndWlfbW90aWZfc2Nyb2xsX2NvbG9ycyh0ZXh0QXJlYUZvcm0pOwoKICAgIHRleHRBcmVhID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInRleHRBcmVhIiwKCXhtRHJhd2luZ0FyZWFXaWRnZXRDbGFzcywgdGV4dEFyZWFGb3JtLAoJWG1OZm9yZWdyb3VuZCwgZ3VpLm5vcm1fcGl4ZWwsCglYbU5iYWNrZ3JvdW5kLCBndWkuYmFja19waXhlbCwKCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgoJLyoKCSAqIFRoZXNlIHRha2Ugc29tZSBjb250cm9sIGF3YXkgZnJvbSB0aGUgdXNlciwgYnV0IGF2b2lkcyBtYWtpbmcgdGhlbQoJICogYWRkIHJlc291cmNlcyB0byBnZXQgYSBkZWNlbnQgbG9va2luZyBzZXR1cC4KCSAqLwoJWG1OYm9yZGVyV2lkdGgsIDAsCglYbU5oaWdobGlnaHRUaGlja25lc3MsIDAsCglYbU5zaGFkb3dUaGlja25lc3MsIDAsCglOVUxMKTsKCiNpZmRlZiBGRUFUX0ZPT1RFUgogICAgLyoKICAgICAqIENyZWF0ZSB0aGUgRm9vdGVyLgogICAgICovCiAgICBmb290ZXIgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJmb290ZXIiLAoJeG1MYWJlbEdhZGdldENsYXNzLCB2aW1Gb3JtLAoJWG1OYWxpZ25tZW50LCBYbUFMSUdOTUVOVF9CRUdJTk5JTkcsCglYbU5tYXJnaW5IZWlnaHQsIDAsCglYbU5tYXJnaW5XaWR0aCwgMCwKCVhtTnRyYXZlcnNhbE9uLCBGYWxzZSwKCVhtTnJlY29tcHV0ZVNpemUsIEZhbHNlLAoJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCglYbU5sZWZ0T2Zmc2V0LCA1LAoJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCU5VTEwpOwogICAgZ3VpX21jaF9zZXRfZm9vdGVyKChjaGFyX3UgKikgIiIpOwojZW5kaWYKCiAgICAvKgogICAgICogSW5zdGFsbCB0aGUgY2FsbGJhY2tzLgogICAgICovCiAgICBndWlfeDExX2NhbGxiYWNrcyh0ZXh0QXJlYSwgdmltRm9ybSk7CgogICAgLyogUHJldGVuZCB3ZSBkb24ndCBoYXZlIGlucHV0IGZvY3VzLCB3ZSB3aWxsIGdldCBhbiBldmVudCBpZiB3ZSBkby4gKi8KICAgIGd1aS5pbl9mb2N1cyA9IEZBTFNFOwp9CgovKgogKiBDYWxsZWQgd2hlbiB0aGUgR1VJIGlzIG5vdCBnb2luZyB0byBzdGFydCBhZnRlciBhbGwuCiAqLwogICAgdm9pZApndWlfeDExX2Rlc3Ryb3lfd2lkZ2V0cygpCnsKICAgIHRleHRBcmVhID0gTlVMTDsKI2lmZGVmIEZFQVRfTUVOVQogICAgbWVudUJhciA9IE5VTEw7CiNlbmRpZgp9CgogICAgdm9pZApndWlfbWNoX3NldF90ZXh0X2FyZWFfcG9zKHgsIHksIHcsIGgpCiAgICBpbnQJICAgIHggVU5VU0VEOwogICAgaW50CSAgICB5IFVOVVNFRDsKICAgIGludAkgICAgdyBVTlVTRUQ7CiAgICBpbnQJICAgIGggVU5VU0VEOwp7CiNpZmRlZiBGRUFUX1RPT0xCQVIKICAgIC8qIEdpdmUga2V5Ym9hcmQgZm9jdXMgdG8gdGhlIHRleHRBcmVhIGluc3RlYWQgb2YgdGhlIHRvb2xiYXIuICovCiAgICByZXNldF9mb2N1cygpOwojZW5kaWYKfQoKICAgIHZvaWQKZ3VpX3gxMV9zZXRfYmFja19jb2xvcigpCnsKICAgIGlmICh0ZXh0QXJlYSAhPSBOVUxMKQojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJWG1DaGFuZ2VDb2xvcih0ZXh0QXJlYSwgZ3VpLmJhY2tfcGl4ZWwpOwojZWxzZQoJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYSwKCQkgIFhtTmJhY2tncm91bmQsIGd1aS5iYWNrX3BpeGVsLAoJCSAgTlVMTCk7CiNlbmRpZgp9CgovKgogKiBNYW5hZ2UgZGlhbG9nIGNlbnRlcmVkIG9uIHBvaW50ZXIuIFRoaXMgY291bGQgYmUgdXNlZCBieSB0aGUgQXRoZW5hIGNvZGUgYXMKICogd2VsbC4KICovCiAgICB2b2lkCm1hbmFnZV9jZW50ZXJlZChkaWFsb2dfY2hpbGQpCiAgICBXaWRnZXQgZGlhbG9nX2NoaWxkOwp7CiAgICBXaWRnZXQgc2hlbGwgPSBYdFBhcmVudChkaWFsb2dfY2hpbGQpOwogICAgV2luZG93IHJvb3QsIGNoaWxkOwogICAgdW5zaWduZWQgaW50IG1hc2s7CiAgICB1bnNpZ25lZCBpbnQgd2lkdGgsIGhlaWdodCwgYm9yZGVyX3dpZHRoLCBkZXB0aDsKICAgIGludCB4LCB5LCB3aW5feCwgd2luX3ksIG1heFgsIG1heFk7CiAgICBCb29sZWFuIG1hcHBlZFdoZW5NYW5hZ2VkOwoKICAgIC8qIFRlbXBvcmFyaWx5IHNldCB2YWx1ZSBvZiBYbU5tYXBwZWRXaGVuTWFuYWdlZAogICAgICAgdG8gc3RvcCB0aGUgZGlhbG9nIGZyb20gcG9wcGluZyB1cCByaWdodCBhd2F5ICovCiAgICBYdFZhR2V0VmFsdWVzKHNoZWxsLCBYbU5tYXBwZWRXaGVuTWFuYWdlZCwgJm1hcHBlZFdoZW5NYW5hZ2VkLCBOVUxMKTsKICAgIFh0VmFTZXRWYWx1ZXMoc2hlbGwsIFhtTm1hcHBlZFdoZW5NYW5hZ2VkLCBGYWxzZSwgTlVMTCk7CgogICAgWHRNYW5hZ2VDaGlsZChkaWFsb2dfY2hpbGQpOwoKICAgIC8qIEdldCB0aGUgcG9pbnRlciBwb3NpdGlvbiAoeCwgeSkgKi8KICAgIFhRdWVyeVBvaW50ZXIoWHREaXNwbGF5KHNoZWxsKSwgWHRXaW5kb3coc2hlbGwpLCAmcm9vdCwgJmNoaWxkLAoJCSAgJngsICZ5LCAmd2luX3gsICZ3aW5feSwgJm1hc2spOwoKICAgIC8qIFRyYW5zbGF0ZSB0aGUgcG9pbnRlciBwb3NpdGlvbiAoeCwgeSkgaW50byBhIHBvc2l0aW9uIGZvciB0aGUgbmV3CiAgICAgICB3aW5kb3cgdGhhdCB3aWxsIHBsYWNlIHRoZSBwb2ludGVyIGF0IGl0cyBjZW50ZXIgKi8KICAgIFhHZXRHZW9tZXRyeShYdERpc3BsYXkoc2hlbGwpLCBYdFdpbmRvdyhzaGVsbCksICZyb290LCAmd2luX3gsICZ3aW5feSwKCQkgJndpZHRoLCAmaGVpZ2h0LCAmYm9yZGVyX3dpZHRoLCAmZGVwdGgpOwogICAgd2lkdGggKz0gMiAqIGJvcmRlcl93aWR0aDsKICAgIGhlaWdodCArPSAyICogYm9yZGVyX3dpZHRoOwogICAgeCAtPSB3aWR0aCAvIDI7CiAgICB5IC09IGhlaWdodCAvIDI7CgogICAgLyogRW5zdXJlIHRoYXQgdGhlIGRpYWxvZyByZW1haW5zIG9uIHNjcmVlbiAqLwogICAgbWF4WCA9IFh0U2NyZWVuKHNoZWxsKS0+d2lkdGggLSB3aWR0aDsKICAgIG1heFkgPSBYdFNjcmVlbihzaGVsbCktPmhlaWdodCAtIGhlaWdodDsKICAgIGlmICh4IDwgMCkKCXggPSAwOwogICAgaWYgKHggPiBtYXhYKQoJeCA9IG1heFg7CiAgICBpZiAoeSA8IDApCgl5ID0gMDsKICAgIGlmICh5ID4gbWF4WSkKCXkgPSBtYXhZOwoKICAgIC8qIFNldCBkZXNpcmVkIHdpbmRvdyBwb3NpdGlvbiBpbiB0aGUgRGlhbG9nU2hlbGwgKi8KICAgIFh0VmFTZXRWYWx1ZXMoc2hlbGwsIFhtTngsIHgsIFhtTnksIHksIE5VTEwpOwoKICAgIC8qIE1hcCB0aGUgd2lkZ2V0ICovCiAgICBYdE1hcFdpZGdldChzaGVsbCk7CgogICAgLyogUmVzdG9yZSB0aGUgdmFsdWUgb2YgWG1ObWFwcGVkV2hlbk1hbmFnZWQgKi8KICAgIFh0VmFTZXRWYWx1ZXMoc2hlbGwsIFhtTm1hcHBlZFdoZW5NYW5hZ2VkLCBtYXBwZWRXaGVuTWFuYWdlZCwgTlVMTCk7Cn0KCiNpZiBkZWZpbmVkKEZFQVRfTUVOVSkgfHwgZGVmaW5lZChGRUFUX1NVTl9XT1JLU0hPUCkgXAoJfHwgZGVmaW5lZChGRUFUX0dVSV9ESUFMT0cpIHx8IGRlZmluZWQoUFJPVE8pCgovKgogKiBFbmNhcHN1bGF0ZSB0aGUgd2F5IGFuIFhtRm9udExpc3QgaXMgY3JlYXRlZC4KICovCiAgICBYbUZvbnRMaXN0Cmd1aV9tb3RpZl9jcmVhdGVfZm9udGxpc3QoZm9udCkKICAgIFhGb250U3RydWN0ICAgICpmb250Owp7CiAgICBYbUZvbnRMaXN0IGZvbnRfbGlzdDsKCiMgaWYgKFhtVmVyc2lvbiA8PSAxMDAxKQogICAgLyogTW90aWYgMS4xIG1ldGhvZCAqLwogICAgZm9udF9saXN0ID0gWG1Gb250TGlzdENyZWF0ZShmb250LCBTVFJJTkdfVEFHKTsKIyBlbHNlCiAgICAvKiBNb3RpZiAxLjIgbWV0aG9kICovCiAgICBYbUZvbnRMaXN0RW50cnkgZm9udF9saXN0X2VudHJ5OwoKICAgIGZvbnRfbGlzdF9lbnRyeSA9IFhtRm9udExpc3RFbnRyeUNyZWF0ZShTVFJJTkdfVEFHLCBYbUZPTlRfSVNfRk9OVCwKCQkJCQkgICAgKFh0UG9pbnRlcilmb250KTsKICAgIGZvbnRfbGlzdCA9IFhtRm9udExpc3RBcHBlbmRFbnRyeShOVUxMLCBmb250X2xpc3RfZW50cnkpOwogICAgWG1Gb250TGlzdEVudHJ5RnJlZSgmZm9udF9saXN0X2VudHJ5KTsKIyBlbmRpZgogICAgcmV0dXJuIGZvbnRfbGlzdDsKfQoKIyBpZiAoKFhtVmVyc2lvbiA+IDEwMDEpICYmIGRlZmluZWQoRkVBVF9YRk9OVFNFVCkpIHx8IGRlZmluZWQoUFJPVE8pCiAgICBYbUZvbnRMaXN0Cmd1aV9tb3RpZl9mb250c2V0MmZvbnRsaXN0KGZvbnRzZXQpCiAgICBYRm9udFNldAkqZm9udHNldDsKewogICAgWG1Gb250TGlzdCBmb250X2xpc3Q7CgogICAgLyogTW90aWYgMS4yIG1ldGhvZCAqLwogICAgWG1Gb250TGlzdEVudHJ5IGZvbnRfbGlzdF9lbnRyeTsKCiAgICBmb250X2xpc3RfZW50cnkgPSBYbUZvbnRMaXN0RW50cnlDcmVhdGUoU1RSSU5HX1RBRywKCQkJCQkgICAgWG1GT05UX0lTX0ZPTlRTRVQsCgkJCQkJICAgIChYdFBvaW50ZXIpKmZvbnRzZXQpOwogICAgZm9udF9saXN0ID0gWG1Gb250TGlzdEFwcGVuZEVudHJ5KE5VTEwsIGZvbnRfbGlzdF9lbnRyeSk7CiAgICBYbUZvbnRMaXN0RW50cnlGcmVlKCZmb250X2xpc3RfZW50cnkpOwogICAgcmV0dXJuIGZvbnRfbGlzdDsKfQojIGVuZGlmCgojZW5kaWYKCiNpZiBkZWZpbmVkKEZFQVRfTUVOVSkgfHwgZGVmaW5lZChQUk9UTykKLyoKICogTWVudSBzdHVmZi4KICovCgpzdGF0aWMgdm9pZCBndWlfbW90aWZfYWRkX2FjdGV4dCBfX0FSR1MoKHZpbW1lbnVfVCAqbWVudSkpOwojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQpzdGF0aWMgdm9pZCB0b2dnbGVfdGVhcm9mZiBfX0FSR1MoKFdpZGdldCB3aWQpKTsKc3RhdGljIHZvaWQgZ3VpX21jaF9yZWN1cnNlX3RlYXJvZmZzIF9fQVJHUygodmltbWVudV9UICptZW51KSk7CiNlbmRpZgpzdGF0aWMgdm9pZCBzdWJtZW51X2NoYW5nZSBfX0FSR1MoKHZpbW1lbnVfVCAqbXAsIGludCBjb2xvcnMpKTsKCnN0YXRpYyB2b2lkIGRvX3NldF9tbmVtb25pY3MgX19BUkdTKChpbnQgZW5hYmxlKSk7CnN0YXRpYyBpbnQgbWVudV9lbmFibGVkID0gVFJVRTsKCiAgICB2b2lkCmd1aV9tY2hfZW5hYmxlX21lbnUoZmxhZykKICAgIGludAkgICAgZmxhZzsKewogICAgaWYgKGZsYWcpCiAgICB7CglYdE1hbmFnZUNoaWxkKG1lbnVCYXIpOwojaWZkZWYgRkVBVF9UT09MQkFSCglpZiAoWHRJc01hbmFnZWQoWHRQYXJlbnQodG9vbEJhcikpKQoJewoJICAgIC8qIHRvb2xCYXIgaXMgYXR0YWNoZWQgdG8gdG9wIGZvcm0gKi8KCSAgICBYdFZhU2V0VmFsdWVzKFh0UGFyZW50KHRvb2xCYXIpLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU50b3BXaWRnZXQsIG1lbnVCYXIsCgkJTlVMTCk7CiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCgkgICAgaWYgKHNob3dpbmdfdGFibGluZSkKCSAgICB7CgkJWHRWYVNldFZhbHVlcyh0YWJMaW5lLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgWHRQYXJlbnQodG9vbEJhciksCgkJCSAgICAgIE5VTEwpOwoJCVh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgdGFiTGluZSwKCQkJICAgICAgTlVMTCk7CgkgICAgfQoJICAgIGVsc2UKI2VuZGlmCgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwKCQkJICAgICAgTlVMTCk7Cgl9CgllbHNlCiNlbmRpZgoJewojaWZkZWYgRkVBVF9HVUlfVEFCTElORQoJICAgIGlmIChzaG93aW5nX3RhYmxpbmUpCgkgICAgewoJCVh0VmFTZXRWYWx1ZXModGFiTGluZSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgICBYbU50b3BXaWRnZXQsIG1lbnVCYXIsCgkJCSAgICAgIE5VTEwpOwoJCVh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgdGFiTGluZSwKCQkJICAgICAgTlVMTCk7CgkgICAgfQoJICAgIGVsc2UKI2VuZGlmCgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBtZW51QmFyLAoJCQkgICAgICBOVUxMKTsKCX0KICAgIH0KICAgIGVsc2UKICAgIHsKCVh0VW5tYW5hZ2VDaGlsZChtZW51QmFyKTsKI2lmZGVmIEZFQVRfVE9PTEJBUgoJaWYgKFh0SXNNYW5hZ2VkKFh0UGFyZW50KHRvb2xCYXIpKSkKCXsKCSAgICBYdFZhU2V0VmFsdWVzKFh0UGFyZW50KHRvb2xCYXIpLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJTlVMTCk7CiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCgkgICAgaWYgKHNob3dpbmdfdGFibGluZSkKCSAgICB7CgkJWHRWYVNldFZhbHVlcyh0YWJMaW5lLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgWHRQYXJlbnQodG9vbEJhciksCgkJCSAgICAgIE5VTEwpOwoJCVh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgdGFiTGluZSwKCQkJICAgICAgTlVMTCk7CgkgICAgfQoJICAgIGVsc2UKI2VuZGlmCgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwKCQkJICAgICAgTlVMTCk7Cgl9CgllbHNlCiNlbmRpZgoJewojaWZkZWYgRkVBVF9HVUlfVEFCTElORQoJICAgIGlmIChzaG93aW5nX3RhYmxpbmUpCgkgICAgewoJCVh0VmFTZXRWYWx1ZXModGFiTGluZSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJICAgICAgTlVMTCk7CgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCB0YWJMaW5lLAoJCQkgICAgICBOVUxMKTsKCSAgICB9CgkgICAgZWxzZQojZW5kaWYKCQlYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJICAgICAgTlVMTCk7Cgl9CiAgICB9Cgp9CgovKgogKiBFbmFibGUgb3IgZGlzYWJsZSBtbmVtb25pY3MgZm9yIHRoZSB0b3BsZXZlbCBtZW51cy4KICovCiAgICB2b2lkCmd1aV9tb3RpZl9zZXRfbW5lbW9uaWNzKGVuYWJsZSkKICAgIGludAkJZW5hYmxlOwp7CiAgICAvKgogICAgICogRG9uJ3QgZW5hYmxlIG1lbnUgbW5lbW9uaWNzIHdoZW4gdGhlIG1lbnUgYmFyIGlzIGRpc2FibGVkLCBMZXNzVGlmCiAgICAgKiBjcmFzaGVzIHdoZW4gdXNpbmcgYSBtbmVtb25pYyB0aGVuLgogICAgICovCiAgICBpZiAoIW1lbnVfZW5hYmxlZCkKCWVuYWJsZSA9IEZBTFNFOwogICAgZG9fc2V0X21uZW1vbmljcyhlbmFibGUpOwp9CgogICAgc3RhdGljIHZvaWQKZG9fc2V0X21uZW1vbmljcyhlbmFibGUpCiAgICBpbnQJCWVuYWJsZTsKewogICAgdmltbWVudV9UCSptZW51OwoKICAgIGZvciAobWVudSA9IHJvb3RfbWVudTsgbWVudSAhPSBOVUxMOyBtZW51ID0gbWVudS0+bmV4dCkKCWlmIChtZW51LT5pZCAhPSAoV2lkZ2V0KTApCgkgICAgWHRWYVNldFZhbHVlcyhtZW51LT5pZCwKCQkgICAgWG1ObW5lbW9uaWMsIGVuYWJsZSA/IG1lbnUtPm1uZW1vbmljIDogTlVMLAoJCSAgICBOVUxMKTsKfQoKICAgIHZvaWQKZ3VpX21jaF9hZGRfbWVudShtZW51LCBpZHgpCiAgICB2aW1tZW51X1QJKm1lbnU7CiAgICBpbnQJCWlkeDsKewogICAgWG1TdHJpbmcJbGFiZWw7CiAgICBXaWRnZXQJc2hlbGw7CiAgICB2aW1tZW51X1QJKnBhcmVudCA9IG1lbnUtPnBhcmVudDsKCiNpZmRlZiBNT1RJRl9QT1BVUAogICAgaWYgKG1lbnVfaXNfcG9wdXAobWVudS0+bmFtZSkpCiAgICB7CglBcmcgYXJnWzJdOwoJaW50IG4gPSAwOwoKCS8qIE9ubHkgY3JlYXRlIHRoZSBwb3B1cCBtZW51IHdoZW4gaXQncyBhY3R1YWxseSB1c2VkLCBvdGhlcndpc2UgdGhlcmUKCSAqIGlzIGEgZGVsYXkgd2hlbiB1c2luZyB0aGUgcmlnaHQgbW91c2UgYnV0dG9uLiAqLwojIGlmIChYbVZlcnNpb24gPD0gMTAwMikKCWlmIChtb3VzZV9tb2RlbF9wb3B1cCgpKQojIGVuZGlmCgl7CgkgICAgaWYgKGd1aS5tZW51X2JnX3BpeGVsICE9IElOVkFMQ09MT1IpCgkgICAgewoJCVh0U2V0QXJnKGFyZ1swXSwgWG1OYmFja2dyb3VuZCwgZ3VpLm1lbnVfYmdfcGl4ZWwpOyBuKys7CgkgICAgfQoJICAgIGlmIChndWkubWVudV9mZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJICAgIHsKCQlYdFNldEFyZyhhcmdbMV0sIFhtTmZvcmVncm91bmQsIGd1aS5tZW51X2ZnX3BpeGVsKTsgbisrOwoJICAgIH0KCSAgICBtZW51LT5zdWJtZW51X2lkID0gWG1DcmVhdGVQb3B1cE1lbnUodGV4dEFyZWEsICJjb250ZXh0TWVudSIsCgkJCQkJCQkJICAgICAgYXJnLCBuKTsKCSAgICBtZW51LT5pZCA9IChXaWRnZXQpMDsKCX0KCXJldHVybjsKICAgIH0KI2VuZGlmCgogICAgaWYgKCFtZW51X2lzX21lbnViYXIobWVudS0+bmFtZSkKCSAgICB8fCAocGFyZW50ICE9IE5VTEwgJiYgcGFyZW50LT5zdWJtZW51X2lkID09IChXaWRnZXQpMCkpCglyZXR1cm47CgogICAgbGFiZWwgPSBYbVN0cmluZ0NyZWF0ZSgoY2hhciAqKW1lbnUtPmRuYW1lLCBTVFJJTkdfVEFHKTsKICAgIGlmIChsYWJlbCA9PSBOVUxMKQoJcmV0dXJuOwogICAgbWVudS0+aWQgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJzdWJNZW51IiwKCSAgICB4bUNhc2NhZGVCdXR0b25XaWRnZXRDbGFzcywKCSAgICAocGFyZW50ID09IE5VTEwpID8gbWVudUJhciA6IHBhcmVudC0+c3VibWVudV9pZCwKCSAgICBYbU5sYWJlbFN0cmluZywgbGFiZWwsCgkgICAgWG1ObW5lbW9uaWMsIHBfd2FrWzBdID09ICduJyA/IE5VTCA6IG1lbnUtPm1uZW1vbmljLAojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJICAgIC8qIHN1Ym1lbnU6IGNvdW50IHRoZSB0ZWFyb2ZmIGl0ZW0gKG5lZWRlZCBmb3IgTGVzc1RpZikgKi8KCSAgICBYbU5wb3NpdGlvbkluZGV4LCBpZHggKyAocGFyZW50ICE9IE5VTEwKCQkJICAgJiYgdGVhcm9mZl92YWwgPT0gKGludClYbVRFQVJfT0ZGX0VOQUJMRUQgPyAxIDogMCksCiNlbmRpZgoJICAgIE5VTEwpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKG1lbnUtPmlkKTsKICAgIGd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KG1lbnUtPmlkKTsKICAgIFhtU3RyaW5nRnJlZShsYWJlbCk7CgogICAgaWYgKG1lbnUtPmlkID09IChXaWRnZXQpMCkJCS8qIGZhaWxlZCAqLwoJcmV0dXJuOwoKICAgIC8qIGFkZCBhY2NlbGVyYXRvciB0ZXh0ICovCiAgICBndWlfbW90aWZfYWRkX2FjdGV4dChtZW51KTsKCiAgICBzaGVsbCA9IFh0VmFDcmVhdGVXaWRnZXQoInN1Yk1lbnVTaGVsbCIsCgl4bU1lbnVTaGVsbFdpZGdldENsYXNzLCBtZW51LT5pZCwKCVhtTndpZHRoLCAxLAoJWG1OaGVpZ2h0LCAxLAoJTlVMTCk7CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnMoc2hlbGwpOwogICAgbWVudS0+c3VibWVudV9pZCA9IFh0VmFDcmVhdGVXaWRnZXQoInJvd0NvbHVtbk1lbnUiLAoJeG1Sb3dDb2x1bW5XaWRnZXRDbGFzcywgc2hlbGwsCglYbU5yb3dDb2x1bW5UeXBlLCBYbU1FTlVfUFVMTERPV04sCglOVUxMKTsKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyhtZW51LT5zdWJtZW51X2lkKTsKCiAgICBpZiAobWVudS0+c3VibWVudV9pZCA9PSAoV2lkZ2V0KTApCQkvKiBmYWlsZWQgKi8KCXJldHVybjsKCiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCiAgICAvKiBTZXQgdGhlIGNvbG9ycyBmb3IgdGhlIHRlYXIgb2ZmIHdpZGdldCAqLwogICAgdG9nZ2xlX3RlYXJvZmYobWVudS0+c3VibWVudV9pZCk7CiNlbmRpZgoKICAgIFh0VmFTZXRWYWx1ZXMobWVudS0+aWQsCglYbU5zdWJNZW51SWQsIG1lbnUtPnN1Ym1lbnVfaWQsCglOVUxMKTsKCiAgICAvKgogICAgICogVGhlICJIZWxwIiBtZW51IGlzIGEgc3BlY2lhbCBjYXNlLCBhbmQgc2hvdWxkIGJlIHBsYWNlZCBhdCB0aGUgZmFyCiAgICAgKiByaWdodCBoYW5kIHNpZGUgb2YgdGhlIG1lbnUtYmFyLiAgSXQncyByZWNvZ25pemVkIGJ5IGl0cyBoaWdoIHByaW9yaXR5LgogICAgICovCiAgICBpZiAocGFyZW50ID09IE5VTEwgJiYgbWVudS0+cHJpb3JpdHkgPj0gOTk5OSkKCVh0VmFTZXRWYWx1ZXMobWVudUJhciwKCQlYbU5tZW51SGVscFdpZGdldCwgbWVudS0+aWQsCgkJTlVMTCk7CgogICAgLyoKICAgICAqIFdoZW4gd2UgYWRkIGEgdG9wLWxldmVsIGl0ZW0gdG8gdGhlIG1lbnUgYmFyLCB3ZSBjYW4gZmlndXJlIG91dCBob3cKICAgICAqIGhpZ2ggdGhlIG1lbnUgYmFyIHNob3VsZCBiZS4KICAgICAqLwogICAgaWYgKHBhcmVudCA9PSBOVUxMKQoJZ3VpX21jaF9jb21wdXRlX21lbnVfaGVpZ2h0KG1lbnUtPmlkKTsKfQoKCi8qCiAqIEFkZCBtbmVtb25pYyBhbmQgYWNjZWxlcmF0b3IgdGV4dCB0byBhIG1lbnUgYnV0dG9uLgogKi8KICAgIHN0YXRpYyB2b2lkCmd1aV9tb3RpZl9hZGRfYWN0ZXh0KG1lbnUpCiAgICB2aW1tZW51X1QJKm1lbnU7CnsKICAgIFhtU3RyaW5nCWxhYmVsOwoKICAgIC8qIEFkZCBhY2NlbGVyYXRvciB0ZXh0LCBpZiB0aGVyZSBpcyBvbmUgKi8KICAgIGlmIChtZW51LT5hY3RleHQgIT0gTlVMTCAmJiBtZW51LT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglsYWJlbCA9IFhtU3RyaW5nQ3JlYXRlKChjaGFyICopbWVudS0+YWN0ZXh0LCBTVFJJTkdfVEFHKTsKCWlmIChsYWJlbCA9PSBOVUxMKQoJICAgIHJldHVybjsKCVh0VmFTZXRWYWx1ZXMobWVudS0+aWQsIFhtTmFjY2VsZXJhdG9yVGV4dCwgbGFiZWwsIE5VTEwpOwoJWG1TdHJpbmdGcmVlKGxhYmVsKTsKICAgIH0KfQoKICAgIHZvaWQKZ3VpX21jaF90b2dnbGVfdGVhcm9mZnMoZW5hYmxlKQogICAgaW50CQllbmFibGU7CnsKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKICAgIGlmIChlbmFibGUpCgl0ZWFyb2ZmX3ZhbCA9IChpbnQpWG1URUFSX09GRl9FTkFCTEVEOwogICAgZWxzZQoJdGVhcm9mZl92YWwgPSAoaW50KVhtVEVBUl9PRkZfRElTQUJMRUQ7CiAgICB0b2dnbGVfdGVhcm9mZihtZW51QmFyKTsKICAgIGd1aV9tY2hfcmVjdXJzZV90ZWFyb2Zmcyhyb290X21lbnUpOwojZW5kaWYKfQoKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKLyoKICogU2V0IHRoZSB0ZWFyb2ZmIGZvciBvbmUgbWVudSB3aWRnZXQgb24gb3Igb2ZmLCBhbmQgc2V0IHRoZSBjb2xvciBvZiB0aGUKICogdGVhcm9mZiB3aWRnZXQuCiAqLwogICAgc3RhdGljIHZvaWQKdG9nZ2xlX3RlYXJvZmYod2lkKQogICAgV2lkZ2V0CXdpZDsKewogICAgV2lkZ2V0CXc7CgogICAgWHRWYVNldFZhbHVlcyh3aWQsIFhtTnRlYXJPZmZNb2RlbCwgdGVhcm9mZl92YWwsIE5VTEwpOwogICAgaWYgKHRlYXJvZmZfdmFsID09IChpbnQpWG1URUFSX09GRl9FTkFCTEVECgkgICAgJiYgKHcgPSBYbUdldFRlYXJPZmZDb250cm9sKHdpZCkpICE9IChXaWRnZXQpMCkKCWd1aV9tb3RpZl9tZW51X2NvbG9ycyh3KTsKfQoKICAgIHN0YXRpYyB2b2lkCmd1aV9tY2hfcmVjdXJzZV90ZWFyb2ZmcyhtZW51KQogICAgdmltbWVudV9UCSptZW51Owp7CiAgICB3aGlsZSAobWVudSAhPSBOVUxMKQogICAgewoJaWYgKCFtZW51X2lzX3BvcHVwKG1lbnUtPm5hbWUpKQoJewoJICAgIGlmIChtZW51LT5zdWJtZW51X2lkICE9IChXaWRnZXQpMCkKCQl0b2dnbGVfdGVhcm9mZihtZW51LT5zdWJtZW51X2lkKTsKCSAgICBndWlfbWNoX3JlY3Vyc2VfdGVhcm9mZnMobWVudS0+Y2hpbGRyZW4pOwoJfQoJbWVudSA9IG1lbnUtPm5leHQ7CiAgICB9Cn0KI2VuZGlmCgogICAgaW50Cmd1aV9tY2hfdGV4dF9hcmVhX2V4dHJhX2hlaWdodCgpCnsKICAgIERpbWVuc2lvbglzaGFkb3dIZWlnaHQ7CgogICAgWHRWYUdldFZhbHVlcyh0ZXh0QXJlYUZvcm0sIFhtTnNoYWRvd1RoaWNrbmVzcywgJnNoYWRvd0hlaWdodCwgTlVMTCk7CiAgICByZXR1cm4gc2hhZG93SGVpZ2h0Owp9CgovKgogKiBDb21wdXRlIHRoZSBoZWlnaHQgb2YgdGhlIG1lbnUgYmFyLgogKiBXZSBuZWVkIHRvIGNoZWNrIGFsbCB0aGUgaXRlbXMgZm9yIHRoZWlyIHBvc2l0aW9uIGFuZCBoZWlnaHQsIGZvciB0aGUgY2FzZQogKiB0aGVyZSBhcmUgc2V2ZXJhbCByb3dzLCBhbmQvb3Igc29tZSBjaGFyYWN0ZXJzIGV4dGVuZCBoaWdoZXIgb3IgbG93ZXIuCiAqLwogICAgdm9pZApndWlfbWNoX2NvbXB1dGVfbWVudV9oZWlnaHQoaWQpCiAgICBXaWRnZXQJaWQ7CQkgICAgLyogY2FuIGJlIE5VTEwgd2hlbiBkZWxldGluZyBtZW51ICovCnsKICAgIERpbWVuc2lvbgl5LCBtYXh5OwogICAgRGltZW5zaW9uCW1hcmdpbiwgc2hhZG93OwogICAgdmltbWVudV9UCSptcDsKICAgIHN0YXRpYyBEaW1lbnNpb24JaGVpZ2h0ID0gMjE7CS8qIG5vcm1hbCBoZWlnaHQgb2YgYSBtZW51IGl0ZW0gKi8KCiAgICAvKgogICAgICogR2V0IHRoZSBoZWlnaHQgb2YgdGhlIG5ldyBpdGVtLCBiZWZvcmUgbWFuYWdpbmcgaXQsIGJlY2F1c2UgaXQgd2lsbAogICAgICogc3RpbGwgcmVmbGVjdCB0aGUgZm9udCBzaXplLiAgQWZ0ZXIgbWFuYWdpbmcgaXQgZGVwZW5kcyBvbiB0aGUgbWVudQogICAgICogaGVpZ2h0LCB3aGljaCBpcyB3aGF0IHdlIGp1c3Qgd2FudGVkIHRvIGdldCEuCiAgICAgKi8KICAgIGlmIChpZCAhPSAoV2lkZ2V0KTApCglYdFZhR2V0VmFsdWVzKGlkLCBYbU5oZWlnaHQsICZoZWlnaHQsIE5VTEwpOwoKICAgIC8qIEZpbmQgYW55IG1lbnUgV2lkZ2V0LCB0byBiZSBhYmxlIHRvIGNhbGwgWHRNYW5hZ2VDaGlsZCgpICovCiAgICBlbHNlCglmb3IgKG1wID0gcm9vdF9tZW51OyBtcCAhPSBOVUxMOyBtcCA9IG1wLT5uZXh0KQoJICAgIGlmIChtcC0+aWQgIT0gKFdpZGdldCkwICYmIG1lbnVfaXNfbWVudWJhcihtcC0+bmFtZSkpCgkgICAgewoJCWlkID0gbXAtPmlkOwoJCWJyZWFrOwoJICAgIH0KCiAgICAvKgogICAgICogTm93IG1hbmFnZSB0aGUgbWVudSBpdGVtLCB0byBtYWtlIHRoZW0gYWxsIGJlIHBvc2l0aW9uZWQgKG1ha2VzIGFuCiAgICAgKiBleHRyYSByb3cgd2hlbiBuZWVkZWQsIHJlbW92ZXMgaXQgd2hlbiBub3QgbmVlZGVkKS4KICAgICAqLwogICAgaWYgKGlkICE9IChXaWRnZXQpMCkKCVh0TWFuYWdlQ2hpbGQoaWQpOwoKICAgIC8qCiAgICAgKiBOb3cgZmluZCB0aGUgbWVudSBpdGVtIHRoYXQgaXMgdGhlIGZ1cnRoZXN0IGRvd24sIGFuZCBnZXQgaXQncyBwb3NpdGlvbi4KICAgICAqLwogICAgbWF4eSA9IDA7CiAgICBmb3IgKG1wID0gcm9vdF9tZW51OyBtcCAhPSBOVUxMOyBtcCA9IG1wLT5uZXh0KQogICAgewoJaWYgKG1wLT5pZCAhPSAoV2lkZ2V0KTAgJiYgbWVudV9pc19tZW51YmFyKG1wLT5uYW1lKSkKCXsKCSAgICBYdFZhR2V0VmFsdWVzKG1wLT5pZCwgWG1OeSwgJnksIE5VTEwpOwoJICAgIGlmICh5ID4gbWF4eSkKCQltYXh5ID0geTsKCX0KICAgIH0KCiAgICBYdFZhR2V0VmFsdWVzKG1lbnVCYXIsCglYbU5tYXJnaW5IZWlnaHQsICZtYXJnaW4sCglYbU5zaGFkb3dUaGlja25lc3MsICZzaGFkb3csCglOVUxMKTsKCiAgICAvKgogICAgICogVGhpcyBjb21wdXRhdGlvbiBpcyB0aGUgcmVzdWx0IG9mIHRyaWFsLWFuZC1lcnJvcjoKICAgICAqIG1heHkgPQlUaGUgbWF4aW11bSBwb3NpdGlvbiBvZiBhbiBpdGVtOyByZXF1aXJlZCBmb3Igd2hlbiB0aGVyZSBhcmUKICAgICAqCQl0d28gb3IgbW9yZSByb3dzCiAgICAgKiBoZWlnaHQgPSBoZWlnaHQgb2YgYW4gaXRlbSwgYmVmb3JlIG1hbmFnaW5nIGl0OwlIb3BlZnVsbHkgdGhpcyB3aWxsCiAgICAgKgkJY2hhbmdlIHdpdGggdGhlIGZvbnQgaGVpZ2h0LiAgSW5jbHVkZXMgc2hhZG93LWJvcmRlci4KICAgICAqIHNoYWRvdyA9CXNoYWRvdy1ib3JkZXI7IG11c3QgYmUgc3VidHJhY3RlZCBmcm9tIHRoZSBoZWlnaHQuCiAgICAgKiBtYXJnaW4gPSBtYXJnaW4gYXJvdW5kIHRoZSBtZW51IGJ1dHRvbnM7ICBNdXN0IGJlIGFkZGVkLgogICAgICogQWRkIDQgZm9yIHRoZSB1bmRlcmxpbmluZyBvZiBzaG9ydGN1dCBrZXlzLgogICAgICovCiAgICBndWkubWVudV9oZWlnaHQgPSBtYXh5ICsgaGVpZ2h0IC0gMiAqIHNoYWRvdyArIDIgKiBtYXJnaW4gKyA0OwoKICAgIC8qIFNvbWVob3cgdGhlIG1lbnUgYmFyIGRvZXNuJ3QgcmVzaXplIGF1dG9tYXRpY2FsbHkuICBTZXQgaXQgaGVyZSwKICAgICAqIGV2ZW4gdGhvdWdoIHRoaXMgaXMgYSBjYXRjaCAyMi4gIERvbid0IGRvIHRoaXMgd2hlbiBzdGFydGluZyB1cCwKICAgICAqIHNvbWVob3cgdGhlIG1lbnUgZ2V0cyB2ZXJ5IGhpZ2ggdGhlbi4gKi8KICAgIGlmIChndWkuc2hlbGxfY3JlYXRlZCkKCVh0VmFTZXRWYWx1ZXMobWVudUJhciwgWG1OaGVpZ2h0LCBndWkubWVudV9oZWlnaHQsIE5VTEwpOwp9CgojaWZkZWYgRkVBVF9UT09MQkFSCgovKgogKiBJY29ucyB1c2VkIGJ5IHRoZSB0b29sYmFyIGNvZGUuCiAqLwojaW5jbHVkZSAiZ3VpX3gxMV9wbS5oIgoKc3RhdGljIGludCBjaGVja194cG0gX19BUkdTKChjaGFyX3UgKnBhdGgpKTsKc3RhdGljIGNoYXIgKipnZXRfdG9vbGJhcl9waXhtYXAgX19BUkdTKCh2aW1tZW51X1QgKm1lbnUsIGNoYXIgKipmbmFtZSkpOwpzdGF0aWMgaW50IGFkZF9waXhtYXBfYXJncyBfX0FSR1MoKHZpbW1lbnVfVCAqbWVudSwgQXJnICphcmdzLCBpbnQgbikpOwoKLyoKICogUmVhZCBhbiBYcG0gZmlsZS4gIFJldHVybiBPSyBvciBGQUlMLgogKi8KICAgIHN0YXRpYyBpbnQKY2hlY2tfeHBtKHBhdGgpCiAgICBjaGFyX3UJKnBhdGg7CnsKICAgIFhwbUF0dHJpYnV0ZXMgYXR0cnM7CiAgICBpbnQJCXN0YXR1czsKICAgIFBpeG1hcAltYXNrOwogICAgUGl4bWFwCW1hcDsKCiAgICBhdHRycy52YWx1ZW1hc2sgPSAwOwoKICAgIC8qIENyZWF0ZSB0aGUgInNlbnNpdGl2ZSIgcGl4bWFwICovCiAgICBzdGF0dXMgPSBYcG1SZWFkRmlsZVRvUGl4bWFwKGd1aS5kcHksCgkgICAgUm9vdFdpbmRvdyhndWkuZHB5LCBEZWZhdWx0U2NyZWVuKGd1aS5kcHkpKSwKCSAgICAoY2hhciAqKXBhdGgsICZtYXAsICZtYXNrLCAmYXR0cnMpOwogICAgWHBtRnJlZUF0dHJpYnV0ZXMoJmF0dHJzKTsKCiAgICBpZiAoc3RhdHVzID09IFhwbVN1Y2Nlc3MpCglyZXR1cm4gT0s7CiAgICByZXR1cm4gRkFJTDsKfQoKCi8qCiAqIEFsbG9jYXRlZCBhIHBpeG1hcCBmb3IgdG9vbGJhciBtZW51ICJtZW51Ii4KICogV2hlbiBpdCdzIHRvIGJlIHJlYWQgZnJvbSBhIGZpbGUsICJmbmFtZSIgaXMgc2V0IHRvIHRoZSBmaWxlIG5hbWUKICogKGluIGFsbG9jYXRlZCBtZW1vcnkpLgogKiBSZXR1cm4gYSBibGFuayBwaXhtYXAgaWYgaXQgZmFpbHMuCiAqLwogICAgc3RhdGljIGNoYXIgKioKZ2V0X3Rvb2xiYXJfcGl4bWFwKG1lbnUsIGZuYW1lKQogICAgdmltbWVudV9UCSptZW51OwogICAgY2hhcgkqKmZuYW1lOwp7CiAgICBjaGFyX3UJYnVmW01BWFBBVEhMXTsJCS8qIGJ1ZmZlciBzdG9yaW5nIGV4cGFuZGVkIHBhdGhuYW1lICovCiAgICBjaGFyCSoqeHBtID0gTlVMTDsJCS8qIHhwbSBhcnJheSAqLwogICAgaW50CQlyZXM7CgogICAgKmZuYW1lID0gTlVMTDsKICAgIGJ1ZlswXSA9IE5VTDsJCQkvKiBzdGFydCB3aXRoIE5VTEwgcGF0aCAqLwoKICAgIGlmIChtZW51LT5pY29uZmlsZSAhPSBOVUxMKQogICAgewoJLyogVXNlIHRoZSAiaWNvbj0iICBhcmd1bWVudC4gKi8KCWd1aV9maW5kX2ljb25maWxlKG1lbnUtPmljb25maWxlLCBidWYsICJ4cG0iKTsKCXJlcyA9IGNoZWNrX3hwbShidWYpOwoKCS8qIElmIGl0IGZhaWxlZCwgdHJ5IHVzaW5nIHRoZSBtZW51IG5hbWUuICovCglpZiAocmVzID09IEZBSUwgJiYgZ3VpX2ZpbmRfYml0bWFwKG1lbnUtPm5hbWUsIGJ1ZiwgInhwbSIpID09IE9LKQoJICAgIHJlcyA9IGNoZWNrX3hwbShidWYpOwoJaWYgKHJlcyA9PSBPSykKCXsKCSAgICAqZm5hbWUgPSAoY2hhciAqKXZpbV9zdHJzYXZlKGJ1Zik7CgkgICAgcmV0dXJuIHRiX2JsYW5rX3hwbTsKCX0KICAgIH0KCiAgICBpZiAobWVudS0+aWNvbl9idWlsdGluIHx8IGd1aV9maW5kX2JpdG1hcChtZW51LT5uYW1lLCBidWYsICJ4cG0iKSA9PSBGQUlMKQogICAgewoJaWYgKG1lbnUtPmljb25pZHggPj0gMCAmJiBtZW51LT5pY29uaWR4CgkgICAgICAgPCAoaW50KShzaXplb2YoYnVpbHRfaW5fcGl4bWFwcykgLyBzaXplb2YoYnVpbHRfaW5fcGl4bWFwc1swXSkpKQoJICAgIHhwbSA9IGJ1aWx0X2luX3BpeG1hcHNbbWVudS0+aWNvbmlkeF07CgllbHNlCgkgICAgeHBtID0gdGJfYmxhbmtfeHBtOwogICAgfQoKICAgIHJldHVybiB4cG07Cn0KCi8qCiAqIEFkZCBhcmd1bWVudHMgZm9yIHRoZSB0b29sYmFyIHBpeG1hcCB0byBhIG1lbnUgaXRlbS4KICovCiAgICBzdGF0aWMgaW50CmFkZF9waXhtYXBfYXJncyhtZW51LCBhcmdzLCBuKQogICAgdmltbWVudV9UCSptZW51OwogICAgQXJnCQkqYXJnczsKICAgIGludAkJbjsKewogICAgdmltX2ZyZWUobWVudS0+eHBtX2ZuYW1lKTsKICAgIG1lbnUtPnhwbSA9IGdldF90b29sYmFyX3BpeG1hcChtZW51LCAmbWVudS0+eHBtX2ZuYW1lKTsKICAgIGlmIChtZW51LT54cG0gPT0gTlVMTCkKICAgIHsKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmxhYmVsVHlwZSwgWG1TVFJJTkcpOyBuKys7CiAgICB9CiAgICBlbHNlCiAgICB7CglpZiAobWVudS0+eHBtX2ZuYW1lICE9IE5VTEwpCgl7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OcGl4bWFwRmlsZSwgbWVudS0+eHBtX2ZuYW1lKTsgbisrOwoJfQoJWHRTZXRBcmcoYXJnc1tuXSwgWG1OcGl4bWFwRGF0YSwgbWVudS0+eHBtKTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGFiZWxMb2NhdGlvbiwgWG1CT1RUT00pOyBuKys7CiAgICB9CiAgICByZXR1cm4gbjsKfQojZW5kaWYgLyogRkVBVF9UT09MQkFSICovCgogICAgdm9pZApndWlfbWNoX2FkZF9tZW51X2l0ZW0obWVudSwgaWR4KQogICAgdmltbWVudV9UCSptZW51OwogICAgaW50CQlpZHg7CnsKICAgIFhtU3RyaW5nCWxhYmVsOwogICAgdmltbWVudV9UCSpwYXJlbnQgPSBtZW51LT5wYXJlbnQ7CgojIGlmZGVmIEVCQ0RJQwogICAgbWVudS0+bW5lbW9uaWMgPSAwOwojIGVuZGlmCgojIGlmIChYbVZlcnNpb24gPD0gMTAwMikKICAgIC8qIERvbid0IGFkZCBQb3B1cCBtZW51IGl0ZW1zIHdoZW4gdGhlIHBvcHVwIG1lbnUgaXNuJ3QgdXNlZC4gKi8KICAgIGlmIChtZW51X2lzX2NoaWxkX29mX3BvcHVwKG1lbnUpICYmICFtb3VzZV9tb2RlbF9wb3B1cCgpKQoJcmV0dXJuOwojIGVuZGlmCgojIGlmZGVmIEZFQVRfVE9PTEJBUgogICAgaWYgKG1lbnVfaXNfdG9vbGJhcihwYXJlbnQtPm5hbWUpKQogICAgewoJV2lkZ2V0Q2xhc3MJdHlwZTsKCVhtU3RyaW5nCXhtcyA9IE5VTEw7ICAgIC8qIGZhbGxiYWNrIGxhYmVsIGlmIHBpeG1hcCBub3QgZm91bmQgKi8KCWludAkJbjsKCUFyZwkJYXJnc1sxOF07CgoJbiA9IDA7CglpZiAobWVudV9pc19zZXBhcmF0b3IobWVudS0+bmFtZSkpCgl7CgkgICAgY2hhcgkqY3A7CgkgICAgRGltZW5zaW9uCXdpZDsKCgkgICAgLyoKCSAgICAgKiBBIHNlcGFyYXRvciBoYXMgdGhlIGZvcm1hdCAiLXNlcCVkWzolZF0tIi4gVGhlIG9wdGlvbmFsIDolZCBpcwoJICAgICAqIGEgd2lkdGggc3BlY2lmaWVyLiBJZiBubyB3aWR0aCBpcyBzcGVjaWZpZWQgdGhlbiB3ZSBjaG9vc2Ugb25lLgoJICAgICAqLwoJICAgIGNwID0gKGNoYXIgKil2aW1fc3RyY2hyKG1lbnUtPm5hbWUsICc6Jyk7CgkgICAgaWYgKGNwICE9IE5VTEwpCgkJd2lkID0gKERpbWVuc2lvbilhdG9pKCsrY3ApOwoJICAgIGVsc2UKCQl3aWQgPSA0OwoKCSAgICB0eXBlID0geG1TZXBhcmF0b3JXaWRnZXRDbGFzczsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU53aWR0aCwgd2lkKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm1pbldpZHRoLCB3aWQpOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Ob3JpZW50YXRpb24sIFhtVkVSVElDQUwpOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Oc2VwYXJhdG9yVHlwZSwgWG1TSEFET1dfRVRDSEVEX0lOKTsgbisrOwoJfQoJZWxzZQoJewoJICAgIC8qIFdpdGhvdXQgc2hhZG93cyBvbmUgY2FuJ3Qgc2Vuc2Ugd2hhdGV2ZXIgdGhlIGJ1dHRvbiBoYXMgYmVlbgoJICAgICAqIHByZXNzZWQgb3Igbm90ISBIb3dldmVyIHdlIHdhbnQgdG8gc2F2ZSBhIGJpdCBvZiBzcGFjZS4uLgoJICAgICAqIE5lZWQgdGhlIGhpZ2hsaWdodFRoaWNrbmVzcyB0byBzZWUgdGhlIGZvY3VzLgoJICAgICAqLwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmhpZ2hsaWdodFRoaWNrbmVzcywgMSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5oaWdobGlnaHRPbkVudGVyLCBUcnVlKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm1hcmdpbldpZHRoLCAwKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm1hcmdpbkhlaWdodCwgMCk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU50cmF2ZXJzYWxPbiwgRmFsc2UpOyBuKys7CgkgICAgLyogU2V0IHRoZSBsYWJlbCBoZXJlLCBzbyB0aGF0IHdlIGNhbiBzd2l0Y2ggYmV0d2VlbiBpY29ucy90ZXh0CgkgICAgICogYnkgY2hhbmdpbmcgdGhlIFhtTmxhYmVsVHlwZSByZXNvdXJjZS4gKi8KCSAgICB4bXMgPSBYbVN0cmluZ0NyZWF0ZSgoY2hhciAqKW1lbnUtPmRuYW1lLCBTVFJJTkdfVEFHKTsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sYWJlbFN0cmluZywgeG1zKTsgbisrOwoKCSAgICBuID0gYWRkX3BpeG1hcF9hcmdzKG1lbnUsIGFyZ3MsIG4pOwoKCSAgICB0eXBlID0geG1FbmhhbmNlZEJ1dHRvbldpZGdldENsYXNzOwoJfQoKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnBvc2l0aW9uSW5kZXgsIGlkeCk7IG4rKzsKCWlmIChtZW51LT5pZCA9PSBOVUxMKQoJewoJICAgIG1lbnUtPmlkID0gWHRDcmVhdGVNYW5hZ2VkV2lkZ2V0KChjaGFyICopbWVudS0+ZG5hbWUsCgkJCXR5cGUsIHRvb2xCYXIsIGFyZ3MsIG4pOwoJICAgIGlmIChtZW51LT5pZCAhPSBOVUxMICYmIHR5cGUgPT0geG1FbmhhbmNlZEJ1dHRvbldpZGdldENsYXNzKQoJICAgIHsKCQlYdEFkZENhbGxiYWNrKG1lbnUtPmlkLAoJCQlYbU5hY3RpdmF0ZUNhbGxiYWNrLCBndWlfeDExX21lbnVfY2IsIG1lbnUpOwojIGlmZGVmIEZFQVRfRk9PVEVSCgkJWHRBZGRFdmVudEhhbmRsZXIobWVudS0+aWQsIEVudGVyV2luZG93TWFzaywgRmFsc2UsCgkJCXRvb2xiYXJidXR0b25fZW50ZXJfY2IsIG1lbnUpOwoJCVh0QWRkRXZlbnRIYW5kbGVyKG1lbnUtPmlkLCBMZWF2ZVdpbmRvd01hc2ssIEZhbHNlLAoJCQl0b29sYmFyYnV0dG9uX2xlYXZlX2NiLCBtZW51KTsKIyBlbmRpZgoJICAgIH0KCX0KCWVsc2UKCSAgICBYdFNldFZhbHVlcyhtZW51LT5pZCwgYXJncywgbik7CglpZiAoeG1zICE9IE5VTEwpCgkgICAgWG1TdHJpbmdGcmVlKHhtcyk7CgojIGlmZGVmIEZFQVRfQkVWQUwKCWd1aV9tY2hfbWVudV9zZXRfdGlwKG1lbnUpOwojIGVuZGlmCgoJbWVudS0+cGFyZW50ID0gcGFyZW50OwoJbWVudS0+c3VibWVudV9pZCA9IE5VTEw7CgkvKiBXaGVuIGFkZGluZyBmaXJzdCBpdGVtIHRvIHRvb2xiYXIgaXQgbWlnaHQgaGF2ZSB0byBiZSBlbmFibGVkIC4qLwoJaWYgKCFYdElzTWFuYWdlZChYdFBhcmVudCh0b29sQmFyKSkKCQkgICAgJiYgdmltX3N0cmNocihwX2dvLCBHT19UT09MQkFSKSAhPSBOVUxMKQoJICAgIGd1aV9tY2hfc2hvd190b29sYmFyKFRSVUUpOwoJZ3VpLnRvb2xiYXJfaGVpZ2h0ID0gZ3VpX21jaF9jb21wdXRlX3Rvb2xiYXJfaGVpZ2h0KCk7CglyZXR1cm47CiAgICB9IC8qIHRvb2xiYXIgbWVudSBpdGVtICovCiMgZW5kaWYKCiAgICAvKiBObyBwYXJlbnQsIG11c3QgYmUgYSBub24tbWVudWJhciBtZW51ICovCiAgICBpZiAocGFyZW50LT5zdWJtZW51X2lkID09IChXaWRnZXQpMCkKCXJldHVybjsKCiAgICBtZW51LT5zdWJtZW51X2lkID0gKFdpZGdldCkwOwoKICAgIC8qIEFkZCBtZW51IHNlcGFyYXRvciAqLwogICAgaWYgKG1lbnVfaXNfc2VwYXJhdG9yKG1lbnUtPm5hbWUpKQogICAgewoJbWVudS0+aWQgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJzdWJNZW51IiwKCQl4bVNlcGFyYXRvckdhZGdldENsYXNzLCBwYXJlbnQtPnN1Ym1lbnVfaWQsCiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCgkJLyogY291bnQgdGhlIHRlYXJvZmYgaXRlbSAobmVlZGVkIGZvciBMZXNzVGlmKSAqLwoJCVhtTnBvc2l0aW9uSW5kZXgsIGlkeCArICh0ZWFyb2ZmX3ZhbCA9PSAoaW50KVhtVEVBUl9PRkZfRU5BQkxFRAoJCQkJCQkJCSAgICAgPyAxIDogMCksCiNlbmRpZgoJCU5VTEwpOwoJZ3VpX21vdGlmX21lbnVfY29sb3JzKG1lbnUtPmlkKTsKCXJldHVybjsKICAgIH0KCiAgICBsYWJlbCA9IFhtU3RyaW5nQ3JlYXRlKChjaGFyICopbWVudS0+ZG5hbWUsIFNUUklOR19UQUcpOwogICAgaWYgKGxhYmVsID09IE5VTEwpCglyZXR1cm47CiAgICBtZW51LT5pZCA9IFh0VmFDcmVhdGVXaWRnZXQoInN1Yk1lbnUiLAoJeG1QdXNoQnV0dG9uV2lkZ2V0Q2xhc3MsIHBhcmVudC0+c3VibWVudV9pZCwKCVhtTmxhYmVsU3RyaW5nLCBsYWJlbCwKCVhtTm1uZW1vbmljLCBtZW51LT5tbmVtb25pYywKI2lmIChYbVZlcnNpb24gPj0gMTAwMikKCS8qIGNvdW50IHRoZSB0ZWFyb2ZmIGl0ZW0gKG5lZWRlZCBmb3IgTGVzc1RpZikgKi8KCVhtTnBvc2l0aW9uSW5kZXgsIGlkeCArICh0ZWFyb2ZmX3ZhbCA9PSAoaW50KVhtVEVBUl9PRkZfRU5BQkxFRAoJCQkJCQkJCSAgICAgPyAxIDogMCksCiNlbmRpZgoJTlVMTCk7CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnMobWVudS0+aWQpOwogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QobWVudS0+aWQpOwogICAgWG1TdHJpbmdGcmVlKGxhYmVsKTsKCiAgICBpZiAobWVudS0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJWHRBZGRDYWxsYmFjayhtZW51LT5pZCwgWG1OYWN0aXZhdGVDYWxsYmFjaywgZ3VpX3gxMV9tZW51X2NiLAoJCShYdFBvaW50ZXIpbWVudSk7CgkvKiBhZGQgYWNjZWxlcmF0b3IgdGV4dCAqLwoJZ3VpX21vdGlmX2FkZF9hY3RleHQobWVudSk7CiAgICB9Cn0KCiNpZiAoWG1WZXJzaW9uIDw9IDEwMDIpIHx8IGRlZmluZWQoUFJPVE8pCi8qCiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBkZXN0cm95L2NyZWF0ZSB0aGUgcG9wdXAgbWVudXMgZHluYW1pY2FsbHksCiAqIGFjY29yZGluZyB0byB0aGUgdmFsdWUgb2YgJ21vdXNlbW9kZWwnLgogKiBUaGlzIHdpbGwgZml4IHRoZSAicmlnaHQgbW91c2UgYnV0dG9uIGZyZWV6ZSIgdGhhdCBvY2N1cnMgd2hlbgogKiB0aGVyZSBleGlzdHMgYSBwb3B1cCBtZW51IGJ1dCBpdCBpc24ndCBtYW5hZ2VkLgogKi8KICAgIHZvaWQKZ3VpX21vdGlmX3VwZGF0ZV9tb3VzZW1vZGVsKG1lbnUpCiAgICB2aW1tZW51X1QJKm1lbnU7CnsKICAgIGludAkJaWR4ID0gMDsKCiAgICAvKiBXaGVuIEdVSSBoYXNuJ3Qgc3RhcnRlZCB0aGUgbWVudXMgaGF2ZSBub3QgYmVlbiBjcmVhdGVkLiAqLwogICAgaWYgKCFndWkuaW5fdXNlKQogICAgICByZXR1cm47CgogICAgd2hpbGUgKG1lbnUpCiAgICB7CiAgICAgIGlmIChtZW51LT5jaGlsZHJlbiAhPSBOVUxMKQogICAgICB7CgkgIGlmIChtZW51X2lzX3BvcHVwKG1lbnUtPm5hbWUpKQoJICB7CgkgICAgICBpZiAobW91c2VfbW9kZWxfcG9wdXAoKSkKCSAgICAgIHsKCQkgIC8qIFBvcHVwIG1lbnUgd2lsbCBiZSB1c2VkLiAgQ3JlYXRlIHRoZSBwb3B1cCBtZW51cy4gKi8KCQkgIGd1aV9tY2hfYWRkX21lbnUobWVudSwgaWR4KTsKCQkgIGd1aV9tb3RpZl91cGRhdGVfbW91c2Vtb2RlbChtZW51LT5jaGlsZHJlbik7CgkgICAgICB9CgkgICAgICBlbHNlCgkgICAgICB7CgkJICAvKiBQb3B1cCBtZW51IHdpbGwgbm90IGJlIHVzZWQuICBEZXN0cm95IHRoZSBwb3B1cCBtZW51cy4gKi8KCQkgIGd1aV9tb3RpZl91cGRhdGVfbW91c2Vtb2RlbChtZW51LT5jaGlsZHJlbik7CgkJICBndWlfbWNoX2Rlc3Ryb3lfbWVudShtZW51KTsKCSAgICAgIH0KCSAgfQogICAgICB9CiAgICAgIGVsc2UgaWYgKG1lbnVfaXNfY2hpbGRfb2ZfcG9wdXAobWVudSkpCiAgICAgIHsKCSAgaWYgKG1vdXNlX21vZGVsX3BvcHVwKCkpCgkgICAgICBndWlfbWNoX2FkZF9tZW51X2l0ZW0obWVudSwgaWR4KTsKCSAgZWxzZQoJICAgICAgZ3VpX21jaF9kZXN0cm95X21lbnUobWVudSk7CiAgICAgIH0KICAgICAgbWVudSA9IG1lbnUtPm5leHQ7CiAgICAgICsraWR4OwogICAgfQp9CiNlbmRpZgoKICAgIHZvaWQKZ3VpX21jaF9uZXdfbWVudV9jb2xvcnMoKQp7CiAgICBpZiAobWVudUJhciA9PSAoV2lkZ2V0KTApCglyZXR1cm47CiAgICBndWlfbW90aWZfbWVudV9jb2xvcnMobWVudUJhcik7CiNpZmRlZiBGRUFUX1RPT0xCQVIKICAgIGd1aV9tb3RpZl9tZW51X2NvbG9ycyh0b29sQmFyRnJhbWUpOwogICAgZ3VpX21vdGlmX21lbnVfY29sb3JzKHRvb2xCYXIpOwojZW5kaWYKCiAgICBzdWJtZW51X2NoYW5nZShyb290X21lbnUsIFRSVUUpOwp9CgogICAgdm9pZApndWlfbWNoX25ld19tZW51X2ZvbnQoKQp7CiAgICBpZiAobWVudUJhciA9PSAoV2lkZ2V0KTApCglyZXR1cm47CiAgICBzdWJtZW51X2NoYW5nZShyb290X21lbnUsIEZBTFNFKTsKICAgIHsKCURpbWVuc2lvbiAgIGhlaWdodDsKCVBvc2l0aW9uIHcsIGg7CgoJWHRWYUdldFZhbHVlcyhtZW51QmFyLCBYbU5oZWlnaHQsICZoZWlnaHQsIE5VTEwpOwoJZ3VpLm1lbnVfaGVpZ2h0ID0gaGVpZ2h0OwoKCVh0VmFHZXRWYWx1ZXModmltU2hlbGwsIFh0TndpZHRoLCAmdywgWHROaGVpZ2h0LCAmaCwgTlVMTCk7CglndWlfcmVzaXplX3NoZWxsKHcsIGgKI2lmZGVmIEZFQVRfWElNCgkJLSB4aW1fZ2V0X3N0YXR1c19hcmVhX2hlaWdodCgpCiNlbmRpZgoJCSAgICAgKTsKICAgIH0KICAgIGd1aV9zZXRfc2hlbGxzaXplKEZBTFNFLCBUUlVFLCBSRVNJWkVfVkVSVCk7CiAgICB1aV9uZXdfc2hlbGxzaXplKCk7Cn0KCiNpZiBkZWZpbmVkKEZFQVRfQkVWQUwpIHx8IGRlZmluZWQoUFJPVE8pCiAgICB2b2lkCmd1aV9tY2hfbmV3X3Rvb2x0aXBfZm9udCgpCnsKIyBpZmRlZiBGRUFUX1RPT0xCQVIKICAgIHZpbW1lbnVfVCAgICptZW51OwoKICAgIGlmICh0b29sQmFyID09IChXaWRnZXQpMCkKCXJldHVybjsKCiAgICBtZW51ID0gZ3VpX2ZpbmRfbWVudSgoY2hhcl91ICopIlRvb2xCYXIiKTsKICAgIGlmIChtZW51ICE9IE5VTEwpCglzdWJtZW51X2NoYW5nZShtZW51LCBGQUxTRSk7CiMgZW5kaWYKfQoKICAgIHZvaWQKZ3VpX21jaF9uZXdfdG9vbHRpcF9jb2xvcnMoKQp7CiMgaWZkZWYgRkVBVF9UT09MQkFSCiAgICB2aW1tZW51X1QgICAqdG9vbGJhcjsKCiAgICBpZiAodG9vbEJhciA9PSAoV2lkZ2V0KTApCglyZXR1cm47CgogICAgdG9vbGJhciA9IGd1aV9maW5kX21lbnUoKGNoYXJfdSAqKSJUb29sQmFyIik7CiAgICBpZiAodG9vbGJhciAhPSBOVUxMKQoJc3VibWVudV9jaGFuZ2UodG9vbGJhciwgVFJVRSk7CiMgZW5kaWYKfQojZW5kaWYKCiAgICBzdGF0aWMgdm9pZApzdWJtZW51X2NoYW5nZShtZW51LCBjb2xvcnMpCiAgICB2aW1tZW51X1QJKm1lbnU7CiAgICBpbnQJCWNvbG9yczsJCS8qIFRSVUUgZm9yIGNvbG9ycywgRkFMU0UgZm9yIGZvbnQgKi8KewogICAgdmltbWVudV9UCSptcDsKCiAgICBmb3IgKG1wID0gbWVudTsgbXAgIT0gTlVMTDsgbXAgPSBtcC0+bmV4dCkKICAgIHsKCWlmIChtcC0+aWQgIT0gKFdpZGdldCkwKQoJewoJICAgIGlmIChjb2xvcnMpCgkgICAgewoJCWd1aV9tb3RpZl9tZW51X2NvbG9ycyhtcC0+aWQpOwojaWZkZWYgRkVBVF9UT09MQkFSCgkJLyogRm9yIGEgdG9vbGJhciBpdGVtOiBGcmVlIHRoZSBwaXhtYXAgYW5kIGFsbG9jYXRlIGEgbmV3IG9uZSwKCQkgKiBzbyB0aGF0IHRoZSBiYWNrZ3JvdW5kIGNvbG9yIGlzIHJpZ2h0LiAqLwoJCWlmIChtcC0+eHBtICE9IE5VTEwpCgkJewoJCSAgICBpbnQJCW4gPSAwOwoJCSAgICBBcmcJCWFyZ3NbMThdOwoKCQkgICAgbiA9IGFkZF9waXhtYXBfYXJncyhtcCwgYXJncywgbik7CgkJICAgIFh0U2V0VmFsdWVzKG1wLT5pZCwgYXJncywgbik7CgkJfQojIGlmZGVmIEZFQVRfQkVWQUwKCQkvKiBJZiB3ZSBoYXZlIGEgdG9vbHRpcCwgdGhlbiB3ZSBuZWVkIHRvIGNoYW5nZSBpdCdzIGZvbnQgKi8KCQlpZiAobXAtPnRpcCAhPSBOVUxMKQoJCXsKCQkgICAgQXJnIGFyZ3NbMl07CgoJCSAgICBhcmdzWzBdLm5hbWUgPSBYbU5iYWNrZ3JvdW5kOwoJCSAgICBhcmdzWzBdLnZhbHVlID0gZ3VpLnRvb2x0aXBfYmdfcGl4ZWw7CgkJICAgIGFyZ3NbMV0ubmFtZSA9IFhtTmZvcmVncm91bmQ7CgkJICAgIGFyZ3NbMV0udmFsdWUgPSBndWkudG9vbHRpcF9mZ19waXhlbDsKCQkgICAgWHRTZXRWYWx1ZXMobXAtPnRpcC0+YmFsbG9vbkxhYmVsLCAmYXJnc1swXSwgWHROdW1iZXIoYXJncykpOwoJCX0KIyBlbmRpZgojZW5kaWYKCSAgICB9CgkgICAgZWxzZQoJICAgIHsKCQlndWlfbW90aWZfbWVudV9mb250bGlzdChtcC0+aWQpOwojaWZkZWYgRkVBVF9CRVZBTAoJCS8qIElmIHdlIGhhdmUgYSB0b29sdGlwLCB0aGVuIHdlIG5lZWQgdG8gY2hhbmdlIGl0J3MgZm9udCAqLwoJCWlmIChtcC0+dGlwICE9IE5VTEwpCgkJewoJCSAgICBBcmcgYXJnc1sxXTsKCgkJICAgIGFyZ3NbMF0ubmFtZSA9IFhtTmZvbnRMaXN0OwoJCSAgICBhcmdzWzBdLnZhbHVlID0gKFh0QXJnVmFsKWd1aV9tb3RpZl9mb250c2V0MmZvbnRsaXN0KAoJCQkJCQkgICAgJmd1aS50b29sdGlwX2ZvbnRzZXQpOwoJCSAgICBYdFNldFZhbHVlcyhtcC0+dGlwLT5iYWxsb29uTGFiZWwsICZhcmdzWzBdLCBYdE51bWJlcihhcmdzKSk7CgkJfQojZW5kaWYKCSAgICB9Cgl9CgoJaWYgKG1wLT5jaGlsZHJlbiAhPSBOVUxMKQoJewojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJICAgIC8qIFNldCB0aGUgY29sb3JzL2ZvbnQgZm9yIHRoZSB0ZWFyIG9mZiB3aWRnZXQgKi8KCSAgICBpZiAobXAtPnN1Ym1lbnVfaWQgIT0gKFdpZGdldCkwKQoJICAgIHsKCQlpZiAoY29sb3JzKQoJCSAgICBndWlfbW90aWZfbWVudV9jb2xvcnMobXAtPnN1Ym1lbnVfaWQpOwoJCWVsc2UKCQkgICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QobXAtPnN1Ym1lbnVfaWQpOwoJCXRvZ2dsZV90ZWFyb2ZmKG1wLT5zdWJtZW51X2lkKTsKCSAgICB9CiNlbmRpZgoJICAgIC8qIFNldCB0aGUgY29sb3JzIGZvciB0aGUgY2hpbGRyZW4gKi8KCSAgICBzdWJtZW51X2NoYW5nZShtcC0+Y2hpbGRyZW4sIGNvbG9ycyk7Cgl9CiAgICB9Cn0KCi8qCiAqIERlc3Ryb3kgdGhlIG1hY2hpbmUgc3BlY2lmaWMgbWVudSB3aWRnZXQuCiAqLwogICAgdm9pZApndWlfbWNoX2Rlc3Ryb3lfbWVudShtZW51KQogICAgdmltbWVudV9UCSptZW51Owp7CiAgICAvKiBQbGVhc2UgYmUgc3VyZSB0byBkZXN0cm95IHRoZSBwYXJlbnQgd2lkZ2V0IGZpcnN0IChpLmUuIG1lbnUtPmlkKS4KICAgICAqIE9uIHRoZSBvdGhlciBoYW5kLCBwcm9ibGVtcyBoYXZlIGJlZW4gcmVwb3J0ZWQgdGhhdCB0aGUgc3VibWVudSBtdXN0IGJlCiAgICAgKiBkZWxldGVkIGZpcnN0Li4uCiAgICAgKgogICAgICogVGhpcyBjb2RlIHNob3VsZCBiZSBiYXNpY2FsbHkgaWRlbnRpY2FsIHRvIHRoYXQgaW4gdGhlIGZpbGUgZ3VpX2F0aGVuYS5jCiAgICAgKiBiZWNhdXNlIHRoZXkgYXJlIGJvdGggWHQgYmFzZWQuCiAgICAgKi8KICAgIGlmIChtZW51LT5zdWJtZW51X2lkICE9IChXaWRnZXQpMCkKICAgIHsKCVh0RGVzdHJveVdpZGdldChtZW51LT5zdWJtZW51X2lkKTsKCW1lbnUtPnN1Ym1lbnVfaWQgPSAoV2lkZ2V0KTA7CiAgICB9CgogICAgaWYgKG1lbnUtPmlkICE9IChXaWRnZXQpMCkKICAgIHsKCVdpZGdldAkgICAgcGFyZW50OwoKCXBhcmVudCA9IFh0UGFyZW50KG1lbnUtPmlkKTsKI2lmIGRlZmluZWQoRkVBVF9UT09MQkFSKSAmJiBkZWZpbmVkKEZFQVRfQkVWQUwpCglpZiAocGFyZW50ID09IHRvb2xCYXIgJiYgbWVudS0+dGlwICE9IE5VTEwpCgl7CgkgICAgLyogV2UgdHJ5IHRvIGRlc3Ryb3kgdGhpcyBiZWZvcmUgdGhlIGFjdHVhbCBtZW51LCBiZWNhdXNlIHRoZXJlIGFyZQoJICAgICAqIGNhbGxiYWNrcywgZXRjLiB0aGF0IHdpbGwgYmUgdW5yZWdpc3RlcmVkIGR1cmluZyB0aGUgdG9vbHRpcAoJICAgICAqIGRlc3RydWN0aW9uLgoJICAgICAqCgkgICAgICogSWYgeW91IGNhbGwgImd1aV9tY2hfZGVzdHJveV9iZXZhbF9hcmVhKCkiIGFmdGVyIGRlc3Ryb3lpbmcKCSAgICAgKiBtZW51LT5pZCwgdGhlbiB0aGUgdG9vbHRpcCdzIHdpbmRvdyB3aWxsIGhhdmUgYWxyZWFkeSBiZWVuCgkgICAgICogZGVhbGxvY2F0ZWQgYnkgWHQsIGFuZCB1bmtub3duIGJlaGF2aW91ciB3aWxsIGVuc3VlIChwcm9iYWJseQoJICAgICAqIGEgY29yZSBkdW1wKS4KCSAgICAgKi8KCSAgICBndWlfbWNoX2Rlc3Ryb3lfYmV2YWxfYXJlYShtZW51LT50aXApOwoJICAgIG1lbnUtPnRpcCA9IE5VTEw7Cgl9CiNlbmRpZgoJWHREZXN0cm95V2lkZ2V0KG1lbnUtPmlkKTsKCW1lbnUtPmlkID0gKFdpZGdldCkwOwoJaWYgKHBhcmVudCA9PSBtZW51QmFyKQoJICAgIGd1aV9tY2hfY29tcHV0ZV9tZW51X2hlaWdodCgoV2lkZ2V0KTApOwojaWZkZWYgRkVBVF9UT09MQkFSCgllbHNlIGlmIChwYXJlbnQgPT0gdG9vbEJhcikKCXsKCSAgICBDYXJkaW5hbCAgICBudW1fY2hpbGRyZW47CgoJICAgIC8qIFdoZW4gcmVtb3ZpbmcgbGFzdCB0b29sYmFyIGl0ZW0sIGRvbid0IGRpc3BsYXkgdGhlIHRvb2xiYXIuICovCgkgICAgWHRWYUdldFZhbHVlcyh0b29sQmFyLCBYbU5udW1DaGlsZHJlbiwgJm51bV9jaGlsZHJlbiwgTlVMTCk7CgkgICAgaWYgKG51bV9jaGlsZHJlbiA9PSAwKQoJCWd1aV9tY2hfc2hvd190b29sYmFyKEZBTFNFKTsKCSAgICBlbHNlCgkJZ3VpLnRvb2xiYXJfaGVpZ2h0ID0gZ3VpX21jaF9jb21wdXRlX3Rvb2xiYXJfaGVpZ2h0KCk7Cgl9CiNlbmRpZgogICAgfQp9CgogICAgdm9pZApndWlfbWNoX3Nob3dfcG9wdXBtZW51KG1lbnUpCiAgICB2aW1tZW51X1QgKm1lbnUgVU5VU0VEOwp7CiNpZmRlZiBNT1RJRl9QT1BVUAogICAgWG1NZW51UG9zaXRpb24obWVudS0+c3VibWVudV9pZCwgZ3VpX3gxMV9nZXRfbGFzdF9tb3VzZV9ldmVudCgpKTsKICAgIFh0TWFuYWdlQ2hpbGQobWVudS0+c3VibWVudV9pZCk7CiNlbmRpZgp9CgojZW5kaWYgLyogRkVBVF9NRU5VICovCgovKgogKiBTZXQgdGhlIG1lbnUgYW5kIHNjcm9sbGJhciBjb2xvcnMgdG8gdGhlaXIgZGVmYXVsdCB2YWx1ZXMuCiAqLwogICAgdm9pZApndWlfbWNoX2RlZl9jb2xvcnMoKQp7CiAgICBpZiAoZ3VpLmluX3VzZSkKICAgIHsKCS8qIFVzZSB0aGUgdmFsdWVzIHNhdmVkIHdoZW4gc3RhcnRpbmcgdXAuICBUaGVzZSBzaG91bGQgY29tZSBmcm9tIHRoZQoJICogd2luZG93IG1hbmFnZXIgb3IgYSByZXNvdXJjZXMgZmlsZS4gKi8KCWd1aS5tZW51X2ZnX3BpeGVsID0gZ3VpLm1lbnVfZGVmX2ZnX3BpeGVsOwoJZ3VpLm1lbnVfYmdfcGl4ZWwgPSBndWkubWVudV9kZWZfYmdfcGl4ZWw7CglndWkuc2Nyb2xsX2ZnX3BpeGVsID0gZ3VpLnNjcm9sbF9kZWZfZmdfcGl4ZWw7CglndWkuc2Nyb2xsX2JnX3BpeGVsID0gZ3VpLnNjcm9sbF9kZWZfYmdfcGl4ZWw7CiNpZmRlZiBGRUFUX0JFVkFMCglndWkudG9vbHRpcF9mZ19waXhlbCA9CgkJCWd1aV9nZXRfY29sb3IoKGNoYXJfdSAqKWd1aS5yc3JjX3Rvb2x0aXBfZmdfbmFtZSk7CglndWkudG9vbHRpcF9iZ19waXhlbCA9CgkJCWd1aV9nZXRfY29sb3IoKGNoYXJfdSAqKWd1aS5yc3JjX3Rvb2x0aXBfYmdfbmFtZSk7CiNlbmRpZgogICAgfQp9CgoKLyoKICogU2Nyb2xsYmFyIHN0dWZmLgogKi8KCiAgICB2b2lkCmd1aV9tY2hfc2V0X3Njcm9sbGJhcl90aHVtYihzYiwgdmFsLCBzaXplLCBtYXgpCiAgICBzY3JvbGxiYXJfVCAqc2I7CiAgICBsb25nCXZhbDsKICAgIGxvbmcJc2l6ZTsKICAgIGxvbmcJbWF4Owp7CiAgICBpZiAoc2ItPmlkICE9IChXaWRnZXQpMCkKCVh0VmFTZXRWYWx1ZXMoc2ItPmlkLAoJCSAgWG1OdmFsdWUsIHZhbCwKCQkgIFhtTnNsaWRlclNpemUsIHNpemUsCgkJICBYbU5wYWdlSW5jcmVtZW50LCAoc2l6ZSA+IDIgPyBzaXplIC0gMiA6IDEpLAoJCSAgWG1ObWF4aW11bSwgbWF4ICsgMSwJICAgIC8qIE1vdGlmIGhhcyBtYXggb25lIHBhc3QgdGhlIGVuZCAqLwoJCSAgTlVMTCk7Cn0KCiAgICB2b2lkCmd1aV9tY2hfc2V0X3Njcm9sbGJhcl9wb3Moc2IsIHgsIHksIHcsIGgpCiAgICBzY3JvbGxiYXJfVCAqc2I7CiAgICBpbnQJCXg7CiAgICBpbnQJCXk7CiAgICBpbnQJCXc7CiAgICBpbnQJCWg7CnsKICAgIGlmIChzYi0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJaWYgKHNiLT50eXBlID09IFNCQVJfTEVGVCB8fCBzYi0+dHlwZSA9PSBTQkFSX1JJR0hUKQoJewoJICAgIGlmICh5ID09IDApCgkJaCAtPSBndWkuYm9yZGVyX29mZnNldDsKCSAgICBlbHNlCgkJeSAtPSBndWkuYm9yZGVyX29mZnNldDsKCSAgICBYdFZhU2V0VmFsdWVzKHNiLT5pZCwKCQkJICBYbU50b3BPZmZzZXQsIHksCgkJCSAgWG1OYm90dG9tT2Zmc2V0LCAteSAtIGgsCgkJCSAgWG1Od2lkdGgsIHcsCgkJCSAgTlVMTCk7Cgl9CgllbHNlCgkgICAgWHRWYVNldFZhbHVlcyhzYi0+aWQsCgkJCSAgWG1OdG9wT2Zmc2V0LCB5LAoJCQkgIFhtTmxlZnRPZmZzZXQsIHgsCgkJCSAgWG1OcmlnaHRPZmZzZXQsIGd1aS53aGljaF9zY3JvbGxiYXJzW1NCQVJfUklHSFRdCgkJCQkJCSAgICA/IGd1aS5zY3JvbGxiYXJfd2lkdGggOiAwLAoJCQkgIFhtTmhlaWdodCwgaCwKCQkJICBOVUxMKTsKCVh0TWFuYWdlQ2hpbGQoc2ItPmlkKTsKICAgIH0KfQoKICAgIHZvaWQKZ3VpX21jaF9lbmFibGVfc2Nyb2xsYmFyKHNiLCBmbGFnKQogICAgc2Nyb2xsYmFyX1QgKnNiOwogICAgaW50CQlmbGFnOwp7CiAgICBBcmcJCWFyZ3NbMTZdOwogICAgaW50CQluOwoKICAgIGlmIChzYi0+aWQgIT0gKFdpZGdldCkwKQogICAgewoJbiA9IDA7CglpZiAoZmxhZykKCXsKCSAgICBzd2l0Y2ggKHNiLT50eXBlKQoJICAgIHsKCQljYXNlIFNCQVJfTEVGVDoKCQkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdE9mZnNldCwgZ3VpLnNjcm9sbGJhcl93aWR0aCk7IG4rKzsKCQkgICAgYnJlYWs7CgoJCWNhc2UgU0JBUl9SSUdIVDoKCQkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OcmlnaHRPZmZzZXQsIGd1aS5zY3JvbGxiYXJfd2lkdGgpOyBuKys7CgkJICAgIGJyZWFrOwoKCQljYXNlIFNCQVJfQk9UVE9NOgoJCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21PZmZzZXQsIGd1aS5zY3JvbGxiYXJfaGVpZ2h0KTtuKys7CgkJICAgIGJyZWFrOwoJICAgIH0KCSAgICBYdFNldFZhbHVlcyh0ZXh0QXJlYSwgYXJncywgbik7CgkgICAgWHRNYW5hZ2VDaGlsZChzYi0+aWQpOwoJfQoJZWxzZQoJewoJICAgIGlmICghZ3VpLndoaWNoX3Njcm9sbGJhcnNbc2ItPnR5cGVdKQoJICAgIHsKCQkvKiBUaGUgc2Nyb2xsYmFycyBvZiB0aGlzIHR5cGUgYXJlIGFsbCBkaXNhYmxlZCwgYWRqdXN0IHRoZQoJCSAqIHRleHRBcmVhIGF0dGFjaG1lbnQgb2Zmc2V0LiAqLwoJCXN3aXRjaCAoc2ItPnR5cGUpCgkJewoJCSAgICBjYXNlIFNCQVJfTEVGVDoKCQkJWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdE9mZnNldCwgMCk7IG4rKzsKCQkJYnJlYWs7CgoJCSAgICBjYXNlIFNCQVJfUklHSFQ6CgkJCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0T2Zmc2V0LCAwKTsgbisrOwoJCQlicmVhazsKCgkJICAgIGNhc2UgU0JBUl9CT1RUT006CgkJCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbU9mZnNldCwgMCk7bisrOwoJCQlicmVhazsKCQl9CgkJWHRTZXRWYWx1ZXModGV4dEFyZWEsIGFyZ3MsIG4pOwoJICAgIH0KCSAgICBYdFVubWFuYWdlQ2hpbGQoc2ItPmlkKTsKCX0KICAgIH0KfQoKICAgIHZvaWQKZ3VpX21jaF9jcmVhdGVfc2Nyb2xsYmFyKHNiLCBvcmllbnQpCiAgICBzY3JvbGxiYXJfVCAqc2I7CiAgICBpbnQJCW9yaWVudDsJLyogU0JBUl9WRVJUIG9yIFNCQVJfSE9SSVogKi8KewogICAgQXJnCQlhcmdzWzE2XTsKICAgIGludAkJbjsKCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTm1pbmltdW0sIDApOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5vcmllbnRhdGlvbiwKCSAgICAob3JpZW50ID09IFNCQVJfVkVSVCkgPyBYbVZFUlRJQ0FMIDogWG1IT1JJWk9OVEFMKTsgbisrOwoKICAgIHN3aXRjaCAoc2ItPnR5cGUpCiAgICB7CgljYXNlIFNCQVJfTEVGVDoKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX09QUE9TSVRFX0ZPUk0pOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgYnJlYWs7CgoJY2FzZSBTQkFSX1JJR0hUOgoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfT1BQT1NJVEVfRk9STSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgYnJlYWs7CgoJY2FzZSBTQkFSX0JPVFRPTToKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKCSAgICBicmVhazsKICAgIH0KCiAgICBzYi0+aWQgPSBYdENyZWF0ZVdpZGdldCgic2Nyb2xsQmFyIiwKCSAgICB4bVNjcm9sbEJhcldpZGdldENsYXNzLCB0ZXh0QXJlYUZvcm0sIGFyZ3MsIG4pOwoKICAgIC8qIFJlbWVtYmVyIHRoZSBkZWZhdWx0IGNvbG9ycywgbmVlZGVkIGZvciAiOmhpIGNsZWFyIi4gKi8KICAgIGlmIChndWkuc2Nyb2xsX2RlZl9iZ19waXhlbCA9PSAoZ3VpY29sb3JfVCkwCgkgICAgJiYgZ3VpLnNjcm9sbF9kZWZfZmdfcGl4ZWwgPT0gKGd1aWNvbG9yX1QpMCkKCVh0VmFHZXRWYWx1ZXMoc2ItPmlkLAoJCVhtTmJhY2tncm91bmQsICZndWkuc2Nyb2xsX2RlZl9iZ19waXhlbCwKCQlYbU5mb3JlZ3JvdW5kLCAmZ3VpLnNjcm9sbF9kZWZfZmdfcGl4ZWwsCgkJTlVMTCk7CgogICAgaWYgKHNiLT5pZCAhPSAoV2lkZ2V0KTApCiAgICB7CglndWlfbWNoX3NldF9zY3JvbGxiYXJfY29sb3JzKHNiKTsKCVh0QWRkQ2FsbGJhY2soc2ItPmlkLCBYbU52YWx1ZUNoYW5nZWRDYWxsYmFjaywKCQkgICAgICBzY3JvbGxfY2IsIChYdFBvaW50ZXIpc2ItPmlkZW50KTsKCVh0QWRkQ2FsbGJhY2soc2ItPmlkLCBYbU5kcmFnQ2FsbGJhY2ssCgkJICAgICAgc2Nyb2xsX2NiLCAoWHRQb2ludGVyKXNiLT5pZGVudCk7CglYdEFkZEV2ZW50SGFuZGxlcihzYi0+aWQsIEtleVByZXNzTWFzaywgRkFMU0UsIGd1aV94MTFfa2V5X2hpdF9jYiwKCSAgICAoWHRQb2ludGVyKTApOwogICAgfQp9CgojaWYgZGVmaW5lZChGRUFUX1dJTkRPV1MpIHx8IGRlZmluZWQoUFJPVE8pCiAgICB2b2lkCmd1aV9tY2hfZGVzdHJveV9zY3JvbGxiYXIoc2IpCiAgICBzY3JvbGxiYXJfVCAqc2I7CnsKICAgIGlmIChzYi0+aWQgIT0gKFdpZGdldCkwKQoJWHREZXN0cm95V2lkZ2V0KHNiLT5pZCk7Cn0KI2VuZGlmCgogICAgdm9pZApndWlfbWNoX3NldF9zY3JvbGxiYXJfY29sb3JzKHNiKQogICAgc2Nyb2xsYmFyX1QgKnNiOwp7CiAgICBpZiAoc2ItPmlkICE9IChXaWRnZXQpMCkKICAgIHsKCWlmIChndWkuc2Nyb2xsX2JnX3BpeGVsICE9IElOVkFMQ09MT1IpCgl7CiNpZiAoWG1WZXJzaW9uPj0xMDAyKQoJICAgIFhtQ2hhbmdlQ29sb3Ioc2ItPmlkLCBndWkuc2Nyb2xsX2JnX3BpeGVsKTsKI2Vsc2UKCSAgICBYdFZhU2V0VmFsdWVzKHNiLT5pZCwKCQkgICAgWG1OdHJvdWdoQ29sb3IsIGd1aS5zY3JvbGxfYmdfcGl4ZWwsCgkJICAgIE5VTEwpOwojZW5kaWYKCX0KCglpZiAoZ3VpLnNjcm9sbF9mZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJICAgIFh0VmFTZXRWYWx1ZXMoc2ItPmlkLAoJCSAgICBYbU5mb3JlZ3JvdW5kLCBndWkuc2Nyb2xsX2ZnX3BpeGVsLAojaWYgKFhtVmVyc2lvbjwxMDAyKQoJCSAgICBYbU5iYWNrZ3JvdW5kLCBndWkuc2Nyb2xsX2ZnX3BpeGVsLAojZW5kaWYKCQkgICAgTlVMTCk7CiAgICB9CgogICAgLyogVGhpcyBpcyBuZWVkZWQgZm9yIHRoZSByZWN0YW5nbGUgYmVsb3cgdGhlIHZlcnRpY2FsIHNjcm9sbGJhcnMuICovCiAgICBpZiAoc2IgPT0gJmd1aS5ib3R0b21fc2JhciAmJiB0ZXh0QXJlYUZvcm0gIT0gKFdpZGdldCkwKQoJZ3VpX21vdGlmX3Njcm9sbF9jb2xvcnModGV4dEFyZWFGb3JtKTsKfQoKLyoKICogTWlzY2VsbGFuZW91cyBzdHVmZjoKICovCgogICAgV2luZG93Cmd1aV94MTFfZ2V0X3dpZCgpCnsKICAgIHJldHVybihYdFdpbmRvdyh0ZXh0QXJlYSkpOwp9CgovKgogKiBMb29rIGZvciBhIHdpZGdldCBpbiB0aGUgd2lkZ2V0IHRyZWUgdywgd2l0aCBhIG1uZW1vbmljIG1hdGNoaW5nIGtleWNvZGUuCiAqIFdoZW4gb25lIGlzIGZvdW5kLCBzaW11bGF0ZSBhIGJ1dHRvbiBwcmVzcyBvbiB0aGF0IHdpZGdldCBhbmQgZ2l2ZSBpdCB0aGUKICoga2V5Ym9hcmQgZm9jdXMuICBJZiB0aGUgbW5lbW9uaWMgaXMgb24gYSBsYWJlbCwgbG9vayBpbiB0aGUgdXNlckRhdGEgZmllbGQKICogb2YgdGhlIGxhYmVsIHRvIHNlZSBpZiBpdCBwb2ludHMgdG8gYW5vdGhlciB3aWRnZXQsIGFuZCBnaXZlIHRoYXQgdGhlIGZvY3VzLgogKi8KICAgIHN0YXRpYyB2b2lkCmRvX21uZW1vbmljKFdpZGdldCB3LCB1bnNpZ25lZCBpbnQga2V5Y29kZSkKewogICAgV2lkZ2V0TGlzdAkgICAgY2hpbGRyZW47CiAgICBpbnQJCSAgICBudW1DaGlsZHJlbiwgaTsKICAgIEJvb2xlYW4JICAgIGlzTWVudTsKICAgIEtleVN5bQkgICAgbW5lbW9uaWMgPSAnXDAnOwogICAgY2hhcgkgICAgbW5lU3RyaW5nWzJdOwogICAgV2lkZ2V0CSAgICB1c2VyRGF0YTsKICAgIHVuc2lnbmVkIGNoYXIgICByb3dDb2xUeXBlOwoKICAgIGlmIChYdElzQ29tcG9zaXRlKHcpKQogICAgewoJaWYgKFh0Q2xhc3ModykgPT0geG1Sb3dDb2x1bW5XaWRnZXRDbGFzcykKCXsKCSAgICBYdFZhR2V0VmFsdWVzKHcsIFhtTnJvd0NvbHVtblR5cGUsICZyb3dDb2xUeXBlLCBOVUxMKTsKCSAgICBpc01lbnUgPSAocm93Q29sVHlwZSAhPSAodW5zaWduZWQgY2hhcilYbVdPUktfQVJFQSk7Cgl9CgllbHNlCgkgICAgaXNNZW51ID0gRmFsc2U7CglpZiAoIWlzTWVudSkKCXsKCSAgICBYdFZhR2V0VmFsdWVzKHcsIFhtTmNoaWxkcmVuLCAmY2hpbGRyZW4sIFhtTm51bUNoaWxkcmVuLAoJCQkgICZudW1DaGlsZHJlbiwgTlVMTCk7CgkgICAgZm9yIChpID0gMDsgaSA8IG51bUNoaWxkcmVuOyBpKyspCgkJZG9fbW5lbW9uaWMoY2hpbGRyZW5baV0sIGtleWNvZGUpOwoJfQogICAgfQogICAgZWxzZQogICAgewoJWHRWYUdldFZhbHVlcyh3LCBYbU5tbmVtb25pYywgJm1uZW1vbmljLCBOVUxMKTsKCWlmIChtbmVtb25pYyAhPSAnXDAnKQoJewoJICAgIG1uZVN0cmluZ1swXSA9IG1uZW1vbmljOwoJICAgIG1uZVN0cmluZ1sxXSA9ICdcMCc7CgkgICAgaWYgKFhLZXlzeW1Ub0tleWNvZGUoWHREaXNwbGF5KFh0UGFyZW50KHcpKSwKCQkJCSAgICAgICBYU3RyaW5nVG9LZXlzeW0obW5lU3RyaW5nKSkgPT0ga2V5Y29kZSkKCSAgICB7CgkJaWYgKFh0Q2xhc3ModykgPT0geG1MYWJlbFdpZGdldENsYXNzCgkJCXx8IFh0Q2xhc3ModykgPT0geG1MYWJlbEdhZGdldENsYXNzKQoJCXsKCQkgICAgWHRWYUdldFZhbHVlcyh3LCBYbU51c2VyRGF0YSwgJnVzZXJEYXRhLCBOVUxMKTsKCQkgICAgaWYgKHVzZXJEYXRhICE9IE5VTEwgJiYgWHRJc1dpZGdldCh1c2VyRGF0YSkpCgkJCVhtUHJvY2Vzc1RyYXZlcnNhbCh1c2VyRGF0YSwgWG1UUkFWRVJTRV9DVVJSRU5UKTsKCQl9CgkJZWxzZQoJCXsKCQkgICAgWEtleVByZXNzZWRFdmVudCBrZXlFdmVudDsKCgkJICAgIFhtUHJvY2Vzc1RyYXZlcnNhbCh3LCBYbVRSQVZFUlNFX0NVUlJFTlQpOwoKCQkgICAgdmltX21lbXNldCgoY2hhciAqKSAma2V5RXZlbnQsIDAsIHNpemVvZihYS2V5UHJlc3NlZEV2ZW50KSk7CgkJICAgIGtleUV2ZW50LnR5cGUgPSBLZXlQcmVzczsKCQkgICAga2V5RXZlbnQuc2VyaWFsID0gMTsKCQkgICAga2V5RXZlbnQuc2VuZF9ldmVudCA9IFRydWU7CgkJICAgIGtleUV2ZW50LmRpc3BsYXkgPSBYdERpc3BsYXkodyk7CgkJICAgIGtleUV2ZW50LndpbmRvdyA9IFh0V2luZG93KHcpOwoJCSAgICBYdENhbGxBY3Rpb25Qcm9jKHcsICJBY3RpdmF0ZSIsIChYRXZlbnQgKikgJiBrZXlFdmVudCwKCQkJCQkJCQkgICAgIE5VTEwsIDApOwoJCX0KCSAgICB9Cgl9CiAgICB9Cn0KCi8qCiAqIENhbGxiYWNrIHJvdXRpbmUgZm9yIGRpYWxvZyBtbmVtb25pYyBwcm9jZXNzaW5nLgogKi8KICAgIHN0YXRpYyB2b2lkCm1uZW1vbmljX2V2ZW50KFdpZGdldCB3LCBYdFBvaW50ZXIgY2FsbF9kYXRhIFVOVVNFRCwgWEtleUV2ZW50ICpldmVudCkKewogICAgZG9fbW5lbW9uaWModywgZXZlbnQtPmtleWNvZGUpOwp9CgoKLyoKICogU2VhcmNoIHRoZSB3aWRnZXQgdHJlZSB1bmRlciB3IGZvciB3aWRnZXRzIHdpdGggbW5lbW9uaWNzLiAgV2hlbiBmb3VuZCwgYWRkCiAqIGEgcGFzc2l2ZSBncmFiIHRvIHRoZSBkaWFsb2cgd2lkZ2V0IGZvciB0aGUgbW5lbW9uaWMgY2hhcmFjdGVyLCB0aHVzCiAqIGRpcmVjdGluZyBtbmVtb25pYyBldmVudHMgdG8gdGhlIGRpYWxvZyB3aWRnZXQuCiAqLwogICAgc3RhdGljIHZvaWQKYWRkX21uZW1vbmljX2dyYWJzKFdpZGdldCBkaWFsb2csIFdpZGdldCB3KQp7CiAgICBjaGFyCSAgICBtbmVTdHJpbmdbMl07CiAgICBXaWRnZXRMaXN0CSAgICBjaGlsZHJlbjsKICAgIGludAkJICAgIG51bUNoaWxkcmVuLCBpOwogICAgQm9vbGVhbgkgICAgaXNNZW51OwogICAgS2V5U3ltCSAgICBtbmVtb25pYyA9ICdcMCc7CiAgICB1bnNpZ25lZCBjaGFyICAgcm93Q29sVHlwZTsKCiAgICBpZiAoWHRJc0NvbXBvc2l0ZSh3KSkKICAgIHsKCWlmIChYdENsYXNzKHcpID09IHhtUm93Q29sdW1uV2lkZ2V0Q2xhc3MpCgl7CgkgICAgWHRWYUdldFZhbHVlcyh3LCBYbU5yb3dDb2x1bW5UeXBlLCAmcm93Q29sVHlwZSwgTlVMTCk7CgkgICAgaXNNZW51ID0gKHJvd0NvbFR5cGUgIT0gKHVuc2lnbmVkIGNoYXIpWG1XT1JLX0FSRUEpOwoJfQoJZWxzZQoJICAgIGlzTWVudSA9IEZhbHNlOwoJaWYgKCFpc01lbnUpCgl7CgkgICAgWHRWYUdldFZhbHVlcyh3LCBYbU5jaGlsZHJlbiwgJmNoaWxkcmVuLCBYbU5udW1DaGlsZHJlbiwKCQkJCQkJCSAgJm51bUNoaWxkcmVuLCBOVUxMKTsKCSAgICBmb3IgKGkgPSAwOyBpIDwgbnVtQ2hpbGRyZW47IGkrKykKCQlhZGRfbW5lbW9uaWNfZ3JhYnMoZGlhbG9nLCBjaGlsZHJlbltpXSk7Cgl9CiAgICB9CiAgICBlbHNlCiAgICB7CglYdFZhR2V0VmFsdWVzKHcsIFhtTm1uZW1vbmljLCAmbW5lbW9uaWMsIE5VTEwpOwoJaWYgKG1uZW1vbmljICE9ICdcMCcpCgl7CgkgICAgbW5lU3RyaW5nWzBdID0gbW5lbW9uaWM7CgkgICAgbW5lU3RyaW5nWzFdID0gJ1wwJzsKCSAgICBYdEdyYWJLZXkoZGlhbG9nLCBYS2V5c3ltVG9LZXljb2RlKFh0RGlzcGxheShkaWFsb2cpLAoJCQkJCQkgIFhTdHJpbmdUb0tleXN5bShtbmVTdHJpbmcpKSwKCQkgICAgTW9kMU1hc2ssIFRydWUsIEdyYWJNb2RlQXN5bmMsIEdyYWJNb2RlQXN5bmMpOwoJfQogICAgfQp9CgovKgogKiBBZGQgYSBoYW5kbGVyIGZvciBtbmVtb25pY3MgaW4gYSBkaWFsb2cuICBNb3RpZiBpdHNlbGYgb25seSBoYW5kbGVzCiAqIG1uZW1vbmljcyBpbiBtZW51cy4gTW5lbW9uaWNzIGFkZGVkIG9yIGNoYW5nZWQgYWZ0ZXIgdGhpcyBjYWxsIHdpbGwgYmUKICogaWdub3JlZC4KICoKICogVG8gYWRkIGEgbW5lbW9uaWMgdG8gYSB0ZXh0IGZpZWxkIG9yIGxpc3QsIHNldCB0aGUgWG1ObW5lbW9uaWMgcmVzb3VyY2Ugb24KICogdGhlIGFwcHJvcHJpYXRlIGxhYmVsIGFuZCBzZXQgdGhlIFhtTnVzZXJEYXRhIHJlc291cmNlIG9mIHRoZSBsYWJlbCB0byB0aGUKICogd2lkZ2V0IHRvIGdldCB0aGUgZm9jdXMgd2hlbiB0aGUgbW5lbW9uaWMgaXMgdHlwZWQuCiAqLwogICAgc3RhdGljIHZvaWQKYWN0aXZhdGVfZGlhbG9nX21uZW1vbmljcyhXaWRnZXQgZGlhbG9nKQp7CiAgICBpZiAoIWRpYWxvZykKCXJldHVybjsKCiAgICBYdEFkZEV2ZW50SGFuZGxlcihkaWFsb2csIEtleVByZXNzTWFzaywgRmFsc2UsCgkJCSAgIChYdEV2ZW50SGFuZGxlcikgbW5lbW9uaWNfZXZlbnQsIChYdFBvaW50ZXIpIE5VTEwpOwogICAgYWRkX21uZW1vbmljX2dyYWJzKGRpYWxvZywgZGlhbG9nKTsKfQoKLyoKICogUmVtb3ZlcyB0aGUgZXZlbnQgaGFuZGxlciBhbmQga2V5LWdyYWJzIGZvciBkaWFsb2cgbW5lbW9uaWMgaGFuZGxpbmcuCiAqLwogICAgc3RhdGljIHZvaWQKc3VwcHJlc3NfZGlhbG9nX21uZW1vbmljcyhXaWRnZXQgZGlhbG9nKQp7CiAgICBpZiAoIWRpYWxvZykKCXJldHVybjsKCiAgICBYdFVuZ3JhYktleShkaWFsb2csIEFueUtleSwgTW9kMU1hc2spOwogICAgWHRSZW1vdmVFdmVudEhhbmRsZXIoZGlhbG9nLCBLZXlQcmVzc01hc2ssIEZhbHNlLAoJCQkgICAoWHRFdmVudEhhbmRsZXIpIG1uZW1vbmljX2V2ZW50LCAoWHRQb2ludGVyKSBOVUxMKTsKfQoKI2lmIGRlZmluZWQoRkVBVF9CUk9XU0UpIHx8IGRlZmluZWQoRkVBVF9HVUlfRElBTE9HKQpzdGF0aWMgdm9pZCBzZXRfZm9udGxpc3QgX19BUkdTKChXaWRnZXQgd2cpKTsKCi8qCiAqIFVzZSB0aGUgJ2d1aWZvbnQnIG9yICdndWlmb250c2V0JyBhcyBhIGZvbnRsaXN0IGZvciBhIGRpYWxvZyB3aWRnZXQuCiAqLwogICAgc3RhdGljIHZvaWQKc2V0X2ZvbnRsaXN0KGlkKQogICAgV2lkZ2V0IGlkOwp7CiAgICBYbUZvbnRMaXN0IGZsOwoKI2lmZGVmIEZPTlRTRVRfQUxXQVlTCiAgICBpZiAoZ3VpLmZvbnRzZXQgIT0gTk9GT05UU0VUKQogICAgewoJZmwgPSBndWlfbW90aWZfZm9udHNldDJmb250bGlzdCgoWEZvbnRTZXQgKikmZ3VpLmZvbnRzZXQpOwoJaWYgKGZsICE9IE5VTEwpCgl7CgkgICAgaWYgKFh0SXNNYW5hZ2VkKGlkKSkKCSAgICB7CgkJWHRVbm1hbmFnZUNoaWxkKGlkKTsKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJCS8qIFdlIHNob3VsZCBmb3JjZSB0aGUgd2lkZ2V0IHRvIHJlY2FsY3VsYXRlIGl0J3MKCQkgKiBnZW9tZXRyeSBub3cuICovCgkJWHRNYW5hZ2VDaGlsZChpZCk7CgkgICAgfQoJICAgIGVsc2UKCQlYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb250TGlzdCwgZmwsIE5VTEwpOwoJICAgIFhtRm9udExpc3RGcmVlKGZsKTsKCX0KICAgIH0KI2Vsc2UKICAgIGlmIChndWkubm9ybV9mb250ICE9IE5PRk9OVCkKICAgIHsKCWZsID0gZ3VpX21vdGlmX2NyZWF0ZV9mb250bGlzdCgoWEZvbnRTdHJ1Y3QgKilndWkubm9ybV9mb250KTsKCWlmIChmbCAhPSBOVUxMKQoJewoJICAgIGlmIChYdElzTWFuYWdlZChpZCkpCgkgICAgewoJCVh0VW5tYW5hZ2VDaGlsZChpZCk7CgkJWHRWYVNldFZhbHVlcyhpZCwgWG1OZm9udExpc3QsIGZsLCBOVUxMKTsKCQkvKiBXZSBzaG91bGQgZm9yY2UgdGhlIHdpZGdldCB0byByZWNhbGN1bGF0ZSBpdCdzCgkJICogZ2VvbWV0cnkgbm93LiAqLwoJCVh0TWFuYWdlQ2hpbGQoaWQpOwoJICAgIH0KCSAgICBlbHNlCgkJWHRWYVNldFZhbHVlcyhpZCwgWG1OZm9udExpc3QsIGZsLCBOVUxMKTsKCSAgICBYbUZvbnRMaXN0RnJlZShmbCk7Cgl9CiAgICB9CiNlbmRpZgp9CiNlbmRpZgoKI2lmIGRlZmluZWQoRkVBVF9CUk9XU0UpIHx8IGRlZmluZWQoUFJPVE8pCgovKgogKiBmaWxlIHNlbGVjdG9yIHJlbGF0ZWQgc3R1ZmYKICovCgojaW5jbHVkZSA8WG0vRmlsZVNCLmg+CiNpbmNsdWRlIDxYbS9YbVN0ckRlZnMuaD4KCnR5cGVkZWYgc3RydWN0IGRpYWxvZ19jYWxsYmFja19hcmcKewogICAgY2hhciAqICBhcmdzOyAgIC8qIG5vdCB1c2VkIHJpZ2h0IG5vdyAqLwogICAgaW50CSAgICBpZDsKfSBkY2JhcmdfVDsKCnN0YXRpYyBXaWRnZXQgZGlhbG9nX3dndDsKc3RhdGljIGNoYXIgKmJyb3dzZV9mbmFtZSA9IE5VTEw7CnN0YXRpYyBYbVN0cmluZ0NoYXJTZXQgY2hhcnNldCA9IChYbVN0cmluZ0NoYXJTZXQpIFhtU1RSSU5HX0RFRkFVTFRfQ0hBUlNFVDsKCQkJCS8qIHVzZWQgdG8gc2V0IHVwIFhtU3RyaW5ncyAqLwoKc3RhdGljIHZvaWQgRGlhbG9nQ2FuY2VsQ0IgX19BUkdTKChXaWRnZXQsIFh0UG9pbnRlciwgWHRQb2ludGVyKSk7CnN0YXRpYyB2b2lkIERpYWxvZ0FjY2VwdENCIF9fQVJHUygoV2lkZ2V0LCBYdFBvaW50ZXIsIFh0UG9pbnRlcikpOwoKLyoKICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHRyYW5zbGF0ZSB0aGUgcHJlZGVmaW5lZCBsYWJlbCB0ZXh0IG9mIHRoZQogKiBwcmVjb21wb3NlZCBkaWFsb2dzLiBXZSBkbyB0aGlzIGV4cGxpY2l0bHkgdG8gYWxsb3c6CiAqCiAqIC0gdXNhZ2Ugb2YgZ2V0dGV4dCBmb3IgdHJhbnNsYXRpb24sIGFzIGluIGFsbCB0aGUgb3RoZXIgcGxhY2VzLgogKgogKiAtIGVxdWFsaXplIHRoZSBtZXNzYWdlcyBiZXR3ZWVuIGRpZmZlcmVudCBHVUkgaW1wbGVtZW50YXRpb25zIGFzIGZhciBhcwogKiBwb3NzaWJsZS4KICovCnN0YXRpYyB2b2lkIHNldF9wcmVkZWZpbmVkX2xhYmVsIF9fQVJHUygoV2lkZ2V0IHBhcmVudCwgU3RyaW5nIG5hbWUsIGNoYXIgKm5ld19sYWJlbCkpOwoKc3RhdGljIHZvaWQKc2V0X3ByZWRlZmluZWRfbGFiZWwocGFyZW50LCBuYW1lLCBuZXdfbGFiZWwpCiAgICBXaWRnZXQgIHBhcmVudDsKICAgIFN0cmluZyAgbmFtZTsKICAgIGNoYXIgICAgKm5ld19sYWJlbDsKewogICAgWG1TdHJpbmcJc3RyOwogICAgV2lkZ2V0CXc7CiAgICBjaGFyX3UJKnAsICpuZXh0OwogICAgS2V5U3ltCW1uZW1vbmljID0gTlVMOwoKICAgIHcgPSBYdE5hbWVUb1dpZGdldChwYXJlbnQsIG5hbWUpOwoKICAgIGlmICghdykKCXJldHVybjsKCiAgICBwID0gdmltX3N0cnNhdmUoKGNoYXJfdSAqKW5ld19sYWJlbCk7CiAgICBpZiAocCA9PSBOVUxMKQoJcmV0dXJuOwogICAgZm9yIChuZXh0ID0gcDsgKm5leHQ7ICsrbmV4dCkKICAgIHsKCWlmICgqbmV4dCA9PSBETEdfSE9US0VZX0NIQVIpCgl7CgkgICAgaW50IGxlbiA9IFNUUkxFTihuZXh0KTsKCgkgICAgaWYgKGxlbiA+IDApCgkgICAgewoJCW1jaF9tZW1tb3ZlKG5leHQsIG5leHQgKyAxLCBsZW4pOwoJCW1uZW1vbmljID0gbmV4dFswXTsKCSAgICB9Cgl9CiAgICB9CgogICAgc3RyID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKilwLCBTVFJJTkdfVEFHKTsKICAgIHZpbV9mcmVlKHApOwoKICAgIGlmIChzdHIgIT0gTlVMTCkKICAgIHsKCVh0VmFTZXRWYWx1ZXModywKCQlYbU5sYWJlbFN0cmluZywgc3RyLAoJCVhtTm1uZW1vbmljLCBtbmVtb25pYywKCQlOVUxMKTsKCVhtU3RyaW5nRnJlZShzdHIpOwogICAgfQogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3Qodyk7Cn0KCnN0YXRpYyB2b2lkCnNldF9wcmVkZWZpbmVkX2ZvbnRsaXN0KHBhcmVudCwgbmFtZSkKICAgIFdpZGdldCBwYXJlbnQ7CiAgICBTdHJpbmcgbmFtZTsKewogICAgV2lkZ2V0IHc7CiAgICB3ID0gWHROYW1lVG9XaWRnZXQocGFyZW50LCBuYW1lKTsKCiAgICBpZiAoIXcpCglyZXR1cm47CgogICAgc2V0X2ZvbnRsaXN0KHcpOwp9CgovKgogKiBQdXQgdXAgYSBmaWxlIHJlcXVlc3Rlci4KICogUmV0dXJucyB0aGUgc2VsZWN0ZWQgbmFtZSBpbiBhbGxvY2F0ZWQgbWVtb3J5LCBvciBOVUxMIGZvciBDYW5jZWwuCiAqLwogICAgY2hhcl91ICoKZ3VpX21jaF9icm93c2Uoc2F2aW5nLCB0aXRsZSwgZGZsdCwgZXh0LCBpbml0ZGlyLCBmaWx0ZXIpCiAgICBpbnQJCXNhdmluZyBVTlVTRUQ7CS8qIHNlbGVjdCBmaWxlIHRvIHdyaXRlICovCiAgICBjaGFyX3UJKnRpdGxlOwkJLyogdGl0bGUgZm9yIHRoZSB3aW5kb3cgKi8KICAgIGNoYXJfdQkqZGZsdDsJCS8qIGRlZmF1bHQgbmFtZSAqLwogICAgY2hhcl91CSpleHQgVU5VU0VEOwkvKiBub3QgdXNlZCAoZXh0ZW5zaW9uIGFkZGVkKSAqLwogICAgY2hhcl91CSppbml0ZGlyOwkvKiBpbml0aWFsIGRpcmVjdG9yeSwgTlVMTCBmb3IgY3VycmVudCBkaXIgKi8KICAgIGNoYXJfdQkqZmlsdGVyOwkvKiBmaWxlIG5hbWUgZmlsdGVyICovCnsKICAgIGNoYXJfdQlkaXJidWZbTUFYUEFUSExdOwogICAgY2hhcl91CWRmbHRidWZbTUFYUEFUSExdOwogICAgY2hhcl91CSpwYXR0ZXJuOwogICAgY2hhcl91CSp0b2ZyZWUgPSBOVUxMOwoKICAgIC8qIFRoZXJlIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSByZXNvdXJjZSBuYW1lIGFuZCB2YWx1ZSwgVGhlcmVmb3JlLCB3ZQogICAgICogYXZvaWQgdG8gKGFiLSl1c2UgdGhlIChtYXliZSBpbnRlcm5hdGlvbmFsaXplZCEpIGRpYWxvZyB0aXRsZSBhcyBhCiAgICAgKiBkaWFsb2cgbmFtZS4KICAgICAqLwoKICAgIGRpYWxvZ193Z3QgPSBYbUNyZWF0ZUZpbGVTZWxlY3Rpb25EaWFsb2codmltU2hlbGwsICJicm93c2VEaWFsb2ciLCBOVUxMLCAwKTsKCiAgICBpZiAoaW5pdGRpciA9PSBOVUxMIHx8ICppbml0ZGlyID09IE5VTCkKICAgIHsKCW1jaF9kaXJuYW1lKGRpcmJ1ZiwgTUFYUEFUSEwpOwoJaW5pdGRpciA9IGRpcmJ1ZjsKICAgIH0KCiAgICBpZiAoZGZsdCA9PSBOVUxMKQoJZGZsdCA9IChjaGFyX3UgKikiIjsKICAgIGVsc2UgaWYgKFNUUkxFTihpbml0ZGlyKSArIFNUUkxFTihkZmx0KSArIDIgPCBNQVhQQVRITCkKICAgIHsKCS8qIFRoZSBkZWZhdWx0IHNlbGVjdGlvbiBzaG91bGQgYmUgdGhlIGZ1bGwgcGF0aCwgImRmbHQiIGlzIG9ubHkgdGhlCgkgKiBmaWxlIG5hbWUuICovCglTVFJDUFkoZGZsdGJ1ZiwgaW5pdGRpcik7CglhZGRfcGF0aHNlcChkZmx0YnVmKTsKCVNUUkNBVChkZmx0YnVmLCBkZmx0KTsKCWRmbHQgPSBkZmx0YnVmOwogICAgfQoKICAgIC8qIENhbiBvbmx5IHVzZSBvbmUgcGF0dGVybiBmb3IgYSBmaWxlIG5hbWUuICBHZXQgdGhlIGZpcnN0IHBhdHRlcm4gb3V0IG9mCiAgICAgKiB0aGUgZmlsdGVyLiAgQW4gZW1wdHkgcGF0dGVybiBtZWFucyBldmVyeXRoaW5nIG1hdGNoZXMuICovCiAgICBpZiAoZmlsdGVyID09IE5VTEwpCglwYXR0ZXJuID0gKGNoYXJfdSAqKSIiOwogICAgZWxzZQogICAgewoJY2hhcl91CSpzLCAqcDsKCglzID0gZmlsdGVyOwoJZm9yIChwID0gZmlsdGVyOyAqcCAhPSBOVUw7ICsrcCkKCXsKCSAgICBpZiAoKnAgPT0gJ1x0JykJLyogZW5kIG9mIGRlc2NyaXB0aW9uLCBzdGFydCBvZiBwYXR0ZXJuICovCgkJcyA9IHAgKyAxOwoJICAgIGlmICgqcCA9PSAnOycgfHwgKnAgPT0gJ1xuJykJLyogZW5kIG9mIChmaXJzdCkgcGF0dGVybiAqLwoJCWJyZWFrOwoJfQoJcGF0dGVybiA9IHZpbV9zdHJuc2F2ZShzLCBwIC0gcyk7Cgl0b2ZyZWUgPSBwYXR0ZXJuOwoJaWYgKHBhdHRlcm4gPT0gTlVMTCkKCSAgICBwYXR0ZXJuID0gKGNoYXJfdSAqKSIiOwogICAgfQoKICAgIFh0VmFTZXRWYWx1ZXMoZGlhbG9nX3dndCwKCVh0VmFUeXBlZEFyZywKCSAgICBYbU5kaXJlY3RvcnksIFhtUlN0cmluZywgKGNoYXIgKilpbml0ZGlyLCBTVFJMRU4oaW5pdGRpcikgKyAxLAoJWHRWYVR5cGVkQXJnLAoJICAgIFhtTmRpclNwZWMsCVhtUlN0cmluZywgKGNoYXIgKilkZmx0LCBTVFJMRU4oZGZsdCkgKyAxLAoJWHRWYVR5cGVkQXJnLAoJICAgIFhtTnBhdHRlcm4sCVhtUlN0cmluZywgKGNoYXIgKilwYXR0ZXJuLCBTVFJMRU4ocGF0dGVybikgKyAxLAoJWHRWYVR5cGVkQXJnLAoJICAgIFhtTmRpYWxvZ1RpdGxlLCBYbVJTdHJpbmcsIChjaGFyICopdGl0bGUsIFNUUkxFTih0aXRsZSkgKyAxLAoJTlVMTCk7CgogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkFwcGx5IiwgXygiJkZpbHRlciIpKTsKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJDYW5jZWwiLCBfKCImQ2FuY2VsIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkRpciIsIF8oIkRpcmVjdG9yaWVzIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkZpbHRlckxhYmVsIiwgXygiRmlsdGVyIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIkhlbHAiLCBfKCImSGVscCIpKTsKICAgIHNldF9wcmVkZWZpbmVkX2xhYmVsKGRpYWxvZ193Z3QsICJJdGVtcyIsIF8oIkZpbGVzIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIk9LIiwgXygiJk9LIikpOwogICAgc2V0X3ByZWRlZmluZWRfbGFiZWwoZGlhbG9nX3dndCwgIlNlbGVjdGlvbiIsIF8oIlNlbGVjdGlvbiIpKTsKCiAgICAvKiBUaGlzIGlzIHRvIHNhdmUgdXMgZnJvbSBzaWxseSBleHRlcm5hbCBzZXR0aW5ncyB1c2luZyBub3QgZml4ZWQgd2l0aAogICAgICogZm9udHMgZm9yIGZpbGUgc2VsZWN0aW9uLgogICAgICovCiAgICBzZXRfcHJlZGVmaW5lZF9mb250bGlzdChkaWFsb2dfd2d0LCAiRGlyTGlzdFNXLkRpckxpc3QiKTsKICAgIHNldF9wcmVkZWZpbmVkX2ZvbnRsaXN0KGRpYWxvZ193Z3QsICJJdGVtc0xpc3RTVy5JdGVtc0xpc3QiKTsKCiAgICBndWlfbW90aWZfbWVudV9jb2xvcnMoZGlhbG9nX3dndCk7CiAgICBpZiAoZ3VpLnNjcm9sbF9iZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJWHRWYVNldFZhbHVlcyhkaWFsb2dfd2d0LCBYbU50cm91Z2hDb2xvciwgZ3VpLnNjcm9sbF9iZ19waXhlbCwgTlVMTCk7CgogICAgWHRBZGRDYWxsYmFjayhkaWFsb2dfd2d0LCBYbU5va0NhbGxiYWNrLCBEaWFsb2dBY2NlcHRDQiwgKFh0UG9pbnRlcikwKTsKICAgIFh0QWRkQ2FsbGJhY2soZGlhbG9nX3dndCwgWG1OY2FuY2VsQ2FsbGJhY2ssIERpYWxvZ0NhbmNlbENCLCAoWHRQb2ludGVyKTApOwogICAgLyogV2UgaGF2ZSBubyBoZWxwIGluIHRoaXMgd2luZG93LCBzbyBoaWRlIGhlbHAgYnV0dG9uICovCiAgICBYdFVubWFuYWdlQ2hpbGQoWG1GaWxlU2VsZWN0aW9uQm94R2V0Q2hpbGQoZGlhbG9nX3dndCwKCQkJCQkodW5zaWduZWQgY2hhcilYbURJQUxPR19IRUxQX0JVVFRPTikpOwoKICAgIG1hbmFnZV9jZW50ZXJlZChkaWFsb2dfd2d0KTsKICAgIGFjdGl2YXRlX2RpYWxvZ19tbmVtb25pY3MoZGlhbG9nX3dndCk7CgogICAgLyogc2l0IGluIGEgbG9vcCB1bnRpbCB0aGUgZGlhbG9nIGJveCBoYXMgZ29uZSBhd2F5ICovCiAgICBkbwogICAgewoJWHRBcHBQcm9jZXNzRXZlbnQoWHRXaWRnZXRUb0FwcGxpY2F0aW9uQ29udGV4dChkaWFsb2dfd2d0KSwKCSAgICAoWHRJbnB1dE1hc2spWHRJTUFsbCk7CiAgICB9IHdoaWxlIChYdElzTWFuYWdlZChkaWFsb2dfd2d0KSk7CgogICAgc3VwcHJlc3NfZGlhbG9nX21uZW1vbmljcyhkaWFsb2dfd2d0KTsKICAgIFh0RGVzdHJveVdpZGdldChkaWFsb2dfd2d0KTsKICAgIHZpbV9mcmVlKHRvZnJlZSk7CgogICAgaWYgKGJyb3dzZV9mbmFtZSA9PSBOVUxMKQoJcmV0dXJuIE5VTEw7CiAgICByZXR1cm4gdmltX3N0cnNhdmUoKGNoYXJfdSAqKWJyb3dzZV9mbmFtZSk7Cn0KCi8qCiAqIFRoZSBjb2RlIGJlbG93IHdhcyBvcmlnaW5hbGx5IHRha2VuIGZyb20KICoJL3Vzci9leGFtcGxlcy9tb3RpZi94bXNhbXBsZXJzL3htZWRpdG9yLmMKICogb24gRGlnaXRhbCBVbml4IDQuMGQsIGJ1dCBoZWF2aWx5IG1vZGlmaWVkLgogKi8KCi8qCiAqIFByb2Nlc3MgY2FsbGJhY2sgZnJvbSBEaWFsb2cgY2FuY2VsIGFjdGlvbnMuCiAqLwogICAgc3RhdGljIHZvaWQKRGlhbG9nQ2FuY2VsQ0IodywgY2xpZW50X2RhdGEsIGNhbGxfZGF0YSkKICAgIFdpZGdldAl3IFVOVVNFRDsJCS8qICB3aWRnZXQgaWQJCSovCiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGEgVU5VU0VEOwkvKiAgZGF0YSBmcm9tIGFwcGxpY2F0aW9uICAgKi8KICAgIFh0UG9pbnRlcgljYWxsX2RhdGEgVU5VU0VEOwkvKiAgZGF0YSBmcm9tIHdpZGdldCBjbGFzcyAgKi8KewogICAgaWYgKGJyb3dzZV9mbmFtZSAhPSBOVUxMKQogICAgewoJWHRGcmVlKGJyb3dzZV9mbmFtZSk7Cglicm93c2VfZm5hbWUgPSBOVUxMOwogICAgfQogICAgWHRVbm1hbmFnZUNoaWxkKGRpYWxvZ193Z3QpOwp9CgovKgogKiBQcm9jZXNzIGNhbGxiYWNrIGZyb20gRGlhbG9nIGFjdGlvbnMuCiAqLwogICAgc3RhdGljIHZvaWQKRGlhbG9nQWNjZXB0Q0IodywgY2xpZW50X2RhdGEsIGNhbGxfZGF0YSkKICAgIFdpZGdldAl3IFVOVVNFRDsJCS8qICB3aWRnZXQgaWQJCSovCiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGEgVU5VU0VEOwkvKiAgZGF0YSBmcm9tIGFwcGxpY2F0aW9uICAgKi8KICAgIFh0UG9pbnRlcgljYWxsX2RhdGE7CQkvKiAgZGF0YSBmcm9tIHdpZGdldCBjbGFzcyAgKi8KewogICAgWG1GaWxlU2VsZWN0aW9uQm94Q2FsbGJhY2tTdHJ1Y3QgKmZjYjsKCiAgICBpZiAoYnJvd3NlX2ZuYW1lICE9IE5VTEwpCiAgICB7CglYdEZyZWUoYnJvd3NlX2ZuYW1lKTsKCWJyb3dzZV9mbmFtZSA9IE5VTEw7CiAgICB9CiAgICBmY2IgPSAoWG1GaWxlU2VsZWN0aW9uQm94Q2FsbGJhY2tTdHJ1Y3QgKiljYWxsX2RhdGE7CgogICAgLyogZ2V0IHRoZSBmaWxlbmFtZSBmcm9tIHRoZSBmaWxlIHNlbGVjdGlvbiBib3ggKi8KICAgIFhtU3RyaW5nR2V0THRvUihmY2ItPnZhbHVlLCBjaGFyc2V0LCAmYnJvd3NlX2ZuYW1lKTsKCiAgICAvKiBwb3Bkb3duIHRoZSBmaWxlIHNlbGVjdGlvbiBib3ggKi8KICAgIFh0VW5tYW5hZ2VDaGlsZChkaWFsb2dfd2d0KTsKfQoKI2VuZGlmIC8qIEZFQVRfQlJPV1NFICovCgojaWYgZGVmaW5lZChGRUFUX0dVSV9ESUFMT0cpIHx8IGRlZmluZWQoUFJPVE8pCgpzdGF0aWMgaW50CWRpYWxvZ1N0YXR1czsKCnN0YXRpYyB2b2lkIGtleWhpdF9jYWxsYmFjayBfX0FSR1MoKFdpZGdldCB3LCBYdFBvaW50ZXIgY2xpZW50X2RhdGEsIFhFdmVudCAqZXZlbnQsIEJvb2xlYW4gKmNvbnQpKTsKc3RhdGljIHZvaWQgYnV0cHJvYyBfX0FSR1MoKFdpZGdldCB3LCBYdFBvaW50ZXIgY2xpZW50X2RhdGEsIFh0UG9pbnRlciBjYWxsX2RhdGEpKTsKCi8qCiAqIENhbGxiYWNrIGZ1bmN0aW9uIGZvciB0aGUgdGV4dGZpZWxkLiAgV2hlbiBDUiBpcyBoaXQgdGhpcyB3b3JrcyBsaWtlCiAqIGhpdHRpbmcgdGhlICJPSyIgYnV0dG9uLCBFU0MgbGlrZSAiQ2FuY2VsIi4KICovCiAgICBzdGF0aWMgdm9pZAprZXloaXRfY2FsbGJhY2sodywgY2xpZW50X2RhdGEsIGV2ZW50LCBjb250KQogICAgV2lkZ2V0CQl3OwogICAgWHRQb2ludGVyCQljbGllbnRfZGF0YSBVTlVTRUQ7CiAgICBYRXZlbnQJCSpldmVudDsKICAgIEJvb2xlYW4JCSpjb250IFVOVVNFRDsKewogICAgY2hhcglidWZbMl07CiAgICBLZXlTeW0Ja2V5X3N5bTsKCiAgICBpZiAoWExvb2t1cFN0cmluZygmKGV2ZW50LT54a2V5KSwgYnVmLCAyLCAma2V5X3N5bSwgTlVMTCkgPT0gMSkKICAgIHsKCWlmICgqYnVmID09IENBUikKCSAgICBkaWFsb2dTdGF0dXMgPSAxOwoJZWxzZSBpZiAoKmJ1ZiA9PSBFU0MpCgkgICAgZGlhbG9nU3RhdHVzID0gMjsKICAgIH0KICAgIGlmICgoa2V5X3N5bSA9PSBYS19MZWZ0IHx8IGtleV9zeW0gPT0gWEtfUmlnaHQpCgkgICAgJiYgIShldmVudC0+eGtleS5zdGF0ZSAmIFNoaWZ0TWFzaykpCglYbVRleHRGaWVsZENsZWFyU2VsZWN0aW9uKHcsIFh0TGFzdFRpbWVzdGFtcFByb2Nlc3NlZChndWkuZHB5KSk7Cn0KCiAgICBzdGF0aWMgdm9pZApidXRwcm9jKHcsIGNsaWVudF9kYXRhLCBjYWxsX2RhdGEpCiAgICBXaWRnZXQJdyBVTlVTRUQ7CiAgICBYdFBvaW50ZXIJY2xpZW50X2RhdGE7CiAgICBYdFBvaW50ZXIJY2FsbF9kYXRhIFVOVVNFRDsKewogICAgZGlhbG9nU3RhdHVzID0gKGludCkobG9uZyljbGllbnRfZGF0YSArIDE7Cn0KCiNpZmRlZiBIQVZFX1hQTQoKc3RhdGljIFdpZGdldCBjcmVhdGVfcGl4bWFwX2xhYmVsKFdpZGdldCBwYXJlbnQsIFN0cmluZyBuYW1lLCBjaGFyICoqZGF0YSwgQXJnTGlzdCBhcmdzLCBDYXJkaW5hbCBhcmcpOwoKICAgIHN0YXRpYyBXaWRnZXQKY3JlYXRlX3BpeG1hcF9sYWJlbChwYXJlbnQsIG5hbWUsIGRhdGEsIGFyZ3MsIGFyZykKICAgIFdpZGdldAlwYXJlbnQ7CiAgICBTdHJpbmcJbmFtZTsKICAgIGNoYXIJKipkYXRhOwogICAgQXJnTGlzdAlhcmdzOwogICAgQ2FyZGluYWwJYXJnOwp7CiAgICBXaWRnZXQJCWxhYmVsOwogICAgRGlzcGxheQkJKmRzcDsKICAgIFNjcmVlbgkJKnNjcjsKICAgIGludAkJCWRlcHRoOwogICAgUGl4bWFwCQlwaXhtYXAgPSAwOwogICAgWHBtQXR0cmlidXRlcwlhdHRyOwogICAgQm9vbGVhbgkJcnM7CiAgICBYcG1Db2xvclN5bWJvbAljb2xvcls1XSA9CiAgICB7Cgl7Im5vbmUiLCBOVUxMLCAwfSwKCXsiaWNvbkNvbG9yMSIsIE5VTEwsIDB9LAoJeyJib3R0b21TaGFkb3dDb2xvciIsIE5VTEwsIDB9LAoJeyJ0b3BTaGFkb3dDb2xvciIsIE5VTEwsIDB9LAoJeyJzZWxlY3RDb2xvciIsIE5VTEwsIDB9CiAgICB9OwoKICAgIGxhYmVsID0gWG1DcmVhdGVMYWJlbEdhZGdldChwYXJlbnQsIG5hbWUsIGFyZ3MsIGFyZyk7CgogICAgLyoKICAgICAqIFdlIG5lZWQgdG8gYmUgY2FyZWZ1bCBoZXJlLCBzaW5jZSBpbiBjYXNlIG9mIGdhZGdldHMsIHRoZXJlIGlzCiAgICAgKiBubyB3YXkgdG8gZ2V0IHRoZSBiYWNrZ3JvdW5kIGNvbG9yIGRpcmVjdGx5IGZyb20gdGhlIHdpZGdldCBpdHNlbGYuCiAgICAgKiBJbiBzdWNoIGNhc2VzIHdlIGdldCBpdCBmcm9tIFRoZSBDb3JlIHBhcnQgb2YgaGlzIHBhcmVudCBpbnN0ZWFkLgogICAgICovCiAgICBkc3AgPSBYdERpc3BsYXlPZk9iamVjdChsYWJlbCk7CiAgICBzY3IgPSBYdFNjcmVlbk9mT2JqZWN0KGxhYmVsKTsKICAgIFh0VmFHZXRWYWx1ZXMoWHRJc1N1YmNsYXNzKGxhYmVsLCBjb3JlV2lkZ2V0Q2xhc3MpCgkgICAgPyAgbGFiZWwgOiBYdFBhcmVudChsYWJlbCksCgkJICBYbU5kZXB0aCwgJmRlcHRoLAoJCSAgWG1OYmFja2dyb3VuZCwgJmNvbG9yWzBdLnBpeGVsLAoJCSAgWG1OZm9yZWdyb3VuZCwgJmNvbG9yWzFdLnBpeGVsLAoJCSAgWG1OYm90dG9tU2hhZG93Q29sb3IsICZjb2xvclsyXS5waXhlbCwKCQkgIFhtTnRvcFNoYWRvd0NvbG9yLCAmY29sb3JbM10ucGl4ZWwsCgkJICBYbU5oaWdobGlnaHQsICZjb2xvcls0XS5waXhlbCwKCQkgIE5VTEwpOwoKICAgIGF0dHIudmFsdWVtYXNrID0gWHBtQ29sb3JTeW1ib2xzIHwgWHBtQ2xvc2VuZXNzIHwgWHBtRGVwdGg7CiAgICBhdHRyLmNvbG9yc3ltYm9scyA9IGNvbG9yOwogICAgYXR0ci5udW1zeW1ib2xzID0gNTsKICAgIGF0dHIuY2xvc2VuZXNzID0gNjU1MzU7CiAgICBhdHRyLmRlcHRoID0gZGVwdGg7CiAgICBYcG1DcmVhdGVQaXhtYXBGcm9tRGF0YShkc3AsIFJvb3RXaW5kb3dPZlNjcmVlbihzY3IpLAoJCSAgICBkYXRhLCAmcGl4bWFwLCBOVUxMLCAmYXR0cik7CgogICAgWHRWYUdldFZhbHVlcyhsYWJlbCwgWG1OcmVjb21wdXRlU2l6ZSwgJnJzLCBOVUxMKTsKICAgIFh0VmFTZXRWYWx1ZXMobGFiZWwsIFhtTnJlY29tcHV0ZVNpemUsIFRydWUsIE5VTEwpOwogICAgWHRWYVNldFZhbHVlcyhsYWJlbCwKCSAgICBYbU5sYWJlbFR5cGUsIFhtUElYTUFQLAoJICAgIFhtTmxhYmVsUGl4bWFwLCBwaXhtYXAsCgkgICAgTlVMTCk7CiAgICBYdFZhU2V0VmFsdWVzKGxhYmVsLCBYbU5yZWNvbXB1dGVTaXplLCBycywgTlVMTCk7CgogICAgcmV0dXJuIGxhYmVsOwp9CiNlbmRpZgoKICAgIGludApndWlfbWNoX2RpYWxvZyh0eXBlLCB0aXRsZSwgbWVzc2FnZSwgYnV0dG9uX25hbWVzLCBkZmx0YnV0dG9uLCB0ZXh0ZmllbGQsIGV4X2NtZCkKICAgIGludAkJdHlwZSBVTlVTRUQ7CiAgICBjaGFyX3UJKnRpdGxlOwogICAgY2hhcl91CSptZXNzYWdlOwogICAgY2hhcl91CSpidXR0b25fbmFtZXM7CiAgICBpbnQJCWRmbHRidXR0b247CiAgICBjaGFyX3UJKnRleHRmaWVsZDsJCS8qIGJ1ZmZlciBvZiBzaXplIElPU0laRSAqLwogICAgaW50CQlleF9jbWQgVU5VU0VEOwp7CiAgICBjaGFyX3UJCSpidXRzOwogICAgY2hhcl91CQkqcCwgKm5leHQ7CiAgICBYdEFwcENvbnRleHQJYXBwOwogICAgWG1TdHJpbmcJCWxhYmVsOwogICAgaW50CQkJYnV0Y291bnQ7CiAgICBXaWRnZXQJCXc7CiAgICBXaWRnZXQJCWRpYWxvZ2Zvcm0gPSBOVUxMOwogICAgV2lkZ2V0CQlmb3JtID0gTlVMTDsKICAgIFdpZGdldAkJZGlhbG9ndGV4dGZpZWxkID0gTlVMTDsKICAgIFdpZGdldAkJKmJ1dHRvbnM7CiAgICBXaWRnZXQJCXNlcF9mb3JtID0gTlVMTDsKICAgIEJvb2xlYW4JCXZlcnRpY2FsOwogICAgV2lkZ2V0CQlzZXBhcmF0b3IgPSBOVUxMOwogICAgaW50CQkJbjsKICAgIEFyZwkJCWFyZ3NbNl07CiNpZmRlZiBIQVZFX1hQTQogICAgY2hhcgkJKippY29uX2RhdGEgPSBOVUxMOwogICAgV2lkZ2V0CQlkaWFsb2dwaXhtYXAgPSBOVUxMOwojZW5kaWYKCiAgICBpZiAodGl0bGUgPT0gTlVMTCkKCXRpdGxlID0gKGNoYXJfdSAqKV8oIlZpbSBkaWFsb2ciKTsKCiAgICAvKiBpZiBvdXIgcG9pbnRlciBpcyBjdXJyZW50bHkgaGlkZGVuLCB0aGVuIHdlIHNob3VsZCBzaG93IGl0LiAqLwogICAgZ3VpX21jaF9tb3VzZWhpZGUoRkFMU0UpOwoKICAgIGRpYWxvZ2Zvcm0gPSBYbUNyZWF0ZUZvcm1EaWFsb2codmltU2hlbGwsIChjaGFyICopImRpYWxvZyIsIE5VTEwsIDApOwoKICAgIC8qIENoZWNrICd2JyBmbGFnIGluICdndWlvcHRpb25zJzogdmVydGljYWwgYnV0dG9uIHBsYWNlbWVudC4gKi8KICAgIHZlcnRpY2FsID0gKHZpbV9zdHJjaHIocF9nbywgR09fVkVSVElDQUwpICE9IE5VTEwpOwoKICAgIC8qIFNldCB0aGUgdGl0bGUgb2YgdGhlIERpYWxvZyB3aW5kb3cgKi8KICAgIGxhYmVsID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoKGNoYXIgKil0aXRsZSk7CiAgICBpZiAobGFiZWwgPT0gTlVMTCkKCXJldHVybiAtMTsKICAgIFh0VmFTZXRWYWx1ZXMoZGlhbG9nZm9ybSwKCSAgICBYbU5kaWFsb2dUaXRsZSwgbGFiZWwsCgkgICAgWG1OaG9yaXpvbnRhbFNwYWNpbmcsIDQsCgkgICAgWG1OdmVydGljYWxTcGFjaW5nLCB2ZXJ0aWNhbCA/IDAgOiA0LAoJICAgIE5VTEwpOwogICAgWG1TdHJpbmdGcmVlKGxhYmVsKTsKCiAgICAvKiBtYWtlIGEgY29weSwgc28gdGhhdCB3ZSBjYW4gaW5zZXJ0IE5VTHMgKi8KICAgIGJ1dHMgPSB2aW1fc3Ryc2F2ZShidXR0b25fbmFtZXMpOwogICAgaWYgKGJ1dHMgPT0gTlVMTCkKCXJldHVybiAtMTsKCiAgICAvKiBDb3VudCB0aGUgbnVtYmVyIG9mIGJ1dHRvbnMgYW5kIGFsbG9jYXRlIGJ1dHRvbnNbXS4gKi8KICAgIGJ1dGNvdW50ID0gMTsKICAgIGZvciAocCA9IGJ1dHM7ICpwOyArK3ApCglpZiAoKnAgPT0gRExHX0JVVFRPTl9TRVApCgkgICAgKytidXRjb3VudDsKICAgIGJ1dHRvbnMgPSAoV2lkZ2V0ICopYWxsb2MoKHVuc2lnbmVkKShidXRjb3VudCAqIHNpemVvZihXaWRnZXQpKSk7CiAgICBpZiAoYnV0dG9ucyA9PSBOVUxMKQogICAgewoJdmltX2ZyZWUoYnV0cyk7CglyZXR1cm4gLTE7CiAgICB9CgogICAgLyoKICAgICAqIENyZWF0ZSB0aGUgYnV0dG9ucy4KICAgICAqLwogICAgc2VwX2Zvcm0gPSAoV2lkZ2V0KSAwOwogICAgcCA9IGJ1dHM7CiAgICBmb3IgKGJ1dGNvdW50ID0gMDsgKnA7ICsrYnV0Y291bnQpCiAgICB7CglLZXlTeW0gbW5lbW9uaWMgPSBOVUw7CgoJZm9yIChuZXh0ID0gcDsgKm5leHQ7ICsrbmV4dCkKCXsKCSAgICBpZiAoKm5leHQgPT0gRExHX0hPVEtFWV9DSEFSKQoJICAgIHsKCQlpbnQgbGVuID0gU1RSTEVOKG5leHQpOwoKCQlpZiAobGVuID4gMCkKCQl7CgkJICAgIG1jaF9tZW1tb3ZlKG5leHQsIG5leHQgKyAxLCBsZW4pOwoJCSAgICBtbmVtb25pYyA9IG5leHRbMF07CgkJfQoJICAgIH0KCSAgICBpZiAoKm5leHQgPT0gRExHX0JVVFRPTl9TRVApCgkgICAgewoJCSpuZXh0KysgPSBOVUw7CgkJYnJlYWs7CgkgICAgfQoJfQoJbGFiZWwgPSBYbVN0cmluZ0NyZWF0ZShfKChjaGFyICopcCksIFNUUklOR19UQUcpOwoJaWYgKGxhYmVsID09IE5VTEwpCgkgICAgYnJlYWs7CgoJYnV0dG9uc1tidXRjb3VudF0gPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgiYnV0dG9uIiwKCQl4bVB1c2hCdXR0b25XaWRnZXRDbGFzcywgZGlhbG9nZm9ybSwKCQlYbU5sYWJlbFN0cmluZywgbGFiZWwsCgkJWG1ObW5lbW9uaWMsIG1uZW1vbmljLAoJCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1OYm90dG9tT2Zmc2V0LCA0LAoJCVhtTnNob3dBc0RlZmF1bHQsIGJ1dGNvdW50ID09IGRmbHRidXR0b24gLSAxLAoJCVhtTmRlZmF1bHRCdXR0b25TaGFkb3dUaGlja25lc3MsIDEsCgkJTlVMTCk7CglYbVN0cmluZ0ZyZWUobGFiZWwpOwoJZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoYnV0dG9uc1tidXRjb3VudF0pOwoKCS8qIExheW91dCBwcm9wZXJseS4gKi8KCglpZiAoYnV0Y291bnQgPiAwKQoJewoJICAgIGlmICh2ZXJ0aWNhbCkKCQlYdFZhU2V0VmFsdWVzKGJ1dHRvbnNbYnV0Y291bnRdLAoJCQlYbU50b3BXaWRnZXQsIGJ1dHRvbnNbYnV0Y291bnQgLSAxXSwKCQkJTlVMTCk7CgkgICAgZWxzZQoJICAgIHsKCQlpZiAoKm5leHQgPT0gTlVMKQoJCXsKCQkgICAgWHRWYVNldFZhbHVlcyhidXR0b25zW2J1dGNvdW50XSwKCQkJICAgIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJICAgIFhtTnJpZ2h0T2Zmc2V0LCA0LAoJCQkgICAgTlVMTCk7CgoJCSAgICAvKiBmaWxsIGluIGEgZm9ybSBhcyBpbnZpc2libGUgc2VwYXJhdG9yICovCgkJICAgIHNlcF9mb3JtID0gWHRWYUNyZWF0ZVdpZGdldCgic2VwYXJhdG9yRm9ybSIsCgkJCSAgICB4bUZvcm1XaWRnZXRDbGFzcywJZGlhbG9nZm9ybSwKCQkJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICBYbU5sZWZ0V2lkZ2V0LCBidXR0b25zW2J1dGNvdW50IC0gMV0sCgkJCSAgICBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgIFhtTnJpZ2h0V2lkZ2V0LCBidXR0b25zW2J1dGNvdW50XSwKCQkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCSAgICBYbU5ib3R0b21PZmZzZXQsIDQsCgkJCSAgICBOVUxMKTsKCQkgICAgWHRNYW5hZ2VDaGlsZChzZXBfZm9ybSk7CgkJfQoJCWVsc2UKCQl7CgkJICAgIFh0VmFTZXRWYWx1ZXMoYnV0dG9uc1tidXRjb3VudF0sCgkJCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgWG1ObGVmdFdpZGdldCwgYnV0dG9uc1tidXRjb3VudCAtIDFdLAoJCQkgICAgTlVMTCk7CgkJfQoJICAgIH0KCX0KCWVsc2UgaWYgKCF2ZXJ0aWNhbCkKCXsKCSAgICBpZiAoKm5leHQgPT0gTlVMKQoJICAgIHsKCQlYdFZhU2V0VmFsdWVzKGJ1dHRvbnNbMF0sCgkJCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJWG1OcmlnaHRPZmZzZXQsIDQsCgkJCU5VTEwpOwoKCQkvKiBmaWxsIGluIGEgZm9ybSBhcyBpbnZpc2libGUgc2VwYXJhdG9yICovCgkJc2VwX2Zvcm0gPSBYdFZhQ3JlYXRlV2lkZ2V0KCJzZXBhcmF0b3JGb3JtIiwKCQkJeG1Gb3JtV2lkZ2V0Q2xhc3MsIGRpYWxvZ2Zvcm0sCgkJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCQlYbU5sZWZ0T2Zmc2V0LCA0LAoJCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJWG1OcmlnaHRXaWRnZXQsIGJ1dHRvbnNbMF0sCgkJCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCVhtTmJvdHRvbU9mZnNldCwgNCwKCQkJTlVMTCk7CgkJWHRNYW5hZ2VDaGlsZChzZXBfZm9ybSk7CgkgICAgfQoJICAgIGVsc2UKCQlYdFZhU2V0VmFsdWVzKGJ1dHRvbnNbMF0sCgkJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCQlYbU5sZWZ0T2Zmc2V0LCA0LAoJCQlOVUxMKTsKCX0KCglYdEFkZENhbGxiYWNrKGJ1dHRvbnNbYnV0Y291bnRdLCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCQkgIChYdENhbGxiYWNrUHJvYylidXRwcm9jLCAoWHRQb2ludGVyKShsb25nKWJ1dGNvdW50KTsKCXAgPSBuZXh0OwogICAgfQogICAgdmltX2ZyZWUoYnV0cyk7CgogICAgc2VwYXJhdG9yID0gKFdpZGdldCkgMDsKICAgIGlmIChidXRjb3VudCA+IDApCiAgICB7CgkvKiBDcmVhdGUgdGhlIHNlcGFyYXRvciBmb3IgYmVhdXR5LiAqLwoJbiA9IDA7CglYdFNldEFyZyhhcmdzW25dLCBYbU5vcmllbnRhdGlvbiwgWG1IT1JJWk9OVEFMKTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VUKTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tV2lkZ2V0LCBidXR0b25zWzBdKTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tT2Zmc2V0LCA0KTsgbisrOwoJWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CglYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CglzZXBhcmF0b3IgPSBYbUNyZWF0ZVNlcGFyYXRvckdhZGdldChkaWFsb2dmb3JtLCAic2VwYXJhdG9yIiwgYXJncywgbik7CglYdE1hbmFnZUNoaWxkKHNlcGFyYXRvcik7CiAgICB9CgogICAgaWYgKHRleHRmaWVsZCAhPSBOVUxMKQogICAgewoJZGlhbG9ndGV4dGZpZWxkID0gWHRWYUNyZWF0ZVdpZGdldCgidGV4dEZpZWxkIiwKCQl4bVRleHRGaWVsZFdpZGdldENsYXNzLCBkaWFsb2dmb3JtLAoJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlOVUxMKTsKCWlmIChidXRjb3VudCA+IDApCgkgICAgWHRWYVNldFZhbHVlcyhkaWFsb2d0ZXh0ZmllbGQsCgkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkgICAgWG1OYm90dG9tV2lkZ2V0LCBzZXBhcmF0b3IsCgkJICAgIE5VTEwpOwoJZWxzZQoJICAgIFh0VmFTZXRWYWx1ZXMoZGlhbG9ndGV4dGZpZWxkLAoJCSAgICBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCSAgICBOVUxMKTsKCglzZXRfZm9udGxpc3QoZGlhbG9ndGV4dGZpZWxkKTsKCVhtVGV4dEZpZWxkU2V0U3RyaW5nKGRpYWxvZ3RleHRmaWVsZCwgKGNoYXIgKil0ZXh0ZmllbGQpOwoJWHRNYW5hZ2VDaGlsZChkaWFsb2d0ZXh0ZmllbGQpOwoJWHRBZGRFdmVudEhhbmRsZXIoZGlhbG9ndGV4dGZpZWxkLCBLZXlQcmVzc01hc2ssIEZhbHNlLAoJCQkgICAgKFh0RXZlbnRIYW5kbGVyKWtleWhpdF9jYWxsYmFjaywgKFh0UG9pbnRlcilOVUxMKTsKICAgIH0KCiAgICAvKiBGb3JtIGhvbGRpbmcgYm90aCBtZXNzYWdlIGFuZCBwaXhtYXAgbGFiZWxzICovCiAgICBmb3JtID0gWHRWYUNyZWF0ZVdpZGdldCgic2VwYXJhdG9yRm9ybSIsCgkgICAgeG1Gb3JtV2lkZ2V0Q2xhc3MsIGRpYWxvZ2Zvcm0sCgkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgTlVMTCk7CiAgICBYdE1hbmFnZUNoaWxkKGZvcm0pOwoKI2lmZGVmIEhBVkVfWFBNCiAgICAvKiBBZGQgYSBwaXhtYXAsIGxlZnQgb2YgdGhlIG1lc3NhZ2UuICovCiAgICBzd2l0Y2ggKHR5cGUpCiAgICB7CgljYXNlIFZJTV9HRU5FUklDOgoJICAgIGljb25fZGF0YSA9IGdlbmVyaWNfeHBtOwoJICAgIGJyZWFrOwoJY2FzZSBWSU1fRVJST1I6CgkgICAgaWNvbl9kYXRhID0gZXJyb3JfeHBtOwoJICAgIGJyZWFrOwoJY2FzZSBWSU1fV0FSTklORzoKCSAgICBpY29uX2RhdGEgPSBhbGVydF94cG07CgkgICAgYnJlYWs7CgljYXNlIFZJTV9JTkZPOgoJICAgIGljb25fZGF0YSA9IGluZm9feHBtOwoJICAgIGJyZWFrOwoJY2FzZSBWSU1fUVVFU1RJT046CgkgICAgaWNvbl9kYXRhID0gcXVlc3RfeHBtOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBpY29uX2RhdGEgPSBnZW5lcmljX3hwbTsKICAgIH0KCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU50b3BPZmZzZXQsIDgpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNKTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OYm90dG9tT2Zmc2V0LCA4KTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5sZWZ0T2Zmc2V0LCA4KTsgbisrOwoKICAgIGRpYWxvZ3BpeG1hcCA9IGNyZWF0ZV9waXhtYXBfbGFiZWwoZm9ybSwgImRpYWxvZ1BpeG1hcCIsCgkgICAgaWNvbl9kYXRhLCBhcmdzLCBuKTsKICAgIFh0TWFuYWdlQ2hpbGQoZGlhbG9ncGl4bWFwKTsKI2VuZGlmCgogICAgLyogQ3JlYXRlIHRoZSBkaWFsb2cgbWVzc2FnZS4KICAgICAqIFNpbmNlIExlc3NUaWYgaXMgYXBwYXJlbnRseSBoYXZpbmcgcHJvYmxlbXMgd2l0aCB0aGUgY3JlYXRpb24gb2YKICAgICAqIHByb3Blcmx5IGxvY2FsaXplZCBzdHJpbmcsIHdlIHVzZSBMdG9SIGhlcmUuIFRoZSBzeW1wdG9tIGlzIHRoYXQgdGhlCiAgICAgKiBzdHJpbmcgc2lsbCBub3Qgc2hvdyBwcm9wZXJseSBpbiBtdWx0aXBsZSBsaW5lcyBhcyBpdCBkb2VzIGluIG5hdGl2ZQogICAgICogTW90aWYuCiAgICAgKi8KICAgIGxhYmVsID0gWG1TdHJpbmdDcmVhdGVMdG9SKChjaGFyICopbWVzc2FnZSwgU1RSSU5HX1RBRyk7CiAgICBpZiAobGFiZWwgPT0gTlVMTCkKCXJldHVybiAtMTsKICAgIHcgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgiZGlhbG9nTWVzc2FnZSIsCgkJCQl4bUxhYmVsR2FkZ2V0Q2xhc3MsIGZvcm0sCgkJCQlYbU5sYWJlbFN0cmluZywgbGFiZWwsCgkJCQlYbU5hbGlnbm1lbnQsIFhtQUxJR05NRU5UX0JFR0lOTklORywKCQkJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCQlYbU50b3BPZmZzZXQsIDgsCiNpZmRlZiBIQVZFX1hQTQoJCQkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJCVhtTmxlZnRXaWRnZXQsIGRpYWxvZ3BpeG1hcCwKI2Vsc2UKCQkJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAojZW5kaWYKCQkJCVhtTmxlZnRPZmZzZXQsIDgsCgkJCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCQlYbU5yaWdodE9mZnNldCwgOCwKCQkJCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJCQlYbU5ib3R0b21PZmZzZXQsIDgsCgkJCQlOVUxMKTsKICAgIFhtU3RyaW5nRnJlZShsYWJlbCk7CiAgICBzZXRfZm9udGxpc3Qodyk7CgogICAgaWYgKHRleHRmaWVsZCAhPSBOVUxMKQogICAgewoJWHRWYVNldFZhbHVlcyhmb3JtLAoJCVhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU5ib3R0b21XaWRnZXQsIGRpYWxvZ3RleHRmaWVsZCwKCQlOVUxMKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWlmIChidXRjb3VudCA+IDApCgkgICAgWHRWYVNldFZhbHVlcyhmb3JtLAoJCSAgICBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJICAgIFhtTmJvdHRvbVdpZGdldCwgc2VwYXJhdG9yLAoJCSAgICBOVUxMKTsKCWVsc2UKCSAgICBYdFZhU2V0VmFsdWVzKGZvcm0sCgkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIE5VTEwpOwogICAgfQoKICAgIGlmIChkZmx0YnV0dG9uIDwgMSkKCWRmbHRidXR0b24gPSAxOwogICAgaWYgKGRmbHRidXR0b24gPiBidXRjb3VudCkKCWRmbHRidXR0b24gPSBidXRjb3VudDsKICAgIFh0VmFTZXRWYWx1ZXMoZGlhbG9nZm9ybSwKCSAgICBYbU5kZWZhdWx0QnV0dG9uLCBidXR0b25zW2RmbHRidXR0b24gLSAxXSwgTlVMTCk7CiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwpCglYdFZhU2V0VmFsdWVzKGRpYWxvZ2Zvcm0sIFhtTmluaXRpYWxGb2N1cywgZGlhbG9ndGV4dGZpZWxkLCBOVUxMKTsKICAgIGVsc2UKCVh0VmFTZXRWYWx1ZXMoZGlhbG9nZm9ybSwgWG1OaW5pdGlhbEZvY3VzLCBidXR0b25zW2RmbHRidXR0b24gLSAxXSwKCQkJCQkJCQkJTlVMTCk7CgogICAgbWFuYWdlX2NlbnRlcmVkKGRpYWxvZ2Zvcm0pOwogICAgYWN0aXZhdGVfZGlhbG9nX21uZW1vbmljcyhkaWFsb2dmb3JtKTsKCiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwgJiYgKnRleHRmaWVsZCAhPSBOVUwpCiAgICB7CgkvKiBUaGlzIG9ubHkgd29ya3MgYWZ0ZXIgdGhlIHRleHRmaWVsZCBoYXMgYmVlbiByZWFsaXNlZC4gKi8KCVhtVGV4dEZpZWxkU2V0U2VsZWN0aW9uKGRpYWxvZ3RleHRmaWVsZCwKCQkJIChYbVRleHRQb3NpdGlvbikwLCAoWG1UZXh0UG9zaXRpb24pU1RSTEVOKHRleHRmaWVsZCksCgkJCQkJICAgWHRMYXN0VGltZXN0YW1wUHJvY2Vzc2VkKGd1aS5kcHkpKTsKCVhtVGV4dEZpZWxkU2V0Q3Vyc29yUG9zaXRpb24oZGlhbG9ndGV4dGZpZWxkLAoJCQkJCSAgIChYbVRleHRQb3NpdGlvbilTVFJMRU4odGV4dGZpZWxkKSk7CiAgICB9CgogICAgYXBwID0gWHRXaWRnZXRUb0FwcGxpY2F0aW9uQ29udGV4dChkaWFsb2dmb3JtKTsKCiAgICAvKiBMb29wIHVudGlsIGEgYnV0dG9uIGlzIHByZXNzZWQgb3IgdGhlIGRpYWxvZyBpcyBraWxsZWQgc29tZWhvdy4gKi8KICAgIGRpYWxvZ1N0YXR1cyA9IC0xOwogICAgZm9yICg7OykKICAgIHsKCVh0QXBwUHJvY2Vzc0V2ZW50KGFwcCwgKFh0SW5wdXRNYXNrKVh0SU1BbGwpOwoJaWYgKGRpYWxvZ1N0YXR1cyA+PSAwIHx8ICFYdElzTWFuYWdlZChkaWFsb2dmb3JtKSkKCSAgICBicmVhazsKICAgIH0KCiAgICB2aW1fZnJlZShidXR0b25zKTsKCiAgICBpZiAodGV4dGZpZWxkICE9IE5VTEwpCiAgICB7CglwID0gKGNoYXJfdSAqKVhtVGV4dEdldFN0cmluZyhkaWFsb2d0ZXh0ZmllbGQpOwoJaWYgKHAgPT0gTlVMTCB8fCBkaWFsb2dTdGF0dXMgPCAwKQoJICAgICp0ZXh0ZmllbGQgPSBOVUw7CgllbHNlCgkgICAgdmltX3N0cm5jcHkodGV4dGZpZWxkLCBwLCBJT1NJWkUgLSAxKTsKCVh0RnJlZSgoY2hhciAqKXApOwogICAgfQoKICAgIHN1cHByZXNzX2RpYWxvZ19tbmVtb25pY3MoZGlhbG9nZm9ybSk7CiAgICBYdERlc3Ryb3lXaWRnZXQoZGlhbG9nZm9ybSk7CgogICAgcmV0dXJuIGRpYWxvZ1N0YXR1czsKfQojZW5kaWYgLyogRkVBVF9HVUlfRElBTE9HICovCgojaWYgZGVmaW5lZChGRUFUX0ZPT1RFUikgfHwgZGVmaW5lZChQUk9UTykKCiAgICBzdGF0aWMgaW50Cmd1aV9tY2hfY29tcHV0ZV9mb290ZXJfaGVpZ2h0KCkKewogICAgRGltZW5zaW9uCWhlaWdodDsJCSAgICAvKiB0b3RhbCBUb29sYmFyIGhlaWdodCAqLwogICAgRGltZW5zaW9uCXRvcDsJCSAgICAvKiBYbU5tYXJnaW5Ub3AgKi8KICAgIERpbWVuc2lvbglib3R0b207CQkgICAgLyogWG1ObWFyZ2luQm90dG9tICovCiAgICBEaW1lbnNpb24Jc2hhZG93OwkJICAgIC8qIFhtTnNoYWRvd1RoaWNrbmVzcyAqLwoKICAgIFh0VmFHZXRWYWx1ZXMoZm9vdGVyLAoJICAgIFhtTmhlaWdodCwgJmhlaWdodCwKCSAgICBYbU5tYXJnaW5Ub3AsICZ0b3AsCgkgICAgWG1ObWFyZ2luQm90dG9tLCAmYm90dG9tLAoJICAgIFhtTnNoYWRvd1RoaWNrbmVzcywgJnNoYWRvdywKCSAgICBOVUxMKTsKCiAgICByZXR1cm4gKGludCkgaGVpZ2h0ICsgdG9wICsgYm90dG9tICsgKHNoYWRvdyA8PCAxKTsKfQoKICAgIHZvaWQKZ3VpX21jaF9lbmFibGVfZm9vdGVyKHNob3dpdCkKICAgIGludAkJc2hvd2l0Owp7CiAgICBpZiAoc2hvd2l0KQogICAgewoJZ3VpLmZvb3Rlcl9oZWlnaHQgPSBndWlfbWNoX2NvbXB1dGVfZm9vdGVyX2hlaWdodCgpOwoJWHRNYW5hZ2VDaGlsZChmb290ZXIpOwogICAgfQogICAgZWxzZQogICAgewoJZ3VpLmZvb3Rlcl9oZWlnaHQgPSAwOwoJWHRVbm1hbmFnZUNoaWxkKGZvb3Rlcik7CiAgICB9CiAgICBYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwgWG1OYm90dG9tT2Zmc2V0LCBndWkuZm9vdGVyX2hlaWdodCwgTlVMTCk7Cn0KCiAgICB2b2lkCmd1aV9tY2hfc2V0X2Zvb3RlcihzKQogICAgY2hhcl91CSpzOwp7CiAgICBYbVN0cmluZwl4bXM7CgogICAgeG1zID0gWG1TdHJpbmdDcmVhdGUoKGNoYXIgKilzLCBTVFJJTkdfVEFHKTsKICAgIGlmICh4bXMgIT0gTlVMTCkKICAgIHsKCVh0VmFTZXRWYWx1ZXMoZm9vdGVyLCBYbU5sYWJlbFN0cmluZywgeG1zLCBOVUxMKTsKCVhtU3RyaW5nRnJlZSh4bXMpOwogICAgfQp9CgojZW5kaWYKCgojaWYgZGVmaW5lZChGRUFUX1RPT0xCQVIpIHx8IGRlZmluZWQoUFJPVE8pCiAgICB2b2lkCmd1aV9tY2hfc2hvd190b29sYmFyKGludCBzaG93aXQpCnsKICAgIENhcmRpbmFsCW51bUNoaWxkcmVuOwkgICAgLyogaG93IG1hbnkgY2hpbGRyZW4gdG9vbEJhciBoYXMgKi8KCiAgICBpZiAodG9vbEJhciA9PSAoV2lkZ2V0KTApCglyZXR1cm47CiAgICBYdFZhR2V0VmFsdWVzKHRvb2xCYXIsIFhtTm51bUNoaWxkcmVuLCAmbnVtQ2hpbGRyZW4sIE5VTEwpOwogICAgaWYgKHNob3dpdCAmJiBudW1DaGlsZHJlbiA+IDApCiAgICB7CgkvKiBBc3N1bWUgdGhhdCB3ZSB3YW50IHRvIHNob3cgdGhlIHRvb2xiYXIgaWYgcF90b29sYmFyIGNvbnRhaW5zCgkgKiB2YWxpZCBvcHRpb24gc2V0dGluZ3MsIHRoZXJlZm9yZSBwX3Rvb2xiYXIgbXVzdCBub3QgYmUgTlVMTC4KCSAqLwoJV2lkZ2V0TGlzdCAgY2hpbGRyZW47CgoJWHRWYUdldFZhbHVlcyh0b29sQmFyLCBYbU5jaGlsZHJlbiwgJmNoaWxkcmVuLCBOVUxMKTsKCXsKCSAgICB2b2lkICAgICgqYWN0aW9uKShCYWxsb29uRXZhbCAqKTsKCSAgICBpbnQJICAgIHRleHQgPSAwOwoKCSAgICBpZiAoc3Ryc3RyKChjb25zdCBjaGFyICopcF90b29sYmFyLCAidG9vbHRpcHMiKSkKCQlhY3Rpb24gPSAmZ3VpX21jaF9lbmFibGVfYmV2YWxfYXJlYTsKCSAgICBlbHNlCgkJYWN0aW9uID0gJmd1aV9tY2hfZGlzYWJsZV9iZXZhbF9hcmVhOwoJICAgIGlmIChzdHJzdHIoKGNvbnN0IGNoYXIgKilwX3Rvb2xiYXIsICJ0ZXh0IikpCgkJdGV4dCA9IDE7CgkgICAgZWxzZSBpZiAoc3Ryc3RyKChjb25zdCBjaGFyICopcF90b29sYmFyLCAiaWNvbnMiKSkKCQl0ZXh0ID0gLTE7CgkgICAgaWYgKHRleHQgIT0gMCkKCSAgICB7CgkJdmltbWVudV9UICAgKnRvb2xiYXI7CgkJdmltbWVudV9UICAgKmN1cjsKCgkJZm9yICh0b29sYmFyID0gcm9vdF9tZW51OyB0b29sYmFyOyB0b29sYmFyID0gdG9vbGJhci0+bmV4dCkKCQkgICAgaWYgKG1lbnVfaXNfdG9vbGJhcih0b29sYmFyLT5kbmFtZSkpCgkJCWJyZWFrOwoJCS8qIEFzc3VtcHRpb246IHRvb2xiYXIgaXMgTlVMTCBpZiB0aGVyZSBpcyBubyB0b29sYmFyLAoJCSAqCSAgICAgICBvdGhlcndpc2UgaXQgY29udGFpbnMgdGhlIHRvb2xiYXIgbWVudSBzdHJ1Y3R1cmUuCgkJICoKCQkgKiBBc3N1bXB0aW9uOiAibnVtQ2hpbGRyZW4iID09IHRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIGxpc3QKCQkgKgkgICAgICAgb2YgaXRlbXMgYmVnaW5uaW5nIHdpdGggdG9vbGJhci0+Y2hpbGRyZW4uCgkJICovCgkJaWYgKHRvb2xiYXIpCgkJewoJCSAgICBmb3IgKGN1ciA9IHRvb2xiYXItPmNoaWxkcmVuOyBjdXI7IGN1ciA9IGN1ci0+bmV4dCkKCQkgICAgewoJCQlBcmcJICAgIGFyZ3NbMV07CgkJCWludAkgICAgbiA9IDA7CgoJCQkvKiBFbmFibGUvRGlzYWJsZSB0b29sdGlwIChPSyB0byBlbmFibGUgd2hpbGUKCQkJICogY3VycmVudGx5IGVuYWJsZWQpLiAqLwoJCQlpZiAoY3VyLT50aXAgIT0gTlVMTCkKCQkJICAgICgqYWN0aW9uKShjdXItPnRpcCk7CgkJCWlmICghbWVudV9pc19zZXBhcmF0b3IoY3VyLT5uYW1lKSkKCQkJewoJCQkgICAgaWYgKHRleHQgPT0gMSB8fCBjdXItPnhwbSA9PSBOVUxMKQoJCQkgICAgewoJCQkJWHRTZXRBcmcoYXJnc1tuXSwgWG1ObGFiZWxUeXBlLCBYbVNUUklORyk7CgkJCQkrK247CgkJCSAgICB9CgkJCSAgICBpZiAoY3VyLT5pZCAhPSBOVUxMKQoJCQkgICAgewoJCQkJWHRVbm1hbmFnZUNoaWxkKGN1ci0+aWQpOwoJCQkJWHRTZXRWYWx1ZXMoY3VyLT5pZCwgYXJncywgbik7CgkJCQlYdE1hbmFnZUNoaWxkKGN1ci0+aWQpOwoJCQkgICAgfQoJCQl9CgkJICAgIH0KCQl9CgkgICAgfQoJfQoJZ3VpLnRvb2xiYXJfaGVpZ2h0ID0gZ3VpX21jaF9jb21wdXRlX3Rvb2xiYXJfaGVpZ2h0KCk7CglYdE1hbmFnZUNoaWxkKFh0UGFyZW50KHRvb2xCYXIpKTsKI2lmZGVmIEZFQVRfR1VJX1RBQkxJTkUKCWlmIChzaG93aW5nX3RhYmxpbmUpCgl7CgkgICAgWHRWYVNldFZhbHVlcyh0YWJMaW5lLAoJCQkgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICBYbU50b3BXaWRnZXQsIFh0UGFyZW50KHRvb2xCYXIpLAoJCQkgIE5VTEwpOwoJICAgIFh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICBYbU50b3BXaWRnZXQsIHRhYkxpbmUsCgkJCSAgTlVMTCk7Cgl9CgllbHNlCiNlbmRpZgoJICAgIFh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICBYbU50b3BXaWRnZXQsIFh0UGFyZW50KHRvb2xCYXIpLAoJCQkgIE5VTEwpOwoJaWYgKFh0SXNNYW5hZ2VkKG1lbnVCYXIpKQoJICAgIFh0VmFTZXRWYWx1ZXMoWHRQYXJlbnQodG9vbEJhciksCgkJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkgICAgWG1OdG9wV2lkZ2V0LCBtZW51QmFyLAoJCSAgICBOVUxMKTsKCWVsc2UKCSAgICBYdFZhU2V0VmFsdWVzKFh0UGFyZW50KHRvb2xCYXIpLAoJCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCSAgICBOVUxMKTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWd1aS50b29sYmFyX2hlaWdodCA9IDA7CglpZiAoWHRJc01hbmFnZWQobWVudUJhcikpCgl7CiNpZmRlZiBGRUFUX0dVSV9UQUJMSU5FCgkgICAgaWYgKHNob3dpbmdfdGFibGluZSkKCSAgICB7CgkJWHRWYVNldFZhbHVlcyh0YWJMaW5lLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgbWVudUJhciwKCQkJICAgICAgTlVMTCk7CgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCB0YWJMaW5lLAoJCQkgICAgICBOVUxMKTsKCSAgICB9CgkgICAgZWxzZQojZW5kaWYKCQlYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgICBYbU50b3BXaWRnZXQsIG1lbnVCYXIsCgkJCSAgICAgIE5VTEwpOwoJfQoJZWxzZQoJewojaWZkZWYgRkVBVF9HVUlfVEFCTElORQoJICAgIGlmIChzaG93aW5nX3RhYmxpbmUpCgkgICAgewoJCVh0VmFTZXRWYWx1ZXModGFiTGluZSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJICAgICAgTlVMTCk7CgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCB0YWJMaW5lLAoJCQkgICAgICBOVUxMKTsKCSAgICB9CgkgICAgZWxzZQojZW5kaWYKCQlYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkJICAgICAgTlVMTCk7Cgl9CgoJWHRVbm1hbmFnZUNoaWxkKFh0UGFyZW50KHRvb2xCYXIpKTsKICAgIH0KICAgIGd1aV9zZXRfc2hlbGxzaXplKEZBTFNFLCBGQUxTRSwgUkVTSVpFX1ZFUlQpOwp9CgovKgogKiBBIHRvb2xiYXIgYnV0dG9uIGhhcyBiZWVuIHB1c2hlZDsgbm93IHJlc2V0IHRoZSBpbnB1dCBmb2N1cwogKiBzdWNoIHRoYXQgdGhlIHVzZXIgY2FuIHR5cGUgcGFnZSB1cC9kb3duIGV0Yy4gYW5kIGhhdmUgdGhlCiAqIGlucHV0IGdvIHRvIHRoZSBlZGl0b3Igd2luZG93LCBub3QgdGhlIGJ1dHRvbgogKi8KICAgIHN0YXRpYyB2b2lkCnJlc2V0X2ZvY3VzKCkKewogICAgaWYgKHRleHRBcmVhICE9IE5VTEwpCglYbVByb2Nlc3NUcmF2ZXJzYWwodGV4dEFyZWEsIFhtVFJBVkVSU0VfQ1VSUkVOVCk7Cn0KCiAgICBpbnQKZ3VpX21jaF9jb21wdXRlX3Rvb2xiYXJfaGVpZ2h0KCkKewogICAgRGltZW5zaW9uCWJvcmRlcnM7CiAgICBEaW1lbnNpb24JaGVpZ2h0OwkJICAgIC8qIHRvdGFsIFRvb2xiYXIgaGVpZ2h0ICovCiAgICBEaW1lbnNpb24Jd2hndDsJCSAgICAvKiBoZWlnaHQgb2YgZWFjaCB3aWRnZXQgKi8KICAgIFdpZGdldExpc3QJY2hpbGRyZW47CSAgICAvKiBsaXN0IG9mIHRvb2xCYXIncyBjaGlsZHJlbiAqLwogICAgQ2FyZGluYWwJbnVtQ2hpbGRyZW47CSAgICAvKiBob3cgbWFueSBjaGlsZHJlbiB0b29sQmFyIGhhcyAqLwogICAgaW50CQlpOwoKICAgIGJvcmRlcnMgPSAwOwogICAgaGVpZ2h0ID0gMDsKICAgIGlmICh0b29sQmFyICE9IChXaWRnZXQpMCAmJiB0b29sQmFyRnJhbWUgIT0gKFdpZGdldCkwKQogICAgewkJCQkgICAgLyogZ2V0IGhlaWdodCBvZiBYbUZyYW1lIHBhcmVudCAqLwoJRGltZW5zaW9uCWZzdDsKCURpbWVuc2lvbglmbWg7CglEaW1lbnNpb24JdHN0OwoJRGltZW5zaW9uCXRtaDsKCglYdFZhR2V0VmFsdWVzKHRvb2xCYXJGcmFtZSwKCQlYbU5zaGFkb3dUaGlja25lc3MsICZmc3QsCgkJWG1ObWFyZ2luSGVpZ2h0LCAmZm1oLAoJCU5VTEwpOwoJYm9yZGVycyArPSBmc3QgKyBmbWg7CglYdFZhR2V0VmFsdWVzKHRvb2xCYXIsCgkJWG1Oc2hhZG93VGhpY2tuZXNzLCAmdHN0LAoJCVhtTm1hcmdpbkhlaWdodCwgJnRtaCwKCQlYbU5jaGlsZHJlbiwgJmNoaWxkcmVuLAoJCVhtTm51bUNoaWxkcmVuLCAmbnVtQ2hpbGRyZW4sIE5VTEwpOwoJYm9yZGVycyArPSB0c3QgKyB0bWg7Cglmb3IgKGkgPSAwOyBpIDwgKGludCludW1DaGlsZHJlbjsgaSsrKQoJewoJICAgIHdoZ3QgPSAwOwoJICAgIFh0VmFHZXRWYWx1ZXMoY2hpbGRyZW5baV0sIFhtTmhlaWdodCwgJndoZ3QsIE5VTEwpOwoJICAgIGlmIChoZWlnaHQgPCB3aGd0KQoJCWhlaWdodCA9IHdoZ3Q7Cgl9CiAgICB9CiNpZmRlZiBMRVNTVElGX1ZFUlNJT04KICAgIC8qIEhhY2s6IFdoZW4gc3RhcnRpbmcgdXAgd2UgZ2V0IHdyb25nIGRpbWVuc2lvbnMuICovCiAgICBpZiAoaGVpZ2h0IDwgMTApCgloZWlnaHQgPSAyNDsKI2VuZGlmCgogICAgcmV0dXJuIChpbnQpKGhlaWdodCArIChib3JkZXJzIDw8IDEpKTsKfQoKICAgIHZvaWQKbW90aWZfZ2V0X3Rvb2xiYXJfY29sb3JzKGJncCwgZmdwLCBic3AsIHRzcCwgaHNwKQogICAgUGl4ZWwgICAgICAgKmJncDsKICAgIFBpeGVsICAgICAgICpmZ3A7CiAgICBQaXhlbCAgICAgICAqYnNwOwogICAgUGl4ZWwgICAgICAgKnRzcDsKICAgIFBpeGVsICAgICAgICpoc3A7CnsKICAgIFh0VmFHZXRWYWx1ZXModG9vbEJhciwKCSAgICBYbU5iYWNrZ3JvdW5kLCBiZ3AsCgkgICAgWG1OZm9yZWdyb3VuZCwgZmdwLAoJICAgIFhtTmJvdHRvbVNoYWRvd0NvbG9yLCBic3AsCgkgICAgWG1OdG9wU2hhZG93Q29sb3IsIHRzcCwKCSAgICBYbU5oaWdobGlnaHRDb2xvciwgaHNwLAoJICAgIE5VTEwpOwp9CgojIGlmZGVmIEZFQVRfRk9PVEVSCi8qCiAqIFRoZSBuZXh0IHRvb2xiYXIgZW50ZXIvbGVhdmUgY2FsbGJhY2tzIHNob3VsZCByZWFsbHkgZG8gYmFsbG9vbiBoZWxwLiAgQnV0CiAqIEkgaGF2ZSB0byB1c2UgZm9vdGVyIGhlbHAgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LiAgSG9wZWZ1bGx5IGJvdGggd2lsbAogKiBnZXQgaW1wbGVtZW50ZWQgYW5kIHRoZSB1c2VyIHdpbGwgaGF2ZSBhIGNob2ljZS4KICovCiAgICBzdGF0aWMgdm9pZAp0b29sYmFyYnV0dG9uX2VudGVyX2NiKHcsIGNsaWVudF9kYXRhLCBldmVudCwgY29udCkKICAgIFdpZGdldAl3IFVOVVNFRDsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsKICAgIFhFdmVudAkqZXZlbnQgVU5VU0VEOwogICAgQm9vbGVhbgkqY29udCBVTlVTRUQ7CnsKICAgIHZpbW1lbnVfVAkqbWVudSA9ICh2aW1tZW51X1QgKikgY2xpZW50X2RhdGE7CgogICAgaWYgKG1lbnUtPnN0cmluZ3NbTUVOVV9JTkRFWF9USVBdICE9IE5VTEwpCiAgICB7CglpZiAodmltX3N0cmNocihwX2dvLCBHT19GT09URVIpICE9IE5VTEwpCgkgICAgZ3VpX21jaF9zZXRfZm9vdGVyKG1lbnUtPnN0cmluZ3NbTUVOVV9JTkRFWF9USVBdKTsKICAgIH0KfQoKICAgIHN0YXRpYyB2b2lkCnRvb2xiYXJidXR0b25fbGVhdmVfY2IodywgY2xpZW50X2RhdGEsIGV2ZW50LCBjb250KQogICAgV2lkZ2V0CXcgVU5VU0VEOwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhIFVOVVNFRDsKICAgIFhFdmVudAkqZXZlbnQgVU5VU0VEOwogICAgQm9vbGVhbgkqY29udCBVTlVTRUQ7CnsKICAgIGd1aV9tY2hfc2V0X2Zvb3RlcigoY2hhcl91ICopICIiKTsKfQojIGVuZGlmCiNlbmRpZgoKI2lmIGRlZmluZWQoRkVBVF9HVUlfVEFCTElORSkgfHwgZGVmaW5lZChQUk9UTykKLyoKICogU2hvdyBvciBoaWRlIHRoZSB0YWJsaW5lLgogKi8KICAgIHZvaWQKZ3VpX21jaF9zaG93X3RhYmxpbmUoaW50IHNob3dpdCkKewogICAgaWYgKHRhYkxpbmUgPT0gKFdpZGdldCkwKQoJcmV0dXJuOwoKICAgIGlmICghc2hvd2l0ICE9ICFzaG93aW5nX3RhYmxpbmUpCiAgICB7CglpZiAoc2hvd2l0KQoJewoJICAgIFh0TWFuYWdlQ2hpbGQodGFiTGluZSk7CgkgICAgWHRVbm1hbmFnZUNoaWxkKFh0TmFtZVRvV2lkZ2V0KHRhYkxpbmUsICJQYWdlU2Nyb2xsZXIiKSk7CgkgICAgWHRVbm1hbmFnZUNoaWxkKFh0TmFtZVRvV2lkZ2V0KHRhYkxpbmUsICJNaW5vclRhYlNjcm9sbGVyTmV4dCIpKTsKCSAgICBYdFVubWFuYWdlQ2hpbGQoWHROYW1lVG9XaWRnZXQodGFiTGluZSwKCQkJCQkgICAiTWlub3JUYWJTY3JvbGxlclByZXZpb3VzIikpOwojaWZkZWYgRkVBVF9NRU5VCiMgaWZkZWYgRkVBVF9UT09MQkFSCgkgICAgaWYgKFh0SXNNYW5hZ2VkKFh0UGFyZW50KHRvb2xCYXIpKSkKCQlYdFZhU2V0VmFsdWVzKHRhYkxpbmUsCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwgTlVMTCk7CgkgICAgZWxzZQojIGVuZGlmCgkJaWYgKFh0SXNNYW5hZ2VkKG1lbnVCYXIpKQoJCVh0VmFTZXRWYWx1ZXModGFiTGluZSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCQkgICAgICBYbU50b3BXaWRnZXQsIG1lbnVCYXIsIE5VTEwpOwoJICAgIGVsc2UKI2VuZGlmCgkJWHRWYVNldFZhbHVlcyh0YWJMaW5lLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLCBOVUxMKTsKCSAgICBYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgWG1OdG9wV2lkZ2V0LCB0YWJMaW5lLAoJCQkgIE5VTEwpOwoJfQoJZWxzZQoJewoJICAgIFh0VW5tYW5hZ2VDaGlsZCh0YWJMaW5lKTsKI2lmZGVmIEZFQVRfTUVOVQojIGlmZGVmIEZFQVRfVE9PTEJBUgoJICAgIGlmIChYdElzTWFuYWdlZChYdFBhcmVudCh0b29sQmFyKSkpCgkJWHRWYVNldFZhbHVlcyh0ZXh0QXJlYUZvcm0sCgkJCSAgICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkJICAgICAgWG1OdG9wV2lkZ2V0LCBYdFBhcmVudCh0b29sQmFyKSwgTlVMTCk7CgkgICAgZWxzZQojIGVuZGlmCgkJaWYgKFh0SXNNYW5hZ2VkKG1lbnVCYXIpKQoJCVh0VmFTZXRWYWx1ZXModGV4dEFyZWFGb3JtLAoJCQkgICAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJCSAgICAgIFhtTnRvcFdpZGdldCwgbWVudUJhciwgTlVMTCk7CgkgICAgZWxzZQojZW5kaWYKCQlYdFZhU2V0VmFsdWVzKHRleHRBcmVhRm9ybSwKCQkJICAgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwgTlVMTCk7Cgl9CglzaG93aW5nX3RhYmxpbmUgPSBzaG93aXQ7CiAgICB9Cn0KCi8qCiAqIFJldHVybiBUUlVFIHdoZW4gdGFibGluZSBpcyBkaXNwbGF5ZWQuCiAqLwogICAgaW50Cmd1aV9tY2hfc2hvd2luZ190YWJsaW5lKHZvaWQpCnsKICAgIHJldHVybiB0YWJMaW5lICE9IChXaWRnZXQpMCAmJiBzaG93aW5nX3RhYmxpbmU7Cn0KCi8qCiAqIFVwZGF0ZSB0aGUgbGFiZWxzIG9mIHRoZSB0YWJsaW5lLgogKi8KICAgIHZvaWQKZ3VpX21jaF91cGRhdGVfdGFibGluZSh2b2lkKQp7CiAgICB0YWJwYWdlX1QJCSp0cDsKICAgIGludAkJCW5yID0gMSwgbjsKICAgIEFyZwkJCWFyZ3NbMTBdOwogICAgaW50CQkJY3VydGFiaWR4ID0gMCwgY3VycmVudHBhZ2U7CiAgICBXaWRnZXQJCXRhYjsKICAgIFhtTm90ZWJvb2tQYWdlSW5mbwlwYWdlX2luZm87CiAgICBYbU5vdGVib29rUGFnZVN0YXR1cyBwYWdlX3N0YXR1czsKICAgIGludAkJCWxhc3RfcGFnZSwgdGFiX2NvdW50OwogICAgWG1TdHJpbmcJCWxhYmVsX3N0cjsKICAgIGNoYXIJCSpsYWJlbF9jc3RyOwogICAgQmFsbG9vbkV2YWwJCSpiZXZhbDsKCiAgICBpZiAodGFiTGluZSA9PSAoV2lkZ2V0KTApCglyZXR1cm47CgogICAgLyogQWRkIGEgbGFiZWwgZm9yIGVhY2ggdGFiIHBhZ2UuICBUaGV5IGFsbCBjb250YWluIHRoZSBzYW1lIHRleHQgYXJlYS4gKi8KICAgIGZvciAodHAgPSBmaXJzdF90YWJwYWdlOyB0cCAhPSBOVUxMOyB0cCA9IHRwLT50cF9uZXh0LCArK25yKQogICAgewoJaWYgKHRwID09IGN1cnRhYikKCSAgICBjdXJ0YWJpZHggPSBucjsKCglwYWdlX3N0YXR1cyA9IFhtTm90ZWJvb2tHZXRQYWdlSW5mbyh0YWJMaW5lLCBuciwgJnBhZ2VfaW5mbyk7CglpZiAocGFnZV9zdGF0dXMgPT0gWG1QQUdFX0lOVkFMSUQKCQl8fCBwYWdlX2luZm8ubWFqb3JfdGFiX3dpZGdldCA9PSAoV2lkZ2V0KTApCgl7CgkgICAgLyogQWRkIHRoZSB0YWIgKi8KCSAgICBuID0gMDsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ub3RlYm9va0NoaWxkVHlwZSwgWG1NQUpPUl9UQUIpOyBuKys7CgkgICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdHJhdmVyc2FsT24sIEZhbHNlKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmFsaWdubWVudCwgWG1BTElHTk1FTlRfQkVHSU5OSU5HKTsgbisrOwoJICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmhpZ2hsaWdodFRoaWNrbmVzcywgMSk7IG4rKzsKCSAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5zaGFkb3dUaGlja25lc3MgLCAxKTsgbisrOwoJICAgIHRhYiA9IFhtQ3JlYXRlUHVzaEJ1dHRvbih0YWJMaW5lLCAiLUVtcHR5LSIsIGFyZ3MsIG4pOwoJICAgIFh0TWFuYWdlQ2hpbGQodGFiKTsKCSAgICBiZXZhbCA9IGd1aV9tY2hfY3JlYXRlX2JldmFsX2FyZWEodGFiLCBOVUxMLCB0YWJsaW5lX2JhbGxvb25fY2IsCgkJCQkJCQkJCU5VTEwpOwoJICAgIFh0VmFTZXRWYWx1ZXModGFiLCBYbU51c2VyRGF0YSwgYmV2YWwsIE5VTEwpOwoJfQoJZWxzZQoJICAgIHRhYiA9IHBhZ2VfaW5mby5tYWpvcl90YWJfd2lkZ2V0OwoKCVh0VmFTZXRWYWx1ZXModGFiLCBYbU5wYWdlTnVtYmVyLCBuciwgTlVMTCk7CgoJLyoKCSAqIENoYW5nZSB0aGUgbGFiZWwgdGV4dCBvbmx5IGlmIGl0IGlzIGRpZmZlcmVudAoJICovCglYdFZhR2V0VmFsdWVzKHRhYiwgWG1ObGFiZWxTdHJpbmcsICZsYWJlbF9zdHIsIE5VTEwpOwoJaWYgKFhtU3RyaW5nR2V0THRvUihsYWJlbF9zdHIsIFhtU1RSSU5HX0RFRkFVTFRfQ0hBUlNFVCwgJmxhYmVsX2NzdHIpKQoJewoJICAgIGdldF90YWJsaW5lX2xhYmVsKHRwLCBGQUxTRSk7CgkgICAgaWYgKFNUUkNNUChsYWJlbF9jc3RyLCBOYW1lQnVmZikgIT0gMCkKCSAgICB7CgkJWHRWYVNldFZhbHVlcyh0YWIsIFh0VmFUeXBlZEFyZywgWG1ObGFiZWxTdHJpbmcsIFhtUlN0cmluZywKCQkJICAgICAgTmFtZUJ1ZmYsIFNUUkxFTihOYW1lQnVmZikgKyAxLCBOVUxMKTsKCQkvKgoJCSAqIEZvcmNlIGEgcmVzaXplIG9mIHRoZSB0YWIgbGFiZWwgYnV0dG9uCgkJICovCgkJWHRVbm1hbmFnZUNoaWxkKHRhYik7CgkJWHRNYW5hZ2VDaGlsZCh0YWIpOwoJICAgIH0KCSAgICBYdEZyZWUobGFiZWxfY3N0cik7Cgl9CiAgICB9CgogICAgdGFiX2NvdW50ID0gbnIgLSAxOwoKICAgIFh0VmFHZXRWYWx1ZXModGFiTGluZSwgWG1ObGFzdFBhZ2VOdW1iZXIsICZsYXN0X3BhZ2UsIE5VTEwpOwoKICAgIC8qIFJlbW92ZSBhbnkgb2xkIGxhYmVscy4gKi8KICAgIHdoaWxlIChuciA8PSBsYXN0X3BhZ2UpCiAgICB7CglpZiAoWG1Ob3RlYm9va0dldFBhZ2VJbmZvKHRhYkxpbmUsIG5yLCAmcGFnZV9pbmZvKSAhPSBYbVBBR0VfSU5WQUxJRAoJICAgICYmIHBhZ2VfaW5mby5wYWdlX251bWJlciA9PSBucgoJICAgICYmIHBhZ2VfaW5mby5tYWpvcl90YWJfd2lkZ2V0ICE9IChXaWRnZXQpMCkKCXsKCSAgICBYdFZhR2V0VmFsdWVzKHBhZ2VfaW5mby5tYWpvcl90YWJfd2lkZ2V0LCBYbU51c2VyRGF0YSwgJmJldmFsLCBOVUxMKTsKCSAgICBpZiAoYmV2YWwgIT0gTlVMTCkKCQlndWlfbWNoX2Rlc3Ryb3lfYmV2YWxfYXJlYShiZXZhbCk7CgkgICAgWHRVbm1hbmFnZUNoaWxkKHBhZ2VfaW5mby5tYWpvcl90YWJfd2lkZ2V0KTsKCSAgICBYdERlc3Ryb3lXaWRnZXQocGFnZV9pbmZvLm1ham9yX3RhYl93aWRnZXQpOwoJfQoJbnIrKzsKICAgIH0KCiAgICBYdFZhU2V0VmFsdWVzKHRhYkxpbmUsIFhtTmxhc3RQYWdlTnVtYmVyLCB0YWJfY291bnQsIE5VTEwpOwoKICAgIFh0VmFHZXRWYWx1ZXModGFiTGluZSwgWG1OY3VycmVudFBhZ2VOdW1iZXIsICZjdXJyZW50cGFnZSwgTlVMTCk7CiAgICBpZiAoY3VycmVudHBhZ2UgIT0gY3VydGFiaWR4KQoJWHRWYVNldFZhbHVlcyh0YWJMaW5lLCBYbU5jdXJyZW50UGFnZU51bWJlciwgY3VydGFiaWR4LCBOVUxMKTsKfQoKLyoKICogU2V0IHRoZSBjdXJyZW50IHRhYiB0byAibnIiLiAgRmlyc3QgdGFiIGlzIDEuCiAqLwogICAgdm9pZApndWlfbWNoX3NldF9jdXJ0YWIobnIpCiAgICBpbnQJCW5yOwp7CiAgICBpbnQJCWN1cnJlbnRwYWdlOwoKICAgIGlmICh0YWJMaW5lID09IChXaWRnZXQpMCkKCXJldHVybjsKCiAgICBYdFZhR2V0VmFsdWVzKHRhYkxpbmUsIFhtTmN1cnJlbnRQYWdlTnVtYmVyLCAmY3VycmVudHBhZ2UsIE5VTEwpOwogICAgaWYgKGN1cnJlbnRwYWdlICE9IG5yKQoJWHRWYVNldFZhbHVlcyh0YWJMaW5lLCBYbU5jdXJyZW50UGFnZU51bWJlciwgbnIsIE5VTEwpOwp9CiNlbmRpZgoKLyoKICogU2V0IHRoZSBjb2xvcnMgb2YgV2lkZ2V0ICJpZCIgdG8gdGhlIG1lbnUgY29sb3JzLgogKi8KICAgIHN0YXRpYyB2b2lkCmd1aV9tb3RpZl9tZW51X2NvbG9ycyhpZCkKICAgIFdpZGdldCAgaWQ7CnsKICAgIGlmIChndWkubWVudV9iZ19waXhlbCAhPSBJTlZBTENPTE9SKQojaWYgKFhtVmVyc2lvbiA+PSAxMDAyKQoJWG1DaGFuZ2VDb2xvcihpZCwgZ3VpLm1lbnVfYmdfcGl4ZWwpOwojZWxzZQoJWHRWYVNldFZhbHVlcyhpZCwgWG1OYmFja2dyb3VuZCwgZ3VpLm1lbnVfYmdfcGl4ZWwsIE5VTEwpOwojZW5kaWYKICAgIGlmIChndWkubWVudV9mZ19waXhlbCAhPSBJTlZBTENPTE9SKQoJWHRWYVNldFZhbHVlcyhpZCwgWG1OZm9yZWdyb3VuZCwgZ3VpLm1lbnVfZmdfcGl4ZWwsIE5VTEwpOwp9CgovKgogKiBTZXQgdGhlIGNvbG9ycyBvZiBXaWRnZXQgImlkIiB0byB0aGUgc2Nyb2xsYmFyIGNvbG9ycy4KICovCiAgICBzdGF0aWMgdm9pZApndWlfbW90aWZfc2Nyb2xsX2NvbG9ycyhpZCkKICAgIFdpZGdldCAgaWQ7CnsKICAgIGlmIChndWkuc2Nyb2xsX2JnX3BpeGVsICE9IElOVkFMQ09MT1IpCiNpZiAoWG1WZXJzaW9uID49IDEwMDIpCglYbUNoYW5nZUNvbG9yKGlkLCBndWkuc2Nyb2xsX2JnX3BpeGVsKTsKI2Vsc2UKCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmJhY2tncm91bmQsIGd1aS5zY3JvbGxfYmdfcGl4ZWwsIE5VTEwpOwojZW5kaWYKICAgIGlmIChndWkuc2Nyb2xsX2ZnX3BpeGVsICE9IElOVkFMQ09MT1IpCglYdFZhU2V0VmFsdWVzKGlkLCBYbU5mb3JlZ3JvdW5kLCBndWkuc2Nyb2xsX2ZnX3BpeGVsLCBOVUxMKTsKfQoKLyoKICogU2V0IHRoZSBmb250bGlzdCBmb3IgV2lkZ2V0ICJpZCIgdG8gdXNlIGd1aS5tZW51X2ZvbnRzZXQgb3IgZ3VpLm1lbnVfZm9udC4KICovCiAgICB2b2lkCmd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KGlkKQogICAgV2lkZ2V0ICBpZCBVTlVTRUQ7CnsKI2lmZGVmIEZFQVRfTUVOVQojaWZkZWYgRk9OVFNFVF9BTFdBWVMKICAgIGlmIChndWkubWVudV9mb250c2V0ICE9IE5PRk9OVFNFVCkKICAgIHsKCVhtRm9udExpc3QgZmw7CgoJZmwgPSBndWlfbW90aWZfZm9udHNldDJmb250bGlzdCgoWEZvbnRTZXQgKikmZ3VpLm1lbnVfZm9udHNldCk7CglpZiAoZmwgIT0gTlVMTCkKCXsKCSAgICBpZiAoWHRJc01hbmFnZWQoaWQpKQoJICAgIHsKCQlYdFVubWFuYWdlQ2hpbGQoaWQpOwoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkJLyogV2Ugc2hvdWxkIGZvcmNlIHRoZSB3aWRnZXQgdG8gcmVjYWxjdWxhdGUgaXQncwoJCSAqIGdlb21ldHJ5IG5vdy4gKi8KCQlYdE1hbmFnZUNoaWxkKGlkKTsKCSAgICB9CgkgICAgZWxzZQoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkgICAgWG1Gb250TGlzdEZyZWUoZmwpOwoJfQogICAgfQojZWxzZQogICAgaWYgKGd1aS5tZW51X2ZvbnQgIT0gTk9GT05UKQogICAgewoJWG1Gb250TGlzdCBmbDsKCglmbCA9IGd1aV9tb3RpZl9jcmVhdGVfZm9udGxpc3QoKFhGb250U3RydWN0ICopZ3VpLm1lbnVfZm9udCk7CglpZiAoZmwgIT0gTlVMTCkKCXsKCSAgICBpZiAoWHRJc01hbmFnZWQoaWQpKQoJICAgIHsKCQlYdFVubWFuYWdlQ2hpbGQoaWQpOwoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkJLyogV2Ugc2hvdWxkIGZvcmNlIHRoZSB3aWRnZXQgdG8gcmVjYWxjdWxhdGUgaXQncwoJCSAqIGdlb21ldHJ5IG5vdy4gKi8KCQlYdE1hbmFnZUNoaWxkKGlkKTsKCSAgICB9CgkgICAgZWxzZQoJCVh0VmFTZXRWYWx1ZXMoaWQsIFhtTmZvbnRMaXN0LCBmbCwgTlVMTCk7CgkgICAgWG1Gb250TGlzdEZyZWUoZmwpOwoJfQogICAgfQojZW5kaWYKI2VuZGlmCn0KCgovKgogKiBXZSBkb24ndCBjcmVhdGUgaXQgdHdpY2UgZm9yIHRoZSBzYWtlIG9mIHNwZWVkLgogKi8KCnR5cGVkZWYgc3RydWN0IF9TaGFyZWRGaW5kUmVwbGFjZQp7CiAgICBXaWRnZXQgZGlhbG9nOwkvKiB0aGUgbWFpbiBkaWFsb2cgd2lkZ2V0ICovCiAgICBXaWRnZXQgd3dvcmQ7CS8qICdFeGFjdCBtYXRjaCcgY2hlY2sgYnV0dG9uICovCiAgICBXaWRnZXQgbWNhc2U7CS8qICdtYXRjaCBjYXNlJyBjaGVjayBidXR0b24gKi8KICAgIFdpZGdldCB1cDsJCS8qIHNlYXJjaCBkaXJlY3Rpb24gJ1VwJyByYWRpbyBidXR0b24gKi8KICAgIFdpZGdldCBkb3duOwkvKiBzZWFyY2ggZGlyZWN0aW9uICdEb3duJyByYWRpbyBidXR0b24gKi8KICAgIFdpZGdldCB3aGF0OwkvKiAnRmluZCB3aGF0JyBlbnRyeSB0ZXh0IHdpZGdldCAqLwogICAgV2lkZ2V0IHdpdGg7CS8qICdSZXBsYWNlIHdpdGgnIGVudHJ5IHRleHQgd2lkZ2V0ICovCiAgICBXaWRnZXQgZmluZDsJLyogJ0ZpbmQgTmV4dCcgYWN0aW9uIGJ1dHRvbiAqLwogICAgV2lkZ2V0IHJlcGxhY2U7CS8qICdSZXBsYWNlIFdpdGgnIGFjdGlvbiBidXR0b24gKi8KICAgIFdpZGdldCBhbGw7CQkvKiAnUmVwbGFjZSBBbGwnIGFjdGlvbiBidXR0b24gKi8KICAgIFdpZGdldCB1bmRvOwkvKiAnVW5kbycgYWN0aW9uIGJ1dHRvbiAqLwoKICAgIFdpZGdldCBjYW5jZWw7Cn0gU2hhcmVkRmluZFJlcGxhY2U7CgpzdGF0aWMgU2hhcmVkRmluZFJlcGxhY2UgZmluZF93aWRnZXRzID0ge05VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEx9OwpzdGF0aWMgU2hhcmVkRmluZFJlcGxhY2UgcmVwbF93aWRnZXRzID0ge05VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEx9OwoKc3RhdGljIHZvaWQgZmluZF9yZXBsYWNlX2Rlc3Ryb3lfY2FsbGJhY2sgX19BUkdTKChXaWRnZXQgdywgWHRQb2ludGVyIGNsaWVudF9kYXRhLCBYdFBvaW50ZXIgY2FsbF9kYXRhKSk7CnN0YXRpYyB2b2lkIGZpbmRfcmVwbGFjZV9kaXNtaXNzX2NhbGxiYWNrIF9fQVJHUygoV2lkZ2V0IHcsIFh0UG9pbnRlciBjbGllbnRfZGF0YSwgWHRQb2ludGVyIGNhbGxfZGF0YSkpOwpzdGF0aWMgdm9pZCBlbnRyeV9hY3RpdmF0ZV9jYWxsYmFjayBfX0FSR1MoKFdpZGdldCB3LCBYdFBvaW50ZXIgY2xpZW50X2RhdGEsIFh0UG9pbnRlciBjYWxsX2RhdGEpKTsKc3RhdGljIHZvaWQgZmluZF9yZXBsYWNlX2NhbGxiYWNrIF9fQVJHUygoV2lkZ2V0IHcsIFh0UG9pbnRlciBjbGllbnRfZGF0YSwgWHRQb2ludGVyIGNhbGxfZGF0YSkpOwpzdGF0aWMgdm9pZCBmaW5kX3JlcGxhY2Vfa2V5cHJlc3MgX19BUkdTKChXaWRnZXQgdywgU2hhcmVkRmluZFJlcGxhY2UgKiBmcmRwLCBYS2V5RXZlbnQgKiBldmVudCkpOwpzdGF0aWMgdm9pZCBmaW5kX3JlcGxhY2VfZGlhbG9nX2NyZWF0ZSBfX0FSR1MoKGNoYXJfdSAqZW50cnlfdGV4dCwgaW50IGRvX3JlcGxhY2UpKTsKCiAgICBzdGF0aWMgdm9pZApmaW5kX3JlcGxhY2VfZGVzdHJveV9jYWxsYmFjayh3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXcgVU5VU0VEOwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwogICAgWHRQb2ludGVyCWNhbGxfZGF0YSBVTlVTRUQ7CnsKICAgIFNoYXJlZEZpbmRSZXBsYWNlICpjZCA9IChTaGFyZWRGaW5kUmVwbGFjZSAqKWNsaWVudF9kYXRhOwoKICAgIGlmIChjZCAhPSBOVUxMKQogICAgICAgLyogc3VwcHJlc3NfZGlhbG9nX21uZW1vbmljcyhjZC0+ZGlhbG9nKTsgKi8KCWNkLT5kaWFsb2cgPSAoV2lkZ2V0KTA7Cn0KCiAgICBzdGF0aWMgdm9pZApmaW5kX3JlcGxhY2VfZGlzbWlzc19jYWxsYmFjayh3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXcgVU5VU0VEOwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwogICAgWHRQb2ludGVyCWNhbGxfZGF0YSBVTlVTRUQ7CnsKICAgIFNoYXJlZEZpbmRSZXBsYWNlICpjZCA9IChTaGFyZWRGaW5kUmVwbGFjZSAqKWNsaWVudF9kYXRhOwoKICAgIGlmIChjZCAhPSBOVUxMKQoJWHRVbm1hbmFnZUNoaWxkKGNkLT5kaWFsb2cpOwp9CgogICAgc3RhdGljIHZvaWQKZW50cnlfYWN0aXZhdGVfY2FsbGJhY2sodywgY2xpZW50X2RhdGEsIGNhbGxfZGF0YSkKICAgIFdpZGdldAl3IFVOVVNFRDsKICAgIFh0UG9pbnRlcgljbGllbnRfZGF0YTsKICAgIFh0UG9pbnRlcgljYWxsX2RhdGEgVU5VU0VEOwp7CiAgICBYbVByb2Nlc3NUcmF2ZXJzYWwoKFdpZGdldCljbGllbnRfZGF0YSwgWG1UUkFWRVJTRV9DVVJSRU5UKTsKfQoKICAgIHN0YXRpYyB2b2lkCmZpbmRfcmVwbGFjZV9jYWxsYmFjayh3LCBjbGllbnRfZGF0YSwgY2FsbF9kYXRhKQogICAgV2lkZ2V0CXcgVU5VU0VEOwogICAgWHRQb2ludGVyCWNsaWVudF9kYXRhOwogICAgWHRQb2ludGVyCWNhbGxfZGF0YSBVTlVTRUQ7CnsKICAgIGxvbmdfdQlmbGFncyA9IChsb25nX3UpY2xpZW50X2RhdGE7CiAgICBjaGFyCSpmaW5kX3RleHQsICpyZXBsX3RleHQ7CiAgICBCb29sZWFuCWRpcmVjdGlvbl9kb3duID0gVFJVRTsKICAgIEJvb2xlYW4Jd3dvcmQ7CiAgICBCb29sZWFuCW1jYXNlOwogICAgU2hhcmVkRmluZFJlcGxhY2UgKnNmcjsKCiAgICBpZiAoZmxhZ3MgPT0gRlJEX1VORE8pCiAgICB7CgljaGFyX3UJKnNhdmVfY3BvID0gcF9jcG87CgoJLyogTm8gbmVlZCB0byBiZSBWaSBjb21wYXRpYmxlIGhlcmUuICovCglwX2NwbyA9IChjaGFyX3UgKikiIjsKCXVfdW5kbygxKTsKCXBfY3BvID0gc2F2ZV9jcG87CglndWlfdXBkYXRlX3NjcmVlbigpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIEdldCB0aGUgc2VhcmNoL3JlcGxhY2Ugc3RyaW5ncyBmcm9tIHRoZSBkaWFsb2cgKi8KICAgIGlmIChmbGFncyA9PSBGUkRfRklORE5FWFQpCiAgICB7CglyZXBsX3RleHQgPSBOVUxMOwoJc2ZyID0gJmZpbmRfd2lkZ2V0czsKICAgIH0KICAgIGVsc2UKICAgIHsKCXJlcGxfdGV4dCA9IFhtVGV4dEZpZWxkR2V0U3RyaW5nKHJlcGxfd2lkZ2V0cy53aXRoKTsKCXNmciA9ICZyZXBsX3dpZGdldHM7CiAgICB9CiAgICBmaW5kX3RleHQgPSBYbVRleHRGaWVsZEdldFN0cmluZyhzZnItPndoYXQpOwogICAgWHRWYUdldFZhbHVlcyhzZnItPmRvd24sIFhtTnNldCwgJmRpcmVjdGlvbl9kb3duLCBOVUxMKTsKICAgIFh0VmFHZXRWYWx1ZXMoc2ZyLT53d29yZCwgWG1Oc2V0LCAmd3dvcmQsIE5VTEwpOwogICAgWHRWYUdldFZhbHVlcyhzZnItPm1jYXNlLCBYbU5zZXQsICZtY2FzZSwgTlVMTCk7CiAgICBpZiAod3dvcmQpCglmbGFncyB8PSBGUkRfV0hPTEVfV09SRDsKICAgIGlmIChtY2FzZSkKCWZsYWdzIHw9IEZSRF9NQVRDSF9DQVNFOwoKICAgICh2b2lkKWd1aV9kb19maW5kcmVwbCgoaW50KWZsYWdzLCAoY2hhcl91ICopZmluZF90ZXh0LCAoY2hhcl91ICopcmVwbF90ZXh0LAoJCQkJCQkJICAgICAgZGlyZWN0aW9uX2Rvd24pOwoKICAgIGlmIChmaW5kX3RleHQgIT0gTlVMTCkKCVh0RnJlZShmaW5kX3RleHQpOwogICAgaWYgKHJlcGxfdGV4dCAhPSBOVUxMKQoJWHRGcmVlKHJlcGxfdGV4dCk7Cn0KCiAgICBzdGF0aWMgdm9pZApmaW5kX3JlcGxhY2Vfa2V5cHJlc3ModywgZnJkcCwgZXZlbnQpCiAgICBXaWRnZXQJCXcgVU5VU0VEOwogICAgU2hhcmVkRmluZFJlcGxhY2UJKmZyZHA7CiAgICBYS2V5RXZlbnQJCSpldmVudDsKewogICAgS2V5U3ltIGtleXN5bTsKCiAgICBpZiAoZnJkcCA9PSBOVUxMKQoJcmV0dXJuOwoKICAgIGtleXN5bSA9IFhMb29rdXBLZXlzeW0oZXZlbnQsIDApOwoKICAgIC8qIHRoZSBzY2FwZSBrZXkgcG9wcyB0aGUgd2hvbGUgZGlhbG9nIGRvd24gKi8KICAgIGlmIChrZXlzeW0gPT0gWEtfRXNjYXBlKQoJWHRVbm1hbmFnZUNoaWxkKGZyZHAtPmRpYWxvZyk7Cn0KCiAgICBzdGF0aWMgdm9pZApzZXRfbGFiZWwodywgbGFiZWwpCiAgICBXaWRnZXQgdzsKICAgIGNoYXIgKmxhYmVsOwp7CiAgICBYbVN0cmluZwlzdHI7CiAgICBjaGFyX3UJKnAsICpuZXh0OwogICAgS2V5U3ltCW1uZW1vbmljID0gTlVMOwoKICAgIGlmICghdykKCXJldHVybjsKCiAgICBwID0gdmltX3N0cnNhdmUoKGNoYXJfdSAqKWxhYmVsKTsKICAgIGlmIChwID09IE5VTEwpCglyZXR1cm47CiAgICBmb3IgKG5leHQgPSBwOyAqbmV4dDsgKytuZXh0KQogICAgewoJaWYgKCpuZXh0ID09IERMR19IT1RLRVlfQ0hBUikKCXsKCSAgICBpbnQgbGVuID0gU1RSTEVOKG5leHQpOwoKCSAgICBpZiAobGVuID4gMCkKCSAgICB7CgkJbWNoX21lbW1vdmUobmV4dCwgbmV4dCArIDEsIGxlbik7CgkJbW5lbW9uaWMgPSBuZXh0WzBdOwoJICAgIH0KCX0KICAgIH0KCiAgICBzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZSgoY2hhciAqKXApOwogICAgdmltX2ZyZWUocCk7CiAgICBpZiAoc3RyKQogICAgewoJWHRWYVNldFZhbHVlcyh3LAoJCVhtTmxhYmVsU3RyaW5nLCBzdHIsCgkJWG1ObW5lbW9uaWMsIG1uZW1vbmljLAoJCU5VTEwpOwoJWG1TdHJpbmdGcmVlKHN0cik7CiAgICB9CiAgICBndWlfbW90aWZfbWVudV9mb250bGlzdCh3KTsKfQoKICAgIHN0YXRpYyB2b2lkCmZpbmRfcmVwbGFjZV9kaWFsb2dfY3JlYXRlKGFyZywgZG9fcmVwbGFjZSkKICAgIGNoYXJfdQkqYXJnOwogICAgaW50CQlkb19yZXBsYWNlOwp7CiAgICBTaGFyZWRGaW5kUmVwbGFjZQkqZnJkcDsKICAgIFdpZGdldAkJc2VwYXJhdG9yOwogICAgV2lkZ2V0CQlpbnB1dF9mb3JtOwogICAgV2lkZ2V0CQlidXR0b25fZm9ybTsKICAgIFdpZGdldAkJdG9nZ2xlX2Zvcm07CiAgICBXaWRnZXQJCWZyYW1lOwogICAgWG1TdHJpbmcJCXN0cjsKICAgIGludAkJCW47CiAgICBBcmcJCQlhcmdzWzZdOwogICAgaW50CQkJd3dvcmQgPSBGQUxTRTsKICAgIGludAkJCW1jYXNlID0gIXBfaWM7CiAgICBEaW1lbnNpb24JCXdpZHRoOwogICAgRGltZW5zaW9uCQl3aWRlc3Q7CiAgICBjaGFyX3UJCSplbnRyeV90ZXh0OwoKICAgIGZyZHAgPSBkb19yZXBsYWNlID8gJnJlcGxfd2lkZ2V0cyA6ICZmaW5kX3dpZGdldHM7CgogICAgLyogR2V0IHRoZSBzZWFyY2ggc3RyaW5nIHRvIHVzZS4gKi8KICAgIGVudHJ5X3RleHQgPSBnZXRfZmluZF9kaWFsb2dfdGV4dChhcmcsICZ3d29yZCwgJm1jYXNlKTsKCiAgICAvKiBJZiB0aGUgZGlhbG9nIGFscmVhZHkgZXhpc3RzLCBqdXN0IHJhaXNlIGl0LiAqLwogICAgaWYgKGZyZHAtPmRpYWxvZykKICAgIHsKCWd1aV9tb3RpZl9zeW5jaF9mb250cygpOwoKCS8qIElmIHRoZSB3aW5kb3cgaXMgYWxyZWFkeSB1cCwganVzdCBwb3AgaXQgdG8gdGhlIHRvcCAqLwoJaWYgKFh0SXNNYW5hZ2VkKGZyZHAtPmRpYWxvZykpCgkgICAgWE1hcFJhaXNlZChYdERpc3BsYXkoZnJkcC0+ZGlhbG9nKSwKCQkJCQkgICAgWHRXaW5kb3coWHRQYXJlbnQoZnJkcC0+ZGlhbG9nKSkpOwoJZWxzZQoJICAgIFh0TWFuYWdlQ2hpbGQoZnJkcC0+ZGlhbG9nKTsKCVh0UG9wdXAoWHRQYXJlbnQoZnJkcC0+ZGlhbG9nKSwgWHRHcmFiTm9uZSk7CglYbVByb2Nlc3NUcmF2ZXJzYWwoZnJkcC0+d2hhdCwgWG1UUkFWRVJTRV9DVVJSRU5UKTsKCglpZiAoZW50cnlfdGV4dCAhPSBOVUxMKQoJICAgIFhtVGV4dEZpZWxkU2V0U3RyaW5nKGZyZHAtPndoYXQsIChjaGFyICopZW50cnlfdGV4dCk7Cgl2aW1fZnJlZShlbnRyeV90ZXh0KTsKCglYdFZhU2V0VmFsdWVzKGZyZHAtPnd3b3JkLCBYbU5zZXQsIHd3b3JkLCBOVUxMKTsKCXJldHVybjsKICAgIH0KCiAgICAvKiBDcmVhdGUgYSBmcmVzaCBuZXcgZGlhbG9nIHdpbmRvdyAqLwogICAgaWYgKGRvX3JlcGxhY2UpCgkgc3RyID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoXygiVklNIC0gU2VhcmNoIGFuZCBSZXBsYWNlLi4uIikpOwogICAgZWxzZQoJIHN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKF8oIlZJTSAtIFNlYXJjaC4uLiIpKTsKCiAgICBuID0gMDsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmF1dG9Vbm1hbmFnZSwgRmFsc2UpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5ub1Jlc2l6ZSwgVHJ1ZSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmRpYWxvZ1RpdGxlLCBzdHIpOyBuKys7CgogICAgZnJkcC0+ZGlhbG9nID0gWG1DcmVhdGVGb3JtRGlhbG9nKHZpbVNoZWxsLCAiZmluZFJlcGxhY2VEaWFsb2ciLCBhcmdzLCBuKTsKICAgIFhtU3RyaW5nRnJlZShzdHIpOwogICAgWHRBZGRDYWxsYmFjayhmcmRwLT5kaWFsb2csIFhtTmRlc3Ryb3lDYWxsYmFjaywKCSAgICBmaW5kX3JlcGxhY2VfZGVzdHJveV9jYWxsYmFjaywgZnJkcCk7CgogICAgYnV0dG9uX2Zvcm0gPSBYdFZhQ3JlYXRlV2lkZ2V0KCJidXR0b25Gb3JtIiwKCSAgICB4bUZvcm1XaWRnZXRDbGFzcywJZnJkcC0+ZGlhbG9nLAoJICAgIFhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU5yaWdodE9mZnNldCwgNCwKCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTnRvcE9mZnNldCwgNCwKCSAgICBYbU5ib3R0b21BdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmJvdHRvbU9mZnNldCwgNCwKCSAgICBOVUxMKTsKCiAgICBmcmRwLT5maW5kID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoImZpbmRCdXR0b24iLAoJICAgIHhtUHVzaEJ1dHRvbldpZGdldENsYXNzLCBidXR0b25fZm9ybSwKCSAgICBYbU5zZW5zaXRpdmUsIFRydWUsCgkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgTlVMTCk7CiAgICBzZXRfbGFiZWwoZnJkcC0+ZmluZCwgXygiRmluZCAmTmV4dCIpKTsKCiAgICBYdEFkZENhbGxiYWNrKGZyZHAtPmZpbmQsIFhtTmFjdGl2YXRlQ2FsbGJhY2ssCgkgICAgZmluZF9yZXBsYWNlX2NhbGxiYWNrLAoJICAgIChkb19yZXBsYWNlID8gKFh0UG9pbnRlcilGUkRfUl9GSU5ETkVYVCA6IChYdFBvaW50ZXIpRlJEX0ZJTkRORVhUKSk7CgogICAgaWYgKGRvX3JlcGxhY2UpCiAgICB7CglmcmRwLT5yZXBsYWNlID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInJlcGxhY2VCdXR0b24iLAoJCXhtUHVzaEJ1dHRvbldpZGdldENsYXNzLCBidXR0b25fZm9ybSwKCQlYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkJWG1OdG9wV2lkZ2V0LCBmcmRwLT5maW5kLAoJCVhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCVhtTnJpZ2h0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlOVUxMKTsKCXNldF9sYWJlbChmcmRwLT5yZXBsYWNlLCBfKCImUmVwbGFjZSIpKTsKCVh0QWRkQ2FsbGJhY2soZnJkcC0+cmVwbGFjZSwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCQlmaW5kX3JlcGxhY2VfY2FsbGJhY2ssIChYdFBvaW50ZXIpRlJEX1JFUExBQ0UpOwoKCWZyZHAtPmFsbCA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJyZXBsYWNlQWxsQnV0dG9uIiwKCQl4bVB1c2hCdXR0b25XaWRnZXRDbGFzcywgYnV0dG9uX2Zvcm0sCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCVhtTnRvcFdpZGdldCwgZnJkcC0+cmVwbGFjZSwKCQlYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJTlVMTCk7CglzZXRfbGFiZWwoZnJkcC0+YWxsLCBfKCJSZXBsYWNlICZBbGwiKSk7CglYdEFkZENhbGxiYWNrKGZyZHAtPmFsbCwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCQlmaW5kX3JlcGxhY2VfY2FsbGJhY2ssIChYdFBvaW50ZXIpRlJEX1JFUExBQ0VBTEwpOwoKCWZyZHAtPnVuZG8gPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgidW5kb0J1dHRvbiIsCgkJeG1QdXNoQnV0dG9uV2lkZ2V0Q2xhc3MsIGJ1dHRvbl9mb3JtLAoJCVhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQlYbU50b3BXaWRnZXQsIGZyZHAtPmFsbCwKCQlYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJTlVMTCk7CglzZXRfbGFiZWwoZnJkcC0+dW5kbywgXygiJlVuZG8iKSk7CglYdEFkZENhbGxiYWNrKGZyZHAtPnVuZG8sIFhtTmFjdGl2YXRlQ2FsbGJhY2ssCgkJZmluZF9yZXBsYWNlX2NhbGxiYWNrLCAoWHRQb2ludGVyKUZSRF9VTkRPKTsKICAgIH0KCiAgICBmcmRwLT5jYW5jZWwgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgiY2xvc2VCdXR0b24iLAoJICAgIHhtUHVzaEJ1dHRvbldpZGdldENsYXNzLCBidXR0b25fZm9ybSwKCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBOVUxMKTsKICAgIHNldF9sYWJlbChmcmRwLT5jYW5jZWwsIF8oIiZDYW5jZWwiKSk7CiAgICBYdEFkZENhbGxiYWNrKGZyZHAtPmNhbmNlbCwgWG1OYWN0aXZhdGVDYWxsYmFjaywKCSAgICBmaW5kX3JlcGxhY2VfZGlzbWlzc19jYWxsYmFjaywgZnJkcCk7CiAgICBndWlfbW90aWZfbWVudV9mb250bGlzdChmcmRwLT5jYW5jZWwpOwoKICAgIFh0TWFuYWdlQ2hpbGQoYnV0dG9uX2Zvcm0pOwoKICAgIG4gPSAwOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1Ob3JpZW50YXRpb24sIFhtVkVSVElDQUwpOyBuKys7CiAgICBYdFNldEFyZyhhcmdzW25dLCBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0V2lkZ2V0LCBidXR0b25fZm9ybSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTnJpZ2h0T2Zmc2V0LCA0KTsgbisrOwogICAgWHRTZXRBcmcoYXJnc1tuXSwgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSk7IG4rKzsKICAgIFh0U2V0QXJnKGFyZ3Nbbl0sIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0pOyBuKys7CiAgICBzZXBhcmF0b3IgPSBYbUNyZWF0ZVNlcGFyYXRvckdhZGdldChmcmRwLT5kaWFsb2csICJzZXBhcmF0b3IiLCBhcmdzLCBuKTsKICAgIFh0TWFuYWdlQ2hpbGQoc2VwYXJhdG9yKTsKCiAgICBpbnB1dF9mb3JtID0gWHRWYUNyZWF0ZVdpZGdldCgiaW5wdXRGb3JtIiwKCSAgICB4bUZvcm1XaWRnZXRDbGFzcywJZnJkcC0+ZGlhbG9nLAoJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmxlZnRPZmZzZXQsIDQsCgkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkgICAgWG1OcmlnaHRXaWRnZXQsIHNlcGFyYXRvciwKCSAgICBYbU5yaWdodE9mZnNldCwgNCwKCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTnRvcE9mZnNldCwgNCwKCSAgICBOVUxMKTsKCiAgICB7CglXaWRnZXQgbGFiZWxfd2hhdDsKCVdpZGdldCBsYWJlbF93aXRoID0gKFdpZGdldCkwOwoKCXN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKF8oIkZpbmQgd2hhdDoiKSk7CglsYWJlbF93aGF0ID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoIndoYXRMYWJlbCIsCgkJeG1MYWJlbEdhZGdldENsYXNzLCBpbnB1dF9mb3JtLAoJCVhtTmxhYmVsU3RyaW5nLCBzdHIsCgkJWG1ObGVmdEF0dGFjaG1lbnQsCVhtQVRUQUNIX0ZPUk0sCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU50b3BPZmZzZXQsIDQsCgkJTlVMTCk7CglYbVN0cmluZ0ZyZWUoc3RyKTsKCWd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KGxhYmVsX3doYXQpOwoKCWZyZHAtPndoYXQgPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgid2hhdFRleHQiLAoJCXhtVGV4dEZpZWxkV2lkZ2V0Q2xhc3MsIGlucHV0X2Zvcm0sCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJTlVMTCk7CgoJaWYgKGRvX3JlcGxhY2UpCgl7CgkgICAgZnJkcC0+d2l0aCA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJ3aXRoVGV4dCIsCgkJICAgIHhtVGV4dEZpZWxkV2lkZ2V0Q2xhc3MsCWlucHV0X2Zvcm0sCgkJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCQkgICAgWG1OdG9wV2lkZ2V0LCBmcmRwLT53aGF0LAoJCSAgICBYbU50b3BPZmZzZXQsIDQsCgkJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJCSAgICBYbU5yaWdodEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkJICAgIE5VTEwpOwoKCSAgICBYdEFkZENhbGxiYWNrKGZyZHAtPndpdGgsIFhtTmFjdGl2YXRlQ2FsbGJhY2ssCgkJICAgIGZpbmRfcmVwbGFjZV9jYWxsYmFjaywgKFh0UG9pbnRlcikgRlJEX1JfRklORE5FWFQpOwoKCSAgICBzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZShfKCJSZXBsYWNlIHdpdGg6IikpOwoJICAgIGxhYmVsX3dpdGggPSBYdFZhQ3JlYXRlTWFuYWdlZFdpZGdldCgid2l0aExhYmVsIiwKCQkgICAgeG1MYWJlbEdhZGdldENsYXNzLCBpbnB1dF9mb3JtLAoJCSAgICBYbU5sYWJlbFN0cmluZywgc3RyLAoJCSAgICBYbU5sZWZ0QXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCSAgICBYbU50b3BXaWRnZXQsIGZyZHAtPndoYXQsCgkJICAgIFhtTnRvcE9mZnNldCwgNCwKCQkgICAgWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQkgICAgTlVMTCk7CgkgICAgWG1TdHJpbmdGcmVlKHN0cik7CgkgICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QobGFiZWxfd2l0aCk7CgoJICAgIC8qCgkgICAgICogTWFrZSB0aGUgZW50cnkgYWN0aXZhdGlvbiBvbmx5IGNoYW5nZSB0aGUgaW5wdXQgZm9jdXMgb250byB0aGUKCSAgICAgKiB3aXRoIGl0ZW0uCgkgICAgICovCgkgICAgWHRBZGRDYWxsYmFjayhmcmRwLT53aGF0LCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCSAgICBlbnRyeV9hY3RpdmF0ZV9jYWxsYmFjaywgZnJkcC0+d2l0aCk7CgkgICAgWHRBZGRFdmVudEhhbmRsZXIoZnJkcC0+d2l0aCwgS2V5UHJlc3NNYXNrLCBGYWxzZSwKCQkJICAgIChYdEV2ZW50SGFuZGxlcilmaW5kX3JlcGxhY2Vfa2V5cHJlc3MsCgkJCSAgICAoWHRQb2ludGVyKSBmcmRwKTsKCgl9CgllbHNlCgl7CgkgICAgLyoKCSAgICAgKiBNYWtlIHRoZSBlbnRyeSBhY3RpdmF0aW9uIGRvIHRoZSBzZWFyY2guCgkgICAgICovCgkgICAgWHRBZGRDYWxsYmFjayhmcmRwLT53aGF0LCBYbU5hY3RpdmF0ZUNhbGxiYWNrLAoJCSAgICBmaW5kX3JlcGxhY2VfY2FsbGJhY2ssIChYdFBvaW50ZXIpRlJEX0ZJTkRORVhUKTsKCX0KCVh0QWRkRXZlbnRIYW5kbGVyKGZyZHAtPndoYXQsIEtleVByZXNzTWFzaywgRmFsc2UsCgkJCSAgICAoWHRFdmVudEhhbmRsZXIpZmluZF9yZXBsYWNlX2tleXByZXNzLAoJCQkgICAgKFh0UG9pbnRlcilmcmRwKTsKCgkvKiBHZXQgdGhlIG1heGltdW0gd2lkdGggYmV0d2VlbiB0aGUgbGFiZWwgd2lkZ2V0cyBhbmQgbGluZSB0aGVtIHVwLgoJICovCgluID0gMDsKCVh0U2V0QXJnKGFyZ3Nbbl0sIFhtTndpZHRoLCAmd2lkdGgpOyBuKys7CglYdEdldFZhbHVlcyhsYWJlbF93aGF0LCBhcmdzLCBuKTsKCXdpZGVzdCA9IHdpZHRoOwoJaWYgKGRvX3JlcGxhY2UpCgl7CgkgICAgWHRHZXRWYWx1ZXMobGFiZWxfd2l0aCwgYXJncywgbik7CgkgICAgaWYgKHdpZHRoID4gd2lkZXN0KQoJCXdpZGVzdCA9IHdpZHRoOwoJfQoKCVh0VmFTZXRWYWx1ZXMoZnJkcC0+d2hhdCwgWG1ObGVmdE9mZnNldCwgd2lkZXN0LCBOVUxMKTsKCWlmIChkb19yZXBsYWNlKQoJICAgIFh0VmFTZXRWYWx1ZXMoZnJkcC0+d2l0aCwgWG1ObGVmdE9mZnNldCwgd2lkZXN0LCBOVUxMKTsKCiAgICB9CgogICAgWHRNYW5hZ2VDaGlsZChpbnB1dF9mb3JtKTsKCiAgICB7CglXaWRnZXQgcmFkaW9fYm94OwoJV2lkZ2V0IHc7CgoJZnJhbWUgPSBYdFZhQ3JlYXRlV2lkZ2V0KCJkaXJlY3Rpb25GcmFtZSIsCgkJeG1GcmFtZVdpZGdldENsYXNzLCBmcmRwLT5kaWFsb2csCgkJWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfV0lER0VULAoJCVhtTnRvcFdpZGdldCwgaW5wdXRfZm9ybSwKCQlYbU50b3BPZmZzZXQsIDQsCgkJWG1OYm90dG9tQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCQlYbU5ib3R0b21PZmZzZXQsIDQsCgkJWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9PUFBPU0lURV9XSURHRVQsCgkJWG1OcmlnaHRXaWRnZXQsIGlucHV0X2Zvcm0sCgkJTlVMTCk7CgoJc3RyID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoXygiRGlyZWN0aW9uIikpOwoJdyA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJkaXJlY3Rpb25GcmFtZUxhYmVsIiwKCQl4bUxhYmVsR2FkZ2V0Q2xhc3MsIGZyYW1lLAoJCVhtTmxhYmVsU3RyaW5nLCBzdHIsCgkJWG1OY2hpbGRIb3Jpem9udGFsQWxpZ25tZW50LCBYbUFMSUdOTUVOVF9CRUdJTk5JTkcsCgkJWG1OY2hpbGRUeXBlLCBYbUZSQU1FX1RJVExFX0NISUxELAoJCU5VTEwpOwoJWG1TdHJpbmdGcmVlKHN0cik7CglndWlfbW90aWZfbWVudV9mb250bGlzdCh3KTsKCglyYWRpb19ib3ggPSBYbUNyZWF0ZVJhZGlvQm94KGZyYW1lLCAicmFkaW9Cb3giLAoJCShBcmdMaXN0KU5VTEwsIDApOwoKCXN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKCBfKCJVcCIpKTsKCWZyZHAtPnVwID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoInVwUmFkaW9CdXR0b24iLAoJCXhtVG9nZ2xlQnV0dG9uR2FkZ2V0Q2xhc3MsIHJhZGlvX2JveCwKCQlYbU5sYWJlbFN0cmluZywgc3RyLAoJCVhtTnNldCwgRmFsc2UsCgkJTlVMTCk7CglYbVN0cmluZ0ZyZWUoc3RyKTsKCWd1aV9tb3RpZl9tZW51X2ZvbnRsaXN0KGZyZHAtPnVwKTsKCglzdHIgPSBYbVN0cmluZ0NyZWF0ZVNpbXBsZShfKCJEb3duIikpOwoJZnJkcC0+ZG93biA9IFh0VmFDcmVhdGVNYW5hZ2VkV2lkZ2V0KCJkb3duUmFkaW9CdXR0b24iLAoJCXhtVG9nZ2xlQnV0dG9uR2FkZ2V0Q2xhc3MsIHJhZGlvX2JveCwKCQlYbU5sYWJlbFN0cmluZywgc3RyLAoJCVhtTnNldCwgVHJ1ZSwKCQlOVUxMKTsKCVhtU3RyaW5nRnJlZShzdHIpOwoJZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoZnJkcC0+ZG93bik7CgoJWHRNYW5hZ2VDaGlsZChyYWRpb19ib3gpOwoJWHRNYW5hZ2VDaGlsZChmcmFtZSk7CiAgICB9CgogICAgdG9nZ2xlX2Zvcm0gPSBYdFZhQ3JlYXRlV2lkZ2V0KCJ0b2dnbGVGb3JtIiwKCSAgICB4bUZvcm1XaWRnZXRDbGFzcywJZnJkcC0+ZGlhbG9nLAoJICAgIFhtTmxlZnRBdHRhY2htZW50LCBYbUFUVEFDSF9GT1JNLAoJICAgIFhtTmxlZnRPZmZzZXQsIDQsCgkgICAgWG1OcmlnaHRBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkgICAgWG1OcmlnaHRXaWRnZXQsIGZyYW1lLAoJICAgIFhtTnJpZ2h0T2Zmc2V0LCA0LAoJICAgIFhtTnRvcEF0dGFjaG1lbnQsIFhtQVRUQUNIX1dJREdFVCwKCSAgICBYbU50b3BXaWRnZXQsIGlucHV0X2Zvcm0sCgkgICAgWG1OdG9wT2Zmc2V0LCA0LAoJICAgIFhtTmJvdHRvbUF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1OYm90dG9tT2Zmc2V0LCA0LAoJICAgIE5VTEwpOwoKICAgIHN0ciA9IFhtU3RyaW5nQ3JlYXRlU2ltcGxlKF8oIk1hdGNoIHdob2xlIHdvcmQgb25seSIpKTsKICAgIGZyZHAtPnd3b3JkID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoIndvcmRUb2dnbGUiLAoJICAgIHhtVG9nZ2xlQnV0dG9uR2FkZ2V0Q2xhc3MsIHRvZ2dsZV9mb3JtLAoJICAgIFhtTmxhYmVsU3RyaW5nLCBzdHIsCgkgICAgWG1OdG9wQXR0YWNobWVudCwgWG1BVFRBQ0hfRk9STSwKCSAgICBYbU50b3BPZmZzZXQsIDQsCgkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1ObGVmdE9mZnNldCwgNCwKCSAgICBYbU5zZXQsIHd3b3JkLAoJICAgIE5VTEwpOwogICAgWG1TdHJpbmdGcmVlKHN0cik7CgogICAgc3RyID0gWG1TdHJpbmdDcmVhdGVTaW1wbGUoXygiTWF0Y2ggY2FzZSIpKTsKICAgIGZyZHAtPm1jYXNlID0gWHRWYUNyZWF0ZU1hbmFnZWRXaWRnZXQoImNhc2VUb2dnbGUiLAoJICAgIHhtVG9nZ2xlQnV0dG9uR2FkZ2V0Q2xhc3MsIHRvZ2dsZV9mb3JtLAoJICAgIFhtTmxhYmVsU3RyaW5nLCBzdHIsCgkgICAgWG1ObGVmdEF0dGFjaG1lbnQsIFhtQVRUQUNIX0ZPUk0sCgkgICAgWG1ObGVmdE9mZnNldCwgNCwKCSAgICBYbU50b3BBdHRhY2htZW50LCBYbUFUVEFDSF9XSURHRVQsCgkgICAgWG1OdG9wV2lkZ2V0LCBmcmRwLT53d29yZCwKCSAgICBYbU50b3BPZmZzZXQsIDQsCgkgICAgWG1Oc2V0LCBtY2FzZSwKCSAgICBOVUxMKTsKICAgIFhtU3RyaW5nRnJlZShzdHIpOwogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoZnJkcC0+d3dvcmQpOwogICAgZ3VpX21vdGlmX21lbnVfZm9udGxpc3QoZnJkcC0+bWNhc2UpOwoKICAgIFh0TWFuYWdlQ2hpbGQodG9nZ2xlX2Zvcm0pOwoKICAgIGlmIChlbnRyeV90ZXh0ICE9IE5VTEwpCglYbVRleHRGaWVsZFNldFN0cmluZyhmcmRwLT53aGF0LCAoY2hhciAqKWVudHJ5X3RleHQpOwogICAgdmltX2ZyZWUoZW50cnlfdGV4dCk7CgogICAgZ3VpX21vdGlmX3N5bmNoX2ZvbnRzKCk7CgogICAgbWFuYWdlX2NlbnRlcmVkKGZyZHAtPmRpYWxvZyk7CiAgICBhY3RpdmF0ZV9kaWFsb2dfbW5lbW9uaWNzKGZyZHAtPmRpYWxvZyk7CiAgICBYbVByb2Nlc3NUcmF2ZXJzYWwoZnJkcC0+d2hhdCwgWG1UUkFWRVJTRV9DVVJSRU5UKTsKfQoKICAgdm9pZApndWlfbWNoX2ZpbmRfZGlhbG9nKGVhcCkKICAgIGV4YXJnX1QJKmVhcDsKewogICAgaWYgKCFndWkuaW5fdXNlKQoJcmV0dXJuOwoKICAgIGZpbmRfcmVwbGFjZV9kaWFsb2dfY3JlYXRlKGVhcC0+YXJnLCBGQUxTRSk7Cn0KCgogICAgdm9pZApndWlfbWNoX3JlcGxhY2VfZGlhbG9nKGVhcCkKICAgIGV4YXJnX1QJKmVhcDsKewogICAgaWYgKCFndWkuaW5fdXNlKQoJcmV0dXJuOwoKICAgIGZpbmRfcmVwbGFjZV9kaWFsb2dfY3JlYXRlKGVhcC0+YXJnLCBUUlVFKTsKfQoKLyoKICogU3luY2hyb25pemUgYWxsIGd1aSBlbGVtZW50cywgd2hpY2ggYXJlIGRlcGVuZGFudCB1cG9uIHRoZQogKiBtYWluIHRleHQgZm9udCB1c2VkLiBUaG9zZSBhcmUgaW4gZXNwLiB0aGUgZmluZC9yZXBsYWNlIGRpYWxvZ3MuCiAqIElmIHlvdSBkb24ndCB1bmRlcnN0YW5kIHdoeSB0aGlzIHNob3VsZCBiZSBuZWVkZWQsIHBsZWFzZSB0cnkgdG8KICogc2VhcmNoIGZvciAicGnqtuYiIGluIGlzbzg4NTktMi4KICovCiAgICB2b2lkCmd1aV9tb3RpZl9zeW5jaF9mb250cyh2b2lkKQp7CiAgICBTaGFyZWRGaW5kUmVwbGFjZSAqZnJkcDsKICAgIGludAkJICAgIGRvX3JlcGxhY2U7CiAgICBYRm9udFN0cnVjdAkgICAgKmZvbnQ7CiAgICBYbUZvbnRMaXN0CSAgICBmb250X2xpc3Q7CgogICAgLyogRklYTUU6IFVubGVzcyB3ZSBmaW5kIG91dCBob3cgdG8gY3JlYXRlIGEgWG1Gb250TGlzdCBmcm9tIGEgWEZvbnRTZXQsCiAgICAgKiB3ZSBqdXN0IGdpdmUgdXAgaGVyZSBvbiBmb250IHN5bmNocm9uaXphdGlvbi4gKi8KICAgIGZvbnQgPSAoWEZvbnRTdHJ1Y3QgKilndWkubm9ybV9mb250OwogICAgaWYgKGZvbnQgPT0gTlVMTCkKCXJldHVybjsKCiAgICBmb250X2xpc3QgPSBndWlfbW90aWZfY3JlYXRlX2ZvbnRsaXN0KGZvbnQpOwoKICAgIC8qIE9LIHRoaXMgbG9vcCBpcyBhIGJpdCB0cmlja3kuLi4gKi8KICAgIGZvciAoZG9fcmVwbGFjZSA9IDA7IGRvX3JlcGxhY2UgPD0gMTsgKytkb19yZXBsYWNlKQogICAgewoJZnJkcCA9IChkb19yZXBsYWNlKSA/ICgmcmVwbF93aWRnZXRzKSA6ICgmZmluZF93aWRnZXRzKTsKCWlmIChmcmRwLT5kaWFsb2cpCgl7CgkgICAgWHRWYVNldFZhbHVlcyhmcmRwLT53aGF0LCBYbU5mb250TGlzdCwgZm9udF9saXN0LCBOVUxMKTsKCSAgICBpZiAoZG9fcmVwbGFjZSkKCQlYdFZhU2V0VmFsdWVzKGZyZHAtPndpdGgsIFhtTmZvbnRMaXN0LCBmb250X2xpc3QsIE5VTEwpOwoJfQogICAgfQoKICAgIFhtRm9udExpc3RGcmVlKGZvbnRfbGlzdCk7Cn0K