Subject: Changes for installboot
To: None <port-macppc@netbsd.org>
From: Bill Studenmund <wrstuden@zembu.com>
List: port-macppc
Date: 08/16/2000 14:31:57
  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.
  Send mail to mime@docserver.cac.washington.edu for more info.

--0-853287946-966453361=:2800
Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
Content-ID: <Pine.NEB.4.21.0008161430222.2800@candlekeep.z.zembu.com>

I'm in Palo Alto this week, so I can't test these out. But here are the
diffs I made for installboot to get it to respect Apple Partition Map
disks.

Oops. There's a bug.. I'm leaving the bug in just to get these diffs out
to be played with. The bug is that &protooffset isn't always getting set
up. Places where it's needed will have an XXX below.


I tested this code to make sure it compiled. I have not actually used it.
Use with caution!



These patches add two new options: -F and -P <num>. -F forces the creation
of a fake partition table like installboot used to always make.

-P <num> uses partition number <num> to store the boot blocks. That
partition needs to exist, and be big enough to hold the boot blocks.



Here's the intended logic flow:

We now go into the partiton map groveling even if we have the -n flag. We
won't write anything (partition is opened r/o), but we will look at what's
around. Can be combined with the -v flag to see what will be done.

We first look to see if either the -F flag was passed or there's not an
existing APM. If so, we make the simple, small partition map we've always
made.

Next, we look at how many partitions there are.

If -P was specified, we make sure that it is within the existing partition
map. If so, we set that partition up. XXX - need to set protooffset

Otherwise we scan the partition map to see what is there. During this
scan, we look for the partition map entry, the smallest free space entry
which will fit the boot blocks, and an existing bootblock entry. The
existing entry will be of type "NetBSD/macppc". We make the comparison
happen case-insensitivly by manually upper-casing the name.

If we find the partition map entry, we note how big it is. The way Apple
part maps work, each partition has an entry of the number of valid
partition entries. There is one partition entry which is the
"Apple_Partition_Map". This partition entry starts at block 1, and covers
all the valid entries. Its size also dictates how many partition entries
can be added. Thus the number of partitions in use is strictly less than
or equal to the size of this special partition.

If we find an "Apple_Free" partition, we found freespace. If it is big
enough to hold the boot blocks and either we haven't found a free space
partition yet, or this one is smaller than the one we already found, we
use it.

If we find a boot partition, we check to see if it's big enough for the
boot blocks. If not, we exit as I'm opposed to the idea of there being two
NetBSD/powerpc boot blocks on a disk. (if we add a startmanager bootblock,
we need to give it a different name). If it's fine, we use it.

If there are more partitions to look at, we read the next one and loop.

If we fall off the bottom of the loop, we didn't find an existing driver
partition and thus need to make one.

If there wasn't any free space, we bail with an error.

If the freespace is within a factor of 2 of the bootblock size (i.e. 4k or
so now), then we just use it. It will change from being a free partition
to a bootblock partition. XXX - need to update protooffset.

If we get to this point in the logic, we have to add a new boot partition.
First we check to see if we have a free partition entry. If not, we bail.

Then we get the freespace partition we're using. We strip space out of it,
and save it. We then itterate over all partitions increasing the count of
active partitions.

Finally we build the new partition. XXX - need to update protooffset.



The actual setting up of a partition to be a boot partition is done in one
routine, makedriverpart(). It is passed the partition number and the file
descriptor for the disk. It does pretty-much everything that the bottom
part of the writeapplepartmap() routine used to do. It expects that part
of the partition entry (the size and offset) has already been set up. One
new thing it does is call fixup_driver() at the end, which tries to fix up
the dirvers list which we've been abusing. We have a sanity check that if
the number of drivers is larger than is possible for the block (61 right
now), we set it to 0. This is because in the past this program left
garbage in that entry. So if it's invalid, chances are it was our fault,
and there are no existing driver entries.

Right now I don't fill in the driver "type" since it will overlap the
struct disklabel on drives which have it. While we're moving towards
getting struct disklabel out of the way, we aren't there yet.

I mainly would like other folks to look at the changes and see if they
make sense. Bob? Tsubai? Dan?

Take care,

Bill

--0-853287946-966453361=:2800
Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; NAME="instb.diffies"
Content-Transfer-Encoding: BASE64
Content-ID: <Pine.NEB.4.21.0008161216010.2800@candlekeep.z.zembu.com>
Content-Description: patches to installboot
Content-Disposition: ATTACHMENT; FILENAME="instb.diffies"

