LyoKICogcmVhZF9jb25maWcuYwogKi8KLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgovKiogQGRlZmdyb3VwIHJlYWRfY29uZmlnIHBhcnNpbmcgdmFyaW91cyBjb25maWd1cmF0aW9uIGZpbGVzIGF0IHJ1biB0aW1lCiAqICBAaW5ncm91cCBsaWJyYXJ5CiAqCiAqIFRoZSByZWFkX2NvbmZpZyByZWxhdGVkIGZ1bmN0aW9ucyBhcmUgYSBmYWlybHkgZXh0ZW5zaWJsZSAgc3lzdGVtICBvZgogKiBwYXJzaW5nIHZhcmlvdXMgY29uZmlndXJhdGlvbiBmaWxlcyBhdCB0aGUgcnVuIHRpbWUuCiAqCiAqIFRoZSBpZGVhIGlzIHRoYXQgdGhlIGNhbGxpbmcgYXBwbGljYXRpb24gaXMgYWJsZSB0byByZWdpc3RlcgogKiBoYW5kbGVycyBmb3IgY2VydGFpbiB0b2tlbnMgc3BlY2lmaWVkIGluIGNlcnRhaW4gdHlwZXMKICogb2YgZmlsZXMuICBUaGUgcmVhZF9jb25maWdzIGZ1bmN0aW9uIGNhbiB0aGVuIGJlICBjYWxsZWQKICogdG8gIGxvb2sgIGZvciBhbGwgdGhlIGZpbGVzIHRoYXQgaXQgaGFzIHJlZ2lzdHJhdGlvbnMgZm9yLAogKiBmaW5kIHRoZSBmaXJzdCB3b3JkIG9uIGVhY2ggbGluZSwgYW5kIHBhc3MgIHRoZSAgcmVtYWluZGVyCiAqIHRvIHRoZSBhcHByb3ByaWF0ZWx5IHJlZ2lzdGVyZWQgaGFuZGxlci4KICoKICogRm9yIHBlcnNpc3RlbnQgY29uZmlndXJhdGlvbiBzdG9yYWdlIHlvdSB3aWxsIG5lZWQgdG8gdXNlIHRoZQogKiByZWFkX2NvbmZpZ19yZWFkX2RhdGEsIHJlYWRfY29uZmlnX3N0b3JlLCBhbmQgcmVhZF9jb25maWdfc3RvcmVfZGF0YQogKiBBUElzIGluIGNvbmp1bmN0aW9uIHdpdGggZmlyc3QgcmVnaXN0ZXJpbmcgYQogKiBjYWxsYmFjayBzbyB3aGVuIHRoZSBhZ2VudCBzaHV0c2Rvd24gZm9yIHdoYXRldmVyIHJlYXNvbiBkYXRhIGlzIHdyaXR0ZW4KICogdG8geW91ciBjb25maWd1cmF0aW9uIGZpbGVzLiAgVGhlIGZvbGxvd2luZyBleHBsYWlucyBpbiBtb3JlIGRldGFpbCB0aGUKICogc2VxdWVuY2UgdG8gbWFrZSB0aGlzIGhhcHBlbi4KICoKICogVGhpcyBpcyB0aGUgY2FsbGJhY2sgcmVnaXN0cmF0aW9uIEFQSSwgeW91IG5lZWQgdG8gY2FsbCB0aGlzIEFQSSB3aXRoCiAqIHRoZSBhcHByb3ByaWF0ZSBwYXJhbWV0ZXJzIGluIG9yZGVyIHRvIGNvbmZpZ3VyZSBwZXJzaXN0ZW50IHN0b3JhZ2UgbmVlZHMuCiAqCiAqICAgICAgICBpbnQgc25tcF9yZWdpc3Rlcl9jYWxsYmFjayhpbnQgbWFqb3IsIGludCBtaW5vciwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBDYWxsYmFjayAqbmV3X2NhbGxiYWNrLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqYXJnKTsKICoKICogWW91IHdpbGwgbmVlZCB0byBzZXQgbWFqb3IgdG8gU05NUF9DQUxMQkFDS19MSUJSQVJZLCBtaW5vciB0bwogKiBTTk1QX0NBTExCQUNLX1NUT1JFX0RBVEEuIGFyZyBpcyB3aGF0ZXZlciB5b3Ugd2FudC4KICoKICogWW91ciBjYWxsYmFjayBmdW5jdGlvbidzIHByb3RvdHlwZSBpczoKICogaW50ICAgICAoU05NUENhbGxiYWNrKSAoaW50IG1ham9ySUQsIGludCBtaW5vcklELCB2b2lkICpzZXJ2ZXJhcmcsCiAqICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xpZW50YXJnKTsKICoKICogVGhlIG1ham9ySUQsIG1pbm9ySUQgYW5kIGNsaWVudGFyZyBhcmUgd2hhdCB5b3UgcGFzc2VkIGluIHRoZSBjYWxsYmFjawogKiByZWdpc3RyYXRpb24gYWJvdmUuICBXaGVuIHRoZSBjYWxsYmFjayBpcyBjYWxsZWQgeW91IGhhdmUgdG8gZXNzZW50aWFsbHkKICogdHJhbnNmZXIgYWxsIHlvdXIgc3RhdGUgZnJvbSBtZW1vcnkgdG8gZGlzay4gWW91IGRvIHRoaXMgYnkgZ2VuZXJhdGluZwogKiBjb25maWd1cmF0aW9uIGxpbmVzIGludG8gYSBidWZmZXIuICBUaGUgbGluZXMgYXJlIG9mIHRoZSBmb3JtIHRva2VuCiAqIGZvbGxvd2VkIGJ5IHRva2VuIHBhcmFtZXRlcnMuCiAqIAogKiBGaW5hbGx5IHN0b3JpbmcgaXMgZG9uZSB1c2luZyByZWFkX2NvbmZpZ19zdG9yZSh0eXBlLCBidWZmZXIpOwogKiB0eXBlIGlzIHRoZSBhcHBsaWNhdGlvbiBuYW1lIHRoaXMgY2FuIGJlIG9idGFpbmVkIGZyb206CiAqCiAqIG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpOwogKgogKiBOb3csIHJlYWRpbmcgYmFjayB0aGUgZGF0YTogVGhpcyBpcyBkb25lIGJ5IHJlZ2lzdGVyaW5nIGEgY29uZmlnIGhhbmRsZXIKICogZm9yIHlvdXIgdG9rZW4gdXNpbmcgdGhlIHJlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyIGZ1bmN0aW9uLiBZb3VyCiAqIGhhbmRsZXIgd2lsbCBiZSBpbnZva2VkIGFuZCB5b3UgY2FuIHBhcnNlIGluIHRoZSBkYXRhIHVzaW5nIHRoZQogKiByZWFkX2NvbmZpZ19yZWFkIEFQSXMuCiAqCiAqICBAewogKi8KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX1NZU19QQVJBTV9ICiNpbmNsdWRlIDxzeXMvcGFyYW0uaD4KI2VuZGlmCiNpZiBUSU1FX1dJVEhfU1lTX1RJTUUKIyBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGluY2x1ZGUgPHRpbWUuaD4KI2Vsc2UKIyBpZiBIQVZFX1NZU19USU1FX0gKIyAgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBlbHNlCiMgIGluY2x1ZGUgPHRpbWUuaD4KIyBlbmRpZgojZW5kaWYKI2lmZGVmIEhBVkVfU1lTX1NUQVRfSAojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2VuZGlmCiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2lmIEhBVkVfQVJQQV9JTkVUX0gKI2luY2x1ZGUgPGFycGEvaW5ldC5oPgojZW5kaWYKI2lmIEhBVkVfU1lTX1NFTEVDVF9ICiNpbmNsdWRlIDxzeXMvc2VsZWN0Lmg+CiNlbmRpZgojaWYgSEFWRV9TWVNfU09DS0VUX0gKI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2VuZGlmCiNpZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaW5jbHVkZSA8ZXJybm8uaD4KCiNpZiBIQVZFX0RJUkVOVF9ICiMgaW5jbHVkZSA8ZGlyZW50Lmg+CiMgZGVmaW5lIE5BTUxFTihkaXJlbnQpIHN0cmxlbigoZGlyZW50KS0+ZF9uYW1lKQojZWxzZQojIGRlZmluZSBkaXJlbnQgZGlyZWN0CiMgZGVmaW5lIE5BTUxFTihkaXJlbnQpIChkaXJlbnQpLT5kX25hbWxlbgojIGlmIEhBVkVfU1lTX05ESVJfSAojICBpbmNsdWRlIDxzeXMvbmRpci5oPgojIGVuZGlmCiMgaWYgSEFWRV9TWVNfRElSX0gKIyAgaW5jbHVkZSA8c3lzL2Rpci5oPgojIGVuZGlmCiMgaWYgSEFWRV9ORElSX0gKIyAgaW5jbHVkZSA8bmRpci5oPgojIGVuZGlmCiNlbmRpZgoKI2lmIEhBVkVfRE1BTExPQ19ICiNpbmNsdWRlIDxkbWFsbG9jLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL3R5cGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9vdXRwdXRfYXBpLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9jb25maWdfYXBpLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3JlYWRfY29uZmlnLmg+ICAgICAgIC8qIGZvciAiaW50ZXJuYWwiIGRlZmluaXRpb25zICovCiNpbmNsdWRlIDxuZXQtc25tcC91dGlsaXRpZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L21pYi5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9wYXJzZS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9jYWxsYmFjay5oPgoKc3RhdGljIGludCAgICAgIGNvbmZpZ19lcnJvcnM7CgpzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjb25maWdfZmlsZXMgPSBOVUxMOwoKCnN0YXRpYyBzdHJ1Y3QgY29uZmlnX2xpbmUgKgppbnRlcm5hbF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0eXBlX3BhcmFtLAoJCQkJIGNvbnN0IGNoYXIgKnRva2VuLAoJCQkJIHZvaWQgKCpwYXJzZXIpIChjb25zdCBjaGFyICosIGNoYXIgKiksCgkJCQkgdm9pZCAoKnJlbGVhc2VyKSAodm9pZCksIGNvbnN0IGNoYXIgKmhlbHAsCgkJCQkgaW50IHdoZW4pCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKipjdG1wID0gJmNvbmZpZ19maWxlczsKICAgIHN0cnVjdCBjb25maWdfbGluZSAgKipsdG1wOwogICAgY29uc3QgY2hhciAgICAgICAgICAgKnR5cGUgPSB0eXBlX3BhcmFtOwoKICAgIGlmICh0eXBlID09IE5VTEwgfHwgKnR5cGUgPT0gJ1wwJykgewogICAgICAgIHR5cGUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgTkVUU05NUF9EU19MSUJfQVBQVFlQRSk7CiAgICB9CgogICAgLyoKICAgICAqIEhhbmRsZSBtdWx0aXBsZSB0eXBlcyAocmVjdXJzaXZlbHkpCiAgICAgKi8KICAgIGlmIChzdHJjaHIodHlwZSwgJzonKSkgewogICAgICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHRtcDIgPSBOVUxMOwogICAgICAgIGNoYXIgICAgICAgICAgICAgICAgYnVmW1NUUklOR01BWF07CiAgICAgICAgY2hhciAgICAgICAgICAgICAgICpjcHRyID0gYnVmOwoKICAgICAgICBzdHJsY3B5KGJ1ZiwgdHlwZSwgU1RSSU5HTUFYKTsKICAgICAgICB3aGlsZSAoY3B0cikgewogICAgICAgICAgICBjaGFyKiBjID0gY3B0cjsKICAgICAgICAgICAgY3B0ciA9IHN0cmNocihjcHRyLCAnOicpOwogICAgICAgICAgICBpZihjcHRyKSB7CiAgICAgICAgICAgICAgICAqY3B0ciA9ICdcMCc7CiAgICAgICAgICAgICAgICArK2NwdHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbHRtcDIgPSBpbnRlcm5hbF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihjLCB0b2tlbiwgcGFyc2VyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbGVhc2VyLCBoZWxwLCB3aGVuKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGx0bXAyOwogICAgfQogICAgCiAgICAvKgogICAgICogRmluZCB0eXBlIGluIGN1cnJlbnQgbGlzdCAgLU9SLSAgY3JlYXRlIGEgbmV3IGZpbGUgdHlwZS4KICAgICAqLwogICAgd2hpbGUgKCpjdG1wICE9IE5VTEwgJiYgc3RyY21wKCgqY3RtcCktPmZpbGVIZWFkZXIsIHR5cGUpKSB7CiAgICAgICAgY3RtcCA9ICYoKCpjdG1wKS0+bmV4dCk7CiAgICB9CgogICAgaWYgKCpjdG1wID09IE5VTEwpIHsKICAgICAgICAqY3RtcCA9IChzdHJ1Y3QgY29uZmlnX2ZpbGVzICopCiAgICAgICAgICAgIGNhbGxvYygxLCBzaXplb2Yoc3RydWN0IGNvbmZpZ19maWxlcykpOwogICAgICAgIGlmICghKmN0bXApIHsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQoKICAgICAgICAoKmN0bXApLT5maWxlSGVhZGVyID0gc3RyZHVwKHR5cGUpOwogICAgICAgIERFQlVHTVNHVEwoKCI5OnJlYWRfY29uZmlnOnR5cGUiLCAibmV3IHR5cGUgJXNcbiIsIHR5cGUpKTsKICAgIH0KCiAgICBERUJVR01TR1RMKCgiOTpyZWFkX2NvbmZpZzpyZWdpc3Rlcl9oYW5kbGVyIiwgInJlZ2lzdGVyaW5nICVzICVzXG4iLAogICAgICAgICAgICAgICAgdHlwZSwgdG9rZW4pKTsKICAgIC8qCiAgICAgKiBGaW5kIHBhcnNlciB0eXBlIGluIGN1cnJlbnQgbGlzdCAgLU9SLSAgY3JlYXRlIGEgbmV3CiAgICAgKiBsaW5lIHBhcnNlciBlbnRyeS4KICAgICAqLwogICAgbHRtcCA9ICYoKCpjdG1wKS0+c3RhcnQpOwoKICAgIHdoaWxlICgqbHRtcCAhPSBOVUxMICYmIHN0cmNtcCgoKmx0bXApLT5jb25maWdfdG9rZW4sIHRva2VuKSkgewogICAgICAgIGx0bXAgPSAmKCgqbHRtcCktPm5leHQpOwogICAgfQoKICAgIGlmICgqbHRtcCA9PSBOVUxMKSB7CiAgICAgICAgKmx0bXAgPSAoc3RydWN0IGNvbmZpZ19saW5lICopCiAgICAgICAgICAgIGNhbGxvYygxLCBzaXplb2Yoc3RydWN0IGNvbmZpZ19saW5lKSk7CiAgICAgICAgaWYgKCEqbHRtcCkgewogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CgogICAgICAgICgqbHRtcCktPmNvbmZpZ190aW1lID0gd2hlbjsKICAgICAgICAoKmx0bXApLT5jb25maWdfdG9rZW4gPSBzdHJkdXAodG9rZW4pOwogICAgICAgIGlmIChoZWxwICE9IE5VTEwpCiAgICAgICAgICAgICgqbHRtcCktPmhlbHAgPSBzdHJkdXAoaGVscCk7CiAgICB9CgogICAgLyoKICAgICAqIEFkZC9SZXBsYWNlIHRoZSBwYXJzZS9mcmVlIGZ1bmN0aW9ucyBmb3IgdGhlIGdpdmVuIGxpbmUgdHlwZQogICAgICogaW4gdGhlIGdpdmVuIGZpbGUgdHlwZS4KICAgICAqLwogICAgKCpsdG1wKS0+cGFyc2VfbGluZSA9IHBhcnNlcjsKICAgICgqbHRtcCktPmZyZWVfZnVuYyA9IHJlbGVhc2VyOwoKICAgIHJldHVybiAoKmx0bXApOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoKSAqLwoKc3RydWN0IGNvbmZpZ19saW5lICoKcmVnaXN0ZXJfcHJlbmV0c25tcF9taWJfaGFuZGxlcihjb25zdCBjaGFyICp0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRva2VuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKCpwYXJzZXIpIChjb25zdCBjaGFyICosIGNoYXIgKiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAoKnJlbGVhc2VyKSAodm9pZCksIGNvbnN0IGNoYXIgKmhlbHApCnsKICAgIHJldHVybiBpbnRlcm5hbF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcih0eXBlLCB0b2tlbiwgcGFyc2VyLCByZWxlYXNlciwKCQkJCQkgICAgaGVscCwgUFJFTUlCX0NPTkZJRyk7Cn0KCnN0cnVjdCBjb25maWdfbGluZSAqCnJlZ2lzdGVyX2FwcF9wcmVuZXRzbm1wX21pYl9oYW5kbGVyKGNvbnN0IGNoYXIgKnRva2VuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqcGFyc2VyKSAoY29uc3QgY2hhciAqLCBjaGFyICopLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqcmVsZWFzZXIpICh2b2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqaGVscCkKewogICAgcmV0dXJuIChyZWdpc3Rlcl9wcmVuZXRzbm1wX21pYl9oYW5kbGVyCiAgICAgICAgICAgIChOVUxMLCB0b2tlbiwgcGFyc2VyLCByZWxlYXNlciwgaGVscCkpOwp9CgovKioKICogcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIgcmVnaXN0ZXJzIGhhbmRsZXJzIGZvciBjZXJ0YWluIHRva2VucyBzcGVjaWZpZWQgaW4KICogY2VydGFpbiB0eXBlcyBvZiBmaWxlcy4KICoKICogQWxsb3dzIGEgbW9kdWxlIHdyaXRlciB1c2UvcmVnaXN0ZXIgbXVsdGlwbGUgY29uZmlndXJhdGlvbiBmaWxlcyBiYXNlZCBvZmYKICogb2YgdGhlIHR5cGUgcGFyYW1ldGVyLiAgQSBtb2R1bGUgd3JpdGVyIG1heSB3YW50IHRvIHNldCB1cCBtdWx0aXBsZQogKiBjb25maWd1cmF0aW9uIGZpbGVzIHRvIHNlcGFyYXRlIG91dCByZWxhdGVkIHRhc2tzL3ZhcmlhYmxlcyBvciBqdXN0IGZvcgogKiBtYW5hZ2VtZW50IG9mIHdoZXJlIHRvIHB1dCB0b2tlbnMgYXMgdGhlIG1vZHVsZSBvciBtb2R1bGVzIGdldCBtb3JlIGNvbXBsZXgKICogaW4gcmVnYXJkIHRvIGhhbmRsaW5nIHRva2VuIHJlZ2lzdHJhdGlvbnMuCiAqCiAqIEBwYXJhbSB0eXBlICAgICB0aGUgY29uZmlndXJhdGlvbiBmaWxlIHVzZWQsIGUuZy4sIGlmIHNubXAuY29uZiBpcyB0aGUKICogICAgICAgICAgICAgICAgIGZpbGUgd2hlcmUgdGhlIHRva2VuIGlzIGxvY2F0ZWQgdXNlICJzbm1wIiBoZXJlLgogKiAgICAgICAgICAgICAgICAgTXVsdGlwbGUgY29sb24gc2VwYXJhdGVkIHRva2VucyBtaWdodCBiZSB1c2VkLgogKiAgICAgICAgICAgICAgICAgSWYgTlVMTCBvciAiIiB0aGVuIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgdXNlZCB3aWxsIGJlCiAqICAgICAgICAgICAgICAgICBcPGFwcGxpY2F0aW9uXD4uY29uZi4KICoKICogQHBhcmFtIHRva2VuICAgIHRoZSB0b2tlbiBiZWluZyBwYXJzZWQgZnJvbSB0aGUgZmlsZS4gIE11c3QgYmUgbm9uLU5VTEwuCiAqCiAqIEBwYXJhbSBwYXJzZXIgICB0aGUgaGFuZGxlciBmdW5jdGlvbiBwb2ludGVyIHRoYXQgdXNlICB0aGUgc3BlY2lmaWVkCiAqICAgICAgICAgICAgICAgICB0b2tlbiBhbmQgdGhlIHJlc3Qgb2YgdGhlIGxpbmUgdG8gZG8gd2hhdGV2ZXIgaXMgcmVxdWlyZWQKICogICAgICAgICAgICAgICAgIFNob3VsZCBiZSBub24tTlVMTCBpbiBvcmRlciB0byBtYWtlIHVzZSBvZiB0aGlzIEFQSS4KICoKICogQHBhcmFtIHJlbGVhc2VyIGlmIG5vbi1OVUxMLCB0aGUgZnVuY3Rpb24gc3BlY2lmaWVkIGlzIGNhbGxlZCB3aGVuCiAqICAgICAgICAgICAgICAgICB1bnJlZ2lzdGVyaW5nIGNvbmZpZyBoYW5kbGVyIG9yIHdoZW4gY29uZmlndXJhdGlvbgogKiAgICAgICAgICAgICAgICAgZmlsZXMgYXJlIHJlLXJlYWQuCiAqICAgICAgICAgICAgICAgICBUaGlzIGZ1bmN0aW9uIHNob3VsZCBmcmVlIGFueSByZXNvdXJjZXMgYWxsb2NhdGVkIGJ5CiAqICAgICAgICAgICAgICAgICB0aGUgdG9rZW4gaGFuZGxlciBmdW5jdGlvbi4KICoKICogQHBhcmFtIGhlbHAgICAgIGlmIG5vbi1OVUxMLCB1c2VkIHRvIGRpc3BsYXkgaGVscCBpbmZvcm1hdGlvbiBvbiB0aGUKICogICAgICAgICAgICAgICAgIGV4cGVjdGVkIGFyZ3VtZW50cyBhZnRlciB0aGUgdG9rZW4uCiAqCiAqIEByZXR1cm4gUG9pbnRlciB0byBhIG5ldyBjb25maWcgbGluZSBlbnRyeSBvciBOVUxMIG9uIGVycm9yLgogKi8Kc3RydWN0IGNvbmZpZ19saW5lICoKcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoY29uc3QgY2hhciAqdHlwZSwKCQkJY29uc3QgY2hhciAqdG9rZW4sCgkJCXZvaWQgKCpwYXJzZXIpIChjb25zdCBjaGFyICosIGNoYXIgKiksCgkJCXZvaWQgKCpyZWxlYXNlcikgKHZvaWQpLCBjb25zdCBjaGFyICpoZWxwKQp7CiAgICByZXR1cm4gaW50ZXJuYWxfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIodHlwZSwgdG9rZW4sIHBhcnNlciwgcmVsZWFzZXIsCgkJCQkJICAgIGhlbHAsIE5PUk1BTF9DT05GSUcpOwp9CgpzdHJ1Y3QgY29uZmlnX2xpbmUgKgpyZWdpc3Rlcl9jb25zdF9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAoKnBhcnNlcikgKGNvbnN0IGNoYXIgKiwgY29uc3QgY2hhciAqKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAoKnJlbGVhc2VyKSAodm9pZCksIGNvbnN0IGNoYXIgKmhlbHApCnsKICAgIHJldHVybiBpbnRlcm5hbF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcih0eXBlLCB0b2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCgqKShjb25zdCBjaGFyICosIGNoYXIgKikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VyLCByZWxlYXNlciwKCQkJCQkgICAgaGVscCwgTk9STUFMX0NPTkZJRyk7Cn0KCnN0cnVjdCBjb25maWdfbGluZSAqCnJlZ2lzdGVyX2FwcF9jb25maWdfaGFuZGxlcihjb25zdCBjaGFyICp0b2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKCpwYXJzZXIpIChjb25zdCBjaGFyICosIGNoYXIgKiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqcmVsZWFzZXIpICh2b2lkKSwgY29uc3QgY2hhciAqaGVscCkKewogICAgcmV0dXJuIChyZWdpc3Rlcl9jb25maWdfaGFuZGxlcihOVUxMLCB0b2tlbiwgcGFyc2VyLCByZWxlYXNlciwgaGVscCkpOwp9CgoKCi8qKgogKiB1cmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIgdW4tcmVnaXN0ZXJzIGhhbmRsZXJzIGdpdmVuIGEgc3BlY2lmaWMgdHlwZV9wYXJhbQogKiBhbmQgdG9rZW4uCiAqCiAqIEBwYXJhbSB0eXBlX3BhcmFtIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgdXNlZCB3aGVyZSB0aGUgdG9rZW4gaXMgbG9jYXRlZC4KICogICAgICAgICAgICAgICAgICAgVXNlZCB0byBsb29rdXAgdGhlIGNvbmZpZyBmaWxlIGVudHJ5CiAqIAogKiBAcGFyYW0gdG9rZW4gICAgICB0aGUgdG9rZW4gdGhhdCBpcyBiZWluZyB1bnJlZ2lzdGVyZWQKICoKICogQHJldHVybiB2b2lkCiAqLwp2b2lkCnVucmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoY29uc3QgY2hhciAqdHlwZV9wYXJhbSwgY29uc3QgY2hhciAqdG9rZW4pCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKipjdG1wID0gJmNvbmZpZ19maWxlczsKICAgIHN0cnVjdCBjb25maWdfbGluZSAgKipsdG1wOwogICAgY29uc3QgY2hhciAgICAgICAgICAgKnR5cGUgPSB0eXBlX3BhcmFtOwoKICAgIGlmICh0eXBlID09IE5VTEwgfHwgKnR5cGUgPT0gJ1wwJykgewogICAgICAgIHR5cGUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgTkVUU05NUF9EU19MSUJfQVBQVFlQRSk7CiAgICB9CgogICAgLyoKICAgICAqIEhhbmRsZSBtdWx0aXBsZSB0eXBlcyAocmVjdXJzaXZlbHkpCiAgICAgKi8KICAgIGlmIChzdHJjaHIodHlwZSwgJzonKSkgewogICAgICAgIGNoYXIgICAgICAgICAgICAgICAgYnVmW1NUUklOR01BWF07CiAgICAgICAgY2hhciAgICAgICAgICAgICAgICpjcHRyID0gYnVmOwoKICAgICAgICBzdHJsY3B5KGJ1ZiwgdHlwZSwgU1RSSU5HTUFYKTsKICAgICAgICB3aGlsZSAoY3B0cikgewogICAgICAgICAgICBjaGFyKiBjID0gY3B0cjsKICAgICAgICAgICAgY3B0ciA9IHN0cmNocihjcHRyLCAnOicpOwogICAgICAgICAgICBpZihjcHRyKSB7CiAgICAgICAgICAgICAgICAqY3B0ciA9ICdcMCc7CiAgICAgICAgICAgICAgICArK2NwdHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihjLCB0b2tlbik7CiAgICAgICAgfQogICAgICAgIHJldHVybjsKICAgIH0KICAgIAogICAgLyoKICAgICAqIGZpbmQgdHlwZSBpbiBjdXJyZW50IGxpc3QgCiAgICAgKi8KICAgIHdoaWxlICgqY3RtcCAhPSBOVUxMICYmIHN0cmNtcCgoKmN0bXApLT5maWxlSGVhZGVyLCB0eXBlKSkgewogICAgICAgIGN0bXAgPSAmKCgqY3RtcCktPm5leHQpOwogICAgfQoKICAgIGlmICgqY3RtcCA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBOb3QgZm91bmQsIHJldHVybi4gCiAgICAgICAgICovCiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGx0bXAgPSAmKCgqY3RtcCktPnN0YXJ0KTsKICAgIGlmICgqbHRtcCA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBOb3QgZm91bmQsIHJldHVybi4gCiAgICAgICAgICovCiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKHN0cmNtcCgoKmx0bXApLT5jb25maWdfdG9rZW4sIHRva2VuKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBmb3VuZCBpdCBhdCB0aGUgdG9wIG9mIHRoZSBsaXN0IAogICAgICAgICAqLwogICAgICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHRtcDIgPSAoKmx0bXApLT5uZXh0OwogICAgICAgIGlmICgoKmx0bXApLT5mcmVlX2Z1bmMpCiAgICAgICAgICAgICgqbHRtcCktPmZyZWVfZnVuYygpOwogICAgICAgIFNOTVBfRlJFRSgoKmx0bXApLT5jb25maWdfdG9rZW4pOwogICAgICAgIFNOTVBfRlJFRSgoKmx0bXApLT5oZWxwKTsKICAgICAgICBTTk1QX0ZSRUUoKmx0bXApOwogICAgICAgICgqY3RtcCktPnN0YXJ0ID0gbHRtcDI7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgd2hpbGUgKCgqbHRtcCktPm5leHQgIT0gTlVMTAogICAgICAgICAgICYmIHN0cmNtcCgoKmx0bXApLT5uZXh0LT5jb25maWdfdG9rZW4sIHRva2VuKSkgewogICAgICAgIGx0bXAgPSAmKCgqbHRtcCktPm5leHQpOwogICAgfQogICAgaWYgKCgqbHRtcCktPm5leHQgIT0gTlVMTCkgewogICAgICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHRtcDIgPSAoKmx0bXApLT5uZXh0LT5uZXh0OwogICAgICAgIGlmICgoKmx0bXApLT5uZXh0LT5mcmVlX2Z1bmMpCiAgICAgICAgICAgICgqbHRtcCktPm5leHQtPmZyZWVfZnVuYygpOwogICAgICAgIFNOTVBfRlJFRSgoKmx0bXApLT5uZXh0LT5jb25maWdfdG9rZW4pOwogICAgICAgIFNOTVBfRlJFRSgoKmx0bXApLT5uZXh0LT5oZWxwKTsKICAgICAgICBTTk1QX0ZSRUUoKCpsdG1wKS0+bmV4dCk7CiAgICAgICAgKCpsdG1wKS0+bmV4dCA9IGx0bXAyOwogICAgfQp9Cgp2b2lkCnVucmVnaXN0ZXJfYXBwX2NvbmZpZ19oYW5kbGVyKGNvbnN0IGNoYXIgKnRva2VuKQp7CiAgICB1bnJlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKE5VTEwsIHRva2VuKTsKfQoKdm9pZAp1bnJlZ2lzdGVyX2FsbF9jb25maWdfaGFuZGxlcnModm9pZCkKewogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCwgKnNhdmU7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmx0bXA7CgogICAgLyoKICAgICAqIEtlZXAgdXNpbmcgY29uZmlnX2ZpbGVzIHVudGlsIHRoZXJlIGFyZSBubyBtb3JlISAKICAgICAqLwogICAgZm9yIChjdG1wID0gY29uZmlnX2ZpbGVzOyBjdG1wOykgewogICAgICAgIGZvciAobHRtcCA9IGN0bXAtPnN0YXJ0OyBsdG1wOyBsdG1wID0gY3RtcC0+c3RhcnQpIHsKICAgICAgICAgICAgdW5yZWdpc3Rlcl9jb25maWdfaGFuZGxlcihjdG1wLT5maWxlSGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGx0bXAtPmNvbmZpZ190b2tlbik7CiAgICAgICAgfQogICAgICAgIFNOTVBfRlJFRShjdG1wLT5maWxlSGVhZGVyKTsKICAgICAgICBzYXZlID0gY3RtcC0+bmV4dDsKICAgICAgICBTTk1QX0ZSRUUoY3RtcCk7CiAgICAgICAgY3RtcCA9IHNhdmU7CiAgICAgICAgY29uZmlnX2ZpbGVzID0gc2F2ZTsKICAgIH0KfQoKI2lmZGVmIFRFU1RJTkcKdm9pZApwcmludF9jb25maWdfaGFuZGxlcnModm9pZCkKewogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCA9IGNvbmZpZ19maWxlczsKICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHRtcDsKCiAgICBmb3IgKDsgY3RtcCAhPSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkgewogICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICJyZWFkX2NvbmY6ICVzXG4iLCBjdG1wLT5maWxlSGVhZGVyKSk7CiAgICAgICAgZm9yIChsdG1wID0gY3RtcC0+c3RhcnQ7IGx0bXAgIT0gTlVMTDsgbHRtcCA9IGx0bXAtPm5leHQpCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsICIgICAgICAgICAgICAgICAgICAgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIGx0bXAtPmNvbmZpZ190b2tlbikpOwogICAgfQp9CiNlbmRpZgoKaW50ICAgICAgICAgICAgIGxpbmVjb3VudCwgICAgcHJldl9saW5lY291bnQ7CmNvbnN0IGNoYXIgICAgICpjdXJmaWxlbmFtZSwgKnByZXZfZmlsZW5hbWU7CgpzdHJ1Y3QgY29uZmlnX2xpbmUgKgpyZWFkX2NvbmZpZ19nZXRfaGFuZGxlcnMoY29uc3QgY2hhciAqdHlwZSkKewogICAgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCA9IGNvbmZpZ19maWxlczsKICAgIGZvciAoOyBjdG1wICE9IE5VTEwgJiYgc3RyY21wKGN0bXAtPmZpbGVIZWFkZXIsIHR5cGUpOwogICAgICAgICBjdG1wID0gY3RtcC0+bmV4dCk7CiAgICBpZiAoY3RtcCkKICAgICAgICByZXR1cm4gY3RtcC0+c3RhcnQ7CiAgICByZXR1cm4gTlVMTDsKfQoKaW50CnJlYWRfY29uZmlnX3dpdGhfdHlwZV93aGVuKGNvbnN0IGNoYXIgKmZpbGVuYW1lLCBjb25zdCBjaGFyICp0eXBlLCBpbnQgd2hlbikKewogICAgc3RydWN0IGNvbmZpZ19saW5lICpjdG1wID0gcmVhZF9jb25maWdfZ2V0X2hhbmRsZXJzKHR5cGUpOwogICAgaWYgKGN0bXApCiAgICAgICAgcmV0dXJuIHJlYWRfY29uZmlnKGZpbGVuYW1lLCBjdG1wLCB3aGVuKTsKICAgIGVsc2UKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLAogICAgICAgICAgICAgICAgICAgICJyZWFkX2NvbmZpZzogSSBoYXZlIG5vIHJlZ2lzdHJhdGlvbnMgZm9yIHR5cGU6JXMsZmlsZTolc1xuIiwKICAgICAgICAgICAgICAgICAgICB0eXBlLCBmaWxlbmFtZSkpOwogICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOyAgICAgLyogTm8gY29uZmlnIGZpbGVzIHJlYWQgKi8KfQoKaW50CnJlYWRfY29uZmlnX3dpdGhfdHlwZShjb25zdCBjaGFyICpmaWxlbmFtZSwgY29uc3QgY2hhciAqdHlwZSkKewogICAgcmV0dXJuIHJlYWRfY29uZmlnX3dpdGhfdHlwZV93aGVuKGZpbGVuYW1lLCB0eXBlLCBFSVRIRVJfQ09ORklHKTsKfQoKCnN0cnVjdCBjb25maWdfbGluZSAqCnJlYWRfY29uZmlnX2ZpbmRfaGFuZGxlcihzdHJ1Y3QgY29uZmlnX2xpbmUgKmxpbmVfaGFuZGxlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2tlbikKewogICAgc3RydWN0IGNvbmZpZ19saW5lICpscHRyOwoKICAgIGZvciAobHB0ciA9IGxpbmVfaGFuZGxlcnM7IGxwdHIgIT0gTlVMTDsgbHB0ciA9IGxwdHItPm5leHQpIHsKICAgICAgICBpZiAoIXN0cmNhc2VjbXAodG9rZW4sIGxwdHItPmNvbmZpZ190b2tlbikpIHsKICAgICAgICAgICAgcmV0dXJuIGxwdHI7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCgovKgogKiBzZWFyY2hlcyBhIGNvbmZpZ19saW5lIGxpbmtlZCBsaXN0IGZvciBhIG1hdGNoIAogKi8KaW50CnJ1bl9jb25maWdfaGFuZGxlcihzdHJ1Y3QgY29uZmlnX2xpbmUgKmxwdHIsCiAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0ciwgaW50IHdoZW4pCnsKICAgIGNoYXIgICAgICAgICAgICpjcDsKICAgIGxwdHIgPSByZWFkX2NvbmZpZ19maW5kX2hhbmRsZXIobHB0ciwgdG9rZW4pOwogICAgaWYgKGxwdHIgIT0gTlVMTCkgewogICAgICAgIGlmICh3aGVuID09IEVJVEhFUl9DT05GSUcgfHwgbHB0ci0+Y29uZmlnX3RpbWUgPT0gd2hlbikgewogICAgICAgICAgICBjaGFyIHRtcGJ1ZlsxXTsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOnBhcnNlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICJGb3VuZCBhIHBhcnNlci4gIENhbGxpbmcgaXQ6ICVzIC8gJXNcbiIsIHRva2VuLAogICAgICAgICAgICAgICAgICAgICAgICBjcHRyKSk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIE1ha2Ugc3VyZSBjcHRyIGlzIG5vbi1udWxsCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIWNwdHIpIHsKICAgICAgICAgICAgICAgIHRtcGJ1ZlswXSA9ICdcMCc7CiAgICAgICAgICAgICAgICBjcHRyID0gdG1wYnVmOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTdG9tcCBvbiBhbnkgdHJhaWxpbmcgd2hpdGVzcGFjZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY3AgPSAmKGNwdHJbc3RybGVuKGNwdHIpLTFdKTsKICAgICAgICAgICAgd2hpbGUgKChjcCA+IGNwdHIpICYmIGlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKCpjcCkpKSB7CiAgICAgICAgICAgICAgICAqKGNwLS0pID0gJ1wwJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAoKihscHRyLT5wYXJzZV9saW5lKSkgKHRva2VuLCBjcHRyKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBERUJVR01TR1RMKCgiOTpyZWFkX2NvbmZpZzpwYXJzZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAiJXMgaGFuZGxlciBub3QgcmVnaXN0ZXJlZCBmb3IgdGhpcyB0aW1lXG4iLCB0b2tlbikpOwogICAgfSBlbHNlIGlmICh3aGVuICE9IFBSRU1JQl9DT05GSUcgJiYgCgkgICAgICAgIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgICBORVRTTk1QX0RTX0xJQl9OT19UT0tFTl9XQVJOSU5HUykpIHsKCW5ldHNubXBfY29uZmlnX3dhcm4oIlVua25vd24gdG9rZW46ICVzLiIsIHRva2VuKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgovKgogKiB0YWtlbnMgYW4gYXJiaXRyYXJ5IHN0cmluZyBhbmQgdHJpZXMgdG8gaW50ZXByZXQgaXQgYmFzZWQgb24gdGhlCiAqIGtub3duIGNvbmZpZ3VyYXRpb24gaGFuZGxlcnMgZm9yIGFsbCByZWdpc3RlcmVkIHR5cGVzLiAgTWF5IHByb2R1Y2UKICogaW5jb25zaXN0ZW50IHJlc3VsdHMgd2hlbiBtdWx0aXBsZSB0b2tlbnMgb2YgdGhlIHNhbWUgbmFtZSBhcmUKICogcmVnaXN0ZXJlZCB1bmRlciBkaWZmZXJlbnQgZmlsZSB0eXBlcy4gCiAqLwoKLyoKICogd2UgYWxsb3cgPSBkZWxpbWV0ZXJzIGhlcmUgCiAqLwojZGVmaW5lIFNOTVBfQ09ORklHX0RFTElNRVRFUlMgIiBcdD0iCgppbnQKc25tcF9jb25maWdfd2hlbihjaGFyICpsaW5lLCBpbnQgd2hlbikKewogICAgY2hhciAgICAgICAgICAgKmNwdHIsIGJ1ZltTVFJJTkdNQVhdOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpscHRyID0gTlVMTDsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAgPSBjb25maWdfZmlsZXM7CiAgICBjaGFyICAgICAgICAgICAqc3Q7CgogICAgaWYgKGxpbmUgPT0gTlVMTCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoInNubXBfY29uZmlnKCkgY2FsbGVkIHdpdGggYSBudWxsIHN0cmluZy4iKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgc3RybGNweShidWYsIGxpbmUsIFNUUklOR01BWCk7CiAgICBjcHRyID0gc3RydG9rX3IoYnVmLCBTTk1QX0NPTkZJR19ERUxJTUVURVJTLCAmc3QpOwogICAgaWYgKCFjcHRyKSB7CiAgICAgICAgbmV0c25tcF9jb25maWdfd2FybigiV3JvbmcgZm9ybWF0OiAlcyIsIGxpbmUpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KICAgIGlmIChjcHRyWzBdID09ICdbJykgewogICAgICAgIGlmIChjcHRyW3N0cmxlbihjcHRyKSAtIDFdICE9ICddJykgewoJICAgIG5ldHNubXBfY29uZmlnX2Vycm9yKCJubyBtYXRjaGluZyAnXScgZm9yIHR5cGUgJXMuIiwgY3B0ciArIDEpOwogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgfQogICAgICAgIGNwdHJbc3RybGVuKGNwdHIpIC0gMV0gPSAnXDAnOwogICAgICAgIGxwdHIgPSByZWFkX2NvbmZpZ19nZXRfaGFuZGxlcnMoY3B0ciArIDEpOwogICAgICAgIGlmIChscHRyID09IE5VTEwpIHsKCSAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiTm8gaGFuZGxlcnMgcmVnZXN0ZXJlZCBmb3IgdHlwZSAlcy4iLAoJCQkJIGNwdHIgKyAxKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgIH0KICAgICAgICBjcHRyID0gc3RydG9rX3IoTlVMTCwgU05NUF9DT05GSUdfREVMSU1FVEVSUywgJnN0KTsKICAgICAgICBscHRyID0gcmVhZF9jb25maWdfZmluZF9oYW5kbGVyKGxwdHIsIGNwdHIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIHdlIGhhdmUgdG8gZmluZCBhIHRva2VuIAogICAgICAgICAqLwogICAgICAgIGZvciAoOyBjdG1wICE9IE5VTEwgJiYgbHB0ciA9PSBOVUxMOyBjdG1wID0gY3RtcC0+bmV4dCkKICAgICAgICAgICAgbHB0ciA9IHJlYWRfY29uZmlnX2ZpbmRfaGFuZGxlcihjdG1wLT5zdGFydCwgY3B0cik7CiAgICB9CiAgICBpZiAobHB0ciA9PSBOVUxMICYmIG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQkgIE5FVFNOTVBfRFNfTElCX05PX1RPS0VOX1dBUk5JTkdTKSkgewoJbmV0c25tcF9jb25maWdfd2FybigiVW5rbm93biB0b2tlbjogJXMuIiwgY3B0cik7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIC8qCiAgICAgKiB1c2UgdGhlIG9yaWdpbmFsIHN0cmluZyBpbnN0ZWFkIHNpbmNlIHN0cnRva19yIG1lc3NlZCB1cCB0aGUgb3JpZ2luYWwgCiAgICAgKi8KICAgIGxpbmUgPSBza2lwX3doaXRlKGxpbmUgKyAoY3B0ciAtIGJ1ZikgKyBzdHJsZW4oY3B0cikgKyAxKTsKCiAgICByZXR1cm4gKHJ1bl9jb25maWdfaGFuZGxlcihscHRyLCBjcHRyLCBsaW5lLCB3aGVuKSk7Cn0KCmludApuZXRzbm1wX2NvbmZpZyhjaGFyICpsaW5lKQp7CiAgICBpbnQgICAgICAgICAgICAgcmV0ID0gU05NUF9FUlJfTk9FUlJPUjsKICAgIERFQlVHTVNHVEwoKCJzbm1wX2NvbmZpZyIsICJyZW1lbWJlcmluZyBsaW5lIFwiJXNcIlxuIiwgbGluZSkpOwogICAgbmV0c25tcF9jb25maWdfcmVtZW1iZXIobGluZSk7ICAgICAgLyogYWx3YXlzIHJlbWVtYmVyIGl0IHNvIGl0J3MgcmVhZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogcHJvY2Vzc2VkIGFmdGVyIGEgZnJlZV9jb25maWcoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogY2FsbCAqLwogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICAgICAgIE5FVFNOTVBfRFNfTElCX0hBVkVfUkVBRF9DT05GSUcpKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfY29uZmlnIiwgIiAgLi4uIHByb2Nlc3NpbmcgaXQgbm93XG4iKSk7CiAgICAgICAgcmV0ID0gc25tcF9jb25maWdfd2hlbihsaW5lLCBOT1JNQUxfQ09ORklHKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcmVtZW1iZXJfaW5fbGlzdChjaGFyICpsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKiptZW0pCnsKICAgIGlmIChtZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgd2hpbGUgKCptZW0gIT0gTlVMTCkKICAgICAgICBtZW0gPSAmKCgqbWVtKS0+bmV4dCk7CgogICAgKm1lbSA9IFNOTVBfTUFMTE9DX1NUUlVDVChyZWFkX2NvbmZpZ19tZW1vcnkpOwogICAgaWYgKCptZW0gIT0gTlVMTCkgewogICAgICAgIGlmIChsaW5lKQogICAgICAgICAgICAoKm1lbSktPmxpbmUgPSBzdHJkdXAobGluZSk7CiAgICB9Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcmVtZW1iZXJfZnJlZV9saXN0KHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKiptZW0pCnsKICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKnRtcG1lbTsKICAgIHdoaWxlICgqbWVtKSB7CiAgICAgICAgU05NUF9GUkVFKCgqbWVtKS0+bGluZSk7CiAgICAgICAgdG1wbWVtID0gKCptZW0pLT5uZXh0OwogICAgICAgIFNOTVBfRlJFRSgqbWVtKTsKICAgICAgICAqbWVtID0gdG1wbWVtOwogICAgfQp9Cgp2b2lkCm5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3J5X2xpc3Qoc3RydWN0IHJlYWRfY29uZmlnX21lbW9yeSAqKm1lbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHdoZW4sIGludCBjbGVhcikKewoKICAgIHN0cnVjdCByZWFkX2NvbmZpZ19tZW1vcnkgKm1lbTsKCiAgICBpZiAoIW1lbXApCiAgICAgICAgcmV0dXJuOwoKICAgIG1lbSA9ICptZW1wOwoKICAgIHdoaWxlIChtZW0pIHsKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWc6bWVtIiwgInByb2Nlc3NpbmcgbWVtb3J5OiAlc1xuIiwgbWVtLT5saW5lKSk7CiAgICAgICAgc25tcF9jb25maWdfd2hlbihtZW0tPmxpbmUsIHdoZW4pOwogICAgICAgIG1lbSA9IG1lbS0+bmV4dDsKICAgIH0KCiAgICBpZiAoY2xlYXIpCiAgICAgICAgbmV0c25tcF9jb25maWdfcmVtZW1iZXJfZnJlZV9saXN0KG1lbXApOwp9CgovKgogKiBkZWZhdWx0IHN0b3JhZ2UgbG9jYXRpb24gaW1wbGVtZW50YXRpb24gCiAqLwpzdGF0aWMgc3RydWN0IHJlYWRfY29uZmlnX21lbW9yeSAqbWVtb3J5bGlzdCA9IE5VTEw7Cgp2b2lkCm5ldHNubXBfY29uZmlnX3JlbWVtYmVyKGNoYXIgKmxpbmUpCnsKICAgIG5ldHNubXBfY29uZmlnX3JlbWVtYmVyX2luX2xpc3QobGluZSwgJm1lbW9yeWxpc3QpOwp9Cgp2b2lkCm5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3JpZXModm9pZCkKewogICAgbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcnlfbGlzdCgmbWVtb3J5bGlzdCwgRUlUSEVSX0NPTkZJRywgMSk7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfcHJvY2Vzc19tZW1vcmllc193aGVuKGludCB3aGVuLCBpbnQgY2xlYXIpCnsKICAgIG5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3J5X2xpc3QoJm1lbW9yeWxpc3QsIHdoZW4sIGNsZWFyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogcmVhZF9jb25maWcKICoKICogUGFyYW1ldGVyczoKICoJKmZpbGVuYW1lCiAqCSpsaW5lX2hhbmRsZXIKICoJIHdoZW4KICoKICogUmVhZCA8ZmlsZW5hbWU+IGFuZCBwcm9jZXNzIGVhY2ggbGluZSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIGxpc3Qgb2YKICogPGxpbmVfaGFuZGxlcj4gZnVuY3Rpb25zLgogKgogKgogKiBGb3IgZWFjaCBsaW5lIGluIDxmaWxlbmFtZT4sIHNlYXJjaCB0aGUgbGlzdCBvZiA8bGluZV9oYW5kbGVyPidzIAogKiBmb3IgYW4gZW50cnkgdGhhdCBtYXRjaGVzIHRoZSBmaXJzdCB0b2tlbiBvbiB0aGUgbGluZS4gIFRoaXMgY29tcGFyaXNvbiBpcwogKiBjYXNlIGluc2Vuc2l0aXZlLgogKgogKiBGb3IgZWFjaCBtYXRjaCwgY2hlY2sgdGhhdCA8d2hlbj4gaXMgdGhlIGRlc2lnbmF0ZWQgdGltZSBmb3IgdGhlCiAqIDxsaW5lX2hhbmRsZXI+IGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGJlZm9yZSBwcm9jZXNzaW5nIHRoZSBsaW5lLgogKgogKiBSZXR1cm5zIFNOTVBFUlJfU1VDQ0VTUyBpZiB0aGUgZmlsZSBpcyBwcm9jZXNzZWQgc3VjY2Vzc2Z1bGx5LgogKiBSZXR1cm5zIFNOTVBFUlJfR0VORVJSICBpZiBpdCBjYW5ub3QuCiAqICAgIE5vdGUgdGhhdCBpbmRpdmlkdWFsIGNvbmZpZyB0b2tlbiBlcnJvcnMgZG8gbm90IHRyaWdnZXIgU05NUEVSUl9HRU5FUlIKICogICAgSXQncyBvbmx5IGlmIHRoZSB3aG9sZSBmaWxlIGNhbm5vdCBiZSBwcm9jZXNzZWQgZm9yIHNvbWUgcmVhc29uLgogKi8KaW50CnJlYWRfY29uZmlnKGNvbnN0IGNoYXIgKmZpbGVuYW1lLAogICAgICAgICAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmxpbmVfaGFuZGxlciwgaW50IHdoZW4pCnsKICAgIHN0YXRpYyBpbnQgICAgICBkZXB0aCA9IDA7CiAgICBzdGF0aWMgaW50ICAgICAgZmlsZXMgPSAwOwogICAgRklMRSAgICAgICAgICAgKmlmaWxlOwogICAgY2hhciAgICAgICAgICAgIGxpbmVbU1RSSU5HTUFYXSwgdG9rZW5bU1RSSU5HTUFYXTsKICAgIGNoYXIgICAgICAgICAgICpjcHRyOwogICAgaW50ICAgICAgICAgICAgIGksIHJldDsKICAgIHN0cnVjdCBjb25maWdfbGluZSAqbHB0cjsKCiAgICAvLyByZXNldCBmaWxlIGNvdW50ZXIgd2hlbiByZWN1cnNpb24gZGVwdGggaXMgMAogICAgaWYgKGRlcHRoID09IDApIGZpbGVzID0gMDsKCiAgICBsaW5lY291bnQgPSAwOwogICAgY3VyZmlsZW5hbWUgPSBmaWxlbmFtZTsKCiAgICBpZiAoKGlmaWxlID0gZm9wZW4oZmlsZW5hbWUsICJyIikpID09IE5VTEwpIHsKI2lmZGVmIEVOT0VOVAogICAgICAgIGlmIChlcnJubyA9PSBFTk9FTlQpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnIiwgIiVzOiAlc1xuIiwgZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVycm9yKGVycm5vKSkpOwogICAgICAgIH0gZWxzZQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEVOT0VOVCAqLwojaWZkZWYgRUFDQ0VTCiAgICAgICAgaWYgKGVycm5vID09IEVBQ0NFUykgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAiJXM6ICVzXG4iLCBmaWxlbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RyZXJyb3IoZXJybm8pKSk7CiAgICAgICAgfSBlbHNlCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRUFDQ0VTICovCiNpZiBkZWZpbmVkKEVOT0VOVCkgfHwgZGVmaW5lZChFQUNDRVMpCiAgICAgICAgewogICAgICAgICAgICBzbm1wX2xvZ19wZXJyb3IoZmlsZW5hbWUpOwogICAgICAgIH0KI2Vsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBkZWZpbmVkKEVOT0VOVCkgfHwgZGVmaW5lZChFQUNDRVMpICovCiAgICAgICAgICAgIHNubXBfbG9nX3BlcnJvcihmaWxlbmFtZSk7CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRU5PRU5UICovCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKI2RlZmluZSBDT05GSUdfTUFYX0ZJTEVTIDQwOTYKICAgIGlmIChmaWxlcyA+IENPTkZJR19NQVhfRklMRVMpIHsKICAgICAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigibWF4aW11bSBjb25mIGZpbGUgY291bnQgKCVkKSBleGNlZWRlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05GSUdfTUFYX0ZJTEVTKTsKCWZjbG9zZShpZmlsZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQojZGVmaW5lIENPTkZJR19NQVhfUkVDVVJTRV9ERVBUSCAxNgogICAgaWYgKGRlcHRoID4gQ09ORklHX01BWF9SRUNVUlNFX0RFUFRIKSB7CiAgICAgICAgbmV0c25tcF9jb25maWdfZXJyb3IoIm5lc3RlZCBpbmNsdWRlIGRlcHRoID4gJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09ORklHX01BWF9SRUNVUlNFX0RFUFRIKTsKCWZjbG9zZShpZmlsZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAgKytmaWxlczsKICAgICsrZGVwdGg7CgogICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOmZpbGUiLCAiUmVhZGluZyBjb25maWd1cmF0aW9uICVzICglZClcbiIsCiAgICAgICAgICAgICAgICBmaWxlbmFtZSwgd2hlbikpOwogICAgCiAgICB3aGlsZSAoZmdldHMobGluZSwgc2l6ZW9mKGxpbmUpLCBpZmlsZSkgIT0gTlVMTCkgewogICAgICAgIGxwdHIgPSBsaW5lX2hhbmRsZXI7CiAgICAgICAgbGluZWNvdW50Kys7CiAgICAgICAgY3B0ciA9IGxpbmU7CiAgICAgICAgaSA9IHN0cmxlbihsaW5lKSAtIDE7CiAgICAgICAgaWYgKGxpbmVbaV0gPT0gJ1xuJykKICAgICAgICAgICAgbGluZVtpXSA9IDA7CiAgICAgICAgREVCVUdNU0dUTCgoIjk6cmVhZF9jb25maWc6bGluZSIsICIlczolZCBleGFtaW5pbmc6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lLCBsaW5lY291bnQsIGxpbmUpKTsKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIGJsYW5rIGxpbmUgb3IgIyBjb21tZW50IAogICAgICAgICAqLwogICAgICAgIGlmICgoY3B0ciA9IHNraXBfd2hpdGUoY3B0cikpKSB7CiAgICAgICAgICAgIGNwdHIgPSBjb3B5X253b3JkKGNwdHIsIHRva2VuLCBzaXplb2YodG9rZW4pKTsKICAgICAgICAgICAgaWYgKHRva2VuWzBdID09ICdbJykgewogICAgICAgICAgICAgICAgaWYgKHRva2VuW3N0cmxlbih0b2tlbikgLSAxXSAhPSAnXScpIHsKCQkgICAgbmV0c25tcF9jb25maWdfZXJyb3IoIm5vIG1hdGNoaW5nICddJyBmb3IgdHlwZSAlcy4iLAoJCQkJCSAmdG9rZW5bMV0pOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdG9rZW5bc3RybGVuKHRva2VuKSAtIDFdID0gJ1wwJzsKICAgICAgICAgICAgICAgIGxwdHIgPSByZWFkX2NvbmZpZ19nZXRfaGFuZGxlcnMoJnRva2VuWzFdKTsKICAgICAgICAgICAgICAgIGlmIChscHRyID09IE5VTEwpIHsKCQkgICAgbmV0c25tcF9jb25maWdfZXJyb3IoIk5vIGhhbmRsZXJzIHJlZ2VzdGVyZWQgZm9yIHR5cGUgJXMuIiwKCQkJCQkgJnRva2VuWzFdKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZzpjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTd2l0Y2hpbmcgdG8gbmV3IGNvbnRleHQ6ICVzJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGNwdHIpID8gIih0aGlzIGxpbmUgb25seSkgIiA6ICIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0b2tlblsxXSkpOwogICAgICAgICAgICAgICAgaWYgKGNwdHIgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogY2hhbmdlIGNvbnRleHQgcGVybWFuZW50bHkgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgbGluZV9oYW5kbGVyID0gbHB0cjsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiB0aGUgcmVzdCBvZiB0aGlzIGxpbmUgb25seSBhcHBsaWVzLiAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBjcHRyID0gY29weV9ud29yZChjcHRyLCB0b2tlbiwgc2l6ZW9mKHRva2VuKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoKHRva2VuWzBdID09ICdpJykgJiYgKHN0cm5jYXNlY21wKHRva2VuLCJpbmNsdWRlIiwgNyApPT0wKSkgewogICAgICAgICAgICAgICAgaWYgKCBzdHJjYXNlY21wKCB0b2tlbiwgImluY2x1ZGUiICk9PTApIHsKICAgICAgICAgICAgICAgICAgICBpZiAod2hlbiAhPSBQUkVNSUJfQ09ORklHICYmIAoJICAgICAgICAgICAgICAgICFuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfTk9fVE9LRU5fV0FSTklOR1MpKSB7CgkgICAgICAgICAgICAgICAgbmV0c25tcF9jb25maWdfd2FybigiQW1iaWd1b3VzIHRva2VuICclcycgLSB1c2UgJ2luY2x1ZGVTZWFyY2gnIChvciAnaW5jbHVkZUZpbGUnKSBpbnN0ZWFkLiIsIHRva2VuKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCBzdHJjYXNlY21wKCB0b2tlbiwgImluY2x1ZGVkaXIiICk9PTApIHsKICAgICAgICAgICAgICAgICAgICBESVIgKmQ7CiAgICAgICAgICAgICAgICAgICAgc3RydWN0IGRpcmVudCAqZW50cnk7CiAgICAgICAgICAgICAgICAgICAgY2hhciAgZm5hbWVbU05NUF9NQVhQQVRIXTsKICAgICAgICAgICAgICAgICAgICBpbnQgICBsZW47CgogICAgICAgICAgICAgICAgICAgIGlmIChjcHRyID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdoZW4gIT0gUFJFTUlCX0NPTkZJRykKCQkgICAgICAgICAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiQmxhbmsgbGluZSBmb2xsb3dpbmcgJXMgdG9rZW4uIiwgdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKChkPW9wZW5kaXIoY3B0cikpID09IE5VTEwgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aGVuICE9IFBSRU1JQl9DT05GSUcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiQ2FuJ3Qgb3BlbiBpbmNsdWRlIGRpciAnJXMnLiIsIGNwdHIpOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcHJldl9maWxlbmFtZSAgPSBjdXJmaWxlbmFtZTsKICAgICAgICAgICAgICAgICAgICBwcmV2X2xpbmVjb3VudCA9IGxpbmVjb3VudDsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGVudHJ5ID0gcmVhZGRpciggZCApKSAhPSBOVUxMICkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGVudHJ5LT5kX25hbWVbMF0gIT0gJy4nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4gPSBOQU1MRU4oZW50cnkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChsZW4gPiA1KSAmJiAoc3RyY21wKCYoZW50cnktPmRfbmFtZVtsZW4tNV0pLCIuY29uZiIpID09IDApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25wcmludGYoZm5hbWUsIFNOTVBfTUFYUEFUSCwgIiVzLyVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcHRyLCBlbnRyeS0+ZF9uYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZClyZWFkX2NvbmZpZyhmbmFtZSwgbGluZV9oYW5kbGVyLCB3aGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjbG9zZWRpcihkKTsKICAgICAgICAgICAgICAgICAgICBjdXJmaWxlbmFtZSA9IHByZXZfZmlsZW5hbWU7CiAgICAgICAgICAgICAgICAgICAgbGluZWNvdW50ICAgPSBwcmV2X2xpbmVjb3VudDsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIHN0cmNhc2VjbXAoIHRva2VuLCAiaW5jbHVkZWZpbGUiICk9PTApIHsKICAgICAgICAgICAgICAgICAgICBjaGFyICBmbmFtZVtTTk1QX01BWFBBVEhdLCAqY3A7CgogICAgICAgICAgICAgICAgICAgIGlmIChjcHRyID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdoZW4gIT0gUFJFTUlCX0NPTkZJRykKCQkgICAgICAgICAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiQmxhbmsgbGluZSBmb2xsb3dpbmcgJXMgdG9rZW4uIiwgdG9rZW4pOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCBjcHRyWzBdID09ICcvJyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RybGNweShmbmFtZSwgY3B0ciwgU05NUF9NQVhQQVRIKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzdHJsY3B5KGZuYW1lLCBmaWxlbmFtZSwgU05NUF9NQVhQQVRIKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3AgPSBzdHJyY2hyKGZuYW1lLCAnLycpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm5hbWVbMF0gPSAnXDAnOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKCsrY3ApID0gJ1wwJzsKICAgICAgICAgICAgICAgICAgICAgICAgc3RybGNhdChmbmFtZSwgY3B0ciwgU05NUF9NQVhQQVRIKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcHJldl9maWxlbmFtZSAgPSBjdXJmaWxlbmFtZTsKICAgICAgICAgICAgICAgICAgICBwcmV2X2xpbmVjb3VudCA9IGxpbmVjb3VudDsKICAgICAgICAgICAgICAgICAgICByZXQgPSByZWFkX2NvbmZpZyhmbmFtZSwgbGluZV9oYW5kbGVyLCB3aGVuKTsKICAgICAgICAgICAgICAgICAgICBjdXJmaWxlbmFtZSA9IHByZXZfZmlsZW5hbWU7CiAgICAgICAgICAgICAgICAgICAgbGluZWNvdW50ICAgPSBwcmV2X2xpbmVjb3VudDsKICAgICAgICAgICAgICAgICAgICBpZiAoKHJldCAhPSBTTk1QRVJSX1NVQ0NFU1MpICYmICh3aGVuICE9IFBSRU1JQl9DT05GSUcpKQogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NvbmZpZ19lcnJvcigiSW5jbHVkZWQgZmlsZSAnJXMnIG5vdCBmb3VuZC4iLCBmbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCBzdHJjYXNlY21wKCB0b2tlbiwgImluY2x1ZGVzZWFyY2giICk9PTApIHsKICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzIGN0bXA7CiAgICAgICAgICAgICAgICAgICAgaW50IGxlbjsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGNwdHIgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAod2hlbiAhPSBQUkVNSUJfQ09ORklHKQoJCSAgICAgICAgICAgIG5ldHNubXBfY29uZmlnX2Vycm9yKCJCbGFuayBsaW5lIGZvbGxvd2luZyAlcyB0b2tlbi4iLCB0b2tlbik7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBsZW4gPSBzdHJsZW4oY3B0cik7CiAgICAgICAgICAgICAgICAgICAgY3RtcC5maWxlSGVhZGVyID0gY3B0cjsKICAgICAgICAgICAgICAgICAgICBjdG1wLnN0YXJ0ID0gbGluZV9oYW5kbGVyOwogICAgICAgICAgICAgICAgICAgIGN0bXAubmV4dCA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgaWYgKChsZW4gPiA1KSAmJiAoc3RyY21wKCZjcHRyW2xlbi01XSwiLmNvbmYiKSA9PSAwKSkKICAgICAgICAgICAgICAgICAgICAgICBjcHRyW2xlbi01XSA9IDA7IC8qIGNob3Agb2ZmIC5jb25mICovCiAgICAgICAgICAgICAgICAgICAgcHJldl9maWxlbmFtZSAgPSBjdXJmaWxlbmFtZTsKICAgICAgICAgICAgICAgICAgICBwcmV2X2xpbmVjb3VudCA9IGxpbmVjb3VudDsKICAgICAgICAgICAgICAgICAgICByZXQgPSByZWFkX2NvbmZpZ19maWxlc19vZl90eXBlKHdoZW4sJmN0bXApOwogICAgICAgICAgICAgICAgICAgIGN1cmZpbGVuYW1lID0gcHJldl9maWxlbmFtZTsKICAgICAgICAgICAgICAgICAgICBsaW5lY291bnQgICA9IHByZXZfbGluZWNvdW50OwogICAgICAgICAgICAgICAgICAgIGlmICgobGVuID4gNSkgJiYgKGNwdHJbbGVuLTVdID09IDApKQogICAgICAgICAgICAgICAgICAgICAgIGNwdHJbbGVuLTVdID0gJy4nOyAvKiByZXN0b3JlIC5jb25mICovCiAgICAgICAgICAgICAgICAgICAgaWYgKCggcmV0ICE9IFNOTVBFUlJfU1VDQ0VTUyApICYmICh3aGVuICE9IFBSRU1JQl9DT05GSUcpKQoJCSAgICAgICAgbmV0c25tcF9jb25maWdfZXJyb3IoIkluY2x1ZGVkIGNvbmZpZyAnJXMnIG5vdCBmb3VuZC4iLCBjcHRyKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbHB0ciA9IGxpbmVfaGFuZGxlcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxwdHIgPSBsaW5lX2hhbmRsZXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNwdHIgPT0gTlVMTCkgewoJCW5ldHNubXBfY29uZmlnX2Vycm9yKCJCbGFuayBsaW5lIGZvbGxvd2luZyAlcyB0b2tlbi4iLCB0b2tlbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWc6bGluZSIsICIlczolZCBleGFtaW5pbmc6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxpbmVjb3VudCwgbGluZSkpOwogICAgICAgICAgICAgICAgcnVuX2NvbmZpZ19oYW5kbGVyKGxwdHIsIHRva2VuLCBjcHRyLCB3aGVuKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGZjbG9zZShpZmlsZSk7CiAgICAtLWRlcHRoOwogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHJlYWRfY29uZmlnKCkgKi8KCgoKdm9pZApmcmVlX2NvbmZpZyh2b2lkKQp7CiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjdG1wID0gY29uZmlnX2ZpbGVzOwogICAgc3RydWN0IGNvbmZpZ19saW5lICpsdG1wOwoKICAgIGZvciAoOyBjdG1wICE9IE5VTEw7IGN0bXAgPSBjdG1wLT5uZXh0KQogICAgICAgIGZvciAobHRtcCA9IGN0bXAtPnN0YXJ0OyBsdG1wICE9IE5VTEw7IGx0bXAgPSBsdG1wLT5uZXh0KQogICAgICAgICAgICBpZiAobHRtcC0+ZnJlZV9mdW5jKQogICAgICAgICAgICAgICAgKCoobHRtcC0+ZnJlZV9mdW5jKSkgKCk7Cn0KCi8qCiAqIFJldHVybiBTTk1QRVJSX1NVQ0NFU1MgaWYgYW55IGNvbmZpZyBmaWxlcyBhcmUgcHJvY2Vzc2VkCiAqIFJldHVybiBTTk1QRVJSX0dFTkVSUiBpZiBfbm9fIGNvbmZpZyBmaWxlcyBhcmUgcHJvY2Vzc2VkCiAqICAgIFdoZXRoZXIgdGhpcyBpcyBhY3R1YWxseSBhbiBlcnJvciBpcyBsZWZ0IHRvIHRoZSBhcHBsaWNhdGlvbgogKi8KaW50CnJlYWRfY29uZmlnc19vcHRpb25hbChjb25zdCBjaGFyICpvcHRpb25hbF9jb25maWcsIGludCB3aGVuKQp7CiAgICBjaGFyICpuZXdwLCAqY3AsICpzdCA9IE5VTEw7CiAgICBpbnQgICAgICAgICAgICAgIHJldCA9IFNOTVBFUlJfR0VORVJSOwogICAgY2hhciAqdHlwZSA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICAgICAgIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpOwoKICAgIGlmICgoTlVMTCA9PSBvcHRpb25hbF9jb25maWcpIHx8IChOVUxMID09IHR5cGUpKQogICAgICAgIHJldHVybiByZXQ7CgogICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnc19vcHRpb25hbCIsCiAgICAgICAgICAgICAgICAicmVhZGluZyBvcHRpb25hbCBjb25maWd1cmF0aW9uIHRva2VucyBmb3IgJXNcbiIsIHR5cGUpKTsKICAgIAogICAgbmV3cCA9IHN0cmR1cChvcHRpb25hbF9jb25maWcpOyAgICAgIC8qIHN0cnRva19yIG1lc3NlcyBpdCB1cCAqLwogICAgY3AgPSBzdHJ0b2tfcihuZXdwLCAiLCIsICZzdCk7CiAgICB3aGlsZSAoY3ApIHsKICAgICAgICBzdHJ1Y3Qgc3RhdCAgICAgc3RhdGJ1ZjsKICAgICAgICBpZiAoc3RhdChjcCwgJnN0YXRidWYpKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJPcHRpb25hbCBGaWxlIFwiJXNcIiBkb2VzIG5vdCBleGlzdC5cbiIsIGNwKSk7CiAgICAgICAgICAgIHNubXBfbG9nX3BlcnJvcihjcCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOm9wdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJSZWFkaW5nIG9wdGlvbmFsIGNvbmZpZyBmaWxlOiBcIiVzXCJcbiIsIGNwKSk7CiAgICAgICAgICAgIGlmICggcmVhZF9jb25maWdfd2l0aF90eXBlX3doZW4oY3AsIHR5cGUsIHdoZW4pID09IFNOTVBFUlJfU1VDQ0VTUyApCiAgICAgICAgICAgICAgICByZXQgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICAgICAgfQogICAgICAgIGNwID0gc3RydG9rX3IoTlVMTCwgIiwiLCAmc3QpOwogICAgfQogICAgZnJlZShuZXdwKTsKICAgIHJldHVybiByZXQ7Cn0KCnZvaWQKcmVhZF9jb25maWdzKHZvaWQpCnsKICAgIGNoYXIgKm9wdGlvbmFsX2NvbmZpZyA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJCSAgICAgICBORVRTTk1QX0RTX0xJQl9PUFRJT05BTENPTkZJRyk7CgogICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0xJQlJBUlksCiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfQ0FMTEJBQ0tfUFJFX1JFQURfQ09ORklHLCBOVUxMKTsKCiAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAicmVhZGluZyBub3JtYWwgY29uZmlndXJhdGlvbiB0b2tlbnNcbiIpKTsKCiAgICBpZiAoKE5VTEwgIT0gb3B0aW9uYWxfY29uZmlnKSAmJiAoKm9wdGlvbmFsX2NvbmZpZyA9PSAnLScpKSB7CiAgICAgICAgKHZvaWQpcmVhZF9jb25maWdzX29wdGlvbmFsKCsrb3B0aW9uYWxfY29uZmlnLCBOT1JNQUxfQ09ORklHKTsKICAgICAgICBvcHRpb25hbF9jb25maWcgPSBOVUxMOyAvKiBjbGVhciwgc28gd2UgZG9uJ3QgcmVhZCB0aGVtIHR3aWNlICovCiAgICB9CgogICAgKHZvaWQpcmVhZF9jb25maWdfZmlsZXMoTk9STUFMX0NPTkZJRyk7CgogICAgLyoKICAgICAqIGRvIHRoaXMgZXZlbiB3aGVuIHRoZSBub3JtYWwgYWJvdmUgd2Fzbid0IGRvbmUgCiAgICAgKi8KICAgIGlmIChOVUxMICE9IG9wdGlvbmFsX2NvbmZpZykKICAgICAgICAodm9pZClyZWFkX2NvbmZpZ3Nfb3B0aW9uYWwob3B0aW9uYWxfY29uZmlnLCBOT1JNQUxfQ09ORklHKTsKCiAgICBuZXRzbm1wX2NvbmZpZ19wcm9jZXNzX21lbW9yaWVzX3doZW4oTk9STUFMX0NPTkZJRywgMSk7CgogICAgbmV0c25tcF9kc19zZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkgICBORVRTTk1QX0RTX0xJQl9IQVZFX1JFQURfQ09ORklHLCAxKTsKICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19MSUJSQVJZLAogICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0NBTExCQUNLX1BPU1RfUkVBRF9DT05GSUcsIE5VTEwpOwp9Cgp2b2lkCnJlYWRfcHJlbWliX2NvbmZpZ3Modm9pZCkKewogICAgY2hhciAqb3B0aW9uYWxfY29uZmlnID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkJICAgICAgIE5FVFNOTVBfRFNfTElCX09QVElPTkFMQ09ORklHKTsKCiAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwKICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9DQUxMQkFDS19QUkVfUFJFTUlCX1JFQURfQ09ORklHLCBOVUxMKTsKCiAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWciLCAicmVhZGluZyBwcmVtaWIgY29uZmlndXJhdGlvbiB0b2tlbnNcbiIpKTsKCiAgICBpZiAoKE5VTEwgIT0gb3B0aW9uYWxfY29uZmlnKSAmJiAoKm9wdGlvbmFsX2NvbmZpZyA9PSAnLScpKSB7CiAgICAgICAgKHZvaWQpcmVhZF9jb25maWdzX29wdGlvbmFsKCsrb3B0aW9uYWxfY29uZmlnLCBQUkVNSUJfQ09ORklHKTsKICAgICAgICBvcHRpb25hbF9jb25maWcgPSBOVUxMOyAvKiBjbGVhciwgc28gd2UgZG9uJ3QgcmVhZCB0aGVtIHR3aWNlICovCiAgICB9CgogICAgKHZvaWQpcmVhZF9jb25maWdfZmlsZXMoUFJFTUlCX0NPTkZJRyk7CgogICAgaWYgKE5VTEwgIT0gb3B0aW9uYWxfY29uZmlnKQogICAgICAgICh2b2lkKXJlYWRfY29uZmlnc19vcHRpb25hbChvcHRpb25hbF9jb25maWcsIFBSRU1JQl9DT05GSUcpOwoKICAgIG5ldHNubXBfY29uZmlnX3Byb2Nlc3NfbWVtb3JpZXNfd2hlbihQUkVNSUJfQ09ORklHLCAwKTsKCiAgICBuZXRzbm1wX2RzX3NldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCSAgIE5FVFNOTVBfRFNfTElCX0hBVkVfUkVBRF9QUkVNSUJfQ09ORklHLCAxKTsKICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19MSUJSQVJZLAogICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0NBTExCQUNLX1BPU1RfUFJFTUlCX1JFQURfQ09ORklHLCBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogc2V0X2NvbmZpZ3VyYXRpb25fZGlyZWN0b3J5CiAqCiAqIFBhcmFtZXRlcnM6CiAqICAgICAgY2hhciAqZGlyIC0gdmFsdWUgb2YgdGhlIGRpcmVjdG9yeQogKiBTZXRzIHRoZSBjb25maWd1cmF0aW9uIGRpcmVjdG9yeS4gTXVsdGlwbGUgZGlyZWN0b3JpZXMgY2FuIGJlCiAqIHNwZWNpZmllZCwgYnV0IG5lZWQgdG8gYmUgc2VwZXJhdGVkIGJ5ICdFTlZfU0VQQVJBVE9SX0NIQVInLgogKi8Kdm9pZApzZXRfY29uZmlndXJhdGlvbl9kaXJlY3RvcnkoY29uc3QgY2hhciAqZGlyKQp7CiAgICBuZXRzbm1wX2RzX3NldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICBORVRTTk1QX0RTX0xJQl9DT05GSUdVUkFUSU9OX0RJUiwgZGlyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogZ2V0X2NvbmZpZ3VyYXRpb25fZGlyZWN0b3J5CiAqCiAqIFBhcmFtZXRlcnM6IC0KICogUmV0cmlldmUgdGhlIGNvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IG9yIGRpcmVjdG9yaWVzLgogKiAoRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHRoYXQgaXM6CiAqICAgICAgIFNOTVBDT05GUEFUSCwgU05NUFNIQVJFUEFUSCwgU05NUExJQlBBVEgsIEhPTUUvLnNubXAKICogRmlyc3QgY2hlY2sgd2hldGhlciB0aGUgdmFsdWUgaXMgc2V0LgogKiBJZiBub3Qgc2V0IGdpdmUgaXQgdGhlIGRlZmF1bHQgdmFsdWUuCiAqIFJldHVybiB0aGUgdmFsdWUuCiAqIFdlIGFsd2F5cyByZXRyaWV2ZSBpdCBuZXcsIHNpbmNlIHdlIGhhdmUgdG8gZG8gaXQgYW55d2F5IGlmIGl0IGlzIGp1c3Qgc2V0LgogKi8KY29uc3QgY2hhciAgICAgKgpnZXRfY29uZmlndXJhdGlvbl9kaXJlY3Rvcnkodm9pZCkKewogICAgY2hhciAgICAgICAgICAgIGRlZmF1bHRQYXRoW1NQUklOVF9NQVhfTEVOXTsKICAgIGNoYXIgICAgICAgICAgICpob21lcGF0aDsKCiAgICBpZiAoTlVMTCA9PSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgIE5FVFNOTVBfRFNfTElCX0NPTkZJR1VSQVRJT05fRElSKSkgewogICAgICAgIGhvbWVwYXRoID0gbmV0c25tcF9nZXRlbnYoIkhPTUUiKTsKICAgICAgICBzbnByaW50ZihkZWZhdWx0UGF0aCwgc2l6ZW9mKGRlZmF1bHRQYXRoKSwgIiVzJWMlcyVjJXMlcyVzJXMiLAogICAgICAgICAgICAgICAgU05NUENPTkZQQVRILCBFTlZfU0VQQVJBVE9SX0NIQVIsCiAgICAgICAgICAgICAgICBTTk1QU0hBUkVQQVRILCBFTlZfU0VQQVJBVE9SX0NIQVIsIFNOTVBMSUJQQVRILAogICAgICAgICAgICAgICAgKChob21lcGF0aCA9PSBOVUxMKSA/ICIiIDogRU5WX1NFUEFSQVRPUiksCiAgICAgICAgICAgICAgICAoKGhvbWVwYXRoID09IE5VTEwpID8gIiIgOiBob21lcGF0aCksCiAgICAgICAgICAgICAgICAoKGhvbWVwYXRoID09IE5VTEwpID8gIiIgOiAiLy5zbm1wIikpOwogICAgICAgIGRlZmF1bHRQYXRoWyBzaXplb2YoZGVmYXVsdFBhdGgpLTEgXSA9IDA7CiAgICAgICAgc2V0X2NvbmZpZ3VyYXRpb25fZGlyZWN0b3J5KGRlZmF1bHRQYXRoKTsKICAgIH0KICAgIHJldHVybiAobmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgIE5FVFNOTVBfRFNfTElCX0NPTkZJR1VSQVRJT05fRElSKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIHNldF9wZXJzaXN0ZW50X2RpcmVjdG9yeQogKgogKiBQYXJhbWV0ZXJzOgogKiAgICAgIGNoYXIgKmRpciAtIHZhbHVlIG9mIHRoZSBkaXJlY3RvcnkKICogU2V0cyB0aGUgY29uZmlndXJhdGlvbiBkaXJlY3RvcnkuIAogKiBObyBtdWx0aXBsZSBkaXJlY3RvcmllcyBtYXkgYmUgc3BlY2lmaWVkLgogKiAoSG93ZXZlciwgdGhpcyBpcyBub3QgY2hlY2tlZCkKICovCnZvaWQKc2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KGNvbnN0IGNoYXIgKmRpcikKewogICAgbmV0c25tcF9kc19zZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCSAgTkVUU05NUF9EU19MSUJfUEVSU0lTVEVOVF9ESVIsIGRpcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeQogKgogKiBQYXJhbWV0ZXJzOiAtCiAqIEZ1bmN0aW9uIHdpbGwgcmV0cmlldmUgdGhlIHBlcnNpc3RlbiBkaXJlY3RvcnkgdmFsdWUuCiAqIEZpcnN0IGNoZWNrIHdoZXRoZXIgdGhlIHZhbHVlIGlzIHNldC4KICogSWYgbm90IHNldCBnaXZlIGl0IHRoZSBkZWZhdWx0IHZhbHVlLgogKiBSZXR1cm4gdGhlIHZhbHVlLiAKICogV2UgYWx3YXlzIHJldHJpZXZlIGl0IG5ldywgc2luY2Ugd2UgaGF2ZSB0byBkbyBpdCBhbnl3YXkgaWYgaXQgaXMganVzdCBzZXQuCiAqLwpjb25zdCBjaGFyICAgICAqCmdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSh2b2lkKQp7CiAgICBpZiAoTlVMTCA9PSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgICAgIE5FVFNOTVBfRFNfTElCX1BFUlNJU1RFTlRfRElSKSkgewogICAgICAgIGNvbnN0IGNoYXIgKnBlcnNkaXIgPSBuZXRzbm1wX2dldGVudigiU05NUF9QRVJTSVNURU5UX0RJUiIpOwogICAgICAgIGlmIChOVUxMID09IHBlcnNkaXIpCiAgICAgICAgICAgIHBlcnNkaXIgPSBORVRTTk1QX1BFUlNJU1RFTlRfRElSRUNUT1JZOwogICAgICAgIHNldF9wZXJzaXN0ZW50X2RpcmVjdG9yeShwZXJzZGlyKTsKICAgIH0KICAgIHJldHVybiAobmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgIE5FVFNOTVBfRFNfTElCX1BFUlNJU1RFTlRfRElSKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIHNldF90ZW1wX2ZpbGVfcGF0dGVybgogKgogKiBQYXJhbWV0ZXJzOgogKiAgICAgIGNoYXIgKnBhdHRlcm4gLSB2YWx1ZSBvZiB0aGUgZmlsZSBwYXR0ZXJuCiAqIFNldHMgdGhlIHRlbXAgZmlsZSBwYXR0ZXJuLiAKICogTXVsdGlwbGUgcGF0dGVybnMgbWF5IG5vdCBiZSBzcGVjaWZpZWQuCiAqIChIb3dldmVyLCB0aGlzIGlzIG5vdCBjaGVja2VkKQogKi8Kdm9pZApzZXRfdGVtcF9maWxlX3BhdHRlcm4oY29uc3QgY2hhciAqcGF0dGVybikKewogICAgbmV0c25tcF9kc19zZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCSAgTkVUU05NUF9EU19MSUJfVEVNUF9GSUxFX1BBVFRFUk4sIHBhdHRlcm4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBnZXRfdGVtcF9maWxlX3BhdHRlcm4KICoKICogUGFyYW1ldGVyczogLQogKiBGdW5jdGlvbiB3aWxsIHJldHJpZXZlIHRoZSB0ZW1wIGZpbGUgcGF0dGVybiB2YWx1ZS4KICogRmlyc3QgY2hlY2sgd2hldGhlciB0aGUgdmFsdWUgaXMgc2V0LgogKiBJZiBub3Qgc2V0IGdpdmUgaXQgdGhlIGRlZmF1bHQgdmFsdWUuCiAqIFJldHVybiB0aGUgdmFsdWUuIAogKiBXZSBhbHdheXMgcmV0cmlldmUgaXQgbmV3LCBzaW5jZSB3ZSBoYXZlIHRvIGRvIGl0IGFueXdheSBpZiBpdCBpcyBqdXN0IHNldC4KICovCmNvbnN0IGNoYXIgICAgICoKZ2V0X3RlbXBfZmlsZV9wYXR0ZXJuKHZvaWQpCnsKICAgIGlmIChOVUxMID09IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJICAgICAgTkVUU05NUF9EU19MSUJfVEVNUF9GSUxFX1BBVFRFUk4pKSB7CiAgICAgICAgc2V0X3RlbXBfZmlsZV9wYXR0ZXJuKE5FVFNOTVBfVEVNUF9GSUxFX1BBVFRFUk4pOwogICAgfQogICAgcmV0dXJuIChuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCSAgTkVUU05NUF9EU19MSUJfVEVNUF9GSUxFX1BBVFRFUk4pKTsKfQoKLyoqCiAqIHV0aWxpdHkgcm91dGluZSBmb3IgcmVhZF9jb25maWdfZmlsZXMKICoKICogUmV0dXJuIFNOTVBFUlJfU1VDQ0VTUyBpZiBhbnkgY29uZmlnIGZpbGVzIGFyZSBwcm9jZXNzZWQKICogUmV0dXJuIFNOTVBFUlJfR0VORVJSIGlmIF9ub18gY29uZmlnIGZpbGVzIGFyZSBwcm9jZXNzZWQKICogICAgV2hldGhlciB0aGlzIGlzIGFjdHVhbGx5IGFuIGVycm9yIGlzIGxlZnQgdG8gdGhlIGFwcGxpY2F0aW9uCiAqLwpzdGF0aWMgaW50CnJlYWRfY29uZmlnX2ZpbGVzX2luX3BhdGgoY29uc3QgY2hhciAqcGF0aCwgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgd2hlbiwgY29uc3QgY2hhciAqcGVyc3BhdGgsIGNvbnN0IGNoYXIgKnBlcnNmaWxlKQp7CiAgICBpbnQgICAgICAgICAgICAgZG9uZSwgajsKICAgIGNoYXIgICAgICAgICAgICBjb25maWdmaWxlWzMwMF07CiAgICBjaGFyICAgICAgICAgICAqY3B0cjEsICpjcHRyMiwgKmVudmNvbmZwYXRoOwogICAgc3RydWN0IHN0YXQgICAgIHN0YXRidWY7CiAgICBpbnQgICAgICAgICAgICAgcmV0ID0gU05NUEVSUl9HRU5FUlI7CgogICAgaWYgKChOVUxMID09IHBhdGgpIHx8IChOVUxMID09IGN0bXApKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICBlbnZjb25mcGF0aCA9IHN0cmR1cChwYXRoKTsKCiAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWc6cGF0aCIsICIgY29uZmlnIHBhdGggdXNlZCBmb3IgJXM6JXMgKHBlcnNpc3RlbnQgcGF0aDolcylcbiIsCiAgICAgICAgICAgICAgICBjdG1wLT5maWxlSGVhZGVyLCBlbnZjb25mcGF0aCwgcGVyc3BhdGgpKTsKICAgIGNwdHIxID0gY3B0cjIgPSBlbnZjb25mcGF0aDsKICAgIGRvbmUgPSAwOwogICAgd2hpbGUgKCghZG9uZSkgJiYgKCpjcHRyMiAhPSAwKSkgewogICAgICAgIHdoaWxlICgqY3B0cjEgIT0gMCAmJiAqY3B0cjEgIT0gRU5WX1NFUEFSQVRPUl9DSEFSKQogICAgICAgICAgICBjcHRyMSsrOwogICAgICAgIGlmICgqY3B0cjEgPT0gMCkKICAgICAgICAgICAgZG9uZSA9IDE7CiAgICAgICAgZWxzZQogICAgICAgICAgICAqY3B0cjEgPSAwOwoKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWc6ZGlyIiwgIiBjb25maWcgZGlyOiAlc1xuIiwgY3B0cjIgKSk7CiAgICAgICAgaWYgKHN0YXQoY3B0cjIsICZzdGF0YnVmKSAhPSAwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIERpcmVjdG9yeSBub3QgdGhlcmUsIGNvbnRpbnVlIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnOmRpciIsICIgRGlyZWN0b3J5IG5vdCBwcmVzZW50OiAlc1xuIiwgY3B0cjIgKSk7CiAgICAgICAgICAgIGNwdHIyID0gKytjcHRyMTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQojaWZkZWYgU19JU0RJUgogICAgICAgIGlmICghU19JU0RJUihzdGF0YnVmLnN0X21vZGUpKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIE5vdCBhIGRpcmVjdG9yeSwgY29udGludWUgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWc6ZGlyIiwgIiBOb3QgYSBkaXJlY3Rvcnk6ICVzXG4iLCBjcHRyMiApKTsKICAgICAgICAgICAgY3B0cjIgPSArK2NwdHIxOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiNlbmRpZgoKICAgICAgICAvKgogICAgICAgICAqIGZvciBwcm9wZXIgcGVyc2lzdGVudCBzdG9yYWdlIHJldHJpZXZhbCwgd2UgbmVlZCB0byByZWFkIG9sZCBiYWNrdXAKICAgICAgICAgKiBjb3BpZXMgb2YgdGhlIHByZXZpb3VzIHN0b3JhZ2UgZmlsZXMuICBJZiB0aGUgYXBwbGljYXRpb24gaW4KICAgICAgICAgKiBxdWVzdGlvbiBoYXMgZGllZCB3aXRob3V0IHRoZSBwcm9wZXIgY2FsbCB0byBzbm1wX2NsZWFuX3BlcnNpc3RlbnQsCiAgICAgICAgICogdGhlbiB3ZSByZWFkIGFsbCB0aGUgY29uZmlndXJhdGlvbiBmaWxlcyB3ZSBjYW4sIHN0YXJ0aW5nIHdpdGgKICAgICAgICAgKiB0aGUgb2xkZXN0IGZpcnN0LgogICAgICAgICAqLwogICAgICAgIGlmIChzdHJuY21wKGNwdHIyLCBwZXJzcGF0aCwgc3RybGVuKHBlcnNwYXRoKSkgPT0gMCB8fAogICAgICAgICAgICAocGVyc2ZpbGUgIT0gTlVMTCAmJgogICAgICAgICAgICAgc3RybmNtcChjcHRyMiwgcGVyc2ZpbGUsIHN0cmxlbihwZXJzZmlsZSkpID09IDApKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZzpwZXJzaXN0IiwgIiBwZXJzaXN0IGRpcjogJXNcbiIsIGNwdHIyICkpOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBsaW1pdCB0aGlzIHRvIHRoZSBrbm93biBzdG9yYWdlIGRpcmVjdG9yeSBvbmx5IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8PSBORVRTTk1QX01BWF9QRVJTSVNURU5UX0JBQ0tVUFM7IGorKykgewogICAgICAgICAgICAgICAgc25wcmludGYoY29uZmlnZmlsZSwgc2l6ZW9mKGNvbmZpZ2ZpbGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIiVzLyVzLiVkLmNvbmYiLCBjcHRyMiwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0bXAtPmZpbGVIZWFkZXIsIGopOwogICAgICAgICAgICAgICAgY29uZmlnZmlsZVsgc2l6ZW9mKGNvbmZpZ2ZpbGUpLTEgXSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoc3RhdChjb25maWdmaWxlLCAmc3RhdGJ1ZikgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogZmlsZSBub3QgdGhlcmUsIGNvbnRpbnVlIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIGJhY2t1cCBleGlzdHMsIHJlYWQgaXQgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnX2ZpbGVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib2xkIGNvbmZpZyBmaWxlIGZvdW5kOiAlcywgcGFyc2luZ1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWdmaWxlKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWRfY29uZmlnKGNvbmZpZ2ZpbGUsIGN0bXAtPnN0YXJ0LCB3aGVuKSA9PSBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IFNOTVBFUlJfU1VDQ0VTUzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzbnByaW50Zihjb25maWdmaWxlLCBzaXplb2YoY29uZmlnZmlsZSksCiAgICAgICAgICAgICAgICAgIiVzLyVzLmNvbmYiLCBjcHRyMiwgY3RtcC0+ZmlsZUhlYWRlcik7CiAgICAgICAgY29uZmlnZmlsZVsgc2l6ZW9mKGNvbmZpZ2ZpbGUpLTEgXSA9IDA7CiAgICAgICAgaWYgKHJlYWRfY29uZmlnKGNvbmZpZ2ZpbGUsIGN0bXAtPnN0YXJ0LCB3aGVuKSA9PSBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgICAgIHJldCA9IFNOTVBFUlJfU1VDQ0VTUzsKICAgICAgICBzbnByaW50Zihjb25maWdmaWxlLCBzaXplb2YoY29uZmlnZmlsZSksCiAgICAgICAgICAgICAgICAgIiVzLyVzLmxvY2FsLmNvbmYiLCBjcHRyMiwgY3RtcC0+ZmlsZUhlYWRlcik7CiAgICAgICAgY29uZmlnZmlsZVsgc2l6ZW9mKGNvbmZpZ2ZpbGUpLTEgXSA9IDA7CiAgICAgICAgaWYgKHJlYWRfY29uZmlnKGNvbmZpZ2ZpbGUsIGN0bXAtPnN0YXJ0LCB3aGVuKSA9PSBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgICAgIHJldCA9IFNOTVBFUlJfU1VDQ0VTUzsKCiAgICAgICAgaWYoZG9uZSkKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNwdHIyID0gKytjcHRyMTsKICAgIH0KICAgIFNOTVBfRlJFRShlbnZjb25mcGF0aCk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiByZWFkX2NvbmZpZ19maWxlcwogKgogKiBQYXJhbWV0ZXJzOgogKgl3aGVuCT09IFBSRU1JQl9DT05GSUcsIE5PUk1BTF9DT05GSUcgIC1vci0gIEVJVEhFUl9DT05GSUcKICoKICoKICogVHJhdmVyc2UgdGhlIGxpc3Qgb2YgY29uZmlnIGZpbGUgdHlwZXMsIHBlcmZvcm1pbmcgdGhlIGZvbGxvd2luZyBhY3Rpb25zCiAqIGZvciBlYWNoIC0tCiAqCiAqIEZpcnN0LCBidWlsZCBhIHNlYXJjaCBwYXRoIGZvciBjb25maWcgZmlsZXMuICBJZiB0aGUgY29udGVudHMgb2YgCiAqIGVudmlyb25tZW50IHZhcmlhYmxlIFNOTVBDT05GUEFUSCBhcmUgTlVMTCwgdGhlbiB1c2UgdGhlIGZvbGxvd2luZwogKiBwYXRoIGxpc3QgKHdoZXJlIHRoZSBsYXN0IGVudHJ5IGV4aXN0cyBvbmx5IGlmIEhPTUUgaXMgbm9uLW51bGwpOgogKgogKglTTk1QU0hBUkVQQVRIOlNOTVBMSUJQQVRIOiR7SE9NRX0vLnNubXAKICoKICogVGhlbiwgSW4gZWFjaCBvZiB0aGVzZSBkaXJlY3RvcmllcywgcmVhZCBjb25maWcgZmlsZXMgYnkgdGhlIG5hbWUgb2Y6CiAqCiAqCTxkaXI+LzxmaWxlSGVhZGVyPi5jb25mCQktQU5ELQogKgk8ZGlyPi88ZmlsZUhlYWRlcj4ubG9jYWwuY29uZgogKgogKiB3aGVyZSA8ZmlsZUhlYWRlcj4gaXMgdGFrZW4gZnJvbSB0aGUgY29uZmlnIGZpbGUgdHlwZSBzdHJ1Y3R1cmUuCiAqCiAqCiAqIFBSRU1JQl9DT05GSUcgY2F1c2VzIGZyZWVfY29uZmlnKCkgdG8gYmUgaW52b2tlZCBwcmlvciB0byBhbnkgb3RoZXIgYWN0aW9uLgogKgogKgogKiBFWElUcyBpZiBhbnkgJ2NvbmZpZ19lcnJvcnMnIGFyZSBsb2dnZWQgd2hpbGUgcGFyc2luZyBjb25maWcgZmlsZSBsaW5lcy4KICoKICogUmV0dXJuIFNOTVBFUlJfU1VDQ0VTUyBpZiBhbnkgY29uZmlnIGZpbGVzIGFyZSBwcm9jZXNzZWQKICogUmV0dXJuIFNOTVBFUlJfR0VORVJSIGlmIF9ub18gY29uZmlnIGZpbGVzIGFyZSBwcm9jZXNzZWQKICogICAgV2hldGhlciB0aGlzIGlzIGFjdHVhbGx5IGFuIGVycm9yIGlzIGxlZnQgdG8gdGhlIGFwcGxpY2F0aW9uCiAqLwppbnQKcmVhZF9jb25maWdfZmlsZXNfb2ZfdHlwZShpbnQgd2hlbiwgc3RydWN0IGNvbmZpZ19maWxlcyAqY3RtcCkKewogICAgY29uc3QgY2hhciAgICAgKmNvbmZwYXRoLCAqcGVyc2ZpbGUsICplbnZjb25mcGF0aDsKICAgIGNoYXIgICAgICAgICAgICpwZXJzcGF0aDsKICAgIGludCAgICAgICAgICAgICByZXQgPSBTTk1QRVJSX0dFTkVSUjsKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ET05UX1BFUlNJU1RfU1RBVEUpCiAgICAgICAgfHwgbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ESVNBQkxFX0NPTkZJR19MT0FEKQogICAgICAgIHx8IChOVUxMID09IGN0bXApKSByZXR1cm4gcmV0OwoKICAgIC8qCiAgICAgKiB0aGVzZSBzaG91bGRuJ3QgY2hhbmdlCiAgICAgKi8KICAgIGNvbmZwYXRoID0gZ2V0X2NvbmZpZ3VyYXRpb25fZGlyZWN0b3J5KCk7CiAgICBwZXJzZmlsZSA9IG5ldHNubXBfZ2V0ZW52KCJTTk1QX1BFUlNJU1RFTlRfRklMRSIpOwogICAgZW52Y29uZnBhdGggPSBuZXRzbm1wX2dldGVudigiU05NUENPTkZQQVRIIik7CgoKICAgICAgICAvKgogICAgICAgICAqIHJlYWQgdGhlIGNvbmZpZyBmaWxlcy4gc3RyZHVwKCkgdGhlIHJlc3VsdCBvZgogICAgICAgICAqIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpIHRvIGF2b2lkIHRoYXQgcGFyc2luZyB0aGUgInBlcnNpc3RlbnREaXIiCiAgICAgICAgICoga2V5d29yZCB0cmFuc2Zvcm1zIHRoZSBwZXJzcGF0aCBwb2ludGVyIGludG8gYSBkYW5nbGluZyBwb2ludGVyLgogICAgICAgICAqLwogICAgICAgIHBlcnNwYXRoID0gc3RyZHVwKGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpKTsKICAgICAgICBpZiAoZW52Y29uZnBhdGggPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByZWFkIGp1c3QgdGhlIGNvbmZpZyBmaWxlcyAobm8gcGVyc2lzdGVudCBzdHVmZiksIHNpbmNlCiAgICAgICAgICAgICAqIHBlcnNpc3RlbnQgcGF0aCBjYW4gY2hhbmdlIHZpYSBjb25mIGZpbGUuIFRoZW4gZ2V0IHRoZQogICAgICAgICAgICAgKiBjdXJyZW50IHBlcnNpc3RlbnQgZGlyZWN0b3J5LCBhbmQgcmVhZCBmaWxlcyB0aGVyZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICggcmVhZF9jb25maWdfZmlsZXNfaW5fcGF0aChjb25mcGF0aCwgY3RtcCwgd2hlbiwgcGVyc3BhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyc2ZpbGUpID09IFNOTVBFUlJfU1VDQ0VTUyApCiAgICAgICAgICAgICAgICByZXQgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICAgICAgICAgIGZyZWUocGVyc3BhdGgpOwogICAgICAgICAgICBwZXJzcGF0aCA9IHN0cmR1cChnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSk7CiAgICAgICAgICAgIGlmICggcmVhZF9jb25maWdfZmlsZXNfaW5fcGF0aChwZXJzcGF0aCwgY3RtcCwgd2hlbiwgcGVyc3BhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyc2ZpbGUpID09IFNOTVBFUlJfU1VDQ0VTUyApCiAgICAgICAgICAgICAgICByZXQgPSBTTk1QRVJSX1NVQ0NFU1M7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBvbmx5IHJlYWQgcGF0aCBzcGVjaWZpZWQgYnkgdXNlcgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCByZWFkX2NvbmZpZ19maWxlc19pbl9wYXRoKGVudmNvbmZwYXRoLCBjdG1wLCB3aGVuLCBwZXJzcGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJzZmlsZSkgPT0gU05NUEVSUl9TVUNDRVNTICkKICAgICAgICAgICAgICAgIHJldCA9IFNOTVBFUlJfU1VDQ0VTUzsKICAgICAgICB9CiAgICAgICAgZnJlZShwZXJzcGF0aCk7CiAgICAgICAgcmV0dXJuIHJldDsKfQoKLyoKICogUmV0dXJuIFNOTVBFUlJfU1VDQ0VTUyBpZiBhbnkgY29uZmlnIGZpbGVzIGFyZSBwcm9jZXNzZWQKICogUmV0dXJuIFNOTVBFUlJfR0VORVJSIGlmIF9ub18gY29uZmlnIGZpbGVzIGFyZSBwcm9jZXNzZWQKICogICAgV2hldGhlciB0aGlzIGlzIGFjdHVhbGx5IGFuIGVycm9yIGlzIGxlZnQgdG8gdGhlIGFwcGxpY2F0aW9uCiAqLwppbnQKcmVhZF9jb25maWdfZmlsZXMoaW50IHdoZW4pIHsKCiAgICBzdHJ1Y3QgY29uZmlnX2ZpbGVzICpjdG1wID0gY29uZmlnX2ZpbGVzOwogICAgaW50ICAgICAgICAgICAgICAgICAgcmV0ICA9IFNOTVBFUlJfR0VORVJSOwoKICAgIGNvbmZpZ19lcnJvcnMgPSAwOwoKICAgIGlmICh3aGVuID09IFBSRU1JQl9DT05GSUcpCiAgICAgICAgZnJlZV9jb25maWcoKTsKCiAgICAvKgogICAgICogcmVhZCBhbGwgY29uZmlnIGZpbGUgdHlwZXMgCiAgICAgKi8KICAgIGZvciAoOyBjdG1wICE9IE5VTEw7IGN0bXAgPSBjdG1wLT5uZXh0KSB7CiAgICAgICAgaWYgKCByZWFkX2NvbmZpZ19maWxlc19vZl90eXBlKHdoZW4sIGN0bXApID09IFNOTVBFUlJfU1VDQ0VTUyApCiAgICAgICAgICAgIHJldCA9IFNOTVBFUlJfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAoY29uZmlnX2Vycm9ycykgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJuZXQtc25tcDogJWQgZXJyb3IocykgaW4gY29uZmlnIGZpbGUocylcbiIsCiAgICAgICAgICAgICAgICAgY29uZmlnX2Vycm9ycyk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9Cgp2b2lkCnJlYWRfY29uZmlnX3ByaW50X3VzYWdlKGNvbnN0IGNoYXIgKmxlYWQpCnsKICAgIHN0cnVjdCBjb25maWdfZmlsZXMgKmN0bXAgPSBjb25maWdfZmlsZXM7CiAgICBzdHJ1Y3QgY29uZmlnX2xpbmUgKmx0bXA7CgogICAgaWYgKGxlYWQgPT0gTlVMTCkKICAgICAgICBsZWFkID0gIiI7CgogICAgZm9yIChjdG1wID0gY29uZmlnX2ZpbGVzOyBjdG1wICE9IE5VTEw7IGN0bXAgPSBjdG1wLT5uZXh0KSB7CiAgICAgICAgc25tcF9sb2coTE9HX0lORk8sICIlc0luICVzLmNvbmYgYW5kICVzLmxvY2FsLmNvbmY6XG4iLCBsZWFkLAogICAgICAgICAgICAgICAgIGN0bXAtPmZpbGVIZWFkZXIsIGN0bXAtPmZpbGVIZWFkZXIpOwogICAgICAgIGZvciAobHRtcCA9IGN0bXAtPnN0YXJ0OyBsdG1wICE9IE5VTEw7IGx0bXAgPSBsdG1wLT5uZXh0KSB7CiAgICAgICAgICAgIERFQlVHSUYoInJlYWRfY29uZmlnX3VzYWdlIikgewogICAgICAgICAgICAgICAgaWYgKGx0bXAtPmNvbmZpZ190aW1lID09IFBSRU1JQl9DT05GSUcpCiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJyZWFkX2NvbmZpZ191c2FnZSIsICIqIikpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgicmVhZF9jb25maWdfdXNhZ2UiLCAiICIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobHRtcC0+aGVscCkgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0lORk8sICIlcyVzJS0yNHMgJXNcbiIsIGxlYWQsIGxlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBsdG1wLT5jb25maWdfdG9rZW4sIGx0bXAtPmhlbHApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgREVCVUdJRigicmVhZF9jb25maWdfdXNhZ2UiKSB7CiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0lORk8sICIlcyVzJS0yNHMgW05PIEhFTFBdXG4iLCBsZWFkLCBsZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGx0bXAtPmNvbmZpZ190b2tlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8qKgogKiByZWFkX2NvbmZpZ19zdG9yZSBpbnRlbmRlZCBmb3IgdXNlIGJ5IGFwcGxpY2F0aW9ucyB0byBzdG9yZSBwZXJtZW5hbnQKICogY29uZmlndXJhdGlvbiBpbmZvcm1hdGlvbiBnZW5lcmF0ZWQgYnkgc2V0cyBvciBwZXJzaXN0ZW50IGNvdW50ZXJzLgogKiBBcHBlbmRzIGxpbmUgdG8gYSBmaWxlIG5hbWVkIGVpdGhlciBFTlYoU05NUF9QRVJTSVNURU5UX0ZJTEUpIG9yCiAqICAgIjxORVRTTk1QX1BFUlNJU1RFTlRfRElSRUNUT1JZPi88dHlwZT4uY29uZiIuCiAqIEFkZHMgYSB0cmFpbGluZyBuZXdsaW5lIHRvIHRoZSBzdG9yZWQgZmlsZSBpZiBuZWNlc3NhcnkuCiAqCiAqIEBwYXJhbSB0eXBlIGlzIHRoZSBhcHBsaWNhdGlvbiBuYW1lCiAqIEBwYXJhbSBsaW5lIGlzIHRoZSBjb25maWd1cmF0aW9uIGxpbmUgd3JpdHRlbiB0byB0aGUgYXBwbGljYXRpb24gbmFtZSdzCiAqIGNvbmZpZ3VyYXRpb24gZmlsZQogKiAgICAgIAogKiBAcmV0dXJuIHZvaWQKICAqLwp2b2lkCnJlYWRfY29uZmlnX3N0b3JlKGNvbnN0IGNoYXIgKnR5cGUsIGNvbnN0IGNoYXIgKmxpbmUpCnsKI2lmZGVmIE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlkKICAgIGNoYXIgICAgICAgICAgICBmaWxlWzUxMl0sICpmaWxlcDsKICAgIEZJTEUgICAgICAgICAgICpmb3V0OwojaWZkZWYgTkVUU05NUF9QRVJTSVNURU5UX01BU0sKICAgIG1vZGVfdCAgICAgICAgICBvbGRtYXNrOwojZW5kaWYKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ET05UX1BFUlNJU1RfU1RBVEUpCiAgICAgfHwgbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ESVNBQkxFX1BFUlNJU1RFTlRfTE9BRCkpIHJldHVybjsKCiAgICAvKgogICAgICogc3RvcmUgY29uZmlndXJhdGlvbiBkaXJlY3RpdmVzIGluIHRoZSBmb2xsb3dpbmcgb3JkZXIgb2YgcHJlZmVyZW5jZToKICAgICAqIDEuIEVOViB2YXJpYWJsZSBTTk1QX1BFUlNJU1RFTlRfRklMRQogICAgICogMi4gY29uZmlndXJlZCA8TkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWT4vPHR5cGU+LmNvbmYKICAgICAqLwogICAgaWYgKChmaWxlcCA9IG5ldHNubXBfZ2V0ZW52KCJTTk1QX1BFUlNJU1RFTlRfRklMRSIpKSA9PSBOVUxMKSB7CiAgICAgICAgc25wcmludGYoZmlsZSwgc2l6ZW9mKGZpbGUpLAogICAgICAgICAgICAgICAgICIlcy8lcy5jb25mIiwgZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KCksIHR5cGUpOwogICAgICAgIGZpbGVbIHNpemVvZihmaWxlKS0xIF0gPSAwOwogICAgICAgIGZpbGVwID0gZmlsZTsKICAgIH0KI2lmZGVmIE5FVFNOTVBfUEVSU0lTVEVOVF9NQVNLCiAgICBvbGRtYXNrID0gdW1hc2soTkVUU05NUF9QRVJTSVNURU5UX01BU0spOwojZW5kaWYKICAgIGlmIChta2RpcmhpZXIoZmlsZXAsIE5FVFNOTVBfQUdFTlRfRElSRUNUT1JZX01PREUsIDEpKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIGNyZWF0ZSB0aGUgcGVyc2lzdGVudCBkaXJlY3RvcnkgZm9yICVzXG4iLAogICAgICAgICAgICAgICAgIGZpbGUpOwogICAgfQogICAgaWYgKChmb3V0ID0gZm9wZW4oZmlsZXAsICJhIikpICE9IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKGZvdXQsICIlcyIsIGxpbmUpOwogICAgICAgIGlmIChsaW5lW3N0cmxlbihsaW5lKV0gIT0gJ1xuJykKICAgICAgICAgICAgZnByaW50Zihmb3V0LCAiXG4iKTsKICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWc6c3RvcmUiLCAic3RvcmluZzogJXNcbiIsIGxpbmUpKTsKICAgICAgICBmY2xvc2UoZm91dCk7CiAgICB9IGVsc2UgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJyZWFkX2NvbmZpZ19zdG9yZSBvcGVuIGZhaWx1cmUgb24gJXNcbiIsIGZpbGVwKTsKICAgIH0KI2lmZGVmIE5FVFNOTVBfUEVSU0lTVEVOVF9NQVNLCiAgICB1bWFzayhvbGRtYXNrKTsKI2VuZGlmCgojZW5kaWYKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgcmVhZF9jb25maWdfc3RvcmUoKSAqLwoKdm9pZApyZWFkX2FwcF9jb25maWdfc3RvcmUoY29uc3QgY2hhciAqbGluZSkKewogICAgcmVhZF9jb25maWdfc3RvcmUobmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkJICAgIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpLCBsaW5lKTsKfQoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogc25tcF9zYXZlX3BlcnNpc3RlbnQKICoKICogUGFyYW1ldGVyczoKICoJKnR5cGUKICogICAgICAKICoKICogU2F2ZSB0aGUgZmlsZSAiPE5FVFNOTVBfUEVSU0lTVEVOVF9ESVJFQ1RPUlk+Lzx0eXBlPi5jb25mIiBpbnRvIGEgYmFja3VwIGNvcHkKICogY2FsbGVkICI8TkVUU05NUF9QRVJTSVNURU5UX0RJUkVDVE9SWT4vPHR5cGU+LiVkLmNvbmYiLCB3aGljaCAlZCBpcyBhbgogKiBpbmNyZW1lbnRpbmcgbnVtYmVyIG9uIGVhY2ggY2FsbCwgYnV0IGxlc3MgdGhhbiBORVRTTk1QX01BWF9QRVJTSVNURU5UX0JBQ0tVUFMuCiAqCiAqIFNob3VsZCBiZSBjYWxsZWQganVzdCBiZWZvcmUgYWxsIHBlcnNpc3RlbnQgaW5mb3JtYXRpb24gaXMgc3VwcG9zZWQgdG8gYmUKICogd3JpdHRlbiB0byBtb3ZlIGFzaWRlIHRoZSBleGlzdGluZyBwZXJzaXN0ZW50IGNhY2hlLgogKiBzbm1wX2NsZWFuX3BlcnNpc3RlbnQgc2hvdWxkIHRoZW4gYmUgY2FsbGVkIGFmdGVyd2FyZCBhbGwgZGF0YSBoYXMgYmVlbgogKiBzYXZlZCB0byByZW1vdmUgdGhlc2UgYmFja3VwIGZpbGVzLgogKgogKiBOb3RlOiBvbiBhbiByZW5hbWUgZXJyb3IsIHRoZSBmaWxlcyBhcmUgcmVtb3ZlZCByYXRoZXIgdGhhbiBzYXZlZC4KICoKICovCnZvaWQKc25tcF9zYXZlX3BlcnNpc3RlbnQoY29uc3QgY2hhciAqdHlwZSkKewogICAgY2hhciAgICAgICAgICAgIGZpbGVbNTEyXSwgZmlsZW9sZFtTUFJJTlRfTUFYX0xFTl07CiAgICBzdHJ1Y3Qgc3RhdCAgICAgc3RhdGJ1ZjsKICAgIGludCAgICAgICAgICAgICBqOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RPTlRfUEVSU0lTVF9TVEFURSkKICAgICB8fCBuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0RJU0FCTEVfUEVSU0lTVEVOVF9TQVZFKSkgcmV0dXJuOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX3NhdmVfcGVyc2lzdGVudCIsICJzYXZpbmcgJXMgZmlsZXMuLi5cbiIsIHR5cGUpKTsKICAgIHNucHJpbnRmKGZpbGUsIHNpemVvZihmaWxlKSwKICAgICAgICAgICAgICIlcy8lcy5jb25mIiwgZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KCksIHR5cGUpOwogICAgZmlsZVsgc2l6ZW9mKGZpbGUpLTEgXSA9IDA7CiAgICBpZiAoc3RhdChmaWxlLCAmc3RhdGJ1ZikgPT0gMCkgewogICAgICAgIGZvciAoaiA9IDA7IGogPD0gTkVUU05NUF9NQVhfUEVSU0lTVEVOVF9CQUNLVVBTOyBqKyspIHsKICAgICAgICAgICAgc25wcmludGYoZmlsZW9sZCwgc2l6ZW9mKGZpbGVvbGQpLAogICAgICAgICAgICAgICAgICAgICAiJXMvJXMuJWQuY29uZiIsIGdldF9wZXJzaXN0ZW50X2RpcmVjdG9yeSgpLCB0eXBlLCBqKTsKICAgICAgICAgICAgZmlsZW9sZFsgc2l6ZW9mKGZpbGVvbGQpLTEgXSA9IDA7CiAgICAgICAgICAgIGlmIChzdGF0KGZpbGVvbGQsICZzdGF0YnVmKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9zYXZlX3BlcnNpc3RlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBzYXZpbmcgb2xkIGNvbmZpZyBmaWxlOiAlcyAtPiAlcy5cbiIsIGZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlb2xkKSk7CiAgICAgICAgICAgICAgICBpZiAocmVuYW1lKGZpbGUsIGZpbGVvbGQpKSB7CiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkNhbm5vdCByZW5hbWUgJXMgdG8gJXNcbiIsIGZpbGUsIGZpbGVvbGQpOwogICAgICAgICAgICAgICAgICAgICAvKiBtb3ZpbmcgaXQgZmFpbGVkLCB0cnkgbnVraW5nIGl0LCBhcyBsZWF2aW5nCiAgICAgICAgICAgICAgICAgICAgICAqIGl0IGFyb3VuZCBpcyB2ZXJ5IGJhZC4gKi8KICAgICAgICAgICAgICAgICAgICBpZiAodW5saW5rKGZpbGUpID09IC0xKQogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiQ2Fubm90IHVubGluayAlc1xuIiwgZmlsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8qCiAgICAgKiBzYXZlIGEgd2FybmluZyBoZWFkZXIgdG8gdGhlIHRvcCBvZiB0aGUgbmV3IGZpbGUgCiAgICAgKi8KICAgIHNucHJpbnRmKGZpbGVvbGQsIHNpemVvZihmaWxlb2xkKSwKICAgICAgICAgICAgIiVzJXMjIFBsZWFzZSBzYXZlIG5vcm1hbCBjb25maWd1cmF0aW9uIHRva2VucyBmb3IgJXMgaW4gU05NUENPTkZQQVRILyVzLmNvbmYuXG4jIE9ubHkgXCJjcmVhdGVVc2VyXCIgdG9rZW5zIHNob3VsZCBiZSBwbGFjZWQgaGVyZSBieSAlcyBhZG1pbmlzdHJhdG9ycy5cbiVzIiwKICAgICAgICAgICAgIiNcbiMgbmV0LXNubXAgKG9yIHVjZC1zbm1wKSBwZXJzaXN0ZW50IGRhdGEgZmlsZS5cbiNcbiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbiMgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgXG4iLAogICAgICAgICAgICAiI1xuIyAgICAgICAgICAqKioqIERPIE5PVCBFRElUIFRISVMgRklMRSAqKioqXG4jXG4jIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFNUT1AgU1RPUCBTVE9QIFxuIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI1xuI1xuIyBETyBOT1QgU1RPUkUgQ09ORklHVVJBVElPTiBFTlRSSUVTIEhFUkUuXG4iLAogICAgICAgICAgICB0eXBlLCB0eXBlLCB0eXBlLAoJICAgICIjIChEaWQgSSBtZW50aW9uOiBkbyBub3QgZWRpdCB0aGlzIGZpbGU/KVxuI1xuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cbiIpOwogICAgZmlsZW9sZFsgc2l6ZW9mKGZpbGVvbGQpLTEgXSA9IDA7CiAgICByZWFkX2NvbmZpZ19zdG9yZSh0eXBlLCBmaWxlb2xkKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIHNubXBfY2xlYW5fcGVyc2lzdGVudAogKgogKiBQYXJhbWV0ZXJzOgogKgkqdHlwZQogKiAgICAgIAogKgogKiBVbmxpbmsgYWxsIGJhY2t1cCBmaWxlcyBjYWxsZWQgIjxORVRTTk1QX1BFUlNJU1RFTlRfRElSRUNUT1JZPi88dHlwZT4uJWQuY29uZiIuCiAqCiAqIFNob3VsZCBiZSBjYWxsZWQganVzdCBhZnRlciB3ZSBzdWNjZXNzZnVsbCBkdW1wZWQgdGhlIGxhc3Qgb2YgdGhlCiAqIHBlcnNpc3RlbnQgZGF0YSwgdG8gcmVtb3ZlIHRoZSBiYWNrdXAgY29waWVzIG9mIHByZXZpb3VzIHN0b3JhZ2UgZHVtcHMuCiAqCiAqIFhYWCAgV29ydGggb3ZlcndyaXRpbmcgd2l0aCByYW5kb20gYnl0ZXMgZmlyc3Q/ICBUaGlzIHdvdWxkCiAqCWVuc3VyZSB0aGF0IHRoZSBkYXRhIGlzIGRlc3Ryb3llZCwgZXZlbiBhIGJ1ZmZlciBjb250YWluaW5nIHRoZQogKglkYXRhIHBlcnNpc3RzIGluIG1lbW9yeSBvciBzd2FwLiAgT25seSBpbXBvcnRhbnQgaWYgc2VjcmV0cwogKgl3aWxsIGJlIHN0b3JlZCBoZXJlLgogKi8Kdm9pZApzbm1wX2NsZWFuX3BlcnNpc3RlbnQoY29uc3QgY2hhciAqdHlwZSkKewogICAgY2hhciAgICAgICAgICAgIGZpbGVbNTEyXTsKICAgIHN0cnVjdCBzdGF0ICAgICBzdGF0YnVmOwogICAgaW50ICAgICAgICAgICAgIGo7CgogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfRE9OVF9QRVJTSVNUX1NUQVRFKQogICAgIHx8IG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfRElTQUJMRV9QRVJTSVNURU5UX1NBVkUpKSByZXR1cm47CgogICAgREVCVUdNU0dUTCgoInNubXBfY2xlYW5fcGVyc2lzdGVudCIsICJjbGVhbmluZyAlcyBmaWxlcy4uLlxuIiwgdHlwZSkpOwogICAgc25wcmludGYoZmlsZSwgc2l6ZW9mKGZpbGUpLAogICAgICAgICAgICAgIiVzLyVzLmNvbmYiLCBnZXRfcGVyc2lzdGVudF9kaXJlY3RvcnkoKSwgdHlwZSk7CiAgICBmaWxlWyBzaXplb2YoZmlsZSktMSBdID0gMDsKICAgIGlmIChzdGF0KGZpbGUsICZzdGF0YnVmKSA9PSAwKSB7CiAgICAgICAgZm9yIChqID0gMDsgaiA8PSBORVRTTk1QX01BWF9QRVJTSVNURU5UX0JBQ0tVUFM7IGorKykgewogICAgICAgICAgICBzbnByaW50ZihmaWxlLCBzaXplb2YoZmlsZSksCiAgICAgICAgICAgICAgICAgICAgICIlcy8lcy4lZC5jb25mIiwgZ2V0X3BlcnNpc3RlbnRfZGlyZWN0b3J5KCksIHR5cGUsIGopOwogICAgICAgICAgICBmaWxlWyBzaXplb2YoZmlsZSktMSBdID0gMDsKICAgICAgICAgICAgaWYgKHN0YXQoZmlsZSwgJnN0YXRidWYpID09IDApIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2NsZWFuX3BlcnNpc3RlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiByZW1vdmluZyBvbGQgY29uZmlnIGZpbGU6ICVzXG4iLCBmaWxlKSk7CiAgICAgICAgICAgICAgICBpZiAodW5saW5rKGZpbGUpID09IC0xKQogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJDYW5ub3QgdW5saW5rICVzXG4iLCBmaWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKCgoKLyoKICogY29uZmlnX3BlcnJvcjogcHJpbnRzIGEgd2FybmluZyBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIGEgZmlsZSBhbmQKICogbGluZSBudW1iZXIgb2YgYSAuY29uZiBmaWxlIGFuZCBpbmNyZW1lbnRzIHRoZSBlcnJvciBjb3VudC4gCiAqLwpzdGF0aWMgdm9pZApjb25maWdfdmxvZyhpbnQgbGV2ZWwsIGNvbnN0IGNoYXIgKmxldmVsbXNnLCBjb25zdCBjaGFyICpzdHIsIHZhX2xpc3QgYXJncykKewogICAgY2hhciB0bXBidWZbMjU2XTsKICAgIGNoYXIqIGJ1ZiA9IHRtcGJ1ZjsKICAgIGludCBsZW4gPSBzbnByaW50Zih0bXBidWYsIHNpemVvZih0bXBidWYpLCAiJXM6IGxpbmUgJWQ6ICVzOiAlc1xuIiwKCQkgICAgICAgY3VyZmlsZW5hbWUsIGxpbmVjb3VudCwgbGV2ZWxtc2csIHN0cik7CiAgICBpZiAobGVuID49IChpbnQpc2l6ZW9mKHRtcGJ1ZikpIHsKCWJ1ZiA9IChjaGFyKiltYWxsb2MobGVuICsgMSk7CglzcHJpbnRmKGJ1ZiwgIiVzOiBsaW5lICVkOiAlczogJXNcbiIsCgkJY3VyZmlsZW5hbWUsIGxpbmVjb3VudCwgbGV2ZWxtc2csIHN0cik7CiAgICB9CiAgICBzbm1wX3Zsb2cobGV2ZWwsIGJ1ZiwgYXJncyk7CiAgICBpZiAoYnVmICE9IHRtcGJ1ZikKCWZyZWUoYnVmKTsKfQoKdm9pZApuZXRzbm1wX2NvbmZpZ19lcnJvcihjb25zdCBjaGFyICpzdHIsIC4uLikKewogICAgdmFfbGlzdCBhcmdzOwogICAgdmFfc3RhcnQoYXJncywgc3RyKTsKICAgIGNvbmZpZ192bG9nKExPR19FUlIsICJFcnJvciIsIHN0ciwgYXJncyk7CiAgICB2YV9lbmQoYXJncyk7CiAgICBjb25maWdfZXJyb3JzKys7Cn0KCnZvaWQKbmV0c25tcF9jb25maWdfd2Fybihjb25zdCBjaGFyICpzdHIsIC4uLikKewogICAgdmFfbGlzdCBhcmdzOwogICAgdmFfc3RhcnQoYXJncywgc3RyKTsKICAgIGNvbmZpZ192bG9nKExPR19XQVJOSU5HLCAiV2FybmluZyIsIHN0ciwgYXJncyk7CiAgICB2YV9lbmQoYXJncyk7Cn0KCnZvaWQKY29uZmlnX3BlcnJvcihjb25zdCBjaGFyICpzdHIpCnsKICAgIG5ldHNubXBfY29uZmlnX2Vycm9yKCIlcyIsIHN0cik7Cn0KCnZvaWQKY29uZmlnX3B3YXJuKGNvbnN0IGNoYXIgKnN0cikKewogICAgbmV0c25tcF9jb25maWdfd2FybigiJXMiLCBzdHIpOwp9CgovKgogKiBza2lwIGFsbCB3aGl0ZSBzcGFjZXMgYW5kIHJldHVybiAxIGlmIGZvdW5kIHNvbWV0aGluZyBlaXRoZXIgZW5kIG9mCiAqIGxpbmUgb3IgYSBjb21tZW50IGNoYXJhY3RlciAKICovCmNoYXIgICAgICAgICAgICoKc2tpcF93aGl0ZShjaGFyICpwdHIpCnsKICAgIHJldHVybiBORVRTTk1QX1JFTU9WRV9DT05TVChjaGFyICosIHNraXBfd2hpdGVfY29uc3QocHRyKSk7Cn0KCmNvbnN0IGNoYXIgICAgICoKc2tpcF93aGl0ZV9jb25zdChjb25zdCBjaGFyICpwdHIpCnsKICAgIGlmIChwdHIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgd2hpbGUgKCpwdHIgIT0gMCAmJiBpc3NwYWNlKCh1bnNpZ25lZCBjaGFyKSpwdHIpKQogICAgICAgIHB0cisrOwogICAgaWYgKCpwdHIgPT0gMCB8fCAqcHRyID09ICcjJykKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgcmV0dXJuIChwdHIpOwp9CgpjaGFyICAgICAgICAgICAqCnNraXBfbm90X3doaXRlKGNoYXIgKnB0cikKewogICAgcmV0dXJuIE5FVFNOTVBfUkVNT1ZFX0NPTlNUKGNoYXIgKiwgc2tpcF9ub3Rfd2hpdGVfY29uc3QocHRyKSk7Cn0KCmNvbnN0IGNoYXIgICAgICoKc2tpcF9ub3Rfd2hpdGVfY29uc3QoY29uc3QgY2hhciAqcHRyKQp7CiAgICBpZiAocHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHdoaWxlICgqcHRyICE9IDAgJiYgIWlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpKnB0cikpCiAgICAgICAgcHRyKys7CiAgICBpZiAoKnB0ciA9PSAwIHx8ICpwdHIgPT0gJyMnKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXR1cm4gKHB0cik7Cn0KCmNoYXIgICAgICAgICAgICoKc2tpcF90b2tlbihjaGFyICpwdHIpCnsKICAgIHJldHVybiBORVRTTk1QX1JFTU9WRV9DT05TVChjaGFyICosIHNraXBfdG9rZW5fY29uc3QocHRyKSk7Cn0KCmNvbnN0IGNoYXIgICAgICoKc2tpcF90b2tlbl9jb25zdChjb25zdCBjaGFyICpwdHIpCnsKICAgIHB0ciA9IHNraXBfd2hpdGVfY29uc3QocHRyKTsKICAgIHB0ciA9IHNraXBfbm90X3doaXRlX2NvbnN0KHB0cik7CiAgICBwdHIgPSBza2lwX3doaXRlX2NvbnN0KHB0cik7CiAgICByZXR1cm4gKHB0cik7Cn0KCi8qCiAqIGNvcHlfd29yZAogKiBjb3BpZXMgdGhlIG5leHQgJ3Rva2VuJyBmcm9tICdmcm9tJyBpbnRvICd0bycsIG1heGltdW0gbGVuLTEgY2hhcmFjdGVycy4KICogY3VycmVudGx5IGEgdG9rZW4gaXMgYW55dGhpbmcgc2VwZXJhdGUgYnkgd2hpdGUgc3BhY2UKICogb3Igd2l0aGluIHF1b3RlcyAoZG91YmxlIG9yIHNpbmdsZSkgKGkuZS4gInRoZSByZWQgcm9zZSIgCiAqIGlzIG9uZSB0b2tlbiwgXCJ0aGUgcmVkIHJvc2VcIiBpcyB0aHJlZSB0b2tlbnMpCiAqIGEgJ1wnIGNoYXJhY3RlciB3aWxsIGFsbG93IGEgcXVvdGUgY2hhcmFjdGVyIHRvIGJlIHRyZWF0ZWQKICogYXMgYSByZWd1bGFyIGNoYXJhY3RlciAKICogSXQgcmV0dXJucyBhIHBvaW50ZXIgdG8gZmlyc3Qgbm9uLXdoaXRlIHNwYWNlIGFmdGVyIHRoZSBlbmQgb2YgdGhlIHRva2VuCiAqIGJlaW5nIGNvcGllZCBvciB0byAwIGlmIHdlIHJlYWNoIHRoZSBlbmQuCiAqIE5vdGU6IFBhcnRpYWxseSBjb3BpZWQgd29yZHMgKGdyZWF0ZXIgdGhhbiBsZW4pIHN0aWxsIHJldHVybnMgYSAhTlVMTCBwdHIKICogTm90ZTogcGFydGlhbGx5IGNvcGllZCB3b3JkcyBhcmUsIGhvd2V2ZXIsIG51bGwgdGVybWluYXRlZC4KICovCgpjaGFyICAgICAgICAgICAqCmNvcHlfbndvcmQoY2hhciAqZnJvbSwgY2hhciAqdG8sIGludCBsZW4pCnsKICAgIHJldHVybiBORVRTTk1QX1JFTU9WRV9DT05TVChjaGFyICosIGNvcHlfbndvcmRfY29uc3QoZnJvbSwgdG8sIGxlbikpOwp9Cgpjb25zdCBjaGFyICAgICAgICAgICAqCmNvcHlfbndvcmRfY29uc3QoY29uc3QgY2hhciAqZnJvbSwgY2hhciAqdG8sIGludCBsZW4pCnsKICAgIGNoYXIgICAgICAgICAgICBxdW90ZTsKICAgIGlmICghZnJvbSB8fCAhdG8pCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBpZiAoKCpmcm9tID09ICdcIicpIHx8ICgqZnJvbSA9PSAnXCcnKSkgewogICAgICAgIHF1b3RlID0gKihmcm9tKyspOwogICAgICAgIHdoaWxlICgoKmZyb20gIT0gcXVvdGUpICYmICgqZnJvbSAhPSAwKSkgewogICAgICAgICAgICBpZiAoKCpmcm9tID09ICdcXCcpICYmICgqKGZyb20gKyAxKSAhPSAwKSkgewogICAgICAgICAgICAgICAgaWYgKGxlbiA+IDApIHsgIC8qIGRvbid0IGNvcHkgYmV5b25kIGxlbiBieXRlcyAqLwogICAgICAgICAgICAgICAgICAgICp0bysrID0gKihmcm9tICsgMSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKC0tbGVuID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICoodG8gLSAxKSA9ICdcMCc7ICAgICAgIC8qIG51bGwgcHJvdGVjdCB0aGUgbGFzdCBzcG90ICovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmcm9tID0gZnJvbSArIDI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAobGVuID4gMCkgeyAgLyogZG9uJ3QgY29weSBiZXlvbmQgbGVuIGJ5dGVzICovCiAgICAgICAgICAgICAgICAgICAgKnRvKysgPSAqZnJvbSsrOwogICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbiA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAqKHRvIC0gMSkgPSAnXDAnOyAgICAgICAvKiBudWxsIHByb3RlY3QgdGhlIGxhc3Qgc3BvdCAqLwogICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgZnJvbSsrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICgqZnJvbSA9PSAwKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19jb3B5X3dvcmQiLAogICAgICAgICAgICAgICAgICAgICAgICAibm8gZW5kIHF1b3RlIGZvdW5kIGluIGNvbmZpZyBzdHJpbmdcbiIpKTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgZnJvbSsrOwogICAgfSBlbHNlIHsKICAgICAgICB3aGlsZSAoKmZyb20gIT0gMCAmJiAhaXNzcGFjZSgodW5zaWduZWQgY2hhcikoKmZyb20pKSkgewogICAgICAgICAgICBpZiAoKCpmcm9tID09ICdcXCcpICYmICgqKGZyb20gKyAxKSAhPSAwKSkgewogICAgICAgICAgICAgICAgaWYgKGxlbiA+IDApIHsgIC8qIGRvbid0IGNvcHkgYmV5b25kIGxlbiBieXRlcyAqLwogICAgICAgICAgICAgICAgICAgICp0bysrID0gKihmcm9tICsgMSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKC0tbGVuID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICoodG8gLSAxKSA9ICdcMCc7ICAgICAgIC8qIG51bGwgcHJvdGVjdCB0aGUgbGFzdCBzcG90ICovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmcm9tID0gZnJvbSArIDI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAobGVuID4gMCkgeyAgLyogZG9uJ3QgY29weSBiZXlvbmQgbGVuIGJ5dGVzICovCiAgICAgICAgICAgICAgICAgICAgKnRvKysgPSAqZnJvbSsrOwogICAgICAgICAgICAgICAgICAgIGlmICgtLWxlbiA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAqKHRvIC0gMSkgPSAnXDAnOyAgICAgICAvKiBudWxsIHByb3RlY3QgdGhlIGxhc3Qgc3BvdCAqLwogICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgZnJvbSsrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgaWYgKGxlbiA+IDApCiAgICAgICAgKnRvID0gMDsKICAgIGZyb20gPSBza2lwX3doaXRlX2NvbnN0KGZyb20pOwogICAgcmV0dXJuIChmcm9tKTsKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjb3B5X253b3JkICovCgovKgogKiBjb3B5X3dvcmQKICogY29waWVzIHRoZSBuZXh0ICd0b2tlbicgZnJvbSAnZnJvbScgaW50byAndG8nLgogKiBjdXJyZW50bHkgYSB0b2tlbiBpcyBhbnl0aGluZyBzZXBlcmF0ZSBieSB3aGl0ZSBzcGFjZQogKiBvciB3aXRoaW4gcXVvdGVzIChkb3VibGUgb3Igc2luZ2xlKSAoaS5lLiAidGhlIHJlZCByb3NlIiAKICogaXMgb25lIHRva2VuLCBcInRoZSByZWQgcm9zZVwiIGlzIHRocmVlIHRva2VucykKICogYSAnXCcgY2hhcmFjdGVyIHdpbGwgYWxsb3cgYSBxdW90ZSBjaGFyYWN0ZXIgdG8gYmUgdHJlYXRlZAogKiBhcyBhIHJlZ3VsYXIgY2hhcmFjdGVyIAogKiBJdCByZXR1cm5zIGEgcG9pbnRlciB0byBmaXJzdCBub24td2hpdGUgc3BhY2UgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgdG9rZW4KICogYmVpbmcgY29waWVkIG9yIHRvIDAgaWYgd2UgcmVhY2ggdGhlIGVuZC4KICovCgpzdGF0aWMgaW50ICAgICAgaGF2ZV93YXJuZWQgPSAwOwpjaGFyICAgICAgICAgICAqCmNvcHlfd29yZChjaGFyICpmcm9tLCBjaGFyICp0bykKewogICAgaWYgKCFoYXZlX3dhcm5lZCkgewogICAgICAgIHNubXBfbG9nKExPR19JTkZPLAogICAgICAgICAgICAgICAgICJjb3B5X3dvcmQoKSBjYWxsZWQuICBVc2UgY29weV9ud29yZCgpIGluc3RlYWQuXG4iKTsKICAgICAgICBoYXZlX3dhcm5lZCA9IDE7CiAgICB9CiAgICByZXR1cm4gY29weV9ud29yZChmcm9tLCB0bywgU1BSSU5UX01BWF9MRU4pOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNvcHlfd29yZCAqLwoKLyoqCiAqIFN0b3JlcyBhbiBxdW90ZWQgdmVyc2lvbiBvZiB0aGUgZmlyc3QgbGVuIGJ5dGVzIGZyb20gc3RyIGludG8gc2F2ZXRvLgogKgogKiBJZiBhbGwgb2N0ZXRzIGluIHN0ciBhcmUgaW4gdGhlIHNldCBbWzphbG51bTpdIF0gdGhlbiB0aGUgcXVvdGF0aW9uCiAqIGlzIHRvIGVuY2xvc2UgdGhlIHN0cmluZyBpbiBxdW90YXRpb24gbWFya3MgKCJzdHIiKSBvdGhlcndpc2UgdGhlCiAqIHF1b3RhdGlvbiBpcyB0byBwcmVwZW5kIHRoZSBzdHJpbmcgMHggYW5kIHRoZW4gYWRkIHRoZSBoZXggcmVwcmVzZW50YXRpb24KICogb2YgYWxsIGNoYXJhY3RlcnMgZnJvbSBzdHIgKDB4NzM3NDcyKQogKgogKiBAcGFyYW1baW5dIHNhdmV0byBwb2ludGVyIHRvIG91dHB1dCBzdHJlYW0sIGlzIGFzc3VtZWQgdG8gYmUgYmlnIGVub3VnaC4KICogQHBhcmFtW2luXSBzdHIgcG9pbnRlciBvZiB0aGUgZGF0YSB0aGF0IGlzIHRvIGJlIHN0b3JlZC4KICogQHBhcmFtW2luXSBsZW4gbGVuZ3RoIG9mIHRoZSBkYXRhIHRoYXQgaXMgdG8gYmUgc3RvcmVkLgogKiBAcmV0dXJuIEEgcG9pbnRlciB0byBzYXZldG8gYWZ0ZXIgc3RyIGlzIGFkZGVkIHRvIGl0LgogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZyhjaGFyICpzYXZldG8sIGNvbnN0IHVfY2hhciAqIHN0ciwgc2l6ZV90IGxlbikKewogICAgc2l6ZV90ICAgICAgICAgIGk7CiAgICBjb25zdCB1X2NoYXIgICAqY3A7CgogICAgLyoKICAgICAqIGlzIGV2ZXJ5dGhpbmcgZWFzaWx5IHByaW50YWJsZQogICAgICovCiAgICBmb3IgKGkgPSAwLCBjcCA9IHN0cjsgaSA8IGxlbiAmJiBjcCAmJgogICAgICAgICAoaXNhbHBoYSgqY3ApIHx8IGlzZGlnaXQoKmNwKSB8fCAqY3AgPT0gJyAnKTsgY3ArKywgaSsrKTsKCiAgICBpZiAobGVuICE9IDAgJiYgaSA9PSBsZW4pIHsKICAgICAgICAqc2F2ZXRvKysgPSAnIic7CiAgICAgICAgbWVtY3B5KHNhdmV0bywgc3RyLCBsZW4pOwogICAgICAgIHNhdmV0byArPSBsZW47CiAgICAgICAgKnNhdmV0bysrID0gJyInOwogICAgICAgICpzYXZldG8gPSAnXDAnOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RyICE9IE5VTEwpIHsKICAgICAgICAgICAgc3ByaW50ZihzYXZldG8sICIweCIpOwogICAgICAgICAgICBzYXZldG8gKz0gMjsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CiAgICAgICAgICAgICAgICBzcHJpbnRmKHNhdmV0bywgIiUwMngiLCBzdHJbaV0pOwogICAgICAgICAgICAgICAgc2F2ZXRvID0gc2F2ZXRvICsgMjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNwcmludGYoc2F2ZXRvLCAiXCJcIiIpOwogICAgICAgICAgICBzYXZldG8gKz0gMjsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gc2F2ZXRvOwp9CgovKioKICogUmVhZHMgYW4gb2N0ZXQgc3RyaW5nIHRoYXQgd2FzIHNhdmVkIGJ5IHRoZQogKiByZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZygpIGZ1bmN0aW9uLgogKgogKiBAcGFyYW1baW5dICAgICByZWFkZnJvbSBQb2ludGVyIHRvIHRoZSBpbnB1dCBkYXRhIHRvIGJlIHBhcnNlZC4KICogQHBhcmFtW2luLG91dF0gc3RyICAgICAgUG9pbnRlciB0byB0aGUgb3V0cHV0IGJ1ZmZlciBwb2ludGVyLiBUaGUgZGF0YQogKiAgIHdyaXR0ZW4gdG8gdGhlIG91dHB1dCBidWZmZXIgd2lsbCBiZSAnXDAnLXRlcm1pbmF0ZWQuIElmICpzdHIgPT0gTlVMTCwKICogICBhbiBvdXRwdXQgYnVmZmVyIHdpbGwgYmUgYWxsb2NhdGVkIHRoYXQgaXMgb25lIGJ5dGUgbGFyZ2VyIHRoYW4gdGhlCiAqICAgZGF0YSBzdG9yZWQuCiAqIEBwYXJhbVtpbixvdXRdIGxlbiAgICAgIElmIHN0ciAhPSBOVUxMLCAqbGVuIGlzIHRoZSBzaXplIG9mIHRoZSBidWZmZXIgKnN0cgogKiAgIHBvaW50cyBhdC4gSWYgc3RyID09IE5VTEwsIHRoZSB2YWx1ZSBwYXNzZWQgdmlhICpsZW4gaXMgaWdub3JlZC4KICogICBCZWZvcmUgdGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCB3aWxsIGJlIHN0b3JlZAogKiAgIGluICpsZW4uIElmIGEgYnVmZmVyIG92ZXJmbG93IG9jY3VycywgKmxlbiB3aWxsIGJlIHNldCB0byAwLgogKgogKiBAcmV0dXJuIEEgcG9pbnRlciB0byB0aGUgbmV4dCBjaGFyYWN0ZXIgaW4gdGhlIGlucHV0IHRvIGJlIHBhcnNlZCBpZgogKiAgIHBhcnNpbmcgc3VjY2VlZGVkOyBOVUxMIHdoZW4gdGhlIGVuZCBvZiB0aGUgaW5wdXQgc3RyaW5nIGhhcyBiZWVuIHJlYWNoZWQKICogICBvciBpZiBhbiBlcnJvciBvY2N1cnJlZC4KICovCmNoYXIgICAgICAgICAgICoKcmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmcoY29uc3QgY2hhciAqcmVhZGZyb20sIHVfY2hhciAqKiBzdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqIGxlbikKewogICAgcmV0dXJuIE5FVFNOTVBfUkVNT1ZFX0NPTlNUKGNoYXIgKiwKICAgICAgICAgICAgICAgcmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmdfY29uc3QocmVhZGZyb20sIHN0ciwgbGVuKSk7Cn0KCmNvbnN0IGNoYXIgICAgICoKcmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmdfY29uc3QoY29uc3QgY2hhciAqcmVhZGZyb20sIHVfY2hhciAqKiBzdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqIGxlbikKewogICAgdV9jaGFyICAgICAgICAgKmNwdHI7CiAgICBjb25zdCBjaGFyICAgICAqY3B0cjE7CiAgICB1X2ludCAgICAgICAgICAgdG1wOwogICAgc2l6ZV90ICAgICAgICAgIGksIGlsZW47CgogICAgaWYgKHJlYWRmcm9tID09IE5VTEwgfHwgc3RyID09IE5VTEwgfHwgbGVuID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKHN0cm5jYXNlY21wKHJlYWRmcm9tLCAiMHgiLCAyKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBBIGhleCBzdHJpbmcgc3VibWl0dGVkLiBIb3cgbG9uZz8gCiAgICAgICAgICovCiAgICAgICAgcmVhZGZyb20gKz0gMjsKICAgICAgICBjcHRyMSA9IHNraXBfbm90X3doaXRlX2NvbnN0KHJlYWRmcm9tKTsKICAgICAgICBpZiAoY3B0cjEpCiAgICAgICAgICAgIGlsZW4gPSAoY3B0cjEgLSByZWFkZnJvbSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBpbGVuID0gc3RybGVuKHJlYWRmcm9tKTsKCiAgICAgICAgaWYgKGlsZW4gJSAyKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLCJpbnZhbGlkIGhleCBzdHJpbmc6IHdyb25nIGxlbmd0aFxuIik7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19yZWFkX29jdGV0X3N0cmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIGhleCBzdHJpbmc6IHdyb25nIGxlbmd0aCIpKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIGlsZW4gPSBpbGVuIC8gMjsKCiAgICAgICAgLyoKICAgICAgICAgKiBtYWxsb2MgZGF0YSBzcGFjZSBpZiBuZWVkZWQgKCsxIGZvciBnb29kIG1lYXN1cmUpIAogICAgICAgICAqLwogICAgICAgIGlmICgqc3RyID09IE5VTEwpIHsKICAgICAgICAgICAgKnN0ciA9ICh1X2NoYXIgKikgbWFsbG9jKGlsZW4gKyAxKTsKICAgICAgICAgICAgaWYgKCEqc3RyKQogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcmVxdWlyZSBjYWxsZXIgdG8gaGF2ZSArMSwgYW5kIGJhaWwgaWYgbm90IGVub3VnaCBzcGFjZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChpbGVuID49ICpsZW4pIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLCJidWZmZXIgdG9vIHNtYWxsIHRvIHJlYWQgb2N0ZXQgc3RyaW5nICglbHUgPCAlbHUpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpKmxlbiwgKHVuc2lnbmVkIGxvbmcpaWxlbik7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJ1ZmZlciB0b28gc21hbGwgKCVsdSA8ICVsdSkiLCAodW5zaWduZWQgbG9uZykqbGVuLCAodW5zaWduZWQgbG9uZylpbGVuKSk7CiAgICAgICAgICAgICAgICAqbGVuID0gMDsKICAgICAgICAgICAgICAgIGNwdHIxID0gc2tpcF9ub3Rfd2hpdGVfY29uc3QocmVhZGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHNraXBfd2hpdGVfY29uc3QoY3B0cjEpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGNvcHkgdmFsaWRhdGVkIGRhdGEgCiAgICAgICAgICovCiAgICAgICAgY3B0ciA9ICpzdHI7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGlsZW47IGkrKykgewogICAgICAgICAgICBpZiAoMSA9PSBzc2NhbmYocmVhZGZyb20sICIlMngiLCAmdG1wKSkKICAgICAgICAgICAgICAgICpjcHRyKysgPSAodV9jaGFyKSB0bXA7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHdlIG1heSBsb3NlIG1lbW9yeSwgYnV0IGRvbid0IGtub3cgY2FsbGVyJ3MgYnVmZmVyIFhYIGZyZWUoY3B0cik7IAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlYWRmcm9tICs9IDI7CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogVGVybWluYXRlIHRoZSBvdXRwdXQgYnVmZmVyLgogICAgICAgICAqLwogICAgICAgICpjcHRyKysgPSAnXDAnOwogICAgICAgICpsZW4gPSBpbGVuOwogICAgICAgIHJlYWRmcm9tID0gc2tpcF93aGl0ZV9jb25zdChyZWFkZnJvbSk7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogTm9ybWFsIHN0cmluZyAKICAgICAgICAgKi8KCiAgICAgICAgLyoKICAgICAgICAgKiBtYWxsb2Mgc3RyaW5nIHNwYWNlIGlmIG5lZWRlZCAoaW5jbHVkaW5nIE5VTEwgdGVybWluYXRvcikgCiAgICAgICAgICovCiAgICAgICAgaWYgKCpzdHIgPT0gTlVMTCkgewogICAgICAgICAgICBjaGFyICAgICAgICAgICAgYnVmW1NOTVBfTUFYQlVGXTsKICAgICAgICAgICAgcmVhZGZyb20gPSBjb3B5X253b3JkX2NvbnN0KHJlYWRmcm9tLCBidWYsIHNpemVvZihidWYpKTsKCiAgICAgICAgICAgICpsZW4gPSBzdHJsZW4oYnVmKTsKICAgICAgICAgICAgKnN0ciA9ICh1X2NoYXIgKikgbWFsbG9jKCpsZW4gKyAxKTsKICAgICAgICAgICAgaWYgKCpzdHIgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICBtZW1jcHkoKnN0ciwgYnVmLCAqbGVuICsgMSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVhZGZyb20gPSBjb3B5X253b3JkX2NvbnN0KHJlYWRmcm9tLCAoY2hhciAqKSAqc3RyLCAqbGVuKTsKICAgICAgICAgICAgaWYgKCpsZW4pCiAgICAgICAgICAgICAgICAqbGVuID0gc3RybGVuKChjaGFyICopICpzdHIpOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVhZGZyb207Cn0KCi8qCiAqIHJlYWRfY29uZmlnX3NhdmVfb2JqaWQoKTogc2F2ZXMgYW4gb2JqaWQgYXMgYSBudW1lcmljYWwgc3RyaW5nIAogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19zYXZlX29iamlkKGNoYXIgKnNhdmV0bywgb2lkICogb2JqaWQsIHNpemVfdCBsZW4pCnsKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIGlmIChsZW4gPT0gMCkgewogICAgICAgIHN0cmNhdChzYXZldG8sICJOVUxMIik7CiAgICAgICAgc2F2ZXRvICs9IHN0cmxlbihzYXZldG8pOwogICAgICAgIHJldHVybiBzYXZldG87CiAgICB9CgogICAgLyoKICAgICAqIGluIGNhc2UgbGVuPTAsIHRoaXMgbWFrZXMgaXQgZWFzaWVyIHRvIHJlYWQgaXQgYmFjayBpbiAKICAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IChpbnQpIGxlbjsgaSsrKSB7CiAgICAgICAgc3ByaW50ZihzYXZldG8sICIuJSIgTkVUU05NUF9QUklvICJkIiwgb2JqaWRbaV0pOwogICAgICAgIHNhdmV0byArPSBzdHJsZW4oc2F2ZXRvKTsKICAgIH0KICAgIHJldHVybiBzYXZldG87Cn0KCi8qCiAqIHJlYWRfY29uZmlnX3JlYWRfb2JqaWQoKTogcmVhZHMgYW4gb2JqaWQgZnJvbSBhIGZvcm1hdCBzYXZlZCBieSB0aGUgYWJvdmUgCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3JlYWRfb2JqaWQoY2hhciAqcmVhZGZyb20sIG9pZCAqKiBvYmppZCwgc2l6ZV90ICogbGVuKQp7CiAgICByZXR1cm4gTkVUU05NUF9SRU1PVkVfQ09OU1QoY2hhciAqLAogICAgICAgICAgICAgcmVhZF9jb25maWdfcmVhZF9vYmppZF9jb25zdChyZWFkZnJvbSwgb2JqaWQsIGxlbikpOwp9Cgpjb25zdCBjaGFyICAgICAqCnJlYWRfY29uZmlnX3JlYWRfb2JqaWRfY29uc3QoY29uc3QgY2hhciAqcmVhZGZyb20sIG9pZCAqKiBvYmppZCwgc2l6ZV90ICogbGVuKQp7CgogICAgaWYgKG9iamlkID09IE5VTEwgfHwgcmVhZGZyb20gPT0gTlVMTCB8fCBsZW4gPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBpZiAoKm9iamlkID09IE5VTEwpIHsKICAgICAgICAqbGVuID0gMDsKICAgICAgICBpZiAoKCpvYmppZCA9IChvaWQgKikgbWFsbG9jKE1BWF9PSURfTEVOICogc2l6ZW9mKG9pZCkpKSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAqbGVuID0gTUFYX09JRF9MRU47CiAgICB9CgogICAgaWYgKHN0cm5jbXAocmVhZGZyb20sICJOVUxMIiwgNCkgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogbnVsbCBsZW5ndGggb2lkIAogICAgICAgICAqLwogICAgICAgICpsZW4gPSAwOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIHF1YWxpZnkgdGhlIHN0cmluZyBmb3IgcmVhZF9vYmppZCAKICAgICAgICAgKi8KICAgICAgICBjaGFyICAgICAgICAgICAgYnVmW1NQUklOVF9NQVhfTEVOXTsKICAgICAgICBjb3B5X253b3JkX2NvbnN0KHJlYWRmcm9tLCBidWYsIHNpemVvZihidWYpKTsKCiAgICAgICAgaWYgKCFyZWFkX29iamlkKGJ1ZiwgKm9iamlkLCBsZW4pKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19yZWFkX29iamlkIiwgIkludmFsaWQgT0lEIikpOwogICAgICAgICAgICAqbGVuID0gMDsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIHJlYWRmcm9tID0gc2tpcF90b2tlbl9jb25zdChyZWFkZnJvbSk7CiAgICByZXR1cm4gcmVhZGZyb207Cn0KCi8qKgogKiByZWFkX2NvbmZpZ19yZWFkX2RhdGEgcmVhZHMgZGF0YSBvZiBhIGdpdmVuIHR5cGUgZnJvbSBhIHRva2VuKHMpIG9uIGEKICogY29uZmlndXJhdGlvbiBsaW5lLiAgVGhlIHN1cHBvcnRlZCB0eXBlcyBhcmU6CiAqCiAqICAgIC0gQVNOX0lOVEVHRVIKICogICAgLSBBU05fVElNRVRJQ0tTCiAqICAgIC0gQVNOX1VOU0lHTkVECiAqICAgIC0gQVNOX09DVEVUX1NUUgogKiAgICAtIEFTTl9CSVRfU1RSCiAqICAgIC0gQVNOX09CSkVDVF9JRAogKgogKiBAcGFyYW0gdHlwZSB0aGUgYXNuIGRhdGEgdHlwZSB0byBiZSByZWFkIGluLgogKgogKiBAcGFyYW0gcmVhZGZyb20gdGhlIGNvbmZpZ3VyYXRpb24gbGluZSBkYXRhIHRvIGJlIHJlYWQuCiAqCiAqIEBwYXJhbSBkYXRhcHRyIGFuIGFsbG9jYXRlZCBwb2ludGVyIGV4cGVjdGVkIHRvIG1hdGNoIHRoZSB0eXBlIGJlaW5nIHJlYWQKICogICAgICAgIChpbnQgKiwgdV9pbnQgKiwgY2hhciAqKiwgb2lkICoqKQogKgogKiBAcGFyYW0gbGVuIGlzIHRoZSBsZW5ndGggb2YgYW4gYXNuIG9pZCBvciBvY3RldC9iaXQgc3RyaW5nLCBub3QgcmVxdWlyZWQKICogICAgICAgICAgICBmb3IgdGhlIGFzbiBpbnRlZ2VyLCB1bnNpZ25lZCBpbnRlZ2VyLCBhbmQgdGltZXRpY2tzIHR5cGVzCiAqCiAqIEByZXR1cm4gdGhlIG5leHQgdG9rZW4gaW4gdGhlIGNvbmZpZ3VyYXRpb24gbGluZS4gIE5VTEwgaWYgbm9uZSBsZWZ0IG9yCiAqIGlmIGFuIHVua25vd24gdHlwZS4KICogCiAqLwpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3JlYWRfZGF0YShpbnQgdHlwZSwgY2hhciAqcmVhZGZyb20sIHZvaWQgKmRhdGFwdHIsCiAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiBsZW4pCnsKICAgIGludCAgICAgICAgICAgICppbnRwOwogICAgY2hhciAgICAgICAgICAqKmNoYXJwcDsKICAgIG9pZCAgICAgICAgICAgKipvaWRwcDsKICAgIHVuc2lnbmVkIGludCAgICp1aW50cDsKCiAgICBpZiAoZGF0YXB0ciAmJiByZWFkZnJvbSkKICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIEFTTl9JTlRFR0VSOgogICAgICAgICAgICBpbnRwID0gKGludCAqKSBkYXRhcHRyOwogICAgICAgICAgICAqaW50cCA9IGF0b2kocmVhZGZyb20pOwogICAgICAgICAgICByZWFkZnJvbSA9IHNraXBfdG9rZW4ocmVhZGZyb20pOwogICAgICAgICAgICByZXR1cm4gcmVhZGZyb207CgogICAgICAgIGNhc2UgQVNOX1RJTUVUSUNLUzoKICAgICAgICBjYXNlIEFTTl9VTlNJR05FRDoKICAgICAgICAgICAgdWludHAgPSAodW5zaWduZWQgaW50ICopIGRhdGFwdHI7CiAgICAgICAgICAgICp1aW50cCA9IHN0cnRvdWwocmVhZGZyb20sIE5VTEwsIDApOwogICAgICAgICAgICByZWFkZnJvbSA9IHNraXBfdG9rZW4ocmVhZGZyb20pOwogICAgICAgICAgICByZXR1cm4gcmVhZGZyb207CgogICAgICAgIGNhc2UgQVNOX0lQQUREUkVTUzoKICAgICAgICAgICAgaW50cCA9IChpbnQgKikgZGF0YXB0cjsKICAgICAgICAgICAgKmludHAgPSBpbmV0X2FkZHIocmVhZGZyb20pOwogICAgICAgICAgICBpZiAoKCppbnRwID09IC0xKSAmJgogICAgICAgICAgICAgICAgKHN0cm5jbXAocmVhZGZyb20sICIyNTUuMjU1LjI1NS4yNTUiLCAxNSkgIT0gMCkpCiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgcmVhZGZyb20gPSBza2lwX3Rva2VuKHJlYWRmcm9tKTsKICAgICAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwoKICAgICAgICBjYXNlIEFTTl9PQ1RFVF9TVFI6CiAgICAgICAgY2FzZSBBU05fQklUX1NUUjoKICAgICAgICAgICAgY2hhcnBwID0gKGNoYXIgKiopIGRhdGFwdHI7CiAgICAgICAgICAgIHJldHVybiByZWFkX2NvbmZpZ19yZWFkX29jdGV0X3N0cmluZyhyZWFkZnJvbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKiopIGNoYXJwcCwgbGVuKTsKCiAgICAgICAgY2FzZSBBU05fT0JKRUNUX0lEOgogICAgICAgICAgICBvaWRwcCA9IChvaWQgKiopIGRhdGFwdHI7CiAgICAgICAgICAgIHJldHVybiByZWFkX2NvbmZpZ19yZWFkX29iamlkKHJlYWRmcm9tLCBvaWRwcCwgbGVuKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlYWRfY29uZmlnX3JlYWRfZGF0YSIsICJGYWlsOiBVbmtub3duIHR5cGU6ICVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSkpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoKICogcmVhZF9jb25maWdfcmVhZF9tZW1vcnkoKToKICogCiAqIHNpbWlsYXIgdG8gcmVhZF9jb25maWdfcmVhZF9kYXRhLCBidXQgZXhwZWN0cyBhIGdlbmVyaWMgbWVtb3J5CiAqIHBvaW50ZXIgcmF0aGVyIHRoYW4gYSBzcGVjaWZpYyB0eXBlIG9mIHBvaW50ZXIuICBMZW4gaXMgZXhwZWN0ZWQgdG8KICogYmUgdGhlIGFtb3VudCBvZiBhdmFpbGFibGUgbWVtb3J5LgogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19yZWFkX21lbW9yeShpbnQgdHlwZSwgY2hhciAqcmVhZGZyb20sCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKmRhdGFwdHIsIHNpemVfdCAqIGxlbikKewogICAgaW50ICAgICAgICAgICAgKmludHA7CiAgICB1bnNpZ25lZCBpbnQgICAqdWludHA7CiAgICBjaGFyICAgICAgICAgICAgYnVmW1NQUklOVF9NQVhfTEVOXTsKCiAgICBpZiAoIWRhdGFwdHIgfHwgIXJlYWRmcm9tKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHN3aXRjaCAodHlwZSkgewogICAgY2FzZSBBU05fSU5URUdFUjoKICAgICAgICBpZiAoKmxlbiA8IHNpemVvZihpbnQpKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICBpbnRwID0gKGludCAqKSBkYXRhcHRyOwogICAgICAgIHJlYWRmcm9tID0gY29weV9ud29yZChyZWFkZnJvbSwgYnVmLCBzaXplb2YoYnVmKSk7CiAgICAgICAgKmludHAgPSBhdG9pKGJ1Zik7CiAgICAgICAgKmxlbiA9IHNpemVvZihpbnQpOwogICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICBjYXNlIEFTTl9DT1VOVEVSOgogICAgY2FzZSBBU05fVElNRVRJQ0tTOgogICAgY2FzZSBBU05fVU5TSUdORUQ6CiAgICAgICAgaWYgKCpsZW4gPCBzaXplb2YodW5zaWduZWQgaW50KSkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgdWludHAgPSAodW5zaWduZWQgaW50ICopIGRhdGFwdHI7CiAgICAgICAgcmVhZGZyb20gPSBjb3B5X253b3JkKHJlYWRmcm9tLCBidWYsIHNpemVvZihidWYpKTsKICAgICAgICAqdWludHAgPSBzdHJ0b3VsKGJ1ZiwgTlVMTCwgMCk7CiAgICAgICAgKmxlbiA9IHNpemVvZih1bnNpZ25lZCBpbnQpOwogICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICBjYXNlIEFTTl9JUEFERFJFU1M6CiAgICAgICAgaWYgKCpsZW4gPCBzaXplb2YoaW50KSkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgaW50cCA9IChpbnQgKikgZGF0YXB0cjsKICAgICAgICByZWFkZnJvbSA9IGNvcHlfbndvcmQocmVhZGZyb20sIGJ1Ziwgc2l6ZW9mKGJ1ZikpOwogICAgICAgICppbnRwID0gaW5ldF9hZGRyKGJ1Zik7CiAgICAgICAgaWYgKCgqaW50cCA9PSAtMSkgJiYgKHN0cmNtcChidWYsICIyNTUuMjU1LjI1NS4yNTUiKSAhPSAwKSkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgKmxlbiA9IHNpemVvZihpbnQpOwogICAgICAgIHJldHVybiByZWFkZnJvbTsKCiAgICBjYXNlIEFTTl9PQ1RFVF9TVFI6CiAgICBjYXNlIEFTTl9CSVRfU1RSOgogICAgY2FzZSBBU05fUFJJVl9JTVBMSUVEX09DVEVUX1NUUjoKICAgICAgICByZXR1cm4gcmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmcocmVhZGZyb20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKiopICYgZGF0YXB0ciwgbGVuKTsKCiAgICBjYXNlIEFTTl9QUklWX0lNUExJRURfT0JKRUNUX0lEOgogICAgY2FzZSBBU05fT0JKRUNUX0lEOgogICAgICAgIHJlYWRmcm9tID0KICAgICAgICAgICAgcmVhZF9jb25maWdfcmVhZF9vYmppZChyZWFkZnJvbSwgKG9pZCAqKikgJiBkYXRhcHRyLCBsZW4pOwogICAgICAgICpsZW4gKj0gc2l6ZW9mKG9pZCk7CiAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwoKICAgIGNhc2UgQVNOX0NPVU5URVI2NDoKICAgICAgICBpZiAoKmxlbiA8IHNpemVvZihVNjQpKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAqbGVuID0gc2l6ZW9mKFU2NCk7CiAgICAgICAgcmVhZDY0KChVNjQgKikgZGF0YXB0ciwgcmVhZGZyb20pOwogICAgICAgIHJlYWRmcm9tID0gc2tpcF90b2tlbihyZWFkZnJvbSk7CiAgICAgICAgcmV0dXJuIHJlYWRmcm9tOwogICAgfQoKICAgIERFQlVHTVNHVEwoKCJyZWFkX2NvbmZpZ19yZWFkX21lbW9yeSIsICJGYWlsOiBVbmtub3duIHR5cGU6ICVkIiwgdHlwZSkpOwogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKgogKiByZWFkX2NvbmZpZ19zdG9yZV9kYXRhIHN0b3JlcyBkYXRhIG9mIGEgZ2l2ZW4gdHlwZSB0byBhIGNvbmZpZ3VyYXRpb24gbGluZQogKiBpbnRvIHRoZSBzdG9yZXRvIGJ1ZmZlci4KICogQ2FsbHMgcmVhZF9jb25maWdfc3RvcmVfZGF0YV9wcmVmaXggd2l0aCB0aGUgcHJlZml4IHBhcmFtZXRlciBzZXQgdG8gYSBjaGFyCiAqIHNwYWNlLiAgVGhlIHN1cHBvcnRlZCB0eXBlcyBhcmU6CiAqCiAqICAgIC0gQVNOX0lOVEVHRVIKICogICAgLSBBU05fVElNRVRJQ0tTCiAqICAgIC0gQVNOX1VOU0lHTkVECiAqICAgIC0gQVNOX09DVEVUX1NUUgogKiAgICAtIEFTTl9CSVRfU1RSCiAqICAgIC0gQVNOX09CSkVDVF9JRAogKgogKiBAcGFyYW0gdHlwZSAgICB0aGUgYXNuIGRhdGEgdHlwZSB0byBiZSBzdG9yZWQKICoKICogQHBhcmFtIHN0b3JldG8gYSBwcmUtYWxsb2NhdGVkIGNoYXIgYnVmZmVyIHdoaWNoIHdpbGwgY29udGFpbiB0aGUgZGF0YQogKiAgICAgICAgICAgICAgICB0byBiZSBzdG9yZWQKICoKICogQHBhcmFtIGRhdGFwdHIgY29udGFpbnMgdGhlIHZhbHVlIHRvIGJlIHN0b3JlZCwgdGhlIHN1cHBvcnRlZCBwb2ludGVyczoKICogICAgICAgICAgICAgICAgKGludCAqLCB1X2ludCAqLCBjaGFyICoqLCBvaWQgKiopCiAqCiAqIEBwYXJhbSBsZW4gICAgIGlzIHRoZSBsZW5ndGggb2YgdGhlIHZhbHVlIHRvIGJlIHN0b3JlZAogKiAgICAgICAgICAgICAgICAobm90IHJlcXVpcmVkIGZvciB0aGUgYXNuIGludGVnZXIsIHVuc2lnbmVkIGludGVnZXIsCiAqICAgICAgICAgICAgICAgICBhbmQgdGltZXRpY2tzIHR5cGVzKQogKgogKiBAcmV0dXJuIGNoYXJhY3RlciBwb2ludGVyIHRvIHRoZSBlbmQgb2YgdGhlIGxpbmUuIE5VTEwgaWYgYW4gdW5rbm93biB0eXBlLgogKi8KY2hhciAgICAgICAgICAgKgpyZWFkX2NvbmZpZ19zdG9yZV9kYXRhKGludCB0eXBlLCBjaGFyICpzdG9yZXRvLCB2b2lkICpkYXRhcHRyLCBzaXplX3QgKiBsZW4pCnsKICAgIHJldHVybiByZWFkX2NvbmZpZ19zdG9yZV9kYXRhX3ByZWZpeCgnICcsIHR5cGUsIHN0b3JldG8sIGRhdGFwdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsZW4gPyAqbGVuIDogMCkpOwp9CgpjaGFyICAgICAgICAgICAqCnJlYWRfY29uZmlnX3N0b3JlX2RhdGFfcHJlZml4KGNoYXIgcHJlZml4LCBpbnQgdHlwZSwgY2hhciAqc3RvcmV0bywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqZGF0YXB0ciwgc2l6ZV90IGxlbikKewogICAgaW50ICAgICAgICAgICAgKmludHA7CiAgICB1X2NoYXIgICAgICAgICoqY2hhcnBwOwogICAgdW5zaWduZWQgaW50ICAgKnVpbnRwOwogICAgc3RydWN0IGluX2FkZHIgIGluOwogICAgb2lkICAgICAgICAgICAqKm9pZHBwOwoKICAgIGlmIChkYXRhcHRyICYmIHN0b3JldG8pCiAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgY2FzZSBBU05fSU5URUdFUjoKICAgICAgICAgICAgaW50cCA9IChpbnQgKikgZGF0YXB0cjsKICAgICAgICAgICAgc3ByaW50ZihzdG9yZXRvLCAiJWMlZCIsIHByZWZpeCwgKmludHApOwogICAgICAgICAgICByZXR1cm4gKHN0b3JldG8gKyBzdHJsZW4oc3RvcmV0bykpOwoKICAgICAgICBjYXNlIEFTTl9USU1FVElDS1M6CiAgICAgICAgY2FzZSBBU05fVU5TSUdORUQ6CiAgICAgICAgICAgIHVpbnRwID0gKHVuc2lnbmVkIGludCAqKSBkYXRhcHRyOwogICAgICAgICAgICBzcHJpbnRmKHN0b3JldG8sICIlYyV1IiwgcHJlZml4LCAqdWludHApOwogICAgICAgICAgICByZXR1cm4gKHN0b3JldG8gKyBzdHJsZW4oc3RvcmV0bykpOwoKICAgICAgICBjYXNlIEFTTl9JUEFERFJFU1M6CiAgICAgICAgICAgIGluLnNfYWRkciA9ICoodW5zaWduZWQgaW50ICopIGRhdGFwdHI7IAogICAgICAgICAgICBzcHJpbnRmKHN0b3JldG8sICIlYyVzIiwgcHJlZml4LCBpbmV0X250b2EoaW4pKTsKICAgICAgICAgICAgcmV0dXJuIChzdG9yZXRvICsgc3RybGVuKHN0b3JldG8pKTsKCiAgICAgICAgY2FzZSBBU05fT0NURVRfU1RSOgogICAgICAgIGNhc2UgQVNOX0JJVF9TVFI6CiAgICAgICAgICAgICpzdG9yZXRvKysgPSBwcmVmaXg7CiAgICAgICAgICAgIGNoYXJwcCA9ICh1X2NoYXIgKiopIGRhdGFwdHI7CiAgICAgICAgICAgIHJldHVybiByZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZyhzdG9yZXRvLCAqY2hhcnBwLCBsZW4pOwoKICAgICAgICBjYXNlIEFTTl9PQkpFQ1RfSUQ6CiAgICAgICAgICAgICpzdG9yZXRvKysgPSBwcmVmaXg7CiAgICAgICAgICAgIG9pZHBwID0gKG9pZCAqKikgZGF0YXB0cjsKICAgICAgICAgICAgcmV0dXJuIHJlYWRfY29uZmlnX3NhdmVfb2JqaWQoc3RvcmV0bywgKm9pZHBwLCBsZW4pOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBERUJVR01TR1RMKCgicmVhZF9jb25maWdfc3RvcmVfZGF0YV9wcmVmaXgiLAogICAgICAgICAgICAgICAgICAgICAgICAiRmFpbDogVW5rbm93biB0eXBlOiAlZCIsIHR5cGUpKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBAfSAqLwo=