LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNkaXIuYyx2IDEuOSAyMDAyLzA4LzMxIDIyOjE3OjMyIGtlaXRocCBFeHAgJAogKgogKiBDb3B5cmlnaHQgqSAyMDAwIEtlaXRoIFBhY2thcmQKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJmY2ludC5oIgojaW5jbHVkZSA8ZGlyZW50Lmg+CgpzdGF0aWMgRmNCb29sCkZjRmlsZUlzRGlyIChjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBzdHJ1Y3Qgc3RhdAkgICAgc3RhdGI7CgogICAgaWYgKHN0YXQgKChjb25zdCBjaGFyICopIGZpbGUsICZzdGF0YikgIT0gMCkKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIFNfSVNESVIoc3RhdGIuc3RfbW9kZSk7Cn0KCkZjQm9vbApGY0ZpbGVTY2FuIChGY0ZvbnRTZXQJICAgICpzZXQsCgkgICAgRmNTdHJTZXQJICAgICpkaXJzLAoJICAgIEZjR2xvYmFsQ2FjaGUgICAqY2FjaGUsCgkgICAgRmNCbGFua3MJICAgICpibGFua3MsCgkgICAgY29uc3QgRmNDaGFyOCAgICpmaWxlLAoJICAgIEZjQm9vbAkgICAgZm9yY2UpCnsKICAgIGludAkJCWlkOwogICAgRmNDaGFyOAkJKm5hbWU7CiAgICBGY1BhdHRlcm4JCSpmb250OwogICAgRmNCb29sCQlyZXQgPSBGY1RydWU7CiAgICBGY0Jvb2wJCWlzRGlyOwogICAgaW50CQkJY291bnQgPSAwOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmNhY2hlX2ZpbGU7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpjYWNoZV9kaXI7CiAgICBGY0Jvb2wJCW5lZWRfc2NhbjsKICAgIAogICAgaWYgKGZvcmNlKQoJY2FjaGUgPSAwOwogICAgaWQgPSAwOwogICAgZG8KICAgIHsKCW5lZWRfc2NhbiA9IEZjVHJ1ZTsKCWZvbnQgPSAwOwoJLyoKCSAqIENoZWNrIHRoZSBjYWNoZQoJICovCglpZiAoY2FjaGUpCgl7CgkgICAgaWYgKChjYWNoZV9maWxlID0gRmNHbG9iYWxDYWNoZUZpbGVHZXQgKGNhY2hlLCBmaWxlLCBpZCwgJmNvdW50KSkpCgkgICAgewoJCS8qCgkJICogRm91bmQgYSBjYWNoZSBlbnRyeSBmb3IgdGhlIGZpbGUKCQkgKi8KCQlpZiAoRmNHbG9iYWxDYWNoZUNoZWNrVGltZSAoZmlsZSwgJmNhY2hlX2ZpbGUtPmluZm8pKQoJCXsKCQkgICAgbmFtZSA9IGNhY2hlX2ZpbGUtPm5hbWU7CgkJICAgIG5lZWRfc2NhbiA9IEZjRmFsc2U7CgkJICAgIEZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgJmNhY2hlX2ZpbGUtPmluZm8pOwoJCSAgICAvKiAiLiIgbWVhbnMgdGhlIGZpbGUgZG9lc24ndCBjb250YWluIGEgZm9udCAqLwoJCSAgICBpZiAoRmNTdHJDbXAgKG5hbWUsIEZDX0ZPTlRfRklMRV9JTlZBTElEKSAhPSAwKQoJCSAgICB7CgkJCWZvbnQgPSBGY05hbWVQYXJzZSAobmFtZSk7CgkJCWlmIChmb250KQoJCQkgICAgaWYgKCFGY1BhdHRlcm5BZGRTdHJpbmcgKGZvbnQsIEZDX0ZJTEUsIGZpbGUpKQoJCQkJcmV0ID0gRmNGYWxzZTsKCQkgICAgfQoJCX0KCSAgICB9CgkgICAgZWxzZSBpZiAoKGNhY2hlX2RpciA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBmaWxlLAoJCQkJCQkgICAgICAgc3RybGVuICgoY29uc3QgY2hhciAqKSBmaWxlKSwKCQkJCQkJICAgICAgIEZjRmFsc2UpKSkKCSAgICB7CgkJaWYgKEZjR2xvYmFsQ2FjaGVDaGVja1RpbWUgKGNhY2hlX2Rpci0+aW5mby5maWxlLCAKCQkJCQkgICAgJmNhY2hlX2Rpci0+aW5mbykpCgkJewoJCSAgICBmb250ID0gMDsKCQkgICAgbmVlZF9zY2FuID0gRmNGYWxzZTsKCQkgICAgRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKGNhY2hlLCAmY2FjaGVfZGlyLT5pbmZvKTsKCQkgICAgaWYgKCFGY1N0clNldEFkZCAoZGlycywgZmlsZSkpCgkJCXJldCA9IEZjRmFsc2U7CgkJfQoJICAgIH0KCX0KCS8qCgkgKiBOb3RoaW5nIGluIHRoZSBjYWNoZSwgc2NhbiB0aGUgZmlsZQoJICovCglpZiAobmVlZF9zY2FuKQoJewoJICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX1NDQU4pCgkgICAgewoJCXByaW50ZiAoIlx0U2Nhbm5pbmcgZmlsZSAlcy4uLiIsIGZpbGUpOwoJCWZmbHVzaCAoc3Rkb3V0KTsKCSAgICB9CgkgICAgZm9udCA9IEZjRnJlZVR5cGVRdWVyeSAoZmlsZSwgaWQsIGJsYW5rcywgJmNvdW50KTsKCSAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19TQ0FOKQoJCXByaW50ZiAoImRvbmVcbiIpOwoJICAgIGlzRGlyID0gRmNGYWxzZTsKCSAgICBpZiAoIWZvbnQgJiYgRmNGaWxlSXNEaXIgKGZpbGUpKQoJICAgIHsKCQlpc0RpciA9IEZjVHJ1ZTsKCQlyZXQgPSBGY1N0clNldEFkZCAoZGlycywgZmlsZSk7CgkgICAgfQoJICAgIC8qCgkgICAgICogVXBkYXRlIHRoZSBjYWNoZQoJICAgICAqLwoJICAgIGlmIChjYWNoZSAmJiBmb250KQoJICAgIHsKCQlGY0NoYXI4CSp1bnBhcnNlOwoKCQl1bnBhcnNlID0gRmNOYW1lVW5wYXJzZSAoZm9udCk7CgkJaWYgKHVucGFyc2UpCgkJewoJCSAgICAodm9pZCkgRmNHbG9iYWxDYWNoZVVwZGF0ZSAoY2FjaGUsIGZpbGUsIGlkLCB1bnBhcnNlKTsKCQkgICAgRmNTdHJGcmVlICh1bnBhcnNlKTsKCQl9CgkgICAgfQoJfQoJLyoKCSAqIEFkZCB0aGUgZm9udAoJICovCglpZiAoZm9udCkKCXsKCSAgICBpZiAoIUZjRm9udFNldEFkZCAoc2V0LCBmb250KSkKCSAgICB7CgkJRmNQYXR0ZXJuRGVzdHJveSAoZm9udCk7CgkJZm9udCA9IDA7CgkJcmV0ID0gRmNGYWxzZTsKCSAgICB9Cgl9CglpZCsrOwogICAgfSB3aGlsZSAoZm9udCAmJiByZXQgJiYgaWQgPCBjb3VudCk7CiAgICByZXR1cm4gcmV0Owp9CgojZGVmaW5lIEZDX01BWF9GSUxFX0xFTgkgICAgNDA5NgoKLyoKICogU2NhbiAnZGlyJywgYWRkaW5nIGZvbnQgZmlsZXMgdG8gJ3NldCcgYW5kCiAqIHN1YmRpcmVjdG9yaWVzIHRvICdkaXJzJwogKi8KCkZjQm9vbApGY0RpclNjYW4gKEZjRm9udFNldAkgICAgKnNldCwKCSAgIEZjU3RyU2V0CSAgICAqZGlycywKCSAgIEZjR2xvYmFsQ2FjaGUgICAgKmNhY2hlLAoJICAgRmNCbGFua3MJICAgICpibGFua3MsCgkgICBjb25zdCBGY0NoYXI4ICAgICpkaXIsCgkgICBGY0Jvb2wJICAgIGZvcmNlKQp7CiAgICBESVIJCQkqZDsKICAgIHN0cnVjdCBkaXJlbnQJKmU7CiAgICBGY0NoYXI4CQkqZmlsZTsKICAgIEZjQ2hhcjgJCSpiYXNlOwogICAgRmNCb29sCQlyZXQgPSBGY1RydWU7CgogICAgaWYgKCFmb3JjZSkKICAgIHsKCS8qCgkgKiBDaGVjayBmb250cy5jYWNoZS08dmVyc2lvbj4gZmlsZQoJICovCglpZiAoRmNEaXJDYWNoZVJlYWREaXIgKHNldCwgZGlycywgZGlyKSkKCXsKCSAgICBpZiAoY2FjaGUpCgkJRmNHbG9iYWxDYWNoZVJlZmVyZW5jZVN1YmRpciAoY2FjaGUsIGRpcik7CgkgICAgcmV0dXJuIEZjVHJ1ZTsKCX0KICAgIAoJLyoKCSAqIENoZWNrIH4vLmZvbnRzLmNhY2hlLTx2ZXJzaW9uPiBmaWxlCgkgKi8KCWlmIChjYWNoZSAmJiBGY0dsb2JhbENhY2hlU2NhbkRpciAoc2V0LCBkaXJzLCBjYWNoZSwgZGlyKSkKCSAgICByZXR1cm4gRmNUcnVlOwogICAgfQogICAgCiAgICAvKiBmcmVlZCBiZWxvdyAqLwogICAgZmlsZSA9IChGY0NoYXI4ICopIG1hbGxvYyAoc3RybGVuICgoY2hhciAqKSBkaXIpICsgMSArIEZDX01BWF9GSUxFX0xFTiArIDEpOwogICAgaWYgKCFmaWxlKQoJcmV0dXJuIEZjRmFsc2U7CgogICAgc3RyY3B5ICgoY2hhciAqKSBmaWxlLCAoY2hhciAqKSBkaXIpOwogICAgc3RyY2F0ICgoY2hhciAqKSBmaWxlLCAiLyIpOwogICAgYmFzZSA9IGZpbGUgKyBzdHJsZW4gKChjaGFyICopIGZpbGUpOwogICAgCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19TQ0FOKQoJcHJpbnRmICgiXHRTY2FubmluZyBkaXIgJXNcbiIsIGRpcik7CgkKICAgIGQgPSBvcGVuZGlyICgoY2hhciAqKSBkaXIpOwogICAgCiAgICBpZiAoIWQpCiAgICB7CglmcmVlIChmaWxlKTsKCS8qIERvbid0IGNvbXBsYWluIGFib3V0IG1pc3NpbmcgZGlyZWN0b3JpZXMgKi8KCWlmIChlcnJubyA9PSBFTk9FTlQpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgd2hpbGUgKHJldCAmJiAoZSA9IHJlYWRkaXIgKGQpKSkKICAgIHsKCWlmIChlLT5kX25hbWVbMF0gIT0gJy4nICYmIHN0cmxlbiAoZS0+ZF9uYW1lKSA8IEZDX01BWF9GSUxFX0xFTikKCXsKCSAgICBzdHJjcHkgKChjaGFyICopIGJhc2UsIChjaGFyICopIGUtPmRfbmFtZSk7CgkgICAgcmV0ID0gRmNGaWxlU2NhbiAoc2V0LCBkaXJzLCBjYWNoZSwgYmxhbmtzLCBmaWxlLCBmb3JjZSk7Cgl9CiAgICB9CiAgICBmcmVlIChmaWxlKTsKICAgIGNsb3NlZGlyIChkKTsKICAgIC8qCiAgICAgKiBOb3cgdGhhdCB0aGUgZGlyZWN0b3J5IGhhcyBiZWVuIHNjYW5uZWQsCiAgICAgKiBhZGQgdGhlIGNhY2hlIGVudHJ5IAogICAgICovCiAgICBpZiAocmV0ICYmIGNhY2hlKQoJRmNHbG9iYWxDYWNoZVVwZGF0ZSAoY2FjaGUsIGRpciwgMCwgMCk7CgkKICAgIHJldHVybiByZXQ7Cn0KCkZjQm9vbApGY0RpclNhdmUgKEZjRm9udFNldCAqc2V0LCBGY1N0clNldCAqZGlycywgY29uc3QgRmNDaGFyOCAqZGlyKQp7CiAgICByZXR1cm4gRmNEaXJDYWNoZVdyaXRlRGlyIChzZXQsIGRpcnMsIGRpcik7Cn0K