PyBpbnN0YWxsYm9vdA0KSW5kZXg6IGRwbWUuaA0KPT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PQ0KUkNTIGZpbGU6IC9jdnNyb290L3N5c3NyYy9zeXMvYXJjaC9t
YWNwcGMvc3RhbmQvaW5zdGFsbGJvb3QvZHBtZS5oLHYNCnJldHJpZXZpbmcg
cmV2aXNpb24gMS4xDQpkaWZmIC1yMS4xIGRwbWUuaA0KNDdjNDcsNjENCjwg
CXVfaW50OF90ICAgICAgICBibG9ja3BhZGRpbmdbMjM4XTsNCi0tLQ0KPiAJ
dV9pbnQ4X3QgICAgICAgIGJsb2NrcGFkZGluZ1s0OTRdOw0KPiB9Ow0KPiAN
Cj4gLyoNCj4gICogRW50cnkgZm9yIGluZGl2aWR1YWwgZHJpdmVyIGVudHJp
ZXMuIFRoZXkgYXJlIGRlZmluZWQgYXMgTG9uZ0ludCwNCj4gICogSW50ZWdl
ciwgYW5kIEludGVnZXIgaW4gSW5zaWRlIE1hY2ludG9zaC4gVGhlIHByb2Js
ZW0gaXMgdGhhdCB0aGV5IGFyZQ0KPiAgKiBhdCB0aGUgZW5kIG9mIHRoZSBk
cnZyX21hcCBhYm92ZSAtIHRoZXkgc3RhcnQgYW4gb2RkIG51bWJlciBvZg0K
PiAgKiBpbnRlZ2VycyBpbi4gVGh1cyB0aGUgTG9uZ0ludCBpcyBub3QgYWxp
Z25lZCByaWdodCBmb3Igc3RyaWN0IGFsaWdubWVudC4NCj4gICogVGh1cyB3
ZSBkbyB0aGlzLg0KPiAgKi8NCj4gc3RydWN0IGRydnJfZW50cnkgew0KPiAJ
dV9pbnQxNl90CWRkQmxvY2tNU1c7CS8qIE1TIHdvcmQgb2YgZHJpdmVyJ3Mg
Zmlyc3QgYmxvY2sgKi8NCj4gCXVfaW50MTZfdAlkZEJsb2NrTFNXOwkvKiBM
UyB3b3JkIG9mIGRyaXZlcidzIGZpcnN0IGJsb2NrICovDQo+IAl1X2ludDE2
X3QJZGRTaXplOwkJLyogZHJpdmVyIHNpemUgaW4gYmxvY2tzICovDQo+IAl1
X2ludDE2X3QJZGRUeXBlOwkJLyogY29kZSBvZiBPUyBib290ZWQgYnkgZHJp
dmVyICovDQoxMDUsMTEwYzExOSwxMjYNCjwgI2RlZmluZSBQQVJUX1VOSVhf
VFlQRQkJIkFQUExFX1VOSVhfU1ZSMiINCjwgI2RlZmluZSBQQVJUX01BQ19U
WVBFCQkiQVBQTEVfSEZTIg0KPCAjZGVmaW5lIFBBUlRfU0NSQVRDSAkJIkFQ
UExFX1NDUkFUQ0giDQo8ICNkZWZpbmUgUEFSVF9EUklWRVJfVFlQRQkiQVBQ
TEVfRFJJVkVSIg0KPCAjZGVmaW5lIFBBUlRfRFJJVkVSNDNfVFlQRQkiQVBQ
TEVfRFJJVkVSNDMiDQo8ICNkZWZpbmUgUEFSVF9QQVJUTUFQX1RZUEUJIkFQ
UExFX1BBUlRJVElPTl9NQVAiDQotLS0NCj4gI2RlZmluZSBQQVJUX1RZUEVf
VU5JWAkJIkFQUExFX1VOSVhfU1ZSMiINCj4gI2RlZmluZSBQQVJUX1RZUEVf
TUFDCQkiQVBQTEVfSEZTIg0KPiAjZGVmaW5lIFBBUlRfVFlQRV9TQ1JBVENI
CSJBUFBMRV9TQ1JBVENIIg0KPiAjZGVmaW5lIFBBUlRfVFlQRV9EUklWRVIJ
IkFQUExFX0RSSVZFUiINCj4gI2RlZmluZSBQQVJUX1RZUEVfRFJJVkVSNDMJ
IkFQUExFX0RSSVZFUjQzIg0KPiAjZGVmaW5lCVBBUlRfVFlQRV9GUkVFCQki
QVBQTEVfRlJFRSINCj4gI2RlZmluZQlQQVJUX1RZUEVfUEFSVE1BUAkiQVBQ
TEVfUEFSVElUSU9OX01BUCINCj4gI2RlZmluZQlQQVJUX1RZUEVfTkJQUENf
Qk9PVAkiTkVUQlNEL01BQ1BQQyINCkluZGV4OiBpbnN0YWxsYm9vdC5jDQo9
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09DQpSQ1MgZmlsZTogL2N2c3Jvb3Qvc3lz
c3JjL3N5cy9hcmNoL21hY3BwYy9zdGFuZC9pbnN0YWxsYm9vdC9pbnN0YWxs
Ym9vdC5jLHYNCnJldHJpZXZpbmcgcmV2aXNpb24gMS40DQpkaWZmIC1yMS40
IGluc3RhbGxib290LmMNCjY0LDY1ZDYzDQo8ICNkZWZpbmUgQk9PVFNFQ1RP
Ul9PRkZTRVQgMjA0OA0KPCANCjg3YTg2LDkwDQo+IC8qIFRoZXNlIGFyZSBz
Y3JhdGNoIGVudHJpZXMgZm9yIGFsbCBvZiB0aGUgYXBtIHJvdXRpbmVzLiBT
YXZlcyBhIGxpdHRsZQ0KPiAgKiBvbiBzdGFjayBzcGFjZSAqLw0KPiBzdHJ1
Y3QgZHJ2cl9tYXAgZG07DQo+IHN0cnVjdCBwYXJ0bWFwZW50cnkgcG1lOw0K
PiANCjkzYzk2LDEwNA0KPCANCi0tLQ0KPiBpbnQJCWdldF9wYXJ0aXRpb24o
aW50LCBpbnQsIG9mZl90ICosIGludCwgaW50KTsNCj4gaW50CQl3cml0ZWFw
cGxlcGFydG1hcChpbnQpOw0KPiBpbnQJCW1ha2Vkcml2ZXJwYXJ0KGludCwg
aW50KTsNCj4gaW50CQlmaXh1cF9kcml2ZXIoaW50IGZkLCBpbnQgc3RhcnQs
IGludCBzaXplKTsNCj4gDQo+ICNkZWZpbmUJUEFSVF9GT1JDRV9GQUtFCQkw
eDENCj4gI2RlZmluZQlQQVJUX0ZPUkNFX05VTUJFUgkweDINCj4gI2RlZmlu
ZQlQQVJUX05PV1JJVEUJCTB4NA0KPiAjZGVmaW5lCVBBUlRfVkVSQk9TRQkJ
MHg4DQo5OWMxMTANCjwgCQkidXNhZ2U6IGluc3RhbGxib290IFstbl0gWy12
XSA8Ym9vdD4gPHByb3RvPiA8ZGV2aWNlPlxuIik7DQotLS0NCj4gCQkidXNh
Z2U6IGluc3RhbGxib290IFsgLUYgfCAtUCA8cGFydG51bWJlcj4gXSBbLW5d
IFstdl0gPGJvb3Q+IDxwcm90bz4gPGRldmljZT5cbiIpOw0KMTExYTEyMw0K
PiAJb2ZmX3QJcHJvdG9vZmZzZXQ7DQoxMTNhMTI2DQo+IAlpbnQJZm9yY2Vf
cGFydGl0aW9uLCBlcnJvciwgZmxhZ3MgPSAwOw0KMTE1YzEyOA0KPCAJd2hp
bGUgKChjID0gZ2V0b3B0KGFyZ2MsIGFyZ3YsICJ2biIpKSAhPSBFT0YpIHsN
Ci0tLQ0KPiAJd2hpbGUgKChjID0gZ2V0b3B0KGFyZ2MsIGFyZ3YsICJGblA6
diIpKSAhPSBFT0YpIHsNCjExN2ExMzEsMTM4DQo+IAkJY2FzZSAnRic6DQo+
IAkJCWlmIChmbGFncyAmIFBBUlRfRk9SQ0VfTlVNQkVSKSB7DQo+IAkJCQlm
cHJpbnRmKHN0ZGVyciwgIi1GIGFuZCAtUCBtYXkgbm90IGJlIHVzZWQiDQo+
IAkJCQkgICAgIiB0b2dldGhlci5cbiIpOw0KPiAJCQkJZXhpdCgxKTsNCj4g
CQkJfQ0KPiAJCQlmbGFncyB8PSBQQVJUX0ZPUkNFX0ZBS0U7DQo+IAkJCWJy
ZWFrOw0KMTIxYTE0MywxNTYNCj4gCQljYXNlICdQJzoNCj4gCQkJaWYgKGZs
YWdzICYgUEFSVF9GT1JDRV9GQUtFKSB7DQo+IAkJCQlmcHJpbnRmKHN0ZGVy
ciwgIi1GIGFuZCAtUCBtYXkgbm90IGJlIHVzZWQiDQo+IAkJCQkgICAgIiB0
b2dldGhlci5cbiIpOw0KPiAJCQkJZXhpdCgxKTsNCj4gCQkJfQ0KPiAJCQlm
bGFncyB8PSBQQVJUX0ZPUkNFX05VTUJFUjsNCj4gCQkJZm9yY2VfcGFydGl0
aW9uID0gYXRvaShvcHRhcmcpOw0KPiAJCQlpZiAoKGZvcmNlX3BhcnRpdGlv
biA8IDEpIHx8IChmb3JjZV9wYXJ0aXRpb24gPiA2MykpIHsNCj4gCQkJCWZw
cmludGYoc3RkZXJyLCAiUGFydGl0aW9uIG51bWJlciBtdXN0IGJlIg0KPiAJ
CQkJICAgICIgYmV0d2VlbiAxIGFuZCA2MyBpbmNsdXNpdmUuXG4iKTsNCj4g
CQkJCWV4aXQoMSk7DQo+IAkJCX0NCj4gCQkJYnJlYWs7DQoxNTksMTYwYzE5
NA0KPCAJaWYgKG5vd3JpdGUpDQo8IAkJcmV0dXJuIDA7DQotLS0NCj4gCS8q
IFdyaXRlIHBhdGNoZWQgcHJvdG8gYm9vdGJsb2NrcyBpbnRvIHRoZSBwYXJ0
aXRpb24qLw0KMTYyLDE2NGMxOTYsMjAzDQo8IAkvKiBXcml0ZSBwYXRjaGVk
IHByb3RvIGJvb3RibG9ja3MgaW50byB0aGUgc3VwZXJibG9jayAqLw0KPCAJ
aWYgKHByb3Rvc2l6ZSA+IFNCU0laRSAtIERFVl9CU0laRSkNCjwgCQllcnJ4
KDEsICJwcm90byBib290YmxvY2tzIHRvbyBiaWciKTsNCi0tLQ0KPiAJLyog
T3BlbiBzbyB3ZSBjYW4gbG9vayBhdCB3aGF0IGlzIGluIHRoZSBwYXJ0aXRp
b24gbWFwICovDQo+IAlpZiAobm93cml0ZSkgew0KPiAJCWlmICgoZGV2ZmQg
PSBvcGVuKGRldiwgT19SRE9OTFksIDApKSA8IDApDQo+IAkJCWVycigxLCAi
b3BlbjogJXMiLCBkZXYpOw0KPiAJfSBlbHNlIHsNCj4gCQlpZiAoKGRldmZk
ID0gb3BlbihkZXYsIE9fUkRXUiwgMCkpIDwgMCkNCj4gCQkJZXJyKDEsICJv
cGVuOiAlcyIsIGRldik7DQo+IAl9DQoxNjYsMTY3YzIwNSwyMDkNCjwgCWlm
ICgoZGV2ZmQgPSBvcGVuKGRldiwgT19SRFdSLCAwKSkgPCAwKQ0KPCAJCWVy
cigxLCAib3BlbjogJXMiLCBkZXYpOw0KLS0tDQo+IAlpZiAoKGVycm9yID0g
Z2V0X3BhcnRpdGlvbihkZXZmZCwgcHJvdG9zaXplLCAmcHJvdG9vZmZzZXQs
IGZsYWdzLA0KPiAJICAgIGZvcmNlX3BhcnRpdGlvbikpIDwgMCkNCj4gCQll
cnIoMSwgImFwbSB1cGRhdGU6ICVzIiwgZGV2KTsNCj4gCWVsc2UgaWYgKGVy
cm9yID4gMCkNCj4gCQlleGl0KDEpOw0KMTY5LDE3MGMyMTEsMjE0DQo8IAlp
ZiAod3JpdGVhcHBsZXBhcnRtYXAoZGV2ZmQpIDwgMCkNCjwgCQllcnIoMSwg
IndyaXRlIGFwbTogJXMiLCBkZXYpOw0KLS0tDQo+IAlpZiAobm93cml0ZSkg
ew0KPiAJCWNsb3NlKGRldmZkKTsNCj4gCQlyZXR1cm4gMDsNCj4gCX0NCjE3
MmMyMTYNCjwgCWlmIChsc2VlayhkZXZmZCwgQk9PVFNFQ1RPUl9PRkZTRVQs
IFNFRUtfU0VUKSAhPSBCT09UU0VDVE9SX09GRlNFVCkNCi0tLQ0KPiAJaWYg
KGxzZWVrKGRldmZkLCBwcm90b29mZnNldCwgU0VFS19TRVQpICE9IHByb3Rv
b2Zmc2V0KQ0KMTc1YzIxOQ0KPCAJLyogU3luYyBmaWxlc3lzdGVtcyAodG8g
Y2xlYW4gaW4tbWVtb3J5IHN1cGVyYmxvY2s/KSAqLw0KLS0tDQo+IAkvKiBT
eW5jIGZpbGVzeXN0ZW1zICh0byBjbGVhbiBpbi1rZXJuZWwgZGlydHkgcGFn
ZXMpICovDQo0MzNhNDc4LDQ4MQ0KPiAvKg0KPiAgKiBNYWtlIGEgZmFrZSBh
cG0gZm9yIHVzZSBvbiBOZXRCU0Qtb25seSBkaXNrcy4gTWFrZXMgcGFydGl0
aW9uIHdoaWNoIGlzDQo+ICAqIDFrIGJpZywgMmsgaW50byBkaXNrLiBDb25z
dGFudHMgYWxzbyBjb2RlZCBpbiBnZXRfcGFydGl0aW9uIGJlbG93Lg0KPiAg
Ki8NCjQzNSw0MzZjNDgzDQo8IHdyaXRlYXBwbGVwYXJ0bWFwKGZkKQ0KPCAJ
aW50IGZkOw0KLS0tDQo+IHdyaXRlYXBwbGVwYXJ0bWFwKGludCBmZCkNCjQz
OCw0NDBkNDg0DQo8IAlzdHJ1Y3QgZHJ2cl9tYXAgZG07DQo8IAlzdHJ1Y3Qg
cGFydG1hcGVudHJ5IHBtZTsNCjwgDQo0NDksNDUwYzQ5Myw0OTQNCjwgCWRt
LnNiU2lnID0gRFJJVkVSX01BUF9NQUdJQzsNCjwgCWRtLnNiQmxvY2tTaXpl
ID0gNTEyOw0KLS0tDQo+IAlkbS5zYlNpZyA9IGh0b25zKERSSVZFUl9NQVBf
TUFHSUMpOw0KPiAJZG0uc2JCbG9ja1NpemUgPSBodG9ucyg1MTIpOw0KNDUx
YTQ5Ng0KPiAJZG0uc2JEcnZyQ291bnQgPSAwOw0KNDU5LDQ2MWM1MDQsNTA3
DQo8IAlwbWUucG1NYXBCbGtDbnQgPSAyOw0KPCAJcG1lLnBtUHlQYXJ0U3Rh
cnQgPSAxOw0KPCAJcG1lLnBtUGFydEJsa0NudCA9IHBtZS5wbURhdGFDbnQg
PSAyOw0KLS0tDQo+IAlwbWUucG1TaWdQYWQgPSAwOw0KPiAJcG1lLnBtTWFw
QmxrQ250ID0gaHRvbmwoMik7DQo+IAlwbWUucG1QeVBhcnRTdGFydCA9IGh0
b25sKDEpOw0KPiAJcG1lLnBtUGFydEJsa0NudCA9IHBtZS5wbURhdGFDbnQg
PSBodG9ubCgyKTsNCjQ3Miw0NzdjNTE4LDU0Mg0KPCAJLyogYmxvY2sgMjog
TmV0QlNEIHBhcnRpdGlvbiAqLw0KPCAJYnplcm8oJnBtZSwgc2l6ZW9mKHBt
ZSkpOw0KPCAJcG1lLnBtU2lnID0gRFBNRV9NQUdJQzsNCjwgCXBtZS5wbU1h
cEJsa0NudCA9IDI7DQo8IAlwbWUucG1QeVBhcnRTdGFydCA9IDQ7DQo8IAlw
bWUucG1QYXJ0QmxrQ250ID0gcG1lLnBtRGF0YUNudCA9IDB4N2ZmZmZmZmY7
DQotLS0NCj4gCS8qIGZpbGwgaW4gZW5vdWdoIG9mIHRoZSBkcml2ZXIgcGFy
dGl0aW9uIHNvIHRoYXQNCj4gCSAqIG1ha2Vkcml2ZXJwYXJ0IHdpbGwgd29y
ay4gKi8NCj4gCXBtZS5wbVBhcnRCbGtDbnQgPSBodG9ubCgyKTsNCj4gCXBt
ZS5wbVB5UGFydFN0YXJ0ID0gaHRvbmwoNCk7DQo+IAlpZiAobHNlZWsoZmQs
IDEwMjQsIFNFRUtfU0VUKSAhPSAxMDI0KQ0KPiAJCXJldHVybiAtMTsNCj4g
CWlmICh3cml0ZShmZCwgJnBtZSwgNTEyKSAhPSA1MTIpDQo+IAkJcmV0dXJu
IC0xOw0KPiANCj4gCXJldHVybiAobWFrZWRyaXZlcnBhcnQoZmQsIDIpKTsN
Cj4gfQ0KPiANCj4gaW50DQo+IG1ha2Vkcml2ZXJwYXJ0KGludCBmZCwgaW50
IHBhcnRpdGlvbikNCj4gew0KPiAJb2ZmX3Qgd2hlcmUgPSA1MTIgKiBwYXJ0
aXRpb247DQo+IA0KPiAJaWYgKGxzZWVrKGZkLCB3aGVyZSwgU0VFS19TRVQp
ICE9IHdoZXJlKQ0KPiAJCXJldHVybiAtMTsNCj4gCWlmIChyZWFkKGZkLCAm
cG1lLCA1MTIpICE9IDUxMikNCj4gCQlyZXR1cm4gLTE7DQo+IA0KPiAJcG1l
LnBtU2lnID0gaHRvbnMoRFBNRV9NQUdJQyk7DQo+IAlwbWUucG1TaWdQYWQg
PSAwOw0KPiAJcG1lLnBtUGFydEJsa0NudCA9IHBtZS5wbURhdGFDbnQgPSBo
dG9ubCgweDdmZmZmZmZmKTsNCjQ4MCw0ODNjNTQ1LDU0OA0KPCAJcG1lLnBt
UGFydFN0YXR1cyA9IDB4M2I7DQo8IAlwbWUucG1Cb290U2l6ZSA9IDB4NDAw
Ow0KPCAJcG1lLnBtQm9vdExvYWQgPSAweDQwMDA7DQo8IAlwbWUucG1Cb290
RW50cnkgPSAweDQwMDA7DQotLS0NCj4gCXBtZS5wbVBhcnRTdGF0dXMgPSBo
dG9ubCgweDNiKTsNCj4gCXBtZS5wbUJvb3RTaXplID0gaHRvbmwoMHg0MDAp
Ow0KPiAJcG1lLnBtQm9vdExvYWQgPSBodG9ubCgweDQwMDApOw0KPiAJcG1l
LnBtQm9vdEVudHJ5ID0gaHRvbmwoMHg0MDAwKTsNCjQ4NmM1NTENCjwgCWlm
IChsc2VlayhmZCwgMTAyNCwgU0VFS19TRVQpICE9IDEwMjQpDQotLS0NCj4g
CWlmIChsc2VlayhmZCwgd2hlcmUsIFNFRUtfU0VUKSAhPSB3aGVyZSkNCjQ4
N2E1NTMsNTU0DQo+IAlpZiAobm93cml0ZSkNCj4gCQlyZXR1cm4gKDApOw0K
NDkxYzU1OCw4NzINCjwgCXJldHVybiAwOw0KLS0tDQo+IAlyZXR1cm4gZml4
dXBfZHJpdmVyKGZkLCBudG9obChwbWUucG1QeVBhcnRTdGFydCksDQo+IAkg
ICAgbnRvaGwocG1lLnBtTWFwQmxrQ250KSk7DQo+IH0NCj4gDQo+IC8qDQo+
ICAqIEZpeCB1cCB0aGUgZHJpdmVyIGVudHJ5IGluIHRoZSBEcml2ZXIgRGVz
Y3JpcHRvciBSZWNvcmQgZm9yIGENCj4gICogZ2l2ZW4gZHJpdmVyLiBXZSB3
aWxsIGVpdGhlciBmaW5kIG9yIG5vdCBmaW5kIHRoZSBnaXZlbiBkcml2ZXIg
aW4NCj4gICogdGhlIGxpc3QuIEFkZCBpdCBpZiBub3QgcHJlc2VudC4NCj4g
ICoNCj4gICogV2UgYWxzbyBzYW5pdHktY2hlY2sgdGhlIG51bWJlciBvZiBk
cml2ZXJzIC0gb2xkZXIgdmVyc2lvbnMgb2YgdGhpcw0KPiAgKiBwcm9ncmFt
IGxlZnQgZ2FyYmFnZSBpbiB0aGUgZHJpdmVyIGNvdW50LiBJZiB3ZSBmaW5k
IGFuIGltcG9zaWJsZSBjb3VudA0KPiAgKiAobW9yZSB0aGFuIHdpbGwgZml0
IGluIG9uZSBibG9jayksIHdlIGp1c3QgcmVzZXQgdGhlIHRhYmxlLg0KPiAg
Ki8NCj4gDQo+ICNkZWZpbmUgTUFYX0RSSVZFUlMJNjENCj4gaW50DQo+IGZp
eHVwX2RyaXZlcihpbnQgZmQsIGludCBzdGFydCwgaW50IHNpemUpDQo+IHsN
Cj4gCXN0cnVjdAlkcnZyX2VudHJ5CSpkcnZyczsNCj4gCWludAlkcnZyX2Nv
dW50LCBpLCBzdGFydE1TVywgc3RhcnRMU1c7DQo+IA0KPiAJLyogYmxvY2sg
MCAqLw0KPiAJaWYgKGxzZWVrKGZkLCAwLCBTRUVLX1NFVCkgIT0gMCkNCj4g
CQlyZXR1cm4gLTE7DQo+IAlpZiAocmVhZChmZCwgJmRtLCA1MTIpICE9IDUx
MikJCS8qIHJlYWQgZXhpc3RpbmcgZGlza2xhYmVsICovDQo+IAkJcmV0dXJu
IC0xOw0KPiAJaWYgKGxzZWVrKGZkLCAwLCBTRUVLX1NFVCkgIT0gMCkNCj4g
CQlyZXR1cm4gLTE7DQo+IA0KPiAJLyogRG9lcyB0aGUgY291bnQgb2YgZHJp
dmVycyBtYWtlIHNlbnNlPyBUaGVyZSBjYW4gYmUgYXQgbW9zdA0KPiAJICog
NjAgZHJpdmVycyBpbiBhIDUxMi1ieXRlIGJsb2NrLiAqLw0KPiAJZHJ2cl9j
b3VudCA9IG50b2hzKGRtLnNiRHJ2ckNvdW50KTsNCj4gDQo+IAlpZiAoZHJ2
cl9jb3VudCA+IE1BWF9EUklWRVJTKQ0KPiAJCWRydnJfY291bnQgPSAwOw0K
PiANCj4gCWRydnJzID0gKHN0cnVjdCBkcnZyX2VudHJ5ICopJmRtLmJsb2Nr
cGFkZGluZzsNCj4gCXN0YXJ0TVNXID0gaHRvbnMoc3RhcnQgPj4gMTYpOw0K
PiAJc3RhcnRMU1cgPSBodG9ucyhzdGFydCAmIDB4ZmZmZik7DQo+IA0KPiAJ
Zm9yIChpPTA7IGkgPCBkcnZyX2NvdW50OyBpKyspDQo+IAkJaWYgKChkcnZy
c1tpXS5kZEJsb2NrTVNXID09IHN0YXJ0TVNXKSAmJg0KPiAJCSAgICAoZHJ2
cnNbaV0uZGRCbG9ja0xTVyA9PSBzdGFydExTVykpIHsNCj4gCQkJYnJlYWs7
DQo+IAkJfQ0KPiANCj4gCWlmIChpID09IGRydnJfY291bnQpIHsNCj4gCQlp
ZiAoZHJ2cl9jb3VudCA9PSBNQVhfRFJJVkVSUykgew0KPiAJCQlmcHJpbnRm
KHN0ZGVyciwNCj4gCQkJCSJObyByb29tIGluIGRyaXZlciB0YWJsZSBmb3Ig
bmV3IGRyaXZlci5cbiIpOw0KPiAJCQlyZXR1cm4gKDEpOw0KPiAJCX0NCj4g
CQlkbS5zYkRydnJDb3VudCA9IGh0b25zKCsrZHJ2cl9jb3VudCk7DQo+IAkJ
ZHJ2cnNbaV0uZGRCbG9ja01TVyA9IHN0YXJ0TVNXOw0KPiAJCWRydnJzW2ld
LmRkQmxvY2tMU1cgPSBzdGFydExTVzsNCj4gCX0NCj4gDQo+IAlkcnZyc1tp
XS5kZFNpemUgPSBodG9ucyhzaXplKTsNCj4gI2lmIDANCj4gCS8qDQo+IAkg
KiBSaWdodCBub3csIGRydnJzWzBdLmRkVHlwZSBvdmVybGFwcyB3aXRoIHRo
ZSBmaXJzdA0KPiAJICogMTYgYml0cyBvZiB0aGUgZGlza2xhYmVsIHdoaWNo
IGxpdmVzIDY0IGJ5dGVzIGludG8gdGhlDQo+IAkgKiBzZWN0b3IuIFNvIGRv
bid0IGZpbGwgdGhpcyBpbiBmb3Igbm93LiBQbHVzIHdlIGRvbid0DQo+IAkg
KiBrbm93IHdoYXQgIk9TIGNvZGUiIHRvIHVzZSBmb3IgTmV0QlNELg0KPiAJ
ICovDQo+IAlkcnZyc1tpXS5kZFR5cGUgPSBodG9ucygxNik7CS8qIFhYWCA/
Pz8gKi8NCj4gI2VuZGlmDQo+IA0KPiAJaWYgKHdyaXRlKGZkLCAmZG0sIDUx
MikgIT0gNTEyKQ0KPiAJCXJldHVybiAtMTsNCj4gDQo+IAlyZXR1cm4gKDAp
Ow0KPiB9DQo+IA0KPiAvKg0KPiAgKiBGaWd1cmUgb3V0IHdoZXJlIHRvIHN0
b3JlIHRoZSBib290IGJsb2Nrcy4NCj4gICoNCj4gICogVGhpcyBwcm9ncmFt
IHN0b3JlcyB0aGUgYm9vdCBsb2FkZXIgYXMgYSAiZHJpdmVyIiBwYXJ0aXRp
b24gaW4NCj4gICogYW4gQXBwbGUgUGFydGl0aW9uIE1hcC4NCj4gICoNCj4g
ICogT3JpZ2luYWxseSwgTmV0QlNEL21hY3BwYyB0b29rIG92ZXIgdGhlIHdo
b2xlIGRpc2ssIGFuZCB1c2VkDQo+ICAqIGEgdHJhZGl0aW9uYWwgdW5peCBk
aXNrbGFiZWwgZm9yIHBhcnRpdGlvbmluZy4gaW5zdGFsbGJvb3Qgd291bGQN
Cj4gICogbWFrZSBhIGZha2UgQXBwbGUgUGFydGl0aW9uIE1hcCBhbmQgc3Rv
cmUgdGhlIGJvb3QgYmxvY2tzLCBhbGwgd2l0aGluDQo+ICAqIHRoZSBzdGFy
dGluZyA4ayByZXNlcnZlZCBpbiB0aGUgZmZzIGZpbGUgc3lzdGVtIHNwZWMu
DQo+ICAqDQo+ICAqIFRoaXMgdmVyc2lvbiBvZiB0aGUgcHJvZ3JhbSBpcyBl
bmhhbmNlZCBpbiB0aGF0IGl0IHdpbGwgcmVhZCBhbiBleGlzdGluZw0KPiAg
KiBBcHBsZSBQYXJ0aXRpb24gTWFwLCBhbmQgaW5zdGFsbCB0aGUgYm9vdCBi
bG9ja3MgaW4gYW4gZXhpc3RpbmcuIFdlIG9ubHkNCj4gICogaW5zdGFsbCB0
aGUgZmFrZSBwYXJ0aXRpb24gbWFwIGlmIG5vdCBtYXAgZXhpc3RzLg0KPiAg
Kg0KPiAgKiBIZXJlJ3MgdGhlIHByb2NlZHVyZS4NCj4gICoNCj4gICogMSkg
SWYgd2UgZWl0aGVyIGZpbmQgbm8gZXhpc3RpbmcgcGFydGl0aW9uIG1hcCwg
b3IgdGhlIC1GIGNvbW1hbmQgbGluZQ0KPiAgKiBvcHRpb24gd2FzIHVzZWQs
IHdlIHdyaXRlIGEgZmFrZSBwYXJ0aXRpb24gbWFwLg0KPiAgKg0KPiAgKiAy
KSBJZiB3ZSB3ZXJlIHRvbGQgYSBzcGVjaWZpYyBwYXJ0aXRpb24gdG8gb3Zl
cndyaXRlICh0aGUgLVAgY29tbWFuZA0KPiAgKiBsaW5lIG9wdGlvbiksIHdl
IG92ZXJ3cml0ZSBpdC4NCj4gICoNCj4gICogMykgd2Ugc2NhbiB0aGUgcGFy
dGl0aW9uIG1hcCBsb29raW5nIGZvciBhbiBleGlzdGluZyBkcml2ZXIgcGFy
dGl0aW9uLA0KPiAgKiBmb3IgYSAiRnJlZSBzcGFjZSIgcGFydGl0aW9uIGJp
ZyBlbm91Z2ggdG8gaG9sZCB0aGUgYm9vdGJsb2NrcywgYW5kDQo+ICAqIGZv
ciBhbiBlbXB0eSBwYXJ0aXRpb24uDQo+ICAqDQo+ICAqIDQpIElmIHdlIGZp
bmQgYSBkcml2ZXIgcGFydGl0aW9uIGJpZyBlbm91Z2ggdG8gZml0IHRoZSBi
b290IGJsb2NrcywNCj4gICogd2UgdXNlIGl0LiBJZiB3ZSBmaW5kIGEgZHJp
dmVyIHBhcnRpdGlvbiwgYnV0IGl0IGlzIE5PVCBiaWcgZW5vdWdoIGZvcg0K
PiAgKiB0aGUgYm9vdCBibG9ja3MsIHdlIGV4aXQgd2l0aCBhbiBlcnJvciBt
ZXNzYWdlLiBXZSBkb24ndCBqdXN0IG1ha2UNCj4gICogYSBzZWNvbmQgZHJp
dmVyIHBhcnRpdGlvbiBhcyB3ZSBkb24ndCBrbm93IHdoYXQgd2lsbCBoYXBw
ZW4gaWYgd2UgaGF2ZQ0KPiAgKiBtb3JlIHRoYW4gb25lIGRpcml2ZXIgcGFy
dGl0aW9uLg0KPiAgKg0KPiAgKiA1KSBJZiB3ZSBkaWRuJ3QgZmluZCBhIGRy
aXZlciBwYXJ0aXRpb24sIGJ1dCB3ZSBoYXZlIGFuIGVtcHR5IHBhcnRpdGlv
bg0KPiAgKiBhbmQgd2UgaGF2ZSBmcmVlIHNwYWNlIGZvciB0aGUgZHJpdmVy
cywgd2UgbWFrZSBvbmUuIFdlIGRlbGV0ZSBzcGFjZQ0KPiAgKiBmcm9tIHRo
ZSBzdGFydCBvZiB0aGUgZnJlZSBzcGFjZSBwYXJ0aXRpb24sIGFuZCBmaWxs
IGluIHRoZSBuZXcgcGFydGl0aW9uDQo+ICAqIGVudHJ5Lg0KPiAgKi8NCj4g
DQo+IGludA0KPiBnZXRfcGFydGl0aW9uKGludCBmZCwgaW50IHByb3Rvc2l6
ZSwgb2ZmX3QgKnByb3Rvb2Zmc2V0LCBpbnQgZmxhZ3MsDQo+IAlpbnQgZm9y
Y2VfcGFydCkNCj4gew0KPiAJaW50CW1heF9wYXJ0cywgbWF4bWF4X3BhcnRz
LCBmcmVlX3BhcnQsIGZyZWVfc2l6ZSwgaSwgajsNCj4gCWludAluZXdfc3Rh
cnQsIHByb3RvYmxvY2tzOw0KPiAJY2hhcgl0eXBlc3RyWzMyXSwgKmM7DQo+
IA0KPiAJcHJvdG9ibG9ja3MgPSBwcm90b3NpemUgPj4gOTsJLyogZGl2aWRl
IGJ5IDUxMiAqLw0KPiANCj4gCS8qIGJsb2NrIDAgKi8NCj4gCWlmIChsc2Vl
ayhmZCwgMCwgU0VFS19TRVQpICE9IDApDQo+IAkJcmV0dXJuIC0xOw0KPiAJ
aWYgKHJlYWQoZmQsICZkbSwgNTEyKSAhPSA1MTIpCQkvKiByZWFkIGV4aXN0
aW5nIGRpc2tsYWJlbCAqLw0KPiAJCXJldHVybiAtMTsNCj4gDQo+IAkvKiBE
byB3ZSBsYWNrIGEgdmFsaWQgQXBwbGUgcG0sIG9yIHdhcyAtRiBwYXNzZWQ/
ICovDQo+IAlpZiAoKG50b2hzKGRtLnNiU2lnKSAhPSAweDQ1NTIpIHx8IChm
bGFncyAmIFBBUlRfRk9SQ0VfRkFLRSkpIHsNCj4gCQlpZiAodmVyYm9zZSkN
Cj4gCQkJcHJpbnRmKCJXcml0aW5nIGZha2UgYXBtIHdpdGhpbiBib290IGJs
b2NrIHNwYWNlIG9mICINCj4gCQkJICAgICAiZmlyc3QgcGFydGl0aW9uXG4i
KTsNCj4gCQlpZiAocHJvdG9zaXplID4gMTAyNCkgew0KPiAJCQlmcHJpbnRm
KHN0ZGVyciwgInByb3RvIGJvb3QgYmxvY2tzIHRvbyBiaWdcbiIpOw0KPiAJ
CQlyZXR1cm4gKDEpOw0KPiAJCX0NCj4gCQlpZiAobm93cml0ZSkNCj4gCQkJ
cmV0dXJuICgwKTsNCj4gCQkqcHJvdG9vZmZzZXQgPSAyMDQ4Ow0KPiAJCXJl
dHVybiAod3JpdGVhcHBsZXBhcnRtYXAoZmQpKTsNCj4gCX0NCj4gDQo+IAkv
KiByZWFkIGZpcnN0IHBhcnRpdGlvbiB0byBnZXQgY291bnQgb2YgcGFydGl0
aW9ucyAmIHZlcmlmeSAqLw0KPiAJaWYgKGxzZWVrKGZkLCA1MTIsIFNFRUtf
U0VUKSAhPSA1MTIpDQo+IAkJcmV0dXJuIC0xOw0KPiAJaWYgKHJlYWQoZmQs
ICZwbWUsIDUxMikgIT0gNTEyKQ0KPiAJCXJldHVybiAtMTsNCj4gCWlmIChu
dG9ocyhwbWUucG1TaWcpICE9IERQTUVfTUFHSUMpIHsNCj4gCQlmcHJpbnRm
KHN0ZGVyciwNCj4gCQkgICAgIkFwcGxlIFBhcnRpdGlvbiBNYXAgbWFnaWMg
bnVtYmVyIHdyb25nIGZvciBibG9jayAxLlxuIik7DQo+IAkJcmV0dXJuICgx
KTsNCj4gCX0NCj4gCW1heF9wYXJ0cyA9IG50b2hzKHBtZS5wbU1hcEJsa0Nu
dCk7DQo+IA0KPiAJLyogTm93IHNlZSBpZiB3ZSB3ZXJlIHBhc3NlZCB0aGUg
LVAgPG51bT4gZmxhZyAqLw0KPiAJaWYgKGZsYWdzICYgUEFSVF9GT1JDRV9O
VU1CRVIpIHsNCj4gCQlpZiAoZm9yY2VfcGFydCA+IG1heF9wYXJ0cykgew0K
PiAJCQlmcHJpbnRmKHN0ZGVyciwgIlBhcnRpdGlvbiBzcGVjaWZpZWQgd2l0
aCAtUCBvcHRpb24sIg0KPiAJCQkgICAgIiVkLCBub3QgaW4gcGFydGl0aW9u
IG1hcC5cbiIsIGZvcmNlX3BhcnQpOw0KPiAJCQlyZXR1cm4gKDEpOw0KPiAJ
CX0NCj4gCQlyZXR1cm4gKG1ha2Vkcml2ZXJwYXJ0KGZkLCBmb3JjZV9wYXJ0
KSk7DQo+IAl9DQo+IA0KPiAJLyoNCj4gCSAqIE5vdyBzY2FuIHRoZSBwYXJ0
aXRpb24gdGFibGUgZm9yIGVpdGhlciBhbiBleGlzdGluZyBkcml2ZXIsIG9y
DQo+IAkgKiBmb3IgYSBmcmVlIHBhcnRpdGlvbi4gQWxzbyBub3RlIG1heCBu
dW1iZXIgb2YgcGFydGl0aW9ucyBhdmFpbGFibGUNCj4gCSAqIGluIHBhcnRp
dGlvbiBtYXAuDQo+IAkgKi8NCj4gCW1heG1heF9wYXJ0cyA9IDA7IGZyZWVf
cGFydCA9IDA7IGZyZWVfc2l6ZSA9IDA7DQo+IAlmb3IoaSA9IDE7aSA8PSBt
YXhfcGFydHM7IGkrKykgew0KPiAJCWlmIChudG9ocyhwbWUucG1TaWcpICE9
IERQTUVfTUFHSUMpDQo+IAkJCWdvdG8gcmVhZG5leHQ7DQo+IA0KPiAJCXN0
cm5jcHkodHlwZXN0ciwgKGNoYXIgKilwbWUucG1QYXJ0VHlwZSwgc2l6ZW9m
KHR5cGVzdHIpKTsNCj4gCQl0eXBlc3RyW3NpemVvZih0eXBlc3RyKSAtIDFd
ID0gJ1wwJzsNCj4gCQlmb3IoYyA9IHR5cGVzdHI7ICpjOyBjKyspDQo+IAkJ
CWlmICgoJ2EnIDw9ICpjKSAmJiAoKmMgPD0gJ3onKSkNCj4gCQkJCSpjID0g
KCpjIC0gJ2EnICsgJ0EnKTsNCj4gDQo+IAkJaWYgKHN0cmNtcChQQVJUX1RZ
UEVfRlJFRSwgdHlwZXN0cikgPT0gMCkgew0KPiAJCQkvKg0KPiAJCQkgKiBJ
ZiB0aGUgZnJlZSBzcGFjZSBwYXJ0aXRpb24gaXMgYmlnIGVub3VnaCBhbmQN
Cj4gCQkJICogZWl0aGVyIHdlIGhhdmVuJ3QgZm91bmQgYSBmcmVlIHBhcnRp
dGlvbiBvciB0aGlzDQo+IAkJCSAqIG9uZSBpcyBzbWFsbGVyIHRoYW4gdGhl
IG9uZSB3ZSBmb3VuZCwgdXNlIGl0Lg0KPiAJCQkgKi8NCj4gCQkJaWYgKCgo
ZnJlZV9wYXJ0ID09IDApIHx8DQo+IAkJCSAgICAobnRvaGwocG1lLnBtUGFy
dEJsa0NudCkgPCBmcmVlX3NpemUpKSAmJiANCj4gCQkJICAgIChudG9obChw
bWUucG1QYXJ0QmxrQ250KSA+PSBwcm90b2Jsb2NrcykpIHsNCj4gCQkJCWlm
ICh2ZXJib3NlKSB7DQo+IAkJCQkJcHJpbnRmKA0KPiAJCQkJCSAgICJGb3Vu
ZCBmcmVlIHNwYWNlIGluIHBhcnRpdGlvbiAlZCIsDQo+IAkJCQkJICAgaSk7
DQo+IAkJCQkJaWYgKGZyZWVfcGFydCkNCj4gCQkJCQkJcHJpbnRmKCIgd2hp
Y2ggaXMgc21hbGxlciB0aGFuIg0KPiAJCQkJCQkgICAgIiB0aGF0IGluIHBh
cnRpdGlvbiAlZCIsDQo+IAkJCQkJCSAgICBmcmVlX3BhcnQpOw0KPiAJCQkJ
CXByaW50ZigiXG4iKTsNCj4gCQkJCX0NCj4gCQkJCWZyZWVfcGFydCA9IGk7
DQo+IAkJCQlmcmVlX3NpemUgPSBudG9obChwbWUucG1QYXJ0QmxrQ250KTsN
Cj4gCQkJfQ0KPiAJCQlnb3RvIHJlYWRuZXh0Ow0KPiAJCX0NCj4gDQo+IAkJ
aWYgKHN0cmNtcChQQVJUX1RZUEVfUEFSVE1BUCwgdHlwZXN0cikgPT0gMCkg
ew0KPiAJCQltYXhtYXhfcGFydHMgPSBudG9obChwbWUucG1QYXJ0QmxrQ250
KTsNCj4gCQkJaWYgKHZlcmJvc2UpDQo+IAkJCQlwcmludGYoDQo+IAkJCQkg
ICAgIkZvdW50IHBhcnRpdGlvbiBtYXAgd2l0aCAlZCBlbnRyaWVzLlxuIiwN
Cj4gCQkJCSAgICBtYXhtYXhfcGFydHMpOw0KPiAJCQlnb3RvIHJlYWRuZXh0
Ow0KPiAJCX0NCj4gDQo+IAkJaWYgKHN0cmNtcChQQVJUX1RZUEVfTkJQUENf
Qk9PVCwgdHlwZXN0cikgPT0gMCkgew0KPiAJCQlpZiAodmVyYm9zZSkNCj4g
CQkJCXByaW50ZigiRm91bmQgbWFjcHBjIGJvb3QgcGFydGl0aW9uICMgJWQu
IiwNCj4gCQkJCSAgICBpKTsNCj4gCQkJaWYgKG50b2hsKHBtZS5wbVBhcnRC
bGtDbnQpID49IHByb3RvYmxvY2tzKSB7DQo+IAkJCQlpZiAodmVyYm9zZSkN
Cj4gCQkJCQlwcmludGYoIiBVc2luZyBpdC5cbiIpOw0KPiAJCQkJcmV0dXJu
IChtYWtlZHJpdmVycGFydChmZCwgaSkpOw0KPiAJCQl9DQo+IAkJCWlmICh2
ZXJib3NlKQ0KPiAJCQkJcHJpbnRmKCJ0b28gc21hbGwhIVxuIik7DQo+IAkJ
CWZwcmludGYoc3RkZXJyLCAiRm91bmQgZXhpc3RpbmcgTmV0QlNEIGJvb3Qg
cGFydGl0aW9uIg0KPiAJCQkgICAgIiB3aGljaCBpcyB0b28gc21hbGwgZm9y
IHRoZXNlIGJvb3Rcblx0YmxvY2tzLiINCj4gCQkJICAgICIgUGFydGl0aW9u
IGhhcyAlZCBibG9ja3MsIG5lZWRzICVkIGJsb2Nrcy5cbiIsDQo+IAkJCSAg
ICBudG9obChwbWUucG1QYXJ0QmxrQ250KSwgcHJvdG9ibG9ja3MpOw0KPiAJ
CQlyZXR1cm4gKDEpOw0KPiAJCX0NCj4gDQo+IHJlYWRuZXh0Og0KPiAJCS8q
IE5vdyByZWFkIG5leHQgcGFydGl0aW9uIGlmIHRoZXJlIGlzIG9uZS4gKi8N
Cj4gCQlpZiAoKGkgPCBtYXhfcGFydHMpICYmIChyZWFkKGZkLCAmcG1lLCA1
MTIpICE9IDUxMikpDQo+IAkJCXJldHVybiAoLTEpOw0KPiAJfQ0KPiANCj4g
CS8qDQo+IAkgKiBJZiB3ZSBnb3QgaGVyZSwgdGhlcmUgaXMgbm8gZXhpc3Rp
bmcgZHJpdmVyIHBhcnRpdGlvbi4gV2UgbmVlZA0KPiAJICogdG8gbWFrZSBv
bmUuDQo+IAkgKi8NCj4gDQo+IAlpZiAoZnJlZV9wYXJ0ID09IDApIHsNCj4g
CQlmcHJpbnRmKHN0ZGVyciwgIk5vdCBlbm91Z2ggZnJlZSBzcGFjZSBvbiBk
aXNrIGZvciINCj4gCQkgICAgIiBib290IGJsb2NrLlxuQXQgbGVhc3QgJWQg
Ynl0ZXMgbmVlZGVkLiIsIHByb3Rvc2l6ZSk7DQo+IAkJcmV0dXJuICgxKTsN
Cj4gCX0NCj4gDQo+IAkvKiBXaWxsIHdlIGp1c3Qgc3RlYWwgdGhlIGZyZWUg
c3BhY2UgdGhhdCdzIGxlZnQ/ICovDQo+IAlpZiAoZnJlZV9zaXplIDw9IDIg
KiBwcm90b2Jsb2Nrcykgew0KPiAJCWlmICh2ZXJib3NlKQ0KPiAJCQlwcmlu
dGYoIlVzaW5nIGZvdW5kIGZyZWVzcGFjZSBwYXJ0aXRpb24uXG4iKTsNCj4g
CQlyZXR1cm4gKG1ha2Vkcml2ZXJwYXJ0KGZkLCBmcmVlX3BhcnQpKTsNCj4g
CX0NCj4gDQo+IAlpZiAobWF4X3BhcnRzID49IG1heG1heF9wYXJ0cykgew0K
PiAJCWZwcmludGYoc3RkZXJyLCAiTm8gZnJlZSBzcGFjZSBpbiBwYXJ0aXRp
b24gbWFwIHRvIGFkZCBuZXciDQo+IAkJICAgICIgcGFydGl0aW9uLlxuIik7
DQo+IAkJcmV0dXJuICgxKTsNCj4gCX0NCj4gDQo+IAkvKg0KPiAJICogTm93
IGFjdHVhbGx5IGFkZCB0aGUgcGFydGl0aW9uLiBXZSBuZWVkIHRvOiAxKSBy
ZW1vdmUgc3BhY2UgZnJvbQ0KPiAJICogdGhlIGZyZWUgcGFydGl0aW9uIGZv
ciB0aGUgbmV3IG1hcCBlbnRyeSwgMikgbWFrZSBhIG5ldyBwYXJ0aXRpb24s
DQo+IAkgKiBhbmQgMykgdXBkYXRlIGFsbCBvZiB0aGUgcGFydGl0aW9ucyBz
byB0aGF0IHRoZWlyIHBhcnRpdG9uIGNvdW50DQo+IAkgKiBtYXRjaGVzIHdo
YXQgaXQgc2hvdWxkIGJlLg0KPiAJICovDQo+IAlpZiAobHNlZWsoZmQsIDUx
MiAqIGZyZWVfcGFydCwgU0VFS19TRVQpICE9IDUxMiAqIGZyZWVfcGFydCkN
Cj4gCQlyZXR1cm4gLTE7DQo+IAlpZiAocmVhZChmZCwgJnBtZSwgNTEyKSAh
PSA1MTIpDQo+IAkJcmV0dXJuIC0xOw0KPiANCj4gCW5ld19zdGFydCA9IG50
b2hsKHBtZS5wbVB5UGFydFN0YXJ0KTsNCj4gCXBtZS5wbVB5UGFydFN0YXJ0
ID0gaHRvbmwoaSA9IChuZXdfc3RhcnQgKyBwcm90b2Jsb2NrcykpOw0KPiAJ
cG1lLnBtTWFwQmxrQ250ID0gaHRvbmwoaiA9IChudG9obChwbWUucG1NYXBC
bGtDbnQpIC0gcHJvdG9ibG9ja3MpKTsNCj4gDQo+IAlpZiAodmVyYm9zZSkN
Cj4gCQlwcmludGYoIlVwZGF0aW5nIGZyZWVzcGFjZSBwYXJ0aXRpb24gJWQu
XG5QYXJ0aXRpb24gbm93IHN0YXJ0cyINCj4gCQkgICAgIiBhdCBibG9jayAl
ZCBmb3Igc2l6ZSAlZC4iLCBmcmVlX3BhcnQsIGksIGopOw0KPiANCj4gCWlm
IChsc2VlayhmZCwgNTEyICogZnJlZV9wYXJ0LCBTRUVLX1NFVCkgIT0gNTEy
ICogZnJlZV9wYXJ0KQ0KPiAJCXJldHVybiAtMTsNCj4gCWlmICgobm93cml0
ZSA9PSAwKSAmJiAod3JpdGUoZmQsICZwbWUsIDUxMikgIT0gNTEyKSkNCj4g
CQlyZXR1cm4gLTE7DQo+IA0KPiAJLyogQWN0dWFsbHkgdXBkYXRlIGFsbCBv
ZiB0aGUgb3RoZXIgcGFydGl0aW9ucyBub3cgKi8NCj4gCW1heF9wYXJ0cysr
Ow0KPiAJaWYgKHZlcmJvc2UpDQo+IAkJcHJpbnRmKCJFeHBhbmRpbmcgYWN0
aXZlIHBhcnRpdGlvbiBjb3VudCB0byAlZC5cbiIsIG1heF9wYXJ0cyk7DQo+
IAlpZiAobHNlZWsoZmQsIDUxMiwgU0VFS19TRVQpICE9IDUxMikNCj4gCQly
ZXR1cm4gLTE7DQo+IAlmb3IoaSA9IDE7IGkgPCBtYXhfcGFydHM7IGkrKykg
ew0KPiAJCWlmIChyZWFkKGZkLCAmcG1lLCA1MTIpICE9IDUxMikNCj4gCQkJ
cmV0dXJuICgtMSk7DQo+IAkJaWYgKGxzZWVrKGZkLCAtNTEyLCBTRUVLX0NV
UikgPCAwKQ0KPiAJCQlyZXR1cm4gKC0xKTsNCj4gCQlwbWUucG1NYXBCbGtD
bnQgPSBodG9ucyhtYXhfcGFydHMpOw0KPiAJCWlmICgobm93cml0ZSA9PSAw
KSAmJiAod3JpdGUoZmQsICZwbWUsIDUxMikgIT0gNTEyKSkNCj4gCQkJcmV0
dXJuICgtMSk7DQo+IAl9DQo+IA0KPiAJLyogTm93IHRoYXQgd2UgaGF2ZSBl
ZmZlY3Rpdmx5IGxzZWVrZWQgdG8gdGhlIG5ldyBzZWN0b3IsIHNldCBpdCB1
cCAqLw0KPiAJaWYgKHZlcmJvc2UpDQo+IAkJcHJpbnRmKCJJbnN0YWxsaW5n
IG5ldyBib290IGJsb2Nrcy5cbiIpOw0KPiAJcG1lLnBtU2lnID0gaHRvbnMo
RFBNRV9NQUdJQyk7DQo+IAlwbWUucG1TaWdQYWQgPSAwOw0KPiAJcG1lLnBt
TWFwQmxrQ250ID0gaHRvbmwobWF4X3BhcnRzKTsNCj4gCXBtZS5wbVBhcnRC
bGtDbnQgPSBodG9ubChwcm90b2Jsb2Nrcyk7DQo+IAlwbWUucG1QeVBhcnRT
dGFydCA9IGh0b25sKG5ld19zdGFydCk7DQo+IAlpZiAoKG5vd3JpdGUgPT0g
MCkgJiYgKHdyaXRlKGZkLCAmcG1lLCA1MTIpICE9IDUxMikpDQo+IAkJcmV0
dXJuIC0xOw0KPiAJcmV0dXJuIChtYWtlZHJpdmVycGFydChmZCwgbWF4X3Bh
cnRzKSk7DQo=
--0-853287946-966453361=:2800--