LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNjYWNoZS5jLHYgMS4xMiAyMDAyLzA4LzIyIDA3OjM2OjQ0IGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJmY2ludC5oIgoKLyoKICogUE9TSVggaGFzIGJyb2tlbiBzdGRpbyBzbyB0aGF0IGdldGMgbXVzdCBkbyB0aHJlYWQtc2FmZSBsb2NraW5nLAogKiB0aGlzIGlzIGEgc2VyaW91cyBwZXJmb3JtYW5jZSBwcm9ibGVtIGZvciBhcHBsaWNhdGlvbnMgZG9pbmcgbGFyZ2UKICogYW1vdW50cyBvZiBJTyB3aXRoIGdldGMgKGFzIGlzIGRvbmUgaGVyZSkuICBJZiBhdmFpbGFibGUsIHVzZQogKiB0aGUgZ2V0Y191bmxvY2tlZCB2YXJpZW50IGluc3RlYWQuCiAqLwogCiNpZiBkZWZpbmVkKGdldGNfdW5sb2NrZWQpIHx8IGRlZmluZWQoX0lPX2dldGNfdW5sb2NrZWQpCiNkZWZpbmUgR0VUQyhmKSBnZXRjX3VubG9ja2VkKGYpCiNkZWZpbmUgUFVUQyhjLGYpIHB1dGNfdW5sb2NrZWQoYyxmKQojZWxzZQojZGVmaW5lIEdFVEMoZikgZ2V0YyhmKQojZGVmaW5lIFBVVEMoYyxmKSBwdXRjKGMsZikKI2VuZGlmCgojZGVmaW5lIEZDX0RCR19DQUNIRV9SRUYgICAgMTAyNAoKc3RhdGljIEZjQ2hhcjggKgpGY0NhY2hlUmVhZFN0cmluZyAoRklMRSAqZiwgRmNDaGFyOCAqZGVzdCwgaW50IGxlbikKewogICAgaW50CQljOwogICAgRmNCb29sCWVzY2FwZTsKICAgIEZjQ2hhcjgJKmQ7CiAgICBpbnQJCXNpemU7CiAgICBpbnQJCWk7CgogICAgd2hpbGUgKChjID0gR0VUQyAoZikpICE9IEVPRikKCWlmIChjID09ICciJykKCSAgICBicmVhazsKICAgIGlmIChjID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGxlbiA9PSAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICAKICAgIHNpemUgPSBsZW47CiAgICBpID0gMDsKICAgIGQgPSBkZXN0OwogICAgZXNjYXBlID0gRmNGYWxzZTsKICAgIHdoaWxlICgoYyA9IEdFVEMgKGYpKSAhPSBFT0YpCiAgICB7CglpZiAoIWVzY2FwZSkKCXsKCSAgICBzd2l0Y2ggKGMpIHsKCSAgICBjYXNlICciJzoKCQljID0gJ1wwJzsKCQlicmVhazsKCSAgICBjYXNlICdcXCc6CgkJZXNjYXBlID0gRmNUcnVlOwoJCWNvbnRpbnVlOwoJICAgIH0KCX0KCWlmIChpID09IHNpemUpCgl7CgkgICAgRmNDaGFyOCAqbmV3ID0gbWFsbG9jIChzaXplICogMik7CS8qIGZyZWVkIGluIGNhbGxlciAqLwoJICAgIGlmICghbmV3KQoJCWJyZWFrOwoJICAgIG1lbWNweSAobmV3LCBkLCBzaXplKTsKCSAgICBzaXplICo9IDI7CgkgICAgaWYgKGQgIT0gZGVzdCkKCQlmcmVlIChkKTsKCSAgICBkID0gbmV3OwoJfQoJZFtpKytdID0gYzsKCWlmIChjID09ICdcMCcpCgkgICAgcmV0dXJuIGQ7Cgllc2NhcGUgPSBGY0ZhbHNlOwogICAgfQogICAgaWYgKGQgIT0gZGVzdCkKCWZyZWUgKGQpOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDYWNoZVJlYWRVbG9uZyAoRklMRSAqZiwgdW5zaWduZWQgbG9uZyAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBpbnQJCSAgICBjOwoKICAgIHdoaWxlICgoYyA9IEdFVEMgKGYpKSAhPSBFT0YpCiAgICB7CglpZiAoIWlzc3BhY2UgKGMpKQoJICAgIGJyZWFrOwogICAgfQogICAgaWYgKGMgPT0gRU9GKQoJcmV0dXJuIEZjRmFsc2U7CiAgICB0ID0gMDsKICAgIGZvciAoOzspCiAgICB7CglpZiAoYyA9PSBFT0YgfHwgaXNzcGFjZSAoYykpCgkgICAgYnJlYWs7CglpZiAoIWlzZGlnaXQgKGMpKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJdCA9IHQgKiAxMCArIChjIC0gJzAnKTsKCWMgPSBHRVRDIChmKTsKICAgIH0KICAgICpkZXN0ID0gdDsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDYWNoZVJlYWRJbnQgKEZJTEUgKmYsIGludCAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBGY0Jvb2wJICAgIHJldDsKCiAgICByZXQgPSBGY0NhY2hlUmVhZFVsb25nIChmLCAmdCk7CiAgICBpZiAocmV0KQoJKmRlc3QgPSAoaW50KSB0OwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlUmVhZFRpbWUgKEZJTEUgKmYsIHRpbWVfdCAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBGY0Jvb2wJICAgIHJldDsKCiAgICByZXQgPSBGY0NhY2hlUmVhZFVsb25nIChmLCAmdCk7CiAgICBpZiAocmV0KQoJKmRlc3QgPSAodGltZV90KSB0OwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVDaGFycyAoRklMRSAqZiwgY29uc3QgRmNDaGFyOCAqY2hhcnMpCnsKICAgIEZjQ2hhcjggICAgYzsKICAgIHdoaWxlICgoYyA9ICpjaGFycysrKSkKICAgIHsKCXN3aXRjaCAoYykgewoJY2FzZSAnIic6CgljYXNlICdcXCc6CgkgICAgaWYgKFBVVEMgKCdcXCcsIGYpID09IEVPRikKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICAvKiBmYWxsIHRocm91Z2ggKi8KCWRlZmF1bHQ6CgkgICAgaWYgKFBVVEMgKGMsIGYpID09IEVPRikKCQlyZXR1cm4gRmNGYWxzZTsKCX0KICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDYWNoZVdyaXRlU3RyaW5nIChGSUxFICpmLCBjb25zdCBGY0NoYXI4ICpzdHJpbmcpCnsKCiAgICBpZiAoUFVUQyAoJyInLCBmKSA9PSBFT0YpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmICghRmNDYWNoZVdyaXRlQ2hhcnMgKGYsIHN0cmluZykpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVQYXRoIChGSUxFICpmLCBjb25zdCBGY0NoYXI4ICpkaXIsIGNvbnN0IEZjQ2hhcjggKmZpbGUpCnsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGRpcikKCWlmICghRmNDYWNoZVdyaXRlQ2hhcnMgKGYsIGRpcikpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiNpZmRlZiBfV0lOMzIKICAgIGlmIChkaXIgJiYKCWRpcltzdHJsZW4oKGNvbnN0IGNoYXIgKikgZGlyKSAtIDFdICE9ICcvJyAmJgoJZGlyW3N0cmxlbigoY29uc3QgY2hhciAqKSBkaXIpIC0gMV0gIT0gJ1xcJykKICAgIHsKCWlmICghRmNDYWNoZVdyaXRlQ2hhcnMgKGYsICJcXCIpKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQojZWxzZQogICAgaWYgKGRpciAmJiBkaXJbc3RybGVuKChjb25zdCBjaGFyICopIGRpcikgLSAxXSAhPSAnLycpCglpZiAoUFVUQyAoJy8nLCBmKSA9PSBFT0YpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiNlbmRpZgogICAgaWYgKCFGY0NhY2hlV3JpdGVDaGFycyAoZiwgZmlsZSkpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVVbG9uZyAoRklMRSAqZiwgdW5zaWduZWQgbG9uZyB0KQp7CiAgICBpbnQJICAgIHBvdzsKICAgIHVuc2lnbmVkIGxvbmcgICB0ZW1wLCBkaWdpdDsKCiAgICB0ZW1wID0gdDsKICAgIHBvdyA9IDE7CiAgICB3aGlsZSAodGVtcCA+PSAxMCkKICAgIHsKCXRlbXAgLz0gMTA7Cglwb3cgKj0gMTA7CiAgICB9CiAgICB0ZW1wID0gdDsKICAgIHdoaWxlIChwb3cpCiAgICB7CglkaWdpdCA9IHRlbXAgLyBwb3c7CglpZiAoUFVUQyAoKGNoYXIpIGRpZ2l0ICsgJzAnLCBmKSA9PSBFT0YpCgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl0ZW1wID0gdGVtcCAtIHBvdyAqIGRpZ2l0OwoJcG93ID0gcG93IC8gMTA7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZUludCAoRklMRSAqZiwgaW50IGkpCnsKICAgIHJldHVybiBGY0NhY2hlV3JpdGVVbG9uZyAoZiwgKHVuc2lnbmVkIGxvbmcpIGkpOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZVRpbWUgKEZJTEUgKmYsIHRpbWVfdCB0KQp7CiAgICByZXR1cm4gRmNDYWNoZVdyaXRlVWxvbmcgKGYsICh1bnNpZ25lZCBsb25nKSB0KTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlRm9udFNldEFkZCAoRmNGb250U2V0CSAgICAqc2V0LAoJCSAgIEZjU3RyU2V0CSAgICAqZGlycywKCQkgICBjb25zdCBGY0NoYXI4ICAgICpkaXIsCgkJICAgaW50CQkgICAgZGlyX2xlbiwKCQkgICBjb25zdCBGY0NoYXI4ICAgICpmaWxlLAoJCSAgIGNvbnN0IEZjQ2hhcjggICAgKm5hbWUsCgkJICAgRmNDb25maWcJICAgICpjb25maWcpCnsKICAgIEZjQ2hhcjgJcGF0aF9idWZbODE5Ml0sICpwYXRoOwogICAgaW50CQlsZW47CiAgICBGY0Jvb2wJcmV0ID0gRmNGYWxzZTsKICAgIEZjUGF0dGVybgkqZm9udDsKICAgIEZjUGF0dGVybgkqZnJvemVuOwoKICAgIHBhdGggPSBwYXRoX2J1ZjsKICAgIGxlbiA9IChkaXJfbGVuICsgMSArIHN0cmxlbiAoKGNvbnN0IGNoYXIgKikgZmlsZSkgKyAxKTsKICAgIGlmIChsZW4gPiBzaXplb2YgKHBhdGhfYnVmKSkKICAgIHsKCXBhdGggPSBtYWxsb2MgKGxlbik7CS8qIGZyZWVkIGRvd24gYmVsb3cgKi8KCWlmICghcGF0aCkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHN0cm5jcHkgKChjaGFyICopIHBhdGgsIChjb25zdCBjaGFyICopIGRpciwgZGlyX2xlbik7CiNpZmRlZiBfV0lOMzIKICAgIGlmIChkaXJbZGlyX2xlbiAtIDFdICE9ICcvJyAmJiBkaXJbZGlyX2xlbiAtIDFdICE9ICdcXCcgKQoJcGF0aFtkaXJfbGVuKytdID0gJ1xcJzsKI2Vsc2UKICAgIGlmIChkaXJbZGlyX2xlbiAtIDFdICE9ICcvJykKCXBhdGhbZGlyX2xlbisrXSA9ICcvJzsKI2VuZGlmCiAgICBzdHJjcHkgKChjaGFyICopIHBhdGggKyBkaXJfbGVuLCAoY29uc3QgY2hhciAqKSBmaWxlKTsKICAgIGlmIChjb25maWcgJiYgIUZjQ29uZmlnQWNjZXB0RmlsZW5hbWUgKGNvbmZpZywgcGF0aCkpCglyZXQgPSBGY1RydWU7CiAgICBlbHNlIGlmICghRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9ESVIpKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIiBkaXIgY2FjaGUgZGlyIFwiJXNcIlxuIiwgcGF0aCk7CglyZXQgPSBGY1N0clNldEFkZCAoZGlycywgcGF0aCk7CiAgICB9CiAgICBlbHNlIGlmICghRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9JTlZBTElEKSkKICAgIHsKCXJldCA9IEZjVHJ1ZTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWZvbnQgPSBGY05hbWVQYXJzZSAobmFtZSk7CglpZiAoZm9udCkKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRVYpCgkJcHJpbnRmICgiIGRpciBjYWNoZSBmaWxlIFwiJXNcIlxuIiwgZmlsZSk7CgkgICAgcmV0ID0gRmNQYXR0ZXJuQWRkU3RyaW5nIChmb250LCBGQ19GSUxFLCBwYXRoKTsKCSAgICBpZiAocmV0ICYmICghY29uZmlnIHx8IEZjQ29uZmlnQWNjZXB0Rm9udCAoY29uZmlnLCBmb250KSkpCgkgICAgewoJCWZyb3plbiA9IEZjUGF0dGVybkZyZWV6ZSAoZm9udCk7CgkJcmV0ID0gKGZyb3plbiAhPSAwKTsKCQlpZiAocmV0KQoJCSAgIHJldCA9IEZjRm9udFNldEFkZCAoc2V0LCBmcm96ZW4pOwoJICAgIH0KCSAgICBGY1BhdHRlcm5EZXN0cm95IChmb250KTsKCX0KICAgIH0KICAgIGlmIChwYXRoICE9IHBhdGhfYnVmKSBmcmVlIChwYXRoKTsKICAgIHJldHVybiByZXQ7CiAgICAKfQoKc3RhdGljIHVuc2lnbmVkIGludApGY0NhY2hlSGFzaCAoY29uc3QgRmNDaGFyOCAqc3RyaW5nLCBpbnQgbGVuKQp7CiAgICB1bnNpZ25lZCBpbnQgICAgaCA9IDA7CiAgICBGY0NoYXI4CSAgICBjOwoKICAgIHdoaWxlIChsZW4tLSAmJiAoYyA9ICpzdHJpbmcrKykpCgloID0gKGggPDwgMSkgXiBjOwogICAgcmV0dXJuIGg7Cn0KCi8qCiAqIFZlcmlmeSB0aGUgc2F2ZWQgdGltZXN0YW1wIGZvciBhIGZpbGUKICovCkZjQm9vbApGY0dsb2JhbENhY2hlQ2hlY2tUaW1lIChjb25zdCBGY0NoYXI4ICpmaWxlLCBGY0dsb2JhbENhY2hlSW5mbyAqaW5mbykKewogICAgc3RydWN0IHN0YXQJICAgIHN0YXRiOwoKICAgIGlmIChzdGF0ICgoY2hhciAqKSBmaWxlLCAmc3RhdGIpIDwgMCkKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJICAgIHByaW50ZiAoIiBmaWxlICVzIG1pc3NpbmdcbiIsIGZpbGUpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoc3RhdGIuc3RfbXRpbWUgIT0gaW5mby0+dGltZSkKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJICAgIHByaW50ZiAoIiB0aW1lc3RhbXAgbWlzbWF0Y2ggKHdhcyAlZCBpcyAlZClcbiIsCgkJICAgIChpbnQpIGluZm8tPnRpbWUsIChpbnQpIHN0YXRiLnN0X210aW1lKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKdm9pZApGY0dsb2JhbENhY2hlUmVmZXJlbmNlZCAoRmNHbG9iYWxDYWNoZQkgICAgKmNhY2hlLAoJCQkgRmNHbG9iYWxDYWNoZUluZm8gICppbmZvKQp7CiAgICBpZiAoIWluZm8tPnJlZmVyZW5jZWQpCiAgICB7CglpbmZvLT5yZWZlcmVuY2VkID0gRmNUcnVlOwoJY2FjaGUtPnJlZmVyZW5jZWQrKzsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFX1JFRikKCSAgICBwcmludGYgKCJSZWZlcmVuY2UgJWQgJXNcbiIsIGNhY2hlLT5yZWZlcmVuY2VkLCBpbmZvLT5maWxlKTsKICAgIH0KfQoKLyoKICogQnJlYWsgYSBwYXRoIGludG8gZGlyL2Jhc2UgZWxlbWVudHMgYW5kIGNvbXB1dGUgdGhlIGJhc2UgaGFzaAogKiBhbmQgdGhlIGRpciBsZW5ndGguICBUaGlzIGlzIHNoYXJlZCBiZXR3ZWVuIHRoZSBmdW5jdGlvbnMKICogd2hpY2ggd2FsayB0aGUgZmlsZSBjYWNoZXMKICovCgp0eXBlZGVmIHN0cnVjdCBfRmNGaWxlUGF0aEluZm8gewogICAgY29uc3QgRmNDaGFyOCAgICpkaXI7CiAgICBpbnQJCSAgICBkaXJfbGVuOwogICAgY29uc3QgRmNDaGFyOCAgICpiYXNlOwogICAgdW5zaWduZWQgaW50ICAgIGJhc2VfaGFzaDsKfSBGY0ZpbGVQYXRoSW5mbzsKCnN0YXRpYyBGY0ZpbGVQYXRoSW5mbwpGY0ZpbGVQYXRoSW5mb0dldCAoY29uc3QgRmNDaGFyOCAgICAqcGF0aCkKewogICAgRmNGaWxlUGF0aEluZm8gIGk7CiAgICBGY0NoYXI4CSAgICAqc2xhc2g7CgogICAgc2xhc2ggPSBGY1N0ckxhc3RTbGFzaCAocGF0aCk7CiAgICBpZiAoc2xhc2gpCiAgICB7CiAgICAgICAgaS5kaXIgPSBwYXRoOwogICAgICAgIGkuZGlyX2xlbiA9IHNsYXNoIC0gcGF0aDsKCWlmICghaS5kaXJfbGVuKQoJICAgIGkuZGlyX2xlbiA9IDE7CglpLmJhc2UgPSBzbGFzaCArIDE7CiAgICB9CiAgICBlbHNlCiAgICB7CglpLmRpciA9IChjb25zdCBGY0NoYXI4ICopICIuIjsKCWkuZGlyX2xlbiA9IDE7CglpLmJhc2UgPSBwYXRoOwogICAgfQogICAgaS5iYXNlX2hhc2ggPSBGY0NhY2hlSGFzaCAoaS5iYXNlLCAtMSk7CiAgICByZXR1cm4gaTsKfQoKRmNHbG9iYWxDYWNoZURpciAqCkZjR2xvYmFsQ2FjaGVEaXJHZXQgKEZjR2xvYmFsQ2FjaGUgICpjYWNoZSwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpkaXIsCgkJICAgICBpbnQJICAgIGxlbiwKCQkgICAgIEZjQm9vbAkgICAgY3JlYXRlX21pc3NpbmcpCnsKICAgIHVuc2lnbmVkIGludAloYXNoID0gRmNDYWNoZUhhc2ggKGRpciwgbGVuKTsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQsICoqcHJldjsKCiAgICBmb3IgKHByZXYgPSAmY2FjaGUtPmVudHNbaGFzaCAlIEZDX0dMT0JBTF9DQUNIRV9ESVJfSEFTSF9TSVpFXTsKCSAoZCA9ICpwcmV2KTsKCSBwcmV2ID0gJigqcHJldiktPm5leHQpCiAgICB7CglpZiAoZC0+aW5mby5oYXNoID09IGhhc2ggJiYgZC0+bGVuID09IGxlbiAmJgoJICAgICFzdHJuY21wICgoY29uc3QgY2hhciAqKSBkLT5pbmZvLmZpbGUsCgkJICAgICAgKGNvbnN0IGNoYXIgKikgZGlyLCBsZW4pKQoJICAgIGJyZWFrOwogICAgfQogICAgaWYgKCEoZCA9ICpwcmV2KSkKICAgIHsKCWludAlpOwoJaWYgKCFjcmVhdGVfbWlzc2luZykKCSAgICByZXR1cm4gMDsKCWQgPSBtYWxsb2MgKHNpemVvZiAoRmNHbG9iYWxDYWNoZURpcikgKyBsZW4gKyAxKTsKCWlmICghZCkKCSAgICByZXR1cm4gMDsKCUZjTWVtQWxsb2MgKEZDX01FTV9DQUNIRSwgc2l6ZW9mIChGY0dsb2JhbENhY2hlRGlyKSArIGxlbiArIDEpOwoJZC0+bmV4dCA9ICpwcmV2OwoJKnByZXYgPSBkOwoJZC0+aW5mby5oYXNoID0gaGFzaDsKCWQtPmluZm8uZmlsZSA9IChGY0NoYXI4ICopIChkICsgMSk7CglzdHJuY3B5ICgoY2hhciAqKSBkLT5pbmZvLmZpbGUsIChjb25zdCBjaGFyICopIGRpciwgbGVuKTsKCWQtPmluZm8uZmlsZVtsZW5dID0gJ1wwJzsKCWQtPmluZm8udGltZSA9IDA7CglkLT5pbmZvLnJlZmVyZW5jZWQgPSBGY0ZhbHNlOwoJZC0+bGVuID0gbGVuOwoJZm9yIChpID0gMDsgaSA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgaSsrKQoJICAgIGQtPmVudHNbaV0gPSAwOwoJZC0+c3ViZGlycyA9IDA7CiAgICB9CiAgICByZXR1cm4gZDsKfQoKc3RhdGljIEZjR2xvYmFsQ2FjaGVJbmZvICoKRmNHbG9iYWxDYWNoZURpckFkZCAoRmNHbG9iYWxDYWNoZSAgKmNhY2hlLAoJCSAgICAgY29uc3QgRmNDaGFyOCAgKmRpciwKCQkgICAgIHRpbWVfdAkgICAgdGltZSwKCQkgICAgIEZjQm9vbAkgICAgcmVwbGFjZSwKCQkgICAgIEZjQm9vbAkgICAgY3JlYXRlX21pc3NpbmcpCnsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQ7CiAgICBGY0ZpbGVQYXRoSW5mbwlpOwogICAgRmNHbG9iYWxDYWNoZVN1YmRpcgkqc3ViZGlyOwogICAgRmNHbG9iYWxDYWNoZURpcgkqcGFyZW50OwoKICAgIGkgPSBGY0ZpbGVQYXRoSW5mb0dldCAoZGlyKTsKICAgIHBhcmVudCA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBpLmRpciwgaS5kaXJfbGVuLCBjcmVhdGVfbWlzc2luZyk7CiAgICAvKgogICAgICogVHJpY2t5IGhlcmUgLS0gZGlyZWN0b3JpZXMgY29udGFpbmluZyBmb250cy5jYWNoZS0xIGZpbGVzCiAgICAgKiBuZWVkIGVudHJpZXMgb25seSB3aGVuIHRoZSBwYXJlbnQgZG9lc24ndCBoYXZlIGEgY2FjaGUgZmlsZS4KICAgICAqIFRoYXQgaXMsIHdoZW4gdGhlIHBhcmVudCBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgY2FjaGUsIGlzCiAgICAgKiByZWZlcmVuY2VkIGFuZCBoYXMgYSAicmVhbCIgdGltZXN0YW1wLiAgVGhlIHRpbWUgb2YgMCBpcwogICAgICogc3BlY2lhbCBhbmQgbWFya3MgZGlyZWN0b3JpZXMgd2hpY2ggZ290IHN0dWNrIGluIHRoZQogICAgICogZ2xvYmFsIGNhY2hlIGZvciB0aGlzIHZlcnkgcmVhc29uLiAgWWVzLCBpdCBjb3VsZAogICAgICogdXNlIGEgc2VwYXJhdGUgYm9vbGVhbiBmaWVsZCwgYW5kIHByb2JhYmx5IHNob3VsZC4KICAgICAqLwogICAgaWYgKCFwYXJlbnQgfHwgKCFjcmVhdGVfbWlzc2luZyAmJiAKCQkgICAgKCFwYXJlbnQtPmluZm8ucmVmZXJlbmNlZCB8fAoJCSAgICAocGFyZW50LT5pbmZvLnRpbWUgPT0gMCkpKSkKCXJldHVybiAwOwogICAgLyoKICAgICAqIEFkZCB0aGlzIGRpcmVjdG9yeSB0byB0aGUgY2FjaGUKICAgICAqLwogICAgZCA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBkaXIsIHN0cmxlbiAoKGNvbnN0IGNoYXIgKikgZGlyKSwgRmNUcnVlKTsKICAgIGlmICghZCkKCXJldHVybiAwOwogICAgZC0+aW5mby50aW1lID0gdGltZTsKICAgIC8qCiAgICAgKiBBZGQgdGhpcyBkaXJlY3RvcnkgdG8gdGhlIHN1YmRpcmVjdG9yeSBsaXN0IG9mIHRoZSBwYXJlbnQKICAgICAqLwogICAgc3ViZGlyID0gbWFsbG9jIChzaXplb2YgKEZjR2xvYmFsQ2FjaGVTdWJkaXIpKTsKICAgIGlmICghc3ViZGlyKQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZVN1YmRpcikpOwogICAgc3ViZGlyLT5lbnQgPSBkOwogICAgc3ViZGlyLT5uZXh0ID0gcGFyZW50LT5zdWJkaXJzOwogICAgcGFyZW50LT5zdWJkaXJzID0gc3ViZGlyOwogICAgcmV0dXJuICZkLT5pbmZvOwp9CgpzdGF0aWMgdm9pZApGY0dsb2JhbENhY2hlRGlyRGVzdHJveSAoRmNHbG9iYWxDYWNoZURpciAqZCkKewogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmYsICpuZXh0OwogICAgaW50CQkJaDsKICAgIEZjR2xvYmFsQ2FjaGVTdWJkaXIJKnMsICpuZXh0czsKCiAgICBmb3IgKGggPSAwOyBoIDwgRkNfR0xPQkFMX0NBQ0hFX0ZJTEVfSEFTSF9TSVpFOyBoKyspCglmb3IgKGYgPSBkLT5lbnRzW2hdOyBmOyBmID0gbmV4dCkKCXsKCSAgICBuZXh0ID0gZi0+bmV4dDsKCSAgICBGY01lbUZyZWUgKEZDX01FTV9DQUNIRSwgc2l6ZW9mIChGY0dsb2JhbENhY2hlRmlsZSkgKwoJCSAgICAgICBzdHJsZW4gKChjaGFyICopIGYtPmluZm8uZmlsZSkgKyAxICsKCQkgICAgICAgc3RybGVuICgoY2hhciAqKSBmLT5uYW1lKSArIDEpOwoJICAgIGZyZWUgKGYpOwoJfQogICAgZm9yIChzID0gZC0+c3ViZGlyczsgczsgcyA9IG5leHRzKQogICAgewoJbmV4dHMgPSBzLT5uZXh0OwoJRmNNZW1GcmVlIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZVN1YmRpcikpOwoJZnJlZSAocyk7CiAgICB9CiAgICBGY01lbUZyZWUgKEZDX01FTV9DQUNIRSwgc2l6ZW9mIChGY0dsb2JhbENhY2hlRGlyKSArIGQtPmxlbiArIDEpOwogICAgZnJlZSAoZCk7Cn0KCi8qCiAqIElmIHRoZSBwYXJlbnQgaXMgaW4gdGhlIGdsb2JhbCBjYWNoZSBhbmQgcmVmZXJlbmNlZCwgYWRkCiAqIGFuIGVudHJ5IGZvciAnZGlyJyB0byB0aGUgZ2xvYmFsIGNhY2hlLiAgVGhpcyBpcyB1c2VkCiAqIGZvciBkaXJlY3RvcmllcyB3aXRoIGZvbnRzLmNhY2hlIGZpbGVzCiAqLwoKdm9pZApGY0dsb2JhbENhY2hlUmVmZXJlbmNlU3ViZGlyIChGY0dsb2JhbENhY2hlICpjYWNoZSwKCQkJICAgICAgY29uc3QgRmNDaGFyOCAqZGlyKQp7CiAgICBGY0dsb2JhbENhY2hlSW5mbwkqaW5mbzsKICAgIGluZm8gPSBGY0dsb2JhbENhY2hlRGlyQWRkIChjYWNoZSwgZGlyLCAwLCBGY0ZhbHNlLCBGY0ZhbHNlKTsKICAgIGlmIChpbmZvICYmICFpbmZvLT5yZWZlcmVuY2VkKQogICAgewoJaW5mby0+cmVmZXJlbmNlZCA9IEZjVHJ1ZTsKCWNhY2hlLT5yZWZlcmVuY2VkKys7CiAgICB9Cn0KCi8qCiAqIENoZWNrIHRvIHNlZSBpZiB0aGUgZ2xvYmFsIGNhY2hlIGNvbnRhaW5zIHZhbGlkIGRhdGEgZm9yICdkaXInLgogKiBJZiBzbywgc2NhbiB0aGUgZ2xvYmFsIGNhY2hlIGZvciBmaWxlcyBhbmQgZGlyZWN0b3JpZXMgaW4gJ2RpcicuCiAqIGVsc2UsIHJldHVybiBGYWxzZS4KICovCkZjQm9vbApGY0dsb2JhbENhY2hlU2NhbkRpciAoRmNGb250U2V0CQkqc2V0LAoJCSAgICAgIEZjU3RyU2V0CQkqZGlycywKCQkgICAgICBGY0dsb2JhbENhY2hlCSpjYWNoZSwKCQkgICAgICBjb25zdCBGY0NoYXI4CSpkaXIsCgkJICAgICAgRmNDb25maWcJCSpjb25maWcpCnsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQgPSBGY0dsb2JhbENhY2hlRGlyR2V0IChjYWNoZSwgZGlyLAoJCQkJCQkgIHN0cmxlbiAoKGNvbnN0IGNoYXIgKikgZGlyKSwKCQkJCQkJICBGY0ZhbHNlKTsKICAgIEZjR2xvYmFsQ2FjaGVGaWxlCSpmOwogICAgaW50CQkJaDsKICAgIGludAkJCWRpcl9sZW47CiAgICBGY0dsb2JhbENhY2hlU3ViZGlyCSpzdWJkaXI7CiAgICBGY0Jvb2wJCWFueV9pbl9jYWNoZSA9IEZjRmFsc2U7CgogICAgaWYgKEZjRGVidWcoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIkZjR2xvYmFsQ2FjaGVTY2FuRGlyICVzXG4iLCBkaXIpOwogICAgCiAgICBpZiAoIWQpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCJcdE5vIGRpciBjYWNoZSBlbnRyeVxuIik7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KCiAgICAvKgogICAgICogU2VlIGlmIHRoZSB0aW1lc3RhbXAgcmVjb3JkZWQgaW4gdGhlIGdsb2JhbCBjYWNoZQogICAgICogbWF0Y2hlcyB0aGUgZGlyZWN0b3J5IHRpbWUsIGlmIG5vdCwgcmV0dXJuIEZhbHNlCiAgICAgKi8KICAgIGlmICghRmNHbG9iYWxDYWNoZUNoZWNrVGltZSAoZC0+aW5mby5maWxlLCAmZC0+aW5mbykpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCJcdGRpciBjYWNoZSBlbnRyeSB0aW1lIG1pc21hdGNoXG4iKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIC8qCiAgICAgKiBBZGQgZmlsZXMgZnJvbSAnZGlyJyB0byB0aGUgZm9udHNldAogICAgICovCiAgICBkaXJfbGVuID0gc3RybGVuICgoY29uc3QgY2hhciAqKSBkaXIpOwogICAgZm9yIChoID0gMDsgaCA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgaCsrKQoJZm9yIChmID0gZC0+ZW50c1toXTsgZjsgZiA9IGYtPm5leHQpCgl7CgkgICAgaWYgKEZjRGVidWcoKSAmIEZDX0RCR19DQUNIRVYpCgkJcHJpbnRmICgiRmNHbG9iYWxDYWNoZVNjYW5EaXIgYWRkIGZpbGUgJXNcbiIsIGYtPmluZm8uZmlsZSk7CgkgICAgYW55X2luX2NhY2hlID0gRmNUcnVlOwoJICAgIGlmICghRmNDYWNoZUZvbnRTZXRBZGQgKHNldCwgZGlycywgZGlyLCBkaXJfbGVuLAoJCQkJICAgIGYtPmluZm8uZmlsZSwgZi0+bmFtZSwgY29uZmlnKSkKCSAgICB7CgkJY2FjaGUtPmJyb2tlbiA9IEZjVHJ1ZTsKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICB9CgkgICAgRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKGNhY2hlLCAmZi0+aW5mbyk7Cgl9CiAgICAvKgogICAgICogQWRkIGRpcmVjdG9yaWVzIGluICdkaXInIHRvICdkaXJzJwogICAgICovCiAgICBmb3IgKHN1YmRpciA9IGQtPnN1YmRpcnM7IHN1YmRpcjsgc3ViZGlyID0gc3ViZGlyLT5uZXh0KQogICAgewoJRmNGaWxlUGF0aEluZm8JaW5mbyA9IEZjRmlsZVBhdGhJbmZvR2V0IChzdWJkaXItPmVudC0+aW5mby5maWxlKTsKCQogICAgICAgIGFueV9pbl9jYWNoZSA9IEZjVHJ1ZTsKCWlmICghRmNDYWNoZUZvbnRTZXRBZGQgKHNldCwgZGlycywgZGlyLCBkaXJfbGVuLAoJCQkJaW5mby5iYXNlLCBGQ19GT05UX0ZJTEVfRElSLCBjb25maWcpKQoJewoJICAgIGNhY2hlLT5icm9rZW4gPSBGY1RydWU7CgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl9CglGY0dsb2JhbENhY2hlUmVmZXJlbmNlZCAoY2FjaGUsICZzdWJkaXItPmVudC0+aW5mbyk7CiAgICB9CiAgICAKICAgIEZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgJmQtPmluZm8pOwoKICAgIC8qCiAgICAgKiBUbyByZWNvdmVyIGZyb20gYSBidWcgaW4gcHJldmlvdXMgdmVyc2lvbnMgb2YgZm9udGNvbmZpZywKICAgICAqIHJldHVybiBGY0ZhbHNlIGlmIG5vIGVudHJpZXMgaW4gdGhlIGNhY2hlIHdlcmUgZm91bmQKICAgICAqIGZvciB0aGlzIGRpcmVjdG9yeS4gIFRoaXMgd2lsbCBjYXVzZSBhbnkgZW1wdHkgZGlyZWN0b3JpZXMKICAgICAqIHRvIGdldCByZXNjYW5uZWQgZXZlcnkgdGltZSBmb250Y29uZmlnIGlzIGluaXRpYWxpemVkLiAgVGhpcwogICAgICogbWlnaHQgZ2V0IHJlbW92ZWQgYXQgc29tZSBwb2ludCB3aGVuIHRoZSBvbGRlciBjYWNoZSBmaWxlcyBhcmUKICAgICAqIHByZXN1bWFibHkgZml4ZWQuCiAgICAgKi8KICAgIHJldHVybiBhbnlfaW5fY2FjaGU7Cn0KCi8qCiAqIExvY2F0ZSB0aGUgY2FjaGUgZW50cnkgZm9yIGEgcGFydGljdWxhciBmaWxlCiAqLwpGY0dsb2JhbENhY2hlRmlsZSAqCkZjR2xvYmFsQ2FjaGVGaWxlR2V0IChGY0dsb2JhbENhY2hlICpjYWNoZSwKCQkgICAgICBjb25zdCBGY0NoYXI4ICpmaWxlLAoJCSAgICAgIGludAkgICAgaWQsCgkJICAgICAgaW50CSAgICAqY291bnQpCnsKICAgIEZjRmlsZVBhdGhJbmZvCWkgPSBGY0ZpbGVQYXRoSW5mb0dldCAoZmlsZSk7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkID0gRmNHbG9iYWxDYWNoZURpckdldCAoY2FjaGUsIGkuZGlyLCAKCQkJCQkJICBpLmRpcl9sZW4sIEZjRmFsc2UpOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmYsICptYXRjaCA9IDA7CiAgICBpbnQJCQltYXggPSAtMTsKCiAgICBpZiAoIWQpCglyZXR1cm4gMDsKICAgIGZvciAoZiA9IGQtPmVudHNbaS5iYXNlX2hhc2ggJSBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkVdOyBmOyBmID0gZi0+bmV4dCkKICAgIHsKCWlmIChmLT5pbmZvLmhhc2ggPT0gaS5iYXNlX2hhc2ggJiYKCSAgICAhc3RyY21wICgoY29uc3QgY2hhciAqKSBmLT5pbmZvLmZpbGUsIChjb25zdCBjaGFyICopIGkuYmFzZSkpCgl7CgkgICAgaWYgKGYtPmlkID09IGlkKQoJCW1hdGNoID0gZjsKCSAgICBpZiAoZi0+aWQgPiBtYXgpCgkJbWF4ID0gZi0+aWQ7Cgl9CiAgICB9CiAgICBpZiAoY291bnQpCgkqY291bnQgPSBtYXggKyAxOwogICAgcmV0dXJuIG1hdGNoOwp9CiAgICAKLyoKICogQWRkIGEgZmlsZSBlbnRyeSB0byB0aGUgY2FjaGUKICovCnN0YXRpYyBGY0dsb2JhbENhY2hlSW5mbyAqCkZjR2xvYmFsQ2FjaGVGaWxlQWRkIChGY0dsb2JhbENhY2hlICpjYWNoZSwKCQkgICAgICBjb25zdCBGY0NoYXI4ICpwYXRoLAoJCSAgICAgIGludAkgICAgaWQsCgkJICAgICAgdGltZV90CSAgICB0aW1lLAoJCSAgICAgIGNvbnN0IEZjQ2hhcjggKm5hbWUsCgkJICAgICAgRmNCb29sCSAgICByZXBsYWNlKQp7CiAgICBGY0ZpbGVQYXRoSW5mbwlpID0gRmNGaWxlUGF0aEluZm9HZXQgKHBhdGgpOwogICAgRmNHbG9iYWxDYWNoZURpcgkqZCA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBpLmRpciwgCgkJCQkJCSAgaS5kaXJfbGVuLCBGY1RydWUpOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmYsICoqcHJldjsKICAgIGludAkJCXNpemU7CgogICAgaWYgKCFkKQoJcmV0dXJuIDA7CiAgICBmb3IgKHByZXYgPSAmZC0+ZW50c1tpLmJhc2VfaGFzaCAlIEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRV07CgkgKGYgPSAqcHJldik7CgkgcHJldiA9ICYoKnByZXYpLT5uZXh0KQogICAgewoJaWYgKGYtPmluZm8uaGFzaCA9PSBpLmJhc2VfaGFzaCAmJiAKCSAgICBmLT5pZCA9PSBpZCAmJgoJICAgICFzdHJjbXAgKChjb25zdCBjaGFyICopIGYtPmluZm8uZmlsZSwgKGNvbnN0IGNoYXIgKikgaS5iYXNlKSkKCXsKCSAgICBicmVhazsKCX0KICAgIH0KICAgIGlmICgqcHJldikKICAgIHsKCWlmICghcmVwbGFjZSkKCSAgICByZXR1cm4gMDsKCglmID0gKnByZXY7CglpZiAoZi0+aW5mby5yZWZlcmVuY2VkKQoJICAgIGNhY2hlLT5yZWZlcmVuY2VkLS07CgkqcHJldiA9IGYtPm5leHQ7CglGY01lbUZyZWUgKEZDX01FTV9DQUNIRSwgc2l6ZW9mIChGY0dsb2JhbENhY2hlRmlsZSkgKwoJCSAgIHN0cmxlbiAoKGNoYXIgKikgZi0+aW5mby5maWxlKSArIDEgKwoJCSAgIHN0cmxlbiAoKGNoYXIgKikgZi0+bmFtZSkgKyAxKTsKCWZyZWUgKGYpOwogICAgfQogICAgc2l6ZSA9IChzaXplb2YgKEZjR2xvYmFsQ2FjaGVGaWxlKSArCgkgICAgc3RybGVuICgoY2hhciAqKSBpLmJhc2UpICsgMSArCgkgICAgc3RybGVuICgoY2hhciAqKSBuYW1lKSArIDEpOwogICAgZiA9IG1hbGxvYyAoc2l6ZSk7CiAgICBpZiAoIWYpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9DQUNIRSwgc2l6ZSk7CiAgICBmLT5uZXh0ID0gKnByZXY7CiAgICAqcHJldiA9IGY7CiAgICBmLT5pbmZvLmhhc2ggPSBpLmJhc2VfaGFzaDsKICAgIGYtPmluZm8uZmlsZSA9IChGY0NoYXI4ICopIChmICsgMSk7CiAgICBmLT5pbmZvLnRpbWUgPSB0aW1lOwogICAgZi0+aW5mby5yZWZlcmVuY2VkID0gRmNGYWxzZTsKICAgIGYtPmlkID0gaWQ7CiAgICBmLT5uYW1lID0gZi0+aW5mby5maWxlICsgc3RybGVuICgoY2hhciAqKSBpLmJhc2UpICsgMTsKICAgIHN0cmNweSAoKGNoYXIgKikgZi0+aW5mby5maWxlLCAoY29uc3QgY2hhciAqKSBpLmJhc2UpOwogICAgc3RyY3B5ICgoY2hhciAqKSBmLT5uYW1lLCAoY29uc3QgY2hhciAqKSBuYW1lKTsKICAgIHJldHVybiAmZi0+aW5mbzsKfQoKRmNHbG9iYWxDYWNoZSAqCkZjR2xvYmFsQ2FjaGVDcmVhdGUgKHZvaWQpCnsKICAgIEZjR2xvYmFsQ2FjaGUgICAqY2FjaGU7CiAgICBpbnQJCSAgICBoOwoKICAgIGNhY2hlID0gbWFsbG9jIChzaXplb2YgKEZjR2xvYmFsQ2FjaGUpKTsKICAgIGlmICghY2FjaGUpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9DQUNIRSwgc2l6ZW9mIChGY0dsb2JhbENhY2hlKSk7CiAgICBmb3IgKGggPSAwOyBoIDwgRkNfR0xPQkFMX0NBQ0hFX0RJUl9IQVNIX1NJWkU7IGgrKykKCWNhY2hlLT5lbnRzW2hdID0gMDsKICAgIGNhY2hlLT5lbnRyaWVzID0gMDsKICAgIGNhY2hlLT5yZWZlcmVuY2VkID0gMDsKICAgIGNhY2hlLT51cGRhdGVkID0gRmNGYWxzZTsKICAgIGNhY2hlLT5icm9rZW4gPSBGY0ZhbHNlOwogICAgcmV0dXJuIGNhY2hlOwp9Cgp2b2lkCkZjR2xvYmFsQ2FjaGVEZXN0cm95IChGY0dsb2JhbENhY2hlICpjYWNoZSkKewogICAgRmNHbG9iYWxDYWNoZURpcgkqZCwgKm5leHQ7CiAgICBpbnQJCQloOwoKICAgIGZvciAoaCA9IDA7IGggPCBGQ19HTE9CQUxfQ0FDSEVfRElSX0hBU0hfU0laRTsgaCsrKQogICAgewoJZm9yIChkID0gY2FjaGUtPmVudHNbaF07IGQ7IGQgPSBuZXh0KQoJewoJICAgIG5leHQgPSBkLT5uZXh0OwoJICAgIEZjR2xvYmFsQ2FjaGVEaXJEZXN0cm95IChkKTsKCX0KICAgIH0KICAgIEZjTWVtRnJlZSAoRkNfTUVNX0NBQ0hFLCBzaXplb2YgKEZjR2xvYmFsQ2FjaGUpKTsKICAgIGZyZWUgKGNhY2hlKTsKfQoKLyoKICogQ2FjaGUgZmlsZSBzeW50YXggaXMgcXVpdGUgc2ltcGxlOgogKgogKiAiZmlsZV9uYW1lIiBpZCB0aW1lICJmb250X25hbWUiIFxuCiAqLwogCnZvaWQKRmNHbG9iYWxDYWNoZUxvYWQgKEZjR2xvYmFsQ2FjaGUgICAgKmNhY2hlLAoJCSAgIGNvbnN0IEZjQ2hhcjggICAgKmNhY2hlX2ZpbGUpCnsKICAgIEZJTEUJCSpmOwogICAgRmNDaGFyOAkJZmlsZV9idWZbODE5Ml0sICpmaWxlOwogICAgaW50CQkJaWQ7CiAgICB0aW1lX3QJCXRpbWU7CiAgICBGY0NoYXI4CQluYW1lX2J1Zls4MTkyXSwgKm5hbWU7CiAgICBGY0dsb2JhbENhY2hlSW5mbwkqaW5mbzsKCiAgICBmID0gZm9wZW4gKChjaGFyICopIGNhY2hlX2ZpbGUsICJyIik7CiAgICBpZiAoIWYpCglyZXR1cm47CgogICAgY2FjaGUtPnVwZGF0ZWQgPSBGY0ZhbHNlOwogICAgZmlsZSA9IDA7CiAgICBuYW1lID0gMDsKICAgIHdoaWxlICgoZmlsZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBmaWxlX2J1Ziwgc2l6ZW9mIChmaWxlX2J1ZikpKSAmJgoJICAgRmNDYWNoZVJlYWRJbnQgKGYsICZpZCkgJiYKCSAgIEZjQ2FjaGVSZWFkVGltZSAoZiwgJnRpbWUpICYmCgkgICAobmFtZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBuYW1lX2J1Ziwgc2l6ZW9mIChuYW1lX2J1ZikpKSkKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFVikKCSAgICBwcmludGYgKCJGY0dsb2JhbENhY2hlTG9hZCBcIiVzXCIgXCIlMjAuMjBzXCJcbiIsIGZpbGUsIG5hbWUpOwoJaWYgKCFGY1N0ckNtcCAobmFtZSwgRkNfRk9OVF9GSUxFX0RJUikpCgkgICAgaW5mbyA9IEZjR2xvYmFsQ2FjaGVEaXJBZGQgKGNhY2hlLCBmaWxlLCB0aW1lLCBGY0ZhbHNlLCBGY1RydWUpOwoJZWxzZQoJICAgIGluZm8gPSBGY0dsb2JhbENhY2hlRmlsZUFkZCAoY2FjaGUsIGZpbGUsIGlkLCB0aW1lLCBuYW1lLCBGY0ZhbHNlKTsKCWlmICghaW5mbykKCSAgICBjYWNoZS0+YnJva2VuID0gRmNUcnVlOwoJZWxzZQoJICAgIGNhY2hlLT5lbnRyaWVzKys7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRV9SRUYpCgkgICAgcHJpbnRmICgiRmNHbG9iYWxDYWNoZUxvYWQgZW50cnkgJWQgJXNcbiIsCgkJICAgIGNhY2hlLT5lbnRyaWVzLCBmaWxlKTsKCWlmIChmaWxlICE9IGZpbGVfYnVmKQoJICAgIGZyZWUgKGZpbGUpOwoJaWYgKG5hbWUgIT0gbmFtZV9idWYpCgkgICAgZnJlZSAobmFtZSk7CglmaWxlID0gMDsKCW5hbWUgPSAwOwogICAgfQogICAgaWYgKGZpbGUgJiYgZmlsZSAhPSBmaWxlX2J1ZikKCWZyZWUgKGZpbGUpOwogICAgaWYgKG5hbWUgJiYgbmFtZSAhPSBuYW1lX2J1ZikKCWZyZWUgKG5hbWUpOwogICAgZmNsb3NlIChmKTsKfQoKRmNCb29sCkZjR2xvYmFsQ2FjaGVVcGRhdGUgKEZjR2xvYmFsQ2FjaGUgICpjYWNoZSwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpmaWxlLAoJCSAgICAgaW50CSAgICBpZCwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpuYW1lKQp7CiAgICBjb25zdCBGY0NoYXI4CSptYXRjaDsKICAgIHN0cnVjdCBzdGF0CQlzdGF0YjsKICAgIEZjR2xvYmFsQ2FjaGVJbmZvCSppbmZvOwoKICAgIG1hdGNoID0gZmlsZTsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgZmlsZSwgJnN0YXRiKSA8IDApCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChTX0lTRElSIChzdGF0Yi5zdF9tb2RlKSkKCWluZm8gPSBGY0dsb2JhbENhY2hlRGlyQWRkIChjYWNoZSwgZmlsZSwgc3RhdGIuc3RfbXRpbWUsIAoJCQkJICAgIEZjVHJ1ZSwgRmNUcnVlKTsKICAgIGVsc2UKCWluZm8gPSBGY0dsb2JhbENhY2hlRmlsZUFkZCAoY2FjaGUsIGZpbGUsIGlkLCBzdGF0Yi5zdF9tdGltZSwgCgkJCQkgICAgbmFtZSwgRmNUcnVlKTsKICAgIGlmIChpbmZvKQogICAgewoJRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKGNhY2hlLCBpbmZvKTsKCWNhY2hlLT51cGRhdGVkID0gRmNUcnVlOwogICAgfQogICAgZWxzZQoJY2FjaGUtPmJyb2tlbiA9IEZjVHJ1ZTsKICAgIHJldHVybiBpbmZvICE9IDA7Cn0KCkZjQm9vbApGY0dsb2JhbENhY2hlU2F2ZSAoRmNHbG9iYWxDYWNoZSAgICAqY2FjaGUsCgkJICAgY29uc3QgRmNDaGFyOCAgICAqY2FjaGVfZmlsZSkKewogICAgRklMRQkJKmY7CiAgICBpbnQJCQlkaXJfaGFzaCwgZmlsZV9oYXNoOwogICAgRmNHbG9iYWxDYWNoZURpcgkqZGlyOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmZpbGU7CiAgICBGY0F0b21pYwkJKmF0b21pYzsKCiAgICBpZiAoIWNhY2hlLT51cGRhdGVkICYmIGNhY2hlLT5yZWZlcmVuY2VkID09IGNhY2hlLT5lbnRyaWVzKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIAogICAgaWYgKGNhY2hlLT5icm9rZW4pCglyZXR1cm4gRmNGYWxzZTsKCiNpZiBkZWZpbmVkIChIQVZFX0dFVFVJRCkgJiYgZGVmaW5lZCAoSEFWRV9HRVRFVUlEKQogICAgLyogU2V0LVVJRCBwcm9ncmFtcyBjYW4ndCBzYWZlbHkgdXBkYXRlIHRoZSBjYWNoZSAqLwogICAgaWYgKGdldHVpZCAoKSAhPSBnZXRldWlkICgpKQoJcmV0dXJuIEZjRmFsc2U7CiNlbmRpZgogICAgCiAgICBhdG9taWMgPSBGY0F0b21pY0NyZWF0ZSAoY2FjaGVfZmlsZSk7CiAgICBpZiAoIWF0b21pYykKCWdvdG8gYmFpbDA7CiAgICBpZiAoIUZjQXRvbWljTG9jayAoYXRvbWljKSkKCWdvdG8gYmFpbDE7CiAgICBmID0gZm9wZW4gKChjaGFyICopIEZjQXRvbWljTmV3RmlsZShhdG9taWMpLCAidyIpOwogICAgaWYgKCFmKQoJZ290byBiYWlsMjsKCiAgICBmb3IgKGRpcl9oYXNoID0gMDsgZGlyX2hhc2ggPCBGQ19HTE9CQUxfQ0FDSEVfRElSX0hBU0hfU0laRTsgZGlyX2hhc2grKykKICAgIHsKCWZvciAoZGlyID0gY2FjaGUtPmVudHNbZGlyX2hhc2hdOyBkaXI7IGRpciA9IGRpci0+bmV4dCkKCXsKCSAgICBpZiAoIWRpci0+aW5mby5yZWZlcmVuY2VkKQoJCWNvbnRpbnVlOwoJICAgIGlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBkaXItPmluZm8uZmlsZSkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgMCkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVRpbWUgKGYsIGRpci0+aW5mby50aW1lKSkKCQlnb3RvIGJhaWw0OwoJICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCQlnb3RvIGJhaWw0OwoJICAgIGlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCAoRmNDaGFyOCAqKSBGQ19GT05UX0ZJTEVfRElSKSkKCQlnb3RvIGJhaWw0OwoJICAgIGlmIChQVVRDICgnXG4nLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICAKCSAgICBmb3IgKGZpbGVfaGFzaCA9IDA7IGZpbGVfaGFzaCA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgZmlsZV9oYXNoKyspCgkgICAgewoJCWZvciAoZmlsZSA9IGRpci0+ZW50c1tmaWxlX2hhc2hdOyBmaWxlOyBmaWxlID0gZmlsZS0+bmV4dCkKCQl7CgkJICAgIGlmICghZmlsZS0+aW5mby5yZWZlcmVuY2VkKQoJCQljb250aW51ZTsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVQYXRoIChmLCBkaXItPmluZm8uZmlsZSwgZmlsZS0+aW5mby5maWxlKSkKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgZmlsZS0+aWQgPCAwID8gMCA6IGZpbGUtPmlkKSkKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVRpbWUgKGYsIGZpbGUtPmluZm8udGltZSkpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIGZpbGUtPm5hbWUpKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoUFVUQyAoJ1xuJywgZikgPT0gRU9GKQoJCQlnb3RvIGJhaWw0OwoJCX0KCSAgICB9Cgl9CiAgICB9CgogICAgaWYgKGZjbG9zZSAoZikgPT0gRU9GKQoJZ290byBiYWlsMzsKICAgIAogICAgaWYgKCFGY0F0b21pY1JlcGxhY2VPcmlnIChhdG9taWMpKQoJZ290byBiYWlsMzsKICAgIAogICAgRmNBdG9taWNVbmxvY2sgKGF0b21pYyk7CiAgICBGY0F0b21pY0Rlc3Ryb3kgKGF0b21pYyk7CgogICAgY2FjaGUtPnVwZGF0ZWQgPSBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKCmJhaWw0OgogICAgZmNsb3NlIChmKTsKYmFpbDM6CiAgICBGY0F0b21pY0RlbGV0ZU5ldyAoYXRvbWljKTsKYmFpbDI6CiAgICBGY0F0b21pY1VubG9jayAoYXRvbWljKTsKYmFpbDE6CiAgICBGY0F0b21pY0Rlc3Ryb3kgKGF0b21pYyk7CmJhaWwwOgogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY0RpckNhY2hlVmFsaWQgKGNvbnN0IEZjQ2hhcjggKmRpcikKewogICAgRmNDaGFyOAkqY2FjaGVfZmlsZSA9IEZjU3RyUGx1cyAoZGlyLCAoRmNDaGFyOCAqKSAiLyIgRkNfRElSX0NBQ0hFX0ZJTEUpOwogICAgc3RydWN0IHN0YXQJZmlsZV9zdGF0LCBkaXJfc3RhdDsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgZGlyLCAmZGlyX3N0YXQpIDwgMCkKICAgIHsKCUZjU3RyRnJlZSAoY2FjaGVfZmlsZSk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGlmIChzdGF0ICgoY2hhciAqKSBjYWNoZV9maWxlLCAmZmlsZV9zdGF0KSA8IDApCiAgICB7CglGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwogICAgLyoKICAgICAqIElmIHRoZSBkaXJlY3RvcnkgaGFzIGJlZW4gbW9kaWZpZWQgbW9yZSByZWNlbnRseSB0aGFuCiAgICAgKiB0aGUgY2FjaGUgZmlsZSwgdGhlIGNhY2hlIGlzIG5vdCB2YWxpZAogICAgICovCiAgICBpZiAoZGlyX3N0YXQuc3RfbXRpbWUgLSBmaWxlX3N0YXQuc3RfbXRpbWUgPiAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNEaXJDYWNoZVJlYWREaXIgKEZjRm9udFNldCAqc2V0LCBGY1N0clNldCAqZGlycywgY29uc3QgRmNDaGFyOCAqZGlyLCBGY0NvbmZpZyAqY29uZmlnKQp7CiAgICBGY0NoYXI4CSAgICAqY2FjaGVfZmlsZSA9IEZjU3RyUGx1cyAoZGlyLCAoRmNDaGFyOCAqKSAiLyIgRkNfRElSX0NBQ0hFX0ZJTEUpOwogICAgRklMRQkgICAgKmY7CiAgICBGY0NoYXI4CSAgICAqYmFzZTsKICAgIGludAkJICAgIGlkOwogICAgaW50CQkgICAgZGlyX2xlbjsKICAgIEZjQ2hhcjgJICAgIGZpbGVfYnVmWzgxOTJdLCAqZmlsZTsKICAgIEZjQ2hhcjgJICAgIG5hbWVfYnVmWzgxOTJdLCAqbmFtZTsKICAgIEZjQm9vbAkgICAgcmV0ID0gRmNGYWxzZTsKCiAgICBpZiAoIWNhY2hlX2ZpbGUpCglnb3RvIGJhaWwwOwogICAgCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIkZjRGlyQ2FjaGVSZWFkRGlyIGNhY2hlX2ZpbGUgXCIlc1wiXG4iLCBjYWNoZV9maWxlKTsKICAgIAogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAiciIpOwogICAgaWYgKCFmKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIG5vIGNhY2hlIGZpbGVcbiIpOwoJZ290byBiYWlsMTsKICAgIH0KCiAgICBpZiAoIUZjRGlyQ2FjaGVWYWxpZCAoZGlyKSkKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJICAgIHByaW50ZiAoIiBjYWNoZSBmaWxlIG9sZGVyIHRoYW4gZGlyZWN0b3J5XG4iKTsKCWdvdG8gYmFpbDI7CiAgICB9CiAgICAKICAgIGJhc2UgPSAoRmNDaGFyOCAqKSBzdHJyY2hyICgoY2hhciAqKSBjYWNoZV9maWxlLCAnLycpOwogICAgaWYgKCFiYXNlKQoJZ290byBiYWlsMjsKICAgIGJhc2UrKzsKICAgIGRpcl9sZW4gPSBiYXNlIC0gY2FjaGVfZmlsZTsKICAgIAogICAgZmlsZSA9IDA7CiAgICBuYW1lID0gMDsKICAgIHdoaWxlICgoZmlsZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBmaWxlX2J1Ziwgc2l6ZW9mIChmaWxlX2J1ZikpKSAmJgoJICAgRmNDYWNoZVJlYWRJbnQgKGYsICZpZCkgJiYKCSAgIChuYW1lID0gRmNDYWNoZVJlYWRTdHJpbmcgKGYsIG5hbWVfYnVmLCBzaXplb2YgKG5hbWVfYnVmKSkpKQogICAgewoJaWYgKCFGY0NhY2hlRm9udFNldEFkZCAoc2V0LCBkaXJzLCBjYWNoZV9maWxlLCBkaXJfbGVuLAoJCQkJZmlsZSwgbmFtZSwgY29uZmlnKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKGZpbGUgIT0gZmlsZV9idWYpCgkgICAgZnJlZSAoZmlsZSk7CglpZiAobmFtZSAhPSBuYW1lX2J1ZikKCSAgICBmcmVlIChuYW1lKTsKCWZpbGUgPSBuYW1lID0gMDsKICAgIH0KICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJcHJpbnRmICgiIGNhY2hlIGxvYWRlZFxuIik7CiAgICAKICAgIHJldCA9IEZjVHJ1ZTsKYmFpbDM6CiAgICBpZiAoZmlsZSAmJiBmaWxlICE9IGZpbGVfYnVmKQoJZnJlZSAoZmlsZSk7CiAgICBpZiAobmFtZSAmJiBuYW1lICE9IG5hbWVfYnVmKQoJZnJlZSAobmFtZSk7CmJhaWwyOgogICAgZmNsb3NlIChmKTsKYmFpbDE6CiAgICBGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwpiYWlsMDoKICAgIHJldHVybiByZXQ7Cn0KCi8qCiAqIHJldHVybiB0aGUgcGF0aCBmcm9tIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyAnY2FjaGUnIHRvICdmaWxlJwogKi8KCnN0YXRpYyBjb25zdCBGY0NoYXI4ICoKRmNGaWxlQmFzZU5hbWUgKGNvbnN0IEZjQ2hhcjggKmNhY2hlLCBjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBjb25zdCBGY0NoYXI4ICAgKmNhY2hlX3NsYXNoOwoKICAgIGNhY2hlX3NsYXNoID0gRmNTdHJMYXN0U2xhc2ggKGNhY2hlKTsKICAgIGlmIChjYWNoZV9zbGFzaCAmJiAhc3RybmNtcCAoKGNvbnN0IGNoYXIgKikgY2FjaGUsIChjb25zdCBjaGFyICopIGZpbGUsCgkJCQkgKGNhY2hlX3NsYXNoICsgMSkgLSBjYWNoZSkpCglyZXR1cm4gZmlsZSArICgoY2FjaGVfc2xhc2ggKyAxKSAtIGNhY2hlKTsKICAgIHJldHVybiBmaWxlOwp9CgpGY0Jvb2wKRmNEaXJDYWNoZVdyaXRlRGlyIChGY0ZvbnRTZXQgKnNldCwgRmNTdHJTZXQgKmRpcnMsIGNvbnN0IEZjQ2hhcjggKmRpcikKewogICAgRmNDaGFyOAkgICAgKmNhY2hlX2ZpbGUgPSBGY1N0clBsdXMgKGRpciwgKEZjQ2hhcjggKikgIi8iIEZDX0RJUl9DQUNIRV9GSUxFKTsKICAgIEZjUGF0dGVybgkgICAgKmZvbnQ7CiAgICBGSUxFCSAgICAqZjsKICAgIEZjQ2hhcjgJICAgICpuYW1lOwogICAgY29uc3QgRmNDaGFyOCAgICpmaWxlLCAqYmFzZTsKICAgIGludAkJICAgIG47CiAgICBpbnQJCSAgICBpZDsKICAgIEZjQm9vbAkgICAgcmV0OwogICAgRmNTdHJMaXN0CSAgICAqbGlzdDsKCiAgICBpZiAoIWNhY2hlX2ZpbGUpCglnb3RvIGJhaWwwOwogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCJGY0RpckNhY2hlV3JpdGVEaXIgY2FjaGVfZmlsZSBcIiVzXCJcbiIsIGNhY2hlX2ZpbGUpOwogICAgCiAgICBmID0gZm9wZW4gKChjaGFyICopIGNhY2hlX2ZpbGUsICJ3Iik7CiAgICBpZiAoIWYpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgY2FuJ3QgY3JlYXRlIFwiJXNcIlxuIiwgY2FjaGVfZmlsZSk7Cglnb3RvIGJhaWwxOwogICAgfQogICAgCiAgICBsaXN0ID0gRmNTdHJMaXN0Q3JlYXRlIChkaXJzKTsKICAgIGlmICghbGlzdCkKCWdvdG8gYmFpbDI7CiAgICAKICAgIHdoaWxlICgoZGlyID0gRmNTdHJMaXN0TmV4dCAobGlzdCkpKQogICAgewoJYmFzZSA9IEZjRmlsZUJhc2VOYW1lIChjYWNoZV9maWxlLCBkaXIpOwoJaWYgKCFGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIGJhc2UpKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkgICAgZ290byBiYWlsMzsKCWlmICghRmNDYWNoZVdyaXRlSW50IChmLCAwKSkKCSAgICBnb3RvIGJhaWwzOwogICAgICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJaWYgKCFGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIEZDX0ZPTlRfRklMRV9ESVIpKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoUFVUQyAoJ1xuJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CiAgICB9CiAgICAKICAgIGZvciAobiA9IDA7IG4gPCBzZXQtPm5mb250OyBuKyspCiAgICB7Cglmb250ID0gc2V0LT5mb250c1tuXTsKCWlmIChGY1BhdHRlcm5HZXRTdHJpbmcgKGZvbnQsIEZDX0ZJTEUsIDAsIChGY0NoYXI4ICoqKSAmZmlsZSkgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICBnb3RvIGJhaWwzOwoJYmFzZSA9IEZjRmlsZUJhc2VOYW1lIChjYWNoZV9maWxlLCBmaWxlKTsKCWlmIChGY1BhdHRlcm5HZXRJbnRlZ2VyIChmb250LCBGQ19JTkRFWCwgMCwgJmlkKSAhPSBGY1Jlc3VsdE1hdGNoKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRVYpCgkgICAgcHJpbnRmICgiIHdyaXRlIGZpbGUgXCIlc1wiXG4iLCBiYXNlKTsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBiYXNlKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgaWQpKQoJICAgIGdvdG8gYmFpbDM7CiAgICAgICAgaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CgluYW1lID0gRmNOYW1lVW5wYXJzZSAoZm9udCk7CglpZiAoIW5hbWUpCgkgICAgZ290byBiYWlsMzsKCXJldCA9IEZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgbmFtZSk7CglGY1N0ckZyZWUgKG5hbWUpOwoJaWYgKCFyZXQpCgkgICAgZ290byBiYWlsMzsKCWlmIChQVVRDICgnXG4nLCBmKSA9PSBFT0YpCgkgICAgZ290byBiYWlsMzsKICAgIH0KICAgIAogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CgogICAgaWYgKGZjbG9zZSAoZikgPT0gRU9GKQoJZ290byBiYWlsMTsKICAgIAogICAgRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIiBjYWNoZSB3cml0dGVuXG4iKTsKICAgIHJldHVybiBGY1RydWU7CiAgICAKYmFpbDM6CiAgICBGY1N0ckxpc3REb25lIChsaXN0KTsKYmFpbDI6CiAgICBmY2xvc2UgKGYpOwpiYWlsMToKICAgIHVubGluayAoKGNoYXIgKikgY2FjaGVfZmlsZSk7CiAgICBGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwpiYWlsMDoKICAgIHJldHVybiBGY0ZhbHNlOwp9Cg==