LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDIKICogU3lzZ28gUmVhbC1UaW1lIFNvbHV0aW9ucywgR21iSCA8d3d3LmVsaW5vcy5jb20+CiAqIEFsZXggWnVlcGtlIDxhenVAc3lzZ28uZGU+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+Cgp1bG9uZyBteWZsdXNoKHZvaWQpOwoKCiNkZWZpbmUgU0M1MjBfTUFYX0ZMQVNIX0JBTktTICAzCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOSzBfQkFTRSAweDM4MDAwMDAwICAvKiBCT09UQ1MgKi8KI2RlZmluZSBTQzUyMF9GTEFTSF9CQU5LMV9CQVNFIDB4MzAwMDAwMDAgIC8qIFJPTUNTMCAqLwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTksyX0JBU0UgMHgyODAwMDAwMCAgLyogUk9NQ1MxICovCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOS1NJWkUgICAweDgwMDAwMDAKCiNkZWZpbmUgQU1EMjlMVjAxNl9TSVpFICAgICAgICAweDIwMDAwMAojZGVmaW5lIEFNRDI5TFYwMTZfU0VDVE9SUyAgICAgMzIKCmZsYXNoX2luZm9fdCAgICBmbGFzaF9pbmZvW1NDNTIwX01BWF9GTEFTSF9CQU5LU107CgojZGVmaW5lIENNRF9SRUFEX0FSUkFZCQkweDAwRjAwMEYwCiNkZWZpbmUgQ01EX1VOTE9DSzEJCTB4MDBBQTAwQUEKI2RlZmluZSBDTURfVU5MT0NLMgkJMHgwMDU1MDA1NQojZGVmaW5lIENNRF9FUkFTRV9TRVRVUAkJMHgwMDgwMDA4MAojZGVmaW5lIENNRF9FUkFTRV9DT05GSVJNCTB4MDAzMDAwMzAKI2RlZmluZSBDTURfUFJPR1JBTQkJMHgwMEEwMDBBMAojZGVmaW5lIENNRF9VTkxPQ0tfQllQQVNTCTB4MDAyMDAwMjAKCgojZGVmaW5lIEJJVF9FUkFTRV9ET05FCQkweDAwODAwMDgwCiNkZWZpbmUgQklUX1JEWV9NQVNLCQkweDAwODAwMDgwCiNkZWZpbmUgQklUX1BST0dSQU1fRVJST1IJMHgwMDIwMDAyMAojZGVmaW5lIEJJVF9USU1FT1VUCQkweDgwMDAwMDAwIC8qIG91ciBmbGFnICovCgojZGVmaW5lIFJFQURZIDEKI2RlZmluZSBFUlIgICAyCiNkZWZpbmUgVE1PICAgNAoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCnVsb25nIGZsYXNoX2luaXQodm9pZCkKewoJaW50IGksIGo7Cgl1bG9uZyBzaXplID0gMDsKCglmb3IgKGkgPSAwOyBpIDwgU0M1MjBfTUFYX0ZMQVNIX0JBTktTOyBpKyspIHsKCQl1bG9uZyBmbGFzaGJhc2UgPSAwOwoJCWludCBzZWN0c2l6ZSA9IDA7CgkJaWYgKGk9PTAgfHwgaT09MikgewoJCQkvKiBGaXhNZTogdGhpcyBhc3N1bWVzIHRoYXQgYmFuayAwIGFuZCAyCgkJCSAqIGFyZSBtYXBwZWQgdG8gdGhlIHR3byA4TWIgYmFua3MgKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spIHwKCQkJCShBTURfSURfTFYwMTZCICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gQU1EMjlMVjAxNl9TSVpFKjQ7CgkJCWZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50ID0gQU1EMjlMVjAxNl9TRUNUT1JTOwoJCQlzZWN0c2l6ZSA9IChBTUQyOUxWMDE2X1NJWkUqNCkvQU1EMjlMVjAxNl9TRUNUT1JTOwoJCX0gZWxzZSB7CgkJCS8qIEZpeE1lOiB0aGlzIGFzc3VtZXMgdGhhdCBiYW5rMSBpcyB1bm1hcHBlZAoJCQkgKiAob3IgbWFwcGVkIHRvIHRoZSBzYW1lIGZsYXNoIGJhbmsgYXMgQk9PVENTKSAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0gMDsKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gMDsKCQkJZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQgPSAwOwoJCQlzZWN0c2l6ZT0wOwoJCX0KCQltZW1zZXQoZmxhc2hfaW5mb1tpXS5wcm90ZWN0LCAwLCBDRkdfTUFYX0ZMQVNIX1NFQ1QpOwoJCXN3aXRjaCAoaSkgewoJCWNhc2UgMDoKCQkJZmxhc2hiYXNlID0gU0M1MjBfRkxBU0hfQkFOSzBfQkFTRTsKCQkJYnJlYWs7CgkJY2FzZSAxOgoJCQlmbGFzaGJhc2UgPSBTQzUyMF9GTEFTSF9CQU5LMV9CQVNFOwoJCQlicmVhazsKCQljYXNlIDI6CgkJCWZsYXNoYmFzZSA9IFNDNTIwX0ZMQVNIX0JBTkswX0JBU0U7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCXBhbmljKCJjb25maWd1cmVkIHRvIG1hbnkgZmxhc2ggYmFua3MhXG4iKTsKCQl9CgoJCWZvciAoaiA9IDA7IGogPCBmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudDsgaisrKSB7CgkJCWZsYXNoX2luZm9baV0uc3RhcnRbal0gPSBzZWN0c2l6ZTsKCQkJZmxhc2hfaW5mb1tpXS5zdGFydFtqXSA9IGZsYXNoYmFzZSArIGogKiBzZWN0c2l6ZTsKCQl9CgkJc2l6ZSArPSBmbGFzaF9pbmZvW2ldLnNpemU7Cgl9CgoJLyoKCSAqIFByb3RlY3QgbW9uaXRvciBhbmQgZW52aXJvbm1lbnQgc2VjdG9ycwoJICovCglmbGFzaF9wcm90ZWN0KEZMQUdfUFJPVEVDVF9TRVQsCgkJICAgICAgaTM4NmJvb3Rfc3RhcnQtU0M1MjBfRkxBU0hfQkFOSzBfQkFTRSwKCQkgICAgICBpMzg2Ym9vdF9lbmQtU0M1MjBfRkxBU0hfQkFOSzBfQkFTRSwKCQkgICAgICAmZmxhc2hfaW5mb1swXSk7CgojaWZkZWYgQ0ZHX0VOVl9BRERSCglmbGFzaF9wcm90ZWN0KEZMQUdfUFJPVEVDVF9TRVQsCgkJICAgICAgQ0ZHX0VOVl9BRERSLAoJCSAgICAgIENGR19FTlZfQUREUiArIENGR19FTlZfU0laRSAtIDEsCgkJICAgICAgJmZsYXNoX2luZm9bMF0pOwojZW5kaWYKCXJldHVybiBzaXplOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwp2b2lkIGZsYXNoX3ByaW50X2luZm8oZmxhc2hfaW5mb190ICppbmZvKQp7CglpbnQgaTsKCglzd2l0Y2ggKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spIHsKCWNhc2UgKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKToKCQlwcmludGYoIkFNRDogIik7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXByaW50ZigiVW5rbm93biBWZW5kb3IgIik7CgkJYnJlYWs7Cgl9CgoJc3dpdGNoIChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1RZUEVNQVNLKSB7CgljYXNlIChBTURfSURfTFYwMTZCICYgRkxBU0hfVFlQRU1BU0spOgoJCXByaW50ZigiNHggQW1kMjlMVjAxNkIgKDE2TWJpdClcbiIpOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlwcmludGYoIlVua25vd24gQ2hpcCBUeXBlXG4iKTsKCQlnb3RvIGRvbmU7CgkJYnJlYWs7Cgl9CgoJcHJpbnRmKCIgIFNpemU6ICVsZCBNQiBpbiAlZCBTZWN0b3JzXG4iLAoJICAgICAgIGluZm8tPnNpemUgPj4gMjAsIGluZm8tPnNlY3Rvcl9jb3VudCk7CgoJcHJpbnRmKCIgIFNlY3RvciBTdGFydCBBZGRyZXNzZXM6Iik7Cglmb3IgKGkgPSAwOyBpIDwgaW5mby0+c2VjdG9yX2NvdW50OyBpKyspIHsKCQlpZiAoKGkgJSA1KSA9PSAwKSB7CgkJCXByaW50ZiAoIlxuICAgIik7CgkJfQoJCXByaW50ZiAoIiAlMDhsWCVzIiwgaW5mby0+c3RhcnRbaV0sCgkJCWluZm8tPnByb3RlY3RbaV0gPyAiIChSTykiIDogIiAgICAgIik7Cgl9CglwcmludGYgKCJcbiIpOwoKCWRvbmU6Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCgppbnQgZmxhc2hfZXJhc2UoZmxhc2hfaW5mb190ICppbmZvLCBpbnQgc19maXJzdCwgaW50IHNfbGFzdCkKewoJdWxvbmcgcmVzdWx0OwoJaW50IGlmbGFnLCBwcm90LCBzZWN0OwoJaW50IHJjID0gRVJSX09LOwoJaW50IGNoaXAxLCBjaGlwMjsKCgkvKiBmaXJzdCBsb29rIGZvciBwcm90ZWN0aW9uIGJpdHMgKi8KCglpZiAoaW5mby0+Zmxhc2hfaWQgPT0gRkxBU0hfVU5LTk9XTikgewoJCXJldHVybiBFUlJfVU5LTk9XTl9GTEFTSF9UWVBFOwoJfQoKCWlmICgoc19maXJzdCA8IDApIHx8IChzX2ZpcnN0ID4gc19sYXN0KSkgewoJCXJldHVybiBFUlJfSU5WQUw7Cgl9CgoJaWYgKChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1ZFTkRNQVNLKSAhPQoJICAgIChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykpIHsKCQlyZXR1cm4gRVJSX1VOS05PV05fRkxBU0hfVkVORE9SOwoJfQoKCXByb3QgPSAwOwoJZm9yIChzZWN0PXNfZmlyc3Q7IHNlY3Q8PXNfbGFzdDsgKytzZWN0KSB7CgkJaWYgKGluZm8tPnByb3RlY3Rbc2VjdF0pIHsKCQkJcHJvdCsrOwoJCX0KCX0KCWlmIChwcm90KSB7CgkJcmV0dXJuIEVSUl9QUk9URUNURUQ7Cgl9CgoJLyoKCSAqIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQKCSAqIGhlcmUuIFJlbWVtYmVyIHRoYXQgb3VyIGV4Y2VwdGlvbiB2ZWN0b3JzIGFyZQoJICogYXQgYWRkcmVzcyAwIGluIHRoZSBmbGFzaCwgYW5kIHdlIGRvbid0IHdhbnQgYQoJICogKHRpY2tlcikgZXhjZXB0aW9uIHRvIGhhcHBlbiB3aGlsZSB0aGUgZmxhc2gKCSAqIGNoaXAgaXMgaW4gcHJvZ3JhbW1pbmcgbW9kZS4KCSAqLwoJaWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkvKiBTdGFydCBlcmFzZSBvbiB1bnByb3RlY3RlZCBzZWN0b3JzICovCglmb3IgKHNlY3QgPSBzX2ZpcnN0OyBzZWN0PD1zX2xhc3QgJiYgIWN0cmxjKCk7IHNlY3QrKykgewoJCXByaW50ZigiRXJhc2luZyBzZWN0b3IgJTJkIC4uLiAiLCBzZWN0KTsKCgkJLyogYXJtIHNpbXBsZSwgbm9uIGludGVycnVwdCBkZXBlbmRlbnQgdGltZXIgKi8KCQlyZXNldF90aW1lcigpOwoKCQlpZiAoaW5mby0+cHJvdGVjdFtzZWN0XSA9PSAwKSB7CgkJCS8qIG5vdCBwcm90ZWN0ZWQgKi8KCQkJdWxvbmcgYWRkciA9IGluZm8tPnN0YXJ0W3NlY3RdOwoKCQkJd3JpdGVsKENNRF9VTkxPQ0sxLCBhZGRyICsgMSk7CgkJCXdyaXRlbChDTURfVU5MT0NLMiwgYWRkciArIDIpOwoJCQl3cml0ZWwoQ01EX0VSQVNFX1NFVFVQLCBhZGRyICsgMSk7CgoJCQl3cml0ZWwoQ01EX1VOTE9DSzEsIGFkZHIgKyAxKTsKCQkJd3JpdGVsKENNRF9VTkxPQ0syLCBhZGRyICsgMik7CgkJCXdyaXRlbChDTURfRVJBU0VfQ09ORklSTSwgYWRkcik7CgoKCQkJLyogd2FpdCB1bnRpbCBmbGFzaCBpcyByZWFkeSAqLwoJCQljaGlwMSA9IGNoaXAyID0gMDsKCgkJCWRvIHsKCQkJCXJlc3VsdCA9IHJlYWRsKGFkZHIpOwoKCQkJCS8qIGNoZWNrIHRpbWVvdXQgKi8KCQkJCWlmIChnZXRfdGltZXIoMCkgPiBDRkdfRkxBU0hfRVJBU0VfVE9VVCkgewoJCQkJCXdyaXRlbChDTURfUkVBRF9BUlJBWSwgYWRkciArIDEpOwoJCQkJCWNoaXAxID0gVE1POwoJCQkJCWJyZWFrOwoJCQkJfQoKCQkJCWlmICghY2hpcDEgJiYgKHJlc3VsdCAmIDB4RkZGRikgJiBCSVRfRVJBU0VfRE9ORSkgewoJCQkJCWNoaXAxID0gUkVBRFk7CgkJCQl9CgoJCQkJaWYgKCFjaGlwMSAmJiAocmVzdWx0ICYgMHhGRkZGKSAmIEJJVF9QUk9HUkFNX0VSUk9SKSB7CgkJCQkJY2hpcDEgPSBFUlI7CgkJCQl9CgoJCQkJaWYgKCFjaGlwMiAmJiAocmVzdWx0ID4+IDE2KSAmIEJJVF9FUkFTRV9ET05FKSB7CgkJCQkJY2hpcDIgPSBSRUFEWTsKCQkJCX0KCgkJCQlpZiAoIWNoaXAyICYmIChyZXN1bHQgPj4gMTYpICYgQklUX1BST0dSQU1fRVJST1IpIHsKCQkJCQljaGlwMiA9IEVSUjsKCQkJCX0KCgkJCX0gIHdoaWxlICghY2hpcDEgfHwgIWNoaXAyKTsKCgkJCXdyaXRlbChDTURfUkVBRF9BUlJBWSwgYWRkciArIDEpOwoKCQkJaWYgKGNoaXAxID09IEVSUiB8fCBjaGlwMiA9PSBFUlIpIHsKCQkJCXJjID0gRVJSX1BST0dfRVJST1I7CgkJCQlnb3RvIG91dGFoZXJlOwoJCQl9CgoJCQlpZiAoY2hpcDEgPT0gVE1PKSB7CgkJCQlyYyA9IEVSUl9USU1PVVQ7CgkJCQlnb3RvIG91dGFoZXJlOwoJCQl9CgoJCQlwcmludGYoIm9rLlxuIik7CgkJfSBlbHNlIHsgLyogaXQgd2FzIHByb3RlY3RlZCAqLwoKCQkJcHJpbnRmKCJwcm90ZWN0ZWQhXG4iKTsKCQl9Cgl9CgoJaWYgKGN0cmxjKCkpIHsKCQlwcmludGYoIlVzZXIgSW50ZXJydXB0IVxuIik7Cgl9CgpvdXRhaGVyZToKCS8qIGFsbG93IGZsYXNoIHRvIHNldHRsZSAtIHdhaXQgMTAgbXMgKi8KCXVkZWxheSgxMDAwMCk7CgoJaWYgKGlmbGFnKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCglyZXR1cm4gcmM7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQ29weSBtZW1vcnkgdG8gZmxhc2gKICovCgp2b2xhdGlsZSBzdGF0aWMgaW50IHdyaXRlX3dvcmQoZmxhc2hfaW5mb190ICppbmZvLCB1bG9uZyBkZXN0LCB1bG9uZyBkYXRhKQp7Cgl1bG9uZyBhZGRyID0gZGVzdDsKCXVsb25nIHJlc3VsdDsKCWludCByYyA9IEVSUl9PSzsKCWludCBpZmxhZzsKCWludCBjaGlwMSwgY2hpcDI7CgoJLyoKCSAqIENoZWNrIGlmIEZsYXNoIGlzIChzdWZmaWNpZW50bHkpIGVyYXNlZAoJICovCglyZXN1bHQgPSByZWFkbChhZGRyKTsKCWlmICgocmVzdWx0ICYgZGF0YSkgIT0gZGF0YSkgewoJCXJldHVybiBFUlJfTk9UX0VSQVNFRDsKCX0KCgkvKgoJICogRGlzYWJsZSBpbnRlcnJ1cHRzIHdoaWNoIG1pZ2h0IGNhdXNlIGEgdGltZW91dAoJICogaGVyZS4gUmVtZW1iZXIgdGhhdCBvdXIgZXhjZXB0aW9uIHZlY3RvcnMgYXJlCgkgKiBhdCBhZGRyZXNzIDAgaW4gdGhlIGZsYXNoLCBhbmQgd2UgZG9uJ3Qgd2FudCBhCgkgKiAodGlja2VyKSBleGNlcHRpb24gdG8gaGFwcGVuIHdoaWxlIHRoZSBmbGFzaAoJICogY2hpcCBpcyBpbiBwcm9ncmFtbWluZyBtb2RlLgoJICovCglpZmxhZyA9IGRpc2FibGVfaW50ZXJydXB0cygpOwoKCXdyaXRlbChDTURfVU5MT0NLMSwgYWRkciArIDEpOwoJd3JpdGVsKENNRF9VTkxPQ0syLCBhZGRyICsgMik7Cgl3cml0ZWwoQ01EX1VOTE9DS19CWVBBU1MsIGFkZHIgKyAxKTsKCXdyaXRlbChhZGRyLCBDTURfUFJPR1JBTSk7Cgl3cml0ZWwoYWRkciwgZGF0YSk7CgoJLyogYXJtIHNpbXBsZSwgbm9uIGludGVycnVwdCBkZXBlbmRlbnQgdGltZXIgKi8KCXJlc2V0X3RpbWVyKCk7CgoJLyogd2FpdCB1bnRpbCBmbGFzaCBpcyByZWFkeSAqLwoJY2hpcDEgPSBjaGlwMiA9IDA7CglkbyB7CgkJcmVzdWx0ID0gcmVhZGwoYWRkcik7CgoJCS8qIGNoZWNrIHRpbWVvdXQgKi8KCQlpZiAoZ2V0X3RpbWVyKDApID4gQ0ZHX0ZMQVNIX0VSQVNFX1RPVVQpIHsKCQkJY2hpcDEgPSBFUlIgfCBUTU87CgkJCWJyZWFrOwoJCX0KCgkJaWYgKCFjaGlwMSAmJiAoKHJlc3VsdCAmIDB4ODApID09IChkYXRhICYgMHg4MCkpKSB7CgkJCWNoaXAxID0gUkVBRFk7CgkJfQoKCQlpZiAoIWNoaXAxICYmICgocmVzdWx0ICYgMHhGRkZGKSAmIEJJVF9QUk9HUkFNX0VSUk9SKSkgewoJCQlyZXN1bHQgPSByZWFkbChhZGRyKTsKCgkJCWlmICgocmVzdWx0ICYgMHg4MCkgPT0gKGRhdGEgJiAweDgwKSkgewoJCQkJY2hpcDEgPSBSRUFEWTsKCQkJfSBlbHNlIHsKCQkJCWNoaXAxID0gRVJSOwoJCQl9CgkJfQoKCQlpZiAoIWNoaXAyICYmICgocmVzdWx0ICYgKDB4ODAgPDwgMTYpKSA9PSAoZGF0YSAmICgweDgwIDw8IDE2KSkpKSB7CgkJCWNoaXAyID0gUkVBRFk7CgkJfQoKCQlpZiAoIWNoaXAyICYmICgocmVzdWx0ID4+IDE2KSAmIEJJVF9QUk9HUkFNX0VSUk9SKSkgewoJCQlyZXN1bHQgPSByZWFkbChhZGRyKTsKCgkJCWlmICgocmVzdWx0ICYgKDB4ODAgPDwgMTYpKSA9PSAoZGF0YSAmICgweDgwIDw8IDE2KSkpIHsKCQkJCWNoaXAyID0gUkVBRFk7CgkJCX0gZWxzZSB7CgkJCQljaGlwMiA9IEVSUjsKCQkJfQoJCX0KCgl9ICB3aGlsZSAoIWNoaXAxIHx8ICFjaGlwMik7CgoJd3JpdGVsKENNRF9SRUFEX0FSUkFZLCBhZGRyKTsKCglpZiAoY2hpcDEgPT0gRVJSIHx8IGNoaXAyID09IEVSUiB8fCByZWFkbChhZGRyKSAhPSBkYXRhKSB7CgkJcmMgPSBFUlJfUFJPR19FUlJPUjsKCX0KCglpZiAoaWZsYWcpIHsKCQllbmFibGVfaW50ZXJydXB0cygpOwoJfQoKCXJldHVybiByYzsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBDb3B5IG1lbW9yeSB0byBmbGFzaC4KICovCgppbnQgd3JpdGVfYnVmZihmbGFzaF9pbmZvX3QgKmluZm8sIHVjaGFyICpzcmMsIHVsb25nIGFkZHIsIHVsb25nIGNudCkKewoJdWxvbmcgY3AsIHdwLCBkYXRhOwoJaW50IGw7CglpbnQgaSwgcmM7CgoJd3AgPSAoYWRkciAmIH4zKTsJLyogZ2V0IGxvd2VyIHdvcmQgYWxpZ25lZCBhZGRyZXNzICovCgoJLyoKCSAqIGhhbmRsZSB1bmFsaWduZWQgc3RhcnQgYnl0ZXMKCSAqLwoJaWYgKChsID0gYWRkciAtIHdwKSAhPSAwKSB7CgkJZGF0YSA9IDA7CgkJZm9yIChpPTAsIGNwPXdwOyBpPGw7ICsraSwgKytjcCkgewoJCQlkYXRhID0gKGRhdGEgPj4gOCkgfCAoKih1Y2hhciAqKWNwIDw8IDI0KTsKCQl9CgkJZm9yICg7IGk8NCAmJiBjbnQ+MDsgKytpKSB7CgkJCWRhdGEgPSAoZGF0YSA+PiA4KSB8ICgqc3JjKysgPDwgMjQpOwoJCQktLWNudDsKCQkJKytjcDsKCQl9CgkJZm9yICg7IGNudD09MCAmJiBpPDQ7ICsraSwgKytjcCkgewoJCQlkYXRhID0gKGRhdGEgPj4gOCkgfCAoKih1Y2hhciAqKWNwIDw8IDI0KTsKCQl9CgoJCWlmICgocmMgPSB3cml0ZV93b3JkKGluZm8sIHdwLCBkYXRhKSkgIT0gMCkgewoJCQlyZXR1cm4gcmM7CgkJfQoJCXdwICs9IDQ7Cgl9CgoJLyoKCSAqIGhhbmRsZSB3b3JkIGFsaWduZWQgcGFydAoJICovCgl3aGlsZSAoY250ID49IDQpIHsKCQlkYXRhID0gKigodnVfbG9uZyopc3JjKTsKCQlpZiAoKHJjID0gd3JpdGVfd29yZChpbmZvLCB3cCwgZGF0YSkpICE9IDApIHsKCQkJcmV0dXJuIHJjOwoJCX0KCQlzcmMgKz0gNDsKCQl3cCAgKz0gNDsKCQljbnQgLT0gNDsKCX0KCglpZiAoY250ID09IDApIHsKCQlyZXR1cm4gRVJSX09LOwoJfQoKCS8qCgkgKiBoYW5kbGUgdW5hbGlnbmVkIHRhaWwgYnl0ZXMKCSAqLwoJZGF0YSA9IDA7Cglmb3IgKGk9MCwgY3A9d3A7IGk8NCAmJiBjbnQ+MDsgKytpLCArK2NwKSB7CgkJZGF0YSA9IChkYXRhID4+IDgpIHwgKCpzcmMrKyA8PCAyNCk7CgkJLS1jbnQ7Cgl9Cglmb3IgKDsgaTw0OyArK2ksICsrY3ApIHsKCQlkYXRhID0gKGRhdGEgPj4gOCkgfCAoKih1Y2hhciAqKWNwIDw8IDI0KTsKCX0KCglyZXR1cm4gd3JpdGVfd29yZChpbmZvLCB3cCwgZGF0YSk7Cn0K