LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNjYWNoZS5jLHYgMS4xMiAyMDAyLzA4LzIyIDA3OjM2OjQ0IGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJmY2ludC5oIgoKLyoKICogUE9TSVggaGFzIGJyb2tlbiBzdGRpbyBzbyB0aGF0IGdldGMgbXVzdCBkbyB0aHJlYWQtc2FmZSBsb2NraW5nLAogKiB0aGlzIGlzIGEgc2VyaW91cyBwZXJmb3JtYW5jZSBwcm9ibGVtIGZvciBhcHBsaWNhdGlvbnMgZG9pbmcgbGFyZ2UKICogYW1vdW50cyBvZiBJTyB3aXRoIGdldGMgKGFzIGlzIGRvbmUgaGVyZSkuICBJZiBhdmFpbGFibGUsIHVzZQogKiB0aGUgZ2V0Y191bmxvY2tlZCB2YXJpZW50IGluc3RlYWQuCiAqLwogCiNpZiBkZWZpbmVkKGdldGNfdW5sb2NrZWQpIHx8IGRlZmluZWQoX0lPX2dldGNfdW5sb2NrZWQpCiNkZWZpbmUgR0VUQyhmKSBnZXRjX3VubG9ja2VkKGYpCiNkZWZpbmUgUFVUQyhjLGYpIHB1dGNfdW5sb2NrZWQoYyxmKQojZWxzZQojZGVmaW5lIEdFVEMoZikgZ2V0YyhmKQojZGVmaW5lIFBVVEMoYyxmKSBwdXRjKGMsZikKI2VuZGlmCgojZGVmaW5lIEZDX0RCR19DQUNIRV9SRUYgICAgMTAyNAoKc3RhdGljIEZjQ2hhcjggKgpGY0NhY2hlUmVhZFN0cmluZyAoRklMRSAqZiwgRmNDaGFyOCAqZGVzdCwgaW50IGxlbikKewogICAgaW50CQljOwogICAgRmNCb29sCWVzY2FwZTsKICAgIEZjQ2hhcjgJKmQ7CiAgICBpbnQJCXNpemU7CiAgICBpbnQJCWk7CgogICAgd2hpbGUgKChjID0gR0VUQyAoZikpICE9IEVPRikKCWlmIChjID09ICciJykKCSAgICBicmVhazsKICAgIGlmIChjID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGxlbiA9PSAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICAKICAgIHNpemUgPSBsZW47CiAgICBpID0gMDsKICAgIGQgPSBkZXN0OwogICAgZXNjYXBlID0gRmNGYWxzZTsKICAgIHdoaWxlICgoYyA9IEdFVEMgKGYpKSAhPSBFT0YpCiAgICB7CglpZiAoIWVzY2FwZSkKCXsKCSAgICBzd2l0Y2ggKGMpIHsKCSAgICBjYXNlICciJzoKCQljID0gJ1wwJzsKCQlicmVhazsKCSAgICBjYXNlICdcXCc6CgkJZXNjYXBlID0gRmNUcnVlOwoJCWNvbnRpbnVlOwoJICAgIH0KCX0KCWlmIChpID09IHNpemUpCgl7CgkgICAgRmNDaGFyOCAqbmV3ID0gbWFsbG9jIChzaXplICogMik7CS8qIGZyZWVkIGluIGNhbGxlciAqLwoJICAgIGlmICghbmV3KQoJCWJyZWFrOwoJICAgIG1lbWNweSAobmV3LCBkLCBzaXplKTsKCSAgICBzaXplICo9IDI7CgkgICAgaWYgKGQgIT0gZGVzdCkKCQlmcmVlIChkKTsKCSAgICBkID0gbmV3OwoJfQoJZFtpKytdID0gYzsKCWlmIChjID09ICdcMCcpCgkgICAgcmV0dXJuIGQ7Cgllc2NhcGUgPSBGY0ZhbHNlOwogICAgfQogICAgaWYgKGQgIT0gZGVzdCkKCWZyZWUgKGQpOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDYWNoZVJlYWRVbG9uZyAoRklMRSAqZiwgdW5zaWduZWQgbG9uZyAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBpbnQJCSAgICBjOwoKICAgIHdoaWxlICgoYyA9IEdFVEMgKGYpKSAhPSBFT0YpCiAgICB7CglpZiAoIWlzc3BhY2UgKGMpKQoJICAgIGJyZWFrOwogICAgfQogICAgaWYgKGMgPT0gRU9GKQoJcmV0dXJuIEZjRmFsc2U7CiAgICB0ID0gMDsKICAgIGZvciAoOzspCiAgICB7CglpZiAoYyA9PSBFT0YgfHwgaXNzcGFjZSAoYykpCgkgICAgYnJlYWs7CglpZiAoIWlzZGlnaXQgKGMpKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJdCA9IHQgKiAxMCArIChjIC0gJzAnKTsKCWMgPSBHRVRDIChmKTsKICAgIH0KICAgICpkZXN0ID0gdDsKICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDYWNoZVJlYWRJbnQgKEZJTEUgKmYsIGludCAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBGY0Jvb2wJICAgIHJldDsKCiAgICByZXQgPSBGY0NhY2hlUmVhZFVsb25nIChmLCAmdCk7CiAgICBpZiAocmV0KQoJKmRlc3QgPSAoaW50KSB0OwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlUmVhZFRpbWUgKEZJTEUgKmYsIHRpbWVfdCAqZGVzdCkKewogICAgdW5zaWduZWQgbG9uZyAgIHQ7CiAgICBGY0Jvb2wJICAgIHJldDsKCiAgICByZXQgPSBGY0NhY2hlUmVhZFVsb25nIChmLCAmdCk7CiAgICBpZiAocmV0KQoJKmRlc3QgPSAodGltZV90KSB0OwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVDaGFycyAoRklMRSAqZiwgY29uc3QgRmNDaGFyOCAqY2hhcnMpCnsKICAgIEZjQ2hhcjggICAgYzsKICAgIHdoaWxlICgoYyA9ICpjaGFycysrKSkKICAgIHsKCXN3aXRjaCAoYykgewoJY2FzZSAnIic6CgljYXNlICdcXCc6CgkgICAgaWYgKFBVVEMgKCdcXCcsIGYpID09IEVPRikKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICAvKiBmYWxsIHRocm91Z2ggKi8KCWRlZmF1bHQ6CgkgICAgaWYgKFBVVEMgKGMsIGYpID09IEVPRikKCQlyZXR1cm4gRmNGYWxzZTsKCX0KICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnN0YXRpYyBGY0Jvb2wKRmNDYWNoZVdyaXRlU3RyaW5nIChGSUxFICpmLCBjb25zdCBGY0NoYXI4ICpzdHJpbmcpCnsKCiAgICBpZiAoUFVUQyAoJyInLCBmKSA9PSBFT0YpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmICghRmNDYWNoZVdyaXRlQ2hhcnMgKGYsIHN0cmluZykpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVQYXRoIChGSUxFICpmLCBjb25zdCBGY0NoYXI4ICpkaXIsIGNvbnN0IEZjQ2hhcjggKmZpbGUpCnsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGRpcikKCWlmICghRmNDYWNoZVdyaXRlQ2hhcnMgKGYsIGRpcikpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiNpZmRlZiBfV0lOMzIKICAgIGlmIChkaXIgJiYKCWRpcltzdHJsZW4oKGNvbnN0IGNoYXIgKikgZGlyKSAtIDFdICE9ICcvJyAmJgoJZGlyW3N0cmxlbigoY29uc3QgY2hhciAqKSBkaXIpIC0gMV0gIT0gJ1xcJykKICAgIHsKCWlmICghRmNDYWNoZVdyaXRlQ2hhcnMgKGYsICJcXCIpKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgfQojZWxzZQogICAgaWYgKGRpciAmJiBkaXJbc3RybGVuKChjb25zdCBjaGFyICopIGRpcikgLSAxXSAhPSAnLycpCglpZiAoUFVUQyAoJy8nLCBmKSA9PSBFT0YpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiNlbmRpZgogICAgaWYgKCFGY0NhY2hlV3JpdGVDaGFycyAoZiwgZmlsZSkpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVVbG9uZyAoRklMRSAqZiwgdW5zaWduZWQgbG9uZyB0KQp7CiAgICBpbnQJICAgIHBvdzsKICAgIHVuc2lnbmVkIGxvbmcgICB0ZW1wLCBkaWdpdDsKCiAgICB0ZW1wID0gdDsKICAgIHBvdyA9IDE7CiAgICB3aGlsZSAodGVtcCA+PSAxMCkKICAgIHsKCXRlbXAgLz0gMTA7Cglwb3cgKj0gMTA7CiAgICB9CiAgICB0ZW1wID0gdDsKICAgIHdoaWxlIChwb3cpCiAgICB7CglkaWdpdCA9IHRlbXAgLyBwb3c7CglpZiAoUFVUQyAoKGNoYXIpIGRpZ2l0ICsgJzAnLCBmKSA9PSBFT0YpCgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl0ZW1wID0gdGVtcCAtIHBvdyAqIGRpZ2l0OwoJcG93ID0gcG93IC8gMTA7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZUludCAoRklMRSAqZiwgaW50IGkpCnsKICAgIHJldHVybiBGY0NhY2hlV3JpdGVVbG9uZyAoZiwgKHVuc2lnbmVkIGxvbmcpIGkpOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZVRpbWUgKEZJTEUgKmYsIHRpbWVfdCB0KQp7CiAgICByZXR1cm4gRmNDYWNoZVdyaXRlVWxvbmcgKGYsICh1bnNpZ25lZCBsb25nKSB0KTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlRm9udFNldEFkZCAoRmNGb250U2V0CSAgICAqc2V0LAoJCSAgIEZjU3RyU2V0CSAgICAqZGlycywKCQkgICBjb25zdCBGY0NoYXI4ICAgICpkaXIsCgkJICAgaW50CQkgICAgZGlyX2xlbiwKCQkgICBjb25zdCBGY0NoYXI4ICAgICpmaWxlLAoJCSAgIGNvbnN0IEZjQ2hhcjggICAgKm5hbWUsCgkJICAgRmNDb25maWcJICAgICpjb25maWcpCnsKICAgIEZjQ2hhcjgJcGF0aF9idWZbODE5Ml0sICpwYXRoOwogICAgaW50CQlsZW47CiAgICBGY0Jvb2wJcmV0ID0gRmNGYWxzZTsKICAgIEZjUGF0dGVybgkqZm9udDsKICAgIEZjUGF0dGVybgkqZnJvemVuOwoKICAgIHBhdGggPSBwYXRoX2J1ZjsKICAgIGxlbiA9IChkaXJfbGVuICsgMSArIHN0cmxlbiAoKGNvbnN0IGNoYXIgKikgZmlsZSkgKyAxKTsKICAgIGlmIChsZW4gPiBzaXplb2YgKHBhdGhfYnVmKSkKICAgIHsKCXBhdGggPSBtYWxsb2MgKGxlbik7CS8qIGZyZWVkIGRvd24gYmVsb3cgKi8KCWlmICghcGF0aCkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHN0cm5jcHkgKChjaGFyICopIHBhdGgsIChjb25zdCBjaGFyICopIGRpciwgZGlyX2xlbik7CiNpZmRlZiBfV0lOMzIKICAgIGlmIChkaXJbZGlyX2xlbiAtIDFdICE9ICcvJyAmJiBkaXJbZGlyX2xlbiAtIDFdICE9ICdcXCcgKQoJcGF0aFtkaXJfbGVuKytdID0gJ1xcJzsKI2Vsc2UKICAgIGlmIChkaXJbZGlyX2xlbiAtIDFdICE9ICcvJykKCXBhdGhbZGlyX2xlbisrXSA9ICcvJzsKI2VuZGlmCiAgICBzdHJjcHkgKChjaGFyICopIHBhdGggKyBkaXJfbGVuLCAoY29uc3QgY2hhciAqKSBmaWxlKTsKICAgIGlmIChjb25maWcgJiYgIUZjQ29uZmlnQWNjZXB0RmlsZW5hbWUgKGNvbmZpZywgcGF0aCkpCglyZXQgPSBGY1RydWU7CiAgICBlbHNlIGlmICghRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9ESVIpKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIiBkaXIgY2FjaGUgZGlyIFwiJXNcIlxuIiwgcGF0aCk7CglyZXQgPSBGY1N0clNldEFkZCAoZGlycywgcGF0aCk7CiAgICB9CiAgICBlbHNlIGlmICghRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9JTlZBTElEKSkKICAgIHsKCXJldCA9IEZjVHJ1ZTsKICAgIH0KICAgIGVsc2UKICAgIHsKCWZvbnQgPSBGY05hbWVQYXJzZSAobmFtZSk7CglpZiAoZm9udCkKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRVYpCgkJcHJpbnRmICgiIGRpciBjYWNoZSBmaWxlIFwiJXNcIlxuIiwgZmlsZSk7CgkgICAgcmV0ID0gRmNQYXR0ZXJuQWRkU3RyaW5nIChmb250LCBGQ19GSUxFLCBwYXRoKTsKCSAgICBpZiAocmV0KQoJICAgIHsKCQlmcm96ZW4gPSBGY1BhdHRlcm5GcmVlemUgKGZvbnQpOwoJCXJldCA9IChmcm96ZW4gIT0gMCk7CgkJaWYgKHJldCkKCQkgICByZXQgPSBGY0ZvbnRTZXRBZGQgKHNldCwgZnJvemVuKTsKCSAgICB9CgkgICAgRmNQYXR0ZXJuRGVzdHJveSAoZm9udCk7Cgl9CiAgICB9CiAgICBpZiAocGF0aCAhPSBwYXRoX2J1ZikgZnJlZSAocGF0aCk7CiAgICByZXR1cm4gcmV0OwogICAgCn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQKRmNDYWNoZUhhc2ggKGNvbnN0IEZjQ2hhcjggKnN0cmluZywgaW50IGxlbikKewogICAgdW5zaWduZWQgaW50ICAgIGggPSAwOwogICAgRmNDaGFyOAkgICAgYzsKCiAgICB3aGlsZSAobGVuLS0gJiYgKGMgPSAqc3RyaW5nKyspKQoJaCA9IChoIDw8IDEpIF4gYzsKICAgIHJldHVybiBoOwp9CgovKgogKiBWZXJpZnkgdGhlIHNhdmVkIHRpbWVzdGFtcCBmb3IgYSBmaWxlCiAqLwpGY0Jvb2wKRmNHbG9iYWxDYWNoZUNoZWNrVGltZSAoY29uc3QgRmNDaGFyOCAqZmlsZSwgRmNHbG9iYWxDYWNoZUluZm8gKmluZm8pCnsKICAgIHN0cnVjdCBzdGF0CSAgICBzdGF0YjsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgZmlsZSwgJnN0YXRiKSA8IDApCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgZmlsZSAlcyBtaXNzaW5nXG4iLCBmaWxlKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgaWYgKHN0YXRiLnN0X210aW1lICE9IGluZm8tPnRpbWUpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgdGltZXN0YW1wIG1pc21hdGNoICh3YXMgJWQgaXMgJWQpXG4iLAoJCSAgICAoaW50KSBpbmZvLT50aW1lLCAoaW50KSBzdGF0Yi5zdF9tdGltZSk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCnZvaWQKRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKEZjR2xvYmFsQ2FjaGUJICAgICpjYWNoZSwKCQkJIEZjR2xvYmFsQ2FjaGVJbmZvICAqaW5mbykKewogICAgaWYgKCFpbmZvLT5yZWZlcmVuY2VkKQogICAgewoJaW5mby0+cmVmZXJlbmNlZCA9IEZjVHJ1ZTsKCWNhY2hlLT5yZWZlcmVuY2VkKys7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRV9SRUYpCgkgICAgcHJpbnRmICgiUmVmZXJlbmNlICVkICVzXG4iLCBjYWNoZS0+cmVmZXJlbmNlZCwgaW5mby0+ZmlsZSk7CiAgICB9Cn0KCi8qCiAqIEJyZWFrIGEgcGF0aCBpbnRvIGRpci9iYXNlIGVsZW1lbnRzIGFuZCBjb21wdXRlIHRoZSBiYXNlIGhhc2gKICogYW5kIHRoZSBkaXIgbGVuZ3RoLiAgVGhpcyBpcyBzaGFyZWQgYmV0d2VlbiB0aGUgZnVuY3Rpb25zCiAqIHdoaWNoIHdhbGsgdGhlIGZpbGUgY2FjaGVzCiAqLwoKdHlwZWRlZiBzdHJ1Y3QgX0ZjRmlsZVBhdGhJbmZvIHsKICAgIGNvbnN0IEZjQ2hhcjggICAqZGlyOwogICAgaW50CQkgICAgZGlyX2xlbjsKICAgIGNvbnN0IEZjQ2hhcjggICAqYmFzZTsKICAgIHVuc2lnbmVkIGludCAgICBiYXNlX2hhc2g7Cn0gRmNGaWxlUGF0aEluZm87CgpzdGF0aWMgRmNGaWxlUGF0aEluZm8KRmNGaWxlUGF0aEluZm9HZXQgKGNvbnN0IEZjQ2hhcjggICAgKnBhdGgpCnsKICAgIEZjRmlsZVBhdGhJbmZvICBpOwogICAgRmNDaGFyOAkgICAgKnNsYXNoOwoKICAgIHNsYXNoID0gRmNTdHJMYXN0U2xhc2ggKHBhdGgpOwogICAgaWYgKHNsYXNoKQogICAgewogICAgICAgIGkuZGlyID0gcGF0aDsKICAgICAgICBpLmRpcl9sZW4gPSBzbGFzaCAtIHBhdGg7CglpZiAoIWkuZGlyX2xlbikKCSAgICBpLmRpcl9sZW4gPSAxOwoJaS5iYXNlID0gc2xhc2ggKyAxOwogICAgfQogICAgZWxzZQogICAgewoJaS5kaXIgPSAoY29uc3QgRmNDaGFyOCAqKSAiLiI7CglpLmRpcl9sZW4gPSAxOwoJaS5iYXNlID0gcGF0aDsKICAgIH0KICAgIGkuYmFzZV9oYXNoID0gRmNDYWNoZUhhc2ggKGkuYmFzZSwgLTEpOwogICAgcmV0dXJuIGk7Cn0KCkZjR2xvYmFsQ2FjaGVEaXIgKgpGY0dsb2JhbENhY2hlRGlyR2V0IChGY0dsb2JhbENhY2hlICAqY2FjaGUsCgkJICAgICBjb25zdCBGY0NoYXI4ICAqZGlyLAoJCSAgICAgaW50CSAgICBsZW4sCgkJICAgICBGY0Jvb2wJICAgIGNyZWF0ZV9taXNzaW5nKQp7CiAgICB1bnNpZ25lZCBpbnQJaGFzaCA9IEZjQ2FjaGVIYXNoIChkaXIsIGxlbik7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkLCAqKnByZXY7CgogICAgZm9yIChwcmV2ID0gJmNhY2hlLT5lbnRzW2hhc2ggJSBGQ19HTE9CQUxfQ0FDSEVfRElSX0hBU0hfU0laRV07CgkgKGQgPSAqcHJldik7CgkgcHJldiA9ICYoKnByZXYpLT5uZXh0KQogICAgewoJaWYgKGQtPmluZm8uaGFzaCA9PSBoYXNoICYmIGQtPmxlbiA9PSBsZW4gJiYKCSAgICAhc3RybmNtcCAoKGNvbnN0IGNoYXIgKikgZC0+aW5mby5maWxlLAoJCSAgICAgIChjb25zdCBjaGFyICopIGRpciwgbGVuKSkKCSAgICBicmVhazsKICAgIH0KICAgIGlmICghKGQgPSAqcHJldikpCiAgICB7CglpbnQJaTsKCWlmICghY3JlYXRlX21pc3NpbmcpCgkgICAgcmV0dXJuIDA7CglkID0gbWFsbG9jIChzaXplb2YgKEZjR2xvYmFsQ2FjaGVEaXIpICsgbGVuICsgMSk7CglpZiAoIWQpCgkgICAgcmV0dXJuIDA7CglGY01lbUFsbG9jIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZURpcikgKyBsZW4gKyAxKTsKCWQtPm5leHQgPSAqcHJldjsKCSpwcmV2ID0gZDsKCWQtPmluZm8uaGFzaCA9IGhhc2g7CglkLT5pbmZvLmZpbGUgPSAoRmNDaGFyOCAqKSAoZCArIDEpOwoJc3RybmNweSAoKGNoYXIgKikgZC0+aW5mby5maWxlLCAoY29uc3QgY2hhciAqKSBkaXIsIGxlbik7CglkLT5pbmZvLmZpbGVbbGVuXSA9ICdcMCc7CglkLT5pbmZvLnRpbWUgPSAwOwoJZC0+aW5mby5yZWZlcmVuY2VkID0gRmNGYWxzZTsKCWQtPmxlbiA9IGxlbjsKCWZvciAoaSA9IDA7IGkgPCBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkU7IGkrKykKCSAgICBkLT5lbnRzW2ldID0gMDsKCWQtPnN1YmRpcnMgPSAwOwogICAgfQogICAgcmV0dXJuIGQ7Cn0KCnN0YXRpYyBGY0dsb2JhbENhY2hlSW5mbyAqCkZjR2xvYmFsQ2FjaGVEaXJBZGQgKEZjR2xvYmFsQ2FjaGUgICpjYWNoZSwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpkaXIsCgkJICAgICB0aW1lX3QJICAgIHRpbWUsCgkJICAgICBGY0Jvb2wJICAgIHJlcGxhY2UsCgkJICAgICBGY0Jvb2wJICAgIGNyZWF0ZV9taXNzaW5nKQp7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkOwogICAgRmNGaWxlUGF0aEluZm8JaTsKICAgIEZjR2xvYmFsQ2FjaGVTdWJkaXIJKnN1YmRpcjsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKnBhcmVudDsKCiAgICBpID0gRmNGaWxlUGF0aEluZm9HZXQgKGRpcik7CiAgICBwYXJlbnQgPSBGY0dsb2JhbENhY2hlRGlyR2V0IChjYWNoZSwgaS5kaXIsIGkuZGlyX2xlbiwgY3JlYXRlX21pc3NpbmcpOwogICAgLyoKICAgICAqIFRyaWNreSBoZXJlIC0tIGRpcmVjdG9yaWVzIGNvbnRhaW5pbmcgZm9udHMuY2FjaGUtMSBmaWxlcwogICAgICogbmVlZCBlbnRyaWVzIG9ubHkgd2hlbiB0aGUgcGFyZW50IGRvZXNuJ3QgaGF2ZSBhIGNhY2hlIGZpbGUuCiAgICAgKiBUaGF0IGlzLCB3aGVuIHRoZSBwYXJlbnQgYWxyZWFkeSBleGlzdHMgaW4gdGhlIGNhY2hlLCBpcwogICAgICogcmVmZXJlbmNlZCBhbmQgaGFzIGEgInJlYWwiIHRpbWVzdGFtcC4gIFRoZSB0aW1lIG9mIDAgaXMKICAgICAqIHNwZWNpYWwgYW5kIG1hcmtzIGRpcmVjdG9yaWVzIHdoaWNoIGdvdCBzdHVjayBpbiB0aGUKICAgICAqIGdsb2JhbCBjYWNoZSBmb3IgdGhpcyB2ZXJ5IHJlYXNvbi4gIFllcywgaXQgY291bGQKICAgICAqIHVzZSBhIHNlcGFyYXRlIGJvb2xlYW4gZmllbGQsIGFuZCBwcm9iYWJseSBzaG91bGQuCiAgICAgKi8KICAgIGlmICghcGFyZW50IHx8ICghY3JlYXRlX21pc3NpbmcgJiYgCgkJICAgICghcGFyZW50LT5pbmZvLnJlZmVyZW5jZWQgfHwKCQkgICAgKHBhcmVudC0+aW5mby50aW1lID09IDApKSkpCglyZXR1cm4gMDsKICAgIC8qCiAgICAgKiBBZGQgdGhpcyBkaXJlY3RvcnkgdG8gdGhlIGNhY2hlCiAgICAgKi8KICAgIGQgPSBGY0dsb2JhbENhY2hlRGlyR2V0IChjYWNoZSwgZGlyLCBzdHJsZW4gKChjb25zdCBjaGFyICopIGRpciksIEZjVHJ1ZSk7CiAgICBpZiAoIWQpCglyZXR1cm4gMDsKICAgIGQtPmluZm8udGltZSA9IHRpbWU7CiAgICAvKgogICAgICogQWRkIHRoaXMgZGlyZWN0b3J5IHRvIHRoZSBzdWJkaXJlY3RvcnkgbGlzdCBvZiB0aGUgcGFyZW50CiAgICAgKi8KICAgIHN1YmRpciA9IG1hbGxvYyAoc2l6ZW9mIChGY0dsb2JhbENhY2hlU3ViZGlyKSk7CiAgICBpZiAoIXN1YmRpcikKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX0NBQ0hFLCBzaXplb2YgKEZjR2xvYmFsQ2FjaGVTdWJkaXIpKTsKICAgIHN1YmRpci0+ZW50ID0gZDsKICAgIHN1YmRpci0+bmV4dCA9IHBhcmVudC0+c3ViZGlyczsKICAgIHBhcmVudC0+c3ViZGlycyA9IHN1YmRpcjsKICAgIHJldHVybiAmZC0+aW5mbzsKfQoKc3RhdGljIHZvaWQKRmNHbG9iYWxDYWNoZURpckRlc3Ryb3kgKEZjR2xvYmFsQ2FjaGVEaXIgKmQpCnsKICAgIEZjR2xvYmFsQ2FjaGVGaWxlCSpmLCAqbmV4dDsKICAgIGludAkJCWg7CiAgICBGY0dsb2JhbENhY2hlU3ViZGlyCSpzLCAqbmV4dHM7CgogICAgZm9yIChoID0gMDsgaCA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgaCsrKQoJZm9yIChmID0gZC0+ZW50c1toXTsgZjsgZiA9IG5leHQpCgl7CgkgICAgbmV4dCA9IGYtPm5leHQ7CgkgICAgRmNNZW1GcmVlIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZUZpbGUpICsKCQkgICAgICAgc3RybGVuICgoY2hhciAqKSBmLT5pbmZvLmZpbGUpICsgMSArCgkJICAgICAgIHN0cmxlbiAoKGNoYXIgKikgZi0+bmFtZSkgKyAxKTsKCSAgICBmcmVlIChmKTsKCX0KICAgIGZvciAocyA9IGQtPnN1YmRpcnM7IHM7IHMgPSBuZXh0cykKICAgIHsKCW5leHRzID0gcy0+bmV4dDsKCUZjTWVtRnJlZSAoRkNfTUVNX0NBQ0hFLCBzaXplb2YgKEZjR2xvYmFsQ2FjaGVTdWJkaXIpKTsKCWZyZWUgKHMpOwogICAgfQogICAgRmNNZW1GcmVlIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZURpcikgKyBkLT5sZW4gKyAxKTsKICAgIGZyZWUgKGQpOwp9CgovKgogKiBJZiB0aGUgcGFyZW50IGlzIGluIHRoZSBnbG9iYWwgY2FjaGUgYW5kIHJlZmVyZW5jZWQsIGFkZAogKiBhbiBlbnRyeSBmb3IgJ2RpcicgdG8gdGhlIGdsb2JhbCBjYWNoZS4gIFRoaXMgaXMgdXNlZAogKiBmb3IgZGlyZWN0b3JpZXMgd2l0aCBmb250cy5jYWNoZSBmaWxlcwogKi8KCnZvaWQKRmNHbG9iYWxDYWNoZVJlZmVyZW5jZVN1YmRpciAoRmNHbG9iYWxDYWNoZSAqY2FjaGUsCgkJCSAgICAgIGNvbnN0IEZjQ2hhcjggKmRpcikKewogICAgRmNHbG9iYWxDYWNoZUluZm8JKmluZm87CiAgICBpbmZvID0gRmNHbG9iYWxDYWNoZURpckFkZCAoY2FjaGUsIGRpciwgMCwgRmNGYWxzZSwgRmNGYWxzZSk7CiAgICBpZiAoaW5mbyAmJiAhaW5mby0+cmVmZXJlbmNlZCkKICAgIHsKCWluZm8tPnJlZmVyZW5jZWQgPSBGY1RydWU7CgljYWNoZS0+cmVmZXJlbmNlZCsrOwogICAgfQp9CgovKgogKiBDaGVjayB0byBzZWUgaWYgdGhlIGdsb2JhbCBjYWNoZSBjb250YWlucyB2YWxpZCBkYXRhIGZvciAnZGlyJy4KICogSWYgc28sIHNjYW4gdGhlIGdsb2JhbCBjYWNoZSBmb3IgZmlsZXMgYW5kIGRpcmVjdG9yaWVzIGluICdkaXInLgogKiBlbHNlLCByZXR1cm4gRmFsc2UuCiAqLwpGY0Jvb2wKRmNHbG9iYWxDYWNoZVNjYW5EaXIgKEZjRm9udFNldAkJKnNldCwKCQkgICAgICBGY1N0clNldAkJKmRpcnMsCgkJICAgICAgRmNHbG9iYWxDYWNoZQkqY2FjaGUsCgkJICAgICAgY29uc3QgRmNDaGFyOAkqZGlyLAoJCSAgICAgIEZjQ29uZmlnCQkqY29uZmlnKQp7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkID0gRmNHbG9iYWxDYWNoZURpckdldCAoY2FjaGUsIGRpciwKCQkJCQkJICBzdHJsZW4gKChjb25zdCBjaGFyICopIGRpciksCgkJCQkJCSAgRmNGYWxzZSk7CiAgICBGY0dsb2JhbENhY2hlRmlsZQkqZjsKICAgIGludAkJCWg7CiAgICBpbnQJCQlkaXJfbGVuOwogICAgRmNHbG9iYWxDYWNoZVN1YmRpcgkqc3ViZGlyOwogICAgRmNCb29sCQlhbnlfaW5fY2FjaGUgPSBGY0ZhbHNlOwoKICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCJGY0dsb2JhbENhY2hlU2NhbkRpciAlc1xuIiwgZGlyKTsKICAgIAogICAgaWYgKCFkKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiXHRObyBkaXIgY2FjaGUgZW50cnlcbiIpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CgogICAgLyoKICAgICAqIFNlZSBpZiB0aGUgdGltZXN0YW1wIHJlY29yZGVkIGluIHRoZSBnbG9iYWwgY2FjaGUKICAgICAqIG1hdGNoZXMgdGhlIGRpcmVjdG9yeSB0aW1lLCBpZiBub3QsIHJldHVybiBGYWxzZQogICAgICovCiAgICBpZiAoIUZjR2xvYmFsQ2FjaGVDaGVja1RpbWUgKGQtPmluZm8uZmlsZSwgJmQtPmluZm8pKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiXHRkaXIgY2FjaGUgZW50cnkgdGltZSBtaXNtYXRjaFxuIik7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KCiAgICAvKgogICAgICogQWRkIGZpbGVzIGZyb20gJ2RpcicgdG8gdGhlIGZvbnRzZXQKICAgICAqLwogICAgZGlyX2xlbiA9IHN0cmxlbiAoKGNvbnN0IGNoYXIgKikgZGlyKTsKICAgIGZvciAoaCA9IDA7IGggPCBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkU7IGgrKykKCWZvciAoZiA9IGQtPmVudHNbaF07IGY7IGYgPSBmLT5uZXh0KQoJewoJICAgIGlmIChGY0RlYnVnKCkgJiBGQ19EQkdfQ0FDSEVWKQoJCXByaW50ZiAoIkZjR2xvYmFsQ2FjaGVTY2FuRGlyIGFkZCBmaWxlICVzXG4iLCBmLT5pbmZvLmZpbGUpOwoJICAgIGFueV9pbl9jYWNoZSA9IEZjVHJ1ZTsKCSAgICBpZiAoIUZjQ2FjaGVGb250U2V0QWRkIChzZXQsIGRpcnMsIGRpciwgZGlyX2xlbiwKCQkJCSAgICBmLT5pbmZvLmZpbGUsIGYtPm5hbWUsIGNvbmZpZykpCgkgICAgewoJCWNhY2hlLT5icm9rZW4gPSBGY1RydWU7CgkJcmV0dXJuIEZjRmFsc2U7CgkgICAgfQoJICAgIEZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgJmYtPmluZm8pOwoJfQogICAgLyoKICAgICAqIEFkZCBkaXJlY3RvcmllcyBpbiAnZGlyJyB0byAnZGlycycKICAgICAqLwogICAgZm9yIChzdWJkaXIgPSBkLT5zdWJkaXJzOyBzdWJkaXI7IHN1YmRpciA9IHN1YmRpci0+bmV4dCkKICAgIHsKCUZjRmlsZVBhdGhJbmZvCWluZm8gPSBGY0ZpbGVQYXRoSW5mb0dldCAoc3ViZGlyLT5lbnQtPmluZm8uZmlsZSk7CgkKICAgICAgICBhbnlfaW5fY2FjaGUgPSBGY1RydWU7CglpZiAoIUZjQ2FjaGVGb250U2V0QWRkIChzZXQsIGRpcnMsIGRpciwgZGlyX2xlbiwKCQkJCWluZm8uYmFzZSwgRkNfRk9OVF9GSUxFX0RJUiwgY29uZmlnKSkKCXsKCSAgICBjYWNoZS0+YnJva2VuID0gRmNUcnVlOwoJICAgIHJldHVybiBGY0ZhbHNlOwoJfQoJRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKGNhY2hlLCAmc3ViZGlyLT5lbnQtPmluZm8pOwogICAgfQogICAgCiAgICBGY0dsb2JhbENhY2hlUmVmZXJlbmNlZCAoY2FjaGUsICZkLT5pbmZvKTsKCiAgICAvKgogICAgICogVG8gcmVjb3ZlciBmcm9tIGEgYnVnIGluIHByZXZpb3VzIHZlcnNpb25zIG9mIGZvbnRjb25maWcsCiAgICAgKiByZXR1cm4gRmNGYWxzZSBpZiBubyBlbnRyaWVzIGluIHRoZSBjYWNoZSB3ZXJlIGZvdW5kCiAgICAgKiBmb3IgdGhpcyBkaXJlY3RvcnkuICBUaGlzIHdpbGwgY2F1c2UgYW55IGVtcHR5IGRpcmVjdG9yaWVzCiAgICAgKiB0byBnZXQgcmVzY2FubmVkIGV2ZXJ5IHRpbWUgZm9udGNvbmZpZyBpcyBpbml0aWFsaXplZC4gIFRoaXMKICAgICAqIG1pZ2h0IGdldCByZW1vdmVkIGF0IHNvbWUgcG9pbnQgd2hlbiB0aGUgb2xkZXIgY2FjaGUgZmlsZXMgYXJlCiAgICAgKiBwcmVzdW1hYmx5IGZpeGVkLgogICAgICovCiAgICByZXR1cm4gYW55X2luX2NhY2hlOwp9CgovKgogKiBMb2NhdGUgdGhlIGNhY2hlIGVudHJ5IGZvciBhIHBhcnRpY3VsYXIgZmlsZQogKi8KRmNHbG9iYWxDYWNoZUZpbGUgKgpGY0dsb2JhbENhY2hlRmlsZUdldCAoRmNHbG9iYWxDYWNoZSAqY2FjaGUsCgkJICAgICAgY29uc3QgRmNDaGFyOCAqZmlsZSwKCQkgICAgICBpbnQJICAgIGlkLAoJCSAgICAgIGludAkgICAgKmNvdW50KQp7CiAgICBGY0ZpbGVQYXRoSW5mbwlpID0gRmNGaWxlUGF0aEluZm9HZXQgKGZpbGUpOwogICAgRmNHbG9iYWxDYWNoZURpcgkqZCA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBpLmRpciwgCgkJCQkJCSAgaS5kaXJfbGVuLCBGY0ZhbHNlKTsKICAgIEZjR2xvYmFsQ2FjaGVGaWxlCSpmLCAqbWF0Y2ggPSAwOwogICAgaW50CQkJbWF4ID0gLTE7CgogICAgaWYgKCFkKQoJcmV0dXJuIDA7CiAgICBmb3IgKGYgPSBkLT5lbnRzW2kuYmFzZV9oYXNoICUgRkNfR0xPQkFMX0NBQ0hFX0ZJTEVfSEFTSF9TSVpFXTsgZjsgZiA9IGYtPm5leHQpCiAgICB7CglpZiAoZi0+aW5mby5oYXNoID09IGkuYmFzZV9oYXNoICYmCgkgICAgIXN0cmNtcCAoKGNvbnN0IGNoYXIgKikgZi0+aW5mby5maWxlLCAoY29uc3QgY2hhciAqKSBpLmJhc2UpKQoJewoJICAgIGlmIChmLT5pZCA9PSBpZCkKCQltYXRjaCA9IGY7CgkgICAgaWYgKGYtPmlkID4gbWF4KQoJCW1heCA9IGYtPmlkOwoJfQogICAgfQogICAgaWYgKGNvdW50KQoJKmNvdW50ID0gbWF4ICsgMTsKICAgIHJldHVybiBtYXRjaDsKfQogICAgCi8qCiAqIEFkZCBhIGZpbGUgZW50cnkgdG8gdGhlIGNhY2hlCiAqLwpzdGF0aWMgRmNHbG9iYWxDYWNoZUluZm8gKgpGY0dsb2JhbENhY2hlRmlsZUFkZCAoRmNHbG9iYWxDYWNoZSAqY2FjaGUsCgkJICAgICAgY29uc3QgRmNDaGFyOCAqcGF0aCwKCQkgICAgICBpbnQJICAgIGlkLAoJCSAgICAgIHRpbWVfdAkgICAgdGltZSwKCQkgICAgICBjb25zdCBGY0NoYXI4ICpuYW1lLAoJCSAgICAgIEZjQm9vbAkgICAgcmVwbGFjZSkKewogICAgRmNGaWxlUGF0aEluZm8JaSA9IEZjRmlsZVBhdGhJbmZvR2V0IChwYXRoKTsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQgPSBGY0dsb2JhbENhY2hlRGlyR2V0IChjYWNoZSwgaS5kaXIsIAoJCQkJCQkgIGkuZGlyX2xlbiwgRmNUcnVlKTsKICAgIEZjR2xvYmFsQ2FjaGVGaWxlCSpmLCAqKnByZXY7CiAgICBpbnQJCQlzaXplOwoKICAgIGlmICghZCkKCXJldHVybiAwOwogICAgZm9yIChwcmV2ID0gJmQtPmVudHNbaS5iYXNlX2hhc2ggJSBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkVdOwoJIChmID0gKnByZXYpOwoJIHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKICAgIHsKCWlmIChmLT5pbmZvLmhhc2ggPT0gaS5iYXNlX2hhc2ggJiYgCgkgICAgZi0+aWQgPT0gaWQgJiYKCSAgICAhc3RyY21wICgoY29uc3QgY2hhciAqKSBmLT5pbmZvLmZpbGUsIChjb25zdCBjaGFyICopIGkuYmFzZSkpCgl7CgkgICAgYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAoKnByZXYpCiAgICB7CglpZiAoIXJlcGxhY2UpCgkgICAgcmV0dXJuIDA7CgoJZiA9ICpwcmV2OwoJaWYgKGYtPmluZm8ucmVmZXJlbmNlZCkKCSAgICBjYWNoZS0+cmVmZXJlbmNlZC0tOwoJKnByZXYgPSBmLT5uZXh0OwoJRmNNZW1GcmVlIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZUZpbGUpICsKCQkgICBzdHJsZW4gKChjaGFyICopIGYtPmluZm8uZmlsZSkgKyAxICsKCQkgICBzdHJsZW4gKChjaGFyICopIGYtPm5hbWUpICsgMSk7CglmcmVlIChmKTsKICAgIH0KICAgIHNpemUgPSAoc2l6ZW9mIChGY0dsb2JhbENhY2hlRmlsZSkgKwoJICAgIHN0cmxlbiAoKGNoYXIgKikgaS5iYXNlKSArIDEgKwoJICAgIHN0cmxlbiAoKGNoYXIgKikgbmFtZSkgKyAxKTsKICAgIGYgPSBtYWxsb2MgKHNpemUpOwogICAgaWYgKCFmKQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fQ0FDSEUsIHNpemUpOwogICAgZi0+bmV4dCA9ICpwcmV2OwogICAgKnByZXYgPSBmOwogICAgZi0+aW5mby5oYXNoID0gaS5iYXNlX2hhc2g7CiAgICBmLT5pbmZvLmZpbGUgPSAoRmNDaGFyOCAqKSAoZiArIDEpOwogICAgZi0+aW5mby50aW1lID0gdGltZTsKICAgIGYtPmluZm8ucmVmZXJlbmNlZCA9IEZjRmFsc2U7CiAgICBmLT5pZCA9IGlkOwogICAgZi0+bmFtZSA9IGYtPmluZm8uZmlsZSArIHN0cmxlbiAoKGNoYXIgKikgaS5iYXNlKSArIDE7CiAgICBzdHJjcHkgKChjaGFyICopIGYtPmluZm8uZmlsZSwgKGNvbnN0IGNoYXIgKikgaS5iYXNlKTsKICAgIHN0cmNweSAoKGNoYXIgKikgZi0+bmFtZSwgKGNvbnN0IGNoYXIgKikgbmFtZSk7CiAgICByZXR1cm4gJmYtPmluZm87Cn0KCkZjR2xvYmFsQ2FjaGUgKgpGY0dsb2JhbENhY2hlQ3JlYXRlICh2b2lkKQp7CiAgICBGY0dsb2JhbENhY2hlICAgKmNhY2hlOwogICAgaW50CQkgICAgaDsKCiAgICBjYWNoZSA9IG1hbGxvYyAoc2l6ZW9mIChGY0dsb2JhbENhY2hlKSk7CiAgICBpZiAoIWNhY2hlKQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fQ0FDSEUsIHNpemVvZiAoRmNHbG9iYWxDYWNoZSkpOwogICAgZm9yIChoID0gMDsgaCA8IEZDX0dMT0JBTF9DQUNIRV9ESVJfSEFTSF9TSVpFOyBoKyspCgljYWNoZS0+ZW50c1toXSA9IDA7CiAgICBjYWNoZS0+ZW50cmllcyA9IDA7CiAgICBjYWNoZS0+cmVmZXJlbmNlZCA9IDA7CiAgICBjYWNoZS0+dXBkYXRlZCA9IEZjRmFsc2U7CiAgICBjYWNoZS0+YnJva2VuID0gRmNGYWxzZTsKICAgIHJldHVybiBjYWNoZTsKfQoKdm9pZApGY0dsb2JhbENhY2hlRGVzdHJveSAoRmNHbG9iYWxDYWNoZSAqY2FjaGUpCnsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQsICpuZXh0OwogICAgaW50CQkJaDsKCiAgICBmb3IgKGggPSAwOyBoIDwgRkNfR0xPQkFMX0NBQ0hFX0RJUl9IQVNIX1NJWkU7IGgrKykKICAgIHsKCWZvciAoZCA9IGNhY2hlLT5lbnRzW2hdOyBkOyBkID0gbmV4dCkKCXsKCSAgICBuZXh0ID0gZC0+bmV4dDsKCSAgICBGY0dsb2JhbENhY2hlRGlyRGVzdHJveSAoZCk7Cgl9CiAgICB9CiAgICBGY01lbUZyZWUgKEZDX01FTV9DQUNIRSwgc2l6ZW9mIChGY0dsb2JhbENhY2hlKSk7CiAgICBmcmVlIChjYWNoZSk7Cn0KCi8qCiAqIENhY2hlIGZpbGUgc3ludGF4IGlzIHF1aXRlIHNpbXBsZToKICoKICogImZpbGVfbmFtZSIgaWQgdGltZSAiZm9udF9uYW1lIiBcbgogKi8KIAp2b2lkCkZjR2xvYmFsQ2FjaGVMb2FkIChGY0dsb2JhbENhY2hlICAgICpjYWNoZSwKCQkgICBjb25zdCBGY0NoYXI4ICAgICpjYWNoZV9maWxlKQp7CiAgICBGSUxFCQkqZjsKICAgIEZjQ2hhcjgJCWZpbGVfYnVmWzgxOTJdLCAqZmlsZTsKICAgIGludAkJCWlkOwogICAgdGltZV90CQl0aW1lOwogICAgRmNDaGFyOAkJbmFtZV9idWZbODE5Ml0sICpuYW1lOwogICAgRmNHbG9iYWxDYWNoZUluZm8JKmluZm87CgogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAiciIpOwogICAgaWYgKCFmKQoJcmV0dXJuOwoKICAgIGNhY2hlLT51cGRhdGVkID0gRmNGYWxzZTsKICAgIGZpbGUgPSAwOwogICAgbmFtZSA9IDA7CiAgICB3aGlsZSAoKGZpbGUgPSBGY0NhY2hlUmVhZFN0cmluZyAoZiwgZmlsZV9idWYsIHNpemVvZiAoZmlsZV9idWYpKSkgJiYKCSAgIEZjQ2FjaGVSZWFkSW50IChmLCAmaWQpICYmCgkgICBGY0NhY2hlUmVhZFRpbWUgKGYsICZ0aW1lKSAmJgoJICAgKG5hbWUgPSBGY0NhY2hlUmVhZFN0cmluZyAoZiwgbmFtZV9idWYsIHNpemVvZiAobmFtZV9idWYpKSkpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRVYpCgkgICAgcHJpbnRmICgiRmNHbG9iYWxDYWNoZUxvYWQgXCIlc1wiIFwiJTIwLjIwc1wiXG4iLCBmaWxlLCBuYW1lKTsKCWlmICghRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9ESVIpKQoJICAgIGluZm8gPSBGY0dsb2JhbENhY2hlRGlyQWRkIChjYWNoZSwgZmlsZSwgdGltZSwgRmNGYWxzZSwgRmNUcnVlKTsKCWVsc2UKCSAgICBpbmZvID0gRmNHbG9iYWxDYWNoZUZpbGVBZGQgKGNhY2hlLCBmaWxlLCBpZCwgdGltZSwgbmFtZSwgRmNGYWxzZSk7CglpZiAoIWluZm8pCgkgICAgY2FjaGUtPmJyb2tlbiA9IEZjVHJ1ZTsKCWVsc2UKCSAgICBjYWNoZS0+ZW50cmllcysrOwoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVfUkVGKQoJICAgIHByaW50ZiAoIkZjR2xvYmFsQ2FjaGVMb2FkIGVudHJ5ICVkICVzXG4iLAoJCSAgICBjYWNoZS0+ZW50cmllcywgZmlsZSk7CglpZiAoZmlsZSAhPSBmaWxlX2J1ZikKCSAgICBmcmVlIChmaWxlKTsKCWlmIChuYW1lICE9IG5hbWVfYnVmKQoJICAgIGZyZWUgKG5hbWUpOwoJZmlsZSA9IDA7CgluYW1lID0gMDsKICAgIH0KICAgIGlmIChmaWxlICYmIGZpbGUgIT0gZmlsZV9idWYpCglmcmVlIChmaWxlKTsKICAgIGlmIChuYW1lICYmIG5hbWUgIT0gbmFtZV9idWYpCglmcmVlIChuYW1lKTsKICAgIGZjbG9zZSAoZik7Cn0KCkZjQm9vbApGY0dsb2JhbENhY2hlVXBkYXRlIChGY0dsb2JhbENhY2hlICAqY2FjaGUsCgkJICAgICBjb25zdCBGY0NoYXI4ICAqZmlsZSwKCQkgICAgIGludAkgICAgaWQsCgkJICAgICBjb25zdCBGY0NoYXI4ICAqbmFtZSkKewogICAgY29uc3QgRmNDaGFyOAkqbWF0Y2g7CiAgICBzdHJ1Y3Qgc3RhdAkJc3RhdGI7CiAgICBGY0dsb2JhbENhY2hlSW5mbwkqaW5mbzsKCiAgICBtYXRjaCA9IGZpbGU7CgogICAgaWYgKHN0YXQgKChjaGFyICopIGZpbGUsICZzdGF0YikgPCAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoU19JU0RJUiAoc3RhdGIuc3RfbW9kZSkpCglpbmZvID0gRmNHbG9iYWxDYWNoZURpckFkZCAoY2FjaGUsIGZpbGUsIHN0YXRiLnN0X210aW1lLCAKCQkJCSAgICBGY1RydWUsIEZjVHJ1ZSk7CiAgICBlbHNlCglpbmZvID0gRmNHbG9iYWxDYWNoZUZpbGVBZGQgKGNhY2hlLCBmaWxlLCBpZCwgc3RhdGIuc3RfbXRpbWUsIAoJCQkJICAgIG5hbWUsIEZjVHJ1ZSk7CiAgICBpZiAoaW5mbykKICAgIHsKCUZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgaW5mbyk7CgljYWNoZS0+dXBkYXRlZCA9IEZjVHJ1ZTsKICAgIH0KICAgIGVsc2UKCWNhY2hlLT5icm9rZW4gPSBGY1RydWU7CiAgICByZXR1cm4gaW5mbyAhPSAwOwp9CgpGY0Jvb2wKRmNHbG9iYWxDYWNoZVNhdmUgKEZjR2xvYmFsQ2FjaGUgICAgKmNhY2hlLAoJCSAgIGNvbnN0IEZjQ2hhcjggICAgKmNhY2hlX2ZpbGUpCnsKICAgIEZJTEUJCSpmOwogICAgaW50CQkJZGlyX2hhc2gsIGZpbGVfaGFzaDsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmRpcjsKICAgIEZjR2xvYmFsQ2FjaGVGaWxlCSpmaWxlOwogICAgRmNBdG9taWMJCSphdG9taWM7CgogICAgaWYgKCFjYWNoZS0+dXBkYXRlZCAmJiBjYWNoZS0+cmVmZXJlbmNlZCA9PSBjYWNoZS0+ZW50cmllcykKCXJldHVybiBGY1RydWU7CiAgICAKICAgIGlmIChjYWNoZS0+YnJva2VuKQoJcmV0dXJuIEZjRmFsc2U7CgojaWYgZGVmaW5lZCAoSEFWRV9HRVRVSUQpICYmIGRlZmluZWQgKEhBVkVfR0VURVVJRCkKICAgIC8qIFNldC1VSUQgcHJvZ3JhbXMgY2FuJ3Qgc2FmZWx5IHVwZGF0ZSB0aGUgY2FjaGUgKi8KICAgIGlmIChnZXR1aWQgKCkgIT0gZ2V0ZXVpZCAoKSkKCXJldHVybiBGY0ZhbHNlOwojZW5kaWYKICAgIAogICAgYXRvbWljID0gRmNBdG9taWNDcmVhdGUgKGNhY2hlX2ZpbGUpOwogICAgaWYgKCFhdG9taWMpCglnb3RvIGJhaWwwOwogICAgaWYgKCFGY0F0b21pY0xvY2sgKGF0b21pYykpCglnb3RvIGJhaWwxOwogICAgZiA9IGZvcGVuICgoY2hhciAqKSBGY0F0b21pY05ld0ZpbGUoYXRvbWljKSwgInciKTsKICAgIGlmICghZikKCWdvdG8gYmFpbDI7CgogICAgZm9yIChkaXJfaGFzaCA9IDA7IGRpcl9oYXNoIDwgRkNfR0xPQkFMX0NBQ0hFX0RJUl9IQVNIX1NJWkU7IGRpcl9oYXNoKyspCiAgICB7Cglmb3IgKGRpciA9IGNhY2hlLT5lbnRzW2Rpcl9oYXNoXTsgZGlyOyBkaXIgPSBkaXItPm5leHQpCgl7CgkgICAgaWYgKCFkaXItPmluZm8ucmVmZXJlbmNlZCkKCQljb250aW51ZTsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgZGlyLT5pbmZvLmZpbGUpKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIDApKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKCFGY0NhY2hlV3JpdGVUaW1lIChmLCBkaXItPmluZm8udGltZSkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgKEZjQ2hhcjggKikgRkNfRk9OVF9GSUxFX0RJUikpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoUFVUQyAoJ1xuJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgCgkgICAgZm9yIChmaWxlX2hhc2ggPSAwOyBmaWxlX2hhc2ggPCBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkU7IGZpbGVfaGFzaCsrKQoJICAgIHsKCQlmb3IgKGZpbGUgPSBkaXItPmVudHNbZmlsZV9oYXNoXTsgZmlsZTsgZmlsZSA9IGZpbGUtPm5leHQpCgkJewoJCSAgICBpZiAoIWZpbGUtPmluZm8ucmVmZXJlbmNlZCkKCQkJY29udGludWU7CgkJICAgIGlmICghRmNDYWNoZVdyaXRlUGF0aCAoZiwgZGlyLT5pbmZvLmZpbGUsIGZpbGUtPmluZm8uZmlsZSkpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIGZpbGUtPmlkIDwgMCA/IDAgOiBmaWxlLT5pZCkpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVUaW1lIChmLCBmaWxlLT5pbmZvLnRpbWUpKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBmaWxlLT5uYW1lKSkKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKFBVVEMgKCdcbicsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQl9CgkgICAgfQoJfQogICAgfQoKICAgIGlmIChmY2xvc2UgKGYpID09IEVPRikKCWdvdG8gYmFpbDM7CiAgICAKICAgIGlmICghRmNBdG9taWNSZXBsYWNlT3JpZyAoYXRvbWljKSkKCWdvdG8gYmFpbDM7CiAgICAKICAgIEZjQXRvbWljVW5sb2NrIChhdG9taWMpOwogICAgRmNBdG9taWNEZXN0cm95IChhdG9taWMpOwoKICAgIGNhY2hlLT51cGRhdGVkID0gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7CgpiYWlsNDoKICAgIGZjbG9zZSAoZik7CmJhaWwzOgogICAgRmNBdG9taWNEZWxldGVOZXcgKGF0b21pYyk7CmJhaWwyOgogICAgRmNBdG9taWNVbmxvY2sgKGF0b21pYyk7CmJhaWwxOgogICAgRmNBdG9taWNEZXN0cm95IChhdG9taWMpOwpiYWlsMDoKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpGY0Jvb2wKRmNEaXJDYWNoZVZhbGlkIChjb25zdCBGY0NoYXI4ICpkaXIpCnsKICAgIEZjQ2hhcjgJKmNhY2hlX2ZpbGUgPSBGY1N0clBsdXMgKGRpciwgKEZjQ2hhcjggKikgIi8iIEZDX0RJUl9DQUNIRV9GSUxFKTsKICAgIHN0cnVjdCBzdGF0CWZpbGVfc3RhdCwgZGlyX3N0YXQ7CgogICAgaWYgKHN0YXQgKChjaGFyICopIGRpciwgJmRpcl9zdGF0KSA8IDApCiAgICB7CglGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoc3RhdCAoKGNoYXIgKikgY2FjaGVfZmlsZSwgJmZpbGVfc3RhdCkgPCAwKQogICAgewoJRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKICAgIC8qCiAgICAgKiBJZiB0aGUgZGlyZWN0b3J5IGhhcyBiZWVuIG1vZGlmaWVkIG1vcmUgcmVjZW50bHkgdGhhbgogICAgICogdGhlIGNhY2hlIGZpbGUsIHRoZSBjYWNoZSBpcyBub3QgdmFsaWQKICAgICAqLwogICAgaWYgKGRpcl9zdGF0LnN0X210aW1lIC0gZmlsZV9zdGF0LnN0X210aW1lID4gMCkKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjRGlyQ2FjaGVSZWFkRGlyIChGY0ZvbnRTZXQgKnNldCwgRmNTdHJTZXQgKmRpcnMsIGNvbnN0IEZjQ2hhcjggKmRpciwgRmNDb25maWcgKmNvbmZpZykKewogICAgRmNDaGFyOAkgICAgKmNhY2hlX2ZpbGUgPSBGY1N0clBsdXMgKGRpciwgKEZjQ2hhcjggKikgIi8iIEZDX0RJUl9DQUNIRV9GSUxFKTsKICAgIEZJTEUJICAgICpmOwogICAgRmNDaGFyOAkgICAgKmJhc2U7CiAgICBpbnQJCSAgICBpZDsKICAgIGludAkJICAgIGRpcl9sZW47CiAgICBGY0NoYXI4CSAgICBmaWxlX2J1Zls4MTkyXSwgKmZpbGU7CiAgICBGY0NoYXI4CSAgICBuYW1lX2J1Zls4MTkyXSwgKm5hbWU7CiAgICBGY0Jvb2wJICAgIHJldCA9IEZjRmFsc2U7CgogICAgaWYgKCFjYWNoZV9maWxlKQoJZ290byBiYWlsMDsKICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCJGY0RpckNhY2hlUmVhZERpciBjYWNoZV9maWxlIFwiJXNcIlxuIiwgY2FjaGVfZmlsZSk7CiAgICAKICAgIGYgPSBmb3BlbiAoKGNoYXIgKikgY2FjaGVfZmlsZSwgInIiKTsKICAgIGlmICghZikKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJICAgIHByaW50ZiAoIiBubyBjYWNoZSBmaWxlXG4iKTsKCWdvdG8gYmFpbDE7CiAgICB9CgogICAgaWYgKCFGY0RpckNhY2hlVmFsaWQgKGRpcikpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgY2FjaGUgZmlsZSBvbGRlciB0aGFuIGRpcmVjdG9yeVxuIik7Cglnb3RvIGJhaWwyOwogICAgfQogICAgCiAgICBiYXNlID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNoYXIgKikgY2FjaGVfZmlsZSwgJy8nKTsKICAgIGlmICghYmFzZSkKCWdvdG8gYmFpbDI7CiAgICBiYXNlKys7CiAgICBkaXJfbGVuID0gYmFzZSAtIGNhY2hlX2ZpbGU7CiAgICAKICAgIGZpbGUgPSAwOwogICAgbmFtZSA9IDA7CiAgICB3aGlsZSAoKGZpbGUgPSBGY0NhY2hlUmVhZFN0cmluZyAoZiwgZmlsZV9idWYsIHNpemVvZiAoZmlsZV9idWYpKSkgJiYKCSAgIEZjQ2FjaGVSZWFkSW50IChmLCAmaWQpICYmCgkgICAobmFtZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBuYW1lX2J1Ziwgc2l6ZW9mIChuYW1lX2J1ZikpKSkKICAgIHsKCWlmICghRmNDYWNoZUZvbnRTZXRBZGQgKHNldCwgZGlycywgY2FjaGVfZmlsZSwgZGlyX2xlbiwKCQkJCWZpbGUsIG5hbWUsIGNvbmZpZykpCgkgICAgZ290byBiYWlsMzsKCWlmIChmaWxlICE9IGZpbGVfYnVmKQoJICAgIGZyZWUgKGZpbGUpOwoJaWYgKG5hbWUgIT0gbmFtZV9idWYpCgkgICAgZnJlZSAobmFtZSk7CglmaWxlID0gbmFtZSA9IDA7CiAgICB9CiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIiBjYWNoZSBsb2FkZWRcbiIpOwogICAgCiAgICByZXQgPSBGY1RydWU7CmJhaWwzOgogICAgaWYgKGZpbGUgJiYgZmlsZSAhPSBmaWxlX2J1ZikKCWZyZWUgKGZpbGUpOwogICAgaWYgKG5hbWUgJiYgbmFtZSAhPSBuYW1lX2J1ZikKCWZyZWUgKG5hbWUpOwpiYWlsMjoKICAgIGZjbG9zZSAoZik7CmJhaWwxOgogICAgRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKYmFpbDA6CiAgICByZXR1cm4gcmV0Owp9CgovKgogKiByZXR1cm4gdGhlIHBhdGggZnJvbSB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgJ2NhY2hlJyB0byAnZmlsZScKICovCgpzdGF0aWMgY29uc3QgRmNDaGFyOCAqCkZjRmlsZUJhc2VOYW1lIChjb25zdCBGY0NoYXI4ICpjYWNoZSwgY29uc3QgRmNDaGFyOCAqZmlsZSkKewogICAgY29uc3QgRmNDaGFyOCAgICpjYWNoZV9zbGFzaDsKCiAgICBjYWNoZV9zbGFzaCA9IEZjU3RyTGFzdFNsYXNoIChjYWNoZSk7CiAgICBpZiAoY2FjaGVfc2xhc2ggJiYgIXN0cm5jbXAgKChjb25zdCBjaGFyICopIGNhY2hlLCAoY29uc3QgY2hhciAqKSBmaWxlLAoJCQkJIChjYWNoZV9zbGFzaCArIDEpIC0gY2FjaGUpKQoJcmV0dXJuIGZpbGUgKyAoKGNhY2hlX3NsYXNoICsgMSkgLSBjYWNoZSk7CiAgICByZXR1cm4gZmlsZTsKfQoKRmNCb29sCkZjRGlyQ2FjaGVXcml0ZURpciAoRmNGb250U2V0ICpzZXQsIEZjU3RyU2V0ICpkaXJzLCBjb25zdCBGY0NoYXI4ICpkaXIpCnsKICAgIEZjQ2hhcjgJICAgICpjYWNoZV9maWxlID0gRmNTdHJQbHVzIChkaXIsIChGY0NoYXI4ICopICIvIiBGQ19ESVJfQ0FDSEVfRklMRSk7CiAgICBGY1BhdHRlcm4JICAgICpmb250OwogICAgRklMRQkgICAgKmY7CiAgICBGY0NoYXI4CSAgICAqbmFtZTsKICAgIGNvbnN0IEZjQ2hhcjggICAqZmlsZSwgKmJhc2U7CiAgICBpbnQJCSAgICBuOwogICAgaW50CQkgICAgaWQ7CiAgICBGY0Jvb2wJICAgIHJldDsKICAgIEZjU3RyTGlzdAkgICAgKmxpc3Q7CgogICAgaWYgKCFjYWNoZV9maWxlKQoJZ290byBiYWlsMDsKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJcHJpbnRmICgiRmNEaXJDYWNoZVdyaXRlRGlyIGNhY2hlX2ZpbGUgXCIlc1wiXG4iLCBjYWNoZV9maWxlKTsKICAgIAogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAidyIpOwogICAgaWYgKCFmKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIGNhbid0IGNyZWF0ZSBcIiVzXCJcbiIsIGNhY2hlX2ZpbGUpOwoJZ290byBiYWlsMTsKICAgIH0KICAgIAogICAgbGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoZGlycyk7CiAgICBpZiAoIWxpc3QpCglnb3RvIGJhaWwyOwogICAgCiAgICB3aGlsZSAoKGRpciA9IEZjU3RyTGlzdE5leHQgKGxpc3QpKSkKICAgIHsKCWJhc2UgPSBGY0ZpbGVCYXNlTmFtZSAoY2FjaGVfZmlsZSwgZGlyKTsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBiYXNlKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgMCkpCgkgICAgZ290byBiYWlsMzsKICAgICAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkgICAgZ290byBiYWlsMzsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBGQ19GT05UX0ZJTEVfRElSKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKFBVVEMgKCdcbicsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwogICAgfQogICAgCiAgICBmb3IgKG4gPSAwOyBuIDwgc2V0LT5uZm9udDsgbisrKQogICAgewoJZm9udCA9IHNldC0+Zm9udHNbbl07CglpZiAoRmNQYXR0ZXJuR2V0U3RyaW5nIChmb250LCBGQ19GSUxFLCAwLCAoRmNDaGFyOCAqKikgJmZpbGUpICE9IEZjUmVzdWx0TWF0Y2gpCgkgICAgZ290byBiYWlsMzsKCWJhc2UgPSBGY0ZpbGVCYXNlTmFtZSAoY2FjaGVfZmlsZSwgZmlsZSk7CglpZiAoRmNQYXR0ZXJuR2V0SW50ZWdlciAoZm9udCwgRkNfSU5ERVgsIDAsICZpZCkgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIiB3cml0ZSBmaWxlIFwiJXNcIlxuIiwgYmFzZSk7CglpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgYmFzZSkpCgkgICAgZ290byBiYWlsMzsKCWlmIChQVVRDICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIGlkKSkKCSAgICBnb3RvIGJhaWwzOwogICAgICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJbmFtZSA9IEZjTmFtZVVucGFyc2UgKGZvbnQpOwoJaWYgKCFuYW1lKQoJICAgIGdvdG8gYmFpbDM7CglyZXQgPSBGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIG5hbWUpOwoJRmNTdHJGcmVlIChuYW1lKTsKCWlmICghcmV0KQoJICAgIGdvdG8gYmFpbDM7CglpZiAoUFVUQyAoJ1xuJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CiAgICB9CiAgICAKICAgIEZjU3RyTGlzdERvbmUgKGxpc3QpOwoKICAgIGlmIChmY2xvc2UgKGYpID09IEVPRikKCWdvdG8gYmFpbDE7CiAgICAKICAgIEZjU3RyRnJlZSAoY2FjaGVfZmlsZSk7CgogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCIgY2FjaGUgd3JpdHRlblxuIik7CiAgICByZXR1cm4gRmNUcnVlOwogICAgCmJhaWwzOgogICAgRmNTdHJMaXN0RG9uZSAobGlzdCk7CmJhaWwyOgogICAgZmNsb3NlIChmKTsKYmFpbDE6CiAgICB1bmxpbmsgKChjaGFyICopIGNhY2hlX2ZpbGUpOwogICAgRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQo=