Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vfxyf-006ZAo-1Z for pgsql-hackers@arkaria.postgresql.org; Wed, 14 Jan 2026 10:19:51 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vfxye-009gva-1I for pgsql-hackers@arkaria.postgresql.org; Wed, 14 Jan 2026 10:19:48 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vfxyd-009gvP-1m for pgsql-hackers@lists.postgresql.org; Wed, 14 Jan 2026 10:19:48 +0000 Received: from forward500a.mail.yandex.net ([2a02:6b8:c0e:500:1:45:d181:d500]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vfxyW-000MNW-2J for pgsql-hackers@lists.postgresql.org; Wed, 14 Jan 2026 10:19:46 +0000 Received: from mail-nwsmtp-smtp-production-main-97.vla.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-97.vla.yp-c.yandex.net [IPv6:2a02:6b8:c15:2804:0:640:a3ea:0]) by forward500a.mail.yandex.net (Yandex) with ESMTPS id A2A6EC1CB9; Wed, 14 Jan 2026 13:19:36 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-97.vla.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id aJRJIXAHnqM0-5f8iIZX1; Wed, 14 Jan 2026 13:19:36 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tantorlabs.com; s=mail; t=1768385976; bh=/I8I+iaIgaj9lPQr27AezySwDXhHvRRoJwI9pXlJBxE=; h=In-Reply-To:References:To:Subject:Message-ID:Date:From; b=tidCYflxtLhWxOp4ITOJyiuKLqkXsFu0Xv191Ohx+0nIh5tg96L37AOF9k9xYqsPe R7tEuG0ZieBvFQ3WXg+HZ1vPhjkYOOmO/kSwuNfyhkmT2rm9Y+SPUXhStbWdwztoux s8NRNJkfHgjXYHbRygaV7io89HC3rv5lwQmMlbCA= Authentication-Results: mail-nwsmtp-smtp-production-main-97.vla.yp-c.yandex.net; dkim=pass header.i=@tantorlabs.com Content-Type: multipart/mixed; boundary="------------JwSYPbG6AjFNqkEs906f5Z7j" Message-ID: <988e3168-6096-488a-bb42-787e1e8c21a4@tantorlabs.com> Date: Wed, 14 Jan 2026 13:19:36 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: Ilia Evdokimov Subject: Re: Hash-based MCV matching for large IN-lists To: David Geier , PostgreSQL Hackers References: <7db341e0-fbc6-4ec5-922c-11fdafe7be12@tantorlabs.com> Content-Language: en-US In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------JwSYPbG6AjFNqkEs906f5Z7j Content-Type: multipart/alternative; boundary="------------jsLBEMUtLwghM0qfeCfbFu0z" --------------jsLBEMUtLwghM0qfeCfbFu0z Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi David! Thanks for feedback. On 05.01.2026 11:54, David Geier wrote: >> This patch introduces a hash-based matching path, analogous to what is >> already done for MCV matching in join selectivity estimation (057012b >> commit). Instead of linearly scanning the MCV array for each IN-list >> element, we build a hash table and probe it to identify matches. >> >> The hash table is built over the MCV values, not over the IN-list. The >> IN-list may contain NULLs, non-Const expressions, and duplicate values, >> whereas the MCV list is guaranteed to contain distinct, non-NULL values >> and represents the statistically meaningful domain we are matching >> against. Hashing the MCVs therefore avoids duplicate work and directly >> supports selectivity estimation. > The downside of doing it this way is that we always pay the price of > building a possibly big hash table if the column has a lot of MCVs, even > for small IN lists. Why can't we build the hash table always on the > smaller list, like we do already in the join selectivity estimation? > > For NULL we can add a flag to the hash entry, non-Const expressions must > anyways be evaluated and duplicate values will be discarded during insert. After thinking more about this I realized that this is actually a better match for how selectivity is currently modeled. After this comments in master          * If we were being really tense we would try to confirm that the          * elements are all distinct, but that would be expensive and it          * doesn't seem to be worth the cycles; it would amount to penalizing          * well-written queries in favor of poorly-written ones. However, we          * do protect ourselves a little bit by checking whether the          * disjointness assumption leads to an impossible (out of range)          * probability; if so, we fall back to the normal calculation. when the hash table is built on the IN-list, duplicate IN-list values are automatically eliminated during insertion, so we no longer risk summing the same MCV frequency multiple times. This makes the disjoint-probability estimate more robust and in practice slightly more accurate. One thing I initially missed that there are actually three different places where ScalarArrayOpExpr is handled - the Const array case, the ArrayExpr case and others - and Const and ArrayExpr require different implementation of the same idea. In Const case we can directly hash and probe Datum value, while ArrayExpr case we must work on Node* element, separating constant and non-constant entries and only hashing the constants. The current v2 therefore applies the same MCV-hash optimization in both branches, but using two tailored code paths that preserve the existing semantics of how non-Const elements are handled by var_eq_non_const(). If the MCV list is smaller than the IN-list, the behavior is the same as in v1 of the patch. If the IN-list is smaller, we instead build a hash table over the distinct constant elements of the IN-list and then: - Scan the MCV list and sum the frequencies of those MCVs that appear in the IN-list; - Count how many distinct IN-list not null constant elements are not present in the MCV list; - Estimate the probability of each such non-MCV value using the remaining frequency mass; - Handle non-constant IN-list elements separately using var_eq_non_const(), exactly as in the existing implementation. >> For each IN-list element, if a matching MCV is found, we add the >> corresponding MCV frequency to the selectivity estimate. If no match is >> found, the remaining selectivity is estimated in the same way as the >> existing non-MCV path (similar to var_eq_const when the constant is not >> present in the MCV list). >> > The code in master currently calls an operator-specific selectivity > estimation function. For equality this is typically eqsel() but the > function can be specified during CREATE OPERATOR. > > Can be safely special-case the behavior of eqsel() for all possible > operators for the ScalarArrayOpExpr case? Unfortunately there is no safe way to make this optimization generic for arbitrary restrict functions, because a custom RESTRICT function does not have to use MCVs at all. IMO, in practice the vast majority of ScalarArrayOpExpr uses with = or <> rely on the built-in equality operators whose selectivity is computed by eqsel()/neqsel(), so I limited this optimization to those cases. I’ve attached v2 of the patch. It currently uses two fairly large helper functions for the Const and ArrayExpr cases; this is intentional to keep the logic explicit and reviewable, even though these will likely need refactoring or consolidation later. -- Best regards, Ilia Evdokimov, Tantor Labs LLC, https://tantorlabs.com/ --------------jsLBEMUtLwghM0qfeCfbFu0z Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

Hi David!

Thanks for feedback.

On 05.01.2026 11:54, David Geier wrote:
This patch introduces a hash-based matching path, analogous to what is
already done for MCV matching in join selectivity estimation (057012b
commit). Instead of linearly scanning the MCV array for each IN-list
element, we build a hash table and probe it to identify matches.

The hash table is built over the MCV values, not over the IN-list. The
IN-list may contain NULLs, non-Const expressions, and duplicate values,
whereas the MCV list is guaranteed to contain distinct, non-NULL values
and represents the statistically meaningful domain we are matching
against. Hashing the MCVs therefore avoids duplicate work and directly
supports selectivity estimation.
The downside of doing it this way is that we always pay the price of
building a possibly big hash table if the column has a lot of MCVs, even
for small IN lists. Why can't we build the hash table always on the
smaller list, like we do already in the join selectivity estimation?

For NULL we can add a flag to the hash entry, non-Const expressions must
anyways be evaluated and duplicate values will be discarded during insert.


After thinking more about this I realized that this is actually a better match for how selectivity is currently modeled. After this comments in master

         * If we were being really tense we would try to confirm that the
         * elements are all distinct, but that would be expensive and it
         * doesn't seem to be worth the cycles; it would amount to penalizing
         * well-written queries in favor of poorly-written ones.  However, we
         * do protect ourselves a little bit by checking whether the
         * disjointness assumption leads to an impossible (out of range)
         * probability; if so, we fall back to the normal calculation.

when the hash table is built on the IN-list, duplicate IN-list values are automatically eliminated during insertion, so we no longer risk summing the same MCV frequency multiple times. This makes the disjoint-probability estimate more robust and in practice slightly more accurate.

One thing I initially missed that there are actually three different places where ScalarArrayOpExpr is handled - the Const array case, the ArrayExpr case and others - and Const and ArrayExpr require different implementation of the same idea. In Const case we can directly hash and probe Datum value, while ArrayExpr case we must work on Node* element, separating constant and non-constant entries and only hashing the constants. The current v2 therefore applies the same MCV-hash optimization in both branches, but using two tailored code paths that preserve the existing semantics of how non-Const elements are handled by var_eq_non_const().

If the MCV list is smaller than the IN-list, the behavior is the same as in v1 of the patch. If the IN-list is smaller, we instead build a hash table over the distinct constant elements of the IN-list and then:
- Scan the MCV list and sum the frequencies of those MCVs that appear in the IN-list;
- Count how many distinct IN-list not null constant elements are not present in the MCV list;
- Estimate the probability of each such non-MCV value using the remaining frequency mass;
- Handle non-constant IN-list elements separately using var_eq_non_const(), exactly as in the existing implementation.


For each IN-list element, if a matching MCV is found, we add the
corresponding MCV frequency to the selectivity estimate. If no match is
found, the remaining selectivity is estimated in the same way as the
existing non-MCV path (similar to var_eq_const when the constant is not
present in the MCV list).

The code in master currently calls an operator-specific selectivity
estimation function. For equality this is typically eqsel() but the
function can be specified during CREATE OPERATOR.

Can be safely special-case the behavior of eqsel() for all possible
operators for the ScalarArrayOpExpr case?


Unfortunately there is no safe way to make this optimization generic for arbitrary restrict functions, because a custom RESTRICT function does not have to use MCVs at all. IMO, in practice the vast majority of ScalarArrayOpExpr uses with = or <> rely on the built-in equality operators whose selectivity is computed by eqsel()/neqsel(), so I limited this optimization to those cases.

I’ve attached v2 of the patch. It currently uses two fairly large helper functions for the Const and ArrayExpr cases; this is intentional to keep the logic explicit and reviewable, even though these will likely need refactoring or consolidation later.

-- 
Best regards,
Ilia Evdokimov,
Tantor Labs LLC,
https://tantorlabs.com/

