LyoKICogQ29weXJpZ2h0IChjKSAxOTgyLCAxOTg2LCAxOTg4LCAxOTkwLCAxOTkzCiAqCVRoZSBSZWdlbnRzIG9mIHRoZSBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICoJQCgjKXRjcF9zdWJyLmMJOC4xIChCZXJrZWxleSkgNi8xMC85MwogKiB0Y3Bfc3Vici5jLHYgMS41IDE5OTQvMTAvMDggMjI6Mzk6NTggcGhrIEV4cAogKi8KCi8qCiAqIENoYW5nZXMgYW5kIGFkZGl0aW9ucyByZWxhdGluZyB0byBTTGlSUAogKiBDb3B5cmlnaHQgKGMpIDE5OTUgRGFubnkgR2FzcGFyb3Zza2kuCiAqIAogKiBQbGVhc2UgcmVhZCB0aGUgZmlsZSBDT1BZUklHSFQgZm9yIHRoZSAKICogdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIGNvcHlyaWdodC4KICovCgojZGVmaW5lIFdBTlRfU1lTX0lPQ1RMX0gKI2luY2x1ZGUgPHNsaXJwLmg+CgovKiBwYXRjaGFibGUvc2V0dGFibGUgcGFyYW1ldGVycyBmb3IgdGNwICovCmludCAJdGNwX21zc2RmbHQgPSBUQ1BfTVNTOwppbnQgCXRjcF9ydHRkZmx0ID0gVENQVFZfU1JUVERGTFQgLyBQUl9TTE9XSFo7CmludAl0Y3BfZG9fcmZjMTMyMyA9IDA7CS8qIERvbid0IGRvIHJmYzEzMjMgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzICovCmludAl0Y3BfcmN2c3BhY2U7CS8qIFlvdSBtYXkgd2FudCB0byBjaGFuZ2UgdGhpcyAqLwppbnQJdGNwX3NuZHNwYWNlOwkvKiBLZWVwIHNtYWxsIGlmIHlvdSBoYXZlIGFuIGVycm9yIHByb25lIGxpbmsgKi8KCi8qCiAqIFRjcCBpbml0aWFsaXphdGlvbgogKi8Kdm9pZAp0Y3BfaW5pdCgpCnsKCXRjcF9pc3MgPSAxOwkJLyogd3JvbmcgKi8KCXRjYi5zb19uZXh0ID0gdGNiLnNvX3ByZXYgPSAmdGNiOwoJCgkvKiB0Y3BfcmN2c3BhY2UgPSBvdXIgV2luZG93IHdlIGFkdmVydGlzZSB0byB0aGUgcmVtb3RlICovCgl0Y3BfcmN2c3BhY2UgPSBUQ1BfUkNWU1BBQ0U7Cgl0Y3Bfc25kc3BhY2UgPSBUQ1BfU05EU1BBQ0U7CgkKCS8qIE1ha2Ugc3VyZSB0Y3Bfc25kc3BhY2UgaXMgYXQgbGVhc3QgMipNU1MgKi8KCWlmICh0Y3Bfc25kc3BhY2UgPCAyKihtaW4oaWZfbXR1LCBpZl9tcnUpIC0gc2l6ZW9mKHN0cnVjdCB0Y3BpcGhkcikpKQoJCXRjcF9zbmRzcGFjZSA9IDIqKG1pbihpZl9tdHUsIGlmX21ydSkgLSBzaXplb2Yoc3RydWN0IHRjcGlwaGRyKSk7Cn0KCi8qCiAqIENyZWF0ZSB0ZW1wbGF0ZSB0byBiZSB1c2VkIHRvIHNlbmQgdGNwIHBhY2tldHMgb24gYSBjb25uZWN0aW9uLgogKiBDYWxsIGFmdGVyIGhvc3QgZW50cnkgY3JlYXRlZCwgZmlsbHMKICogaW4gYSBza2VsZXRhbCB0Y3AvaXAgaGVhZGVyLCBtaW5pbWl6aW5nIHRoZSBhbW91bnQgb2Ygd29yawogKiBuZWNlc3Nhcnkgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyB1c2VkLgogKi8KLyogc3RydWN0IHRjcGlwaGRyICogKi8Kdm9pZAp0Y3BfdGVtcGxhdGUodHApCglzdHJ1Y3QgdGNwY2IgKnRwOwp7CglzdHJ1Y3Qgc29ja2V0ICpzbyA9IHRwLT50X3NvY2tldDsKCXJlZ2lzdGVyIHN0cnVjdCB0Y3BpcGhkciAqbiA9ICZ0cC0+dF90ZW1wbGF0ZTsKCgluLT50aV9uZXh0ID0gbi0+dGlfcHJldiA9IDA7CgluLT50aV94MSA9IDA7CgluLT50aV9wciA9IElQUFJPVE9fVENQOwoJbi0+dGlfbGVuID0gaHRvbnMoc2l6ZW9mIChzdHJ1Y3QgdGNwaXBoZHIpIC0gc2l6ZW9mIChzdHJ1Y3QgaXApKTsKCW4tPnRpX3NyYyA9IHNvLT5zb19mYWRkcjsKCW4tPnRpX2RzdCA9IHNvLT5zb19sYWRkcjsKCW4tPnRpX3Nwb3J0ID0gc28tPnNvX2Zwb3J0OwoJbi0+dGlfZHBvcnQgPSBzby0+c29fbHBvcnQ7CgkKCW4tPnRpX3NlcSA9IDA7CgluLT50aV9hY2sgPSAwOwoJbi0+dGlfeDIgPSAwOwoJbi0+dGlfb2ZmID0gNTsKCW4tPnRpX2ZsYWdzID0gMDsKCW4tPnRpX3dpbiA9IDA7CgluLT50aV9zdW0gPSAwOwoJbi0+dGlfdXJwID0gMDsKfQoKLyoKICogU2VuZCBhIHNpbmdsZSBtZXNzYWdlIHRvIHRoZSBUQ1AgYXQgYWRkcmVzcyBzcGVjaWZpZWQgYnkKICogdGhlIGdpdmVuIFRDUC9JUCBoZWFkZXIuICBJZiBtID09IDAsIHRoZW4gd2UgbWFrZSBhIGNvcHkKICogb2YgdGhlIHRjcGlwaGRyIGF0IHRpIGFuZCBzZW5kIGRpcmVjdGx5IHRvIHRoZSBhZGRyZXNzZWQgaG9zdC4KICogVGhpcyBpcyB1c2VkIHRvIGZvcmNlIGtlZXAgYWxpdmUgbWVzc2FnZXMgb3V0IHVzaW5nIHRoZSBUQ1AKICogdGVtcGxhdGUgZm9yIGEgY29ubmVjdGlvbiB0cC0+dF90ZW1wbGF0ZS4gIElmIGZsYWdzIGFyZSBnaXZlbgogKiB0aGVuIHdlIHNlbmQgYSBtZXNzYWdlIGJhY2sgdG8gdGhlIFRDUCB3aGljaCBvcmlnaW5hdGVkIHRoZQogKiBzZWdtZW50IHRpLCBhbmQgZGlzY2FyZCB0aGUgbWJ1ZiBjb250YWluaW5nIGl0IGFuZCBhbnkgb3RoZXIKICogYXR0YWNoZWQgbWJ1ZnMuCiAqCiAqIEluIGFueSBjYXNlIHRoZSBhY2sgYW5kIHNlcXVlbmNlIG51bWJlciBvZiB0aGUgdHJhbnNtaXR0ZWQKICogc2VnbWVudCBhcmUgYXMgc3BlY2lmaWVkIGJ5IHRoZSBwYXJhbWV0ZXJzLgogKi8Kdm9pZAp0Y3BfcmVzcG9uZCh0cCwgdGksIG0sIGFjaywgc2VxLCBmbGFncykKCXN0cnVjdCB0Y3BjYiAqdHA7CglyZWdpc3RlciBzdHJ1Y3QgdGNwaXBoZHIgKnRpOwoJcmVnaXN0ZXIgc3RydWN0IG1idWYgKm07Cgl0Y3Bfc2VxIGFjaywgc2VxOwoJaW50IGZsYWdzOwp7CglyZWdpc3RlciBpbnQgdGxlbjsKCWludCB3aW4gPSAwOwoKCURFQlVHX0NBTEwoInRjcF9yZXNwb25kIik7CglERUJVR19BUkcoInRwID0gJWx4IiwgKGxvbmcpdHApOwoJREVCVUdfQVJHKCJ0aSA9ICVseCIsIChsb25nKXRpKTsKCURFQlVHX0FSRygibSA9ICVseCIsIChsb25nKW0pOwoJREVCVUdfQVJHKCJhY2sgPSAldSIsIGFjayk7CglERUJVR19BUkcoInNlcSA9ICV1Iiwgc2VxKTsKCURFQlVHX0FSRygiZmxhZ3MgPSAleCIsIGZsYWdzKTsKCQoJaWYgKHRwKQoJCXdpbiA9IHNic3BhY2UoJnRwLT50X3NvY2tldC0+c29fcmN2KTsKCWlmIChtID09IDApIHsKCQlpZiAoKG0gPSBtX2dldCgpKSA9PSBOVUxMKQoJCQlyZXR1cm47CiNpZmRlZiBUQ1BfQ09NUEFUXzQyCgkJdGxlbiA9IDE7CiNlbHNlCgkJdGxlbiA9IDA7CiNlbmRpZgoJCW0tPm1fZGF0YSArPSBpZl9tYXhsaW5raGRyOwoJCSptdG9kKG0sIHN0cnVjdCB0Y3BpcGhkciAqKSA9ICp0aTsKCQl0aSA9IG10b2QobSwgc3RydWN0IHRjcGlwaGRyICopOwoJCWZsYWdzID0gVEhfQUNLOwoJfSBlbHNlIHsKCQkvKiAKCQkgKiB0aSBwb2ludHMgaW50byBtIHNvIHRoZSBuZXh0IGxpbmUgaXMganVzdCBtYWtpbmcKCQkgKiB0aGUgbWJ1ZiBwb2ludCB0byB0aQoJCSAqLwoJCW0tPm1fZGF0YSA9IChjYWRkcl90KXRpOwoJCQoJCW0tPm1fbGVuID0gc2l6ZW9mIChzdHJ1Y3QgdGNwaXBoZHIpOwoJCXRsZW4gPSAwOwojZGVmaW5lIHhjaGcoYSxiLHR5cGUpIHsgdHlwZSB0OyB0PWE7IGE9YjsgYj10OyB9CgkJeGNoZyh0aS0+dGlfZHN0LnNfYWRkciwgdGktPnRpX3NyYy5zX2FkZHIsIHVfaW50MzJfdCk7CgkJeGNoZyh0aS0+dGlfZHBvcnQsIHRpLT50aV9zcG9ydCwgdV9pbnQxNl90KTsKI3VuZGVmIHhjaGcKCX0KCXRpLT50aV9sZW4gPSBodG9ucygodV9zaG9ydCkoc2l6ZW9mIChzdHJ1Y3QgdGNwaGRyKSArIHRsZW4pKTsKCXRsZW4gKz0gc2l6ZW9mIChzdHJ1Y3QgdGNwaXBoZHIpOwoJbS0+bV9sZW4gPSB0bGVuOwoKCXRpLT50aV9uZXh0ID0gdGktPnRpX3ByZXYgPSAwOwoJdGktPnRpX3gxID0gMDsKCXRpLT50aV9zZXEgPSBodG9ubChzZXEpOwoJdGktPnRpX2FjayA9IGh0b25sKGFjayk7Cgl0aS0+dGlfeDIgPSAwOwoJdGktPnRpX29mZiA9IHNpemVvZiAoc3RydWN0IHRjcGhkcikgPj4gMjsKCXRpLT50aV9mbGFncyA9IGZsYWdzOwoJaWYgKHRwKQoJCXRpLT50aV93aW4gPSBodG9ucygodV9pbnQxNl90KSAod2luID4+IHRwLT5yY3Zfc2NhbGUpKTsKCWVsc2UKCQl0aS0+dGlfd2luID0gaHRvbnMoKHVfaW50MTZfdCl3aW4pOwoJdGktPnRpX3VycCA9IDA7Cgl0aS0+dGlfc3VtID0gMDsKCXRpLT50aV9zdW0gPSBja3N1bShtLCB0bGVuKTsKCSgoc3RydWN0IGlwICopdGkpLT5pcF9sZW4gPSB0bGVuOwoKCWlmKGZsYWdzICYgVEhfUlNUKSAKCSAgKChzdHJ1Y3QgaXAgKil0aSktPmlwX3R0bCA9IE1BWFRUTDsKCWVsc2UgCgkgICgoc3RydWN0IGlwICopdGkpLT5pcF90dGwgPSBpcF9kZWZ0dGw7CgkKCSh2b2lkKSBpcF9vdXRwdXQoKHN0cnVjdCBzb2NrZXQgKikwLCBtKTsKfQoKLyoKICogQ3JlYXRlIGEgbmV3IFRDUCBjb250cm9sIGJsb2NrLCBtYWtpbmcgYW4KICogZW1wdHkgcmVhc3NlbWJseSBxdWV1ZSBhbmQgaG9va2luZyBpdCB0byB0aGUgYXJndW1lbnQKICogcHJvdG9jb2wgY29udHJvbCBibG9jay4KICovCnN0cnVjdCB0Y3BjYiAqCnRjcF9uZXd0Y3BjYihzbykKCXN0cnVjdCBzb2NrZXQgKnNvOwp7CglyZWdpc3RlciBzdHJ1Y3QgdGNwY2IgKnRwOwoJCgl0cCA9IChzdHJ1Y3QgdGNwY2IgKiltYWxsb2Moc2l6ZW9mKCp0cCkpOwoJaWYgKHRwID09IE5VTEwpCgkJcmV0dXJuICgoc3RydWN0IHRjcGNiICopMCk7CgkKCW1lbXNldCgoY2hhciAqKSB0cCwgMCwgc2l6ZW9mKHN0cnVjdCB0Y3BjYikpOwoJdHAtPnNlZ19uZXh0ID0gdHAtPnNlZ19wcmV2ID0gKHRjcGlwaGRycF8zMil0cDsKCXRwLT50X21heHNlZyA9IHRjcF9tc3NkZmx0OwoJCgl0cC0+dF9mbGFncyA9IHRjcF9kb19yZmMxMzIzID8gKFRGX1JFUV9TQ0FMRXxURl9SRVFfVFNUTVApIDogMDsKCXRwLT50X3NvY2tldCA9IHNvOwoJCgkvKgoJICogSW5pdCBzcnR0IHRvIFRDUFRWX1NSVFRCQVNFICgwKSwgc28gd2UgY2FuIHRlbGwgdGhhdCB3ZSBoYXZlIG5vCgkgKiBydHQgZXN0aW1hdGUuICBTZXQgcnR0dmFyIHNvIHRoYXQgc3J0dCArIDIgKiBydHR2YXIgZ2l2ZXMKCSAqIHJlYXNvbmFibGUgaW5pdGlhbCByZXRyYW5zbWl0IHRpbWUuCgkgKi8KCXRwLT50X3NydHQgPSBUQ1BUVl9TUlRUQkFTRTsKCXRwLT50X3J0dHZhciA9IHRjcF9ydHRkZmx0ICogUFJfU0xPV0haIDw8IDI7Cgl0cC0+dF9ydHRtaW4gPSBUQ1BUVl9NSU47CgoJVENQVF9SQU5HRVNFVCh0cC0+dF9yeHRjdXIsIAoJICAgICgoVENQVFZfU1JUVEJBU0UgPj4gMikgKyAoVENQVFZfU1JUVERGTFQgPDwgMikpID4+IDEsCgkgICAgVENQVFZfTUlOLCBUQ1BUVl9SRVhNVE1BWCk7CgoJdHAtPnNuZF9jd25kID0gVENQX01BWFdJTiA8PCBUQ1BfTUFYX1dJTlNISUZUOwoJdHAtPnNuZF9zc3RocmVzaCA9IFRDUF9NQVhXSU4gPDwgVENQX01BWF9XSU5TSElGVDsKCXRwLT50X3N0YXRlID0gVENQU19DTE9TRUQ7CgkKCXNvLT5zb190Y3BjYiA9IHRwOwoKCXJldHVybiAodHApOwp9CgovKgogKiBEcm9wIGEgVENQIGNvbm5lY3Rpb24sIHJlcG9ydGluZwogKiB0aGUgc3BlY2lmaWVkIGVycm9yLiAgSWYgY29ubmVjdGlvbiBpcyBzeW5jaHJvbml6ZWQsCiAqIHRoZW4gc2VuZCBhIFJTVCB0byBwZWVyLgogKi8Kc3RydWN0IHRjcGNiICp0Y3BfZHJvcChzdHJ1Y3QgdGNwY2IgKnRwLCBpbnQgZXJybm8pIAp7Ci8qIHRjcF9kcm9wKHRwLCBlcnJubykKCXJlZ2lzdGVyIHN0cnVjdCB0Y3BjYiAqdHA7CglpbnQgZXJybm87CnsKKi8KCglERUJVR19DQUxMKCJ0Y3BfZHJvcCIpOwoJREVCVUdfQVJHKCJ0cCA9ICVseCIsIChsb25nKXRwKTsKCURFQlVHX0FSRygiZXJybm8gPSAlZCIsIGVycm5vKTsKCQoJaWYgKFRDUFNfSEFWRVJDVkRTWU4odHAtPnRfc3RhdGUpKSB7CgkJdHAtPnRfc3RhdGUgPSBUQ1BTX0NMT1NFRDsKCQkodm9pZCkgdGNwX291dHB1dCh0cCk7CgkJdGNwc3RhdC50Y3BzX2Ryb3BzKys7Cgl9IGVsc2UKCQl0Y3BzdGF0LnRjcHNfY29ubmRyb3BzKys7Ci8qCWlmIChlcnJubyA9PSBFVElNRURPVVQgJiYgdHAtPnRfc29mdGVycm9yKQogKgkJZXJybm8gPSB0cC0+dF9zb2Z0ZXJyb3I7CiAqLwovKglzby0+c29fZXJyb3IgPSBlcnJubzsgKi8KCXJldHVybiAodGNwX2Nsb3NlKHRwKSk7Cn0KCi8qCiAqIENsb3NlIGEgVENQIGNvbnRyb2wgYmxvY2s6CiAqCWRpc2NhcmQgYWxsIHNwYWNlIGhlbGQgYnkgdGhlIHRjcAogKglkaXNjYXJkIGludGVybmV0IHByb3RvY29sIGJsb2NrCiAqCXdha2UgdXAgYW55IHNsZWVwZXJzCiAqLwpzdHJ1Y3QgdGNwY2IgKgp0Y3BfY2xvc2UodHApCglyZWdpc3RlciBzdHJ1Y3QgdGNwY2IgKnRwOwp7CglyZWdpc3RlciBzdHJ1Y3QgdGNwaXBoZHIgKnQ7CglzdHJ1Y3Qgc29ja2V0ICpzbyA9IHRwLT50X3NvY2tldDsKCXJlZ2lzdGVyIHN0cnVjdCBtYnVmICptOwoKCURFQlVHX0NBTEwoInRjcF9jbG9zZSIpOwoJREVCVUdfQVJHKCJ0cCA9ICVseCIsIChsb25nICl0cCk7CgkKCS8qIGZyZWUgdGhlIHJlYXNzZW1ibHkgcXVldWUsIGlmIGFueSAqLwoJdCA9IChzdHJ1Y3QgdGNwaXBoZHIgKikgdHAtPnNlZ19uZXh0OwoJd2hpbGUgKHQgIT0gKHN0cnVjdCB0Y3BpcGhkciAqKXRwKSB7CgkJdCA9IChzdHJ1Y3QgdGNwaXBoZHIgKil0LT50aV9uZXh0OwoJCW0gPSAoc3RydWN0IG1idWYgKikgUkVBU1NfTUJVRigoc3RydWN0IHRjcGlwaGRyICopdC0+dGlfcHJldik7CgkJcmVtcXVlXzMyKChzdHJ1Y3QgdGNwaXBoZHIgKikgdC0+dGlfcHJldik7CgkJbV9mcmVlbShtKTsKCX0KCS8qIEl0J3Mgc3RhdGljICovCi8qCWlmICh0cC0+dF90ZW1wbGF0ZSkKICoJCSh2b2lkKSBtX2ZyZWUoZHRvbSh0cC0+dF90ZW1wbGF0ZSkpOwogKi8KLyoJZnJlZSh0cCwgTV9QQ0IpOyAgKi8KCWZyZWUodHApOwoJc28tPnNvX3RjcGNiID0gMDsKCXNvaXNmZGlzY29ubmVjdGVkKHNvKTsKCS8qIGNsb2JiZXIgaW5wdXQgc29ja2V0IGNhY2hlIGlmIHdlJ3JlIGNsb3NpbmcgdGhlIGNhY2hlZCBjb25uZWN0aW9uICovCglpZiAoc28gPT0gdGNwX2xhc3Rfc28pCgkJdGNwX2xhc3Rfc28gPSAmdGNiOwoJY2xvc2Uoc28tPnMpOwoJc2JmcmVlKCZzby0+c29fcmN2KTsKCXNiZnJlZSgmc28tPnNvX3NuZCk7Cglzb2ZyZWUoc28pOwoJdGNwc3RhdC50Y3BzX2Nsb3NlZCsrOwoJcmV0dXJuICgoc3RydWN0IHRjcGNiICopMCk7Cn0KCnZvaWQKdGNwX2RyYWluKCkKewoJLyogWFhYICovCn0KCi8qCiAqIFdoZW4gYSBzb3VyY2UgcXVlbmNoIGlzIHJlY2VpdmVkLCBjbG9zZSBjb25nZXN0aW9uIHdpbmRvdwogKiB0byBvbmUgc2VnbWVudC4gIFdlIHdpbGwgZ3JhZHVhbGx5IG9wZW4gaXQgYWdhaW4gYXMgd2UgcHJvY2VlZC4KICovCgojaWZkZWYgbm90ZGVmCgp2b2lkCnRjcF9xdWVuY2goaSwgZXJybm8pCgoJaW50IGVycm5vOwp7CglzdHJ1Y3QgdGNwY2IgKnRwID0gaW50b3RjcGNiKGlucCk7CgoJaWYgKHRwKQoJCXRwLT5zbmRfY3duZCA9IHRwLT50X21heHNlZzsKfQoKI2VuZGlmIC8qIG5vdGRlZiAqLwoKLyoKICogVENQIHByb3RvY29sIGludGVyZmFjZSB0byBzb2NrZXQgYWJzdHJhY3Rpb24uCiAqLwoKLyoKICogVXNlciBpc3N1ZWQgY2xvc2UsIGFuZCB3aXNoIHRvIHRyYWlsIHRocm91Z2ggc2h1dGRvd24gc3RhdGVzOgogKiBpZiBuZXZlciByZWNlaXZlZCBTWU4sIGp1c3QgZm9yZ2V0IGl0LiAgSWYgZ290IGEgU1lOIGZyb20gcGVlciwKICogYnV0IGhhdmVuJ3Qgc2VudCBGSU4sIHRoZW4gZ28gdG8gRklOX1dBSVRfMSBzdGF0ZSB0byBzZW5kIHBlZXIgYSBGSU4uCiAqIElmIGFscmVhZHkgZ290IGEgRklOIGZyb20gcGVlciwgdGhlbiBhbG1vc3QgZG9uZTsgZ28gdG8gTEFTVF9BQ0sKICogc3RhdGUuICBJbiBhbGwgb3RoZXIgY2FzZXMsIGhhdmUgYWxyZWFkeSBzZW50IEZJTiB0byBwZWVyIChlLmcuCiAqIGFmdGVyIFBSVV9TSFVURE9XTiksIGFuZCBqdXN0IGhhdmUgdG8gcGxheSB0ZWRpb3VzIGdhbWUgd2FpdGluZwogKiBmb3IgcGVlciB0byBzZW5kIEZJTiBvciBub3QgcmVzcG9uZCB0byBrZWVwLWFsaXZlcywgZXRjLgogKiBXZSBjYW4gbGV0IHRoZSB1c2VyIGV4aXQgZnJvbSB0aGUgY2xvc2UgYXMgc29vbiBhcyB0aGUgRklOIGlzIGFja2VkLgogKi8Kdm9pZAp0Y3Bfc29ja2Nsb3NlZCh0cCkKCXN0cnVjdCB0Y3BjYiAqdHA7CnsKCglERUJVR19DQUxMKCJ0Y3Bfc29ja2Nsb3NlZCIpOwoJREVCVUdfQVJHKCJ0cCA9ICVseCIsIChsb25nKXRwKTsKCQoJc3dpdGNoICh0cC0+dF9zdGF0ZSkgewoKCWNhc2UgVENQU19DTE9TRUQ6CgljYXNlIFRDUFNfTElTVEVOOgoJY2FzZSBUQ1BTX1NZTl9TRU5UOgoJCXRwLT50X3N0YXRlID0gVENQU19DTE9TRUQ7CgkJdHAgPSB0Y3BfY2xvc2UodHApOwoJCWJyZWFrOwoKCWNhc2UgVENQU19TWU5fUkVDRUlWRUQ6CgljYXNlIFRDUFNfRVNUQUJMSVNIRUQ6CgkJdHAtPnRfc3RhdGUgPSBUQ1BTX0ZJTl9XQUlUXzE7CgkJYnJlYWs7CgoJY2FzZSBUQ1BTX0NMT1NFX1dBSVQ6CgkJdHAtPnRfc3RhdGUgPSBUQ1BTX0xBU1RfQUNLOwoJCWJyZWFrOwoJfQovKglzb2lzZmRpc2Nvbm5lY3RpbmcodHAtPnRfc29ja2V0KTsgKi8KCWlmICh0cCAmJiB0cC0+dF9zdGF0ZSA+PSBUQ1BTX0ZJTl9XQUlUXzIpCgkJc29pc2ZkaXNjb25uZWN0ZWQodHAtPnRfc29ja2V0KTsKCWlmICh0cCkKCQl0Y3Bfb3V0cHV0KHRwKTsKfQoKLyogCiAqIENvbm5lY3QgdG8gYSBob3N0IG9uIHRoZSBJbnRlcm5ldAogKiBDYWxsZWQgYnkgdGNwX2lucHV0CiAqIE9ubHkgZG8gYSBjb25uZWN0LCB0aGUgdGNwIGZpZWxkcyB3aWxsIGJlIHNldCBpbiB0Y3BfaW5wdXQKICogcmV0dXJuIDAgaWYgdGhlcmUncyBhIHJlc3VsdCBvZiB0aGUgY29ubmVjdCwKICogZWxzZSByZXR1cm4gLTEgbWVhbnMgd2UncmUgc3RpbGwgY29ubmVjdGluZwogKiBUaGUgcmV0dXJuIHZhbHVlIGlzIGFsbW9zdCBhbHdheXMgLTEgc2luY2UgdGhlIHNvY2tldCBpcwogKiBub25ibG9ja2luZy4gIENvbm5lY3QgcmV0dXJucyBhZnRlciB0aGUgU1lOIGlzIHNlbnQsIGFuZCBkb2VzIAogKiBub3Qgd2FpdCBmb3IgQUNLK1NZTi4KICovCmludCB0Y3BfZmNvbm5lY3Qoc28pCiAgICAgc3RydWN0IHNvY2tldCAqc287CnsKICBpbnQgcmV0PTA7CiAgCiAgREVCVUdfQ0FMTCgidGNwX2Zjb25uZWN0Iik7CiAgREVCVUdfQVJHKCJzbyA9ICVseCIsIChsb25nIClzbyk7CgogIGlmKCAocmV0PXNvLT5zPXNvY2tldChBRl9JTkVULFNPQ0tfU1RSRUFNLDApKSA+PSAwKSB7CiAgICBpbnQgb3B0LCBzPXNvLT5zOwogICAgc3RydWN0IHNvY2thZGRyX2luIGFkZHI7CgogICAgZmRfbm9uYmxvY2socyk7CiAgICBvcHQgPSAxOwogICAgc2V0c29ja29wdChzLFNPTF9TT0NLRVQsU09fUkVVU0VBRERSLChjaGFyICopJm9wdCxzaXplb2Yob3B0ICkpOwogICAgb3B0ID0gMTsKICAgIHNldHNvY2tvcHQocyxTT0xfU09DS0VULFNPX09PQklOTElORSwoY2hhciAqKSZvcHQsc2l6ZW9mKG9wdCApKTsKICAgIAogICAgYWRkci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgIGlmICgoc28tPnNvX2ZhZGRyLnNfYWRkciAmIGh0b25sKDB4ZmZmZmZmMDApKSA9PSBzcGVjaWFsX2FkZHIuc19hZGRyKSB7CiAgICAgIC8qIEl0J3MgYW4gYWxpYXMgKi8KICAgICAgc3dpdGNoKG50b2hsKHNvLT5zb19mYWRkci5zX2FkZHIpICYgMHhmZikgewogICAgICBjYXNlIENUTF9ETlM6CglhZGRyLnNpbl9hZGRyID0gZG5zX2FkZHI7CglicmVhazsKICAgICAgY2FzZSBDVExfQUxJQVM6CiAgICAgIGRlZmF1bHQ6CglhZGRyLnNpbl9hZGRyID0gbG9vcGJhY2tfYWRkcjsKCWJyZWFrOwogICAgICB9CiAgICB9IGVsc2UKICAgICAgYWRkci5zaW5fYWRkciA9IHNvLT5zb19mYWRkcjsKICAgIGFkZHIuc2luX3BvcnQgPSBzby0+c29fZnBvcnQ7CiAgICAKICAgIERFQlVHX01JU0MoKGRmZCwgIiBjb25uZWN0KClpbmcsIGFkZHIuc2luX3BvcnQ9JWQsICIKCQkiYWRkci5zaW5fYWRkci5zX2FkZHI9JS4xNnNcbiIsIAoJCW50b2hzKGFkZHIuc2luX3BvcnQpLCBpbmV0X250b2EoYWRkci5zaW5fYWRkcikpKTsKICAgIC8qIFdlIGRvbid0IGNhcmUgd2hhdCBwb3J0IHdlIGdldCAqLwogICAgcmV0ID0gY29ubmVjdChzLChzdHJ1Y3Qgc29ja2FkZHIgKikmYWRkcixzaXplb2YgKGFkZHIpKTsKICAgIAogICAgLyoKICAgICAqIElmIGl0J3Mgbm90IGluIHByb2dyZXNzLCBpdCBmYWlsZWQsIHNvIHdlIGp1c3QgcmV0dXJuIDAsCiAgICAgKiB3aXRob3V0IGNsZWFyaW5nIFNTX05PRkRSRUYKICAgICAqLwogICAgc29pc2Zjb25uZWN0aW5nKHNvKTsKICB9CgogIHJldHVybihyZXQpOwp9CgovKgogKiBBY2NlcHQgdGhlIHNvY2tldCBhbmQgY29ubmVjdCB0byB0aGUgbG9jYWwtaG9zdAogKiAKICogV2UgaGF2ZSBhIHByb2JsZW0uIFRoZSBjb3JyZWN0IHRoaW5nIHRvIGRvIHdvdWxkIGJlCiAqIHRvIGZpcnN0IGNvbm5lY3QgdG8gdGhlIGxvY2FsLWhvc3QsIGFuZCBvbmx5IGlmIHRoZQogKiBjb25uZWN0aW9uIGlzIGFjY2VwdGVkLCB0aGVuIGRvIGFuIGFjY2VwdCgpIGhlcmUuCiAqIEJ1dCwgYSkgd2UgbmVlZCB0byBrbm93IHdobydzIHRyeWluZyB0byBjb25uZWN0IAogKiB0byB0aGUgc29ja2V0IHRvIGJlIGFibGUgdG8gU1lOIHRoZSBsb2NhbC1ob3N0LCBhbmQKICogYikgd2UgYXJlIGFscmVhZHkgY29ubmVjdGVkIHRvIHRoZSBmb3JlaWduIGhvc3QgYnkKICogdGhlIHRpbWUgaXQgZ2V0cyB0byBhY2NlcHQoKSwgc28uLi4gV2Ugc2ltcGx5IGFjY2VwdAogKiBoZXJlIGFuZCBTWU4gdGhlIGxvY2FsLWhvc3QuCiAqLyAKdm9pZAp0Y3BfY29ubmVjdChpbnNvKQoJc3RydWN0IHNvY2tldCAqaW5zbzsKewoJc3RydWN0IHNvY2tldCAqc287CglzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRkcjsKCWludCBhZGRybGVuID0gc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcl9pbik7CglzdHJ1Y3QgdGNwY2IgKnRwOwoJaW50IHMsIG9wdDsKCglERUJVR19DQUxMKCJ0Y3BfY29ubmVjdCIpOwoJREVCVUdfQVJHKCJpbnNvID0gJWx4IiwgKGxvbmcpaW5zbyk7CgkKCS8qCgkgKiBJZiBpdCdzIGFuIFNTX0FDQ0VQVE9OQ0Ugc29ja2V0LCBubyBuZWVkIHRvIHNvY3JlYXRlKCkKCSAqIGFub3RoZXIgc29ja2V0LCBqdXN0IHVzZSB0aGUgYWNjZXB0KCkgc29ja2V0LgoJICovCglpZiAoaW5zby0+c29fc3RhdGUgJiBTU19GQUNDRVBUT05DRSkgewoJCS8qIEZBQ0NFUFRPTkNFIGFscmVhZHkgaGF2ZSBhIHRjcGNiICovCgkJc28gPSBpbnNvOwoJfSBlbHNlIHsKCQlpZiAoKHNvID0gc29jcmVhdGUoKSkgPT0gTlVMTCkgewoJCQkvKiBJZiBpdCBmYWlsZWQsIGdldCByaWQgb2YgdGhlIHBlbmRpbmcgY29ubmVjdGlvbiAqLwoJCQljbG9zZShhY2NlcHQoaW5zby0+cywoc3RydWN0IHNvY2thZGRyICopJmFkZHIsJmFkZHJsZW4pKTsKCQkJcmV0dXJuOwoJCX0KCQlpZiAodGNwX2F0dGFjaChzbykgPCAwKSB7CgkJCWZyZWUoc28pOyAvKiBOT1Qgc29mcmVlICovCgkJCXJldHVybjsKCQl9CgkJc28tPnNvX2xhZGRyID0gaW5zby0+c29fbGFkZHI7CgkJc28tPnNvX2xwb3J0ID0gaW5zby0+c29fbHBvcnQ7Cgl9CgkKCSh2b2lkKSB0Y3BfbXNzKHNvdG90Y3BjYihzbyksIDApOwoKCWlmICgocyA9IGFjY2VwdChpbnNvLT5zLChzdHJ1Y3Qgc29ja2FkZHIgKikmYWRkciwmYWRkcmxlbikpIDwgMCkgewoJCXRjcF9jbG9zZShzb3RvdGNwY2Ioc28pKTsgLyogVGhpcyB3aWxsIHNvZnJlZSgpIGFzIHdlbGwgKi8KCQlyZXR1cm47Cgl9CglmZF9ub25ibG9jayhzKTsKCW9wdCA9IDE7CglzZXRzb2Nrb3B0KHMsU09MX1NPQ0tFVCxTT19SRVVTRUFERFIsKGNoYXIgKikmb3B0LHNpemVvZihpbnQpKTsKCW9wdCA9IDE7CglzZXRzb2Nrb3B0KHMsU09MX1NPQ0tFVCxTT19PT0JJTkxJTkUsKGNoYXIgKikmb3B0LHNpemVvZihpbnQpKTsKCQoJc28tPnNvX2Zwb3J0ID0gYWRkci5zaW5fcG9ydDsKCXNvLT5zb19mYWRkciA9IGFkZHIuc2luX2FkZHI7CgkvKiBUcmFuc2xhdGUgY29ubmVjdGlvbnMgZnJvbSBsb2NhbGhvc3QgdG8gdGhlIHJlYWwgaG9zdG5hbWUgKi8KCWlmIChzby0+c29fZmFkZHIuc19hZGRyID09IDAgfHwgc28tPnNvX2ZhZGRyLnNfYWRkciA9PSBsb29wYmFja19hZGRyLnNfYWRkcikKCSAgIHNvLT5zb19mYWRkciA9IG91cl9hZGRyOwoJCgkvKiBDbG9zZSB0aGUgYWNjZXB0KCkgc29ja2V0LCBzZXQgcmlnaHQgc3RhdGUgKi8KCWlmIChpbnNvLT5zb19zdGF0ZSAmIFNTX0ZBQ0NFUFRPTkNFKSB7CgkJY2xvc2Uoc28tPnMpOyAvKiBJZiB3ZSBvbmx5IGFjY2VwdCBvbmNlLCBjbG9zZSB0aGUgYWNjZXB0KCkgc29ja2V0ICovCgkJc28tPnNvX3N0YXRlID0gU1NfTk9GRFJFRjsgLyogRG9uJ3Qgc2VsZWN0IGl0IHlldCwgZXZlbiB0aG91Z2ggd2UgaGF2ZSBhbiBGRCAqLwoJCQkJCSAgIC8qIGlmIGl0J3Mgbm90IEZBQ0NFUFRPTkNFLCBpdCdzIGFscmVhZHkgTk9GRFJFRiAqLwoJfQoJc28tPnMgPSBzOwoJCglzby0+c29faXB0b3MgPSB0Y3BfdG9zKHNvKTsKCXRwID0gc290b3RjcGNiKHNvKTsKCgl0Y3BfdGVtcGxhdGUodHApOwoJCgkvKiBDb21wdXRlIHdpbmRvdyBzY2FsaW5nIHRvIHJlcXVlc3QuICAqLwovKgl3aGlsZSAodHAtPnJlcXVlc3Rfcl9zY2FsZSA8IFRDUF9NQVhfV0lOU0hJRlQgJiYKICoJCShUQ1BfTUFYV0lOIDw8IHRwLT5yZXF1ZXN0X3Jfc2NhbGUpIDwgc28tPnNvX3Jjdi5zYl9oaXdhdCkKICoJCXRwLT5yZXF1ZXN0X3Jfc2NhbGUrKzsKICovCgovKglzb2lzY29ubmVjdGluZyhzbyk7ICovIC8qIE5PRkRSRUYgdXNlZCBpbnN0ZWFkICovCgl0Y3BzdGF0LnRjcHNfY29ubmF0dGVtcHQrKzsKCQoJdHAtPnRfc3RhdGUgPSBUQ1BTX1NZTl9TRU5UOwoJdHAtPnRfdGltZXJbVENQVF9LRUVQXSA9IFRDUFRWX0tFRVBfSU5JVDsKCXRwLT5pc3MgPSB0Y3BfaXNzOyAKCXRjcF9pc3MgKz0gVENQX0lTU0lOQ1IvMjsKCXRjcF9zZW5kc2VxaW5pdCh0cCk7Cgl0Y3Bfb3V0cHV0KHRwKTsKfQoKLyoKICogQXR0YWNoIGEgVENQQ0IgdG8gYSBzb2NrZXQuCiAqLwppbnQKdGNwX2F0dGFjaChzbykKCXN0cnVjdCBzb2NrZXQgKnNvOwp7CglpZiAoKHNvLT5zb190Y3BjYiA9IHRjcF9uZXd0Y3BjYihzbykpID09IE5VTEwpCgkgICByZXR1cm4gLTE7CgkKCWluc3F1ZShzbywgJnRjYik7CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIFNldCB0aGUgc29ja2V0J3MgdHlwZSBvZiBzZXJ2aWNlIGZpZWxkCiAqLwpzdHJ1Y3QgdG9zX3QgdGNwdG9zW10gPSB7CgkgIHswLCAyMCwgSVBUT1NfVEhST1VHSFBVVCwgMH0sCS8qIGZ0cCBkYXRhICovCgkgIHsyMSwgMjEsIElQVE9TX0xPV0RFTEFZLCAgRU1VX0ZUUH0sCS8qIGZ0cCBjb250cm9sICovCgkgIHswLCAyMywgSVBUT1NfTE9XREVMQVksIDB9LAkvKiB0ZWxuZXQgKi8KCSAgezAsIDgwLCBJUFRPU19USFJPVUdIUFVULCAwfSwJLyogV1dXICovCgkgIHswLCA1MTMsIElQVE9TX0xPV0RFTEFZLCBFTVVfUkxPR0lOfEVNVV9OT0NPTk5FQ1R9LAkvKiBybG9naW4gKi8KCSAgezAsIDUxNCwgSVBUT1NfTE9XREVMQVksIEVNVV9SU0h8RU1VX05PQ09OTkVDVH0sCS8qIHNoZWxsICovCgkgIHswLCA1NDQsIElQVE9TX0xPV0RFTEFZLCBFTVVfS1NIfSwJCS8qIGtzaGVsbCAqLwoJICB7MCwgNTQzLCBJUFRPU19MT1dERUxBWSwgMH0sCS8qIGtsb2dpbiAqLwoJICB7MCwgNjY2NywgSVBUT1NfVEhST1VHSFBVVCwgRU1VX0lSQ30sCS8qIElSQyAqLwoJICB7MCwgNjY2OCwgSVBUT1NfVEhST1VHSFBVVCwgRU1VX0lSQ30sCS8qIElSQyB1bmRlcm5ldCAqLwoJICB7MCwgNzA3MCwgSVBUT1NfTE9XREVMQVksIEVNVV9SRUFMQVVESU8gfSwgLyogUmVhbEF1ZGlvIGNvbnRyb2wgKi8KCSAgezAsIDExMywgSVBUT1NfTE9XREVMQVksIEVNVV9JREVOVCB9LCAvKiBpZGVudGQgcHJvdG9jb2wgKi8KCSAgezAsIDAsIDAsIDB9Cn07CgpzdHJ1Y3QgZW11X3QgKnRjcGVtdSA9IDA7CgkJCi8qCiAqIFJldHVybiBUT1MgYWNjb3JkaW5nIHRvIHRoZSBhYm92ZSB0YWJsZQogKi8KdV9pbnQ4X3QKdGNwX3RvcyhzbykKCXN0cnVjdCBzb2NrZXQgKnNvOwp7CglpbnQgaSA9IDA7CglzdHJ1Y3QgZW11X3QgKmVtdXA7CgkKCXdoaWxlKHRjcHRvc1tpXS50b3MpIHsKCQlpZiAoKHRjcHRvc1tpXS5mcG9ydCAmJiAobnRvaHMoc28tPnNvX2Zwb3J0KSA9PSB0Y3B0b3NbaV0uZnBvcnQpKSB8fAoJCSAgICAodGNwdG9zW2ldLmxwb3J0ICYmIChudG9ocyhzby0+c29fbHBvcnQpID09IHRjcHRvc1tpXS5scG9ydCkpKSB7CgkJCXNvLT5zb19lbXUgPSB0Y3B0b3NbaV0uZW11OwoJCQlyZXR1cm4gdGNwdG9zW2ldLnRvczsKCQl9CgkJaSsrOwoJfQoJCgkvKiBOb3BlLCBsZXRzIHNlZSBpZiB0aGVyZSdzIGEgdXNlci1hZGRlZCBvbmUgKi8KCWZvciAoZW11cCA9IHRjcGVtdTsgZW11cDsgZW11cCA9IGVtdXAtPm5leHQpIHsKCQlpZiAoKGVtdXAtPmZwb3J0ICYmIChudG9ocyhzby0+c29fZnBvcnQpID09IGVtdXAtPmZwb3J0KSkgfHwKCQkgICAgKGVtdXAtPmxwb3J0ICYmIChudG9ocyhzby0+c29fbHBvcnQpID09IGVtdXAtPmxwb3J0KSkpIHsKCQkJc28tPnNvX2VtdSA9IGVtdXAtPmVtdTsKCQkJcmV0dXJuIGVtdXAtPnRvczsKCQl9Cgl9CgkKCXJldHVybiAwOwp9CgppbnQgZG9fZWNobyA9IC0xOwoKLyoKICogRW11bGF0ZSBwcm9ncmFtcyB0aGF0IHRyeSBhbmQgY29ubmVjdCB0byB1cwogKiBUaGlzIGluY2x1ZGVzIGZ0cCAodGhlIGRhdGEgY29ubmVjdGlvbiBpcwogKiBpbml0aWF0ZWQgYnkgdGhlIHNlcnZlcikgYW5kIElSQyAoRENDIENIQVQgYW5kCiAqIERDQyBTRU5EKSBmb3Igbm93CiAqIAogKiBOT1RFOiBJdCdzIHBvc3NpYmxlIHRvIGNyYXNoIFNMaVJQIGJ5IHNlbmRpbmcgaXQKICogdW5zdGFuZGFyZCBzdHJpbmdzIHRvIGVtdWxhdGUuLi4gaWYgdGhpcyBpcyBhIHByb2JsZW0sCiAqIG1vcmUgY2hlY2tzIGFyZSBuZWVkZWQgaGVyZQogKgogKiBYWFggQXNzdW1lcyB0aGUgd2hvbGUgY29tbWFuZCBjYW1lIGluIG9uZSBwYWNrZXQKICoJCQkJCSAgICAKICogWFhYIFNvbWUgZnRwIGNsaWVudHMgd2lsbCBoYXZlIHRoZWlyIFRPUyBzZXQgdG8KICogTE9XREVMQVkgYW5kIHNvIE5hZ2VsIHdpbGwga2ljayBpbi4gIEJlY2F1c2Ugb2YgdGhpcywKICogd2UnbGwgZ2V0IHRoZSBmaXJzdCBsZXR0ZXIsIGZvbGxvd2VkIGJ5IHRoZSByZXN0LCBzbwogKiB3ZSBzaW1wbHkgc2NhbiBmb3IgT1JUIGluc3RlYWQgb2YgUE9SVC4uLgogKiBEQ0MgZG9lc24ndCBoYXZlIHRoaXMgcHJvYmxlbSBiZWNhdXNlIHRoZXJlJ3Mgb3RoZXIgc3R1ZmYKICogaW4gdGhlIHBhY2tldCBiZWZvcmUgdGhlIERDQyBjb21tYW5kLgogKiAKICogUmV0dXJuIDEgaWYgdGhlIG1idWYgbSBpcyBzdGlsbCB2YWxpZCBhbmQgc2hvdWxkIGJlIAogKiBzYmFwcGVuZCgpZWQKICogCiAqIE5PVEU6IGlmIHlvdSByZXR1cm4gMCB5b3UgTVVTVCBtX2ZyZWUoKSB0aGUgbWJ1ZiEKICovCmludAp0Y3BfZW11KHNvLCBtKQoJc3RydWN0IHNvY2tldCAqc287CglzdHJ1Y3QgbWJ1ZiAqbTsKewoJdV9pbnQgbjEsIG4yLCBuMywgbjQsIG41LCBuNjsKCWNoYXIgYnVmZlsyNTZdOwoJdV9pbnQzMl90IGxhZGRyOwoJdV9pbnQgbHBvcnQ7CgljaGFyICpicHRyOwoJCglERUJVR19DQUxMKCJ0Y3BfZW11Iik7CglERUJVR19BUkcoInNvID0gJWx4IiwgKGxvbmcpc28pOwoJREVCVUdfQVJHKCJtID0gJWx4IiwgKGxvbmcpbSk7CgkKCXN3aXRjaChzby0+c29fZW11KSB7CgkJaW50IHgsIGk7CgkJCgkgY2FzZSBFTVVfSURFTlQ6CgkJLyoKCQkgKiBJZGVudGlmaWNhdGlvbiBwcm90b2NvbCBhcyBwZXIgcmZjLTE0MTMKCQkgKi8KCQkKCQl7CgkJCXN0cnVjdCBzb2NrZXQgKnRtcHNvOwoJCQlzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRkcjsKCQkJaW50IGFkZHJsZW4gPSBzaXplb2Yoc3RydWN0IHNvY2thZGRyX2luKTsKCQkJc3RydWN0IHNidWYgKnNvX3JjdiA9ICZzby0+c29fcmN2OwoJCQkKCQkJbWVtY3B5KHNvX3Jjdi0+c2Jfd3B0ciwgbS0+bV9kYXRhLCBtLT5tX2xlbik7CgkJCXNvX3Jjdi0+c2Jfd3B0ciArPSBtLT5tX2xlbjsKCQkJc29fcmN2LT5zYl9ycHRyICs9IG0tPm1fbGVuOwoJCQltLT5tX2RhdGFbbS0+bV9sZW5dID0gMDsgLyogTlVMTCB0ZXJtaW5hdGUgKi8KCQkJaWYgKHN0cmNocihtLT5tX2RhdGEsICdccicpIHx8IHN0cmNocihtLT5tX2RhdGEsICdcbicpKSB7CgkJCQlpZiAoc3NjYW5mKHNvX3Jjdi0+c2JfZGF0YSwgIiVkJSpbICxdJWQiLCAmbjEsICZuMikgPT0gMikgewoJCQkJCUhUT05TKG4xKTsKCQkJCQlIVE9OUyhuMik7CgkJCQkJLyogbjIgaXMgdGhlIG9uZSBvbiBvdXIgaG9zdCAqLwoJCQkJCWZvciAodG1wc28gPSB0Y2Iuc29fbmV4dDsgdG1wc28gIT0gJnRjYjsgdG1wc28gPSB0bXBzby0+c29fbmV4dCkgewoJCQkJCQlpZiAodG1wc28tPnNvX2xhZGRyLnNfYWRkciA9PSBzby0+c29fbGFkZHIuc19hZGRyICYmCgkJCQkJCSAgICB0bXBzby0+c29fbHBvcnQgPT0gbjIgJiYKCQkJCQkJICAgIHRtcHNvLT5zb19mYWRkci5zX2FkZHIgPT0gc28tPnNvX2ZhZGRyLnNfYWRkciAmJgoJCQkJCQkgICAgdG1wc28tPnNvX2Zwb3J0ID09IG4xKSB7CgkJCQkJCQlpZiAoZ2V0c29ja25hbWUodG1wc28tPnMsCgkJCQkJCQkJKHN0cnVjdCBzb2NrYWRkciAqKSZhZGRyLCAmYWRkcmxlbikgPT0gMCkKCQkJCQkJCSAgIG4yID0gbnRvaHMoYWRkci5zaW5fcG9ydCk7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCXNvX3Jjdi0+c2JfY2MgPSBzcHJpbnRmKHNvX3Jjdi0+c2JfZGF0YSwgIiVkLCVkXHJcbiIsIG4xLCBuMik7CgkJCQlzb19yY3YtPnNiX3JwdHIgPSBzb19yY3YtPnNiX2RhdGE7CgkJCQlzb19yY3YtPnNiX3dwdHIgPSBzb19yY3YtPnNiX2RhdGEgKyBzb19yY3YtPnNiX2NjOwoJCQl9CgkJCW1fZnJlZShtKTsKCQkJcmV0dXJuIDA7CgkJfQoJCQojaWYgMAoJIGNhc2UgRU1VX1JMT0dJTjoKCQkvKgoJCSAqIFJsb2dpbiBlbXVsYXRpb24KCQkgKiBGaXJzdCB3ZSBhY2N1bXVsYXRlIGFsbCB0aGUgaW5pdGlhbCBvcHRpb24gbmVnb3RpYXRpb24sCgkJICogdGhlbiBmb3JrX2V4ZWMoKSBybG9naW4gYWNjb3JkaW5nIHRvIHRoZSAgb3B0aW9ucwoJCSAqLwoJCXsKCQkJaW50IGksIGkyLCBuOwoJCQljaGFyICpwdHI7CgkJCWNoYXIgYXJnc1sxMDBdOwoJCQljaGFyIHRlcm1bMTAwXTsKCQkJc3RydWN0IHNidWYgKnNvX3NuZCA9ICZzby0+c29fc25kOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fcmN2ID0gJnNvLT5zb19yY3Y7CgkJCQoJCQkvKiBGaXJzdCBjaGVjayBpZiB0aGV5IGhhdmUgYSBwcml2ZWxhZGdlZCBwb3J0LCBvciB0b28gbXVjaCBkYXRhIGhhcyBhcnJpdmVkICovCgkJCWlmIChudG9ocyhzby0+c29fbHBvcnQpID4gMTAyMyB8fCBudG9ocyhzby0+c29fbHBvcnQpIDwgNTEyIHx8CgkJCSAgICAobS0+bV9sZW4gKyBzb19yY3YtPnNiX3dwdHIpID4gKHNvX3Jjdi0+c2JfZGF0YSArIHNvX3Jjdi0+c2JfZGF0YWxlbikpIHsKCQkJCW1lbWNweShzb19zbmQtPnNiX3dwdHIsICJQZXJtaXNzaW9uIGRlbmllZFxuIiwgMTgpOwoJCQkJc29fc25kLT5zYl93cHRyICs9IDE4OwoJCQkJc29fc25kLT5zYl9jYyArPSAxODsKCQkJCXRjcF9zb2NrY2xvc2VkKHNvdG90Y3BjYihzbykpOwoJCQkJbV9mcmVlKG0pOwoJCQkJcmV0dXJuIDA7CgkJCX0KCQkJCgkJCS8qIEFwcGVuZCB0aGUgY3VycmVudCBkYXRhICovCgkJCW1lbWNweShzb19yY3YtPnNiX3dwdHIsIG0tPm1fZGF0YSwgbS0+bV9sZW4pOwoJCQlzb19yY3YtPnNiX3dwdHIgKz0gbS0+bV9sZW47CgkJCXNvX3Jjdi0+c2JfcnB0ciArPSBtLT5tX2xlbjsKCQkJbV9mcmVlKG0pOwoJCQkKCQkJLyoKCQkJICogQ2hlY2sgaWYgd2UgaGF2ZSBhbGwgdGhlIGluaXRpYWwgb3B0aW9ucywKCQkJICogYW5kIGJ1aWxkIGFyZ3VtZW50IGxpc3QgdG8gcmxvZ2luIHdoaWxlIHdlJ3JlIGhlcmUKCQkJICovCgkJCW4gPSAwOwoJCQlwdHIgPSBzb19yY3YtPnNiX2RhdGE7CgkJCWFyZ3NbMF0gPSAwOwoJCQl0ZXJtWzBdID0gMDsKCQkJd2hpbGUgKHB0ciA8IHNvX3Jjdi0+c2Jfd3B0cikgewoJCQkJaWYgKCpwdHIrKyA9PSAwKSB7CgkJCQkJbisrOwoJCQkJCWlmIChuID09IDIpIHsKCQkJCQkJc3ByaW50ZihhcmdzLCAicmxvZ2luIC1sICVzICVzIiwKCQkJCQkJCXB0ciwgaW5ldF9udG9hKHNvLT5zb19mYWRkcikpOwoJCQkJCX0gZWxzZSBpZiAobiA9PSAzKSB7CgkJCQkJCWkyID0gc29fcmN2LT5zYl93cHRyIC0gcHRyOwoJCQkJCQlmb3IgKGkgPSAwOyBpIDwgaTI7IGkrKykgewoJCQkJCQkJaWYgKHB0cltpXSA9PSAnLycpIHsKCQkJCQkJCQlwdHJbaV0gPSAwOwojaWZkZWYgSEFWRV9TRVRFTlYKCQkJCQkJCQlzcHJpbnRmKHRlcm0sICIlcyIsIHB0cik7CiNlbHNlCgkJCQkJCQkJc3ByaW50Zih0ZXJtLCAiVEVSTT0lcyIsIHB0cik7CiNlbmRpZgoJCQkJCQkJCXB0cltpXSA9ICcvJzsKCQkJCQkJCQlicmVhazsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCQkKCQkJaWYgKG4gIT0gNCkKCQkJICAgcmV0dXJuIDA7CgkJCQoJCQkvKiBXZSBoYXZlIGl0LCBzZXQgb3VyIHRlcm0gdmFyaWFibGUgYW5kIGZvcmtfZXhlYygpICovCiNpZmRlZiBIQVZFX1NFVEVOVgoJCQlzZXRlbnYoIlRFUk0iLCB0ZXJtLCAxKTsKI2Vsc2UKCQkJcHV0ZW52KHRlcm0pOwojZW5kaWYKCQkJZm9ya19leGVjKHNvLCBhcmdzLCAyKTsKCQkJdGVybVswXSA9IDA7CgkJCXNvLT5zb19lbXUgPSAwOwoJCQkKCQkJLyogQW5kIGZpbmFsbHksIHNlbmQgdGhlIGNsaWVudCBhIDAgY2hhcmFjdGVyICovCgkJCXNvX3NuZC0+c2Jfd3B0clswXSA9IDA7CgkJCXNvX3NuZC0+c2Jfd3B0cisrOwoJCQlzb19zbmQtPnNiX2NjKys7CgkJCQoJCQlyZXR1cm4gMDsKCQl9CgkJCgkgY2FzZSBFTVVfUlNIOgoJCS8qCgkJICogcnNoIGVtdWxhdGlvbgoJCSAqIEZpcnN0IHdlIGFjY3VtdWxhdGUgYWxsIHRoZSBpbml0aWFsIG9wdGlvbiBuZWdvdGlhdGlvbiwKCQkgKiB0aGVuIHJzaF9leGVjKCkgcnNoIGFjY29yZGluZyB0byB0aGUgIG9wdGlvbnMKCQkgKi8KCQl7CgkJCWludCAgbjsKCQkJY2hhciAqcHRyOwoJCQljaGFyICp1c2VyOwoJCQljaGFyICphcmdzOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fc25kID0gJnNvLT5zb19zbmQ7CgkJCXN0cnVjdCBzYnVmICpzb19yY3YgPSAmc28tPnNvX3JjdjsKCQkJCgkJCS8qIEZpcnN0IGNoZWNrIGlmIHRoZXkgaGF2ZSBhIHByaXZlbGFkZ2VkIHBvcnQsIG9yIHRvbyBtdWNoIGRhdGEgaGFzIGFycml2ZWQgKi8KCQkJaWYgKG50b2hzKHNvLT5zb19scG9ydCkgPiAxMDIzIHx8IG50b2hzKHNvLT5zb19scG9ydCkgPCA1MTIgfHwKCQkJICAgIChtLT5tX2xlbiArIHNvX3Jjdi0+c2Jfd3B0cikgPiAoc29fcmN2LT5zYl9kYXRhICsgc29fcmN2LT5zYl9kYXRhbGVuKSkgewoJCQkJbWVtY3B5KHNvX3NuZC0+c2Jfd3B0ciwgIlBlcm1pc3Npb24gZGVuaWVkXG4iLCAxOCk7CgkJCQlzb19zbmQtPnNiX3dwdHIgKz0gMTg7CgkJCQlzb19zbmQtPnNiX2NjICs9IDE4OwoJCQkJdGNwX3NvY2tjbG9zZWQoc290b3RjcGNiKHNvKSk7CgkJCQltX2ZyZWUobSk7CgkJCQlyZXR1cm4gMDsKCQkJfQoJCQkKCQkJLyogQXBwZW5kIHRoZSBjdXJyZW50IGRhdGEgKi8KCQkJbWVtY3B5KHNvX3Jjdi0+c2Jfd3B0ciwgbS0+bV9kYXRhLCBtLT5tX2xlbik7CgkJCXNvX3Jjdi0+c2Jfd3B0ciArPSBtLT5tX2xlbjsKCQkJc29fcmN2LT5zYl9ycHRyICs9IG0tPm1fbGVuOwoJCQltX2ZyZWUobSk7CgkJCQoJCQkvKgoJCQkgKiBDaGVjayBpZiB3ZSBoYXZlIGFsbCB0aGUgaW5pdGlhbCBvcHRpb25zLAoJCQkgKiBhbmQgYnVpbGQgYXJndW1lbnQgbGlzdCB0byBybG9naW4gd2hpbGUgd2UncmUgaGVyZQoJCQkgKi8KCQkJbiA9IDA7CgkJCXB0ciA9IHNvX3Jjdi0+c2JfZGF0YTsKCQkJdXNlcj0iIjsKCQkJYXJncz0iIjsKCQkJaWYgKHNvLT5leHRyYT09TlVMTCkgewoJCQkJc3RydWN0IHNvY2tldCAqbnM7CgkJCQlzdHJ1Y3QgdGNwY2IqIHRwOwoJCQkJaW50IHBvcnQ9YXRvaShwdHIpOwoJCQkJaWYgKHBvcnQgPD0gMCkgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICBpZiAocG9ydCA+IDEwMjMgfHwgcG9ydCA8IDUxMikgewogICAgICAgICAgICAgICAgICBtZW1jcHkoc29fc25kLT5zYl93cHRyLCAiUGVybWlzc2lvbiBkZW5pZWRcbiIsIDE4KTsKICAgICAgICAgICAgICAgICAgc29fc25kLT5zYl93cHRyICs9IDE4OwogICAgICAgICAgICAgICAgICBzb19zbmQtPnNiX2NjICs9IDE4OwogICAgICAgICAgICAgICAgICB0Y3Bfc29ja2Nsb3NlZChzb3RvdGNwY2Ioc28pKTsKICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9CgkJCQlpZiAoKG5zPXNvY3JlYXRlKCkpID09IE5VTEwpCiAgICAgICAgICAgICAgICAgIHJldHVybiAwOwoJCQkJaWYgKHRjcF9hdHRhY2gobnMpPDApIHsKICAgICAgICAgICAgICAgICAgZnJlZShucyk7CiAgICAgICAgICAgICAgICAgIHJldHVybiAwOwoJCQkJfQoKCQkJCW5zLT5zb19sYWRkcj1zby0+c29fbGFkZHI7CgkJCQlucy0+c29fbHBvcnQ9aHRvbnMocG9ydCk7CgoJCQkJKHZvaWQpIHRjcF9tc3Moc290b3RjcGNiKG5zKSwgMCk7CgoJCQkJbnMtPnNvX2ZhZGRyPXNvLT5zb19mYWRkcjsKCQkJCW5zLT5zb19mcG9ydD1odG9ucyhJUFBPUlRfUkVTRVJWRUQtMSk7IC8qIFVzZSBhIGZha2UgcG9ydC4gKi8KCgkJCQlpZiAobnMtPnNvX2ZhZGRyLnNfYWRkciA9PSAwIHx8IAoJCQkJCW5zLT5zb19mYWRkci5zX2FkZHIgPT0gbG9vcGJhY2tfYWRkci5zX2FkZHIpCiAgICAgICAgICAgICAgICAgIG5zLT5zb19mYWRkciA9IG91cl9hZGRyOwoKCQkJCW5zLT5zb19pcHRvcyA9IHRjcF90b3MobnMpOwoJCQkJdHAgPSBzb3RvdGNwY2IobnMpOwogICAgICAgICAgICAgICAgCgkJCQl0Y3BfdGVtcGxhdGUodHApOwogICAgICAgICAgICAgICAgCgkJCQkvKiBDb21wdXRlIHdpbmRvdyBzY2FsaW5nIHRvIHJlcXVlc3QuICAqLwoJCQkJLyoJd2hpbGUgKHRwLT5yZXF1ZXN0X3Jfc2NhbGUgPCBUQ1BfTUFYX1dJTlNISUZUICYmCgkJCQkgKgkJKFRDUF9NQVhXSU4gPDwgdHAtPnJlcXVlc3Rfcl9zY2FsZSkgPCBzby0+c29fcmN2LnNiX2hpd2F0KQoJCQkJICoJCXRwLT5yZXF1ZXN0X3Jfc2NhbGUrKzsKCQkJCSAqLwoKICAgICAgICAgICAgICAgIC8qc29pc2Zjb25uZWN0aW5nKG5zKTsqLwoKCQkJCXRjcHN0YXQudGNwc19jb25uYXR0ZW1wdCsrOwoJCQkJCQoJCQkJdHAtPnRfc3RhdGUgPSBUQ1BTX1NZTl9TRU5UOwoJCQkJdHAtPnRfdGltZXJbVENQVF9LRUVQXSA9IFRDUFRWX0tFRVBfSU5JVDsKCQkJCXRwLT5pc3MgPSB0Y3BfaXNzOyAKCQkJCXRjcF9pc3MgKz0gVENQX0lTU0lOQ1IvMjsKCQkJCXRjcF9zZW5kc2VxaW5pdCh0cCk7CgkJCQl0Y3Bfb3V0cHV0KHRwKTsKCQkJCXNvLT5leHRyYT1uczsKCQkJfQoJCQl3aGlsZSAocHRyIDwgc29fcmN2LT5zYl93cHRyKSB7CiAgICAgICAgICAgICAgaWYgKCpwdHIrKyA9PSAwKSB7CiAgICAgICAgICAgICAgICBuKys7CiAgICAgICAgICAgICAgICBpZiAobiA9PSAyKSB7CiAgICAgICAgICAgICAgICAgIHVzZXI9cHRyOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuID09IDMpIHsKICAgICAgICAgICAgICAgICAgYXJncz1wdHI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQoJCQl9CgkJCQoJCQlpZiAobiAhPSA0KQogICAgICAgICAgICAgIHJldHVybiAwOwoJCQkKCQkJcnNoX2V4ZWMoc28sc28tPmV4dHJhLCB1c2VyLCBpbmV0X250b2Eoc28tPnNvX2ZhZGRyKSwgYXJncyk7CgkJCXNvLT5zb19lbXUgPSAwOwoJCQlzby0+ZXh0cmE9TlVMTDsKCQkJCgkJCS8qIEFuZCBmaW5hbGx5LCBzZW5kIHRoZSBjbGllbnQgYSAwIGNoYXJhY3RlciAqLwoJCQlzb19zbmQtPnNiX3dwdHJbMF0gPSAwOwoJCQlzb19zbmQtPnNiX3dwdHIrKzsKCQkJc29fc25kLT5zYl9jYysrOwoJCQkKCQkJcmV0dXJuIDA7CgkJfQoKCSBjYXNlIEVNVV9DVEw6CgkJewoJCQlpbnQgbnVtOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fc25kID0gJnNvLT5zb19zbmQ7CgkJCXN0cnVjdCBzYnVmICpzb19yY3YgPSAmc28tPnNvX3JjdjsKCQkJCgkJCS8qCgkJCSAqIElmIHRoZXJlIGlzIGJpbmFyeSBkYXRhIGhlcmUsIHdlIHNhdmUgaXQgaW4gc28tPnNvX20KCQkJICovCgkJCWlmICghc28tPnNvX20pIHsKCQkJICBpbnQgcnhsZW47CgkJCSAgY2hhciAqcnhkYXRhOwoJCQkgIHJ4ZGF0YT1tdG9kKG0sIGNoYXIgKik7CgkJCSAgZm9yIChyeGxlbj1tLT5tX2xlbjsgcnhsZW47IHJ4bGVuLS0pIHsKCQkJICAgIGlmICgqcnhkYXRhKysgJiAweDgwKSB7CgkJCSAgICAgIHNvLT5zb19tID0gbTsKCQkJICAgICAgcmV0dXJuIDA7CgkJCSAgICB9CgkJCSAgfQoJCQl9IC8qIGlmKHNvLT5zb19tPT1OVUxMKSAqLwoJCQkKCQkJLyoKCQkJICogQXBwZW5kIHRoZSBsaW5lCgkJCSAqLwoJCQlzYmFwcGVuZHNiKHNvX3JjdiwgbSk7CgkJCQoJCQkvKiBUbyBhdm9pZCBnb2luZyBvdmVyIHRoZSBlZGdlIG9mIHRoZSBidWZmZXIsIHdlIHJlc2V0IGl0ICovCgkJCWlmIChzb19zbmQtPnNiX2NjID09IDApCgkJCSAgIHNvX3NuZC0+c2Jfd3B0ciA9IHNvX3NuZC0+c2JfcnB0ciA9IHNvX3NuZC0+c2JfZGF0YTsKCQkJCgkJCS8qCgkJCSAqIEEgYml0IG9mIGEgaGFjazoKCQkJICogSWYgdGhlIGZpcnN0IHBhY2tldCB3ZSBnZXQgaGVyZSBpcyAxIGJ5dGUgbG9uZywgdGhlbiBpdAoJCQkgKiB3YXMgZG9uZSBpbiB0ZWxuZXQgY2hhcmFjdGVyIG1vZGUsIHRoZXJlZm9yZSB3ZSBtdXN0IGVjaG8KCQkJICogdGhlIGNoYXJhY3RlcnMgYXMgdGhleSBjb21lLiAgT3RoZXJ3aXNlLCB3ZSBlY2hvIG5vdGhpbmcsCgkJCSAqIGJlY2F1c2UgaW4gbGluZW1vZGUsIHRoZSBsaW5lIGlzIGFscmVhZHkgZWNob2VkCgkJCSAqIFhYWCB0d28gb3IgbW9yZSBjb250cm9sIGNvbm5lY3Rpb25zIHdvbid0IHdvcmsKCQkJICovCgkJCWlmIChkb19lY2hvID09IC0xKSB7CgkJCQlpZiAobS0+bV9sZW4gPT0gMSkgZG9fZWNobyA9IDE7CgkJCQllbHNlIGRvX2VjaG8gPSAwOwoJCQl9CgkJCWlmIChkb19lY2hvKSB7CgkJCSAgc2JhcHBlbmRzYihzb19zbmQsIG0pOwoJCQkgIG1fZnJlZShtKTsKCQkJICB0Y3Bfb3V0cHV0KHNvdG90Y3BjYihzbykpOyAvKiBYWFggKi8KCQkJfSBlbHNlCgkJCSAgbV9mcmVlKG0pOwoJCQkKCQkJbnVtID0gMDsKCQkJd2hpbGUgKG51bSA8IHNvLT5zb19yY3Yuc2JfY2MpIHsKCQkJCWlmICgqKHNvLT5zb19yY3Yuc2JfcnB0ciArIG51bSkgPT0gJ1xuJyB8fAoJCQkJICAgICooc28tPnNvX3Jjdi5zYl9ycHRyICsgbnVtKSA9PSAnXHInKSB7CgkJCQkJaW50IG47CgkJCQkJCgkJCQkJKihzb19yY3YtPnNiX3JwdHIgKyBudW0pID0gMDsKCQkJCQlpZiAoY3RsX3Bhc3N3b3JkICYmICFjdGxfcGFzc3dvcmRfb2spIHsKCQkJCQkJLyogTmVlZCBhIHBhc3N3b3JkICovCgkJCQkJCWlmIChzc2NhbmYoc29fcmN2LT5zYl9ycHRyLCAicGFzcyAlMjU2cyIsIGJ1ZmYpID09IDEpIHsKCQkJCQkJCWlmIChzdHJjbXAoYnVmZiwgY3RsX3Bhc3N3b3JkKSA9PSAwKSB7CgkJCQkJCQkJY3RsX3Bhc3N3b3JkX29rID0gMTsKCQkJCQkJCQluID0gc3ByaW50Zihzb19zbmQtPnNiX3dwdHIsCgkJCQkJCQkJCSAgICAiUGFzc3dvcmQgT0suXHJcbiIpOwoJCQkJCQkJCWdvdG8gZG9fcHJvbXB0OwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCW4gPSBzcHJpbnRmKHNvX3NuZC0+c2Jfd3B0ciwKCQkJCQkgIkVycm9yOiBQYXNzd29yZCByZXF1aXJlZCwgbG9nIG9uIHdpdGggXCJwYXNzIFBBU1NXT1JEXCJcclxuIik7CgkJCQkJCWdvdG8gZG9fcHJvbXB0OwoJCQkJCX0KCQkJCQljZmdfcXVpdHRpbmcgPSAwOwoJCQkJCW4gPSBkb19jb25maWcoc29fcmN2LT5zYl9ycHRyLCBzbywgUFJOX1NQUklOVEYpOwoJCQkJCWlmICghY2ZnX3F1aXR0aW5nKSB7CgkJCQkJCS8qIFJlZ2lzdGVyIHRoZSBwcmludGVkIGRhdGEgKi8KZG9fcHJvbXB0OgoJCQkJCQlzb19zbmQtPnNiX2NjICs9IG47CgkJCQkJCXNvX3NuZC0+c2Jfd3B0ciArPSBuOwoJCQkJCQkvKiBBZGQgcHJvbXB0ICovCgkJCQkJCW4gPSBzcHJpbnRmKHNvX3NuZC0+c2Jfd3B0ciwgIlNsaXJwPiAiKTsKCQkJCQkJc29fc25kLT5zYl9jYyArPSBuOwoJCQkJCQlzb19zbmQtPnNiX3dwdHIgKz0gbjsKCQkJCQl9CgkJCQkJLyogRHJvcCBzb19yY3YgZGF0YSAqLwoJCQkJCXNvX3Jjdi0+c2JfY2MgPSAwOwoJCQkJCXNvX3Jjdi0+c2Jfd3B0ciA9IHNvX3Jjdi0+c2JfcnB0ciA9IHNvX3Jjdi0+c2JfZGF0YTsKCQkJCQl0Y3Bfb3V0cHV0KHNvdG90Y3BjYihzbykpOyAvKiBTZW5kIHRoZSByZXBseSAqLwoJCQkJfQoJCQkJbnVtKys7CgkJCX0KCQkJcmV0dXJuIDA7CgkJfQojZW5kaWYJCQogICAgICAgIGNhc2UgRU1VX0ZUUDogLyogZnRwICovCgkJKihtLT5tX2RhdGErbS0+bV9sZW4pID0gMDsgLyogTlVMTCB0ZXJtaW5hdGUgZm9yIHN0cnN0ciAqLwoJCWlmICgoYnB0ciA9IChjaGFyICopc3Ryc3RyKG0tPm1fZGF0YSwgIk9SVCIpKSAhPSBOVUxMKSB7CgkJCS8qCgkJCSAqIE5lZWQgdG8gZW11bGF0ZSB0aGUgUE9SVCBjb21tYW5kCgkJCSAqLwkJCQoJCQl4ID0gc3NjYW5mKGJwdHIsICJPUlQgJWQsJWQsJWQsJWQsJWQsJWRcclxuJTI1NlteXDE3N10iLCAKCQkJCSAgICZuMSwgJm4yLCAmbjMsICZuNCwgJm41LCAmbjYsIGJ1ZmYpOwoJCQlpZiAoeCA8IDYpCgkJCSAgIHJldHVybiAxOwoJCQkKCQkJbGFkZHIgPSBodG9ubCgobjEgPDwgMjQpIHwgKG4yIDw8IDE2KSB8IChuMyA8PCA4KSB8IChuNCkpOwoJCQlscG9ydCA9IGh0b25zKChuNSA8PCA4KSB8IChuNikpOwoJCQkKCQkJaWYgKChzbyA9IHNvbGlzdGVuKDAsIGxhZGRyLCBscG9ydCwgU1NfRkFDQ0VQVE9OQ0UpKSA9PSBOVUxMKQoJCQkgICByZXR1cm4gMTsKCQkJCgkJCW42ID0gbnRvaHMoc28tPnNvX2Zwb3J0KTsKCQkJCgkJCW41ID0gKG42ID4+IDgpICYgMHhmZjsKCQkJbjYgJj0gMHhmZjsKCQkJCgkJCWxhZGRyID0gbnRvaGwoc28tPnNvX2ZhZGRyLnNfYWRkcik7CgkJCQoJCQluMSA9ICgobGFkZHIgPj4gMjQpICYgMHhmZik7CgkJCW4yID0gKChsYWRkciA+PiAxNikgJiAweGZmKTsKCQkJbjMgPSAoKGxhZGRyID4+IDgpICAmIDB4ZmYpOwoJCQluNCA9ICAobGFkZHIgJiAweGZmKTsKCQkJCgkJCW0tPm1fbGVuID0gYnB0ciAtIG0tPm1fZGF0YTsgLyogQWRqdXN0IGxlbmd0aCAqLwoJCQltLT5tX2xlbiArPSBzcHJpbnRmKGJwdHIsIk9SVCAlZCwlZCwlZCwlZCwlZCwlZFxyXG4lcyIsIAoJCQkJCSAgICBuMSwgbjIsIG4zLCBuNCwgbjUsIG42LCB4PT03P2J1ZmY6IiIpOwoJCQlyZXR1cm4gMTsKCQl9IGVsc2UgaWYgKChicHRyID0gKGNoYXIgKilzdHJzdHIobS0+bV9kYXRhLCAiMjcgRW50ZXJpbmciKSkgIT0gTlVMTCkgewoJCQkvKgoJCQkgKiBOZWVkIHRvIGVtdWxhdGUgdGhlIFBBU1YgcmVzcG9uc2UKCQkJICovCgkJCXggPSBzc2NhbmYoYnB0ciwgIjI3IEVudGVyaW5nIFBhc3NpdmUgTW9kZSAoJWQsJWQsJWQsJWQsJWQsJWQpXHJcbiUyNTZbXlwxNzddIiwKCQkJCSAgICZuMSwgJm4yLCAmbjMsICZuNCwgJm41LCAmbjYsIGJ1ZmYpOwoJCQlpZiAoeCA8IDYpCgkJCSAgIHJldHVybiAxOwoJCQkKCQkJbGFkZHIgPSBodG9ubCgobjEgPDwgMjQpIHwgKG4yIDw8IDE2KSB8IChuMyA8PCA4KSB8IChuNCkpOwoJCQlscG9ydCA9IGh0b25zKChuNSA8PCA4KSB8IChuNikpOwoJCQkKCQkJaWYgKChzbyA9IHNvbGlzdGVuKDAsIGxhZGRyLCBscG9ydCwgU1NfRkFDQ0VQVE9OQ0UpKSA9PSBOVUxMKQoJCQkgICByZXR1cm4gMTsKCQkJCgkJCW42ID0gbnRvaHMoc28tPnNvX2Zwb3J0KTsKCQkJCgkJCW41ID0gKG42ID4+IDgpICYgMHhmZjsKCQkJbjYgJj0gMHhmZjsKCQkJCgkJCWxhZGRyID0gbnRvaGwoc28tPnNvX2ZhZGRyLnNfYWRkcik7CgkJCQoJCQluMSA9ICgobGFkZHIgPj4gMjQpICYgMHhmZik7CgkJCW4yID0gKChsYWRkciA+PiAxNikgJiAweGZmKTsKCQkJbjMgPSAoKGxhZGRyID4+IDgpICAmIDB4ZmYpOwoJCQluNCA9ICAobGFkZHIgJiAweGZmKTsKCQkJCgkJCW0tPm1fbGVuID0gYnB0ciAtIG0tPm1fZGF0YTsgLyogQWRqdXN0IGxlbmd0aCAqLwoJCQltLT5tX2xlbiArPSBzcHJpbnRmKGJwdHIsIjI3IEVudGVyaW5nIFBhc3NpdmUgTW9kZSAoJWQsJWQsJWQsJWQsJWQsJWQpXHJcbiVzIiwKCQkJCQkgICAgbjEsIG4yLCBuMywgbjQsIG41LCBuNiwgeD09Nz9idWZmOiIiKTsKCQkJCgkJCXJldHVybiAxOwoJCX0KCQkKCQlyZXR1cm4gMTsKCQkJCSAgIAoJIGNhc2UgRU1VX0tTSDoKCQkvKgoJCSAqIFRoZSBrc2hlbGwgKEtlcmJlcm9zIHJzaCkgYW5kIHNoZWxsIHNlcnZpY2VzIGJvdGggcGFzcwoJCSAqIGEgbG9jYWwgcG9ydCBwb3J0IG51bWJlciB0byBjYXJyeSBzaWduYWxzIHRvIHRoZSBzZXJ2ZXIKCQkgKiBhbmQgc3RkZXJyIHRvIHRoZSBjbGllbnQuICBJdCBpcyBwYXNzZWQgYXQgdGhlIGJlZ2lubmluZwoJCSAqIG9mIHRoZSBjb25uZWN0aW9uIGFzIGEgTlVMLXRlcm1pbmF0ZWQgZGVjaW1hbCBBU0NJSSBzdHJpbmcuCgkJICovCgkJc28tPnNvX2VtdSA9IDA7CgkJZm9yIChscG9ydCA9IDAsIGkgPSAwOyBpIDwgbS0+bV9sZW4tMTsgKytpKSB7CgkJCWlmIChtLT5tX2RhdGFbaV0gPCAnMCcgfHwgbS0+bV9kYXRhW2ldID4gJzknKQoJCQkJcmV0dXJuIDE7ICAgICAgIC8qIGludmFsaWQgbnVtYmVyICovCgkJCWxwb3J0ICo9IDEwOwoJCQlscG9ydCArPSBtLT5tX2RhdGFbaV0gLSAnMCc7CgkJfQoJCWlmIChtLT5tX2RhdGFbbS0+bV9sZW4tMV0gPT0gJ1wwJyAmJiBscG9ydCAhPSAwICYmCgkJICAgIChzbyA9IHNvbGlzdGVuKDAsIHNvLT5zb19sYWRkci5zX2FkZHIsIGh0b25zKGxwb3J0KSwgU1NfRkFDQ0VQVE9OQ0UpKSAhPSBOVUxMKQoJCQltLT5tX2xlbiA9IHNwcmludGYobS0+bV9kYXRhLCAiJWQiLCBudG9ocyhzby0+c29fZnBvcnQpKSsxOwoJCXJldHVybiAxOwoJCQoJIGNhc2UgRU1VX0lSQzoKCQkvKgoJCSAqIE5lZWQgdG8gZW11bGF0ZSBEQ0MgQ0hBVCwgRENDIFNFTkQgYW5kIERDQyBNT1ZFCgkJICovCgkJKihtLT5tX2RhdGErbS0+bV9sZW4pID0gMDsgLyogTlVMTCB0ZXJtaW5hdGUgdGhlIHN0cmluZyBmb3Igc3Ryc3RyICovCgkJaWYgKChicHRyID0gKGNoYXIgKilzdHJzdHIobS0+bV9kYXRhLCAiRENDIikpID09IE5VTEwpCgkJCSByZXR1cm4gMTsKCQkKCQkvKiBUaGUgJTI1NnMgaXMgZm9yIHRoZSBicm9rZW4gbUlSQyAqLwoJCWlmIChzc2NhbmYoYnB0ciwgIkRDQyBDSEFUICUyNTZzICV1ICV1IiwgYnVmZiwgJmxhZGRyLCAmbHBvcnQpID09IDMpIHsKCQkJaWYgKChzbyA9IHNvbGlzdGVuKDAsIGh0b25sKGxhZGRyKSwgaHRvbnMobHBvcnQpLCBTU19GQUNDRVBUT05DRSkpID09IE5VTEwpCgkJCQlyZXR1cm4gMTsKCQkJCgkJCW0tPm1fbGVuID0gYnB0ciAtIG0tPm1fZGF0YTsgLyogQWRqdXN0IGxlbmd0aCAqLwoJCQltLT5tX2xlbiArPSBzcHJpbnRmKGJwdHIsICJEQ0MgQ0hBVCBjaGF0ICVsdSAldSVjXG4iLAoJCQkgICAgICh1bnNpZ25lZCBsb25nKW50b2hsKHNvLT5zb19mYWRkci5zX2FkZHIpLAoJCQkgICAgIG50b2hzKHNvLT5zb19mcG9ydCksIDEpOwoJCX0gZWxzZSBpZiAoc3NjYW5mKGJwdHIsICJEQ0MgU0VORCAlMjU2cyAldSAldSAldSIsIGJ1ZmYsICZsYWRkciwgJmxwb3J0LCAmbjEpID09IDQpIHsKCQkJaWYgKChzbyA9IHNvbGlzdGVuKDAsIGh0b25sKGxhZGRyKSwgaHRvbnMobHBvcnQpLCBTU19GQUNDRVBUT05DRSkpID09IE5VTEwpCgkJCQlyZXR1cm4gMTsKCQkJCgkJCW0tPm1fbGVuID0gYnB0ciAtIG0tPm1fZGF0YTsgLyogQWRqdXN0IGxlbmd0aCAqLwoJCQltLT5tX2xlbiArPSBzcHJpbnRmKGJwdHIsICJEQ0MgU0VORCAlcyAlbHUgJXUgJXUlY1xuIiwgCgkJCSAgICAgIGJ1ZmYsICh1bnNpZ25lZCBsb25nKW50b2hsKHNvLT5zb19mYWRkci5zX2FkZHIpLAoJCQkgICAgICBudG9ocyhzby0+c29fZnBvcnQpLCBuMSwgMSk7CgkJfSBlbHNlIGlmIChzc2NhbmYoYnB0ciwgIkRDQyBNT1ZFICUyNTZzICV1ICV1ICV1IiwgYnVmZiwgJmxhZGRyLCAmbHBvcnQsICZuMSkgPT0gNCkgewoJCQlpZiAoKHNvID0gc29saXN0ZW4oMCwgaHRvbmwobGFkZHIpLCBodG9ucyhscG9ydCksIFNTX0ZBQ0NFUFRPTkNFKSkgPT0gTlVMTCkKCQkJCXJldHVybiAxOwoJCQkKCQkJbS0+bV9sZW4gPSBicHRyIC0gbS0+bV9kYXRhOyAvKiBBZGp1c3QgbGVuZ3RoICovCgkJCW0tPm1fbGVuICs9IHNwcmludGYoYnB0ciwgIkRDQyBNT1ZFICVzICVsdSAldSAldSVjXG4iLAoJCQkgICAgICBidWZmLCAodW5zaWduZWQgbG9uZyludG9obChzby0+c29fZmFkZHIuc19hZGRyKSwKCQkJICAgICAgbnRvaHMoc28tPnNvX2Zwb3J0KSwgbjEsIDEpOwoJCX0KCQlyZXR1cm4gMTsKCgkgY2FzZSBFTVVfUkVBTEFVRElPOgogICAgICAgICAgICAgICAgLyogCgkJICogUmVhbEF1ZGlvIGVtdWxhdGlvbiAtIEpQLiBXZSBtdXN0IHRyeSB0byBwYXJzZSB0aGUgaW5jb21pbmcKCQkgKiBkYXRhIGFuZCB0cnkgdG8gZmluZCB0aGUgdHdvIGNoYXJhY3RlcnMgdGhhdCBjb250YWluIHRoZQoJCSAqIHBvcnQgbnVtYmVyLiBUaGVuIHdlIHJlZGlyZWN0IGFuIHVkcCBwb3J0IGFuZCByZXBsYWNlIHRoZQoJCSAqIG51bWJlciB3aXRoIHRoZSByZWFsIHBvcnQgd2UgZ290LgoJCSAqCgkJICogVGhlIDEuMCBiZXRhIHZlcnNpb25zIG9mIHRoZSBwbGF5ZXIgYXJlIG5vdCBzdXBwb3J0ZWQKCQkgKiBhbnkgbW9yZS4KCQkgKiAKCQkgKiBBIHR5cGljYWwgcGFja2V0IGZvciBwbGF5ZXIgdmVyc2lvbiAxLjAgKHJlbGVhc2UgdmVyc2lvbik6CgkJICogICAgICAgIAoJCSAqIDAwMDA6NTAgNEUgNDEgMDAgMDUgCgkJICogMDAwMDowMCAwMSAwMCAwMiAxQiBENyAwMCAwMCA2NyBFNiA2QyBEQyA2MyAwMCAxMiA1MCAuLi4uLtcuLmfmbNxjLi5QCgkJICogMDAxMDo0RSA0MyA0QyA0OSA0NSA0RSA1NCAyMCAzMSAzMCAzMSAyMCA0MSA0QyA1MCA0OCBOQ0xJRU5UIDEwMSBBTFBICgkJICogMDAyMDo0MSA2QyAwMCAwMCA1MiAwMCAxNyA3MiA2MSA2NiA2OSA2QyA2NSA3MyAyRiA3NiBBbC4uUi4ucmFmaWxlcy92CgkJICogMDAzMDo2RiA2MSAyRiA2NSA2RSA2NyA2QyA2OSA3MyA2OCA1RiAyRSA3MiA2MSA3OSA0MiBvYS9lbmdsaXNoXy5yYXlCCgkJICogICAgICAgICAKCQkgKiBOb3cgdGhlIHBvcnQgbnVtYmVyIDB4MUJENyBpcyBmb3VuZCBhdCBvZmZzZXQgMHgwNCBvZiB0aGUKCQkgKiBOb3cgdGhlIHBvcnQgbnVtYmVyIDB4MUJENyBpcyBmb3VuZCBhdCBvZmZzZXQgMHgwNCBvZiB0aGUKCQkgKiBzZWNvbmQgcGFja2V0LiBUaGlzIHRpbWUgd2UgcmVjZWl2ZWQgZml2ZSBieXRlcyBmaXJzdCBhbmQKCQkgKiB0aGVuIHRoZSByZXN0LiBZb3UgbmV2ZXIga25vdyBob3cgbWFueSBieXRlcyB5b3UgZ2V0LgoJCSAqCgkJICogQSB0eXBpY2FsIHBhY2tldCBmb3IgcGxheWVyIHZlcnNpb24gMi4wIChiZXRhKToKCQkgKiAgICAgICAgCgkJICogMDAwMDo1MCA0RSA0MSAwMCAwNiAwMCAwMiAwMCAwMCAwMCAwMSAwMCAwMiAxQiBDMSAwMCBQTkEuLi4uLi4uLi4uLsEuCgkJICogMDAxMDowMCA2NyA3NSA3OCBGNSA2MyAwMCAwQSA1NyA2OSA2RSAzMiAyRSAzMCAyRSAzMCAuZ3V49WMuLldpbjIuMC4wCgkJICogMDAyMDoyRSAzNSA2QyAwMCAwMCA1MiAwMCAxQyA3MiA2MSA2NiA2OSA2QyA2NSA3MyAyRiAuNWwuLlIuLnJhZmlsZXMvCgkJICogMDAzMDo3NyA2NSA2MiA3MyA2OSA3NCA2NSAyRiAzMiAzMCA3MiA2NSA2QyA2NSA2MSA3MyB3ZWJzaXRlLzIwcmVsZWFzCgkJICogMDA0MDo2NSAyRSA3MiA2MSA3OSA1MyAwMCAwMCAwNiAzNiA0MiAgICAgICAgICAgICAgICBlLnJheVMuLi42QgoJCSAqICAgICAgICAKCQkgKiBQb3J0IG51bWJlciAweDFCQzEgaXMgZm91bmQgYXQgb2Zmc2V0IDB4MGQuCgkJICogICAgICAKCQkgKiBUaGlzIGlzIGp1c3QgYSBob3JyaWJsZSBzd2l0Y2ggc3RhdGVtZW50LiBWYXJpYWJsZSByYSB0ZWxscwoJCSAqIHVzIHdoZXJlIHdlJ3JlIGdvaW5nLgoJCSAqLwoJCQoJCWJwdHIgPSBtLT5tX2RhdGE7CgkJd2hpbGUgKGJwdHIgPCBtLT5tX2RhdGEgKyBtLT5tX2xlbikgewoJCQl1X3Nob3J0IHA7CgkJCXN0YXRpYyBpbnQgcmEgPSAwOwoJCQljaGFyIHJhX3RibFs0XTsgCgkJCQoJCQlyYV90YmxbMF0gPSAweDUwOwoJCQlyYV90YmxbMV0gPSAweDRlOwoJCQlyYV90YmxbMl0gPSAweDQxOwoJCQlyYV90YmxbM10gPSAwOwoJCQkKCQkJc3dpdGNoIChyYSkgewoJCQkgY2FzZSAwOgoJCQkgY2FzZSAyOgoJCQkgY2FzZSAzOgoJCQkJaWYgKCpicHRyKysgIT0gcmFfdGJsW3JhXSkgewoJCQkJCXJhID0gMDsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCWJyZWFrOwoJCQkJCgkJCSBjYXNlIDE6CgkJCQkvKgoJCQkJICogV2UgbWF5IGdldCAweDUwIHNldmVyYWwgdGltZXMsIGlnbm9yZSB0aGVtCgkJCQkgKi8KCQkJCWlmICgqYnB0ciA9PSAweDUwKSB7CgkJCQkJcmEgPSAxOwoJCQkJCWJwdHIrKzsKCQkJCQljb250aW51ZTsKCQkJCX0gZWxzZSBpZiAoKmJwdHIrKyAhPSByYV90YmxbcmFdKSB7CgkJCQkJcmEgPSAwOwoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJYnJlYWs7CgkJCQkKCQkJIGNhc2UgNDogCgkJCQkvKiAKCQkJCSAqIHNraXAgdmVyc2lvbiBudW1iZXIKCQkJCSAqLwoJCQkJYnB0cisrOwoJCQkJYnJlYWs7CgkJCQkKCQkJIGNhc2UgNTogCgkJCQkvKgoJCQkJICogVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB2ZXJzaW9ucyAxLjAgYW5kCgkJCQkgKiAyLjAgaXMgaGVyZS4gRm9yIGZ1dHVyZSB2ZXJzaW9ucyBvZgoJCQkJICogdGhlIHBsYXllciB0aGlzIG1heSBuZWVkIHRvIGJlIG1vZGlmaWVkLgoJCQkJICovCgkJCQlpZiAoKihicHRyICsgMSkgPT0gMHgwMikKCQkJCSAgIGJwdHIgKz0gODsKCQkJCWVsc2UKCQkJCSAgIGJwdHIgKz0gNDsKCQkJCWJyZWFrOyAgICAgICAgICAgICAgICAgICAgICAgICAgCgkJCQkKCQkJIGNhc2UgNjoKCQkJCS8qIFRoaXMgaXMgdGhlIGZpZWxkIGNvbnRhaW5pbmcgdGhlIHBvcnQKCQkJCSAqIG51bWJlciB0aGF0IFJBLXBsYXllciBpcyBsaXN0ZW5pbmcgdG8uCgkJCQkgKi8KCQkJCWxwb3J0ID0gKCgodV9jaGFyKilicHRyKVswXSA8PCA4KSAKCQkJCSsgKCh1X2NoYXIgKilicHRyKVsxXTsKCQkJCWlmIChscG9ydCA8IDY5NzApICAgICAgCgkJCQkgICBscG9ydCArPSAyNTY7ICAgLyogZG9uJ3Qga25vdyB3aHkgKi8KCQkJCWlmIChscG9ydCA8IDY5NzAgfHwgbHBvcnQgPiA3MTcwKQoJCQkJICAgcmV0dXJuIDE7ICAgICAgIC8qIGZhaWxlZCAqLwoJCQkJCgkJCQkvKiB0cnkgdG8gZ2V0IHVkcCBwb3J0IGJldHdlZW4gNjk3MCAtIDcxNzAgKi8KCQkJCWZvciAocCA9IDY5NzA7IHAgPCA3MDcxOyBwKyspIHsKCQkJCQlpZiAodWRwX2xpc3RlbiggaHRvbnMocCksCgkJCQkJCSAgICAgICBzby0+c29fbGFkZHIuc19hZGRyLAoJCQkJCQkgICAgICAgaHRvbnMobHBvcnQpLAoJCQkJCQkgICAgICAgU1NfRkFDQ0VQVE9OQ0UpKSB7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJCWlmIChwID09IDcwNzEpCgkJCQkgICBwID0gMDsKCQkJCSoodV9jaGFyICopYnB0cisrID0gKHAgPj4gOCkgJiAweGZmOwoJCQkJKih1X2NoYXIgKilicHRyKysgPSBwICYgMHhmZjsKCQkJCXJhID0gMDsgCgkJCQlyZXR1cm4gMTsgICAvKiBwb3J0IHJlZGlyZWN0ZWQsIHdlJ3JlIGRvbmUgKi8KCQkJCWJyZWFrOyAgCgkJCQkKCQkJIGRlZmF1bHQ6CgkJCQlyYSA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAgIAoJCQl9CgkJCXJhKys7CgkJfQoJCXJldHVybiAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgkJCgkgZGVmYXVsdDoKCQkvKiBPb29wcywgbm90IGVtdWxhdGVkLCB3b24ndCBjYWxsIHRjcF9lbXUgYWdhaW4gKi8KCQlzby0+c29fZW11ID0gMDsKCQlyZXR1cm4gMTsKCX0KfQoKLyoKICogRG8gbWlzYy4gY29uZmlnIG9mIFNMaVJQIHdoaWxlIGl0cyBydW5uaW5nLgogKiBSZXR1cm4gMCBpZiB0aGlzIGNvbm5lY3Rpb25zIGlzIHRvIGJlIGNsb3NlZCwgMSBvdGhlcndpc2UsCiAqIHJldHVybiAyIGlmIHRoaXMgaXMgYSBjb21tYW5kLWxpbmUgY29ubmVjdGlvbgogKi8KaW50CnRjcF9jdGwoc28pCglzdHJ1Y3Qgc29ja2V0ICpzbzsKewojaWYgMAoJc3RydWN0IHNidWYgKnNiID0gJnNvLT5zb19zbmQ7CglpbnQgY29tbWFuZDsKIAlzdHJ1Y3QgZXhfbGlzdCAqZXhfcHRyOwoJaW50IGRvX3B0eTsKCXN0cnVjdCBzb2NrZXQgKnRtcHNvOwoJCglERUJVR19DQUxMKCJ0Y3BfY3RsIik7CglERUJVR19BUkcoInNvID0gJWx4IiwgKGxvbmcgKXNvKTsKCQoJLyoKCSAqIENoZWNrIGlmIHRoZXkncmUgYXV0aG9yaXNlZAoJICovCglpZiAoY3RsX2FkZHIuc19hZGRyICYmIChjdGxfYWRkci5zX2FkZHIgPT0gLTEgfHwgKHNvLT5zb19sYWRkci5zX2FkZHIgIT0gY3RsX2FkZHIuc19hZGRyKSkpIHsKCQlzYi0+c2JfY2MgPSBzcHJpbnRmKHNiLT5zYl93cHRyLCJFcnJvcjogUGVybWlzc2lvbiBkZW5pZWQuXHJcbiIpOwoJCXNiLT5zYl93cHRyICs9IHNiLT5zYl9jYzsKCQlyZXR1cm4gMDsKCX0KCQoJY29tbWFuZCA9IChudG9obChzby0+c29fZmFkZHIuc19hZGRyKSAmIDB4ZmYpOwoJCglzd2l0Y2goY29tbWFuZCkgewoJZGVmYXVsdDogLyogQ2hlY2sgZm9yIGV4ZWMncyAqLwoJCQoJCS8qCgkJICogQ2hlY2sgaWYgaXQncyBwdHlfZXhlYwoJCSAqLwoJCWZvciAoZXhfcHRyID0gZXhlY19saXN0OyBleF9wdHI7IGV4X3B0ciA9IGV4X3B0ci0+ZXhfbmV4dCkgewoJCQlpZiAoZXhfcHRyLT5leF9mcG9ydCA9PSBzby0+c29fZnBvcnQgJiYKCQkJICAgIGNvbW1hbmQgPT0gZXhfcHRyLT5leF9hZGRyKSB7CgkJCQlkb19wdHkgPSBleF9wdHItPmV4X3B0eTsKCQkJCWdvdG8gZG9fZXhlYzsKCQkJfQoJCX0KCQkKCQkvKgoJCSAqIE5vdGhpbmcgYm91bmQuLgoJCSAqLwoJCS8qIHRjcF9mY29ubmVjdChzbyk7ICovCgkJCgkJLyogRkFMTFRIUk9VR0ggKi8KCWNhc2UgQ1RMX0FMSUFTOgoJICBzYi0+c2JfY2MgPSBzcHJpbnRmKHNiLT5zYl93cHRyLAoJCQkgICAgICAiRXJyb3I6IE5vIGFwcGxpY2F0aW9uIGNvbmZpZ3VyZWQuXHJcbiIpOwoJICBzYi0+c2Jfd3B0ciArPSBzYi0+c2JfY2M7CgkgIHJldHVybigwKTsKCglkb19leGVjOgoJCURFQlVHX01JU0MoKGRmZCwgIiBleGVjdXRpbmcgJXMgXG4iLGV4X3B0ci0+ZXhfZXhlYykpOwoJCXJldHVybihmb3JrX2V4ZWMoc28sIGV4X3B0ci0+ZXhfZXhlYywgZG9fcHR5KSk7CgkJCgljYXNlIENUTF9DTUQ6CgkgICBmb3IgKHRtcHNvID0gdGNiLnNvX25leHQ7IHRtcHNvICE9ICZ0Y2I7IHRtcHNvID0gdG1wc28tPnNvX25leHQpIHsKCSAgICAgaWYgKHRtcHNvLT5zb19lbXUgPT0gRU1VX0NUTCAmJiAKCQkgISh0bXBzby0+c29fdGNwY2I/IAoJCSAgICh0bXBzby0+c29fdGNwY2ItPnRfc3RhdGUgJiAoVENQU19USU1FX1dBSVR8VENQU19MQVNUX0FDSykpCgkJICAgOjApKSB7CgkgICAgICAgLyogT29vcHMsIGNvbnRyb2wgY29ubmVjdGlvbiBhbHJlYWR5IGFjdGl2ZSAqLwoJICAgICAgIHNiLT5zYl9jYyA9IHNwcmludGYoc2ItPnNiX3dwdHIsIlNvcnJ5LCBhbHJlYWR5IGNvbm5lY3RlZC5cclxuIik7CgkgICAgICAgc2ItPnNiX3dwdHIgKz0gc2ItPnNiX2NjOwoJICAgICAgIHJldHVybiAwOwoJICAgICB9CgkgICB9CgkgICBzby0+c29fZW11ID0gRU1VX0NUTDsKCSAgIGN0bF9wYXNzd29yZF9vayA9IDA7CgkgICBzYi0+c2JfY2MgPSBzcHJpbnRmKHNiLT5zYl93cHRyLCAiU2xpcnAgY29tbWFuZC1saW5lIHJlYWR5ICh0eXBlIFwiaGVscFwiIGZvciBoZWxwKS5cclxuU2xpcnA+ICIpOwoJICAgc2ItPnNiX3dwdHIgKz0gc2ItPnNiX2NjOwoJICAgZG9fZWNobz0tMTsKCSAgIHJldHVybigyKTsKCX0KI2Vsc2UKICAgICAgICByZXR1cm4gMDsKI2VuZGlmCn0K