LyoKICogQ29weXJpZ2h0IChjKSAxOTgyLCAxOTg2LCAxOTg4LCAxOTkwLCAxOTkzCiAqCVRoZSBSZWdlbnRzIG9mIHRoZSBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICoJQCgjKXRjcF9zdWJyLmMJOC4xIChCZXJrZWxleSkgNi8xMC85MwogKiB0Y3Bfc3Vici5jLHYgMS41IDE5OTQvMTAvMDggMjI6Mzk6NTggcGhrIEV4cAogKi8KCi8qCiAqIENoYW5nZXMgYW5kIGFkZGl0aW9ucyByZWxhdGluZyB0byBTTGlSUAogKiBDb3B5cmlnaHQgKGMpIDE5OTUgRGFubnkgR2FzcGFyb3Zza2kuCiAqCiAqIFBsZWFzZSByZWFkIHRoZSBmaWxlIENPUFlSSUdIVCBmb3IgdGhlCiAqIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHRoZSBjb3B5cmlnaHQuCiAqLwoKI2RlZmluZSBXQU5UX1NZU19JT0NUTF9ICiNpbmNsdWRlIDxzbGlycC5oPgoKLyogcGF0Y2hhYmxlL3NldHRhYmxlIHBhcmFtZXRlcnMgZm9yIHRjcCAqLwovKiBEb24ndCBkbyByZmMxMzIzIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50cyAqLwojZGVmaW5lIFRDUF9ET19SRkMxMzIzIDAKCi8qCiAqIFRjcCBpbml0aWFsaXphdGlvbgogKi8Kdm9pZCB0Y3BfaW5pdCgpCnsKICAgIHRjcF9pc3MgPSAxOyAvKiB3cm9uZyAqLwogICAgdGNiLnNvX25leHQgPSB0Y2Iuc29fcHJldiA9ICZ0Y2I7Cn0KCi8qCiAqIENyZWF0ZSB0ZW1wbGF0ZSB0byBiZSB1c2VkIHRvIHNlbmQgdGNwIHBhY2tldHMgb24gYSBjb25uZWN0aW9uLgogKiBDYWxsIGFmdGVyIGhvc3QgZW50cnkgY3JlYXRlZCwgZmlsbHMKICogaW4gYSBza2VsZXRhbCB0Y3AvaXAgaGVhZGVyLCBtaW5pbWl6aW5nIHRoZSBhbW91bnQgb2Ygd29yawogKiBuZWNlc3Nhcnkgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyB1c2VkLgogKi8KLyogc3RydWN0IHRjcGlwaGRyICogKi8Kdm9pZCB0Y3BfdGVtcGxhdGUodHApIHN0cnVjdCB0Y3BjYiAqdHA7CnsKICAgIHN0cnVjdCBzb2NrZXQgKnNvID0gdHAtPnRfc29ja2V0OwogICAgcmVnaXN0ZXIgc3RydWN0IHRjcGlwaGRyICpuID0gJnRwLT50X3RlbXBsYXRlOwoKICAgIG4tPnRpX21idWYgPSBOVUxMOwogICAgbi0+dGlfeDEgPSAwOwogICAgbi0+dGlfcHIgPSBJUFBST1RPX1RDUDsKICAgIG4tPnRpX2xlbiA9IGh0b25zKHNpemVvZihzdHJ1Y3QgdGNwaXBoZHIpIC0gc2l6ZW9mKHN0cnVjdCBpcCkpOwogICAgbi0+dGlfc3JjID0gc28tPnNvX2ZhZGRyOwogICAgbi0+dGlfZHN0ID0gc28tPnNvX2xhZGRyOwogICAgbi0+dGlfc3BvcnQgPSBzby0+c29fZnBvcnQ7CiAgICBuLT50aV9kcG9ydCA9IHNvLT5zb19scG9ydDsKCiAgICBuLT50aV9zZXEgPSAwOwogICAgbi0+dGlfYWNrID0gMDsKICAgIG4tPnRpX3gyID0gMDsKICAgIG4tPnRpX29mZiA9IDU7CiAgICBuLT50aV9mbGFncyA9IDA7CiAgICBuLT50aV93aW4gPSAwOwogICAgbi0+dGlfc3VtID0gMDsKICAgIG4tPnRpX3VycCA9IDA7Cn0KCi8qCiAqIFNlbmQgYSBzaW5nbGUgbWVzc2FnZSB0byB0aGUgVENQIGF0IGFkZHJlc3Mgc3BlY2lmaWVkIGJ5CiAqIHRoZSBnaXZlbiBUQ1AvSVAgaGVhZGVyLiAgSWYgbSA9PSAwLCB0aGVuIHdlIG1ha2UgYSBjb3B5CiAqIG9mIHRoZSB0Y3BpcGhkciBhdCB0aSBhbmQgc2VuZCBkaXJlY3RseSB0byB0aGUgYWRkcmVzc2VkIGhvc3QuCiAqIFRoaXMgaXMgdXNlZCB0byBmb3JjZSBrZWVwIGFsaXZlIG1lc3NhZ2VzIG91dCB1c2luZyB0aGUgVENQCiAqIHRlbXBsYXRlIGZvciBhIGNvbm5lY3Rpb24gdHAtPnRfdGVtcGxhdGUuICBJZiBmbGFncyBhcmUgZ2l2ZW4KICogdGhlbiB3ZSBzZW5kIGEgbWVzc2FnZSBiYWNrIHRvIHRoZSBUQ1Agd2hpY2ggb3JpZ2luYXRlZCB0aGUKICogc2VnbWVudCB0aSwgYW5kIGRpc2NhcmQgdGhlIG1idWYgY29udGFpbmluZyBpdCBhbmQgYW55IG90aGVyCiAqIGF0dGFjaGVkIG1idWZzLgogKgogKiBJbiBhbnkgY2FzZSB0aGUgYWNrIGFuZCBzZXF1ZW5jZSBudW1iZXIgb2YgdGhlIHRyYW5zbWl0dGVkCiAqIHNlZ21lbnQgYXJlIGFzIHNwZWNpZmllZCBieSB0aGUgcGFyYW1ldGVycy4KICovCnZvaWQgdGNwX3Jlc3BvbmQodHAsIHRpLCBtLCBhY2ssIHNlcSwgZmxhZ3MpIHN0cnVjdCB0Y3BjYiAqdHA7CnJlZ2lzdGVyIHN0cnVjdCB0Y3BpcGhkciAqdGk7CnJlZ2lzdGVyIHN0cnVjdCBtYnVmICptOwp0Y3Bfc2VxIGFjaywgc2VxOwppbnQgZmxhZ3M7CnsKICAgIHJlZ2lzdGVyIGludCB0bGVuOwogICAgaW50IHdpbiA9IDA7CgogICAgREVCVUdfQ0FMTCgidGNwX3Jlc3BvbmQiKTsKICAgIERFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyl0cCk7CiAgICBERUJVR19BUkcoInRpID0gJWx4IiwgKGxvbmcpdGkpOwogICAgREVCVUdfQVJHKCJtID0gJWx4IiwgKGxvbmcpbSk7CiAgICBERUJVR19BUkcoImFjayA9ICV1IiwgYWNrKTsKICAgIERFQlVHX0FSRygic2VxID0gJXUiLCBzZXEpOwogICAgREVCVUdfQVJHKCJmbGFncyA9ICV4IiwgZmxhZ3MpOwoKICAgIGlmICh0cCkKICAgICAgICB3aW4gPSBzYnNwYWNlKCZ0cC0+dF9zb2NrZXQtPnNvX3Jjdik7CiAgICBpZiAobSA9PSAwKSB7CiAgICAgICAgaWYgKChtID0gbV9nZXQoKSkgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuOwojaWZkZWYgVENQX0NPTVBBVF80MgogICAgICAgIHRsZW4gPSAxOwojZWxzZQogICAgICAgIHRsZW4gPSAwOwojZW5kaWYKICAgICAgICBtLT5tX2RhdGEgKz0gSUZfTUFYTElOS0hEUjsKICAgICAgICAqbXRvZChtLCBzdHJ1Y3QgdGNwaXBoZHIgKikgPSAqdGk7CiAgICAgICAgdGkgPSBtdG9kKG0sIHN0cnVjdCB0Y3BpcGhkciAqKTsKICAgICAgICBmbGFncyA9IFRIX0FDSzsKICAgIH0gZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aSBwb2ludHMgaW50byBtIHNvIHRoZSBuZXh0IGxpbmUgaXMganVzdCBtYWtpbmcKICAgICAgICAgKiB0aGUgbWJ1ZiBwb2ludCB0byB0aQogICAgICAgICAqLwogICAgICAgIG0tPm1fZGF0YSA9IChjYWRkcl90KXRpOwoKICAgICAgICBtLT5tX2xlbiA9IHNpemVvZihzdHJ1Y3QgdGNwaXBoZHIpOwogICAgICAgIHRsZW4gPSAwOwojZGVmaW5lIHhjaGcoYSwgYiwgdHlwZSkgXAogICAgeyAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHR5cGUgdDsgICAgICAgICAgXAogICAgICAgIHQgPSBhOyAgICAgICAgICAgXAogICAgICAgIGEgPSBiOyAgICAgICAgICAgXAogICAgICAgIGIgPSB0OyAgICAgICAgICAgXAogICAgfQogICAgICAgIHhjaGcodGktPnRpX2RzdC5zX2FkZHIsIHRpLT50aV9zcmMuc19hZGRyLCB1X2ludDMyX3QpOwogICAgICAgIHhjaGcodGktPnRpX2Rwb3J0LCB0aS0+dGlfc3BvcnQsIHVfaW50MTZfdCk7CiN1bmRlZiB4Y2hnCiAgICB9CiAgICB0aS0+dGlfbGVuID0gaHRvbnMoKHVfc2hvcnQpKHNpemVvZihzdHJ1Y3QgdGNwaGRyKSArIHRsZW4pKTsKICAgIHRsZW4gKz0gc2l6ZW9mKHN0cnVjdCB0Y3BpcGhkcik7CiAgICBtLT5tX2xlbiA9IHRsZW47CgogICAgdGktPnRpX21idWYgPSAwOwogICAgdGktPnRpX3gxID0gMDsKICAgIHRpLT50aV9zZXEgPSBodG9ubChzZXEpOwogICAgdGktPnRpX2FjayA9IGh0b25sKGFjayk7CiAgICB0aS0+dGlfeDIgPSAwOwogICAgdGktPnRpX29mZiA9IHNpemVvZihzdHJ1Y3QgdGNwaGRyKSA+PiAyOwogICAgdGktPnRpX2ZsYWdzID0gZmxhZ3M7CiAgICBpZiAodHApCiAgICAgICAgdGktPnRpX3dpbiA9IGh0b25zKCh1X2ludDE2X3QpKHdpbiA+PiB0cC0+cmN2X3NjYWxlKSk7CiAgICBlbHNlCiAgICAgICAgdGktPnRpX3dpbiA9IGh0b25zKCh1X2ludDE2X3Qpd2luKTsKICAgIHRpLT50aV91cnAgPSAwOwogICAgdGktPnRpX3N1bSA9IDA7CiAgICB0aS0+dGlfc3VtID0gY2tzdW0obSwgdGxlbik7CiAgICAoKHN0cnVjdCBpcCAqKXRpKS0+aXBfbGVuID0gdGxlbjsKCiAgICBpZiAoZmxhZ3MgJiBUSF9SU1QpCiAgICAgICAgKChzdHJ1Y3QgaXAgKil0aSktPmlwX3R0bCA9IE1BWFRUTDsKICAgIGVsc2UKICAgICAgICAoKHN0cnVjdCBpcCAqKXRpKS0+aXBfdHRsID0gSVBERUZUVEw7CgogICAgKHZvaWQpaXBfb3V0cHV0KChzdHJ1Y3Qgc29ja2V0ICopMCwgbSk7Cn0KCi8qCiAqIENyZWF0ZSBhIG5ldyBUQ1AgY29udHJvbCBibG9jaywgbWFraW5nIGFuCiAqIGVtcHR5IHJlYXNzZW1ibHkgcXVldWUgYW5kIGhvb2tpbmcgaXQgdG8gdGhlIGFyZ3VtZW50CiAqIHByb3RvY29sIGNvbnRyb2wgYmxvY2suCiAqLwpzdHJ1Y3QgdGNwY2IgKnRjcF9uZXd0Y3BjYihzbykgc3RydWN0IHNvY2tldCAqc287CnsKICAgIHJlZ2lzdGVyIHN0cnVjdCB0Y3BjYiAqdHA7CgogICAgdHAgPSAoc3RydWN0IHRjcGNiICopbWFsbG9jKHNpemVvZigqdHApKTsKICAgIGlmICh0cCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoKHN0cnVjdCB0Y3BjYiAqKTApOwoKICAgIG1lbXNldCgoY2hhciAqKXRwLCAwLCBzaXplb2Yoc3RydWN0IHRjcGNiKSk7CiAgICB0cC0+c2VnX25leHQgPSB0cC0+c2VnX3ByZXYgPSAoc3RydWN0IHRjcGlwaGRyICopdHA7CiAgICB0cC0+dF9tYXhzZWcgPSBUQ1BfTVNTOwoKICAgIHRwLT50X2ZsYWdzID0gVENQX0RPX1JGQzEzMjMgPyAoVEZfUkVRX1NDQUxFIHwgVEZfUkVRX1RTVE1QKSA6IDA7CiAgICB0cC0+dF9zb2NrZXQgPSBzbzsKCiAgICAvKgogICAgICogSW5pdCBzcnR0IHRvIFRDUFRWX1NSVFRCQVNFICgwKSwgc28gd2UgY2FuIHRlbGwgdGhhdCB3ZSBoYXZlIG5vCiAgICAgKiBydHQgZXN0aW1hdGUuICBTZXQgcnR0dmFyIHNvIHRoYXQgc3J0dCArIDIgKiBydHR2YXIgZ2l2ZXMKICAgICAqIHJlYXNvbmFibGUgaW5pdGlhbCByZXRyYW5zbWl0IHRpbWUuCiAgICAgKi8KICAgIHRwLT50X3NydHQgPSBUQ1BUVl9TUlRUQkFTRTsKICAgIHRwLT50X3J0dHZhciA9IFRDUFRWX1NSVFRERkxUIDw8IDI7CiAgICB0cC0+dF9ydHRtaW4gPSBUQ1BUVl9NSU47CgogICAgVENQVF9SQU5HRVNFVCh0cC0+dF9yeHRjdXIsCiAgICAgICAgICAgICAgICAgICgoVENQVFZfU1JUVEJBU0UgPj4gMikgKyAoVENQVFZfU1JUVERGTFQgPDwgMikpID4+IDEsCiAgICAgICAgICAgICAgICAgIFRDUFRWX01JTiwgVENQVFZfUkVYTVRNQVgpOwoKICAgIHRwLT5zbmRfY3duZCA9IFRDUF9NQVhXSU4gPDwgVENQX01BWF9XSU5TSElGVDsKICAgIHRwLT5zbmRfc3N0aHJlc2ggPSBUQ1BfTUFYV0lOIDw8IFRDUF9NQVhfV0lOU0hJRlQ7CiAgICB0cC0+dF9zdGF0ZSA9IFRDUFNfQ0xPU0VEOwoKICAgIHNvLT5zb190Y3BjYiA9IHRwOwoKICAgIHJldHVybiAodHApOwp9CgovKgogKiBEcm9wIGEgVENQIGNvbm5lY3Rpb24sIHJlcG9ydGluZwogKiB0aGUgc3BlY2lmaWVkIGVycm9yLiAgSWYgY29ubmVjdGlvbiBpcyBzeW5jaHJvbml6ZWQsCiAqIHRoZW4gc2VuZCBhIFJTVCB0byBwZWVyLgogKi8Kc3RydWN0IHRjcGNiICp0Y3BfZHJvcChzdHJ1Y3QgdGNwY2IgKnRwLCBpbnQgZXJyKQp7CiAgICAvKiB0Y3BfZHJvcCh0cCwgZXJybm8pCiAgICAgICAgICAgIHJlZ2lzdGVyIHN0cnVjdCB0Y3BjYiAqdHA7CiAgICAgICAgICAgIGludCBlcnJubzsKICAgIHsKICAgICovCgogICAgREVCVUdfQ0FMTCgidGNwX2Ryb3AiKTsKICAgIERFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyl0cCk7CiAgICBERUJVR19BUkcoImVycm5vID0gJWQiLCBlcnJubyk7CgogICAgaWYgKFRDUFNfSEFWRVJDVkRTWU4odHAtPnRfc3RhdGUpKSB7CiAgICAgICAgdHAtPnRfc3RhdGUgPSBUQ1BTX0NMT1NFRDsKICAgICAgICAodm9pZCl0Y3Bfb3V0cHV0KHRwKTsKICAgICAgICBTVEFUKHRjcHN0YXQudGNwc19kcm9wcysrKTsKICAgIH0gZWxzZQogICAgICAgIFNUQVQodGNwc3RhdC50Y3BzX2Nvbm5kcm9wcysrKTsKICAgIC8qCWlmIChlcnJubyA9PSBFVElNRURPVVQgJiYgdHAtPnRfc29mdGVycm9yKQogICAgICoJCWVycm5vID0gdHAtPnRfc29mdGVycm9yOwogICAgICovCiAgICAvKglzby0+c29fZXJyb3IgPSBlcnJubzsgKi8KICAgIHJldHVybiAodGNwX2Nsb3NlKHRwKSk7Cn0KCi8qCiAqIENsb3NlIGEgVENQIGNvbnRyb2wgYmxvY2s6CiAqCWRpc2NhcmQgYWxsIHNwYWNlIGhlbGQgYnkgdGhlIHRjcAogKglkaXNjYXJkIGludGVybmV0IHByb3RvY29sIGJsb2NrCiAqCXdha2UgdXAgYW55IHNsZWVwZXJzCiAqLwpzdHJ1Y3QgdGNwY2IgKnRjcF9jbG9zZSh0cCkgcmVnaXN0ZXIgc3RydWN0IHRjcGNiICp0cDsKewogICAgcmVnaXN0ZXIgc3RydWN0IHRjcGlwaGRyICp0OwogICAgc3RydWN0IHNvY2tldCAqc28gPSB0cC0+dF9zb2NrZXQ7CiAgICByZWdpc3RlciBzdHJ1Y3QgbWJ1ZiAqbTsKCiAgICBERUJVR19DQUxMKCJ0Y3BfY2xvc2UiKTsKICAgIERFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyl0cCk7CgogICAgLyogZnJlZSB0aGUgcmVhc3NlbWJseSBxdWV1ZSwgaWYgYW55ICovCiAgICB0ID0gdGNwZnJhZ19saXN0X2ZpcnN0KHRwKTsKICAgIHdoaWxlICghdGNwZnJhZ19saXN0X2VuZCh0LCB0cCkpIHsKICAgICAgICB0ID0gdGNwaXBoZHJfbmV4dCh0KTsKICAgICAgICBtID0gdGNwaXBoZHJfcHJldih0KS0+dGlfbWJ1ZjsKICAgICAgICByZW1xdWUodGNwaXBoZHIycWxpbmsodGNwaXBoZHJfcHJldih0KSkpOwogICAgICAgIG1fZnJlZW0obSk7CiAgICB9CiAgICAvKiBJdCdzIHN0YXRpYyAqLwogICAgLyoJaWYgKHRwLT50X3RlbXBsYXRlKQogICAgICoJCSh2b2lkKSBtX2ZyZWUoZHRvbSh0cC0+dF90ZW1wbGF0ZSkpOwogICAgICovCiAgICAvKglmcmVlKHRwLCBNX1BDQik7ICAqLwogICAgZnJlZSh0cCk7CiAgICBzby0+c29fdGNwY2IgPSAwOwogICAgc29pc2ZkaXNjb25uZWN0ZWQoc28pOwogICAgLyogY2xvYmJlciBpbnB1dCBzb2NrZXQgY2FjaGUgaWYgd2UncmUgY2xvc2luZyB0aGUgY2FjaGVkIGNvbm5lY3Rpb24gKi8KICAgIGlmIChzbyA9PSB0Y3BfbGFzdF9zbykKICAgICAgICB0Y3BfbGFzdF9zbyA9ICZ0Y2I7CiAgICBjbG9zZXNvY2tldChzby0+cyk7CiAgICBzYmZyZWUoJnNvLT5zb19yY3YpOwogICAgc2JmcmVlKCZzby0+c29fc25kKTsKICAgIHNvZnJlZShzbyk7CiAgICBTVEFUKHRjcHN0YXQudGNwc19jbG9zZWQrKyk7CiAgICByZXR1cm4gKChzdHJ1Y3QgdGNwY2IgKikwKTsKfQoKI2lmZGVmIG5vdGRlZgp2b2lkIHRjcF9kcmFpbigpCnsKICAgIC8qIFhYWCAqLwp9CgovKgogKiBXaGVuIGEgc291cmNlIHF1ZW5jaCBpcyByZWNlaXZlZCwgY2xvc2UgY29uZ2VzdGlvbiB3aW5kb3cKICogdG8gb25lIHNlZ21lbnQuICBXZSB3aWxsIGdyYWR1YWxseSBvcGVuIGl0IGFnYWluIGFzIHdlIHByb2NlZWQuCiAqLwp2b2lkIHRjcF9xdWVuY2goaSwgZXJybm8pCgogICAgaW50IGVycm5vOwp7CiAgICBzdHJ1Y3QgdGNwY2IgKnRwID0gaW50b3RjcGNiKGlucCk7CgogICAgaWYgKHRwKQogICAgICAgIHRwLT5zbmRfY3duZCA9IHRwLT50X21heHNlZzsKfQoKI2VuZGlmIC8qIG5vdGRlZiAqLwoKLyoKICogVENQIHByb3RvY29sIGludGVyZmFjZSB0byBzb2NrZXQgYWJzdHJhY3Rpb24uCiAqLwoKLyoKICogVXNlciBpc3N1ZWQgY2xvc2UsIGFuZCB3aXNoIHRvIHRyYWlsIHRocm91Z2ggc2h1dGRvd24gc3RhdGVzOgogKiBpZiBuZXZlciByZWNlaXZlZCBTWU4sIGp1c3QgZm9yZ2V0IGl0LiAgSWYgZ290IGEgU1lOIGZyb20gcGVlciwKICogYnV0IGhhdmVuJ3Qgc2VudCBGSU4sIHRoZW4gZ28gdG8gRklOX1dBSVRfMSBzdGF0ZSB0byBzZW5kIHBlZXIgYSBGSU4uCiAqIElmIGFscmVhZHkgZ290IGEgRklOIGZyb20gcGVlciwgdGhlbiBhbG1vc3QgZG9uZTsgZ28gdG8gTEFTVF9BQ0sKICogc3RhdGUuICBJbiBhbGwgb3RoZXIgY2FzZXMsIGhhdmUgYWxyZWFkeSBzZW50IEZJTiB0byBwZWVyIChlLmcuCiAqIGFmdGVyIFBSVV9TSFVURE9XTiksIGFuZCBqdXN0IGhhdmUgdG8gcGxheSB0ZWRpb3VzIGdhbWUgd2FpdGluZwogKiBmb3IgcGVlciB0byBzZW5kIEZJTiBvciBub3QgcmVzcG9uZCB0byBrZWVwLWFsaXZlcywgZXRjLgogKiBXZSBjYW4gbGV0IHRoZSB1c2VyIGV4aXQgZnJvbSB0aGUgY2xvc2UgYXMgc29vbiBhcyB0aGUgRklOIGlzIGFja2VkLgogKi8Kdm9pZCB0Y3Bfc29ja2Nsb3NlZCh0cCkgc3RydWN0IHRjcGNiICp0cDsKewogICAgREVCVUdfQ0FMTCgidGNwX3NvY2tjbG9zZWQiKTsKICAgIERFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyl0cCk7CgogICAgc3dpdGNoICh0cC0+dF9zdGF0ZSkgewogICAgY2FzZSBUQ1BTX0NMT1NFRDoKICAgIGNhc2UgVENQU19MSVNURU46CiAgICBjYXNlIFRDUFNfU1lOX1NFTlQ6CiAgICAgICAgdHAtPnRfc3RhdGUgPSBUQ1BTX0NMT1NFRDsKICAgICAgICB0cCA9IHRjcF9jbG9zZSh0cCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBUQ1BTX1NZTl9SRUNFSVZFRDoKICAgIGNhc2UgVENQU19FU1RBQkxJU0hFRDoKICAgICAgICB0cC0+dF9zdGF0ZSA9IFRDUFNfRklOX1dBSVRfMTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFRDUFNfQ0xPU0VfV0FJVDoKICAgICAgICB0cC0+dF9zdGF0ZSA9IFRDUFNfTEFTVF9BQ0s7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICAvKglzb2lzZmRpc2Nvbm5lY3RpbmcodHAtPnRfc29ja2V0KTsgKi8KICAgIGlmICh0cCAmJiB0cC0+dF9zdGF0ZSA+PSBUQ1BTX0ZJTl9XQUlUXzIpCiAgICAgICAgc29pc2ZkaXNjb25uZWN0ZWQodHAtPnRfc29ja2V0KTsKICAgIGlmICh0cCkKICAgICAgICB0Y3Bfb3V0cHV0KHRwKTsKfQoKLyoKICogQ29ubmVjdCB0byBhIGhvc3Qgb24gdGhlIEludGVybmV0CiAqIENhbGxlZCBieSB0Y3BfaW5wdXQKICogT25seSBkbyBhIGNvbm5lY3QsIHRoZSB0Y3AgZmllbGRzIHdpbGwgYmUgc2V0IGluIHRjcF9pbnB1dAogKiByZXR1cm4gMCBpZiB0aGVyZSdzIGEgcmVzdWx0IG9mIHRoZSBjb25uZWN0LAogKiBlbHNlIHJldHVybiAtMSBtZWFucyB3ZSdyZSBzdGlsbCBjb25uZWN0aW5nCiAqIFRoZSByZXR1cm4gdmFsdWUgaXMgYWxtb3N0IGFsd2F5cyAtMSBzaW5jZSB0aGUgc29ja2V0IGlzCiAqIG5vbmJsb2NraW5nLiAgQ29ubmVjdCByZXR1cm5zIGFmdGVyIHRoZSBTWU4gaXMgc2VudCwgYW5kIGRvZXMKICogbm90IHdhaXQgZm9yIEFDSytTWU4uCiAqLwppbnQgdGNwX2Zjb25uZWN0KHNvKSBzdHJ1Y3Qgc29ja2V0ICpzbzsKewogICAgaW50IHJldCA9IDA7CgogICAgREVCVUdfQ0FMTCgidGNwX2Zjb25uZWN0Iik7CiAgICBERUJVR19BUkcoInNvID0gJWx4IiwgKGxvbmcpc28pOwoKICAgIGlmICgocmV0ID0gc28tPnMgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0sIDApKSA+PSAwKSB7CiAgICAgICAgaW50IG9wdCwgcyA9IHNvLT5zOwogICAgICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZGRyOwoKICAgICAgICBmZF9ub25ibG9jayhzKTsKICAgICAgICBvcHQgPSAxOwogICAgICAgIHNldHNvY2tvcHQocywgU09MX1NPQ0tFVCwgU09fUkVVU0VBRERSLCAoY2hhciAqKSZvcHQsIHNpemVvZihvcHQpKTsKICAgICAgICBvcHQgPSAxOwogICAgICAgIHNldHNvY2tvcHQocywgU09MX1NPQ0tFVCwgU09fT09CSU5MSU5FLCAoY2hhciAqKSZvcHQsIHNpemVvZihvcHQpKTsKCiAgICAgICAgYWRkci5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgICAgICBpZiAoKHNvLT5zb19mYWRkci5zX2FkZHIgJiBodG9ubCgweGZmZmZmZjAwKSkgPT0gc3BlY2lhbF9hZGRyLnNfYWRkcikgewogICAgICAgICAgICAvKiBJdCdzIGFuIGFsaWFzICovCiAgICAgICAgICAgIHN3aXRjaCAobnRvaGwoc28tPnNvX2ZhZGRyLnNfYWRkcikgJiAweGZmKSB7CiAgICAgICAgICAgIGNhc2UgQ1RMX0ROUzoKICAgICAgICAgICAgICAgIGFkZHIuc2luX2FkZHIgPSBkbnNfYWRkcjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIENUTF9BTElBUzoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGFkZHIuc2luX2FkZHIgPSBsb29wYmFja19hZGRyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UKICAgICAgICAgICAgYWRkci5zaW5fYWRkciA9IHNvLT5zb19mYWRkcjsKICAgICAgICBhZGRyLnNpbl9wb3J0ID0gc28tPnNvX2Zwb3J0OwoKICAgICAgICBERUJVR19NSVNDKChkZmQsCiAgICAgICAgICAgICAgICAgICAgIiBjb25uZWN0KClpbmcsIGFkZHIuc2luX3BvcnQ9JWQsICIKICAgICAgICAgICAgICAgICAgICAiYWRkci5zaW5fYWRkci5zX2FkZHI9JS4xNnNcbiIsCiAgICAgICAgICAgICAgICAgICAgbnRvaHMoYWRkci5zaW5fcG9ydCksIGluZXRfbnRvYShhZGRyLnNpbl9hZGRyKSkpOwogICAgICAgIC8qIFdlIGRvbid0IGNhcmUgd2hhdCBwb3J0IHdlIGdldCAqLwogICAgICAgIHJldCA9IGNvbm5lY3QocywgKHN0cnVjdCBzb2NrYWRkciAqKSZhZGRyLCBzaXplb2YoYWRkcikpOwoKICAgICAgICAvKgogICAgICAgICAqIElmIGl0J3Mgbm90IGluIHByb2dyZXNzLCBpdCBmYWlsZWQsIHNvIHdlIGp1c3QgcmV0dXJuIDAsCiAgICAgICAgICogd2l0aG91dCBjbGVhcmluZyBTU19OT0ZEUkVGCiAgICAgICAgICovCiAgICAgICAgc29pc2Zjb25uZWN0aW5nKHNvKTsKICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qCiAqIEFjY2VwdCB0aGUgc29ja2V0IGFuZCBjb25uZWN0IHRvIHRoZSBsb2NhbC1ob3N0CiAqCiAqIFdlIGhhdmUgYSBwcm9ibGVtLiBUaGUgY29ycmVjdCB0aGluZyB0byBkbyB3b3VsZCBiZQogKiB0byBmaXJzdCBjb25uZWN0IHRvIHRoZSBsb2NhbC1ob3N0LCBhbmQgb25seSBpZiB0aGUKICogY29ubmVjdGlvbiBpcyBhY2NlcHRlZCwgdGhlbiBkbyBhbiBhY2NlcHQoKSBoZXJlLgogKiBCdXQsIGEpIHdlIG5lZWQgdG8ga25vdyB3aG8ncyB0cnlpbmcgdG8gY29ubmVjdAogKiB0byB0aGUgc29ja2V0IHRvIGJlIGFibGUgdG8gU1lOIHRoZSBsb2NhbC1ob3N0LCBhbmQKICogYikgd2UgYXJlIGFscmVhZHkgY29ubmVjdGVkIHRvIHRoZSBmb3JlaWduIGhvc3QgYnkKICogdGhlIHRpbWUgaXQgZ2V0cyB0byBhY2NlcHQoKSwgc28uLi4gV2Ugc2ltcGx5IGFjY2VwdAogKiBoZXJlIGFuZCBTWU4gdGhlIGxvY2FsLWhvc3QuCiAqLwp2b2lkIHRjcF9jb25uZWN0KGluc28pIHN0cnVjdCBzb2NrZXQgKmluc287CnsKICAgIHN0cnVjdCBzb2NrZXQgKnNvOwogICAgc3RydWN0IHNvY2thZGRyX2luIGFkZHI7CiAgICBzb2NrbGVuX3QgYWRkcmxlbiA9IHNpemVvZihzdHJ1Y3Qgc29ja2FkZHJfaW4pOwogICAgc3RydWN0IHRjcGNiICp0cDsKICAgIGludCBzLCBvcHQ7CgogICAgREVCVUdfQ0FMTCgidGNwX2Nvbm5lY3QiKTsKICAgIERFQlVHX0FSRygiaW5zbyA9ICVseCIsIChsb25nKWluc28pOwoKICAgIC8qCiAgICAgKiBJZiBpdCdzIGFuIFNTX0FDQ0VQVE9OQ0Ugc29ja2V0LCBubyBuZWVkIHRvIHNvY3JlYXRlKCkKICAgICAqIGFub3RoZXIgc29ja2V0LCBqdXN0IHVzZSB0aGUgYWNjZXB0KCkgc29ja2V0LgogICAgICovCiAgICBpZiAoaW5zby0+c29fc3RhdGUgJiBTU19GQUNDRVBUT05DRSkgewogICAgICAgIC8qIEZBQ0NFUFRPTkNFIGFscmVhZHkgaGF2ZSBhIHRjcGNiICovCiAgICAgICAgc28gPSBpbnNvOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoKHNvID0gc29jcmVhdGUoKSkgPT0gTlVMTCkgewogICAgICAgICAgICAvKiBJZiBpdCBmYWlsZWQsIGdldCByaWQgb2YgdGhlIHBlbmRpbmcgY29ubmVjdGlvbiAqLwogICAgICAgICAgICBjbG9zZXNvY2tldChhY2NlcHQoaW5zby0+cywgKHN0cnVjdCBzb2NrYWRkciAqKSZhZGRyLCAmYWRkcmxlbikpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmICh0Y3BfYXR0YWNoKHNvKSA8IDApIHsKICAgICAgICAgICAgZnJlZShzbyk7IC8qIE5PVCBzb2ZyZWUgKi8KICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBzby0+c29fbGFkZHIgPSBpbnNvLT5zb19sYWRkcjsKICAgICAgICBzby0+c29fbHBvcnQgPSBpbnNvLT5zb19scG9ydDsKICAgIH0KCiAgICAodm9pZCl0Y3BfbXNzKHNvdG90Y3BjYihzbyksIDApOwoKICAgIGlmICgocyA9IGFjY2VwdChpbnNvLT5zLCAoc3RydWN0IHNvY2thZGRyICopJmFkZHIsICZhZGRybGVuKSkgPCAwKSB7CiAgICAgICAgdGNwX2Nsb3NlKHNvdG90Y3BjYihzbykpOyAvKiBUaGlzIHdpbGwgc29mcmVlKCkgYXMgd2VsbCAqLwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZkX25vbmJsb2NrKHMpOwogICAgb3B0ID0gMTsKICAgIHNldHNvY2tvcHQocywgU09MX1NPQ0tFVCwgU09fUkVVU0VBRERSLCAoY2hhciAqKSZvcHQsIHNpemVvZihpbnQpKTsKICAgIG9wdCA9IDE7CiAgICBzZXRzb2Nrb3B0KHMsIFNPTF9TT0NLRVQsIFNPX09PQklOTElORSwgKGNoYXIgKikmb3B0LCBzaXplb2YoaW50KSk7CiAgICBvcHQgPSAxOwogICAgc2V0c29ja29wdChzLCBJUFBST1RPX1RDUCwgVENQX05PREVMQVksIChjaGFyICopJm9wdCwgc2l6ZW9mKGludCkpOwoKICAgIHNvLT5zb19mcG9ydCA9IGFkZHIuc2luX3BvcnQ7CiAgICBzby0+c29fZmFkZHIgPSBhZGRyLnNpbl9hZGRyOwogICAgLyogVHJhbnNsYXRlIGNvbm5lY3Rpb25zIGZyb20gbG9jYWxob3N0IHRvIHRoZSByZWFsIGhvc3RuYW1lICovCiAgICBpZiAoc28tPnNvX2ZhZGRyLnNfYWRkciA9PSAwIHx8IHNvLT5zb19mYWRkci5zX2FkZHIgPT0gbG9vcGJhY2tfYWRkci5zX2FkZHIpCiAgICAgICAgc28tPnNvX2ZhZGRyID0gYWxpYXNfYWRkcjsKCiAgICAvKiBDbG9zZSB0aGUgYWNjZXB0KCkgc29ja2V0LCBzZXQgcmlnaHQgc3RhdGUgKi8KICAgIGlmIChpbnNvLT5zb19zdGF0ZSAmIFNTX0ZBQ0NFUFRPTkNFKSB7CiAgICAgICAgY2xvc2Vzb2NrZXQoCiAgICAgICAgICAgIHNvLT5zKTsgLyogSWYgd2Ugb25seSBhY2NlcHQgb25jZSwgY2xvc2UgdGhlIGFjY2VwdCgpIHNvY2tldCAqLwogICAgICAgIHNvLT5zb19zdGF0ZSA9CiAgICAgICAgICAgIFNTX05PRkRSRUY7IC8qIERvbid0IHNlbGVjdCBpdCB5ZXQsIGV2ZW4gdGhvdWdoIHdlIGhhdmUgYW4gRkQgKi8KICAgICAgICAvKiBpZiBpdCdzIG5vdCBGQUNDRVBUT05DRSwgaXQncyBhbHJlYWR5IE5PRkRSRUYgKi8KICAgIH0KICAgIHNvLT5zID0gczsKCiAgICBzby0+c29faXB0b3MgPSB0Y3BfdG9zKHNvKTsKICAgIHRwID0gc290b3RjcGNiKHNvKTsKCiAgICB0Y3BfdGVtcGxhdGUodHApOwoKICAgIC8qIENvbXB1dGUgd2luZG93IHNjYWxpbmcgdG8gcmVxdWVzdC4gICovCiAgICAvKgl3aGlsZSAodHAtPnJlcXVlc3Rfcl9zY2FsZSA8IFRDUF9NQVhfV0lOU0hJRlQgJiYKICAgICAqCQkoVENQX01BWFdJTiA8PCB0cC0+cmVxdWVzdF9yX3NjYWxlKSA8IHNvLT5zb19yY3Yuc2JfaGl3YXQpCiAgICAgKgkJdHAtPnJlcXVlc3Rfcl9zY2FsZSsrOwogICAgICovCgogICAgLyoJc29pc2Nvbm5lY3Rpbmcoc28pOyAqLyAvKiBOT0ZEUkVGIHVzZWQgaW5zdGVhZCAqLwogICAgU1RBVCh0Y3BzdGF0LnRjcHNfY29ubmF0dGVtcHQrKyk7CgogICAgdHAtPnRfc3RhdGUgPSBUQ1BTX1NZTl9TRU5UOwogICAgdHAtPnRfdGltZXJbVENQVF9LRUVQXSA9IFRDUFRWX0tFRVBfSU5JVDsKICAgIHRwLT5pc3MgPSB0Y3BfaXNzOwogICAgdGNwX2lzcyArPSBUQ1BfSVNTSU5DUiAvIDI7CiAgICB0Y3Bfc2VuZHNlcWluaXQodHApOwogICAgdGNwX291dHB1dCh0cCk7Cn0KCi8qCiAqIEF0dGFjaCBhIFRDUENCIHRvIGEgc29ja2V0LgogKi8KaW50IHRjcF9hdHRhY2goc28pIHN0cnVjdCBzb2NrZXQgKnNvOwp7CiAgICBpZiAoKHNvLT5zb190Y3BjYiA9IHRjcF9uZXd0Y3BjYihzbykpID09IE5VTEwpCiAgICAgICAgcmV0dXJuIC0xOwoKICAgIGluc3F1ZShzbywgJnRjYik7CgogICAgcmV0dXJuIDA7Cn0KCi8qCiAqIFNldCB0aGUgc29ja2V0J3MgdHlwZSBvZiBzZXJ2aWNlIGZpZWxkCiAqLwpzdGF0aWMgY29uc3Qgc3RydWN0IHRvc190IHRjcHRvc1tdID0gewogICAgeyAwLCAyMCwgSVBUT1NfVEhST1VHSFBVVCwgMCB9LCAvKiBmdHAgZGF0YSAqLwogICAgeyAyMSwgMjEsIElQVE9TX0xPV0RFTEFZLCBFTVVfRlRQIH0sIC8qIGZ0cCBjb250cm9sICovCiAgICB7IDAsIDIzLCBJUFRPU19MT1dERUxBWSwgMCB9LCAvKiB0ZWxuZXQgKi8KICAgIHsgMCwgODAsIElQVE9TX1RIUk9VR0hQVVQsIDAgfSwgLyogV1dXICovCiAgICB7IDAsIDUxMywgSVBUT1NfTE9XREVMQVksIEVNVV9STE9HSU4gfCBFTVVfTk9DT05ORUNUIH0sIC8qIHJsb2dpbiAqLwogICAgeyAwLCA1MTQsIElQVE9TX0xPV0RFTEFZLCBFTVVfUlNIIHwgRU1VX05PQ09OTkVDVCB9LCAvKiBzaGVsbCAqLwogICAgeyAwLCA1NDQsIElQVE9TX0xPV0RFTEFZLCBFTVVfS1NIIH0sIC8qIGtzaGVsbCAqLwogICAgeyAwLCA1NDMsIElQVE9TX0xPV0RFTEFZLCAwIH0sIC8qIGtsb2dpbiAqLwogICAgeyAwLCA2NjY3LCBJUFRPU19USFJPVUdIUFVULCBFTVVfSVJDIH0sIC8qIElSQyAqLwogICAgeyAwLCA2NjY4LCBJUFRPU19USFJPVUdIUFVULCBFTVVfSVJDIH0sIC8qIElSQyB1bmRlcm5ldCAqLwogICAgeyAwLCA3MDcwLCBJUFRPU19MT1dERUxBWSwgRU1VX1JFQUxBVURJTyB9LCAvKiBSZWFsQXVkaW8gY29udHJvbCAqLwogICAgeyAwLCAxMTMsIElQVE9TX0xPV0RFTEFZLCBFTVVfSURFTlQgfSwgLyogaWRlbnRkIHByb3RvY29sICovCiAgICB7IDAsIDAsIDAsIDAgfQp9OwoKI2lmZGVmIENPTkZJR19RRU1VCnN0YXRpYwojZW5kaWYKICAgIHN0cnVjdCBlbXVfdCAqdGNwZW11ID0gMDsKCi8qCiAqIFJldHVybiBUT1MgYWNjb3JkaW5nIHRvIHRoZSBhYm92ZSB0YWJsZQogKi8KdV9pbnQ4X3QgdGNwX3Rvcyhzbykgc3RydWN0IHNvY2tldCAqc287CnsKICAgIGludCBpID0gMDsKICAgIHN0cnVjdCBlbXVfdCAqZW11cDsKCiAgICB3aGlsZSAodGNwdG9zW2ldLnRvcykgewogICAgICAgIGlmICgodGNwdG9zW2ldLmZwb3J0ICYmIChudG9ocyhzby0+c29fZnBvcnQpID09IHRjcHRvc1tpXS5mcG9ydCkpIHx8CiAgICAgICAgICAgICh0Y3B0b3NbaV0ubHBvcnQgJiYgKG50b2hzKHNvLT5zb19scG9ydCkgPT0gdGNwdG9zW2ldLmxwb3J0KSkpIHsKICAgICAgICAgICAgc28tPnNvX2VtdSA9IHRjcHRvc1tpXS5lbXU7CiAgICAgICAgICAgIHJldHVybiB0Y3B0b3NbaV0udG9zOwogICAgICAgIH0KICAgICAgICBpKys7CiAgICB9CgogICAgLyogTm9wZSwgbGV0cyBzZWUgaWYgdGhlcmUncyBhIHVzZXItYWRkZWQgb25lICovCiAgICBmb3IgKGVtdXAgPSB0Y3BlbXU7IGVtdXA7IGVtdXAgPSBlbXVwLT5uZXh0KSB7CiAgICAgICAgaWYgKChlbXVwLT5mcG9ydCAmJiAobnRvaHMoc28tPnNvX2Zwb3J0KSA9PSBlbXVwLT5mcG9ydCkpIHx8CiAgICAgICAgICAgIChlbXVwLT5scG9ydCAmJiAobnRvaHMoc28tPnNvX2xwb3J0KSA9PSBlbXVwLT5scG9ydCkpKSB7CiAgICAgICAgICAgIHNvLT5zb19lbXUgPSBlbXVwLT5lbXU7CiAgICAgICAgICAgIHJldHVybiBlbXVwLT50b3M7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAwOwp9CgojaWYgMAppbnQgZG9fZWNobyA9IC0xOwojZW5kaWYKCi8qCiAqIEVtdWxhdGUgcHJvZ3JhbXMgdGhhdCB0cnkgYW5kIGNvbm5lY3QgdG8gdXMKICogVGhpcyBpbmNsdWRlcyBmdHAgKHRoZSBkYXRhIGNvbm5lY3Rpb24gaXMKICogaW5pdGlhdGVkIGJ5IHRoZSBzZXJ2ZXIpIGFuZCBJUkMgKERDQyBDSEFUIGFuZAogKiBEQ0MgU0VORCkgZm9yIG5vdwogKgogKiBOT1RFOiBJdCdzIHBvc3NpYmxlIHRvIGNyYXNoIFNMaVJQIGJ5IHNlbmRpbmcgaXQKICogdW5zdGFuZGFyZCBzdHJpbmdzIHRvIGVtdWxhdGUuLi4gaWYgdGhpcyBpcyBhIHByb2JsZW0sCiAqIG1vcmUgY2hlY2tzIGFyZSBuZWVkZWQgaGVyZQogKgogKiBYWFggQXNzdW1lcyB0aGUgd2hvbGUgY29tbWFuZCBjYW1lIGluIG9uZSBwYWNrZXQKICoKICogWFhYIFNvbWUgZnRwIGNsaWVudHMgd2lsbCBoYXZlIHRoZWlyIFRPUyBzZXQgdG8KICogTE9XREVMQVkgYW5kIHNvIE5hZ2VsIHdpbGwga2ljayBpbi4gIEJlY2F1c2Ugb2YgdGhpcywKICogd2UnbGwgZ2V0IHRoZSBmaXJzdCBsZXR0ZXIsIGZvbGxvd2VkIGJ5IHRoZSByZXN0LCBzbwogKiB3ZSBzaW1wbHkgc2NhbiBmb3IgT1JUIGluc3RlYWQgb2YgUE9SVC4uLgogKiBEQ0MgZG9lc24ndCBoYXZlIHRoaXMgcHJvYmxlbSBiZWNhdXNlIHRoZXJlJ3Mgb3RoZXIgc3R1ZmYKICogaW4gdGhlIHBhY2tldCBiZWZvcmUgdGhlIERDQyBjb21tYW5kLgogKgogKiBSZXR1cm4gMSBpZiB0aGUgbWJ1ZiBtIGlzIHN0aWxsIHZhbGlkIGFuZCBzaG91bGQgYmUKICogc2JhcHBlbmQoKWVkCiAqCiAqIE5PVEU6IGlmIHlvdSByZXR1cm4gMCB5b3UgTVVTVCBtX2ZyZWUoKSB0aGUgbWJ1ZiEKICovCmludCB0Y3BfZW11KHNvLCBtKSBzdHJ1Y3Qgc29ja2V0ICpzbzsKc3RydWN0IG1idWYgKm07CnsKICAgIHVfaW50IG4xLCBuMiwgbjMsIG40LCBuNSwgbjY7CiAgICBjaGFyIGJ1ZmZbMjU3XTsKICAgIHVfaW50MzJfdCBsYWRkcjsKICAgIHVfaW50IGxwb3J0OwogICAgY2hhciAqYnB0cjsKCiAgICBERUJVR19DQUxMKCJ0Y3BfZW11Iik7CiAgICBERUJVR19BUkcoInNvID0gJWx4IiwgKGxvbmcpc28pOwogICAgREVCVUdfQVJHKCJtID0gJWx4IiwgKGxvbmcpbSk7CgogICAgc3dpdGNoIChzby0+c29fZW11KSB7CiAgICAgICAgaW50IHgsIGk7CgogICAgY2FzZSBFTVVfSURFTlQ6CiAgICAgICAgLyoKICAgICAgICAgKiBJZGVudGlmaWNhdGlvbiBwcm90b2NvbCBhcyBwZXIgcmZjLTE0MTMKICAgICAgICAgKi8KCiAgICAgICAgewogICAgICAgICAgICBzdHJ1Y3Qgc29ja2V0ICp0bXBzbzsKICAgICAgICAgICAgc3RydWN0IHNvY2thZGRyX2luIGFkZHI7CiAgICAgICAgICAgIHNvY2tsZW5fdCBhZGRybGVuID0gc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcl9pbik7CiAgICAgICAgICAgIHN0cnVjdCBzYnVmICpzb19yY3YgPSAmc28tPnNvX3JjdjsKCiAgICAgICAgICAgIG1lbWNweShzb19yY3YtPnNiX3dwdHIsIG0tPm1fZGF0YSwgbS0+bV9sZW4pOwogICAgICAgICAgICBzb19yY3YtPnNiX3dwdHIgKz0gbS0+bV9sZW47CiAgICAgICAgICAgIHNvX3Jjdi0+c2JfcnB0ciArPSBtLT5tX2xlbjsKICAgICAgICAgICAgbS0+bV9kYXRhW20tPm1fbGVuXSA9IDA7IC8qIE5VTEwgdGVybWluYXRlICovCiAgICAgICAgICAgIGlmIChzdHJjaHIobS0+bV9kYXRhLCAnXHInKSB8fCBzdHJjaHIobS0+bV9kYXRhLCAnXG4nKSkgewogICAgICAgICAgICAgICAgaWYgKHNzY2FuZihzb19yY3YtPnNiX2RhdGEsICIldSUqWyAsXSV1IiwgJm4xLCAmbjIpID09IDIpIHsKICAgICAgICAgICAgICAgICAgICBIVE9OUyhuMSk7CiAgICAgICAgICAgICAgICAgICAgSFRPTlMobjIpOwogICAgICAgICAgICAgICAgICAgIC8qIG4yIGlzIHRoZSBvbmUgb24gb3VyIGhvc3QgKi8KICAgICAgICAgICAgICAgICAgICBmb3IgKHRtcHNvID0gdGNiLnNvX25leHQ7IHRtcHNvICE9ICZ0Y2I7CiAgICAgICAgICAgICAgICAgICAgICAgICB0bXBzbyA9IHRtcHNvLT5zb19uZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bXBzby0+c29fbGFkZHIuc19hZGRyID09IHNvLT5zb19sYWRkci5zX2FkZHIgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcHNvLT5zb19scG9ydCA9PSBuMiAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wc28tPnNvX2ZhZGRyLnNfYWRkciA9PSBzby0+c29fZmFkZHIuc19hZGRyICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXBzby0+c29fZnBvcnQgPT0gbjEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnZXRzb2NrbmFtZSh0bXBzby0+cywgKHN0cnVjdCBzb2NrYWRkciAqKSZhZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZhZGRybGVuKSA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4yID0gbnRvaHMoYWRkci5zaW5fcG9ydCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNvX3Jjdi0+c2JfY2MgPSBzbnByaW50Zihzb19yY3YtPnNiX2RhdGEsIHNvX3Jjdi0+c2JfZGF0YWxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJWQsJWRcclxuIiwgbjEsIG4yKTsKICAgICAgICAgICAgICAgIHNvX3Jjdi0+c2JfcnB0ciA9IHNvX3Jjdi0+c2JfZGF0YTsKICAgICAgICAgICAgICAgIHNvX3Jjdi0+c2Jfd3B0ciA9IHNvX3Jjdi0+c2JfZGF0YSArIHNvX3Jjdi0+c2JfY2M7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbV9mcmVlKG0pOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgojaWYgMAoJIGNhc2UgRU1VX1JMT0dJTjoKCQkvKgoJCSAqIFJsb2dpbiBlbXVsYXRpb24KCQkgKiBGaXJzdCB3ZSBhY2N1bXVsYXRlIGFsbCB0aGUgaW5pdGlhbCBvcHRpb24gbmVnb3RpYXRpb24sCgkJICogdGhlbiBmb3JrX2V4ZWMoKSBybG9naW4gYWNjb3JkaW5nIHRvIHRoZSAgb3B0aW9ucwoJCSAqLwoJCXsKCQkJaW50IGksIGkyLCBuOwoJCQljaGFyICpwdHI7CgkJCWNoYXIgYXJnc1sxMDBdOwoJCQljaGFyIHRlcm1bMTAwXTsKCQkJc3RydWN0IHNidWYgKnNvX3NuZCA9ICZzby0+c29fc25kOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fcmN2ID0gJnNvLT5zb19yY3Y7CgoJCQkvKiBGaXJzdCBjaGVjayBpZiB0aGV5IGhhdmUgYSBwcml2ZWxhZGdlZCBwb3J0LCBvciB0b28gbXVjaCBkYXRhIGhhcyBhcnJpdmVkICovCgkJCWlmIChudG9ocyhzby0+c29fbHBvcnQpID4gMTAyMyB8fCBudG9ocyhzby0+c29fbHBvcnQpIDwgNTEyIHx8CgkJCSAgICAobS0+bV9sZW4gKyBzb19yY3YtPnNiX3dwdHIpID4gKHNvX3Jjdi0+c2JfZGF0YSArIHNvX3Jjdi0+c2JfZGF0YWxlbikpIHsKCQkJCW1lbWNweShzb19zbmQtPnNiX3dwdHIsICJQZXJtaXNzaW9uIGRlbmllZFxuIiwgMTgpOwoJCQkJc29fc25kLT5zYl93cHRyICs9IDE4OwoJCQkJc29fc25kLT5zYl9jYyArPSAxODsKCQkJCXRjcF9zb2NrY2xvc2VkKHNvdG90Y3BjYihzbykpOwoJCQkJbV9mcmVlKG0pOwoJCQkJcmV0dXJuIDA7CgkJCX0KCgkJCS8qIEFwcGVuZCB0aGUgY3VycmVudCBkYXRhICovCgkJCW1lbWNweShzb19yY3YtPnNiX3dwdHIsIG0tPm1fZGF0YSwgbS0+bV9sZW4pOwoJCQlzb19yY3YtPnNiX3dwdHIgKz0gbS0+bV9sZW47CgkJCXNvX3Jjdi0+c2JfcnB0ciArPSBtLT5tX2xlbjsKCQkJbV9mcmVlKG0pOwoKCQkJLyoKCQkJICogQ2hlY2sgaWYgd2UgaGF2ZSBhbGwgdGhlIGluaXRpYWwgb3B0aW9ucywKCQkJICogYW5kIGJ1aWxkIGFyZ3VtZW50IGxpc3QgdG8gcmxvZ2luIHdoaWxlIHdlJ3JlIGhlcmUKCQkJICovCgkJCW4gPSAwOwoJCQlwdHIgPSBzb19yY3YtPnNiX2RhdGE7CgkJCWFyZ3NbMF0gPSAwOwoJCQl0ZXJtWzBdID0gMDsKCQkJd2hpbGUgKHB0ciA8IHNvX3Jjdi0+c2Jfd3B0cikgewoJCQkJaWYgKCpwdHIrKyA9PSAwKSB7CgkJCQkJbisrOwoJCQkJCWlmIChuID09IDIpIHsKCQkJCQkJc3ByaW50ZihhcmdzLCAicmxvZ2luIC1sICVzICVzIiwKCQkJCQkJCXB0ciwgaW5ldF9udG9hKHNvLT5zb19mYWRkcikpOwoJCQkJCX0gZWxzZSBpZiAobiA9PSAzKSB7CgkJCQkJCWkyID0gc29fcmN2LT5zYl93cHRyIC0gcHRyOwoJCQkJCQlmb3IgKGkgPSAwOyBpIDwgaTI7IGkrKykgewoJCQkJCQkJaWYgKHB0cltpXSA9PSAnLycpIHsKCQkJCQkJCQlwdHJbaV0gPSAwOwojaWZkZWYgSEFWRV9TRVRFTlYKCQkJCQkJCQlzcHJpbnRmKHRlcm0sICIlcyIsIHB0cik7CiNlbHNlCgkJCQkJCQkJc3ByaW50Zih0ZXJtLCAiVEVSTT0lcyIsIHB0cik7CiNlbmRpZgoJCQkJCQkJCXB0cltpXSA9ICcvJzsKCQkJCQkJCQlicmVhazsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJaWYgKG4gIT0gNCkKCQkJICAgcmV0dXJuIDA7CgoJCQkvKiBXZSBoYXZlIGl0LCBzZXQgb3VyIHRlcm0gdmFyaWFibGUgYW5kIGZvcmtfZXhlYygpICovCiNpZmRlZiBIQVZFX1NFVEVOVgoJCQlzZXRlbnYoIlRFUk0iLCB0ZXJtLCAxKTsKI2Vsc2UKCQkJcHV0ZW52KHRlcm0pOwojZW5kaWYKCQkJZm9ya19leGVjKHNvLCBhcmdzLCAyKTsKCQkJdGVybVswXSA9IDA7CgkJCXNvLT5zb19lbXUgPSAwOwoKCQkJLyogQW5kIGZpbmFsbHksIHNlbmQgdGhlIGNsaWVudCBhIDAgY2hhcmFjdGVyICovCgkJCXNvX3NuZC0+c2Jfd3B0clswXSA9IDA7CgkJCXNvX3NuZC0+c2Jfd3B0cisrOwoJCQlzb19zbmQtPnNiX2NjKys7CgoJCQlyZXR1cm4gMDsKCQl9CgoJIGNhc2UgRU1VX1JTSDoKCQkvKgoJCSAqIHJzaCBlbXVsYXRpb24KCQkgKiBGaXJzdCB3ZSBhY2N1bXVsYXRlIGFsbCB0aGUgaW5pdGlhbCBvcHRpb24gbmVnb3RpYXRpb24sCgkJICogdGhlbiByc2hfZXhlYygpIHJzaCBhY2NvcmRpbmcgdG8gdGhlICBvcHRpb25zCgkJICovCgkJewoJCQlpbnQgIG47CgkJCWNoYXIgKnB0cjsKCQkJY2hhciAqdXNlcjsKCQkJY2hhciAqYXJnczsKCQkJc3RydWN0IHNidWYgKnNvX3NuZCA9ICZzby0+c29fc25kOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fcmN2ID0gJnNvLT5zb19yY3Y7CgoJCQkvKiBGaXJzdCBjaGVjayBpZiB0aGV5IGhhdmUgYSBwcml2ZWxhZGdlZCBwb3J0LCBvciB0b28gbXVjaCBkYXRhIGhhcyBhcnJpdmVkICovCgkJCWlmIChudG9ocyhzby0+c29fbHBvcnQpID4gMTAyMyB8fCBudG9ocyhzby0+c29fbHBvcnQpIDwgNTEyIHx8CgkJCSAgICAobS0+bV9sZW4gKyBzb19yY3YtPnNiX3dwdHIpID4gKHNvX3Jjdi0+c2JfZGF0YSArIHNvX3Jjdi0+c2JfZGF0YWxlbikpIHsKCQkJCW1lbWNweShzb19zbmQtPnNiX3dwdHIsICJQZXJtaXNzaW9uIGRlbmllZFxuIiwgMTgpOwoJCQkJc29fc25kLT5zYl93cHRyICs9IDE4OwoJCQkJc29fc25kLT5zYl9jYyArPSAxODsKCQkJCXRjcF9zb2NrY2xvc2VkKHNvdG90Y3BjYihzbykpOwoJCQkJbV9mcmVlKG0pOwoJCQkJcmV0dXJuIDA7CgkJCX0KCgkJCS8qIEFwcGVuZCB0aGUgY3VycmVudCBkYXRhICovCgkJCW1lbWNweShzb19yY3YtPnNiX3dwdHIsIG0tPm1fZGF0YSwgbS0+bV9sZW4pOwoJCQlzb19yY3YtPnNiX3dwdHIgKz0gbS0+bV9sZW47CgkJCXNvX3Jjdi0+c2JfcnB0ciArPSBtLT5tX2xlbjsKCQkJbV9mcmVlKG0pOwoKCQkJLyoKCQkJICogQ2hlY2sgaWYgd2UgaGF2ZSBhbGwgdGhlIGluaXRpYWwgb3B0aW9ucywKCQkJICogYW5kIGJ1aWxkIGFyZ3VtZW50IGxpc3QgdG8gcmxvZ2luIHdoaWxlIHdlJ3JlIGhlcmUKCQkJICovCgkJCW4gPSAwOwoJCQlwdHIgPSBzb19yY3YtPnNiX2RhdGE7CgkJCXVzZXI9IiI7CgkJCWFyZ3M9IiI7CgkJCWlmIChzby0+ZXh0cmE9PU5VTEwpIHsKCQkJCXN0cnVjdCBzb2NrZXQgKm5zOwoJCQkJc3RydWN0IHRjcGNiKiB0cDsKCQkJCWludCBwb3J0PWF0b2kocHRyKTsKCQkJCWlmIChwb3J0IDw9IDApIHJldHVybiAwOwogICAgICAgICAgICAgICAgaWYgKHBvcnQgPiAxMDIzIHx8IHBvcnQgPCA1MTIpIHsKICAgICAgICAgICAgICAgICAgbWVtY3B5KHNvX3NuZC0+c2Jfd3B0ciwgIlBlcm1pc3Npb24gZGVuaWVkXG4iLCAxOCk7CiAgICAgICAgICAgICAgICAgIHNvX3NuZC0+c2Jfd3B0ciArPSAxODsKICAgICAgICAgICAgICAgICAgc29fc25kLT5zYl9jYyArPSAxODsKICAgICAgICAgICAgICAgICAgdGNwX3NvY2tjbG9zZWQoc290b3RjcGNiKHNvKSk7CiAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgfQoJCQkJaWYgKChucz1zb2NyZWF0ZSgpKSA9PSBOVUxMKQogICAgICAgICAgICAgICAgICByZXR1cm4gMDsKCQkJCWlmICh0Y3BfYXR0YWNoKG5zKTwwKSB7CiAgICAgICAgICAgICAgICAgIGZyZWUobnMpOwogICAgICAgICAgICAgICAgICByZXR1cm4gMDsKCQkJCX0KCgkJCQlucy0+c29fbGFkZHI9c28tPnNvX2xhZGRyOwoJCQkJbnMtPnNvX2xwb3J0PWh0b25zKHBvcnQpOwoKCQkJCSh2b2lkKSB0Y3BfbXNzKHNvdG90Y3BjYihucyksIDApOwoKCQkJCW5zLT5zb19mYWRkcj1zby0+c29fZmFkZHI7CgkJCQlucy0+c29fZnBvcnQ9aHRvbnMoSVBQT1JUX1JFU0VSVkVELTEpOyAvKiBVc2UgYSBmYWtlIHBvcnQuICovCgoJCQkJaWYgKG5zLT5zb19mYWRkci5zX2FkZHIgPT0gMCB8fAoJCQkJCW5zLT5zb19mYWRkci5zX2FkZHIgPT0gbG9vcGJhY2tfYWRkci5zX2FkZHIpCiAgICAgICAgICAgICAgICAgIG5zLT5zb19mYWRkciA9IGFsaWFzX2FkZHI7CgoJCQkJbnMtPnNvX2lwdG9zID0gdGNwX3Rvcyhucyk7CgkJCQl0cCA9IHNvdG90Y3BjYihucyk7CgoJCQkJdGNwX3RlbXBsYXRlKHRwKTsKCgkJCQkvKiBDb21wdXRlIHdpbmRvdyBzY2FsaW5nIHRvIHJlcXVlc3QuICAqLwoJCQkJLyoJd2hpbGUgKHRwLT5yZXF1ZXN0X3Jfc2NhbGUgPCBUQ1BfTUFYX1dJTlNISUZUICYmCgkJCQkgKgkJKFRDUF9NQVhXSU4gPDwgdHAtPnJlcXVlc3Rfcl9zY2FsZSkgPCBzby0+c29fcmN2LnNiX2hpd2F0KQoJCQkJICoJCXRwLT5yZXF1ZXN0X3Jfc2NhbGUrKzsKCQkJCSAqLwoKICAgICAgICAgICAgICAgIC8qc29pc2Zjb25uZWN0aW5nKG5zKTsqLwoKCQkJCVNUQVQodGNwc3RhdC50Y3BzX2Nvbm5hdHRlbXB0KyspOwoKCQkJCXRwLT50X3N0YXRlID0gVENQU19TWU5fU0VOVDsKCQkJCXRwLT50X3RpbWVyW1RDUFRfS0VFUF0gPSBUQ1BUVl9LRUVQX0lOSVQ7CgkJCQl0cC0+aXNzID0gdGNwX2lzczsKCQkJCXRjcF9pc3MgKz0gVENQX0lTU0lOQ1IvMjsKCQkJCXRjcF9zZW5kc2VxaW5pdCh0cCk7CgkJCQl0Y3Bfb3V0cHV0KHRwKTsKCQkJCXNvLT5leHRyYT1uczsKCQkJfQoJCQl3aGlsZSAocHRyIDwgc29fcmN2LT5zYl93cHRyKSB7CiAgICAgICAgICAgICAgaWYgKCpwdHIrKyA9PSAwKSB7CiAgICAgICAgICAgICAgICBuKys7CiAgICAgICAgICAgICAgICBpZiAobiA9PSAyKSB7CiAgICAgICAgICAgICAgICAgIHVzZXI9cHRyOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuID09IDMpIHsKICAgICAgICAgICAgICAgICAgYXJncz1wdHI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQoJCQl9CgoJCQlpZiAobiAhPSA0KQogICAgICAgICAgICAgIHJldHVybiAwOwoKCQkJcnNoX2V4ZWMoc28sc28tPmV4dHJhLCB1c2VyLCBpbmV0X250b2Eoc28tPnNvX2ZhZGRyKSwgYXJncyk7CgkJCXNvLT5zb19lbXUgPSAwOwoJCQlzby0+ZXh0cmE9TlVMTDsKCgkJCS8qIEFuZCBmaW5hbGx5LCBzZW5kIHRoZSBjbGllbnQgYSAwIGNoYXJhY3RlciAqLwoJCQlzb19zbmQtPnNiX3dwdHJbMF0gPSAwOwoJCQlzb19zbmQtPnNiX3dwdHIrKzsKCQkJc29fc25kLT5zYl9jYysrOwoKCQkJcmV0dXJuIDA7CgkJfQoKCSBjYXNlIEVNVV9DVEw6CgkJewoJCQlpbnQgbnVtOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fc25kID0gJnNvLT5zb19zbmQ7CgkJCXN0cnVjdCBzYnVmICpzb19yY3YgPSAmc28tPnNvX3JjdjsKCgkJCS8qCgkJCSAqIElmIHRoZXJlIGlzIGJpbmFyeSBkYXRhIGhlcmUsIHdlIHNhdmUgaXQgaW4gc28tPnNvX20KCQkJICovCgkJCWlmICghc28tPnNvX20pIHsKCQkJICBpbnQgcnhsZW47CgkJCSAgY2hhciAqcnhkYXRhOwoJCQkgIHJ4ZGF0YT1tdG9kKG0sIGNoYXIgKik7CgkJCSAgZm9yIChyeGxlbj1tLT5tX2xlbjsgcnhsZW47IHJ4bGVuLS0pIHsKCQkJICAgIGlmICgqcnhkYXRhKysgJiAweDgwKSB7CgkJCSAgICAgIHNvLT5zb19tID0gbTsKCQkJICAgICAgcmV0dXJuIDA7CgkJCSAgICB9CgkJCSAgfQoJCQl9IC8qIGlmKHNvLT5zb19tPT1OVUxMKSAqLwoKCQkJLyoKCQkJICogQXBwZW5kIHRoZSBsaW5lCgkJCSAqLwoJCQlzYmFwcGVuZHNiKHNvX3JjdiwgbSk7CgoJCQkvKiBUbyBhdm9pZCBnb2luZyBvdmVyIHRoZSBlZGdlIG9mIHRoZSBidWZmZXIsIHdlIHJlc2V0IGl0ICovCgkJCWlmIChzb19zbmQtPnNiX2NjID09IDApCgkJCSAgIHNvX3NuZC0+c2Jfd3B0ciA9IHNvX3NuZC0+c2JfcnB0ciA9IHNvX3NuZC0+c2JfZGF0YTsKCgkJCS8qCgkJCSAqIEEgYml0IG9mIGEgaGFjazoKCQkJICogSWYgdGhlIGZpcnN0IHBhY2tldCB3ZSBnZXQgaGVyZSBpcyAxIGJ5dGUgbG9uZywgdGhlbiBpdAoJCQkgKiB3YXMgZG9uZSBpbiB0ZWxuZXQgY2hhcmFjdGVyIG1vZGUsIHRoZXJlZm9yZSB3ZSBtdXN0IGVjaG8KCQkJICogdGhlIGNoYXJhY3RlcnMgYXMgdGhleSBjb21lLiAgT3RoZXJ3aXNlLCB3ZSBlY2hvIG5vdGhpbmcsCgkJCSAqIGJlY2F1c2UgaW4gbGluZW1vZGUsIHRoZSBsaW5lIGlzIGFscmVhZHkgZWNob2VkCgkJCSAqIFhYWCB0d28gb3IgbW9yZSBjb250cm9sIGNvbm5lY3Rpb25zIHdvbid0IHdvcmsKCQkJICovCgkJCWlmIChkb19lY2hvID09IC0xKSB7CgkJCQlpZiAobS0+bV9sZW4gPT0gMSkgZG9fZWNobyA9IDE7CgkJCQllbHNlIGRvX2VjaG8gPSAwOwoJCQl9CgkJCWlmIChkb19lY2hvKSB7CgkJCSAgc2JhcHBlbmRzYihzb19zbmQsIG0pOwoJCQkgIG1fZnJlZShtKTsKCQkJICB0Y3Bfb3V0cHV0KHNvdG90Y3BjYihzbykpOyAvKiBYWFggKi8KCQkJfSBlbHNlCgkJCSAgbV9mcmVlKG0pOwoKCQkJbnVtID0gMDsKCQkJd2hpbGUgKG51bSA8IHNvLT5zb19yY3Yuc2JfY2MpIHsKCQkJCWlmICgqKHNvLT5zb19yY3Yuc2JfcnB0ciArIG51bSkgPT0gJ1xuJyB8fAoJCQkJICAgICooc28tPnNvX3Jjdi5zYl9ycHRyICsgbnVtKSA9PSAnXHInKSB7CgkJCQkJaW50IG47CgoJCQkJCSooc29fcmN2LT5zYl9ycHRyICsgbnVtKSA9IDA7CgkJCQkJaWYgKGN0bF9wYXNzd29yZCAmJiAhY3RsX3Bhc3N3b3JkX29rKSB7CgkJCQkJCS8qIE5lZWQgYSBwYXNzd29yZCAqLwoJCQkJCQlpZiAoc3NjYW5mKHNvX3Jjdi0+c2JfcnB0ciwgInBhc3MgJTI1NnMiLCBidWZmKSA9PSAxKSB7CgkJCQkJCQlpZiAoc3RyY21wKGJ1ZmYsIGN0bF9wYXNzd29yZCkgPT0gMCkgewoJCQkJCQkJCWN0bF9wYXNzd29yZF9vayA9IDE7CgkJCQkJCQkJbiA9IHNwcmludGYoc29fc25kLT5zYl93cHRyLAoJCQkJCQkJCQkgICAgIlBhc3N3b3JkIE9LLlxyXG4iKTsKCQkJCQkJCQlnb3RvIGRvX3Byb21wdDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQluID0gc3ByaW50Zihzb19zbmQtPnNiX3dwdHIsCgkJCQkJICJFcnJvcjogUGFzc3dvcmQgcmVxdWlyZWQsIGxvZyBvbiB3aXRoIFwicGFzcyBQQVNTV09SRFwiXHJcbiIpOwoJCQkJCQlnb3RvIGRvX3Byb21wdDsKCQkJCQl9CgkJCQkJY2ZnX3F1aXR0aW5nID0gMDsKCQkJCQluID0gZG9fY29uZmlnKHNvX3Jjdi0+c2JfcnB0ciwgc28sIFBSTl9TUFJJTlRGKTsKCQkJCQlpZiAoIWNmZ19xdWl0dGluZykgewoJCQkJCQkvKiBSZWdpc3RlciB0aGUgcHJpbnRlZCBkYXRhICovCmRvX3Byb21wdDoKCQkJCQkJc29fc25kLT5zYl9jYyArPSBuOwoJCQkJCQlzb19zbmQtPnNiX3dwdHIgKz0gbjsKCQkJCQkJLyogQWRkIHByb21wdCAqLwoJCQkJCQluID0gc3ByaW50Zihzb19zbmQtPnNiX3dwdHIsICJTbGlycD4gIik7CgkJCQkJCXNvX3NuZC0+c2JfY2MgKz0gbjsKCQkJCQkJc29fc25kLT5zYl93cHRyICs9IG47CgkJCQkJfQoJCQkJCS8qIERyb3Agc29fcmN2IGRhdGEgKi8KCQkJCQlzb19yY3YtPnNiX2NjID0gMDsKCQkJCQlzb19yY3YtPnNiX3dwdHIgPSBzb19yY3YtPnNiX3JwdHIgPSBzb19yY3YtPnNiX2RhdGE7CgkJCQkJdGNwX291dHB1dChzb3RvdGNwY2Ioc28pKTsgLyogU2VuZCB0aGUgcmVwbHkgKi8KCQkJCX0KCQkJCW51bSsrOwoJCQl9CgkJCXJldHVybiAwOwoJCX0KI2VuZGlmCiAgICBjYXNlIEVNVV9GVFA6IC8qIGZ0cCAqLwogICAgICAgICoobS0+bV9kYXRhICsgbS0+bV9sZW4pID0gMDsgLyogTlVMTCB0ZXJtaW5hdGUgZm9yIHN0cnN0ciAqLwogICAgICAgIGlmICgoYnB0ciA9IChjaGFyICopc3Ryc3RyKG0tPm1fZGF0YSwgIk9SVCIpKSAhPSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIE5lZWQgdG8gZW11bGF0ZSB0aGUgUE9SVCBjb21tYW5kCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB4ID0gc3NjYW5mKGJwdHIsICJPUlQgJXUsJXUsJXUsJXUsJXUsJXVcclxuJTI1NlteXDE3N10iLCAmbjEsICZuMiwKICAgICAgICAgICAgICAgICAgICAgICAmbjMsICZuNCwgJm41LCAmbjYsIGJ1ZmYpOwogICAgICAgICAgICBpZiAoeCA8IDYpCiAgICAgICAgICAgICAgICByZXR1cm4gMTsKCiAgICAgICAgICAgIGxhZGRyID0gaHRvbmwoKG4xIDw8IDI0KSB8IChuMiA8PCAxNikgfCAobjMgPDwgOCkgfCAobjQpKTsKICAgICAgICAgICAgbHBvcnQgPSBodG9ucygobjUgPDwgOCkgfCAobjYpKTsKCiAgICAgICAgICAgIGlmICgoc28gPSBzb2xpc3RlbigwLCBsYWRkciwgbHBvcnQsIFNTX0ZBQ0NFUFRPTkNFKSkgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiAxOwoKICAgICAgICAgICAgbjYgPSBudG9ocyhzby0+c29fZnBvcnQpOwoKICAgICAgICAgICAgbjUgPSAobjYgPj4gOCkgJiAweGZmOwogICAgICAgICAgICBuNiAmPSAweGZmOwoKICAgICAgICAgICAgbGFkZHIgPSBudG9obChzby0+c29fZmFkZHIuc19hZGRyKTsKCiAgICAgICAgICAgIG4xID0gKChsYWRkciA+PiAyNCkgJiAweGZmKTsKICAgICAgICAgICAgbjIgPSAoKGxhZGRyID4+IDE2KSAmIDB4ZmYpOwogICAgICAgICAgICBuMyA9ICgobGFkZHIgPj4gOCkgJiAweGZmKTsKICAgICAgICAgICAgbjQgPSAobGFkZHIgJiAweGZmKTsKCiAgICAgICAgICAgIG0tPm1fbGVuID0gYnB0ciAtIG0tPm1fZGF0YTsgLyogQWRqdXN0IGxlbmd0aCAqLwogICAgICAgICAgICBtLT5tX2xlbiArPSBzbnByaW50ZihicHRyLCBtLT5tX2hkci5taF9zaXplIC0gbS0+bV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPUlQgJWQsJWQsJWQsJWQsJWQsJWRcclxuJXMiLCBuMSwgbjIsIG4zLCBuNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbjUsIG42LCB4ID09IDcgPyBidWZmIDogIiIpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGVsc2UgaWYgKChicHRyID0gKGNoYXIgKilzdHJzdHIobS0+bV9kYXRhLCAiMjcgRW50ZXJpbmciKSkgIT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBOZWVkIHRvIGVtdWxhdGUgdGhlIFBBU1YgcmVzcG9uc2UKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHggPSBzc2NhbmYoCiAgICAgICAgICAgICAgICBicHRyLAogICAgICAgICAgICAgICAgIjI3IEVudGVyaW5nIFBhc3NpdmUgTW9kZSAoJXUsJXUsJXUsJXUsJXUsJXUpXHJcbiUyNTZbXlwxNzddIiwKICAgICAgICAgICAgICAgICZuMSwgJm4yLCAmbjMsICZuNCwgJm41LCAmbjYsIGJ1ZmYpOwogICAgICAgICAgICBpZiAoeCA8IDYpCiAgICAgICAgICAgICAgICByZXR1cm4gMTsKCiAgICAgICAgICAgIGxhZGRyID0gaHRvbmwoKG4xIDw8IDI0KSB8IChuMiA8PCAxNikgfCAobjMgPDwgOCkgfCAobjQpKTsKICAgICAgICAgICAgbHBvcnQgPSBodG9ucygobjUgPDwgOCkgfCAobjYpKTsKCiAgICAgICAgICAgIGlmICgoc28gPSBzb2xpc3RlbigwLCBsYWRkciwgbHBvcnQsIFNTX0ZBQ0NFUFRPTkNFKSkgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiAxOwoKICAgICAgICAgICAgbjYgPSBudG9ocyhzby0+c29fZnBvcnQpOwoKICAgICAgICAgICAgbjUgPSAobjYgPj4gOCkgJiAweGZmOwogICAgICAgICAgICBuNiAmPSAweGZmOwoKICAgICAgICAgICAgbGFkZHIgPSBudG9obChzby0+c29fZmFkZHIuc19hZGRyKTsKCiAgICAgICAgICAgIG4xID0gKChsYWRkciA+PiAyNCkgJiAweGZmKTsKICAgICAgICAgICAgbjIgPSAoKGxhZGRyID4+IDE2KSAmIDB4ZmYpOwogICAgICAgICAgICBuMyA9ICgobGFkZHIgPj4gOCkgJiAweGZmKTsKICAgICAgICAgICAgbjQgPSAobGFkZHIgJiAweGZmKTsKCiAgICAgICAgICAgIG0tPm1fbGVuID0gYnB0ciAtIG0tPm1fZGF0YTsgLyogQWRqdXN0IGxlbmd0aCAqLwogICAgICAgICAgICBtLT5tX2xlbiArPQogICAgICAgICAgICAgICAgc25wcmludGYoYnB0ciwgbS0+bV9oZHIubWhfc2l6ZSAtIG0tPm1fbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIjI3IEVudGVyaW5nIFBhc3NpdmUgTW9kZSAoJWQsJWQsJWQsJWQsJWQsJWQpXHJcbiVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgIG4xLCBuMiwgbjMsIG40LCBuNSwgbjYsIHggPT0gNyA/IGJ1ZmYgOiAiIik7CgogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAxOwoKICAgIGNhc2UgRU1VX0tTSDoKICAgICAgICAvKgogICAgICAgICAqIFRoZSBrc2hlbGwgKEtlcmJlcm9zIHJzaCkgYW5kIHNoZWxsIHNlcnZpY2VzIGJvdGggcGFzcwogICAgICAgICAqIGEgbG9jYWwgcG9ydCBwb3J0IG51bWJlciB0byBjYXJyeSBzaWduYWxzIHRvIHRoZSBzZXJ2ZXIKICAgICAgICAgKiBhbmQgc3RkZXJyIHRvIHRoZSBjbGllbnQuICBJdCBpcyBwYXNzZWQgYXQgdGhlIGJlZ2lubmluZwogICAgICAgICAqIG9mIHRoZSBjb25uZWN0aW9uIGFzIGEgTlVMLXRlcm1pbmF0ZWQgZGVjaW1hbCBBU0NJSSBzdHJpbmcuCiAgICAgICAgICovCiAgICAgICAgc28tPnNvX2VtdSA9IDA7CiAgICAgICAgZm9yIChscG9ydCA9IDAsIGkgPSAwOyBpIDwgbS0+bV9sZW4gLSAxOyArK2kpIHsKICAgICAgICAgICAgaWYgKG0tPm1fZGF0YVtpXSA8ICcwJyB8fCBtLT5tX2RhdGFbaV0gPiAnOScpCiAgICAgICAgICAgICAgICByZXR1cm4gMTsgLyogaW52YWxpZCBudW1iZXIgKi8KICAgICAgICAgICAgbHBvcnQgKj0gMTA7CiAgICAgICAgICAgIGxwb3J0ICs9IG0tPm1fZGF0YVtpXSAtICcwJzsKICAgICAgICB9CiAgICAgICAgaWYgKG0tPm1fZGF0YVttLT5tX2xlbiAtIDFdID09ICdcMCcgJiYgbHBvcnQgIT0gMCAmJgogICAgICAgICAgICAoc28gPSBzb2xpc3RlbigwLCBzby0+c29fbGFkZHIuc19hZGRyLCBodG9ucyhscG9ydCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTX0ZBQ0NFUFRPTkNFKSkgIT0gTlVMTCkKICAgICAgICAgICAgbS0+bV9sZW4gPSBzbnByaW50ZihtLT5tX2RhdGEsIG0tPm1faGRyLm1oX3NpemUsICIlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnRvaHMoc28tPnNvX2Zwb3J0KSkgKwogICAgICAgICAgICAgICAgICAgICAgIDE7CiAgICAgICAgcmV0dXJuIDE7CgogICAgY2FzZSBFTVVfSVJDOgogICAgICAgIC8qCiAgICAgICAgICogTmVlZCB0byBlbXVsYXRlIERDQyBDSEFULCBEQ0MgU0VORCBhbmQgRENDIE1PVkUKICAgICAgICAgKi8KICAgICAgICAqKG0tPm1fZGF0YSArIG0tPm1fbGVuKSA9IDA7IC8qIE5VTEwgdGVybWluYXRlIHRoZSBzdHJpbmcgZm9yIHN0cnN0ciAqLwogICAgICAgIGlmICgoYnB0ciA9IChjaGFyICopc3Ryc3RyKG0tPm1fZGF0YSwgIkRDQyIpKSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gMTsKCiAgICAgICAgLyogVGhlICUyNTZzIGlzIGZvciB0aGUgYnJva2VuIG1JUkMgKi8KICAgICAgICBpZiAoc3NjYW5mKGJwdHIsICJEQ0MgQ0hBVCAlMjU2cyAldSAldSIsIGJ1ZmYsICZsYWRkciwgJmxwb3J0KSA9PSAzKSB7CiAgICAgICAgICAgIGlmICgoc28gPSBzb2xpc3RlbigwLCBodG9ubChsYWRkciksIGh0b25zKGxwb3J0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTX0ZBQ0NFUFRPTkNFKSkgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiAxOwoKICAgICAgICAgICAgbS0+bV9sZW4gPSBicHRyIC0gbS0+bV9kYXRhOyAvKiBBZGp1c3QgbGVuZ3RoICovCiAgICAgICAgICAgIG0tPm1fbGVuICs9CiAgICAgICAgICAgICAgICBzbnByaW50ZihicHRyLCBtLT5tX2hkci5taF9zaXplLCAiRENDIENIQVQgY2hhdCAlbHUgJXUlY1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKW50b2hsKHNvLT5zb19mYWRkci5zX2FkZHIpLAogICAgICAgICAgICAgICAgICAgICAgICAgbnRvaHMoc28tPnNvX2Zwb3J0KSwgMSk7CiAgICAgICAgfSBlbHNlIGlmIChzc2NhbmYoYnB0ciwgIkRDQyBTRU5EICUyNTZzICV1ICV1ICV1IiwgYnVmZiwgJmxhZGRyLCAmbHBvcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJm4xKSA9PSA0KSB7CiAgICAgICAgICAgIGlmICgoc28gPSBzb2xpc3RlbigwLCBodG9ubChsYWRkciksIGh0b25zKGxwb3J0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNTX0ZBQ0NFUFRPTkNFKSkgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiAxOwoKICAgICAgICAgICAgbS0+bV9sZW4gPSBicHRyIC0gbS0+bV9kYXRhOyAvKiBBZGp1c3QgbGVuZ3RoICovCiAgICAgICAgICAgIG0tPm1fbGVuICs9CiAgICAgICAgICAgICAgICBzbnByaW50ZihicHRyLCBtLT5tX2hkci5taF9zaXplLCAiRENDIFNFTkQgJXMgJWx1ICV1ICV1JWNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBidWZmLCAodW5zaWduZWQgbG9uZyludG9obChzby0+c29fZmFkZHIuc19hZGRyKSwKICAgICAgICAgICAgICAgICAgICAgICAgIG50b2hzKHNvLT5zb19mcG9ydCksIG4xLCAxKTsKICAgICAgICB9IGVsc2UgaWYgKHNzY2FuZihicHRyLCAiRENDIE1PVkUgJTI1NnMgJXUgJXUgJXUiLCBidWZmLCAmbGFkZHIsICZscG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAmbjEpID09IDQpIHsKICAgICAgICAgICAgaWYgKChzbyA9IHNvbGlzdGVuKDAsIGh0b25sKGxhZGRyKSwgaHRvbnMobHBvcnQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NfRkFDQ0VQVE9OQ0UpKSA9PSBOVUxMKQogICAgICAgICAgICAgICAgcmV0dXJuIDE7CgogICAgICAgICAgICBtLT5tX2xlbiA9IGJwdHIgLSBtLT5tX2RhdGE7IC8qIEFkanVzdCBsZW5ndGggKi8KICAgICAgICAgICAgbS0+bV9sZW4gKz0KICAgICAgICAgICAgICAgIHNucHJpbnRmKGJwdHIsIG0tPm1faGRyLm1oX3NpemUsICJEQ0MgTU9WRSAlcyAlbHUgJXUgJXUlY1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmYsICh1bnNpZ25lZCBsb25nKW50b2hsKHNvLT5zb19mYWRkci5zX2FkZHIpLAogICAgICAgICAgICAgICAgICAgICAgICAgbnRvaHMoc28tPnNvX2Zwb3J0KSwgbjEsIDEpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMTsKCiAgICBjYXNlIEVNVV9SRUFMQVVESU86CiAgICAgICAgLyoKICAgICAgICAgKiBSZWFsQXVkaW8gZW11bGF0aW9uIC0gSlAuIFdlIG11c3QgdHJ5IHRvIHBhcnNlIHRoZSBpbmNvbWluZwogICAgICAgICAqIGRhdGEgYW5kIHRyeSB0byBmaW5kIHRoZSB0d28gY2hhcmFjdGVycyB0aGF0IGNvbnRhaW4gdGhlCiAgICAgICAgICogcG9ydCBudW1iZXIuIFRoZW4gd2UgcmVkaXJlY3QgYW4gdWRwIHBvcnQgYW5kIHJlcGxhY2UgdGhlCiAgICAgICAgICogbnVtYmVyIHdpdGggdGhlIHJlYWwgcG9ydCB3ZSBnb3QuCiAgICAgICAgICoKICAgICAgICAgKiBUaGUgMS4wIGJldGEgdmVyc2lvbnMgb2YgdGhlIHBsYXllciBhcmUgbm90IHN1cHBvcnRlZAogICAgICAgICAqIGFueSBtb3JlLgogICAgICAgICAqCiAgICAgICAgICogQSB0eXBpY2FsIHBhY2tldCBmb3IgcGxheWVyIHZlcnNpb24gMS4wIChyZWxlYXNlIHZlcnNpb24pOgogICAgICAgICAqCiAgICAgICAgICogMDAwMDo1MCA0RSA0MSAwMCAwNQogICAgICAgICAqIDAwMDA6MDAgMDEgMDAgMDIgMUIgRDcgMDAgMDAgNjcgRTYgNkMgREMgNjMgMDAgMTIgNTAgLi4uLi7XLi5n5mzcYy4uUAogICAgICAgICAqIDAwMTA6NEUgNDMgNEMgNDkgNDUgNEUgNTQgMjAgMzEgMzAgMzEgMjAgNDEgNEMgNTAgNDggTkNMSUVOVCAxMDEgQUxQSAogICAgICAgICAqIDAwMjA6NDEgNkMgMDAgMDAgNTIgMDAgMTcgNzIgNjEgNjYgNjkgNkMgNjUgNzMgMkYgNzYgQWwuLlIuLnJhZmlsZXMvdgogICAgICAgICAqIDAwMzA6NkYgNjEgMkYgNjUgNkUgNjcgNkMgNjkgNzMgNjggNUYgMkUgNzIgNjEgNzkgNDIgb2EvZW5nbGlzaF8ucmF5QgogICAgICAgICAqCiAgICAgICAgICogTm93IHRoZSBwb3J0IG51bWJlciAweDFCRDcgaXMgZm91bmQgYXQgb2Zmc2V0IDB4MDQgb2YgdGhlCiAgICAgICAgICogTm93IHRoZSBwb3J0IG51bWJlciAweDFCRDcgaXMgZm91bmQgYXQgb2Zmc2V0IDB4MDQgb2YgdGhlCiAgICAgICAgICogc2Vjb25kIHBhY2tldC4gVGhpcyB0aW1lIHdlIHJlY2VpdmVkIGZpdmUgYnl0ZXMgZmlyc3QgYW5kCiAgICAgICAgICogdGhlbiB0aGUgcmVzdC4gWW91IG5ldmVyIGtub3cgaG93IG1hbnkgYnl0ZXMgeW91IGdldC4KICAgICAgICAgKgogICAgICAgICAqIEEgdHlwaWNhbCBwYWNrZXQgZm9yIHBsYXllciB2ZXJzaW9uIDIuMCAoYmV0YSk6CiAgICAgICAgICoKICAgICAgICAgKiAwMDAwOjUwIDRFIDQxIDAwIDA2IDAwIDAyIDAwIDAwIDAwIDAxIDAwIDAyIDFCIEMxIDAwIFBOQS4uLi4uLi4uLi4uwS4KICAgICAgICAgKiAwMDEwOjAwIDY3IDc1IDc4IEY1IDYzIDAwIDBBIDU3IDY5IDZFIDMyIDJFIDMwIDJFIDMwIC5ndXj1Yy4uV2luMi4wLjAKICAgICAgICAgKiAwMDIwOjJFIDM1IDZDIDAwIDAwIDUyIDAwIDFDIDcyIDYxIDY2IDY5IDZDIDY1IDczIDJGIC41bC4uUi4ucmFmaWxlcy8KICAgICAgICAgKiAwMDMwOjc3IDY1IDYyIDczIDY5IDc0IDY1IDJGIDMyIDMwIDcyIDY1IDZDIDY1IDYxIDczIHdlYnNpdGUvMjByZWxlYXMKICAgICAgICAgKiAwMDQwOjY1IDJFIDcyIDYxIDc5IDUzIDAwIDAwIDA2IDM2IDQyICAgICAgICAgICAgICAgIGUucmF5Uy4uLjZCCiAgICAgICAgICoKICAgICAgICAgKiBQb3J0IG51bWJlciAweDFCQzEgaXMgZm91bmQgYXQgb2Zmc2V0IDB4MGQuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIGlzIGp1c3QgYSBob3JyaWJsZSBzd2l0Y2ggc3RhdGVtZW50LiBWYXJpYWJsZSByYSB0ZWxscwogICAgICAgICAqIHVzIHdoZXJlIHdlJ3JlIGdvaW5nLgogICAgICAgICAqLwoKICAgICAgICBicHRyID0gbS0+bV9kYXRhOwogICAgICAgIHdoaWxlIChicHRyIDwgbS0+bV9kYXRhICsgbS0+bV9sZW4pIHsKICAgICAgICAgICAgdV9zaG9ydCBwOwogICAgICAgICAgICBzdGF0aWMgaW50IHJhID0gMDsKICAgICAgICAgICAgY2hhciByYV90YmxbNF07CgogICAgICAgICAgICByYV90YmxbMF0gPSAweDUwOwogICAgICAgICAgICByYV90YmxbMV0gPSAweDRlOwogICAgICAgICAgICByYV90YmxbMl0gPSAweDQxOwogICAgICAgICAgICByYV90YmxbM10gPSAwOwoKICAgICAgICAgICAgc3dpdGNoIChyYSkgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgaWYgKCpicHRyKysgIT0gcmFfdGJsW3JhXSkgewogICAgICAgICAgICAgICAgICAgIHJhID0gMDsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFdlIG1heSBnZXQgMHg1MCBzZXZlcmFsIHRpbWVzLCBpZ25vcmUgdGhlbQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoKmJwdHIgPT0gMHg1MCkgewogICAgICAgICAgICAgICAgICAgIHJhID0gMTsKICAgICAgICAgICAgICAgICAgICBicHRyKys7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCpicHRyKysgIT0gcmFfdGJsW3JhXSkgewogICAgICAgICAgICAgICAgICAgIHJhID0gMDsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHNraXAgdmVyc2lvbiBudW1iZXIKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgYnB0cisrOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB2ZXJzaW9ucyAxLjAgYW5kCiAgICAgICAgICAgICAgICAgKiAyLjAgaXMgaGVyZS4gRm9yIGZ1dHVyZSB2ZXJzaW9ucyBvZgogICAgICAgICAgICAgICAgICogdGhlIHBsYXllciB0aGlzIG1heSBuZWVkIHRvIGJlIG1vZGlmaWVkLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoKihicHRyICsgMSkgPT0gMHgwMikKICAgICAgICAgICAgICAgICAgICBicHRyICs9IDg7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgYnB0ciArPSA0OwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgICAgICAvKiBUaGlzIGlzIHRoZSBmaWVsZCBjb250YWluaW5nIHRoZSBwb3J0CiAgICAgICAgICAgICAgICAgKiBudW1iZXIgdGhhdCBSQS1wbGF5ZXIgaXMgbGlzdGVuaW5nIHRvLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBscG9ydCA9ICgoKHVfY2hhciAqKWJwdHIpWzBdIDw8IDgpICsgKCh1X2NoYXIgKilicHRyKVsxXTsKICAgICAgICAgICAgICAgIGlmIChscG9ydCA8IDY5NzApCiAgICAgICAgICAgICAgICAgICAgbHBvcnQgKz0gMjU2OyAvKiBkb24ndCBrbm93IHdoeSAqLwogICAgICAgICAgICAgICAgaWYgKGxwb3J0IDwgNjk3MCB8fCBscG9ydCA+IDcxNzApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7IC8qIGZhaWxlZCAqLwoKICAgICAgICAgICAgICAgIC8qIHRyeSB0byBnZXQgdWRwIHBvcnQgYmV0d2VlbiA2OTcwIC0gNzE3MCAqLwogICAgICAgICAgICAgICAgZm9yIChwID0gNjk3MDsgcCA8IDcwNzE7IHArKykgewogICAgICAgICAgICAgICAgICAgIGlmICh1ZHBfbGlzdGVuKGh0b25zKHApLCBzby0+c29fbGFkZHIuc19hZGRyLCBodG9ucyhscG9ydCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1NfRkFDQ0VQVE9OQ0UpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChwID09IDcwNzEpCiAgICAgICAgICAgICAgICAgICAgcCA9IDA7CiAgICAgICAgICAgICAgICAqKHVfY2hhciAqKWJwdHIrKyA9IChwID4+IDgpICYgMHhmZjsKICAgICAgICAgICAgICAgICoodV9jaGFyICopYnB0cisrID0gcCAmIDB4ZmY7CiAgICAgICAgICAgICAgICByYSA9IDA7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsgLyogcG9ydCByZWRpcmVjdGVkLCB3ZSdyZSBkb25lICovCiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByYSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmErKzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDE7CgogICAgZGVmYXVsdDoKICAgICAgICAvKiBPb29wcywgbm90IGVtdWxhdGVkLCB3b24ndCBjYWxsIHRjcF9lbXUgYWdhaW4gKi8KICAgICAgICBzby0+c29fZW11ID0gMDsKICAgICAgICByZXR1cm4gMTsKICAgIH0KfQoKLyoKICogRG8gbWlzYy4gY29uZmlnIG9mIFNMaVJQIHdoaWxlIGl0cyBydW5uaW5nLgogKiBSZXR1cm4gMCBpZiB0aGlzIGNvbm5lY3Rpb25zIGlzIHRvIGJlIGNsb3NlZCwgMSBvdGhlcndpc2UsCiAqIHJldHVybiAyIGlmIHRoaXMgaXMgYSBjb21tYW5kLWxpbmUgY29ubmVjdGlvbgogKi8KaW50IHRjcF9jdGwoc28pIHN0cnVjdCBzb2NrZXQgKnNvOwp7CiAgICBzdHJ1Y3Qgc2J1ZiAqc2IgPSAmc28tPnNvX3NuZDsKICAgIGludCBjb21tYW5kOwogICAgc3RydWN0IGV4X2xpc3QgKmV4X3B0cjsKICAgIGludCBkb19wdHk7CiAgICAvLwlzdHJ1Y3Qgc29ja2V0ICp0bXBzbzsKCiAgICBERUJVR19DQUxMKCJ0Y3BfY3RsIik7CiAgICBERUJVR19BUkcoInNvID0gJWx4IiwgKGxvbmcpc28pOwoKI2lmIDAKCS8qCgkgKiBDaGVjayBpZiB0aGV5J3JlIGF1dGhvcmlzZWQKCSAqLwoJaWYgKGN0bF9hZGRyLnNfYWRkciAmJiAoY3RsX2FkZHIuc19hZGRyID09IC0xIHx8IChzby0+c29fbGFkZHIuc19hZGRyICE9IGN0bF9hZGRyLnNfYWRkcikpKSB7CgkJc2ItPnNiX2NjID0gc3ByaW50ZihzYi0+c2Jfd3B0ciwiRXJyb3I6IFBlcm1pc3Npb24gZGVuaWVkLlxyXG4iKTsKCQlzYi0+c2Jfd3B0ciArPSBzYi0+c2JfY2M7CgkJcmV0dXJuIDA7Cgl9CiNlbmRpZgogICAgY29tbWFuZCA9IChudG9obChzby0+c29fZmFkZHIuc19hZGRyKSAmIDB4ZmYpOwoKICAgIHN3aXRjaCAoY29tbWFuZCkgewogICAgZGVmYXVsdDogLyogQ2hlY2sgZm9yIGV4ZWMncyAqLwoKICAgICAgICAvKgogICAgICAgICAqIENoZWNrIGlmIGl0J3MgcHR5X2V4ZWMKICAgICAgICAgKi8KICAgICAgICBmb3IgKGV4X3B0ciA9IGV4ZWNfbGlzdDsgZXhfcHRyOyBleF9wdHIgPSBleF9wdHItPmV4X25leHQpIHsKICAgICAgICAgICAgaWYgKGV4X3B0ci0+ZXhfZnBvcnQgPT0gc28tPnNvX2Zwb3J0ICYmCiAgICAgICAgICAgICAgICBjb21tYW5kID09IGV4X3B0ci0+ZXhfYWRkcikgewogICAgICAgICAgICAgICAgaWYgKGV4X3B0ci0+ZXhfcHR5ID09IDMpIHsKICAgICAgICAgICAgICAgICAgICBzby0+cyA9IC0xOwogICAgICAgICAgICAgICAgICAgIHNvLT5leHRyYSA9ICh2b2lkICopZXhfcHRyLT5leF9leGVjOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZG9fcHR5ID0gZXhfcHRyLT5leF9wdHk7CiAgICAgICAgICAgICAgICBnb3RvIGRvX2V4ZWM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogTm90aGluZyBib3VuZC4uCiAgICAgICAgICovCiAgICAgICAgLyogdGNwX2Zjb25uZWN0KHNvKTsgKi8KCiAgICAgICAgLyogRkFMTFRIUk9VR0ggKi8KICAgIGNhc2UgQ1RMX0FMSUFTOgogICAgICAgIHNiLT5zYl9jYyA9CiAgICAgICAgICAgIHNucHJpbnRmKHNiLT5zYl93cHRyLCBzYi0+c2JfZGF0YWxlbiAtIChzYi0+c2Jfd3B0ciAtIHNiLT5zYl9kYXRhKSwKICAgICAgICAgICAgICAgICAgICAgIkVycm9yOiBObyBhcHBsaWNhdGlvbiBjb25maWd1cmVkLlxyXG4iKTsKICAgICAgICBzYi0+c2Jfd3B0ciArPSBzYi0+c2JfY2M7CiAgICAgICAgcmV0dXJuICgwKTsKCiAgICBkb19leGVjOgogICAgICAgIERFQlVHX01JU0MoKGRmZCwgIiBleGVjdXRpbmcgJXMgXG4iLCBleF9wdHItPmV4X2V4ZWMpKTsKICAgICAgICByZXR1cm4gKGZvcmtfZXhlYyhzbywgZXhfcHRyLT5leF9leGVjLCBkb19wdHkpKTsKCiNpZiAwCgljYXNlIENUTF9DTUQ6CgkgICBmb3IgKHRtcHNvID0gdGNiLnNvX25leHQ7IHRtcHNvICE9ICZ0Y2I7IHRtcHNvID0gdG1wc28tPnNvX25leHQpIHsKCSAgICAgaWYgKHRtcHNvLT5zb19lbXUgPT0gRU1VX0NUTCAmJgoJCSAhKHRtcHNvLT5zb190Y3BjYj8KCQkgICAodG1wc28tPnNvX3RjcGNiLT50X3N0YXRlICYgKFRDUFNfVElNRV9XQUlUfFRDUFNfTEFTVF9BQ0spKQoJCSAgIDowKSkgewoJICAgICAgIC8qIE9vb3BzLCBjb250cm9sIGNvbm5lY3Rpb24gYWxyZWFkeSBhY3RpdmUgKi8KCSAgICAgICBzYi0+c2JfY2MgPSBzcHJpbnRmKHNiLT5zYl93cHRyLCJTb3JyeSwgYWxyZWFkeSBjb25uZWN0ZWQuXHJcbiIpOwoJICAgICAgIHNiLT5zYl93cHRyICs9IHNiLT5zYl9jYzsKCSAgICAgICByZXR1cm4gMDsKCSAgICAgfQoJICAgfQoJICAgc28tPnNvX2VtdSA9IEVNVV9DVEw7CgkgICBjdGxfcGFzc3dvcmRfb2sgPSAwOwoJICAgc2ItPnNiX2NjID0gc3ByaW50ZihzYi0+c2Jfd3B0ciwgIlNsaXJwIGNvbW1hbmQtbGluZSByZWFkeSAodHlwZSBcImhlbHBcIiBmb3IgaGVscCkuXHJcblNsaXJwPiAiKTsKCSAgIHNiLT5zYl93cHRyICs9IHNiLT5zYl9jYzsKCSAgIGRvX2VjaG89LTE7CgkgICByZXR1cm4oMik7CiNlbmRpZgogICAgfQp9Cg==