LyoKICogcmVhZF9jb25maWcuYwogKi8KLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgovKiogQGRlZmdyb3VwIHJlYWRfY29uZmlnIHBhcnNpbmcgdmFyaW91cyBjb25maWd1cmF0aW9uIGZpbGVzIGF0IHJ1biB0aW1lCiAqICBAaW5ncm91cCBsaWJyYXJ5CiAqCiAqIFRoZSByZWFkX2NvbmZpZyByZWxhdGVkIGZ1bmN0aW9ucyBhcmUgYSBmYWlybHkgZXh0ZW5zaWJsZSAgc3lzdGVtICBvZgogKiBwYXJzaW5nIHZhcmlvdXMgY29uZmlndXJhdGlvbiBmaWxlcyBhdCB0aGUgcnVuIHRpbWUuCiAqCiAqIFRoZSBpZGVhIGlzIHRoYXQgdGhlIGNhbGxpbmcgYXBwbGljYXRpb24gaXMgYWJsZSB0byByZWdpc3RlcgogKiBoYW5kbGVycyBmb3IgY2VydGFpbiB0b2tlbnMgc3BlY2lmaWVkIGluIGNlcnRhaW4gdHlwZXMKICogb2YgZmlsZXMuICBUaGUgcmVhZF9jb25maWdzIGZ1bmN0aW9uIGNhbiB0aGVuIGJlICBjYWxsZWQKICogdG8gIGxvb2sgIGZvciBhbGwgdGhlIGZpbGVzIHRoYXQgaXQgaGFzIHJlZ2lzdHJhdGlvbnMgZm9yLAogKiBmaW5kIHRoZSBmaXJzdCB3b3JkIG9uIGVhY2ggbGluZSwgYW5kIHBhc3MgIHRoZSAgcmVtYWluZGVyCiAqIHRvIHRoZSBhcHByb3ByaWF0ZWx5IHJlZ2lzdGVyZWQgaGFuZGxlci4KICoKICogRm9yIHBlcnNpc3RlbnQgY29uZmlndXJhdGlvbiBzdG9yYWdlIHlvdSB3aWxsIG5lZWQgdG8gdXNlIHRoZQogKiByZWFkX2NvbmZpZ19yZWFkX2RhdGEsIHJlYWRfY29uZmlnX3N0b3JlLCBhbmQgcmVhZF9jb25maWdfc3RvcmVfZGF0YQogKiBBUElzIGluIGNvbmp1bmN0aW9uIHdpdGggZmlyc3QgcmVnaXN0ZXJpbmcgYQogKiBjYWxsYmFjayBzbyB3aGVuIHRoZSBhZ2VudCBzaHV0c2Rvd24gZm9yIHdoYXRldmVyIHJlYXNvbiBkYXRhIGlzIHdyaXR0ZW4KICogdG8geW91ciBjb25maWd1cmF0aW9uIGZpbGVzLiAgVGhlIGZvbGxvd2luZyBleHBsYWlucyBpbiBtb3JlIGRldGFpbCB0aGUKICogc2VxdWVuY2UgdG8gbWFrZSB0aGlzIGhhcHBlbi4KICoKICogVGhpcyBpcyB0aGUgY2FsbGJhY2sgcmVnaXN0cmF0aW9uIEFQSSwgeW91IG5lZWQgdG8gY2FsbCB0aGlzIEFQSSB3aXRoCiAqIHRoZSBhcHByb3ByaWF0ZSBwYXJhbWV0ZXJzIGluIG9yZGVyIHRvIGNvbmZpZ3VyZSBwZXJzaXN0ZW50IHN0b3JhZ2UgbmVlZHMuCiAqCiAqICAgICAgICBpbnQgc25tcF9yZWdpc3Rlcl9jYWxsYmFjayhpbnQgbWFqb3IsIGludCBtaW5vciwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBDYWxsYmFjayAqbmV3X2NhbGxiYWNrLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqYXJnKTsKICoKICogWW91IHdpbGwgbmVlZCB0byBzZXQgbWFqb3IgdG8gU05NUF9DQUxMQkFDS19MSUJSQVJZLCBtaW5vciB0bwogKiBTTk1QX0NBTExCQUNLX1NUT1JFX0RBVEEuIGFyZyBpcyB3aGF0ZXZlciB5b3Ugd2FudC4KICoKICogWW91ciBjYWxsYmFjayBmdW5jdGlvbidzIHByb3RvdHlwZSBpczoKICogaW50ICAgICAoU05NUENhbGxiYWNrKSAoaW50IG1ham9ySUQsIGludCBtaW5vcklELCB2b2lkICpzZXJ2ZXJhcmcsCiAqICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xpZW50YXJnKTsKICoKICogVGhlIG1ham9ySUQsIG1pbm9ySUQgYW5kIGNsaWVudGFyZyBhcmUgd2hhdCB5b3UgcGFzc2VkIGluIHRoZSBjYWxsYmFjawogKiByZWdpc3RyYXRpb24gYWJvdmUuICBXaGVuIHRoZSBjYWxsYmFjayBpcyBjYWxsZWQgeW91IGhhdmUgdG8gZXNzZW50aWFsbHkKICogdHJhbnNmZXIgYWxsIHlvdXIgc3RhdGUgZnJvbSBtZW1vcnkgdG8gZGlzay4gWW91IGRvIHRoaXMgYnkgZ2VuZXJhdGluZwogKiBjb25maWd1cmF0aW9uIGxpbmVzIGludG8gYSBidWZmZXIuICBUaGUgbGluZXMgYXJlIG9mIHRoZSBmb3JtIHRva2VuCiAqIGZvbGxvd2VkIGJ5IHRva2VuIHBhcmFtZXRlcnMuCiAqIAogKiBGaW5hbGx5IHN0b3JpbmcgaXMgZG9uZSB1c2luZyByZWFkX2NvbmZpZ19zdG9yZSh0eXBlLCBidWZmZXIpOwogKiB0eXBlIGlzIHRoZSBhcHBsaWNhdGlvbiBuYW1lIHRoaXMgY2FuIGJlIG9idGFpbmVkIGZyb206CiAqCiAqIG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpOwogKgogKiBOb3csIHJlYWRpbmcgYmFjayB0aGUgZGF0YTogVGhpcyBpcyBkb25lIGJ5IHJlZ2lzdGVyaW5nIGEgY29uZmlnIGhhbmRsZXIKICogZm9yIHlvdXIgdG9rZW4gdXNpbmcgdGhlIHJlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyIGZ1bmN0aW9uLiBZb3VyCiAqIGhhbmRsZXIgd2lsbCBiZSBpbnZva2VkIGFuZCB5b3UgY2FuIHBhcnNlIGluIHRoZSBkYXRhIHVzaW5nIHRoZQogKiByZWFkX2NvbmZpZ19yZWFkIEFQSXMuCiAqCiAqICBAewogKi8KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtZmVhdHVyZXMuaD4KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWYgSEFWRV9TWVNfUEFSQU1fSAojaW5jbHVkZSA8c3lzL3BhcmFtLmg+CiNlbmRpZgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBpbmNsdWRlIDx0aW1lLmg+CiNlbHNlCiMgaWYgSEFWRV9TWVNfVElNRV9ICiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZWxzZQojICBpbmNsdWRlIDx0aW1lLmg+CiMgZW5kaWYKI2VuZGlmCiNpZmRlZiBIQVZFX1NZU19TVEFUX0gKI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZiBIQVZFX0FSUEFfSU5FVF9ICiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2VuZGlmCiNpZiBIQVZFX1NZU19TRUxFQ1RfSAojaW5jbHVkZSA8c3lzL3NlbGVjdC5oPgojZW5kaWYKI2lmIEhBVkVfU1lTX1NPQ0tFVF9ICiNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNlbmRpZgojaWYgSEFWRV9ORVREQl9ICiNpbmNsdWRlIDxuZXRkYi5oPgojZW5kaWYKI2luY2x1ZGUgPGVycm5vLmg+CgojaWYgSEFWRV9ESVJFTlRfSAojIGluY2x1ZGUgPGRpcmVudC5oPgojIGRlZmluZSBOQU1MRU4oZGlyZW50KSBzdHJsZW4oKGRpcmVudCktPmRfbmFtZSkKI2Vsc2UKIyBkZWZpbmUgZGlyZW50IGRpcmVjdAojIGRlZmluZSBOQU1MRU4oZGlyZW50KSAoZGlyZW50KS0+ZF9uYW1sZW4KIyBpZiBIQVZFX1NZU19ORElSX0gKIyAgaW5jbHVkZSA8c3lzL25kaXIuaD4KIyBlbmRpZgojIGlmIEhBVkVfU1lTX0RJUl9ICiMgIGluY2x1ZGUgPHN5cy9kaXIuaD4KIyBlbmRpZgojIGlmIEhBVkVfTkRJUl9ICiMgIGluY2x1ZGUgPG5kaXIuaD4KIyBlbmRpZgojZW5kaWYKCiNpZiBIQVZFX0RNQUxMT0NfSAojaW5jbHVkZSA8ZG1hbGxvYy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC90eXBlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvb3V0cHV0X2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvY29uZmlnX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9yZWFkX2NvbmZpZy5oPiAgICAgICAvKiBmb3IgImludGVybmFsIiBkZWZpbml0aW9ucyAqLwojaW5jbHVkZSA8bmV0LXNubXAvdXRpbGl0aWVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9taWIuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvcGFyc2UuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcF9hcGkuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvY2FsbGJhY2suaD4KCm5ldHNubXBfZmVhdHVyZV9jaGlsZF9vZihyZWFkX2NvbmZpZ19hbGwsIGxpYm5ldHNubXApCgpuZXRzbm1wX2ZlYXR1cmVfY2hpbGRfb2YodW5yZWdpc3Rlcl9hcHBfY29uZmlnX2hhbmRsZXIsIHJlYWRfY29uZmlnX2FsbCkKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHJlYWRfY29uZmlnX3JlZ2lzdGVyX2FwcF9wcmVuZXRzbm1wX21pYl9oYW5kbGVyLCBuZXRzbm1wX3VudXNlZCkKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHJlYWRfY29uZmlnX3JlZ2lzdGVyX2NvbnN0X2NvbmZpZ19oYW5kbGVyLCBuZXRzbm1wX3VudXNlZCkKCnN0YXRpYyBpbnQgICAgICBjb25maWdfZXJyb3JzOwoKc3RydWN0IGNvbmZpZ19maWxlcyAqY29uZmlnX2ZpbGVzID0gTlVMTDsKCgpzdGF0aWMgc3RydWN0IGNvbmZpZ19saW5lICoKaW50ZXJuYWxfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoY29uc3QgY2hhciAqdHlwZV9wYXJhbSwKCQkJCSBjb25zdCBjaGFyICp0b2tlbiwKCQkJCSB2b2lkICgqcGFyc2VyKSAoY29uc3QgY2hhciAqLCBjaGFyICopLAoJCQkJIHZvaWQgKCpyZWxlYXNlcikgKHZvaWQpLCBjb25zdCBjaGFyICpoZWxwLAoJCQkJIGludCB3aGVuKQp7CiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICoqY3RtcCA9ICZjb25maWdfZmlsZXM7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgICoqbHRtcDsKICAgIGNvbnN0IGNoYXIgICAgICAgICAgICp0eXBlID0gdHlwZV9wYXJhbTsKCiAgICBpZiAodHlwZSA9PSBOVUxMIHx8ICp0eXBlID09ICdcMCcpIHsKICAgICAgICB0eXBlID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpOwogICAgfQoKICAgIC8qCiAgICAgKiBIYW5kbGUgbXVsdGlwbGUgdHlwZXMgKHJlY3Vyc2l2ZWx5KQogICAgICovCiAgICBpZiAoc3RyY2hyKHR5cGUsICc6JykpIHsKICAgICAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmx0bXAyID0gTlVMTDsKICAgICAgICBjaGFyICAgICAgICAgICAgICAgIGJ1ZltTVFJJTkdNQVhdOwogICAgICAgIGNoYXIgICAgICAgICAgICAgICAqY3B0ciA9IGJ1ZjsKCiAgICAgICAgc3RybGNweShidWYsIHR5cGUsIFNUUklOR01BWCk7CiAgICAgICAgd2hpbGUgKGNwdHIpIHsKICAgICAgICAgICAgY2hhciogYyA9IGNwdHI7CiAgICAgICAgICAgIGNwdHIgPSBzdHJjaHIoY3B0ciwgJzonKTsKICAgICAgICAgICAgaWYoY3B0cikgewogICAgICAgICAgICAgICAgKmNwdHIgPSAnXDAnOwogICAgICAgICAgICAgICAgKytjcHRyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGx0bXAyID0gaW50ZXJuYWxfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoYywgdG9rZW4sIHBhcnNlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxlYXNlciwgaGVscCwgd2hlbik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsdG1wMjsKICAgIH0KICAgIAogICAgLyoKICAgICAqIEZpbmQgdHlwZSBpbiBjdXJyZW50IGxpc3QgIC1PUi0gIGNyZWF0ZSBhIG5ldyBmaWxlIHR5cGUuCiAgICAgKi8KICAgIHdoaWxlICgqY3RtcCAhPSBOVUxMICYmIHN0cmNtcCgoKmN0bXApLT5maWxlSGVhZGVyLCB0eXBlKSkgewogICAgICAgIGN0bXAgPSAmKCgqY3RtcCktPm5leHQpOwogICAgfQoKICAgIGlmICgqY3RtcCA9PSBOVUxMKSB7CiAgICAgICAgKmN0bXAgPSAoc3RydWN0IGNvbmZpZ19maWxlcyAqKQogICAgICAgICAgICBjYWxsb2MoMSwgc2l6ZW9mKHN0cnVjdCBjb25maWdfZmlsZXMpKTsKICAgICAgICBpZiAoISpjdG1wKSB7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KCiAgICAgICAgKCpjdG1wKS0+ZmlsZUhlYWRlciA9IHN0cmR1cCh0eXBlKTsKICAgICAgICBERUJVR01TR1RMKCgiOTpyZWFkX2NvbmZpZzp0eXBlIiwgIm5ldyB0eXBlICVzXG4iLCB0eXBlKSk7CiAgICB9CgogICAgREVCVUdNU0dUTCgoIjk6cmVhZF9jb25maWc6cmVnaXN0ZXJfaGFuZGxlciIsICJyZWdpc3RlcmluZyAlcyAlc1xuIiwKICAgICAgICAgICAgICAgIHR5cGUsIHRva2VuKSk7CiAgICAvKgogICAgICogRmluZCBwYXJzZXIgdHlwZSBpbiBjdXJyZW50IGxpc3QgIC1PUi0gIGNyZWF0ZSBhIG5ldwogICAgICogbGluZSBwYXJzZXIgZW50cnkuCiAgICAgKi8KICAgIGx0bXAgPSAmKCgqY3RtcCktPnN0YXJ0KTsKCiAgICB3aGlsZSAoKmx0bXAgIT0gTlVMTCAmJiBzdHJjbXAoKCpsdG1wKS0+Y29uZmlnX3Rva2VuLCB0b2tlbikpIHsKICAgICAgICBsdG1wID0gJigoKmx0bXApLT5uZXh0KTsKICAgIH0KCiAgICBpZiAoKmx0bXAgPT0gTlVMTCkgewogICAgICAgICpsdG1wID0gKHN0cnVjdCBjb25maWdfbGluZSAqKQogICAgICAgICAgICBjYWxsb2MoMSwgc2l6ZW9mKHN0cnVjdCBjb25maWdfbGluZSkpOwogICAgICAgIGlmICghKmx0bXApIHsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQoKICAgICAgICAoKmx0bXApLT5jb25maWdfdGltZSA9IHdoZW47CiAgICAgICAgKCpsdG1wKS0+Y29uZmlnX3Rva2VuID0gc3RyZHVwKHRva2VuKTsKICAgICAgICBpZiAoaGVscCAhPSBOVUxMKQogICAgICAgICAgICAoKmx0bXApLT5oZWxwID0gc3RyZHVwKGhlbHApOwogICAgfQoKICAgIC8qCiAgICAgKiBBZGQvUmVwbGFjZSB0aGUgcGFyc2UvZnJlZSBmdW5jdGlvbnMgZm9yIHRoZSBnaXZlbiBsaW5lIHR5cGUKICAgICAqIGluIHRoZSBnaXZlbiBmaWxlIHR5cGUuCiAgICAgKi8KICAgICgqbHRtcCktPnBhcnNlX2xpbmUgPSBwYXJzZXI7CiAgICAoKmx0bXApLT5mcmVlX2Z1bmMgPSByZWxlYXNlcjsKCiAgICByZXR1cm4gKCpsdG1wKTsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHJlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCkgKi8KCnN0cnVjdCBjb25maWdfbGluZSAqCnJlZ2lzdGVyX3ByZW5ldHNubXBfbWliX2hhbmRsZXIoY29uc3QgY2hhciAqdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqcGFyc2VyKSAoY29uc3QgY2hhciAqLCBjaGFyICopLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKCpyZWxlYXNlcikgKHZvaWQpLCBjb25zdCBjaGFyICpoZWxwKQp7CiAgICByZXR1cm4gaW50ZXJuYWxfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIodHlwZSwgdG9rZW4sIHBhcnNlciwgcmVsZWFzZXIsCgkJCQkJICAgIGhlbHAsIFBSRU1JQl9DT05GSUcpOwp9CgojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfUkVBRF9DT05GSUdfUkVHSVNURVJfQVBQX1BSRU5FVFNOTVBfTUlCX0hBTkRMRVIKc3RydWN0IGNvbmZpZ19saW5lICoKcmVnaXN0ZXJfYXBwX3ByZW5ldHNubXBfbWliX2hhbmRsZXIoY29uc3QgY2hhciAqdG9rZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKCpwYXJzZXIpIChjb25zdCBjaGFyICosIGNoYXIgKiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKCpyZWxlYXNlcikgKHZvaWQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpoZWxwKQp7CiAgICByZXR1cm4gKHJlZ2lzdGVyX3ByZW5ldHNubXBfbWliX2hhbmRsZXIKICAgICAgICAgICAgKE5VTEwsIHRva2VuLCBwYXJzZXIsIHJlbGVhc2VyLCBoZWxwKSk7Cn0KI2VuZGlmIC8qIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfUkVBRF9DT05GSUdfUkVHSVNURVJfQVBQX1BSRU5FVFNOTVBfTUlCX0hBTkRMRVIgKi8KCi8qKgogKiByZWdpc3Rlcl9jb25maWdfaGFuZGxlciByZWdpc3RlcnMgaGFuZGxlcnMgZm9yIGNlcnRhaW4gdG9rZW5zIHNwZWNpZmllZCBpbgogKiBjZXJ0YWluIHR5cGVzIG9mIGZpbGVzLgogKgogKiBBbGxvd3MgYSBtb2R1bGUgd3JpdGVyIHVzZS9yZWdpc3RlciBtdWx0aXBsZSBjb25maWd1cmF0aW9uIGZpbGVzIGJhc2VkIG9mZgogKiBvZiB0aGUgdHlwZSBwYXJhbWV0ZXIuICBBIG1vZHVsZSB3cml0ZXIgbWF5IHdhbnQgdG8gc2V0IHVwIG11bHRpcGxlCiAqIGNvbmZpZ3VyYXRpb24gZmlsZXMgdG8gc2VwYXJhdGUgb3V0IHJlbGF0ZWQgdGFza3MvdmFyaWFibGVzIG9yIGp1c3QgZm9yCiAqIG1hbmFnZW1lbnQgb2Ygd2hlcmUgdG8gcHV0IHRva2VucyBhcyB0aGUgbW9kdWxlIG9yIG1vZHVsZXMgZ2V0IG1vcmUgY29tcGxleAogKiBpbiByZWdhcmQgdG8gaGFuZGxpbmcgdG9rZW4gcmVnaXN0cmF0aW9ucy4KICoKICogQHBhcmFtIHR5cGUgICAgIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgdXNlZCwgZS5nLiwgaWYgc25tcC5jb25mIGlzIHRoZQogKiAgICAgICAgICAgICAgICAgZmlsZSB3aGVyZSB0aGUgdG9rZW4gaXMgbG9jYXRlZCB1c2UgInNubXAiIGhlcmUuCiAqICAgICAgICAgICAgICAgICBNdWx0aXBsZSBjb2xvbiBzZXBhcmF0ZWQgdG9rZW5zIG1pZ2h0IGJlIHVzZWQuCiAqICAgICAgICAgICAgICAgICBJZiBOVUxMIG9yICIiIHRoZW4gdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSB1c2VkIHdpbGwgYmUKICogICAgICAgICAgICAgICAgIFw8YXBwbGljYXRpb25cPi5jb25mLgogKgogKiBAcGFyYW0gdG9rZW4gICAgdGhlIHRva2VuIGJlaW5nIHBhcnNlZCBmcm9tIHRoZSBmaWxlLiAgTXVzdCBiZSBub24tTlVMTC4KICoKICogQHBhcmFtIHBhcnNlciAgIHRoZSBoYW5kbGVyIGZ1bmN0aW9uIHBvaW50ZXIgdGhhdCB1c2UgIHRoZSBzcGVjaWZpZWQKICogICAgICAgICAgICAgICAgIHRva2VuIGFuZCB0aGUgcmVzdCBvZiB0aGUgbGluZSB0byBkbyB3aGF0ZXZlciBpcyByZXF1aXJlZAogKiAgICAgICAgICAgICAgICAgU2hvdWxkIGJlIG5vbi1OVUxMIGluIG9yZGVyIHRvIG1ha2UgdXNlIG9mIHRoaXMgQVBJLgogKgogKiBAcGFyYW0gcmVsZWFzZXIgaWYgbm9uLU5VTEwsIHRoZSBmdW5jdGlvbiBzcGVjaWZpZWQgaXMgY2FsbGVkIHdoZW4KICogICAgICAgICAgICAgICAgIHVucmVnaXN0ZXJpbmcgY29uZmlnIGhhbmRsZXIgb3Igd2hlbiBjb25maWd1cmF0aW9uCiAqICAgICAgICAgICAgICAgICBmaWxlcyBhcmUgcmUtcmVhZC4KICogICAgICAgICAgICAgICAgIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGZyZWUgYW55IHJlc291cmNlcyBhbGxvY2F0ZWQgYnkKICogICAgICAgICAgICAgICAgIHRoZSB0b2tlbiBoYW5kbGVyIGZ1bmN0aW9uLgogKgogKiBAcGFyYW0gaGVscCAgICAgaWYgbm9uLU5VTEwsIHVzZWQgdG8gZGlzcGxheSBoZWxwIGluZm9ybWF0aW9uIG9uIHRoZQogKiAgICAgICAgICAgICAgICAgZXhwZWN0ZWQgYXJndW1lbnRzIGFmdGVyIHRoZSB0b2tlbi4KICoKICogQHJldHVybiBQb2ludGVyIHRvIGEgbmV3IGNvbmZpZyBsaW5lIGVudHJ5IG9yIE5VTEwgb24gZXJyb3IuCiAqLwpzdHJ1Y3QgY29uZmlnX2xpbmUgKgpyZWdpc3Rlcl9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0eXBlLAoJCQljb25zdCBjaGFyICp0b2tlbiwKCQkJdm9pZCAoKnBhcnNlcikgKGNvbnN0IGNoYXIgKiwgY2hhciAqKSwKCQkJdm9pZCAoKnJlbGVhc2VyKSAodm9pZCksIGNvbnN0IGNoYXIgKmhlbHApCnsKICAgIHJldHVybiBpbnRlcm5hbF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcih0eXBlLCB0b2tlbiwgcGFyc2VyLCByZWxlYXNlciwKCQkJCQkgICAgaGVscCwgTk9STUFMX0NPTkZJRyk7Cn0KCiNpZm5kZWYgTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9SRUFEX0NPTkZJR19SRUdJU1RFUl9DT05TVF9DT05GSUdfSEFORExFUgpzdHJ1Y3QgY29uZmlnX2xpbmUgKgpyZWdpc3Rlcl9jb25zdF9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAoKnBhcnNlcikgKGNvbnN0IGNoYXIgKiwgY29uc3QgY2hhciAqKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAoKnJlbGVhc2VyKSAodm9pZCksIGNvbnN0IGNoYXIgKmhlbHApCnsKICAgIHJldHVybiBpbnRlcm5hbF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcih0eXBlLCB0b2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCgqKShjb25zdCBjaGFyICosIGNoYXIgKikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLCByZWxlYXNlciwKCQkJCQkgICAgaGVscCwgTk9STUFMX0NPTkZJRyk7Cn0KI2VuZGlmIC8qIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfUkVBRF9DT05GSUdfUkVHSVNURVJfQ09OU1RfQ09ORklHX0hBTkRMRVIgKi8KCnN0cnVjdCBjb25maWdfbGluZSAqCnJlZ2lzdGVyX2FwcF9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0b2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKCpwYXJzZXIpIChjb25zdCBjaGFyICosIGNoYXIgKiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqcmVsZWFzZXIpICh2b2lkKSwgY29uc3QgY2hhciAqaGVscCkKewogICAgcmV0dXJuIChyZWdpc3Rlcl9jb25maWdfaGFuZGxlcihOVUxMLCB0b2tlbiwgcGFyc2VyLCByZWxlYXNlciwgaGVscCkpOwp9CgoKCi8qKgogKiB1cmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIgdW4tcmVnaXN0ZXJzIGhhbmRsZXJzIGdpdmVuIGEgc3BlY2lmaWMgdHlwZV9wYXJhbQogKiBhbmQgdG9rZW4uCiAqCiAqIEBwYXJhbSB0eXBlX3BhcmFtIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgdXNlZCB3aGVyZSB0aGUgdG9rZW4gaXMgbG9jYXRlZC4KICogICAgICAgICAgICAgICAgICAgVXNlZCB0byBsb29rdXAgdGhlIGNvbmZpZyBmaWxlIGVudHJ5CiAqIAogKiBAcGFyYW0gdG9rZW4gICAgICB0aGUgdG9rZW4gdGhhdCBpcyBiZWluZyB1bnJlZ2lzdGVyZWQKICoKICogQHJldHVybiB2b2lkCiAqLwp2b2lkCnVucmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoY29uc3QgY2hhciAqdHlwZV9wYXJhbSwgY29uc3QgY2hhciAqdG9rZW4pCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKipjdG1wID0gJmNvbmZpZ19maWxlczsKICAgIHN0cnVjdCBjb25maWdfbGluZSAgKipsdG1wOwogICAgY29uc3QgY2hhciAgICAgICAgICAgKnR5cGUgPSB0eXBlX3BhcmFtOwoKICAgIGlmICh0eXBlID09IE5VTEwgfHwgKnR5cGUgPT0gJ1wwJykgewogICAgICAgIHR5cGUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgTkVUU05NUF9EU19MSUJfQVBQVFlQRSk7CiAgICB9CgogICAgLyoKICAgICAqIEhhbmRsZSBtdWx0aXBsZSB0eXBlcyAocmVjdXJzaXZlbHkpCiAgICAgKi8KICAgIGlmIChzdHJjaHIodHlwZSwgJzonKSkgewogICAgICAgIGNoYXIgICAgICAgICAgICAgICAgYnVmW1NUUklOR01BWF07CiAgICAgICAgY2hhciAgICAgICAgICAgICAgICpjcHRyID0gYnVmOwoKICAgICAgICBzdHJsY3B5KGJ1ZiwgdHlwZSwgU1RSSU5HTUFYKTsKICAgICAgICB3aGlsZSAoY3B0cikgewogICAgICAgICAgICBjaGFyKiBjID0gY3B0cjsKICAgICAgICAgICAgY3B0ciA9IHN0cmNocihjcHRyLCAnOicpOwogICAgICAgICAgICBpZihjcHRyKSB7CiAgICAgICAgICAgICAgICAqY3B0ciA9ICdcMCc7CiAgICAgICAgICAgICAgICArK2NwdHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihjLCB0b2tlbik7CiAgICAgICAgfQogICAgICAgIHJldHVybjsKICAgIH0KICAgIAogICAgLyoKICAgICAqIGZpbmQgdHlwZSBpbiBjdXJyZW50IGxpc3QgCiAgICAgKi8KICAgIHdoaWxlICgqY3RtcCAhPSBOVUxMICYmIHN0cmNtcCgoKmN0bXApLT5maWxlSGVhZGVyLCB0eXBlKSkgewogICAgICAgIGN0bXAgPSAmKCgqY3RtcCktPm5leHQpOwogICAgfQoKICAgIGlmICgqY3RtcCA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBOb3QgZm91bmQsIHJldHVybi4gCiAgICAgICAgICovCiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGx0bXAgPSAmKCgqY3RtcCktPnN0YXJ0KTsKICAgIGlmICgqbHRtcCA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBOb3QgZm91bmQsIHJldHVybi4gCiAgICAgICAgICovCiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKHN0cmNtcCgoKmx0bXApLT5jb25maWdfdG9rZW4sIHRva2VuKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBmb3VuZCBpdCBhdCB0aGUgdG9wIG9mIHRoZSBsaXN0IAogICAgICAgICAqLwogICAgICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHRtcDIgPSAoKmx0bXApLT5uZXh0OwogICAgICAgIGlmICgoKmx0bXApLT5mcmVlX2Z1bmMpCiAgICAgICAgICAgICgqbHRtcCktPmZyZWVfZnVuYygpOwogICAgICAgIFNOTVBfRlJFRSgoKmx0bXApLT5jb25maWdfdG9rZW4pOwogICAgICAgIFNOTVBfRlJFRSgoKmx0bXApLT5oZWxwKTsKICAgICAgICBTTk1QX0ZSRUUoKmx0bXApOwogICAgICAgICgqY3RtcCktPnN0YXJ0ID0gbHRtcDI7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgd2hpbGUgKCgqbHRtcCktPm5leHQgIT0gTlVMTAogICAgICAgICAgICYmIHN0cmNtcCgoKmx0bXApLT5uZXh0LT5jb25maWdfdG9rZW4sIHRva2VuKSkgewogICAgICAgIGx0bXAgPSAmKCgqbHRtcCktPm5leHQpOwogICAgfQogICAgaWYgKCgqbHRtcCktPm5leHQgIT0gTlVMTCkgewogICAgICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHRtcDIgPSAoKmx0bXApLT5uZXh0LT5uZXh0OwogICAgICAgIGlmICgoKmx0bXApLT5uZXh0LT5mcmVlX2Z1bmMpCiAgICAgICAgICAgICgqbHRtcCktPm5leHQtPmZyZWVfZnVuYygpOwogICAgICAgIFNOTVBfRlJFRSgoKmx0bXApLT5uZXh0LT5jb25maWdfdG9rZW4pOwogICAgICAgIFNOTVBfRlJFRSgoKmx0bXApLT5uZXh0LT5oZWxwKTsKICAgICAgICBTTk1QX0ZSRUUoKCpsdG1wKS0+bmV4dCk7CiAgICAgICAgKCpsdG1wKS0+bmV4dCA9IGx0bXAyOwogICAgfQp9CgojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfVU5SRUdJU1RFUl9BUFBfQ09ORklHX0hBTkRMRVIKdm9pZAp1bnJlZ2lzdGVyX2FwcF9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0b2tlbikKewogICAgdW5yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihOVUxMLCB0b2tlbik7Cn0KI2VuZGlmIC8qIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfVU5SRUdJU1RFUl9BUFBfQ09ORklHX0hBTkRMRVIgKi8KCnZvaWQKdW5yZWdpc3Rlcl9hbGxfY29uZmlnX2hhbmRsZXJzKHZvaWQpCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAsICpzYXZlOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpsdG1wOwoKICAgIC8qCiAgICAgKiBLZWVwIHVzaW5nIGNvbmZpZ19maWxlcyB1bnRpbCB0aGVyZSBhcmUgbm8gbW9yZSEgCiAgICAgKi8KICAgIGZvciAoY3RtcCA9IGNvbmZpZ19maWxlczsgY3RtcDspIHsKICAgICAgICBmb3IgKGx0bXAgPSBjdG1wLT5zdGFydDsgbHRtcDsgbHRtcCA9IGN0bXAtPnN0YXJ0KSB7CiAgICAgICAgICAgIHVucmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoY3RtcC0+ZmlsZUhlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsdG1wLT5jb25maWdfdG9rZW4pOwogICAgICAgIH0KICAgICAgICBTTk1QX0ZSRUUoY3RtcC0+ZmlsZUhlYWRlcik7CiAgICAgICAgc2F2ZSA9IGN0bXAtPm5leHQ7CiAgICAgICAgU05NUF9GUkVFKGN0bXApOwogICAgICAgIGN0bXAgPSBzYXZlOwogICAgICAgIGNvbmZpZ19maWxlcyA9IHNhdmU7CiAgICB9Cn0KCiNpZmRlZiBURVNUSU5HCnZvaWQKcHJpbnRfY29uZmlnX2hhbmRsZXJzKHZvaWQpCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAgPSBjb25maWdfZmlsZXM7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmx0bXA7CgogICAgZm9yICg7IGN0bXAgIT0gTlVMTDsgY3RtcCA9IGN0bXAtPm5leHQpIHsKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAicmVhZF9jb25mOiAlc1xuIiwgY3RtcC0+ZmlsZUhlYWRlcikpOwogICAgICAgIGZvciAobHRtcCA9IGN0bXAtPnN0YXJ0OyBsdG1wICE9IE5VTEw7IGx0bXAgPSBsdG1wLT5uZXh0KQogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAiICAgICAgICAgICAgICAgICAgICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBsdG1wLT5jb25maWdfdG9rZW4pKTsKICAgIH0KfQojZW5kaWYKCnN0YXRpYyB1bnNpZ25lZCBpbnQgIGxpbmVjb3VudDsKc3RhdGljIGNvbnN0IGNoYXIgICAqY3VyZmlsZW5hbWU7CgpzdHJ1Y3QgY29uZmlnX2xpbmUgKgpyZWFkX2NvbmZpZ19nZXRfaGFuZGxlcnMoY29uc3QgY2hhciAqdHlwZSkKewogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCA9IGNvbmZpZ19maWxlczsKICAgIGZvciAoOyBjdG1wICE9IE5VTEwgJiYgc3RyY21wKGN0bXAtPmZpbGVIZWFkZXIsIHR5cGUpOwogICAgICAgICBjdG1wID0gY3RtcC0+bmV4dCk7CiAgICBpZiAoY3RtcCkKICAgICAgICByZXR1cm4gY3RtcC0+c3RhcnQ7CiAgICByZXR1cm4gTlVMTDsKfQoKaW50CnJlYWRfY29uZmlnX3dpdGhfdHlwZV93aGVuKGNvbnN0IGNoYXIgKmZpbGVuYW1lLCBjb25zdCBjaGFyICp0eXBlLCBpbnQgd2hlbikKewogICAgc3RydWN0IGNvbmZpZ19saW5lICpjdG1wID0gcmVhZF9jb25maWdfZ2V0X2hhbmRsZXJzKHR5cGUpOwogICAgaWYgKGN0bXApCiAgICAgICAgcmV0dXJuIHJlYWRfY29uZmlnKGZpbGVuYW1lLCBjdG1wLCB3aGVuKTsKICAgIGVsc2UKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLAogICAgICAgICAgICAgICAgICAgICJyZWFkX2NvbmZpZzogSSBoYXZlIG5vIHJlZ2lzdHJhdGlvbnMgZm9yIHR5cGU6JXMsZmlsZTolc1xuIiwKICAgICAgICAgICAgICAgICAgICB0eXBlLCBmaWxlbmFtZSkpOwogICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOyAgICAgLyogTm8gY29uZmlnIGZpbGVzIHJlYWQgKi8KfQoKaW50CnJlYWRfY29uZmlnX3dpdGhfdHlwZShjb25zdCBjaGFyICpmaWxlbmFtZSwgY29uc3QgY2hhciAqdHlwZSkKewogICAgcmV0dXJuIHJlYWRfY29uZmlnX3dpdGhfdHlwZV93aGVuKGZpbGVuYW1lLCB0eXBlLCBFSVRIRVJfQ09ORklHKTsKfQoKCnN0cnVjdCBjb25maWdfbGluZSAqCnJlYWRfY29uZmlnX2ZpbmRfaGFuZGxlcihzdHJ1Y3QgY29uZmlnX2xpbmUgKmxpbmVfaGFuZGxlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2tlbikKewogICAgc3RydWN0IGNvbmZpZ19saW5lICpscHRyOwoKICAgIGZvciAobHB0ciA9IGxpbmVfaGFuZGxlcnM7IGxwdHIgIT0gTlVMTDsgbHB0ciA9IGxwdHItPm5leHQpIHsKICAgICAgICBpZiAoIXN0cmNhc2VjbXAodG9rZW4sIGxwdHItPmNvbmZpZ190b2tlbikpIHsKICAgICAgICAgICAgcmV0dXJuIGxwdHI7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCgovKgogKiBzZWFyY2hlcyBhIGNvbmZpZ19saW5lIGxpbmtlZCBsaXN0IGZvciBhIG1hdGNoIAogKi8KaW50CnJ1bl9jb25maWdfaGFuZGxlcihzdHJ1Y3QgY29uZmlnX2xpbmUgKmxwdHIsCiAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0ciwgaW50IHdoZW4pCnsKICAgIGNoYXIgICAgICAgICAgICpjcDsKICAgIGxwdHIgPSByZWFkX2NvbmZpZ19maW5kX2hhbmRsZXIobHB0ciwgdG9rZW4pOwogICAgaWYgKGxwdHIgIT0gTlVMTCkgewogICAgICAgIGlmICh3aGVuID09IEVJVEhFUl9DT05GSUcgfHwgbHB0ci0+Y29uZmlnX3RpbWUgPT0gd2hlbikgewogICAgICAgICAgICBjaGFyIHRtcGJ1ZlsxXTsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOnBhcnNlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICJGb3VuZCBhIHBhcnNlci4gIENhbGxpbmcgaXQ6ICVzIC8gJXNcbiIsIHRva2VuLAogICAgICAgICAgICAgICAgICAgICAgICBjcHRyKSk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIE1ha2Ugc3VyZSBjcHRyIGlzIG5vbi1udWxsCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIWNwdHIpIHsKICAgICAgICAgICAgICAgIHRtcGJ1ZlswXSA9ICdcMCc7CiAgICAgICAgICAgICAgICBjcHRyID0gdG1wYnVmOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTdG9tcCBvbiBhbnkgdHJhaWxpbmcgd2hpdGVzcGFjZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY3AgPSAmKGNwdHJbc3RybGVuKGNwdHIpLTFdKTsKICAgICAgICAgICAgd2hpbGUgKChjcCA+IGNwdHIpICYmIGlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKCpjcCkpKSB7CiAgICAgICAgICAgICAgICAqKGNwLS0pID0gJ1wwJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAoKihscHRyLT5wYXJzZV9saW5lKSkgKHRva2VuLCBjcHRyKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBERUJVR01TR1RMKCgiOTpyZWFkX2NvbmZpZzpwYXJzZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAiJXMgaGFuZGxlciBub3QgcmVnaXN0ZXJlZCBmb3IgdGhpcyB0aW1lXG4iLCB0b2tlbikpOwogICAgfSBlbHNlIGlmICh3aGVuICE9IFBSRU1JQl9DT05GSUcgJiYgCgkgICAgICAgIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgICBORVRTTk1QX0RTX0xJQl9OT19UT0tFTl9XQVJOSU5HUykpIHsKCW5ldHNubXBfY29uZmlnX3dhcm4oIlVua25vd24gdG9rZW46ICVzLiIsIHRva2VuKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgovKgogKiB0YWtlbnMgYW4gYXJiaXRyYXJ5IHN0cmluZyBhbmQgdHJpZXMgdG8gaW50ZXByZXQgaXQgYmFzZWQgb24gdGhlCiAqIGtub3duIGNvbmZpZ3VyYXRpb24gaGFuZGxlcnMgZm9yIGFsbCByZWdpc3RlcmVkIHR5cGVzLiAgTWF5IHByb2R1Y2UKICogaW5jb25zaXN0ZW50IHJlc3VsdHMgd2hlbiBtdWx0aXBsZSB0b2tlbnMgb2YgdGhlIHNhbWUgbmFtZSBhcmUKICogcmVnaXN0ZXJlZCB1bmRlciBkaWZmZXJlbnQgZmlsZSB0eXBlcy4gCiAqLwoKLyoKICogd2UgYWxsb3cgPSBkZWxpbWV0ZXJzIGhlcmUgCiAqLwojZGVmaW5lIFNOTVBfQ09ORklHX0RFTElNRVRFUlMgIiBcdD0iCgppbnQKc25tcF9jb25maWdfd2hlbihjaGFyICpsaW5lLCBpbnQgd2hlbikKewogICAgY2hhciAgICAgICAgICAgKmNwdHIsIGJ1ZltTVFJJTkdNQVhdOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpscHRyID0gTlVMTDsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAgPSBjb25maWdfZmlsZXM7CiAgICBjaGFyICAgICAgICAgICAqc3Q7CgogICAgaWYgKGxpbmUgPT0gTlVMTCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoInNubXBfY29uZmlnKCkgY2FsbGVkIHdpdGggYSBudWxsIHN0cmluZy4iKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgc3RybGNweShidWYsIGxpbmUsIFNUUklOR01BWCk7CiAgICBjcHRyID0gc3RydG9rX3IoYnVmLCBTTk1QX0NPTkZJR19ERUxJTUVURVJTLCAmc3QpOwogICAgaWYgKCFjcHRyKSB7CiAgICAgICAgbmV0c25tcF9jb25maWdfd2FybigiV3JvbmcgZm9ybWF0OiAlcyIsIGxpbmUpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KICAgIGlmIChjcHRyWzBdID09ICdbJykgewogICAgICAgIGlmIChjcHRyW3N0cmxlbihjcHRyKSAtIDFdICE9ICddJykgewoJICAgIG5ldHNubXBfY29uZmlnX2Vycm9yKCJubyBtYXRjaGluZyAnXScgZm9yIHR5cGUgJXMuIiwgY3B0ciArIDEpOwogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgfQogICAgICAgIGNwdHJbc3RybGVuKGNwdHIpIC0gMV0gPSAnXDAnOwogICAgICAgIGxwdHIgPSByZWFkX2NvbmZpZ19nZXRfaGFuZGxlcnMoY3B0ciArIDEpOwogICAgICAgIGlmIChscHRyID09IE5VTEwpIHsKCSAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiTm8gaGFuZGxlcnMgcmVnZXN0ZXJlZCBmb3IgdHlwZSAlcy4iLAoJCQkJIGNwdHIgKyAxKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgIH0KICAgICAgICBjcHRyID0gc3RydG9rX3IoTlVMTCwgU05NUF9DT05GSUdfREVMSU1FVEVSUywgJnN0KTsKICAgICAgICBscHRyID0gcmVhZF9jb25maWdfZmluZF9oYW5kbGVyKGxwdHIsIGNwdHIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIHdlIGhhdmUgdG8gZmluZCBhIHRva2VuIAogICAgICAgICAqLwogICAgICAgIGZvciAoOyBjdG1wICE9IE5VTEwgJiYgbHB0ciA9PSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkKICAgICAgICAgICAgbHB0ciA9IHJlYWRfY29uZmlnX2ZpbmRfaGFuZGxlcihjdG1wLT5zdGFydCwgY3B0cik7CiAgICB9CiAgICBpZiAobHB0ciA9PSBOVUxMICYmIG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQkgIE5FVFNOTVBfRFNfTElCX05PX1RPS0VOX1dBUk5JTkdTKSkgewoJbmV0c25tcF9jb25maWdfd2FybigiVW5rbm93biB0b2tlbjogJXMuIiwgY3B0cik7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIC8qCiAgICAgKiB1c2UgdGhlIG9yaWdpbmFsIHN0cmluZyBpbnN0ZWFkIHNpbmNlIHN0cnRva19yIG1lc3NlZCB1cCB0aGUgb3JpZ2luYWwgCiAgICAgKi8KICAgIGxpbmUgPSBza2lwX3doaXRlKGxpbmUgKyAoY3B0ciAtIGJ1ZikgKyBzdHJsZW4oY3B0cikgKyAxKTsKCiAgICByZXR1cm4gKHJ1bl9jb25maWdfaGFuZGxlcihscHRyLCBjcHRyLCBsaW5lLCB3aGVuKSk7Cn0KCmludApuZXRzbm1wX2NvbmZpZyhjaGFyICpsaW5lKQp7CiAgICBpbnQgICAgICAgICAgICAgcmV0ID0gU05NUF9FUlJfTk9FUlJPUjsKICAgIERFQlVHTVNHVEwoKCJzbm1wX2NvbmZpZyIsICJyZW1lbWJlcmluZyBsaW5lIFwiJXNcIlxuIiwgbGluZSkpOwogICAgbmV0c25tcF9jb25maWdfcmVtZW1iZXIobGluZSk7ICAgICAgLyogYWx3YXlzIHJlbWVtYmVyIGl0IHNvIGl0J3MgcmVhZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogcHJvY2Vzc2VkIGFmdGVyIGEgZnJlZV9jb25maWcoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogY2FsbCAqLwogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICAgICAgIE5FVFNOTVBfRFNfTElCX0hBVkVfUkVBRF9DT05GSUcpKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfY29uZmlnIiwgIiAgLi4uIHByb2Nlc3NpbmcgaXQgbm93XG4iKSk7CiAgICAgICAgcmV0ID0gc25tcF9jb25maWdfd2hlbihsaW5lLCBOT1JNQUxfQ09ORklHKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcmVtZW1iZXJfaW5fbGlzdChjaGFyICpsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKiptZW0pCnsKICAgIGlmIChtZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgd2hpbGUgKCptZW0gIT0gTlVMTCkKICAgICAgICBtZW0gPSAmKCgqbWVtKS0+bmV4dCk7CgogICAgKm1lbSA9IFNOTVBfTUFMTE9DX1NUUlVDVChyZWFkX2NvbmZpZ19tZW1vcnkpOwogICAgaWYgKCptZW0gIT0gTlVMTCkgewogICAgICAgIGlmIChsaW5lKQogICAgICAgICAgICAoKm1lbSktPmxpbmUgPSBzdHJkdXAobGluZSk7CiAgICB9Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcmVtZW1iZXJfZnJlZV9saXN0KHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKiptZW0pCnsKICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKnRtcG1lbTsKICAgIHdoaWxlICgqbWVtKSB7CiAgICAgICAgU05NUF9GUkVFKCgqbWVtKS0+bGluZSk7CiAgICAgICAgdG1wbWVtID0gKCptZW0pLT5uZXh0OwogICAgICAgIFNOTVBfRlJFRSgqbWVtKTsKICAgICAgICAqbWVtID0gdG1wbWVtOwogICAgfQp9Cgp2b2lkCm5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3J5X2xpc3Qoc3RydWN0IHJlYWRfY29uZmlnX21lbW9yeSAqKm1lbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdoZW4sIGludCBjbGVhcikKewoKICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKm1lbTsKCiAgICBpZiAoIW1lbXApCiAgICAgICAgcmV0dXJuOwoKICAgIG1lbSA9ICptZW1wOwoKICAgIHdoaWxlIChtZW0pIHsKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWc6bWVtIiwgInByb2Nlc3NpbmcgbWVtb3J5OiAlc1xuIiwgbWVtLT5saW5lKSk7CiAgICAgICAgc25tcF9jb25maWdfd2hlbihtZW0tPmxpbmUsIHdoZW4pOwogICAgICAgIG1lbSA9IG1lbS0+bmV4dDsKICAgIH0KCiAgICBpZiAoY2xlYXIpCiAgICAgICAgbmV0c25tcF9jb25maWdfcmVtZW1iZXJfZnJlZV9saXN0KG1lbXApOwp9CgovKgogKiBkZWZhdWx0IHN0b3JhZ2UgbG9jYXRpb24gaW1wbGVtZW50YXRpb24gCiAqLwpzdGF0aWMgc3RydWN0IHJlYWRfY29uZmlnX21lbW9yeSAqbWVtb3J5bGlzdCA9IE5VTEw7Cgp2b2lkCm5ldHNubXBfY29uZmlnX3JlbWVtYmVyKGNoYXIgKmxpbmUpCnsKICAgIG5ldHNubXBfY29uZmlnX3JlbWVtYmVyX2luX2xpc3QobGluZSwgJm1lbW9yeWxpc3QpOwp9Cgp2b2lkCm5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3JpZXModm9pZCkKewogICAgbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcnlfbGlzdCgmbWVtb3J5bGlzdCwgRUlUSEVSX0NPTkZJRywgMSk7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcmllc193aGVuKGludCB3aGVuLCBpbnQgY2xlYXIpCnsKICAgIG5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3J5X2xpc3QoJm1lbW9yeWxpc3QsIHdoZW4sIGNsZWFyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogcmVhZF9jb25maWcKICoKICogUGFyYW1ldGVyczoKICoJKmZpbGVuYW1lCiAqCSpsaW5lX2hhbmRsZXIKICoJIHdoZW4KICoKICogUmVhZCA8ZmlsZW5hbWU+IGFuZCBwcm9jZXNzIGVhY2ggbGluZSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIGxpc3Qgb2YKICogPGxpbmVfaGFuZGxlcj4gZnVuY3Rpb25zLgogKgogKgogKiBGb3IgZWFjaCBsaW5lIGluIDxmaWxlbmFtZT4sIHNlYXJjaCB0aGUgbGlzdCBvZiA8bGluZV9oYW5kbGVyPidzIAogKiBmb3IgYW4gZW50cnkgdGhhdCBtYXRjaGVzIHRoZSBmaXJzdCB0b2tlbiBvbiB0aGUgbGluZS4gIFRoaXMgY29tcGFyaXNvbiBpcwogKiBjYXNlIGluc2Vuc2l0aXZlLgogKgogKiBGb3IgZWFjaCBtYXRjaCwgY2hlY2sgdGhhdCA8d2hlbj4gaXMgdGhlIGRlc2lnbmF0ZWQgdGltZSBmb3IgdGhlCiAqIDxsaW5lX2hhbmRsZXI+IGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGJlZm9yZSBwcm9jZXNzaW5nIHRoZSBsaW5lLgogKgogKiBSZXR1cm5zIFNOTVBFUlJfU1VDQ0VTUyBpZiB0aGUgZmlsZSBpcyBwcm9jZXNzZWQgc3VjY2Vzc2Z1bGx5LgogKiBSZXR1cm5zIFNOTVBFUlJfR0VORVJSICBpZiBpdCBjYW5ub3QuCiAqICAgIE5vdGUgdGhhdCBpbmRpdmlkdWFsIGNvbmZpZyB0b2tlbiBlcnJvcnMgZG8gbm90IHRyaWdnZXIgU05NUEVSUl9HRU5FUlIKICogICAgSXQncyBvbmx5IGlmIHRoZSB3aG9sZSBmaWxlIGNhbm5vdCBiZSBwcm9jZXNzZWQgZm9yIHNvbWUgcmVhc29uLgogKi8KaW50CnJlYWRfY29uZmlnKGNvbnN0IGNoYXIgKmZpbGVuYW1lLAogICAgICAgICAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmxpbmVfaGFuZGxlciwgaW50IHdoZW4pCnsKICAgIHN0YXRpYyBpbnQgICAgICBkZXB0aCA9IDA7CiAgICBzdGF0aWMgaW50ICAgICAgZmlsZXMgPSAwOwoKICAgIGNvbnN0IGNoYXIgKiBjb25zdCBwcmV2X2ZpbGVuYW1lID0gY3VyZmlsZW5hbWU7CiAgICBjb25zdCB1bnNpZ25lZCBpbnQgcHJldl9saW5lY291bnQgPSBsaW5lY291bnQ7CgogICAgRklMRSAgICAgICAgICAgKmlmaWxlOwogICAgY2hhciAgICAgICAgICAgKmxpbmUgPSBOVUxMOyAgLyogY3VycmVudCBsaW5lIGJ1ZmZlciAqLwogICAgc2l6ZV90ICAgICAgICAgIGxpbmVzaXplID0gMDsgLyogYWxsb2NhdGVkIHNpemUgb2YgbGluZSAqLwoKICAgIC8qIHJlc2V0IGZpbGUgY291bnRlciB3aGVuIHJlY3Vyc2lvbiBkZXB0aCBpcyAwICovCiAgICBpZiAoZGVwdGggPT0gMCkKICAgICAgICBmaWxlcyA9IDA7CgogICAgaWYgKChpZmlsZSA9IGZvcGVuKGZpbGVuYW1lLCAiciIpKSA9PSBOVUxMKSB7CiNpZmRlZiBFTk9FTlQKICAgICAgICBpZiAoZXJybm8gPT0gRU5PRU5UKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICIlczogJXNcbiIsIGZpbGVuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBzdHJlcnJvcihlcnJubykpKTsKICAgICAgICB9IGVsc2UKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBFTk9FTlQgKi8KI2lmZGVmIEVBQ0NFUwogICAgICAgIGlmIChlcnJubyA9PSBFQUNDRVMpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIiVzOiAlc1xuIiwgZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVycm9yKGVycm5vKSkpOwogICAgICAgIH0gZWxzZQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEVBQ0NFUyAqLwogICAgICAgIHsKICAgICAgICAgICAgc25tcF9sb2dfcGVycm9yKGZpbGVuYW1lKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKI2RlZmluZSBDT05GSUdfTUFYX0ZJTEVTIDQwOTYKICAgIGlmIChmaWxlcyA+IENPTkZJR19NQVhfRklMRVMpIHsKICAgICAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigibWF4aW11bSBjb25mIGZpbGUgY291bnQgKCVkKSBleGNlZWRlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05GSUdfTUFYX0ZJTEVTKTsKCWZjbG9zZShpZmlsZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQojZGVmaW5lIENPTkZJR19NQVhfUkVDVVJTRV9ERVBUSCAxNgogICAgaWYgKGRlcHRoID4gQ09ORklHX01BWF9SRUNVUlNFX0RFUFRIKSB7CiAgICAgICAgbmV0c25tcF9jb25maWdfZXJyb3IoIm5lc3RlZCBpbmNsdWRlIGRlcHRoID4gJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ORklHX01BWF9SRUNVUlNFX0RFUFRIKTsKCWZjbG9zZShpZmlsZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIGxpbmVjb3VudCA9IDA7CiAgICBjdXJmaWxlbmFtZSA9IGZpbGVuYW1lOwoKICAgICsrZmlsZXM7CiAgICArK2RlcHRoOwoKICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZzpmaWxlIiwgIlJlYWRpbmcgY29uZmlndXJhdGlvbiAlcyAoJWQpXG4iLAogICAgICAgICAgICAgICAgZmlsZW5hbWUsIHdoZW4pKTsKCiAgICB3aGlsZSAoaWZpbGUpIHsKICAgICAgICBzaXplX3QgICAgICAgICAgICAgIGxpbmVsZW4gPSAwOyAvKiBzdHJsZW4gb2YgdGhlIGN1cnJlbnQgbGluZSAqLwogICAgICAgIGNoYXIgICAgICAgICAgICAgICAqY3B0cjsKICAgICAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmxwdHIgPSBsaW5lX2hhbmRsZXI7CgogICAgICAgIGZvciAoOzspIHsKICAgICAgICAgICAgaWYgKGxpbmVzaXplIDw9IGxpbmVsZW4gKyAxKSB7CiAgICAgICAgICAgICAgICBjaGFyICp0bXAgPSByZWFsbG9jKGxpbmUsIGxpbmVzaXplICsgMjU2KTsKICAgICAgICAgICAgICAgIGlmICh0bXApIHsKICAgICAgICAgICAgICAgICAgICBsaW5lID0gdG1wOwogICAgICAgICAgICAgICAgICAgIGxpbmVzaXplICs9IDI1NjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jb25maWdfZXJyb3IoIkZhaWxlZCB0byBhbGxvY2F0ZSBtZW1vcnlcbiIpOwogICAgICAgICAgICAgICAgICAgIGZyZWUobGluZSk7CiAgICAgICAgICAgICAgICAgICAgZmNsb3NlKGlmaWxlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGZnZXRzKGxpbmUgKyBsaW5lbGVuLCBsaW5lc2l6ZSAtIGxpbmVsZW4sIGlmaWxlKSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBsaW5lW2xpbmVsZW5dID0gJ1wwJzsKICAgICAgICAgICAgICAgIGZjbG9zZSAoaWZpbGUpOwogICAgICAgICAgICAgICAgaWZpbGUgPSBOVUxMOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxpbmVsZW4gKz0gc3RybGVuKGxpbmUgKyBsaW5lbGVuKTsKCiAgICAgICAgICAgIGlmIChsaW5lW2xpbmVsZW4gLSAxXSA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgbGluZVtsaW5lbGVuIC0gMV0gPSAnXDAnOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICArK2xpbmVjb3VudDsKICAgICAgICBERUJVR01TR1RMKCgiOTpyZWFkX2NvbmZpZzpsaW5lIiwgIiVzOiVkIGV4YW1pbmluZzogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxpbmVjb3VudCwgbGluZSkpOwogICAgICAgIC8qCiAgICAgICAgICogY2hlY2sgYmxhbmsgbGluZSBvciAjIGNvbW1lbnQgCiAgICAgICAgICovCiAgICAgICAgaWYgKChjcHRyID0gc2tpcF93aGl0ZShsaW5lKSkpIHsKICAgICAgICAgICAgY2hhciB0b2tlbltTVFJJTkdNQVhdOwoKICAgICAgICAgICAgY3B0ciA9IGNvcHlfbndvcmQoY3B0ciwgdG9rZW4sIHNpemVvZih0b2tlbikpOwogICAgICAgICAgICBpZiAodG9rZW5bMF0gPT0gJ1snKSB7CiAgICAgICAgICAgICAgICBpZiAodG9rZW5bc3RybGVuKHRva2VuKSAtIDFdICE9ICddJykgewoJCSAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigibm8gbWF0Y2hpbmcgJ10nIGZvciB0eXBlICVzLiIsCgkJCQkJICZ0b2tlblsxXSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0b2tlbltzdHJsZW4odG9rZW4pIC0gMV0gPSAnXDAnOwogICAgICAgICAgICAgICAgbHB0ciA9IHJlYWRfY29uZmlnX2dldF9oYW5kbGVycygmdG9rZW5bMV0pOwogICAgICAgICAgICAgICAgaWYgKGxwdHIgPT0gTlVMTCkgewoJCSAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiTm8gaGFuZGxlcnMgcmVnZXN0ZXJlZCBmb3IgdHlwZSAlcy4iLAoJCQkJCSAmdG9rZW5bMV0pOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOmNvbnRleHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN3aXRjaGluZyB0byBuZXcgY29udGV4dDogJXMlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoY3B0cikgPyAiKHRoaXMgbGluZSBvbmx5KSAiIDogIiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRva2VuWzFdKSk7CiAgICAgICAgICAgICAgICBpZiAoY3B0ciA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBjaGFuZ2UgY29udGV4dCBwZXJtYW5lbnRseSAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBsaW5lX2hhbmRsZXIgPSBscHRyOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIHRoZSByZXN0IG9mIHRoaXMgbGluZSBvbmx5IGFwcGxpZXMuIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGNwdHIgPSBjb3B5X253b3JkKGNwdHIsIHRva2VuLCBzaXplb2YodG9rZW4pKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICgodG9rZW5bMF0gPT0gJ2knKSAmJiAoc3RybmNhc2VjbXAodG9rZW4sImluY2x1ZGUiLCA3ICk9PTApKSB7CiAgICAgICAgICAgICAgICBpZiAoIHN0cmNhc2VjbXAoIHRva2VuLCAiaW5jbHVkZSIgKT09MCkgewogICAgICAgICAgICAgICAgICAgIGlmICh3aGVuICE9IFBSRU1JQl9DT05GSUcgJiYgCgkgICAgICAgICAgICAgICAgIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9OT19UT0tFTl9XQVJOSU5HUykpIHsKCSAgICAgICAgICAgICAgICBuZXRzbm1wX2NvbmZpZ193YXJuKCJBbWJpZ3VvdXMgdG9rZW4gJyVzJyAtIHVzZSAnaW5jbHVkZVNlYXJjaCcgKG9yICdpbmNsdWRlRmlsZScpIGluc3RlYWQuIiwgdG9rZW4pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIHN0cmNhc2VjbXAoIHRva2VuLCAiaW5jbHVkZWRpciIgKT09MCkgewogICAgICAgICAgICAgICAgICAgIERJUiAqZDsKICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgZGlyZW50ICplbnRyeTsKICAgICAgICAgICAgICAgICAgICBjaGFyICBmbmFtZVtTTk1QX01BWFBBVEhdOwogICAgICAgICAgICAgICAgICAgIGludCAgIGxlbjsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGNwdHIgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAod2hlbiAhPSBQUkVNSUJfQ09ORklHKQoJCSAgICAgICAgICAgIG5ldHNubXBfY29uZmlnX2Vycm9yKCJCbGFuayBsaW5lIGZvbGxvd2luZyAlcyB0b2tlbi4iLCB0b2tlbik7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoKGQ9b3BlbmRpcihjcHRyKSkgPT0gTlVMTCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdoZW4gIT0gUFJFTUlCX0NPTkZJRykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY29uZmlnX2Vycm9yKCJDYW4ndCBvcGVuIGluY2x1ZGUgZGlyICclcycuIiwgY3B0cik7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGVudHJ5ID0gcmVhZGRpciggZCApKSAhPSBOVUxMICkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGVudHJ5LT5kX25hbWVbMF0gIT0gJy4nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSBOQU1MRU4oZW50cnkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChsZW4gPiA1KSAmJiAoc3RyY21wKCYoZW50cnktPmRfbmFtZVtsZW4tNV0pLCIuY29uZiIpID09IDApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25wcmludGYoZm5hbWUsIFNOTVBfTUFYUEFUSCwgIiVzLyVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcHRyLCBlbnRyeS0+ZF9uYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZClyZWFkX2NvbmZpZyhmbmFtZSwgbGluZV9oYW5kbGVyLCB3aGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjbG9zZWRpcihkKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIHN0cmNhc2VjbXAoIHRva2VuLCAiaW5jbHVkZWZpbGUiICk9PTApIHsKICAgICAgICAgICAgICAgICAgICBjaGFyICBmbmFtZVtTTk1QX01BWFBBVEhdLCAqY3A7CgogICAgICAgICAgICAgICAgICAgIGlmIChjcHRyID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdoZW4gIT0gUFJFTUlCX0NPTkZJRykKCQkgICAgICAgICAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiQmxhbmsgbGluZSBmb2xsb3dpbmcgJXMgdG9rZW4uIiwgdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCBjcHRyWzBdID09ICcvJyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RybGNweShmbmFtZSwgY3B0ciwgU05NUF9NQVhQQVRIKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzdHJsY3B5KGZuYW1lLCBmaWxlbmFtZSwgU05NUF9NQVhQQVRIKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3AgPSBzdHJyY2hyKGZuYW1lLCAnLycpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm5hbWVbMF0gPSAnXDAnOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKCsrY3ApID0gJ1wwJzsKICAgICAgICAgICAgICAgICAgICAgICAgc3RybGNhdChmbmFtZSwgY3B0ciwgU05NUF9NQVhQQVRIKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWRfY29uZmlnKGZuYW1lLCBsaW5lX2hhbmRsZXIsIHdoZW4pICE9CiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBFUlJfU1VDQ0VTUyAmJiB3aGVuICE9IFBSRU1JQl9DT05GSUcpCiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY29uZmlnX2Vycm9yKCJJbmNsdWRlZCBmaWxlICclcycgbm90IGZvdW5kLiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZuYW1lKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIHN0cmNhc2VjbXAoIHRva2VuLCAiaW5jbHVkZXNlYXJjaCIgKT09MCkgewogICAgICAgICAgICAgICAgICAgIHN0cnVjdCBjb25maWdfZmlsZXMgY3RtcDsKICAgICAgICAgICAgICAgICAgICBpbnQgbGVuLCByZXQ7CgogICAgICAgICAgICAgICAgICAgIGlmIChjcHRyID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdoZW4gIT0gUFJFTUlCX0NPTkZJRykKCQkgICAgICAgICAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiQmxhbmsgbGluZSBmb2xsb3dpbmcgJXMgdG9rZW4uIiwgdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbGVuID0gc3RybGVuKGNwdHIpOwogICAgICAgICAgICAgICAgICAgIGN0bXAuZmlsZUhlYWRlciA9IGNwdHI7CiAgICAgICAgICAgICAgICAgICAgY3RtcC5zdGFydCA9IGxpbmVfaGFuZGxlcjsKICAgICAgICAgICAgICAgICAgICBjdG1wLm5leHQgPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIGlmICgobGVuID4gNSkgJiYgKHN0cmNtcCgmY3B0cltsZW4tNV0sIi5jb25mIikgPT0gMCkpCiAgICAgICAgICAgICAgICAgICAgICAgY3B0cltsZW4tNV0gPSAwOyAvKiBjaG9wIG9mZiAuY29uZiAqLwogICAgICAgICAgICAgICAgICAgIHJldCA9IHJlYWRfY29uZmlnX2ZpbGVzX29mX3R5cGUod2hlbiwmY3RtcCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKChsZW4gPiA1KSAmJiAoY3B0cltsZW4tNV0gPT0gMCkpCiAgICAgICAgICAgICAgICAgICAgICAgY3B0cltsZW4tNV0gPSAnLic7IC8qIHJlc3RvcmUgLmNvbmYgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoKCByZXQgIT0gU05NUEVSUl9TVUNDRVNTICkgJiYgKHdoZW4gIT0gUFJFTUlCX0NPTkZJRykpCgkJICAgICAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiSW5jbHVkZWQgY29uZmlnICclcycgbm90IGZvdW5kLiIsIGNwdHIpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBscHRyID0gbGluZV9oYW5kbGVyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbHB0ciA9IGxpbmVfaGFuZGxlcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3B0ciA9PSBOVUxMKSB7CgkJbmV0c25tcF9jb25maWdfZXJyb3IoIkJsYW5rIGxpbmUgZm9sbG93aW5nICVzIHRva2VuLiIsIHRva2VuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZzpsaW5lIiwgIiVzOiVkIGV4YW1pbmluZzogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgbGluZWNvdW50LCBsaW5lKSk7CiAgICAgICAgICAgICAgICBydW5fY29uZmlnX2hhbmRsZXIobHB0ciwgdG9rZW4sIGNwdHIsIHdoZW4pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZnJlZShsaW5lKTsKICAgIGxpbmVjb3VudCA9IHByZXZfbGluZWNvdW50OwogICAgY3VyZmlsZW5hbWUgPSBwcmV2X2ZpbGVuYW1lOwogICAgLS1kZXB0aDsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCByZWFkX2NvbmZpZygpICovCgoKCnZvaWQKZnJlZV9jb25maWcodm9pZCkKewogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCA9IGNvbmZpZ19maWxlczsKICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHRtcDsKCiAgICBmb3IgKDsgY3RtcCAhPSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkKICAgICAgICBmb3IgKGx0bXAgPSBjdG1wLT5zdGFydDsgbHRtcCAhPSBOVUxMOyBsdG1wID0gbHRtcC0+bmV4dCkKICAgICAgICAgICAgaWYgKGx0bXAtPmZyZWVfZnVuYykKICAgICAgICAgICAgICAgICgqKGx0bXAtPmZyZWVfZnVuYykpICgpOwp9CgovKgogKiBSZXR1cm4gU05NUEVSUl9TVUNDRVNTIGlmIGFueSBjb25maWcgZmlsZXMgYXJlIHByb2Nlc3NlZAogKiBSZXR1cm4gU05NUEVSUl9HRU5FUlIgaWYgX25vXyBjb25maWcgZmlsZXMgYXJlIHByb2Nlc3NlZAogKiAgICBXaGV0aGVyIHRoaXMgaXMgYWN0dWFsbHkgYW4gZXJyb3IgaXMgbGVmdCB0byB0aGUgYXBwbGljYXRpb24KICovCmludApyZWFkX2NvbmZpZ3Nfb3B0aW9uYWwoY29uc3QgY2hhciAqb3B0aW9uYWxfY29uZmlnLCBpbnQgd2hlbikKewogICAgY2hhciAqbmV3cCwgKmNwLCAqc3QgPSBOVUxMOwogICAgaW50ICAgICAgICAgICAgICByZXQgPSBTTk1QRVJSX0dFTkVSUjsKICAgIGNoYXIgKnR5cGUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFKTsKCiAgICBpZiAoKE5VTEwgPT0gb3B0aW9uYWxfY29uZmlnKSB8fCAoTlVMTCA9PSB0eXBlKSkKICAgICAgICByZXR1cm4gcmV0OwoKICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ3Nfb3B0aW9uYWwiLAogICAgICAgICAgICAgICAgInJlYWRpbmcgb3B0aW9uYWwgY29uZmlndXJhdGlvbiB0b2tlbnMgZm9yICVzXG4iLCB0eXBlKSk7CiAgICAKICAgIG5ld3AgPSBzdHJkdXAob3B0aW9uYWxfY29uZmlnKTsgICAgICAvKiBzdHJ0b2tfciBtZXNzZXMgaXQgdXAgKi8KICAgIGNwID0gc3RydG9rX3IobmV3cCwgIiwiLCAmc3QpOwogICAgd2hpbGUgKGNwKSB7CiAgICAgICAgc3RydWN0IHN0YXQgICAgIHN0YXRidWY7CiAgICAgICAgaWYgKHN0YXQoY3AsICZzdGF0YnVmKSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLAogICAgICAgICAgICAgICAgICAgICAgICAiT3B0aW9uYWwgRmlsZSBcIiVzXCIgZG9lcyBub3QgZXhpc3QuXG4iLCBjcCkpOwogICAgICAgICAgICBzbm1wX2xvZ19wZXJyb3IoY3ApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZzpvcHQiLAogICAgICAgICAgICAgICAgICAgICAgICAiUmVhZGluZyBvcHRpb25hbCBjb25maWcgZmlsZTogXCIlc1wiXG4iLCBjcCkpOwogICAgICAgICAgICBpZiAoIHJlYWRfY29uZmlnX3dpdGhfdHlwZV93aGVuKGNwLCB0eXBlLCB3aGVuKSA9PSBTTk1QRVJSX1NVQ0NFU1MgKQogICAgICAgICAgICAgICAgcmV0ID0gU05NUEVSUl9TVUNDRVNTOwogICAgICAgIH0KICAgICAgICBjcCA9IHN0cnRva19yKE5VTEwsICIsIiwgJnN0KTsKICAgIH0KICAgIGZyZWUobmV3cCk7CiAgICByZXR1cm4gcmV0Owp9Cgp2b2lkCnJlYWRfY29uZmlncyh2b2lkKQp7CiAgICBjaGFyICpvcHRpb25hbF9jb25maWcgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQkgICAgICAgTkVUU05NUF9EU19MSUJfT1BUSU9OQUxDT05GSUcpOwoKICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19MSUJSQVJZLAogICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0NBTExCQUNLX1BSRV9SRUFEX0NPTkZJRywgTlVMTCk7CgogICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgInJlYWRpbmcgbm9ybWFsIGNvbmZpZ3VyYXRpb24gdG9rZW5zXG4iKSk7CgogICAgaWYgKChOVUxMICE9IG9wdGlvbmFsX2NvbmZpZykgJiYgKCpvcHRpb25hbF9jb25maWcgPT0gJy0nKSkgewogICAgICAgICh2b2lkKXJlYWRfY29uZmlnc19vcHRpb25hbCgrK29wdGlvbmFsX2NvbmZpZywgTk9STUFMX0NPTkZJRyk7CiAgICAgICAgb3B0aW9uYWxfY29uZmlnID0gTlVMTDsgLyogY2xlYXIsIHNvIHdlIGRvbid0IHJlYWQgdGhlbSB0d2ljZSAqLwogICAgfQoKICAgICh2b2lkKXJlYWRfY29uZmlnX2ZpbGVzKE5PUk1BTF9DT05GSUcpOwoKICAgIC8qCiAgICAgKiBkbyB0aGlzIGV2ZW4gd2hlbiB0aGUgbm9ybWFsIGFib3ZlIHdhc24ndCBkb25lIAogICAgICovCiAgICBpZiAoTlVMTCAhPSBvcHRpb25hbF9jb25maWcpCiAgICAgICAgKHZvaWQpcmVhZF9jb25maWdzX29wdGlvbmFsKG9wdGlvbmFsX2NvbmZpZywgTk9STUFMX0NPTkZJRyk7CgogICAgbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcmllc193aGVuKE5PUk1BTF9DT05GSUcsIDEpOwoKICAgIG5ldHNubXBfZHNfc2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICAgTkVUU05NUF9EU19MSUJfSEFWRV9SRUFEX0NPTkZJRywgMSk7CiAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwKICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9DQUxMQkFDS19QT1NUX1JFQURfQ09ORklHLCBOVUxMKTsKfQoKdm9pZApyZWFkX3ByZW1pYl9jb25maWdzKHZvaWQpCnsKICAgIGNoYXIgKm9wdGlvbmFsX2NvbmZpZyA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJCSAgICAgICBORVRTTk1QX0RTX0xJQl9PUFRJT05BTENPTkZJRyk7CgogICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0xJQlJBUlksCiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfQ0FMTEJBQ0tfUFJFX1BSRU1JQl9SRUFEX0NPTkZJRywgTlVMTCk7CgogICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgInJlYWRpbmcgcHJlbWliIGNvbmZpZ3VyYXRpb24gdG9rZW5zXG4iKSk7CgogICAgaWYgKChOVUxMICE9IG9wdGlvbmFsX2NvbmZpZykgJiYgKCpvcHRpb25hbF9jb25maWcgPT0gJy0nKSkgewogICAgICAgICh2b2lkKXJlYWRfY29uZmlnc19vcHRpb25hbCgrK29wdGlvbmFsX2NvbmZpZywgUFJFTUlCX0NPTkZJRyk7CiAgICAgICAgb3B0aW9uYWxfY29uZmlnID0gTlVMTDsgLyogY2xlYXIsIHNvIHdlIGRvbid0IHJlYWQgdGhlbSB0d2ljZSAqLwogICAgfQoKICAgICh2b2lkKXJlYWRfY29uZmlnX2ZpbGVzKFBSRU1JQl9DT05GSUcpOwoKICAgIGlmIChOVUxMICE9IG9wdGlvbmFsX2NvbmZpZykKICAgICAgICAodm9pZClyZWFkX2NvbmZpZ3Nfb3B0aW9uYWwob3B0aW9uYWxfY29uZmlnLCBQUkVNSUJfQ09ORklHKTsKCiAgICBuZXRzbm1wX2NvbmZpZ19wcm9jZXNzX21lbW9yaWVzX3doZW4oUFJFTUlCX0NPTkZJRywgMCk7CgogICAgbmV0c25tcF9kc19zZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgICBORVRTTk1QX0RTX0xJQl9IQVZFX1JFQURfUFJFTUlCX0NPTkZJRywgMSk7CiAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwKICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9DQUxMQkFDS19QT1NUX1BSRU1JQl9SRUFEX0NPTkZJRywgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIHNldF9jb25maWd1cmF0aW9uX2RpcmVjdG9yeQogKgogKiBQYXJhbWV0ZXJzOgogKiAgICAgIGNoYXIgKmRpciAtIHZhbHVlIG9mIHRoZSBkaXJlY3RvcnkKICogU2V0cyB0aGUgY29uZmlndXJhdGlvbiBkaXJlY3RvcnkuIE11bHRpcGxlIGRpcmVjdG9yaWVzIGNhbiBiZQogKiBzcGVjaWZpZWQsIGJ1dCBuZWVkIHRvIGJlIHNlcGVyYXRlZCBieSAnRU5WX1NFUEFSQVRPUl9DSEFSJy4KICovCnZvaWQKc2V0X2NvbmZpZ3VyYXRpb25fZGlyZWN0b3J5KGNvbnN0IGNoYXIgKmRpcikKewogICAgbmV0c25tcF9kc19zZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCSAgTkVUU05NUF9EU19MSUJfQ09ORklHVVJBVElPTl9ESVIsIGRpcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGdldF9jb25maWd1cmF0aW9uX2RpcmVjdG9yeQogKgogKiBQYXJhbWV0ZXJzOiAtCiAqIFJldHJpZXZlIHRoZSBjb25maWd1cmF0aW9uIGRpcmVjdG9yeSBvciBkaXJlY3Rvcmllcy4KICogKEZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSB0aGF0IGlzOgogKiAgICAgICBTTk1QQ09ORlBBVEgsIFNOTVBTSEFSRVBBVEgsIFNOTVBMSUJQQVRILCBIT01FLy5zbm1wCiAqIEZpcnN0IGNoZWNrIHdoZXRoZXIgdGhlIHZhbHVlIGlzIHNldC4KICogSWYgbm90IHNldCBnaXZlIGl0IHRoZSBkZWZhdWx0IHZhbHVlLgogKiBSZXR1cm4gdGhlIHZhbHVlLgogKiBXZSBhbHdheXMgcmV0cmlldmUgaXQgbmV3LCBzaW5jZSB3ZSBoYXZlIHRvIGRvIGl0IGFueXdheSBpZiBpdCBpcyBqdXN0IHNldC4KICovCmNvbnN0IGNoYXIgICAgICoKZ2V0X2NvbmZpZ3VyYXRpb25fZGlyZWN0b3J5KHZvaWQpCnsKICAgIGNoYXIgICAgICAgICAgICBkZWZhdWx0UGF0aFtTUFJJTlRfTUFYX0xFTl07CiAgICBjaGFyICAgICAgICAgICAqaG9tZXBhdGg7CgogICAgaWYgKE5VTEwgPT0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgICBORVRTTk1QX0RTX0xJQl9DT05GSUdVUkFUSU9OX0RJUikpIHsKICAgICAgICBob21lcGF0aCA9IG5ldHNubXBfZ2V0ZW52KCJIT01FIik7CiAgICAgICAgc25wcmludGYoZGVmYXVsdFBhdGgsIHNpemVvZihkZWZhdWx0UGF0aCksICIlcyVjJXMlYyVzJXMlcyVzIiwKICAgICAgICAgICAgICAgIFNOTVBDT05GUEFUSCwgRU5WX1NFUEFSQVRPUl9DSEFSLAogICAgICAgICAgICAgICAgU05NUFNIQVJFUEFUSCwgRU5WX1NFUEFSQVRPUl9DSEFSLCBTTk1QTElCUEFUSCwKICAgICAgICAgICAgICAgICgoaG9tZXBhdGggPT0gTlVMTCkgPyAiIiA6IEVOVl9TRVBBUkFUT1IpLAogICAgICAgICAgICAgICAgKChob21lcGF0aCA9PSBOVUxMKSA/ICIiIDogaG9tZXBhdGgpLAogICAgICAgICAgICAgICAgKChob21lcGF0aCA9PSBOVUxMKSA/ICIiIDogIi8uc25tcCIpKTsKICAgICAgICBkZWZhdWx0UGF0aFsgc2l6ZW9mKGRlZmF1bHRQYXRoKS0xIF0gPSAwOwogICAgICAgIHNldF9jb25maWd1cmF0aW9uX2RpcmVjdG9yeShkZWZhdWx0UGF0aCk7CiAgICB9CiAgICByZXR1cm4gKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICBORVRTTk1QX0RTX0xJQl9DT05GSUdVUkFUSU9OX0RJUikpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBzZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkKICoKICogUGFyYW1ldGVyczoKICogICAgICBjaGFyICpkaXIgLSB2YWx1ZSBvZiB0aGUgZGlyZWN0b3J5CiAqIFNldHMgdGhlIGNvbmZpZ3VyYXRpb24gZGlyZWN0b3J5LiAKICogTm8gbXVsdGlwbGUgZGlyZWN0b3JpZXMgbWF5IGJlIHNwZWNpZmllZC4KICogKEhvd2V2ZXIsIHRoaXMgaXMgbm90IGNoZWNrZWQpCiAqLwp2b2lkCnNldF9wZXJzaXN0ZW50X2RpcmVjdG9yeShjb25zdCBjaGFyICpkaXIpCnsKICAgIG5ldHNubXBfZHNfc2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgIE5FVFNOTVBfRFNfTElCX1BFUlNJU1RFTlRfRElSLCBkaXIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkKICoKICogUGFyYW1ldGVyczogLQogKiBGdW5jdGlvbiB3aWxsIHJldHJpZXZlIHRoZSBwZXJzaXN0ZW4gZGlyZWN0b3J5IHZhbHVlLgogKiBGaXJzdCBjaGVjayB3aGV0aGVyIHRoZSB2YWx1ZSBpcyBzZXQuCiAqIElmIG5vdCBzZXQgZ2l2ZSBpdCB0aGUgZGVmYXVsdCB2YWx1ZS4KICogUmV0dXJuIHRoZSB2YWx1ZS4gCiAqIFdlIGFsd2F5cyByZXRyaWV2ZSBpdCBuZXcsIHNpbmNlIHdlIGhhdmUgdG8gZG8gaXQgYW55d2F5IGlmIGl0IGlzIGp1c3Qgc2V0LgogKi8KY29uc3QgY2hhciAgICAgKgpnZXRfcGVyc2lzdGVudF9kaXJlY3Rvcnkodm9pZCkKewogICAgaWYgKE5VTEwgPT0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgICBORVRTTk1QX0RTX0xJQl9QRVJTSVNURU5UX0RJUikpIHsKICAgICAgICBjb25zdCBjaGFyICpwZXJzZGlyID0gbmV0c25tcF9nZXRlbnYoIlNOTVBfUEVSU0lTVEVOVF9ESVIiKTsKICAgICAgICBpZiAoTlVMTCA9PSBwZXJzZGlyKQogICAgICAgICAgICBwZXJzZGlyID0gTkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWTsKICAgICAgICBzZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkocGVyc2Rpcik7CiAgICB9CiAgICByZXR1cm4gKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICBORVRTTk1QX0RTX0xJQl9QRVJTSVNURU5UX0RJUikpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBzZXRfdGVtcF9maWxlX3BhdHRlcm4KICoKICogUGFyYW1ldGVyczoKICogICAgICBjaGFyICpwYXR0ZXJuIC0gdmFsdWUgb2YgdGhlIGZpbGUgcGF0dGVybgogKiBTZXRzIHRoZSB0ZW1wIGZpbGUgcGF0dGVybi4gCiAqIE11bHRpcGxlIHBhdHRlcm5zIG1heSBub3QgYmUgc3BlY2lmaWVkLgogKiAoSG93ZXZlciwgdGhpcyBpcyBub3QgY2hlY2tlZCkKICovCnZvaWQKc2V0X3RlbXBfZmlsZV9wYXR0ZXJuKGNvbnN0IGNoYXIgKnBhdHRlcm4pCnsKICAgIG5ldHNubXBfZHNfc2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgIE5FVFNOTVBfRFNfTElCX1RFTVBfRklMRV9QQVRURVJOLCBwYXR0ZXJuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZ2V0X3RlbXBfZmlsZV9wYXR0ZXJuCiAqCiAqIFBhcmFtZXRlcnM6IC0KICogRnVuY3Rpb24gd2lsbCByZXRyaWV2ZSB0aGUgdGVtcCBmaWxlIHBhdHRlcm4gdmFsdWUuCiAqIEZpcnN0IGNoZWNrIHdoZXRoZXIgdGhlIHZhbHVlIGlzIHNldC4KICogSWYgbm90IHNldCBnaXZlIGl0IHRoZSBkZWZhdWx0IHZhbHVlLgogKiBSZXR1cm4gdGhlIHZhbHVlLiAKICogV2UgYWx3YXlzIHJldHJpZXZlIGl0IG5ldywgc2luY2Ugd2UgaGF2ZSB0byBkbyBpdCBhbnl3YXkgaWYgaXQgaXMganVzdCBzZXQuCiAqLwpjb25zdCBjaGFyICAgICAqCmdldF90ZW1wX2ZpbGVfcGF0dGVybih2b2lkKQp7CiAgICBpZiAoTlVMTCA9PSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgIE5FVFNOTVBfRFNfTElCX1RFTVBfRklMRV9QQVRURVJOKSkgewogICAgICAgIHNldF90ZW1wX2ZpbGVfcGF0dGVybihORVRTTk1QX1RFTVBfRklMRV9QQVRURVJOKTsKICAgIH0KICAgIHJldHVybiAobmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgIE5FVFNOTVBfRFNfTElCX1RFTVBfRklMRV9QQVRURVJOKSk7Cn0KCi8qKgogKiB1dGlsaXR5IHJvdXRpbmUgZm9yIHJlYWRfY29uZmlnX2ZpbGVzCiAqCiAqIFJldHVybiBTTk1QRVJSX1NVQ0NFU1MgaWYgYW55IGNvbmZpZyBmaWxlcyBhcmUgcHJvY2Vzc2VkCiAqIFJldHVybiBTTk1QRVJSX0dFTkVSUiBpZiBfbm9fIGNvbmZpZyBmaWxlcyBhcmUgcHJvY2Vzc2VkCiAqICAgIFdoZXRoZXIgdGhpcyBpcyBhY3R1YWxseSBhbiBlcnJvciBpcyBsZWZ0IHRvIHRoZSBhcHBsaWNhdGlvbgogKi8Kc3RhdGljIGludApyZWFkX2NvbmZpZ19maWxlc19pbl9wYXRoKGNvbnN0IGNoYXIgKnBhdGgsIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdoZW4sIGNvbnN0IGNoYXIgKnBlcnNwYXRoLCBjb25zdCBjaGFyICpwZXJzZmlsZSkKewogICAgaW50ICAgICAgICAgICAgIGRvbmUsIGo7CiAgICBjaGFyICAgICAgICAgICAgY29uZmlnZmlsZVszMDBdOwogICAgY2hhciAgICAgICAgICAgKmNwdHIxLCAqY3B0cjIsICplbnZjb25mcGF0aDsKICAgIHN0cnVjdCBzdGF0ICAgICBzdGF0YnVmOwogICAgaW50ICAgICAgICAgICAgIHJldCA9IFNOTVBFUlJfR0VORVJSOwoKICAgIGlmICgoTlVMTCA9PSBwYXRoKSB8fCAoTlVMTCA9PSBjdG1wKSkKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgZW52Y29uZnBhdGggPSBzdHJkdXAocGF0aCk7CgogICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOnBhdGgiLCAiIGNvbmZpZyBwYXRoIHVzZWQgZm9yICVzOiVzIChwZXJzaXN0ZW50IHBhdGg6JXMpXG4iLAogICAgICAgICAgICAgICAgY3RtcC0+ZmlsZUhlYWRlciwgZW52Y29uZnBhdGgsIHBlcnNwYXRoKSk7CiAgICBjcHRyMSA9IGNwdHIyID0gZW52Y29uZnBhdGg7CiAgICBkb25lID0gMDsKICAgIHdoaWxlICgoIWRvbmUpICYmICgqY3B0cjIgIT0gMCkpIHsKICAgICAgICB3aGlsZSAoKmNwdHIxICE9IDAgJiYgKmNwdHIxICE9IEVOVl9TRVBBUkFUT1JfQ0hBUikKICAgICAgICAgICAgY3B0cjErKzsKICAgICAgICBpZiAoKmNwdHIxID09IDApCiAgICAgICAgICAgIGRvbmUgPSAxOwogICAgICAgIGVsc2UKICAgICAgICAgICAgKmNwdHIxID0gMDsKCiAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOmRpciIsICIgY29uZmlnIGRpcjogJXNcbiIsIGNwdHIyICkpOwogICAgICAgIGlmIChzdGF0KGNwdHIyLCAmc3RhdGJ1ZikgIT0gMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBEaXJlY3Rvcnkgbm90IHRoZXJlLCBjb250aW51ZSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZzpkaXIiLCAiIERpcmVjdG9yeSBub3QgcHJlc2VudDogJXNcbiIsIGNwdHIyICkpOwogICAgICAgICAgICBjcHRyMiA9ICsrY3B0cjE7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KI2lmZGVmIFNfSVNESVIKICAgICAgICBpZiAoIVNfSVNESVIoc3RhdGJ1Zi5zdF9tb2RlKSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBOb3QgYSBkaXJlY3RvcnksIGNvbnRpbnVlIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOmRpciIsICIgTm90IGEgZGlyZWN0b3J5OiAlc1xuIiwgY3B0cjIgKSk7CiAgICAgICAgICAgIGNwdHIyID0gKytjcHRyMTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgLyoKICAgICAgICAgKiBmb3IgcHJvcGVyIHBlcnNpc3RlbnQgc3RvcmFnZSByZXRyaWV2YWwsIHdlIG5lZWQgdG8gcmVhZCBvbGQgYmFja3VwCiAgICAgICAgICogY29waWVzIG9mIHRoZSBwcmV2aW91cyBzdG9yYWdlIGZpbGVzLiAgSWYgdGhlIGFwcGxpY2F0aW9uIGluCiAgICAgICAgICogcXVlc3Rpb24gaGFzIGRpZWQgd2l0aG91dCB0aGUgcHJvcGVyIGNhbGwgdG8gc25tcF9jbGVhbl9wZXJzaXN0ZW50LAogICAgICAgICAqIHRoZW4gd2UgcmVhZCBhbGwgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZXMgd2UgY2FuLCBzdGFydGluZyB3aXRoCiAgICAgICAgICogdGhlIG9sZGVzdCBmaXJzdC4KICAgICAgICAgKi8KICAgICAgICBpZiAoc3RybmNtcChjcHRyMiwgcGVyc3BhdGgsIHN0cmxlbihwZXJzcGF0aCkpID09IDAgfHwKICAgICAgICAgICAgKHBlcnNmaWxlICE9IE5VTEwgJiYKICAgICAgICAgICAgIHN0cm5jbXAoY3B0cjIsIHBlcnNmaWxlLCBzdHJsZW4ocGVyc2ZpbGUpKSA9PSAwKSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWc6cGVyc2lzdCIsICIgcGVyc2lzdCBkaXI6ICVzXG4iLCBjcHRyMiApKTsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogbGltaXQgdGhpcyB0byB0aGUga25vd24gc3RvcmFnZSBkaXJlY3Rvcnkgb25seSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPD0gTkVUU05NUF9NQVhfUEVSU0lTVEVOVF9CQUNLVVBTOyBqKyspIHsKICAgICAgICAgICAgICAgIHNucHJpbnRmKGNvbmZpZ2ZpbGUsIHNpemVvZihjb25maWdmaWxlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICIlcy8lcy4lZC5jb25mIiwgY3B0cjIsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdG1wLT5maWxlSGVhZGVyLCBqKTsKICAgICAgICAgICAgICAgIGNvbmZpZ2ZpbGVbIHNpemVvZihjb25maWdmaWxlKS0xIF0gPSAwOwogICAgICAgICAgICAgICAgaWYgKHN0YXQoY29uZmlnZmlsZSwgJnN0YXRidWYpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIGZpbGUgbm90IHRoZXJlLCBjb250aW51ZSAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBiYWNrdXAgZXhpc3RzLCByZWFkIGl0IAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19maWxlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9sZCBjb25maWcgZmlsZSBmb3VuZDogJXMsIHBhcnNpbmdcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnZmlsZSkpOwogICAgICAgICAgICAgICAgICAgIGlmIChyZWFkX2NvbmZpZyhjb25maWdmaWxlLCBjdG1wLT5zdGFydCwgd2hlbikgPT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc25wcmludGYoY29uZmlnZmlsZSwgc2l6ZW9mKGNvbmZpZ2ZpbGUpLAogICAgICAgICAgICAgICAgICIlcy8lcy5jb25mIiwgY3B0cjIsIGN0bXAtPmZpbGVIZWFkZXIpOwogICAgICAgIGNvbmZpZ2ZpbGVbIHNpemVvZihjb25maWdmaWxlKS0xIF0gPSAwOwogICAgICAgIGlmIChyZWFkX2NvbmZpZyhjb25maWdmaWxlLCBjdG1wLT5zdGFydCwgd2hlbikgPT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICByZXQgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICAgICAgc25wcmludGYoY29uZmlnZmlsZSwgc2l6ZW9mKGNvbmZpZ2ZpbGUpLAogICAgICAgICAgICAgICAgICIlcy8lcy5sb2NhbC5jb25mIiwgY3B0cjIsIGN0bXAtPmZpbGVIZWFkZXIpOwogICAgICAgIGNvbmZpZ2ZpbGVbIHNpemVvZihjb25maWdmaWxlKS0xIF0gPSAwOwogICAgICAgIGlmIChyZWFkX2NvbmZpZyhjb25maWdmaWxlLCBjdG1wLT5zdGFydCwgd2hlbikgPT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICByZXQgPSBTTk1QRVJSX1NVQ0NFU1M7CgogICAgICAgIGlmKGRvbmUpCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjcHRyMiA9ICsrY3B0cjE7CiAgICB9CiAgICBTTk1QX0ZSRUUoZW52Y29uZnBhdGgpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogcmVhZF9jb25maWdfZmlsZXMKICoKICogUGFyYW1ldGVyczoKICoJd2hlbgk9PSBQUkVNSUJfQ09ORklHLCBOT1JNQUxfQ09ORklHICAtb3ItICBFSVRIRVJfQ09ORklHCiAqCiAqCiAqIFRyYXZlcnNlIHRoZSBsaXN0IG9mIGNvbmZpZyBmaWxlIHR5cGVzLCBwZXJmb3JtaW5nIHRoZSBmb2xsb3dpbmcgYWN0aW9ucwogKiBmb3IgZWFjaCAtLQogKgogKiBGaXJzdCwgYnVpbGQgYSBzZWFyY2ggcGF0aCBmb3IgY29uZmlnIGZpbGVzLiAgSWYgdGhlIGNvbnRlbnRzIG9mIAogKiBlbnZpcm9ubWVudCB2YXJpYWJsZSBTTk1QQ09ORlBBVEggYXJlIE5VTEwsIHRoZW4gdXNlIHRoZSBmb2xsb3dpbmcKICogcGF0aCBsaXN0ICh3aGVyZSB0aGUgbGFzdCBlbnRyeSBleGlzdHMgb25seSBpZiBIT01FIGlzIG5vbi1udWxsKToKICoKICoJU05NUFNIQVJFUEFUSDpTTk1QTElCUEFUSDoke0hPTUV9Ly5zbm1wCiAqCiAqIFRoZW4sIEluIGVhY2ggb2YgdGhlc2UgZGlyZWN0b3JpZXMsIHJlYWQgY29uZmlnIGZpbGVzIGJ5IHRoZSBuYW1lIG9mOgogKgogKgk8ZGlyPi88ZmlsZUhlYWRlcj4uY29uZgkJLUFORC0KICoJPGRpcj4vPGZpbGVIZWFkZXI+LmxvY2FsLmNvbmYKICoKICogd2hlcmUgPGZpbGVIZWFkZXI+IGlzIHRha2VuIGZyb20gdGhlIGNvbmZpZyBmaWxlIHR5cGUgc3RydWN0dXJlLgogKgogKgogKiBQUkVNSUJfQ09ORklHIGNhdXNlcyBmcmVlX2NvbmZpZygpIHRvIGJlIGludm9rZWQgcHJpb3IgdG8gYW55IG90aGVyIGFjdGlvbi4KICoKICoKICogRVhJVHMgaWYgYW55ICdjb25maWdfZXJyb3JzJyBhcmUgbG9nZ2VkIHdoaWxlIHBhcnNpbmcgY29uZmlnIGZpbGUgbGluZXMuCiAqCiAqIFJldHVybiBTTk1QRVJSX1NVQ0NFU1MgaWYgYW55IGNvbmZpZyBmaWxlcyBhcmUgcHJvY2Vzc2VkCiAqIFJldHVybiBTTk1QRVJSX0dFTkVSUiBpZiBfbm9fIGNvbmZpZyBmaWxlcyBhcmUgcHJvY2Vzc2VkCiAqICAgIFdoZXRoZXIgdGhpcyBpcyBhY3R1YWxseSBhbiBlcnJvciBpcyBsZWZ0IHRvIHRoZSBhcHBsaWNhdGlvbgogKi8KaW50CnJlYWRfY29uZmlnX2ZpbGVzX29mX3R5cGUoaW50IHdoZW4sIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXApCnsKICAgIGNvbnN0IGNoYXIgICAgICpjb25mcGF0aCwgKnBlcnNmaWxlLCAqZW52Y29uZnBhdGg7CiAgICBjaGFyICAgICAgICAgICAqcGVyc3BhdGg7CiAgICBpbnQgICAgICAgICAgICAgcmV0ID0gU05NUEVSUl9HRU5FUlI7CgogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfRE9OVF9QRVJTSVNUX1NUQVRFKQogICAgICAgIHx8IG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfRElTQUJMRV9DT05GSUdfTE9BRCkKICAgICAgICB8fCAoTlVMTCA9PSBjdG1wKSkgcmV0dXJuIHJldDsKCiAgICAvKgogICAgICogdGhlc2Ugc2hvdWxkbid0IGNoYW5nZQogICAgICovCiAgICBjb25mcGF0aCA9IGdldF9jb25maWd1cmF0aW9uX2RpcmVjdG9yeSgpOwogICAgcGVyc2ZpbGUgPSBuZXRzbm1wX2dldGVudigiU05NUF9QRVJTSVNURU5UX0ZJTEUiKTsKICAgIGVudmNvbmZwYXRoID0gbmV0c25tcF9nZXRlbnYoIlNOTVBDT05GUEFUSCIpOwoKCiAgICAgICAgLyoKICAgICAgICAgKiByZWFkIHRoZSBjb25maWcgZmlsZXMuIHN0cmR1cCgpIHRoZSByZXN1bHQgb2YKICAgICAgICAgKiBnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSB0byBhdm9pZCB0aGF0IHBhcnNpbmcgdGhlICJwZXJzaXN0ZW50RGlyIgogICAgICAgICAqIGtleXdvcmQgdHJhbnNmb3JtcyB0aGUgcGVyc3BhdGggcG9pbnRlciBpbnRvIGEgZGFuZ2xpbmcgcG9pbnRlci4KICAgICAgICAgKi8KICAgICAgICBwZXJzcGF0aCA9IHN0cmR1cChnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSk7CiAgICAgICAgaWYgKGVudmNvbmZwYXRoID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcmVhZCBqdXN0IHRoZSBjb25maWcgZmlsZXMgKG5vIHBlcnNpc3RlbnQgc3R1ZmYpLCBzaW5jZQogICAgICAgICAgICAgKiBwZXJzaXN0ZW50IHBhdGggY2FuIGNoYW5nZSB2aWEgY29uZiBmaWxlLiBUaGVuIGdldCB0aGUKICAgICAgICAgICAgICogY3VycmVudCBwZXJzaXN0ZW50IGRpcmVjdG9yeSwgYW5kIHJlYWQgZmlsZXMgdGhlcmUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIHJlYWRfY29uZmlnX2ZpbGVzX2luX3BhdGgoY29uZnBhdGgsIGN0bXAsIHdoZW4sIHBlcnNwYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcnNmaWxlKSA9PSBTTk1QRVJSX1NVQ0NFU1MgKQogICAgICAgICAgICAgICAgcmV0ID0gU05NUEVSUl9TVUNDRVNTOwogICAgICAgICAgICBmcmVlKHBlcnNwYXRoKTsKICAgICAgICAgICAgcGVyc3BhdGggPSBzdHJkdXAoZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KCkpOwogICAgICAgICAgICBpZiAoIHJlYWRfY29uZmlnX2ZpbGVzX2luX3BhdGgocGVyc3BhdGgsIGN0bXAsIHdoZW4sIHBlcnNwYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcnNmaWxlKSA9PSBTTk1QRVJSX1NVQ0NFU1MgKQogICAgICAgICAgICAgICAgcmV0ID0gU05NUEVSUl9TVUNDRVNTOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogb25seSByZWFkIHBhdGggc3BlY2lmaWVkIGJ5IHVzZXIKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICggcmVhZF9jb25maWdfZmlsZXNfaW5fcGF0aChlbnZjb25mcGF0aCwgY3RtcCwgd2hlbiwgcGVyc3BhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyc2ZpbGUpID09IFNOTVBFUlJfU1VDQ0VTUyApCiAgICAgICAgICAgICAgICByZXQgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICAgICAgfQogICAgICAgIGZyZWUocGVyc3BhdGgpOwogICAgICAgIHJldHVybiByZXQ7Cn0KCi8qCiAqIFJldHVybiBTTk1QRVJSX1NVQ0NFU1MgaWYgYW55IGNvbmZpZyBmaWxlcyBhcmUgcHJvY2Vzc2VkCiAqIFJldHVybiBTTk1QRVJSX0dFTkVSUiBpZiBfbm9fIGNvbmZpZyBmaWxlcyBhcmUgcHJvY2Vzc2VkCiAqICAgIFdoZXRoZXIgdGhpcyBpcyBhY3R1YWxseSBhbiBlcnJvciBpcyBsZWZ0IHRvIHRoZSBhcHBsaWNhdGlvbgogKi8KaW50CnJlYWRfY29uZmlnX2ZpbGVzKGludCB3aGVuKSB7CgogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCA9IGNvbmZpZ19maWxlczsKICAgIGludCAgICAgICAgICAgICAgICAgIHJldCAgPSBTTk1QRVJSX0dFTkVSUjsKCiAgICBjb25maWdfZXJyb3JzID0gMDsKCiAgICBpZiAod2hlbiA9PSBQUkVNSUJfQ09ORklHKQogICAgICAgIGZyZWVfY29uZmlnKCk7CgogICAgLyoKICAgICAqIHJlYWQgYWxsIGNvbmZpZyBmaWxlIHR5cGVzIAogICAgICovCiAgICBmb3IgKDsgY3RtcCAhPSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkgewogICAgICAgIGlmICggcmVhZF9jb25maWdfZmlsZXNfb2ZfdHlwZSh3aGVuLCBjdG1wKSA9PSBTTk1QRVJSX1NVQ0NFU1MgKQogICAgICAgICAgICByZXQgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKGNvbmZpZ19lcnJvcnMpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0LXNubXA6ICVkIGVycm9yKHMpIGluIGNvbmZpZyBmaWxlKHMpXG4iLAogICAgICAgICAgICAgICAgIGNvbmZpZ19lcnJvcnMpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKdm9pZApyZWFkX2NvbmZpZ19wcmludF91c2FnZShjb25zdCBjaGFyICpsZWFkKQp7CiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjdG1wID0gY29uZmlnX2ZpbGVzOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpsdG1wOwoKICAgIGlmIChsZWFkID09IE5VTEwpCiAgICAgICAgbGVhZCA9ICIiOwoKICAgIGZvciAoY3RtcCA9IGNvbmZpZ19maWxlczsgY3RtcCAhPSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkgewogICAgICAgIHNubXBfbG9nKExPR19JTkZPLCAiJXNJbiAlcy5jb25mIGFuZCAlcy5sb2NhbC5jb25mOlxuIiwgbGVhZCwKICAgICAgICAgICAgICAgICBjdG1wLT5maWxlSGVhZGVyLCBjdG1wLT5maWxlSGVhZGVyKTsKICAgICAgICBmb3IgKGx0bXAgPSBjdG1wLT5zdGFydDsgbHRtcCAhPSBOVUxMOyBsdG1wID0gbHRtcC0+bmV4dCkgewogICAgICAgICAgICBERUJVR0lGKCJyZWFkX2NvbmZpZ191c2FnZSIpIHsKICAgICAgICAgICAgICAgIGlmIChsdG1wLT5jb25maWdfdGltZSA9PSBQUkVNSUJfQ09ORklHKQogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgicmVhZF9jb25maWdfdXNhZ2UiLCAiKiIpKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoInJlYWRfY29uZmlnX3VzYWdlIiwgIiAiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGx0bXAtPmhlbHApIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19JTkZPLCAiJXMlcyUtMjRzICVzXG4iLCBsZWFkLCBsZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgbHRtcC0+Y29uZmlnX3Rva2VuLCBsdG1wLT5oZWxwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIERFQlVHSUYoInJlYWRfY29uZmlnX3VzYWdlIikgewogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19JTkZPLCAiJXMlcyUtMjRzIFtOTyBIRUxQXVxuIiwgbGVhZCwgbGVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsdG1wLT5jb25maWdfdG9rZW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgovKioKICogcmVhZF9jb25maWdfc3RvcmUgaW50ZW5kZWQgZm9yIHVzZSBieSBhcHBsaWNhdGlvbnMgdG8gc3RvcmUgcGVybWVuYW50CiAqIGNvbmZpZ3VyYXRpb24gaW5mb3JtYXRpb24gZ2VuZXJhdGVkIGJ5IHNldHMgb3IgcGVyc2lzdGVudCBjb3VudGVycy4KICogQXBwZW5kcyBsaW5lIHRvIGEgZmlsZSBuYW1lZCBlaXRoZXIgRU5WKFNOTVBfUEVSU0lTVEVOVF9GSUxFKSBvcgogKiAgICI8TkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWT4vPHR5cGU+LmNvbmYiLgogKiBBZGRzIGEgdHJhaWxpbmcgbmV3bGluZSB0byB0aGUgc3RvcmVkIGZpbGUgaWYgbmVjZXNzYXJ5LgogKgogKiBAcGFyYW0gdHlwZSBpcyB0aGUgYXBwbGljYXRpb24gbmFtZQogKiBAcGFyYW0gbGluZSBpcyB0aGUgY29uZmlndXJhdGlvbiBsaW5lIHdyaXR0ZW4gdG8gdGhlIGFwcGxpY2F0aW9uIG5hbWUncwogKiBjb25maWd1cmF0aW9uIGZpbGUKICogICAgICAKICogQHJldHVybiB2b2lkCiAgKi8Kdm9pZApyZWFkX2NvbmZpZ19zdG9yZShjb25zdCBjaGFyICp0eXBlLCBjb25zdCBjaGFyICpsaW5lKQp7CiNpZmRlZiBORVRTTk1QX1BFUlNJU1RFTlRfRElSRUNUT1JZCiAgICBjaGFyICAgICAgICAgICAgZmlsZVs1MTJdLCAqZmlsZXA7CiAgICBGSUxFICAgICAgICAgICAqZm91dDsKI2lmZGVmIE5FVFNOTVBfUEVSU0lTVEVOVF9NQVNLCiAgICBtb2RlX3QgICAgICAgICAgb2xkbWFzazsKI2VuZGlmCgogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfRE9OVF9QRVJTSVNUX1NUQVRFKQogICAgIHx8IG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfRElTQUJMRV9QRVJTSVNURU5UX0xPQUQpKSByZXR1cm47CgogICAgLyoKICAgICAqIHN0b3JlIGNvbmZpZ3VyYXRpb24gZGlyZWN0aXZlcyBpbiB0aGUgZm9sbG93aW5nIG9yZGVyIG9mIHByZWZlcmVuY2U6CiAgICAgKiAxLiBFTlYgdmFyaWFibGUgU05NUF9QRVJTSVNURU5UX0ZJTEUKICAgICAqIDIuIGNvbmZpZ3VyZWQgPE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlk+Lzx0eXBlPi5jb25mCiAgICAgKi8KICAgIGlmICgoZmlsZXAgPSBuZXRzbm1wX2dldGVudigiU05NUF9QRVJTSVNURU5UX0ZJTEUiKSkgPT0gTlVMTCkgewogICAgICAgIHNucHJpbnRmKGZpbGUsIHNpemVvZihmaWxlKSwKICAgICAgICAgICAgICAgICAiJXMvJXMuY29uZiIsIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpLCB0eXBlKTsKICAgICAgICBmaWxlWyBzaXplb2YoZmlsZSktMSBdID0gMDsKICAgICAgICBmaWxlcCA9IGZpbGU7CiAgICB9CiNpZmRlZiBORVRTTk1QX1BFUlNJU1RFTlRfTUFTSwogICAgb2xkbWFzayA9IHVtYXNrKE5FVFNOTVBfUEVSU0lTVEVOVF9NQVNLKTsKI2VuZGlmCiAgICBpZiAobWtkaXJoaWVyKGZpbGVwLCBORVRTTk1QX0FHRU5UX0RJUkVDVE9SWV9NT0RFLCAxKSkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBjcmVhdGUgdGhlIHBlcnNpc3RlbnQgZGlyZWN0b3J5IGZvciAlc1xuIiwKICAgICAgICAgICAgICAgICBmaWxlKTsKICAgIH0KICAgIGlmICgoZm91dCA9IGZvcGVuKGZpbGVwLCAiYSIpKSAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50Zihmb3V0LCAiJXMiLCBsaW5lKTsKICAgICAgICBpZiAobGluZVtzdHJsZW4obGluZSldICE9ICdcbicpCiAgICAgICAgICAgIGZwcmludGYoZm91dCwgIlxuIik7CiAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOnN0b3JlIiwgInN0b3Jpbmc6ICVzXG4iLCBsaW5lKSk7CiAgICAgICAgZmNsb3NlKGZvdXQpOwogICAgfSBlbHNlIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAicmVhZF9jb25maWdfc3RvcmUgb3BlbiBmYWlsdXJlIG9uICVzXG4iLCBmaWxlcCk7CiAgICB9CiNpZmRlZiBORVRTTk1QX1BFUlNJU1RFTlRfTUFTSwogICAgdW1hc2sob2xkbWFzayk7CiNlbmRpZgoKI2VuZGlmCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHJlYWRfY29uZmlnX3N0b3JlKCkgKi8KCnZvaWQKcmVhZF9hcHBfY29uZmlnX3N0b3JlKGNvbnN0IGNoYXIgKmxpbmUpCnsKICAgIHJlYWRfY29uZmlnX3N0b3JlKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJCSAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFKSwgbGluZSk7Cn0KCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIHNubXBfc2F2ZV9wZXJzaXN0ZW50CiAqCiAqIFBhcmFtZXRlcnM6CiAqCSp0eXBlCiAqICAgICAgCiAqCiAqIFNhdmUgdGhlIGZpbGUgIjxORVRTTk1QX1BFUlNJU1RFTlRfRElSRUNUT1JZPi88dHlwZT4uY29uZiIgaW50byBhIGJhY2t1cCBjb3B5CiAqIGNhbGxlZCAiPE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlk+Lzx0eXBlPi4lZC5jb25mIiwgd2hpY2ggJWQgaXMgYW4KICogaW5jcmVtZW50aW5nIG51bWJlciBvbiBlYWNoIGNhbGwsIGJ1dCBsZXNzIHRoYW4gTkVUU05NUF9NQVhfUEVSU0lTVEVOVF9CQUNLVVBTLgogKgogKiBTaG91bGQgYmUgY2FsbGVkIGp1c3QgYmVmb3JlIGFsbCBwZXJzaXN0ZW50IGluZm9ybWF0aW9uIGlzIHN1cHBvc2VkIHRvIGJlCiAqIHdyaXR0ZW4gdG8gbW92ZSBhc2lkZSB0aGUgZXhpc3RpbmcgcGVyc2lzdGVudCBjYWNoZS4KICogc25tcF9jbGVhbl9wZXJzaXN0ZW50IHNob3VsZCB0aGVuIGJlIGNhbGxlZCBhZnRlcndhcmQgYWxsIGRhdGEgaGFzIGJlZW4KICogc2F2ZWQgdG8gcmVtb3ZlIHRoZXNlIGJhY2t1cCBmaWxlcy4KICoKICogTm90ZTogb24gYW4gcmVuYW1lIGVycm9yLCB0aGUgZmlsZXMgYXJlIHJlbW92ZWQgcmF0aGVyIHRoYW4gc2F2ZWQuCiAqCiAqLwp2b2lkCnNubXBfc2F2ZV9wZXJzaXN0ZW50KGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIGNoYXIgICAgICAgICAgICBmaWxlWzUxMl0sIGZpbGVvbGRbU1BSSU5UX01BWF9MRU5dOwogICAgc3RydWN0IHN0YXQgICAgIHN0YXRidWY7CiAgICBpbnQgICAgICAgICAgICAgajsKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ET05UX1BFUlNJU1RfU1RBVEUpCiAgICAgfHwgbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ESVNBQkxFX1BFUlNJU1RFTlRfU0FWRSkpIHJldHVybjsKCiAgICBERUJVR01TR1RMKCgic25tcF9zYXZlX3BlcnNpc3RlbnQiLCAic2F2aW5nICVzIGZpbGVzLi4uXG4iLCB0eXBlKSk7CiAgICBzbnByaW50ZihmaWxlLCBzaXplb2YoZmlsZSksCiAgICAgICAgICAgICAiJXMvJXMuY29uZiIsIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpLCB0eXBlKTsKICAgIGZpbGVbIHNpemVvZihmaWxlKS0xIF0gPSAwOwogICAgaWYgKHN0YXQoZmlsZSwgJnN0YXRidWYpID09IDApIHsKICAgICAgICBmb3IgKGogPSAwOyBqIDw9IE5FVFNOTVBfTUFYX1BFUlNJU1RFTlRfQkFDS1VQUzsgaisrKSB7CiAgICAgICAgICAgIHNucHJpbnRmKGZpbGVvbGQsIHNpemVvZihmaWxlb2xkKSwKICAgICAgICAgICAgICAgICAgICAgIiVzLyVzLiVkLmNvbmYiLCBnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSwgdHlwZSwgaik7CiAgICAgICAgICAgIGZpbGVvbGRbIHNpemVvZihmaWxlb2xkKS0xIF0gPSAwOwogICAgICAgICAgICBpZiAoc3RhdChmaWxlb2xkLCAmc3RhdGJ1ZikgIT0gMCkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfc2F2ZV9wZXJzaXN0ZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgc2F2aW5nIG9sZCBjb25maWcgZmlsZTogJXMgLT4gJXMuXG4iLCBmaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW9sZCkpOwogICAgICAgICAgICAgICAgaWYgKHJlbmFtZShmaWxlLCBmaWxlb2xkKSkgewogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJDYW5ub3QgcmVuYW1lICVzIHRvICVzXG4iLCBmaWxlLCBmaWxlb2xkKTsKICAgICAgICAgICAgICAgICAgICAgLyogbW92aW5nIGl0IGZhaWxlZCwgdHJ5IG51a2luZyBpdCwgYXMgbGVhdmluZwogICAgICAgICAgICAgICAgICAgICAgKiBpdCBhcm91bmQgaXMgdmVyeSBiYWQuICovCiAgICAgICAgICAgICAgICAgICAgaWYgKHVubGluayhmaWxlKSA9PSAtMSkKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkNhbm5vdCB1bmxpbmsgJXNcbiIsIGZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvKgogICAgICogc2F2ZSBhIHdhcm5pbmcgaGVhZGVyIHRvIHRoZSB0b3Agb2YgdGhlIG5ldyBmaWxlIAogICAgICovCiAgICBzbnByaW50ZihmaWxlb2xkLCBzaXplb2YoZmlsZW9sZCksCiAgICAgICAgICAgICIlcyVzIyBQbGVhc2Ugc2F2ZSBub3JtYWwgY29uZmlndXJhdGlvbiB0b2tlbnMgZm9yICVzIGluIFNOTVBDT05GUEFUSC8lcy5jb25mLlxuIyBPbmx5IFwiY3JlYXRlVXNlclwiIHRva2VucyBzaG91bGQgYmUgcGxhY2VkIGhlcmUgYnkgJXMgYWRtaW5pc3RyYXRvcnMuXG4lcyIsCiAgICAgICAgICAgICIjXG4jIG5ldC1zbm1wIChvciB1Y2Qtc25tcCkgcGVyc2lzdGVudCBkYXRhIGZpbGUuXG4jXG4jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjXG4jIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFxuIiwKICAgICAgICAgICAgIiNcbiMgICAgICAgICAgKioqKiBETyBOT1QgRURJVCBUSElTIEZJTEUgKioqKlxuI1xuIyBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBcbiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbiNcbiMgRE8gTk9UIFNUT1JFIENPTkZJR1VSQVRJT04gRU5UUklFUyBIRVJFLlxuIiwKICAgICAgICAgICAgdHlwZSwgdHlwZSwgdHlwZSwKCSAgICAiIyAoRGlkIEkgbWVudGlvbjogZG8gbm90IGVkaXQgdGhpcyBmaWxlPylcbiNcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG4iKTsKICAgIGZpbGVvbGRbIHNpemVvZihmaWxlb2xkKS0xIF0gPSAwOwogICAgcmVhZF9jb25maWdfc3RvcmUodHlwZSwgZmlsZW9sZCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBzbm1wX2NsZWFuX3BlcnNpc3RlbnQKICoKICogUGFyYW1ldGVyczoKICoJKnR5cGUKICogICAgICAKICoKICogVW5saW5rIGFsbCBiYWNrdXAgZmlsZXMgY2FsbGVkICI8TkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWT4vPHR5cGU+LiVkLmNvbmYiLgogKgogKiBTaG91bGQgYmUgY2FsbGVkIGp1c3QgYWZ0ZXIgd2Ugc3VjY2Vzc2Z1bGwgZHVtcGVkIHRoZSBsYXN0IG9mIHRoZQogKiBwZXJzaXN0ZW50IGRhdGEsIHRvIHJlbW92ZSB0aGUgYmFja3VwIGNvcGllcyBvZiBwcmV2aW91cyBzdG9yYWdlIGR1bXBzLgogKgogKiBYWFggIFdvcnRoIG92ZXJ3cml0aW5nIHdpdGggcmFuZG9tIGJ5dGVzIGZpcnN0PyAgVGhpcyB3b3VsZAogKgllbnN1cmUgdGhhdCB0aGUgZGF0YSBpcyBkZXN0cm95ZWQsIGV2ZW4gYSBidWZmZXIgY29udGFpbmluZyB0aGUKICoJZGF0YSBwZXJzaXN0cyBpbiBtZW1vcnkgb3Igc3dhcC4gIE9ubHkgaW1wb3J0YW50IGlmIHNlY3JldHMKICoJd2lsbCBiZSBzdG9yZWQgaGVyZS4KICovCnZvaWQKc25tcF9jbGVhbl9wZXJzaXN0ZW50KGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIGNoYXIgICAgICAgICAgICBmaWxlWzUxMl07CiAgICBzdHJ1Y3Qgc3RhdCAgICAgc3RhdGJ1ZjsKICAgIGludCAgICAgICAgICAgICBqOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RPTlRfUEVSU0lTVF9TVEFURSkKICAgICB8fCBuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RJU0FCTEVfUEVSU0lTVEVOVF9TQVZFKSkgcmV0dXJuOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2NsZWFuX3BlcnNpc3RlbnQiLCAiY2xlYW5pbmcgJXMgZmlsZXMuLi5cbiIsIHR5cGUpKTsKICAgIHNucHJpbnRmKGZpbGUsIHNpemVvZihmaWxlKSwKICAgICAgICAgICAgICIlcy8lcy5jb25mIiwgZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KCksIHR5cGUpOwogICAgZmlsZVsgc2l6ZW9mKGZpbGUpLTEgXSA9IDA7CiAgICBpZiAoc3RhdChmaWxlLCAmc3RhdGJ1ZikgPT0gMCkgewogICAgICAgIGZvciAoaiA9IDA7IGogPD0gTkVUU05NUF9NQVhfUEVSU0lTVEVOVF9CQUNLVVBTOyBqKyspIHsKICAgICAgICAgICAgc25wcmludGYoZmlsZSwgc2l6ZW9mKGZpbGUpLAogICAgICAgICAgICAgICAgICAgICAiJXMvJXMuJWQuY29uZiIsIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpLCB0eXBlLCBqKTsKICAgICAgICAgICAgZmlsZVsgc2l6ZW9mKGZpbGUpLTEgXSA9IDA7CiAgICAgICAgICAgIGlmIChzdGF0KGZpbGUsICZzdGF0YnVmKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9jbGVhbl9wZXJzaXN0ZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgcmVtb3Zpbmcgb2xkIGNvbmZpZyBmaWxlOiAlc1xuIiwgZmlsZSkpOwogICAgICAgICAgICAgICAgaWYgKHVubGluayhmaWxlKSA9PSAtMSkKICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiQ2Fubm90IHVubGluayAlc1xuIiwgZmlsZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCgoKCi8qCiAqIGNvbmZpZ19wZXJyb3I6IHByaW50cyBhIHdhcm5pbmcgc3RyaW5nIGFzc29jaWF0ZWQgd2l0aCBhIGZpbGUgYW5kCiAqIGxpbmUgbnVtYmVyIG9mIGEgLmNvbmYgZmlsZSBhbmQgaW5jcmVtZW50cyB0aGUgZXJyb3IgY291bnQuIAogKi8Kc3RhdGljIHZvaWQKY29uZmlnX3Zsb2coaW50IGxldmVsLCBjb25zdCBjaGFyICpsZXZlbG1zZywgY29uc3QgY2hhciAqc3RyLCB2YV9saXN0IGFyZ3MpCnsKICAgIGNoYXIgdG1wYnVmWzI1Nl07CiAgICBjaGFyKiBidWYgPSB0bXBidWY7CiAgICBpbnQgbGVuID0gc25wcmludGYodG1wYnVmLCBzaXplb2YodG1wYnVmKSwgIiVzOiBsaW5lICVkOiAlczogJXNcbiIsCgkJICAgICAgIGN1cmZpbGVuYW1lLCBsaW5lY291bnQsIGxldmVsbXNnLCBzdHIpOwogICAgaWYgKGxlbiA+PSAoaW50KXNpemVvZih0bXBidWYpKSB7CglidWYgPSAoY2hhciopbWFsbG9jKGxlbiArIDEpOwoJc3ByaW50ZihidWYsICIlczogbGluZSAlZDogJXM6ICVzXG4iLAoJCWN1cmZpbGVuYW1lLCBsaW5lY291bnQsIGxldmVsbXNnLCBzdHIpOwogICAgfQogICAgc25tcF92bG9nKGxldmVsLCBidWYsIGFyZ3MpOwogICAgaWYgKGJ1ZiAhPSB0bXBidWYpCglmcmVlKGJ1Zik7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfZXJyb3IoY29uc3QgY2hhciAqc3RyLCAuLi4pCnsKICAgIHZhX2xpc3QgYXJnczsKICAgIHZhX3N0YXJ0KGFyZ3MsIHN0cik7CiAgICBjb25maWdfdmxvZyhMT0dfRVJSLCAiRXJyb3IiLCBzdHIsIGFyZ3MpOwogICAgdmFfZW5kKGFyZ3MpOwogICAgY29uZmlnX2Vycm9ycysrOwp9Cgp2b2lkCm5ldHNubXBfY29uZmlnX3dhcm4oY29uc3QgY2hhciAqc3RyLCAuLi4pCnsKICAgIHZhX2xpc3QgYXJnczsKICAgIHZhX3N0YXJ0KGFyZ3MsIHN0cik7CiAgICBjb25maWdfdmxvZyhMT0dfV0FSTklORywgIldhcm5pbmciLCBzdHIsIGFyZ3MpOwogICAgdmFfZW5kKGFyZ3MpOwp9Cgp2b2lkCmNvbmZpZ19wZXJyb3IoY29uc3QgY2hhciAqc3RyKQp7CiAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiJXMiLCBzdHIpOwp9Cgp2b2lkCmNvbmZpZ19wd2Fybihjb25zdCBjaGFyICpzdHIpCnsKICAgIG5ldHNubXBfY29uZmlnX3dhcm4oIiVzIiwgc3RyKTsKfQoKLyoKICogc2tpcCBhbGwgd2hpdGUgc3BhY2VzIGFuZCByZXR1cm4gMSBpZiBmb3VuZCBzb21ldGhpbmcgZWl0aGVyIGVuZCBvZgogKiBsaW5lIG9yIGEgY29tbWVudCBjaGFyYWN0ZXIgCiAqLwpjaGFyICAgICAgICAgICAqCnNraXBfd2hpdGUoY2hhciAqcHRyKQp7CiAgICByZXR1cm4gTkVUU05NUF9SRU1PVkVfQ09OU1QoY2hhciAqLCBza2lwX3doaXRlX2NvbnN0KHB0cikpOwp9Cgpjb25zdCBjaGFyICAgICAqCnNraXBfd2hpdGVfY29uc3QoY29uc3QgY2hhciAqcHRyKQp7CiAgICBpZiAocHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHdoaWxlICgqcHRyICE9IDAgJiYgaXNzcGFjZSgodW5zaWduZWQgY2hhcikqcHRyKSkKICAgICAgICBwdHIrKzsKICAgIGlmICgqcHRyID09IDAgfHwgKnB0ciA9PSAnIycpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHJldHVybiAocHRyKTsKfQoKY2hhciAgICAgICAgICAgKgpza2lwX25vdF93aGl0ZShjaGFyICpwdHIpCnsKICAgIHJldHVybiBORVRTTk1QX1JFTU9WRV9DT05TVChjaGFyICosIHNraXBfbm90X3doaXRlX2NvbnN0KHB0cikpOwp9Cgpjb25zdCBjaGFyICAgICAqCnNraXBfbm90X3doaXRlX2NvbnN0KGNvbnN0IGNoYXIgKnB0cikKewogICAgaWYgKHB0ciA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB3aGlsZSAoKnB0ciAhPSAwICYmICFpc3NwYWNlKCh1bnNpZ25lZCBjaGFyKSpwdHIpKQogICAgICAgIHB0cisrOwogICAgaWYgKCpwdHIgPT0gMCB8fCAqcHRyID09ICcjJykKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgcmV0dXJuIChwdHIpOwp9CgpjaGFyICAgICAgICAgICAqCnNraXBfdG9rZW4oY2hhciAqcHRyKQp7CiAgICByZXR1cm4gTkVUU05NUF9SRU1PVkVfQ09OU1QoY2hhciAqLCBza2lwX3Rva2VuX2NvbnN0KHB0cikpOwp9Cgpjb25zdCBjaGFyICAgICAqCnNraXBfdG9rZW5fY29uc3QoY29uc3QgY2hhciAqcHRyKQp7CiAgICBwdHIgPSBza2lwX3doaXRlX2NvbnN0KHB0cik7CiAgICBwdHIgPSBza2lwX25vdF93aGl0ZV9jb25zdChwdHIpOwogICAgcHRyID0gc2tpcF93aGl0ZV9jb25zdChwdHIpOwogICAgcmV0dXJuIChwdHIpOwp9CgovKgogKiBjb3B5X3dvcmQKICogY29waWVzIHRoZSBuZXh0ICd0b2tlbicgZnJvbSAnZnJvbScgaW50byAndG8nLCBtYXhpbXVtIGxlbi0xIGNoYXJhY3RlcnMuCiAqIGN1cnJlbnRseSBhIHRva2VuIGlzIGFueXRoaW5nIHNlcGVyYXRlIGJ5IHdoaXRlIHNwYWNlCiAqIG9yIHdpdGhpbiBxdW90ZXMgKGRvdWJsZSBvciBzaW5nbGUpIChpLmUuICJ0aGUgcmVkIHJvc2UiIAogKiBpcyBvbmUgdG9rZW4sIFwidGhlIHJlZCByb3NlXCIgaXMgdGhyZWUgdG9rZW5zKQogKiBhICdcJyBjaGFyYWN0ZXIgd2lsbCBhbGxvdyBhIHF1b3RlIGNoYXJhY3RlciB0byBiZSB0cmVhdGVkCiAqIGFzIGEgcmVndWxhciBjaGFyYWN0ZXIgCiAqIEl0IHJldHVybnMgYSBwb2ludGVyIHRvIGZpcnN0IG5vbi13aGl0ZSBzcGFjZSBhZnRlciB0aGUgZW5kIG9mIHRoZSB0b2tlbgogKiBiZWluZyBjb3BpZWQgb3IgdG8gMCBpZiB3ZSByZWFjaCB0aGUgZW5kLgogKiBOb3RlOiBQYXJ0aWFsbHkgY29waWVkIHdvcmRzIChncmVhdGVyIHRoYW4gbGVuKSBzdGlsbCByZXR1cm5zIGEgIU5VTEwgcHRyCiAqIE5vdGU6IHBhcnRpYWxseSBjb3BpZWQgd29yZHMgYXJlLCBob3dldmVyLCBudWxsIHRlcm1pbmF0ZWQuCiAqLwoKY2hhciAgICAgICAgICAgKgpjb3B5X253b3JkKGNoYXIgKmZyb20sIGNoYXIgKnRvLCBpbnQgbGVuKQp7CiAgICByZXR1cm4gTkVUU05NUF9SRU1PVkVfQ09OU1QoY2hhciAqLCBjb3B5X253b3JkX2NvbnN0KGZyb20sIHRvLCBsZW4pKTsKfQoKY29uc3QgY2hhciAgICAgICAgICAgKgpjb3B5X253b3JkX2NvbnN0KGNvbnN0IGNoYXIgKmZyb20sIGNoYXIgKnRvLCBpbnQgbGVuKQp7CiAgICBjaGFyICAgICAgICAgICAgcXVvdGU7CiAgICBpZiAoIWZyb20gfHwgIXRvKQogICAgICAgIHJldHVybiBOVUxMOwogICAgaWYgKCgqZnJvbSA9PSAnXCInKSB8fCAoKmZyb20gPT0gJ1wnJykpIHsKICAgICAgICBxdW90ZSA9ICooZnJvbSsrKTsKICAgICAgICB3aGlsZSAoKCpmcm9tICE9IHF1b3RlKSAmJiAoKmZyb20gIT0gMCkpIHsKICAgICAgICAgICAgaWYgKCgqZnJvbSA9PSAnXFwnKSAmJiAoKihmcm9tICsgMSkgIT0gMCkpIHsKICAgICAgICAgICAgICAgIGlmIChsZW4gPiAwKSB7ICAvKiBkb24ndCBjb3B5IGJleW9uZCBsZW4gYnl0ZXMgKi8KICAgICAgICAgICAgICAgICAgICAqdG8rKyA9ICooZnJvbSArIDEpOwogICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbiA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAqKHRvIC0gMSkgPSAnXDAnOyAgICAgICAvKiBudWxsIHByb3RlY3QgdGhlIGxhc3Qgc3BvdCAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnJvbSA9IGZyb20gKyAyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGxlbiA+IDApIHsgIC8qIGRvbid0IGNvcHkgYmV5b25kIGxlbiBieXRlcyAqLwogICAgICAgICAgICAgICAgICAgICp0bysrID0gKmZyb20rKzsKICAgICAgICAgICAgICAgICAgICBpZiAoLS1sZW4gPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgKih0byAtIDEpID0gJ1wwJzsgICAgICAgLyogbnVsbCBwcm90ZWN0IHRoZSBsYXN0IHNwb3QgKi8KICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgIGZyb20rKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoKmZyb20gPT0gMCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfY29weV93b3JkIiwKICAgICAgICAgICAgICAgICAgICAgICAgIm5vIGVuZCBxdW90ZSBmb3VuZCBpbiBjb25maWcgc3RyaW5nXG4iKSk7CiAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIGZyb20rKzsKICAgIH0gZWxzZSB7CiAgICAgICAgd2hpbGUgKCpmcm9tICE9IDAgJiYgIWlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKCpmcm9tKSkpIHsKICAgICAgICAgICAgaWYgKCgqZnJvbSA9PSAnXFwnKSAmJiAoKihmcm9tICsgMSkgIT0gMCkpIHsKICAgICAgICAgICAgICAgIGlmIChsZW4gPiAwKSB7ICAvKiBkb24ndCBjb3B5IGJleW9uZCBsZW4gYnl0ZXMgKi8KICAgICAgICAgICAgICAgICAgICAqdG8rKyA9ICooZnJvbSArIDEpOwogICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbiA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAqKHRvIC0gMSkgPSAnXDAnOyAgICAgICAvKiBudWxsIHByb3RlY3QgdGhlIGxhc3Qgc3BvdCAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnJvbSA9IGZyb20gKyAyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGxlbiA+IDApIHsgIC8qIGRvbid0IGNvcHkgYmV5b25kIGxlbiBieXRlcyAqLwogICAgICAgICAgICAgICAgICAgICp0bysrID0gKmZyb20rKzsKICAgICAgICAgICAgICAgICAgICBpZiAoLS1sZW4gPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgKih0byAtIDEpID0gJ1wwJzsgICAgICAgLyogbnVsbCBwcm90ZWN0IHRoZSBsYXN0IHNwb3QgKi8KICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgIGZyb20rKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGlmIChsZW4gPiAwKQogICAgICAgICp0byA9IDA7CiAgICBmcm9tID0gc2tpcF93aGl0ZV9jb25zdChmcm9tKTsKICAgIHJldHVybiAoZnJvbSk7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY29weV9ud29yZCAqLwoKLyoKICogY29weV93b3JkCiAqIGNvcGllcyB0aGUgbmV4dCAndG9rZW4nIGZyb20gJ2Zyb20nIGludG8gJ3RvJy4KICogY3VycmVudGx5IGEgdG9rZW4gaXMgYW55dGhpbmcgc2VwZXJhdGUgYnkgd2hpdGUgc3BhY2UKICogb3Igd2l0aGluIHF1b3RlcyAoZG91YmxlIG9yIHNpbmdsZSkgKGkuZS4gInRoZSByZWQgcm9zZSIgCiAqIGlzIG9uZSB0b2tlbiwgXCJ0aGUgcmVkIHJvc2VcIiBpcyB0aHJlZSB0b2tlbnMpCiAqIGEgJ1wnIGNoYXJhY3RlciB3aWxsIGFsbG93IGEgcXVvdGUgY2hhcmFjdGVyIHRvIGJlIHRyZWF0ZWQKICogYXMgYSByZWd1bGFyIGNoYXJhY3RlciAKICogSXQgcmV0dXJucyBhIHBvaW50ZXIgdG8gZmlyc3Qgbm9uLXdoaXRlIHNwYWNlIGFmdGVyIHRoZSBlbmQgb2YgdGhlIHRva2VuCiAqIGJlaW5nIGNvcGllZCBvciB0byAwIGlmIHdlIHJlYWNoIHRoZSBlbmQuCiAqLwoKc3RhdGljIGludCAgICAgIGhhdmVfd2FybmVkID0gMDsKY2hhciAgICAgICAgICAgKgpjb3B5X3dvcmQoY2hhciAqZnJvbSwgY2hhciAqdG8pCnsKICAgIGlmICghaGF2ZV93YXJuZWQpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfSU5GTywKICAgICAgICAgICAgICAgICAiY29weV93b3JkKCkgY2FsbGVkLiAgVXNlIGNvcHlfbndvcmQoKSBpbnN0ZWFkLlxuIik7CiAgICAgICAgaGF2ZV93YXJuZWQgPSAxOwogICAgfQogICAgcmV0dXJuIGNvcHlfbndvcmQoZnJvbSwgdG8sIFNQUklOVF9NQVhfTEVOKTsKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjb3B5X3dvcmQgKi8KCi8qKgogKiBTdG9yZXMgYW4gcXVvdGVkIHZlcnNpb24gb2YgdGhlIGZpcnN0IGxlbiBieXRlcyBmcm9tIHN0ciBpbnRvIHNhdmV0by4KICoKICogSWYgYWxsIG9jdGV0cyBpbiBzdHIgYXJlIGluIHRoZSBzZXQgW1s6YWxudW06XSBdIHRoZW4gdGhlIHF1b3RhdGlvbgogKiBpcyB0byBlbmNsb3NlIHRoZSBzdHJpbmcgaW4gcXVvdGF0aW9uIG1hcmtzICgic3RyIikgb3RoZXJ3aXNlIHRoZQogKiBxdW90YXRpb24gaXMgdG8gcHJlcGVuZCB0aGUgc3RyaW5nIDB4IGFuZCB0aGVuIGFkZCB0aGUgaGV4IHJlcHJlc2VudGF0aW9uCiAqIG9mIGFsbCBjaGFyYWN0ZXJzIGZyb20gc3RyICgweDczNzQ3MikKICoKICogQHBhcmFtW2luXSBzYXZldG8gcG9pbnRlciB0byBvdXRwdXQgc3RyZWFtLCBpcyBhc3N1bWVkIHRvIGJlIGJpZyBlbm91Z2guCiAqIEBwYXJhbVtpbl0gc3RyIHBvaW50ZXIgb2YgdGhlIGRhdGEgdGhhdCBpcyB0byBiZSBzdG9yZWQuCiAqIEBwYXJhbVtpbl0gbGVuIGxlbmd0aCBvZiB0aGUgZGF0YSB0aGF0IGlzIHRvIGJlIHN0b3JlZC4KICogQHJldHVybiBBIHBvaW50ZXIgdG8gc2F2ZXRvIGFmdGVyIHN0ciBpcyBhZGRlZCB0byBpdC4KICovCmNoYXIgICAgICAgICAgICoKcmVhZF9jb25maWdfc2F2ZV9vY3RldF9zdHJpbmcoY2hhciAqc2F2ZXRvLCBjb25zdCB1X2NoYXIgKiBzdHIsIHNpemVfdCBsZW4pCnsKICAgIHNpemVfdCAgICAgICAgICBpOwogICAgY29uc3QgdV9jaGFyICAgKmNwOwoKICAgIC8qCiAgICAgKiBpcyBldmVyeXRoaW5nIGVhc2lseSBwcmludGFibGUKICAgICAqLwogICAgZm9yIChpID0gMCwgY3AgPSBzdHI7IGkgPCBsZW4gJiYgY3AgJiYKICAgICAgICAgKGlzYWxwaGEoKmNwKSB8fCBpc2RpZ2l0KCpjcCkgfHwgKmNwID09ICcgJyk7IGNwKyssIGkrKyk7CgogICAgaWYgKGxlbiAhPSAwICYmIGkgPT0gbGVuKSB7CiAgICAgICAgKnNhdmV0bysrID0gJyInOwogICAgICAgIG1lbWNweShzYXZldG8sIHN0ciwgbGVuKTsKICAgICAgICBzYXZldG8gKz0gbGVuOwogICAgICAgICpzYXZldG8rKyA9ICciJzsKICAgICAgICAqc2F2ZXRvID0gJ1wwJzsKICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHN0ciAhPSBOVUxMKSB7CiAgICAgICAgICAgIHNwcmludGYoc2F2ZXRvLCAiMHgiKTsKICAgICAgICAgICAgc2F2ZXRvICs9IDI7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICAgICAgICAgICAgc3ByaW50ZihzYXZldG8sICIlMDJ4Iiwgc3RyW2ldKTsKICAgICAgICAgICAgICAgIHNhdmV0byA9IHNhdmV0byArIDI7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzcHJpbnRmKHNhdmV0bywgIlwiXCIiKTsKICAgICAgICAgICAgc2F2ZXRvICs9IDI7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHNhdmV0bzsKfQoKLyoqCiAqIFJlYWRzIGFuIG9jdGV0IHN0cmluZyB0aGF0IHdhcyBzYXZlZCBieSB0aGUKICogcmVhZF9jb25maWdfc2F2ZV9vY3RldF9zdHJpbmcoKSBmdW5jdGlvbi4KICoKICogQHBhcmFtW2luXSAgICAgcmVhZGZyb20gUG9pbnRlciB0byB0aGUgaW5wdXQgZGF0YSB0byBiZSBwYXJzZWQuCiAqIEBwYXJhbVtpbixvdXRdIHN0ciAgICAgIFBvaW50ZXIgdG8gdGhlIG91dHB1dCBidWZmZXIgcG9pbnRlci4gVGhlIGRhdGEKICogICB3cml0dGVuIHRvIHRoZSBvdXRwdXQgYnVmZmVyIHdpbGwgYmUgJ1wwJy10ZXJtaW5hdGVkLiBJZiAqc3RyID09IE5VTEwsCiAqICAgYW4gb3V0cHV0IGJ1ZmZlciB3aWxsIGJlIGFsbG9jYXRlZCB0aGF0IGlzIG9uZSBieXRlIGxhcmdlciB0aGFuIHRoZQogKiAgIGRhdGEgc3RvcmVkLgogKiBAcGFyYW1baW4sb3V0XSBsZW4gICAgICBJZiBzdHIgIT0gTlVMTCwgKmxlbiBpcyB0aGUgc2l6ZSBvZiB0aGUgYnVmZmVyICpzdHIKICogICBwb2ludHMgYXQuIElmIHN0ciA9PSBOVUxMLCB0aGUgdmFsdWUgcGFzc2VkIHZpYSAqbGVuIGlzIGlnbm9yZWQuCiAqICAgQmVmb3JlIHRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlYWQgd2lsbCBiZSBzdG9yZWQKICogICBpbiAqbGVuLiBJZiBhIGJ1ZmZlciBvdmVyZmxvdyBvY2N1cnMsICpsZW4gd2lsbCBiZSBzZXQgdG8gMC4KICoKICogQHJldHVybiBBIHBvaW50ZXIgdG8gdGhlIG5leHQgY2hhcmFjdGVyIGluIHRoZSBpbnB1dCB0byBiZSBwYXJzZWQgaWYKICogICBwYXJzaW5nIHN1Y2NlZWRlZDsgTlVMTCB3aGVuIHRoZSBlbmQgb2YgdGhlIGlucHV0IHN0cmluZyBoYXMgYmVlbiByZWFjaGVkCiAqICAgb3IgaWYgYW4gZXJyb3Igb2NjdXJyZWQuCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKGNvbnN0IGNoYXIgKnJlYWRmcm9tLCB1X2NoYXIgKiogc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiBsZW4pCnsKICAgIHJldHVybiBORVRTTk1QX1JFTU9WRV9DT05TVChjaGFyICosCiAgICAgICAgICAgICAgIHJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nX2NvbnN0KHJlYWRmcm9tLCBzdHIsIGxlbikpOwp9Cgpjb25zdCBjaGFyICAgICAqCnJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nX2NvbnN0KGNvbnN0IGNoYXIgKnJlYWRmcm9tLCB1X2NoYXIgKiogc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiBsZW4pCnsKICAgIHVfY2hhciAgICAgICAgICpjcHRyOwogICAgY29uc3QgY2hhciAgICAgKmNwdHIxOwogICAgdV9pbnQgICAgICAgICAgIHRtcDsKICAgIHNpemVfdCAgICAgICAgICBpLCBpbGVuOwoKICAgIGlmIChyZWFkZnJvbSA9PSBOVUxMIHx8IHN0ciA9PSBOVUxMIHx8IGxlbiA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmIChzdHJuY2FzZWNtcChyZWFkZnJvbSwgIjB4IiwgMikgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogQSBoZXggc3RyaW5nIHN1Ym1pdHRlZC4gSG93IGxvbmc/IAogICAgICAgICAqLwogICAgICAgIHJlYWRmcm9tICs9IDI7CiAgICAgICAgY3B0cjEgPSBza2lwX25vdF93aGl0ZV9jb25zdChyZWFkZnJvbSk7CiAgICAgICAgaWYgKGNwdHIxKQogICAgICAgICAgICBpbGVuID0gKGNwdHIxIC0gcmVhZGZyb20pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgaWxlbiA9IHN0cmxlbihyZWFkZnJvbSk7CgogICAgICAgIGlmIChpbGVuICUgMikgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywiaW52YWxpZCBoZXggc3RyaW5nOiB3cm9uZyBsZW5ndGhcbiIpOwogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBoZXggc3RyaW5nOiB3cm9uZyBsZW5ndGgiKSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICBpbGVuID0gaWxlbiAvIDI7CgogICAgICAgIC8qCiAgICAgICAgICogbWFsbG9jIGRhdGEgc3BhY2UgaWYgbmVlZGVkICgrMSBmb3IgZ29vZCBtZWFzdXJlKSAKICAgICAgICAgKi8KICAgICAgICBpZiAoKnN0ciA9PSBOVUxMKSB7CiAgICAgICAgICAgICpzdHIgPSAodV9jaGFyICopIG1hbGxvYyhpbGVuICsgMSk7CiAgICAgICAgICAgIGlmICghKnN0cikKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHJlcXVpcmUgY2FsbGVyIHRvIGhhdmUgKzEsIGFuZCBiYWlsIGlmIG5vdCBlbm91Z2ggc3BhY2UuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoaWxlbiA+PSAqbGVuKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywiYnVmZmVyIHRvbyBzbWFsbCB0byByZWFkIG9jdGV0IHN0cmluZyAoJWx1IDwgJWx1KVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKSpsZW4sICh1bnNpZ25lZCBsb25nKWlsZW4pOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJidWZmZXIgdG9vIHNtYWxsICglbHUgPCAlbHUpIiwgKHVuc2lnbmVkIGxvbmcpKmxlbiwgKHVuc2lnbmVkIGxvbmcpaWxlbikpOwogICAgICAgICAgICAgICAgKmxlbiA9IDA7CiAgICAgICAgICAgICAgICBjcHRyMSA9IHNraXBfbm90X3doaXRlX2NvbnN0KHJlYWRmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiBza2lwX3doaXRlX2NvbnN0KGNwdHIxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBjb3B5IHZhbGlkYXRlZCBkYXRhIAogICAgICAgICAqLwogICAgICAgIGNwdHIgPSAqc3RyOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBpbGVuOyBpKyspIHsKICAgICAgICAgICAgaWYgKDEgPT0gc3NjYW5mKHJlYWRmcm9tLCAiJTJ4IiwgJnRtcCkpCiAgICAgICAgICAgICAgICAqY3B0cisrID0gKHVfY2hhcikgdG1wOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiB3ZSBtYXkgbG9zZSBtZW1vcnksIGJ1dCBkb24ndCBrbm93IGNhbGxlcidzIGJ1ZmZlciBYWCBmcmVlKGNwdHIpOyAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZWFkZnJvbSArPSAyOwogICAgICAgIH0KICAgICAgICAvKgogICAgICAgICAqIFRlcm1pbmF0ZSB0aGUgb3V0cHV0IGJ1ZmZlci4KICAgICAgICAgKi8KICAgICAgICAqY3B0cisrID0gJ1wwJzsKICAgICAgICAqbGVuID0gaWxlbjsKICAgICAgICByZWFkZnJvbSA9IHNraXBfd2hpdGVfY29uc3QocmVhZGZyb20pOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIE5vcm1hbCBzdHJpbmcgCiAgICAgICAgICovCgogICAgICAgIC8qCiAgICAgICAgICogbWFsbG9jIHN0cmluZyBzcGFjZSBpZiBuZWVkZWQgKGluY2x1ZGluZyBOVUxMIHRlcm1pbmF0b3IpIAogICAgICAgICAqLwogICAgICAgIGlmICgqc3RyID09IE5VTEwpIHsKICAgICAgICAgICAgY2hhciAgICAgICAgICAgIGJ1ZltTTk1QX01BWEJVRl07CiAgICAgICAgICAgIHJlYWRmcm9tID0gY29weV9ud29yZF9jb25zdChyZWFkZnJvbSwgYnVmLCBzaXplb2YoYnVmKSk7CgogICAgICAgICAgICAqbGVuID0gc3RybGVuKGJ1Zik7CiAgICAgICAgICAgICpzdHIgPSAodV9jaGFyICopIG1hbGxvYygqbGVuICsgMSk7CiAgICAgICAgICAgIGlmICgqc3RyID09IE5VTEwpCiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgbWVtY3B5KCpzdHIsIGJ1ZiwgKmxlbiArIDEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlYWRmcm9tID0gY29weV9ud29yZF9jb25zdChyZWFkZnJvbSwgKGNoYXIgKikgKnN0ciwgKmxlbik7CiAgICAgICAgICAgIGlmICgqbGVuKQogICAgICAgICAgICAgICAgKmxlbiA9IHN0cmxlbigoY2hhciAqKSAqc3RyKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlYWRmcm9tOwp9CgovKgogKiByZWFkX2NvbmZpZ19zYXZlX29iamlkKCk6IHNhdmVzIGFuIG9iamlkIGFzIGEgbnVtZXJpY2FsIHN0cmluZyAKICovCmNoYXIgICAgICAgICAgICoKcmVhZF9jb25maWdfc2F2ZV9vYmppZChjaGFyICpzYXZldG8sIG9pZCAqIG9iamlkLCBzaXplX3QgbGVuKQp7CiAgICBpbnQgICAgICAgICAgICAgaTsKCiAgICBpZiAobGVuID09IDApIHsKICAgICAgICBzdHJjYXQoc2F2ZXRvLCAiTlVMTCIpOwogICAgICAgIHNhdmV0byArPSBzdHJsZW4oc2F2ZXRvKTsKICAgICAgICByZXR1cm4gc2F2ZXRvOwogICAgfQoKICAgIC8qCiAgICAgKiBpbiBjYXNlIGxlbj0wLCB0aGlzIG1ha2VzIGl0IGVhc2llciB0byByZWFkIGl0IGJhY2sgaW4gCiAgICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCAoaW50KSBsZW47IGkrKykgewogICAgICAgIHNwcmludGYoc2F2ZXRvLCAiLiUiIE5FVFNOTVBfUFJJbyAiZCIsIG9iamlkW2ldKTsKICAgICAgICBzYXZldG8gKz0gc3RybGVuKHNhdmV0byk7CiAgICB9CiAgICByZXR1cm4gc2F2ZXRvOwp9CgovKgogKiByZWFkX2NvbmZpZ19yZWFkX29iamlkKCk6IHJlYWRzIGFuIG9iamlkIGZyb20gYSBmb3JtYXQgc2F2ZWQgYnkgdGhlIGFib3ZlIAogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19yZWFkX29iamlkKGNoYXIgKnJlYWRmcm9tLCBvaWQgKiogb2JqaWQsIHNpemVfdCAqIGxlbikKewogICAgcmV0dXJuIE5FVFNOTVBfUkVNT1ZFX0NPTlNUKGNoYXIgKiwKICAgICAgICAgICAgIHJlYWRfY29uZmlnX3JlYWRfb2JqaWRfY29uc3QocmVhZGZyb20sIG9iamlkLCBsZW4pKTsKfQoKY29uc3QgY2hhciAgICAgKgpyZWFkX2NvbmZpZ19yZWFkX29iamlkX2NvbnN0KGNvbnN0IGNoYXIgKnJlYWRmcm9tLCBvaWQgKiogb2JqaWQsIHNpemVfdCAqIGxlbikKewoKICAgIGlmIChvYmppZCA9PSBOVUxMIHx8IHJlYWRmcm9tID09IE5VTEwgfHwgbGVuID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKCpvYmppZCA9PSBOVUxMKSB7CiAgICAgICAgKmxlbiA9IDA7CiAgICAgICAgaWYgKCgqb2JqaWQgPSAob2lkICopIG1hbGxvYyhNQVhfT0lEX0xFTiAqIHNpemVvZihvaWQpKSkgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgKmxlbiA9IE1BWF9PSURfTEVOOwogICAgfQoKICAgIGlmIChzdHJuY21wKHJlYWRmcm9tLCAiTlVMTCIsIDQpID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIG51bGwgbGVuZ3RoIG9pZCAKICAgICAgICAgKi8KICAgICAgICAqbGVuID0gMDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiBxdWFsaWZ5IHRoZSBzdHJpbmcgZm9yIHJlYWRfb2JqaWQgCiAgICAgICAgICovCiAgICAgICAgY2hhciAgICAgICAgICAgIGJ1ZltTUFJJTlRfTUFYX0xFTl07CiAgICAgICAgY29weV9ud29yZF9jb25zdChyZWFkZnJvbSwgYnVmLCBzaXplb2YoYnVmKSk7CgogICAgICAgIGlmICghcmVhZF9vYmppZChidWYsICpvYmppZCwgbGVuKSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfcmVhZF9vYmppZCIsICJJbnZhbGlkIE9JRCIpKTsKICAgICAgICAgICAgKmxlbiA9IDA7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICByZWFkZnJvbSA9IHNraXBfdG9rZW5fY29uc3QocmVhZGZyb20pOwogICAgcmV0dXJuIHJlYWRmcm9tOwp9CgovKioKICogcmVhZF9jb25maWdfcmVhZF9kYXRhIHJlYWRzIGRhdGEgb2YgYSBnaXZlbiB0eXBlIGZyb20gYSB0b2tlbihzKSBvbiBhCiAqIGNvbmZpZ3VyYXRpb24gbGluZS4gIFRoZSBzdXBwb3J0ZWQgdHlwZXMgYXJlOgogKgogKiAgICAtIEFTTl9JTlRFR0VSCiAqICAgIC0gQVNOX1RJTUVUSUNLUwogKiAgICAtIEFTTl9VTlNJR05FRAogKiAgICAtIEFTTl9PQ1RFVF9TVFIKICogICAgLSBBU05fQklUX1NUUgogKiAgICAtIEFTTl9PQkpFQ1RfSUQKICoKICogQHBhcmFtIHR5cGUgdGhlIGFzbiBkYXRhIHR5cGUgdG8gYmUgcmVhZCBpbi4KICoKICogQHBhcmFtIHJlYWRmcm9tIHRoZSBjb25maWd1cmF0aW9uIGxpbmUgZGF0YSB0byBiZSByZWFkLgogKgogKiBAcGFyYW0gZGF0YXB0ciBhbiBhbGxvY2F0ZWQgcG9pbnRlciBleHBlY3RlZCB0byBtYXRjaCB0aGUgdHlwZSBiZWluZyByZWFkCiAqICAgICAgICAoaW50ICosIHVfaW50ICosIGNoYXIgKiosIG9pZCAqKikKICoKICogQHBhcmFtIGxlbiBpcyB0aGUgbGVuZ3RoIG9mIGFuIGFzbiBvaWQgb3Igb2N0ZXQvYml0IHN0cmluZywgbm90IHJlcXVpcmVkCiAqICAgICAgICAgICAgZm9yIHRoZSBhc24gaW50ZWdlciwgdW5zaWduZWQgaW50ZWdlciwgYW5kIHRpbWV0aWNrcyB0eXBlcwogKgogKiBAcmV0dXJuIHRoZSBuZXh0IHRva2VuIGluIHRoZSBjb25maWd1cmF0aW9uIGxpbmUuICBOVUxMIGlmIG5vbmUgbGVmdCBvcgogKiBpZiBhbiB1bmtub3duIHR5cGUuCiAqIAogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19yZWFkX2RhdGEoaW50IHR5cGUsIGNoYXIgKnJlYWRmcm9tLCB2b2lkICpkYXRhcHRyLAogICAgICAgICAgICAgICAgICAgICAgc2l6ZV90ICogbGVuKQp7CiAgICBpbnQgICAgICAgICAgICAqaW50cDsKICAgIGNoYXIgICAgICAgICAgKipjaGFycHA7CiAgICBvaWQgICAgICAgICAgICoqb2lkcHA7CiAgICB1bnNpZ25lZCBpbnQgICAqdWludHA7CgogICAgaWYgKGRhdGFwdHIgJiYgcmVhZGZyb20pCiAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgY2FzZSBBU05fSU5URUdFUjoKICAgICAgICAgICAgaW50cCA9IChpbnQgKikgZGF0YXB0cjsKICAgICAgICAgICAgKmludHAgPSBhdG9pKHJlYWRmcm9tKTsKICAgICAgICAgICAgcmVhZGZyb20gPSBza2lwX3Rva2VuKHJlYWRmcm9tKTsKICAgICAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwoKICAgICAgICBjYXNlIEFTTl9USU1FVElDS1M6CiAgICAgICAgY2FzZSBBU05fVU5TSUdORUQ6CiAgICAgICAgICAgIHVpbnRwID0gKHVuc2lnbmVkIGludCAqKSBkYXRhcHRyOwogICAgICAgICAgICAqdWludHAgPSBzdHJ0b3VsKHJlYWRmcm9tLCBOVUxMLCAwKTsKICAgICAgICAgICAgcmVhZGZyb20gPSBza2lwX3Rva2VuKHJlYWRmcm9tKTsKICAgICAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwoKICAgICAgICBjYXNlIEFTTl9JUEFERFJFU1M6CiAgICAgICAgICAgIGludHAgPSAoaW50ICopIGRhdGFwdHI7CiAgICAgICAgICAgICppbnRwID0gaW5ldF9hZGRyKHJlYWRmcm9tKTsKICAgICAgICAgICAgaWYgKCgqaW50cCA9PSAtMSkgJiYKICAgICAgICAgICAgICAgIChzdHJuY21wKHJlYWRmcm9tLCAiMjU1LjI1NS4yNTUuMjU1IiwgMTUpICE9IDApKQogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIHJlYWRmcm9tID0gc2tpcF90b2tlbihyZWFkZnJvbSk7CiAgICAgICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICAgICAgY2FzZSBBU05fT0NURVRfU1RSOgogICAgICAgIGNhc2UgQVNOX0JJVF9TVFI6CiAgICAgICAgICAgIGNoYXJwcCA9IChjaGFyICoqKSBkYXRhcHRyOwogICAgICAgICAgICByZXR1cm4gcmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmcocmVhZGZyb20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICoqKSBjaGFycHAsIGxlbik7CgogICAgICAgIGNhc2UgQVNOX09CSkVDVF9JRDoKICAgICAgICAgICAgb2lkcHAgPSAob2lkICoqKSBkYXRhcHRyOwogICAgICAgICAgICByZXR1cm4gcmVhZF9jb25maWdfcmVhZF9vYmppZChyZWFkZnJvbSwgb2lkcHAsIGxlbik7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19yZWFkX2RhdGEiLCAiRmFpbDogVW5rbm93biB0eXBlOiAlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUpKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qCiAqIHJlYWRfY29uZmlnX3JlYWRfbWVtb3J5KCk6CiAqIAogKiBzaW1pbGFyIHRvIHJlYWRfY29uZmlnX3JlYWRfZGF0YSwgYnV0IGV4cGVjdHMgYSBnZW5lcmljIG1lbW9yeQogKiBwb2ludGVyIHJhdGhlciB0aGFuIGEgc3BlY2lmaWMgdHlwZSBvZiBwb2ludGVyLiAgTGVuIGlzIGV4cGVjdGVkIHRvCiAqIGJlIHRoZSBhbW91bnQgb2YgYXZhaWxhYmxlIG1lbW9yeS4KICovCmNoYXIgICAgICAgICAgICoKcmVhZF9jb25maWdfcmVhZF9tZW1vcnkoaW50IHR5cGUsIGNoYXIgKnJlYWRmcm9tLAogICAgICAgICAgICAgICAgICAgICAgICBjaGFyICpkYXRhcHRyLCBzaXplX3QgKiBsZW4pCnsKICAgIGludCAgICAgICAgICAgICppbnRwOwogICAgdW5zaWduZWQgaW50ICAgKnVpbnRwOwogICAgY2hhciAgICAgICAgICAgIGJ1ZltTUFJJTlRfTUFYX0xFTl07CgogICAgaWYgKCFkYXRhcHRyIHx8ICFyZWFkZnJvbSkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgQVNOX0lOVEVHRVI6CiAgICAgICAgaWYgKCpsZW4gPCBzaXplb2YoaW50KSkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgaW50cCA9IChpbnQgKikgZGF0YXB0cjsKICAgICAgICByZWFkZnJvbSA9IGNvcHlfbndvcmQocmVhZGZyb20sIGJ1Ziwgc2l6ZW9mKGJ1ZikpOwogICAgICAgICppbnRwID0gYXRvaShidWYpOwogICAgICAgICpsZW4gPSBzaXplb2YoaW50KTsKICAgICAgICByZXR1cm4gcmVhZGZyb207CgogICAgY2FzZSBBU05fQ09VTlRFUjoKICAgIGNhc2UgQVNOX1RJTUVUSUNLUzoKICAgIGNhc2UgQVNOX1VOU0lHTkVEOgogICAgICAgIGlmICgqbGVuIDwgc2l6ZW9mKHVuc2lnbmVkIGludCkpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIHVpbnRwID0gKHVuc2lnbmVkIGludCAqKSBkYXRhcHRyOwogICAgICAgIHJlYWRmcm9tID0gY29weV9ud29yZChyZWFkZnJvbSwgYnVmLCBzaXplb2YoYnVmKSk7CiAgICAgICAgKnVpbnRwID0gc3RydG91bChidWYsIE5VTEwsIDApOwogICAgICAgICpsZW4gPSBzaXplb2YodW5zaWduZWQgaW50KTsKICAgICAgICByZXR1cm4gcmVhZGZyb207CgogICAgY2FzZSBBU05fSVBBRERSRVNTOgogICAgICAgIGlmICgqbGVuIDwgc2l6ZW9mKGludCkpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIGludHAgPSAoaW50ICopIGRhdGFwdHI7CiAgICAgICAgcmVhZGZyb20gPSBjb3B5X253b3JkKHJlYWRmcm9tLCBidWYsIHNpemVvZihidWYpKTsKICAgICAgICAqaW50cCA9IGluZXRfYWRkcihidWYpOwogICAgICAgIGlmICgoKmludHAgPT0gLTEpICYmIChzdHJjbXAoYnVmLCAiMjU1LjI1NS4yNTUuMjU1IikgIT0gMCkpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICpsZW4gPSBzaXplb2YoaW50KTsKICAgICAgICByZXR1cm4gcmVhZGZyb207CgogICAgY2FzZSBBU05fT0NURVRfU1RSOgogICAgY2FzZSBBU05fQklUX1NUUjoKICAgIGNhc2UgQVNOX1BSSVZfSU1QTElFRF9PQ1RFVF9TVFI6CiAgICAgICAgcmV0dXJuIHJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKHJlYWRmcm9tLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICoqKSAmIGRhdGFwdHIsIGxlbik7CgogICAgY2FzZSBBU05fUFJJVl9JTVBMSUVEX09CSkVDVF9JRDoKICAgIGNhc2UgQVNOX09CSkVDVF9JRDoKICAgICAgICByZWFkZnJvbSA9CiAgICAgICAgICAgIHJlYWRfY29uZmlnX3JlYWRfb2JqaWQocmVhZGZyb20sIChvaWQgKiopICYgZGF0YXB0ciwgbGVuKTsKICAgICAgICAqbGVuICo9IHNpemVvZihvaWQpOwogICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICBjYXNlIEFTTl9DT1VOVEVSNjQ6CiAgICAgICAgaWYgKCpsZW4gPCBzaXplb2YoVTY0KSkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgKmxlbiA9IHNpemVvZihVNjQpOwogICAgICAgIHJlYWQ2NCgoVTY0ICopIGRhdGFwdHIsIHJlYWRmcm9tKTsKICAgICAgICByZWFkZnJvbSA9IHNraXBfdG9rZW4ocmVhZGZyb20pOwogICAgICAgIHJldHVybiByZWFkZnJvbTsKICAgIH0KCiAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfcmVhZF9tZW1vcnkiLCAiRmFpbDogVW5rbm93biB0eXBlOiAlZCIsIHR5cGUpKTsKICAgIHJldHVybiBOVUxMOwp9CgovKioKICogcmVhZF9jb25maWdfc3RvcmVfZGF0YSBzdG9yZXMgZGF0YSBvZiBhIGdpdmVuIHR5cGUgdG8gYSBjb25maWd1cmF0aW9uIGxpbmUKICogaW50byB0aGUgc3RvcmV0byBidWZmZXIuCiAqIENhbGxzIHJlYWRfY29uZmlnX3N0b3JlX2RhdGFfcHJlZml4IHdpdGggdGhlIHByZWZpeCBwYXJhbWV0ZXIgc2V0IHRvIGEgY2hhcgogKiBzcGFjZS4gIFRoZSBzdXBwb3J0ZWQgdHlwZXMgYXJlOgogKgogKiAgICAtIEFTTl9JTlRFR0VSCiAqICAgIC0gQVNOX1RJTUVUSUNLUwogKiAgICAtIEFTTl9VTlNJR05FRAogKiAgICAtIEFTTl9PQ1RFVF9TVFIKICogICAgLSBBU05fQklUX1NUUgogKiAgICAtIEFTTl9PQkpFQ1RfSUQKICoKICogQHBhcmFtIHR5cGUgICAgdGhlIGFzbiBkYXRhIHR5cGUgdG8gYmUgc3RvcmVkCiAqCiAqIEBwYXJhbSBzdG9yZXRvIGEgcHJlLWFsbG9jYXRlZCBjaGFyIGJ1ZmZlciB3aGljaCB3aWxsIGNvbnRhaW4gdGhlIGRhdGEKICogICAgICAgICAgICAgICAgdG8gYmUgc3RvcmVkCiAqCiAqIEBwYXJhbSBkYXRhcHRyIGNvbnRhaW5zIHRoZSB2YWx1ZSB0byBiZSBzdG9yZWQsIHRoZSBzdXBwb3J0ZWQgcG9pbnRlcnM6CiAqICAgICAgICAgICAgICAgIChpbnQgKiwgdV9pbnQgKiwgY2hhciAqKiwgb2lkICoqKQogKgogKiBAcGFyYW0gbGVuICAgICBpcyB0aGUgbGVuZ3RoIG9mIHRoZSB2YWx1ZSB0byBiZSBzdG9yZWQKICogICAgICAgICAgICAgICAgKG5vdCByZXF1aXJlZCBmb3IgdGhlIGFzbiBpbnRlZ2VyLCB1bnNpZ25lZCBpbnRlZ2VyLAogKiAgICAgICAgICAgICAgICAgYW5kIHRpbWV0aWNrcyB0eXBlcykKICoKICogQHJldHVybiBjaGFyYWN0ZXIgcG9pbnRlciB0byB0aGUgZW5kIG9mIHRoZSBsaW5lLiBOVUxMIGlmIGFuIHVua25vd24gdHlwZS4KICovCmNoYXIgICAgICAgICAgICoKcmVhZF9jb25maWdfc3RvcmVfZGF0YShpbnQgdHlwZSwgY2hhciAqc3RvcmV0bywgdm9pZCAqZGF0YXB0ciwgc2l6ZV90ICogbGVuKQp7CiAgICByZXR1cm4gcmVhZF9jb25maWdfc3RvcmVfZGF0YV9wcmVmaXgoJyAnLCB0eXBlLCBzdG9yZXRvLCBkYXRhcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGVuID8gKmxlbiA6IDApKTsKfQoKY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19zdG9yZV9kYXRhX3ByZWZpeChjaGFyIHByZWZpeCwgaW50IHR5cGUsIGNoYXIgKnN0b3JldG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmRhdGFwdHIsIHNpemVfdCBsZW4pCnsKICAgIGludCAgICAgICAgICAgICppbnRwOwogICAgdV9jaGFyICAgICAgICAqKmNoYXJwcDsKICAgIHVuc2lnbmVkIGludCAgICp1aW50cDsKICAgIHN0cnVjdCBpbl9hZGRyICBpbjsKICAgIG9pZCAgICAgICAgICAgKipvaWRwcDsKCiAgICBpZiAoZGF0YXB0ciAmJiBzdG9yZXRvKQogICAgICAgIHN3aXRjaCAodHlwZSkgewogICAgICAgIGNhc2UgQVNOX0lOVEVHRVI6CiAgICAgICAgICAgIGludHAgPSAoaW50ICopIGRhdGFwdHI7CiAgICAgICAgICAgIHNwcmludGYoc3RvcmV0bywgIiVjJWQiLCBwcmVmaXgsICppbnRwKTsKICAgICAgICAgICAgcmV0dXJuIChzdG9yZXRvICsgc3RybGVuKHN0b3JldG8pKTsKCiAgICAgICAgY2FzZSBBU05fVElNRVRJQ0tTOgogICAgICAgIGNhc2UgQVNOX1VOU0lHTkVEOgogICAgICAgICAgICB1aW50cCA9ICh1bnNpZ25lZCBpbnQgKikgZGF0YXB0cjsKICAgICAgICAgICAgc3ByaW50ZihzdG9yZXRvLCAiJWMldSIsIHByZWZpeCwgKnVpbnRwKTsKICAgICAgICAgICAgcmV0dXJuIChzdG9yZXRvICsgc3RybGVuKHN0b3JldG8pKTsKCiAgICAgICAgY2FzZSBBU05fSVBBRERSRVNTOgogICAgICAgICAgICBpbi5zX2FkZHIgPSAqKHVuc2lnbmVkIGludCAqKSBkYXRhcHRyOyAKICAgICAgICAgICAgc3ByaW50ZihzdG9yZXRvLCAiJWMlcyIsIHByZWZpeCwgaW5ldF9udG9hKGluKSk7CiAgICAgICAgICAgIHJldHVybiAoc3RvcmV0byArIHN0cmxlbihzdG9yZXRvKSk7CgogICAgICAgIGNhc2UgQVNOX09DVEVUX1NUUjoKICAgICAgICBjYXNlIEFTTl9CSVRfU1RSOgogICAgICAgICAgICAqc3RvcmV0bysrID0gcHJlZml4OwogICAgICAgICAgICBjaGFycHAgPSAodV9jaGFyICoqKSBkYXRhcHRyOwogICAgICAgICAgICByZXR1cm4gcmVhZF9jb25maWdfc2F2ZV9vY3RldF9zdHJpbmcoc3RvcmV0bywgKmNoYXJwcCwgbGVuKTsKCiAgICAgICAgY2FzZSBBU05fT0JKRUNUX0lEOgogICAgICAgICAgICAqc3RvcmV0bysrID0gcHJlZml4OwogICAgICAgICAgICBvaWRwcCA9IChvaWQgKiopIGRhdGFwdHI7CiAgICAgICAgICAgIHJldHVybiByZWFkX2NvbmZpZ19zYXZlX29iamlkKHN0b3JldG8sICpvaWRwcCwgbGVuKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnX3N0b3JlX2RhdGFfcHJlZml4IiwKICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWw6IFVua25vd24gdHlwZTogJWQiLCB0eXBlKSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKiogQH0gKi8K