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+aGVscCk7CiAgICAgICAgU05NUF9GUkVFKCgqbHRtcCktPm5leHQpOwogICAgICAgICgqbHRtcCktPm5leHQgPSBsdG1wMjsKICAgIH0KfQoKdm9pZAp1bnJlZ2lzdGVyX2FwcF9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0b2tlbikKewogICAgdW5yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihOVUxMLCB0b2tlbik7Cn0KCnZvaWQKdW5yZWdpc3Rlcl9hbGxfY29uZmlnX2hhbmRsZXJzKHZvaWQpCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAsICpzYXZlOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpsdG1wOwoKICAgIC8qCiAgICAgKiBLZWVwIHVzaW5nIGNvbmZpZ19maWxlcyB1bnRpbCB0aGVyZSBhcmUgbm8gbW9yZSEgCiAgICAgKi8KICAgIGZvciAoY3RtcCA9IGNvbmZpZ19maWxlczsgY3RtcDspIHsKICAgICAgICBmb3IgKGx0bXAgPSBjdG1wLT5zdGFydDsgbHRtcDsgbHRtcCA9IGN0bXAtPnN0YXJ0KSB7CiAgICAgICAgICAgIHVucmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoY3RtcC0+ZmlsZUhlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsdG1wLT5jb25maWdfdG9rZW4pOwogICAgICAgIH0KICAgICAgICBTTk1QX0ZSRUUoY3RtcC0+ZmlsZUhlYWRlcik7CiAgICAgICAgc2F2ZSA9IGN0bXAtPm5leHQ7CiAgICAgICAgU05NUF9GUkVFKGN0bXApOwogICAgICAgIGN0bXAgPSBzYXZlOwogICAgICAgIGNvbmZpZ19maWxlcyA9IHNhdmU7CiAgICB9Cn0KCiNpZmRlZiBURVNUSU5HCnZvaWQKcHJpbnRfY29uZmlnX2hhbmRsZXJzKHZvaWQpCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAgPSBjb25maWdfZmlsZXM7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmx0bXA7CgogICAgZm9yICg7IGN0bXAgIT0gTlVMTDsgY3RtcCA9IGN0bXAtPm5leHQpIHsKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAicmVhZF9jb25mOiAlc1xuIiwgY3RtcC0+ZmlsZUhlYWRlcikpOwogICAgICAgIGZvciAobHRtcCA9IGN0bXAtPnN0YXJ0OyBsdG1wICE9IE5VTEw7IGx0bXAgPSBsdG1wLT5uZXh0KQogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAiICAgICAgICAgICAgICAgICAgICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBsdG1wLT5jb25maWdfdG9rZW4pKTsKICAgIH0KfQojZW5kaWYKCmludCAgICAgICAgICAgICBsaW5lY291bnQ7CmNvbnN0IGNoYXIgICAgICpjdXJmaWxlbmFtZTsKCnN0cnVjdCBjb25maWdfbGluZSAqCnJlYWRfY29uZmlnX2dldF9oYW5kbGVycyhjb25zdCBjaGFyICp0eXBlKQp7CiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjdG1wID0gY29uZmlnX2ZpbGVzOwogICAgZm9yICg7IGN0bXAgIT0gTlVMTCAmJiBzdHJjbXAoY3RtcC0+ZmlsZUhlYWRlciwgdHlwZSk7CiAgICAgICAgIGN0bXAgPSBjdG1wLT5uZXh0KTsKICAgIGlmIChjdG1wKQogICAgICAgIHJldHVybiBjdG1wLT5zdGFydDsKICAgIHJldHVybiBOVUxMOwp9Cgp2b2lkCnJlYWRfY29uZmlnX3dpdGhfdHlwZV93aGVuKGNvbnN0IGNoYXIgKmZpbGVuYW1lLCBjb25zdCBjaGFyICp0eXBlLCBpbnQgd2hlbikKewogICAgc3RydWN0IGNvbmZpZ19saW5lICpjdG1wID0gcmVhZF9jb25maWdfZ2V0X2hhbmRsZXJzKHR5cGUpOwogICAgaWYgKGN0bXApCiAgICAgICAgcmVhZF9jb25maWcoZmlsZW5hbWUsIGN0bXAsIHdoZW4pOwogICAgZWxzZQogICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsCiAgICAgICAgICAgICAgICAgICAgInJlYWRfY29uZmlnOiBJIGhhdmUgbm8gcmVnaXN0cmF0aW9ucyBmb3IgdHlwZTolcyxmaWxlOiVzXG4iLAogICAgICAgICAgICAgICAgICAgIHR5cGUsIGZpbGVuYW1lKSk7Cn0KCnZvaWQKcmVhZF9jb25maWdfd2l0aF90eXBlKGNvbnN0IGNoYXIgKmZpbGVuYW1lLCBjb25zdCBjaGFyICp0eXBlKQp7CiAgICByZWFkX2NvbmZpZ193aXRoX3R5cGVfd2hlbihmaWxlbmFtZSwgdHlwZSwgRUlUSEVSX0NPTkZJRyk7Cn0KCgpzdHJ1Y3QgY29uZmlnX2xpbmUgKgpyZWFkX2NvbmZpZ19maW5kX2hhbmRsZXIoc3RydWN0IGNvbmZpZ19saW5lICpsaW5lX2hhbmRsZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqdG9rZW4pCnsKICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHB0cjsKCiAgICBmb3IgKGxwdHIgPSBsaW5lX2hhbmRsZXJzOyBscHRyICE9IE5VTEw7IGxwdHIgPSBscHRyLT5uZXh0KSB7CiAgICAgICAgaWYgKCFzdHJjYXNlY21wKHRva2VuLCBscHRyLT5jb25maWdfdG9rZW4pKSB7CiAgICAgICAgICAgIHJldHVybiBscHRyOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgoKLyoKICogc2VhcmNoZXMgYSBjb25maWdfbGluZSBsaW5rZWQgbGlzdCBmb3IgYSBtYXRjaCAKICovCmludApydW5fY29uZmlnX2hhbmRsZXIoc3RydWN0IGNvbmZpZ19saW5lICpscHRyLAogICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIsIGludCB3aGVuKQp7CiAgICBjaGFyICAgICAgICAgICAqY3A7CiAgICBscHRyID0gcmVhZF9jb25maWdfZmluZF9oYW5kbGVyKGxwdHIsIHRva2VuKTsKICAgIGlmIChscHRyICE9IE5VTEwpIHsKICAgICAgICBpZiAod2hlbiA9PSBFSVRIRVJfQ09ORklHIHx8IGxwdHItPmNvbmZpZ190aW1lID09IHdoZW4pIHsKICAgICAgICAgICAgY2hhciB0bXBidWZbMV07CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJGb3VuZCBhIHBhcnNlci4gIENhbGxpbmcgaXQ6ICVzIC8gJXNcbiIsIHRva2VuLAogICAgICAgICAgICAgICAgICAgICAgICBjcHRyKSk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIE1ha2Ugc3VyZSBjcHRyIGlzIG5vbi1udWxsCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIWNwdHIpIHsKICAgICAgICAgICAgICAgIHRtcGJ1ZlswXSA9ICdcMCc7CiAgICAgICAgICAgICAgICBjcHRyID0gdG1wYnVmOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTdG9tcCBvbiBhbnkgdHJhaWxpbmcgd2hpdGVzcGFjZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY3AgPSAmKGNwdHJbc3RybGVuKGNwdHIpLTFdKTsKICAgICAgICAgICAgd2hpbGUgKGlzc3BhY2UoKmNwKSkgewogICAgICAgICAgICAgICAgKihjcC0tKSA9ICdcMCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKCoobHB0ci0+cGFyc2VfbGluZSkpICh0b2tlbiwgY3B0cik7CiAgICAgICAgfQogICAgfSBlbHNlIGlmICh3aGVuICE9IFBSRU1JQl9DT05GSUcgJiYgCgkgICAgICAgIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgICBORVRTTk1QX0RTX0xJQl9OT19UT0tFTl9XQVJOSU5HUykpIHsKCW5ldHNubXBfY29uZmlnX3dhcm4oIlVua25vd24gdG9rZW46ICVzLiIsIHRva2VuKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgovKgogKiB0YWtlbnMgYW4gYXJiaXRyYXJ5IHN0cmluZyBhbmQgdHJpZXMgdG8gaW50ZXByZXQgaXQgYmFzZWQgb24gdGhlCiAqIGtub3duIGNvbmZpZ3VyYXRpb24gaGFuZGxlcnMgZm9yIGFsbCByZWdpc3RlcmVkIHR5cGVzLiAgTWF5IHByb2R1Y2UKICogaW5jb25zaXN0ZW50IHJlc3VsdHMgd2hlbiBtdWx0aXBsZSB0b2tlbnMgb2YgdGhlIHNhbWUgbmFtZSBhcmUKICogcmVnaXN0ZXJlZCB1bmRlciBkaWZmZXJlbnQgZmlsZSB0eXBlcy4gCiAqLwoKLyoKICogd2UgYWxsb3cgPSBkZWxpbWV0ZXJzIGhlcmUgCiAqLwojZGVmaW5lIFNOTVBfQ09ORklHX0RFTElNRVRFUlMgIiBcdD0iCgppbnQKc25tcF9jb25maWdfd2hlbihjaGFyICpsaW5lLCBpbnQgd2hlbikKewogICAgY2hhciAgICAgICAgICAgKmNwdHIsIGJ1ZltTVFJJTkdNQVhdOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpscHRyID0gTlVMTDsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAgPSBjb25maWdfZmlsZXM7CiAgICBjaGFyICAgICAgICAgICAqc3Q7CgogICAgaWYgKGxpbmUgPT0gTlVMTCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoInNubXBfY29uZmlnKCkgY2FsbGVkIHdpdGggYSBudWxsIHN0cmluZy4iKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgc3RybGNweShidWYsIGxpbmUsIFNUUklOR01BWCk7CiAgICBjcHRyID0gc3RydG9rX3IoYnVmLCBTTk1QX0NPTkZJR19ERUxJTUVURVJTLCAmc3QpOwogICAgaWYgKCFjcHRyKSB7CiAgICAgICAgbmV0c25tcF9jb25maWdfd2FybigiV3JvbmcgZm9ybWF0OiAlcyIsIGxpbmUpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KICAgIGlmIChjcHRyWzBdID09ICdbJykgewogICAgICAgIGlmIChjcHRyW3N0cmxlbihjcHRyKSAtIDFdICE9ICddJykgewoJICAgIG5ldHNubXBfY29uZmlnX2Vycm9yKCJubyBtYXRjaGluZyAnXScgZm9yIHR5cGUgJXMuIiwgY3B0ciArIDEpOwogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgfQogICAgICAgIGNwdHJbc3RybGVuKGNwdHIpIC0gMV0gPSAnXDAnOwogICAgICAgIGxwdHIgPSByZWFkX2NvbmZpZ19nZXRfaGFuZGxlcnMoY3B0ciArIDEpOwogICAgICAgIGlmIChscHRyID09IE5VTEwpIHsKCSAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiTm8gaGFuZGxlcnMgcmVnZXN0ZXJlZCBmb3IgdHlwZSAlcy4iLAoJCQkJIGNwdHIgKyAxKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgIH0KICAgICAgICBjcHRyID0gc3RydG9rX3IoTlVMTCwgU05NUF9DT05GSUdfREVMSU1FVEVSUywgJnN0KTsKICAgICAgICBscHRyID0gcmVhZF9jb25maWdfZmluZF9oYW5kbGVyKGxwdHIsIGNwdHIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIHdlIGhhdmUgdG8gZmluZCBhIHRva2VuIAogICAgICAgICAqLwogICAgICAgIGZvciAoOyBjdG1wICE9IE5VTEwgJiYgbHB0ciA9PSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkKICAgICAgICAgICAgbHB0ciA9IHJlYWRfY29uZmlnX2ZpbmRfaGFuZGxlcihjdG1wLT5zdGFydCwgY3B0cik7CiAgICB9CiAgICBpZiAobHB0ciA9PSBOVUxMICYmIG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQkgIE5FVFNOTVBfRFNfTElCX05PX1RPS0VOX1dBUk5JTkdTKSkgewoJbmV0c25tcF9jb25maWdfd2FybigiVW5rbm93biB0b2tlbjogJXMuIiwgY3B0cik7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIC8qCiAgICAgKiB1c2UgdGhlIG9yaWdpbmFsIHN0cmluZyBpbnN0ZWFkIHNpbmNlIHN0cnRva19yIG1lc3NlZCB1cCB0aGUgb3JpZ2luYWwgCiAgICAgKi8KICAgIGxpbmUgPSBza2lwX3doaXRlKGxpbmUgKyAoY3B0ciAtIGJ1ZikgKyBzdHJsZW4oY3B0cikgKyAxKTsKCiAgICByZXR1cm4gKHJ1bl9jb25maWdfaGFuZGxlcihscHRyLCBjcHRyLCBsaW5lLCB3aGVuKSk7Cn0KCmludApuZXRzbm1wX2NvbmZpZyhjaGFyICpsaW5lKQp7CiAgICBpbnQgICAgICAgICAgICAgcmV0ID0gU05NUF9FUlJfTk9FUlJPUjsKICAgIERFQlVHTVNHVEwoKCJzbm1wX2NvbmZpZyIsICJyZW1lbWJlcmluZyBsaW5lIFwiJXNcIlxuIiwgbGluZSkpOwogICAgbmV0c25tcF9jb25maWdfcmVtZW1iZXIobGluZSk7ICAgICAgLyogYWx3YXlzIHJlbWVtYmVyIGl0IHNvIGl0J3MgcmVhZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogcHJvY2Vzc2VkIGFmdGVyIGEgZnJlZV9jb25maWcoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogY2FsbCAqLwogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICAgICAgIE5FVFNOTVBfRFNfTElCX0hBVkVfUkVBRF9DT05GSUcpKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfY29uZmlnIiwgIiAgLi4uIHByb2Nlc3NpbmcgaXQgbm93XG4iKSk7CiAgICAgICAgcmV0ID0gc25tcF9jb25maWdfd2hlbihsaW5lLCBOT1JNQUxfQ09ORklHKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcmVtZW1iZXJfaW5fbGlzdChjaGFyICpsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKiptZW0pCnsKICAgIGlmIChtZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgd2hpbGUgKCptZW0gIT0gTlVMTCkKICAgICAgICBtZW0gPSAmKCgqbWVtKS0+bmV4dCk7CgogICAgKm1lbSA9IFNOTVBfTUFMTE9DX1NUUlVDVChyZWFkX2NvbmZpZ19tZW1vcnkpOwogICAgaWYgKCptZW0gIT0gTlVMTCkgewogICAgICAgIGlmIChsaW5lKQogICAgICAgICAgICAoKm1lbSktPmxpbmUgPSBzdHJkdXAobGluZSk7CiAgICB9Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcmVtZW1iZXJfZnJlZV9saXN0KHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKiptZW0pCnsKICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKnRtcG1lbTsKICAgIHdoaWxlICgqbWVtKSB7CiAgICAgICAgU05NUF9GUkVFKCgqbWVtKS0+bGluZSk7CiAgICAgICAgdG1wbWVtID0gKCptZW0pLT5uZXh0OwogICAgICAgIFNOTVBfRlJFRSgqbWVtKTsKICAgICAgICAqbWVtID0gdG1wbWVtOwogICAgfQp9Cgp2b2lkCm5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3J5X2xpc3Qoc3RydWN0IHJlYWRfY29uZmlnX21lbW9yeSAqKm1lbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdoZW4sIGludCBjbGVhcikKewoKICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKm1lbTsKCiAgICBpZiAoIW1lbXApCiAgICAgICAgcmV0dXJuOwoKICAgIG1lbSA9ICptZW1wOwoKICAgIHdoaWxlIChtZW0pIHsKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAicHJvY2Vzc2luZyBtZW1vcnk6ICVzXG4iLCBtZW0tPmxpbmUpKTsKICAgICAgICBzbm1wX2NvbmZpZ193aGVuKG1lbS0+bGluZSwgd2hlbik7CiAgICAgICAgbWVtID0gbWVtLT5uZXh0OwogICAgfQoKICAgIGlmIChjbGVhcikKICAgICAgICBuZXRzbm1wX2NvbmZpZ19yZW1lbWJlcl9mcmVlX2xpc3QobWVtcCk7Cn0KCi8qCiAqIGRlZmF1bHQgc3RvcmFnZSBsb2NhdGlvbiBpbXBsZW1lbnRhdGlvbiAKICovCnN0YXRpYyBzdHJ1Y3QgcmVhZF9jb25maWdfbWVtb3J5ICptZW1vcnlsaXN0ID0gTlVMTDsKCnZvaWQKbmV0c25tcF9jb25maWdfcmVtZW1iZXIoY2hhciAqbGluZSkKewogICAgbmV0c25tcF9jb25maWdfcmVtZW1iZXJfaW5fbGlzdChsaW5lLCAmbWVtb3J5bGlzdCk7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcmllcyh2b2lkKQp7CiAgICBuZXRzbm1wX2NvbmZpZ19wcm9jZXNzX21lbW9yeV9saXN0KCZtZW1vcnlsaXN0LCBFSVRIRVJfQ09ORklHLCAxKTsKfQoKdm9pZApuZXRzbm1wX2NvbmZpZ19wcm9jZXNzX21lbW9yaWVzX3doZW4oaW50IHdoZW4sIGludCBjbGVhcikKewogICAgbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcnlfbGlzdCgmbWVtb3J5bGlzdCwgd2hlbiwgY2xlYXIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiByZWFkX2NvbmZpZwogKgogKiBQYXJhbWV0ZXJzOgogKgkqZmlsZW5hbWUKICoJKmxpbmVfaGFuZGxlcgogKgkgd2hlbgogKgogKiBSZWFkIDxmaWxlbmFtZT4gYW5kIHByb2Nlc3MgZWFjaCBsaW5lIGluIGFjY29yZGFuY2Ugd2l0aCB0aGUgbGlzdCBvZgogKiA8bGluZV9oYW5kbGVyPiBmdW5jdGlvbnMuCiAqCiAqCiAqIEZvciBlYWNoIGxpbmUgaW4gPGZpbGVuYW1lPiwgc2VhcmNoIHRoZSBsaXN0IG9mIDxsaW5lX2hhbmRsZXI+J3MgCiAqIGZvciBhbiBlbnRyeSB0aGF0IG1hdGNoZXMgdGhlIGZpcnN0IHRva2VuIG9uIHRoZSBsaW5lLiAgVGhpcyBjb21wYXJpc29uIGlzCiAqIGNhc2UgaW5zZW5zaXRpdmUuCiAqCiAqIEZvciBlYWNoIG1hdGNoLCBjaGVjayB0aGF0IDx3aGVuPiBpcyB0aGUgZGVzaWduYXRlZCB0aW1lIGZvciB0aGUKICogPGxpbmVfaGFuZGxlcj4gZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgYmVmb3JlIHByb2Nlc3NpbmcgdGhlIGxpbmUuCiAqLwp2b2lkCnJlYWRfY29uZmlnKGNvbnN0IGNoYXIgKmZpbGVuYW1lLAogICAgICAgICAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmxpbmVfaGFuZGxlciwgaW50IHdoZW4pCnsKCiAgICBGSUxFICAgICAgICAgICAqaWZpbGU7CiAgICBjaGFyICAgICAgICAgICAgbGluZVtTVFJJTkdNQVhdLCB0b2tlbltTVFJJTkdNQVhdOwogICAgY2hhciAgICAgICAgICAgKmNwdHI7CiAgICBpbnQgICAgICAgICAgICAgaTsKICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHB0cjsKCiAgICBsaW5lY291bnQgPSAwOwogICAgY3VyZmlsZW5hbWUgPSBmaWxlbmFtZTsKCiAgICBpZiAoKGlmaWxlID0gZm9wZW4oZmlsZW5hbWUsICJyIikpID09IE5VTEwpIHsKI2lmZGVmIEVOT0VOVAogICAgICAgIGlmIChlcnJubyA9PSBFTk9FTlQpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIiVzOiAlc1xuIiwgZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVycm9yKGVycm5vKSkpOwogICAgICAgIH0gZWxzZQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEVOT0VOVCAqLwojaWZkZWYgRUFDQ0VTCiAgICAgICAgaWYgKGVycm5vID09IEVBQ0NFUykgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAiJXM6ICVzXG4iLCBmaWxlbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RyZXJyb3IoZXJybm8pKSk7CiAgICAgICAgfSBlbHNlCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRUFDQ0VTICovCiNpZiBkZWZpbmVkKEVOT0VOVCkgfHwgZGVmaW5lZChFQUNDRVMpCiAgICAgICAgewogICAgICAgICAgICBzbm1wX2xvZ19wZXJyb3IoZmlsZW5hbWUpOwogICAgICAgIH0KI2Vsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBkZWZpbmVkKEVOT0VOVCkgfHwgZGVmaW5lZChFQUNDRVMpICovCiAgICAgICAgICAgIHNubXBfbG9nX3BlcnJvcihmaWxlbmFtZSk7CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRU5PRU5UICovCiAgICAgICAgcmV0dXJuOwogICAgfSBlbHNlIHsKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAiUmVhZGluZyBjb25maWd1cmF0aW9uICVzXG4iLAogICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lKSk7CiAgICB9CgogICAgd2hpbGUgKGZnZXRzKGxpbmUsIHNpemVvZihsaW5lKSwgaWZpbGUpICE9IE5VTEwpIHsKICAgICAgICBscHRyID0gbGluZV9oYW5kbGVyOwogICAgICAgIGxpbmVjb3VudCsrOwogICAgICAgIGNwdHIgPSBsaW5lOwogICAgICAgIGkgPSBzdHJsZW4obGluZSkgLSAxOwogICAgICAgIGlmIChsaW5lW2ldID09ICdcbicpCiAgICAgICAgICAgIGxpbmVbaV0gPSAwOwogICAgICAgIC8qCiAgICAgICAgICogY2hlY2sgYmxhbmsgbGluZSBvciAjIGNvbW1lbnQgCiAgICAgICAgICovCiAgICAgICAgaWYgKChjcHRyID0gc2tpcF93aGl0ZShjcHRyKSkpIHsKICAgICAgICAgICAgY3B0ciA9IGNvcHlfbndvcmQoY3B0ciwgdG9rZW4sIHNpemVvZih0b2tlbikpOwogICAgICAgICAgICBpZiAodG9rZW5bMF0gPT0gJ1snKSB7CiAgICAgICAgICAgICAgICBpZiAodG9rZW5bc3RybGVuKHRva2VuKSAtIDFdICE9ICddJykgewoJCSAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigibm8gbWF0Y2hpbmcgJ10nIGZvciB0eXBlICVzLiIsCgkJCQkJICZ0b2tlblsxXSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0b2tlbltzdHJsZW4odG9rZW4pIC0gMV0gPSAnXDAnOwogICAgICAgICAgICAgICAgbHB0ciA9IHJlYWRfY29uZmlnX2dldF9oYW5kbGVycygmdG9rZW5bMV0pOwogICAgICAgICAgICAgICAgaWYgKGxwdHIgPT0gTlVMTCkgewoJCSAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiTm8gaGFuZGxlcnMgcmVnZXN0ZXJlZCBmb3IgdHlwZSAlcy4iLAoJCQkJCSAmdG9rZW5bMV0pOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTd2l0Y2hpbmcgdG8gbmV3IGNvbnRleHQ6ICVzJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGNwdHIpID8gIih0aGlzIGxpbmUgb25seSkgIiA6ICIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0b2tlblsxXSkpOwogICAgICAgICAgICAgICAgaWYgKGNwdHIgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogY2hhbmdlIGNvbnRleHQgcGVybWFuZW50bHkgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgbGluZV9oYW5kbGVyID0gbHB0cjsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiB0aGUgcmVzdCBvZiB0aGlzIGxpbmUgb25seSBhcHBsaWVzLiAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBjcHRyID0gY29weV9ud29yZChjcHRyLCB0b2tlbiwgc2l6ZW9mKHRva2VuKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBscHRyID0gbGluZV9oYW5kbGVyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjcHRyID09IE5VTEwpIHsKCQluZXRzbm1wX2NvbmZpZ19lcnJvcigiQmxhbmsgbGluZSBmb2xsb3dpbmcgJXMgdG9rZW4uIiwgdG9rZW4pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIiVzOiVkIGV4YW1pbmluZzogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgbGluZWNvdW50LCBsaW5lKSk7CiAgICAgICAgICAgICAgICBydW5fY29uZmlnX2hhbmRsZXIobHB0ciwgdG9rZW4sIGNwdHIsIHdoZW4pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZmNsb3NlKGlmaWxlKTsKICAgIHJldHVybjsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHJlYWRfY29uZmlnKCkgKi8KCgoKdm9pZApmcmVlX2NvbmZpZyh2b2lkKQp7CiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjdG1wID0gY29uZmlnX2ZpbGVzOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpsdG1wOwoKICAgIGZvciAoOyBjdG1wICE9IE5VTEw7IGN0bXAgPSBjdG1wLT5uZXh0KQogICAgICAgIGZvciAobHRtcCA9IGN0bXAtPnN0YXJ0OyBsdG1wICE9IE5VTEw7IGx0bXAgPSBsdG1wLT5uZXh0KQogICAgICAgICAgICBpZiAobHRtcC0+ZnJlZV9mdW5jKQogICAgICAgICAgICAgICAgKCoobHRtcC0+ZnJlZV9mdW5jKSkgKCk7Cn0KCnZvaWQKcmVhZF9jb25maWdzX29wdGlvbmFsKGNvbnN0IGNoYXIgKm9wdGlvbmFsX2NvbmZpZywgaW50IHdoZW4pCnsKICAgIGNoYXIgKm5ld3AsICpjcCwgKnN0ID0gTlVMTDsKICAgIGNoYXIgKnR5cGUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFKTsKCiAgICBpZiAoKE5VTEwgPT0gb3B0aW9uYWxfY29uZmlnKSB8fCAoTlVMTCA9PSB0eXBlKSkKICAgICAgICByZXR1cm47CgogICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnc19vcHRpb25hbCIsCiAgICAgICAgICAgICAgICAicmVhZGluZyBvcHRpb25hbCBjb25maWd1cmF0aW9uIHRva2VucyBmb3IgJXNcbiIsIHR5cGUpKTsKICAgIAogICAgbmV3cCA9IHN0cmR1cChvcHRpb25hbF9jb25maWcpOyAgICAgIC8qIHN0cnRva19yIG1lc3NlcyBpdCB1cCAqLwogICAgY3AgPSBzdHJ0b2tfcihuZXdwLCAiLCIsICZzdCk7CiAgICB3aGlsZSAoY3ApIHsKICAgICAgICBzdHJ1Y3Qgc3RhdCAgICAgc3RhdGJ1ZjsKICAgICAgICBpZiAoc3RhdChjcCwgJnN0YXRidWYpKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJPcHRpb25hbCBGaWxlIFwiJXNcIiBkb2VzIG5vdCBleGlzdC5cbiIsIGNwKSk7CiAgICAgICAgICAgIHNubXBfbG9nX3BlcnJvcihjcCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwKICAgICAgICAgICAgICAgICAgICAgICAgIlJlYWRpbmcgb3B0aW9uYWwgY29uZmlnIGZpbGU6IFwiJXNcIlxuIiwgY3ApKTsKICAgICAgICAgICAgcmVhZF9jb25maWdfd2l0aF90eXBlX3doZW4oY3AsIHR5cGUsIHdoZW4pOwogICAgICAgIH0KICAgICAgICBjcCA9IHN0cnRva19yKE5VTEwsICIsIiwgJnN0KTsKICAgIH0KICAgIGZyZWUobmV3cCk7CiAgICAKfQoKdm9pZApyZWFkX2NvbmZpZ3Modm9pZCkKewogICAgY2hhciAqb3B0aW9uYWxfY29uZmlnID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkJICAgICAgIE5FVFNOTVBfRFNfTElCX09QVElPTkFMQ09ORklHKTsKCiAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwKICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9DQUxMQkFDS19QUkVfUkVBRF9DT05GSUcsIE5VTEwpOwoKICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICJyZWFkaW5nIG5vcm1hbCBjb25maWd1cmF0aW9uIHRva2Vuc1xuIikpOwoKICAgIGlmICgoTlVMTCAhPSBvcHRpb25hbF9jb25maWcpICYmICgqb3B0aW9uYWxfY29uZmlnID09ICctJykpIHsKICAgICAgICByZWFkX2NvbmZpZ3Nfb3B0aW9uYWwoKytvcHRpb25hbF9jb25maWcsIE5PUk1BTF9DT05GSUcpOwogICAgICAgIG9wdGlvbmFsX2NvbmZpZyA9IE5VTEw7IC8qIGNsZWFyLCBzbyB3ZSBkb24ndCByZWFkIHRoZW0gdHdpY2UgKi8KICAgIH0KCiAgICByZWFkX2NvbmZpZ19maWxlcyhOT1JNQUxfQ09ORklHKTsKCiAgICAvKgogICAgICogZG8gdGhpcyBldmVuIHdoZW4gdGhlIG5vcm1hbCBhYm92ZSB3YXNuJ3QgZG9uZSAKICAgICAqLwogICAgaWYgKE5VTEwgIT0gb3B0aW9uYWxfY29uZmlnKQogICAgICAgIHJlYWRfY29uZmlnc19vcHRpb25hbChvcHRpb25hbF9jb25maWcsIE5PUk1BTF9DT05GSUcpOwoKICAgIG5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3JpZXNfd2hlbihOT1JNQUxfQ09ORklHLCAxKTsKCiAgICBuZXRzbm1wX2RzX3NldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCSAgIE5FVFNOTVBfRFNfTElCX0hBVkVfUkVBRF9DT05GSUcsIDEpOwogICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0xJQlJBUlksCiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfQ0FMTEJBQ0tfUE9TVF9SRUFEX0NPTkZJRywgTlVMTCk7Cn0KCnZvaWQKcmVhZF9wcmVtaWJfY29uZmlncyh2b2lkKQp7CiAgICBjaGFyICpvcHRpb25hbF9jb25maWcgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQkgICAgICAgTkVUU05NUF9EU19MSUJfT1BUSU9OQUxDT05GSUcpOwoKICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19MSUJSQVJZLAogICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0NBTExCQUNLX1BSRV9QUkVNSUJfUkVBRF9DT05GSUcsIE5VTEwpOwoKICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICJyZWFkaW5nIHByZW1pYiBjb25maWd1cmF0aW9uIHRva2Vuc1xuIikpOwoKICAgIGlmICgoTlVMTCAhPSBvcHRpb25hbF9jb25maWcpICYmICgqb3B0aW9uYWxfY29uZmlnID09ICctJykpIHsKICAgICAgICByZWFkX2NvbmZpZ3Nfb3B0aW9uYWwoKytvcHRpb25hbF9jb25maWcsIFBSRU1JQl9DT05GSUcpOwogICAgICAgIG9wdGlvbmFsX2NvbmZpZyA9IE5VTEw7IC8qIGNsZWFyLCBzbyB3ZSBkb24ndCByZWFkIHRoZW0gdHdpY2UgKi8KICAgIH0KCiAgICByZWFkX2NvbmZpZ19maWxlcyhQUkVNSUJfQ09ORklHKTsKCiAgICBpZiAoTlVMTCAhPSBvcHRpb25hbF9jb25maWcpCiAgICAgICAgcmVhZF9jb25maWdzX29wdGlvbmFsKG9wdGlvbmFsX2NvbmZpZywgUFJFTUlCX0NPTkZJRyk7CgogICAgbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcmllc193aGVuKFBSRU1JQl9DT05GSUcsIDApOwoKICAgIG5ldHNubXBfZHNfc2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICAgTkVUU05NUF9EU19MSUJfSEFWRV9SRUFEX1BSRU1JQl9DT05GSUcsIDEpOwogICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0xJQlJBUlksCiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfQ0FMTEJBQ0tfUE9TVF9QUkVNSUJfUkVBRF9DT05GSUcsIE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBzZXRfY29uZmlndXJhdGlvbl9kaXJlY3RvcnkKICoKICogUGFyYW1ldGVyczoKICogICAgICBjaGFyICpkaXIgLSB2YWx1ZSBvZiB0aGUgZGlyZWN0b3J5CiAqIFNldHMgdGhlIGNvbmZpZ3VyYXRpb24gZGlyZWN0b3J5LiBNdWx0aXBsZSBkaXJlY3RvcmllcyBjYW4gYmUKICogc3BlY2lmaWVkLCBidXQgbmVlZCB0byBiZSBzZXBlcmF0ZWQgYnkgJ0VOVl9TRVBBUkFUT1JfQ0hBUicuCiAqLwp2b2lkCnNldF9jb25maWd1cmF0aW9uX2RpcmVjdG9yeShjb25zdCBjaGFyICpkaXIpCnsKICAgIG5ldHNubXBfZHNfc2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgIE5FVFNOTVBfRFNfTElCX0NPTkZJR1VSQVRJT05fRElSLCBkaXIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBnZXRfY29uZmlndXJhdGlvbl9kaXJlY3RvcnkKICoKICogUGFyYW1ldGVyczogLQogKiBSZXRyaWV2ZSB0aGUgY29uZmlndXJhdGlvbiBkaXJlY3Rvcnkgb3IgZGlyZWN0b3JpZXMuCiAqIChGb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgdGhhdCBpczoKICogICAgICAgU05NUENPTkZQQVRILCBTTk1QU0hBUkVQQVRILCBTTk1QTElCUEFUSCwgSE9NRS8uc25tcAogKiBGaXJzdCBjaGVjayB3aGV0aGVyIHRoZSB2YWx1ZSBpcyBzZXQuCiAqIElmIG5vdCBzZXQgZ2l2ZSBpdCB0aGUgZGVmYXVsdCB2YWx1ZS4KICogUmV0dXJuIHRoZSB2YWx1ZS4KICogV2UgYWx3YXlzIHJldHJpZXZlIGl0IG5ldywgc2luY2Ugd2UgaGF2ZSB0byBkbyBpdCBhbnl3YXkgaWYgaXQgaXMganVzdCBzZXQuCiAqLwpjb25zdCBjaGFyICAgICAqCmdldF9jb25maWd1cmF0aW9uX2RpcmVjdG9yeSh2b2lkKQp7CiAgICBjaGFyICAgICAgICAgICAgZGVmYXVsdFBhdGhbU1BSSU5UX01BWF9MRU5dOwogICAgY2hhciAgICAgICAgICAgKmhvbWVwYXRoOwoKICAgIGlmIChOVUxMID09IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICAgICAgTkVUU05NUF9EU19MSUJfQ09ORklHVVJBVElPTl9ESVIpKSB7CiAgICAgICAgaG9tZXBhdGggPSBuZXRzbm1wX2dldGVudigiSE9NRSIpOwogICAgICAgIHNucHJpbnRmKGRlZmF1bHRQYXRoLCBzaXplb2YoZGVmYXVsdFBhdGgpLCAiJXMlYyVzJWMlcyVzJXMlcyIsCiAgICAgICAgICAgICAgICBTTk1QQ09ORlBBVEgsIEVOVl9TRVBBUkFUT1JfQ0hBUiwKICAgICAgICAgICAgICAgIFNOTVBTSEFSRVBBVEgsIEVOVl9TRVBBUkFUT1JfQ0hBUiwgU05NUExJQlBBVEgsCiAgICAgICAgICAgICAgICAoKGhvbWVwYXRoID09IE5VTEwpID8gIiIgOiBFTlZfU0VQQVJBVE9SKSwKICAgICAgICAgICAgICAgICgoaG9tZXBhdGggPT0gTlVMTCkgPyAiIiA6IGhvbWVwYXRoKSwKICAgICAgICAgICAgICAgICgoaG9tZXBhdGggPT0gTlVMTCkgPyAiIiA6ICIvLnNubXAiKSk7CiAgICAgICAgZGVmYXVsdFBhdGhbIHNpemVvZihkZWZhdWx0UGF0aCktMSBdID0gMDsKICAgICAgICBzZXRfY29uZmlndXJhdGlvbl9kaXJlY3RvcnkoZGVmYXVsdFBhdGgpOwogICAgfQogICAgcmV0dXJuIChuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgTkVUU05NUF9EU19MSUJfQ09ORklHVVJBVElPTl9ESVIpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogc2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5CiAqCiAqIFBhcmFtZXRlcnM6CiAqICAgICAgY2hhciAqZGlyIC0gdmFsdWUgb2YgdGhlIGRpcmVjdG9yeQogKiBTZXRzIHRoZSBjb25maWd1cmF0aW9uIGRpcmVjdG9yeS4gCiAqIE5vIG11bHRpcGxlIGRpcmVjdG9yaWVzIG1heSBiZSBzcGVjaWZpZWQuCiAqIChIb3dldmVyLCB0aGlzIGlzIG5vdCBjaGVja2VkKQogKi8Kdm9pZApzZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoY29uc3QgY2hhciAqZGlyKQp7CiAgICBuZXRzbm1wX2RzX3NldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICBORVRTTk1QX0RTX0xJQl9QRVJTSVNURU5UX0RJUiwgZGlyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5CiAqCiAqIFBhcmFtZXRlcnM6IC0KICogRnVuY3Rpb24gd2lsbCByZXRyaWV2ZSB0aGUgcGVyc2lzdGVuIGRpcmVjdG9yeSB2YWx1ZS4KICogRmlyc3QgY2hlY2sgd2hldGhlciB0aGUgdmFsdWUgaXMgc2V0LgogKiBJZiBub3Qgc2V0IGdpdmUgaXQgdGhlIGRlZmF1bHQgdmFsdWUuCiAqIFJldHVybiB0aGUgdmFsdWUuIAogKiBXZSBhbHdheXMgcmV0cmlldmUgaXQgbmV3LCBzaW5jZSB3ZSBoYXZlIHRvIGRvIGl0IGFueXdheSBpZiBpdCBpcyBqdXN0IHNldC4KICovCmNvbnN0IGNoYXIgICAgICoKZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KHZvaWQpCnsKICAgIGlmIChOVUxMID09IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICAgICAgTkVUU05NUF9EU19MSUJfUEVSU0lTVEVOVF9ESVIpKSB7CiAgICAgICAgY29uc3QgY2hhciAqcGVyc2RpciA9IG5ldHNubXBfZ2V0ZW52KCJTTk1QX1BFUlNJU1RFTlRfRElSIik7CiAgICAgICAgaWYgKE5VTEwgPT0gcGVyc2RpcikKICAgICAgICAgICAgcGVyc2RpciA9IE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlk7CiAgICAgICAgc2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KHBlcnNkaXIpOwogICAgfQogICAgcmV0dXJuIChuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgTkVUU05NUF9EU19MSUJfUEVSU0lTVEVOVF9ESVIpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogc2V0X3RlbXBfZmlsZV9wYXR0ZXJuCiAqCiAqIFBhcmFtZXRlcnM6CiAqICAgICAgY2hhciAqcGF0dGVybiAtIHZhbHVlIG9mIHRoZSBmaWxlIHBhdHRlcm4KICogU2V0cyB0aGUgdGVtcCBmaWxlIHBhdHRlcm4uIAogKiBNdWx0aXBsZSBwYXR0ZXJucyBtYXkgbm90IGJlIHNwZWNpZmllZC4KICogKEhvd2V2ZXIsIHRoaXMgaXMgbm90IGNoZWNrZWQpCiAqLwp2b2lkCnNldF90ZW1wX2ZpbGVfcGF0dGVybihjb25zdCBjaGFyICpwYXR0ZXJuKQp7CiAgICBuZXRzbm1wX2RzX3NldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICBORVRTTk1QX0RTX0xJQl9URU1QX0ZJTEVfUEFUVEVSTiwgcGF0dGVybik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGdldF90ZW1wX2ZpbGVfcGF0dGVybgogKgogKiBQYXJhbWV0ZXJzOiAtCiAqIEZ1bmN0aW9uIHdpbGwgcmV0cmlldmUgdGhlIHRlbXAgZmlsZSBwYXR0ZXJuIHZhbHVlLgogKiBGaXJzdCBjaGVjayB3aGV0aGVyIHRoZSB2YWx1ZSBpcyBzZXQuCiAqIElmIG5vdCBzZXQgZ2l2ZSBpdCB0aGUgZGVmYXVsdCB2YWx1ZS4KICogUmV0dXJuIHRoZSB2YWx1ZS4gCiAqIFdlIGFsd2F5cyByZXRyaWV2ZSBpdCBuZXcsIHNpbmNlIHdlIGhhdmUgdG8gZG8gaXQgYW55d2F5IGlmIGl0IGlzIGp1c3Qgc2V0LgogKi8KY29uc3QgY2hhciAgICAgKgpnZXRfdGVtcF9maWxlX3BhdHRlcm4odm9pZCkKewogICAgaWYgKE5VTEwgPT0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgICBORVRTTk1QX0RTX0xJQl9URU1QX0ZJTEVfUEFUVEVSTikpIHsKICAgICAgICBzZXRfdGVtcF9maWxlX3BhdHRlcm4oTkVUU05NUF9URU1QX0ZJTEVfUEFUVEVSTik7CiAgICB9CiAgICByZXR1cm4gKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICBORVRTTk1QX0RTX0xJQl9URU1QX0ZJTEVfUEFUVEVSTikpOwp9CgovKioKICogdXRpbGl0eSByb3V0aW5lIGZvciByZWFkX2NvbmZpZ19maWxlcwogKi8Kc3RhdGljIHZvaWQKcmVhZF9jb25maWdfZmlsZXNfaW5fcGF0aChjb25zdCBjaGFyICpwYXRoLCBzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgIGludCB3aGVuLCBjb25zdCBjaGFyICpwZXJzcGF0aCwgY29uc3QgY2hhciAqcGVyc2ZpbGUpCnsKICAgIGludCAgICAgICAgICAgICBkb25lLCBqOwogICAgY2hhciAgICAgICAgICAgIGNvbmZpZ2ZpbGVbMzAwXTsKICAgIGNoYXIgICAgICAgICAgICpjcHRyMSwgKmNwdHIyLCAqZW52Y29uZnBhdGg7CiAgICBzdHJ1Y3Qgc3RhdCAgICAgc3RhdGJ1ZjsKCiAgICBpZiAoKE5VTEwgPT0gcGF0aCkgfHwgKE5VTEwgPT0gY3RtcCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGVudmNvbmZwYXRoID0gc3RyZHVwKHBhdGgpOwoKICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICIgY29uZmlnIHBhdGggdXNlZCBmb3IgJXM6JXMgKHBlcnNpc3RlbnQgcGF0aDolcylcbiIsCiAgICAgICAgICAgICAgICBjdG1wLT5maWxlSGVhZGVyLCBlbnZjb25mcGF0aCwgcGVyc3BhdGgpKTsKICAgIGNwdHIxID0gY3B0cjIgPSBlbnZjb25mcGF0aDsKICAgIGRvbmUgPSAwOwogICAgd2hpbGUgKCghZG9uZSkgJiYgKCpjcHRyMiAhPSAwKSkgewogICAgICAgIHdoaWxlICgqY3B0cjEgIT0gMCAmJiAqY3B0cjEgIT0gRU5WX1NFUEFSQVRPUl9DSEFSKQogICAgICAgICAgICBjcHRyMSsrOwogICAgICAgIGlmICgqY3B0cjEgPT0gMCkKICAgICAgICAgICAgZG9uZSA9IDE7CiAgICAgICAgZWxzZQogICAgICAgICAgICAqY3B0cjEgPSAwOwoKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAiIGNvbmZpZyBkaXI6ICVzXG4iLCBjcHRyMiApKTsKICAgICAgICBpZiAoc3RhdChjcHRyMiwgJnN0YXRidWYpICE9IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogRGlyZWN0b3J5IG5vdCB0aGVyZSwgY29udGludWUgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAiIERpcmVjdG9yeSBub3QgcHJlc2VudDogJXNcbiIsIGNwdHIyICkpOwogICAgICAgICAgICBjcHRyMiA9ICsrY3B0cjE7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KI2lmZGVmIFNfSVNESVIKICAgICAgICBpZiAoIVNfSVNESVIoc3RhdGJ1Zi5zdF9tb2RlKSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBOb3QgYSBkaXJlY3RvcnksIGNvbnRpbnVlIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIiBOb3QgYSBkaXJlY3Rvcnk6ICVzXG4iLCBjcHRyMiApKTsKICAgICAgICAgICAgY3B0cjIgPSArK2NwdHIxOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiNlbmRpZgoKICAgICAgICAvKgogICAgICAgICAqIGZvciBwcm9wZXIgcGVyc2lzdGVudCBzdG9yYWdlIHJldHJpdmFsLCB3ZSBuZWVkIHRvIHJlYWQgb2xkIGJhY2t1cAogICAgICAgICAqIGNvcGllcyBvZiB0aGUgcHJldmlvdXMgc3RvcmFnZSBmaWxlcy4gIElmIHRoZSBhcHBsaWNhdGlvbiBpbgogICAgICAgICAqIHF1ZXN0aW9uIGhhcyBkaWVkIHdpdGhvdXQgdGhlIHByb3BlciBjYWxsIHRvIHNubXBfY2xlYW5fcGVyc2lzdGVudCwKICAgICAgICAgKiB0aGVuIHdlIHJlYWQgYWxsIHRoZSBjb25maWd1cmF0aW9uIGZpbGVzIHdlIGNhbiwgc3RhcnRpbmcgd2l0aAogICAgICAgICAqIHRoZSBvbGRlc3QgZmlyc3QuCiAgICAgICAgICovCiAgICAgICAgaWYgKHN0cm5jbXAoY3B0cjIsIHBlcnNwYXRoLCBzdHJsZW4ocGVyc3BhdGgpKSA9PSAwIHx8CiAgICAgICAgICAgIChwZXJzZmlsZSAhPSBOVUxMICYmCiAgICAgICAgICAgICBzdHJuY21wKGNwdHIyLCBwZXJzZmlsZSwgc3RybGVuKHBlcnNmaWxlKSkgPT0gMCkpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogbGltaXQgdGhpcyB0byB0aGUga25vd24gc3RvcmFnZSBkaXJlY3Rvcnkgb25seSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPD0gTkVUU05NUF9NQVhfUEVSU0lTVEVOVF9CQUNLVVBTOyBqKyspIHsKICAgICAgICAgICAgICAgIHNucHJpbnRmKGNvbmZpZ2ZpbGUsIHNpemVvZihjb25maWdmaWxlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICIlcy8lcy4lZC5jb25mIiwgY3B0cjIsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdG1wLT5maWxlSGVhZGVyLCBqKTsKICAgICAgICAgICAgICAgIGNvbmZpZ2ZpbGVbIHNpemVvZihjb25maWdmaWxlKS0xIF0gPSAwOwogICAgICAgICAgICAgICAgaWYgKHN0YXQoY29uZmlnZmlsZSwgJnN0YXRidWYpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIGZpbGUgbm90IHRoZXJlLCBjb250aW51ZSAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBiYWNrdXAgZXhpc3RzLCByZWFkIGl0IAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19maWxlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9sZCBjb25maWcgZmlsZSBmb3VuZDogJXMsIHBhcnNpbmdcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnZmlsZSkpOwogICAgICAgICAgICAgICAgICAgIHJlYWRfY29uZmlnKGNvbmZpZ2ZpbGUsIGN0bXAtPnN0YXJ0LCB3aGVuKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzbnByaW50Zihjb25maWdmaWxlLCBzaXplb2YoY29uZmlnZmlsZSksCiAgICAgICAgICAgICAgICAgIiVzLyVzLmNvbmYiLCBjcHRyMiwgY3RtcC0+ZmlsZUhlYWRlcik7CiAgICAgICAgY29uZmlnZmlsZVsgc2l6ZW9mKGNvbmZpZ2ZpbGUpLTEgXSA9IDA7CiAgICAgICAgcmVhZF9jb25maWcoY29uZmlnZmlsZSwgY3RtcC0+c3RhcnQsIHdoZW4pOwogICAgICAgIHNucHJpbnRmKGNvbmZpZ2ZpbGUsIHNpemVvZihjb25maWdmaWxlKSwKICAgICAgICAgICAgICAgICAiJXMvJXMubG9jYWwuY29uZiIsIGNwdHIyLCBjdG1wLT5maWxlSGVhZGVyKTsKICAgICAgICBjb25maWdmaWxlWyBzaXplb2YoY29uZmlnZmlsZSktMSBdID0gMDsKICAgICAgICByZWFkX2NvbmZpZyhjb25maWdmaWxlLCBjdG1wLT5zdGFydCwgd2hlbik7CgogICAgICAgIGlmKGRvbmUpCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjcHRyMiA9ICsrY3B0cjE7CiAgICB9CiAgICBTTk1QX0ZSRUUoZW52Y29uZnBhdGgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiByZWFkX2NvbmZpZ19maWxlcwogKgogKiBQYXJhbWV0ZXJzOgogKgl3aGVuCT09IFBSRU1JQl9DT05GSUcsIE5PUk1BTF9DT05GSUcgIC1vci0gIEVJVEhFUl9DT05GSUcKICoKICoKICogVHJhdmVyc2UgdGhlIGxpc3Qgb2YgY29uZmlnIGZpbGUgdHlwZXMsIHBlcmZvcm1pbmcgdGhlIGZvbGxvd2luZyBhY3Rpb25zCiAqIGZvciBlYWNoIC0tCiAqCiAqIEZpcnN0LCBidWlsZCBhIHNlYXJjaCBwYXRoIGZvciBjb25maWcgZmlsZXMuICBJZiB0aGUgY29udGVudHMgb2YgCiAqIGVudmlyb25tZW50IHZhcmlhYmxlIFNOTVBDT05GUEFUSCBhcmUgTlVMTCwgdGhlbiB1c2UgdGhlIGZvbGxvd2luZwogKiBwYXRoIGxpc3QgKHdoZXJlIHRoZSBsYXN0IGVudHJ5IGV4aXN0cyBvbmx5IGlmIEhPTUUgaXMgbm9uLW51bGwpOgogKgogKglTTk1QU0hBUkVQQVRIOlNOTVBMSUJQQVRIOiR7SE9NRX0vLnNubXAKICoKICogVGhlbiwgSW4gZWFjaCBvZiB0aGVzZSBkaXJlY3RvcmllcywgcmVhZCBjb25maWcgZmlsZXMgYnkgdGhlIG5hbWUgb2Y6CiAqCiAqCTxkaXI+LzxmaWxlSGVhZGVyPi5jb25mCQktQU5ELQogKgk8ZGlyPi88ZmlsZUhlYWRlcj4ubG9jYWwuY29uZgogKgogKiB3aGVyZSA8ZmlsZUhlYWRlcj4gaXMgdGFrZW4gZnJvbSB0aGUgY29uZmlnIGZpbGUgdHlwZSBzdHJ1Y3R1cmUuCiAqCiAqCiAqIFBSRU1JQl9DT05GSUcgY2F1c2VzIGZyZWVfY29uZmlnKCkgdG8gYmUgaW52b2tlZCBwcmlvciB0byBhbnkgb3RoZXIgYWN0aW9uLgogKgogKgogKiBFWElUcyBpZiBhbnkgJ2NvbmZpZ19lcnJvcnMnIGFyZSBsb2dnZWQgd2hpbGUgcGFyc2luZyBjb25maWcgZmlsZSBsaW5lcy4KICovCnZvaWQKcmVhZF9jb25maWdfZmlsZXMoaW50IHdoZW4pCnsKICAgIGNvbnN0IGNoYXIgICAgICpjb25mcGF0aCwgKnBlcnNmaWxlLCAqZW52Y29uZnBhdGg7CiAgICBjaGFyICAgICAgICAgICAqcGVyc3BhdGg7CiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjdG1wID0gY29uZmlnX2ZpbGVzOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RPTlRfUEVSU0lTVF9TVEFURSkKICAgICB8fCBuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RJU0FCTEVfQ09ORklHX0xPQUQpKSByZXR1cm47CgogICAgY29uZmlnX2Vycm9ycyA9IDA7CgogICAgaWYgKHdoZW4gPT0gUFJFTUlCX0NPTkZJRykKICAgICAgICBmcmVlX2NvbmZpZygpOwoKICAgIC8qCiAgICAgKiB0aGVzZSBzaG91bGRuJ3QgY2hhbmdlCiAgICAgKi8KICAgIGNvbmZwYXRoID0gZ2V0X2NvbmZpZ3VyYXRpb25fZGlyZWN0b3J5KCk7CiAgICBwZXJzZmlsZSA9IG5ldHNubXBfZ2V0ZW52KCJTTk1QX1BFUlNJU1RFTlRfRklMRSIpOwogICAgZW52Y29uZnBhdGggPSBuZXRzbm1wX2dldGVudigiU05NUENPTkZQQVRIIik7CgogICAgLyoKICAgICAqIHJlYWQgYWxsIGNvbmZpZyBmaWxlIHR5cGVzIAogICAgICovCiAgICBmb3IgKDsgY3RtcCAhPSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkgewoKICAgICAgICAvKgogICAgICAgICAqIHJlYWQgdGhlIGNvbmZpZyBmaWxlcy4gc3RyZHVwKCkgdGhlIHJlc3VsdCBvZgogICAgICAgICAqIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpIHRvIGF2b2lkIHRoYXQgcGFyc2luZyB0aGUgInBlcnNpc3RlbnREaXIiCiAgICAgICAgICoga2V5d29yZCB0cmFuc2Zvcm1zIHRoZSBwZXJzcGF0aCBwb2ludGVyIGludG8gYSBkYW5nbGluZyBwb2ludGVyLgogICAgICAgICAqLwogICAgICAgIHBlcnNwYXRoID0gc3RyZHVwKGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpKTsKICAgICAgICBpZiAoZW52Y29uZnBhdGggPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByZWFkIGp1c3QgdGhlIGNvbmZpZyBmaWxlcyAobm8gcGVyc2lzdGVudCBzdHVmZiksIHNpbmNlCiAgICAgICAgICAgICAqIHBlcnNpc3RlbnQgcGF0aCBjYW4gY2hhbmdlIHZpYSBjb25mIGZpbGUuIFRoZW4gZ2V0IHRoZQogICAgICAgICAgICAgKiBjdXJyZW50IHBlcnNpc3RlbnQgZGlyZWN0b3J5LCBhbmQgcmVhZCBmaWxlcyB0aGVyZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlYWRfY29uZmlnX2ZpbGVzX2luX3BhdGgoY29uZnBhdGgsIGN0bXAsIHdoZW4sIHBlcnNwYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcnNmaWxlKTsKICAgICAgICAgICAgZnJlZShwZXJzcGF0aCk7CiAgICAgICAgICAgIHBlcnNwYXRoID0gc3RyZHVwKGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpKTsKICAgICAgICAgICAgcmVhZF9jb25maWdfZmlsZXNfaW5fcGF0aChwZXJzcGF0aCwgY3RtcCwgd2hlbiwgcGVyc3BhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyc2ZpbGUpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogb25seSByZWFkIHBhdGggc3BlY2lmaWVkIGJ5IHVzZXIKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlYWRfY29uZmlnX2ZpbGVzX2luX3BhdGgoZW52Y29uZnBhdGgsIGN0bXAsIHdoZW4sIHBlcnNwYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcnNmaWxlKTsKICAgICAgICB9CiAgICAgICAgZnJlZShwZXJzcGF0aCk7CiAgICB9CgogICAgaWYgKGNvbmZpZ19lcnJvcnMpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0LXNubXA6ICVkIGVycm9yKHMpIGluIGNvbmZpZyBmaWxlKHMpXG4iLAogICAgICAgICAgICAgICAgIGNvbmZpZ19lcnJvcnMpOwogICAgfQp9Cgp2b2lkCnJlYWRfY29uZmlnX3ByaW50X3VzYWdlKGNvbnN0IGNoYXIgKmxlYWQpCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAgPSBjb25maWdfZmlsZXM7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmx0bXA7CgogICAgaWYgKGxlYWQgPT0gTlVMTCkKICAgICAgICBsZWFkID0gIiI7CgogICAgZm9yIChjdG1wID0gY29uZmlnX2ZpbGVzOyBjdG1wICE9IE5VTEw7IGN0bXAgPSBjdG1wLT5uZXh0KSB7CiAgICAgICAgc25tcF9sb2coTE9HX0lORk8sICIlc0luICVzLmNvbmYgYW5kICVzLmxvY2FsLmNvbmY6XG4iLCBsZWFkLAogICAgICAgICAgICAgICAgIGN0bXAtPmZpbGVIZWFkZXIsIGN0bXAtPmZpbGVIZWFkZXIpOwogICAgICAgIGZvciAobHRtcCA9IGN0bXAtPnN0YXJ0OyBsdG1wICE9IE5VTEw7IGx0bXAgPSBsdG1wLT5uZXh0KSB7CiAgICAgICAgICAgIERFQlVHSUYoInJlYWRfY29uZmlnX3VzYWdlIikgewogICAgICAgICAgICAgICAgaWYgKGx0bXAtPmNvbmZpZ190aW1lID09IFBSRU1JQl9DT05GSUcpCiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJyZWFkX2NvbmZpZ191c2FnZSIsICIqIikpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgicmVhZF9jb25maWdfdXNhZ2UiLCAiICIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobHRtcC0+aGVscCkgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0lORk8sICIlcyVzJS0yNHMgJXNcbiIsIGxlYWQsIGxlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBsdG1wLT5jb25maWdfdG9rZW4sIGx0bXAtPmhlbHApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgREVCVUdJRigicmVhZF9jb25maWdfdXNhZ2UiKSB7CiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0lORk8sICIlcyVzJS0yNHMgW05PIEhFTFBdXG4iLCBsZWFkLCBsZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGx0bXAtPmNvbmZpZ190b2tlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8qKgogKiByZWFkX2NvbmZpZ19zdG9yZSBpbnRlbmRlZCBmb3IgdXNlIGJ5IGFwcGxpY2F0aW9ucyB0byBzdG9yZSBwZXJtZW5hbnQKICogY29uZmlndXJhdGlvbiBpbmZvcm1hdGlvbiBnZW5lcmF0ZWQgYnkgc2V0cyBvciBwZXJzaXN0ZW50IGNvdW50ZXJzLgogKiBBcHBlbmRzIGxpbmUgdG8gYSBmaWxlIG5hbWVkIGVpdGhlciBFTlYoU05NUF9QRVJTSVNURU5UX0ZJTEUpIG9yCiAqICAgIjxORVRTTk1QX1BFUlNJU1RFTlRfRElSRUNUT1JZPi88dHlwZT4uY29uZiIuCiAqIEFkZHMgYSB0cmFpbGluZyBuZXdsaW5lIHRvIHRoZSBzdG9yZWQgZmlsZSBpZiBuZWNlc3NhcnkuCiAqCiAqIEBwYXJhbSB0eXBlIGlzIHRoZSBhcHBsaWNhdGlvbiBuYW1lCiAqIEBwYXJhbSBsaW5lIGlzIHRoZSBjb25maWd1cmF0aW9uIGxpbmUgd3JpdHRlbiB0byB0aGUgYXBwbGljYXRpb24gbmFtZSdzCiAqIGNvbmZpZ3VyYXRpb24gZmlsZQogKiAgICAgIAogKiBAcmV0dXJuIHZvaWQKICAqLwp2b2lkCnJlYWRfY29uZmlnX3N0b3JlKGNvbnN0IGNoYXIgKnR5cGUsIGNvbnN0IGNoYXIgKmxpbmUpCnsKI2lmZGVmIE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlkKICAgIGNoYXIgICAgICAgICAgICBmaWxlWzUxMl0sICpmaWxlcDsKICAgIEZJTEUgICAgICAgICAgICpmb3V0OwojaWZkZWYgTkVUU05NUF9QRVJTSVNURU5UX01BU0sKICAgIG1vZGVfdCAgICAgICAgICBvbGRtYXNrOwojZW5kaWYKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ET05UX1BFUlNJU1RfU1RBVEUpCiAgICAgfHwgbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ESVNBQkxFX1BFUlNJU1RFTlRfTE9BRCkpIHJldHVybjsKCiAgICAvKgogICAgICogc3RvcmUgY29uZmlndXJhdGlvbiBkaXJlY3RpdmVzIGluIHRoZSBmb2xsb3dpbmcgb3JkZXIgb2YgcHJlZmVyZW5jZToKICAgICAqIDEuIEVOViB2YXJpYWJsZSBTTk1QX1BFUlNJU1RFTlRfRklMRQogICAgICogMi4gY29uZmlndXJlZCA8TkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWT4vPHR5cGU+LmNvbmYKICAgICAqLwogICAgaWYgKChmaWxlcCA9IG5ldHNubXBfZ2V0ZW52KCJTTk1QX1BFUlNJU1RFTlRfRklMRSIpKSA9PSBOVUxMKSB7CiAgICAgICAgc25wcmludGYoZmlsZSwgc2l6ZW9mKGZpbGUpLAogICAgICAgICAgICAgICAgICIlcy8lcy5jb25mIiwgZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KCksIHR5cGUpOwogICAgICAgIGZpbGVbIHNpemVvZihmaWxlKS0xIF0gPSAwOwogICAgICAgIGZpbGVwID0gZmlsZTsKICAgIH0KI2lmZGVmIE5FVFNOTVBfUEVSU0lTVEVOVF9NQVNLCiAgICBvbGRtYXNrID0gdW1hc2soTkVUU05NUF9QRVJTSVNURU5UX01BU0spOwojZW5kaWYKICAgIGlmIChta2RpcmhpZXIoZmlsZXAsIE5FVFNOTVBfQUdFTlRfRElSRUNUT1JZX01PREUsIDEpKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIGNyZWF0ZSB0aGUgcGVyc2lzdGVudCBkaXJlY3RvcnkgZm9yICVzXG4iLAogICAgICAgICAgICAgICAgIGZpbGUpOwogICAgfQogICAgaWYgKChmb3V0ID0gZm9wZW4oZmlsZXAsICJhIikpICE9IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKGZvdXQsICIlcyIsIGxpbmUpOwogICAgICAgIGlmIChsaW5lW3N0cmxlbihsaW5lKV0gIT0gJ1xuJykKICAgICAgICAgICAgZnByaW50Zihmb3V0LCAiXG4iKTsKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAic3RvcmluZzogJXNcbiIsIGxpbmUpKTsKICAgICAgICBmY2xvc2UoZm91dCk7CiAgICB9IGVsc2UgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJyZWFkX2NvbmZpZ19zdG9yZSBvcGVuIGZhaWx1cmUgb24gJXNcbiIsIGZpbGVwKTsKICAgIH0KI2lmZGVmIE5FVFNOTVBfUEVSU0lTVEVOVF9NQVNLCiAgICB1bWFzayhvbGRtYXNrKTsKI2VuZGlmCgojZW5kaWYKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgcmVhZF9jb25maWdfc3RvcmUoKSAqLwoKdm9pZApyZWFkX2FwcF9jb25maWdfc3RvcmUoY29uc3QgY2hhciAqbGluZSkKewogICAgcmVhZF9jb25maWdfc3RvcmUobmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkJICAgIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpLCBsaW5lKTsKfQoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogc25tcF9zYXZlX3BlcnNpc3RlbnQKICoKICogUGFyYW1ldGVyczoKICoJKnR5cGUKICogICAgICAKICoKICogU2F2ZSB0aGUgZmlsZSAiPE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlk+Lzx0eXBlPi5jb25mIiBpbnRvIGEgYmFja3VwIGNvcHkKICogY2FsbGVkICI8TkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWT4vPHR5cGU+LiVkLmNvbmYiLCB3aGljaCAlZCBpcyBhbgogKiBpbmNyZW1lbnRpbmcgbnVtYmVyIG9uIGVhY2ggY2FsbCwgYnV0IGxlc3MgdGhhbiBORVRTTk1QX01BWF9QRVJTSVNURU5UX0JBQ0tVUFMuCiAqCiAqIFNob3VsZCBiZSBjYWxsZWQganVzdCBiZWZvcmUgYWxsIHBlcnNpc3RlbnQgaW5mb3JtYXRpb24gaXMgc3VwcG9zZWQgdG8gYmUKICogd3JpdHRlbiB0byBtb3ZlIGFzaWRlIHRoZSBleGlzdGluZyBwZXJzaXN0ZW50IGNhY2hlLgogKiBzbm1wX2NsZWFuX3BlcnNpc3RlbnQgc2hvdWxkIHRoZW4gYmUgY2FsbGVkIGFmdGVyd2FyZCBhbGwgZGF0YSBoYXMgYmVlbgogKiBzYXZlZCB0byByZW1vdmUgdGhlc2UgYmFja3VwIGZpbGVzLgogKgogKiBOb3RlOiBvbiBhbiByZW5hbWUgZXJyb3IsIHRoZSBmaWxlcyBhcmUgcmVtb3ZlZCByYXRoZXIgdGhhbiBzYXZlZC4KICoKICovCnZvaWQKc25tcF9zYXZlX3BlcnNpc3RlbnQoY29uc3QgY2hhciAqdHlwZSkKewogICAgY2hhciAgICAgICAgICAgIGZpbGVbNTEyXSwgZmlsZW9sZFtTUFJJTlRfTUFYX0xFTl07CiAgICBzdHJ1Y3Qgc3RhdCAgICAgc3RhdGJ1ZjsKICAgIGludCAgICAgICAgICAgICBqOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RPTlRfUEVSU0lTVF9TVEFURSkKICAgICB8fCBuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RJU0FCTEVfUEVSU0lTVEVOVF9TQVZFKSkgcmV0dXJuOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX3NhdmVfcGVyc2lzdGVudCIsICJzYXZpbmcgJXMgZmlsZXMuLi5cbiIsIHR5cGUpKTsKICAgIHNucHJpbnRmKGZpbGUsIHNpemVvZihmaWxlKSwKICAgICAgICAgICAgICIlcy8lcy5jb25mIiwgZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KCksIHR5cGUpOwogICAgZmlsZVsgc2l6ZW9mKGZpbGUpLTEgXSA9IDA7CiAgICBpZiAoc3RhdChmaWxlLCAmc3RhdGJ1ZikgPT0gMCkgewogICAgICAgIGZvciAoaiA9IDA7IGogPD0gTkVUU05NUF9NQVhfUEVSU0lTVEVOVF9CQUNLVVBTOyBqKyspIHsKICAgICAgICAgICAgc25wcmludGYoZmlsZW9sZCwgc2l6ZW9mKGZpbGVvbGQpLAogICAgICAgICAgICAgICAgICAgICAiJXMvJXMuJWQuY29uZiIsIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpLCB0eXBlLCBqKTsKICAgICAgICAgICAgZmlsZW9sZFsgc2l6ZW9mKGZpbGVvbGQpLTEgXSA9IDA7CiAgICAgICAgICAgIGlmIChzdGF0KGZpbGVvbGQsICZzdGF0YnVmKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9zYXZlX3BlcnNpc3RlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBzYXZpbmcgb2xkIGNvbmZpZyBmaWxlOiAlcyAtPiAlcy5cbiIsIGZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlb2xkKSk7CiAgICAgICAgICAgICAgICBpZiAocmVuYW1lKGZpbGUsIGZpbGVvbGQpKSB7CiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkNhbm5vdCByZW5hbWUgJXMgdG8gJXNcbiIsIGZpbGUsIGZpbGVvbGQpOwogICAgICAgICAgICAgICAgICAgICAvKiBtb3ZpbmcgaXQgZmFpbGVkLCB0cnkgbnVraW5nIGl0LCBhcyBsZWF2aW5nCiAgICAgICAgICAgICAgICAgICAgICAqIGl0IGFyb3VuZCBpcyB2ZXJ5IGJhZC4gKi8KICAgICAgICAgICAgICAgICAgICBpZiAodW5saW5rKGZpbGUpID09IC0xKQogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiQ2Fubm90IHVubGluayAlc1xuIiwgZmlsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8qCiAgICAgKiBzYXZlIGEgd2FybmluZyBoZWFkZXIgdG8gdGhlIHRvcCBvZiB0aGUgbmV3IGZpbGUgCiAgICAgKi8KICAgIHNucHJpbnRmKGZpbGVvbGQsIHNpemVvZihmaWxlb2xkKSwKICAgICAgICAgICAgIiNcbiMgbmV0LXNubXAgKG9yIHVjZC1zbm1wKSBwZXJzaXN0ZW50IGRhdGEgZmlsZS5cbiNcbiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbiMgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgXG4jXG4jICAgICAgICAgICoqKiogRE8gTk9UIEVESVQgVEhJUyBGSUxFICoqKipcbiNcbiMgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgXG4jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjXG4jXG4jIERPIE5PVCBTVE9SRSBDT05GSUdVUkFUSU9OIEVOVFJJRVMgSEVSRS5cbiMgUGxlYXNlIHNhdmUgbm9ybWFsIGNvbmZpZ3VyYXRpb24gdG9rZW5zIGZvciAlcyBpbiBTTk1QQ09ORlBBVEgvJXMuY29uZi5cbiMgT25seSBcImNyZWF0ZVVzZXJcIiB0b2tlbnMgc2hvdWxkIGJlIHBsYWNlZCBoZXJlIGJ5ICVzIGFkbWluaXN0cmF0b3JzLlxuIyAoRGlkIEkgbWVudGlvbjogZG8gbm90IGVkaXQgdGhpcyBmaWxlPylcbiNcblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG4iLAogICAgICAgICAgICB0eXBlLCB0eXBlLCB0eXBlKTsKICAgIGZpbGVvbGRbIHNpemVvZihmaWxlb2xkKS0xIF0gPSAwOwogICAgcmVhZF9jb25maWdfc3RvcmUodHlwZSwgZmlsZW9sZCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBzbm1wX2NsZWFuX3BlcnNpc3RlbnQKICoKICogUGFyYW1ldGVyczoKICoJKnR5cGUKICogICAgICAKICoKICogVW5saW5rIGFsbCBiYWNrdXAgZmlsZXMgY2FsbGVkICI8TkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWT4vPHR5cGU+LiVkLmNvbmYiLgogKgogKiBTaG91bGQgYmUgY2FsbGVkIGp1c3QgYWZ0ZXIgd2Ugc3VjY2Vzc2Z1bGwgZHVtcGVkIHRoZSBsYXN0IG9mIHRoZQogKiBwZXJzaXN0ZW50IGRhdGEsIHRvIHJlbW92ZSB0aGUgYmFja3VwIGNvcGllcyBvZiBwcmV2aW91cyBzdG9yYWdlIGR1bXBzLgogKgogKiBYWFggIFdvcnRoIG92ZXJ3cml0aW5nIHdpdGggcmFuZG9tIGJ5dGVzIGZpcnN0PyAgVGhpcyB3b3VsZAogKgllbnN1cmUgdGhhdCB0aGUgZGF0YSBpcyBkZXN0cm95ZWQsIGV2ZW4gYSBidWZmZXIgY29udGFpbmluZyB0aGUKICoJZGF0YSBwZXJzaXN0cyBpbiBtZW1vcnkgb3Igc3dhcC4gIE9ubHkgaW1wb3J0YW50IGlmIHNlY3JldHMKICoJd2lsbCBiZSBzdG9yZWQgaGVyZS4KICovCnZvaWQKc25tcF9jbGVhbl9wZXJzaXN0ZW50KGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIGNoYXIgICAgICAgICAgICBmaWxlWzUxMl07CiAgICBzdHJ1Y3Qgc3RhdCAgICAgc3RhdGJ1ZjsKICAgIGludCAgICAgICAgICAgICBqOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RPTlRfUEVSU0lTVF9TVEFURSkKICAgICB8fCBuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RJU0FCTEVfUEVSU0lTVEVOVF9TQVZFKSkgcmV0dXJuOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2NsZWFuX3BlcnNpc3RlbnQiLCAiY2xlYW5pbmcgJXMgZmlsZXMuLi5cbiIsIHR5cGUpKTsKICAgIHNucHJpbnRmKGZpbGUsIHNpemVvZihmaWxlKSwKICAgICAgICAgICAgICIlcy8lcy5jb25mIiwgZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KCksIHR5cGUpOwogICAgZmlsZVsgc2l6ZW9mKGZpbGUpLTEgXSA9IDA7CiAgICBpZiAoc3RhdChmaWxlLCAmc3RhdGJ1ZikgPT0gMCkgewogICAgICAgIGZvciAoaiA9IDA7IGogPD0gTkVUU05NUF9NQVhfUEVSU0lTVEVOVF9CQUNLVVBTOyBqKyspIHsKICAgICAgICAgICAgc25wcmludGYoZmlsZSwgc2l6ZW9mKGZpbGUpLAogICAgICAgICAgICAgICAgICAgICAiJXMvJXMuJWQuY29uZiIsIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpLCB0eXBlLCBqKTsKICAgICAgICAgICAgZmlsZVsgc2l6ZW9mKGZpbGUpLTEgXSA9IDA7CiAgICAgICAgICAgIGlmIChzdGF0KGZpbGUsICZzdGF0YnVmKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9jbGVhbl9wZXJzaXN0ZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgcmVtb3Zpbmcgb2xkIGNvbmZpZyBmaWxlOiAlc1xuIiwgZmlsZSkpOwogICAgICAgICAgICAgICAgaWYgKHVubGluayhmaWxlKSA9PSAtMSkKICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiQ2Fubm90IHVubGluayAlc1xuIiwgZmlsZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCgoKCi8qCiAqIGNvbmZpZ19wZXJyb3I6IHByaW50cyBhIHdhcm5pbmcgc3RyaW5nIGFzc29jaWF0ZWQgd2l0aCBhIGZpbGUgYW5kCiAqIGxpbmUgbnVtYmVyIG9mIGEgLmNvbmYgZmlsZSBhbmQgaW5jcmVtZW50cyB0aGUgZXJyb3IgY291bnQuIAogKi8Kc3RhdGljIHZvaWQKY29uZmlnX3Zsb2coaW50IGxldmVsLCBjb25zdCBjaGFyICpsZXZlbG1zZywgY29uc3QgY2hhciAqc3RyLCB2YV9saXN0IGFyZ3MpCnsKICAgIGNoYXIgdG1wYnVmWzI1Nl07CiAgICBjaGFyKiBidWYgPSB0bXBidWY7CiAgICBpbnQgbGVuID0gc25wcmludGYodG1wYnVmLCBzaXplb2YodG1wYnVmKSwgIiVzOiBsaW5lICVkOiAlczogJXNcbiIsCgkJICAgICAgIGN1cmZpbGVuYW1lLCBsaW5lY291bnQsIGxldmVsbXNnLCBzdHIpOwogICAgaWYgKGxlbiA+PSBzaXplb2YodG1wYnVmKSkgewoJYnVmID0gKGNoYXIqKW1hbGxvYyhsZW4gKyAxKTsKCXNwcmludGYoYnVmLCAiJXM6IGxpbmUgJWQ6ICVzOiAlc1xuIiwKCQljdXJmaWxlbmFtZSwgbGluZWNvdW50LCBsZXZlbG1zZywgc3RyKTsKICAgIH0KICAgIHNubXBfdmxvZyhsZXZlbCwgYnVmLCBhcmdzKTsKICAgIGlmIChidWYgIT0gdG1wYnVmKQoJZnJlZShidWYpOwp9Cgp2b2lkCm5ldHNubXBfY29uZmlnX2Vycm9yKGNvbnN0IGNoYXIgKnN0ciwgLi4uKQp7CiAgICB2YV9saXN0IGFyZ3M7CiAgICB2YV9zdGFydChhcmdzLCBzdHIpOwogICAgY29uZmlnX3Zsb2coTE9HX0VSUiwgIkVycm9yIiwgc3RyLCBhcmdzKTsKICAgIHZhX2VuZChhcmdzKTsKICAgIGNvbmZpZ19lcnJvcnMrKzsKfQoKdm9pZApuZXRzbm1wX2NvbmZpZ193YXJuKGNvbnN0IGNoYXIgKnN0ciwgLi4uKQp7CiAgICB2YV9saXN0IGFyZ3M7CiAgICB2YV9zdGFydChhcmdzLCBzdHIpOwogICAgY29uZmlnX3Zsb2coTE9HX1dBUk5JTkcsICJXYXJuaW5nIiwgc3RyLCBhcmdzKTsKICAgIHZhX2VuZChhcmdzKTsKfQoKdm9pZApjb25maWdfcGVycm9yKGNvbnN0IGNoYXIgKnN0cikKewogICAgbmV0c25tcF9jb25maWdfZXJyb3IoIiVzIiwgc3RyKTsKfQoKdm9pZApjb25maWdfcHdhcm4oY29uc3QgY2hhciAqc3RyKQp7CiAgICBuZXRzbm1wX2NvbmZpZ193YXJuKCIlcyIsIHN0cik7Cn0KCi8qCiAqIHNraXAgYWxsIHdoaXRlIHNwYWNlcyBhbmQgcmV0dXJuIDEgaWYgZm91bmQgc29tZXRoaW5nIGVpdGhlciBlbmQgb2YKICogbGluZSBvciBhIGNvbW1lbnQgY2hhcmFjdGVyIAogKi8KY2hhciAgICAgICAgICAgKgpza2lwX3doaXRlKGNoYXIgKnB0cikKewogICAgaWYgKHB0ciA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB3aGlsZSAoKnB0ciAhPSAwICYmIGlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKnB0cikpCiAgICAgICAgcHRyKys7CiAgICBpZiAoKnB0ciA9PSAwIHx8ICpwdHIgPT0gJyMnKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXR1cm4gKHB0cik7Cn0KCmNoYXIgICAgICAgICAgICoKc2tpcF9ub3Rfd2hpdGUoY2hhciAqcHRyKQp7CiAgICBpZiAocHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHdoaWxlICgqcHRyICE9IDAgJiYgIWlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKnB0cikpCiAgICAgICAgcHRyKys7CiAgICBpZiAoKnB0ciA9PSAwIHx8ICpwdHIgPT0gJyMnKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXR1cm4gKHB0cik7Cn0KCmNoYXIgICAgICAgICAgICoKc2tpcF90b2tlbihjaGFyICpwdHIpCnsKICAgIHB0ciA9IHNraXBfd2hpdGUocHRyKTsKICAgIHB0ciA9IHNraXBfbm90X3doaXRlKHB0cik7CiAgICBwdHIgPSBza2lwX3doaXRlKHB0cik7CiAgICByZXR1cm4gKHB0cik7Cn0KCi8qCiAqIGNvcHlfd29yZAogKiBjb3BpZXMgdGhlIG5leHQgJ3Rva2VuJyBmcm9tICdmcm9tJyBpbnRvICd0bycsIG1heGltdW0gbGVuLTEgY2hhcmFjdGVycy4KICogY3VycmVudGx5IGEgdG9rZW4gaXMgYW55dGhpbmcgc2VwZXJhdGUgYnkgd2hpdGUgc3BhY2UKICogb3Igd2l0aGluIHF1b3RlcyAoZG91YmxlIG9yIHNpbmdsZSkgKGkuZS4gInRoZSByZWQgcm9zZSIgCiAqIGlzIG9uZSB0b2tlbiwgXCJ0aGUgcmVkIHJvc2VcIiBpcyB0aHJlZSB0b2tlbnMpCiAqIGEgJ1wnIGNoYXJhY3RlciB3aWxsIGFsbG93IGEgcXVvdGUgY2hhcmFjdGVyIHRvIGJlIHRyZWF0ZWQKICogYXMgYSByZWd1bGFyIGNoYXJhY3RlciAKICogSXQgcmV0dXJucyBhIHBvaW50ZXIgdG8gZmlyc3Qgbm9uLXdoaXRlIHNwYWNlIGFmdGVyIHRoZSBlbmQgb2YgdGhlIHRva2VuCiAqIGJlaW5nIGNvcGllZCBvciB0byAwIGlmIHdlIHJlYWNoIHRoZSBlbmQuCiAqIE5vdGU6IFBhcnRpYWxseSBjb3BpZWQgd29yZHMgKGdyZWF0ZXIgdGhhbiBsZW4pIHN0aWxsIHJldHVybnMgYSAhTlVMTCBwdHIKICogTm90ZTogcGFydGlhbGx5IGNvcGllZCB3b3JkcyBhcmUsIGhvd2V2ZXIsIG51bGwgdGVybWluYXRlZC4KICovCgpjaGFyICAgICAgICAgICAqCmNvcHlfbndvcmQoY2hhciAqZnJvbSwgY2hhciAqdG8sIGludCBsZW4pCnsKICAgIGNoYXIgICAgICAgICAgICBxdW90ZTsKICAgIGlmICghZnJvbSB8fCAhdG8pCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBpZiAoKCpmcm9tID09ICdcIicpIHx8ICgqZnJvbSA9PSAnXCcnKSkgewogICAgICAgIHF1b3RlID0gKihmcm9tKyspOwogICAgICAgIHdoaWxlICgoKmZyb20gIT0gcXVvdGUpICYmICgqZnJvbSAhPSAwKSkgewogICAgICAgICAgICBpZiAoKCpmcm9tID09ICdcXCcpICYmICgqKGZyb20gKyAxKSAhPSAwKSkgewogICAgICAgICAgICAgICAgaWYgKGxlbiA+IDApIHsgIC8qIGRvbid0IGNvcHkgYmV5b25kIGxlbiBieXRlcyAqLwogICAgICAgICAgICAgICAgICAgICp0bysrID0gKihmcm9tICsgMSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKC0tbGVuID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICoodG8gLSAxKSA9ICdcMCc7ICAgICAgIC8qIG51bGwgcHJvdGVjdCB0aGUgbGFzdCBzcG90ICovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmcm9tID0gZnJvbSArIDI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAobGVuID4gMCkgeyAgLyogZG9uJ3QgY29weSBiZXlvbmQgbGVuIGJ5dGVzICovCiAgICAgICAgICAgICAgICAgICAgKnRvKysgPSAqZnJvbSsrOwogICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbiA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAqKHRvIC0gMSkgPSAnXDAnOyAgICAgICAvKiBudWxsIHByb3RlY3QgdGhlIGxhc3Qgc3BvdCAqLwogICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgZnJvbSsrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgqZnJvbSA9PSAwKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19jb3B5X3dvcmQiLAogICAgICAgICAgICAgICAgICAgICAgICAibm8gZW5kIHF1b3RlIGZvdW5kIGluIGNvbmZpZyBzdHJpbmdcbiIpKTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgZnJvbSsrOwogICAgfSBlbHNlIHsKICAgICAgICB3aGlsZSAoKmZyb20gIT0gMCAmJiAhaXNzcGFjZSgqZnJvbSkpIHsKICAgICAgICAgICAgaWYgKCgqZnJvbSA9PSAnXFwnKSAmJiAoKihmcm9tICsgMSkgIT0gMCkpIHsKICAgICAgICAgICAgICAgIGlmIChsZW4gPiAwKSB7ICAvKiBkb24ndCBjb3B5IGJleW9uZCBsZW4gYnl0ZXMgKi8KICAgICAgICAgICAgICAgICAgICAqdG8rKyA9ICooZnJvbSArIDEpOwogICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbiA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAqKHRvIC0gMSkgPSAnXDAnOyAgICAgICAvKiBudWxsIHByb3RlY3QgdGhlIGxhc3Qgc3BvdCAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnJvbSA9IGZyb20gKyAyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGxlbiA+IDApIHsgIC8qIGRvbid0IGNvcHkgYmV5b25kIGxlbiBieXRlcyAqLwogICAgICAgICAgICAgICAgICAgICp0bysrID0gKmZyb20rKzsKICAgICAgICAgICAgICAgICAgICBpZiAoLS1sZW4gPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgKih0byAtIDEpID0gJ1wwJzsgICAgICAgLyogbnVsbCBwcm90ZWN0IHRoZSBsYXN0IHNwb3QgKi8KICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgIGZyb20rKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGlmIChsZW4gPiAwKQogICAgICAgICp0byA9IDA7CiAgICBmcm9tID0gc2tpcF93aGl0ZShmcm9tKTsKICAgIHJldHVybiAoZnJvbSk7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY29weV93b3JkICovCgovKgogKiBjb3B5X3dvcmQKICogY29waWVzIHRoZSBuZXh0ICd0b2tlbicgZnJvbSAnZnJvbScgaW50byAndG8nLgogKiBjdXJyZW50bHkgYSB0b2tlbiBpcyBhbnl0aGluZyBzZXBlcmF0ZSBieSB3aGl0ZSBzcGFjZQogKiBvciB3aXRoaW4gcXVvdGVzIChkb3VibGUgb3Igc2luZ2xlKSAoaS5lLiAidGhlIHJlZCByb3NlIiAKICogaXMgb25lIHRva2VuLCBcInRoZSByZWQgcm9zZVwiIGlzIHRocmVlIHRva2VucykKICogYSAnXCcgY2hhcmFjdGVyIHdpbGwgYWxsb3cgYSBxdW90ZSBjaGFyYWN0ZXIgdG8gYmUgdHJlYXRlZAogKiBhcyBhIHJlZ3VsYXIgY2hhcmFjdGVyIAogKiBJdCByZXR1cm5zIGEgcG9pbnRlciB0byBmaXJzdCBub24td2hpdGUgc3BhY2UgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgdG9rZW4KICogYmVpbmcgY29waWVkIG9yIHRvIDAgaWYgd2UgcmVhY2ggdGhlIGVuZC4KICovCgpzdGF0aWMgaW50ICAgICAgaGF2ZV93YXJuZWQgPSAwOwpjaGFyICAgICAgICAgICAqCmNvcHlfd29yZChjaGFyICpmcm9tLCBjaGFyICp0bykKewogICAgaWYgKCFoYXZlX3dhcm5lZCkgewogICAgICAgIHNubXBfbG9nKExPR19JTkZPLAogICAgICAgICAgICAgICAgICJjb3B5X3dvcmQoKSBjYWxsZWQuICBVc2UgY29weV9ud29yZCgpIGluc3RlYWQuXG4iKTsKICAgICAgICBoYXZlX3dhcm5lZCA9IDE7CiAgICB9CiAgICByZXR1cm4gY29weV9ud29yZChmcm9tLCB0bywgU1BSSU5UX01BWF9MRU4pOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNvcHlfd29yZCAqLwoKLyoqCiAqIFN0b3JlcyBhbiBxdW90ZWQgdmVyc2lvbiBvZiB0aGUgZmlyc3QgbGVuIGJ5dGVzIGZyb20gc3RyIGludG8gc2F2ZXRvLgogKgogKiBJZiBhbGwgb2N0ZXRzIGluIHN0ciBhcmUgaW4gdGhlIHNldCBbWzphbG51bTpdIF0gdGhlbiB0aGUgcXVvdGF0aW9uCiAqIGlzIHRvIGVuY2xvc2UgdGhlIHN0cmluZyBpbiBxdW90YXRpb24gbWFya3MgKCJzdHIiKSBvdGhlcndpc2UgdGhlCiAqIHF1b3RhdGlvbiBpcyB0byBwcmVwZW5kIHRoZSBzdHJpbmcgMHggYW5kIHRoZW4gYWRkIHRoZSBoZXggcmVwcmVzZW50YXRpb24KICogb2YgYWxsIGNoYXJhY3RlcnMgZnJvbSBzdHIgKDB4NzM3NDcyKQogKgogKiBAcGFyYW1baW5dIHNhdmV0byBwb2ludGVyIHRvIG91dHB1dCBzdHJlYW0sIGlzIGFzc3VtZWQgdG8gYmUgYmlnIGVub3VnaC4KICogQHBhcmFtW2luXSBzdHIgcG9pbnRlciBvZiB0aGUgZGF0YSB0aGF0IGlzIHRvIGJlIHN0b3JlZC4KICogQHBhcmFtW2luXSBsZW4gbGVuZ3RoIG9mIHRoZSBkYXRhIHRoYXQgaXMgdG8gYmUgc3RvcmVkLgogKiBAcmV0dXJuIEEgcG9pbnRlciB0byBzYXZldG8gYWZ0ZXIgc3RyIGlzIGFkZGVkIHRvIGl0LgogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZyhjaGFyICpzYXZldG8sIGNvbnN0IHVfY2hhciAqIHN0ciwgc2l6ZV90IGxlbikKewogICAgc2l6ZV90ICAgICAgICAgIGk7CiAgICBjb25zdCB1X2NoYXIgICAqY3A7CgogICAgLyoKICAgICAqIGlzIGV2ZXJ5dGhpbmcgZWFzaWx5IHByaW50YWJsZQogICAgICovCiAgICBmb3IgKGkgPSAwLCBjcCA9IHN0cjsgaSA8IGxlbiAmJiBjcCAmJgogICAgICAgICAoaXNhbHBoYSgqY3ApIHx8IGlzZGlnaXQoKmNwKSB8fCAqY3AgPT0gJyAnKTsgY3ArKywgaSsrKTsKCiAgICBpZiAobGVuICE9IDAgJiYgaSA9PSBsZW4pIHsKICAgICAgICAqc2F2ZXRvKysgPSAnIic7CiAgICAgICAgbWVtY3B5KHNhdmV0bywgc3RyLCBsZW4pOwogICAgICAgIHNhdmV0byArPSBsZW47CiAgICAgICAgKnNhdmV0bysrID0gJyInOwogICAgICAgICpzYXZldG8gPSAnXDAnOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RyICE9IE5VTEwpIHsKICAgICAgICAgICAgc3ByaW50ZihzYXZldG8sICIweCIpOwogICAgICAgICAgICBzYXZldG8gKz0gMjsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgICAgICAgICBzcHJpbnRmKHNhdmV0bywgIiUwMngiLCBzdHJbaV0pOwogICAgICAgICAgICAgICAgc2F2ZXRvID0gc2F2ZXRvICsgMjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNwcmludGYoc2F2ZXRvLCAiXCJcIiIpOwogICAgICAgICAgICBzYXZldG8gKz0gMjsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gc2F2ZXRvOwp9CgovKgogKiByZWFkX2NvbmZpZ19yZWFkX29jdGV0X3N0cmluZygpOiByZWFkcyBhbiBvY3RldCBzdHJpbmcgdGhhdCB3YXMKICogc2F2ZWQgYnkgdGhlIHJlYWRfY29uZmlnX3NhdmVfb2N0ZXRfc3RyaW5nKCkgZnVuY3Rpb24gCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKGNoYXIgKnJlYWRmcm9tLCB1X2NoYXIgKiogc3RyLCBzaXplX3QgKiBsZW4pCnsKICAgIHVfY2hhciAgICAgICAgICpjcHRyID0gTlVMTDsKICAgIGNoYXIgICAgICAgICAgICpjcHRyMTsKICAgIHVfaW50ICAgICAgICAgICB0bXA7CiAgICBpbnQgICAgICAgICAgICAgaTsKICAgIHNpemVfdCAgICAgICAgICBpbGVuOwoKICAgIGlmIChyZWFkZnJvbSA9PSBOVUxMIHx8IHN0ciA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmIChzdHJuY2FzZWNtcChyZWFkZnJvbSwgIjB4IiwgMikgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogQSBoZXggc3RyaW5nIHN1Ym1pdHRlZC4gSG93IGxvbmc/IAogICAgICAgICAqLwogICAgICAgIHJlYWRmcm9tICs9IDI7CiAgICAgICAgY3B0cjEgPSBza2lwX25vdF93aGl0ZShyZWFkZnJvbSk7CiAgICAgICAgaWYgKGNwdHIxKQogICAgICAgICAgICBpbGVuID0gKGNwdHIxIC0gcmVhZGZyb20pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgaWxlbiA9IHN0cmxlbihyZWFkZnJvbSk7CgogICAgICAgIGlmIChpbGVuICUgMikgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywiaW52YWxpZCBoZXggc3RyaW5nOiB3cm9uZyBsZW5ndGhcbiIpOwogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBoZXggc3RyaW5nOiB3cm9uZyBsZW5ndGgiKSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICBpbGVuID0gaWxlbiAvIDI7CgogICAgICAgIC8qCiAgICAgICAgICogbWFsbG9jIGRhdGEgc3BhY2UgaWYgbmVlZGVkICgrMSBmb3IgZ29vZCBtZWFzdXJlKSAKICAgICAgICAgKi8KICAgICAgICBpZiAoKnN0ciA9PSBOVUxMKSB7CiAgICAgICAgICAgIGlmICgoY3B0ciA9ICh1X2NoYXIgKikgbWFsbG9jKGlsZW4gKyAxKSkgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKnN0ciA9IGNwdHI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZG9uJ3QgcmVxdWlyZSBjYWxsZXIgdG8gaGF2ZSArMSBmb3IgZ29vZCBtZWFzdXJlLCBhbmQgCiAgICAgICAgICAgICAqIGJhaWwgaWYgbm90IGVub3VnaCBzcGFjZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChpbGVuID4gKmxlbikgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsImJ1ZmZlciB0b28gc21hbGwgdG8gcmVhZCBvY3RldCBzdHJpbmcgKCVsdSA8ICVsdSlcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZykqbGVuLCAodW5zaWduZWQgbG9uZylpbGVuKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19yZWFkX29jdGV0X3N0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYnVmZmVyIHRvbyBzbWFsbCAoJWx1IDwgJWx1KSIsICh1bnNpZ25lZCBsb25nKSpsZW4sICh1bnNpZ25lZCBsb25nKWlsZW4pKTsKICAgICAgICAgICAgICAgIGNwdHIxID0gc2tpcF9ub3Rfd2hpdGUocmVhZGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHNraXBfd2hpdGUoY3B0cjEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNwdHIgPSAqc3RyOwogICAgICAgIH0KICAgICAgICAqbGVuID0gaWxlbjsKCiAgICAgICAgLyoKICAgICAgICAgKiBjb3B5IHZhbGlkYXRlZCBkYXRhIAogICAgICAgICAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAoaW50KSAqbGVuOyBpKyspIHsKICAgICAgICAgICAgaWYgKDEgPT0gc3NjYW5mKHJlYWRmcm9tLCAiJTJ4IiwgJnRtcCkpCiAgICAgICAgICAgICAgICAqY3B0cisrID0gKHVfY2hhcikgdG1wOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiB3ZSBtYXkgbG9zZSBtZW1vcnksIGJ1dCBkb24ndCBrbm93IGNhbGxlcidzIGJ1ZmZlciBYWCBmcmVlKGNwdHIpOyAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZWFkZnJvbSArPSAyOwogICAgICAgIH0KICAgICAgICAvKgogICAgICAgICAqIG9ubHkgbnVsbCB0ZXJtaW5hdGUgaWYgd2UgaGF2ZSB0aGUgc3BhY2UKICAgICAgICAgKi8KICAgICAgICBpZiAoaWxlbiA+ICpsZW4pIHsKICAgICAgICAgICAgaWxlbiA9ICpsZW4tMTsKICAgICAgICAgICAgKmNwdHIrKyA9ICdcMCc7CiAgICAgICAgfQogICAgICAgIHJlYWRmcm9tID0gc2tpcF93aGl0ZShyZWFkZnJvbSk7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogTm9ybWFsIHN0cmluZyAKICAgICAgICAgKi8KCiAgICAgICAgLyoKICAgICAgICAgKiBtYWxsb2Mgc3RyaW5nIHNwYWNlIGlmIG5lZWRlZCAoaW5jbHVkaW5nIE5VTEwgdGVybWluYXRvcikgCiAgICAgICAgICovCiAgICAgICAgaWYgKCpzdHIgPT0gTlVMTCkgewogICAgICAgICAgICBjaGFyICAgICAgICAgICAgYnVmW1NOTVBfTUFYQlVGXTsKICAgICAgICAgICAgcmVhZGZyb20gPSBjb3B5X253b3JkKHJlYWRmcm9tLCBidWYsIHNpemVvZihidWYpKTsKCiAgICAgICAgICAgICpsZW4gPSBzdHJsZW4oYnVmKTsKICAgICAgICAgICAgaWYgKChjcHRyID0gKHVfY2hhciAqKSBtYWxsb2MoKmxlbiArIDEpKSA9PSBOVUxMKQogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICpzdHIgPSBjcHRyOwogICAgICAgICAgICBpZiAoY3B0cikgewogICAgICAgICAgICAgICAgbWVtY3B5KGNwdHIsIGJ1ZiwgKmxlbiArIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVhZGZyb20gPSBjb3B5X253b3JkKHJlYWRmcm9tLCAoY2hhciAqKSAqc3RyLCAqbGVuKTsKICAgICAgICAgICAgKmxlbiA9IHN0cmxlbigoY2hhciAqKSAqc3RyKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlYWRmcm9tOwp9CgoKLyoKICogcmVhZF9jb25maWdfc2F2ZV9vYmppZCgpOiBzYXZlcyBhbiBvYmppZCBhcyBhIG51bWVyaWNhbCBzdHJpbmcgCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3NhdmVfb2JqaWQoY2hhciAqc2F2ZXRvLCBvaWQgKiBvYmppZCwgc2l6ZV90IGxlbikKewogICAgaW50ICAgICAgICAgICAgIGk7CgogICAgaWYgKGxlbiA9PSAwKSB7CiAgICAgICAgc3RyY2F0KHNhdmV0bywgIk5VTEwiKTsKICAgICAgICBzYXZldG8gKz0gc3RybGVuKHNhdmV0byk7CiAgICAgICAgcmV0dXJuIHNhdmV0bzsKICAgIH0KCiAgICAvKgogICAgICogaW4gY2FzZSBsZW49MCwgdGhpcyBtYWtlcyBpdCBlYXNpZXIgdG8gcmVhZCBpdCBiYWNrIGluIAogICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgKGludCkgbGVuOyBpKyspIHsKICAgICAgICBzcHJpbnRmKHNhdmV0bywgIi4lbGQiLCBvYmppZFtpXSk7CiAgICAgICAgc2F2ZXRvICs9IHN0cmxlbihzYXZldG8pOwogICAgfQogICAgcmV0dXJuIHNhdmV0bzsKfQoKLyoKICogcmVhZF9jb25maWdfcmVhZF9vYmppZCgpOiByZWFkcyBhbiBvYmppZCBmcm9tIGEgZm9ybWF0IHNhdmVkIGJ5IHRoZSBhYm92ZSAKICovCmNoYXIgICAgICAgICAgICoKcmVhZF9jb25maWdfcmVhZF9vYmppZChjaGFyICpyZWFkZnJvbSwgb2lkICoqIG9iamlkLCBzaXplX3QgKiBsZW4pCnsKCiAgICBpZiAob2JqaWQgPT0gTlVMTCB8fCByZWFkZnJvbSA9PSBOVUxMIHx8IGxlbiA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICgqb2JqaWQgPT0gTlVMTCkgewogICAgICAgICpsZW4gPSAwOwogICAgICAgIGlmICgoKm9iamlkID0gKG9pZCAqKSBtYWxsb2MoTUFYX09JRF9MRU4gKiBzaXplb2Yob2lkKSkpID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICpsZW4gPSBNQVhfT0lEX0xFTjsKICAgIH0KCiAgICBpZiAoc3RybmNtcChyZWFkZnJvbSwgIk5VTEwiLCA0KSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBudWxsIGxlbmd0aCBvaWQgCiAgICAgICAgICovCiAgICAgICAgKmxlbiA9IDA7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogcXVhbGlmeSB0aGUgc3RyaW5nIGZvciByZWFkX29iamlkIAogICAgICAgICAqLwogICAgICAgIGNoYXIgICAgICAgICAgICBidWZbU1BSSU5UX01BWF9MRU5dOwogICAgICAgIGNvcHlfbndvcmQocmVhZGZyb20sIGJ1Ziwgc2l6ZW9mKGJ1ZikpOwoKICAgICAgICBpZiAoIXJlYWRfb2JqaWQoYnVmLCAqb2JqaWQsIGxlbikpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnX3JlYWRfb2JqaWQiLCAiSW52YWxpZCBPSUQiKSk7CiAgICAgICAgICAgICpsZW4gPSAwOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgcmVhZGZyb20gPSBza2lwX3Rva2VuKHJlYWRmcm9tKTsKICAgIHJldHVybiByZWFkZnJvbTsKfQoKLyoqCiAqIHJlYWRfY29uZmlnX3JlYWRfZGF0YSByZWFkcyBkYXRhIG9mIGEgZ2l2ZW4gdHlwZSBmcm9tIGEgdG9rZW4ocykgb24gYQogKiBjb25maWd1cmF0aW9uIGxpbmUuICBUaGUgc3VwcG9ydGVkIHR5cGVzIGFyZToKICoKICogICAgLSBBU05fSU5URUdFUgogKiAgICAtIEFTTl9USU1FVElDS1MKICogICAgLSBBU05fVU5TSUdORUQKICogICAgLSBBU05fT0NURVRfU1RSCiAqICAgIC0gQVNOX0JJVF9TVFIKICogICAgLSBBU05fT0JKRUNUX0lECiAqCiAqIEBwYXJhbSB0eXBlIHRoZSBhc24gZGF0YSB0eXBlIHRvIGJlIHJlYWQgaW4uCiAqCiAqIEBwYXJhbSByZWFkZnJvbSB0aGUgY29uZmlndXJhdGlvbiBsaW5lIGRhdGEgdG8gYmUgcmVhZC4KICoKICogQHBhcmFtIGRhdGFwdHIgYW4gYWxsb2NhdGVkIHBvaW50ZXIgZXhwZWN0ZWQgdG8gbWF0Y2ggdGhlIHR5cGUgYmVpbmcgcmVhZAogKiAgICAgICAgKGludCAqLCB1X2ludCAqLCBjaGFyICoqLCBvaWQgKiopCiAqCiAqIEBwYXJhbSBsZW4gaXMgdGhlIGxlbmd0aCBvZiBhbiBhc24gb2lkIG9yIG9jdGV0L2JpdCBzdHJpbmcsIG5vdCByZXF1aXJlZAogKiAgICAgICAgICAgIGZvciB0aGUgYXNuIGludGVnZXIsIHVuc2lnbmVkIGludGVnZXIsIGFuZCB0aW1ldGlja3MgdHlwZXMKICoKICogQHJldHVybiB0aGUgbmV4dCB0b2tlbiBpbiB0aGUgY29uZmlndXJhdGlvbiBsaW5lLiAgTlVMTCBpZiBub25lIGxlZnQgb3IKICogaWYgYW4gdW5rbm93biB0eXBlLgogKiAKICovCmNoYXIgICAgICAgICAgICoKcmVhZF9jb25maWdfcmVhZF9kYXRhKGludCB0eXBlLCBjaGFyICpyZWFkZnJvbSwgdm9pZCAqZGF0YXB0ciwKICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqIGxlbikKewogICAgaW50ICAgICAgICAgICAgKmludHA7CiAgICBjaGFyICAgICAgICAgICoqY2hhcnBwOwogICAgb2lkICAgICAgICAgICAqKm9pZHBwOwogICAgdW5zaWduZWQgaW50ICAgKnVpbnRwOwoKICAgIGlmIChkYXRhcHRyICYmIHJlYWRmcm9tKQogICAgICAgIHN3aXRjaCAodHlwZSkgewogICAgICAgIGNhc2UgQVNOX0lOVEVHRVI6CiAgICAgICAgICAgIGludHAgPSAoaW50ICopIGRhdGFwdHI7CiAgICAgICAgICAgICppbnRwID0gYXRvaShyZWFkZnJvbSk7CiAgICAgICAgICAgIHJlYWRmcm9tID0gc2tpcF90b2tlbihyZWFkZnJvbSk7CiAgICAgICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICAgICAgY2FzZSBBU05fVElNRVRJQ0tTOgogICAgICAgIGNhc2UgQVNOX1VOU0lHTkVEOgogICAgICAgICAgICB1aW50cCA9ICh1bnNpZ25lZCBpbnQgKikgZGF0YXB0cjsKICAgICAgICAgICAgKnVpbnRwID0gc3RydG91bChyZWFkZnJvbSwgTlVMTCwgMCk7CiAgICAgICAgICAgIHJlYWRmcm9tID0gc2tpcF90b2tlbihyZWFkZnJvbSk7CiAgICAgICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICAgICAgY2FzZSBBU05fSVBBRERSRVNTOgogICAgICAgICAgICBpbnRwID0gKGludCAqKSBkYXRhcHRyOwogICAgICAgICAgICAqaW50cCA9IGluZXRfYWRkcihyZWFkZnJvbSk7CiAgICAgICAgICAgIGlmICgoKmludHAgPT0gLTEpICYmCiAgICAgICAgICAgICAgICAoc3RybmNtcChyZWFkZnJvbSwgIjI1NS4yNTUuMjU1LjI1NSIsIDE1KSAhPSAwKSkKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICByZWFkZnJvbSA9IHNraXBfdG9rZW4ocmVhZGZyb20pOwogICAgICAgICAgICByZXR1cm4gcmVhZGZyb207CgogICAgICAgIGNhc2UgQVNOX09DVEVUX1NUUjoKICAgICAgICBjYXNlIEFTTl9CSVRfU1RSOgogICAgICAgICAgICBjaGFycHAgPSAoY2hhciAqKikgZGF0YXB0cjsKICAgICAgICAgICAgcmV0dXJuIHJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKHJlYWRmcm9tLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKikgY2hhcnBwLCBsZW4pOwoKICAgICAgICBjYXNlIEFTTl9PQkpFQ1RfSUQ6CiAgICAgICAgICAgIG9pZHBwID0gKG9pZCAqKikgZGF0YXB0cjsKICAgICAgICAgICAgcmV0dXJuIHJlYWRfY29uZmlnX3JlYWRfb2JqaWQocmVhZGZyb20sIG9pZHBwLCBsZW4pOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfcmVhZF9kYXRhIiwgIkZhaWw6IFVua25vd24gdHlwZTogJWQiLAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlKSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKgogKiByZWFkX2NvbmZpZ19yZWFkX21lbW9yeSgpOgogKiAKICogc2ltaWxhciB0byByZWFkX2NvbmZpZ19yZWFkX2RhdGEsIGJ1dCBleHBlY3RzIGEgZ2VuZXJpYyBtZW1vcnkKICogcG9pbnRlciByYXRoZXIgdGhhbiBhIHNwZWNpZmljIHR5cGUgb2YgcG9pbnRlci4gIExlbiBpcyBleHBlY3RlZCB0bwogKiBiZSB0aGUgYW1vdW50IG9mIGF2YWlsYWJsZSBtZW1vcnkuCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3JlYWRfbWVtb3J5KGludCB0eXBlLCBjaGFyICpyZWFkZnJvbSwKICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqZGF0YXB0ciwgc2l6ZV90ICogbGVuKQp7CiAgICBpbnQgICAgICAgICAgICAqaW50cDsKICAgIHVuc2lnbmVkIGludCAgICp1aW50cDsKICAgIGNoYXIgICAgICAgICAgICBidWZbU1BSSU5UX01BWF9MRU5dOwoKICAgIGlmICghZGF0YXB0ciB8fCAhcmVhZGZyb20pCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIEFTTl9JTlRFR0VSOgogICAgICAgIGlmICgqbGVuIDwgc2l6ZW9mKGludCkpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIGludHAgPSAoaW50ICopIGRhdGFwdHI7CiAgICAgICAgcmVhZGZyb20gPSBjb3B5X253b3JkKHJlYWRmcm9tLCBidWYsIHNpemVvZihidWYpKTsKICAgICAgICAqaW50cCA9IGF0b2koYnVmKTsKICAgICAgICAqbGVuID0gc2l6ZW9mKGludCk7CiAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwoKICAgIGNhc2UgQVNOX0NPVU5URVI6CiAgICBjYXNlIEFTTl9USU1FVElDS1M6CiAgICBjYXNlIEFTTl9VTlNJR05FRDoKICAgICAgICBpZiAoKmxlbiA8IHNpemVvZih1bnNpZ25lZCBpbnQpKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB1aW50cCA9ICh1bnNpZ25lZCBpbnQgKikgZGF0YXB0cjsKICAgICAgICByZWFkZnJvbSA9IGNvcHlfbndvcmQocmVhZGZyb20sIGJ1Ziwgc2l6ZW9mKGJ1ZikpOwogICAgICAgICp1aW50cCA9IHN0cnRvdWwoYnVmLCBOVUxMLCAwKTsKICAgICAgICAqbGVuID0gc2l6ZW9mKHVuc2lnbmVkIGludCk7CiAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwoKICAgIGNhc2UgQVNOX0lQQUREUkVTUzoKICAgICAgICBpZiAoKmxlbiA8IHNpemVvZihpbnQpKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICBpbnRwID0gKGludCAqKSBkYXRhcHRyOwogICAgICAgIHJlYWRmcm9tID0gY29weV9ud29yZChyZWFkZnJvbSwgYnVmLCBzaXplb2YoYnVmKSk7CiAgICAgICAgKmludHAgPSBpbmV0X2FkZHIoYnVmKTsKICAgICAgICBpZiAoKCppbnRwID09IC0xKSAmJiAoc3RyY21wKGJ1ZiwgIjI1NS4yNTUuMjU1LjI1NSIpICE9IDApKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAqbGVuID0gc2l6ZW9mKGludCk7CiAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwoKICAgIGNhc2UgQVNOX09DVEVUX1NUUjoKICAgIGNhc2UgQVNOX0JJVF9TVFI6CiAgICBjYXNlIEFTTl9QUklWX0lNUExJRURfT0NURVRfU1RSOgogICAgICAgIHJldHVybiByZWFkX2NvbmZpZ19yZWFkX29jdGV0X3N0cmluZyhyZWFkZnJvbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKikgJiBkYXRhcHRyLCBsZW4pOwoKICAgIGNhc2UgQVNOX1BSSVZfSU1QTElFRF9PQkpFQ1RfSUQ6CiAgICBjYXNlIEFTTl9PQkpFQ1RfSUQ6CiAgICAgICAgcmVhZGZyb20gPQogICAgICAgICAgICByZWFkX2NvbmZpZ19yZWFkX29iamlkKHJlYWRmcm9tLCAob2lkICoqKSAmIGRhdGFwdHIsIGxlbik7CiAgICAgICAgKmxlbiAqPSBzaXplb2Yob2lkKTsKICAgICAgICByZXR1cm4gcmVhZGZyb207CgogICAgY2FzZSBBU05fQ09VTlRFUjY0OgogICAgICAgIGlmICgqbGVuIDwgc2l6ZW9mKFU2NCkpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICpsZW4gPSBzaXplb2YoVTY0KTsKICAgICAgICByZWFkNjQoKFU2NCAqKSBkYXRhcHRyLCByZWFkZnJvbSk7CiAgICAgICAgcmVhZGZyb20gPSBza2lwX3Rva2VuKHJlYWRmcm9tKTsKICAgICAgICByZXR1cm4gcmVhZGZyb207CiAgICB9CgogICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnX3JlYWRfbWVtb3J5IiwgIkZhaWw6IFVua25vd24gdHlwZTogJWQiLCB0eXBlKSk7CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqCiAqIHJlYWRfY29uZmlnX3N0b3JlX2RhdGEgc3RvcmVzIGRhdGEgb2YgYSBnaXZlbiB0eXBlIHRvIGEgY29uZmlndXJhdGlvbiBsaW5lCiAqIGludG8gdGhlIHN0b3JldG8gYnVmZmVyLgogKiBDYWxscyByZWFkX2NvbmZpZ19zdG9yZV9kYXRhX3ByZWZpeCB3aXRoIHRoZSBwcmVmaXggcGFyYW1ldGVyIHNldCB0byBhIGNoYXIKICogc3BhY2UuICBUaGUgc3VwcG9ydGVkIHR5cGVzIGFyZToKICoKICogICAgLSBBU05fSU5URUdFUgogKiAgICAtIEFTTl9USU1FVElDS1MKICogICAgLSBBU05fVU5TSUdORUQKICogICAgLSBBU05fT0NURVRfU1RSCiAqICAgIC0gQVNOX0JJVF9TVFIKICogICAgLSBBU05fT0JKRUNUX0lECiAqCiAqIEBwYXJhbSB0eXBlICAgIHRoZSBhc24gZGF0YSB0eXBlIHRvIGJlIHN0b3JlZAogKgogKiBAcGFyYW0gc3RvcmV0byBhIHByZS1hbGxvY2F0ZWQgY2hhciBidWZmZXIgd2hpY2ggd2lsbCBjb250YWluIHRoZSBkYXRhCiAqICAgICAgICAgICAgICAgIHRvIGJlIHN0b3JlZAogKgogKiBAcGFyYW0gZGF0YXB0ciBjb250YWlucyB0aGUgdmFsdWUgdG8gYmUgc3RvcmVkLCB0aGUgc3VwcG9ydGVkIHBvaW50ZXJzOgogKiAgICAgICAgICAgICAgICAoaW50ICosIHVfaW50ICosIGNoYXIgKiosIG9pZCAqKikKICoKICogQHBhcmFtIGxlbiAgICAgaXMgdGhlIGxlbmd0aCBvZiB0aGUgdmFsdWUgdG8gYmUgc3RvcmVkCiAqICAgICAgICAgICAgICAgIChub3QgcmVxdWlyZWQgZm9yIHRoZSBhc24gaW50ZWdlciwgdW5zaWduZWQgaW50ZWdlciwKICogICAgICAgICAgICAgICAgIGFuZCB0aW1ldGlja3MgdHlwZXMpCiAqCiAqIEByZXR1cm4gY2hhcmFjdGVyIHBvaW50ZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGluZS4gTlVMTCBpZiBhbiB1bmtub3duIHR5cGUuCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3N0b3JlX2RhdGEoaW50IHR5cGUsIGNoYXIgKnN0b3JldG8sIHZvaWQgKmRhdGFwdHIsIHNpemVfdCAqIGxlbikKewogICAgcmV0dXJuIHJlYWRfY29uZmlnX3N0b3JlX2RhdGFfcHJlZml4KCcgJywgdHlwZSwgc3RvcmV0bywgZGF0YXB0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxlbiA/ICpsZW4gOiAwKSk7Cn0KCmNoYXIgICAgICAgICAgICoKcmVhZF9jb25maWdfc3RvcmVfZGF0YV9wcmVmaXgoY2hhciBwcmVmaXgsIGludCB0eXBlLCBjaGFyICpzdG9yZXRvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpkYXRhcHRyLCBzaXplX3QgbGVuKQp7CiAgICBpbnQgICAgICAgICAgICAqaW50cDsKICAgIHVfY2hhciAgICAgICAgKipjaGFycHA7CiAgICB1bnNpZ25lZCBpbnQgICAqdWludHA7CiAgICBzdHJ1Y3QgaW5fYWRkciAgaW47CiAgICBvaWQgICAgICAgICAgICoqb2lkcHA7CgogICAgaWYgKGRhdGFwdHIgJiYgc3RvcmV0bykKICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIEFTTl9JTlRFR0VSOgogICAgICAgICAgICBpbnRwID0gKGludCAqKSBkYXRhcHRyOwogICAgICAgICAgICBzcHJpbnRmKHN0b3JldG8sICIlYyVkIiwgcHJlZml4LCAqaW50cCk7CiAgICAgICAgICAgIHJldHVybiAoc3RvcmV0byArIHN0cmxlbihzdG9yZXRvKSk7CgogICAgICAgIGNhc2UgQVNOX1RJTUVUSUNLUzoKICAgICAgICBjYXNlIEFTTl9VTlNJR05FRDoKICAgICAgICAgICAgdWludHAgPSAodW5zaWduZWQgaW50ICopIGRhdGFwdHI7CiAgICAgICAgICAgIHNwcmludGYoc3RvcmV0bywgIiVjJXUiLCBwcmVmaXgsICp1aW50cCk7CiAgICAgICAgICAgIHJldHVybiAoc3RvcmV0byArIHN0cmxlbihzdG9yZXRvKSk7CgogICAgICAgIGNhc2UgQVNOX0lQQUREUkVTUzoKICAgICAgICAgICAgaW4uc19hZGRyID0gKih1bnNpZ25lZCBpbnQgKikgZGF0YXB0cjsgCiAgICAgICAgICAgIHNwcmludGYoc3RvcmV0bywgIiVjJXMiLCBwcmVmaXgsIGluZXRfbnRvYShpbikpOwogICAgICAgICAgICByZXR1cm4gKHN0b3JldG8gKyBzdHJsZW4oc3RvcmV0bykpOwoKICAgICAgICBjYXNlIEFTTl9PQ1RFVF9TVFI6CiAgICAgICAgY2FzZSBBU05fQklUX1NUUjoKICAgICAgICAgICAgKnN0b3JldG8rKyA9IHByZWZpeDsKICAgICAgICAgICAgY2hhcnBwID0gKHVfY2hhciAqKikgZGF0YXB0cjsKICAgICAgICAgICAgcmV0dXJuIHJlYWRfY29uZmlnX3NhdmVfb2N0ZXRfc3RyaW5nKHN0b3JldG8sICpjaGFycHAsIGxlbik7CgogICAgICAgIGNhc2UgQVNOX09CSkVDVF9JRDoKICAgICAgICAgICAgKnN0b3JldG8rKyA9IHByZWZpeDsKICAgICAgICAgICAgb2lkcHAgPSAob2lkICoqKSBkYXRhcHRyOwogICAgICAgICAgICByZXR1cm4gcmVhZF9jb25maWdfc2F2ZV9vYmppZChzdG9yZXRvLCAqb2lkcHAsIGxlbik7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19zdG9yZV9kYXRhX3ByZWZpeCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJGYWlsOiBVbmtub3duIHR5cGU6ICVkIiwgdHlwZSkpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICByZXR1cm4gTlVMTDsKfQovKiogQH0gKi8K