LyoKICogcmVhZF9jb25maWcuYwogKi8KLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgovKiogQGRlZmdyb3VwIHJlYWRfY29uZmlnIHBhcnNpbmcgdmFyaW91cyBjb25maWd1cmF0aW9uIGZpbGVzIGF0IHJ1biB0aW1lCiAqICBAaW5ncm91cCBsaWJyYXJ5CiAqCiAqIFRoZSByZWFkX2NvbmZpZyByZWxhdGVkIGZ1bmN0aW9ucyBhcmUgYSBmYWlybHkgZXh0ZW5zaWJsZSAgc3lzdGVtICBvZgogKiBwYXJzaW5nIHZhcmlvdXMgY29uZmlndXJhdGlvbiBmaWxlcyBhdCB0aGUgcnVuIHRpbWUuCiAqCiAqIFRoZSBpZGVhIGlzIHRoYXQgdGhlIGNhbGxpbmcgYXBwbGljYXRpb24gaXMgYWJsZSB0byByZWdpc3RlcgogKiBoYW5kbGVycyBmb3IgY2VydGFpbiB0b2tlbnMgc3BlY2lmaWVkIGluIGNlcnRhaW4gdHlwZXMKICogb2YgZmlsZXMuICBUaGUgcmVhZF9jb25maWdzIGZ1bmN0aW9uIGNhbiB0aGVuIGJlICBjYWxsZWQKICogdG8gIGxvb2sgIGZvciBhbGwgdGhlIGZpbGVzIHRoYXQgaXQgaGFzIHJlZ2lzdHJhdGlvbnMgZm9yLAogKiBmaW5kIHRoZSBmaXJzdCB3b3JkIG9uIGVhY2ggbGluZSwgYW5kIHBhc3MgIHRoZSAgcmVtYWluZGVyCiAqIHRvIHRoZSBhcHByb3ByaWF0ZWx5IHJlZ2lzdGVyZWQgaGFuZGxlci4KICoKICogRm9yIHBlcnNpc3RlbnQgY29uZmlndXJhdGlvbiBzdG9yYWdlIHlvdSB3aWxsIG5lZWQgdG8gdXNlIHRoZQogKiByZWFkX2NvbmZpZ19yZWFkX2RhdGEsIHJlYWRfY29uZmlnX3N0b3JlLCBhbmQgcmVhZF9jb25maWdfc3RvcmVfZGF0YQogKiBBUElzIGluIGNvbmp1bmN0aW9uIHdpdGggZmlyc3QgcmVnaXN0ZXJpbmcgYQogKiBjYWxsYmFjayBzbyB3aGVuIHRoZSBhZ2VudCBzaHV0c2Rvd24gZm9yIHdoYXRldmVyIHJlYXNvbiBkYXRhIGlzIHdyaXR0ZW4KICogdG8geW91ciBjb25maWd1cmF0aW9uIGZpbGVzLiAgVGhlIGZvbGxvd2luZyBleHBsYWlucyBpbiBtb3JlIGRldGFpbCB0aGUKICogc2VxdWVuY2UgdG8gbWFrZSB0aGlzIGhhcHBlbi4KICoKICogVGhpcyBpcyB0aGUgY2FsbGJhY2sgcmVnaXN0cmF0aW9uIEFQSSwgeW91IG5lZWQgdG8gY2FsbCB0aGlzIEFQSSB3aXRoCiAqIHRoZSBhcHByb3ByaWF0ZSBwYXJhbWV0ZXJzIGluIG9yZGVyIHRvIGNvbmZpZ3VyZSBwZXJzaXN0ZW50IHN0b3JhZ2UgbmVlZHMuCiAqCiAqICAgICAgICBpbnQgc25tcF9yZWdpc3Rlcl9jYWxsYmFjayhpbnQgbWFqb3IsIGludCBtaW5vciwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBDYWxsYmFjayAqbmV3X2NhbGxiYWNrLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqYXJnKTsKICoKICogWW91IHdpbGwgbmVlZCB0byBzZXQgbWFqb3IgdG8gU05NUF9DQUxMQkFDS19MSUJSQVJZLCBtaW5vciB0bwogKiBTTk1QX0NBTExCQUNLX1NUT1JFX0RBVEEuIGFyZyBpcyB3aGF0ZXZlciB5b3Ugd2FudC4KICoKICogWW91ciBjYWxsYmFjayBmdW5jdGlvbidzIHByb3RvdHlwZSBpczoKICogaW50ICAgICAoU05NUENhbGxiYWNrKSAoaW50IG1ham9ySUQsIGludCBtaW5vcklELCB2b2lkICpzZXJ2ZXJhcmcsCiAqICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xpZW50YXJnKTsKICoKICogVGhlIG1ham9ySUQsIG1pbm9ySUQgYW5kIGNsaWVudGFyZyBhcmUgd2hhdCB5b3UgcGFzc2VkIGluIHRoZSBjYWxsYmFjawogKiByZWdpc3RyYXRpb24gYWJvdmUuICBXaGVuIHRoZSBjYWxsYmFjayBpcyBjYWxsZWQgeW91IGhhdmUgdG8gZXNzZW50aWFsbHkKICogdHJhbnNmZXIgYWxsIHlvdXIgc3RhdGUgZnJvbSBtZW1vcnkgdG8gZGlzay4gWW91IGRvIHRoaXMgYnkgZ2VuZXJhdGluZwogKiBjb25maWd1cmF0aW9uIGxpbmVzIGludG8gYSBidWZmZXIuICBUaGUgbGluZXMgYXJlIG9mIHRoZSBmb3JtIHRva2VuCiAqIGZvbGxvd2VkIGJ5IHRva2VuIHBhcmFtZXRlcnMuCiAqIAogKiBGaW5hbGx5IHN0b3JpbmcgaXMgZG9uZSB1c2luZyByZWFkX2NvbmZpZ19zdG9yZSh0eXBlLCBidWZmZXIpOwogKiB0eXBlIGlzIHRoZSBhcHBsaWNhdGlvbiBuYW1lIHRoaXMgY2FuIGJlIG9idGFpbmVkIGZyb206CiAqCiAqIG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpOwogKgogKiBOb3csIHJlYWRpbmcgYmFjayB0aGUgZGF0YTogVGhpcyBpcyBkb25lIGJ5IHJlZ2lzdGVyaW5nIGEgY29uZmlnIGhhbmRsZXIKICogZm9yIHlvdXIgdG9rZW4gdXNpbmcgdGhlIHJlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyIGZ1bmN0aW9uLiBZb3VyCiAqIGhhbmRsZXIgd2lsbCBiZSBpbnZva2VkIGFuZCB5b3UgY2FuIHBhcnNlIGluIHRoZSBkYXRhIHVzaW5nIHRoZQogKiByZWFkX2NvbmZpZ19yZWFkIEFQSXMuCiAqCiAqICBAewogKi8KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX1NZU19QQVJBTV9ICiNpbmNsdWRlIDxzeXMvcGFyYW0uaD4KI2VuZGlmCiNpZiBUSU1FX1dJVEhfU1lTX1RJTUUKIyBpZmRlZiBXSU4zMgojICBpbmNsdWRlIDxzeXMvdGltZWIuaD4KIyBlbHNlCiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZW5kaWYKIyBpbmNsdWRlIDx0aW1lLmg+CiNlbHNlCiMgaWYgSEFWRV9TWVNfVElNRV9ICiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZWxzZQojICBpbmNsdWRlIDx0aW1lLmg+CiMgZW5kaWYKI2VuZGlmCiNpZmRlZiBIQVZFX1NZU19TVEFUX0gKI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZiBIQVZFX0FSUEFfSU5FVF9ICiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2VuZGlmCiNpZiBIQVZFX1NZU19TRUxFQ1RfSAojaW5jbHVkZSA8c3lzL3NlbGVjdC5oPgojZW5kaWYKI2lmIEhBVkVfV0lOU09DS19ICiNpbmNsdWRlIDx3aW5zb2NrLmg+CiNlbmRpZgojaWYgSEFWRV9TWVNfU09DS0VUX0gKI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2VuZGlmCiNpZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaW5jbHVkZSA8ZXJybm8uaD4KCiNpZiBIQVZFX0RNQUxMT0NfSAojaW5jbHVkZSA8ZG1hbGxvYy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC90eXBlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvb3V0cHV0X2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvY29uZmlnX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9yZWFkX2NvbmZpZy5oPiAgICAgICAvKiBmb3IgImludGVybmFsIiBkZWZpbml0aW9ucyAqLwojaW5jbHVkZSA8bmV0LXNubXAvdXRpbGl0aWVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9taWIuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvcGFyc2UuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcF9hcGkuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvY2FsbGJhY2suaD4KCnN0YXRpYyBpbnQgICAgICBjb25maWdfZXJyb3JzOwoKc3RydWN0IGNvbmZpZ19maWxlcyAqY29uZmlnX2ZpbGVzID0gTlVMTDsKCnN0YXRpYyBzdHJ1Y3QgY29uZmlnX2xpbmUgKgppbnRlcm5hbF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0eXBlX3BhcmFtLAoJCQkJIGNvbnN0IGNoYXIgKnRva2VuLAoJCQkJIHZvaWQgKCpwYXJzZXIpIChjb25zdCBjaGFyICosIGNoYXIgKiksCgkJCQkgdm9pZCAoKnJlbGVhc2VyKSAodm9pZCksIGNvbnN0IGNoYXIgKmhlbHAsCgkJCQkgaW50IHdoZW4pCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKipjdG1wID0gJmNvbmZpZ19maWxlczsKICAgIHN0cnVjdCBjb25maWdfbGluZSAgKipsdG1wOwogICAgY29uc3QgY2hhciAgICAgICAgICAgKnR5cGUgPSB0eXBlX3BhcmFtOwoKICAgIGlmICh0eXBlID09IE5VTEwgfHwgKnR5cGUgPT0gJ1wwJykgewogICAgICAgIHR5cGUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgTkVUU05NUF9EU19MSUJfQVBQVFlQRSk7CiAgICB9CgogICAgLyoKICAgICAqIEhhbmRsZSBtdWx0aXBsZSB0eXBlcyAocmVjdXJzaXZlbHkpCiAgICAgKi8KICAgIGlmIChzdHJjaHIodHlwZSwgJzonKSkgewogICAgICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHRtcDIgPSBOVUxMOwogICAgICAgIGNoYXIgICAgICAgICAgICAgICAgYnVmW1NUUklOR01BWF07CiAgICAgICAgY2hhciAgICAgICAgICAgICAgICpjcHRyID0gYnVmOwoKICAgICAgICBzdHJsY3B5KGJ1ZiwgdHlwZSwgU1RSSU5HTUFYKTsKICAgICAgICB3aGlsZSAoY3B0cikgewogICAgICAgICAgICBjaGFyKiBjID0gY3B0cjsKICAgICAgICAgICAgY3B0ciA9IHN0cmNocihjcHRyLCAnOicpOwogICAgICAgICAgICBpZihjcHRyKSB7CiAgICAgICAgICAgICAgICAqY3B0ciA9ICdcMCc7CiAgICAgICAgICAgICAgICArK2NwdHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbHRtcDIgPSBpbnRlcm5hbF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihjLCB0b2tlbiwgcGFyc2VyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbGVhc2VyLCBoZWxwLCB3aGVuKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGx0bXAyOwogICAgfQogICAgCiAgICAvKgogICAgICogRmluZCB0eXBlIGluIGN1cnJlbnQgbGlzdCAgLU9SLSAgY3JlYXRlIGEgbmV3IGZpbGUgdHlwZS4KICAgICAqLwogICAgd2hpbGUgKCpjdG1wICE9IE5VTEwgJiYgc3RyY21wKCgqY3RtcCktPmZpbGVIZWFkZXIsIHR5cGUpKSB7CiAgICAgICAgY3RtcCA9ICYoKCpjdG1wKS0+bmV4dCk7CiAgICB9CgogICAgaWYgKCpjdG1wID09IE5VTEwpIHsKICAgICAgICAqY3RtcCA9IChzdHJ1Y3QgY29uZmlnX2ZpbGVzICopCiAgICAgICAgICAgIGNhbGxvYygxLCBzaXplb2Yoc3RydWN0IGNvbmZpZ19maWxlcykpOwogICAgICAgIGlmICghKmN0bXApIHsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQoKICAgICAgICAoKmN0bXApLT5maWxlSGVhZGVyID0gc3RyZHVwKHR5cGUpOwogICAgfQoKICAgIC8qCiAgICAgKiBGaW5kIHBhcnNlciB0eXBlIGluIGN1cnJlbnQgbGlzdCAgLU9SLSAgY3JlYXRlIGEgbmV3CiAgICAgKiBsaW5lIHBhcnNlciBlbnRyeS4KICAgICAqLwogICAgbHRtcCA9ICYoKCpjdG1wKS0+c3RhcnQpOwoKICAgIHdoaWxlICgqbHRtcCAhPSBOVUxMICYmIHN0cmNtcCgoKmx0bXApLT5jb25maWdfdG9rZW4sIHRva2VuKSkgewogICAgICAgIGx0bXAgPSAmKCgqbHRtcCktPm5leHQpOwogICAgfQoKICAgIGlmICgqbHRtcCA9PSBOVUxMKSB7CiAgICAgICAgKmx0bXAgPSAoc3RydWN0IGNvbmZpZ19saW5lICopCiAgICAgICAgICAgIGNhbGxvYygxLCBzaXplb2Yoc3RydWN0IGNvbmZpZ19saW5lKSk7CiAgICAgICAgaWYgKCEqbHRtcCkgewogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgICgqbHRtcCktPmNvbmZpZ190aW1lID0gd2hlbjsKICAgICAgICAoKmx0bXApLT5jb25maWdfdG9rZW4gPSBzdHJkdXAodG9rZW4pOwogICAgICAgIGlmIChoZWxwICE9IE5VTEwpCiAgICAgICAgICAgICgqbHRtcCktPmhlbHAgPSBzdHJkdXAoaGVscCk7CiAgICB9CgogICAgLyoKICAgICAqIEFkZC9SZXBsYWNlIHRoZSBwYXJzZS9mcmVlIGZ1bmN0aW9ucyBmb3IgdGhlIGdpdmVuIGxpbmUgdHlwZQogICAgICogaW4gdGhlIGdpdmVuIGZpbGUgdHlwZS4KICAgICAqLwogICAgKCpsdG1wKS0+cGFyc2VfbGluZSA9IHBhcnNlcjsKICAgICgqbHRtcCktPmZyZWVfZnVuYyA9IHJlbGVhc2VyOwoKICAgIHJldHVybiAoKmx0bXApOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoKSAqLwoKc3RydWN0IGNvbmZpZ19saW5lICoKcmVnaXN0ZXJfcHJlbmV0c25tcF9taWJfaGFuZGxlcihjb25zdCBjaGFyICp0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRva2VuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKCpwYXJzZXIpIChjb25zdCBjaGFyICosIGNoYXIgKiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAoKnJlbGVhc2VyKSAodm9pZCksIGNvbnN0IGNoYXIgKmhlbHApCnsKICAgIHJldHVybiBpbnRlcm5hbF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcih0eXBlLCB0b2tlbiwgcGFyc2VyLCByZWxlYXNlciwKCQkJCQkgICAgaGVscCwgUFJFTUlCX0NPTkZJRyk7Cn0KCnN0cnVjdCBjb25maWdfbGluZSAqCnJlZ2lzdGVyX2FwcF9wcmVuZXRzbm1wX21pYl9oYW5kbGVyKGNvbnN0IGNoYXIgKnRva2VuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqcGFyc2VyKSAoY29uc3QgY2hhciAqLCBjaGFyICopLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqcmVsZWFzZXIpICh2b2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqaGVscCkKewogICAgcmV0dXJuIChyZWdpc3Rlcl9wcmVuZXRzbm1wX21pYl9oYW5kbGVyCiAgICAgICAgICAgIChOVUxMLCB0b2tlbiwgcGFyc2VyLCByZWxlYXNlciwgaGVscCkpOwp9CgovKioKICogcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIgcmVnaXN0ZXJzIGhhbmRsZXJzIGZvciBjZXJ0YWluIHRva2VucyBzcGVjaWZpZWQgaW4KICogY2VydGFpbiB0eXBlcyBvZiBmaWxlcy4KICoKICogQWxsb3dzIGEgbW9kdWxlIHdyaXRlciB1c2UvcmVnaXN0ZXIgbXVsdGlwbGUgY29uZmlndXJhdGlvbiBmaWxlcyBiYXNlZCBvZmYKICogb2YgdGhlIHR5cGUgcGFyYW1ldGVyLiAgQSBtb2R1bGUgd3JpdGVyIG1heSB3YW50IHRvIHNldCB1cCBtdWx0aXBsZQogKiBjb25maWd1cmF0aW9uIGZpbGVzIHRvIHNlcGFyYXRlIG91dCByZWxhdGVkIHRhc2tzL3ZhcmlhYmxlcyBvciBqdXN0IGZvcgogKiBtYW5hZ2VtZW50IG9mIHdoZXJlIHRvIHB1dCB0b2tlbnMgYXMgdGhlIG1vZHVsZSBvciBtb2R1bGVzIGdldCBtb3JlIGNvbXBsZXgKICogaW4gcmVnYXJkIHRvIGhhbmRsaW5nIHRva2VuIHJlZ2lzdHJhdGlvbnMuCiAqCiAqIEBwYXJhbSB0eXBlICAgICB0aGUgY29uZmlndXJhdGlvbiBmaWxlIHVzZWQsIGUuZy4sIGlmIHNubXAuY29uZiBpcyB0aGUKICogICAgICAgICAgICAgICAgIGZpbGUgd2hlcmUgdGhlIHRva2VuIGlzIGxvY2F0ZWQgdXNlICJzbm1wIiBoZXJlLgogKiAgICAgICAgICAgICAgICAgTXVsdGlwbGUgY29sb24gc2VwYXJhdGVkIHRva2VucyBtaWdodCBiZSB1c2VkLgogKiAgICAgICAgICAgICAgICAgSWYgTlVMTCBvciAiIiB0aGVuIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgdXNlZCB3aWxsIGJlCiAqICAgICAgICAgICAgICAgICBcPGFwcGxpY2F0aW9uXD4uY29uZi4KICoKICogQHBhcmFtIHRva2VuICAgIHRoZSB0b2tlbiBiZWluZyBwYXJzZWQgZnJvbSB0aGUgZmlsZS4gIE11c3QgYmUgbm9uLU5VTEwuCiAqCiAqIEBwYXJhbSBwYXJzZXIgICB0aGUgaGFuZGxlciBmdW5jdGlvbiBwb2ludGVyIHRoYXQgdXNlICB0aGUgc3BlY2lmaWVkCiAqICAgICAgICAgICAgICAgICB0b2tlbiBhbmQgdGhlIHJlc3Qgb2YgdGhlIGxpbmUgdG8gZG8gd2hhdGV2ZXIgaXMgcmVxdWlyZWQKICogICAgICAgICAgICAgICAgIFNob3VsZCBiZSBub24tTlVMTCBpbiBvcmRlciB0byBtYWtlIHVzZSBvZiB0aGlzIEFQSS4KICoKICogQHBhcmFtIHJlbGVhc2VyIGlmIG5vbi1OVUxMLCB0aGUgZnVuY3Rpb24gc3BlY2lmaWVkIGlzIGNhbGxlZCB3aGVuCiAqICAgICAgICAgICAgICAgICB1bnJlZ2lzdGVyaW5nIGNvbmZpZyBoYW5kbGVyIG9yIHdoZW4gY29uZmlndXJhdGlvbgogKiAgICAgICAgICAgICAgICAgZmlsZXMgYXJlIHJlLXJlYWQuCiAqICAgICAgICAgICAgICAgICBUaGlzIGZ1bmN0aW9uIHNob3VsZCBmcmVlIGFueSByZXNvdXJjZXMgYWxsb2NhdGVkIGJ5CiAqICAgICAgICAgICAgICAgICB0aGUgdG9rZW4gaGFuZGxlciBmdW5jdGlvbi4KICoKICogQHBhcmFtIGhlbHAgICAgIGlmIG5vbi1OVUxMLCB1c2VkIHRvIGRpc3BsYXkgaGVscCBpbmZvcm1hdGlvbiBvbiB0aGUKICogICAgICAgICAgICAgICAgIGV4cGVjdGVkIGFyZ3VtZW50cyBhZnRlciB0aGUgdG9rZW4uCiAqCiAqIEByZXR1cm4gUG9pbnRlciB0byBhIG5ldyBjb25maWcgbGluZSBlbnRyeSBvciBOVUxMIG9uIGVycm9yLgogKi8Kc3RydWN0IGNvbmZpZ19saW5lICoKcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoY29uc3QgY2hhciAqdHlwZSwKCQkJY29uc3QgY2hhciAqdG9rZW4sCgkJCXZvaWQgKCpwYXJzZXIpIChjb25zdCBjaGFyICosIGNoYXIgKiksCgkJCXZvaWQgKCpyZWxlYXNlcikgKHZvaWQpLCBjb25zdCBjaGFyICpoZWxwKQp7CiAgICByZXR1cm4gaW50ZXJuYWxfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIodHlwZSwgdG9rZW4sIHBhcnNlciwgcmVsZWFzZXIsCgkJCQkJICAgIGhlbHAsIE5PUk1BTF9DT05GSUcpOwp9CgpzdHJ1Y3QgY29uZmlnX2xpbmUgKgpyZWdpc3Rlcl9hcHBfY29uZmlnX2hhbmRsZXIoY29uc3QgY2hhciAqdG9rZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqcGFyc2VyKSAoY29uc3QgY2hhciAqLCBjaGFyICopLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAoKnJlbGVhc2VyKSAodm9pZCksIGNvbnN0IGNoYXIgKmhlbHApCnsKICAgIHJldHVybiAocmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoTlVMTCwgdG9rZW4sIHBhcnNlciwgcmVsZWFzZXIsIGhlbHApKTsKfQoKCgovKioKICogdXJlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyIHVuLXJlZ2lzdGVycyBoYW5kbGVycyBnaXZlbiBhIHNwZWNpZmljIHR5cGVfcGFyYW0KICogYW5kIHRva2VuLgogKgogKiBAcGFyYW0gdHlwZV9wYXJhbSB0aGUgY29uZmlndXJhdGlvbiBmaWxlIHVzZWQgd2hlcmUgdGhlIHRva2VuIGlzIGxvY2F0ZWQuCiAqICAgICAgICAgICAgICAgICAgIFVzZWQgdG8gbG9va3VwIHRoZSBjb25maWcgZmlsZSBlbnRyeQogKiAKICogQHBhcmFtIHRva2VuICAgICAgdGhlIHRva2VuIHRoYXQgaXMgYmVpbmcgdW5yZWdpc3RlcmVkCiAqCiAqIEByZXR1cm4gdm9pZAogKi8Kdm9pZAp1bnJlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKGNvbnN0IGNoYXIgKnR5cGVfcGFyYW0sIGNvbnN0IGNoYXIgKnRva2VuKQp7CiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICoqY3RtcCA9ICZjb25maWdfZmlsZXM7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgICoqbHRtcDsKICAgIGNvbnN0IGNoYXIgICAgICAgICAgICp0eXBlID0gdHlwZV9wYXJhbTsKCiAgICBpZiAodHlwZSA9PSBOVUxMIHx8ICp0eXBlID09ICdcMCcpIHsKICAgICAgICB0eXBlID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpOwogICAgfQoKICAgIC8qCiAgICAgKiBIYW5kbGUgbXVsdGlwbGUgdHlwZXMgKHJlY3Vyc2l2ZWx5KQogICAgICovCiAgICBpZiAoc3RyY2hyKHR5cGUsICc6JykpIHsKICAgICAgICBjaGFyICAgICAgICAgICAgICAgIGJ1ZltTVFJJTkdNQVhdOwogICAgICAgIGNoYXIgICAgICAgICAgICAgICAqY3B0ciA9IGJ1ZjsKCiAgICAgICAgc3RybGNweShidWYsIHR5cGUsIFNUUklOR01BWCk7CiAgICAgICAgd2hpbGUgKGNwdHIpIHsKICAgICAgICAgICAgY2hhciogYyA9IGNwdHI7CiAgICAgICAgICAgIGNwdHIgPSBzdHJjaHIoY3B0ciwgJzonKTsKICAgICAgICAgICAgaWYoY3B0cikgewogICAgICAgICAgICAgICAgKmNwdHIgPSAnXDAnOwogICAgICAgICAgICAgICAgKytjcHRyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHVucmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoYywgdG9rZW4pOwogICAgICAgIH0KICAgICAgICByZXR1cm47CiAgICB9CiAgICAKICAgIC8qCiAgICAgKiBmaW5kIHR5cGUgaW4gY3VycmVudCBsaXN0IAogICAgICovCiAgICB3aGlsZSAoKmN0bXAgIT0gTlVMTCAmJiBzdHJjbXAoKCpjdG1wKS0+ZmlsZUhlYWRlciwgdHlwZSkpIHsKICAgICAgICBjdG1wID0gJigoKmN0bXApLT5uZXh0KTsKICAgIH0KCiAgICBpZiAoKmN0bXAgPT0gTlVMTCkgewogICAgICAgIC8qCiAgICAgICAgICogTm90IGZvdW5kLCByZXR1cm4uIAogICAgICAgICAqLwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsdG1wID0gJigoKmN0bXApLT5zdGFydCk7CiAgICBpZiAoKmx0bXAgPT0gTlVMTCkgewogICAgICAgIC8qCiAgICAgICAgICogTm90IGZvdW5kLCByZXR1cm4uIAogICAgICAgICAqLwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChzdHJjbXAoKCpsdG1wKS0+Y29uZmlnX3Rva2VuLCB0b2tlbikgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogZm91bmQgaXQgYXQgdGhlIHRvcCBvZiB0aGUgbGlzdCAKICAgICAgICAgKi8KICAgICAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmx0bXAyID0gKCpsdG1wKS0+bmV4dDsKICAgICAgICBpZiAoKCpsdG1wKS0+ZnJlZV9mdW5jKQogICAgICAgICAgICAoKmx0bXApLT5mcmVlX2Z1bmMoKTsKICAgICAgICBTTk1QX0ZSRUUoKCpsdG1wKS0+Y29uZmlnX3Rva2VuKTsKICAgICAgICBTTk1QX0ZSRUUoKCpsdG1wKS0+aGVscCk7CiAgICAgICAgU05NUF9GUkVFKCpsdG1wKTsKICAgICAgICAoKmN0bXApLT5zdGFydCA9IGx0bXAyOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHdoaWxlICgoKmx0bXApLT5uZXh0ICE9IE5VTEwKICAgICAgICAgICAmJiBzdHJjbXAoKCpsdG1wKS0+bmV4dC0+Y29uZmlnX3Rva2VuLCB0b2tlbikpIHsKICAgICAgICBsdG1wID0gJigoKmx0bXApLT5uZXh0KTsKICAgIH0KICAgIGlmICgoKmx0bXApLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmx0bXAyID0gKCpsdG1wKS0+bmV4dC0+bmV4dDsKICAgICAgICBpZiAoKCpsdG1wKS0+bmV4dC0+ZnJlZV9mdW5jKQogICAgICAgICAgICAoKmx0bXApLT5uZXh0LT5mcmVlX2Z1bmMoKTsKICAgICAgICBTTk1QX0ZSRUUoKCpsdG1wKS0+bmV4dC0+Y29uZmlnX3Rva2VuKTsKICAgICAgICBTTk1QX0ZSRUUoKCpsdG1wKS0+bmV4dC0+aGVscCk7CiAgICAgICAgU05NUF9GUkVFKCgqbHRtcCktPm5leHQpOwogICAgICAgICgqbHRtcCktPm5leHQgPSBsdG1wMjsKICAgIH0KfQoKdm9pZAp1bnJlZ2lzdGVyX2FwcF9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0b2tlbikKewogICAgdW5yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihOVUxMLCB0b2tlbik7Cn0KCnZvaWQKdW5yZWdpc3Rlcl9hbGxfY29uZmlnX2hhbmRsZXJzKCkKewogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCwgKnNhdmU7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmx0bXA7CgogICAgLyoKICAgICAqIEtlZXAgdXNpbmcgY29uZmlnX2ZpbGVzIHVudGlsIHRoZXJlIGFyZSBubyBtb3JlISAKICAgICAqLwogICAgZm9yIChjdG1wID0gY29uZmlnX2ZpbGVzOyBjdG1wOykgewogICAgICAgIGZvciAobHRtcCA9IGN0bXAtPnN0YXJ0OyBsdG1wOyBsdG1wID0gY3RtcC0+c3RhcnQpIHsKICAgICAgICAgICAgdW5yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihjdG1wLT5maWxlSGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGx0bXAtPmNvbmZpZ190b2tlbik7CiAgICAgICAgfQogICAgICAgIFNOTVBfRlJFRShjdG1wLT5maWxlSGVhZGVyKTsKICAgICAgICBzYXZlID0gY3RtcC0+bmV4dDsKICAgICAgICBTTk1QX0ZSRUUoY3RtcCk7CiAgICAgICAgY3RtcCA9IHNhdmU7CiAgICAgICAgY29uZmlnX2ZpbGVzID0gc2F2ZTsKICAgIH0KfQoKI2lmZGVmIFRFU1RJTkcKdm9pZApwcmludF9jb25maWdfaGFuZGxlcnModm9pZCkKewogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCA9IGNvbmZpZ19maWxlczsKICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHRtcDsKCiAgICBmb3IgKDsgY3RtcCAhPSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkgewogICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICJyZWFkX2NvbmY6ICVzXG4iLCBjdG1wLT5maWxlSGVhZGVyKSk7CiAgICAgICAgZm9yIChsdG1wID0gY3RtcC0+c3RhcnQ7IGx0bXAgIT0gTlVMTDsgbHRtcCA9IGx0bXAtPm5leHQpCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICIgICAgICAgICAgICAgICAgICAgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIGx0bXAtPmNvbmZpZ190b2tlbikpOwogICAgfQp9CiNlbmRpZgoKaW50ICAgICAgICAgICAgIGxpbmVjb3VudDsKY29uc3QgY2hhciAgICAgKmN1cmZpbGVuYW1lOwoKc3RydWN0IGNvbmZpZ19saW5lICoKcmVhZF9jb25maWdfZ2V0X2hhbmRsZXJzKGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAgPSBjb25maWdfZmlsZXM7CiAgICBmb3IgKDsgY3RtcCAhPSBOVUxMICYmIHN0cmNtcChjdG1wLT5maWxlSGVhZGVyLCB0eXBlKTsKICAgICAgICAgY3RtcCA9IGN0bXAtPm5leHQpOwogICAgaWYgKGN0bXApCiAgICAgICAgcmV0dXJuIGN0bXAtPnN0YXJ0OwogICAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQKcmVhZF9jb25maWdfd2l0aF90eXBlX3doZW4oY29uc3QgY2hhciAqZmlsZW5hbWUsIGNvbnN0IGNoYXIgKnR5cGUsIGludCB3aGVuKQp7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmN0bXAgPSByZWFkX2NvbmZpZ19nZXRfaGFuZGxlcnModHlwZSk7CiAgICBpZiAoY3RtcCkKICAgICAgICByZWFkX2NvbmZpZyhmaWxlbmFtZSwgY3RtcCwgd2hlbik7CiAgICBlbHNlCiAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwKICAgICAgICAgICAgICAgICAgICAicmVhZF9jb25maWc6IEkgaGF2ZSBubyByZWdpc3RyYXRpb25zIGZvciB0eXBlOiVzLGZpbGU6JXNcbiIsCiAgICAgICAgICAgICAgICAgICAgdHlwZSwgZmlsZW5hbWUpKTsKfQoKdm9pZApyZWFkX2NvbmZpZ193aXRoX3R5cGUoY29uc3QgY2hhciAqZmlsZW5hbWUsIGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIHJlYWRfY29uZmlnX3dpdGhfdHlwZV93aGVuKGZpbGVuYW1lLCB0eXBlLCBFSVRIRVJfQ09ORklHKTsKfQoKCnN0cnVjdCBjb25maWdfbGluZSAqCnJlYWRfY29uZmlnX2ZpbmRfaGFuZGxlcihzdHJ1Y3QgY29uZmlnX2xpbmUgKmxpbmVfaGFuZGxlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2tlbikKewogICAgc3RydWN0IGNvbmZpZ19saW5lICpscHRyOwoKICAgIGZvciAobHB0ciA9IGxpbmVfaGFuZGxlcnM7IGxwdHIgIT0gTlVMTDsgbHB0ciA9IGxwdHItPm5leHQpIHsKICAgICAgICBpZiAoIXN0cmNhc2VjbXAodG9rZW4sIGxwdHItPmNvbmZpZ190b2tlbikpIHsKICAgICAgICAgICAgcmV0dXJuIGxwdHI7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCgovKgogKiBzZWFyY2hlcyBhIGNvbmZpZ19saW5lIGxpbmtlZCBsaXN0IGZvciBhIG1hdGNoIAogKi8KaW50CnJ1bl9jb25maWdfaGFuZGxlcihzdHJ1Y3QgY29uZmlnX2xpbmUgKmxwdHIsCiAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0ciwgaW50IHdoZW4pCnsKICAgIGNoYXIgICAgICAgICAgICB0bXBidWZbU1RSSU5HTUFYXTsKICAgIGNoYXIgICAgICAgICAgICpjcDsKICAgIGxwdHIgPSByZWFkX2NvbmZpZ19maW5kX2hhbmRsZXIobHB0ciwgdG9rZW4pOwogICAgaWYgKGxwdHIgIT0gTlVMTCkgewogICAgICAgIGlmICh3aGVuID09IEVJVEhFUl9DT05GSUcgfHwgbHB0ci0+Y29uZmlnX3RpbWUgPT0gd2hlbikgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLAogICAgICAgICAgICAgICAgICAgICAgICAiRm91bmQgYSBwYXJzZXIuICBDYWxsaW5nIGl0OiAlcyAvICVzXG4iLCB0b2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgY3B0cikpOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBNYWtlIHN1cmUgY3B0ciBpcyBub24tbnVsbAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFjcHRyKSB7CiAgICAgICAgICAgICAgICB0bXBidWZbMF0gPSAnXDAnOwogICAgICAgICAgICAgICAgY3B0ciA9IHRtcGJ1ZjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogU3RvbXAgb24gYW55IHRyYWlsaW5nIHdoaXRlc3BhY2UKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNwID0gJihjcHRyW3N0cmxlbihjcHRyKS0xXSk7CiAgICAgICAgICAgIHdoaWxlIChpc3NwYWNlKCpjcCkpIHsKICAgICAgICAgICAgICAgICooY3AtLSkgPSAnXDAnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICgqKGxwdHItPnBhcnNlX2xpbmUpKSAodG9rZW4sIGNwdHIpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAod2hlbiAhPSBQUkVNSUJfQ09ORklHICYmIAoJICAgICAgICFuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgICAgTkVUU05NUF9EU19MSUJfTk9fVE9LRU5fV0FSTklOR1MpKSB7CiAgICAgICAgc25wcmludGYodG1wYnVmLCBzaXplb2YodG1wYnVmKSwgIlVua25vd24gdG9rZW46ICVzLiIsIHRva2VuKTsKICAgICAgICB0bXBidWZbIHNpemVvZih0bXBidWYpLTEgXSA9IDA7CiAgICAgICAgY29uZmlnX3B3YXJuKHRtcGJ1Zik7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKLyoKICogdGFrZW5zIGFuIGFyYml0cmFyeSBzdHJpbmcgYW5kIHRyaWVzIHRvIGludGVwcmV0IGl0IGJhc2VkIG9uIHRoZQogKiBrbm93biBjb25maWd1cmF0aW9uIGhhbmRsZXJzIGZvciBhbGwgcmVnaXN0ZXJlZCB0eXBlcy4gIE1heSBwcm9kdWNlCiAqIGluY29uc2lzdGVudCByZXN1bHRzIHdoZW4gbXVsdGlwbGUgdG9rZW5zIG9mIHRoZSBzYW1lIG5hbWUgYXJlCiAqIHJlZ2lzdGVyZWQgdW5kZXIgZGlmZmVyZW50IGZpbGUgdHlwZXMuIAogKi8KCi8qCiAqIHdlIGFsbG93ID0gZGVsaW1ldGVycyBoZXJlIAogKi8KI2RlZmluZSBTTk1QX0NPTkZJR19ERUxJTUVURVJTICIgXHQ9IgoKaW50CnNubXBfY29uZmlnX3doZW4oY2hhciAqbGluZSwgaW50IHdoZW4pCnsKICAgIGNoYXIgICAgICAgICAgICpjcHRyLCBidWZbU1RSSU5HTUFYXSwgdG1wYnVmW1NUUklOR01BWF07CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmxwdHIgPSBOVUxMOwogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCA9IGNvbmZpZ19maWxlczsKICAgIGNoYXIgICAgICAgICAgICpzdDsKCiAgICBpZiAobGluZSA9PSBOVUxMKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigic25tcF9jb25maWcoKSBjYWxsZWQgd2l0aCBhIG51bGwgc3RyaW5nLiIpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KCiAgICBzdHJsY3B5KGJ1ZiwgbGluZSwgU1RSSU5HTUFYKTsKICAgIGNwdHIgPSBzdHJ0b2tfcihidWYsIFNOTVBfQ09ORklHX0RFTElNRVRFUlMsICZzdCk7CiAgICBpZiAoIWNwdHIpIHsKICAgICAgICBzbnByaW50Zih0bXBidWYsIHNpemVvZih0bXBidWYpLCAiV3JvbmcgZm9ybWF0OiAlcyIsIGxpbmUpOwogICAgICAgIHRtcGJ1Zlsgc2l6ZW9mKHRtcGJ1ZiktMSBdID0gJ1wwJzsKICAgICAgICBjb25maWdfcGVycm9yKHRtcGJ1Zik7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAgaWYgKGNwdHJbMF0gPT0gJ1snKSB7CiAgICAgICAgaWYgKGNwdHJbc3RybGVuKGNwdHIpIC0gMV0gIT0gJ10nKSB7CiAgICAgICAgICAgIHNucHJpbnRmKHRtcGJ1Ziwgc2l6ZW9mKHRtcGJ1ZiksCiAgICAgICAgICAgICAgICAgICAgIm5vIG1hdGNoaW5nICddJyBmb3IgdHlwZSAlcy4iLAogICAgICAgICAgICAgICAgICAgIGNwdHIgKyAxKTsKICAgICAgICAgICAgdG1wYnVmWyBzaXplb2YodG1wYnVmKS0xIF0gPSAwOwogICAgICAgICAgICBjb25maWdfcGVycm9yKHRtcGJ1Zik7CiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICB9CiAgICAgICAgY3B0cltzdHJsZW4oY3B0cikgLSAxXSA9ICdcMCc7CiAgICAgICAgbHB0ciA9IHJlYWRfY29uZmlnX2dldF9oYW5kbGVycyhjcHRyICsgMSk7CiAgICAgICAgaWYgKGxwdHIgPT0gTlVMTCkgewogICAgICAgICAgICBzbnByaW50Zih0bXBidWYsICBzaXplb2YodG1wYnVmKSwKICAgICAgICAgICAgICAgICAgICAgIk5vIGhhbmRsZXJzIHJlZ2VzdGVyZWQgZm9yIHR5cGUgJXMuIiwKICAgICAgICAgICAgICAgICAgICBjcHRyICsgMSk7CiAgICAgICAgICAgIHRtcGJ1Zlsgc2l6ZW9mKHRtcGJ1ZiktMSBdID0gMDsKICAgICAgICAgICAgY29uZmlnX3BlcnJvcih0bXBidWYpOwogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgfQogICAgICAgIGNwdHIgPSBzdHJ0b2tfcihOVUxMLCBTTk1QX0NPTkZJR19ERUxJTUVURVJTLCAmc3QpOwogICAgICAgIGxwdHIgPSByZWFkX2NvbmZpZ19maW5kX2hhbmRsZXIobHB0ciwgY3B0cik7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogd2UgaGF2ZSB0byBmaW5kIGEgdG9rZW4gCiAgICAgICAgICovCiAgICAgICAgZm9yICg7IGN0bXAgIT0gTlVMTCAmJiBscHRyID09IE5VTEw7IGN0bXAgPSBjdG1wLT5uZXh0KQogICAgICAgICAgICBscHRyID0gcmVhZF9jb25maWdfZmluZF9oYW5kbGVyKGN0bXAtPnN0YXJ0LCBjcHRyKTsKICAgIH0KICAgIGlmIChscHRyID09IE5VTEwgJiYgbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJCSAgTkVUU05NUF9EU19MSUJfTk9fVE9LRU5fV0FSTklOR1MpKSB7CiAgICAgICAgc25wcmludGYodG1wYnVmLCBzaXplb2YodG1wYnVmKSwgIlVua25vd24gdG9rZW46ICVzLiIsIGNwdHIpOwogICAgICAgIHRtcGJ1Zlsgc2l6ZW9mKHRtcGJ1ZiktMSBdID0gMDsKICAgICAgICBjb25maWdfcHdhcm4odG1wYnVmKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgLyoKICAgICAqIHVzZSB0aGUgb3JpZ2luYWwgc3RyaW5nIGluc3RlYWQgc2luY2Ugc3RydG9rX3IgbWVzc2VkIHVwIHRoZSBvcmlnaW5hbCAKICAgICAqLwogICAgbGluZSA9IHNraXBfd2hpdGUobGluZSArIChjcHRyIC0gYnVmKSArIHN0cmxlbihjcHRyKSArIDEpOwoKICAgIHJldHVybiAocnVuX2NvbmZpZ19oYW5kbGVyKGxwdHIsIGNwdHIsIGxpbmUsIHdoZW4pKTsKfQoKaW50Cm5ldHNubXBfY29uZmlnKGNoYXIgKmxpbmUpCnsKICAgIGludCAgICAgICAgICAgICByZXQgPSBTTk1QX0VSUl9OT0VSUk9SOwogICAgREVCVUdNU0dUTCgoInNubXBfY29uZmlnIiwgInJlbWVtYmVyaW5nIGxpbmUgXCIlc1wiXG4iLCBsaW5lKSk7CiAgICBuZXRzbm1wX2NvbmZpZ19yZW1lbWJlcihsaW5lKTsgICAgICAvKiBhbHdheXMgcmVtZW1iZXIgaXQgc28gaXQncyByZWFkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBwcm9jZXNzZWQgYWZ0ZXIgYSBmcmVlX2NvbmZpZygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBjYWxsICovCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgICAgICAgTkVUU05NUF9EU19MSUJfSEFWRV9SRUFEX0NPTkZJRykpIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9jb25maWciLCAiICAuLi4gcHJvY2Vzc2luZyBpdCBub3dcbiIpKTsKICAgICAgICByZXQgPSBzbm1wX2NvbmZpZ193aGVuKGxpbmUsIE5PUk1BTF9DT05GSUcpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKdm9pZApuZXRzbm1wX2NvbmZpZ19yZW1lbWJlcl9pbl9saXN0KGNoYXIgKmxpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHJlYWRfY29uZmlnX21lbW9yeSAqKm1lbSkKewogICAgaWYgKG1lbSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICB3aGlsZSAoKm1lbSAhPSBOVUxMKQogICAgICAgIG1lbSA9ICYoKCptZW0pLT5uZXh0KTsKCiAgICAqbWVtID0gU05NUF9NQUxMT0NfU1RSVUNUKHJlYWRfY29uZmlnX21lbW9yeSk7CiAgICBpZiAobGluZSkKICAgICAgICAoKm1lbSktPmxpbmUgPSBzdHJkdXAobGluZSk7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcmVtZW1iZXJfZnJlZV9saXN0KHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKiptZW0pCnsKICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKnRtcG1lbTsKICAgIHdoaWxlICgqbWVtKSB7CiAgICAgICAgU05NUF9GUkVFKCgqbWVtKS0+bGluZSk7CiAgICAgICAgdG1wbWVtID0gKCptZW0pLT5uZXh0OwogICAgICAgIFNOTVBfRlJFRSgqbWVtKTsKICAgICAgICAqbWVtID0gdG1wbWVtOwogICAgfQp9Cgp2b2lkCm5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3J5X2xpc3Qoc3RydWN0IHJlYWRfY29uZmlnX21lbW9yeSAqKm1lbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdoZW4sIGludCBjbGVhcikKewoKICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKm1lbTsKCiAgICBpZiAoIW1lbXApCiAgICAgICAgcmV0dXJuOwoKICAgIG1lbSA9ICptZW1wOwoKICAgIHdoaWxlIChtZW0pIHsKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAicHJvY2Vzc2luZyBtZW1vcnk6ICVzXG4iLCBtZW0tPmxpbmUpKTsKICAgICAgICBzbm1wX2NvbmZpZ193aGVuKG1lbS0+bGluZSwgd2hlbik7CiAgICAgICAgbWVtID0gbWVtLT5uZXh0OwogICAgfQoKICAgIGlmIChjbGVhcikKICAgICAgICBuZXRzbm1wX2NvbmZpZ19yZW1lbWJlcl9mcmVlX2xpc3QobWVtcCk7Cn0KCi8qCiAqIGRlZmF1bHQgc3RvcmFnZSBsb2NhdGlvbiBpbXBsZW1lbnRhdGlvbiAKICovCnN0YXRpYyBzdHJ1Y3QgcmVhZF9jb25maWdfbWVtb3J5ICptZW1vcnlsaXN0ID0gTlVMTDsKCnZvaWQKbmV0c25tcF9jb25maWdfcmVtZW1iZXIoY2hhciAqbGluZSkKewogICAgbmV0c25tcF9jb25maWdfcmVtZW1iZXJfaW5fbGlzdChsaW5lLCAmbWVtb3J5bGlzdCk7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcmllcyh2b2lkKQp7CiAgICBuZXRzbm1wX2NvbmZpZ19wcm9jZXNzX21lbW9yeV9saXN0KCZtZW1vcnlsaXN0LCBFSVRIRVJfQ09ORklHLCAxKTsKfQoKdm9pZApuZXRzbm1wX2NvbmZpZ19wcm9jZXNzX21lbW9yaWVzX3doZW4oaW50IHdoZW4sIGludCBjbGVhcikKewogICAgbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcnlfbGlzdCgmbWVtb3J5bGlzdCwgd2hlbiwgY2xlYXIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiByZWFkX2NvbmZpZwogKgogKiBQYXJhbWV0ZXJzOgogKgkqZmlsZW5hbWUKICoJKmxpbmVfaGFuZGxlcgogKgkgd2hlbgogKgogKiBSZWFkIDxmaWxlbmFtZT4gYW5kIHByb2Nlc3MgZWFjaCBsaW5lIGluIGFjY29yZGFuY2Ugd2l0aCB0aGUgbGlzdCBvZgogKiA8bGluZV9oYW5kbGVyPiBmdW5jdGlvbnMuCiAqCiAqCiAqIEZvciBlYWNoIGxpbmUgaW4gPGZpbGVuYW1lPiwgc2VhcmNoIHRoZSBsaXN0IG9mIDxsaW5lX2hhbmRsZXI+J3MgCiAqIGZvciBhbiBlbnRyeSB0aGF0IG1hdGNoZXMgdGhlIGZpcnN0IHRva2VuIG9uIHRoZSBsaW5lLiAgVGhpcyBjb21wYXJpc29uIGlzCiAqIGNhc2UgaW5zZW5zaXRpdmUuCiAqCiAqIEZvciBlYWNoIG1hdGNoLCBjaGVjayB0aGF0IDx3aGVuPiBpcyB0aGUgZGVzaWduYXRlZCB0aW1lIGZvciB0aGUKICogPGxpbmVfaGFuZGxlcj4gZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgYmVmb3JlIHByb2Nlc3NpbmcgdGhlIGxpbmUuCiAqLwp2b2lkCnJlYWRfY29uZmlnKGNvbnN0IGNoYXIgKmZpbGVuYW1lLAogICAgICAgICAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmxpbmVfaGFuZGxlciwgaW50IHdoZW4pCnsKCiAgICBGSUxFICAgICAgICAgICAqaWZpbGU7CiAgICBjaGFyICAgICAgICAgICAgbGluZVtTVFJJTkdNQVhdLCB0b2tlbltTVFJJTkdNQVhdLCB0bXBidWZbU1RSSU5HTUFYXTsKICAgIGNoYXIgICAgICAgICAgICpjcHRyOwogICAgaW50ICAgICAgICAgICAgIGk7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmxwdHI7CgogICAgbGluZWNvdW50ID0gMDsKICAgIGN1cmZpbGVuYW1lID0gZmlsZW5hbWU7CgogICAgaWYgKChpZmlsZSA9IGZvcGVuKGZpbGVuYW1lLCAiciIpKSA9PSBOVUxMKSB7CiNpZmRlZiBFTk9FTlQKICAgICAgICBpZiAoZXJybm8gPT0gRU5PRU5UKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICIlczogJXNcbiIsIGZpbGVuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBzdHJlcnJvcihlcnJubykpKTsKICAgICAgICB9IGVsc2UKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBFTk9FTlQgKi8KI2lmZGVmIEVBQ0NFUwogICAgICAgIGlmIChlcnJubyA9PSBFQUNDRVMpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIiVzOiAlc1xuIiwgZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVycm9yKGVycm5vKSkpOwogICAgICAgIH0gZWxzZQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEVBQ0NFUyAqLwojaWYgZGVmaW5lZChFTk9FTlQpIHx8IGRlZmluZWQoRUFDQ0VTKQogICAgICAgIHsKICAgICAgICAgICAgc25tcF9sb2dfcGVycm9yKGZpbGVuYW1lKTsKICAgICAgICB9CiNlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZGVmaW5lZChFTk9FTlQpIHx8IGRlZmluZWQoRUFDQ0VTKSAqLwogICAgICAgICAgICBzbm1wX2xvZ19wZXJyb3IoZmlsZW5hbWUpOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEVOT0VOVCAqLwogICAgICAgIHJldHVybjsKICAgIH0gZWxzZSB7CiAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIlJlYWRpbmcgY29uZmlndXJhdGlvbiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSkpOwogICAgfQoKICAgIHdoaWxlIChmZ2V0cyhsaW5lLCBzaXplb2YobGluZSksIGlmaWxlKSAhPSBOVUxMKSB7CiAgICAgICAgbHB0ciA9IGxpbmVfaGFuZGxlcjsKICAgICAgICBsaW5lY291bnQrKzsKICAgICAgICBjcHRyID0gbGluZTsKICAgICAgICBpID0gc3RybGVuKGxpbmUpIC0gMTsKICAgICAgICBpZiAobGluZVtpXSA9PSAnXG4nKQogICAgICAgICAgICBsaW5lW2ldID0gMDsKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIGJsYW5rIGxpbmUgb3IgIyBjb21tZW50IAogICAgICAgICAqLwogICAgICAgIGlmICgoY3B0ciA9IHNraXBfd2hpdGUoY3B0cikpKSB7CiAgICAgICAgICAgIGNwdHIgPSBjb3B5X253b3JkKGNwdHIsIHRva2VuLCBzaXplb2YodG9rZW4pKTsKICAgICAgICAgICAgaWYgKHRva2VuWzBdID09ICdbJykgewogICAgICAgICAgICAgICAgaWYgKHRva2VuW3N0cmxlbih0b2tlbikgLSAxXSAhPSAnXScpIHsKICAgICAgICAgICAgICAgICAgICBzbnByaW50Zih0bXBidWYsIHNpemVvZih0bXBidWYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vIG1hdGNoaW5nICddJyBmb3IgdHlwZSAlcy4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRva2VuWzFdKTsKICAgICAgICAgICAgICAgICAgICB0bXBidWZbIHNpemVvZih0bXBidWYpLTEgXSA9IDA7CiAgICAgICAgICAgICAgICAgICAgY29uZmlnX3BlcnJvcih0bXBidWYpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdG9rZW5bc3RybGVuKHRva2VuKSAtIDFdID0gJ1wwJzsKICAgICAgICAgICAgICAgIGxwdHIgPSByZWFkX2NvbmZpZ19nZXRfaGFuZGxlcnMoJnRva2VuWzFdKTsKICAgICAgICAgICAgICAgIGlmIChscHRyID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBzbnByaW50Zih0bXBidWYsIHNpemVvZih0bXBidWYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIGhhbmRsZXJzIHJlZ2VzdGVyZWQgZm9yIHR5cGUgJXMuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0b2tlblsxXSk7CiAgICAgICAgICAgICAgICAgICAgdG1wYnVmWyBzaXplb2YodG1wYnVmKS0xIF0gPSAwOwogICAgICAgICAgICAgICAgICAgIGNvbmZpZ19wZXJyb3IodG1wYnVmKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dpdGNoaW5nIHRvIG5ldyBjb250ZXh0OiAlcyVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChjcHRyKSA/ICIodGhpcyBsaW5lIG9ubHkpICIgOiAiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdG9rZW5bMV0pKTsKICAgICAgICAgICAgICAgIGlmIChjcHRyID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIGNoYW5nZSBjb250ZXh0IHBlcm1hbmVudGx5IAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGxpbmVfaGFuZGxlciA9IGxwdHI7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogdGhlIHJlc3Qgb2YgdGhpcyBsaW5lIG9ubHkgYXBwbGllcy4gCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgY3B0ciA9IGNvcHlfbndvcmQoY3B0ciwgdG9rZW4sIHNpemVvZih0b2tlbikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbHB0ciA9IGxpbmVfaGFuZGxlcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3B0ciA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBzbnByaW50Zih0bXBidWYsIHNpemVvZih0bXBidWYpLAogICAgICAgICAgICAgICAgICAgICAgICAiQmxhbmsgbGluZSBmb2xsb3dpbmcgJXMgdG9rZW4uIiwgdG9rZW4pOwogICAgICAgICAgICAgICAgdG1wYnVmWyBzaXplb2YodG1wYnVmKS0xIF0gPSAwOwogICAgICAgICAgICAgICAgY29uZmlnX3BlcnJvcih0bXBidWYpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIiVzOiVkIGV4YW1pbmluZzogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgbGluZWNvdW50LCBsaW5lKSk7CiAgICAgICAgICAgICAgICBydW5fY29uZmlnX2hhbmRsZXIobHB0ciwgdG9rZW4sIGNwdHIsIHdoZW4pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZmNsb3NlKGlmaWxlKTsKICAgIHJldHVybjsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHJlYWRfY29uZmlnKCkgKi8KCgoKdm9pZApmcmVlX2NvbmZpZyh2b2lkKQp7CiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjdG1wID0gY29uZmlnX2ZpbGVzOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpsdG1wOwoKICAgIGZvciAoOyBjdG1wICE9IE5VTEw7IGN0bXAgPSBjdG1wLT5uZXh0KQogICAgICAgIGZvciAobHRtcCA9IGN0bXAtPnN0YXJ0OyBsdG1wICE9IE5VTEw7IGx0bXAgPSBsdG1wLT5uZXh0KQogICAgICAgICAgICBpZiAobHRtcC0+ZnJlZV9mdW5jKQogICAgICAgICAgICAgICAgKCoobHRtcC0+ZnJlZV9mdW5jKSkgKCk7Cn0KCnZvaWQKcmVhZF9jb25maWdzX29wdGlvbmFsKGNvbnN0IGNoYXIgKm9wdGlvbmFsX2NvbmZpZywgaW50IHdoZW4pCnsKICAgIGNoYXIgKm5ld3AsICpjcCwgKnN0ID0gTlVMTDsKICAgIGNoYXIgKnR5cGUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFKTsKCiAgICBpZiAoKE5VTEwgPT0gb3B0aW9uYWxfY29uZmlnKSB8fCAoTlVMTCA9PSB0eXBlKSkKICAgICAgICByZXR1cm47CgogICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnc19vcHRpb25hbCIsCiAgICAgICAgICAgICAgICAicmVhZGluZyBvcHRpb25hbCBjb25maWd1cmF0aW9uIHRva2VucyBmb3IgJXNcbiIsIHR5cGUpKTsKICAgIAogICAgbmV3cCA9IHN0cmR1cChvcHRpb25hbF9jb25maWcpOyAgICAgIC8qIHN0cnRva19yIG1lc3NlcyBpdCB1cCAqLwogICAgY3AgPSBzdHJ0b2tfcihuZXdwLCAiLCIsICZzdCk7CiAgICB3aGlsZSAoY3ApIHsKICAgICAgICBzdHJ1Y3Qgc3RhdCAgICAgc3RhdGJ1ZjsKICAgICAgICBpZiAoc3RhdChjcCwgJnN0YXRidWYpKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJPcHRpb25hbCBGaWxlIFwiJXNcIiBkb2VzIG5vdCBleGlzdC5cbiIsIGNwKSk7CiAgICAgICAgICAgIHNubXBfbG9nX3BlcnJvcihjcCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwKICAgICAgICAgICAgICAgICAgICAgICAgIlJlYWRpbmcgb3B0aW9uYWwgY29uZmlnIGZpbGU6IFwiJXNcIlxuIiwgY3ApKTsKICAgICAgICAgICAgcmVhZF9jb25maWdfd2l0aF90eXBlX3doZW4oY3AsIHR5cGUsIHdoZW4pOwogICAgICAgIH0KICAgICAgICBjcCA9IHN0cnRva19yKE5VTEwsICIsIiwgJnN0KTsKICAgIH0KICAgIGZyZWUobmV3cCk7CiAgICAKfQoKdm9pZApyZWFkX2NvbmZpZ3Modm9pZCkKewogICAgY2hhciAqb3B0aW9uYWxfY29uZmlnID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkJICAgICAgIE5FVFNOTVBfRFNfTElCX09QVElPTkFMQ09ORklHKTsKCiAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAicmVhZGluZyBub3JtYWwgY29uZmlndXJhdGlvbiB0b2tlbnNcbiIpKTsKCiAgICBpZiAoKE5VTEwgIT0gb3B0aW9uYWxfY29uZmlnKSAmJiAoKm9wdGlvbmFsX2NvbmZpZyA9PSAnLScpKSB7CiAgICAgICAgcmVhZF9jb25maWdzX29wdGlvbmFsKCsrb3B0aW9uYWxfY29uZmlnLCBOT1JNQUxfQ09ORklHKTsKICAgICAgICBvcHRpb25hbF9jb25maWcgPSBOVUxMOyAvKiBjbGVhciwgc28gd2UgZG9uJ3QgcmVhZCB0aGVtIHR3aWNlICovCiAgICB9CgogICAgcmVhZF9jb25maWdfZmlsZXMoTk9STUFMX0NPTkZJRyk7CgogICAgLyoKICAgICAqIGRvIHRoaXMgZXZlbiB3aGVuIHRoZSBub3JtYWwgYWJvdmUgd2Fzbid0IGRvbmUgCiAgICAgKi8KICAgIGlmIChOVUxMICE9IG9wdGlvbmFsX2NvbmZpZykKICAgICAgICByZWFkX2NvbmZpZ3Nfb3B0aW9uYWwob3B0aW9uYWxfY29uZmlnLCBOT1JNQUxfQ09ORklHKTsKCiAgICBuZXRzbm1wX2NvbmZpZ19wcm9jZXNzX21lbW9yaWVzX3doZW4oTk9STUFMX0NPTkZJRywgMSk7CgogICAgbmV0c25tcF9kc19zZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgICBORVRTTk1QX0RTX0xJQl9IQVZFX1JFQURfQ09ORklHLCAxKTsKICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19MSUJSQVJZLAogICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0NBTExCQUNLX1BPU1RfUkVBRF9DT05GSUcsIE5VTEwpOwp9Cgp2b2lkCnJlYWRfcHJlbWliX2NvbmZpZ3Modm9pZCkKewogICAgY2hhciAqb3B0aW9uYWxfY29uZmlnID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkJICAgICAgIE5FVFNOTVBfRFNfTElCX09QVElPTkFMQ09ORklHKTsKCiAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAicmVhZGluZyBwcmVtaWIgY29uZmlndXJhdGlvbiB0b2tlbnNcbiIpKTsKCiAgICBpZiAoKE5VTEwgIT0gb3B0aW9uYWxfY29uZmlnKSAmJiAoKm9wdGlvbmFsX2NvbmZpZyA9PSAnLScpKSB7CiAgICAgICAgcmVhZF9jb25maWdzX29wdGlvbmFsKCsrb3B0aW9uYWxfY29uZmlnLCBQUkVNSUJfQ09ORklHKTsKICAgICAgICBvcHRpb25hbF9jb25maWcgPSBOVUxMOyAvKiBjbGVhciwgc28gd2UgZG9uJ3QgcmVhZCB0aGVtIHR3aWNlICovCiAgICB9CgogICAgcmVhZF9jb25maWdfZmlsZXMoUFJFTUlCX0NPTkZJRyk7CgogICAgaWYgKE5VTEwgIT0gb3B0aW9uYWxfY29uZmlnKQogICAgICAgIHJlYWRfY29uZmlnc19vcHRpb25hbChvcHRpb25hbF9jb25maWcsIFBSRU1JQl9DT05GSUcpOwoKICAgIG5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3JpZXNfd2hlbihQUkVNSUJfQ09ORklHLCAwKTsKCiAgICBuZXRzbm1wX2RzX3NldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCSAgIE5FVFNOTVBfRFNfTElCX0hBVkVfUkVBRF9QUkVNSUJfQ09ORklHLCAxKTsKICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19MSUJSQVJZLAogICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0NBTExCQUNLX1BPU1RfUFJFTUlCX1JFQURfQ09ORklHLCBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogc2V0X2NvbmZpZ3VyYXRpb25fZGlyZWN0b3J5CiAqCiAqIFBhcmFtZXRlcnM6CiAqICAgICAgY2hhciAqZGlyIC0gdmFsdWUgb2YgdGhlIGRpcmVjdG9yeQogKiBTZXRzIHRoZSBjb25maWd1cmF0aW9uIGRpcmVjdG9yeS4gTXVsdGlwbGUgZGlyZWN0b3JpZXMgY2FuIGJlCiAqIHNwZWNpZmllZCwgYnV0IG5lZWQgdG8gYmUgc2VwZXJhdGVkIGJ5ICdFTlZfU0VQQVJBVE9SX0NIQVInLgogKi8Kdm9pZApzZXRfY29uZmlndXJhdGlvbl9kaXJlY3RvcnkoY29uc3QgY2hhciAqZGlyKQp7CiAgICBuZXRzbm1wX2RzX3NldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICBORVRTTk1QX0RTX0xJQl9DT05GSUdVUkFUSU9OX0RJUiwgZGlyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZ2V0X2NvbmZpZ3VyYXRpb25fZGlyZWN0b3J5CiAqCiAqIFBhcmFtZXRlcnM6IC0KICogUmV0cmlldmUgdGhlIGNvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IG9yIGRpcmVjdG9yaWVzLgogKiAoRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHRoYXQgaXM6CiAqICAgICAgIFNOTVBDT05GUEFUSCwgU05NUFNIQVJFUEFUSCwgU05NUExJQlBBVEgsIEhPTUUvLnNubXAKICogRmlyc3QgY2hlY2sgd2hldGhlciB0aGUgdmFsdWUgaXMgc2V0LgogKiBJZiBub3Qgc2V0IGdpdmUgaXQgdGhlIGRlZmF1bHQgdmFsdWUuCiAqIFJldHVybiB0aGUgdmFsdWUuCiAqIFdlIGFsd2F5cyByZXRyaWV2ZSBpdCBuZXcsIHNpbmNlIHdlIGhhdmUgdG8gZG8gaXQgYW55d2F5IGlmIGl0IGlzIGp1c3Qgc2V0LgogKi8KY29uc3QgY2hhciAgICAgKgpnZXRfY29uZmlndXJhdGlvbl9kaXJlY3RvcnkoKQp7CiAgICBjaGFyICAgICAgICAgICAgZGVmYXVsdFBhdGhbU1BSSU5UX01BWF9MRU5dOwogICAgY2hhciAgICAgICAgICAgKmhvbWVwYXRoOwoKICAgIGlmIChOVUxMID09IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICAgICAgTkVUU05NUF9EU19MSUJfQ09ORklHVVJBVElPTl9ESVIpKSB7CiAgICAgICAgaG9tZXBhdGggPSBuZXRzbm1wX2dldGVudigiSE9NRSIpOwogICAgICAgIHNucHJpbnRmKGRlZmF1bHRQYXRoLCBzaXplb2YoZGVmYXVsdFBhdGgpLCAiJXMlYyVzJWMlcyVzJXMlcyIsCiAgICAgICAgICAgICAgICBTTk1QQ09ORlBBVEgsIEVOVl9TRVBBUkFUT1JfQ0hBUiwKICAgICAgICAgICAgICAgIFNOTVBTSEFSRVBBVEgsIEVOVl9TRVBBUkFUT1JfQ0hBUiwgU05NUExJQlBBVEgsCiAgICAgICAgICAgICAgICAoKGhvbWVwYXRoID09IE5VTEwpID8gIiIgOiBFTlZfU0VQQVJBVE9SKSwKICAgICAgICAgICAgICAgICgoaG9tZXBhdGggPT0gTlVMTCkgPyAiIiA6IGhvbWVwYXRoKSwKICAgICAgICAgICAgICAgICgoaG9tZXBhdGggPT0gTlVMTCkgPyAiIiA6ICIvLnNubXAiKSk7CiAgICAgICAgZGVmYXVsdFBhdGhbIHNpemVvZihkZWZhdWx0UGF0aCktMSBdID0gMDsKICAgICAgICBzZXRfY29uZmlndXJhdGlvbl9kaXJlY3RvcnkoZGVmYXVsdFBhdGgpOwogICAgfQogICAgcmV0dXJuIChuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgTkVUU05NUF9EU19MSUJfQ09ORklHVVJBVElPTl9ESVIpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogc2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5CiAqCiAqIFBhcmFtZXRlcnM6CiAqICAgICAgY2hhciAqZGlyIC0gdmFsdWUgb2YgdGhlIGRpcmVjdG9yeQogKiBTZXRzIHRoZSBjb25maWd1cmF0aW9uIGRpcmVjdG9yeS4gCiAqIE5vIG11bHRpcGxlIGRpcmVjdG9yaWVzIG1heSBiZSBzcGVjaWZpZWQuCiAqIChIb3dldmVyLCB0aGlzIGlzIG5vdCBjaGVja2VkKQogKi8Kdm9pZApzZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoY29uc3QgY2hhciAqZGlyKQp7CiAgICBuZXRzbm1wX2RzX3NldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICBORVRTTk1QX0RTX0xJQl9QRVJTSVNURU5UX0RJUiwgZGlyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5CiAqCiAqIFBhcmFtZXRlcnM6IC0KICogRnVuY3Rpb24gd2lsbCByZXRyaWV2ZSB0aGUgcGVyc2lzdGVuIGRpcmVjdG9yeSB2YWx1ZS4KICogRmlyc3QgY2hlY2sgd2hldGhlciB0aGUgdmFsdWUgaXMgc2V0LgogKiBJZiBub3Qgc2V0IGdpdmUgaXQgdGhlIGRlZmF1bHQgdmFsdWUuCiAqIFJldHVybiB0aGUgdmFsdWUuIAogKiBXZSBhbHdheXMgcmV0cmlldmUgaXQgbmV3LCBzaW5jZSB3ZSBoYXZlIHRvIGRvIGl0IGFueXdheSBpZiBpdCBpcyBqdXN0IHNldC4KICovCmNvbnN0IGNoYXIgICAgICoKZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KCkKewogICAgaWYgKE5VTEwgPT0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgICBORVRTTk1QX0RTX0xJQl9QRVJTSVNURU5UX0RJUikpIHsKICAgICAgICBjb25zdCBjaGFyICpwZXJzZGlyID0gbmV0c25tcF9nZXRlbnYoIlNOTVBfUEVSU0lTVEVOVF9ESVIiKTsKICAgICAgICBpZiAoTlVMTCA9PSBwZXJzZGlyKQogICAgICAgICAgICBwZXJzZGlyID0gTkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWTsKICAgICAgICBzZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkocGVyc2Rpcik7CiAgICB9CiAgICByZXR1cm4gKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICBORVRTTk1QX0RTX0xJQl9QRVJTSVNURU5UX0RJUikpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBzZXRfdGVtcF9maWxlX3BhdHRlcm4KICoKICogUGFyYW1ldGVyczoKICogICAgICBjaGFyICpwYXR0ZXJuIC0gdmFsdWUgb2YgdGhlIGZpbGUgcGF0dGVybgogKiBTZXRzIHRoZSB0ZW1wIGZpbGUgcGF0dGVybi4gCiAqIE11bHRpcGxlIHBhdHRlcm5zIG1heSBub3QgYmUgc3BlY2lmaWVkLgogKiAoSG93ZXZlciwgdGhpcyBpcyBub3QgY2hlY2tlZCkKICovCnZvaWQKc2V0X3RlbXBfZmlsZV9wYXR0ZXJuKGNvbnN0IGNoYXIgKnBhdHRlcm4pCnsKICAgIG5ldHNubXBfZHNfc2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgIE5FVFNOTVBfRFNfTElCX1RFTVBfRklMRV9QQVRURVJOLCBwYXR0ZXJuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZ2V0X3RlbXBfZmlsZV9wYXR0ZXJuCiAqCiAqIFBhcmFtZXRlcnM6IC0KICogRnVuY3Rpb24gd2lsbCByZXRyaWV2ZSB0aGUgdGVtcCBmaWxlIHBhdHRlcm4gdmFsdWUuCiAqIEZpcnN0IGNoZWNrIHdoZXRoZXIgdGhlIHZhbHVlIGlzIHNldC4KICogSWYgbm90IHNldCBnaXZlIGl0IHRoZSBkZWZhdWx0IHZhbHVlLgogKiBSZXR1cm4gdGhlIHZhbHVlLiAKICogV2UgYWx3YXlzIHJldHJpZXZlIGl0IG5ldywgc2luY2Ugd2UgaGF2ZSB0byBkbyBpdCBhbnl3YXkgaWYgaXQgaXMganVzdCBzZXQuCiAqLwpjb25zdCBjaGFyICAgICAqCmdldF90ZW1wX2ZpbGVfcGF0dGVybigpCnsKICAgIGlmIChOVUxMID09IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICAgICAgTkVUU05NUF9EU19MSUJfVEVNUF9GSUxFX1BBVFRFUk4pKSB7CiAgICAgICAgc2V0X3RlbXBfZmlsZV9wYXR0ZXJuKE5FVFNOTVBfVEVNUF9GSUxFX1BBVFRFUk4pOwogICAgfQogICAgcmV0dXJuIChuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgTkVUU05NUF9EU19MSUJfVEVNUF9GSUxFX1BBVFRFUk4pKTsKfQoKLyoqCiAqIHV0aWxpdHkgcm91dGluZSBmb3IgcmVhZF9jb25maWdfZmlsZXMKICovCnN0YXRpYyB2b2lkCnJlYWRfY29uZmlnX2ZpbGVzX2luX3BhdGgoY29uc3QgY2hhciAqcGF0aCwgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgd2hlbiwgY29uc3QgY2hhciAqcGVyc3BhdGgsIGNvbnN0IGNoYXIgKnBlcnNmaWxlKQp7CiAgICBpbnQgICAgICAgICAgICAgZG9uZSwgajsKICAgIGNoYXIgICAgICAgICAgICBjb25maWdmaWxlWzMwMF07CiAgICBjaGFyICAgICAgICAgICAqY3B0cjEsICpjcHRyMiwgKmVudmNvbmZwYXRoOwogICAgc3RydWN0IHN0YXQgICAgIHN0YXRidWY7CgogICAgaWYgKChOVUxMID09IHBhdGgpIHx8IChOVUxMID09IGN0bXApKQogICAgICAgIHJldHVybjsKCiAgICBlbnZjb25mcGF0aCA9IHN0cmR1cChwYXRoKTsKCiAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAiIGNvbmZpZyBwYXRoIHVzZWQgZm9yICVzOiVzIChwZXJzaXN0ZW50IHBhdGg6JXMpXG4iLAogICAgICAgICAgICAgICAgY3RtcC0+ZmlsZUhlYWRlciwgZW52Y29uZnBhdGgsIHBlcnNwYXRoKSk7CiAgICBjcHRyMSA9IGNwdHIyID0gZW52Y29uZnBhdGg7CiAgICBkb25lID0gMDsKICAgIHdoaWxlICgoIWRvbmUpICYmICgqY3B0cjIgIT0gMCkpIHsKICAgICAgICB3aGlsZSAoKmNwdHIxICE9IDAgJiYgKmNwdHIxICE9IEVOVl9TRVBBUkFUT1JfQ0hBUikKICAgICAgICAgICAgY3B0cjErKzsKICAgICAgICBpZiAoKmNwdHIxID09IDApCiAgICAgICAgICAgIGRvbmUgPSAxOwogICAgICAgIGVsc2UKICAgICAgICAgICAgKmNwdHIxID0gMDsKCiAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIiBjb25maWcgZGlyOiAlc1xuIiwgY3B0cjIgKSk7CiAgICAgICAgaWYgKHN0YXQoY3B0cjIsICZzdGF0YnVmKSAhPSAwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIERpcmVjdG9yeSBub3QgdGhlcmUsIGNvbnRpbnVlIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIiBEaXJlY3Rvcnkgbm90IHByZXNlbnQ6ICVzXG4iLCBjcHRyMiApKTsKICAgICAgICAgICAgY3B0cjIgPSArK2NwdHIxOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiNpZmRlZiBTX0lTRElSCiAgICAgICAgaWYgKCFTX0lTRElSKHN0YXRidWYuc3RfbW9kZSkpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogTm90IGEgZGlyZWN0b3J5LCBjb250aW51ZSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICIgTm90IGEgZGlyZWN0b3J5OiAlc1xuIiwgY3B0cjIgKSk7CiAgICAgICAgICAgIGNwdHIyID0gKytjcHRyMTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgLyoKICAgICAgICAgKiBmb3IgcHJvcGVyIHBlcnNpc3RlbnQgc3RvcmFnZSByZXRyaXZhbCwgd2UgbmVlZCB0byByZWFkIG9sZCBiYWNrdXAKICAgICAgICAgKiBjb3BpZXMgb2YgdGhlIHByZXZpb3VzIHN0b3JhZ2UgZmlsZXMuICBJZiB0aGUgYXBwbGljYXRpb24gaW4KICAgICAgICAgKiBxdWVzdGlvbiBoYXMgZGllZCB3aXRob3V0IHRoZSBwcm9wZXIgY2FsbCB0byBzbm1wX2NsZWFuX3BlcnNpc3RlbnQsCiAgICAgICAgICogdGhlbiB3ZSByZWFkIGFsbCB0aGUgY29uZmlndXJhdGlvbiBmaWxlcyB3ZSBjYW4sIHN0YXJ0aW5nIHdpdGgKICAgICAgICAgKiB0aGUgb2xkZXN0IGZpcnN0LgogICAgICAgICAqLwogICAgICAgIGlmIChzdHJuY21wKGNwdHIyLCBwZXJzcGF0aCwgc3RybGVuKHBlcnNwYXRoKSkgPT0gMCB8fAogICAgICAgICAgICAocGVyc2ZpbGUgIT0gTlVMTCAmJgogICAgICAgICAgICAgc3RybmNtcChjcHRyMiwgcGVyc2ZpbGUsIHN0cmxlbihwZXJzZmlsZSkpID09IDApKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGxpbWl0IHRoaXMgdG8gdGhlIGtub3duIHN0b3JhZ2UgZGlyZWN0b3J5IG9ubHkgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmb3IgKGogPSAwOyBqIDw9IE5FVFNOTVBfTUFYX1BFUlNJU1RFTlRfQkFDS1VQUzsgaisrKSB7CiAgICAgICAgICAgICAgICBzbnByaW50Zihjb25maWdmaWxlLCBzaXplb2YoY29uZmlnZmlsZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAiJXMvJXMuJWQuY29uZiIsIGNwdHIyLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RtcC0+ZmlsZUhlYWRlciwgaik7CiAgICAgICAgICAgICAgICBjb25maWdmaWxlWyBzaXplb2YoY29uZmlnZmlsZSktMSBdID0gMDsKICAgICAgICAgICAgICAgIGlmIChzdGF0KGNvbmZpZ2ZpbGUsICZzdGF0YnVmKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBmaWxlIG5vdCB0aGVyZSwgY29udGludWUgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogYmFja3VwIGV4aXN0cywgcmVhZCBpdCAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfZmlsZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvbGQgY29uZmlnIGZpbGUgZm91bmQ6ICVzLCBwYXJzaW5nXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ2ZpbGUpKTsKICAgICAgICAgICAgICAgICAgICByZWFkX2NvbmZpZyhjb25maWdmaWxlLCBjdG1wLT5zdGFydCwgd2hlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc25wcmludGYoY29uZmlnZmlsZSwgc2l6ZW9mKGNvbmZpZ2ZpbGUpLAogICAgICAgICAgICAgICAgICIlcy8lcy5jb25mIiwgY3B0cjIsIGN0bXAtPmZpbGVIZWFkZXIpOwogICAgICAgIGNvbmZpZ2ZpbGVbIHNpemVvZihjb25maWdmaWxlKS0xIF0gPSAwOwogICAgICAgIHJlYWRfY29uZmlnKGNvbmZpZ2ZpbGUsIGN0bXAtPnN0YXJ0LCB3aGVuKTsKICAgICAgICBzbnByaW50Zihjb25maWdmaWxlLCBzaXplb2YoY29uZmlnZmlsZSksCiAgICAgICAgICAgICAgICAgIiVzLyVzLmxvY2FsLmNvbmYiLCBjcHRyMiwgY3RtcC0+ZmlsZUhlYWRlcik7CiAgICAgICAgY29uZmlnZmlsZVsgc2l6ZW9mKGNvbmZpZ2ZpbGUpLTEgXSA9IDA7CiAgICAgICAgcmVhZF9jb25maWcoY29uZmlnZmlsZSwgY3RtcC0+c3RhcnQsIHdoZW4pOwoKICAgICAgICBpZihkb25lKQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY3B0cjIgPSArK2NwdHIxOwogICAgfQogICAgU05NUF9GUkVFKGVudmNvbmZwYXRoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogcmVhZF9jb25maWdfZmlsZXMKICoKICogUGFyYW1ldGVyczoKICoJd2hlbgk9PSBQUkVNSUJfQ09ORklHLCBOT1JNQUxfQ09ORklHICAtb3ItICBFSVRIRVJfQ09ORklHCiAqCiAqCiAqIFRyYXZlcnNlIHRoZSBsaXN0IG9mIGNvbmZpZyBmaWxlIHR5cGVzLCBwZXJmb3JtaW5nIHRoZSBmb2xsb3dpbmcgYWN0aW9ucwogKiBmb3IgZWFjaCAtLQogKgogKiBGaXJzdCwgYnVpbGQgYSBzZWFyY2ggcGF0aCBmb3IgY29uZmlnIGZpbGVzLiAgSWYgdGhlIGNvbnRlbnRzIG9mIAogKiBlbnZpcm9ubWVudCB2YXJpYWJsZSBTTk1QQ09ORlBBVEggYXJlIE5VTEwsIHRoZW4gdXNlIHRoZSBmb2xsb3dpbmcKICogcGF0aCBsaXN0ICh3aGVyZSB0aGUgbGFzdCBlbnRyeSBleGlzdHMgb25seSBpZiBIT01FIGlzIG5vbi1udWxsKToKICoKICoJU05NUFNIQVJFUEFUSDpTTk1QTElCUEFUSDoke0hPTUV9Ly5zbm1wCiAqCiAqIFRoZW4sIEluIGVhY2ggb2YgdGhlc2UgZGlyZWN0b3JpZXMsIHJlYWQgY29uZmlnIGZpbGVzIGJ5IHRoZSBuYW1lIG9mOgogKgogKgk8ZGlyPi88ZmlsZUhlYWRlcj4uY29uZgkJLUFORC0KICoJPGRpcj4vPGZpbGVIZWFkZXI+LmxvY2FsLmNvbmYKICoKICogd2hlcmUgPGZpbGVIZWFkZXI+IGlzIHRha2VuIGZyb20gdGhlIGNvbmZpZyBmaWxlIHR5cGUgc3RydWN0dXJlLgogKgogKgogKiBQUkVNSUJfQ09ORklHIGNhdXNlcyBmcmVlX2NvbmZpZygpIHRvIGJlIGludm9rZWQgcHJpb3IgdG8gYW55IG90aGVyIGFjdGlvbi4KICoKICoKICogRVhJVHMgaWYgYW55ICdjb25maWdfZXJyb3JzJyBhcmUgbG9nZ2VkIHdoaWxlIHBhcnNpbmcgY29uZmlnIGZpbGUgbGluZXMuCiAqLwp2b2lkCnJlYWRfY29uZmlnX2ZpbGVzKGludCB3aGVuKQp7CiAgICBjb25zdCBjaGFyICAgICAqY29uZnBhdGgsICpwZXJzZmlsZSwgKmVudmNvbmZwYXRoOwogICAgY2hhciAgICAgICAgICAgKnBlcnNwYXRoOwogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCA9IGNvbmZpZ19maWxlczsKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ET05UX1BFUlNJU1RfU1RBVEUpCiAgICAgfHwgbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ESVNBQkxFX0NPTkZJR19MT0FEKSkgcmV0dXJuOwoKICAgIGNvbmZpZ19lcnJvcnMgPSAwOwoKICAgIGlmICh3aGVuID09IFBSRU1JQl9DT05GSUcpCiAgICAgICAgZnJlZV9jb25maWcoKTsKCiAgICAvKgogICAgICogdGhlc2Ugc2hvdWxkbid0IGNoYW5nZQogICAgICovCiAgICBjb25mcGF0aCA9IGdldF9jb25maWd1cmF0aW9uX2RpcmVjdG9yeSgpOwogICAgcGVyc2ZpbGUgPSBuZXRzbm1wX2dldGVudigiU05NUF9QRVJTSVNURU5UX0ZJTEUiKTsKICAgIGVudmNvbmZwYXRoID0gbmV0c25tcF9nZXRlbnYoIlNOTVBDT05GUEFUSCIpOwoKICAgIC8qCiAgICAgKiByZWFkIGFsbCBjb25maWcgZmlsZSB0eXBlcyAKICAgICAqLwogICAgZm9yICg7IGN0bXAgIT0gTlVMTDsgY3RtcCA9IGN0bXAtPm5leHQpIHsKCiAgICAgICAgLyoKICAgICAgICAgKiByZWFkIHRoZSBjb25maWcgZmlsZXMuIHN0cmR1cCgpIHRoZSByZXN1bHQgb2YKICAgICAgICAgKiBnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSB0byBhdm9pZCB0aGF0IHBhcnNpbmcgdGhlICJwZXJzaXN0ZW50RGlyIgogICAgICAgICAqIGtleXdvcmQgdHJhbnNmb3JtcyB0aGUgcGVyc3BhdGggcG9pbnRlciBpbnRvIGEgZGFuZ2xpbmcgcG9pbnRlci4KICAgICAgICAgKi8KICAgICAgICBwZXJzcGF0aCA9IHN0cmR1cChnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSk7CiAgICAgICAgaWYgKGVudmNvbmZwYXRoID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcmVhZCBqdXN0IHRoZSBjb25maWcgZmlsZXMgKG5vIHBlcnNpc3RlbnQgc3R1ZmYpLCBzaW5jZQogICAgICAgICAgICAgKiBwZXJzaXN0ZW50IHBhdGggY2FuIGNoYW5nZSB2aWEgY29uZiBmaWxlLiBUaGVuIGdldCB0aGUKICAgICAgICAgICAgICogY3VycmVudCBwZXJzaXN0ZW50IGRpcmVjdG9yeSwgYW5kIHJlYWQgZmlsZXMgdGhlcmUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZWFkX2NvbmZpZ19maWxlc19pbl9wYXRoKGNvbmZwYXRoLCBjdG1wLCB3aGVuLCBwZXJzcGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJzZmlsZSk7CiAgICAgICAgICAgIGZyZWUocGVyc3BhdGgpOwogICAgICAgICAgICBwZXJzcGF0aCA9IHN0cmR1cChnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSk7CiAgICAgICAgICAgIHJlYWRfY29uZmlnX2ZpbGVzX2luX3BhdGgocGVyc3BhdGgsIGN0bXAsIHdoZW4sIHBlcnNwYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcnNmaWxlKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG9ubHkgcmVhZCBwYXRoIHNwZWNpZmllZCBieSB1c2VyCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZWFkX2NvbmZpZ19maWxlc19pbl9wYXRoKGVudmNvbmZwYXRoLCBjdG1wLCB3aGVuLCBwZXJzcGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJzZmlsZSk7CiAgICAgICAgfQogICAgICAgIGZyZWUocGVyc3BhdGgpOwogICAgfQoKICAgIGlmIChjb25maWdfZXJyb3JzKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5ldC1zbm1wOiAlZCBlcnJvcihzKSBpbiBjb25maWcgZmlsZShzKVxuIiwKICAgICAgICAgICAgICAgICBjb25maWdfZXJyb3JzKTsKICAgIH0KfQoKdm9pZApyZWFkX2NvbmZpZ19wcmludF91c2FnZShjb25zdCBjaGFyICpsZWFkKQp7CiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjdG1wID0gY29uZmlnX2ZpbGVzOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpsdG1wOwoKICAgIGlmIChsZWFkID09IE5VTEwpCiAgICAgICAgbGVhZCA9ICIiOwoKICAgIGZvciAoY3RtcCA9IGNvbmZpZ19maWxlczsgY3RtcCAhPSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkgewogICAgICAgIHNubXBfbG9nKExPR19JTkZPLCAiJXNJbiAlcy5jb25mIGFuZCAlcy5sb2NhbC5jb25mOlxuIiwgbGVhZCwKICAgICAgICAgICAgICAgICBjdG1wLT5maWxlSGVhZGVyLCBjdG1wLT5maWxlSGVhZGVyKTsKICAgICAgICBmb3IgKGx0bXAgPSBjdG1wLT5zdGFydDsgbHRtcCAhPSBOVUxMOyBsdG1wID0gbHRtcC0+bmV4dCkgewogICAgICAgICAgICBERUJVR0lGKCJyZWFkX2NvbmZpZ191c2FnZSIpIHsKICAgICAgICAgICAgICAgIGlmIChsdG1wLT5jb25maWdfdGltZSA9PSBQUkVNSUJfQ09ORklHKQogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgicmVhZF9jb25maWdfdXNhZ2UiLCAiKiIpKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoInJlYWRfY29uZmlnX3VzYWdlIiwgIiAiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGx0bXAtPmhlbHApIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19JTkZPLCAiJXMlcyUtMjRzICVzXG4iLCBsZWFkLCBsZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgbHRtcC0+Y29uZmlnX3Rva2VuLCBsdG1wLT5oZWxwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIERFQlVHSUYoInJlYWRfY29uZmlnX3VzYWdlIikgewogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19JTkZPLCAiJXMlcyUtMjRzIFtOTyBIRUxQXVxuIiwgbGVhZCwgbGVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsdG1wLT5jb25maWdfdG9rZW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgovKioKICogcmVhZF9jb25maWdfc3RvcmUgaW50ZW5kZWQgZm9yIHVzZSBieSBhcHBsaWNhdGlvbnMgdG8gc3RvcmUgcGVybWVuYW50CiAqIGNvbmZpZ3VyYXRpb24gaW5mb3JtYXRpb24gZ2VuZXJhdGVkIGJ5IHNldHMgb3IgcGVyc2lzdGVudCBjb3VudGVycy4KICogQXBwZW5kcyBsaW5lIHRvIGEgZmlsZSBuYW1lZCBlaXRoZXIgRU5WKFNOTVBfUEVSU0lTVEVOVF9GSUxFKSBvcgogKiAgICI8TkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWT4vPHR5cGU+LmNvbmYiLgogKiBBZGRzIGEgdHJhaWxpbmcgbmV3bGluZSB0byB0aGUgc3RvcmVkIGZpbGUgaWYgbmVjZXNzYXJ5LgogKgogKiBAcGFyYW0gdHlwZSBpcyB0aGUgYXBwbGljYXRpb24gbmFtZQogKiBAcGFyYW0gbGluZSBpcyB0aGUgY29uZmlndXJhdGlvbiBsaW5lIHdyaXR0ZW4gdG8gdGhlIGFwcGxpY2F0aW9uIG5hbWUncwogKiBjb25maWd1cmF0aW9uIGZpbGUKICogICAgICAKICogQHJldHVybiB2b2lkCiAgKi8Kdm9pZApyZWFkX2NvbmZpZ19zdG9yZShjb25zdCBjaGFyICp0eXBlLCBjb25zdCBjaGFyICpsaW5lKQp7CiNpZmRlZiBORVRTTk1QX1BFUlNJU1RFTlRfRElSRUNUT1JZCiAgICBjaGFyICAgICAgICAgICAgZmlsZVs1MTJdLCAqZmlsZXA7CiAgICBGSUxFICAgICAgICAgICAqZm91dDsKI2lmZGVmIE5FVFNOTVBfUEVSU0lTVEVOVF9NQVNLCiAgICBtb2RlX3QgICAgICAgICAgb2xkbWFzazsKI2VuZGlmCgogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfRE9OVF9QRVJTSVNUX1NUQVRFKQogICAgIHx8IG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfRElTQUJMRV9QRVJTSVNURU5UX0xPQUQpKSByZXR1cm47CgogICAgLyoKICAgICAqIHN0b3JlIGNvbmZpZ3VyYXRpb24gZGlyZWN0aXZlcyBpbiB0aGUgZm9sbG93aW5nIG9yZGVyIG9mIHByZWZlcmVuY2U6CiAgICAgKiAxLiBFTlYgdmFyaWFibGUgU05NUF9QRVJTSVNURU5UX0ZJTEUKICAgICAqIDIuIGNvbmZpZ3VyZWQgPE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlk+Lzx0eXBlPi5jb25mCiAgICAgKi8KICAgIGlmICgoZmlsZXAgPSBuZXRzbm1wX2dldGVudigiU05NUF9QRVJTSVNURU5UX0ZJTEUiKSkgPT0gTlVMTCkgewogICAgICAgIHNucHJpbnRmKGZpbGUsIHNpemVvZihmaWxlKSwKICAgICAgICAgICAgICAgICAiJXMvJXMuY29uZiIsIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpLCB0eXBlKTsKICAgICAgICBmaWxlWyBzaXplb2YoZmlsZSktMSBdID0gMDsKICAgICAgICBmaWxlcCA9IGZpbGU7CiAgICB9CiNpZmRlZiBORVRTTk1QX1BFUlNJU1RFTlRfTUFTSwogICAgb2xkbWFzayA9IHVtYXNrKE5FVFNOTVBfUEVSU0lTVEVOVF9NQVNLKTsKI2VuZGlmCiAgICBpZiAobWtkaXJoaWVyKGZpbGVwLCBORVRTTk1QX0FHRU5UX0RJUkVDVE9SWV9NT0RFLCAxKSkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBjcmVhdGUgdGhlIHBlcnNpc3RlbnQgZGlyZWN0b3J5IGZvciAlc1xuIiwKICAgICAgICAgICAgICAgICBmaWxlKTsKICAgIH0KICAgIGlmICgoZm91dCA9IGZvcGVuKGZpbGVwLCAiYSIpKSAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50Zihmb3V0LCAiJXMiLCBsaW5lKTsKICAgICAgICBpZiAobGluZVtzdHJsZW4obGluZSldICE9ICdcbicpCiAgICAgICAgICAgIGZwcmludGYoZm91dCwgIlxuIik7CiAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgInN0b3Jpbmc6ICVzXG4iLCBsaW5lKSk7CiAgICAgICAgZmNsb3NlKGZvdXQpOwogICAgfSBlbHNlIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAicmVhZF9jb25maWdfc3RvcmUgb3BlbiBmYWlsdXJlIG9uICVzXG4iLCBmaWxlcCk7CiAgICB9CiNpZmRlZiBORVRTTk1QX1BFUlNJU1RFTlRfTUFTSwogICAgdW1hc2sob2xkbWFzayk7CiNlbmRpZgoKI2VuZGlmCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHJlYWRfY29uZmlnX3N0b3JlKCkgKi8KCnZvaWQKcmVhZF9hcHBfY29uZmlnX3N0b3JlKGNvbnN0IGNoYXIgKmxpbmUpCnsKICAgIHJlYWRfY29uZmlnX3N0b3JlKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJCSAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFKSwgbGluZSk7Cn0KCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIHNubXBfc2F2ZV9wZXJzaXN0ZW50CiAqCiAqIFBhcmFtZXRlcnM6CiAqCSp0eXBlCiAqICAgICAgCiAqCiAqIFNhdmUgdGhlIGZpbGUgIjxORVRTTk1QX1BFUlNJU1RFTlRfRElSRUNUT1JZPi88dHlwZT4uY29uZiIgaW50byBhIGJhY2t1cCBjb3B5CiAqIGNhbGxlZCAiPE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlk+Lzx0eXBlPi4lZC5jb25mIiwgd2hpY2ggJWQgaXMgYW4KICogaW5jcmVtZW50aW5nIG51bWJlciBvbiBlYWNoIGNhbGwsIGJ1dCBsZXNzIHRoYW4gTkVUU05NUF9NQVhfUEVSU0lTVEVOVF9CQUNLVVBTLgogKgogKiBTaG91bGQgYmUgY2FsbGVkIGp1c3QgYmVmb3JlIGFsbCBwZXJzaXN0ZW50IGluZm9ybWF0aW9uIGlzIHN1cHBvc2VkIHRvIGJlCiAqIHdyaXR0ZW4gdG8gbW92ZSBhc2lkZSB0aGUgZXhpc3RpbmcgcGVyc2lzdGVudCBjYWNoZS4KICogc25tcF9jbGVhbl9wZXJzaXN0ZW50IHNob3VsZCB0aGVuIGJlIGNhbGxlZCBhZnRlcndhcmQgYWxsIGRhdGEgaGFzIGJlZW4KICogc2F2ZWQgdG8gcmVtb3ZlIHRoZXNlIGJhY2t1cCBmaWxlcy4KICoKICogTm90ZTogb24gYW4gcmVuYW1lIGVycm9yLCB0aGUgZmlsZXMgYXJlIHJlbW92ZWQgcmF0aGVyIHRoYW4gc2F2ZWQuCiAqCiAqLwp2b2lkCnNubXBfc2F2ZV9wZXJzaXN0ZW50KGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIGNoYXIgICAgICAgICAgICBmaWxlWzUxMl0sIGZpbGVvbGRbU1BSSU5UX01BWF9MRU5dOwogICAgc3RydWN0IHN0YXQgICAgIHN0YXRidWY7CiAgICBpbnQgICAgICAgICAgICAgajsKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ET05UX1BFUlNJU1RfU1RBVEUpCiAgICAgfHwgbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ESVNBQkxFX1BFUlNJU1RFTlRfU0FWRSkpIHJldHVybjsKCiAgICBERUJVR01TR1RMKCgic25tcF9zYXZlX3BlcnNpc3RlbnQiLCAic2F2aW5nICVzIGZpbGVzLi4uXG4iLCB0eXBlKSk7CiAgICBzbnByaW50ZihmaWxlLCBzaXplb2YoZmlsZSksCiAgICAgICAgICAgICAiJXMvJXMuY29uZiIsIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpLCB0eXBlKTsKICAgIGZpbGVbIHNpemVvZihmaWxlKS0xIF0gPSAwOwogICAgaWYgKHN0YXQoZmlsZSwgJnN0YXRidWYpID09IDApIHsKICAgICAgICBmb3IgKGogPSAwOyBqIDw9IE5FVFNOTVBfTUFYX1BFUlNJU1RFTlRfQkFDS1VQUzsgaisrKSB7CiAgICAgICAgICAgIHNucHJpbnRmKGZpbGVvbGQsIHNpemVvZihmaWxlb2xkKSwKICAgICAgICAgICAgICAgICAgICAgIiVzLyVzLiVkLmNvbmYiLCBnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSwgdHlwZSwgaik7CiAgICAgICAgICAgIGZpbGVvbGRbIHNpemVvZihmaWxlb2xkKS0xIF0gPSAwOwogICAgICAgICAgICBpZiAoc3RhdChmaWxlb2xkLCAmc3RhdGJ1ZikgIT0gMCkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfc2F2ZV9wZXJzaXN0ZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgc2F2aW5nIG9sZCBjb25maWcgZmlsZTogJXMgLT4gJXMuXG4iLCBmaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW9sZCkpOwogICAgICAgICAgICAgICAgaWYgKHJlbmFtZShmaWxlLCBmaWxlb2xkKSkgewogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJDYW5ub3QgcmVuYW1lICVzIHRvICVzXG4iLCBmaWxlLCBmaWxlb2xkKTsKICAgICAgICAgICAgICAgICAgICAgLyogbW92aW5nIGl0IGZhaWxlZCwgdHJ5IG51a2luZyBpdCwgYXMgbGVhdmluZwogICAgICAgICAgICAgICAgICAgICAgKiBpdCBhcm91bmQgaXMgdmVyeSBiYWQuICovCiAgICAgICAgICAgICAgICAgICAgaWYgKHVubGluayhmaWxlKSA9PSAtMSkKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkNhbm5vdCB1bmxpbmsgJXNcbiIsIGZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvKgogICAgICogc2F2ZSBhIHdhcm5pbmcgaGVhZGVyIHRvIHRoZSB0b3Agb2YgdGhlIG5ldyBmaWxlIAogICAgICovCiAgICBzbnByaW50ZihmaWxlb2xkLCBzaXplb2YoZmlsZW9sZCksCiAgICAgICAgICAgICIjXG4jIG5ldC1zbm1wIChvciB1Y2Qtc25tcCkgcGVyc2lzdGVudCBkYXRhIGZpbGUuXG4jXG4jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjXG4jIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFxuI1xuIyAgICAgICAgICAqKioqIERPIE5PVCBFRElUIFRISVMgRklMRSAqKioqXG4jXG4jIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFxuIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI1xuI1xuIyBETyBOT1QgU1RPUkUgQ09ORklHVVJBVElPTiBFTlRSSUVTIEhFUkUuXG4jIFBsZWFzZSBzYXZlIG5vcm1hbCBjb25maWd1cmF0aW9uIHRva2VucyBmb3IgJXMgaW4gU05NUENPTkZQQVRILyVzLmNvbmYuXG4jIE9ubHkgXCJjcmVhdGVVc2VyXCIgdG9rZW5zIHNob3VsZCBiZSBwbGFjZWQgaGVyZSBieSAlcyBhZG1pbmlzdHJhdG9ycy5cbiMgKERpZCBJIG1lbnRpb246IGRvIG5vdCBlZGl0IHRoaXMgZmlsZT8pXG4jXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuIiwKICAgICAgICAgICAgdHlwZSwgdHlwZSwgdHlwZSk7CiAgICBmaWxlb2xkWyBzaXplb2YoZmlsZW9sZCktMSBdID0gMDsKICAgIHJlYWRfY29uZmlnX3N0b3JlKHR5cGUsIGZpbGVvbGQpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogc25tcF9jbGVhbl9wZXJzaXN0ZW50CiAqCiAqIFBhcmFtZXRlcnM6CiAqCSp0eXBlCiAqICAgICAgCiAqCiAqIFVubGluayBhbGwgYmFja3VwIGZpbGVzIGNhbGxlZCAiPE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlk+Lzx0eXBlPi4lZC5jb25mIi4KICoKICogU2hvdWxkIGJlIGNhbGxlZCBqdXN0IGFmdGVyIHdlIHN1Y2Nlc3NmdWxsIGR1bXBlZCB0aGUgbGFzdCBvZiB0aGUKICogcGVyc2lzdGVudCBkYXRhLCB0byByZW1vdmUgdGhlIGJhY2t1cCBjb3BpZXMgb2YgcHJldmlvdXMgc3RvcmFnZSBkdW1wcy4KICoKICogWFhYICBXb3J0aCBvdmVyd3JpdGluZyB3aXRoIHJhbmRvbSBieXRlcyBmaXJzdD8gIFRoaXMgd291bGQKICoJZW5zdXJlIHRoYXQgdGhlIGRhdGEgaXMgZGVzdHJveWVkLCBldmVuIGEgYnVmZmVyIGNvbnRhaW5pbmcgdGhlCiAqCWRhdGEgcGVyc2lzdHMgaW4gbWVtb3J5IG9yIHN3YXAuICBPbmx5IGltcG9ydGFudCBpZiBzZWNyZXRzCiAqCXdpbGwgYmUgc3RvcmVkIGhlcmUuCiAqLwp2b2lkCnNubXBfY2xlYW5fcGVyc2lzdGVudChjb25zdCBjaGFyICp0eXBlKQp7CiAgICBjaGFyICAgICAgICAgICAgZmlsZVs1MTJdOwogICAgc3RydWN0IHN0YXQgICAgIHN0YXRidWY7CiAgICBpbnQgICAgICAgICAgICAgajsKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ET05UX1BFUlNJU1RfU1RBVEUpCiAgICAgfHwgbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ESVNBQkxFX1BFUlNJU1RFTlRfU0FWRSkpIHJldHVybjsKCiAgICBERUJVR01TR1RMKCgic25tcF9jbGVhbl9wZXJzaXN0ZW50IiwgImNsZWFuaW5nICVzIGZpbGVzLi4uXG4iLCB0eXBlKSk7CiAgICBzbnByaW50ZihmaWxlLCBzaXplb2YoZmlsZSksCiAgICAgICAgICAgICAiJXMvJXMuY29uZiIsIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpLCB0eXBlKTsKICAgIGZpbGVbIHNpemVvZihmaWxlKS0xIF0gPSAwOwogICAgaWYgKHN0YXQoZmlsZSwgJnN0YXRidWYpID09IDApIHsKICAgICAgICBmb3IgKGogPSAwOyBqIDw9IE5FVFNOTVBfTUFYX1BFUlNJU1RFTlRfQkFDS1VQUzsgaisrKSB7CiAgICAgICAgICAgIHNucHJpbnRmKGZpbGUsIHNpemVvZihmaWxlKSwKICAgICAgICAgICAgICAgICAgICAgIiVzLyVzLiVkLmNvbmYiLCBnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSwgdHlwZSwgaik7CiAgICAgICAgICAgIGZpbGVbIHNpemVvZihmaWxlKS0xIF0gPSAwOwogICAgICAgICAgICBpZiAoc3RhdChmaWxlLCAmc3RhdGJ1ZikgPT0gMCkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfY2xlYW5fcGVyc2lzdGVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHJlbW92aW5nIG9sZCBjb25maWcgZmlsZTogJXNcbiIsIGZpbGUpKTsKICAgICAgICAgICAgICAgIGlmICh1bmxpbmsoZmlsZSkgPT0gLTEpCiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkNhbm5vdCB1bmxpbmsgJXNcbiIsIGZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgoKCgovKgogKiBjb25maWdfcGVycm9yOiBwcmludHMgYSB3YXJuaW5nIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggYSBmaWxlIGFuZAogKiBsaW5lIG51bWJlciBvZiBhIC5jb25mIGZpbGUgYW5kIGluY3JlbWVudHMgdGhlIGVycm9yIGNvdW50LiAKICovCnZvaWQKY29uZmlnX3BlcnJvcihjb25zdCBjaGFyICpzdHIpCnsKICAgIHNubXBfbG9nKExPR19FUlIsICIlczogbGluZSAlZDogRXJyb3I6ICVzXG4iLCBjdXJmaWxlbmFtZSwgbGluZWNvdW50LAogICAgICAgICAgICAgc3RyKTsKICAgIGNvbmZpZ19lcnJvcnMrKzsKfQoKdm9pZApjb25maWdfcHdhcm4oY29uc3QgY2hhciAqc3RyKQp7CiAgICBzbm1wX2xvZyhMT0dfV0FSTklORywgIiVzOiBsaW5lICVkOiBXYXJuaW5nOiAlc1xuIiwgY3VyZmlsZW5hbWUsCiAgICAgICAgICAgICBsaW5lY291bnQsIHN0cik7Cn0KCi8qCiAqIHNraXAgYWxsIHdoaXRlIHNwYWNlcyBhbmQgcmV0dXJuIDEgaWYgZm91bmQgc29tZXRoaW5nIGVpdGhlciBlbmQgb2YKICogbGluZSBvciBhIGNvbW1lbnQgY2hhcmFjdGVyIAogKi8KY2hhciAgICAgICAgICAgKgpza2lwX3doaXRlKGNoYXIgKnB0cikKewogICAgaWYgKHB0ciA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB3aGlsZSAoKnB0ciAhPSAwICYmIGlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKnB0cikpCiAgICAgICAgcHRyKys7CiAgICBpZiAoKnB0ciA9PSAwIHx8ICpwdHIgPT0gJyMnKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXR1cm4gKHB0cik7Cn0KCmNoYXIgICAgICAgICAgICoKc2tpcF9ub3Rfd2hpdGUoY2hhciAqcHRyKQp7CiAgICBpZiAocHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHdoaWxlICgqcHRyICE9IDAgJiYgIWlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKnB0cikpCiAgICAgICAgcHRyKys7CiAgICBpZiAoKnB0ciA9PSAwIHx8ICpwdHIgPT0gJyMnKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXR1cm4gKHB0cik7Cn0KCmNoYXIgICAgICAgICAgICoKc2tpcF90b2tlbihjaGFyICpwdHIpCnsKICAgIHB0ciA9IHNraXBfd2hpdGUocHRyKTsKICAgIHB0ciA9IHNraXBfbm90X3doaXRlKHB0cik7CiAgICBwdHIgPSBza2lwX3doaXRlKHB0cik7CiAgICByZXR1cm4gKHB0cik7Cn0KCi8qCiAqIGNvcHlfd29yZAogKiBjb3BpZXMgdGhlIG5leHQgJ3Rva2VuJyBmcm9tICdmcm9tJyBpbnRvICd0bycsIG1heGltdW0gbGVuLTEgY2hhcmFjdGVycy4KICogY3VycmVudGx5IGEgdG9rZW4gaXMgYW55dGhpbmcgc2VwZXJhdGUgYnkgd2hpdGUgc3BhY2UKICogb3Igd2l0aGluIHF1b3RlcyAoZG91YmxlIG9yIHNpbmdsZSkgKGkuZS4gInRoZSByZWQgcm9zZSIgCiAqIGlzIG9uZSB0b2tlbiwgXCJ0aGUgcmVkIHJvc2VcIiBpcyB0aHJlZSB0b2tlbnMpCiAqIGEgJ1wnIGNoYXJhY3RlciB3aWxsIGFsbG93IGEgcXVvdGUgY2hhcmFjdGVyIHRvIGJlIHRyZWF0ZWQKICogYXMgYSByZWd1bGFyIGNoYXJhY3RlciAKICogSXQgcmV0dXJucyBhIHBvaW50ZXIgdG8gZmlyc3Qgbm9uLXdoaXRlIHNwYWNlIGFmdGVyIHRoZSBlbmQgb2YgdGhlIHRva2VuCiAqIGJlaW5nIGNvcGllZCBvciB0byAwIGlmIHdlIHJlYWNoIHRoZSBlbmQuCiAqIE5vdGU6IFBhcnRpYWxseSBjb3BpZWQgd29yZHMgKGdyZWF0ZXIgdGhhbiBsZW4pIHN0aWxsIHJldHVybnMgYSAhTlVMTCBwdHIKICogTm90ZTogcGFydGlhbGx5IGNvcGllZCB3b3JkcyBhcmUsIGhvd2V2ZXIsIG51bGwgdGVybWluYXRlZC4KICovCgpjaGFyICAgICAgICAgICAqCmNvcHlfbndvcmQoY2hhciAqZnJvbSwgY2hhciAqdG8sIGludCBsZW4pCnsKICAgIGNoYXIgICAgICAgICAgICBxdW90ZTsKICAgIGlmICghZnJvbSB8fCAhdG8pCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBpZiAoKCpmcm9tID09ICdcIicpIHx8ICgqZnJvbSA9PSAnXCcnKSkgewogICAgICAgIHF1b3RlID0gKihmcm9tKyspOwogICAgICAgIHdoaWxlICgoKmZyb20gIT0gcXVvdGUpICYmICgqZnJvbSAhPSAwKSkgewogICAgICAgICAgICBpZiAoKCpmcm9tID09ICdcXCcpICYmICgqKGZyb20gKyAxKSAhPSAwKSkgewogICAgICAgICAgICAgICAgaWYgKGxlbiA+IDApIHsgIC8qIGRvbid0IGNvcHkgYmV5b25kIGxlbiBieXRlcyAqLwogICAgICAgICAgICAgICAgICAgICp0bysrID0gKihmcm9tICsgMSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKC0tbGVuID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICoodG8gLSAxKSA9ICdcMCc7ICAgICAgIC8qIG51bGwgcHJvdGVjdCB0aGUgbGFzdCBzcG90ICovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmcm9tID0gZnJvbSArIDI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAobGVuID4gMCkgeyAgLyogZG9uJ3QgY29weSBiZXlvbmQgbGVuIGJ5dGVzICovCiAgICAgICAgICAgICAgICAgICAgKnRvKysgPSAqZnJvbSsrOwogICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbiA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAqKHRvIC0gMSkgPSAnXDAnOyAgICAgICAvKiBudWxsIHByb3RlY3QgdGhlIGxhc3Qgc3BvdCAqLwogICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgZnJvbSsrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgqZnJvbSA9PSAwKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19jb3B5X3dvcmQiLAogICAgICAgICAgICAgICAgICAgICAgICAibm8gZW5kIHF1b3RlIGZvdW5kIGluIGNvbmZpZyBzdHJpbmdcbiIpKTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgZnJvbSsrOwogICAgfSBlbHNlIHsKICAgICAgICB3aGlsZSAoKmZyb20gIT0gMCAmJiAhaXNzcGFjZSgqZnJvbSkpIHsKICAgICAgICAgICAgaWYgKCgqZnJvbSA9PSAnXFwnKSAmJiAoKihmcm9tICsgMSkgIT0gMCkpIHsKICAgICAgICAgICAgICAgIGlmIChsZW4gPiAwKSB7ICAvKiBkb24ndCBjb3B5IGJleW9uZCBsZW4gYnl0ZXMgKi8KICAgICAgICAgICAgICAgICAgICAqdG8rKyA9ICooZnJvbSArIDEpOwogICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbiA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAqKHRvIC0gMSkgPSAnXDAnOyAgICAgICAvKiBudWxsIHByb3RlY3QgdGhlIGxhc3Qgc3BvdCAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnJvbSA9IGZyb20gKyAyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGxlbiA+IDApIHsgIC8qIGRvbid0IGNvcHkgYmV5b25kIGxlbiBieXRlcyAqLwogICAgICAgICAgICAgICAgICAgICp0bysrID0gKmZyb20rKzsKICAgICAgICAgICAgICAgICAgICBpZiAoLS1sZW4gPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgKih0byAtIDEpID0gJ1wwJzsgICAgICAgLyogbnVsbCBwcm90ZWN0IHRoZSBsYXN0IHNwb3QgKi8KICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgIGZyb20rKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGlmIChsZW4gPiAwKQogICAgICAgICp0byA9IDA7CiAgICBmcm9tID0gc2tpcF93aGl0ZShmcm9tKTsKICAgIHJldHVybiAoZnJvbSk7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY29weV93b3JkICovCgovKgogKiBjb3B5X3dvcmQKICogY29waWVzIHRoZSBuZXh0ICd0b2tlbicgZnJvbSAnZnJvbScgaW50byAndG8nLgogKiBjdXJyZW50bHkgYSB0b2tlbiBpcyBhbnl0aGluZyBzZXBlcmF0ZSBieSB3aGl0ZSBzcGFjZQogKiBvciB3aXRoaW4gcXVvdGVzIChkb3VibGUgb3Igc2luZ2xlKSAoaS5lLiAidGhlIHJlZCByb3NlIiAKICogaXMgb25lIHRva2VuLCBcInRoZSByZWQgcm9zZVwiIGlzIHRocmVlIHRva2VucykKICogYSAnXCcgY2hhcmFjdGVyIHdpbGwgYWxsb3cgYSBxdW90ZSBjaGFyYWN0ZXIgdG8gYmUgdHJlYXRlZAogKiBhcyBhIHJlZ3VsYXIgY2hhcmFjdGVyIAogKiBJdCByZXR1cm5zIGEgcG9pbnRlciB0byBmaXJzdCBub24td2hpdGUgc3BhY2UgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgdG9rZW4KICogYmVpbmcgY29waWVkIG9yIHRvIDAgaWYgd2UgcmVhY2ggdGhlIGVuZC4KICovCgpzdGF0aWMgaW50ICAgICAgaGF2ZV93YXJuZWQgPSAwOwpjaGFyICAgICAgICAgICAqCmNvcHlfd29yZChjaGFyICpmcm9tLCBjaGFyICp0bykKewogICAgaWYgKCFoYXZlX3dhcm5lZCkgewogICAgICAgIHNubXBfbG9nKExPR19JTkZPLAogICAgICAgICAgICAgICAgICJjb3B5X3dvcmQoKSBjYWxsZWQuICBVc2UgY29weV9ud29yZCgpIGluc3RlYWQuXG4iKTsKICAgICAgICBoYXZlX3dhcm5lZCA9IDE7CiAgICB9CiAgICByZXR1cm4gY29weV9ud29yZChmcm9tLCB0bywgU1BSSU5UX01BWF9MRU4pOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNvcHlfd29yZCAqLwoKLyoqCiAqIFN0b3JlcyBhbiBxdW90ZWQgdmVyc2lvbiBvZiB0aGUgZmlyc3QgbGVuIGJ5dGVzIGZyb20gc3RyIGludG8gc2F2ZXRvLgogKgogKiBJZiBhbGwgb2N0ZXRzIGluIHN0ciBhcmUgaW4gdGhlIHNldCBbWzphbG51bTpdIF0gdGhlbiB0aGUgcXVvdGF0aW9uCiAqIGlzIHRvIGVuY2xvc2UgdGhlIHN0cmluZyBpbiBxdW90YXRpb24gbWFya3MgKCJzdHIiKSBvdGhlcndpc2UgdGhlCiAqIHF1b3RhdGlvbiBpcyB0byBwcmVwZW5kIHRoZSBzdHJpbmcgMHggYW5kIHRoZW4gYWRkIHRoZSBoZXggcmVwcmVzZW50YXRpb24KICogb2YgYWxsIGNoYXJhY3RlcnMgZnJvbSBzdHIgKDB4NzM3NDcyKQogKgogKiBAcGFyYW1baW5dIHNhdmV0byBwb2ludGVyIHRvIG91dHB1dCBzdHJlYW0sIGlzIGFzc3VtZWQgdG8gYmUgYmlnIGVub3VnaC4KICogQHBhcmFtW2luXSBzdHIgcG9pbnRlciBvZiB0aGUgZGF0YSB0aGF0IGlzIHRvIGJlIHN0b3JlZC4KICogQHBhcmFtW2luXSBsZW4gbGVuZ3RoIG9mIHRoZSBkYXRhIHRoYXQgaXMgdG8gYmUgc3RvcmVkLgogKiBAcmV0dXJuIEEgcG9pbnRlciB0byBzYXZldG8gYWZ0ZXIgc3RyIGlzIGFkZGVkIHRvIGl0LgogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZyhjaGFyICpzYXZldG8sIGNvbnN0IHVfY2hhciAqIHN0ciwgc2l6ZV90IGxlbikKewogICAgc2l6ZV90ICAgICAgICAgIGk7CiAgICBjb25zdCB1X2NoYXIgICAqY3A7CgogICAgLyoKICAgICAqIGlzIGV2ZXJ5dGhpbmcgZWFzaWx5IHByaW50YWJsZQogICAgICovCiAgICBmb3IgKGkgPSAwLCBjcCA9IHN0cjsgaSA8IGxlbiAmJiBjcCAmJgogICAgICAgICAoaXNhbHBoYSgqY3ApIHx8IGlzZGlnaXQoKmNwKSB8fCAqY3AgPT0gJyAnKTsgY3ArKywgaSsrKTsKCiAgICBpZiAobGVuICE9IDAgJiYgaSA9PSBsZW4pIHsKICAgICAgICAqc2F2ZXRvKysgPSAnIic7CiAgICAgICAgbWVtY3B5KHNhdmV0bywgc3RyLCBsZW4pOwogICAgICAgIHNhdmV0byArPSBsZW47CiAgICAgICAgKnNhdmV0bysrID0gJyInOwogICAgICAgICpzYXZldG8gPSAnXDAnOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RyICE9IE5VTEwpIHsKICAgICAgICAgICAgc3ByaW50ZihzYXZldG8sICIweCIpOwogICAgICAgICAgICBzYXZldG8gKz0gMjsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgICAgICAgICBzcHJpbnRmKHNhdmV0bywgIiUwMngiLCBzdHJbaV0pOwogICAgICAgICAgICAgICAgc2F2ZXRvID0gc2F2ZXRvICsgMjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNwcmludGYoc2F2ZXRvLCAiXCJcIiIpOwogICAgICAgICAgICBzYXZldG8gKz0gMjsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gc2F2ZXRvOwp9CgovKgogKiByZWFkX2NvbmZpZ19yZWFkX29jdGV0X3N0cmluZygpOiByZWFkcyBhbiBvY3RldCBzdHJpbmcgdGhhdCB3YXMKICogc2F2ZWQgYnkgdGhlIHJlYWRfY29uZmlnX3NhdmVfb2N0ZXRfc3RyaW5nKCkgZnVuY3Rpb24gCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKGNoYXIgKnJlYWRmcm9tLCB1X2NoYXIgKiogc3RyLCBzaXplX3QgKiBsZW4pCnsKICAgIHVfY2hhciAgICAgICAgICpjcHRyID0gTlVMTDsKICAgIGNoYXIgICAgICAgICAgICpjcHRyMTsKICAgIHVfaW50ICAgICAgICAgICB0bXA7CiAgICBpbnQgICAgICAgICAgICAgaTsKICAgIHNpemVfdCAgICAgICAgICBpbGVuOwoKICAgIGlmIChyZWFkZnJvbSA9PSBOVUxMIHx8IHN0ciA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmIChzdHJuY2FzZWNtcChyZWFkZnJvbSwgIjB4IiwgMikgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogQSBoZXggc3RyaW5nIHN1Ym1pdHRlZC4gSG93IGxvbmc/IAogICAgICAgICAqLwogICAgICAgIHJlYWRmcm9tICs9IDI7CiAgICAgICAgY3B0cjEgPSBza2lwX25vdF93aGl0ZShyZWFkZnJvbSk7CiAgICAgICAgaWYgKGNwdHIxKQogICAgICAgICAgICBpbGVuID0gKGNwdHIxIC0gcmVhZGZyb20pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgaWxlbiA9IHN0cmxlbihyZWFkZnJvbSk7CgogICAgICAgIGlmIChpbGVuICUgMikgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywiaW52YWxpZCBoZXggc3RyaW5nOiB3cm9uZyBsZW5ndGhcbiIpOwogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBoZXggc3RyaW5nOiB3cm9uZyBsZW5ndGgiKSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICBpbGVuID0gaWxlbiAvIDI7CgogICAgICAgIC8qCiAgICAgICAgICogbWFsbG9jIGRhdGEgc3BhY2UgaWYgbmVlZGVkICgrMSBmb3IgZ29vZCBtZWFzdXJlKSAKICAgICAgICAgKi8KICAgICAgICBpZiAoKnN0ciA9PSBOVUxMKSB7CiAgICAgICAgICAgIGlmICgoY3B0ciA9ICh1X2NoYXIgKikgbWFsbG9jKGlsZW4gKyAxKSkgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKnN0ciA9IGNwdHI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZG9uJ3QgcmVxdWlyZSBjYWxsZXIgdG8gaGF2ZSArMSBmb3IgZ29vZCBtZWFzdXJlLCBhbmQgCiAgICAgICAgICAgICAqIGJhaWwgaWYgbm90IGVub3VnaCBzcGFjZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChpbGVuID4gKmxlbikgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsImJ1ZmZlciB0b28gc21hbGwgdG8gcmVhZCBvY3RldCBzdHJpbmcgKCVkIDwgJWQpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgKmxlbiwgaWxlbik7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJ1ZmZlciB0b28gc21hbGwgKCVsdSA8ICVsdSkiLCAodW5zaWduZWQgbG9uZykqbGVuLCAodW5zaWduZWQgbG9uZylpbGVuKSk7CiAgICAgICAgICAgICAgICBjcHRyMSA9IHNraXBfbm90X3doaXRlKHJlYWRmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiBza2lwX3doaXRlKGNwdHIxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjcHRyID0gKnN0cjsKICAgICAgICB9CiAgICAgICAgKmxlbiA9IGlsZW47CgogICAgICAgIC8qCiAgICAgICAgICogY29weSB2YWxpZGF0ZWQgZGF0YSAKICAgICAgICAgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgKGludCkgKmxlbjsgaSsrKSB7CiAgICAgICAgICAgIGlmICgxID09IHNzY2FuZihyZWFkZnJvbSwgIiUyeCIsICZ0bXApKQogICAgICAgICAgICAgICAgKmNwdHIrKyA9ICh1X2NoYXIpIHRtcDsKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogd2UgbWF5IGxvc2UgbWVtb3J5LCBidXQgZG9uJ3Qga25vdyBjYWxsZXIncyBidWZmZXIgWFggZnJlZShjcHRyKTsgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVhZGZyb20gKz0gMjsKICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBvbmx5IG51bGwgdGVybWluYXRlIGlmIHdlIGhhdmUgdGhlIHNwYWNlCiAgICAgICAgICovCiAgICAgICAgaWYgKGlsZW4gPiAqbGVuKSB7CiAgICAgICAgICAgIGlsZW4gPSAqbGVuLTE7CiAgICAgICAgICAgICpjcHRyKysgPSAnXDAnOwogICAgICAgIH0KICAgICAgICByZWFkZnJvbSA9IHNraXBfd2hpdGUocmVhZGZyb20pOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIE5vcm1hbCBzdHJpbmcgCiAgICAgICAgICovCgogICAgICAgIC8qCiAgICAgICAgICogbWFsbG9jIHN0cmluZyBzcGFjZSBpZiBuZWVkZWQgKGluY2x1ZGluZyBOVUxMIHRlcm1pbmF0b3IpIAogICAgICAgICAqLwogICAgICAgIGlmICgqc3RyID09IE5VTEwpIHsKICAgICAgICAgICAgY2hhciAgICAgICAgICAgIGJ1ZltTTk1QX01BWEJVRl07CiAgICAgICAgICAgIHJlYWRmcm9tID0gY29weV9ud29yZChyZWFkZnJvbSwgYnVmLCBzaXplb2YoYnVmKSk7CgogICAgICAgICAgICAqbGVuID0gc3RybGVuKGJ1Zik7CiAgICAgICAgICAgIGlmICgoY3B0ciA9ICh1X2NoYXIgKikgbWFsbG9jKCpsZW4gKyAxKSkgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAqc3RyID0gY3B0cjsKICAgICAgICAgICAgaWYgKGNwdHIpIHsKICAgICAgICAgICAgICAgIG1lbWNweShjcHRyLCBidWYsICpsZW4gKyAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlYWRmcm9tID0gY29weV9ud29yZChyZWFkZnJvbSwgKGNoYXIgKikgKnN0ciwgKmxlbik7CiAgICAgICAgICAgICpsZW4gPSBzdHJsZW4oKGNoYXIgKikgKnN0cik7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiByZWFkZnJvbTsKfQoKCi8qCiAqIHJlYWRfY29uZmlnX3NhdmVfb2JqaWQoKTogc2F2ZXMgYW4gb2JqaWQgYXMgYSBudW1lcmljYWwgc3RyaW5nIAogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19zYXZlX29iamlkKGNoYXIgKnNhdmV0bywgb2lkICogb2JqaWQsIHNpemVfdCBsZW4pCnsKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIGlmIChsZW4gPT0gMCkgewogICAgICAgIHN0cmNhdChzYXZldG8sICJOVUxMIik7CiAgICAgICAgc2F2ZXRvICs9IHN0cmxlbihzYXZldG8pOwogICAgICAgIHJldHVybiBzYXZldG87CiAgICB9CgogICAgLyoKICAgICAqIGluIGNhc2UgbGVuPTAsIHRoaXMgbWFrZXMgaXQgZWFzaWVyIHRvIHJlYWQgaXQgYmFjayBpbiAKICAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IChpbnQpIGxlbjsgaSsrKSB7CiAgICAgICAgc3ByaW50ZihzYXZldG8sICIuJWxkIiwgb2JqaWRbaV0pOwogICAgICAgIHNhdmV0byArPSBzdHJsZW4oc2F2ZXRvKTsKICAgIH0KICAgIHJldHVybiBzYXZldG87Cn0KCi8qCiAqIHJlYWRfY29uZmlnX3JlYWRfb2JqaWQoKTogcmVhZHMgYW4gb2JqaWQgZnJvbSBhIGZvcm1hdCBzYXZlZCBieSB0aGUgYWJvdmUgCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3JlYWRfb2JqaWQoY2hhciAqcmVhZGZyb20sIG9pZCAqKiBvYmppZCwgc2l6ZV90ICogbGVuKQp7CgogICAgaWYgKG9iamlkID09IE5VTEwgfHwgcmVhZGZyb20gPT0gTlVMTCB8fCBsZW4gPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBpZiAoKm9iamlkID09IE5VTEwpIHsKICAgICAgICAqbGVuID0gMDsKICAgICAgICBpZiAoKCpvYmppZCA9IChvaWQgKikgbWFsbG9jKE1BWF9PSURfTEVOICogc2l6ZW9mKG9pZCkpKSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAqbGVuID0gTUFYX09JRF9MRU47CiAgICB9CgogICAgaWYgKHN0cm5jbXAocmVhZGZyb20sICJOVUxMIiwgNCkgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogbnVsbCBsZW5ndGggb2lkIAogICAgICAgICAqLwogICAgICAgICpsZW4gPSAwOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIHF1YWxpZnkgdGhlIHN0cmluZyBmb3IgcmVhZF9vYmppZCAKICAgICAgICAgKi8KICAgICAgICBjaGFyICAgICAgICAgICAgYnVmW1NQUklOVF9NQVhfTEVOXTsKICAgICAgICBjb3B5X253b3JkKHJlYWRmcm9tLCBidWYsIHNpemVvZihidWYpKTsKCiAgICAgICAgaWYgKCFyZWFkX29iamlkKGJ1ZiwgKm9iamlkLCBsZW4pKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19yZWFkX29iamlkIiwgIkludmFsaWQgT0lEIikpOwogICAgICAgICAgICAqbGVuID0gMDsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIHJlYWRmcm9tID0gc2tpcF90b2tlbihyZWFkZnJvbSk7CiAgICByZXR1cm4gcmVhZGZyb207Cn0KCi8qKgogKiByZWFkX2NvbmZpZ19yZWFkX2RhdGEgcmVhZHMgZGF0YSBvZiBhIGdpdmVuIHR5cGUgZnJvbSBhIHRva2VuKHMpIG9uIGEKICogY29uZmlndXJhdGlvbiBsaW5lLiAgVGhlIHN1cHBvcnRlZCB0eXBlcyBhcmU6CiAqCiAqICAgIC0gQVNOX0lOVEVHRVIKICogICAgLSBBU05fVElNRVRJQ0tTCiAqICAgIC0gQVNOX1VOU0lHTkVECiAqICAgIC0gQVNOX09DVEVUX1NUUgogKiAgICAtIEFTTl9CSVRfU1RSCiAqICAgIC0gQVNOX09CSkVDVF9JRAogKgogKiBAcGFyYW0gdHlwZSB0aGUgYXNuIGRhdGEgdHlwZSB0byBiZSByZWFkIGluLgogKgogKiBAcGFyYW0gcmVhZGZyb20gdGhlIGNvbmZpZ3VyYXRpb24gbGluZSBkYXRhIHRvIGJlIHJlYWQuCiAqCiAqIEBwYXJhbSBkYXRhcHRyIGFuIGFsbG9jYXRlZCBwb2ludGVyIGV4cGVjdGVkIHRvIG1hdGNoIHRoZSB0eXBlIGJlaW5nIHJlYWQKICogICAgICAgIChpbnQgKiwgdV9pbnQgKiwgY2hhciAqKiwgb2lkICoqKQogKgogKiBAcGFyYW0gbGVuIGlzIHRoZSBsZW5ndGggb2YgYW4gYXNuIG9pZCBvciBvY3RldC9iaXQgc3RyaW5nLCBub3QgcmVxdWlyZWQKICogICAgICAgICAgICBmb3IgdGhlIGFzbiBpbnRlZ2VyLCB1bnNpZ25lZCBpbnRlZ2VyLCBhbmQgdGltZXRpY2tzIHR5cGVzCiAqCiAqIEByZXR1cm4gdGhlIG5leHQgdG9rZW4gaW4gdGhlIGNvbmZpZ3VyYXRpb24gbGluZS4gIE5VTEwgaWYgbm9uZSBsZWZ0IG9yCiAqIGlmIGFuIHVua25vd24gdHlwZS4KICogCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3JlYWRfZGF0YShpbnQgdHlwZSwgY2hhciAqcmVhZGZyb20sIHZvaWQgKmRhdGFwdHIsCiAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiBsZW4pCnsKICAgIGludCAgICAgICAgICAgICppbnRwOwogICAgY2hhciAgICAgICAgICAqKmNoYXJwcDsKICAgIG9pZCAgICAgICAgICAgKipvaWRwcDsKICAgIHVuc2lnbmVkIGludCAgICp1aW50cDsKCiAgICBpZiAoZGF0YXB0ciAmJiByZWFkZnJvbSkKICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIEFTTl9JTlRFR0VSOgogICAgICAgICAgICBpbnRwID0gKGludCAqKSBkYXRhcHRyOwogICAgICAgICAgICAqaW50cCA9IGF0b2kocmVhZGZyb20pOwogICAgICAgICAgICByZWFkZnJvbSA9IHNraXBfdG9rZW4ocmVhZGZyb20pOwogICAgICAgICAgICByZXR1cm4gcmVhZGZyb207CgogICAgICAgIGNhc2UgQVNOX1RJTUVUSUNLUzoKICAgICAgICBjYXNlIEFTTl9VTlNJR05FRDoKICAgICAgICAgICAgdWludHAgPSAodW5zaWduZWQgaW50ICopIGRhdGFwdHI7CiAgICAgICAgICAgICp1aW50cCA9IHN0cnRvdWwocmVhZGZyb20sIE5VTEwsIDApOwogICAgICAgICAgICByZWFkZnJvbSA9IHNraXBfdG9rZW4ocmVhZGZyb20pOwogICAgICAgICAgICByZXR1cm4gcmVhZGZyb207CgogICAgICAgIGNhc2UgQVNOX0lQQUREUkVTUzoKICAgICAgICAgICAgaW50cCA9IChpbnQgKikgZGF0YXB0cjsKICAgICAgICAgICAgKmludHAgPSBpbmV0X2FkZHIocmVhZGZyb20pOwogICAgICAgICAgICBpZiAoKCppbnRwID09IC0xKSAmJgogICAgICAgICAgICAgICAgKHN0cm5jbXAocmVhZGZyb20sICIyNTUuMjU1LjI1NS4yNTUiLCAxNSkgIT0gMCkpCiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgcmVhZGZyb20gPSBza2lwX3Rva2VuKHJlYWRmcm9tKTsKICAgICAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwoKICAgICAgICBjYXNlIEFTTl9PQ1RFVF9TVFI6CiAgICAgICAgY2FzZSBBU05fQklUX1NUUjoKICAgICAgICAgICAgY2hhcnBwID0gKGNoYXIgKiopIGRhdGFwdHI7CiAgICAgICAgICAgIHJldHVybiByZWFkX2NvbmZpZ19yZWFkX29jdGV0X3N0cmluZyhyZWFkZnJvbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKiopIGNoYXJwcCwgbGVuKTsKCiAgICAgICAgY2FzZSBBU05fT0JKRUNUX0lEOgogICAgICAgICAgICBvaWRwcCA9IChvaWQgKiopIGRhdGFwdHI7CiAgICAgICAgICAgIHJldHVybiByZWFkX2NvbmZpZ19yZWFkX29iamlkKHJlYWRmcm9tLCBvaWRwcCwgbGVuKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnX3JlYWRfZGF0YSIsICJGYWlsOiBVbmtub3duIHR5cGU6ICVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSkpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoKICogcmVhZF9jb25maWdfcmVhZF9tZW1vcnkoKToKICogCiAqIHNpbWlsYXIgdG8gcmVhZF9jb25maWdfcmVhZF9kYXRhLCBidXQgZXhwZWN0cyBhIGdlbmVyaWMgbWVtb3J5CiAqIHBvaW50ZXIgcmF0aGVyIHRoYW4gYSBzcGVjaWZpYyB0eXBlIG9mIHBvaW50ZXIuICBMZW4gaXMgZXhwZWN0ZWQgdG8KICogYmUgdGhlIGFtb3VudCBvZiBhdmFpbGFibGUgbWVtb3J5LgogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19yZWFkX21lbW9yeShpbnQgdHlwZSwgY2hhciAqcmVhZGZyb20sCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKmRhdGFwdHIsIHNpemVfdCAqIGxlbikKewogICAgaW50ICAgICAgICAgICAgKmludHA7CiAgICB1bnNpZ25lZCBpbnQgICAqdWludHA7CiAgICBjaGFyICAgICAgICAgICAgYnVmW1NQUklOVF9NQVhfTEVOXTsKCiAgICBpZiAoIWRhdGFwdHIgfHwgIXJlYWRmcm9tKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHN3aXRjaCAodHlwZSkgewogICAgY2FzZSBBU05fSU5URUdFUjoKICAgICAgICBpZiAoKmxlbiA8IHNpemVvZihpbnQpKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICBpbnRwID0gKGludCAqKSBkYXRhcHRyOwogICAgICAgIHJlYWRmcm9tID0gY29weV9ud29yZChyZWFkZnJvbSwgYnVmLCBzaXplb2YoYnVmKSk7CiAgICAgICAgKmludHAgPSBhdG9pKGJ1Zik7CiAgICAgICAgKmxlbiA9IHNpemVvZihpbnQpOwogICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICBjYXNlIEFTTl9DT1VOVEVSOgogICAgY2FzZSBBU05fVElNRVRJQ0tTOgogICAgY2FzZSBBU05fVU5TSUdORUQ6CiAgICAgICAgaWYgKCpsZW4gPCBzaXplb2YodW5zaWduZWQgaW50KSkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgdWludHAgPSAodW5zaWduZWQgaW50ICopIGRhdGFwdHI7CiAgICAgICAgcmVhZGZyb20gPSBjb3B5X253b3JkKHJlYWRmcm9tLCBidWYsIHNpemVvZihidWYpKTsKICAgICAgICAqdWludHAgPSBzdHJ0b3VsKGJ1ZiwgTlVMTCwgMCk7CiAgICAgICAgKmxlbiA9IHNpemVvZih1bnNpZ25lZCBpbnQpOwogICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICBjYXNlIEFTTl9JUEFERFJFU1M6CiAgICAgICAgaWYgKCpsZW4gPCBzaXplb2YoaW50KSkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgaW50cCA9IChpbnQgKikgZGF0YXB0cjsKICAgICAgICByZWFkZnJvbSA9IGNvcHlfbndvcmQocmVhZGZyb20sIGJ1Ziwgc2l6ZW9mKGJ1ZikpOwogICAgICAgICppbnRwID0gaW5ldF9hZGRyKGJ1Zik7CiAgICAgICAgaWYgKCgqaW50cCA9PSAtMSkgJiYgKHN0cmNtcChidWYsICIyNTUuMjU1LjI1NS4yNTUiKSAhPSAwKSkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgKmxlbiA9IHNpemVvZihpbnQpOwogICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICBjYXNlIEFTTl9PQ1RFVF9TVFI6CiAgICBjYXNlIEFTTl9CSVRfU1RSOgogICAgY2FzZSBBU05fUFJJVl9JTVBMSUVEX09DVEVUX1NUUjoKICAgICAgICByZXR1cm4gcmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmcocmVhZGZyb20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKiopICYgZGF0YXB0ciwgbGVuKTsKCiAgICBjYXNlIEFTTl9QUklWX0lNUExJRURfT0JKRUNUX0lEOgogICAgY2FzZSBBU05fT0JKRUNUX0lEOgogICAgICAgIHJlYWRmcm9tID0KICAgICAgICAgICAgcmVhZF9jb25maWdfcmVhZF9vYmppZChyZWFkZnJvbSwgKG9pZCAqKikgJiBkYXRhcHRyLCBsZW4pOwogICAgICAgICpsZW4gKj0gc2l6ZW9mKG9pZCk7CiAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwoKICAgIGNhc2UgQVNOX0NPVU5URVI2NDoKICAgIHsKICAgICAgICBpZiAoKmxlbiA8IHNpemVvZihVNjQpKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAqbGVuID0gc2l6ZW9mKFU2NCk7CiAgICAgICAgcmVhZDY0KChVNjQgKikgZGF0YXB0ciwgcmVhZGZyb20pOwogICAgICAgIHJlYWRmcm9tID0gc2tpcF90b2tlbihyZWFkZnJvbSk7CiAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwogICAgfQoKICAgIGRlZmF1bHQ6CiAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnX3JlYWRfbWVtb3J5IiwgIkZhaWw6IFVua25vd24gdHlwZTogJWQiLAogICAgICAgICAgICAgICAgICAgIHR5cGUpKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKioKICogcmVhZF9jb25maWdfc3RvcmVfZGF0YSBzdG9yZXMgZGF0YSBvZiBhIGdpdmVuIHR5cGUgdG8gYSBjb25maWd1cmF0aW9uIGxpbmUKICogaW50byB0aGUgc3RvcmV0byBidWZmZXIuCiAqIENhbGxzIHJlYWRfY29uZmlnX3N0b3JlX2RhdGFfcHJlZml4IHdpdGggdGhlIHByZWZpeCBwYXJhbWV0ZXIgc2V0IHRvIGEgY2hhcgogKiBzcGFjZS4gIFRoZSBzdXBwb3J0ZWQgdHlwZXMgYXJlOgogKgogKiAgICAtIEFTTl9JTlRFR0VSCiAqICAgIC0gQVNOX1RJTUVUSUNLUwogKiAgICAtIEFTTl9VTlNJR05FRAogKiAgICAtIEFTTl9PQ1RFVF9TVFIKICogICAgLSBBU05fQklUX1NUUgogKiAgICAtIEFTTl9PQkpFQ1RfSUQKICoKICogQHBhcmFtIHR5cGUgICAgdGhlIGFzbiBkYXRhIHR5cGUgdG8gYmUgc3RvcmVkCiAqCiAqIEBwYXJhbSBzdG9yZXRvIGEgcHJlLWFsbG9jYXRlZCBjaGFyIGJ1ZmZlciB3aGljaCB3aWxsIGNvbnRhaW4gdGhlIGRhdGEKICogICAgICAgICAgICAgICAgdG8gYmUgc3RvcmVkCiAqCiAqIEBwYXJhbSBkYXRhcHRyIGNvbnRhaW5zIHRoZSB2YWx1ZSB0byBiZSBzdG9yZWQsIHRoZSBzdXBwb3J0ZWQgcG9pbnRlcnM6CiAqICAgICAgICAgICAgICAgIChpbnQgKiwgdV9pbnQgKiwgY2hhciAqKiwgb2lkICoqKQogKgogKiBAcGFyYW0gbGVuICAgICBpcyB0aGUgbGVuZ3RoIG9mIHRoZSB2YWx1ZSB0byBiZSBzdG9yZWQKICogICAgICAgICAgICAgICAgKG5vdCByZXF1aXJlZCBmb3IgdGhlIGFzbiBpbnRlZ2VyLCB1bnNpZ25lZCBpbnRlZ2VyLAogKiAgICAgICAgICAgICAgICAgYW5kIHRpbWV0aWNrcyB0eXBlcykKICoKICogQHJldHVybiBjaGFyYWN0ZXIgcG9pbnRlciB0byB0aGUgZW5kIG9mIHRoZSBsaW5lLiBOVUxMIGlmIGFuIHVua25vd24gdHlwZS4KICovCmNoYXIgICAgICAgICAgICoKcmVhZF9jb25maWdfc3RvcmVfZGF0YShpbnQgdHlwZSwgY2hhciAqc3RvcmV0bywgdm9pZCAqZGF0YXB0ciwgc2l6ZV90ICogbGVuKQp7CiAgICByZXR1cm4gcmVhZF9jb25maWdfc3RvcmVfZGF0YV9wcmVmaXgoJyAnLCB0eXBlLCBzdG9yZXRvLCBkYXRhcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGVuID8gKmxlbiA6IDApKTsKfQoKY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19zdG9yZV9kYXRhX3ByZWZpeChjaGFyIHByZWZpeCwgaW50IHR5cGUsIGNoYXIgKnN0b3JldG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmRhdGFwdHIsIHNpemVfdCBsZW4pCnsKICAgIGludCAgICAgICAgICAgICppbnRwOwogICAgdV9jaGFyICAgICAgICAqKmNoYXJwcDsKICAgIHVuc2lnbmVkIGludCAgICp1aW50cDsKICAgIHN0cnVjdCBpbl9hZGRyICBpbjsKICAgIG9pZCAgICAgICAgICAgKipvaWRwcDsKCiAgICBpZiAoZGF0YXB0ciAmJiBzdG9yZXRvKQogICAgICAgIHN3aXRjaCAodHlwZSkgewogICAgICAgIGNhc2UgQVNOX0lOVEVHRVI6CiAgICAgICAgICAgIGludHAgPSAoaW50ICopIGRhdGFwdHI7CiAgICAgICAgICAgIHNwcmludGYoc3RvcmV0bywgIiVjJWQiLCBwcmVmaXgsICppbnRwKTsKICAgICAgICAgICAgcmV0dXJuIChzdG9yZXRvICsgc3RybGVuKHN0b3JldG8pKTsKCiAgICAgICAgY2FzZSBBU05fVElNRVRJQ0tTOgogICAgICAgIGNhc2UgQVNOX1VOU0lHTkVEOgogICAgICAgICAgICB1aW50cCA9ICh1bnNpZ25lZCBpbnQgKikgZGF0YXB0cjsKICAgICAgICAgICAgc3ByaW50ZihzdG9yZXRvLCAiJWMldSIsIHByZWZpeCwgKnVpbnRwKTsKICAgICAgICAgICAgcmV0dXJuIChzdG9yZXRvICsgc3RybGVuKHN0b3JldG8pKTsKCiAgICAgICAgY2FzZSBBU05fSVBBRERSRVNTOgogICAgICAgICAgICBpbi5zX2FkZHIgPSAqKHVuc2lnbmVkIGludCAqKSBkYXRhcHRyOyAKICAgICAgICAgICAgc3ByaW50ZihzdG9yZXRvLCAiJWMlcyIsIHByZWZpeCwgaW5ldF9udG9hKGluKSk7CiAgICAgICAgICAgIHJldHVybiAoc3RvcmV0byArIHN0cmxlbihzdG9yZXRvKSk7CgogICAgICAgIGNhc2UgQVNOX09DVEVUX1NUUjoKICAgICAgICBjYXNlIEFTTl9CSVRfU1RSOgogICAgICAgICAgICAqc3RvcmV0bysrID0gcHJlZml4OwogICAgICAgICAgICBjaGFycHAgPSAodV9jaGFyICoqKSBkYXRhcHRyOwogICAgICAgICAgICByZXR1cm4gcmVhZF9jb25maWdfc2F2ZV9vY3RldF9zdHJpbmcoc3RvcmV0bywgKmNoYXJwcCwgbGVuKTsKCiAgICAgICAgY2FzZSBBU05fT0JKRUNUX0lEOgogICAgICAgICAgICAqc3RvcmV0bysrID0gcHJlZml4OwogICAgICAgICAgICBvaWRwcCA9IChvaWQgKiopIGRhdGFwdHI7CiAgICAgICAgICAgIHJldHVybiByZWFkX2NvbmZpZ19zYXZlX29iamlkKHN0b3JldG8sICpvaWRwcCwgbGVuKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnX3N0b3JlX2RhdGFfcHJlZml4IiwKICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWw6IFVua25vd24gdHlwZTogJWQiLCB0eXBlKSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIHJldHVybiBOVUxMOwp9Ci8qKiBAfSAqLwo=