LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2Rpci5jLHYgMS43IDIwMDIvMDcvMjggMTA6NTA6NTkga2VpdGhwIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDAgS2VpdGggUGFja2FyZCwgbWVtYmVyIG9mIFRoZSBYRnJlZTg2IFByb2plY3QsIEluYy4KICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJmY2ludC5oIgojaW5jbHVkZSA8ZGlyZW50Lmg+CgpzdGF0aWMgRmNCb29sCkZjRmlsZUlzRGlyIChjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBzdHJ1Y3Qgc3RhdAkgICAgc3RhdGI7CgogICAgaWYgKHN0YXQgKChjb25zdCBjaGFyICopIGZpbGUsICZzdGF0YikgIT0gMCkKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIFNfSVNESVIoc3RhdGIuc3RfbW9kZSk7Cn0KCkZjQm9vbApGY0ZpbGVTY2FuIChGY0ZvbnRTZXQJICAgICpzZXQsCgkgICAgRmNTdHJTZXQJICAgICpkaXJzLAoJICAgIEZjR2xvYmFsQ2FjaGUgICAqY2FjaGUsCgkgICAgRmNCbGFua3MJICAgICpibGFua3MsCgkgICAgY29uc3QgRmNDaGFyOCAgICpmaWxlLAoJICAgIEZjQm9vbAkgICAgZm9yY2UpCnsKICAgIGludAkJCWlkOwogICAgRmNDaGFyOAkJKm5hbWU7CiAgICBGY1BhdHRlcm4JCSpmb250OwogICAgRmNCb29sCQlyZXQgPSBGY1RydWU7CiAgICBGY0Jvb2wJCWlzRGlyOwogICAgaW50CQkJY291bnQgPSAwOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmNhY2hlX2ZpbGU7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpjYWNoZV9kaXI7CiAgICBGY0Jvb2wJCW5lZWRfc2NhbjsKICAgIAogICAgaWYgKGZvcmNlKQoJY2FjaGUgPSAwOwogICAgaWQgPSAwOwogICAgZG8KICAgIHsKCW5lZWRfc2NhbiA9IEZjVHJ1ZTsKCWZvbnQgPSAwOwoJLyoKCSAqIENoZWNrIHRoZSBjYWNoZQoJICovCglpZiAoY2FjaGUpCgl7CgkgICAgaWYgKChjYWNoZV9maWxlID0gRmNHbG9iYWxDYWNoZUZpbGVHZXQgKGNhY2hlLCBmaWxlLCBpZCwgJmNvdW50KSkpCgkgICAgewoJCS8qCgkJICogRm91bmQgYSBjYWNoZSBlbnRyeSBmb3IgdGhlIGZpbGUKCQkgKi8KCQlpZiAoRmNHbG9iYWxDYWNoZUNoZWNrVGltZSAoJmNhY2hlX2ZpbGUtPmluZm8pKQoJCXsKCQkgICAgbmFtZSA9IGNhY2hlX2ZpbGUtPm5hbWU7CgkJICAgIG5lZWRfc2NhbiA9IEZjRmFsc2U7CgkJICAgIEZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgJmNhY2hlX2ZpbGUtPmluZm8pOwoJCSAgICAvKiAiLiIgbWVhbnMgdGhlIGZpbGUgZG9lc24ndCBjb250YWluIGEgZm9udCAqLwoJCSAgICBpZiAoRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9JTlZBTElEKSAhPSAwKQoJCSAgICB7CgkJCWZvbnQgPSBGY05hbWVQYXJzZSAobmFtZSk7CgkJCWlmIChmb250KQoJCQkgICAgaWYgKCFGY1BhdHRlcm5BZGRTdHJpbmcgKGZvbnQsIEZDX0ZJTEUsIGZpbGUpKQoJCQkJcmV0ID0gRmNGYWxzZTsKCQkgICAgfQoJCX0KCSAgICB9CgkgICAgZWxzZSBpZiAoKGNhY2hlX2RpciA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBmaWxlLAoJCQkJCQkgICAgICAgc3RybGVuICgoY29uc3QgY2hhciAqKSBmaWxlKSwKCQkJCQkJICAgICAgIEZjRmFsc2UpKSkKCSAgICB7CgkJaWYgKEZjR2xvYmFsQ2FjaGVDaGVja1RpbWUgKCZjYWNoZV9kaXItPmluZm8pKQoJCXsKCQkgICAgZm9udCA9IDA7CgkJICAgIG5lZWRfc2NhbiA9IEZjRmFsc2U7CgkJICAgIEZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgJmNhY2hlX2Rpci0+aW5mbyk7CgkJICAgIGlmICghRmNTdHJTZXRBZGQgKGRpcnMsIGZpbGUpKQoJCQlyZXQgPSBGY0ZhbHNlOwoJCX0KCSAgICB9Cgl9CgkvKgoJICogTm90aGluZyBpbiB0aGUgY2FjaGUsIHNjYW4gdGhlIGZpbGUKCSAqLwoJaWYgKG5lZWRfc2NhbikKCXsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19TQ0FOKQoJICAgIHsKCQlwcmludGYgKCJcdFNjYW5uaW5nIGZpbGUgJXMuLi4iLCBmaWxlKTsKCQlmZmx1c2ggKHN0ZG91dCk7CgkgICAgfQoJICAgIGZvbnQgPSBGY0ZyZWVUeXBlUXVlcnkgKGZpbGUsIGlkLCBibGFua3MsICZjb3VudCk7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfU0NBTikKCQlwcmludGYgKCJkb25lXG4iKTsKCSAgICBpc0RpciA9IEZjRmFsc2U7CgkgICAgaWYgKCFmb250ICYmIEZjRmlsZUlzRGlyIChmaWxlKSkKCSAgICB7CgkJaXNEaXIgPSBGY1RydWU7CgkJcmV0ID0gRmNTdHJTZXRBZGQgKGRpcnMsIGZpbGUpOwoJICAgIH0KCSAgICAvKgoJICAgICAqIFVwZGF0ZSB0aGUgY2FjaGUKCSAgICAgKi8KCSAgICBpZiAoY2FjaGUgJiYgZm9udCkKCSAgICB7CgkJRmNDaGFyOAkqdW5wYXJzZTsKCgkJdW5wYXJzZSA9IEZjTmFtZVVucGFyc2UgKGZvbnQpOwoJCWlmICh1bnBhcnNlKQoJCXsKCQkgICAgKHZvaWQpIEZjR2xvYmFsQ2FjaGVVcGRhdGUgKGNhY2hlLCBmaWxlLCBpZCwgdW5wYXJzZSk7CgkJICAgIGZyZWUgKHVucGFyc2UpOwoJCX0KCSAgICB9Cgl9CgkvKgoJICogQWRkIHRoZSBmb250CgkgKi8KCWlmIChmb250KQoJewoJICAgIGlmICghRmNGb250U2V0QWRkIChzZXQsIGZvbnQpKQoJICAgIHsKCQlGY1BhdHRlcm5EZXN0cm95IChmb250KTsKCQlmb250ID0gMDsKCQlyZXQgPSBGY0ZhbHNlOwoJICAgIH0KCX0KCWlkKys7CiAgICB9IHdoaWxlIChmb250ICYmIHJldCAmJiBpZCA8IGNvdW50KTsKICAgIHJldHVybiByZXQ7Cn0KCiNkZWZpbmUgRkNfTUFYX0ZJTEVfTEVOCSAgICA0MDk2CgpGY0Jvb2wKRmNEaXJTY2FuIChGY0ZvbnRTZXQJICAgICpzZXQsCgkgICBGY1N0clNldAkgICAgKmRpcnMsCgkgICBGY0dsb2JhbENhY2hlICAgICpjYWNoZSwKCSAgIEZjQmxhbmtzCSAgICAqYmxhbmtzLAoJICAgY29uc3QgRmNDaGFyOCAgICAqZGlyLAoJICAgRmNCb29sCSAgICBmb3JjZSkKewogICAgRElSCQkJKmQ7CiAgICBzdHJ1Y3QgZGlyZW50CSplOwogICAgRmNDaGFyOAkJKmZpbGU7CiAgICBGY0NoYXI4CQkqYmFzZTsKICAgIEZjQm9vbAkJcmV0ID0gRmNUcnVlOwoKICAgIGlmICghZm9yY2UpCiAgICB7CgkvKgoJICogQ2hlY2sgZm9udHMuY2FjaGUtPHZlcnNpb24+IGZpbGUKCSAqLwoJaWYgKEZjRGlyQ2FjaGVSZWFkRGlyIChzZXQsIGRpcnMsIGRpcikpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKICAgIAoJLyoKCSAqIENoZWNrIH4vLmZvbnRzLmNhY2hlLTx2ZXJzaW9uPiBmaWxlCgkgKi8KCWlmIChjYWNoZSAmJiBGY0dsb2JhbENhY2hlU2NhbkRpciAoc2V0LCBkaXJzLCBjYWNoZSwgZGlyKSkKCSAgICByZXR1cm4gRmNUcnVlOwogICAgfQogICAgCiAgICBmaWxlID0gKEZjQ2hhcjggKikgbWFsbG9jIChzdHJsZW4gKChjaGFyICopIGRpcikgKyAxICsgRkNfTUFYX0ZJTEVfTEVOICsgMSk7CiAgICBpZiAoIWZpbGUpCglyZXR1cm4gRmNGYWxzZTsKCiAgICBzdHJjcHkgKChjaGFyICopIGZpbGUsIChjaGFyICopIGRpcik7CiAgICBzdHJjYXQgKChjaGFyICopIGZpbGUsICIvIik7CiAgICBiYXNlID0gZmlsZSArIHN0cmxlbiAoKGNoYXIgKikgZmlsZSk7CiAgICAKICAgIGQgPSBvcGVuZGlyICgoY2hhciAqKSBkaXIpOwogICAgCiAgICBpZiAoIWQpCiAgICB7CglmcmVlIChmaWxlKTsKCS8qIERvbid0IGNvbXBsYWluIGFib3V0IG1pc3NpbmcgZGlyZWN0b3JpZXMgKi8KCWlmIChlcnJubyA9PSBFTk9FTlQpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgd2hpbGUgKHJldCAmJiAoZSA9IHJlYWRkaXIgKGQpKSkKICAgIHsKCWlmIChlLT5kX25hbWVbMF0gIT0gJy4nICYmIHN0cmxlbiAoZS0+ZF9uYW1lKSA8IEZDX01BWF9GSUxFX0xFTikKCXsKCSAgICBzdHJjcHkgKChjaGFyICopIGJhc2UsIChjaGFyICopIGUtPmRfbmFtZSk7CgkgICAgcmV0ID0gRmNGaWxlU2NhbiAoc2V0LCBkaXJzLCBjYWNoZSwgYmxhbmtzLCBmaWxlLCBmb3JjZSk7Cgl9CiAgICB9CiAgICBmcmVlIChmaWxlKTsKICAgIGNsb3NlZGlyIChkKTsKICAgIGlmIChyZXQgJiYgY2FjaGUpCglGY0dsb2JhbENhY2hlVXBkYXRlIChjYWNoZSwgZGlyLCAwLCAwKTsKCQogICAgcmV0dXJuIHJldDsKfQoKRmNCb29sCkZjRGlyU2F2ZSAoRmNGb250U2V0ICpzZXQsIEZjU3RyU2V0ICpkaXJzLCBjb25zdCBGY0NoYXI4ICpkaXIpCnsKICAgIHJldHVybiBGY0RpckNhY2hlV3JpdGVEaXIgKHNldCwgZGlycywgZGlyKTsKfQo=