LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2Rpci5jLHYgMS41IDIwMDIvMDUvMjEgMTc6MDY6MjIga2VpdGhwIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDAgS2VpdGggUGFja2FyZCwgbWVtYmVyIG9mIFRoZSBYRnJlZTg2IFByb2plY3QsIEluYy4KICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJmY2ludC5oIgojaW5jbHVkZSA8ZGlyZW50Lmg+CgpzdGF0aWMgRmNCb29sCkZjRmlsZUlzRGlyIChjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBzdHJ1Y3Qgc3RhdAkgICAgc3RhdGI7CgogICAgaWYgKHN0YXQgKChjb25zdCBjaGFyICopIGZpbGUsICZzdGF0YikgIT0gMCkKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIFNfSVNESVIoc3RhdGIuc3RfbW9kZSk7Cn0KCkZjQm9vbApGY0ZpbGVTY2FuIChGY0ZvbnRTZXQJICAgICpzZXQsCgkgICAgRmNTdHJTZXQJICAgICpkaXJzLAoJICAgIEZjR2xvYmFsQ2FjaGUgICAqY2FjaGUsCgkgICAgRmNCbGFua3MJICAgICpibGFua3MsCgkgICAgY29uc3QgRmNDaGFyOCAgICpmaWxlLAoJICAgIEZjQm9vbAkgICAgZm9yY2UpCnsKICAgIGludAkJCWlkOwogICAgRmNDaGFyOAkJKm5hbWU7CiAgICBGY1BhdHRlcm4JCSpmb250OwogICAgRmNCb29sCQlyZXQgPSBGY1RydWU7CiAgICBGY0Jvb2wJCWlzRGlyOwogICAgaW50CQkJY291bnQgPSAwOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmNhY2hlX2ZpbGU7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpjYWNoZV9kaXI7CiAgICBGY0Jvb2wJCW5lZWRfc2NhbjsKICAgIAogICAgaWYgKGZvcmNlKQoJY2FjaGUgPSAwOwogICAgaWQgPSAwOwogICAgZG8KICAgIHsKCW5lZWRfc2NhbiA9IEZjVHJ1ZTsKCWZvbnQgPSAwOwoJLyoKCSAqIENoZWNrIHRoZSBjYWNoZQoJICovCglpZiAoY2FjaGUpCgl7CgkgICAgaWYgKChjYWNoZV9maWxlID0gRmNHbG9iYWxDYWNoZUZpbGVHZXQgKGNhY2hlLCBmaWxlLCBpZCwgJmNvdW50KSkpCgkgICAgewoJCS8qCgkJICogRm91bmQgYSBjYWNoZSBlbnRyeSBmb3IgdGhlIGZpbGUKCQkgKi8KCQlpZiAoRmNHbG9iYWxDYWNoZUNoZWNrVGltZSAoJmNhY2hlX2ZpbGUtPmluZm8pKQoJCXsKCQkgICAgbmFtZSA9IGNhY2hlX2ZpbGUtPm5hbWU7CgkJICAgIG5lZWRfc2NhbiA9IEZjRmFsc2U7CgkJICAgIEZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgJmNhY2hlX2ZpbGUtPmluZm8pOwoJCSAgICAvKiAiLiIgbWVhbnMgdGhlIGZpbGUgZG9lc24ndCBjb250YWluIGEgZm9udCAqLwoJCSAgICBpZiAoRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9JTlZBTElEKSAhPSAwKQoJCSAgICB7CgkJCWZvbnQgPSBGY05hbWVQYXJzZSAobmFtZSk7CgkJCWlmIChmb250KQoJCQkgICAgaWYgKCFGY1BhdHRlcm5BZGRTdHJpbmcgKGZvbnQsIEZDX0ZJTEUsIGZpbGUpKQoJCQkJcmV0ID0gRmNGYWxzZTsKCQkgICAgfQoJCX0KCSAgICB9CgkgICAgZWxzZSBpZiAoKGNhY2hlX2RpciA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBmaWxlLAoJCQkJCQkgICAgICAgc3RybGVuICgoY29uc3QgY2hhciAqKSBmaWxlKSwKCQkJCQkJICAgICAgIEZjRmFsc2UpKSkKCSAgICB7CgkJaWYgKEZjR2xvYmFsQ2FjaGVDaGVja1RpbWUgKCZjYWNoZV9kaXItPmluZm8pKQoJCXsKCQkgICAgZm9udCA9IDA7CgkJICAgIG5lZWRfc2NhbiA9IEZjRmFsc2U7CgkJICAgIEZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgJmNhY2hlX2Rpci0+aW5mbyk7CgkJICAgIGlmICghRmNTdHJTZXRBZGQgKGRpcnMsIGZpbGUpKQoJCQlyZXQgPSBGY0ZhbHNlOwoJCX0KCSAgICB9Cgl9CgkvKgoJICogTm90aGluZyBpbiB0aGUgY2FjaGUsIHNjYW4gdGhlIGZpbGUKCSAqLwoJaWYgKG5lZWRfc2NhbikKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19TQ0FOKQoJICAgIHsKCQlwcmludGYgKCJcdFNjYW5uaW5nIGZpbGUgJXMuLi4iLCBmaWxlKTsKCQlmZmx1c2ggKHN0ZG91dCk7CgkgICAgfQoJICAgIGZvbnQgPSBGY0ZyZWVUeXBlUXVlcnkgKGZpbGUsIGlkLCBibGFua3MsICZjb3VudCk7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfU0NBTikKCQlwcmludGYgKCJkb25lXG4iKTsKCSAgICBpc0RpciA9IEZjRmFsc2U7CgkgICAgaWYgKCFmb250ICYmIEZjRmlsZUlzRGlyIChmaWxlKSkKCSAgICB7CgkJaXNEaXIgPSBGY1RydWU7CgkJcmV0ID0gRmNTdHJTZXRBZGQgKGRpcnMsIGZpbGUpOwoJICAgIH0KCSAgICAvKgoJICAgICAqIFVwZGF0ZSB0aGUgY2FjaGUKCSAgICAgKi8KCSAgICBpZiAoY2FjaGUgJiYgZm9udCkKCSAgICB7CgkJRmNDaGFyOAkqdW5wYXJzZTsKCgkJdW5wYXJzZSA9IEZjTmFtZVVucGFyc2UgKGZvbnQpOwoJCWlmICh1bnBhcnNlKQoJCXsKCQkgICAgKHZvaWQpIEZjR2xvYmFsQ2FjaGVVcGRhdGUgKGNhY2hlLCBmaWxlLCBpZCwgdW5wYXJzZSk7CgkJICAgIGZyZWUgKHVucGFyc2UpOwoJCX0KCSAgICB9Cgl9CgkvKgoJICogQWRkIHRoZSBmb250CgkgKi8KCWlmIChmb250KQoJewoJICAgIGlmICghRmNGb250U2V0QWRkIChzZXQsIGZvbnQpKQoJICAgIHsKCQlGY1BhdHRlcm5EZXN0cm95IChmb250KTsKCQlmb250ID0gMDsKCQlyZXQgPSBGY0ZhbHNlOwoJICAgIH0KCX0KCWlkKys7CiAgICB9IHdoaWxlIChmb250ICYmIHJldCAmJiBpZCA8IGNvdW50KTsKICAgIHJldHVybiByZXQ7Cn0KCiNkZWZpbmUgRkNfTUFYX0ZJTEVfTEVOCSAgICA0MDk2CgpGY0Jvb2wKRmNEaXJTY2FuIChGY0ZvbnRTZXQJICAgICpzZXQsCgkgICBGY1N0clNldAkgICAgKmRpcnMsCgkgICBGY0dsb2JhbENhY2hlICAgICpjYWNoZSwKCSAgIEZjQmxhbmtzCSAgICAqYmxhbmtzLAoJICAgY29uc3QgRmNDaGFyOCAgICAqZGlyLAoJICAgRmNCb29sCSAgICBmb3JjZSkKewogICAgRElSCQkJKmQ7CiAgICBzdHJ1Y3QgZGlyZW50CSplOwogICAgRmNDaGFyOAkJKmZpbGU7CiAgICBGY0NoYXI4CQkqYmFzZTsKICAgIEZjQm9vbAkJcmV0ID0gRmNUcnVlOwoKICAgIGlmICghZm9yY2UpCiAgICB7CgkvKgoJICogQ2hlY2sgZm9udHMuY2FjaGUgZmlsZQoJICovCglpZiAoRmNEaXJDYWNoZVJlYWREaXIgKHNldCwgZGlycywgZGlyKSkKCSAgICByZXR1cm4gRmNUcnVlOwogICAgCgkvKgoJICogQ2hlY2sgfi8uZm9udHMuY2FjaGUgZmlsZQoJICovCglpZiAoY2FjaGUgJiYgRmNHbG9iYWxDYWNoZVNjYW5EaXIgKHNldCwgZGlycywgY2FjaGUsIGRpcikpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKICAgIH0KICAgIAogICAgZmlsZSA9IChGY0NoYXI4ICopIG1hbGxvYyAoc3RybGVuICgoY2hhciAqKSBkaXIpICsgMSArIEZDX01BWF9GSUxFX0xFTiArIDEpOwogICAgaWYgKCFmaWxlKQoJcmV0dXJuIEZjRmFsc2U7CgogICAgc3RyY3B5ICgoY2hhciAqKSBmaWxlLCAoY2hhciAqKSBkaXIpOwogICAgc3RyY2F0ICgoY2hhciAqKSBmaWxlLCAiLyIpOwogICAgYmFzZSA9IGZpbGUgKyBzdHJsZW4gKChjaGFyICopIGZpbGUpOwogICAgCiAgICBkID0gb3BlbmRpciAoKGNoYXIgKikgZGlyKTsKICAgIAogICAgaWYgKCFkKQogICAgewoJZnJlZSAoZmlsZSk7CgkvKiBEb24ndCBjb21wbGFpbiBhYm91dCBtaXNzaW5nIGRpcmVjdG9yaWVzICovCglpZiAoZXJybm8gPT0gRU5PRU5UKQoJICAgIHJldHVybiBGY1RydWU7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHdoaWxlIChyZXQgJiYgKGUgPSByZWFkZGlyIChkKSkpCiAgICB7CglpZiAoZS0+ZF9uYW1lWzBdICE9ICcuJyAmJiBzdHJsZW4gKGUtPmRfbmFtZSkgPCBGQ19NQVhfRklMRV9MRU4pCgl7CgkgICAgc3RyY3B5ICgoY2hhciAqKSBiYXNlLCAoY2hhciAqKSBlLT5kX25hbWUpOwoJICAgIHJldCA9IEZjRmlsZVNjYW4gKHNldCwgZGlycywgY2FjaGUsIGJsYW5rcywgZmlsZSwgZm9yY2UpOwoJfQogICAgfQogICAgZnJlZSAoZmlsZSk7CiAgICBjbG9zZWRpciAoZCk7CiAgICBpZiAocmV0ICYmIGNhY2hlKQoJRmNHbG9iYWxDYWNoZVVwZGF0ZSAoY2FjaGUsIGRpciwgMCwgMCk7CgkKICAgIHJldHVybiByZXQ7Cn0KCkZjQm9vbApGY0RpclNhdmUgKEZjRm9udFNldCAqc2V0LCBGY1N0clNldCAqZGlycywgY29uc3QgRmNDaGFyOCAqZGlyKQp7CiAgICByZXR1cm4gRmNEaXJDYWNoZVdyaXRlRGlyIChzZXQsIGRpcnMsIGRpcik7Cn0K