--------------jsLBEMUtLwghM0qfeCfbFu0z-- --------------JwSYPbG6AjFNqkEs906f5Z7j Content-Type: text/x-patch; charset=UTF-8; name="v2-0001-Use-hash-based-matching-for-MCVs-in-ScalarArrayOp.patch" Content-Disposition: attachment; filename*0="v2-0001-Use-hash-based-matching-for-MCVs-in-ScalarArrayOp.pa"; filename*1="tch" Content-Transfer-Encoding: base64 RnJvbSA5MzNjODljNWEyZjQyYmI1M2M1NjYzYmM0NmYyNTQ3M2JmMmE5N2JhIE1vbiBTZXAg MTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBJbGlhIEV2ZG9raW1vdiA8aWx5YS5ldmRva2ltb3ZA dGFudG9ybGFicy5ydT4KRGF0ZTogV2VkLCAxNCBKYW4gMjAyNiAxMzoxMzoyMSArMDMwMApT dWJqZWN0OiBbUEFUQ0ggdjJdIFVzZSBoYXNoLWJhc2VkIG1hdGNoaW5nIGZvciBNQ1ZzIGlu IFNjYWxhckFycmF5T3BFeHByCiBzZWxlY3Rpdml0eQoKV2hlbiBlc3RpbWF0aW5nIHNlbGVj dGl2aXR5IGZvciBTY2FsYXJBcnJheU9wRXhwciAoSU4gLyBBTlkgLyBBTEwpIHdpdGgKYXZh aWxhYmxlIE1DViBzdGF0aXN0aWNzLCB0aGUgcGxhbm5lciBjdXJyZW50bHkgbWF0Y2hlcyBJ Ti1saXN0IGVsZW1lbnRzCmFnYWluc3QgdGhlIE1DViBhcnJheSB1c2luZyBuZXN0ZWQgbG9v cHMuIEZvciBsYXJnZSBJTi1saXN0cyBhbmQvb3IgTUNWCmxpc3RzIHRoaXMgcmVzdWx0cyBp biBPKE4qTSkgcGxhbm5pbmctdGltZSBiZWhhdmlvci4KClRoaXMgcGF0Y2ggaW50cm9kdWNl cyBhIGhhc2gtYmFzZWQgbWF0Y2hpbmcgc3RyYXRlZ3ksIGFuYWxvZ291cyB0byB3aGF0Cmlz IGFscmVhZHkgdXNlZCBmb3IgTUNWIG1hdGNoaW5nIGluIGpvaW4gc2VsZWN0aXZpdHkgZXN0 aW1hdGlvbi4gVGhlCmltcGxlbWVudGF0aW9uIGNvdmVycyBib3RoIFNjYWxhckFycmF5T3BF eHByIGZvcm1zOgoxLiBDb25zdCBhcnJheSwgd2hlcmUgSU4tbGlzdCBlbGVtZW50cyBhcmUg YXZhaWxhYmxlIGFzIERhdHVtcywgYW5kCjIuIEFycmF5RXhwciwgd2hlcmUgZWxlbWVudHMg YXJlIE5vZGVzIGFuZCBtYXkgaW5jbHVkZSBub24tY29uc3RhbnQKZXhwcmVzc2lvbnMuCgpJ biBib3RoIGNhc2VzLCB3aGVuIE1DViBzdGF0aXN0aWNzIGFuZCBzdWl0YWJsZSBoYXNoIGZ1 bmN0aW9ucyBhcmUKYXZhaWxhYmxlLCB0aGUgYWxnb3JpdGhtIGNob29zZXMgdGhlIHNtYWxs ZXIgc2lkZSB0byBoYXNoOiBlaXRoZXIgdGhlCk1DViBsaXN0IG9yIHRoZSBkaXN0aW5jdCBj b25zdGFudCBlbGVtZW50cyBvZiB0aGUgSU4tbGlzdC4gVGhlIG90aGVyCnNpZGUgaXMgdGhl biBzY2FubmVkIG9uY2UsIHJlZHVjaW5nIHRoZSBjb21wbGV4aXR5IGZyb20gTyhOKk0pIHRv Ck8oTitNKS4KCkZvciB0aGUgQXJyYXlFeHByIGNhc2UsIG9ubHkgY29uc3RhbnQgSU4tbGlz dCBlbGVtZW50cyBwYXJ0aWNpcGF0ZSBpbgpoYXNoaW5nIGFuZCBNQ1YgbWF0Y2hpbmc7IG5v bi1jb25zdGFudCBlbGVtZW50cyBhcmUgaGFuZGxlZCBzZXBhcmF0ZWx5CnVzaW5nIHZhcl9l cV9ub25fY29uc3QoKSwgcHJlc2VydmluZyB0aGUgZXhpc3Rpbmcgc2VtYW50aWNzIGFuZApw cm9iYWJpbGl0eSBtb2RlbC4KCldoZW4gdGhlIGhhc2ggdGFibGUgaXMgYnVpbHQgb3ZlciB0 aGUgSU4tbGlzdCwgZHVwbGljYXRlIGNvbnN0YW50IHZhbHVlcwphcmUgZWxpbWluYXRlZCBk dXJpbmcgaW5zZXJ0aW9uLiBUaGlzIHByZXZlbnRzIGRvdWJsZSBjb3VudGluZyBvZiBNQ1YK ZnJlcXVlbmNpZXMgYW5kIHByb2R1Y2VzIGEgbW9yZSByb2J1c3QgZGlzam9pbnQtcHJvYmFi aWxpdHkgZXN0aW1hdGUgZm9yCj0gQU5ZIGFuZCA8PiBBTEwuCgpUaGUgaGFzaC1iYXNlZCBw YXRoIGlzIHVzZWQgb25seSBmb3IgZXF1YWxpdHkgYW5kIGluZXF1YWxpdHkgb3BlcmF0b3Jz CnRoYXQgdXNlIGVxc2VsKCkvbmVxc2VsKCksIHdoZW4gTUNWIHN0YXRpc3RpY3MgYXJlIGF2 YWlsYWJsZSBhbmQgc3VpdGFibGUKaGFzaCBmdW5jdGlvbnMgZXhpc3QgZm9yIHRoZSBvcGVy YXRvci4KLS0tCiBzcmMvYmFja2VuZC91dGlscy9hZHQvc2VsZnVuY3MuYyB8IDEwNjAgKysr KysrKysrKysrKysrKysrKysrKysrKysrKystCiBzcmMvdG9vbHMvcGdpbmRlbnQvdHlwZWRl ZnMubGlzdCB8ICAgIDMgKwogMiBmaWxlcyBjaGFuZ2VkLCAxMDYyIGluc2VydGlvbnMoKyks IDEgZGVsZXRpb24oLSkKCmRpZmYgLS1naXQgYS9zcmMvYmFja2VuZC91dGlscy9hZHQvc2Vs ZnVuY3MuYyBiL3NyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5jcy5jCmluZGV4IDI5ZmVj NjU1NTkzLi4xNjFkM2RlNTMwZSAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvdXRpbHMvYWR0 L3NlbGZ1bmNzLmMKKysrIGIvc3JjL2JhY2tlbmQvdXRpbHMvYWR0L3NlbGZ1bmNzLmMKQEAg LTE0Niw3ICsxNDYsNyBAQAogLyoKICAqIEluIHByb2R1Y3Rpb24gYnVpbGRzLCBzd2l0Y2gg dG8gaGFzaC1iYXNlZCBNQ1YgbWF0Y2hpbmcgd2hlbiB0aGUgbGlzdHMgYXJlCiAgKiBsYXJn ZSBlbm91Z2ggdG8gYW1vcnRpemUgaGFzaCBzZXR1cCBjb3N0LiAgKFRoaXMgdGhyZXNob2xk IGlzIGNvbXBhcmVkIHRvCi0gKiB0aGUgc3VtIG9mIHRoZSBsZW5ndGhzIG9mIHRoZSB0d28g TUNWIGxpc3RzLiAgVGhpcyBpcyBzaW1wbGlzdGljIGJ1dCBzZWVtcworICogdGhlIHN1bSBv ZiB0aGUgbGVuZ3RocyBvZiB0aGUgdHdvIGxpc3RzLiAgVGhpcyBpcyBzaW1wbGlzdGljIGJ1 dCBzZWVtcwogICogdG8gd29yayB3ZWxsIGVub3VnaC4pICBJbiBkZWJ1ZyBidWlsZHMsIHdl IHVzZSBhIHNtYWxsZXIgdGhyZXNob2xkIHNvIHRoYXQKICAqIHRoZSByZWdyZXNzaW9uIHRl c3RzIGNvdmVyIGJvdGggcGF0aHMgd2VsbC4KICAqLwpAQCAtMTU2LDYgKzE1NiwxMiBAQAog I2RlZmluZSBFUUpPSU5TRUxfTUNWX0hBU0hfVEhSRVNIT0xEIDIwCiAjZW5kaWYKIAorI2lm bmRlZiBVU0VfQVNTRVJUX0NIRUNLSU5HCisjZGVmaW5lIFNDQUxBUkFSUkFZX01DVl9IQVNI X1RIUkVTSE9MRCAyMDAKKyNlbHNlCisjZGVmaW5lIFNDQUxBUkFSUkFZX01DVl9IQVNIX1RI UkVTSE9MRCAyMAorI2VuZGlmCisKIC8qIEVudHJpZXMgaW4gdGhlIHNpbXBsZWhhc2ggaGFz aCB0YWJsZSB1c2VkIGJ5IGVxam9pbnNlbF9maW5kX21hdGNoZXMgKi8KIHR5cGVkZWYgc3Ry dWN0IE1DVkhhc2hFbnRyeQogewpAQCAtMTc2LDE0ICsxODIsNDQgQEAgdHlwZWRlZiBzdHJ1 Y3QgTUNWSGFzaENvbnRleHQKIAlpbnQxNgkJaGFzaF90eXBsZW47CS8qIHR5cGxlbiBvZiBo YXNoZWQgZGF0YSB0eXBlICovCiB9IE1DVkhhc2hDb250ZXh0OwogCisvKiBFbnRyaWVzIGlu IHRoZSBzaW1wbGVoYXNoIGhhc2ggdGFibGUgdXNlZCBieSBzY2FsYXJhcnJheV9tY3ZfaGFz aF9tYXRjaCAqLwordHlwZWRlZiBzdHJ1Y3QgTUNWSW5IYXNoRW50cnkKK3sKKwlEYXR1bQkJ dmFsdWU7CQkJLyogdGhlIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZW50cnkgKi8KKwlp bnQJCQlpbmRleDsJCQkvKiBpdHMgaW5kZXggaW4gdGhlIHJlbGV2YW50IEF0dFN0YXRzU2xv dCAqLworCXVpbnQzMgkJaGFzaDsJCQkvKiBoYXNoIGNvZGUgZm9yIHRoZSBEYXR1bSAqLwor CWNoYXIJCXN0YXR1czsJCQkvKiBzdGF0dXMgY29kZSB1c2VkIGJ5IHNpbXBsZWhhc2guaCAq LworfSBNQ1ZJbkhhc2hFbnRyeTsKKworLyogcHJpdmF0ZV9kYXRhIGZvciB0aGUgc2ltcGxl aGFzaCBoYXNoIHRhYmxlICovCit0eXBlZGVmIHN0cnVjdCBNQ1ZJbkhhc2hDb250ZXh0Cit7 CisJRnVuY3Rpb25DYWxsSW5mbyBlcXVhbF9mY2luZm87CS8qIHRoZSBlcXVhbGl0eSBqb2lu IG9wZXJhdG9yICovCisJRnVuY3Rpb25DYWxsSW5mbyBoYXNoX2ZjaW5mbzsJLyogdGhlIGhh c2ggZnVuY3Rpb24gdG8gdXNlICovCisJYm9vbAkJaW5zZXJ0X21vZGU7CS8qIGRvaW5nIGlu c2VydHMgb3IgbG9va3Vwcz8gKi8KKwlib29sCQloYXNoX3R5cGJ5dmFsOwkvKiB0eXBieXZh bCBvZiBoYXNoZWQgZGF0YSB0eXBlICovCisJaW50MTYJCWhhc2hfdHlwbGVuOwkvKiB0eXBs ZW4gb2YgaGFzaGVkIGRhdGEgdHlwZSAqLworfSBNQ1ZJbkhhc2hDb250ZXh0OworCiAvKiBm b3J3YXJkIHJlZmVyZW5jZSAqLwogdHlwZWRlZiBzdHJ1Y3QgTUNWSGFzaFRhYmxlX2hhc2gg TUNWSGFzaFRhYmxlX2hhc2g7Cit0eXBlZGVmIHN0cnVjdCBNQ1ZJbkhhc2hUYWJsZV9oYXNo IE1DVkluSGFzaFRhYmxlX2hhc2g7CiAKIC8qIEhvb2tzIGZvciBwbHVnaW5zIHRvIGdldCBj b250cm9sIHdoZW4gd2UgYXNrIGZvciBzdGF0cyAqLwogZ2V0X3JlbGF0aW9uX3N0YXRzX2hv b2tfdHlwZSBnZXRfcmVsYXRpb25fc3RhdHNfaG9vayA9IE5VTEw7CiBnZXRfaW5kZXhfc3Rh dHNfaG9va190eXBlIGdldF9pbmRleF9zdGF0c19ob29rID0gTlVMTDsKIAogc3RhdGljIGRv dWJsZSBlcXNlbF9pbnRlcm5hbChQR19GVU5DVElPTl9BUkdTLCBib29sIG5lZ2F0ZSk7Citz dGF0aWMgZG91YmxlIHNjYWxhcmFycmF5X21jdl9oYXNoX21hdGNoX2V4cHIoVmFyaWFibGVT dGF0RGF0YSAqdmFyZGF0YSwgT2lkIG9wZXJhdG9yLCBPaWQgY29sbGF0aW9uLAorCQkJCQkJ CQkJCQkgIE5vZGUgKm90aGVyX29wLCBib29sIHZhcl9vbl9sZWZ0LCBBcnJheUV4cHIgKmFy cmF5ZXhwciwKKwkJCQkJCQkJCQkJICBPaWQgbm9taW5hbF9lbGVtZW50X3R5cGUsIGJvb2wg dXNlT3IsIGJvb2wgaXNFcXVhbGl0eSwKKwkJCQkJCQkJCQkJICBib29sIGlzSW5lcXVhbGl0 eSk7CitzdGF0aWMgZG91YmxlIHNjYWxhcmFycmF5X21jdl9oYXNoX21hdGNoX2NvbnN0KFZh cmlhYmxlU3RhdERhdGEgKnZhcmRhdGEsIE9pZCBvcGVyYXRvciwgT2lkIGNvbGxhdGlvbiwK KwkJCQkJCQkJCQkJICAgRGF0dW0gKmVsZW1fdmFsdWVzLCBib29sICplbGVtX251bGxzLCBp bnQgbnVtX2VsZW1zLAorCQkJCQkJCQkJCQkgICBPaWQgbm9taW5hbF9lbGVtZW50X3R5cGUs IGJvb2wgdXNlT3IsIGJvb2wgaXNFcXVhbGl0eSwKKwkJCQkJCQkJCQkJICAgYm9vbCBpc0lu ZXF1YWxpdHkpOworc3RhdGljIHVpbnQzMiBoYXNoX21jdl9pbihNQ1ZJbkhhc2hUYWJsZV9o YXNoICp0YWIsIERhdHVtIGtleSk7CitzdGF0aWMgYm9vbCBtY3ZzX2luX2VxdWFsKE1DVklu SGFzaFRhYmxlX2hhc2ggKnRhYiwgRGF0dW0ga2V5MCwgRGF0dW0ga2V5MSk7CiBzdGF0aWMg ZG91YmxlIGVxam9pbnNlbF9pbm5lcihGbWdySW5mbyAqZXFwcm9jLCBPaWQgY29sbGF0aW9u LAogCQkJCQkJCSAgT2lkIGhhc2hMZWZ0LCBPaWQgaGFzaFJpZ2h0LAogCQkJCQkJCSAgVmFy aWFibGVTdGF0RGF0YSAqdmFyZGF0YTEsIFZhcmlhYmxlU3RhdERhdGEgKnZhcmRhdGEyLApA QCAtMjg3LDYgKzMyMywxOSBAQCBzdGF0aWMgZG91YmxlIGJ0Y29zdF9jb3JyZWxhdGlvbihJ bmRleE9wdEluZm8gKmluZGV4LAogI2RlZmluZSBTSF9ERUNMQVJFCiAjaW5jbHVkZSAibGli L3NpbXBsZWhhc2guaCIKIAorI2RlZmluZSBTSF9QUkVGSVgJCQkJTUNWSW5IYXNoVGFibGUK KyNkZWZpbmUgU0hfRUxFTUVOVF9UWVBFCQkJTUNWSW5IYXNoRW50cnkKKyNkZWZpbmUgU0hf S0VZX1RZUEUJCQkJRGF0dW0KKyNkZWZpbmUgU0hfS0VZCQkJCQl2YWx1ZQorI2RlZmluZSBT SF9IQVNIX0tFWSh0YWIsa2V5KQloYXNoX21jdl9pbih0YWIsIGtleSkKKyNkZWZpbmUgU0hf RVFVQUwodGFiLGtleTAsa2V5MSkJbWN2c19pbl9lcXVhbCh0YWIsIGtleTAsIGtleTEpCisj ZGVmaW5lIFNIX1NDT1BFCQkJCXN0YXRpYyBpbmxpbmUKKyNkZWZpbmUgU0hfU1RPUkVfSEFT SAorI2RlZmluZSBTSF9HRVRfSEFTSCh0YWIsZW50KQkoZW50KS0+aGFzaAorI2RlZmluZSBT SF9ERUZJTkUKKyNkZWZpbmUgU0hfREVDTEFSRQorI2luY2x1ZGUgImxpYi9zaW1wbGVoYXNo LmgiCisKIAogLyoKICAqCQllcXNlbAkJCS0gU2VsZWN0aXZpdHkgb2YgIj0iIGZvciBhbnkg ZGF0YSB0eXBlcy4KQEAgLTIwMjUsNiArMjA3NCwzNSBAQCBzY2FsYXJhcnJheXNlbChQbGFu bmVySW5mbyAqcm9vdCwKIAkJCQkJCSAgZWxtbGVuLCBlbG1ieXZhbCwgZWxtYWxpZ24sCiAJ CQkJCQkgICZlbGVtX3ZhbHVlcywgJmVsZW1fbnVsbHMsICZudW1fZWxlbXMpOwogCisJCS8q CisJCSAqIFRyeSB0byBjYWxjdWxhdGUgc2VsZWN0aXZpdHkgYnkgaGFzaC1zZWFyY2ggTyhO KSBpbnN0ZWFkIG9mIE8oTl4yKQorCQkgKiBpbiBjYXNlIG9mIE1DViBtYXRjaGluZy4gIFdl IHVzZSBoYXNoLXNlYXJjaCBvbmx5IGZvciBlcXNlbCgpIGFuZAorCQkgKiBuZXFzZWwoKS4K KwkJICovCisJCWlmICgoaXNFcXVhbGl0eSB8fCBpc0luZXF1YWxpdHkpICYmICFpc19qb2lu X2NsYXVzZSkKKwkJeworCQkJVmFyaWFibGVTdGF0RGF0YSB2YXJkYXRhOworCQkJTm9kZQkg ICAqb3RoZXJfb3AgPSBOVUxMOworCQkJYm9vbAkJdmFyX29uX2xlZnQ7CisKKwkJCS8qCisJ CQkgKiBJZiBleHByZXNzaW9uIGlzIG5vdCB2YXJpYWJsZSA9IHNvbWV0aGluZyBvciBzb21l dGhpbmcgPQorCQkJICogdmFyaWFibGUsIHRoZW4gcHVudCBhbmQgcmV0dXJuIGEgZGVmYXVs dCBlc3RpbWF0ZS4KKwkJCSAqLworCQkJaWYgKGdldF9yZXN0cmljdGlvbl92YXJpYWJsZShy b290LCBjbGF1c2UtPmFyZ3MsIHZhclJlbGlkLAorCQkJCQkJCQkJCSAmdmFyZGF0YSwgJm90 aGVyX29wLCAmdmFyX29uX2xlZnQpKQorCQkJeworCQkJCXMxID0gc2NhbGFyYXJyYXlfbWN2 X2hhc2hfbWF0Y2hfY29uc3QoJnZhcmRhdGEsIG9wZXJhdG9yLCBjbGF1c2UtPmlucHV0Y29s bGlkLAorCQkJCQkJCQkJCQkJCSAgZWxlbV92YWx1ZXMsIGVsZW1fbnVsbHMsIG51bV9lbGVt cywKKwkJCQkJCQkJCQkJCQkgIG5vbWluYWxfZWxlbWVudF90eXBlLCB1c2VPciwgaXNFcXVh bGl0eSwgaXNJbmVxdWFsaXR5KTsKKworCQkJCVJlbGVhc2VWYXJpYWJsZVN0YXRzKHZhcmRh dGEpOworCisJCQkJaWYgKHMxID49IDAuMCkKKwkJCQkJcmV0dXJuIHMxOworCQkJfQorCQl9 CisKIAkJLyoKIAkJICogRm9yIGdlbmVyaWMgb3BlcmF0b3JzLCB3ZSBhc3N1bWUgdGhlIHBy b2JhYmlsaXR5IG9mIHN1Y2Nlc3MgaXMKIAkJICogaW5kZXBlbmRlbnQgZm9yIGVhY2ggYXJy YXkgZWxlbWVudC4gIEJ1dCBmb3IgIj0gQU5ZIiBvciAiPD4gQUxMIiwKQEAgLTIxMDAsNiAr MjE3OCwzNSBAQCBzY2FsYXJhcnJheXNlbChQbGFubmVySW5mbyAqcm9vdCwKIAkJZ2V0X3R5 cGxlbmJ5dmFsKGFycmF5ZXhwci0+ZWxlbWVudF90eXBlaWQsCiAJCQkJCQkmZWxtbGVuLCAm ZWxtYnl2YWwpOwogCisJCS8qCisJCSAqIFRyeSB0byBjYWxjdWxhdGUgc2VsZWN0aXZpdHkg YnkgaGFzaC1zZWFyY2ggTyhOKSBpbnN0ZWFkIG9mIE8oTl4yKQorCQkgKiBpbiBjYXNlIG9m IE1DViBtYXRjaGluZy4gIFdlIHVzZSBoYXNoLXNlYXJjaCBvbmx5IGZvciBlcXNlbCgpIGFu ZAorCQkgKiBuZXFzZWwoKS4KKwkJICovCisJCWlmICgoaXNFcXVhbGl0eSB8fCBpc0luZXF1 YWxpdHkpICYmICFpc19qb2luX2NsYXVzZSkKKwkJeworCQkJVmFyaWFibGVTdGF0RGF0YSB2 YXJkYXRhOworCQkJTm9kZQkgICAqb3RoZXJfb3AgPSBOVUxMOworCQkJYm9vbAkJdmFyX29u X2xlZnQ7CisKKwkJCS8qCisJCQkgKiBJZiBleHByZXNzaW9uIGlzIG5vdCB2YXJpYWJsZSA9 IHNvbWV0aGluZyBvciBzb21ldGhpbmcgPQorCQkJICogdmFyaWFibGUsIHRoZW4gcHVudCBh bmQgcmV0dXJuIGEgZGVmYXVsdCBlc3RpbWF0ZS4KKwkJCSAqLworCQkJaWYgKGdldF9yZXN0 cmljdGlvbl92YXJpYWJsZShyb290LCBjbGF1c2UtPmFyZ3MsIHZhclJlbGlkLAorCQkJCQkJ CQkJCSAmdmFyZGF0YSwgJm90aGVyX29wLCAmdmFyX29uX2xlZnQpKQorCQkJeworCQkJCXMx ID0gc2NhbGFyYXJyYXlfbWN2X2hhc2hfbWF0Y2hfZXhwcigmdmFyZGF0YSwgb3BlcmF0b3Is IGNsYXVzZS0+aW5wdXRjb2xsaWQsCisJCQkJCQkJCQkJCQkJIG90aGVyX29wLCB2YXJfb25f bGVmdCwgYXJyYXlleHByLAorCQkJCQkJCQkJCQkJCSBub21pbmFsX2VsZW1lbnRfdHlwZSwg dXNlT3IsIGlzRXF1YWxpdHksIGlzSW5lcXVhbGl0eSk7CisKKwkJCQlSZWxlYXNlVmFyaWFi bGVTdGF0cyh2YXJkYXRhKTsKKworCQkJCWlmIChzMSA+PSAwLjApCisJCQkJCXJldHVybiBz MTsKKwkJCX0KKwkJfQorCiAJCS8qCiAJCSAqIFdlIHVzZSB0aGUgYXNzdW1wdGlvbiBvZiBk aXNqb2ludCBwcm9iYWJpbGl0aWVzIGhlcmUgdG9vLCBhbHRob3VnaAogCQkgKiB0aGUgb2Rk cyBvZiBlcXVhbCBhcnJheSBlbGVtZW50cyBhcmUgcmF0aGVyIGhpZ2hlciBpZiB0aGUgZWxl bWVudHMKQEAgLTIyMTAsNiArMjMxNyw5NTcgQEAgc2NhbGFyYXJyYXlzZWwoUGxhbm5lcklu Zm8gKnJvb3QsCiAJcmV0dXJuIHMxOwogfQogCisvKgorICogRXN0aW1hdGUgc2VsZWN0aXZp dHkgb2YgYSBTY2FsYXJBcnJheU9wRXhwciAoQU5ZL0FMTCkgdXNpbmcgTUNWIHN0YXRpc3Rp Y3MuCisgKgorICogVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIHRoZSBzYW1lIHByb2JhYmls aXR5IG1vZGVsIGFzIHRoZSBzdGFuZGFyZAorICogU2NhbGFyQXJyYXlPcEV4cHIgZXN0aW1h dGlvbiBjb2RlIChpbmRlcGVuZGVudCBvciBkaXNqb2ludCBwcm9iYWJpbGl0aWVzCisgKiBm b3IgT1IvQU5EKSwgYnV0IHVzZXMgTUNWIHN0YXRpc3RpY3MgYW5kIGhhc2hpbmcgdG8gY29t cHV0ZQorICogcGVyLWVsZW1lbnQgcHJvYmFiaWxpdGllcyBlZmZpY2llbnRseSB3aGVuIHBv c3NpYmxlLgorICoKKyAqIE1DVnMgYXJlIHVzZWQgb25seSB0byBvYnRhaW4gbW9yZSBhY2N1 cmF0ZSB2YWx1ZXM7IHRoZSBjb21iaW5hdGlvbgorICogb2YgZnJlcXVlbmNpZXMgZm9sbG93 cyB0aGUgc3RhbmRhcmQgQU5ZL0FMTCBmb3JtdWxhcy4KKyAqCisgKiBJbnB1dHM6CisgKgl2 YXJkYXRhOiBzdGF0aXN0aWNzIGFuZCBtZXRhZGF0YSBmb3IgdGhlIHZhcmlhYmxlIGJlaW5n IGVzdGltYXRlZAorICoJb3BlcmF0b3I6IGVxdWFsaXR5IG9yIGluZXF1YWxpdHkgb3BlcmF0 b3IgdG8gYXBwbHkKKyAqCWNvbGxhdGlvbjogT0lEIG9mIGNvbGxhdGlvbiB0byB1c2UKKyAq CW90aGVyX29wOiBleHByZXNzaW9uIGZvciB0aGUgbm9uLXZhcmlhYmxlIHNpZGUgb2YgdGhl IGNvbXBhcmlzb24KKyAqCXZhcl9vbl9sZWZ0OiB0cnVlIGlmIHRoZSB2YXJpYWJsZSBpcyBv biB0aGUgbGVmdCBzaWRlIG9mIHRoZSBvcGVyYXRvcgorICoJYXJyYXlleHByOiBhcnJheSBv ZiBJTi1saXN0IHdpdGggZXhwcmVzc2lvbnMKKyAqICBub21pbmFsX2VsZW1lbnRfdHlwZTog dHlwZSBvZiBJTi1saXN0IGVsZW1lbnRzCisgKgl1c2VPcjogdHJ1ZSBpZiBlbGVtZW50cyBh cmUgY29tYmluZWQgdXNpbmcgT1Igc2VtYW50aWNzLCBmYWxzZSBmb3IgQU5ECisgKglpc0Vx dWFsaXR5OiB0cnVlIGlmIHRoZSBvcGVyYXRvciBpcyBlcXVhbGl0eQorICoJaXNJbmVxdWFs aXR5OiB0cnVlIGlmIHRoZSBvcGVyYXRvciBpcyBpbmVxdWFsaXR5CisgKgorICogUmVzdWx0 OgorICoJUmV0dXJucyBhIHNlbGVjdGl2aXR5IGVzdGltYXRlIGluIHRoZSByYW5nZSBbMC4w LCAxLjBdLCBvciAtMS4wIGlmIHRoZQorICoJc2VsZWN0aXZpdHkgY2Fubm90IGJlIHJlbGlh Ymx5IGVzdGltYXRlZCBieSB0aGlzIGZ1bmN0aW9uLgorICoKKyAqIE5vdGU6IHRoaXMgZnVu Y3Rpb24gYXNzdW1lcyB0aGF0IHRoZSBvcGVyYXRvcuKAmXMgc2VsZWN0aXZpdHkgYmVoYXZp b3IKKyAqIG1hdGNoZXMgZXFzZWwoKS9uZXFzZWwgc2VtYW50aWNzIChlcXVhbGl0eSBvciBp bmVxdWFsaXR5KS4KKyAqIEl0IG11c3Qgbm90IGJlIHVzZWQgZm9yIG9wZXJhdG9ycyB3aXRo IGN1c3RvbSBvciBub24tc3RhbmRhcmQKKyAqIHNlbGVjdGl2aXR5IGZ1bmN0aW9ucy4KKyAq Lworc3RhdGljIGRvdWJsZQorc2NhbGFyYXJyYXlfbWN2X2hhc2hfbWF0Y2hfZXhwcihWYXJp YWJsZVN0YXREYXRhICp2YXJkYXRhLCBPaWQgb3BlcmF0b3IsIE9pZCBjb2xsYXRpb24sCisJ CQkJCQkJCU5vZGUgKm90aGVyX29wLCBib29sIHZhcl9vbl9sZWZ0LCBBcnJheUV4cHIgKmFy cmF5ZXhwciwKKwkJCQkJCQkJT2lkIG5vbWluYWxfZWxlbWVudF90eXBlLCBib29sIHVzZU9y LCBib29sIGlzRXF1YWxpdHksCisJCQkJCQkJCWJvb2wgaXNJbmVxdWFsaXR5KQoreworCUZv cm1fcGdfc3RhdGlzdGljIHN0YXRzOworCUF0dFN0YXRzU2xvdCBzc2xvdDsKKwlGbWdySW5m bwllcXByb2M7CisJZG91YmxlCQlzZWxlYyA9IC0xLjAsCisJCQkJczFkaXNqb2ludCwKKwkJ CQludWxsZnJhYyA9IDAuMDsKKwlPaWQJCQloYXNoTGVmdCA9IEludmFsaWRPaWQsCisJCQkJ aGFzaFJpZ2h0ID0gSW52YWxpZE9pZCwKKwkJCQlvcGZ1bmNvaWQ7CisJYm9vbAkJaGF2ZV9t Y3ZzID0gZmFsc2U7CisJaW50CQkJbnVtX2VsZW1zID0gMDsKKwlMaXN0Q2VsbCAgICpsOwor CisJLyoKKwkgKiBJZiB0aGUgdmFyaWFibGUgaXMga25vd24gdG8gYmUgdW5pcXVlLCBNQ1Yg c3RhdGlzdGljcyBkbyBub3QgcmVwcmVzZW50CisJICogYSBtZWFuaW5nZnVsIGZyZXF1ZW5j eSBkaXN0cmlidXRpb24sIHNvIHNraXAgTUNWLWJhc2VkIGVzdGltYXRpb24uCisJICovCisJ aWYgKHZhcmRhdGEtPmlzdW5pcXVlICYmIHZhcmRhdGEtPnJlbCAmJiB2YXJkYXRhLT5yZWwt PnR1cGxlcyA+PSAxLjApCisJCXJldHVybiAtMS4wOworCisJLyoKKwkgKiBGb3IgaW5lcXVh bGl0eSAoPD4sIEFMTCksIHdlIGNvbXB1dGUgcHJvYmFiaWxpdGllcyB1c2luZyB0aGUgbmVn YXRlZAorCSAqIGVxdWFsaXR5IG9wZXJhdG9yIGFuZCBsYXRlciB0cmFuc2Zvcm0gdGhlbSBh cworCSAqCisJICogcCh4IDw+IGMpID0gMSAtIHAoeCA9IGMpIC0gbnVsbGZyYWMKKwkgKi8K KwlpZiAoaXNJbmVxdWFsaXR5KQorCXsKKwkJb3BlcmF0b3IgPSBnZXRfbmVnYXRvcihvcGVy YXRvcik7CisJCWlmICghT2lkSXNWYWxpZChvcGVyYXRvcikpCisJCQlyZXR1cm4gLTEuMDsK Kwl9CisKKwlvcGZ1bmNvaWQgPSBnZXRfb3Bjb2RlKG9wZXJhdG9yKTsKKwltZW1zZXQoJnNz bG90LCAwLCBzaXplb2Yoc3Nsb3QpKTsKKworCWlmIChIZWFwVHVwbGVJc1ZhbGlkKHZhcmRh dGEtPnN0YXRzVHVwbGUpKQorCXsKKwkJaWYgKHN0YXRpc3RpY19wcm9jX3NlY3VyaXR5X2No ZWNrKHZhcmRhdGEsIG9wZnVuY29pZCkpCisJCQloYXZlX21jdnMgPSBnZXRfYXR0c3RhdHNz bG90KCZzc2xvdCwgdmFyZGF0YS0+c3RhdHNUdXBsZSwKKwkJCQkJCQkJCQkgU1RBVElTVElD X0tJTkRfTUNWLCBJbnZhbGlkT2lkLAorCQkJCQkJCQkJCSBBVFRTVEFUU1NMT1RfVkFMVUVT IHwgQVRUU1RBVFNTTE9UX05VTUJFUlMpOworCX0KKworCWlmIChoYXZlX21jdnMpCisJewor CQlmbWdyX2luZm8ob3BmdW5jb2lkLCAmZXFwcm9jKTsKKworCQludW1fZWxlbXMgPSBsaXN0 X2xlbmd0aChhcnJheWV4cHItPmVsZW1lbnRzKTsKKworCQkvKgorCQkgKiBmIHRoZSBNQ1Yg bGlzdCBhbmQgSU4tbGlzdCBhcmUgbGFyZ2UgZW5vdWdoLCBhbmQgdGhlIG9wZXJhdG9yCisJ CSAqIHN1cHBvcnRzIGhhc2hpbmcsIGF0dGVtcHQgdG8gdXNlIGhhc2ggZnVuY3Rpb25zIHNv IHRoYXQgTUNW4oCTSU4KKwkJICogbWF0Y2hpbmcgY2FuIGJlIGRvbmUgaW4gTyhOK00pIGlu c3RlYWQgb2YgTyhOw5dNKS4KKwkJICovCisJCWlmIChzc2xvdC5udmFsdWVzICsgbnVtX2Vs ZW1zID49IFNDQUxBUkFSUkFZX01DVl9IQVNIX1RIUkVTSE9MRCkKKwkJCSh2b2lkKSBnZXRf b3BfaGFzaF9mdW5jdGlvbnMob3BlcmF0b3IsICZoYXNoTGVmdCwgJmhhc2hSaWdodCk7CisJ fQorCisJaWYgKGhhdmVfbWN2cyAmJiBPaWRJc1ZhbGlkKGhhc2hMZWZ0KSAmJiBPaWRJc1Zh bGlkKGhhc2hSaWdodCkpCisJeworCQkvKiBVc2UgYSBoYXNoIHRhYmxlIHRvIHNwZWVkIHVw IHRoZSBtYXRjaGluZyAqLworCQlMT0NBTF9GQ0lORk8oZmNpbmZvLCAyKTsKKwkJTE9DQUxf RkNJTkZPKGhhc2hfZmNpbmZvLCAxKTsKKwkJTUNWSW5IYXNoVGFibGVfaGFzaCAqaGFzaFRh YmxlOworCQlGbWdySW5mbwloYXNoX3Byb2M7CisJCU1DVkluSGFzaENvbnRleHQgaGFzaENv bnRleHQ7CisJCWRvdWJsZQkJc3VtYWxsY29tbW9uID0gMC4wLAorCQkJCQlyZW1haW5pbmdf c2VsZWMgPSAwLjA7CisJCWJvb2wJCWlzZGVmYXVsdDsKKwkJZG91YmxlCQlvdGhlcmRpc3Rp bmN0OworCisJCS8qIEdyYWIgdGhlIG51bGxmcmFjIGZvciB1c2UgYmVsb3cuICovCisJCXN0 YXRzID0gKEZvcm1fcGdfc3RhdGlzdGljKSBHRVRTVFJVQ1QodmFyZGF0YS0+c3RhdHNUdXBs ZSk7CisJCW51bGxmcmFjID0gc3RhdHMtPnN0YW51bGxmcmFjOworCisJCXNlbGVjID0gczFk aXNqb2ludCA9ICh1c2VPciA/IDAuMCA6IDEuMCk7CisKKwkJSW5pdEZ1bmN0aW9uQ2FsbElu Zm9EYXRhKCpmY2luZm8sICZlcXByb2MsIDIsIGNvbGxhdGlvbiwKKwkJCQkJCQkJIE5VTEws IE5VTEwpOworCQlmY2luZm8tPmFyZ3NbMF0uaXNudWxsID0gZmFsc2U7CisJCWZjaW5mby0+ YXJnc1sxXS5pc251bGwgPSBmYWxzZTsKKworCQlpZiAoc3Nsb3QubnZhbHVlcyA8PSBudW1f ZWxlbXMpCisJCXsKKwkJCS8qCisJCQkgKiBCdWlsZCBhIGhhc2ggdGFibGUgb3ZlciB0aGUg TUNWIHZhbHVlcy4KKwkJCSAqCisJCQkgKiBGb3IgZWFjaCBJTi1saXN0IGVsZW1lbnQsIHdl IGNvbXB1dGUgcCh4ID0gZWxlbWVudCk6IGNvbnN0YW50cworCQkJICogYXJlIG1hdGNoZWQg YWdhaW5zdCBNQ1ZzIChvciB0aGUgcmVzaWR1YWwgZnJlcXVlbmN5KSwgd2hpbGUKKwkJCSAq IG5vbi1jb25zdGFudCBlbGVtZW50cyBmYWxsIGJhY2sgdG8gdGhlIG9wZXJhdG9yJ3MgZ2Vu ZXJpYworCQkJICogc2VsZWN0aXZpdHkgZXN0aW1hdG9yLiBUaGVzZSBwcm9iYWJpbGl0aWVz IGFyZSB0aGVuIGNvbWJpbmVkCisJCQkgKiB1c2luZyB0aGUgc3RhbmRhcmQgQU5ZL0FMTCBm b3JtdWxhcy4KKwkJCSAqLworCQkJZm1ncl9pbmZvKGhhc2hMZWZ0LCAmaGFzaF9wcm9jKTsK KwkJCUluaXRGdW5jdGlvbkNhbGxJbmZvRGF0YSgqaGFzaF9mY2luZm8sICZoYXNoX3Byb2Ms IDEsIGNvbGxhdGlvbiwKKwkJCQkJCQkJCSBOVUxMLCBOVUxMKTsKKwkJCWhhc2hfZmNpbmZv LT5hcmdzWzBdLmlzbnVsbCA9IGZhbHNlOworCisJCQloYXNoQ29udGV4dC5lcXVhbF9mY2lu Zm8gPSBmY2luZm87CisJCQloYXNoQ29udGV4dC5oYXNoX2ZjaW5mbyA9IGhhc2hfZmNpbmZv OworCQkJaGFzaENvbnRleHQuaW5zZXJ0X21vZGUgPSB0cnVlOworCisJCQlnZXRfdHlwbGVu Ynl2YWwoc3Nsb3QudmFsdWV0eXBlLAorCQkJCQkJCSZoYXNoQ29udGV4dC5oYXNoX3R5cGxl biwKKwkJCQkJCQkmaGFzaENvbnRleHQuaGFzaF90eXBieXZhbCk7CisKKwkJCWhhc2hUYWJs ZSA9IE1DVkluSGFzaFRhYmxlX2NyZWF0ZShDdXJyZW50TWVtb3J5Q29udGV4dCwKKwkJCQkJ CQkJCQkJICBzc2xvdC5udmFsdWVzLAorCQkJCQkJCQkJCQkgICZoYXNoQ29udGV4dCk7CisK KwkJCWZvciAoaW50IGkgPSAwOyBpIDwgc3Nsb3QubnZhbHVlczsgaSsrKQorCQkJeworCQkJ CWJvb2wJCWZvdW5kID0gZmFsc2U7CisJCQkJTUNWSW5IYXNoRW50cnkgKmVudHJ5OworCisJ CQkJZW50cnkgPSBNQ1ZJbkhhc2hUYWJsZV9pbnNlcnQoaGFzaFRhYmxlLCBzc2xvdC52YWx1 ZXNbaV0sICZmb3VuZCk7CisKKwkJCQkvKgorCQkJCSAqIE1DVkhhc2hUYWJsZV9pbnNlcnQg d2lsbCBvbmx5IHJlcG9ydCAiZm91bmQiIGlmIHRoZSBuZXcKKwkJCQkgKiB2YWx1ZSBpcyBl cXVhbCB0byBzb21lIHByZXZpb3VzIG9uZSBwZXIgZGF0dW1faW1hZ2VfZXEoKS4KKwkJCQkg KiBUaGF0IHByb2JhYmx5IHNob3VsZG4ndCBoYXBwZW4sIHNpbmNlIHdlJ3JlIG5vdCBleHBl Y3RpbmcKKwkJCQkgKiBkdXBsaWNhdGVzIGluIHRoZSBNQ1YgbGlzdC4gIElmIHdlIGRvIGZp bmQgYSBkdXAsIGp1c3QKKwkJCQkgKiBpZ25vcmUgaXQsIGxlYXZpbmcgdGhlIGhhc2ggZW50 cnkncyBpbmRleCBwb2ludGluZyBhdCB0aGUKKwkJCQkgKiBmaXJzdCBvY2N1cnJlbmNlLiAg VGhhdCBtYXRjaGVzIHRoZSBiZWhhdmlvciB0aGF0IHRoZQorCQkJCSAqIG5vbi1oYXNoZWQg Y29kZSBwYXRoIHdvdWxkIGhhdmUuCisJCQkJICovCisJCQkJaWYgKGxpa2VseSghZm91bmQp KQorCQkJCQllbnRyeS0+aW5kZXggPSBpOworCisJCQkJc3VtYWxsY29tbW9uICs9IHNzbG90 Lm51bWJlcnNbaV07CisJCQl9CisKKwkJCS8qCisJCQkgKiBQcmVwYXJlIHRvIHByb2JlIHRo ZSBoYXNoIHRhYmxlLiAgSWYgdGhlIHByb2JlIHZhbHVlcyBhcmUgb2YgYQorCQkJICogZGlm ZmVyZW50IGRhdGEgdHlwZSwgdGhlbiB3ZSBuZWVkIHRvIGNoYW5nZSBoYXNoIGZ1bmN0aW9u cy4KKwkJCSAqIChUaGlzIGNvZGUgcmVsaWVzIG9uIHRoZSBhc3N1bXB0aW9uIHRoYXQgc2lu Y2Ugd2UgZGVmaW5lZAorCQkJICogU0hfU1RPUkVfSEFTSCwgc2ltcGxlaGFzaC5oIHdpbGwg bmV2ZXIgbmVlZCB0byBjb21wdXRlIGhhc2gKKwkJCSAqIHZhbHVlcyBmb3IgZXhpc3Rpbmcg aGFzaCB0YWJsZSBlbnRyaWVzLikKKwkJCSAqLworCQkJaGFzaENvbnRleHQuaW5zZXJ0X21v ZGUgPSBmYWxzZTsKKwkJCWlmIChoYXNoTGVmdCAhPSBoYXNoUmlnaHQpCisJCQl7CisJCQkJ Zm1ncl9pbmZvKGhhc2hSaWdodCwgJmhhc2hfcHJvYyk7CisJCQkJLyogUmVzZXR0aW5nIGhh c2hfZmNpbmZvIGlzIHByb2JhYmx5IHVubmVjZXNzYXJ5LCBidXQgYmUgc2FmZSAqLworCQkJ CUluaXRGdW5jdGlvbkNhbGxJbmZvRGF0YSgqaGFzaF9mY2luZm8sICZoYXNoX3Byb2MsIDEs IGNvbGxhdGlvbiwKKwkJCQkJCQkJCQkgTlVMTCwgTlVMTCk7CisJCQkJaGFzaF9mY2luZm8t PmFyZ3NbMF0uaXNudWxsID0gZmFsc2U7CisJCQl9CisKKwkJCS8qCisJCQkgKiByZW1haW5p bmdfc2VsZWMgaXMgdGhlIHRvdGFsIHByb2JhYmlsaXR5IG1hc3Mgb2YgYWxsIG5vbi1NQ1YK KwkJCSAqIHZhbHVlcyAoaS5lLiwgMSAtIHN1bShNQ1YgZnJlcXVlbmNpZXMpIC0gbnVsbGZy YWMpLiAgVGhpcyBtYXNzCisJCQkgKiBpcyBsYXRlciBkaXZpZGVkIGFtb25nIHRoZSByZW1h aW5pbmcgZGlzdGluY3QgdmFsdWVzIHRvCisJCQkgKiBlc3RpbWF0ZSBwKHggPSBjKSBmb3Ig Y29uc3RhbnRzIG5vdCBwcmVzZW50IGluIHRoZSBNQ1YgbGlzdC4KKwkJCSAqLworCQkJcmVt YWluaW5nX3NlbGVjID0gMS4wIC0gc3VtYWxsY29tbW9uIC0gbnVsbGZyYWM7CisJCQlDTEFN UF9QUk9CQUJJTElUWShyZW1haW5pbmdfc2VsZWMpOworCisJCQkvKgorCQkJICogYW5kIGlu IGZhY3QgaXQncyBwcm9iYWJseSBhIGdvb2QgZGVhbCBsZXNzLiBXZSBhcHByb3hpbWF0ZSB0 aGF0CisJCQkgKiBhbGwgdGhlIG5vdC1jb21tb24gdmFsdWVzIHNoYXJlIHRoaXMgcmVtYWlu aW5nIGZyYWN0aW9uCisJCQkgKiBlcXVhbGx5LCBzbyB3ZSBkaXZpZGUgYnkgdGhlIG51bWJl ciBvZiBvdGhlciBkaXN0aW5jdCB2YWx1ZXMuCisJCQkgKi8KKwkJCW90aGVyZGlzdGluY3Qg PSBnZXRfdmFyaWFibGVfbnVtZGlzdGluY3QodmFyZGF0YSwgJmlzZGVmYXVsdCkgLSBzc2xv dC5ubnVtYmVyczsKKwkJCWlmIChvdGhlcmRpc3RpbmN0ID4gMSkKKwkJCQlyZW1haW5pbmdf c2VsZWMgLz0gb3RoZXJkaXN0aW5jdDsKKworCQkJLyoKKwkJCSAqIEFub3RoZXIgY3Jvc3Mt Y2hlY2s6IHNlbGVjdGl2aXR5IHNob3VsZG4ndCBiZSBlc3RpbWF0ZWQgYXMgbW9yZQorCQkJ ICogdGhhbiB0aGUgbGVhc3QgY29tbW9uICJtb3N0IGNvbW1vbiB2YWx1ZSIuCisJCQkgKi8K KwkJCWlmIChzc2xvdC5ubnVtYmVycyA+IDAgJiYgcmVtYWluaW5nX3NlbGVjID4gc3Nsb3Qu bnVtYmVyc1tzc2xvdC5ubnVtYmVycyAtIDFdKQorCQkJCXJlbWFpbmluZ19zZWxlYyA9IHNz bG90Lm51bWJlcnNbc3Nsb3Qubm51bWJlcnMgLSAxXTsKKworCQkJLyogRXZhbHVhdGUgc2Vs ZWN0aXZpdHkgY29udHJpYnV0aW9uIG9mIGVhY2ggSU4tbGlzdCBlbGVtZW50LiAqLworCQkJ Zm9yZWFjaChsLCBhcnJheWV4cHItPmVsZW1lbnRzKQorCQkJeworCQkJCU1DVkluSGFzaEVu dHJ5ICplbnRyeTsKKwkJCQlTZWxlY3Rpdml0eSBzMTsKKwkJCQlOb2RlCSAgICplbGVtX3Zh bHVlID0gKE5vZGUgKikgbGZpcnN0KGwpOworCisJCQkJaWYgKElzQShlbGVtX3ZhbHVlLCBD b25zdCkpCisJCQkJeworCQkJCQkvKgorCQkJCQkgKiBJZiB0aGUgY29uc3RhbnQgaXMgTlVM TCwgYXNzdW1lIG9wZXJhdG9yIGlzIHN0cmljdCBhbmQKKwkJCQkJICogcmV0dXJuIHplcm8s IGllLCBvcGVyYXRvciB3aWxsIG5ldmVyIHJldHVybiBUUlVFLgorCQkJCQkgKiAoSXQncyB6 ZXJvIGV2ZW4gZm9yIGEgbmVnYXRvciBvcC4pCisJCQkJCSAqLworCQkJCQlpZiAoKChDb25z dCAqKSBlbGVtX3ZhbHVlKS0+Y29uc3Rpc251bGwpCisJCQkJCQljb250aW51ZTsKKworCQkJ CQllbnRyeSA9IE1DVkluSGFzaFRhYmxlX2xvb2t1cChoYXNoVGFibGUsICgoQ29uc3QgKikg ZWxlbV92YWx1ZSktPmNvbnN0dmFsdWUpOworCisJCQkJCWlmIChlbnRyeSAhPSBOVUxMKQor CQkJCQl7CisJCQkJCQkvKgorCQkJCQkJICogQXMgaW4gdGhlIG90aGVyIGNvZGUgcGF0aCwg c2tpcCBhbHJlYWR5LW1hdGNoZWQKKwkJCQkJCSAqIGhhc2ggZW50cmllcworCQkJCQkJICov CisJCQkJCQlzMSA9IHNzbG90Lm51bWJlcnNbZW50cnktPmluZGV4XTsKKwkJCQkJfQorCQkJ CQllbHNlCisJCQkJCXsKKwkJCQkJCXMxID0gcmVtYWluaW5nX3NlbGVjOworCQkJCQl9CisK KwkJCQkJaWYgKGlzSW5lcXVhbGl0eSkKKwkJCQkJCXMxID0gMS4wIC0gczEgLSBudWxsZnJh YzsKKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJczEgPSB2YXJfZXFfbm9uX2NvbnN0 KHZhcmRhdGEsIG9wZXJhdG9yLCBjb2xsYXRpb24sIG90aGVyX29wLAorCQkJCQkJCQkJCSAg dmFyX29uX2xlZnQsIGlzSW5lcXVhbGl0eSk7CisJCQkJfQorCisJCQkJQ0xBTVBfUFJPQkFC SUxJVFkoczEpOworCisJCQkJaWYgKHVzZU9yKQorCQkJCXsKKwkJCQkJc2VsZWMgPSBzZWxl YyArIHMxIC0gc2VsZWMgKiBzMTsKKwkJCQkJaWYgKGlzRXF1YWxpdHkpCisJCQkJCQlzMWRp c2pvaW50ICs9IHMxOworCQkJCX0KKwkJCQllbHNlCisJCQkJeworCQkJCQlzZWxlYyA9IHNl bGVjICogczE7CisJCQkJCWlmIChpc0luZXF1YWxpdHkpCisJCQkJCQlzMWRpc2pvaW50ICs9 IHMxIC0gMS4wOworCQkJCX0KKwkJCX0KKworCQkJTUNWSW5IYXNoVGFibGVfZGVzdHJveSho YXNoVGFibGUpOworCisJCQkvKgorCQkJICogRm9yID0gQU5ZIG9yIDw+IEFMTCwgaWYgdGhl IElOLWxpc3QgZWxlbWVudHMgYXJlIGFzc3VtZWQKKwkJCSAqIGRpc3RpbmN0LCB0aGUgZXZl bnRzIGFyZSBkaXNqb2ludCBhbmQgdGhlIHRvdGFsIHByb2JhYmlsaXR5IGlzCisJCQkgKiB0 aGUgc3VtIG9mIGluZGl2aWR1YWwgcHJvYmFiaWxpdGllcy4gIFVzZSB0aGF0IGVzdGltYXRl IGlmIGl0CisJCQkgKiBsaWVzIGluIFswLDFdLgorCQkJICovCisJCQlpZiAoKHVzZU9yID8g aXNFcXVhbGl0eSA6IGlzSW5lcXVhbGl0eSkgJiYKKwkJCQlzMWRpc2pvaW50ID49IDAuMCAm JiBzMWRpc2pvaW50IDw9IDEuMCkKKwkJCQlzZWxlYyA9IHMxZGlzam9pbnQ7CisJCX0KKwkJ ZWxzZQorCQl7CisJCQkvKgorCQkJICogSGVyZSB0aGUgSU4tbGlzdCBpcyBzaG9ydGVyIHRo YW4gdGhlIE1DViBsaXN0LgorCQkJICoKKwkJCSAqIFdlIGJ1aWxkIGEgaGFzaCB0YWJsZSBv dmVyIHRoZSBJTi1saXN0IHZhbHVlcyBzbyB0aGF0IHdlIGNhbgorCQkJICogcXVpY2tseSBk ZXRlcm1pbmUgd2hpY2ggTUNWcyBhcmUgcmVmZXJlbmNlZCBieSB0aGUgcXVlcnkuCisJCQkg KgorCQkJICogV2UgdGhlbjogLSBzdW0gcHJvYmFiaWxpdGllcyBvZiBNQ1ZzIHRoYXQgYXBw ZWFyIGluIHRoZSBJTi1saXN0CisJCQkgKiAtIGNvdW50IGhvdyBtYW55IElOLWxpc3QgdmFs dWVzIGFyZSBub3QgTUNWcyAtIGVzdGltYXRlIHRoZWlyCisJCQkgKiBwcm9iYWJpbGl0aWVz IGZyb20gdGhlIHJlbWFpbmluZyBmcmVxdWVuY3kgbWFzcyAtIGNvbWJpbmUKKwkJCSAqIGV2 ZXJ5dGhpbmcgdXNpbmcgdGhlIHN0YW5kYXJkIEFOWS9BTEwgcHJvYmFiaWxpdHkgcnVsZXMK KwkJCSAqLworCQkJaW50CQkJZGlzdGluY3RfaW4gPSAwOworCQkJaW50CQkJbWN2X21hdGNo ZXMgPSAwOworCQkJaW50CQkJbm9uX21jdl9pbiA9IDA7CisJCQlkb3VibGUJCW1jdl9zdW0g PSAwLjA7CisJCQlTZWxlY3Rpdml0eSBkaXNqb2ludF9zZWwgPSAwLjA7CisKKwkJCWZtZ3Jf aW5mbyhoYXNoUmlnaHQsICZoYXNoX3Byb2MpOworCQkJSW5pdEZ1bmN0aW9uQ2FsbEluZm9E YXRhKCpoYXNoX2ZjaW5mbywgJmhhc2hfcHJvYywgMSwgY29sbGF0aW9uLAorCQkJCQkJCQkJ IE5VTEwsIE5VTEwpOworCQkJaGFzaF9mY2luZm8tPmFyZ3NbMF0uaXNudWxsID0gZmFsc2U7 CisKKwkJCWhhc2hDb250ZXh0LmVxdWFsX2ZjaW5mbyA9IGZjaW5mbzsKKwkJCWhhc2hDb250 ZXh0Lmhhc2hfZmNpbmZvID0gaGFzaF9mY2luZm87CisJCQloYXNoQ29udGV4dC5pbnNlcnRf bW9kZSA9IHRydWU7CisKKwkJCWdldF90eXBsZW5ieXZhbChub21pbmFsX2VsZW1lbnRfdHlw ZSwKKwkJCQkJCQkmaGFzaENvbnRleHQuaGFzaF90eXBsZW4sCisJCQkJCQkJJmhhc2hDb250 ZXh0Lmhhc2hfdHlwYnl2YWwpOworCisJCQkvKgorCQkJICogQnVpbGQgYSBoYXNoIHRhYmxl IG92ZXIgdGhlIGRpc3RpbmN0IGNvbnN0YW50IHZhbHVlcyBmcm9tIHRoZQorCQkJICogSU4t bGlzdC4gRHVwbGljYXRlcyBhcmUgaWdub3JlZCBiZWNhdXNlIEFOWS9BTEwgc2VtYW50aWNz CisJCQkgKiBhc3N1bWUgdGhlIGVsZW1lbnRzIGFyZSBkaXN0aW5jdCBmb3IgZGlzam9pbnQt cHJvYmFiaWxpdHkKKwkJCSAqIGVzdGltYXRpb24uCisJCQkgKi8KKwkJCWhhc2hUYWJsZSA9 IE1DVkluSGFzaFRhYmxlX2NyZWF0ZShDdXJyZW50TWVtb3J5Q29udGV4dCwKKwkJCQkJCQkJ CQkJICBudW1fZWxlbXMsCisJCQkJCQkJCQkJCSAgJmhhc2hDb250ZXh0KTsKKworCQkJLyoK KwkJCSAqIEluc2VydCBhbGwgY29uc3RhbnQgSU4tbGlzdCBlbGVtZW50cyBpbnRvIHRoZSBo YXNoIHRhYmxlLAorCQkJICoga2VlcGluZyBvbmx5IG9uZSBjb3B5IG9mIGVhY2ggZGlzdGlu Y3QgdmFsdWUuCisJCQkgKi8KKwkJCWZvcmVhY2gobCwgYXJyYXlleHByLT5lbGVtZW50cykK KwkJCXsKKwkJCQlib29sCQlmb3VuZCA9IGZhbHNlOworCQkJCU5vZGUJICAgKmVsZW1fdmFs dWUgPSAoTm9kZSAqKSBsZmlyc3QobCk7CisKKwkJCQlpZiAoIUlzQShlbGVtX3ZhbHVlLCBD b25zdCkpCisJCQkJCWNvbnRpbnVlOworCisJCQkJaWYgKCgoQ29uc3QgKikgZWxlbV92YWx1 ZSktPmNvbnN0aXNudWxsKQorCQkJCQljb250aW51ZTsKKworCQkJCU1DVkluSGFzaFRhYmxl X2luc2VydChoYXNoVGFibGUsICgoQ29uc3QgKikgZWxlbV92YWx1ZSktPmNvbnN0dmFsdWUs ICZmb3VuZCk7CisKKwkJCQlpZiAobGlrZWx5KCFmb3VuZCkpCisJCQkJCWRpc3RpbmN0X2lu Kys7CisJCQl9CisKKwkJCWhhc2hDb250ZXh0Lmluc2VydF9tb2RlID0gZmFsc2U7CisJCQlp ZiAoaGFzaExlZnQgIT0gaGFzaFJpZ2h0KQorCQkJeworCQkJCWZtZ3JfaW5mbyhoYXNoTGVm dCwgJmhhc2hfcHJvYyk7CisJCQkJLyogUmVzZXR0aW5nIGhhc2hfZmNpbmZvIGlzIHByb2Jh Ymx5IHVubmVjZXNzYXJ5LCBidXQgYmUgc2FmZSAqLworCQkJCUluaXRGdW5jdGlvbkNhbGxJ bmZvRGF0YSgqaGFzaF9mY2luZm8sICZoYXNoX3Byb2MsIDEsIGNvbGxhdGlvbiwKKwkJCQkJ CQkJCQkgTlVMTCwgTlVMTCk7CisJCQkJaGFzaF9mY2luZm8tPmFyZ3NbMF0uaXNudWxsID0g ZmFsc2U7CisJCQl9CisKKwkJCS8qCisJCQkgKiBTY2FuIHRoZSBNQ1YgbGlzdCBvbmNlLgor CQkJICoKKwkJCSAqIEZvciBlYWNoIE1DViB2YWx1ZTogLSBhbHdheXMgYWRkIGl0cyBmcmVx dWVuY3kgdG8gc3VtYWxsY29tbW9uCisJCQkgKiAobmVlZGVkIHRvIGNvbXB1dGUgdGhlIHJl bWFpbmluZyBub24tTUNWIHByb2JhYmlsaXR5IG1hc3MpIC0gaWYKKwkJCSAqIHRoZSBNQ1Yg YXBwZWFycyBpbiB0aGUgSU4tbGlzdCwgcmVjb3JkIGl0IGFzIGEgbWF0Y2ggYW5kIGFkZAor CQkJICogaXRzIHByb2JhYmlsaXR5IHRvIG1jdl9zdW0KKwkJCSAqCisJCQkgKiBBdCB0aGUg c2FtZSB0aW1lIHdlIGFsc28gZm9sZCBpdHMgY29udHJpYnV0aW9uIGludG8gdGhlIHJ1bm5p bmcKKwkJCSAqIEFOWS9BTEwgcHJvYmFiaWxpdHkgKHNlbGVjKSwgZXhhY3RseSBhcyB0aGUg Z2VuZXJpYyBjb2RlIGRvZXMuCisJCQkgKi8KKwkJCWZvciAoaW50IGkgPSAwOyBpIDwgc3Ns b3QubnZhbHVlczsgaSsrKQorCQkJeworCQkJCU1DVkluSGFzaEVudHJ5ICplbnRyeTsKKwor CQkJCXN1bWFsbGNvbW1vbiArPSBzc2xvdC5udW1iZXJzW2ldOworCisJCQkJZW50cnkgPSBN Q1ZJbkhhc2hUYWJsZV9sb29rdXAoaGFzaFRhYmxlLCBzc2xvdC52YWx1ZXNbaV0pOworCQkJ CWlmIChlbnRyeSAhPSBOVUxMKQorCQkJCXsKKwkJCQkJU2VsZWN0aXZpdHkgczEgPSBzc2xv dC5udW1iZXJzW2ldOworCisJCQkJCW1jdl9zdW0gKz0gczE7CisJCQkJCW1jdl9tYXRjaGVz Kys7CisKKwkJCQkJaWYgKGlzSW5lcXVhbGl0eSkKKwkJCQkJCXMxID0gMS4wIC0gczEgLSBu dWxsZnJhYzsKKworCQkJCQlDTEFNUF9QUk9CQUJJTElUWShzMSk7CisKKwkJCQkJaWYgKHVz ZU9yKQorCQkJCQkJc2VsZWMgPSBzZWxlYyArIHMxIC0gc2VsZWMgKiBzMTsKKwkJCQkJZWxz ZQorCQkJCQkJc2VsZWMgPSBzZWxlYyAqIHMxOworCQkJCX0KKwkJCX0KKworCQkJLyoKKwkJ CSAqIENvbXB1dGUgdGhlIHRvdGFsIHByb2JhYmlsaXR5IG1hc3Mgb2YgYWxsIG5vbi1NQ1Yg dmFsdWVzLiBUaGlzCisJCQkgKiBpcyB0aGUgcGFydCBvZiB0aGUgY29sdW1uIGRpc3RyaWJ1 dGlvbiBub3QgY292ZXJlZCBieSBNQ1ZzLgorCQkJICovCisJCQlyZW1haW5pbmdfc2VsZWMg PSAxLjAgLSBzdW1hbGxjb21tb24gLSBudWxsZnJhYzsKKwkJCUNMQU1QX1BST0JBQklMSVRZ KHJlbWFpbmluZ19zZWxlYyk7CisKKwkJCS8qCisJCQkgKiBBcHByb3hpbWF0ZSB0aGUgcGVy LXZhbHVlIHByb2JhYmlsaXR5IG9mIGEgbm9uLU1DViBjb25zdGFudCBieQorCQkJICogZGl2 aWRpbmcgdGhlIHJlbWFpbmluZyBwcm9iYWJpbGl0eSBtYXNzIGJ5IHRoZSBudW1iZXIgb2Yg b3RoZXIKKwkJCSAqIGRpc3RpbmN0IHZhbHVlcy4KKwkJCSAqLworCQkJb3RoZXJkaXN0aW5j dCA9IGdldF92YXJpYWJsZV9udW1kaXN0aW5jdCh2YXJkYXRhLCAmaXNkZWZhdWx0KSAtIHNz bG90Lm5udW1iZXJzOworCQkJaWYgKG90aGVyZGlzdGluY3QgPiAxKQorCQkJCXJlbWFpbmlu Z19zZWxlYyAvPSBvdGhlcmRpc3RpbmN0OworCisJCQlpZiAoc3Nsb3Qubm51bWJlcnMgPiAw ICYmIHJlbWFpbmluZ19zZWxlYyA+IHNzbG90Lm51bWJlcnNbc3Nsb3Qubm51bWJlcnMgLSAx XSkKKwkJCQlyZW1haW5pbmdfc2VsZWMgPSBzc2xvdC5udW1iZXJzW3NzbG90Lm5udW1iZXJz IC0gMV07CisKKwkJCS8qCisJCQkgKiBOdW1iZXIgb2YgSU4tbGlzdCB2YWx1ZXMgdGhhdCBh cmUgbm90IE1DVnMuIEVhY2ggb2YgdGhlc2UgaXMKKwkJCSAqIGFzc3VtZWQgdG8gaGF2ZSBw cm9iYWJpbGl0eSA9IHJlbWFpbmluZ19zZWxlYy4KKwkJCSAqLworCQkJbm9uX21jdl9pbiA9 IGRpc3RpbmN0X2luIC0gbWN2X21hdGNoZXM7CisJCQlBc3NlcnQobm9uX21jdl9pbiA+PSAw KTsKKworCQkJLyoKKwkJCSAqIENvbXB1dGUgdGhlIGRpc2pvaW50LXByb2JhYmlsaXR5IGVz dGltYXRlOgorCQkJICoKKwkJCSAqIHMgPSBzdW0gb2YgcHJvYmFiaWxpdGllcyBvZiBhbGwg TUNWIHZhbHVlcyBwcmVzZW50IGluIHRoZQorCQkJICogSU4tbGlzdCArIHN1bSBvZiBwcm9i YWJpbGl0aWVzIG9mIGFsbCBub24tTUNWIElOLWxpc3QgdmFsdWVzCisJCQkgKgorCQkJICog VGhpcyBpcyB2YWxpZCBmb3IgPSBBTlkgYW5kIDw+IEFMTCB3aGVuIHRoZSBJTi1saXN0IGVs ZW1lbnRzCisJCQkgKiBhcmUgYXNzdW1lZCBkaXN0aW5jdC4KKwkJCSAqLworCQkJZGlzam9p bnRfc2VsID0gbWN2X3N1bSArIG5vbl9tY3ZfaW4gKiByZW1haW5pbmdfc2VsZWM7CisKKwkJ CWlmIChpc0luZXF1YWxpdHkpCisJCQkJZGlzam9pbnRfc2VsID0gMS4wIC0gZGlzam9pbnRf c2VsIC0gbnVsbGZyYWM7CisKKwkJCWlmICgodXNlT3IgPyBpc0VxdWFsaXR5IDogaXNJbmVx dWFsaXR5KSAmJgorCQkJCWRpc2pvaW50X3NlbCA+PSAwLjAgJiYgZGlzam9pbnRfc2VsIDw9 IDEuMCkKKwkJCQlzZWxlYyA9IGRpc2pvaW50X3NlbDsKKworCQkJLyoKKwkJCSAqIFRoZXNl IGVsZW1lbnRzIGNhbm5vdCBiZSBtYXRjaGVkIGFnYWluc3QgTUNWcyBhbmQgdGhlcmVmb3Jl CisJCQkgKiBtdXN0IGFsd2F5cyBiZSBoYW5kbGVkIGJ5IHRoZSBnZW5lcmljIGVzdGltYXRv ci4gVGhlaXIKKwkJCSAqIHByb2JhYmlsaXRpZXMgYXJlIGNvbWJpbmVkIGludG8gdGhlIHNh bWUgQU5ZL0FMTCBwcm9iYWJpbGl0eQorCQkJICogY2hhaW4gdG8gcHJlc2VydmUgdGhlIGNv cnJlY3QgcHJvYmFiaWxpdHkgbW9kZWwuCisJCQkgKi8KKwkJCWZvcmVhY2gobCwgYXJyYXll eHByLT5lbGVtZW50cykKKwkJCXsKKwkJCQlTZWxlY3Rpdml0eSBzMSA9IDAuMDsKKwkJCQlO b2RlCSAgICplbGVtX3ZhbHVlID0gKE5vZGUgKikgbGZpcnN0KGwpOworCisJCQkJaWYgKElz QShlbGVtX3ZhbHVlLCBDb25zdCkpCisJCQkJCWNvbnRpbnVlOworCisJCQkJczEgPSB2YXJf ZXFfbm9uX2NvbnN0KHZhcmRhdGEsIG9wZXJhdG9yLCBjb2xsYXRpb24sCisJCQkJCQkJCQkg IG90aGVyX29wLCB2YXJfb25fbGVmdCwgaXNJbmVxdWFsaXR5KTsKKworCQkJCWlmIChpc0lu ZXF1YWxpdHkpCisJCQkJCXMxID0gMS4wIC0gczEgLSBudWxsZnJhYzsKKworCQkJCUNMQU1Q X1BST0JBQklMSVRZKHMxKTsKKworCQkJCWlmICh1c2VPcikKKwkJCQkJc2VsZWMgPSBzZWxl YyArIHMxIC0gc2VsZWMgKiBzMTsKKwkJCQllbHNlCisJCQkJCXNlbGVjID0gc2VsZWMgKiBz MTsKKwkJCX0KKworCQkJTUNWSW5IYXNoVGFibGVfZGVzdHJveShoYXNoVGFibGUpOworCQl9 CisKKwkJQ0xBTVBfUFJPQkFCSUxJVFkoc2VsZWMpOworCX0KKworCWZyZWVfYXR0c3RhdHNz bG90KCZzc2xvdCk7CisKKwlyZXR1cm4gc2VsZWM7Cit9CisKKy8qCisgKiBFc3RpbWF0ZSBz ZWxlY3Rpdml0eSBvZiBhIFNjYWxhckFycmF5T3BFeHByIChBTlkvQUxMKSB1c2luZyBNQ1Yg c3RhdGlzdGljcy4KKyAqCisgKiBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgdGhlIHNhbWUg cHJvYmFiaWxpdHkgbW9kZWwgYXMgdGhlIHN0YW5kYXJkCisgKiBTY2FsYXJBcnJheU9wRXhw ciBlc3RpbWF0aW9uIGNvZGUgKGluZGVwZW5kZW50IG9yIGRpc2pvaW50IHByb2JhYmlsaXRp ZXMKKyAqIGZvciBPUi9BTkQpLCBidXQgdXNlcyBNQ1Ygc3RhdGlzdGljcyBhbmQgaGFzaGlu ZyB0byBjb21wdXRlCisgKiBwZXItZWxlbWVudCBwcm9iYWJpbGl0aWVzIGVmZmljaWVudGx5 IHdoZW4gcG9zc2libGUuCisgKgorICogTUNWcyBhcmUgdXNlZCBvbmx5IHRvIG9idGFpbiBt b3JlIGFjY3VyYXRlIHZhbHVlczsgdGhlIGNvbWJpbmF0aW9uCisgKiBvZiBmcmVxdWVuY2ll cyBmb2xsb3dzIHRoZSBzdGFuZGFyZCBBTlkvQUxMIGZvcm11bGFzLgorICoKKyAqIElucHV0 czoKKyAqCXZhcmRhdGE6IHN0YXRpc3RpY3MgYW5kIG1ldGFkYXRhIGZvciB0aGUgdmFyaWFi bGUgYmVpbmcgZXN0aW1hdGVkCisgKglvcGVyYXRvcjogZXF1YWxpdHkgb3IgaW5lcXVhbGl0 eSBvcGVyYXRvciB0byBhcHBseQorICoJY29sbGF0aW9uOiBPSUQgb2YgY29sbGF0aW9uIHRv IHVzZQorICoJb3RoZXJfb3A6IGV4cHJlc3Npb24gZm9yIHRoZSBub24tdmFyaWFibGUgc2lk ZSBvZiB0aGUgY29tcGFyaXNvbgorICoJdmFyX29uX2xlZnQ6IHRydWUgaWYgdGhlIHZhcmlh YmxlIGlzIG9uIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIG9wZXJhdG9yCisgKgllbGVtX3ZhbHVl czogYXJyYXkgb2YgSU4tbGlzdCBlbGVtZW50IGNvbnN0IHZhbHVlcworICoJZWxlbV9udWxs czogYXJyYXkgaW5kaWNhdGluZyB3aGljaCBJTi1saXN0IGVsZW1lbnRzIGFyZSBOVUxMCisg KgludW1fZWxlbXM6IG51bWJlciBvZiBJTi1saXN0IGNvbnN0IGVsZW1lbnRzCisgKiAgbm9t aW5hbF9lbGVtZW50X3R5cGU6IHR5cGUgb2YgSU4tbGlzdCBlbGVtZW50cworICoJdXNlT3I6 IHRydWUgaWYgZWxlbWVudHMgYXJlIGNvbWJpbmVkIHVzaW5nIE9SIHNlbWFudGljcywgZmFs c2UgZm9yIEFORAorICoJaXNFcXVhbGl0eTogdHJ1ZSBpZiB0aGUgb3BlcmF0b3IgaXMgZXF1 YWxpdHkKKyAqCWlzSW5lcXVhbGl0eTogdHJ1ZSBpZiB0aGUgb3BlcmF0b3IgaXMgaW5lcXVh bGl0eQorICoKKyAqIFJlc3VsdDoKKyAqCVJldHVybnMgYSBzZWxlY3Rpdml0eSBlc3RpbWF0 ZSBpbiB0aGUgcmFuZ2UgWzAuMCwgMS4wXSwgb3IgLTEuMCBpZiB0aGUKKyAqCXNlbGVjdGl2 aXR5IGNhbm5vdCBiZSByZWxpYWJseSBlc3RpbWF0ZWQgYnkgdGhpcyBmdW5jdGlvbi4KKyAq CisgKiBOb3RlOiB0aGlzIGZ1bmN0aW9uIGFzc3VtZXMgdGhhdCB0aGUgb3BlcmF0b3LigJlz IHNlbGVjdGl2aXR5IGJlaGF2aW9yCisgKiBtYXRjaGVzIGVxc2VsKCkvbmVxc2VsIHNlbWFu dGljcyAoZXF1YWxpdHkgb3IgaW5lcXVhbGl0eSkuCisgKiBJdCBtdXN0IG5vdCBiZSB1c2Vk IGZvciBvcGVyYXRvcnMgd2l0aCBjdXN0b20gb3Igbm9uLXN0YW5kYXJkCisgKiBzZWxlY3Rp dml0eSBmdW5jdGlvbnMuCisgKi8KK3N0YXRpYyBkb3VibGUKK3NjYWxhcmFycmF5X21jdl9o YXNoX21hdGNoX2NvbnN0KFZhcmlhYmxlU3RhdERhdGEgKnZhcmRhdGEsIE9pZCBvcGVyYXRv ciwgT2lkIGNvbGxhdGlvbiwKKwkJCQkJCQkJIERhdHVtICplbGVtX3ZhbHVlcywgYm9vbCAq ZWxlbV9udWxscywgaW50IG51bV9lbGVtcywKKwkJCQkJCQkJIE9pZCBub21pbmFsX2VsZW1l bnRfdHlwZSwgYm9vbCB1c2VPciwgYm9vbCBpc0VxdWFsaXR5LAorCQkJCQkJCQkgYm9vbCBp c0luZXF1YWxpdHkpCit7CisJRm9ybV9wZ19zdGF0aXN0aWMgc3RhdHM7CisJQXR0U3RhdHNT bG90IHNzbG90OworCUZtZ3JJbmZvCWVxcHJvYzsKKwlkb3VibGUJCXNlbGVjID0gLTEuMCwK KwkJCQlzMWRpc2pvaW50LAorCQkJCW51bGxmcmFjID0gMC4wOworCU9pZAkJCWhhc2hMZWZ0 ID0gSW52YWxpZE9pZCwKKwkJCQloYXNoUmlnaHQgPSBJbnZhbGlkT2lkLAorCQkJCW9wZnVu Y29pZDsKKwlib29sCQloYXZlX21jdnMgPSBmYWxzZTsKKworCS8qCisJICogSWYgdGhlIHZh cmlhYmxlIGlzIGtub3duIHRvIGJlIHVuaXF1ZSwgTUNWIHN0YXRpc3RpY3MgZG8gbm90IHJl cHJlc2VudAorCSAqIGEgbWVhbmluZ2Z1bCBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uLCBzbyBz a2lwIE1DVi1iYXNlZCBlc3RpbWF0aW9uLgorCSAqLworCWlmICh2YXJkYXRhLT5pc3VuaXF1 ZSAmJiB2YXJkYXRhLT5yZWwgJiYgdmFyZGF0YS0+cmVsLT50dXBsZXMgPj0gMS4wKQorCQly ZXR1cm4gLTEuMDsKKworCS8qCisJICogRm9yIGluZXF1YWxpdHkgKDw+LCBBTEwpLCB3ZSBj b21wdXRlIHByb2JhYmlsaXRpZXMgdXNpbmcgdGhlIG5lZ2F0ZWQKKwkgKiBlcXVhbGl0eSBv cGVyYXRvciBhbmQgbGF0ZXIgdHJhbnNmb3JtIHRoZW0gYXMKKwkgKgorCSAqIHAoeCA8PiBj KSA9IDEgLSBwKHggPSBjKSAtIG51bGxmcmFjCisJICovCisJaWYgKGlzSW5lcXVhbGl0eSkK Kwl7CisJCW9wZXJhdG9yID0gZ2V0X25lZ2F0b3Iob3BlcmF0b3IpOworCQlpZiAoIU9pZElz VmFsaWQob3BlcmF0b3IpKQorCQkJcmV0dXJuIC0xLjA7CisJfQorCisJb3BmdW5jb2lkID0g Z2V0X29wY29kZShvcGVyYXRvcik7CisJbWVtc2V0KCZzc2xvdCwgMCwgc2l6ZW9mKHNzbG90 KSk7CisKKwlpZiAoSGVhcFR1cGxlSXNWYWxpZCh2YXJkYXRhLT5zdGF0c1R1cGxlKSkKKwl7 CisJCWlmIChzdGF0aXN0aWNfcHJvY19zZWN1cml0eV9jaGVjayh2YXJkYXRhLCBvcGZ1bmNv aWQpKQorCQkJaGF2ZV9tY3ZzID0gZ2V0X2F0dHN0YXRzc2xvdCgmc3Nsb3QsIHZhcmRhdGEt PnN0YXRzVHVwbGUsCisJCQkJCQkJCQkJIFNUQVRJU1RJQ19LSU5EX01DViwgSW52YWxpZE9p ZCwKKwkJCQkJCQkJCQkgQVRUU1RBVFNTTE9UX1ZBTFVFUyB8IEFUVFNUQVRTU0xPVF9OVU1C RVJTKTsKKwl9CisKKwlpZiAoaGF2ZV9tY3ZzKQorCXsKKwkJZm1ncl9pbmZvKG9wZnVuY29p ZCwgJmVxcHJvYyk7CisKKwkJLyoKKwkJICogZiB0aGUgTUNWIGxpc3QgYW5kIElOLWxpc3Qg YXJlIGxhcmdlIGVub3VnaCwgYW5kIHRoZSBvcGVyYXRvcgorCQkgKiBzdXBwb3J0cyBoYXNo aW5nLCBhdHRlbXB0IHRvIHVzZSBoYXNoIGZ1bmN0aW9ucyBzbyB0aGF0IE1DVuKAk0lOCisJ CSAqIG1hdGNoaW5nIGNhbiBiZSBkb25lIGluIE8oTitNKSBpbnN0ZWFkIG9mIE8oTsOXTSku CisJCSAqLworCQlpZiAoc3Nsb3QubnZhbHVlcyArIG51bV9lbGVtcyA+PSBTQ0FMQVJBUlJB WV9NQ1ZfSEFTSF9USFJFU0hPTEQpCisJCQkodm9pZCkgZ2V0X29wX2hhc2hfZnVuY3Rpb25z KG9wZXJhdG9yLCAmaGFzaExlZnQsICZoYXNoUmlnaHQpOworCX0KKworCWlmIChoYXZlX21j dnMgJiYgT2lkSXNWYWxpZChoYXNoTGVmdCkgJiYgT2lkSXNWYWxpZChoYXNoUmlnaHQpKQor CXsKKwkJLyogVXNlIGEgaGFzaCB0YWJsZSB0byBzcGVlZCB1cCB0aGUgbWF0Y2hpbmcgKi8K KwkJTE9DQUxfRkNJTkZPKGZjaW5mbywgMik7CisJCUxPQ0FMX0ZDSU5GTyhoYXNoX2ZjaW5m bywgMSk7CisJCU1DVkluSGFzaFRhYmxlX2hhc2ggKmhhc2hUYWJsZTsKKwkJRm1nckluZm8J aGFzaF9wcm9jOworCQlNQ1ZJbkhhc2hDb250ZXh0IGhhc2hDb250ZXh0OworCQlkb3VibGUJ CXN1bWFsbGNvbW1vbiA9IDAuMCwKKwkJCQkJcmVtYWluaW5nX3NlbGVjID0gMC4wOworCQli b29sCQlpc2RlZmF1bHQ7CisJCWRvdWJsZQkJb3RoZXJkaXN0aW5jdDsKKworCQkvKiBHcmFi IHRoZSBudWxsZnJhYyBmb3IgdXNlIGJlbG93LiAqLworCQlzdGF0cyA9IChGb3JtX3BnX3N0 YXRpc3RpYykgR0VUU1RSVUNUKHZhcmRhdGEtPnN0YXRzVHVwbGUpOworCQludWxsZnJhYyA9 IHN0YXRzLT5zdGFudWxsZnJhYzsKKworCQlzZWxlYyA9IHMxZGlzam9pbnQgPSAodXNlT3Ig PyAwLjAgOiAxLjApOworCisJCUluaXRGdW5jdGlvbkNhbGxJbmZvRGF0YSgqZmNpbmZvLCAm ZXFwcm9jLCAyLCBjb2xsYXRpb24sCisJCQkJCQkJCSBOVUxMLCBOVUxMKTsKKwkJZmNpbmZv LT5hcmdzWzBdLmlzbnVsbCA9IGZhbHNlOworCQlmY2luZm8tPmFyZ3NbMV0uaXNudWxsID0g ZmFsc2U7CisKKwkJaWYgKHNzbG90Lm52YWx1ZXMgPD0gbnVtX2VsZW1zKQorCQl7CisJCQkv KgorCQkJICogQnVpbGQgYSBoYXNoIHRhYmxlIG92ZXIgdGhlIE1DViB2YWx1ZXMuCisJCQkg KgorCQkJICogRm9yIGVhY2ggSU4tbGlzdCBlbGVtZW50LCB3ZSBjb21wdXRlIHAoeCA9IGVs ZW1lbnQpOiBjb25zdGFudHMKKwkJCSAqIGFyZSBtYXRjaGVkIGFnYWluc3QgTUNWcyAob3Ig dGhlIHJlc2lkdWFsIGZyZXF1ZW5jeSkuIFRoZXNlCisJCQkgKiBwcm9iYWJpbGl0aWVzIGFy ZSB0aGVuIGNvbWJpbmVkIHVzaW5nIHRoZSBzdGFuZGFyZCBBTlkvQUxMCisJCQkgKiBmb3Jt dWxhcy4KKwkJCSAqLworCQkJZm1ncl9pbmZvKGhhc2hMZWZ0LCAmaGFzaF9wcm9jKTsKKwkJ CUluaXRGdW5jdGlvbkNhbGxJbmZvRGF0YSgqaGFzaF9mY2luZm8sICZoYXNoX3Byb2MsIDEs IGNvbGxhdGlvbiwKKwkJCQkJCQkJCSBOVUxMLCBOVUxMKTsKKwkJCWhhc2hfZmNpbmZvLT5h cmdzWzBdLmlzbnVsbCA9IGZhbHNlOworCisJCQloYXNoQ29udGV4dC5lcXVhbF9mY2luZm8g PSBmY2luZm87CisJCQloYXNoQ29udGV4dC5oYXNoX2ZjaW5mbyA9IGhhc2hfZmNpbmZvOwor CQkJaGFzaENvbnRleHQuaW5zZXJ0X21vZGUgPSB0cnVlOworCisJCQlnZXRfdHlwbGVuYnl2 YWwoc3Nsb3QudmFsdWV0eXBlLAorCQkJCQkJCSZoYXNoQ29udGV4dC5oYXNoX3R5cGxlbiwK KwkJCQkJCQkmaGFzaENvbnRleHQuaGFzaF90eXBieXZhbCk7CisKKwkJCWhhc2hUYWJsZSA9 IE1DVkluSGFzaFRhYmxlX2NyZWF0ZShDdXJyZW50TWVtb3J5Q29udGV4dCwKKwkJCQkJCQkJ CQkJICBzc2xvdC5udmFsdWVzLAorCQkJCQkJCQkJCQkgICZoYXNoQ29udGV4dCk7CisKKwkJ CWZvciAoaW50IGkgPSAwOyBpIDwgc3Nsb3QubnZhbHVlczsgaSsrKQorCQkJeworCQkJCWJv b2wJCWZvdW5kID0gZmFsc2U7CisJCQkJTUNWSW5IYXNoRW50cnkgKmVudHJ5OworCisJCQkJ ZW50cnkgPSBNQ1ZJbkhhc2hUYWJsZV9pbnNlcnQoaGFzaFRhYmxlLCBzc2xvdC52YWx1ZXNb aV0sICZmb3VuZCk7CisKKwkJCQkvKgorCQkJCSAqIE1DVkhhc2hUYWJsZV9pbnNlcnQgd2ls bCBvbmx5IHJlcG9ydCAiZm91bmQiIGlmIHRoZSBuZXcKKwkJCQkgKiB2YWx1ZSBpcyBlcXVh bCB0byBzb21lIHByZXZpb3VzIG9uZSBwZXIgZGF0dW1faW1hZ2VfZXEoKS4KKwkJCQkgKiBU aGF0IHByb2JhYmx5IHNob3VsZG4ndCBoYXBwZW4sIHNpbmNlIHdlJ3JlIG5vdCBleHBlY3Rp bmcKKwkJCQkgKiBkdXBsaWNhdGVzIGluIHRoZSBNQ1YgbGlzdC4gIElmIHdlIGRvIGZpbmQg YSBkdXAsIGp1c3QKKwkJCQkgKiBpZ25vcmUgaXQsIGxlYXZpbmcgdGhlIGhhc2ggZW50cnkn cyBpbmRleCBwb2ludGluZyBhdCB0aGUKKwkJCQkgKiBmaXJzdCBvY2N1cnJlbmNlLiAgVGhh dCBtYXRjaGVzIHRoZSBiZWhhdmlvciB0aGF0IHRoZQorCQkJCSAqIG5vbi1oYXNoZWQgY29k ZSBwYXRoIHdvdWxkIGhhdmUuCisJCQkJICovCisJCQkJaWYgKGxpa2VseSghZm91bmQpKQor CQkJCQllbnRyeS0+aW5kZXggPSBpOworCisJCQkJc3VtYWxsY29tbW9uICs9IHNzbG90Lm51 bWJlcnNbaV07CisJCQl9CisKKwkJCS8qCisJCQkgKiBQcmVwYXJlIHRvIHByb2JlIHRoZSBo YXNoIHRhYmxlLiAgSWYgdGhlIHByb2JlIHZhbHVlcyBhcmUgb2YgYQorCQkJICogZGlmZmVy ZW50IGRhdGEgdHlwZSwgdGhlbiB3ZSBuZWVkIHRvIGNoYW5nZSBoYXNoIGZ1bmN0aW9ucy4K KwkJCSAqIChUaGlzIGNvZGUgcmVsaWVzIG9uIHRoZSBhc3N1bXB0aW9uIHRoYXQgc2luY2Ug d2UgZGVmaW5lZAorCQkJICogU0hfU1RPUkVfSEFTSCwgc2ltcGxlaGFzaC5oIHdpbGwgbmV2 ZXIgbmVlZCB0byBjb21wdXRlIGhhc2gKKwkJCSAqIHZhbHVlcyBmb3IgZXhpc3RpbmcgaGFz aCB0YWJsZSBlbnRyaWVzLikKKwkJCSAqLworCQkJaGFzaENvbnRleHQuaW5zZXJ0X21vZGUg PSBmYWxzZTsKKwkJCWlmIChoYXNoTGVmdCAhPSBoYXNoUmlnaHQpCisJCQl7CisJCQkJZm1n cl9pbmZvKGhhc2hSaWdodCwgJmhhc2hfcHJvYyk7CisJCQkJLyogUmVzZXR0aW5nIGhhc2hf ZmNpbmZvIGlzIHByb2JhYmx5IHVubmVjZXNzYXJ5LCBidXQgYmUgc2FmZSAqLworCQkJCUlu aXRGdW5jdGlvbkNhbGxJbmZvRGF0YSgqaGFzaF9mY2luZm8sICZoYXNoX3Byb2MsIDEsIGNv bGxhdGlvbiwKKwkJCQkJCQkJCQkgTlVMTCwgTlVMTCk7CisJCQkJaGFzaF9mY2luZm8tPmFy Z3NbMF0uaXNudWxsID0gZmFsc2U7CisJCQl9CisKKwkJCS8qCisJCQkgKiByZW1haW5pbmdf c2VsZWMgaXMgdGhlIHRvdGFsIHByb2JhYmlsaXR5IG1hc3Mgb2YgYWxsIG5vbi1NQ1YKKwkJ CSAqIHZhbHVlcyAoaS5lLiwgMSAtIHN1bShNQ1YgZnJlcXVlbmNpZXMpIC0gbnVsbGZyYWMp LiAgVGhpcyBtYXNzCisJCQkgKiBpcyBsYXRlciBkaXZpZGVkIGFtb25nIHRoZSByZW1haW5p bmcgZGlzdGluY3QgdmFsdWVzIHRvCisJCQkgKiBlc3RpbWF0ZSBwKHggPSBjKSBmb3IgY29u c3RhbnRzIG5vdCBwcmVzZW50IGluIHRoZSBNQ1YgbGlzdC4KKwkJCSAqLworCQkJcmVtYWlu aW5nX3NlbGVjID0gMS4wIC0gc3VtYWxsY29tbW9uIC0gbnVsbGZyYWM7CisJCQlDTEFNUF9Q Uk9CQUJJTElUWShyZW1haW5pbmdfc2VsZWMpOworCisJCQkvKgorCQkJICogYW5kIGluIGZh Y3QgaXQncyBwcm9iYWJseSBhIGdvb2QgZGVhbCBsZXNzLiBXZSBhcHByb3hpbWF0ZSB0aGF0 CisJCQkgKiBhbGwgdGhlIG5vdC1jb21tb24gdmFsdWVzIHNoYXJlIHRoaXMgcmVtYWluaW5n IGZyYWN0aW9uCisJCQkgKiBlcXVhbGx5LCBzbyB3ZSBkaXZpZGUgYnkgdGhlIG51bWJlciBv ZiBvdGhlciBkaXN0aW5jdCB2YWx1ZXMuCisJCQkgKi8KKwkJCW90aGVyZGlzdGluY3QgPSBn ZXRfdmFyaWFibGVfbnVtZGlzdGluY3QodmFyZGF0YSwgJmlzZGVmYXVsdCkgLSBzc2xvdC5u bnVtYmVyczsKKwkJCWlmIChvdGhlcmRpc3RpbmN0ID4gMSkKKwkJCQlyZW1haW5pbmdfc2Vs ZWMgLz0gb3RoZXJkaXN0aW5jdDsKKworCQkJLyoKKwkJCSAqIEFub3RoZXIgY3Jvc3MtY2hl Y2s6IHNlbGVjdGl2aXR5IHNob3VsZG4ndCBiZSBlc3RpbWF0ZWQgYXMgbW9yZQorCQkJICog dGhhbiB0aGUgbGVhc3QgY29tbW9uICJtb3N0IGNvbW1vbiB2YWx1ZSIuCisJCQkgKi8KKwkJ CWlmIChzc2xvdC5ubnVtYmVycyA+IDAgJiYgcmVtYWluaW5nX3NlbGVjID4gc3Nsb3QubnVt YmVyc1tzc2xvdC5ubnVtYmVycyAtIDFdKQorCQkJCXJlbWFpbmluZ19zZWxlYyA9IHNzbG90 Lm51bWJlcnNbc3Nsb3Qubm51bWJlcnMgLSAxXTsKKworCQkJLyogRXZhbHVhdGUgc2VsZWN0 aXZpdHkgY29udHJpYnV0aW9uIG9mIGVhY2ggSU4tbGlzdCBlbGVtZW50LiAqLworCQkJZm9y IChpbnQgaSA9IDA7IGkgPCBudW1fZWxlbXM7IGkrKykKKwkJCXsKKwkJCQlNQ1ZJbkhhc2hF bnRyeSAqZW50cnk7CisJCQkJU2VsZWN0aXZpdHkgczE7CisKKwkJCQkvKgorCQkJCSAqIElm IHRoZSBjb25zdGFudCBpcyBOVUxMLCBhc3N1bWUgb3BlcmF0b3IgaXMgc3RyaWN0IGFuZAor CQkJCSAqIHJldHVybiB6ZXJvLCBpZSwgb3BlcmF0b3Igd2lsbCBuZXZlciByZXR1cm4gVFJV RS4gIChJdCdzCisJCQkJICogemVybyBldmVuIGZvciBhIG5lZ2F0b3Igb3AuKQorCQkJCSAq LworCQkJCWlmIChlbGVtX251bGxzW2ldKQorCQkJCQljb250aW51ZTsKKworCQkJCWVudHJ5 ID0gTUNWSW5IYXNoVGFibGVfbG9va3VwKGhhc2hUYWJsZSwgZWxlbV92YWx1ZXNbaV0pOwor CisJCQkJaWYgKGVudHJ5ICE9IE5VTEwpCisJCQkJeworCQkJCQkvKgorCQkJCQkgKiBBcyBp biB0aGUgb3RoZXIgY29kZSBwYXRoLCBza2lwIGFscmVhZHktbWF0Y2hlZCBoYXNoCisJCQkJ CSAqIGVudHJpZXMKKwkJCQkJICovCisJCQkJCXMxID0gc3Nsb3QubnVtYmVyc1tlbnRyeS0+ aW5kZXhdOworCQkJCX0KKwkJCQllbHNlCisJCQkJCXMxID0gcmVtYWluaW5nX3NlbGVjOwor CisJCQkJaWYgKGlzSW5lcXVhbGl0eSkKKwkJCQkJczEgPSAxLjAgLSBzMSAtIG51bGxmcmFj OworCisJCQkJQ0xBTVBfUFJPQkFCSUxJVFkoczEpOworCisJCQkJaWYgKHVzZU9yKQorCQkJ CXsKKwkJCQkJc2VsZWMgPSBzZWxlYyArIHMxIC0gc2VsZWMgKiBzMTsKKwkJCQkJaWYgKGlz RXF1YWxpdHkpCisJCQkJCQlzMWRpc2pvaW50ICs9IHMxOworCQkJCX0KKwkJCQllbHNlCisJ CQkJeworCQkJCQlzZWxlYyA9IHNlbGVjICogczE7CisJCQkJCWlmIChpc0luZXF1YWxpdHkp CisJCQkJCQlzMWRpc2pvaW50ICs9IHMxIC0gMS4wOworCQkJCX0KKwkJCX0KKworCQkJTUNW SW5IYXNoVGFibGVfZGVzdHJveShoYXNoVGFibGUpOworCisJCQkvKgorCQkJICogRm9yID0g QU5ZIG9yIDw+IEFMTCwgaWYgdGhlIElOLWxpc3QgZWxlbWVudHMgYXJlIGFzc3VtZWQKKwkJ CSAqIGRpc3RpbmN0LCB0aGUgZXZlbnRzIGFyZSBkaXNqb2ludCBhbmQgdGhlIHRvdGFsIHBy b2JhYmlsaXR5IGlzCisJCQkgKiB0aGUgc3VtIG9mIGluZGl2aWR1YWwgcHJvYmFiaWxpdGll cy4gIFVzZSB0aGF0IGVzdGltYXRlIGlmIGl0CisJCQkgKiBsaWVzIGluIFswLDFdLgorCQkJ ICovCisJCQlpZiAoKHVzZU9yID8gaXNFcXVhbGl0eSA6IGlzSW5lcXVhbGl0eSkgJiYKKwkJ CQlzMWRpc2pvaW50ID49IDAuMCAmJiBzMWRpc2pvaW50IDw9IDEuMCkKKwkJCQlzZWxlYyA9 IHMxZGlzam9pbnQ7CisJCX0KKwkJZWxzZQorCQl7CisJCQkvKgorCQkJICogSGVyZSB0aGUg SU4tbGlzdCBpcyBzaG9ydGVyIHRoYW4gdGhlIE1DViBsaXN0LgorCQkJICoKKwkJCSAqIFdl IGJ1aWxkIGEgaGFzaCB0YWJsZSBvdmVyIHRoZSBJTi1saXN0IHZhbHVlcyBzbyB0aGF0IHdl IGNhbgorCQkJICogcXVpY2tseSBkZXRlcm1pbmUgd2hpY2ggTUNWcyBhcmUgcmVmZXJlbmNl ZCBieSB0aGUgcXVlcnkuCisJCQkgKgorCQkJICogV2UgdGhlbjogLSBzdW0gcHJvYmFiaWxp dGllcyBvZiBNQ1ZzIHRoYXQgYXBwZWFyIGluIHRoZSBJTi1saXN0CisJCQkgKiAtIGNvdW50 IGhvdyBtYW55IElOLWxpc3QgdmFsdWVzIGFyZSBub3QgTUNWcyAtIGVzdGltYXRlIHRoZWly CisJCQkgKiBwcm9iYWJpbGl0aWVzIGZyb20gdGhlIHJlbWFpbmluZyBmcmVxdWVuY3kgbWFz cyAtIGNvbWJpbmUKKwkJCSAqIGV2ZXJ5dGhpbmcgdXNpbmcgdGhlIHN0YW5kYXJkIEFOWS9B TEwgcHJvYmFiaWxpdHkgcnVsZXMKKwkJCSAqLworCQkJaW50CQkJZGlzdGluY3RfaW4gPSAw OworCQkJaW50CQkJbWN2X21hdGNoZXMgPSAwOworCQkJaW50CQkJbm9uX21jdl9pbiA9IDA7 CisJCQlkb3VibGUJCW1jdl9zdW0gPSAwLjA7CisJCQlTZWxlY3Rpdml0eSBkaXNqb2ludF9z ZWwgPSAwLjA7CisKKwkJCWZtZ3JfaW5mbyhoYXNoUmlnaHQsICZoYXNoX3Byb2MpOworCQkJ SW5pdEZ1bmN0aW9uQ2FsbEluZm9EYXRhKCpoYXNoX2ZjaW5mbywgJmhhc2hfcHJvYywgMSwg Y29sbGF0aW9uLAorCQkJCQkJCQkJIE5VTEwsIE5VTEwpOworCQkJaGFzaF9mY2luZm8tPmFy Z3NbMF0uaXNudWxsID0gZmFsc2U7CisKKwkJCWhhc2hDb250ZXh0LmVxdWFsX2ZjaW5mbyA9 IGZjaW5mbzsKKwkJCWhhc2hDb250ZXh0Lmhhc2hfZmNpbmZvID0gaGFzaF9mY2luZm87CisJ CQloYXNoQ29udGV4dC5pbnNlcnRfbW9kZSA9IHRydWU7CisKKwkJCWdldF90eXBsZW5ieXZh bChub21pbmFsX2VsZW1lbnRfdHlwZSwKKwkJCQkJCQkmaGFzaENvbnRleHQuaGFzaF90eXBs ZW4sCisJCQkJCQkJJmhhc2hDb250ZXh0Lmhhc2hfdHlwYnl2YWwpOworCisJCQkvKgorCQkJ ICogQnVpbGQgYSBoYXNoIHRhYmxlIG92ZXIgdGhlIGRpc3RpbmN0IGNvbnN0YW50IHZhbHVl cyBmcm9tIHRoZQorCQkJICogSU4tbGlzdC4gRHVwbGljYXRlcyBhcmUgaWdub3JlZCBiZWNh dXNlIEFOWS9BTEwgc2VtYW50aWNzCisJCQkgKiBhc3N1bWUgdGhlIGVsZW1lbnRzIGFyZSBk aXN0aW5jdCBmb3IgZGlzam9pbnQtcHJvYmFiaWxpdHkKKwkJCSAqIGVzdGltYXRpb24uCisJ CQkgKi8KKwkJCWhhc2hUYWJsZSA9IE1DVkluSGFzaFRhYmxlX2NyZWF0ZShDdXJyZW50TWVt b3J5Q29udGV4dCwKKwkJCQkJCQkJCQkJICBudW1fZWxlbXMsCisJCQkJCQkJCQkJCSAgJmhh c2hDb250ZXh0KTsKKworCQkJLyoKKwkJCSAqIEluc2VydCBhbGwgY29uc3RhbnQgSU4tbGlz dCBlbGVtZW50cyBpbnRvIHRoZSBoYXNoIHRhYmxlLAorCQkJICoga2VlcGluZyBvbmx5IG9u ZSBjb3B5IG9mIGVhY2ggZGlzdGluY3QgdmFsdWUuCisJCQkgKi8KKwkJCWZvciAoaW50IGkg PSAwOyBpIDwgbnVtX2VsZW1zOyBpKyspCisJCQl7CisJCQkJYm9vbAkJZm91bmQgPSBmYWxz ZTsKKworCQkJCWlmIChlbGVtX251bGxzW2ldKQorCQkJCQljb250aW51ZTsKKworCQkJCU1D VkluSGFzaFRhYmxlX2luc2VydChoYXNoVGFibGUsIGVsZW1fdmFsdWVzW2ldLCAmZm91bmQp OworCisJCQkJaWYgKGxpa2VseSghZm91bmQpKQorCQkJCQlkaXN0aW5jdF9pbisrOworCQkJ fQorCisJCQloYXNoQ29udGV4dC5pbnNlcnRfbW9kZSA9IGZhbHNlOworCQkJaWYgKGhhc2hM ZWZ0ICE9IGhhc2hSaWdodCkKKwkJCXsKKwkJCQlmbWdyX2luZm8oaGFzaExlZnQsICZoYXNo X3Byb2MpOworCQkJCS8qIFJlc2V0dGluZyBoYXNoX2ZjaW5mbyBpcyBwcm9iYWJseSB1bm5l Y2Vzc2FyeSwgYnV0IGJlIHNhZmUgKi8KKwkJCQlJbml0RnVuY3Rpb25DYWxsSW5mb0RhdGEo Kmhhc2hfZmNpbmZvLCAmaGFzaF9wcm9jLCAxLCBjb2xsYXRpb24sCisJCQkJCQkJCQkJIE5V TEwsIE5VTEwpOworCQkJCWhhc2hfZmNpbmZvLT5hcmdzWzBdLmlzbnVsbCA9IGZhbHNlOwor CQkJfQorCisJCQkvKgorCQkJICogU2NhbiB0aGUgTUNWIGxpc3Qgb25jZS4KKwkJCSAqCisJ CQkgKiBGb3IgZWFjaCBNQ1YgdmFsdWU6IC0gYWx3YXlzIGFkZCBpdHMgZnJlcXVlbmN5IHRv IHN1bWFsbGNvbW1vbgorCQkJICogKG5lZWRlZCB0byBjb21wdXRlIHRoZSByZW1haW5pbmcg bm9uLU1DViBwcm9iYWJpbGl0eSBtYXNzKSAtIGlmCisJCQkgKiB0aGUgTUNWIGFwcGVhcnMg aW4gdGhlIElOLWxpc3QsIHJlY29yZCBpdCBhcyBhIG1hdGNoIGFuZCBhZGQKKwkJCSAqIGl0 cyBwcm9iYWJpbGl0eSB0byBtY3Zfc3VtCisJCQkgKgorCQkJICogQXQgdGhlIHNhbWUgdGlt ZSB3ZSBhbHNvIGZvbGQgaXRzIGNvbnRyaWJ1dGlvbiBpbnRvIHRoZSBydW5uaW5nCisJCQkg KiBBTlkvQUxMIHByb2JhYmlsaXR5IChzZWxlYyksIGV4YWN0bHkgYXMgdGhlIGdlbmVyaWMg Y29kZSBkb2VzLgorCQkJICovCisJCQlmb3IgKGludCBpID0gMDsgaSA8IHNzbG90Lm52YWx1 ZXM7IGkrKykKKwkJCXsKKwkJCQlNQ1ZJbkhhc2hFbnRyeSAqZW50cnk7CisKKwkJCQlzdW1h bGxjb21tb24gKz0gc3Nsb3QubnVtYmVyc1tpXTsKKworCQkJCWVudHJ5ID0gTUNWSW5IYXNo VGFibGVfbG9va3VwKGhhc2hUYWJsZSwgc3Nsb3QudmFsdWVzW2ldKTsKKwkJCQlpZiAoZW50 cnkgIT0gTlVMTCkKKwkJCQl7CisJCQkJCVNlbGVjdGl2aXR5IHMxID0gc3Nsb3QubnVtYmVy c1tpXTsKKworCQkJCQltY3Zfc3VtICs9IHMxOworCQkJCQltY3ZfbWF0Y2hlcysrOworCisJ CQkJCWlmIChpc0luZXF1YWxpdHkpCisJCQkJCQlzMSA9IDEuMCAtIHMxIC0gbnVsbGZyYWM7 CisKKwkJCQkJQ0xBTVBfUFJPQkFCSUxJVFkoczEpOworCisJCQkJCWlmICh1c2VPcikKKwkJ CQkJCXNlbGVjID0gc2VsZWMgKyBzMSAtIHNlbGVjICogczE7CisJCQkJCWVsc2UKKwkJCQkJ CXNlbGVjID0gc2VsZWMgKiBzMTsKKwkJCQl9CisJCQl9CisKKwkJCS8qCisJCQkgKiBDb21w dXRlIHRoZSB0b3RhbCBwcm9iYWJpbGl0eSBtYXNzIG9mIGFsbCBub24tTUNWIHZhbHVlcy4g VGhpcworCQkJICogaXMgdGhlIHBhcnQgb2YgdGhlIGNvbHVtbiBkaXN0cmlidXRpb24gbm90 IGNvdmVyZWQgYnkgTUNWcy4KKwkJCSAqLworCQkJcmVtYWluaW5nX3NlbGVjID0gMS4wIC0g c3VtYWxsY29tbW9uIC0gbnVsbGZyYWM7CisJCQlDTEFNUF9QUk9CQUJJTElUWShyZW1haW5p bmdfc2VsZWMpOworCisJCQkvKgorCQkJICogQXBwcm94aW1hdGUgdGhlIHBlci12YWx1ZSBw cm9iYWJpbGl0eSBvZiBhIG5vbi1NQ1YgY29uc3RhbnQgYnkKKwkJCSAqIGRpdmlkaW5nIHRo ZSByZW1haW5pbmcgcHJvYmFiaWxpdHkgbWFzcyBieSB0aGUgbnVtYmVyIG9mIG90aGVyCisJ CQkgKiBkaXN0aW5jdCB2YWx1ZXMuCisJCQkgKi8KKwkJCW90aGVyZGlzdGluY3QgPSBnZXRf dmFyaWFibGVfbnVtZGlzdGluY3QodmFyZGF0YSwgJmlzZGVmYXVsdCkgLSBzc2xvdC5ubnVt YmVyczsKKwkJCWlmIChvdGhlcmRpc3RpbmN0ID4gMSkKKwkJCQlyZW1haW5pbmdfc2VsZWMg Lz0gb3RoZXJkaXN0aW5jdDsKKworCQkJaWYgKHNzbG90Lm5udW1iZXJzID4gMCAmJiByZW1h aW5pbmdfc2VsZWMgPiBzc2xvdC5udW1iZXJzW3NzbG90Lm5udW1iZXJzIC0gMV0pCisJCQkJ cmVtYWluaW5nX3NlbGVjID0gc3Nsb3QubnVtYmVyc1tzc2xvdC5ubnVtYmVycyAtIDFdOwor CisJCQkvKgorCQkJICogTnVtYmVyIG9mIElOLWxpc3QgdmFsdWVzIHRoYXQgYXJlIG5vdCBN Q1ZzLiBFYWNoIG9mIHRoZXNlIGlzCisJCQkgKiBhc3N1bWVkIHRvIGhhdmUgcHJvYmFiaWxp dHkgPSByZW1haW5pbmdfc2VsZWMuCisJCQkgKi8KKwkJCW5vbl9tY3ZfaW4gPSBkaXN0aW5j dF9pbiAtIG1jdl9tYXRjaGVzOworCQkJQXNzZXJ0KG5vbl9tY3ZfaW4gPj0gMCk7CisKKwkJ CS8qCisJCQkgKiBDb21wdXRlIHRoZSBkaXNqb2ludC1wcm9iYWJpbGl0eSBlc3RpbWF0ZToK KwkJCSAqCisJCQkgKiBzID0gc3VtIG9mIHByb2JhYmlsaXRpZXMgb2YgYWxsIE1DViB2YWx1 ZXMgcHJlc2VudCBpbiB0aGUKKwkJCSAqIElOLWxpc3QgKyBzdW0gb2YgcHJvYmFiaWxpdGll cyBvZiBhbGwgbm9uLU1DViBJTi1saXN0IHZhbHVlcworCQkJICoKKwkJCSAqIFRoaXMgaXMg dmFsaWQgZm9yID0gQU5ZIGFuZCA8PiBBTEwgd2hlbiB0aGUgSU4tbGlzdCBlbGVtZW50cwor CQkJICogYXJlIGFzc3VtZWQgZGlzdGluY3QuCisJCQkgKi8KKwkJCWRpc2pvaW50X3NlbCA9 IG1jdl9zdW0gKyBub25fbWN2X2luICogcmVtYWluaW5nX3NlbGVjOworCisJCQlpZiAoaXNJ bmVxdWFsaXR5KQorCQkJCWRpc2pvaW50X3NlbCA9IDEuMCAtIGRpc2pvaW50X3NlbCAtIG51 bGxmcmFjOworCisJCQlpZiAoKHVzZU9yID8gaXNFcXVhbGl0eSA6IGlzSW5lcXVhbGl0eSkg JiYKKwkJCQlkaXNqb2ludF9zZWwgPj0gMC4wICYmIGRpc2pvaW50X3NlbCA8PSAxLjApCisJ CQkJc2VsZWMgPSBkaXNqb2ludF9zZWw7CisKKwkJCU1DVkluSGFzaFRhYmxlX2Rlc3Ryb3ko aGFzaFRhYmxlKTsKKwkJfQorCisJCUNMQU1QX1BST0JBQklMSVRZKHNlbGVjKTsKKwl9CisK KwlmcmVlX2F0dHN0YXRzc2xvdCgmc3Nsb3QpOworCisJcmV0dXJuIHNlbGVjOworfQorCisv KgorICogU3VwcG9ydCBmdW5jdGlvbnMgZm9yIHRoZSBoYXNoIHRhYmxlcyB1c2VkIGJ5IGVx am9pbnNlbF9maW5kX21hdGNoZXMKKyAqLworc3RhdGljIHVpbnQzMgoraGFzaF9tY3ZfaW4o TUNWSW5IYXNoVGFibGVfaGFzaCAqdGFiLCBEYXR1bSBrZXkpCit7CisJTUNWSW5IYXNoQ29u dGV4dCAqY29udGV4dCA9IChNQ1ZJbkhhc2hDb250ZXh0ICopIHRhYi0+cHJpdmF0ZV9kYXRh OworCUZ1bmN0aW9uQ2FsbEluZm8gZmNpbmZvID0gY29udGV4dC0+aGFzaF9mY2luZm87CisJ RGF0dW0JCWZyZXN1bHQ7CisKKwlmY2luZm8tPmFyZ3NbMF0udmFsdWUgPSBrZXk7CisJZmNp bmZvLT5pc251bGwgPSBmYWxzZTsKKwlmcmVzdWx0ID0gRnVuY3Rpb25DYWxsSW52b2tlKGZj aW5mbyk7CisJQXNzZXJ0KCFmY2luZm8tPmlzbnVsbCk7CisJcmV0dXJuIERhdHVtR2V0VUlu dDMyKGZyZXN1bHQpOworfQorCitzdGF0aWMgYm9vbAorbWN2c19pbl9lcXVhbChNQ1ZJbkhh c2hUYWJsZV9oYXNoICp0YWIsIERhdHVtIGtleTAsIERhdHVtIGtleTEpCit7CisJTUNWSW5I YXNoQ29udGV4dCAqY29udGV4dCA9IChNQ1ZJbkhhc2hDb250ZXh0ICopIHRhYi0+cHJpdmF0 ZV9kYXRhOworCisJaWYgKGNvbnRleHQtPmluc2VydF9tb2RlKQorCXsKKwkJLyoKKwkJICog RHVyaW5nIHRoZSBpbnNlcnRpb24gc3RlcCwgYW55IGNvbXBhcmlzb25zIHdpbGwgYmUgYmV0 d2VlbiB0d28KKwkJICogRGF0dW1zIG9mIHRoZSBoYXNoIHRhYmxlJ3MgZGF0YSB0eXBlLCBz byBpZiB0aGUgZ2l2ZW4gb3BlcmF0b3IgaXMKKwkJICogY3Jvc3MtdHlwZSBpdCB3aWxsIGJl IHRoZSB3cm9uZyB0aGluZyB0byB1c2UuICBGb3J0dW5hdGVseSwgd2UgY2FuCisJCSAqIHVz ZSBkYXR1bV9pbWFnZV9lcSBpbnN0ZWFkLiAgVGhlIE1DViB2YWx1ZXMgc2hvdWxkIGFsbCBi ZSBkaXN0aW5jdAorCQkgKiBhbnl3YXksIHNvIGl0J3MgbW9zdGx5IHByby1mb3JtYSB0byBj b21wYXJlIHRoZW0gYXQgYWxsLgorCQkgKi8KKwkJcmV0dXJuIGRhdHVtX2ltYWdlX2VxKGtl eTAsIGtleTEsCisJCQkJCQkJICBjb250ZXh0LT5oYXNoX3R5cGJ5dmFsLCBjb250ZXh0LT5o YXNoX3R5cGxlbik7CisJfQorCWVsc2UKKwl7CisJCUZ1bmN0aW9uQ2FsbEluZm8gZmNpbmZv ID0gY29udGV4dC0+ZXF1YWxfZmNpbmZvOworCQlEYXR1bQkJZnJlc3VsdDsKKworCQlmY2lu Zm8tPmFyZ3NbMF0udmFsdWUgPSBrZXkwOworCQlmY2luZm8tPmFyZ3NbMV0udmFsdWUgPSBr ZXkxOworCQlmY2luZm8tPmlzbnVsbCA9IGZhbHNlOworCQlmcmVzdWx0ID0gRnVuY3Rpb25D YWxsSW52b2tlKGZjaW5mbyk7CisJCXJldHVybiAoIWZjaW5mby0+aXNudWxsICYmIERhdHVt R2V0Qm9vbChmcmVzdWx0KSk7CisJfQorfQorCiAvKgogICogRXN0aW1hdGUgbnVtYmVyIG9m IGVsZW1lbnRzIGluIHRoZSBhcnJheSB5aWVsZGVkIGJ5IGFuIGV4cHJlc3Npb24uCiAgKgpk aWZmIC0tZ2l0IGEvc3JjL3Rvb2xzL3BnaW5kZW50L3R5cGVkZWZzLmxpc3QgYi9zcmMvdG9v bHMvcGdpbmRlbnQvdHlwZWRlZnMubGlzdAppbmRleCAxNGRlYzJkNDljMS4uYWRmZThmNGM1 ODggMTAwNjQ0Ci0tLSBhL3NyYy90b29scy9wZ2luZGVudC90eXBlZGVmcy5saXN0CisrKyBi L3NyYy90b29scy9wZ2luZGVudC90eXBlZGVmcy5saXN0CkBAIC0xNjY3LDYgKzE2NjcsOSBA QCBNQnVmCiBNQ1ZIYXNoQ29udGV4dAogTUNWSGFzaEVudHJ5CiBNQ1ZIYXNoVGFibGVfaGFz aAorTUNWSW5IYXNoQ29udGV4dAorTUNWSW5IYXNoRW50cnkKK01DVkluSGFzaFRhYmxlX2hh c2gKIE1DVkl0ZW0KIE1DVkxpc3QKIE1FTU9SWV9CQVNJQ19JTkZPUk1BVElPTgotLSAKMi4z NC4xCgo= --------------JwSYPbG6AjFNqkEs906f5Z7j--