LyogZmlsZXhmZXIuaAogKgogKiBDb3B5cmlnaHQgqSAyMDEzIC0gMjAxMyBVTklTWVMgQ09SUE9SQVRJT04KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0CiAqIHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dAogKiBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwgR09PRCBUSVRMRSBvcgogKiBOT04gSU5GUklOR0VNRU5ULiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZQogKiBkZXRhaWxzLgogKi8KCi8qIFRoaXMgaGVhZGVyIGZpbGUgZGVmaW5lcyB0aGUgaW50ZXJmYWNlIHRoYXQgZmlsZXhmZXIuYyBwcm92aWRlcyB0byBvdGhlcgogKiBjb2RlIGluIHRoZSB2aXNvcmNoaXBzZXQgZHJpdmVyLgogKi8KCiNpZm5kZWYgX19GSUxFWEZFUl9IX18KI2RlZmluZSBfX0ZJTEVYRkVSX0hfXwoKI2luY2x1ZGUgImdsb2JhbHMuaCIKI2luY2x1ZGUgImNvbnRyb2x2bWNoYW5uZWwuaCIKI2luY2x1ZGUgPGxpbnV4L3NlcV9maWxlLmg+Cgp0eXBlZGVmIHZvaWQgKigqR0VUX0NPTlRJR1VPVVNfQ09OVFJPTFZNX1BBWUxPQURfRlVOQykgKHVsb25nIG1pbl9zaXplLAoJCQkJCQkJdWxvbmcgbWF4X3NpemUsCgkJCQkJCQl1bG9uZyAqYWN0dWFsX3NpemUpOwoKdHlwZWRlZiBCT09MCigqQ09OVFJPTFZNX1JFU1BPTkRfV0lUSF9QQVlMT0FEX0ZVTkMpIChDT05UUk9MVk1fTUVTU0FHRV9IRUFERVIgKm1zZ0hkciwKCQkJCQl1NjQgZmlsZVJlcXVlc3ROdW1iZXIsCgkJCQkJdTY0IGRhdGFTZXF1ZW5jZU51bWJlciwKCQkJCQlpbnQgcmVzcG9uc2UsCgkJCQkJdm9pZCAqYnVja2V0LCB1bG9uZyBwYXlsb2FkQ2h1bmtTaXplLAoJCQkJCXVsb25nIHBheWxvYWRVc2VkQnl0ZXMsIEJPT0wgcGFydGlhbCk7Cgp0eXBlZGVmIHZvaWQKKCpUUkFOU01JVEZJTEVfSU5JVF9DT05URVhUX0ZVTkMpKHZvaWQgKmN0eCwKCQkJCSAgY29uc3QgQ09OVFJPTFZNX01FU1NBR0VfSEVBREVSICpoZHIsCgkJCQkgIHU2NCBmaWxlX3JlcXVlc3RfbnVtYmVyKTsKdHlwZWRlZiB2b2lkICgqVFJBTlNNSVRGSUxFX0RVTVBfRlVOQykgKHN0cnVjdCBzZXFfZmlsZSAqZiwgdm9pZCAqY3R4LAoJCQkJCWNvbnN0IGNoYXIgKnBmeCk7CnR5cGVkZWYgaW50ICgqR0VUX0NPTlRST0xWTV9GSUxFREFUQV9GVU5DKSAodm9pZCAqY3R4LAoJCQkJCSAgICB2b2lkICpidWYsIHNpemVfdCBidWZzaXplLAoJCQkJCSAgICBCT09MIGJ1Zl9pc191c2Vyc3BhY2UsCgkJCQkJICAgIHNpemVfdCAqYnl0ZXNfdHJhbnNmZXJyZWQpOwp0eXBlZGVmIHZvaWQgKCpDT05UUk9MVk1fUkVTUE9ORF9GVU5DKSAodm9pZCAqY3R4LCBpbnQgcmVzcG9uc2UpOwoKLyogQ2FsbCBvbmNlIHRvIGluaXRpYWxpemUgZmlsZXhmZXIuby4KICogcmVxX2NvbnRleHRfYnl0ZXMgbnVtYmVyIG9mIGJ5dGVzIHRoZSBjYWxsZXIgbmVlZHMgdG8ga2VlcCB0cmFjayBvZiBlYWNoIGZpbGUKICogdHJhbnNmZXIgY29udmVyc2F0aW9uLiAgVGhlIDxjdHhfaW5pdF92YWx1ZT4gcGFzc2VkIHRvIGZpbGV4ZmVyX3B1dEZpbGUoKSBpcwogKiBhc3N1bWVkIHRvIGJlIHRoaXMgbWFueSBieXRlcyBpbiBzaXplLiAgQ29kZSB3aXRoaW4gZmlsZXhmZXIubyB3aWxsIGNvcHkgdGhpcwogKiBpbnRvIGEgZHluYW1pY2FsbHktYWxsb2NhdGVkIGFyZWEsIGFuZCBwYXNzIGJhY2sgYSBwb2ludGVyIHRvIHRoYXQgYXJlYSBpbgogKiBjYWxsYmFjayBmdW5jdGlvbnMuCiAqLwppbnQgZmlsZXhmZXJfY29uc3RydWN0b3Ioc2l6ZV90IHJlcV9jb250ZXh0X2J5dGVzKTsKCi8qIENhbGwgb25jZSB0byBjbGVhbiB1cCBmaWxleGZlci5vICovCnZvaWQgZmlsZXhmZXJfZGVzdHJ1Y3Rvcih2b2lkKTsKCi8qIENhbGwgdGhpcyB0byBkdW1wIGRpYWdub3N0aWMgaW5mbyBhYm91dCBhbGwgb3V0c3RhbmRpbmcgZ2V0RmlsZXMvcHV0RmlsZXMgKi8Kdm9pZCBmaWxleGZlcl9kdW1wKHN0cnVjdCBzZXFfZmlsZSAqZik7CgovKiBDYWxsIHRvIHRyYW5zZmVyIGEgZmlsZSBmcm9tIHRoZSBsb2NhbCBmaWxlc3lzdGVtIChpLmUuLCBmcm9tIHRoZSBlbnZpcm9ubWVudAogKiB3aGVyZSB0aGlzIGRyaXZlciBpcyBydW5uaW5nKSBhY3Jvc3MgdGhlIGNvbnRyb2x2bSBjaGFubmVsIHRvIGEgcmVtb3RlCiAqIGVudmlyb25tZW50LiAgMSBvciBtb3JlIGNvbnRyb2x2bSByZXNwb25zZXMgd2lsbCBiZSBzZW50IGFzIGEgcmVzdWx0LCBlYWNoCiAqIG9mIHdoaWNoIHdob3NlIHBheWxvYWQgY29udGFpbnMgZmlsZSBkYXRhLiAgT25seSB0aGUgbGFzdCBjb250cm9sdm0gbWVzc2FnZQogKiB3aWxsIGhhdmUgRmxhZ3MucGFydGlhbENvbXBsZXRpb249PTAuCiAqCiAqICAgbXNnSGRyICAgICAgdGhlIGNvbnRyb2x2bSBtZXNzYWdlIGhlYWRlciBvZiB0aGUgR0VURklMRSByZXF1ZXN0IHdoaWNoCiAqICAgICAgICAgICAgICAgd2UganVzdCByZWNlaXZlZAogKiAgIGZpbGVfcmVxdWVzdF9udW1iZXIgIHRoaXMgaXMgYWxsIGRhdGEgZnJvbSB0aGUgR0VURklMRSByZXF1ZXN0IHRoYXQKICogICB1cGxpbmtfaW5kZXggICAgICAgICBkZWZpbmUgd2hpY2ggZmlsZSBpcyB0byBiZSB0cmFuc2ZlcnJlZAogKiAgIGRpc2tfaW5kZXgKICogICBmaWxlX25hbWUKICogICBnZXRfY29udGlndW91c19jb250cm9sdm1fcGF5bG9hZCAgZnVuY3Rpb24gdG8gY2FsbCB3aGVuIHNwYWNlIGlzIG5lZWRlZAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbiB0aGUgcGF5bG9hZCBhcmVhCiAqICAgY29udHJvbHZtX3Jlc3BvbmRfd2l0aF9wYXlsb2FkICAgIGZ1bmN0aW9uIHRvIGNhbGwgdG8gc2VuZCBlYWNoIGNvbnRyb2x2bQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZSBjb250YWluaW5nIGZpbGUgZGF0YSBhcyB0aGUKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZDsgcmV0dXJucyBGQUxTRSBvbmx5IGlmIHRoZQogKgkJCQkgICAgICAgcGF5bG9hZCBidWZmZXIgd2FzIGZyZWVkIGlubGluZQogKiAgIGR1bXBfZnVuYyAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiB0byBkdW1wIGNvbnRleHQgZGF0YSBpbgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBodW1hbi1yZWFkYWJsZSBmb3JtYXQKICoKICogIFJldHVybnMgVFJVRSBpZmYgdGhlIGZpbGUgdHJhbnNmZXIgcmVxdWVzdCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgaW5pdGlhdGVkLAogKiAgb3IgRkFMU0UgdG8gaW5kaWNhdGUgZmFpbHVyZS4KICovCkJPT0wKZmlsZXhmZXJfZ2V0RmlsZShDT05UUk9MVk1fTUVTU0FHRV9IRUFERVIgKm1zZ0hkciwKCQkgdTY0IGZpbGVfcmVxdWVzdF9udW1iZXIsCgkJIHVpbnQgdXBsaW5rX2luZGV4LAoJCSB1aW50IGRpc2tfaW5kZXgsCgkJIGNoYXIgKmZpbGVfbmFtZSwKCQkgR0VUX0NPTlRJR1VPVVNfQ09OVFJPTFZNX1BBWUxPQURfRlVOQwoJCSBnZXRfY29udGlndW91c19jb250cm9sdm1fcGF5bG9hZCwKCQkgQ09OVFJPTFZNX1JFU1BPTkRfV0lUSF9QQVlMT0FEX0ZVTkMKCQkgY29udHJvbHZtX3Jlc3BvbmRfd2l0aF9wYXlsb2FkLAoJCSBUUkFOU01JVEZJTEVfRFVNUF9GVU5DIGR1bXBfZnVuYyk7CgovKiBDYWxsIHRvIGNyZWF0ZSBhIGZpbGUgaW4gdGhlIGxvY2FsIGZpbGVzeXN0ZW0gKGkuZS4sIGluIHRoZSBlbnZpcm9ubWVudAogKiB3aGVyZSB0aGlzIGRyaXZlciBpcyBydW5uaW5nKSBmcm9tIGRhdGEgcmVjZWl2ZWQgYXMgcGF5bG9hZCBpbgogKiBjb250cm9sdm0gY2hhbm5lbCBtZXNzYWdlcyBmcm9tIGEgcmVtb3RlIGVudmlyb25tZW50LiAgMSBvciBtb3JlIGNvbnRyb2x2bQogKiBtZXNzYWdlcyB3aWxsIGJlIHJlY2VpdmVkIGZvciB0aGlzIHRyYW5zZmVyLCBhbmQgb25seSB0aGUgbGFzdCB3aWxsIGhhdmUKICogRmxhZ3MucGFydGlhbENvbXBsZXRpb249PTAuCiAqCiAqICAgbXNnSGRyICAgICAgdGhlIGNvbnRyb2x2bSBtZXNzYWdlIGhlYWRlciBvZiB0aGUgUFVURklMRSByZXF1ZXN0IHdoaWNoCiAqICAgICAgICAgICAgICAgd2UganVzdCByZWNlaXZlZAogKiAgIGZpbGVfcmVxdWVzdF9udW1iZXIgIHRoaXMgaXMgYWxsIGRhdGEgZnJvbSB0aGUgUFVURklMRSByZXF1ZXN0IHRoYXQKICogICB1cGxpbmtfaW5kZXggICAgICAgICBkZWZpbmUgd2hpY2ggZmlsZSBpcyB0byBiZSBjcmVhdGVkIGluIHRoZSBsb2NhbAogKiAgIGRpc2tfaW5kZXggICAgICAgICAgIGZpbGVzeXN0ZW0KICogICBmaWxlX25hbWUKICogICBpbml0X2NvbnRleHQgICAgICAgICBmdW5jdGlvbiB0byBjYWxsIHRvIGluaXRpYWxpemUgdGhlCiAqICAgICAgICAgICAgICAgICAgICAgICAgPHJlcV9jb250ZXh0X2J5dGVzPi1zaXplZCBzdG9yYWdlIGFyZWEgcmV0dXJuZWQgYnkKICogICAgICAgICAgICAgICAgICAgICAgICB0aGlzIGZ1bmM7IG5vdGUgdGhhdCBpdCB3b3VsZCBOT1QgYmUgc3VmZmljaWVudCB0bwogKiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93IHRoZSBjYWxsZXIgdG8gaW5pdGlhbGl6ZSB0aGlzIHVwb24gcmV0dXJuLCBhcwogKiAgICAgICAgICAgICAgICAgICAgICAgIHRoZSB0aGUgb3RoZXIgdXNlci1zdXBwbGllZCBjYWxsYmFja3MgbWlnaHQgaGF2ZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGFscmVhZHkgYmVlbiBjYWxsZWQgYnkgdGhlbgogKiAgIGdldF9jb250cm9sdm1fZmlsZWRhdGEgICBmdW5jdGlvbiB0byBjYWxsIHRvIG9idGFpbiBtb3JlIGRhdGEgZm9yIHRoZSBmaWxlCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlaW5nIHdyaXR0ZW47IHJlZmVyIHRvIGdldF9jb250cm9sdm1fZmlsZWRhdGEoKQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbiB2aXNvcmNoaXBzZXRfbWFpbi5jIGZvciBhIGNvbXBsZXRlIGRlc2NyaXB0aW9uCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mIHBhcmFtZXRlcnMKICogICBjb250cm9sdm1fZW5kX3B1dEZpbGUgICAgZnVuY3Rpb24gdG8gY2FsbCB0byBpbmRpY2F0ZSB0aGF0IGNyZWF0aW9uIG9mIHRoZQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbCBmaWxlIGhhcyBjb21wbGV0ZWQ7ICBzZXQgPHJlc3BvbnNlPiB0byBhCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlIHZhbHVlIHRvIGluZGljYXRlIGFuIGVycm9yCiAqICAgZHVtcF9mdW5jICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRvIGR1bXAgY29udGV4dCBkYXRhIGluIGh1bWFuLXJlYWRhYmxlCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdAogKgogKiAgUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBkeW5hbWljYWxseS1hbGxvY2F0ZWQgc3RvcmFnZSBhcmVhIG9mIHNpemUKICogIDxyZXFfY29udGV4dF9ieXRlcz4gd2hpY2ggdGhlIGNhbGxlciBjYW4gdXNlLCBvciBOVUxMIGZvciBlcnJvci4gIFRoZQogKiAgY2FsbGVyIHNob3VsZCBORVZFUiBmcmVlIHRoZSByZXR1cm5lZCBwb2ludGVyLCBidXQgc2hvdWxkIGV4cGVjdCB0byByZWNlaXZlCiAqICBpdCBhcyB0aGUgPGN0eD4gYXJndW1lbnQgd2hlbiBjYWxsYmFjayBmdW5jdGlvbnMgYXJlIGNhbGxlZC4KICovCnZvaWQgKmZpbGV4ZmVyX3B1dEZpbGUoQ09OVFJPTFZNX01FU1NBR0VfSEVBREVSICptc2dIZHIsCgkJICAgICAgIHU2NCBmaWxlX3JlcXVlc3RfbnVtYmVyLAoJCSAgICAgICB1aW50IHVwbGlua19pbmRleCwKCQkgICAgICAgdWludCBkaXNrX2luZGV4LAoJCSAgICAgICBjaGFyICpmaWxlX25hbWUsCgkJICAgICAgIFRSQU5TTUlURklMRV9JTklUX0NPTlRFWFRfRlVOQyBpbml0X2NvbnRleHQsCgkJICAgICAgIEdFVF9DT05UUk9MVk1fRklMRURBVEFfRlVOQyBnZXRfY29udHJvbHZtX2ZpbGVkYXRhLAoJCSAgICAgICBDT05UUk9MVk1fUkVTUE9ORF9GVU5DIGNvbnRyb2x2bV9lbmRfcHV0RmlsZSwKCQkgICAgICAgVFJBTlNNSVRGSUxFX0RVTVBfRlVOQyBkdW1wX2Z1bmMpOwoKI2VuZGlmCg==