LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2NhY2hlLmMsdiAxLjcgMjAwMi8wNS8yMSAxNzowNjoyMiBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkLCBtZW1iZXIgb2YgVGhlIFhGcmVlODYgUHJvamVjdCwgSW5jLgogKgogKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBhbmQgc2VsbCB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKICogZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgaXMgaGVyZWJ5IGdyYW50ZWQgd2l0aG91dCBmZWUsIHByb3ZpZGVkIHRoYXQKICogdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMgYW5kIHRoYXQgYm90aCB0aGF0CiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIHN1cHBvcnRpbmcKICogZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgS2VpdGggUGFja2FyZCBub3QgYmUgdXNlZCBpbgogKiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQKICogc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gIEtlaXRoIFBhY2thcmQgbWFrZXMgbm8KICogcmVwcmVzZW50YXRpb25zIGFib3V0IHRoZSBzdWl0YWJpbGl0eSBvZiB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gIEl0CiAqIGlzIHByb3ZpZGVkICJhcyBpcyIgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuCiAqCiAqIEtFSVRIIFBBQ0tBUkQgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsCiAqIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8KICogRVZFTlQgU0hBTEwgS0VJVEggUEFDS0FSRCBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkRJUkVDVCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwKICogREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKI2luY2x1ZGUgImZjaW50LmgiCgojZGVmaW5lIEZDX0RCR19DQUNIRV9SRUYgICAgMTAyNAoKc3RhdGljIEZjQ2hhcjggKgpGY0NhY2hlUmVhZFN0cmluZyAoRklMRSAqZiwgRmNDaGFyOCAqZGVzdCwgaW50IGxlbikKewogICAgaW50CQljOwogICAgRmNCb29sCWVzY2FwZTsKICAgIEZjQ2hhcjgJKmQ7CiAgICBpbnQJCXNpemU7CiAgICBpbnQJCWk7CgogICAgd2hpbGUgKChjID0gZ2V0YyAoZikpICE9IEVPRikKCWlmIChjID09ICciJykKCSAgICBicmVhazsKICAgIGlmIChjID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGxlbiA9PSAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICAKICAgIHNpemUgPSBsZW47CiAgICBpID0gMDsKICAgIGQgPSBkZXN0OwogICAgZXNjYXBlID0gRmNGYWxzZTsKICAgIHdoaWxlICgoYyA9IGdldGMgKGYpKSAhPSBFT0YpCiAgICB7CglpZiAoIWVzY2FwZSkKCXsKCSAgICBzd2l0Y2ggKGMpIHsKCSAgICBjYXNlICciJzoKCQljID0gJ1wwJzsKCQlicmVhazsKCSAgICBjYXNlICdcXCc6CgkJZXNjYXBlID0gRmNUcnVlOwoJCWNvbnRpbnVlOwoJICAgIH0KCX0KCWlmIChpID09IHNpemUpCgl7CgkgICAgRmNDaGFyOCAqbmV3ID0gbWFsbG9jIChzaXplICogMik7CgkgICAgaWYgKCFuZXcpCgkJYnJlYWs7CgkgICAgbWVtY3B5IChuZXcsIGQsIHNpemUpOwoJICAgIHNpemUgKj0gMjsKCSAgICBpZiAoZCAhPSBkZXN0KQoJCWZyZWUgKGQpOwoJICAgIGQgPSBuZXc7Cgl9CglkW2krK10gPSBjOwoJaWYgKGMgPT0gJ1wwJykKCSAgICByZXR1cm4gZDsKCWVzY2FwZSA9IEZjRmFsc2U7CiAgICB9CiAgICBpZiAoZCAhPSBkZXN0KQoJZnJlZSAoZCk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlUmVhZFVsb25nIChGSUxFICpmLCB1bnNpZ25lZCBsb25nICpkZXN0KQp7CiAgICB1bnNpZ25lZCBsb25nICAgdDsKICAgIGludAkJICAgIGM7CgogICAgd2hpbGUgKChjID0gZ2V0YyAoZikpICE9IEVPRikKICAgIHsKCWlmICghaXNzcGFjZSAoYykpCgkgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoYyA9PSBFT0YpCglyZXR1cm4gRmNGYWxzZTsKICAgIHQgPSAwOwogICAgZm9yICg7OykKICAgIHsKCWlmIChjID09IEVPRiB8fCBpc3NwYWNlIChjKSkKCSAgICBicmVhazsKCWlmICghaXNkaWdpdCAoYykpCgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl0ID0gdCAqIDEwICsgKGMgLSAnMCcpOwoJYyA9IGdldGMgKGYpOwogICAgfQogICAgKmRlc3QgPSB0OwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlUmVhZEludCAoRklMRSAqZiwgaW50ICpkZXN0KQp7CiAgICB1bnNpZ25lZCBsb25nICAgdDsKICAgIEZjQm9vbAkgICAgcmV0OwoKICAgIHJldCA9IEZjQ2FjaGVSZWFkVWxvbmcgKGYsICZ0KTsKICAgIGlmIChyZXQpCgkqZGVzdCA9IChpbnQpIHQ7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVSZWFkVGltZSAoRklMRSAqZiwgdGltZV90ICpkZXN0KQp7CiAgICB1bnNpZ25lZCBsb25nICAgdDsKICAgIEZjQm9vbAkgICAgcmV0OwoKICAgIHJldCA9IEZjQ2FjaGVSZWFkVWxvbmcgKGYsICZ0KTsKICAgIGlmIChyZXQpCgkqZGVzdCA9ICh0aW1lX3QpIHQ7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZUNoYXJzIChGSUxFICpmLCBjb25zdCBGY0NoYXI4ICpjaGFycykKewogICAgRmNDaGFyOCAgICBjOwogICAgd2hpbGUgKChjID0gKmNoYXJzKyspKQogICAgewoJc3dpdGNoIChjKSB7CgljYXNlICciJzoKCWNhc2UgJ1xcJzoKCSAgICBpZiAocHV0YyAoJ1xcJywgZikgPT0gRU9GKQoJCXJldHVybiBGY0ZhbHNlOwoJICAgIC8qIGZhbGwgdGhyb3VnaCAqLwoJZGVmYXVsdDoKCSAgICBpZiAocHV0YyAoYywgZikgPT0gRU9GKQoJCXJldHVybiBGY0ZhbHNlOwoJfQogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVTdHJpbmcgKEZJTEUgKmYsIGNvbnN0IEZjQ2hhcjggKnN0cmluZykKewoKICAgIGlmIChwdXRjICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKCFGY0NhY2hlV3JpdGVDaGFycyAoZiwgc3RyaW5nKSkKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKHB1dGMgKCciJywgZikgPT0gRU9GKQoJcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZVBhdGggKEZJTEUgKmYsIGNvbnN0IEZjQ2hhcjggKmRpciwgY29uc3QgRmNDaGFyOCAqZmlsZSkKewogICAgaWYgKHB1dGMgKCciJywgZikgPT0gRU9GKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoZGlyKQoJaWYgKCFGY0NhY2hlV3JpdGVDaGFycyAoZiwgZGlyKSkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIGlmIChkaXIgJiYgZGlyW3N0cmxlbigoY29uc3QgY2hhciAqKSBkaXIpIC0gMV0gIT0gJy8nKQoJaWYgKHB1dGMgKCcvJywgZikgPT0gRU9GKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgaWYgKCFGY0NhY2hlV3JpdGVDaGFycyAoZiwgZmlsZSkpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChwdXRjICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVVbG9uZyAoRklMRSAqZiwgdW5zaWduZWQgbG9uZyB0KQp7CiAgICBpbnQJICAgIHBvdzsKICAgIHVuc2lnbmVkIGxvbmcgICB0ZW1wLCBkaWdpdDsKCiAgICB0ZW1wID0gdDsKICAgIHBvdyA9IDE7CiAgICB3aGlsZSAodGVtcCA+PSAxMCkKICAgIHsKCXRlbXAgLz0gMTA7Cglwb3cgKj0gMTA7CiAgICB9CiAgICB0ZW1wID0gdDsKICAgIHdoaWxlIChwb3cpCiAgICB7CglkaWdpdCA9IHRlbXAgLyBwb3c7CglpZiAocHV0YyAoKGNoYXIpIGRpZ2l0ICsgJzAnLCBmKSA9PSBFT0YpCgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl0ZW1wID0gdGVtcCAtIHBvdyAqIGRpZ2l0OwoJcG93ID0gcG93IC8gMTA7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZUludCAoRklMRSAqZiwgaW50IGkpCnsKICAgIHJldHVybiBGY0NhY2hlV3JpdGVVbG9uZyAoZiwgKHVuc2lnbmVkIGxvbmcpIGkpOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZVRpbWUgKEZJTEUgKmYsIHRpbWVfdCB0KQp7CiAgICByZXR1cm4gRmNDYWNoZVdyaXRlVWxvbmcgKGYsICh1bnNpZ25lZCBsb25nKSB0KTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlRm9udFNldEFkZCAoRmNGb250U2V0CSAgICAqc2V0LAoJCSAgIEZjU3RyU2V0CSAgICAqZGlycywKCQkgICBjb25zdCBGY0NoYXI4ICAgICpkaXIsCgkJICAgaW50CQkgICAgZGlyX2xlbiwKCQkgICBjb25zdCBGY0NoYXI4ICAgICpmaWxlLAoJCSAgIGNvbnN0IEZjQ2hhcjggICAgKm5hbWUpCnsKICAgIEZjQ2hhcjgJcGF0aF9idWZbODE5Ml0sICpwYXRoOwogICAgaW50CQlsZW47CiAgICBGY0Jvb2wJcmV0ID0gRmNGYWxzZTsKICAgIEZjUGF0dGVybgkqZm9udDsKCiAgICBwYXRoID0gcGF0aF9idWY7CiAgICBsZW4gPSAoZGlyX2xlbiArIDEgKyBzdHJsZW4gKChjb25zdCBjaGFyICopIGZpbGUpICsgMSk7CiAgICBpZiAobGVuID4gc2l6ZW9mIChwYXRoX2J1ZikpCiAgICB7CglwYXRoID0gbWFsbG9jIChsZW4pOwoJaWYgKCFwYXRoKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQogICAgc3RybmNweSAoKGNoYXIgKikgcGF0aCwgKGNvbnN0IGNoYXIgKikgZGlyLCBkaXJfbGVuKTsKICAgIGlmIChkaXJbZGlyX2xlbiAtIDFdICE9ICcvJykKCXBhdGhbZGlyX2xlbisrXSA9ICcvJzsKICAgIHN0cmNweSAoKGNoYXIgKikgcGF0aCArIGRpcl9sZW4sIChjb25zdCBjaGFyICopIGZpbGUpOwogICAgaWYgKCFGY1N0ckNtcCAobmFtZSwgRkNfRk9OVF9GSUxFX0RJUikpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRVYpCgkgICAgcHJpbnRmICgiIGRpciBjYWNoZSBkaXIgXCIlc1wiXG4iLCBwYXRoKTsKCXJldCA9IEZjU3RyU2V0QWRkIChkaXJzLCBwYXRoKTsKICAgIH0KICAgIGVsc2UgaWYgKCFGY1N0ckNtcCAobmFtZSwgRkNfRk9OVF9GSUxFX0lOVkFMSUQpKQogICAgewoJcmV0ID0gRmNUcnVlOwogICAgfQogICAgZWxzZQogICAgewoJZm9udCA9IEZjTmFtZVBhcnNlIChuYW1lKTsKCWlmIChmb250KQoJewoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFVikKCQlwcmludGYgKCIgZGlyIGNhY2hlIGZpbGUgXCIlc1wiXG4iLCBmaWxlKTsKCSAgICByZXQgPSAoRmNQYXR0ZXJuQWRkU3RyaW5nIChmb250LCBGQ19GSUxFLCBwYXRoKSAmJgoJCSAgIEZjRm9udFNldEFkZCAoc2V0LCBmb250KSk7CgkgICAgaWYgKCFyZXQpCgkJRmNQYXR0ZXJuRGVzdHJveSAoZm9udCk7Cgl9CiAgICB9CiAgICBpZiAocGF0aCAhPSBwYXRoX2J1ZikgZnJlZSAocGF0aCk7CiAgICByZXR1cm4gcmV0OwogICAgCn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQKRmNDYWNoZUhhc2ggKGNvbnN0IEZjQ2hhcjggKnN0cmluZykKewogICAgdW5zaWduZWQgaW50ICAgIGggPSAwOwogICAgRmNDaGFyOAkgICAgYzsKCiAgICB3aGlsZSAoKGMgPSAqc3RyaW5nKyspKQoJaCA9IChoIDw8IDEpIF4gYzsKICAgIHJldHVybiAwOwp9CgovKgogKiBWZXJpZnkgdGhlIHNhdmVkIHRpbWVzdGFtcCBmb3IgYSBmaWxlCiAqLwpGY0Jvb2wKRmNHbG9iYWxDYWNoZUNoZWNrVGltZSAoRmNHbG9iYWxDYWNoZUluZm8gKmluZm8pCnsKICAgIHN0cnVjdCBzdGF0CSAgICBzdGF0YjsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgaW5mby0+ZmlsZSwgJnN0YXRiKSA8IDApCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgZmlsZSBtaXNzaW5nXG4iKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgaWYgKHN0YXRiLnN0X210aW1lICE9IGluZm8tPnRpbWUpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgdGltZXN0YW1wIG1pc21hdGNoICh3YXMgJWQgaXMgJWQpXG4iLAoJCSAgICAoaW50KSBpbmZvLT50aW1lLCAoaW50KSBzdGF0Yi5zdF9tdGltZSk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnZvaWQKRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKEZjR2xvYmFsQ2FjaGUJICAgICpjYWNoZSwKCQkJIEZjR2xvYmFsQ2FjaGVJbmZvICAqaW5mbykKewogICAgaWYgKCFpbmZvLT5yZWZlcmVuY2VkKQogICAgewoJaW5mby0+cmVmZXJlbmNlZCA9IEZjVHJ1ZTsKCWNhY2hlLT5yZWZlcmVuY2VkKys7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRV9SRUYpCgkgICAgcHJpbnRmICgiUmVmZXJlbmNlICVkICVzXG4iLCBjYWNoZS0+cmVmZXJlbmNlZCwgaW5mby0+ZmlsZSk7CiAgICB9Cn0KCi8qCiAqIEJyZWFrIGEgcGF0aCBpbnRvIGRpci9iYXNlIGVsZW1lbnRzIGFuZCBjb21wdXRlIHRoZSBiYXNlIGhhc2gKICogYW5kIHRoZSBkaXIgbGVuZ3RoLiAgVGhpcyBpcyBzaGFyZWQgYmV0d2VlbiB0aGUgZnVuY3Rpb25zCiAqIHdoaWNoIHdhbGsgdGhlIGZpbGUgY2FjaGVzCiAqLwoKdHlwZWRlZiBzdHJ1Y3QgX0ZjRmlsZVBhdGhJbmZvIHsKICAgIGNvbnN0IEZjQ2hhcjggICAqZGlyOwogICAgaW50CQkgICAgZGlyX2xlbjsKICAgIGNvbnN0IEZjQ2hhcjggICAqYmFzZTsKICAgIHVuc2lnbmVkIGludCAgICBiYXNlX2hhc2g7Cn0gRmNGaWxlUGF0aEluZm87CgpzdGF0aWMgRmNGaWxlUGF0aEluZm8KRmNGaWxlUGF0aEluZm9HZXQgKGNvbnN0IEZjQ2hhcjggICAgKnBhdGgpCnsKICAgIEZjRmlsZVBhdGhJbmZvICBpOwogICAgRmNDaGFyOAkgICAgKnNsYXNoOwoKICAgIHNsYXNoID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNvbnN0IGNoYXIgKikgcGF0aCwgJy8nKTsKICAgIGlmIChzbGFzaCkKICAgIHsKICAgICAgICBpLmRpciA9IHBhdGg7CiAgICAgICAgaS5kaXJfbGVuID0gc2xhc2ggLSBwYXRoOwoJaWYgKCFpLmRpcl9sZW4pCgkgICAgaS5kaXJfbGVuID0gMTsKCWkuYmFzZSA9IHNsYXNoICsgMTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWkuZGlyID0gKGNvbnN0IEZjQ2hhcjggKikgIi4iOwoJaS5kaXJfbGVuID0gMTsKCWkuYmFzZSA9IHBhdGg7CiAgICB9CiAgICBpLmJhc2VfaGFzaCA9IEZjQ2FjaGVIYXNoIChpLmJhc2UpOwogICAgcmV0dXJuIGk7Cn0KCkZjR2xvYmFsQ2FjaGVEaXIgKgpGY0dsb2JhbENhY2hlRGlyR2V0IChGY0dsb2JhbENhY2hlICAqY2FjaGUsCgkJICAgICBjb25zdCBGY0NoYXI4ICAqZGlyLAoJCSAgICAgaW50CSAgICBsZW4sCgkJICAgICBGY0Jvb2wJICAgIGNyZWF0ZV9taXNzaW5nKQp7CiAgICB1bnNpZ25lZCBpbnQJaGFzaCA9IEZjQ2FjaGVIYXNoIChkaXIpOwogICAgRmNHbG9iYWxDYWNoZURpcgkqZCwgKipwcmV2OwoKICAgIGZvciAocHJldiA9ICZjYWNoZS0+ZW50c1toYXNoICUgRkNfR0xPQkFMX0NBQ0hFX0RJUl9IQVNIX1NJWkVdOwoJIChkID0gKnByZXYpOwoJIHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKICAgIHsKCWlmIChkLT5pbmZvLmhhc2ggPT0gaGFzaCAmJiBkLT5sZW4gPT0gbGVuICYmCgkgICAgIXN0cm5jbXAgKChjb25zdCBjaGFyICopIGQtPmluZm8uZmlsZSwKCQkgICAgICAoY29uc3QgY2hhciAqKSBkaXIsIGxlbikpCgkgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoIShkID0gKnByZXYpKQogICAgewoJaW50CWk7CglpZiAoIWNyZWF0ZV9taXNzaW5nKQoJICAgIHJldHVybiAwOwoJZCA9IG1hbGxvYyAoc2l6ZW9mIChGY0dsb2JhbENhY2hlRGlyKSArIGxlbiArIDEpOwoJaWYgKCFkKQoJICAgIHJldHVybiAwOwoJZC0+bmV4dCA9ICpwcmV2OwoJKnByZXYgPSBkOwoJZC0+aW5mby5oYXNoID0gaGFzaDsKCWQtPmluZm8uZmlsZSA9IChGY0NoYXI4ICopIChkICsgMSk7CglzdHJuY3B5ICgoY2hhciAqKSBkLT5pbmZvLmZpbGUsIChjb25zdCBjaGFyICopIGRpciwgbGVuKTsKCWQtPmluZm8uZmlsZVtsZW5dID0gJ1wwJzsKCWQtPmluZm8udGltZSA9IDA7CglkLT5pbmZvLnJlZmVyZW5jZWQgPSBGY0ZhbHNlOwoJZC0+bGVuID0gbGVuOwoJZm9yIChpID0gMDsgaSA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgaSsrKQoJICAgIGQtPmVudHNbaV0gPSAwOwoJZC0+c3ViZGlycyA9IDA7CiAgICB9CiAgICByZXR1cm4gZDsKfQoKc3RhdGljIEZjR2xvYmFsQ2FjaGVJbmZvICoKRmNHbG9iYWxDYWNoZURpckFkZCAoRmNHbG9iYWxDYWNoZSAgKmNhY2hlLAoJCSAgICAgY29uc3QgRmNDaGFyOCAgKmRpciwKCQkgICAgIHRpbWVfdAkgICAgdGltZSwKCQkgICAgIEZjQm9vbAkgICAgcmVwbGFjZSkKewogICAgRmNHbG9iYWxDYWNoZURpcgkqZDsKICAgIEZjRmlsZVBhdGhJbmZvCWk7CiAgICBGY0dsb2JhbENhY2hlU3ViZGlyCSpzdWJkaXI7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpwYXJlbnQ7CgogICAgLyoKICAgICAqIEFkZCB0aGlzIGRpcmVjdG9yeSB0byB0aGUgY2FjaGUKICAgICAqLwogICAgZCA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBkaXIsIHN0cmxlbiAoKGNvbnN0IGNoYXIgKikgZGlyKSwgRmNUcnVlKTsKICAgIGlmICghZCkKCXJldHVybiAwOwogICAgZC0+aW5mby50aW1lID0gdGltZTsKICAgIGkgPSBGY0ZpbGVQYXRoSW5mb0dldCAoZGlyKTsKICAgIC8qCiAgICAgKiBBZGQgdGhpcyBkaXJlY3RvcnkgdG8gdGhlIHN1YmRpcmVjdG9yeSBsaXN0IG9mIHRoZSBwYXJlbnQKICAgICAqLwogICAgcGFyZW50ID0gRmNHbG9iYWxDYWNoZURpckdldCAoY2FjaGUsIGkuZGlyLCBpLmRpcl9sZW4sIEZjVHJ1ZSk7CiAgICBpZiAoIXBhcmVudCkKCXJldHVybiAwOwogICAgc3ViZGlyID0gbWFsbG9jIChzaXplb2YgKEZjR2xvYmFsQ2FjaGVTdWJkaXIpICsgCgkJICAgICBzdHJsZW4gKChjb25zdCBjaGFyICopIGkuYmFzZSkgKyAxKTsKICAgIGlmICghc3ViZGlyKQoJcmV0dXJuIDA7CiAgICBzdWJkaXItPmZpbGUgPSAoRmNDaGFyOCAqKSAoc3ViZGlyICsgMSk7CiAgICBzdHJjcHkgKChjaGFyICopIHN1YmRpci0+ZmlsZSwgKGNvbnN0IGNoYXIgKikgaS5iYXNlKTsKICAgIHN1YmRpci0+bmV4dCA9IHBhcmVudC0+c3ViZGlyczsKICAgIHBhcmVudC0+c3ViZGlycyA9IHN1YmRpcjsKICAgIHJldHVybiAmZC0+aW5mbzsKfQoKc3RhdGljIHZvaWQKRmNHbG9iYWxDYWNoZURpckRlc3Ryb3kgKEZjR2xvYmFsQ2FjaGVEaXIgKmQpCnsKICAgIEZjR2xvYmFsQ2FjaGVGaWxlCSpmLCAqbmV4dDsKICAgIGludAkJCWg7CiAgICBGY0dsb2JhbENhY2hlU3ViZGlyCSpzLCAqbmV4dHM7CgogICAgZm9yIChoID0gMDsgaCA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgaCsrKQoJZm9yIChmID0gZC0+ZW50c1toXTsgZjsgZiA9IG5leHQpCgl7CgkgICAgbmV4dCA9IGYtPm5leHQ7CgkgICAgZnJlZSAoZik7Cgl9CiAgICBmb3IgKHMgPSBkLT5zdWJkaXJzOyBzOyBzID0gbmV4dHMpCiAgICB7CgluZXh0cyA9IHMtPm5leHQ7CglmcmVlIChzKTsKICAgIH0KICAgIGZyZWUgKGQpOwp9CgpGY0Jvb2wKRmNHbG9iYWxDYWNoZVNjYW5EaXIgKEZjRm9udFNldAkJKnNldCwKCQkgICAgICBGY1N0clNldAkJKmRpcnMsCgkJICAgICAgRmNHbG9iYWxDYWNoZQkqY2FjaGUsCgkJICAgICAgY29uc3QgRmNDaGFyOAkqZGlyKQp7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkID0gRmNHbG9iYWxDYWNoZURpckdldCAoY2FjaGUsIGRpciwKCQkJCQkJICBzdHJsZW4gKChjb25zdCBjaGFyICopIGRpciksCgkJCQkJCSAgRmNGYWxzZSk7CiAgICBGY0dsb2JhbENhY2hlRmlsZQkqZjsKICAgIGludAkJCWg7CiAgICBpbnQJCQlkaXJfbGVuOwogICAgRmNHbG9iYWxDYWNoZVN1YmRpcgkqc3ViZGlyOwoKICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCJGY0dsb2JhbENhY2hlU2NhbkRpciAlc1xuIiwgZGlyKTsKICAgIAogICAgaWYgKCFkKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiXHRObyBkaXIgY2FjaGUgZW50cnlcbiIpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CgogICAgaWYgKCFGY0dsb2JhbENhY2hlQ2hlY2tUaW1lICgmZC0+aW5mbykpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCJcdGRpciBjYWNoZSBlbnRyeSB0aW1lIG1pc21hdGNoXG4iKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIGRpcl9sZW4gPSBzdHJsZW4gKChjb25zdCBjaGFyICopIGRpcik7CiAgICBmb3IgKGggPSAwOyBoIDwgRkNfR0xPQkFMX0NBQ0hFX0ZJTEVfSEFTSF9TSVpFOyBoKyspCglmb3IgKGYgPSBkLT5lbnRzW2hdOyBmOyBmID0gZi0+bmV4dCkKCXsKCSAgICBpZiAoRmNEZWJ1ZygpICYgRkNfREJHX0NBQ0hFVikKCQlwcmludGYgKCJGY0dsb2JhbENhY2hlU2NhbkRpciBhZGQgZmlsZSAlc1xuIiwgZi0+aW5mby5maWxlKTsKCSAgICBpZiAoIUZjQ2FjaGVGb250U2V0QWRkIChzZXQsIGRpcnMsIGRpciwgZGlyX2xlbiwKCQkJCSAgICBmLT5pbmZvLmZpbGUsIGYtPm5hbWUpKQoJICAgIHsKCQljYWNoZS0+YnJva2VuID0gRmNUcnVlOwoJCXJldHVybiBGY0ZhbHNlOwoJICAgIH0KCSAgICBGY0dsb2JhbENhY2hlUmVmZXJlbmNlZCAoY2FjaGUsICZmLT5pbmZvKTsKCX0KICAgIGZvciAoc3ViZGlyID0gZC0+c3ViZGlyczsgc3ViZGlyOyBzdWJkaXIgPSBzdWJkaXItPm5leHQpCiAgICB7CglpZiAoIUZjQ2FjaGVGb250U2V0QWRkIChzZXQsIGRpcnMsIGRpciwgZGlyX2xlbiwKCQkJCXN1YmRpci0+ZmlsZSwgRkNfRk9OVF9GSUxFX0RJUikpCgl7CgkgICAgY2FjaGUtPmJyb2tlbiA9IEZjVHJ1ZTsKCSAgICByZXR1cm4gRmNGYWxzZTsKCX0KICAgIH0KICAgIAogICAgRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKGNhY2hlLCAmZC0+aW5mbyk7CgogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKLyoKICogTG9jYXRlIHRoZSBjYWNoZSBlbnRyeSBmb3IgYSBwYXJ0aWN1bGFyIGZpbGUKICovCkZjR2xvYmFsQ2FjaGVGaWxlICoKRmNHbG9iYWxDYWNoZUZpbGVHZXQgKEZjR2xvYmFsQ2FjaGUgKmNhY2hlLAoJCSAgICAgIGNvbnN0IEZjQ2hhcjggKmZpbGUsCgkJICAgICAgaW50CSAgICBpZCwKCQkgICAgICBpbnQJICAgICpjb3VudCkKewogICAgRmNGaWxlUGF0aEluZm8JaSA9IEZjRmlsZVBhdGhJbmZvR2V0IChmaWxlKTsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQgPSBGY0dsb2JhbENhY2hlRGlyR2V0IChjYWNoZSwgaS5kaXIsIAoJCQkJCQkgIGkuZGlyX2xlbiwgRmNGYWxzZSk7CiAgICBGY0dsb2JhbENhY2hlRmlsZQkqZiwgKm1hdGNoID0gMDsKICAgIGludAkJCW1heCA9IC0xOwoKICAgIGlmICghZCkKCXJldHVybiAwOwogICAgZm9yIChmID0gZC0+ZW50c1tpLmJhc2VfaGFzaCAlIEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRV07IGY7IGYgPSBmLT5uZXh0KQogICAgewoJaWYgKGYtPmluZm8uaGFzaCA9PSBpLmJhc2VfaGFzaCAmJgoJICAgICFzdHJjbXAgKChjb25zdCBjaGFyICopIGYtPmluZm8uZmlsZSwgKGNvbnN0IGNoYXIgKikgaS5iYXNlKSkKCXsKCSAgICBpZiAoZi0+aWQgPT0gaWQpCgkJbWF0Y2ggPSBmOwoJICAgIGlmIChmLT5pZCA+IG1heCkKCQltYXggPSBmLT5pZDsKCX0KICAgIH0KICAgIGlmIChjb3VudCkKCSpjb3VudCA9IG1heDsKICAgIHJldHVybiBtYXRjaDsKfQogICAgCi8qCiAqIEFkZCBhIGZpbGUgZW50cnkgdG8gdGhlIGNhY2hlCiAqLwpzdGF0aWMgRmNHbG9iYWxDYWNoZUluZm8gKgpGY0dsb2JhbENhY2hlRmlsZUFkZCAoRmNHbG9iYWxDYWNoZSAqY2FjaGUsCgkJICAgICAgY29uc3QgRmNDaGFyOCAqcGF0aCwKCQkgICAgICBpbnQJICAgIGlkLAoJCSAgICAgIHRpbWVfdAkgICAgdGltZSwKCQkgICAgICBjb25zdCBGY0NoYXI4ICpuYW1lLAoJCSAgICAgIEZjQm9vbAkgICAgcmVwbGFjZSkKewogICAgRmNGaWxlUGF0aEluZm8JaSA9IEZjRmlsZVBhdGhJbmZvR2V0IChwYXRoKTsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQgPSBGY0dsb2JhbENhY2hlRGlyR2V0IChjYWNoZSwgaS5kaXIsIAoJCQkJCQkgIGkuZGlyX2xlbiwgRmNUcnVlKTsKICAgIEZjR2xvYmFsQ2FjaGVGaWxlCSpmLCAqKnByZXY7CgogICAgaWYgKCFkKQoJcmV0dXJuIDA7CiAgICBmb3IgKHByZXYgPSAmZC0+ZW50c1tpLmJhc2VfaGFzaCAlIEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRV07CgkgKGYgPSAqcHJldik7CgkgcHJldiA9ICYoKnByZXYpLT5uZXh0KQogICAgewoJaWYgKGYtPmluZm8uaGFzaCA9PSBpLmJhc2VfaGFzaCAmJiAKCSAgICBmLT5pZCA9PSBpZCAmJgoJICAgICFzdHJjbXAgKChjb25zdCBjaGFyICopIGYtPmluZm8uZmlsZSwgKGNvbnN0IGNoYXIgKikgaS5iYXNlKSkKCXsKCSAgICBicmVhazsKCX0KICAgIH0KICAgIGlmICgqcHJldikKICAgIHsKCWlmICghcmVwbGFjZSkKCSAgICByZXR1cm4gMDsKCglmID0gKnByZXY7CglpZiAoZi0+aW5mby5yZWZlcmVuY2VkKQoJICAgIGNhY2hlLT5yZWZlcmVuY2VkLS07CgkqcHJldiA9IGYtPm5leHQ7CglmcmVlIChmKTsKICAgIH0KICAgIGYgPSBtYWxsb2MgKHNpemVvZiAoRmNHbG9iYWxDYWNoZUZpbGUpICsKCQlzdHJsZW4gKChjaGFyICopIGkuYmFzZSkgKyAxICsKCQlzdHJsZW4gKChjaGFyICopIG5hbWUpICsgMSk7CiAgICBpZiAoIWYpCglyZXR1cm4gMDsKICAgIGYtPm5leHQgPSAqcHJldjsKICAgICpwcmV2ID0gZjsKICAgIGYtPmluZm8uaGFzaCA9IGkuYmFzZV9oYXNoOwogICAgZi0+aW5mby5maWxlID0gKEZjQ2hhcjggKikgKGYgKyAxKTsKICAgIGYtPmluZm8udGltZSA9IHRpbWU7CiAgICBmLT5pbmZvLnJlZmVyZW5jZWQgPSBGY0ZhbHNlOwogICAgZi0+aWQgPSBpZDsKICAgIGYtPm5hbWUgPSBmLT5pbmZvLmZpbGUgKyBzdHJsZW4gKChjaGFyICopIGkuYmFzZSkgKyAxOwogICAgc3RyY3B5ICgoY2hhciAqKSBmLT5pbmZvLmZpbGUsIChjb25zdCBjaGFyICopIGkuYmFzZSk7CiAgICBzdHJjcHkgKChjaGFyICopIGYtPm5hbWUsIChjb25zdCBjaGFyICopIG5hbWUpOwogICAgcmV0dXJuICZmLT5pbmZvOwp9CgpGY0dsb2JhbENhY2hlICoKRmNHbG9iYWxDYWNoZUNyZWF0ZSAodm9pZCkKewogICAgRmNHbG9iYWxDYWNoZSAgICpjYWNoZTsKICAgIGludAkJICAgIGg7CgogICAgY2FjaGUgPSBtYWxsb2MgKHNpemVvZiAoRmNHbG9iYWxDYWNoZSkpOwogICAgaWYgKCFjYWNoZSkKCXJldHVybiAwOwogICAgZm9yIChoID0gMDsgaCA8IEZDX0dMT0JBTF9DQUNIRV9ESVJfSEFTSF9TSVpFOyBoKyspCgljYWNoZS0+ZW50c1toXSA9IDA7CiAgICBjYWNoZS0+ZW50cmllcyA9IDA7CiAgICBjYWNoZS0+cmVmZXJlbmNlZCA9IDA7CiAgICBjYWNoZS0+dXBkYXRlZCA9IEZjRmFsc2U7CiAgICBjYWNoZS0+YnJva2VuID0gRmNGYWxzZTsKICAgIHJldHVybiBjYWNoZTsKfQoKdm9pZApGY0dsb2JhbENhY2hlRGVzdHJveSAoRmNHbG9iYWxDYWNoZSAqY2FjaGUpCnsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQsICpuZXh0OwogICAgaW50CQkJaDsKCiAgICBmb3IgKGggPSAwOyBoIDwgRkNfR0xPQkFMX0NBQ0hFX0RJUl9IQVNIX1NJWkU7IGgrKykKICAgIHsKCWZvciAoZCA9IGNhY2hlLT5lbnRzW2hdOyBkOyBkID0gbmV4dCkKCXsKCSAgICBuZXh0ID0gZC0+bmV4dDsKCSAgICBGY0dsb2JhbENhY2hlRGlyRGVzdHJveSAoZCk7Cgl9CiAgICB9CiAgICBmcmVlIChjYWNoZSk7Cn0KCi8qCiAqIENhY2hlIGZpbGUgc3ludGF4IGlzIHF1aXRlIHNpbXBsZToKICoKICogImZpbGVfbmFtZSIgaWQgdGltZSAiZm9udF9uYW1lIiBcbgogKi8KIAp2b2lkCkZjR2xvYmFsQ2FjaGVMb2FkIChGY0dsb2JhbENhY2hlICAgICpjYWNoZSwKCQkgICBjb25zdCBGY0NoYXI4ICAgICpjYWNoZV9maWxlKQp7CiAgICBGSUxFCQkqZjsKICAgIEZjQ2hhcjgJCWZpbGVfYnVmWzgxOTJdLCAqZmlsZTsKICAgIGludAkJCWlkOwogICAgdGltZV90CQl0aW1lOwogICAgRmNDaGFyOAkJbmFtZV9idWZbODE5Ml0sICpuYW1lOwogICAgRmNHbG9iYWxDYWNoZUluZm8JKmluZm87CgogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAiciIpOwogICAgaWYgKCFmKQoJcmV0dXJuOwoKICAgIGNhY2hlLT51cGRhdGVkID0gRmNGYWxzZTsKICAgIGZpbGUgPSAwOwogICAgbmFtZSA9IDA7CiAgICB3aGlsZSAoKGZpbGUgPSBGY0NhY2hlUmVhZFN0cmluZyAoZiwgZmlsZV9idWYsIHNpemVvZiAoZmlsZV9idWYpKSkgJiYKCSAgIEZjQ2FjaGVSZWFkSW50IChmLCAmaWQpICYmCgkgICBGY0NhY2hlUmVhZFRpbWUgKGYsICZ0aW1lKSAmJgoJICAgKG5hbWUgPSBGY0NhY2hlUmVhZFN0cmluZyAoZiwgbmFtZV9idWYsIHNpemVvZiAobmFtZV9idWYpKSkpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRVYpCgkgICAgcHJpbnRmICgiRmNHbG9iYWxDYWNoZUxvYWQgXCIlc1wiIFwiJTIwLjIwc1wiXG4iLCBmaWxlLCBuYW1lKTsKCWlmICghRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9ESVIpKQoJICAgIGluZm8gPSBGY0dsb2JhbENhY2hlRGlyQWRkIChjYWNoZSwgZmlsZSwgdGltZSwgRmNGYWxzZSk7CgllbHNlCgkgICAgaW5mbyA9IEZjR2xvYmFsQ2FjaGVGaWxlQWRkIChjYWNoZSwgZmlsZSwgaWQsIHRpbWUsIG5hbWUsIEZjRmFsc2UpOwoJaWYgKCFpbmZvKQoJICAgIGNhY2hlLT5icm9rZW4gPSBGY1RydWU7CgllbHNlCgkgICAgY2FjaGUtPmVudHJpZXMrKzsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFX1JFRikKCSAgICBwcmludGYgKCJGY0dsb2JhbENhY2hlTG9hZCBlbnRyeSAlZCAlc1xuIiwKCQkgICAgY2FjaGUtPmVudHJpZXMsIGZpbGUpOwoJaWYgKGZpbGUgIT0gZmlsZV9idWYpCgkgICAgZnJlZSAoZmlsZSk7CglpZiAobmFtZSAhPSBuYW1lX2J1ZikKCSAgICBmcmVlIChuYW1lKTsKCWZpbGUgPSAwOwoJbmFtZSA9IDA7CiAgICB9CiAgICBpZiAoZmlsZSAmJiBmaWxlICE9IGZpbGVfYnVmKQoJZnJlZSAoZmlsZSk7CiAgICBpZiAobmFtZSAmJiBuYW1lICE9IG5hbWVfYnVmKQoJZnJlZSAobmFtZSk7CiAgICBmY2xvc2UgKGYpOwp9CgpGY0Jvb2wKRmNHbG9iYWxDYWNoZVVwZGF0ZSAoRmNHbG9iYWxDYWNoZSAgKmNhY2hlLAoJCSAgICAgY29uc3QgRmNDaGFyOCAgKmZpbGUsCgkJICAgICBpbnQJICAgIGlkLAoJCSAgICAgY29uc3QgRmNDaGFyOCAgKm5hbWUpCnsKICAgIGNvbnN0IEZjQ2hhcjgJKm1hdGNoOwogICAgc3RydWN0IHN0YXQJCXN0YXRiOwogICAgRmNHbG9iYWxDYWNoZUluZm8JKmluZm87CgogICAgbWF0Y2ggPSBmaWxlOwoKICAgIGlmIChzdGF0ICgoY2hhciAqKSBmaWxlLCAmc3RhdGIpIDwgMCkKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKFNfSVNESVIgKHN0YXRiLnN0X21vZGUpKQoJaW5mbyA9IEZjR2xvYmFsQ2FjaGVEaXJBZGQgKGNhY2hlLCBmaWxlLCBzdGF0Yi5zdF9tdGltZSwgCgkJCQkgICBGY1RydWUpOwogICAgZWxzZQoJaW5mbyA9IEZjR2xvYmFsQ2FjaGVGaWxlQWRkIChjYWNoZSwgZmlsZSwgaWQsIHN0YXRiLnN0X210aW1lLCAKCQkJCSAgICBuYW1lLCBGY1RydWUpOwogICAgaWYgKGluZm8pCiAgICB7CglGY0dsb2JhbENhY2hlUmVmZXJlbmNlZCAoY2FjaGUsIGluZm8pOwoJY2FjaGUtPnVwZGF0ZWQgPSBGY1RydWU7CiAgICB9CiAgICBlbHNlCgljYWNoZS0+YnJva2VuID0gRmNUcnVlOwogICAgcmV0dXJuIGluZm8gIT0gMDsKfQoKRmNCb29sCkZjR2xvYmFsQ2FjaGVTYXZlIChGY0dsb2JhbENhY2hlICAgICpjYWNoZSwKCQkgICBjb25zdCBGY0NoYXI4ICAgICpjYWNoZV9maWxlKQp7CiAgICBGSUxFCQkqZjsKICAgIGludAkJCWRpcl9oYXNoLCBmaWxlX2hhc2g7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkaXI7CiAgICBGY0dsb2JhbENhY2hlRmlsZQkqZmlsZTsKICAgIEZjQXRvbWljCQkqYXRvbWljOwoKICAgIGlmICghY2FjaGUtPnVwZGF0ZWQgJiYgY2FjaGUtPnJlZmVyZW5jZWQgPT0gY2FjaGUtPmVudHJpZXMpCglyZXR1cm4gRmNUcnVlOwogICAgCiAgICBpZiAoY2FjaGUtPmJyb2tlbikKCXJldHVybiBGY0ZhbHNlOwoKICAgIC8qIFNldC1VSUQgcHJvZ3JhbXMgY2FuJ3Qgc2FmZWx5IHVwZGF0ZSB0aGUgY2FjaGUgKi8KICAgIGlmIChnZXR1aWQgKCkgIT0gZ2V0ZXVpZCAoKSkKCXJldHVybiBGY0ZhbHNlOwogICAgCiAgICBhdG9taWMgPSBGY0F0b21pY0NyZWF0ZSAoY2FjaGVfZmlsZSk7CiAgICBpZiAoIWF0b21pYykKCWdvdG8gYmFpbDA7CiAgICBpZiAoIUZjQXRvbWljTG9jayAoYXRvbWljKSkKCWdvdG8gYmFpbDE7CiAgICBmID0gZm9wZW4gKChjaGFyICopIEZjQXRvbWljTmV3RmlsZShhdG9taWMpLCAidyIpOwogICAgaWYgKCFmKQoJZ290byBiYWlsMjsKCiAgICBmb3IgKGRpcl9oYXNoID0gMDsgZGlyX2hhc2ggPCBGQ19HTE9CQUxfQ0FDSEVfRElSX0hBU0hfU0laRTsgZGlyX2hhc2grKykKICAgIHsKCWZvciAoZGlyID0gY2FjaGUtPmVudHNbZGlyX2hhc2hdOyBkaXI7IGRpciA9IGRpci0+bmV4dCkKCXsKCSAgICBpZiAoIWRpci0+aW5mby5yZWZlcmVuY2VkKQoJCWNvbnRpbnVlOwoJICAgIGlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBkaXItPmluZm8uZmlsZSkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAocHV0YyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgMCkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAocHV0YyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVRpbWUgKGYsIGRpci0+aW5mby50aW1lKSkKCQlnb3RvIGJhaWw0OwoJICAgIGlmIChwdXRjICgnICcsIGYpID09IEVPRikKCQlnb3RvIGJhaWw0OwoJICAgIGlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCAoRmNDaGFyOCAqKSBGQ19GT05UX0ZJTEVfRElSKSkKCQlnb3RvIGJhaWw0OwoJICAgIGlmIChwdXRjICgnXG4nLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICAKCSAgICBmb3IgKGZpbGVfaGFzaCA9IDA7IGZpbGVfaGFzaCA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgZmlsZV9oYXNoKyspCgkgICAgewoJCWZvciAoZmlsZSA9IGRpci0+ZW50c1tmaWxlX2hhc2hdOyBmaWxlOyBmaWxlID0gZmlsZS0+bmV4dCkKCQl7CgkJICAgIGlmICghZmlsZS0+aW5mby5yZWZlcmVuY2VkKQoJCQljb250aW51ZTsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVQYXRoIChmLCBkaXItPmluZm8uZmlsZSwgZmlsZS0+aW5mby5maWxlKSkKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKHB1dGMgKCcgJywgZikgPT0gRU9GKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgZmlsZS0+aWQgPCAwID8gMCA6IGZpbGUtPmlkKSkKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKHB1dGMgKCcgJywgZikgPT0gRU9GKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVRpbWUgKGYsIGZpbGUtPmluZm8udGltZSkpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmIChwdXRjICgnICcsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIGZpbGUtPm5hbWUpKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAocHV0YyAoJ1xuJywgZikgPT0gRU9GKQoJCQlnb3RvIGJhaWw0OwoJCX0KCSAgICB9Cgl9CiAgICB9CgogICAgaWYgKGZjbG9zZSAoZikgPT0gRU9GKQoJZ290byBiYWlsMzsKICAgIAogICAgaWYgKCFGY0F0b21pY1JlcGxhY2VPcmlnIChhdG9taWMpKQoJZ290byBiYWlsMzsKICAgIAogICAgRmNBdG9taWNVbmxvY2sgKGF0b21pYyk7CiAgICBGY0F0b21pY0Rlc3Ryb3kgKGF0b21pYyk7CgogICAgY2FjaGUtPnVwZGF0ZWQgPSBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKCmJhaWw0OgogICAgZmNsb3NlIChmKTsKYmFpbDM6CiAgICBGY0F0b21pY0RlbGV0ZU5ldyAoYXRvbWljKTsKYmFpbDI6CiAgICBGY0F0b21pY1VubG9jayAoYXRvbWljKTsKYmFpbDE6CiAgICBGY0F0b21pY0Rlc3Ryb3kgKGF0b21pYyk7CmJhaWwwOgogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY0RpckNhY2hlVmFsaWQgKGNvbnN0IEZjQ2hhcjggKmRpcikKewogICAgRmNDaGFyOAkqY2FjaGVfZmlsZSA9IEZjU3RyUGx1cyAoZGlyLCAoRmNDaGFyOCAqKSAiLyIgRkNfRElSX0NBQ0hFX0ZJTEUpOwogICAgc3RydWN0IHN0YXQJZmlsZV9zdGF0LCBkaXJfc3RhdDsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgZGlyLCAmZGlyX3N0YXQpIDwgMCkKICAgIHsKCUZjU3RyRnJlZSAoY2FjaGVfZmlsZSk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGlmIChzdGF0ICgoY2hhciAqKSBjYWNoZV9maWxlLCAmZmlsZV9zdGF0KSA8IDApCiAgICB7CglGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwogICAgLyoKICAgICAqIElmIHRoZSBkaXJlY3RvcnkgaGFzIGJlZW4gbW9kaWZpZWQgbW9yZSByZWNlbnRseSB0aGFuCiAgICAgKiB0aGUgY2FjaGUgZmlsZSwgdGhlIGNhY2hlIGlzIG5vdCB2YWxpZAogICAgICovCiAgICBpZiAoZGlyX3N0YXQuc3RfbXRpbWUgLSBmaWxlX3N0YXQuc3RfbXRpbWUgPiAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNEaXJDYWNoZVJlYWREaXIgKEZjRm9udFNldCAqc2V0LCBGY1N0clNldCAqZGlycywgY29uc3QgRmNDaGFyOCAqZGlyKQp7CiAgICBGY0NoYXI4CSAgICAqY2FjaGVfZmlsZSA9IEZjU3RyUGx1cyAoZGlyLCAoRmNDaGFyOCAqKSAiLyIgRkNfRElSX0NBQ0hFX0ZJTEUpOwogICAgRklMRQkgICAgKmY7CiAgICBGY0NoYXI4CSAgICAqYmFzZTsKICAgIGludAkJICAgIGlkOwogICAgaW50CQkgICAgZGlyX2xlbjsKICAgIEZjQ2hhcjgJICAgIGZpbGVfYnVmWzgxOTJdLCAqZmlsZTsKICAgIEZjQ2hhcjgJICAgIG5hbWVfYnVmWzgxOTJdLCAqbmFtZTsKICAgIEZjQm9vbAkgICAgcmV0ID0gRmNGYWxzZTsKCiAgICBpZiAoIWNhY2hlX2ZpbGUpCglnb3RvIGJhaWwwOwogICAgCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIkZjRGlyQ2FjaGVSZWFkRGlyIGNhY2hlX2ZpbGUgXCIlc1wiXG4iLCBjYWNoZV9maWxlKTsKICAgIAogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAiciIpOwogICAgaWYgKCFmKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIG5vIGNhY2hlIGZpbGVcbiIpOwoJZ290byBiYWlsMTsKICAgIH0KCiAgICBpZiAoIUZjRGlyQ2FjaGVWYWxpZCAoZGlyKSkKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJICAgIHByaW50ZiAoIiBjYWNoZSBmaWxlIG9sZGVyIHRoYW4gZGlyZWN0b3J5XG4iKTsKCWdvdG8gYmFpbDI7CiAgICB9CiAgICAKICAgIGJhc2UgPSAoRmNDaGFyOCAqKSBzdHJyY2hyICgoY2hhciAqKSBjYWNoZV9maWxlLCAnLycpOwogICAgaWYgKCFiYXNlKQoJZ290byBiYWlsMjsKICAgIGJhc2UrKzsKICAgIGRpcl9sZW4gPSBiYXNlIC0gY2FjaGVfZmlsZTsKICAgIAogICAgZmlsZSA9IDA7CiAgICBuYW1lID0gMDsKICAgIHdoaWxlICgoZmlsZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBmaWxlX2J1Ziwgc2l6ZW9mIChmaWxlX2J1ZikpKSAmJgoJICAgRmNDYWNoZVJlYWRJbnQgKGYsICZpZCkgJiYKCSAgIChuYW1lID0gRmNDYWNoZVJlYWRTdHJpbmcgKGYsIG5hbWVfYnVmLCBzaXplb2YgKG5hbWVfYnVmKSkpKQogICAgewoJaWYgKCFGY0NhY2hlRm9udFNldEFkZCAoc2V0LCBkaXJzLCBjYWNoZV9maWxlLCBkaXJfbGVuLAoJCQkJZmlsZSwgbmFtZSkpCgkgICAgZ290byBiYWlsMzsKCWlmIChmaWxlICE9IGZpbGVfYnVmKQoJICAgIGZyZWUgKGZpbGUpOwoJaWYgKG5hbWUgIT0gbmFtZV9idWYpCgkgICAgZnJlZSAobmFtZSk7CglmaWxlID0gbmFtZSA9IDA7CiAgICB9CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIiBjYWNoZSBsb2FkZWRcbiIpOwogICAgCiAgICByZXQgPSBGY1RydWU7CmJhaWwzOgogICAgaWYgKGZpbGUgJiYgZmlsZSAhPSBmaWxlX2J1ZikKCWZyZWUgKGZpbGUpOwogICAgaWYgKG5hbWUgJiYgbmFtZSAhPSBuYW1lX2J1ZikKCWZyZWUgKG5hbWUpOwpiYWlsMjoKICAgIGZjbG9zZSAoZik7CmJhaWwxOgogICAgZnJlZSAoY2FjaGVfZmlsZSk7CmJhaWwwOgogICAgcmV0dXJuIHJldDsKfQoKLyoKICogcmV0dXJuIHRoZSBwYXRoIGZyb20gdGhlIGRpcmVjdG9yeSBjb250YWluaW5nICdjYWNoZScgdG8gJ2ZpbGUnCiAqLwoKc3RhdGljIGNvbnN0IEZjQ2hhcjggKgpGY0ZpbGVCYXNlTmFtZSAoY29uc3QgRmNDaGFyOCAqY2FjaGUsIGNvbnN0IEZjQ2hhcjggKmZpbGUpCnsKICAgIGNvbnN0IEZjQ2hhcjggICAqY2FjaGVfc2xhc2g7CgogICAgY2FjaGVfc2xhc2ggPSAoY29uc3QgRmNDaGFyOCAqKSBzdHJyY2hyICgoY29uc3QgY2hhciAqKSBjYWNoZSwgJy8nKTsKICAgIGlmIChjYWNoZV9zbGFzaCAmJiAhc3RybmNtcCAoKGNvbnN0IGNoYXIgKikgY2FjaGUsIChjb25zdCBjaGFyICopIGZpbGUsCgkJCQkgKGNhY2hlX3NsYXNoICsgMSkgLSBjYWNoZSkpCglyZXR1cm4gZmlsZSArICgoY2FjaGVfc2xhc2ggKyAxKSAtIGNhY2hlKTsKICAgIHJldHVybiBmaWxlOwp9CgpGY0Jvb2wKRmNEaXJDYWNoZVdyaXRlRGlyIChGY0ZvbnRTZXQgKnNldCwgRmNTdHJTZXQgKmRpcnMsIGNvbnN0IEZjQ2hhcjggKmRpcikKewogICAgRmNDaGFyOAkgICAgKmNhY2hlX2ZpbGUgPSBGY1N0clBsdXMgKGRpciwgKEZjQ2hhcjggKikgIi8iIEZDX0RJUl9DQUNIRV9GSUxFKTsKICAgIEZjUGF0dGVybgkgICAgKmZvbnQ7CiAgICBGSUxFCSAgICAqZjsKICAgIEZjQ2hhcjgJICAgICpuYW1lOwogICAgY29uc3QgRmNDaGFyOCAgICpmaWxlLCAqYmFzZTsKICAgIGludAkJICAgIG47CiAgICBpbnQJCSAgICBpZDsKICAgIEZjQm9vbAkgICAgcmV0OwogICAgRmNTdHJMaXN0CSAgICAqbGlzdDsKCiAgICBpZiAoIWNhY2hlX2ZpbGUpCglnb3RvIGJhaWwwOwogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCJGY0RpckNhY2hlV3JpdGVEaXIgY2FjaGVfZmlsZSBcIiVzXCJcbiIsIGNhY2hlX2ZpbGUpOwogICAgCiAgICBmID0gZm9wZW4gKChjaGFyICopIGNhY2hlX2ZpbGUsICJ3Iik7CiAgICBpZiAoIWYpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgY2FuJ3QgY3JlYXRlIFwiJXNcIlxuIiwgY2FjaGVfZmlsZSk7Cglnb3RvIGJhaWwxOwogICAgfQogICAgCiAgICBsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChkaXJzKTsKICAgIGlmICghbGlzdCkKCWdvdG8gYmFpbDI7CiAgICAKICAgIHdoaWxlICgoZGlyID0gRmNTdHJMaXN0TmV4dCAobGlzdCkpKQogICAgewoJYmFzZSA9IEZjRmlsZUJhc2VOYW1lIChjYWNoZV9maWxlLCBkaXIpOwoJaWYgKCFGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIGJhc2UpKQoJICAgIGdvdG8gYmFpbDM7CglpZiAocHV0YyAoJyAnLCBmKSA9PSBFT0YpCgkgICAgZ290byBiYWlsMzsKCWlmICghRmNDYWNoZVdyaXRlSW50IChmLCAwKSkKCSAgICBnb3RvIGJhaWwzOwogICAgICAgIGlmIChwdXRjICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJaWYgKCFGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIEZDX0ZPTlRfRklMRV9ESVIpKQoJICAgIGdvdG8gYmFpbDM7CglpZiAocHV0YyAoJ1xuJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CiAgICB9CiAgICAKICAgIGZvciAobiA9IDA7IG4gPCBzZXQtPm5mb250OyBuKyspCiAgICB7Cglmb250ID0gc2V0LT5mb250c1tuXTsKCWlmIChGY1BhdHRlcm5HZXRTdHJpbmcgKGZvbnQsIEZDX0ZJTEUsIDAsIChGY0NoYXI4ICoqKSAmZmlsZSkgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICBnb3RvIGJhaWwzOwoJYmFzZSA9IEZjRmlsZUJhc2VOYW1lIChjYWNoZV9maWxlLCBmaWxlKTsKCWlmIChGY1BhdHRlcm5HZXRJbnRlZ2VyIChmb250LCBGQ19JTkRFWCwgMCwgJmlkKSAhPSBGY1Jlc3VsdE1hdGNoKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRVYpCgkgICAgcHJpbnRmICgiIHdyaXRlIGZpbGUgXCIlc1wiXG4iLCBiYXNlKTsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBiYXNlKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKHB1dGMgKCcgJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgaWQpKQoJICAgIGdvdG8gYmFpbDM7CiAgICAgICAgaWYgKHB1dGMgKCcgJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CgluYW1lID0gRmNOYW1lVW5wYXJzZSAoZm9udCk7CglpZiAoIW5hbWUpCgkgICAgZ290byBiYWlsMzsKCXJldCA9IEZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgbmFtZSk7CglmcmVlIChuYW1lKTsKCWlmICghcmV0KQoJICAgIGdvdG8gYmFpbDM7CglpZiAocHV0YyAoJ1xuJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CiAgICB9CiAgICAKICAgIEZjU3RyTGlzdERvbmUgKGxpc3QpOwoKICAgIGlmIChmY2xvc2UgKGYpID09IEVPRikKCWdvdG8gYmFpbDE7CiAgICAKICAgIGZyZWUgKGNhY2hlX2ZpbGUpOwoKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJcHJpbnRmICgiIGNhY2hlIHdyaXR0ZW5cbiIpOwogICAgcmV0dXJuIEZjVHJ1ZTsKICAgIApiYWlsMzoKICAgIEZjU3RyTGlzdERvbmUgKGxpc3QpOwpiYWlsMjoKICAgIGZjbG9zZSAoZik7CmJhaWwxOgogICAgdW5saW5rICgoY2hhciAqKSBjYWNoZV9maWxlKTsKICAgIGZyZWUgKGNhY2hlX2ZpbGUpOwpiYWlsMDoKICAgIHJldHVybiBGY0ZhbHNlOwp9Cg==