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+dXBkYXRlZCA9IEZjRmFsc2U7CiAgICByZXR1cm4gY2FjaGU7Cn0KCnZvaWQKRmNHbG9iYWxDYWNoZURlc3Ryb3kgKEZjR2xvYmFsQ2FjaGUgKmNhY2hlKQp7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkLCAqbmV4dDsKICAgIGludAkJCWg7CgogICAgZm9yIChoID0gMDsgaCA8IEZDX0dMT0JBTF9DQUNIRV9ESVJfSEFTSF9TSVpFOyBoKyspCiAgICB7Cglmb3IgKGQgPSBjYWNoZS0+ZW50c1toXTsgZDsgZCA9IG5leHQpCgl7CgkgICAgbmV4dCA9IGQtPm5leHQ7CgkgICAgRmNHbG9iYWxDYWNoZURpckRlc3Ryb3kgKGQpOwoJfQogICAgfQogICAgZnJlZSAoY2FjaGUpOwp9CgovKgogKiBDYWNoZSBmaWxlIHN5bnRheCBpcyBxdWl0ZSBzaW1wbGU6CiAqCiAqICJmaWxlX25hbWUiIGlkIHRpbWUgImZvbnRfbmFtZSIgXG4KICovCiAKdm9pZApGY0dsb2JhbENhY2hlTG9hZCAoRmNHbG9iYWxDYWNoZSAgICAqY2FjaGUsCgkJICAgY29uc3QgRmNDaGFyOCAgICAqY2FjaGVfZmlsZSkKewogICAgRklMRQkJKmY7CiAgICBGY0NoYXI4CQlmaWxlX2J1Zls4MTkyXSwgKmZpbGU7CiAgICBpbnQJCQlpZDsKICAgIHRpbWVfdAkJdGltZTsKICAgIEZjQ2hhcjgJCW5hbWVfYnVmWzgxOTJdLCAqbmFtZTsKICAgIEZjR2xvYmFsQ2FjaGVJbmZvCSppbmZvOwoKICAgIGYgPSBmb3BlbiAoKGNoYXIgKikgY2FjaGVfZmlsZSwgInIiKTsKICAgIGlmICghZikKCXJldHVybjsKCiAgICBjYWNoZS0+dXBkYXRlZCA9IEZjRmFsc2U7CiAgICBmaWxlID0gMDsKICAgIG5hbWUgPSAwOwogICAgd2hpbGUgKChmaWxlID0gRmNDYWNoZVJlYWRTdHJpbmcgKGYsIGZpbGVfYnVmLCBzaXplb2YgKGZpbGVfYnVmKSkpICYmCgkgICBGY0NhY2hlUmVhZEludCAoZiwgJmlkKSAmJgoJICAgRmNDYWNoZVJlYWRUaW1lIChmLCAmdGltZSkgJiYKCSAgIChuYW1lID0gRmNDYWNoZVJlYWRTdHJpbmcgKGYsIG5hbWVfYnVmLCBzaXplb2YgKG5hbWVfYnVmKSkpKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIkZjR2xvYmFsQ2FjaGVMb2FkIFwiJXNcIiBcIiUyMC4yMHNcIlxuIiwgZmlsZSwgbmFtZSk7CglpZiAoIUZjU3RyQ21wIChuYW1lLCBGQ19GT05UX0ZJTEVfRElSKSkKCSAgICBpbmZvID0gRmNHbG9iYWxDYWNoZURpckFkZCAoY2FjaGUsIGZpbGUsIHRpbWUsIEZjRmFsc2UpOwoJZWxzZQoJICAgIGluZm8gPSBGY0dsb2JhbENhY2hlRmlsZUFkZCAoY2FjaGUsIGZpbGUsIGlkLCB0aW1lLCBuYW1lLCBGY0ZhbHNlKTsKCWlmICghaW5mbykKCSAgICBjYWNoZS0+YnJva2VuID0gRmNUcnVlOwoJZWxzZQoJICAgIGNhY2hlLT5lbnRyaWVzKys7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRV9SRUYpCgkgICAgcHJpbnRmICgiRmNHbG9iYWxDYWNoZUxvYWQgZW50cnkgJWQgJXNcbiIsCgkJICAgIGNhY2hlLT5lbnRyaWVzLCBmaWxlKTsKCWlmIChmaWxlICE9IGZpbGVfYnVmKQoJICAgIGZyZWUgKGZpbGUpOwoJaWYgKG5hbWUgIT0gbmFtZV9idWYpCgkgICAgZnJlZSAobmFtZSk7CglmaWxlID0gMDsKCW5hbWUgPSAwOwogICAgfQogICAgaWYgKGZpbGUgJiYgZmlsZSAhPSBmaWxlX2J1ZikKCWZyZWUgKGZpbGUpOwogICAgaWYgKG5hbWUgJiYgbmFtZSAhPSBuYW1lX2J1ZikKCWZyZWUgKG5hbWUpOwogICAgZmNsb3NlIChmKTsKfQoKRmNCb29sCkZjR2xvYmFsQ2FjaGVVcGRhdGUgKEZjR2xvYmFsQ2FjaGUgICpjYWNoZSwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpmaWxlLAoJCSAgICAgaW50CSAgICBpZCwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpuYW1lKQp7CiAgICBjb25zdCBGY0NoYXI4CSptYXRjaDsKICAgIHN0cnVjdCBzdGF0CQlzdGF0YjsKICAgIEZjR2xvYmFsQ2FjaGVJbmZvCSppbmZvOwoKICAgIG1hdGNoID0gZmlsZTsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgZmlsZSwgJnN0YXRiKSA8IDApCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChTX0lTRElSIChzdGF0Yi5zdF9tb2RlKSkKCWluZm8gPSBGY0dsb2JhbENhY2hlRGlyQWRkIChjYWNoZSwgZmlsZSwgc3RhdGIuc3RfbXRpbWUsIAoJCQkJICAgRmNUcnVlKTsKICAgIGVsc2UKCWluZm8gPSBGY0dsb2JhbENhY2hlRmlsZUFkZCAoY2FjaGUsIGZpbGUsIGlkLCBzdGF0Yi5zdF9tdGltZSwgCgkJCQkgICAgbmFtZSwgRmNUcnVlKTsKICAgIGlmIChpbmZvKQogICAgewoJRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKGNhY2hlLCBpbmZvKTsKCWNhY2hlLT51cGRhdGVkID0gRmNUcnVlOwogICAgfQogICAgZWxzZQoJY2FjaGUtPmJyb2tlbiA9IEZjVHJ1ZTsKICAgIHJldHVybiBpbmZvICE9IDA7Cn0KCkZjQm9vbApGY0dsb2JhbENhY2hlU2F2ZSAoRmNHbG9iYWxDYWNoZSAgICAqY2FjaGUsCgkJICAgY29uc3QgRmNDaGFyOCAgICAqY2FjaGVfZmlsZSkKewogICAgRklMRQkJKmY7CiAgICBpbnQJCQlkaXJfaGFzaCwgZmlsZV9oYXNoOwogICAgRmNHbG9iYWxDYWNoZURpcgkqZGlyOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmZpbGU7CiAgICBGY0F0b21pYwkJKmF0b21pYzsKCiAgICBpZiAoIWNhY2hlLT51cGRhdGVkICYmIGNhY2hlLT5yZWZlcmVuY2VkID09IGNhY2hlLT5lbnRyaWVzKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIAogICAgaWYgKGNhY2hlLT5icm9rZW4pCglyZXR1cm4gRmNGYWxzZTsKCiAgICAvKiBTZXQtVUlEIHByb2dyYW1zIGNhbid0IHNhZmVseSB1cGRhdGUgdGhlIGNhY2hlICovCiAgICBpZiAoZ2V0dWlkICgpICE9IGdldGV1aWQgKCkpCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgYXRvbWljID0gRmNBdG9taWNDcmVhdGUgKGNhY2hlX2ZpbGUpOwogICAgaWYgKCFhdG9taWMpCglnb3RvIGJhaWwwOwogICAgaWYgKCFGY0F0b21pY0xvY2sgKGF0b21pYykpCglnb3RvIGJhaWwxOwogICAgZiA9IGZvcGVuICgoY2hhciAqKSBGY0F0b21pY05ld0ZpbGUoYXRvbWljKSwgInciKTsKICAgIGlmICghZikKCWdvdG8gYmFpbDI7CgogICAgZm9yIChkaXJfaGFzaCA9IDA7IGRpcl9oYXNoIDwgRkNfR0xPQkFMX0NBQ0hFX0RJUl9IQVNIX1NJWkU7IGRpcl9oYXNoKyspCiAgICB7Cglmb3IgKGRpciA9IGNhY2hlLT5lbnRzW2Rpcl9oYXNoXTsgZGlyOyBkaXIgPSBkaXItPm5leHQpCgl7CgkgICAgaWYgKCFkaXItPmluZm8ucmVmZXJlbmNlZCkKCQljb250aW51ZTsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgZGlyLT5pbmZvLmZpbGUpKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKHB1dGMgKCcgJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIDApKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKHB1dGMgKCcgJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKCFGY0NhY2hlV3JpdGVUaW1lIChmLCBkaXItPmluZm8udGltZSkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAocHV0YyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgKEZjQ2hhcjggKikgRkNfRk9OVF9GSUxFX0RJUikpCgkJZ290byBiYWlsNDsKCSAgICBpZiAocHV0YyAoJ1xuJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgCgkgICAgZm9yIChmaWxlX2hhc2ggPSAwOyBmaWxlX2hhc2ggPCBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkU7IGZpbGVfaGFzaCsrKQoJICAgIHsKCQlmb3IgKGZpbGUgPSBkaXItPmVudHNbZmlsZV9oYXNoXTsgZmlsZTsgZmlsZSA9IGZpbGUtPm5leHQpCgkJewoJCSAgICBpZiAoIWZpbGUtPmluZm8ucmVmZXJlbmNlZCkKCQkJY29udGludWU7CgkJICAgIGlmICghRmNDYWNoZVdyaXRlUGF0aCAoZiwgZGlyLT5pbmZvLmZpbGUsIGZpbGUtPmluZm8uZmlsZSkpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmIChwdXRjICgnICcsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIGZpbGUtPmlkIDwgMCA/IDAgOiBmaWxlLT5pZCkpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmIChwdXRjICgnICcsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVUaW1lIChmLCBmaWxlLT5pbmZvLnRpbWUpKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAocHV0YyAoJyAnLCBmKSA9PSBFT0YpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBmaWxlLT5uYW1lKSkKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKHB1dGMgKCdcbicsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQl9CgkgICAgfQoJfQogICAgfQoKICAgIGlmIChmY2xvc2UgKGYpID09IEVPRikKCWdvdG8gYmFpbDM7CiAgICAKICAgIGlmICghRmNBdG9taWNSZXBsYWNlT3JpZyAoYXRvbWljKSkKCWdvdG8gYmFpbDM7CiAgICAKICAgIEZjQXRvbWljVW5sb2NrIChhdG9taWMpOwogICAgRmNBdG9taWNEZXN0cm95IChhdG9taWMpOwoKICAgIGNhY2hlLT51cGRhdGVkID0gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7CgpiYWlsNDoKICAgIGZjbG9zZSAoZik7CmJhaWwzOgogICAgRmNBdG9taWNEZWxldGVOZXcgKGF0b21pYyk7CmJhaWwyOgogICAgRmNBdG9taWNVbmxvY2sgKGF0b21pYyk7CmJhaWwxOgogICAgRmNBdG9taWNEZXN0cm95IChhdG9taWMpOwpiYWlsMDoKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpGY0Jvb2wKRmNEaXJDYWNoZVZhbGlkIChjb25zdCBGY0NoYXI4ICpkaXIpCnsKICAgIEZjQ2hhcjgJKmNhY2hlX2ZpbGUgPSBGY1N0clBsdXMgKGRpciwgKEZjQ2hhcjggKikgIi8iIEZDX0RJUl9DQUNIRV9GSUxFKTsKICAgIHN0cnVjdCBzdGF0CWZpbGVfc3RhdCwgZGlyX3N0YXQ7CgogICAgaWYgKHN0YXQgKChjaGFyICopIGRpciwgJmRpcl9zdGF0KSA8IDApCiAgICB7CglGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoc3RhdCAoKGNoYXIgKikgY2FjaGVfZmlsZSwgJmZpbGVfc3RhdCkgPCAwKQogICAgewoJRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKICAgIC8qCiAgICAgKiBJZiB0aGUgZGlyZWN0b3J5IGhhcyBiZWVuIG1vZGlmaWVkIG1vcmUgcmVjZW50bHkgdGhhbgogICAgICogdGhlIGNhY2hlIGZpbGUsIHRoZSBjYWNoZSBpcyBub3QgdmFsaWQKICAgICAqLwogICAgaWYgKGRpcl9zdGF0LnN0X210aW1lIC0gZmlsZV9zdGF0LnN0X210aW1lID4gMCkKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjRGlyQ2FjaGVSZWFkRGlyIChGY0ZvbnRTZXQgKnNldCwgRmNTdHJTZXQgKmRpcnMsIGNvbnN0IEZjQ2hhcjggKmRpcikKewogICAgRmNDaGFyOAkgICAgKmNhY2hlX2ZpbGUgPSBGY1N0clBsdXMgKGRpciwgKEZjQ2hhcjggKikgIi8iIEZDX0RJUl9DQUNIRV9GSUxFKTsKICAgIEZJTEUJICAgICpmOwogICAgRmNDaGFyOAkgICAgKmJhc2U7CiAgICBpbnQJCSAgICBpZDsKICAgIGludAkJICAgIGRpcl9sZW47CiAgICBGY0NoYXI4CSAgICBmaWxlX2J1Zls4MTkyXSwgKmZpbGU7CiAgICBGY0NoYXI4CSAgICBuYW1lX2J1Zls4MTkyXSwgKm5hbWU7CiAgICBGY0Jvb2wJICAgIHJldCA9IEZjRmFsc2U7CgogICAgaWYgKCFjYWNoZV9maWxlKQoJZ290byBiYWlsMDsKICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCJGY0RpckNhY2hlUmVhZERpciBjYWNoZV9maWxlIFwiJXNcIlxuIiwgY2FjaGVfZmlsZSk7CiAgICAKICAgIGYgPSBmb3BlbiAoKGNoYXIgKikgY2FjaGVfZmlsZSwgInIiKTsKICAgIGlmICghZikKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJICAgIHByaW50ZiAoIiBubyBjYWNoZSBmaWxlXG4iKTsKCWdvdG8gYmFpbDE7CiAgICB9CgogICAgaWYgKCFGY0RpckNhY2hlVmFsaWQgKGRpcikpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgY2FjaGUgZmlsZSBvbGRlciB0aGFuIGRpcmVjdG9yeVxuIik7Cglnb3RvIGJhaWwyOwogICAgfQogICAgCiAgICBiYXNlID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNoYXIgKikgY2FjaGVfZmlsZSwgJy8nKTsKICAgIGlmICghYmFzZSkKCWdvdG8gYmFpbDI7CiAgICBiYXNlKys7CiAgICBkaXJfbGVuID0gYmFzZSAtIGNhY2hlX2ZpbGU7CiAgICAKICAgIGZpbGUgPSAwOwogICAgbmFtZSA9IDA7CiAgICB3aGlsZSAoKGZpbGUgPSBGY0NhY2hlUmVhZFN0cmluZyAoZiwgZmlsZV9idWYsIHNpemVvZiAoZmlsZV9idWYpKSkgJiYKCSAgIEZjQ2FjaGVSZWFkSW50IChmLCAmaWQpICYmCgkgICAobmFtZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBuYW1lX2J1Ziwgc2l6ZW9mIChuYW1lX2J1ZikpKSkKICAgIHsKCWlmICghRmNDYWNoZUZvbnRTZXRBZGQgKHNldCwgZGlycywgY2FjaGVfZmlsZSwgZGlyX2xlbiwKCQkJCWZpbGUsIG5hbWUpKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoZmlsZSAhPSBmaWxlX2J1ZikKCSAgICBmcmVlIChmaWxlKTsKCWlmIChuYW1lICE9IG5hbWVfYnVmKQoJICAgIGZyZWUgKG5hbWUpOwoJZmlsZSA9IG5hbWUgPSAwOwogICAgfQogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCIgY2FjaGUgbG9hZGVkXG4iKTsKICAgIAogICAgcmV0ID0gRmNUcnVlOwpiYWlsMzoKICAgIGlmIChmaWxlICYmIGZpbGUgIT0gZmlsZV9idWYpCglmcmVlIChmaWxlKTsKICAgIGlmIChuYW1lICYmIG5hbWUgIT0gbmFtZV9idWYpCglmcmVlIChuYW1lKTsKYmFpbDI6CiAgICBmY2xvc2UgKGYpOwpiYWlsMToKICAgIGZyZWUgKGNhY2hlX2ZpbGUpOwpiYWlsMDoKICAgIHJldHVybiByZXQ7Cn0KCi8qCiAqIHJldHVybiB0aGUgcGF0aCBmcm9tIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyAnY2FjaGUnIHRvICdmaWxlJwogKi8KCnN0YXRpYyBjb25zdCBGY0NoYXI4ICoKRmNGaWxlQmFzZU5hbWUgKGNvbnN0IEZjQ2hhcjggKmNhY2hlLCBjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBjb25zdCBGY0NoYXI4ICAgKmNhY2hlX3NsYXNoOwoKICAgIGNhY2hlX3NsYXNoID0gKGNvbnN0IEZjQ2hhcjggKikgc3RycmNociAoKGNvbnN0IGNoYXIgKikgY2FjaGUsICcvJyk7CiAgICBpZiAoY2FjaGVfc2xhc2ggJiYgIXN0cm5jbXAgKChjb25zdCBjaGFyICopIGNhY2hlLCAoY29uc3QgY2hhciAqKSBmaWxlLAoJCQkJIChjYWNoZV9zbGFzaCArIDEpIC0gY2FjaGUpKQoJcmV0dXJuIGZpbGUgKyAoKGNhY2hlX3NsYXNoICsgMSkgLSBjYWNoZSk7CiAgICByZXR1cm4gZmlsZTsKfQoKRmNCb29sCkZjRGlyQ2FjaGVXcml0ZURpciAoRmNGb250U2V0ICpzZXQsIEZjU3RyU2V0ICpkaXJzLCBjb25zdCBGY0NoYXI4ICpkaXIpCnsKICAgIEZjQ2hhcjgJICAgICpjYWNoZV9maWxlID0gRmNTdHJQbHVzIChkaXIsIChGY0NoYXI4ICopICIvIiBGQ19ESVJfQ0FDSEVfRklMRSk7CiAgICBGY1BhdHRlcm4JICAgICpmb250OwogICAgRklMRQkgICAgKmY7CiAgICBGY0NoYXI4CSAgICAqbmFtZTsKICAgIGNvbnN0IEZjQ2hhcjggICAqZmlsZSwgKmJhc2U7CiAgICBpbnQJCSAgICBuOwogICAgaW50CQkgICAgaWQ7CiAgICBGY0Jvb2wJICAgIHJldDsKICAgIEZjU3RyTGlzdAkgICAgKmxpc3Q7CgogICAgaWYgKCFjYWNoZV9maWxlKQoJZ290byBiYWlsMDsKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJcHJpbnRmICgiRmNEaXJDYWNoZVdyaXRlRGlyIGNhY2hlX2ZpbGUgXCIlc1wiXG4iLCBjYWNoZV9maWxlKTsKICAgIAogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAidyIpOwogICAgaWYgKCFmKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIGNhbid0IGNyZWF0ZSBcIiVzXCJcbiIsIGNhY2hlX2ZpbGUpOwoJZ290byBiYWlsMTsKICAgIH0KICAgIAogICAgbGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoZGlycyk7CiAgICBpZiAoIWxpc3QpCglnb3RvIGJhaWwyOwogICAgCiAgICB3aGlsZSAoKGRpciA9IEZjU3RyTGlzdE5leHQgKGxpc3QpKSkKICAgIHsKCWJhc2UgPSBGY0ZpbGVCYXNlTmFtZSAoY2FjaGVfZmlsZSwgZGlyKTsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBiYXNlKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKHB1dGMgKCcgJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgMCkpCgkgICAgZ290byBiYWlsMzsKICAgICAgICBpZiAocHV0YyAoJyAnLCBmKSA9PSBFT0YpCgkgICAgZ290byBiYWlsMzsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBGQ19GT05UX0ZJTEVfRElSKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKHB1dGMgKCdcbicsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwogICAgfQogICAgCiAgICBmb3IgKG4gPSAwOyBuIDwgc2V0LT5uZm9udDsgbisrKQogICAgewoJZm9udCA9IHNldC0+Zm9udHNbbl07CglpZiAoRmNQYXR0ZXJuR2V0U3RyaW5nIChmb250LCBGQ19GSUxFLCAwLCAoRmNDaGFyOCAqKikgJmZpbGUpICE9IEZjUmVzdWx0TWF0Y2gpCgkgICAgZ290byBiYWlsMzsKCWJhc2UgPSBGY0ZpbGVCYXNlTmFtZSAoY2FjaGVfZmlsZSwgZmlsZSk7CglpZiAoRmNQYXR0ZXJuR2V0SW50ZWdlciAoZm9udCwgRkNfSU5ERVgsIDAsICZpZCkgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIiB3cml0ZSBmaWxlIFwiJXNcIlxuIiwgYmFzZSk7CglpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgYmFzZSkpCgkgICAgZ290byBiYWlsMzsKCWlmIChwdXRjICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIGlkKSkKCSAgICBnb3RvIGJhaWwzOwogICAgICAgIGlmIChwdXRjICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJbmFtZSA9IEZjTmFtZVVucGFyc2UgKGZvbnQpOwoJaWYgKCFuYW1lKQoJICAgIGdvdG8gYmFpbDM7CglyZXQgPSBGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIG5hbWUpOwoJZnJlZSAobmFtZSk7CglpZiAoIXJldCkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKHB1dGMgKCdcbicsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwogICAgfQogICAgCiAgICBGY1N0ckxpc3REb25lIChsaXN0KTsKCiAgICBpZiAoZmNsb3NlIChmKSA9PSBFT0YpCglnb3RvIGJhaWwxOwogICAgCiAgICBmcmVlIChjYWNoZV9maWxlKTsKCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIiBjYWNoZSB3cml0dGVuXG4iKTsKICAgIHJldHVybiBGY1RydWU7CiAgICAKYmFpbDM6CiAgICBGY1N0ckxpc3REb25lIChsaXN0KTsKYmFpbDI6CiAgICBmY2xvc2UgKGYpOwpiYWlsMToKICAgIHVubGluayAoKGNoYXIgKikgY2FjaGVfZmlsZSk7CiAgICBmcmVlIChjYWNoZV9maWxlKTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQo=