LyoKICogQ29weXJpZ2h0IChjKSAxOTgyLCAxOTg2LCAxOTg4LCAxOTkwLCAxOTkzCiAqCVRoZSBSZWdlbnRzIG9mIHRoZSBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICoJQCgjKXRjcF9zdWJyLmMJOC4xIChCZXJrZWxleSkgNi8xMC85MwogKiB0Y3Bfc3Vici5jLHYgMS41IDE5OTQvMTAvMDggMjI6Mzk6NTggcGhrIEV4cAogKi8KCi8qCiAqIENoYW5nZXMgYW5kIGFkZGl0aW9ucyByZWxhdGluZyB0byBTTGlSUAogKiBDb3B5cmlnaHQgKGMpIDE5OTUgRGFubnkgR2FzcGFyb3Zza2kuCiAqIAogKiBQbGVhc2UgcmVhZCB0aGUgZmlsZSBDT1BZUklHSFQgZm9yIHRoZSAKICogdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIGNvcHlyaWdodC4KICovCgojZGVmaW5lIFdBTlRfU1lTX0lPQ1RMX0gKI2luY2x1ZGUgPHNsaXJwLmg+CgovKiBwYXRjaGFibGUvc2V0dGFibGUgcGFyYW1ldGVycyBmb3IgdGNwICovCmludCAJdGNwX21zc2RmbHQgPSBUQ1BfTVNTOwppbnQgCXRjcF9ydHRkZmx0ID0gVENQVFZfU1JUVERGTFQgLyBQUl9TTE9XSFo7CmludAl0Y3BfZG9fcmZjMTMyMyA9IDA7CS8qIERvbid0IGRvIHJmYzEzMjMgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzICovCmludAl0Y3BfcmN2c3BhY2U7CS8qIFlvdSBtYXkgd2FudCB0byBjaGFuZ2UgdGhpcyAqLwppbnQJdGNwX3NuZHNwYWNlOwkvKiBLZWVwIHNtYWxsIGlmIHlvdSBoYXZlIGFuIGVycm9yIHByb25lIGxpbmsgKi8KCi8qCiAqIFRjcCBpbml0aWFsaXphdGlvbgogKi8Kdm9pZAp0Y3BfaW5pdCgpCnsKCXRjcF9pc3MgPSAxOwkJLyogd3JvbmcgKi8KCXRjYi5zb19uZXh0ID0gdGNiLnNvX3ByZXYgPSAmdGNiOwoJCgkvKiB0Y3BfcmN2c3BhY2UgPSBvdXIgV2luZG93IHdlIGFkdmVydGlzZSB0byB0aGUgcmVtb3RlICovCgl0Y3BfcmN2c3BhY2UgPSBUQ1BfUkNWU1BBQ0U7Cgl0Y3Bfc25kc3BhY2UgPSBUQ1BfU05EU1BBQ0U7CgkKCS8qIE1ha2Ugc3VyZSB0Y3Bfc25kc3BhY2UgaXMgYXQgbGVhc3QgMipNU1MgKi8KCWlmICh0Y3Bfc25kc3BhY2UgPCAyKihtaW4oaWZfbXR1LCBpZl9tcnUpIC0gc2l6ZW9mKHN0cnVjdCB0Y3BpcGhkcikpKQoJCXRjcF9zbmRzcGFjZSA9IDIqKG1pbihpZl9tdHUsIGlmX21ydSkgLSBzaXplb2Yoc3RydWN0IHRjcGlwaGRyKSk7Cn0KCi8qCiAqIENyZWF0ZSB0ZW1wbGF0ZSB0byBiZSB1c2VkIHRvIHNlbmQgdGNwIHBhY2tldHMgb24gYSBjb25uZWN0aW9uLgogKiBDYWxsIGFmdGVyIGhvc3QgZW50cnkgY3JlYXRlZCwgZmlsbHMKICogaW4gYSBza2VsZXRhbCB0Y3AvaXAgaGVhZGVyLCBtaW5pbWl6aW5nIHRoZSBhbW91bnQgb2Ygd29yawogKiBuZWNlc3Nhcnkgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyB1c2VkLgogKi8KLyogc3RydWN0IHRjcGlwaGRyICogKi8Kdm9pZAp0Y3BfdGVtcGxhdGUodHApCglzdHJ1Y3QgdGNwY2IgKnRwOwp7CglzdHJ1Y3Qgc29ja2V0ICpzbyA9IHRwLT50X3NvY2tldDsKCXJlZ2lzdGVyIHN0cnVjdCB0Y3BpcGhkciAqbiA9ICZ0cC0+dF90ZW1wbGF0ZTsKCgluLT50aV9uZXh0ID0gbi0+dGlfcHJldiA9IDA7CgluLT50aV94MSA9IDA7CgluLT50aV9wciA9IElQUFJPVE9fVENQOwoJbi0+dGlfbGVuID0gaHRvbnMoc2l6ZW9mIChzdHJ1Y3QgdGNwaXBoZHIpIC0gc2l6ZW9mIChzdHJ1Y3QgaXApKTsKCW4tPnRpX3NyYyA9IHNvLT5zb19mYWRkcjsKCW4tPnRpX2RzdCA9IHNvLT5zb19sYWRkcjsKCW4tPnRpX3Nwb3J0ID0gc28tPnNvX2Zwb3J0OwoJbi0+dGlfZHBvcnQgPSBzby0+c29fbHBvcnQ7CgkKCW4tPnRpX3NlcSA9IDA7CgluLT50aV9hY2sgPSAwOwoJbi0+dGlfeDIgPSAwOwoJbi0+dGlfb2ZmID0gNTsKCW4tPnRpX2ZsYWdzID0gMDsKCW4tPnRpX3dpbiA9IDA7CgluLT50aV9zdW0gPSAwOwoJbi0+dGlfdXJwID0gMDsKfQoKLyoKICogU2VuZCBhIHNpbmdsZSBtZXNzYWdlIHRvIHRoZSBUQ1AgYXQgYWRkcmVzcyBzcGVjaWZpZWQgYnkKICogdGhlIGdpdmVuIFRDUC9JUCBoZWFkZXIuICBJZiBtID09IDAsIHRoZW4gd2UgbWFrZSBhIGNvcHkKICogb2YgdGhlIHRjcGlwaGRyIGF0IHRpIGFuZCBzZW5kIGRpcmVjdGx5IHRvIHRoZSBhZGRyZXNzZWQgaG9zdC4KICogVGhpcyBpcyB1c2VkIHRvIGZvcmNlIGtlZXAgYWxpdmUgbWVzc2FnZXMgb3V0IHVzaW5nIHRoZSBUQ1AKICogdGVtcGxhdGUgZm9yIGEgY29ubmVjdGlvbiB0cC0+dF90ZW1wbGF0ZS4gIElmIGZsYWdzIGFyZSBnaXZlbgogKiB0aGVuIHdlIHNlbmQgYSBtZXNzYWdlIGJhY2sgdG8gdGhlIFRDUCB3aGljaCBvcmlnaW5hdGVkIHRoZQogKiBzZWdtZW50IHRpLCBhbmQgZGlzY2FyZCB0aGUgbWJ1ZiBjb250YWluaW5nIGl0IGFuZCBhbnkgb3RoZXIKICogYXR0YWNoZWQgbWJ1ZnMuCiAqCiAqIEluIGFueSBjYXNlIHRoZSBhY2sgYW5kIHNlcXVlbmNlIG51bWJlciBvZiB0aGUgdHJhbnNtaXR0ZWQKICogc2VnbWVudCBhcmUgYXMgc3BlY2lmaWVkIGJ5IHRoZSBwYXJhbWV0ZXJzLgogKi8Kdm9pZAp0Y3BfcmVzcG9uZCh0cCwgdGksIG0sIGFjaywgc2VxLCBmbGFncykKCXN0cnVjdCB0Y3BjYiAqdHA7CglyZWdpc3RlciBzdHJ1Y3QgdGNwaXBoZHIgKnRpOwoJcmVnaXN0ZXIgc3RydWN0IG1idWYgKm07Cgl0Y3Bfc2VxIGFjaywgc2VxOwoJaW50IGZsYWdzOwp7CglyZWdpc3RlciBpbnQgdGxlbjsKCWludCB3aW4gPSAwOwoKCURFQlVHX0NBTEwoInRjcF9yZXNwb25kIik7CglERUJVR19BUkcoInRwID0gJWx4IiwgKGxvbmcpdHApOwoJREVCVUdfQVJHKCJ0aSA9ICVseCIsIChsb25nKXRpKTsKCURFQlVHX0FSRygibSA9ICVseCIsIChsb25nKW0pOwoJREVCVUdfQVJHKCJhY2sgPSAldSIsIGFjayk7CglERUJVR19BUkcoInNlcSA9ICV1Iiwgc2VxKTsKCURFQlVHX0FSRygiZmxhZ3MgPSAleCIsIGZsYWdzKTsKCQoJaWYgKHRwKQoJCXdpbiA9IHNic3BhY2UoJnRwLT50X3NvY2tldC0+c29fcmN2KTsKCWlmIChtID09IDApIHsKCQlpZiAoKG0gPSBtX2dldCgpKSA9PSBOVUxMKQoJCQlyZXR1cm47CiNpZmRlZiBUQ1BfQ09NUEFUXzQyCgkJdGxlbiA9IDE7CiNlbHNlCgkJdGxlbiA9IDA7CiNlbmRpZgoJCW0tPm1fZGF0YSArPSBpZl9tYXhsaW5raGRyOwoJCSptdG9kKG0sIHN0cnVjdCB0Y3BpcGhkciAqKSA9ICp0aTsKCQl0aSA9IG10b2QobSwgc3RydWN0IHRjcGlwaGRyICopOwoJCWZsYWdzID0gVEhfQUNLOwoJfSBlbHNlIHsKCQkvKiAKCQkgKiB0aSBwb2ludHMgaW50byBtIHNvIHRoZSBuZXh0IGxpbmUgaXMganVzdCBtYWtpbmcKCQkgKiB0aGUgbWJ1ZiBwb2ludCB0byB0aQoJCSAqLwoJCW0tPm1fZGF0YSA9IChjYWRkcl90KXRpOwoJCQoJCW0tPm1fbGVuID0gc2l6ZW9mIChzdHJ1Y3QgdGNwaXBoZHIpOwoJCXRsZW4gPSAwOwojZGVmaW5lIHhjaGcoYSxiLHR5cGUpIHsgdHlwZSB0OyB0PWE7IGE9YjsgYj10OyB9CgkJeGNoZyh0aS0+dGlfZHN0LnNfYWRkciwgdGktPnRpX3NyYy5zX2FkZHIsIHVfaW50MzJfdCk7CgkJeGNoZyh0aS0+dGlfZHBvcnQsIHRpLT50aV9zcG9ydCwgdV9pbnQxNl90KTsKI3VuZGVmIHhjaGcKCX0KCXRpLT50aV9sZW4gPSBodG9ucygodV9zaG9ydCkoc2l6ZW9mIChzdHJ1Y3QgdGNwaGRyKSArIHRsZW4pKTsKCXRsZW4gKz0gc2l6ZW9mIChzdHJ1Y3QgdGNwaXBoZHIpOwoJbS0+bV9sZW4gPSB0bGVuOwoKCXRpLT50aV9uZXh0ID0gdGktPnRpX3ByZXYgPSAwOwoJdGktPnRpX3gxID0gMDsKCXRpLT50aV9zZXEgPSBodG9ubChzZXEpOwoJdGktPnRpX2FjayA9IGh0b25sKGFjayk7Cgl0aS0+dGlfeDIgPSAwOwoJdGktPnRpX29mZiA9IHNpemVvZiAoc3RydWN0IHRjcGhkcikgPj4gMjsKCXRpLT50aV9mbGFncyA9IGZsYWdzOwoJaWYgKHRwKQoJCXRpLT50aV93aW4gPSBodG9ucygodV9pbnQxNl90KSAod2luID4+IHRwLT5yY3Zfc2NhbGUpKTsKCWVsc2UKCQl0aS0+dGlfd2luID0gaHRvbnMoKHVfaW50MTZfdCl3aW4pOwoJdGktPnRpX3VycCA9IDA7Cgl0aS0+dGlfc3VtID0gMDsKCXRpLT50aV9zdW0gPSBja3N1bShtLCB0bGVuKTsKCSgoc3RydWN0IGlwICopdGkpLT5pcF9sZW4gPSB0bGVuOwoKCWlmKGZsYWdzICYgVEhfUlNUKSAKCSAgKChzdHJ1Y3QgaXAgKil0aSktPmlwX3R0bCA9IE1BWFRUTDsKCWVsc2UgCgkgICgoc3RydWN0IGlwICopdGkpLT5pcF90dGwgPSBpcF9kZWZ0dGw7CgkKCSh2b2lkKSBpcF9vdXRwdXQoKHN0cnVjdCBzb2NrZXQgKikwLCBtKTsKfQoKLyoKICogQ3JlYXRlIGEgbmV3IFRDUCBjb250cm9sIGJsb2NrLCBtYWtpbmcgYW4KICogZW1wdHkgcmVhc3NlbWJseSBxdWV1ZSBhbmQgaG9va2luZyBpdCB0byB0aGUgYXJndW1lbnQKICogcHJvdG9jb2wgY29udHJvbCBibG9jay4KICovCnN0cnVjdCB0Y3BjYiAqCnRjcF9uZXd0Y3BjYihzbykKCXN0cnVjdCBzb2NrZXQgKnNvOwp7CglyZWdpc3RlciBzdHJ1Y3QgdGNwY2IgKnRwOwoJCgl0cCA9IChzdHJ1Y3QgdGNwY2IgKiltYWxsb2Moc2l6ZW9mKCp0cCkpOwoJaWYgKHRwID09IE5VTEwpCgkJcmV0dXJuICgoc3RydWN0IHRjcGNiICopMCk7CgkKCW1lbXNldCgoY2hhciAqKSB0cCwgMCwgc2l6ZW9mKHN0cnVjdCB0Y3BjYikpOwoJdHAtPnNlZ19uZXh0ID0gdHAtPnNlZ19wcmV2ID0gKHRjcGlwaGRycF8zMil0cDsKCXRwLT50X21heHNlZyA9IHRjcF9tc3NkZmx0OwoJCgl0cC0+dF9mbGFncyA9IHRjcF9kb19yZmMxMzIzID8gKFRGX1JFUV9TQ0FMRXxURl9SRVFfVFNUTVApIDogMDsKCXRwLT50X3NvY2tldCA9IHNvOwoJCgkvKgoJICogSW5pdCBzcnR0IHRvIFRDUFRWX1NSVFRCQVNFICgwKSwgc28gd2UgY2FuIHRlbGwgdGhhdCB3ZSBoYXZlIG5vCgkgKiBydHQgZXN0aW1hdGUuICBTZXQgcnR0dmFyIHNvIHRoYXQgc3J0dCArIDIgKiBydHR2YXIgZ2l2ZXMKCSAqIHJlYXNvbmFibGUgaW5pdGlhbCByZXRyYW5zbWl0IHRpbWUuCgkgKi8KCXRwLT50X3NydHQgPSBUQ1BUVl9TUlRUQkFTRTsKCXRwLT50X3J0dHZhciA9IHRjcF9ydHRkZmx0ICogUFJfU0xPV0haIDw8IDI7Cgl0cC0+dF9ydHRtaW4gPSBUQ1BUVl9NSU47CgoJVENQVF9SQU5HRVNFVCh0cC0+dF9yeHRjdXIsIAoJICAgICgoVENQVFZfU1JUVEJBU0UgPj4gMikgKyAoVENQVFZfU1JUVERGTFQgPDwgMikpID4+IDEsCgkgICAgVENQVFZfTUlOLCBUQ1BUVl9SRVhNVE1BWCk7CgoJdHAtPnNuZF9jd25kID0gVENQX01BWFdJTiA8PCBUQ1BfTUFYX1dJTlNISUZUOwoJdHAtPnNuZF9zc3RocmVzaCA9IFRDUF9NQVhXSU4gPDwgVENQX01BWF9XSU5TSElGVDsKCXRwLT50X3N0YXRlID0gVENQU19DTE9TRUQ7CgkKCXNvLT5zb190Y3BjYiA9IHRwOwoKCXJldHVybiAodHApOwp9CgovKgogKiBEcm9wIGEgVENQIGNvbm5lY3Rpb24sIHJlcG9ydGluZwogKiB0aGUgc3BlY2lmaWVkIGVycm9yLiAgSWYgY29ubmVjdGlvbiBpcyBzeW5jaHJvbml6ZWQsCiAqIHRoZW4gc2VuZCBhIFJTVCB0byBwZWVyLgogKi8Kc3RydWN0IHRjcGNiICp0Y3BfZHJvcChzdHJ1Y3QgdGNwY2IgKnRwLCBpbnQgZXJyKSAKewovKiB0Y3BfZHJvcCh0cCwgZXJybm8pCglyZWdpc3RlciBzdHJ1Y3QgdGNwY2IgKnRwOwoJaW50IGVycm5vOwp7CiovCgoJREVCVUdfQ0FMTCgidGNwX2Ryb3AiKTsKCURFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyl0cCk7CglERUJVR19BUkcoImVycm5vID0gJWQiLCBlcnJubyk7CgkKCWlmIChUQ1BTX0hBVkVSQ1ZEU1lOKHRwLT50X3N0YXRlKSkgewoJCXRwLT50X3N0YXRlID0gVENQU19DTE9TRUQ7CgkJKHZvaWQpIHRjcF9vdXRwdXQodHApOwoJCXRjcHN0YXQudGNwc19kcm9wcysrOwoJfSBlbHNlCgkJdGNwc3RhdC50Y3BzX2Nvbm5kcm9wcysrOwovKglpZiAoZXJybm8gPT0gRVRJTUVET1VUICYmIHRwLT50X3NvZnRlcnJvcikKICoJCWVycm5vID0gdHAtPnRfc29mdGVycm9yOwogKi8KLyoJc28tPnNvX2Vycm9yID0gZXJybm87ICovCglyZXR1cm4gKHRjcF9jbG9zZSh0cCkpOwp9CgovKgogKiBDbG9zZSBhIFRDUCBjb250cm9sIGJsb2NrOgogKglkaXNjYXJkIGFsbCBzcGFjZSBoZWxkIGJ5IHRoZSB0Y3AKICoJZGlzY2FyZCBpbnRlcm5ldCBwcm90b2NvbCBibG9jawogKgl3YWtlIHVwIGFueSBzbGVlcGVycwogKi8Kc3RydWN0IHRjcGNiICoKdGNwX2Nsb3NlKHRwKQoJcmVnaXN0ZXIgc3RydWN0IHRjcGNiICp0cDsKewoJcmVnaXN0ZXIgc3RydWN0IHRjcGlwaGRyICp0OwoJc3RydWN0IHNvY2tldCAqc28gPSB0cC0+dF9zb2NrZXQ7CglyZWdpc3RlciBzdHJ1Y3QgbWJ1ZiAqbTsKCglERUJVR19DQUxMKCJ0Y3BfY2xvc2UiKTsKCURFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyApdHApOwoJCgkvKiBmcmVlIHRoZSByZWFzc2VtYmx5IHF1ZXVlLCBpZiBhbnkgKi8KCXQgPSAoc3RydWN0IHRjcGlwaGRyICopIHRwLT5zZWdfbmV4dDsKCXdoaWxlICh0ICE9IChzdHJ1Y3QgdGNwaXBoZHIgKil0cCkgewoJCXQgPSAoc3RydWN0IHRjcGlwaGRyICopdC0+dGlfbmV4dDsKCQltID0gKHN0cnVjdCBtYnVmICopIFJFQVNTX01CVUYoKHN0cnVjdCB0Y3BpcGhkciAqKXQtPnRpX3ByZXYpOwoJCXJlbXF1ZV8zMigoc3RydWN0IHRjcGlwaGRyICopIHQtPnRpX3ByZXYpOwoJCW1fZnJlZW0obSk7Cgl9CgkvKiBJdCdzIHN0YXRpYyAqLwovKglpZiAodHAtPnRfdGVtcGxhdGUpCiAqCQkodm9pZCkgbV9mcmVlKGR0b20odHAtPnRfdGVtcGxhdGUpKTsKICovCi8qCWZyZWUodHAsIE1fUENCKTsgICovCglmcmVlKHRwKTsKCXNvLT5zb190Y3BjYiA9IDA7Cglzb2lzZmRpc2Nvbm5lY3RlZChzbyk7CgkvKiBjbG9iYmVyIGlucHV0IHNvY2tldCBjYWNoZSBpZiB3ZSdyZSBjbG9zaW5nIHRoZSBjYWNoZWQgY29ubmVjdGlvbiAqLwoJaWYgKHNvID09IHRjcF9sYXN0X3NvKQoJCXRjcF9sYXN0X3NvID0gJnRjYjsKCWNsb3Nlc29ja2V0KHNvLT5zKTsKCXNiZnJlZSgmc28tPnNvX3Jjdik7CglzYmZyZWUoJnNvLT5zb19zbmQpOwoJc29mcmVlKHNvKTsKCXRjcHN0YXQudGNwc19jbG9zZWQrKzsKCXJldHVybiAoKHN0cnVjdCB0Y3BjYiAqKTApOwp9Cgp2b2lkCnRjcF9kcmFpbigpCnsKCS8qIFhYWCAqLwp9CgovKgogKiBXaGVuIGEgc291cmNlIHF1ZW5jaCBpcyByZWNlaXZlZCwgY2xvc2UgY29uZ2VzdGlvbiB3aW5kb3cKICogdG8gb25lIHNlZ21lbnQuICBXZSB3aWxsIGdyYWR1YWxseSBvcGVuIGl0IGFnYWluIGFzIHdlIHByb2NlZWQuCiAqLwoKI2lmZGVmIG5vdGRlZgoKdm9pZAp0Y3BfcXVlbmNoKGksIGVycm5vKQoKCWludCBlcnJubzsKewoJc3RydWN0IHRjcGNiICp0cCA9IGludG90Y3BjYihpbnApOwoKCWlmICh0cCkKCQl0cC0+c25kX2N3bmQgPSB0cC0+dF9tYXhzZWc7Cn0KCiNlbmRpZiAvKiBub3RkZWYgKi8KCi8qCiAqIFRDUCBwcm90b2NvbCBpbnRlcmZhY2UgdG8gc29ja2V0IGFic3RyYWN0aW9uLgogKi8KCi8qCiAqIFVzZXIgaXNzdWVkIGNsb3NlLCBhbmQgd2lzaCB0byB0cmFpbCB0aHJvdWdoIHNodXRkb3duIHN0YXRlczoKICogaWYgbmV2ZXIgcmVjZWl2ZWQgU1lOLCBqdXN0IGZvcmdldCBpdC4gIElmIGdvdCBhIFNZTiBmcm9tIHBlZXIsCiAqIGJ1dCBoYXZlbid0IHNlbnQgRklOLCB0aGVuIGdvIHRvIEZJTl9XQUlUXzEgc3RhdGUgdG8gc2VuZCBwZWVyIGEgRklOLgogKiBJZiBhbHJlYWR5IGdvdCBhIEZJTiBmcm9tIHBlZXIsIHRoZW4gYWxtb3N0IGRvbmU7IGdvIHRvIExBU1RfQUNLCiAqIHN0YXRlLiAgSW4gYWxsIG90aGVyIGNhc2VzLCBoYXZlIGFscmVhZHkgc2VudCBGSU4gdG8gcGVlciAoZS5nLgogKiBhZnRlciBQUlVfU0hVVERPV04pLCBhbmQganVzdCBoYXZlIHRvIHBsYXkgdGVkaW91cyBnYW1lIHdhaXRpbmcKICogZm9yIHBlZXIgdG8gc2VuZCBGSU4gb3Igbm90IHJlc3BvbmQgdG8ga2VlcC1hbGl2ZXMsIGV0Yy4KICogV2UgY2FuIGxldCB0aGUgdXNlciBleGl0IGZyb20gdGhlIGNsb3NlIGFzIHNvb24gYXMgdGhlIEZJTiBpcyBhY2tlZC4KICovCnZvaWQKdGNwX3NvY2tjbG9zZWQodHApCglzdHJ1Y3QgdGNwY2IgKnRwOwp7CgoJREVCVUdfQ0FMTCgidGNwX3NvY2tjbG9zZWQiKTsKCURFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyl0cCk7CgkKCXN3aXRjaCAodHAtPnRfc3RhdGUpIHsKCgljYXNlIFRDUFNfQ0xPU0VEOgoJY2FzZSBUQ1BTX0xJU1RFTjoKCWNhc2UgVENQU19TWU5fU0VOVDoKCQl0cC0+dF9zdGF0ZSA9IFRDUFNfQ0xPU0VEOwoJCXRwID0gdGNwX2Nsb3NlKHRwKTsKCQlicmVhazsKCgljYXNlIFRDUFNfU1lOX1JFQ0VJVkVEOgoJY2FzZSBUQ1BTX0VTVEFCTElTSEVEOgoJCXRwLT50X3N0YXRlID0gVENQU19GSU5fV0FJVF8xOwoJCWJyZWFrOwoKCWNhc2UgVENQU19DTE9TRV9XQUlUOgoJCXRwLT50X3N0YXRlID0gVENQU19MQVNUX0FDSzsKCQlicmVhazsKCX0KLyoJc29pc2ZkaXNjb25uZWN0aW5nKHRwLT50X3NvY2tldCk7ICovCglpZiAodHAgJiYgdHAtPnRfc3RhdGUgPj0gVENQU19GSU5fV0FJVF8yKQoJCXNvaXNmZGlzY29ubmVjdGVkKHRwLT50X3NvY2tldCk7CglpZiAodHApCgkJdGNwX291dHB1dCh0cCk7Cn0KCi8qIAogKiBDb25uZWN0IHRvIGEgaG9zdCBvbiB0aGUgSW50ZXJuZXQKICogQ2FsbGVkIGJ5IHRjcF9pbnB1dAogKiBPbmx5IGRvIGEgY29ubmVjdCwgdGhlIHRjcCBmaWVsZHMgd2lsbCBiZSBzZXQgaW4gdGNwX2lucHV0CiAqIHJldHVybiAwIGlmIHRoZXJlJ3MgYSByZXN1bHQgb2YgdGhlIGNvbm5lY3QsCiAqIGVsc2UgcmV0dXJuIC0xIG1lYW5zIHdlJ3JlIHN0aWxsIGNvbm5lY3RpbmcKICogVGhlIHJldHVybiB2YWx1ZSBpcyBhbG1vc3QgYWx3YXlzIC0xIHNpbmNlIHRoZSBzb2NrZXQgaXMKICogbm9uYmxvY2tpbmcuICBDb25uZWN0IHJldHVybnMgYWZ0ZXIgdGhlIFNZTiBpcyBzZW50LCBhbmQgZG9lcyAKICogbm90IHdhaXQgZm9yIEFDSytTWU4uCiAqLwppbnQgdGNwX2Zjb25uZWN0KHNvKQogICAgIHN0cnVjdCBzb2NrZXQgKnNvOwp7CiAgaW50IHJldD0wOwogIAogIERFQlVHX0NBTEwoInRjcF9mY29ubmVjdCIpOwogIERFQlVHX0FSRygic28gPSAlbHgiLCAobG9uZyApc28pOwoKICBpZiggKHJldD1zby0+cz1zb2NrZXQoQUZfSU5FVCxTT0NLX1NUUkVBTSwwKSkgPj0gMCkgewogICAgaW50IG9wdCwgcz1zby0+czsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZGRyOwoKICAgIGZkX25vbmJsb2NrKHMpOwogICAgb3B0ID0gMTsKICAgIHNldHNvY2tvcHQocyxTT0xfU09DS0VULFNPX1JFVVNFQUREUiwoY2hhciAqKSZvcHQsc2l6ZW9mKG9wdCApKTsKICAgIG9wdCA9IDE7CiAgICBzZXRzb2Nrb3B0KHMsU09MX1NPQ0tFVCxTT19PT0JJTkxJTkUsKGNoYXIgKikmb3B0LHNpemVvZihvcHQgKSk7CiAgICAKICAgIGFkZHIuc2luX2ZhbWlseSA9IEFGX0lORVQ7CiAgICBpZiAoKHNvLT5zb19mYWRkci5zX2FkZHIgJiBodG9ubCgweGZmZmZmZjAwKSkgPT0gc3BlY2lhbF9hZGRyLnNfYWRkcikgewogICAgICAvKiBJdCdzIGFuIGFsaWFzICovCiAgICAgIHN3aXRjaChudG9obChzby0+c29fZmFkZHIuc19hZGRyKSAmIDB4ZmYpIHsKICAgICAgY2FzZSBDVExfRE5TOgoJYWRkci5zaW5fYWRkciA9IGRuc19hZGRyOwoJYnJlYWs7CiAgICAgIGNhc2UgQ1RMX0FMSUFTOgogICAgICBkZWZhdWx0OgoJYWRkci5zaW5fYWRkciA9IGxvb3BiYWNrX2FkZHI7CglicmVhazsKICAgICAgfQogICAgfSBlbHNlCiAgICAgIGFkZHIuc2luX2FkZHIgPSBzby0+c29fZmFkZHI7CiAgICBhZGRyLnNpbl9wb3J0ID0gc28tPnNvX2Zwb3J0OwogICAgCiAgICBERUJVR19NSVNDKChkZmQsICIgY29ubmVjdCgpaW5nLCBhZGRyLnNpbl9wb3J0PSVkLCAiCgkJImFkZHIuc2luX2FkZHIuc19hZGRyPSUuMTZzXG4iLCAKCQludG9ocyhhZGRyLnNpbl9wb3J0KSwgaW5ldF9udG9hKGFkZHIuc2luX2FkZHIpKSk7CiAgICAvKiBXZSBkb24ndCBjYXJlIHdoYXQgcG9ydCB3ZSBnZXQgKi8KICAgIHJldCA9IGNvbm5lY3Qocywoc3RydWN0IHNvY2thZGRyICopJmFkZHIsc2l6ZW9mIChhZGRyKSk7CiAgICAKICAgIC8qCiAgICAgKiBJZiBpdCdzIG5vdCBpbiBwcm9ncmVzcywgaXQgZmFpbGVkLCBzbyB3ZSBqdXN0IHJldHVybiAwLAogICAgICogd2l0aG91dCBjbGVhcmluZyBTU19OT0ZEUkVGCiAgICAgKi8KICAgIHNvaXNmY29ubmVjdGluZyhzbyk7CiAgfQoKICByZXR1cm4ocmV0KTsKfQoKLyoKICogQWNjZXB0IHRoZSBzb2NrZXQgYW5kIGNvbm5lY3QgdG8gdGhlIGxvY2FsLWhvc3QKICogCiAqIFdlIGhhdmUgYSBwcm9ibGVtLiBUaGUgY29ycmVjdCB0aGluZyB0byBkbyB3b3VsZCBiZQogKiB0byBmaXJzdCBjb25uZWN0IHRvIHRoZSBsb2NhbC1ob3N0LCBhbmQgb25seSBpZiB0aGUKICogY29ubmVjdGlvbiBpcyBhY2NlcHRlZCwgdGhlbiBkbyBhbiBhY2NlcHQoKSBoZXJlLgogKiBCdXQsIGEpIHdlIG5lZWQgdG8ga25vdyB3aG8ncyB0cnlpbmcgdG8gY29ubmVjdCAKICogdG8gdGhlIHNvY2tldCB0byBiZSBhYmxlIHRvIFNZTiB0aGUgbG9jYWwtaG9zdCwgYW5kCiAqIGIpIHdlIGFyZSBhbHJlYWR5IGNvbm5lY3RlZCB0byB0aGUgZm9yZWlnbiBob3N0IGJ5CiAqIHRoZSB0aW1lIGl0IGdldHMgdG8gYWNjZXB0KCksIHNvLi4uIFdlIHNpbXBseSBhY2NlcHQKICogaGVyZSBhbmQgU1lOIHRoZSBsb2NhbC1ob3N0LgogKi8gCnZvaWQKdGNwX2Nvbm5lY3QoaW5zbykKCXN0cnVjdCBzb2NrZXQgKmluc287CnsKCXN0cnVjdCBzb2NrZXQgKnNvOwoJc3RydWN0IHNvY2thZGRyX2luIGFkZHI7CglpbnQgYWRkcmxlbiA9IHNpemVvZihzdHJ1Y3Qgc29ja2FkZHJfaW4pOwoJc3RydWN0IHRjcGNiICp0cDsKCWludCBzLCBvcHQ7CgoJREVCVUdfQ0FMTCgidGNwX2Nvbm5lY3QiKTsKCURFQlVHX0FSRygiaW5zbyA9ICVseCIsIChsb25nKWluc28pOwoJCgkvKgoJICogSWYgaXQncyBhbiBTU19BQ0NFUFRPTkNFIHNvY2tldCwgbm8gbmVlZCB0byBzb2NyZWF0ZSgpCgkgKiBhbm90aGVyIHNvY2tldCwganVzdCB1c2UgdGhlIGFjY2VwdCgpIHNvY2tldC4KCSAqLwoJaWYgKGluc28tPnNvX3N0YXRlICYgU1NfRkFDQ0VQVE9OQ0UpIHsKCQkvKiBGQUNDRVBUT05DRSBhbHJlYWR5IGhhdmUgYSB0Y3BjYiAqLwoJCXNvID0gaW5zbzsKCX0gZWxzZSB7CgkJaWYgKChzbyA9IHNvY3JlYXRlKCkpID09IE5VTEwpIHsKCQkJLyogSWYgaXQgZmFpbGVkLCBnZXQgcmlkIG9mIHRoZSBwZW5kaW5nIGNvbm5lY3Rpb24gKi8KCQkJY2xvc2Vzb2NrZXQoYWNjZXB0KGluc28tPnMsKHN0cnVjdCBzb2NrYWRkciAqKSZhZGRyLCZhZGRybGVuKSk7CgkJCXJldHVybjsKCQl9CgkJaWYgKHRjcF9hdHRhY2goc28pIDwgMCkgewoJCQlmcmVlKHNvKTsgLyogTk9UIHNvZnJlZSAqLwoJCQlyZXR1cm47CgkJfQoJCXNvLT5zb19sYWRkciA9IGluc28tPnNvX2xhZGRyOwoJCXNvLT5zb19scG9ydCA9IGluc28tPnNvX2xwb3J0OwoJfQoJCgkodm9pZCkgdGNwX21zcyhzb3RvdGNwY2Ioc28pLCAwKTsKCglpZiAoKHMgPSBhY2NlcHQoaW5zby0+cywoc3RydWN0IHNvY2thZGRyICopJmFkZHIsJmFkZHJsZW4pKSA8IDApIHsKCQl0Y3BfY2xvc2Uoc290b3RjcGNiKHNvKSk7IC8qIFRoaXMgd2lsbCBzb2ZyZWUoKSBhcyB3ZWxsICovCgkJcmV0dXJuOwoJfQoJZmRfbm9uYmxvY2socyk7CglvcHQgPSAxOwoJc2V0c29ja29wdChzLFNPTF9TT0NLRVQsU09fUkVVU0VBRERSLChjaGFyICopJm9wdCxzaXplb2YoaW50KSk7CglvcHQgPSAxOwoJc2V0c29ja29wdChzLFNPTF9TT0NLRVQsU09fT09CSU5MSU5FLChjaGFyICopJm9wdCxzaXplb2YoaW50KSk7CgkKCXNvLT5zb19mcG9ydCA9IGFkZHIuc2luX3BvcnQ7Cglzby0+c29fZmFkZHIgPSBhZGRyLnNpbl9hZGRyOwoJLyogVHJhbnNsYXRlIGNvbm5lY3Rpb25zIGZyb20gbG9jYWxob3N0IHRvIHRoZSByZWFsIGhvc3RuYW1lICovCglpZiAoc28tPnNvX2ZhZGRyLnNfYWRkciA9PSAwIHx8IHNvLT5zb19mYWRkci5zX2FkZHIgPT0gbG9vcGJhY2tfYWRkci5zX2FkZHIpCgkgICBzby0+c29fZmFkZHIgPSBvdXJfYWRkcjsKCQoJLyogQ2xvc2UgdGhlIGFjY2VwdCgpIHNvY2tldCwgc2V0IHJpZ2h0IHN0YXRlICovCglpZiAoaW5zby0+c29fc3RhdGUgJiBTU19GQUNDRVBUT05DRSkgewoJCWNsb3Nlc29ja2V0KHNvLT5zKTsgLyogSWYgd2Ugb25seSBhY2NlcHQgb25jZSwgY2xvc2UgdGhlIGFjY2VwdCgpIHNvY2tldCAqLwoJCXNvLT5zb19zdGF0ZSA9IFNTX05PRkRSRUY7IC8qIERvbid0IHNlbGVjdCBpdCB5ZXQsIGV2ZW4gdGhvdWdoIHdlIGhhdmUgYW4gRkQgKi8KCQkJCQkgICAvKiBpZiBpdCdzIG5vdCBGQUNDRVBUT05DRSwgaXQncyBhbHJlYWR5IE5PRkRSRUYgKi8KCX0KCXNvLT5zID0gczsKCQoJc28tPnNvX2lwdG9zID0gdGNwX3Rvcyhzbyk7Cgl0cCA9IHNvdG90Y3BjYihzbyk7CgoJdGNwX3RlbXBsYXRlKHRwKTsKCQoJLyogQ29tcHV0ZSB3aW5kb3cgc2NhbGluZyB0byByZXF1ZXN0LiAgKi8KLyoJd2hpbGUgKHRwLT5yZXF1ZXN0X3Jfc2NhbGUgPCBUQ1BfTUFYX1dJTlNISUZUICYmCiAqCQkoVENQX01BWFdJTiA8PCB0cC0+cmVxdWVzdF9yX3NjYWxlKSA8IHNvLT5zb19yY3Yuc2JfaGl3YXQpCiAqCQl0cC0+cmVxdWVzdF9yX3NjYWxlKys7CiAqLwoKLyoJc29pc2Nvbm5lY3Rpbmcoc28pOyAqLyAvKiBOT0ZEUkVGIHVzZWQgaW5zdGVhZCAqLwoJdGNwc3RhdC50Y3BzX2Nvbm5hdHRlbXB0Kys7CgkKCXRwLT50X3N0YXRlID0gVENQU19TWU5fU0VOVDsKCXRwLT50X3RpbWVyW1RDUFRfS0VFUF0gPSBUQ1BUVl9LRUVQX0lOSVQ7Cgl0cC0+aXNzID0gdGNwX2lzczsgCgl0Y3BfaXNzICs9IFRDUF9JU1NJTkNSLzI7Cgl0Y3Bfc2VuZHNlcWluaXQodHApOwoJdGNwX291dHB1dCh0cCk7Cn0KCi8qCiAqIEF0dGFjaCBhIFRDUENCIHRvIGEgc29ja2V0LgogKi8KaW50CnRjcF9hdHRhY2goc28pCglzdHJ1Y3Qgc29ja2V0ICpzbzsKewoJaWYgKChzby0+c29fdGNwY2IgPSB0Y3BfbmV3dGNwY2Ioc28pKSA9PSBOVUxMKQoJICAgcmV0dXJuIC0xOwoJCglpbnNxdWUoc28sICZ0Y2IpOwoKCXJldHVybiAwOwp9CgovKgogKiBTZXQgdGhlIHNvY2tldCdzIHR5cGUgb2Ygc2VydmljZSBmaWVsZAogKi8Kc3RydWN0IHRvc190IHRjcHRvc1tdID0gewoJICB7MCwgMjAsIElQVE9TX1RIUk9VR0hQVVQsIDB9LAkvKiBmdHAgZGF0YSAqLwoJICB7MjEsIDIxLCBJUFRPU19MT1dERUxBWSwgIEVNVV9GVFB9LAkvKiBmdHAgY29udHJvbCAqLwoJICB7MCwgMjMsIElQVE9TX0xPV0RFTEFZLCAwfSwJLyogdGVsbmV0ICovCgkgIHswLCA4MCwgSVBUT1NfVEhST1VHSFBVVCwgMH0sCS8qIFdXVyAqLwoJICB7MCwgNTEzLCBJUFRPU19MT1dERUxBWSwgRU1VX1JMT0dJTnxFTVVfTk9DT05ORUNUfSwJLyogcmxvZ2luICovCgkgIHswLCA1MTQsIElQVE9TX0xPV0RFTEFZLCBFTVVfUlNIfEVNVV9OT0NPTk5FQ1R9LAkvKiBzaGVsbCAqLwoJICB7MCwgNTQ0LCBJUFRPU19MT1dERUxBWSwgRU1VX0tTSH0sCQkvKiBrc2hlbGwgKi8KCSAgezAsIDU0MywgSVBUT1NfTE9XREVMQVksIDB9LAkvKiBrbG9naW4gKi8KCSAgezAsIDY2NjcsIElQVE9TX1RIUk9VR0hQVVQsIEVNVV9JUkN9LAkvKiBJUkMgKi8KCSAgezAsIDY2NjgsIElQVE9TX1RIUk9VR0hQVVQsIEVNVV9JUkN9LAkvKiBJUkMgdW5kZXJuZXQgKi8KCSAgezAsIDcwNzAsIElQVE9TX0xPV0RFTEFZLCBFTVVfUkVBTEFVRElPIH0sIC8qIFJlYWxBdWRpbyBjb250cm9sICovCgkgIHswLCAxMTMsIElQVE9TX0xPV0RFTEFZLCBFTVVfSURFTlQgfSwgLyogaWRlbnRkIHByb3RvY29sICovCgkgIHswLCAwLCAwLCAwfQp9OwoKc3RydWN0IGVtdV90ICp0Y3BlbXUgPSAwOwoJCQovKgogKiBSZXR1cm4gVE9TIGFjY29yZGluZyB0byB0aGUgYWJvdmUgdGFibGUKICovCnVfaW50OF90CnRjcF90b3Moc28pCglzdHJ1Y3Qgc29ja2V0ICpzbzsKewoJaW50IGkgPSAwOwoJc3RydWN0IGVtdV90ICplbXVwOwoJCgl3aGlsZSh0Y3B0b3NbaV0udG9zKSB7CgkJaWYgKCh0Y3B0b3NbaV0uZnBvcnQgJiYgKG50b2hzKHNvLT5zb19mcG9ydCkgPT0gdGNwdG9zW2ldLmZwb3J0KSkgfHwKCQkgICAgKHRjcHRvc1tpXS5scG9ydCAmJiAobnRvaHMoc28tPnNvX2xwb3J0KSA9PSB0Y3B0b3NbaV0ubHBvcnQpKSkgewoJCQlzby0+c29fZW11ID0gdGNwdG9zW2ldLmVtdTsKCQkJcmV0dXJuIHRjcHRvc1tpXS50b3M7CgkJfQoJCWkrKzsKCX0KCQoJLyogTm9wZSwgbGV0cyBzZWUgaWYgdGhlcmUncyBhIHVzZXItYWRkZWQgb25lICovCglmb3IgKGVtdXAgPSB0Y3BlbXU7IGVtdXA7IGVtdXAgPSBlbXVwLT5uZXh0KSB7CgkJaWYgKChlbXVwLT5mcG9ydCAmJiAobnRvaHMoc28tPnNvX2Zwb3J0KSA9PSBlbXVwLT5mcG9ydCkpIHx8CgkJICAgIChlbXVwLT5scG9ydCAmJiAobnRvaHMoc28tPnNvX2xwb3J0KSA9PSBlbXVwLT5scG9ydCkpKSB7CgkJCXNvLT5zb19lbXUgPSBlbXVwLT5lbXU7CgkJCXJldHVybiBlbXVwLT50b3M7CgkJfQoJfQoJCglyZXR1cm4gMDsKfQoKaW50IGRvX2VjaG8gPSAtMTsKCi8qCiAqIEVtdWxhdGUgcHJvZ3JhbXMgdGhhdCB0cnkgYW5kIGNvbm5lY3QgdG8gdXMKICogVGhpcyBpbmNsdWRlcyBmdHAgKHRoZSBkYXRhIGNvbm5lY3Rpb24gaXMKICogaW5pdGlhdGVkIGJ5IHRoZSBzZXJ2ZXIpIGFuZCBJUkMgKERDQyBDSEFUIGFuZAogKiBEQ0MgU0VORCkgZm9yIG5vdwogKiAKICogTk9URTogSXQncyBwb3NzaWJsZSB0byBjcmFzaCBTTGlSUCBieSBzZW5kaW5nIGl0CiAqIHVuc3RhbmRhcmQgc3RyaW5ncyB0byBlbXVsYXRlLi4uIGlmIHRoaXMgaXMgYSBwcm9ibGVtLAogKiBtb3JlIGNoZWNrcyBhcmUgbmVlZGVkIGhlcmUKICoKICogWFhYIEFzc3VtZXMgdGhlIHdob2xlIGNvbW1hbmQgY2FtZSBpbiBvbmUgcGFja2V0CiAqCQkJCQkgICAgCiAqIFhYWCBTb21lIGZ0cCBjbGllbnRzIHdpbGwgaGF2ZSB0aGVpciBUT1Mgc2V0IHRvCiAqIExPV0RFTEFZIGFuZCBzbyBOYWdlbCB3aWxsIGtpY2sgaW4uICBCZWNhdXNlIG9mIHRoaXMsCiAqIHdlJ2xsIGdldCB0aGUgZmlyc3QgbGV0dGVyLCBmb2xsb3dlZCBieSB0aGUgcmVzdCwgc28KICogd2Ugc2ltcGx5IHNjYW4gZm9yIE9SVCBpbnN0ZWFkIG9mIFBPUlQuLi4KICogRENDIGRvZXNuJ3QgaGF2ZSB0aGlzIHByb2JsZW0gYmVjYXVzZSB0aGVyZSdzIG90aGVyIHN0dWZmCiAqIGluIHRoZSBwYWNrZXQgYmVmb3JlIHRoZSBEQ0MgY29tbWFuZC4KICogCiAqIFJldHVybiAxIGlmIHRoZSBtYnVmIG0gaXMgc3RpbGwgdmFsaWQgYW5kIHNob3VsZCBiZSAKICogc2JhcHBlbmQoKWVkCiAqIAogKiBOT1RFOiBpZiB5b3UgcmV0dXJuIDAgeW91IE1VU1QgbV9mcmVlKCkgdGhlIG1idWYhCiAqLwppbnQKdGNwX2VtdShzbywgbSkKCXN0cnVjdCBzb2NrZXQgKnNvOwoJc3RydWN0IG1idWYgKm07CnsKCXVfaW50IG4xLCBuMiwgbjMsIG40LCBuNSwgbjY7CgljaGFyIGJ1ZmZbMjU2XTsKCXVfaW50MzJfdCBsYWRkcjsKCXVfaW50IGxwb3J0OwoJY2hhciAqYnB0cjsKCQoJREVCVUdfQ0FMTCgidGNwX2VtdSIpOwoJREVCVUdfQVJHKCJzbyA9ICVseCIsIChsb25nKXNvKTsKCURFQlVHX0FSRygibSA9ICVseCIsIChsb25nKW0pOwoJCglzd2l0Y2goc28tPnNvX2VtdSkgewoJCWludCB4LCBpOwoJCQoJIGNhc2UgRU1VX0lERU5UOgoJCS8qCgkJICogSWRlbnRpZmljYXRpb24gcHJvdG9jb2wgYXMgcGVyIHJmYy0xNDEzCgkJICovCgkJCgkJewoJCQlzdHJ1Y3Qgc29ja2V0ICp0bXBzbzsKCQkJc3RydWN0IHNvY2thZGRyX2luIGFkZHI7CgkJCWludCBhZGRybGVuID0gc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcl9pbik7CgkJCXN0cnVjdCBzYnVmICpzb19yY3YgPSAmc28tPnNvX3JjdjsKCQkJCgkJCW1lbWNweShzb19yY3YtPnNiX3dwdHIsIG0tPm1fZGF0YSwgbS0+bV9sZW4pOwoJCQlzb19yY3YtPnNiX3dwdHIgKz0gbS0+bV9sZW47CgkJCXNvX3Jjdi0+c2JfcnB0ciArPSBtLT5tX2xlbjsKCQkJbS0+bV9kYXRhW20tPm1fbGVuXSA9IDA7IC8qIE5VTEwgdGVybWluYXRlICovCgkJCWlmIChzdHJjaHIobS0+bV9kYXRhLCAnXHInKSB8fCBzdHJjaHIobS0+bV9kYXRhLCAnXG4nKSkgewoJCQkJaWYgKHNzY2FuZihzb19yY3YtPnNiX2RhdGEsICIlZCUqWyAsXSVkIiwgJm4xLCAmbjIpID09IDIpIHsKCQkJCQlIVE9OUyhuMSk7CgkJCQkJSFRPTlMobjIpOwoJCQkJCS8qIG4yIGlzIHRoZSBvbmUgb24gb3VyIGhvc3QgKi8KCQkJCQlmb3IgKHRtcHNvID0gdGNiLnNvX25leHQ7IHRtcHNvICE9ICZ0Y2I7IHRtcHNvID0gdG1wc28tPnNvX25leHQpIHsKCQkJCQkJaWYgKHRtcHNvLT5zb19sYWRkci5zX2FkZHIgPT0gc28tPnNvX2xhZGRyLnNfYWRkciAmJgoJCQkJCQkgICAgdG1wc28tPnNvX2xwb3J0ID09IG4yICYmCgkJCQkJCSAgICB0bXBzby0+c29fZmFkZHIuc19hZGRyID09IHNvLT5zb19mYWRkci5zX2FkZHIgJiYKCQkJCQkJICAgIHRtcHNvLT5zb19mcG9ydCA9PSBuMSkgewoJCQkJCQkJaWYgKGdldHNvY2tuYW1lKHRtcHNvLT5zLAoJCQkJCQkJCShzdHJ1Y3Qgc29ja2FkZHIgKikmYWRkciwgJmFkZHJsZW4pID09IDApCgkJCQkJCQkgICBuMiA9IG50b2hzKGFkZHIuc2luX3BvcnQpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCQlzb19yY3YtPnNiX2NjID0gc3ByaW50Zihzb19yY3YtPnNiX2RhdGEsICIlZCwlZFxyXG4iLCBuMSwgbjIpOwoJCQkJc29fcmN2LT5zYl9ycHRyID0gc29fcmN2LT5zYl9kYXRhOwoJCQkJc29fcmN2LT5zYl93cHRyID0gc29fcmN2LT5zYl9kYXRhICsgc29fcmN2LT5zYl9jYzsKCQkJfQoJCQltX2ZyZWUobSk7CgkJCXJldHVybiAwOwoJCX0KCQkKI2lmIDAKCSBjYXNlIEVNVV9STE9HSU46CgkJLyoKCQkgKiBSbG9naW4gZW11bGF0aW9uCgkJICogRmlyc3Qgd2UgYWNjdW11bGF0ZSBhbGwgdGhlIGluaXRpYWwgb3B0aW9uIG5lZ290aWF0aW9uLAoJCSAqIHRoZW4gZm9ya19leGVjKCkgcmxvZ2luIGFjY29yZGluZyB0byB0aGUgIG9wdGlvbnMKCQkgKi8KCQl7CgkJCWludCBpLCBpMiwgbjsKCQkJY2hhciAqcHRyOwoJCQljaGFyIGFyZ3NbMTAwXTsKCQkJY2hhciB0ZXJtWzEwMF07CgkJCXN0cnVjdCBzYnVmICpzb19zbmQgPSAmc28tPnNvX3NuZDsKCQkJc3RydWN0IHNidWYgKnNvX3JjdiA9ICZzby0+c29fcmN2OwoJCQkKCQkJLyogRmlyc3QgY2hlY2sgaWYgdGhleSBoYXZlIGEgcHJpdmVsYWRnZWQgcG9ydCwgb3IgdG9vIG11Y2ggZGF0YSBoYXMgYXJyaXZlZCAqLwoJCQlpZiAobnRvaHMoc28tPnNvX2xwb3J0KSA+IDEwMjMgfHwgbnRvaHMoc28tPnNvX2xwb3J0KSA8IDUxMiB8fAoJCQkgICAgKG0tPm1fbGVuICsgc29fcmN2LT5zYl93cHRyKSA+IChzb19yY3YtPnNiX2RhdGEgKyBzb19yY3YtPnNiX2RhdGFsZW4pKSB7CgkJCQltZW1jcHkoc29fc25kLT5zYl93cHRyLCAiUGVybWlzc2lvbiBkZW5pZWRcbiIsIDE4KTsKCQkJCXNvX3NuZC0+c2Jfd3B0ciArPSAxODsKCQkJCXNvX3NuZC0+c2JfY2MgKz0gMTg7CgkJCQl0Y3Bfc29ja2Nsb3NlZChzb3RvdGNwY2Ioc28pKTsKCQkJCW1fZnJlZShtKTsKCQkJCXJldHVybiAwOwoJCQl9CgkJCQoJCQkvKiBBcHBlbmQgdGhlIGN1cnJlbnQgZGF0YSAqLwoJCQltZW1jcHkoc29fcmN2LT5zYl93cHRyLCBtLT5tX2RhdGEsIG0tPm1fbGVuKTsKCQkJc29fcmN2LT5zYl93cHRyICs9IG0tPm1fbGVuOwoJCQlzb19yY3YtPnNiX3JwdHIgKz0gbS0+bV9sZW47CgkJCW1fZnJlZShtKTsKCQkJCgkJCS8qCgkJCSAqIENoZWNrIGlmIHdlIGhhdmUgYWxsIHRoZSBpbml0aWFsIG9wdGlvbnMsCgkJCSAqIGFuZCBidWlsZCBhcmd1bWVudCBsaXN0IHRvIHJsb2dpbiB3aGlsZSB3ZSdyZSBoZXJlCgkJCSAqLwoJCQluID0gMDsKCQkJcHRyID0gc29fcmN2LT5zYl9kYXRhOwoJCQlhcmdzWzBdID0gMDsKCQkJdGVybVswXSA9IDA7CgkJCXdoaWxlIChwdHIgPCBzb19yY3YtPnNiX3dwdHIpIHsKCQkJCWlmICgqcHRyKysgPT0gMCkgewoJCQkJCW4rKzsKCQkJCQlpZiAobiA9PSAyKSB7CgkJCQkJCXNwcmludGYoYXJncywgInJsb2dpbiAtbCAlcyAlcyIsCgkJCQkJCQlwdHIsIGluZXRfbnRvYShzby0+c29fZmFkZHIpKTsKCQkJCQl9IGVsc2UgaWYgKG4gPT0gMykgewoJCQkJCQlpMiA9IHNvX3Jjdi0+c2Jfd3B0ciAtIHB0cjsKCQkJCQkJZm9yIChpID0gMDsgaSA8IGkyOyBpKyspIHsKCQkJCQkJCWlmIChwdHJbaV0gPT0gJy8nKSB7CgkJCQkJCQkJcHRyW2ldID0gMDsKI2lmZGVmIEhBVkVfU0VURU5WCgkJCQkJCQkJc3ByaW50Zih0ZXJtLCAiJXMiLCBwdHIpOwojZWxzZQoJCQkJCQkJCXNwcmludGYodGVybSwgIlRFUk09JXMiLCBwdHIpOwojZW5kaWYKCQkJCQkJCQlwdHJbaV0gPSAnLyc7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQkJCgkJCWlmIChuICE9IDQpCgkJCSAgIHJldHVybiAwOwoJCQkKCQkJLyogV2UgaGF2ZSBpdCwgc2V0IG91ciB0ZXJtIHZhcmlhYmxlIGFuZCBmb3JrX2V4ZWMoKSAqLwojaWZkZWYgSEFWRV9TRVRFTlYKCQkJc2V0ZW52KCJURVJNIiwgdGVybSwgMSk7CiNlbHNlCgkJCXB1dGVudih0ZXJtKTsKI2VuZGlmCgkJCWZvcmtfZXhlYyhzbywgYXJncywgMik7CgkJCXRlcm1bMF0gPSAwOwoJCQlzby0+c29fZW11ID0gMDsKCQkJCgkJCS8qIEFuZCBmaW5hbGx5LCBzZW5kIHRoZSBjbGllbnQgYSAwIGNoYXJhY3RlciAqLwoJCQlzb19zbmQtPnNiX3dwdHJbMF0gPSAwOwoJCQlzb19zbmQtPnNiX3dwdHIrKzsKCQkJc29fc25kLT5zYl9jYysrOwoJCQkKCQkJcmV0dXJuIDA7CgkJfQoJCQoJIGNhc2UgRU1VX1JTSDoKCQkvKgoJCSAqIHJzaCBlbXVsYXRpb24KCQkgKiBGaXJzdCB3ZSBhY2N1bXVsYXRlIGFsbCB0aGUgaW5pdGlhbCBvcHRpb24gbmVnb3RpYXRpb24sCgkJICogdGhlbiByc2hfZXhlYygpIHJzaCBhY2NvcmRpbmcgdG8gdGhlICBvcHRpb25zCgkJICovCgkJewoJCQlpbnQgIG47CgkJCWNoYXIgKnB0cjsKCQkJY2hhciAqdXNlcjsKCQkJY2hhciAqYXJnczsKCQkJc3RydWN0IHNidWYgKnNvX3NuZCA9ICZzby0+c29fc25kOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fcmN2ID0gJnNvLT5zb19yY3Y7CgkJCQoJCQkvKiBGaXJzdCBjaGVjayBpZiB0aGV5IGhhdmUgYSBwcml2ZWxhZGdlZCBwb3J0LCBvciB0b28gbXVjaCBkYXRhIGhhcyBhcnJpdmVkICovCgkJCWlmIChudG9ocyhzby0+c29fbHBvcnQpID4gMTAyMyB8fCBudG9ocyhzby0+c29fbHBvcnQpIDwgNTEyIHx8CgkJCSAgICAobS0+bV9sZW4gKyBzb19yY3YtPnNiX3dwdHIpID4gKHNvX3Jjdi0+c2JfZGF0YSArIHNvX3Jjdi0+c2JfZGF0YWxlbikpIHsKCQkJCW1lbWNweShzb19zbmQtPnNiX3dwdHIsICJQZXJtaXNzaW9uIGRlbmllZFxuIiwgMTgpOwoJCQkJc29fc25kLT5zYl93cHRyICs9IDE4OwoJCQkJc29fc25kLT5zYl9jYyArPSAxODsKCQkJCXRjcF9zb2NrY2xvc2VkKHNvdG90Y3BjYihzbykpOwoJCQkJbV9mcmVlKG0pOwoJCQkJcmV0dXJuIDA7CgkJCX0KCQkJCgkJCS8qIEFwcGVuZCB0aGUgY3VycmVudCBkYXRhICovCgkJCW1lbWNweShzb19yY3YtPnNiX3dwdHIsIG0tPm1fZGF0YSwgbS0+bV9sZW4pOwoJCQlzb19yY3YtPnNiX3dwdHIgKz0gbS0+bV9sZW47CgkJCXNvX3Jjdi0+c2JfcnB0ciArPSBtLT5tX2xlbjsKCQkJbV9mcmVlKG0pOwoJCQkKCQkJLyoKCQkJICogQ2hlY2sgaWYgd2UgaGF2ZSBhbGwgdGhlIGluaXRpYWwgb3B0aW9ucywKCQkJICogYW5kIGJ1aWxkIGFyZ3VtZW50IGxpc3QgdG8gcmxvZ2luIHdoaWxlIHdlJ3JlIGhlcmUKCQkJICovCgkJCW4gPSAwOwoJCQlwdHIgPSBzb19yY3YtPnNiX2RhdGE7CgkJCXVzZXI9IiI7CgkJCWFyZ3M9IiI7CgkJCWlmIChzby0+ZXh0cmE9PU5VTEwpIHsKCQkJCXN0cnVjdCBzb2NrZXQgKm5zOwoJCQkJc3RydWN0IHRjcGNiKiB0cDsKCQkJCWludCBwb3J0PWF0b2kocHRyKTsKCQkJCWlmIChwb3J0IDw9IDApIHJldHVybiAwOwogICAgICAgICAgICAgICAgaWYgKHBvcnQgPiAxMDIzIHx8IHBvcnQgPCA1MTIpIHsKICAgICAgICAgICAgICAgICAgbWVtY3B5KHNvX3NuZC0+c2Jfd3B0ciwgIlBlcm1pc3Npb24gZGVuaWVkXG4iLCAxOCk7CiAgICAgICAgICAgICAgICAgIHNvX3NuZC0+c2Jfd3B0ciArPSAxODsKICAgICAgICAgICAgICAgICAgc29fc25kLT5zYl9jYyArPSAxODsKICAgICAgICAgICAgICAgICAgdGNwX3NvY2tjbG9zZWQoc290b3RjcGNiKHNvKSk7CiAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgfQoJCQkJaWYgKChucz1zb2NyZWF0ZSgpKSA9PSBOVUxMKQogICAgICAgICAgICAgICAgICByZXR1cm4gMDsKCQkJCWlmICh0Y3BfYXR0YWNoKG5zKTwwKSB7CiAgICAgICAgICAgICAgICAgIGZyZWUobnMpOwogICAgICAgICAgICAgICAgICByZXR1cm4gMDsKCQkJCX0KCgkJCQlucy0+c29fbGFkZHI9c28tPnNvX2xhZGRyOwoJCQkJbnMtPnNvX2xwb3J0PWh0b25zKHBvcnQpOwoKCQkJCSh2b2lkKSB0Y3BfbXNzKHNvdG90Y3BjYihucyksIDApOwoKCQkJCW5zLT5zb19mYWRkcj1zby0+c29fZmFkZHI7CgkJCQlucy0+c29fZnBvcnQ9aHRvbnMoSVBQT1JUX1JFU0VSVkVELTEpOyAvKiBVc2UgYSBmYWtlIHBvcnQuICovCgoJCQkJaWYgKG5zLT5zb19mYWRkci5zX2FkZHIgPT0gMCB8fCAKCQkJCQlucy0+c29fZmFkZHIuc19hZGRyID09IGxvb3BiYWNrX2FkZHIuc19hZGRyKQogICAgICAgICAgICAgICAgICBucy0+c29fZmFkZHIgPSBvdXJfYWRkcjsKCgkJCQlucy0+c29faXB0b3MgPSB0Y3BfdG9zKG5zKTsKCQkJCXRwID0gc290b3RjcGNiKG5zKTsKICAgICAgICAgICAgICAgIAoJCQkJdGNwX3RlbXBsYXRlKHRwKTsKICAgICAgICAgICAgICAgIAoJCQkJLyogQ29tcHV0ZSB3aW5kb3cgc2NhbGluZyB0byByZXF1ZXN0LiAgKi8KCQkJCS8qCXdoaWxlICh0cC0+cmVxdWVzdF9yX3NjYWxlIDwgVENQX01BWF9XSU5TSElGVCAmJgoJCQkJICoJCShUQ1BfTUFYV0lOIDw8IHRwLT5yZXF1ZXN0X3Jfc2NhbGUpIDwgc28tPnNvX3Jjdi5zYl9oaXdhdCkKCQkJCSAqCQl0cC0+cmVxdWVzdF9yX3NjYWxlKys7CgkJCQkgKi8KCiAgICAgICAgICAgICAgICAvKnNvaXNmY29ubmVjdGluZyhucyk7Ki8KCgkJCQl0Y3BzdGF0LnRjcHNfY29ubmF0dGVtcHQrKzsKCQkJCQkKCQkJCXRwLT50X3N0YXRlID0gVENQU19TWU5fU0VOVDsKCQkJCXRwLT50X3RpbWVyW1RDUFRfS0VFUF0gPSBUQ1BUVl9LRUVQX0lOSVQ7CgkJCQl0cC0+aXNzID0gdGNwX2lzczsgCgkJCQl0Y3BfaXNzICs9IFRDUF9JU1NJTkNSLzI7CgkJCQl0Y3Bfc2VuZHNlcWluaXQodHApOwoJCQkJdGNwX291dHB1dCh0cCk7CgkJCQlzby0+ZXh0cmE9bnM7CgkJCX0KCQkJd2hpbGUgKHB0ciA8IHNvX3Jjdi0+c2Jfd3B0cikgewogICAgICAgICAgICAgIGlmICgqcHRyKysgPT0gMCkgewogICAgICAgICAgICAgICAgbisrOwogICAgICAgICAgICAgICAgaWYgKG4gPT0gMikgewogICAgICAgICAgICAgICAgICB1c2VyPXB0cjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobiA9PSAzKSB7CiAgICAgICAgICAgICAgICAgIGFyZ3M9cHRyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KCQkJfQoJCQkKCQkJaWYgKG4gIT0gNCkKICAgICAgICAgICAgICByZXR1cm4gMDsKCQkJCgkJCXJzaF9leGVjKHNvLHNvLT5leHRyYSwgdXNlciwgaW5ldF9udG9hKHNvLT5zb19mYWRkciksIGFyZ3MpOwoJCQlzby0+c29fZW11ID0gMDsKCQkJc28tPmV4dHJhPU5VTEw7CgkJCQoJCQkvKiBBbmQgZmluYWxseSwgc2VuZCB0aGUgY2xpZW50IGEgMCBjaGFyYWN0ZXIgKi8KCQkJc29fc25kLT5zYl93cHRyWzBdID0gMDsKCQkJc29fc25kLT5zYl93cHRyKys7CgkJCXNvX3NuZC0+c2JfY2MrKzsKCQkJCgkJCXJldHVybiAwOwoJCX0KCgkgY2FzZSBFTVVfQ1RMOgoJCXsKCQkJaW50IG51bTsKCQkJc3RydWN0IHNidWYgKnNvX3NuZCA9ICZzby0+c29fc25kOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fcmN2ID0gJnNvLT5zb19yY3Y7CgkJCQoJCQkvKgoJCQkgKiBJZiB0aGVyZSBpcyBiaW5hcnkgZGF0YSBoZXJlLCB3ZSBzYXZlIGl0IGluIHNvLT5zb19tCgkJCSAqLwoJCQlpZiAoIXNvLT5zb19tKSB7CgkJCSAgaW50IHJ4bGVuOwoJCQkgIGNoYXIgKnJ4ZGF0YTsKCQkJICByeGRhdGE9bXRvZChtLCBjaGFyICopOwoJCQkgIGZvciAocnhsZW49bS0+bV9sZW47IHJ4bGVuOyByeGxlbi0tKSB7CgkJCSAgICBpZiAoKnJ4ZGF0YSsrICYgMHg4MCkgewoJCQkgICAgICBzby0+c29fbSA9IG07CgkJCSAgICAgIHJldHVybiAwOwoJCQkgICAgfQoJCQkgIH0KCQkJfSAvKiBpZihzby0+c29fbT09TlVMTCkgKi8KCQkJCgkJCS8qCgkJCSAqIEFwcGVuZCB0aGUgbGluZQoJCQkgKi8KCQkJc2JhcHBlbmRzYihzb19yY3YsIG0pOwoJCQkKCQkJLyogVG8gYXZvaWQgZ29pbmcgb3ZlciB0aGUgZWRnZSBvZiB0aGUgYnVmZmVyLCB3ZSByZXNldCBpdCAqLwoJCQlpZiAoc29fc25kLT5zYl9jYyA9PSAwKQoJCQkgICBzb19zbmQtPnNiX3dwdHIgPSBzb19zbmQtPnNiX3JwdHIgPSBzb19zbmQtPnNiX2RhdGE7CgkJCQoJCQkvKgoJCQkgKiBBIGJpdCBvZiBhIGhhY2s6CgkJCSAqIElmIHRoZSBmaXJzdCBwYWNrZXQgd2UgZ2V0IGhlcmUgaXMgMSBieXRlIGxvbmcsIHRoZW4gaXQKCQkJICogd2FzIGRvbmUgaW4gdGVsbmV0IGNoYXJhY3RlciBtb2RlLCB0aGVyZWZvcmUgd2UgbXVzdCBlY2hvCgkJCSAqIHRoZSBjaGFyYWN0ZXJzIGFzIHRoZXkgY29tZS4gIE90aGVyd2lzZSwgd2UgZWNobyBub3RoaW5nLAoJCQkgKiBiZWNhdXNlIGluIGxpbmVtb2RlLCB0aGUgbGluZSBpcyBhbHJlYWR5IGVjaG9lZAoJCQkgKiBYWFggdHdvIG9yIG1vcmUgY29udHJvbCBjb25uZWN0aW9ucyB3b24ndCB3b3JrCgkJCSAqLwoJCQlpZiAoZG9fZWNobyA9PSAtMSkgewoJCQkJaWYgKG0tPm1fbGVuID09IDEpIGRvX2VjaG8gPSAxOwoJCQkJZWxzZSBkb19lY2hvID0gMDsKCQkJfQoJCQlpZiAoZG9fZWNobykgewoJCQkgIHNiYXBwZW5kc2Ioc29fc25kLCBtKTsKCQkJICBtX2ZyZWUobSk7CgkJCSAgdGNwX291dHB1dChzb3RvdGNwY2Ioc28pKTsgLyogWFhYICovCgkJCX0gZWxzZQoJCQkgIG1fZnJlZShtKTsKCQkJCgkJCW51bSA9IDA7CgkJCXdoaWxlIChudW0gPCBzby0+c29fcmN2LnNiX2NjKSB7CgkJCQlpZiAoKihzby0+c29fcmN2LnNiX3JwdHIgKyBudW0pID09ICdcbicgfHwKCQkJCSAgICAqKHNvLT5zb19yY3Yuc2JfcnB0ciArIG51bSkgPT0gJ1xyJykgewoJCQkJCWludCBuOwoJCQkJCQoJCQkJCSooc29fcmN2LT5zYl9ycHRyICsgbnVtKSA9IDA7CgkJCQkJaWYgKGN0bF9wYXNzd29yZCAmJiAhY3RsX3Bhc3N3b3JkX29rKSB7CgkJCQkJCS8qIE5lZWQgYSBwYXNzd29yZCAqLwoJCQkJCQlpZiAoc3NjYW5mKHNvX3Jjdi0+c2JfcnB0ciwgInBhc3MgJTI1NnMiLCBidWZmKSA9PSAxKSB7CgkJCQkJCQlpZiAoc3RyY21wKGJ1ZmYsIGN0bF9wYXNzd29yZCkgPT0gMCkgewoJCQkJCQkJCWN0bF9wYXNzd29yZF9vayA9IDE7CgkJCQkJCQkJbiA9IHNwcmludGYoc29fc25kLT5zYl93cHRyLAoJCQkJCQkJCQkgICAgIlBhc3N3b3JkIE9LLlxyXG4iKTsKCQkJCQkJCQlnb3RvIGRvX3Byb21wdDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQluID0gc3ByaW50Zihzb19zbmQtPnNiX3dwdHIsCgkJCQkJICJFcnJvcjogUGFzc3dvcmQgcmVxdWlyZWQsIGxvZyBvbiB3aXRoIFwicGFzcyBQQVNTV09SRFwiXHJcbiIpOwoJCQkJCQlnb3RvIGRvX3Byb21wdDsKCQkJCQl9CgkJCQkJY2ZnX3F1aXR0aW5nID0gMDsKCQkJCQluID0gZG9fY29uZmlnKHNvX3Jjdi0+c2JfcnB0ciwgc28sIFBSTl9TUFJJTlRGKTsKCQkJCQlpZiAoIWNmZ19xdWl0dGluZykgewoJCQkJCQkvKiBSZWdpc3RlciB0aGUgcHJpbnRlZCBkYXRhICovCmRvX3Byb21wdDoKCQkJCQkJc29fc25kLT5zYl9jYyArPSBuOwoJCQkJCQlzb19zbmQtPnNiX3dwdHIgKz0gbjsKCQkJCQkJLyogQWRkIHByb21wdCAqLwoJCQkJCQluID0gc3ByaW50Zihzb19zbmQtPnNiX3dwdHIsICJTbGlycD4gIik7CgkJCQkJCXNvX3NuZC0+c2JfY2MgKz0gbjsKCQkJCQkJc29fc25kLT5zYl93cHRyICs9IG47CgkJCQkJfQoJCQkJCS8qIERyb3Agc29fcmN2IGRhdGEgKi8KCQkJCQlzb19yY3YtPnNiX2NjID0gMDsKCQkJCQlzb19yY3YtPnNiX3dwdHIgPSBzb19yY3YtPnNiX3JwdHIgPSBzb19yY3YtPnNiX2RhdGE7CgkJCQkJdGNwX291dHB1dChzb3RvdGNwY2Ioc28pKTsgLyogU2VuZCB0aGUgcmVwbHkgKi8KCQkJCX0KCQkJCW51bSsrOwoJCQl9CgkJCXJldHVybiAwOwoJCX0KI2VuZGlmCQkKICAgICAgICBjYXNlIEVNVV9GVFA6IC8qIGZ0cCAqLwoJCSoobS0+bV9kYXRhK20tPm1fbGVuKSA9IDA7IC8qIE5VTEwgdGVybWluYXRlIGZvciBzdHJzdHIgKi8KCQlpZiAoKGJwdHIgPSAoY2hhciAqKXN0cnN0cihtLT5tX2RhdGEsICJPUlQiKSkgIT0gTlVMTCkgewoJCQkvKgoJCQkgKiBOZWVkIHRvIGVtdWxhdGUgdGhlIFBPUlQgY29tbWFuZAoJCQkgKi8JCQkKCQkJeCA9IHNzY2FuZihicHRyLCAiT1JUICVkLCVkLCVkLCVkLCVkLCVkXHJcbiUyNTZbXlwxNzddIiwgCgkJCQkgICAmbjEsICZuMiwgJm4zLCAmbjQsICZuNSwgJm42LCBidWZmKTsKCQkJaWYgKHggPCA2KQoJCQkgICByZXR1cm4gMTsKCQkJCgkJCWxhZGRyID0gaHRvbmwoKG4xIDw8IDI0KSB8IChuMiA8PCAxNikgfCAobjMgPDwgOCkgfCAobjQpKTsKCQkJbHBvcnQgPSBodG9ucygobjUgPDwgOCkgfCAobjYpKTsKCQkJCgkJCWlmICgoc28gPSBzb2xpc3RlbigwLCBsYWRkciwgbHBvcnQsIFNTX0ZBQ0NFUFRPTkNFKSkgPT0gTlVMTCkKCQkJICAgcmV0dXJuIDE7CgkJCQoJCQluNiA9IG50b2hzKHNvLT5zb19mcG9ydCk7CgkJCQoJCQluNSA9IChuNiA+PiA4KSAmIDB4ZmY7CgkJCW42ICY9IDB4ZmY7CgkJCQoJCQlsYWRkciA9IG50b2hsKHNvLT5zb19mYWRkci5zX2FkZHIpOwoJCQkKCQkJbjEgPSAoKGxhZGRyID4+IDI0KSAmIDB4ZmYpOwoJCQluMiA9ICgobGFkZHIgPj4gMTYpICYgMHhmZik7CgkJCW4zID0gKChsYWRkciA+PiA4KSAgJiAweGZmKTsKCQkJbjQgPSAgKGxhZGRyICYgMHhmZik7CgkJCQoJCQltLT5tX2xlbiA9IGJwdHIgLSBtLT5tX2RhdGE7IC8qIEFkanVzdCBsZW5ndGggKi8KCQkJbS0+bV9sZW4gKz0gc3ByaW50ZihicHRyLCJPUlQgJWQsJWQsJWQsJWQsJWQsJWRcclxuJXMiLCAKCQkJCQkgICAgbjEsIG4yLCBuMywgbjQsIG41LCBuNiwgeD09Nz9idWZmOiIiKTsKCQkJcmV0dXJuIDE7CgkJfSBlbHNlIGlmICgoYnB0ciA9IChjaGFyICopc3Ryc3RyKG0tPm1fZGF0YSwgIjI3IEVudGVyaW5nIikpICE9IE5VTEwpIHsKCQkJLyoKCQkJICogTmVlZCB0byBlbXVsYXRlIHRoZSBQQVNWIHJlc3BvbnNlCgkJCSAqLwoJCQl4ID0gc3NjYW5mKGJwdHIsICIyNyBFbnRlcmluZyBQYXNzaXZlIE1vZGUgKCVkLCVkLCVkLCVkLCVkLCVkKVxyXG4lMjU2W15cMTc3XSIsCgkJCQkgICAmbjEsICZuMiwgJm4zLCAmbjQsICZuNSwgJm42LCBidWZmKTsKCQkJaWYgKHggPCA2KQoJCQkgICByZXR1cm4gMTsKCQkJCgkJCWxhZGRyID0gaHRvbmwoKG4xIDw8IDI0KSB8IChuMiA8PCAxNikgfCAobjMgPDwgOCkgfCAobjQpKTsKCQkJbHBvcnQgPSBodG9ucygobjUgPDwgOCkgfCAobjYpKTsKCQkJCgkJCWlmICgoc28gPSBzb2xpc3RlbigwLCBsYWRkciwgbHBvcnQsIFNTX0ZBQ0NFUFRPTkNFKSkgPT0gTlVMTCkKCQkJICAgcmV0dXJuIDE7CgkJCQoJCQluNiA9IG50b2hzKHNvLT5zb19mcG9ydCk7CgkJCQoJCQluNSA9IChuNiA+PiA4KSAmIDB4ZmY7CgkJCW42ICY9IDB4ZmY7CgkJCQoJCQlsYWRkciA9IG50b2hsKHNvLT5zb19mYWRkci5zX2FkZHIpOwoJCQkKCQkJbjEgPSAoKGxhZGRyID4+IDI0KSAmIDB4ZmYpOwoJCQluMiA9ICgobGFkZHIgPj4gMTYpICYgMHhmZik7CgkJCW4zID0gKChsYWRkciA+PiA4KSAgJiAweGZmKTsKCQkJbjQgPSAgKGxhZGRyICYgMHhmZik7CgkJCQoJCQltLT5tX2xlbiA9IGJwdHIgLSBtLT5tX2RhdGE7IC8qIEFkanVzdCBsZW5ndGggKi8KCQkJbS0+bV9sZW4gKz0gc3ByaW50ZihicHRyLCIyNyBFbnRlcmluZyBQYXNzaXZlIE1vZGUgKCVkLCVkLCVkLCVkLCVkLCVkKVxyXG4lcyIsCgkJCQkJICAgIG4xLCBuMiwgbjMsIG40LCBuNSwgbjYsIHg9PTc/YnVmZjoiIik7CgkJCQoJCQlyZXR1cm4gMTsKCQl9CgkJCgkJcmV0dXJuIDE7CgkJCQkgICAKCSBjYXNlIEVNVV9LU0g6CgkJLyoKCQkgKiBUaGUga3NoZWxsIChLZXJiZXJvcyByc2gpIGFuZCBzaGVsbCBzZXJ2aWNlcyBib3RoIHBhc3MKCQkgKiBhIGxvY2FsIHBvcnQgcG9ydCBudW1iZXIgdG8gY2Fycnkgc2lnbmFscyB0byB0aGUgc2VydmVyCgkJICogYW5kIHN0ZGVyciB0byB0aGUgY2xpZW50LiAgSXQgaXMgcGFzc2VkIGF0IHRoZSBiZWdpbm5pbmcKCQkgKiBvZiB0aGUgY29ubmVjdGlvbiBhcyBhIE5VTC10ZXJtaW5hdGVkIGRlY2ltYWwgQVNDSUkgc3RyaW5nLgoJCSAqLwoJCXNvLT5zb19lbXUgPSAwOwoJCWZvciAobHBvcnQgPSAwLCBpID0gMDsgaSA8IG0tPm1fbGVuLTE7ICsraSkgewoJCQlpZiAobS0+bV9kYXRhW2ldIDwgJzAnIHx8IG0tPm1fZGF0YVtpXSA+ICc5JykKCQkJCXJldHVybiAxOyAgICAgICAvKiBpbnZhbGlkIG51bWJlciAqLwoJCQlscG9ydCAqPSAxMDsKCQkJbHBvcnQgKz0gbS0+bV9kYXRhW2ldIC0gJzAnOwoJCX0KCQlpZiAobS0+bV9kYXRhW20tPm1fbGVuLTFdID09ICdcMCcgJiYgbHBvcnQgIT0gMCAmJgoJCSAgICAoc28gPSBzb2xpc3RlbigwLCBzby0+c29fbGFkZHIuc19hZGRyLCBodG9ucyhscG9ydCksIFNTX0ZBQ0NFUFRPTkNFKSkgIT0gTlVMTCkKCQkJbS0+bV9sZW4gPSBzcHJpbnRmKG0tPm1fZGF0YSwgIiVkIiwgbnRvaHMoc28tPnNvX2Zwb3J0KSkrMTsKCQlyZXR1cm4gMTsKCQkKCSBjYXNlIEVNVV9JUkM6CgkJLyoKCQkgKiBOZWVkIHRvIGVtdWxhdGUgRENDIENIQVQsIERDQyBTRU5EIGFuZCBEQ0MgTU9WRQoJCSAqLwoJCSoobS0+bV9kYXRhK20tPm1fbGVuKSA9IDA7IC8qIE5VTEwgdGVybWluYXRlIHRoZSBzdHJpbmcgZm9yIHN0cnN0ciAqLwoJCWlmICgoYnB0ciA9IChjaGFyICopc3Ryc3RyKG0tPm1fZGF0YSwgIkRDQyIpKSA9PSBOVUxMKQoJCQkgcmV0dXJuIDE7CgkJCgkJLyogVGhlICUyNTZzIGlzIGZvciB0aGUgYnJva2VuIG1JUkMgKi8KCQlpZiAoc3NjYW5mKGJwdHIsICJEQ0MgQ0hBVCAlMjU2cyAldSAldSIsIGJ1ZmYsICZsYWRkciwgJmxwb3J0KSA9PSAzKSB7CgkJCWlmICgoc28gPSBzb2xpc3RlbigwLCBodG9ubChsYWRkciksIGh0b25zKGxwb3J0KSwgU1NfRkFDQ0VQVE9OQ0UpKSA9PSBOVUxMKQoJCQkJcmV0dXJuIDE7CgkJCQoJCQltLT5tX2xlbiA9IGJwdHIgLSBtLT5tX2RhdGE7IC8qIEFkanVzdCBsZW5ndGggKi8KCQkJbS0+bV9sZW4gKz0gc3ByaW50ZihicHRyLCAiRENDIENIQVQgY2hhdCAlbHUgJXUlY1xuIiwKCQkJICAgICAodW5zaWduZWQgbG9uZyludG9obChzby0+c29fZmFkZHIuc19hZGRyKSwKCQkJICAgICBudG9ocyhzby0+c29fZnBvcnQpLCAxKTsKCQl9IGVsc2UgaWYgKHNzY2FuZihicHRyLCAiRENDIFNFTkQgJTI1NnMgJXUgJXUgJXUiLCBidWZmLCAmbGFkZHIsICZscG9ydCwgJm4xKSA9PSA0KSB7CgkJCWlmICgoc28gPSBzb2xpc3RlbigwLCBodG9ubChsYWRkciksIGh0b25zKGxwb3J0KSwgU1NfRkFDQ0VQVE9OQ0UpKSA9PSBOVUxMKQoJCQkJcmV0dXJuIDE7CgkJCQoJCQltLT5tX2xlbiA9IGJwdHIgLSBtLT5tX2RhdGE7IC8qIEFkanVzdCBsZW5ndGggKi8KCQkJbS0+bV9sZW4gKz0gc3ByaW50ZihicHRyLCAiRENDIFNFTkQgJXMgJWx1ICV1ICV1JWNcbiIsIAoJCQkgICAgICBidWZmLCAodW5zaWduZWQgbG9uZyludG9obChzby0+c29fZmFkZHIuc19hZGRyKSwKCQkJICAgICAgbnRvaHMoc28tPnNvX2Zwb3J0KSwgbjEsIDEpOwoJCX0gZWxzZSBpZiAoc3NjYW5mKGJwdHIsICJEQ0MgTU9WRSAlMjU2cyAldSAldSAldSIsIGJ1ZmYsICZsYWRkciwgJmxwb3J0LCAmbjEpID09IDQpIHsKCQkJaWYgKChzbyA9IHNvbGlzdGVuKDAsIGh0b25sKGxhZGRyKSwgaHRvbnMobHBvcnQpLCBTU19GQUNDRVBUT05DRSkpID09IE5VTEwpCgkJCQlyZXR1cm4gMTsKCQkJCgkJCW0tPm1fbGVuID0gYnB0ciAtIG0tPm1fZGF0YTsgLyogQWRqdXN0IGxlbmd0aCAqLwoJCQltLT5tX2xlbiArPSBzcHJpbnRmKGJwdHIsICJEQ0MgTU9WRSAlcyAlbHUgJXUgJXUlY1xuIiwKCQkJICAgICAgYnVmZiwgKHVuc2lnbmVkIGxvbmcpbnRvaGwoc28tPnNvX2ZhZGRyLnNfYWRkciksCgkJCSAgICAgIG50b2hzKHNvLT5zb19mcG9ydCksIG4xLCAxKTsKCQl9CgkJcmV0dXJuIDE7CgoJIGNhc2UgRU1VX1JFQUxBVURJTzoKICAgICAgICAgICAgICAgIC8qIAoJCSAqIFJlYWxBdWRpbyBlbXVsYXRpb24gLSBKUC4gV2UgbXVzdCB0cnkgdG8gcGFyc2UgdGhlIGluY29taW5nCgkJICogZGF0YSBhbmQgdHJ5IHRvIGZpbmQgdGhlIHR3byBjaGFyYWN0ZXJzIHRoYXQgY29udGFpbiB0aGUKCQkgKiBwb3J0IG51bWJlci4gVGhlbiB3ZSByZWRpcmVjdCBhbiB1ZHAgcG9ydCBhbmQgcmVwbGFjZSB0aGUKCQkgKiBudW1iZXIgd2l0aCB0aGUgcmVhbCBwb3J0IHdlIGdvdC4KCQkgKgoJCSAqIFRoZSAxLjAgYmV0YSB2ZXJzaW9ucyBvZiB0aGUgcGxheWVyIGFyZSBub3Qgc3VwcG9ydGVkCgkJICogYW55IG1vcmUuCgkJICogCgkJICogQSB0eXBpY2FsIHBhY2tldCBmb3IgcGxheWVyIHZlcnNpb24gMS4wIChyZWxlYXNlIHZlcnNpb24pOgoJCSAqICAgICAgICAKCQkgKiAwMDAwOjUwIDRFIDQxIDAwIDA1IAoJCSAqIDAwMDA6MDAgMDEgMDAgMDIgMUIgRDcgMDAgMDAgNjcgRTYgNkMgREMgNjMgMDAgMTIgNTAgLi4uLi7XLi5n5mzcYy4uUAoJCSAqIDAwMTA6NEUgNDMgNEMgNDkgNDUgNEUgNTQgMjAgMzEgMzAgMzEgMjAgNDEgNEMgNTAgNDggTkNMSUVOVCAxMDEgQUxQSAoJCSAqIDAwMjA6NDEgNkMgMDAgMDAgNTIgMDAgMTcgNzIgNjEgNjYgNjkgNkMgNjUgNzMgMkYgNzYgQWwuLlIuLnJhZmlsZXMvdgoJCSAqIDAwMzA6NkYgNjEgMkYgNjUgNkUgNjcgNkMgNjkgNzMgNjggNUYgMkUgNzIgNjEgNzkgNDIgb2EvZW5nbGlzaF8ucmF5QgoJCSAqICAgICAgICAgCgkJICogTm93IHRoZSBwb3J0IG51bWJlciAweDFCRDcgaXMgZm91bmQgYXQgb2Zmc2V0IDB4MDQgb2YgdGhlCgkJICogTm93IHRoZSBwb3J0IG51bWJlciAweDFCRDcgaXMgZm91bmQgYXQgb2Zmc2V0IDB4MDQgb2YgdGhlCgkJICogc2Vjb25kIHBhY2tldC4gVGhpcyB0aW1lIHdlIHJlY2VpdmVkIGZpdmUgYnl0ZXMgZmlyc3QgYW5kCgkJICogdGhlbiB0aGUgcmVzdC4gWW91IG5ldmVyIGtub3cgaG93IG1hbnkgYnl0ZXMgeW91IGdldC4KCQkgKgoJCSAqIEEgdHlwaWNhbCBwYWNrZXQgZm9yIHBsYXllciB2ZXJzaW9uIDIuMCAoYmV0YSk6CgkJICogICAgICAgIAoJCSAqIDAwMDA6NTAgNEUgNDEgMDAgMDYgMDAgMDIgMDAgMDAgMDAgMDEgMDAgMDIgMUIgQzEgMDAgUE5BLi4uLi4uLi4uLi7BLgoJCSAqIDAwMTA6MDAgNjcgNzUgNzggRjUgNjMgMDAgMEEgNTcgNjkgNkUgMzIgMkUgMzAgMkUgMzAgLmd1ePVjLi5XaW4yLjAuMAoJCSAqIDAwMjA6MkUgMzUgNkMgMDAgMDAgNTIgMDAgMUMgNzIgNjEgNjYgNjkgNkMgNjUgNzMgMkYgLjVsLi5SLi5yYWZpbGVzLwoJCSAqIDAwMzA6NzcgNjUgNjIgNzMgNjkgNzQgNjUgMkYgMzIgMzAgNzIgNjUgNkMgNjUgNjEgNzMgd2Vic2l0ZS8yMHJlbGVhcwoJCSAqIDAwNDA6NjUgMkUgNzIgNjEgNzkgNTMgMDAgMDAgMDYgMzYgNDIgICAgICAgICAgICAgICAgZS5yYXlTLi4uNkIKCQkgKiAgICAgICAgCgkJICogUG9ydCBudW1iZXIgMHgxQkMxIGlzIGZvdW5kIGF0IG9mZnNldCAweDBkLgoJCSAqICAgICAgCgkJICogVGhpcyBpcyBqdXN0IGEgaG9ycmlibGUgc3dpdGNoIHN0YXRlbWVudC4gVmFyaWFibGUgcmEgdGVsbHMKCQkgKiB1cyB3aGVyZSB3ZSdyZSBnb2luZy4KCQkgKi8KCQkKCQlicHRyID0gbS0+bV9kYXRhOwoJCXdoaWxlIChicHRyIDwgbS0+bV9kYXRhICsgbS0+bV9sZW4pIHsKCQkJdV9zaG9ydCBwOwoJCQlzdGF0aWMgaW50IHJhID0gMDsKCQkJY2hhciByYV90YmxbNF07IAoJCQkKCQkJcmFfdGJsWzBdID0gMHg1MDsKCQkJcmFfdGJsWzFdID0gMHg0ZTsKCQkJcmFfdGJsWzJdID0gMHg0MTsKCQkJcmFfdGJsWzNdID0gMDsKCQkJCgkJCXN3aXRjaCAocmEpIHsKCQkJIGNhc2UgMDoKCQkJIGNhc2UgMjoKCQkJIGNhc2UgMzoKCQkJCWlmICgqYnB0cisrICE9IHJhX3RibFtyYV0pIHsKCQkJCQlyYSA9IDA7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQlicmVhazsKCQkJCQoJCQkgY2FzZSAxOgoJCQkJLyoKCQkJCSAqIFdlIG1heSBnZXQgMHg1MCBzZXZlcmFsIHRpbWVzLCBpZ25vcmUgdGhlbQoJCQkJICovCgkJCQlpZiAoKmJwdHIgPT0gMHg1MCkgewoJCQkJCXJhID0gMTsKCQkJCQlicHRyKys7CgkJCQkJY29udGludWU7CgkJCQl9IGVsc2UgaWYgKCpicHRyKysgIT0gcmFfdGJsW3JhXSkgewoJCQkJCXJhID0gMDsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJCWJyZWFrOwoJCQkJCgkJCSBjYXNlIDQ6IAoJCQkJLyogCgkJCQkgKiBza2lwIHZlcnNpb24gbnVtYmVyCgkJCQkgKi8KCQkJCWJwdHIrKzsKCQkJCWJyZWFrOwoJCQkJCgkJCSBjYXNlIDU6IAoJCQkJLyoKCQkJCSAqIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdmVyc2lvbnMgMS4wIGFuZAoJCQkJICogMi4wIGlzIGhlcmUuIEZvciBmdXR1cmUgdmVyc2lvbnMgb2YKCQkJCSAqIHRoZSBwbGF5ZXIgdGhpcyBtYXkgbmVlZCB0byBiZSBtb2RpZmllZC4KCQkJCSAqLwoJCQkJaWYgKCooYnB0ciArIDEpID09IDB4MDIpCgkJCQkgICBicHRyICs9IDg7CgkJCQllbHNlCgkJCQkgICBicHRyICs9IDQ7CgkJCQlicmVhazsgICAgICAgICAgICAgICAgICAgICAgICAgIAoJCQkJCgkJCSBjYXNlIDY6CgkJCQkvKiBUaGlzIGlzIHRoZSBmaWVsZCBjb250YWluaW5nIHRoZSBwb3J0CgkJCQkgKiBudW1iZXIgdGhhdCBSQS1wbGF5ZXIgaXMgbGlzdGVuaW5nIHRvLgoJCQkJICovCgkJCQlscG9ydCA9ICgoKHVfY2hhciopYnB0cilbMF0gPDwgOCkgCgkJCQkrICgodV9jaGFyICopYnB0cilbMV07CgkJCQlpZiAobHBvcnQgPCA2OTcwKSAgICAgIAoJCQkJICAgbHBvcnQgKz0gMjU2OyAgIC8qIGRvbid0IGtub3cgd2h5ICovCgkJCQlpZiAobHBvcnQgPCA2OTcwIHx8IGxwb3J0ID4gNzE3MCkKCQkJCSAgIHJldHVybiAxOyAgICAgICAvKiBmYWlsZWQgKi8KCQkJCQoJCQkJLyogdHJ5IHRvIGdldCB1ZHAgcG9ydCBiZXR3ZWVuIDY5NzAgLSA3MTcwICovCgkJCQlmb3IgKHAgPSA2OTcwOyBwIDwgNzA3MTsgcCsrKSB7CgkJCQkJaWYgKHVkcF9saXN0ZW4oIGh0b25zKHApLAoJCQkJCQkgICAgICAgc28tPnNvX2xhZGRyLnNfYWRkciwKCQkJCQkJICAgICAgIGh0b25zKGxwb3J0KSwKCQkJCQkJICAgICAgIFNTX0ZBQ0NFUFRPTkNFKSkgewoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQlpZiAocCA9PSA3MDcxKQoJCQkJICAgcCA9IDA7CgkJCQkqKHVfY2hhciAqKWJwdHIrKyA9IChwID4+IDgpICYgMHhmZjsKCQkJCSoodV9jaGFyICopYnB0cisrID0gcCAmIDB4ZmY7CgkJCQlyYSA9IDA7IAoJCQkJcmV0dXJuIDE7ICAgLyogcG9ydCByZWRpcmVjdGVkLCB3ZSdyZSBkb25lICovCgkJCQlicmVhazsgIAoJCQkJCgkJCSBkZWZhdWx0OgoJCQkJcmEgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAKCQkJfQoJCQlyYSsrOwoJCX0KCQlyZXR1cm4gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoJCQoJIGRlZmF1bHQ6CgkJLyogT29vcHMsIG5vdCBlbXVsYXRlZCwgd29uJ3QgY2FsbCB0Y3BfZW11IGFnYWluICovCgkJc28tPnNvX2VtdSA9IDA7CgkJcmV0dXJuIDE7Cgl9Cn0KCi8qCiAqIERvIG1pc2MuIGNvbmZpZyBvZiBTTGlSUCB3aGlsZSBpdHMgcnVubmluZy4KICogUmV0dXJuIDAgaWYgdGhpcyBjb25uZWN0aW9ucyBpcyB0byBiZSBjbG9zZWQsIDEgb3RoZXJ3aXNlLAogKiByZXR1cm4gMiBpZiB0aGlzIGlzIGEgY29tbWFuZC1saW5lIGNvbm5lY3Rpb24KICovCmludAp0Y3BfY3RsKHNvKQoJc3RydWN0IHNvY2tldCAqc287CnsKCXN0cnVjdCBzYnVmICpzYiA9ICZzby0+c29fc25kOwoJaW50IGNvbW1hbmQ7CiAJc3RydWN0IGV4X2xpc3QgKmV4X3B0cjsKCWludCBkb19wdHk7CiAgICAgICAgLy8Jc3RydWN0IHNvY2tldCAqdG1wc287CgkKCURFQlVHX0NBTEwoInRjcF9jdGwiKTsKCURFQlVHX0FSRygic28gPSAlbHgiLCAobG9uZyApc28pOwoJCiNpZiAwCgkvKgoJICogQ2hlY2sgaWYgdGhleSdyZSBhdXRob3Jpc2VkCgkgKi8KCWlmIChjdGxfYWRkci5zX2FkZHIgJiYgKGN0bF9hZGRyLnNfYWRkciA9PSAtMSB8fCAoc28tPnNvX2xhZGRyLnNfYWRkciAhPSBjdGxfYWRkci5zX2FkZHIpKSkgewoJCXNiLT5zYl9jYyA9IHNwcmludGYoc2ItPnNiX3dwdHIsIkVycm9yOiBQZXJtaXNzaW9uIGRlbmllZC5cclxuIik7CgkJc2ItPnNiX3dwdHIgKz0gc2ItPnNiX2NjOwoJCXJldHVybiAwOwoJfQojZW5kaWYJCgljb21tYW5kID0gKG50b2hsKHNvLT5zb19mYWRkci5zX2FkZHIpICYgMHhmZik7CgkKCXN3aXRjaChjb21tYW5kKSB7CglkZWZhdWx0OiAvKiBDaGVjayBmb3IgZXhlYydzICovCgkJCgkJLyoKCQkgKiBDaGVjayBpZiBpdCdzIHB0eV9leGVjCgkJICovCgkJZm9yIChleF9wdHIgPSBleGVjX2xpc3Q7IGV4X3B0cjsgZXhfcHRyID0gZXhfcHRyLT5leF9uZXh0KSB7CgkJCWlmIChleF9wdHItPmV4X2Zwb3J0ID09IHNvLT5zb19mcG9ydCAmJgoJCQkgICAgY29tbWFuZCA9PSBleF9wdHItPmV4X2FkZHIpIHsKCQkJCWRvX3B0eSA9IGV4X3B0ci0+ZXhfcHR5OwoJCQkJZ290byBkb19leGVjOwoJCQl9CgkJfQoJCQoJCS8qCgkJICogTm90aGluZyBib3VuZC4uCgkJICovCgkJLyogdGNwX2Zjb25uZWN0KHNvKTsgKi8KCQkKCQkvKiBGQUxMVEhST1VHSCAqLwoJY2FzZSBDVExfQUxJQVM6CgkgIHNiLT5zYl9jYyA9IHNwcmludGYoc2ItPnNiX3dwdHIsCgkJCSAgICAgICJFcnJvcjogTm8gYXBwbGljYXRpb24gY29uZmlndXJlZC5cclxuIik7CgkgIHNiLT5zYl93cHRyICs9IHNiLT5zYl9jYzsKCSAgcmV0dXJuKDApOwoKCWRvX2V4ZWM6CgkJREVCVUdfTUlTQygoZGZkLCAiIGV4ZWN1dGluZyAlcyBcbiIsZXhfcHRyLT5leF9leGVjKSk7CgkJcmV0dXJuKGZvcmtfZXhlYyhzbywgZXhfcHRyLT5leF9leGVjLCBkb19wdHkpKTsKCQkKI2lmIDAKCWNhc2UgQ1RMX0NNRDoKCSAgIGZvciAodG1wc28gPSB0Y2Iuc29fbmV4dDsgdG1wc28gIT0gJnRjYjsgdG1wc28gPSB0bXBzby0+c29fbmV4dCkgewoJICAgICBpZiAodG1wc28tPnNvX2VtdSA9PSBFTVVfQ1RMICYmIAoJCSAhKHRtcHNvLT5zb190Y3BjYj8gCgkJICAgKHRtcHNvLT5zb190Y3BjYi0+dF9zdGF0ZSAmIChUQ1BTX1RJTUVfV0FJVHxUQ1BTX0xBU1RfQUNLKSkKCQkgICA6MCkpIHsKCSAgICAgICAvKiBPb29wcywgY29udHJvbCBjb25uZWN0aW9uIGFscmVhZHkgYWN0aXZlICovCgkgICAgICAgc2ItPnNiX2NjID0gc3ByaW50ZihzYi0+c2Jfd3B0ciwiU29ycnksIGFscmVhZHkgY29ubmVjdGVkLlxyXG4iKTsKCSAgICAgICBzYi0+c2Jfd3B0ciArPSBzYi0+c2JfY2M7CgkgICAgICAgcmV0dXJuIDA7CgkgICAgIH0KCSAgIH0KCSAgIHNvLT5zb19lbXUgPSBFTVVfQ1RMOwoJICAgY3RsX3Bhc3N3b3JkX29rID0gMDsKCSAgIHNiLT5zYl9jYyA9IHNwcmludGYoc2ItPnNiX3dwdHIsICJTbGlycCBjb21tYW5kLWxpbmUgcmVhZHkgKHR5cGUgXCJoZWxwXCIgZm9yIGhlbHApLlxyXG5TbGlycD4gIik7CgkgICBzYi0+c2Jfd3B0ciArPSBzYi0+c2JfY2M7CgkgICBkb19lY2hvPS0xOwoJICAgcmV0dXJuKDIpOwojZW5kaWYKCX0KfQo=