ZGlmZiAtLWdpdCBhL0FVVEhPUlMgYi9BVVRIT1JTCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA5NGViYmMKLS0tIC9kZXYvbnVsbAorKysgYi9BVVRIT1JTCkBAIC0wLDAgKzEsMjAgQEAKK0RhbmllbCBWZWlsbGFyZDoKKyAgIGRhbmllbEB2ZWlsbGFyZC5jb20KKyAgIERWIG9uICNnbm9tZSBJUkMgY2hhbm5lbAorICAgaHR0cDovL3ZlaWxsYXJkLmNvbS8KKyAgIFVzZWQgdG8gd29yayBhdCBXM0MsIG5vdyBSZWQgSGF0CisgICBjby1jaGFpciBvZiBXM0MgWE1MIExpbmtpbmcgV0cKKyAgIGludml0ZWQgZXhwZXJ0IG9uIHRoZSBXM0MgWE1MIENvcmUgV0cKKyAgIEF1dGhvciBvZiBsaWJ4bWwgdXBvbiB3aGljaCB0aGlzIGxpYnJhcnkgaXMgYmFzZWQuCisKK0Jqb3JuIFJlZXNlOgorICAgYnJlZXNlQHVzZXJzLnNvdXJjZWZvcmdlLm5ldAorICAgaHR0cDovL2hvbWUxLnN0b2ZhbmV0LmRrL2JyZWVzZS8KKyAgIFNvZnR3YXJlIGRldmVsb3BlciBhdCBodHRwOi8vd3d3LnN5c3RlbWF0aWMuZGsvCisgICBNZW1iZXIgb2YgdGhlIFhNTC1NVEYgTWFwcGluZyBXRy4KKworV2lsbGlhbSBCcmFjayA8d2JyYWNrQG1tbS5jb20uaGs+CisKK1Rob21hcyBCcm95ZXIgPHRicm95ZXJAbHRndC5uZXQ+CisKK0lnb3IgWmxhdGtvdmljIDxpZ29yQHpsYXRrb3ZpYy5jb20+IGZvciB0aGUgV2luZG93cyBwb3J0CmRpZmYgLS1naXQgYS9Db3B5cmlnaHQgYi9Db3B5cmlnaHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjI3ZWVmZgotLS0gL2Rldi9udWxsCisrKyBiL0NvcHlyaWdodApAQCAtMCwwICsxLDUzIEBACitMaWNlbmNlIGZvciBsaWJ4c2x0IGV4Y2VwdCBsaWJleHNsdAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIENvcHlyaWdodCAoQykgMjAwMS0yMDAyIERhbmllbCBWZWlsbGFyZC4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCisKK1Blcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKK29mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCitpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCit0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCitjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVyLQorbmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKworVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KK2FsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgorCitUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgorSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVC0KK05FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKK0RBTklFTCBWRUlMTEFSRCBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIKK0lOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTi0KK05FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCisKK0V4Y2VwdCBhcyBjb250YWluZWQgaW4gdGhpcyBub3RpY2UsIHRoZSBuYW1lIG9mIERhbmllbCBWZWlsbGFyZCBzaGFsbCBub3QKK2JlIHVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3Igb3RoZXJ3aXNlIHRvIHByb21vdGUgdGhlIHNhbGUsIHVzZSBvciBvdGhlciBkZWFsLQoraW5ncyBpbiB0aGlzIFNvZnR3YXJlIHdpdGhvdXQgcHJpb3Igd3JpdHRlbiBhdXRob3JpemF0aW9uIGZyb20gaGltLgorCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK0xpY2VuY2UgZm9yIGxpYmV4c2x0CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDIgVGhvbWFzIEJyb3llciwgQ2hhcmxpZSBCb3plbWFuIGFuZCBEYW5pZWwgVmVpbGxhcmQuCisgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKworUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQorb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKK2luIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKK3RvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKK2NvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXItCituaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorCitUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgorYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCisKK1RIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCitJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgRklULQorTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRQorQVVUSE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIKK0lOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTi0KK05FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCisKK0V4Y2VwdCBhcyBjb250YWluZWQgaW4gdGhpcyBub3RpY2UsIHRoZSBuYW1lIG9mIHRoZSBhdXRob3JzIHNoYWxsIG5vdAorYmUgdXNlZCBpbiBhZHZlcnRpc2luZyBvciBvdGhlcndpc2UgdG8gcHJvbW90ZSB0aGUgc2FsZSwgdXNlIG9yIG90aGVyIGRlYWwtCitpbmdzIGluIHRoaXMgU29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIGF1dGhvcml6YXRpb24gZnJvbSBoaW0uCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmRpZmYgLS1naXQgYS9SRUFETUUgYi9SRUFETUUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODViZjgwZQotLS0gL2Rldi9udWxsCisrKyBiL1JFQURNRQpAQCAtMCwwICsxLDI0IEBACisKKyAgICAgWFNMVCBzdXBwb3J0IGZvciBsaWJ4bWwyIChYTUwgdG9vbGtpdCBmcm9tIHRoZSBHTk9NRSBwcm9qZWN0KQorCitGdWxsIGRvY3VtZW50YXRpb24gaXMgYXZhaWxhYmxlIG9uLWxpbmUgYXQKKyAgICBodHRwOi8veG1sc29mdC5vcmcvWFNMVC8KKworVGhpcyBjb2RlIGlzIHJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5jZSBzZWUgdGhlIENvcHlyaWdodCBmaWxlLgorIAorVG8gcmVwb3J0IGJ1Z3MsIGZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zIGF0OgorICBodHRwOi8veG1sc29mdC5vcmcvWFNMVC9idWdzLmh0bWwKKworQSBtYWlsaW5nLWxpc3QgeHNsdEBnbm9tZS5vcmcgaXMgYXZhaWxhYmxlLCB0byBzdWJzY3JpYmU6CisgICAgaHR0cDovL21haWwuZ25vbWUub3JnL21haWxtYW4vbGlzdGluZm8veHNsdAorCitUaGUgbGlzdCBhcmNoaXZlIGlzIGF0OgorICAgIGh0dHA6Ly9tYWlsLmdub21lLm9yZy9hcmNoaXZlcy94c2x0LworCitBbGwgdGVjaG5pY2FsIGFuc3dlcnMgYXNrZWQgcHJpdmF0ZWx5IHdpbGwgYmUgYXV0b21hdGljYWxseSBhbnN3ZXJlZCBvbgordGhlIGxpc3QgYW5kIGFyY2hpdmVkIGZvciBwdWJsaWMgYWNjZXNzIHVubGVzcyBwcmljYWN5IGlzIGV4cGxpY2l0ZWx5CityZXF1aXJlZCBhbmQganVzdGlmaWVkLgorCitEYW5pZWwgVmVpbGxhcmQKKworJElkJApkaWZmIC0tZ2l0IGEvbGlieHNsdC9hdHRyaWJ1dGVzLmMgYi9saWJ4c2x0L2F0dHJpYnV0ZXMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZTQ3ZGY3Ci0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9hdHRyaWJ1dGVzLmMKQEAgLTAsMCArMSwxMTM5IEBACisvKgorICogYXR0cmlidXRlcy5jOiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgWFNMVCBhdHRyaWJ1dGVzIGhhbmRsaW5nCisgKgorICogUmVmZXJlbmNlOgorICogICBodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14c2x0LTE5OTkxMTE2CisgKgorICogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIGRhbmllbEB2ZWlsbGFyZC5jb20KKyAqLworCisjZGVmaW5lIElOX0xJQlhTTFQKKyNpbmNsdWRlICJsaWJ4c2x0LmgiCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2lmZGVmIEhBVkVfU1lTX1RZUEVTX0gKKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfTUFUSF9ICisjaW5jbHVkZSA8bWF0aC5oPgorI2VuZGlmCisjaWZkZWYgSEFWRV9GTE9BVF9ICisjaW5jbHVkZSA8ZmxvYXQuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfSUVFRUZQX0gKKyNpbmNsdWRlIDxpZWVlZnAuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfTkFOX0gKKyNpbmNsdWRlIDxuYW4uaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfQ1RZUEVfSAorI2luY2x1ZGUgPGN0eXBlLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGxpYnhtbC94bWxtZW1vcnkuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgPGxpYnhtbC9oYXNoLmg+CisjaW5jbHVkZSA8bGlieG1sL3htbGVycm9yLmg+CisjaW5jbHVkZSA8bGlieG1sL3VyaS5oPgorI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KKyNpbmNsdWRlICJ4c2x0LmgiCisjaW5jbHVkZSAieHNsdEludGVybmFscy5oIgorI2luY2x1ZGUgInhzbHR1dGlscy5oIgorI2luY2x1ZGUgImF0dHJpYnV0ZXMuaCIKKyNpbmNsdWRlICJuYW1lc3BhY2VzLmgiCisjaW5jbHVkZSAidGVtcGxhdGVzLmgiCisjaW5jbHVkZSAiaW1wb3J0cy5oIgorI2luY2x1ZGUgInRyYW5zZm9ybS5oIgorI2luY2x1ZGUgInByZXByb2MuaCIKKworI2RlZmluZSBXSVRIX1hTTFRfREVCVUdfQVRUUklCVVRFUworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworI2RlZmluZSBXSVRIX1hTTFRfREVCVUdfQVRUUklCVVRFUworI2VuZGlmCisKKy8qCisgKiBUT0RPOiBtZXJnZSBhdHRyaWJ1dGUgc2V0cyBmcm9tIGRpZmZlcmVudCBpbXBvcnQgcHJlY2VkZW5jZS4KKyAqICAgICAgIGFsbCB0aGlzIHNob3VsZCBiZSBwcmVjb21wdXRlZCBqdXN0IGJlZm9yZSB0aGUgdHJhbnNmb3JtYXRpb24KKyAqICAgICAgIHN0YXJ0cyBvciBhdCBmaXJzdCBoaXQgd2l0aCBhIGNhY2hlIGluIHRoZSBjb250ZXh0LgorICogICAgICAgVGhlIHNpbXBsZSB3YXkgZm9yIG5vdyB3b3VsZCBiZSB0byBub3QgYWxsb3cgcmVkZWZpbml0aW9uIG9mCisgKiAgICAgICBhdHRyaWJ1dGVzIG9uY2UgZ2VuZXJhdGVkIGluIHRoZSBvdXRwdXQgdHJlZSwgcG9zc2libHkgY29zdGxpZXIuCisgKi8KKworLyoKKyAqIFVzZWZ1bCBtYWNyb3MKKyAqLworI2lmZGVmIElTX0JMQU5LCisjdW5kZWYgSVNfQkxBTksKKyNlbmRpZgorCisjZGVmaW5lIElTX0JMQU5LKGMpICgoKGMpID09IDB4MjApIHx8ICgoYykgPT0gMHgwOSkgfHwgKChjKSA9PSAweEEpIHx8CVwKKyAgICAgICAgICAgICAgICAgICAgICgoYykgPT0gMHgwRCkpCisKKyNkZWZpbmUgSVNfQkxBTktfTk9ERShuKQkJCQkJCVwKKyAgICAoKChuKS0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSAmJiAoeHNsdElzQmxhbmsoKG4pLT5jb250ZW50KSkpCisKKworLyoKKyAqIFRoZSBpbi1tZW1vcnkgc3RydWN0dXJlIGNvcnJlc3BvbmRpbmcgdG8gYW4gWFNMVCBBdHRyaWJ1dGUgaW4KKyAqIGFuIGF0dHJpYnV0ZSBzZXQKKyAqLworCisKK3R5cGVkZWYgc3RydWN0IF94c2x0QXR0ckVsZW0geHNsdEF0dHJFbGVtOwordHlwZWRlZiB4c2x0QXR0ckVsZW0gKnhzbHRBdHRyRWxlbVB0cjsKK3N0cnVjdCBfeHNsdEF0dHJFbGVtIHsKKyAgICBzdHJ1Y3QgX3hzbHRBdHRyRWxlbSAqbmV4dDsvKiBjaGFpbmVkIGxpc3QgKi8KKyAgICB4bWxOb2RlUHRyIGF0dHI7CS8qIHRoZSB4c2w6YXR0cmlidXRlIGRlZmluaXRpb24gKi8KKyAgICBjb25zdCB4bWxDaGFyICpzZXQ7IC8qIG9yIHRoZSBhdHRyaWJ1dGUgc2V0ICovCisgICAgY29uc3QgeG1sQ2hhciAqbnM7ICAvKiBhbmQgaXRzIG5hbWVzcGFjZSAqLworfTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJCVhTTFQgQXR0cmlidXRlIGhhbmRsaW5nCQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0TmV3QXR0ckVsZW06CisgKiBAYXR0cjogIHRoZSBuZXcgeHNsOmF0dHJpYnV0ZSBub2RlCisgKgorICogQ3JlYXRlIGEgbmV3IFhTTFQgQXR0ckVsZW0KKyAqCisgKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgeHNsdEF0dHJFbGVtUHRyIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgorICovCitzdGF0aWMgeHNsdEF0dHJFbGVtUHRyCit4c2x0TmV3QXR0ckVsZW0oeG1sTm9kZVB0ciBhdHRyKSB7CisgICAgeHNsdEF0dHJFbGVtUHRyIGN1cjsKKworICAgIGN1ciA9ICh4c2x0QXR0ckVsZW1QdHIpIHhtbE1hbGxvYyhzaXplb2YoeHNsdEF0dHJFbGVtKSk7CisgICAgaWYgKGN1ciA9PSBOVUxMKSB7CisgICAgICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsCisJCSJ4c2x0TmV3QXR0ckVsZW0gOiBtYWxsb2MgZmFpbGVkXG4iKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIG1lbXNldChjdXIsIDAsIHNpemVvZih4c2x0QXR0ckVsZW0pKTsKKyAgICBjdXItPmF0dHIgPSBhdHRyOworICAgIHJldHVybihjdXIpOworfQorCisvKioKKyAqIHhzbHRGcmVlQXR0ckVsZW06CisgKiBAYXR0cjogIGFuIFhTTFQgQXR0ckVsZW0KKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGJ5IEBhdHRyCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0RnJlZUF0dHJFbGVtKHhzbHRBdHRyRWxlbVB0ciBhdHRyKSB7CisgICAgeG1sRnJlZShhdHRyKTsKK30KKworLyoqCisgKiB4c2x0RnJlZUF0dHJFbGVtTGlzdDoKKyAqIEBsaXN0OiAgYW4gWFNMVCBBdHRyRWxlbSBsaXN0CisgKgorICogRnJlZSB1cCB0aGUgbWVtb3J5IGFsbG9jYXRlZCBieSBAbGlzdAorICovCitzdGF0aWMgdm9pZAoreHNsdEZyZWVBdHRyRWxlbUxpc3QoeHNsdEF0dHJFbGVtUHRyIGxpc3QpIHsKKyAgICB4c2x0QXR0ckVsZW1QdHIgbmV4dDsKKyAgICAKKyAgICB3aGlsZSAobGlzdCAhPSBOVUxMKSB7CisJbmV4dCA9IGxpc3QtPm5leHQ7CisJeHNsdEZyZWVBdHRyRWxlbShsaXN0KTsKKwlsaXN0ID0gbmV4dDsKKyAgICB9Cit9CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICAvKgorICAgICogVGhpcyB3YXMgbW92ZWQgdG8geHNsdFBhcnNlU3R5bGVzaGVldEF0dHJpYnV0ZVNldCgpLgorICAgICovCisjZWxzZQorLyoqCisgKiB4c2x0QWRkQXR0ckVsZW1MaXN0OgorICogQGxpc3Q6ICBhbiBYU0xUIEF0dHJFbGVtIGxpc3QKKyAqIEBhdHRyOiAgdGhlIG5ldyB4c2w6YXR0cmlidXRlIG5vZGUKKyAqCisgKiBBZGQgdGhlIG5ldyBhdHRyaWJ1dGUgdG8gdGhlIGxpc3QuCisgKgorICogUmV0dXJucyB0aGUgbmV3IGxpc3QgcG9pbnRlcgorICovCitzdGF0aWMgeHNsdEF0dHJFbGVtUHRyCit4c2x0QWRkQXR0ckVsZW1MaXN0KHhzbHRBdHRyRWxlbVB0ciBsaXN0LCB4bWxOb2RlUHRyIGF0dHIpIHsKKyAgICB4c2x0QXR0ckVsZW1QdHIgbmV4dCwgY3VyOworCisgICAgaWYgKGF0dHIgPT0gTlVMTCkKKwlyZXR1cm4obGlzdCk7CisgICAgaWYgKGxpc3QgPT0gTlVMTCkKKwlyZXR1cm4oeHNsdE5ld0F0dHJFbGVtKGF0dHIpKTsKKyAgICBjdXIgPSBsaXN0OworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewkKKwluZXh0ID0gY3VyLT5uZXh0OworCWlmIChjdXItPmF0dHIgPT0gYXR0cikKKwkgICAgcmV0dXJuKGN1cik7CisJaWYgKGN1ci0+bmV4dCA9PSBOVUxMKSB7CisJICAgIGN1ci0+bmV4dCA9IHhzbHROZXdBdHRyRWxlbShhdHRyKTsKKwkgICAgcmV0dXJuKGxpc3QpOworCX0KKwljdXIgPSBuZXh0OworICAgIH0KKyAgICByZXR1cm4obGlzdCk7Cit9CisjZW5kaWYgLyogWFNMVF9SRUZBQ1RPUkVEICovCisKKy8qKgorICogeHNsdE1lcmdlQXR0ckVsZW1MaXN0OgorICogQGxpc3Q6ICBhbiBYU0xUIEF0dHJFbGVtIGxpc3QKKyAqIEBvbGQ6ICBhbm90aGVyIFhTTFQgQXR0ckVsZW0gbGlzdAorICoKKyAqIEFkZCBhbGwgdGhlIGF0dHJpYnV0ZXMgZnJvbSBsaXN0IEBvbGQgdG8gbGlzdCBAbGlzdCwKKyAqIGJ1dCBkcm9wIHJlZGVmaW5pdGlvbiBvZiBleGlzdGluZyB2YWx1ZXMuCisgKgorICogUmV0dXJucyB0aGUgbmV3IGxpc3QgcG9pbnRlcgorICovCitzdGF0aWMgeHNsdEF0dHJFbGVtUHRyCit4c2x0TWVyZ2VBdHRyRWxlbUxpc3QoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCSAgICAgIHhzbHRBdHRyRWxlbVB0ciBsaXN0LCB4c2x0QXR0ckVsZW1QdHIgb2xkKSB7CisgICAgeHNsdEF0dHJFbGVtUHRyIGN1cjsKKyAgICBpbnQgYWRkOworCisgICAgd2hpbGUgKG9sZCAhPSBOVUxMKSB7CisJaWYgKChvbGQtPmF0dHIgPT0gTlVMTCkgJiYgKG9sZC0+c2V0ID09IE5VTEwpKSB7CisJICAgIG9sZCA9IG9sZC0+bmV4dDsKKwkgICAgY29udGludWU7CisJfQorCS8qCisJICogQ2hlY2sgdGhhdCB0aGUgYXR0cmlidXRlIGlzIG5vdCB5ZXQgaW4gdGhlIGxpc3QKKwkgKi8KKwljdXIgPSBsaXN0OworCWFkZCA9IDE7CisJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJICAgIGlmICgoY3VyLT5hdHRyID09IE5VTEwpICYmIChjdXItPnNldCA9PSBOVUxMKSkgeworCQlpZiAoY3VyLT5uZXh0ID09IE5VTEwpCisJCSAgICBicmVhazsKKwkJY3VyID0gY3VyLT5uZXh0OworCQljb250aW51ZTsKKwkgICAgfQorCSAgICBpZiAoKGN1ci0+c2V0ICE9IE5VTEwpICYmIChjdXItPnNldCA9PSBvbGQtPnNldCkpIHsKKwkJYWRkID0gMDsKKwkJYnJlYWs7CisJICAgIH0KKwkgICAgaWYgKGN1ci0+c2V0ICE9IE5VTEwpIHsKKwkJaWYgKGN1ci0+bmV4dCA9PSBOVUxMKQorCQkgICAgYnJlYWs7CisJCWN1ciA9IGN1ci0+bmV4dDsKKwkJY29udGludWU7CisJICAgIH0KKwkgICAgaWYgKG9sZC0+c2V0ICE9IE5VTEwpIHsKKwkJaWYgKGN1ci0+bmV4dCA9PSBOVUxMKQorCQkgICAgYnJlYWs7CisJCWN1ciA9IGN1ci0+bmV4dDsKKwkJY29udGludWU7CisJICAgIH0KKwkgICAgaWYgKGN1ci0+YXR0ciA9PSBvbGQtPmF0dHIpIHsKKwkJeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkgICAgICJ4c2w6YXR0cmlidXRlLXNldCA6IHVzZS1hdHRyaWJ1dGUtc2V0cyByZWN1cnNpb24gZGV0ZWN0ZWRcbiIpOworCQlyZXR1cm4obGlzdCk7CisJICAgIH0KKwkgICAgaWYgKGN1ci0+bmV4dCA9PSBOVUxMKQorCQlicmVhazsKKyAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKKwl9CisKKwlpZiAoYWRkID09IDEpIHsKKwkgICAgLyoKKwkgICAgKiBDaGFuZ2VkIHRvIHVzZSB0aGUgc3RyaW5nLWRpY3QsIHJhdGhlciB0aGFuIGR1cGxpY2F0aW5nCisJICAgICogQHNldCBhbmQgQG5zOyB0aGlzIGZpeGVzIGJ1ZyAjMzQwNDAwLgorCSAgICAqLworCSAgICBpZiAoY3VyID09IE5VTEwpIHsKKwkJbGlzdCA9IHhzbHROZXdBdHRyRWxlbShvbGQtPmF0dHIpOworCQlpZiAob2xkLT5zZXQgIT0gTlVMTCkgeworCQkgICAgbGlzdC0+c2V0ID0geG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgb2xkLT5zZXQsIC0xKTsKKwkJICAgIGlmIChvbGQtPm5zICE9IE5VTEwpCisJCQlsaXN0LT5ucyA9IHhtbERpY3RMb29rdXAoc3R5bGUtPmRpY3QsIG9sZC0+bnMsIC0xKTsKKwkJfQorCSAgICB9IGVsc2UgaWYgKGFkZCkgeworCQljdXItPm5leHQgPSB4c2x0TmV3QXR0ckVsZW0ob2xkLT5hdHRyKTsKKwkJaWYgKG9sZC0+c2V0ICE9IE5VTEwpIHsKKwkJICAgIGN1ci0+bmV4dC0+c2V0ID0geG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgb2xkLT5zZXQsIC0xKTsKKwkJICAgIGlmIChvbGQtPm5zICE9IE5VTEwpCisJCQljdXItPm5leHQtPm5zID0geG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgb2xkLT5ucywgLTEpOworCQl9CisJICAgIH0KKwl9CisKKwlvbGQgPSBvbGQtPm5leHQ7CisgICAgfQorICAgIHJldHVybihsaXN0KTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJCU1vZHVsZSBpbnRlcmZhY2VzCQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0UGFyc2VTdHlsZXNoZWV0QXR0cmlidXRlU2V0OgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICogQGN1cjogIHRoZSAiYXR0cmlidXRlLXNldCIgZWxlbWVudAorICoKKyAqIHBhcnNlIGFuIFhTTFQgc3R5bGVzaGVldCBhdHRyaWJ1dGUtc2V0IGVsZW1lbnQKKyAqLworCit2b2lkCit4c2x0UGFyc2VTdHlsZXNoZWV0QXR0cmlidXRlU2V0KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGN1cikgeworICAgIGNvbnN0IHhtbENoYXIgKm5jbmFtZTsKKyAgICBjb25zdCB4bWxDaGFyICpwcmVmaXg7CisgICAgeG1sQ2hhciAqdmFsdWU7CisgICAgeG1sTm9kZVB0ciBjaGlsZDsKKyAgICB4c2x0QXR0ckVsZW1QdHIgYXR0ckl0ZW1zOworCisgICAgaWYgKChjdXIgPT0gTlVMTCkgfHwgKHN0eWxlID09IE5VTEwpKQorCXJldHVybjsKKworICAgIHZhbHVlID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikibmFtZSIsIE5VTEwpOworICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CisJeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkgICAgICJ4c2w6YXR0cmlidXRlLXNldCA6IG5hbWUgaXMgbWlzc2luZ1xuIik7CisJcmV0dXJuOworICAgIH0KKworICAgIG5jbmFtZSA9IHhzbHRTcGxpdFFOYW1lKHN0eWxlLT5kaWN0LCB2YWx1ZSwgJnByZWZpeCk7CisgICAgeG1sRnJlZSh2YWx1ZSk7CisgICAgdmFsdWUgPSBOVUxMOworCisgICAgaWYgKHN0eWxlLT5hdHRyaWJ1dGVTZXRzID09IE5VTEwpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfQVRUUklCVVRFUworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICJjcmVhdGluZyBhdHRyaWJ1dGUgc2V0IHRhYmxlXG4iKTsKKyNlbmRpZgorCXN0eWxlLT5hdHRyaWJ1dGVTZXRzID0geG1sSGFzaENyZWF0ZSgxMCk7CisgICAgfQorICAgIGlmIChzdHlsZS0+YXR0cmlidXRlU2V0cyA9PSBOVUxMKQorCXJldHVybjsKKworICAgIGF0dHJJdGVtcyA9IHhtbEhhc2hMb29rdXAyKHN0eWxlLT5hdHRyaWJ1dGVTZXRzLCBuY25hbWUsIHByZWZpeCk7CisKKyAgICAvKgorICAgICogUGFyc2UgdGhlIGNvbnRlbnQuIE9ubHkgeHNsOmF0dHJpYnV0ZSBlbGVtZW50cyBhcmUgYWxsb3dlZC4KKyAgICAqLworICAgIGNoaWxkID0gY3VyLT5jaGlsZHJlbjsKKyAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgeworCS8qCisJKiBSZXBvcnQgaW52YWxpZCBub2Rlcy4KKwkqLworCWlmICgoY2hpbGQtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkgfHwKKwkgICAgKGNoaWxkLT5ucyA9PSBOVUxMKSB8fAorCSAgICAoISBJU19YU0xUX0VMRU0oY2hpbGQpKSkKKwl7CisJICAgIGlmIChjaGlsZC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKQorCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGNoaWxkLAorCQkJInhzbDphdHRyaWJ1dGUtc2V0IDogdW5leHBlY3RlZCBjaGlsZCAlc1xuIiwKKwkJICAgICAgICAgICAgICAgICBjaGlsZC0+bmFtZSk7CisJICAgIGVsc2UKKwkJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjaGlsZCwKKwkJCSJ4c2w6YXR0cmlidXRlLXNldCA6IGNoaWxkIG9mIHVuZXhwZWN0ZWQgdHlwZVxuIik7CisJfSBlbHNlIGlmICghSVNfWFNMVF9OQU1FKGNoaWxkLCAiYXR0cmlidXRlIikpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjaGlsZCwKKwkJInhzbDphdHRyaWJ1dGUtc2V0IDogdW5leHBlY3RlZCBjaGlsZCB4c2w6JXNcbiIsCisJCWNoaWxkLT5uYW1lKTsKKwl9IGVsc2UgeworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCSAgICB4c2x0QXR0ckVsZW1QdHIgbmV4dEF0dHIsIGN1ckF0dHI7CisKKwkgICAgLyoKKwkgICAgKiBQcm9jZXNzIHhzbDphdHRyaWJ1dGUKKwkgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwkgICAgKi8KKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19BVFRSSUJVVEVTCisJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSJhZGQgYXR0cmlidXRlIHRvIGxpc3QgJXNcbiIsIG5jbmFtZSk7CisjZW5kaWYKKwkgICAgLyoKKwkgICAgKiBUaGUgZm9sbG93aW5nIHdhcyB0YWtlbiBvdmVyIGZyb20KKwkgICAgKiB4c2x0QWRkQXR0ckVsZW1MaXN0KCkuCisJICAgICovCisJICAgIGlmIChhdHRySXRlbXMgPT0gTlVMTCkgeworCQlhdHRySXRlbXMgPSB4c2x0TmV3QXR0ckVsZW0oY2hpbGQpOworCSAgICB9IGVsc2UgeworCQljdXJBdHRyID0gYXR0ckl0ZW1zOworCQl3aGlsZSAoY3VyQXR0ciAhPSBOVUxMKSB7CisJCSAgICBuZXh0QXR0ciA9IGN1ckF0dHItPm5leHQ7CisJCSAgICBpZiAoY3VyQXR0ci0+YXR0ciA9PSBjaGlsZCkgeworCQkJLyoKKwkJCSogVVJHRU5UIFRPRE86IENhbiBzb21lYm9keSBleHBsYWluCisJCQkqICB3aHkgYXR0ckl0ZW1zIGlzIHNldCB0byBjdXJBdHRyCisJCQkqICBoZXJlPyBJcyB0aGlzIHNvbWVob3cgcmVsYXRlZCB0bworCQkJKiAgYXZvaWRhbmNlIG9mIHJlY3Vyc2lvbnM/CisJCQkqLworCQkJYXR0ckl0ZW1zID0gY3VyQXR0cjsKKwkJCWdvdG8gbmV4dF9jaGlsZDsKKwkJICAgIH0KKwkJICAgIGlmIChjdXJBdHRyLT5uZXh0ID09IE5VTEwpCQkJCisJCQljdXJBdHRyLT5uZXh0ID0geHNsdE5ld0F0dHJFbGVtKGNoaWxkKTsKKwkJICAgIGN1ckF0dHIgPSBuZXh0QXR0cjsKKwkJfQorCSAgICB9CisJICAgIC8qCisJICAgICogUGFyc2UgdGhlIHhzbDphdHRyaWJ1dGUgYW5kIGl0cyBjb250ZW50LgorCSAgICAqLworCSAgICB4c2x0UGFyc2VBbnlYU0xURWxlbShYU0xUX0NDVFhUKHN0eWxlKSwgY2hpbGQpOworI2Vsc2UKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfQVRUUklCVVRFUworCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkiYWRkIGF0dHJpYnV0ZSB0byBsaXN0ICVzXG4iLCBuY25hbWUpOworI2VuZGlmCisJICAgIC8qCisJICAgICogT0xEIGJlaGF2aW91cjoKKwkgICAgKi8KKwkgICAgYXR0ckl0ZW1zID0geHNsdEFkZEF0dHJFbGVtTGlzdChhdHRySXRlbXMsIGNoaWxkKTsKKyNlbmRpZgorCX0KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorbmV4dF9jaGlsZDoKKyNlbmRpZgorCWNoaWxkID0gY2hpbGQtPm5leHQ7CisgICAgfQorCisgICAgLyoKKyAgICAqIFByb2Nlc3MgYXR0cmlidWUgInVzZS1hdHRyaWJ1dGUtc2V0cyIuCisgICAgKi8KKyAgICAvKiBUT0RPIGNoZWNrIHJlY3Vyc2lvbiAqLyAgICAKKyAgICB2YWx1ZSA9IHhtbEdldE5zUHJvcChjdXIsIChjb25zdCB4bWxDaGFyICopInVzZS1hdHRyaWJ1dGUtc2V0cyIsCisJTlVMTCk7CisgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKwljb25zdCB4bWxDaGFyICpjdXJ2YWwsICplbmR2YWw7CisJY3VydmFsID0gdmFsdWU7CisJd2hpbGUgKCpjdXJ2YWwgIT0gMCkgeworCSAgICB3aGlsZSAoSVNfQkxBTksoKmN1cnZhbCkpIGN1cnZhbCsrOworCSAgICBpZiAoKmN1cnZhbCA9PSAwKQorCQlicmVhazsKKwkgICAgZW5kdmFsID0gY3VydmFsOworCSAgICB3aGlsZSAoKCplbmR2YWwgIT0gMCkgJiYgKCFJU19CTEFOSygqZW5kdmFsKSkpIGVuZHZhbCsrOworCSAgICBjdXJ2YWwgPSB4bWxEaWN0TG9va3VwKHN0eWxlLT5kaWN0LCBjdXJ2YWwsIGVuZHZhbCAtIGN1cnZhbCk7CisJICAgIGlmIChjdXJ2YWwpIHsKKwkJY29uc3QgeG1sQ2hhciAqbmNuYW1lMiA9IE5VTEw7CisJCWNvbnN0IHhtbENoYXIgKnByZWZpeDIgPSBOVUxMOworCQl4c2x0QXR0ckVsZW1QdHIgcmVmQXR0ckl0ZW1zOworCQkKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfQVRUUklCVVRFUworCQl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgInhzbDphdHRyaWJ1dGUtc2V0IDogJXMgYWRkcyB1c2UgJXNcbiIsIG5jbmFtZSwgY3VydmFsKTsKKyNlbmRpZgorCQluY25hbWUyID0geHNsdFNwbGl0UU5hbWUoc3R5bGUtPmRpY3QsIGN1cnZhbCwgJnByZWZpeDIpOworCQlyZWZBdHRySXRlbXMgPSB4c2x0TmV3QXR0ckVsZW0oTlVMTCk7CisJCWlmIChyZWZBdHRySXRlbXMgIT0gTlVMTCkgeworCQkgICAgcmVmQXR0ckl0ZW1zLT5zZXQgPSBuY25hbWUyOworCQkgICAgcmVmQXR0ckl0ZW1zLT5ucyA9IHByZWZpeDI7CisJCSAgICBhdHRySXRlbXMgPSB4c2x0TWVyZ2VBdHRyRWxlbUxpc3Qoc3R5bGUsCisJCQlhdHRySXRlbXMsIHJlZkF0dHJJdGVtcyk7CisJCSAgICB4c2x0RnJlZUF0dHJFbGVtKHJlZkF0dHJJdGVtcyk7CisJCX0KKwkgICAgfQorCSAgICBjdXJ2YWwgPSBlbmR2YWw7CisJfQorCXhtbEZyZWUodmFsdWUpOworCXZhbHVlID0gTlVMTDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFVwZGF0ZSB0aGUgdmFsdWUKKyAgICAgKi8KKyAgICAvKgorICAgICogVE9ETzogV2h5IGlzIHRoaXMgZHVtbXkgZW50cnkgbmVlZGVkLj8KKyAgICAqLworICAgIGlmIChhdHRySXRlbXMgPT0gTlVMTCkKKwlhdHRySXRlbXMgPSB4c2x0TmV3QXR0ckVsZW0oTlVMTCk7CisgICAgeG1sSGFzaFVwZGF0ZUVudHJ5MihzdHlsZS0+YXR0cmlidXRlU2V0cywgbmNuYW1lLCBwcmVmaXgsIGF0dHJJdGVtcywgTlVMTCk7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0FUVFJJQlVURVMKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJ1cGRhdGVkIGF0dHJpYnV0ZSBsaXN0ICVzXG4iLCBuY25hbWUpOworI2VuZGlmCit9CisKKy8qKgorICogeHNsdEdldFNBUzoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBsaXN0IG5hbWUKKyAqIEBuczogIHRoZSBhdHRyaWJ1dGUgbGlzdCBuYW1lc3BhY2UKKyAqCisgKiBsb29rdXAgYW4gYXR0cmlidXRlIHNldCBiYXNlZCBvbiB0aGUgc3R5bGUgY2FzY2FkZQorICoKKyAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBzZXQgb3IgTlVMTAorICovCitzdGF0aWMgeHNsdEF0dHJFbGVtUHRyCit4c2x0R2V0U0FTKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCBjb25zdCB4bWxDaGFyICpuYW1lLCBjb25zdCB4bWxDaGFyICpucykgeworICAgIHhzbHRBdHRyRWxlbVB0ciB2YWx1ZXM7CisKKyAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworCXZhbHVlcyA9IHhtbEhhc2hMb29rdXAyKHN0eWxlLT5hdHRyaWJ1dGVTZXRzLCBuYW1lLCBucyk7CisJaWYgKHZhbHVlcyAhPSBOVUxMKQorCSAgICByZXR1cm4odmFsdWVzKTsKKwlzdHlsZSA9IHhzbHROZXh0SW1wb3J0KHN0eWxlKTsKKyAgICB9CisgICAgcmV0dXJuKE5VTEwpOworfQorCisvKioKKyAqIHhzbHRSZXNvbHZlU0FTQ2FsbGJhY2ssOgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICoKKyAqIHJlc29sdmUgdGhlIHJlZmVyZW5jZXMgaW4gYW4gYXR0cmlidXRlIHNldC4KKyAqLworc3RhdGljIHZvaWQKK3hzbHRSZXNvbHZlU0FTQ2FsbGJhY2soeHNsdEF0dHJFbGVtUHRyIHZhbHVlcywgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgY29uc3QgeG1sQ2hhciAqbnMsCisJCSAgICAgICBBVFRSSUJVVEVfVU5VU0VEIGNvbnN0IHhtbENoYXIgKmlnbm9yZWQpIHsKKyAgICB4c2x0QXR0ckVsZW1QdHIgdG1wOworICAgIHhzbHRBdHRyRWxlbVB0ciByZWZzOworCisgICAgdG1wID0gdmFsdWVzOworICAgIHdoaWxlICh0bXAgIT0gTlVMTCkgeworCWlmICh0bXAtPnNldCAhPSBOVUxMKSB7CisJICAgIC8qCisJICAgICAqIENoZWNrIGFnYWluc3QgY3ljbGVzICEKKwkgICAgICovCisJICAgIGlmICgoeG1sU3RyRXF1YWwobmFtZSwgdG1wLT5zZXQpKSAmJiAoeG1sU3RyRXF1YWwobnMsIHRtcC0+bnMpKSkgeworCQl4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LAorICAgICAieHNsOmF0dHJpYnV0ZS1zZXQgOiB1c2UtYXR0cmlidXRlLXNldHMgcmVjdXJzaW9uIGRldGVjdGVkIG9uICVzXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CisJICAgIH0gZWxzZSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0FUVFJJQlVURVMKKwkJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSJJbXBvcnRpbmcgYXR0cmlidXRlIGxpc3QgJXNcbiIsIHRtcC0+c2V0KTsKKyNlbmRpZgorCisJCXJlZnMgPSB4c2x0R2V0U0FTKHN0eWxlLCB0bXAtPnNldCwgdG1wLT5ucyk7CisJCWlmIChyZWZzID09IE5VTEwpIHsKKwkJICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsCisgICAgICJ4c2w6YXR0cmlidXRlLXNldCA6IHVzZS1hdHRyaWJ1dGUtc2V0cyAlcyByZWZlcmVuY2UgbWlzc2luZyAlc1xuIiwKKwkJCQkgICAgIG5hbWUsIHRtcC0+c2V0KTsKKwkJfSBlbHNlIHsKKwkJICAgIC8qCisJCSAgICAgKiByZWN1cnNlIGZpcnN0IGZvciBjbGVhbnVwCisJCSAgICAgKi8KKwkJICAgIHhzbHRSZXNvbHZlU0FTQ2FsbGJhY2socmVmcywgc3R5bGUsIG5hbWUsIG5zLCBOVUxMKTsKKwkJICAgIC8qCisJCSAgICAgKiBUaGVuIG1lcmdlCisJCSAgICAgKi8KKwkJICAgIHhzbHRNZXJnZUF0dHJFbGVtTGlzdChzdHlsZSwgdmFsdWVzLCByZWZzKTsKKwkJICAgIC8qCisJCSAgICAgKiBUaGVuIHN1cHByZXNzIHRoZSByZWZlcmVuY2UKKwkJICAgICAqLworCQkgICAgdG1wLT5zZXQgPSBOVUxMOworCQkgICAgdG1wLT5ucyA9IE5VTEw7CisJCX0KKwkgICAgfQorCX0KKwl0bXAgPSB0bXAtPm5leHQ7CisgICAgfQorfQorCisvKioKKyAqIHhzbHRNZXJnZVNBU0NhbGxiYWNrLDoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqCisgKiBNZXJnZSBhbiBhdHRyaWJ1dGUgc2V0IGZyb20gYW4gaW1wb3J0ZWQgc3R5bGVzaGVldC4KKyAqLworc3RhdGljIHZvaWQKK3hzbHRNZXJnZVNBU0NhbGxiYWNrKHhzbHRBdHRyRWxlbVB0ciB2YWx1ZXMsIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCSAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKm5zLAorCQkgICAgICAgQVRUUklCVVRFX1VOVVNFRCBjb25zdCB4bWxDaGFyICppZ25vcmVkKSB7CisgICAgaW50IHJldDsKKyAgICB4c2x0QXR0ckVsZW1QdHIgdG9wU2V0OworCisgICAgcmV0ID0geG1sSGFzaEFkZEVudHJ5MihzdHlsZS0+YXR0cmlidXRlU2V0cywgbmFtZSwgbnMsIHZhbHVlcyk7CisgICAgaWYgKHJldCA8IDApIHsKKwkvKgorCSAqIEFkZCBmYWlsZWQsIHRoaXMgYXR0cmlidXRlIHNldCBjYW4gYmUgcmVtb3ZlZC4KKwkgKi8KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfQVRUUklCVVRFUworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSJhdHRyaWJ1dGUgc2V0ICVzIHByZXNlbnQgYWxyZWFkeSBpbiB0b3Agc3R5bGVzaGVldCIKKwkJIiAtIG1lcmdpbmdcbiIsIG5hbWUpOworI2VuZGlmCisJdG9wU2V0ID0geG1sSGFzaExvb2t1cDIoc3R5bGUtPmF0dHJpYnV0ZVNldHMsIG5hbWUsIG5zKTsKKwlpZiAodG9wU2V0PT1OVUxMKSB7CisJICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsCisJICAgICAgICAieHNsOmF0dHJpYnV0ZS1zZXQgOiBsb2dpYyBlcnJvciBtZXJnaW5nIGZyb20gaW1wb3J0cyBmb3IiCisJCSIgYXR0cmlidXRlLXNldCAlc1xuIiwgbmFtZSk7CisJfSBlbHNlIHsKKwkgICAgdG9wU2V0ID0geHNsdE1lcmdlQXR0ckVsZW1MaXN0KHN0eWxlLCB0b3BTZXQsIHZhbHVlcyk7CisJICAgIHhtbEhhc2hVcGRhdGVFbnRyeTIoc3R5bGUtPmF0dHJpYnV0ZVNldHMsIG5hbWUsIG5zLCB0b3BTZXQsIE5VTEwpOworCX0KKwl4c2x0RnJlZUF0dHJFbGVtTGlzdCh2YWx1ZXMpOworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19BVFRSSUJVVEVTCisgICAgfSBlbHNlIHsKKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkiYXR0cmlidXRlIHNldCAlcyBtb3ZlZCB0byB0b3Agc3R5bGVzaGVldFxuIiwKKwkJICAgICAgICAgbmFtZSk7CisjZW5kaWYKKyAgICB9Cit9CisKKy8qKgorICogeHNsdFJlc29sdmVTdHlsZXNoZWV0QXR0cmlidXRlU2V0OgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICoKKyAqIHJlc29sdmUgdGhlIHJlZmVyZW5jZXMgYmV0d2VlbiBhdHRyaWJ1dGUgc2V0cy4KKyAqLwordm9pZAoreHNsdFJlc29sdmVTdHlsZXNoZWV0QXR0cmlidXRlU2V0KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKSB7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgY3VyOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0FUVFJJQlVURVMKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAiUmVzb2x2aW5nIGF0dHJpYnV0ZSBzZXRzIHJlZmVyZW5jZXNcbiIpOworI2VuZGlmCisgICAgLyoKKyAgICAgKiBGaXJzdCBhZ2dyZWdhdGUgYWxsIHRoZSBhdHRyaWJ1dGUgc2V0cyBkZWZpbml0aW9ucyBmcm9tIHRoZSBpbXBvcnRzCisgICAgICovCisgICAgY3VyID0geHNsdE5leHRJbXBvcnQoc3R5bGUpOworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCWlmIChjdXItPmF0dHJpYnV0ZVNldHMgIT0gTlVMTCkgeworCSAgICBpZiAoc3R5bGUtPmF0dHJpYnV0ZVNldHMgPT0gTlVMTCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19BVFRSSUJVVEVTCisJCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAiY3JlYXRpbmcgYXR0cmlidXRlIHNldCB0YWJsZVxuIik7CisjZW5kaWYKKwkJc3R5bGUtPmF0dHJpYnV0ZVNldHMgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKKwkgICAgfQorCSAgICB4bWxIYXNoU2NhbkZ1bGwoY3VyLT5hdHRyaWJ1dGVTZXRzLCAKKwkJKHhtbEhhc2hTY2FubmVyRnVsbCkgeHNsdE1lcmdlU0FTQ2FsbGJhY2ssIHN0eWxlKTsKKwkgICAgLyoKKwkgICAgICogdGhlIGF0dHJpYnV0ZSBsaXN0cyBoYXZlIGVpdGhlciBiZWVuIG1pZ3JhdGVkIHRvIHN0eWxlCisJICAgICAqIG9yIGZyZWVkIGRpcmVjdGx5IGluIHhzbHRNZXJnZVNBU0NhbGxiYWNrKCkKKwkgICAgICovCisJICAgIHhtbEhhc2hGcmVlKGN1ci0+YXR0cmlidXRlU2V0cywgTlVMTCk7CisJICAgIGN1ci0+YXR0cmlidXRlU2V0cyA9IE5VTEw7CisJfQorCWN1ciA9IHhzbHROZXh0SW1wb3J0KGN1cik7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGVuIHJlc29sdmUgYWxsIHRoZSByZWZlcmVuY2VzIGFuZCBjb21wdXRlcyB0aGUgcmVzdWx0aW5nIHNldHMKKyAgICAgKi8KKyAgICBpZiAoc3R5bGUtPmF0dHJpYnV0ZVNldHMgIT0gTlVMTCkgeworCXhtbEhhc2hTY2FuRnVsbChzdHlsZS0+YXR0cmlidXRlU2V0cywgCisJCSh4bWxIYXNoU2Nhbm5lckZ1bGwpIHhzbHRSZXNvbHZlU0FTQ2FsbGJhY2ssIHN0eWxlKTsKKyAgICB9Cit9CisKKy8qKgorICogeHNsdEF0dHJpYnV0ZUludGVybmFsOgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAbm9kZTogIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlCisgKiBAaW5zdDogIHRoZSB4c2w6YXR0cmlidXRlIGVsZW1lbnQKKyAqIEBjb21wOiAgcHJlY29tcHV0ZWQgaW5mb3JtYXRpb24KKyAqIEBmcm9tQXR0cmlidXRlU2V0OiAgdGhlIGF0dHJpYnV0ZSBjb21lcyBmcm9tIGFuIGF0dHJpYnV0ZS1zZXQKKyAqCisgKiBQcm9jZXNzIHRoZSB4c2x0IGF0dHJpYnV0ZSBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCitzdGF0aWMgdm9pZAoreHNsdEF0dHJpYnV0ZUludGVybmFsKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCSAgICAgIHhtbE5vZGVQdHIgY29udGV4dE5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBpbnN0LAorCQkgICAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNhc3RlZENvbXAsCisgICAgICAgICAgICAgICAgICAgICAgaW50IGZyb21BdHRyaWJ1dGVTZXQpCit7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbUF0dHJpYnV0ZVB0ciBjb21wID0KKwkoeHNsdFN0eWxlSXRlbUF0dHJpYnV0ZVB0cikgY2FzdGVkQ29tcDsgICAKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wID0gY2FzdGVkQ29tcDsKKyNlbmRpZgorICAgIHhtbE5vZGVQdHIgdGFyZ2V0RWxlbTsKKyAgICB4bWxDaGFyICpwcm9wID0gTlVMTDsgICAgCisgICAgY29uc3QgeG1sQ2hhciAqbmFtZSA9IE5VTEwsICpwcmVmaXggPSBOVUxMLCAqbnNOYW1lID0gTlVMTDsKKyAgICB4bWxDaGFyICp2YWx1ZSA9IE5VTEw7CisgICAgeG1sTnNQdHIgbnMgPSBOVUxMOworICAgIHhtbEF0dHJQdHIgYXR0cjsgICAgCisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGNvbnRleHROb2RlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpKQorICAgICAgICByZXR1cm47CisKKyAgICAvKiAKKyAgICAqIEEgY29tcC0+aGFzX25hbWUgPT0gMCBpbmRpY2F0ZXMgdGhhdCB3ZSBuZWVkIHRvIHNraXAgdGhpcyBpbnN0cnVjdGlvbiwKKyAgICAqIHNpbmNlIGl0IHdhcyBldmFsdWF0ZWQgdG8gYmUgaW52YWxpZCBhbHJlYWR5IGR1cmluZyBjb21waWxhdGlvbi4KKyAgICAqLworICAgIGlmICghY29tcC0+aGFzX25hbWUpCisgICAgICAgIHJldHVybjsKKyAgICAvKgorICAgICogQklHIE5PVEU6IFRoaXMgcHJldmlvdXNseSB1c2VkIHhzbHRHZXRTcGVjaWFsTmFtZXNwYWNlKCkgYW5kCisgICAgKiAgeHNsdEdldE5hbWVzcGFjZSgpLCBidXQgc2luY2UgYm90aCBhcmUgbm90IGFwcHJvcHJpYXRlLCB3ZQorICAgICogIHdpbGwgcHJvY2VzcyBuYW1lc3BhY2UgbG9va3VwIGhlcmUgdG8gYXZvaWQgYWRkaW5nIHlldCBhbm90aGVyCisgICAgKiAgbnMtbG9va3VwIGZ1bmN0aW9uIHRvIG5hbWVzcGFjZXMuYy4KKyAgICAqLworICAgIC8qCisgICAgKiBTUEVDIFhTTFQgMS4wOiBFcnJvciBjYXNlczoKKyAgICAqIC0gQ3JlYXRpbmcgbm9kZXMgb3RoZXIgdGhhbiB0ZXh0IG5vZGVzIGR1cmluZyB0aGUgaW5zdGFudGlhdGlvbiBvZgorICAgICogICB0aGUgY29udGVudCBvZiB0aGUgeHNsOmF0dHJpYnV0ZSBlbGVtZW50OyBpbXBsZW1lbnRhdGlvbnMgbWF5CisgICAgKiAgIGVpdGhlciBzaWduYWwgdGhlIGVycm9yIG9yIGlnbm9yZSB0aGUgb2ZmZW5kaW5nIG5vZGVzLiIKKyAgICAqLworCisgICAgaWYgKGNvbXAgPT0gTlVMTCkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkgICAgIkludGVybmFsIGVycm9yIGluIHhzbHRBdHRyaWJ1dGVJbnRlcm5hbCgpOiAiCisJICAgICJUaGUgWFNMVCAnYXR0cmlidXRlJyBpbnN0cnVjdGlvbiB3YXMgbm90IGNvbXBpbGVkLlxuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgLyoKKyAgICAqIFRPRE86IFNob3VsZG4ndCBjdHh0LT5pbnNlcnQgPT0gTlVMTCBiZSB0cmVhdGVkIGFzIGFuIGludGVybmFsIGVycm9yPworICAgICogICBTbyByZXBvcnQgYW4gaW50ZXJuYWwgZXJyb3I/CisgICAgKi8KKyAgICBpZiAoY3R4dC0+aW5zZXJ0ID09IE5VTEwpCisgICAgICAgIHJldHVybjsgICAgCisgICAgLyoKKyAgICAqIFNQRUMgWFNMVCAxLjA6CisgICAgKiAgIkFkZGluZyBhbiBhdHRyaWJ1dGUgdG8gYSBub2RlIHRoYXQgaXMgbm90IGFuIGVsZW1lbnQ7CisgICAgKiAgaW1wbGVtZW50YXRpb25zIG1heSBlaXRoZXIgc2lnbmFsIHRoZSBlcnJvciBvciBpZ25vcmUgdGhlIGF0dHJpYnV0ZS4iCisgICAgKgorICAgICogVE9ETzogSSB0aGluayB3ZSBzaG91bGQgc2lnbmFsIHN1Y2ggZXJyb3JzIGluIHRoZSBmdXR1cmUsIGFuZCBtYXliZQorICAgICogIHByb3ZpZGUgYW4gb3B0aW9uIHRvIGlnbm9yZSBzdWNoIGVycm9ycy4KKyAgICAqLworICAgIHRhcmdldEVsZW0gPSBjdHh0LT5pbnNlcnQ7CisgICAgaWYgKHRhcmdldEVsZW0tPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkKKwlyZXR1cm47CisgICAgCisgICAgLyoKKyAgICAqIFNQRUMgWFNMVCAxLjA6CisgICAgKiAiQWRkaW5nIGFuIGF0dHJpYnV0ZSB0byBhbiBlbGVtZW50IGFmdGVyIGNoaWxkcmVuIGhhdmUgYmVlbiBhZGRlZAorICAgICogIHRvIGl0OyBpbXBsZW1lbnRhdGlvbnMgbWF5IGVpdGhlciBzaWduYWwgdGhlIGVycm9yIG9yIGlnbm9yZSB0aGUKKyAgICAqICBhdHRyaWJ1dGUuIgorICAgICoKKyAgICAqIFRPRE86IFdlIHNob3VsZCBkZWNpZGUgd2hldGhlciBub3QgdG8gcmVwb3J0IHN1Y2ggZXJyb3JzIG9yCisgICAgKiAgdG8gaWdub3JlIHRoZW07IG5vdGUgdGhhdCB3ZSAqaWdub3JlKiBpZiB0aGUgcGFyZW50IGlzIG5vdCBhbgorICAgICogIGVsZW1lbnQsIGJ1dCBoZXJlIHdlIHJlcG9ydCBhbiBlcnJvci4KKyAgICAqLworICAgIGlmICh0YXJnZXRFbGVtLT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJLyoKKwkqIE5PVEU6IEFoISBUaGlzIHNlZW1zIHRvIGJlIGludGVuZGVkIHRvIHN1cHBvcnQgc3RyZWFtZWQKKwkqICByZXN1bHQgZ2VuZXJhdGlvbiEuCisJKi8KKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJICAgICJ4c2w6YXR0cmlidXRlOiBDYW5ub3QgYWRkIGF0dHJpYnV0ZXMgdG8gYW4gIgorCSAgICAiZWxlbWVudCBpZiBjaGlsZHJlbiBoYXZlIGJlZW4gYWxyZWFkeSBhZGRlZCAiCisJICAgICJ0byB0aGUgZWxlbWVudC5cbiIpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLyoKKyAgICAqIFByb2Nlc3MgdGhlIG5hbWUKKyAgICAqIC0tLS0tLS0tLS0tLS0tLS0KKyAgICAqLyAgICAKKworI2lmZGVmIFdJVEhfREVCVUdHRVIKKyAgICBpZiAoY3R4dC0+ZGVidWdTdGF0dXMgIT0gWFNMVF9ERUJVR19OT05FKQorICAgICAgICB4c2xIYW5kbGVEZWJ1Z2dlcihpbnN0LCBjb250ZXh0Tm9kZSwgTlVMTCwgY3R4dCk7CisjZW5kaWYKKworICAgIGlmIChjb21wLT5uYW1lID09IE5VTEwpIHsKKwkvKiBUT0RPOiBmaXggYXR0ciBhY3F1aXNpdGlvbiB3cnQgdG8gdGhlIFhTTFQgbmFtZXNwYWNlICovCisgICAgICAgIHByb3AgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIGluc3QsCisJICAgIChjb25zdCB4bWxDaGFyICopICJuYW1lIiwgWFNMVF9OQU1FU1BBQ0UpOworICAgICAgICBpZiAocHJvcCA9PSBOVUxMKSB7CisgICAgICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkJInhzbDphdHRyaWJ1dGU6IFRoZSBhdHRyaWJ1dGUgJ25hbWUnIGlzIG1pc3NpbmcuXG4iKTsKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgIH0KKwlpZiAoeG1sVmFsaWRhdGVRTmFtZShwcm9wLCAwKSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkJInhzbDphdHRyaWJ1dGU6IFRoZSBlZmZlY3RpdmUgbmFtZSAnJXMnIGlzIG5vdCBhICIKKwkJInZhbGlkIFFOYW1lLlxuIiwgcHJvcCk7CisJICAgIC8qIHdlIGZhbGwgdGhyb3VnaCB0byBjYXRjaCBhbnkgZnVydGhlciBlcnJvcnMsIGlmIHBvc3NpYmxlICovCisJfQorCW5hbWUgPSB4c2x0U3BsaXRRTmFtZShjdHh0LT5kaWN0LCBwcm9wLCAmcHJlZml4KTsKKwl4bWxGcmVlKHByb3ApOworCisJLyoKKwkqIFJlamVjdCBhIHByZWZpeCBvZiAieG1sbnMiLgorCSovCisJaWYgKChwcmVmaXggIT0gTlVMTCkgJiYKKwkgICAgKCF4bWxTdHJuY2FzZWNtcChwcmVmaXgsICh4bWxDaGFyICopICJ4bWxucyIsIDUpKSkKKwl7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKwkgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJInhzbHRBdHRyaWJ1dGU6IHhtbG5zIHByZWZpeCBmb3JiaWRkZW5cbiIpOworI2VuZGlmCisJICAgIC8qCisJICAgICogU1BFQyBYU0xUIDEuMDoKKwkgICAgKiAgIkl0IGlzIGFuIGVycm9yIGlmIHRoZSBzdHJpbmcgdGhhdCByZXN1bHRzIGZyb20gaW5zdGFudGlhdGluZworCSAgICAqICB0aGUgYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIGlzIG5vdCBhIFFOYW1lIG9yIGlzIHRoZSBzdHJpbmcKKwkgICAgKiAgeG1sbnMuIEFuIFhTTFQgcHJvY2Vzc29yIG1heSBzaWduYWwgdGhlIGVycm9yOyBpZiBpdCBkb2VzIG5vdAorCSAgICAqICBzaWduYWwgdGhlIGVycm9yLCBpdCBtdXN0IHJlY292ZXIgYnkgbm90IGFkZGluZyB0aGUgYXR0cmlidXRlCisJICAgICogIHRvIHRoZSByZXN1bHQgdHJlZS4iCisJICAgICogVE9ETzogRGVjaWRlIHdoaWNoIHdheSB0byBnbyBoZXJlLgorCSAgICAqLworCSAgICBnb3RvIGVycm9yOworCX0KKworICAgIH0gZWxzZSB7CisJLyoKKwkqIFRoZSAibmFtZSIgdmFsdWUgd2FzIHN0YXRpYy4KKwkqLworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCXByZWZpeCA9IGNvbXAtPm5zUHJlZml4OworCW5hbWUgPSBjb21wLT5uYW1lOworI2Vsc2UKKwluYW1lID0geHNsdFNwbGl0UU5hbWUoY3R4dC0+ZGljdCwgY29tcC0+bmFtZSwgJnByZWZpeCk7CisjZW5kaWYKKyAgICB9CisgICAgCisgICAgLyoKKyAgICAqIFByb2Nlc3MgbmFtZXNwYWNlIHNlbWFudGljcworICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgKgorICAgICogRXZhbHVhdGUgdGhlIG5hbWVzcGFjZSBuYW1lLgorICAgICovCisgICAgaWYgKGNvbXAtPmhhc19ucykgeworCS8qCisJKiBUaGUgIm5hbWVzcGFjZSIgYXR0cmlidXRlIHdhcyBleGlzdGVudC4KKwkqLworCWlmIChjb21wLT5ucyAhPSBOVUxMKSB7CisJICAgIC8qCisJICAgICogTm8gQVZUOyBqdXN0IHBsYWluIHRleHQgZm9yIHRoZSBuYW1lc3BhY2UgbmFtZS4KKwkgICAgKi8KKwkgICAgaWYgKGNvbXAtPm5zWzBdICE9IDApCisJCW5zTmFtZSA9IGNvbXAtPm5zOworCX0gZWxzZSB7CisJICAgIHhtbENoYXIgKnRtcE5zTmFtZTsKKwkgICAgLyoKKwkgICAgKiBFdmFsIHRoZSBBVlQuCisJICAgICovCisJICAgIC8qIFRPRE86IGNoZWNrIGF0dHIgYWNxdWlzaXRpb24gd3J0IHRvIHRoZSBYU0xUIG5hbWVzcGFjZSAqLworCSAgICB0bXBOc05hbWUgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIGluc3QsCisJCShjb25zdCB4bWxDaGFyICopICJuYW1lc3BhY2UiLCBYU0xUX05BTUVTUEFDRSk7CQorCSAgICAvKgorCSAgICAqIFRoaXMgZml4ZXMgYnVnICMzMDIwMjA6IFRoZSBBVlQgbWlnaHQgYWxzbyBldmFsdWF0ZSB0byB0aGUgCisJICAgICogZW1wdHkgc3RyaW5nOyB0aGlzIG1lYW5zIHRoYXQgdGhlIGVtcHR5IHN0cmluZyBhbHNvIGluZGljYXRlcworCSAgICAqICJubyBuYW1lc3BhY2UiLgorCSAgICAqIFNQRUMgWFNMVCAxLjA6CisJICAgICogICJJZiB0aGUgc3RyaW5nIGlzIGVtcHR5LCB0aGVuIHRoZSBleHBhbmRlZC1uYW1lIG9mIHRoZQorCSAgICAqICBhdHRyaWJ1dGUgaGFzIGEgbnVsbCBuYW1lc3BhY2UgVVJJLiIKKwkgICAgKi8KKwkgICAgaWYgKCh0bXBOc05hbWUgIT0gTlVMTCkgJiYgKHRtcE5zTmFtZVswXSAhPSAwKSkKKwkJbnNOYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBCQURfQ0FTVCB0bXBOc05hbWUsIC0xKTsKKwkgICAgeG1sRnJlZSh0bXBOc05hbWUpOwkJCisJfTsJICAgIAorICAgIH0gZWxzZSBpZiAocHJlZml4ICE9IE5VTEwpIHsKKwkvKgorCSogU1BFQyBYU0xUIDEuMDoKKwkqICAiSWYgdGhlIG5hbWVzcGFjZSBhdHRyaWJ1dGUgaXMgbm90IHByZXNlbnQsIHRoZW4gdGhlIFFOYW1lIGlzCisJKiAgZXhwYW5kZWQgaW50byBhbiBleHBhbmRlZC1uYW1lIHVzaW5nIHRoZSBuYW1lc3BhY2UgZGVjbGFyYXRpb25zCisJKiAgaW4gZWZmZWN0IGZvciB0aGUgeHNsOmF0dHJpYnV0ZSBlbGVtZW50LCAqbm90KiBpbmNsdWRpbmcgYW55CisJKiAgZGVmYXVsdCBuYW1lc3BhY2UgZGVjbGFyYXRpb24uIgorCSovCQorCW5zID0geG1sU2VhcmNoTnMoaW5zdC0+ZG9jLCBpbnN0LCBwcmVmaXgpOworCWlmIChucyA9PSBOVUxMKSB7CisJICAgIC8qCisJICAgICogTm90ZSB0aGF0IHRoaXMgaXMgdHJlYXRlZCBhcyBhbiBlcnJvciBub3cgKGNoZWNrZWQgd2l0aAorCSAgICAqICBTYXhvbiwgWGFsYW4tSiBhbmQgTVNYTUwpLgorCSAgICAqLworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkJInhzbDphdHRyaWJ1dGU6IFRoZSBRTmFtZSAnJXM6JXMnIGhhcyBubyAiCisJCSJuYW1lc3BhY2UgYmluZGluZyBpbiBzY29wZSBpbiB0aGUgc3R5bGVzaGVldDsgIgorCQkidGhpcyBpcyBhbiBlcnJvciwgc2luY2UgdGhlIG5hbWVzcGFjZSB3YXMgbm90ICIKKwkJInNwZWNpZmllZCBieSB0aGUgaW5zdHJ1Y3Rpb24gaXRzZWxmLlxuIiwgcHJlZml4LCBuYW1lKTsKKwl9IGVsc2UKKwkgICAgbnNOYW1lID0gbnMtPmhyZWY7CQorICAgIH0KKworICAgIGlmIChmcm9tQXR0cmlidXRlU2V0KSB7CisJLyoKKwkqIFRoaXMgdHJpZXMgdG8gZW5zdXJlIHRoYXQgeHNsOmF0dHJpYnV0ZShzKSBjb21pbmcKKwkqIGZyb20gYW4geHNsOmF0dHJpYnV0ZS1zZXQgd29uJ3Qgb3ZlcnJpZGUgYXR0cmlidXRlIG9mCisJKiBsaXRlcmFsIHJlc3VsdCBlbGVtZW50cyBvciBvZiBleHBsaWNpdCB4c2w6YXR0cmlidXRlKHMpLgorCSogVVJHRU5UIFRPRE86IFRoaXMgbWlnaHQgYmUgYnVnZ3ksIHNpbmNlIGl0IHdpbGwgbWlzcyB0bworCSogIG92ZXJ3cml0ZSB0d28gZXF1YWwgYXR0cmlidXRlcyBib3RoIGZyb20gYXR0cmlidXRlIHNldHMuCisJKi8KKwlhdHRyID0geG1sSGFzTnNQcm9wKHRhcmdldEVsZW0sIG5hbWUsIG5zTmFtZSk7CisJaWYgKGF0dHIgIT0gTlVMTCkKKwkgICAgcmV0dXJuOworICAgIH0KKworICAgIC8qCisgICAgKiBGaW5kL2NyZWF0ZSBhIG1hdGNoaW5nIG5zLWRlY2wgaW4gdGhlIHJlc3VsdCB0cmVlLgorICAgICovCisgICAgbnMgPSBOVUxMOworICAgIAorI2lmIDAKKyAgICBpZiAoMCkgewkKKwkvKgorCSogT1BUSU1JWkUgVE9ETzogSG93IGRvIHdlIGtub3cgaWYgd2UgYXJlIGFkZGluZyB0byBhCisJKiAgZnJhZ21lbnQgb3IgdG8gdGhlIHJlc3VsdCB0cmVlPworCSoKKwkqIElmIHdlIGFyZSBhZGRpbmcgdG8gYSByZXN1bHQgdHJlZSBmcmFnbWVudCAoaS5lLiwgbm90IHRvIHRoZQorCSogYWN0dWFsIHJlc3VsdCB0cmVlKSwgd2UnbGwgZG9uJ3QgYm90aGVyIHNlYXJjaGluZyBmb3IgdGhlCisJKiBucy1kZWNsLCBidXQganVzdCBzdG9yZSBpdCBpbiB0aGUgZHVtbXktZG9jIG9mIHRoZSByZXN1bHQKKwkqIHRyZWUgZnJhZ21lbnQuCisJKi8KKwlpZiAobnNOYW1lICE9IE5VTEwpIHsKKwkgICAgLyoKKwkgICAgKiBUT0RPOiBHZXQgdGhlIGRvYyBvZiBAdGFyZ2V0RWxlbS4KKwkgICAgKi8KKwkgICAgbnMgPSB4c2x0VHJlZUFjcXVpcmVTdG9yZWROcyhzb21lIGRvYywgbnNOYW1lLCBwcmVmaXgpOworCX0KKyAgICB9CisjZW5kaWYKKworICAgIGlmIChuc05hbWUgIT0gTlVMTCkgewkKKwkvKgorCSogU29tZXRoaW5nIGFib3V0IG5zLXByZWZpeGVzOgorCSogU1BFQyBYU0xUIDEuMDoKKwkqICAiWFNMVCBwcm9jZXNzb3JzIG1heSBtYWtlIHVzZSBvZiB0aGUgcHJlZml4IG9mIHRoZSBRTmFtZSBzcGVjaWZpZWQKKwkqICBpbiB0aGUgbmFtZSBhdHRyaWJ1dGUgd2hlbiBzZWxlY3RpbmcgdGhlIHByZWZpeCB1c2VkIGZvciBvdXRwdXR0aW5nCisJKiAgdGhlIGNyZWF0ZWQgYXR0cmlidXRlIGFzIFhNTDsgaG93ZXZlciwgdGhleSBhcmUgbm90IHJlcXVpcmVkIHRvIGRvCisJKiAgc28gYW5kLCBpZiB0aGUgcHJlZml4IGlzIHhtbG5zLCB0aGV5IG11c3Qgbm90IGRvIHNvIgorCSovCisJLyoKKwkqIHhzbDphdHRyaWJ1dGUgY2FuIHByb2R1Y2UgYSBzY2VuYXJpbyB3aGVyZSB0aGUgcHJlZml4IGlzIE5VTEwsCisJKiBzbyBnZW5lcmF0ZSBhIHByZWZpeC4KKwkqLworCWlmIChwcmVmaXggPT0gTlVMTCkgeworCSAgICB4bWxDaGFyICpwcmVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJuc18xIik7CisKKwkgICAgbnMgPSB4c2x0R2V0U3BlY2lhbE5hbWVzcGFjZShjdHh0LCBpbnN0LCBuc05hbWUsIEJBRF9DQVNUIHByZWYsCisJCXRhcmdldEVsZW0pOworCisJICAgIHhtbEZyZWUocHJlZik7CisJfSBlbHNlIHsKKwkgICAgbnMgPSB4c2x0R2V0U3BlY2lhbE5hbWVzcGFjZShjdHh0LCBpbnN0LCBuc05hbWUsIHByZWZpeCwKKwkJdGFyZ2V0RWxlbSk7CisJfQorCWlmIChucyA9PSBOVUxMKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkiTmFtZXNwYWNlIGZpeHVwIGVycm9yOiBGYWlsZWQgdG8gYWNxdWlyZSBhbiBpbi1zY29wZSAiCisJCSJuYW1lc3BhY2UgYmluZGluZyBmb3IgdGhlIGdlbmVyYXRlZCBhdHRyaWJ1dGUgJ3slc30lcycuXG4iLAorCQluc05hbWUsIG5hbWUpOworCSAgICBnb3RvIGVycm9yOworCX0KKyAgICB9CisgICAgLyoKKyAgICAqIENvbnN0cnVjdGlvbiBvZiB0aGUgdmFsdWUKKyAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAqLworICAgIGlmIChpbnN0LT5jaGlsZHJlbiA9PSBOVUxMKSB7CisJLyoKKwkqIE5vIGNvbnRlbnQuCisJKiBUT0RPOiBEbyB3ZSBuZWVkIHRvIHB1dCB0aGUgZW1wdHkgc3RyaW5nIGluID8KKwkqLworCWF0dHIgPSB4bWxTZXROc1Byb3AoY3R4dC0+aW5zZXJ0LCBucywgbmFtZSwgKGNvbnN0IHhtbENoYXIgKikgIiIpOworICAgIH0gZWxzZSBpZiAoKGluc3QtPmNoaWxkcmVuLT5uZXh0ID09IE5VTEwpICYmIAorCSAgICAoKGluc3QtPmNoaWxkcmVuLT50eXBlID09IFhNTF9URVhUX05PREUpIHx8CisJICAgICAoaW5zdC0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpKQorICAgIHsKKwl4bWxOb2RlUHRyIGNvcHlUeHQ7CisJCisJLyoKKwkqIHhtbFNldE5zUHJvcCgpIHdpbGwgdGFrZSBjYXJlIG9mIGR1cGxpY2F0ZXMuCisJKi8KKwlhdHRyID0geG1sU2V0TnNQcm9wKGN0eHQtPmluc2VydCwgbnMsIG5hbWUsIE5VTEwpOworCWlmIChhdHRyID09IE5VTEwpIC8qIFRPRE86IHJlcG9ydCBlcnJvciA/ICovCisJICAgIGdvdG8gZXJyb3I7CisJLyoKKwkqIFRoaXMgd2FzIHRha2VuIG92ZXIgZnJvbSB4c2x0Q29weVRleHQoKSAodHJhbnNmb3JtLmMpLgorCSovCisJaWYgKGN0eHQtPmludGVybmFsaXplZCAmJgorCSAgICAoY3R4dC0+aW5zZXJ0LT5kb2MgIT0gTlVMTCkgJiYKKwkgICAgKGN0eHQtPmluc2VydC0+ZG9jLT5kaWN0ID09IGN0eHQtPmRpY3QpKQorCXsKKwkgICAgY29weVR4dCA9IHhtbE5ld1RleHQoTlVMTCk7CisJICAgIGlmIChjb3B5VHh0ID09IE5VTEwpIC8qIFRPRE86IHJlcG9ydCBlcnJvciAqLworCQlnb3RvIGVycm9yOworCSAgICAvKgorCSAgICAqIFRoaXMgaXMgYSBzYWZlIHNjZW5hcmlvIHdoZXJlIHdlIGRvbid0IG5lZWQgdG8gbG9va3VwCisJICAgICogdGhlIGRpY3QuCisJICAgICovCisJICAgIGNvcHlUeHQtPmNvbnRlbnQgPSBpbnN0LT5jaGlsZHJlbi0+Y29udGVudDsKKwkgICAgLyoKKwkgICAgKiBDb3B5ICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIgaW5mb3JtYXRpb24uCisJICAgICogVE9ETzogRG9lcyB0aGlzIGhhdmUgYW55IGVmZmVjdCBmb3IgYXR0cmlidXRlIHZhbHVlcworCSAgICAqICBhbnl3YXk/CisJICAgICovCisJICAgIGlmIChpbnN0LT5jaGlsZHJlbi0+bmFtZSA9PSB4bWxTdHJpbmdUZXh0Tm9lbmMpCisJCWNvcHlUeHQtPm5hbWUgPSB4bWxTdHJpbmdUZXh0Tm9lbmM7CisJfSBlbHNlIHsKKwkgICAgLyoKKwkgICAgKiBDb3B5IHRoZSB2YWx1ZS4KKwkgICAgKi8KKwkgICAgY29weVR4dCA9IHhtbE5ld1RleHQoaW5zdC0+Y2hpbGRyZW4tPmNvbnRlbnQpOworCSAgICBpZiAoY29weVR4dCA9PSBOVUxMKSAvKiBUT0RPOiByZXBvcnQgZXJyb3IgKi8KKwkJZ290byBlcnJvcjsJICAgIAkgICAgCisJfQorCWF0dHItPmNoaWxkcmVuID0gYXR0ci0+bGFzdCA9IGNvcHlUeHQ7CisJY29weVR4dC0+cGFyZW50ID0gKHhtbE5vZGVQdHIpIGF0dHI7CisJY29weVR4dC0+ZG9jID0gYXR0ci0+ZG9jOworCS8qCisJKiBDb3B5ICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIgaW5mb3JtYXRpb24uCisJKiBUT0RPOiBEb2VzIHRoaXMgaGF2ZSBhbnkgZWZmZWN0IGZvciBhdHRyaWJ1dGUgdmFsdWVzCisJKiAgYW55d2F5PworCSovCisJaWYgKGluc3QtPmNoaWxkcmVuLT5uYW1lID09IHhtbFN0cmluZ1RleHROb2VuYykKKwkgICAgY29weVR4dC0+bmFtZSA9IHhtbFN0cmluZ1RleHROb2VuYzsJCisKKyAgICAgICAgLyoKKyAgICAgICAgICogc2luY2Ugd2UgY3JlYXRlIHRoZSBhdHRyaWJ1dGUgd2l0aG91dCBjb250ZW50IElEbmVzcyBtdXN0IGJlCisgICAgICAgICAqIGFzc2VydGVkIGFzIGEgc2Vjb25kIHN0ZXAKKyAgICAgICAgICovCisgICAgICAgIGlmICgoY29weVR4dC0+Y29udGVudCAhPSBOVUxMKSAmJgorICAgICAgICAgICAgKHhtbElzSUQoYXR0ci0+ZG9jLCBhdHRyLT5wYXJlbnQsIGF0dHIpKSkKKyAgICAgICAgICAgIHhtbEFkZElEKE5VTEwsIGF0dHItPmRvYywgY29weVR4dC0+Y29udGVudCwgYXR0cik7CisgICAgfSBlbHNlIHsKKwkvKgorCSogVGhlIHNlcXVlbmNlIGNvbnN0cnVjdG9yIG1pZ2h0IGJlIGNvbXBsZXgsIHNvIGluc3RhbnRpYXRlIGl0LgorCSovCisJdmFsdWUgPSB4c2x0RXZhbFRlbXBsYXRlU3RyaW5nKGN0eHQsIGNvbnRleHROb2RlLCBpbnN0KTsKKwlpZiAodmFsdWUgIT0gTlVMTCkgeworCSAgICBhdHRyID0geG1sU2V0TnNQcm9wKGN0eHQtPmluc2VydCwgbnMsIG5hbWUsIHZhbHVlKTsKKwkgICAgeG1sRnJlZSh2YWx1ZSk7CisJfSBlbHNlIHsKKwkgICAgLyoKKwkgICAgKiBUT0RPOiBEbyB3ZSBoYXZlIHRvIGFkZCB0aGUgZW1wdHkgc3RyaW5nIHRvIHRoZSBhdHRyPworCSAgICAqIFRPRE86IERvZXMgYSAgdmFsdWUgb2YgTlVMTCBpbmRpY2F0ZSBhbgorCSAgICAqICBlcnJvciBpbiB4c2x0RXZhbFRlbXBsYXRlU3RyaW5nKCkgPworCSAgICAqLworCSAgICBhdHRyID0geG1sU2V0TnNQcm9wKGN0eHQtPmluc2VydCwgbnMsIG5hbWUsCisJCShjb25zdCB4bWxDaGFyICopICIiKTsKKwl9CisgICAgfQorCitlcnJvcjoKKyAgICByZXR1cm47ICAgIAorfQorCisvKioKKyAqIHhzbHRBdHRyaWJ1dGU6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBub2RlOiAgdGhlIG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlLgorICogQGluc3Q6ICB0aGUgeHNsdCBhdHRyaWJ1dGUgbm9kZQorICogQGNvbXA6ICBwcmVjb21wdXRlZCBpbmZvcm1hdGlvbgorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgYXR0cmlidXRlIG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3ZvaWQKK3hzbHRBdHRyaWJ1dGUoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAorCSAgICAgIHhtbE5vZGVQdHIgaW5zdCwgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wKSB7CisgICAgeHNsdEF0dHJpYnV0ZUludGVybmFsKGN0eHQsIG5vZGUsIGluc3QsIGNvbXAsIDApOworfQorCisvKioKKyAqIHhzbHRBcHBseUF0dHJpYnV0ZVNldDoKKyAqIEBjdHh0OiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICogQG5vZGU6ICB0aGUgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUuCisgKiBAaW5zdDogIHRoZSBhdHRyaWJ1dGUgbm9kZSAieHNsOnVzZS1hdHRyaWJ1dGUtc2V0cyIKKyAqIEBhdHRyU2V0czogIHRoZSBsaXN0IG9mIFFOYW1lcyBvZiB0aGUgYXR0cmlidXRlLXNldHMgdG8gYmUgYXBwbGllZAorICoKKyAqIEFwcGx5IHRoZSB4c2w6dXNlLWF0dHJpYnV0ZS1zZXRzLgorICogSWYgQGF0dHJTZXRzIGlzIE5VTEwsIHRoZW4gQGluc3Qgd2lsbCBiZSB1c2VkIHRvIGV4Y3RyYWN0IHRoaXMKKyAqIHZhbHVlLgorICogSWYgYm90aCwgQGF0dHJTZXRzIGFuZCBAaW5zdCwgYXJlIE5VTEwsIHRoZW4gdGhpcyB3aWxsIGRvIG5vdGhpbmcuCisgKi8KK3ZvaWQKK3hzbHRBcHBseUF0dHJpYnV0ZVNldCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBpbnN0LAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKmF0dHJTZXRzKQoreworICAgIGNvbnN0IHhtbENoYXIgKm5jbmFtZSA9IE5VTEw7CisgICAgY29uc3QgeG1sQ2hhciAqcHJlZml4ID0gTlVMTDsgICAgCisgICAgY29uc3QgeG1sQ2hhciAqY3Vyc3RyLCAqZW5kc3RyOworICAgIHhzbHRBdHRyRWxlbVB0ciBhdHRyczsKKyAgICB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZTsgICAgCisKKyAgICBpZiAoYXR0clNldHMgPT0gTlVMTCkgeworCWlmIChpbnN0ID09IE5VTEwpCisJICAgIHJldHVybjsKKwllbHNlIHsKKwkgICAgLyoKKwkgICAgKiBFeHRyYWN0IHRoZSB2YWx1ZSBmcm9tIEBpbnN0LgorCSAgICAqLworCSAgICBpZiAoaW5zdC0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsKKwkJaWYgKCAoKHhtbEF0dHJQdHIpIGluc3QpLT5jaGlsZHJlbiAhPSBOVUxMKQorCQkgICAgYXR0clNldHMgPSAoKHhtbEF0dHJQdHIpIGluc3QpLT5jaGlsZHJlbi0+Y29udGVudDsKKwkJCisJICAgIH0KKwkgICAgaWYgKGF0dHJTZXRzID09IE5VTEwpIHsKKwkJLyoKKwkJKiBUT0RPOiBSZXR1cm4gYW4gZXJyb3I/CisJCSovCisJCXJldHVybjsKKwkgICAgfQorCX0KKyAgICB9CisgICAgLyoKKyAgICAqIFBhcnNlL2FwcGx5IHRoZSBsaXN0IG9mIFFOYW1lcy4KKyAgICAqLworICAgIGN1cnN0ciA9IGF0dHJTZXRzOworICAgIHdoaWxlICgqY3Vyc3RyICE9IDApIHsKKyAgICAgICAgd2hpbGUgKElTX0JMQU5LKCpjdXJzdHIpKQorICAgICAgICAgICAgY3Vyc3RyKys7CisgICAgICAgIGlmICgqY3Vyc3RyID09IDApCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZW5kc3RyID0gY3Vyc3RyOworICAgICAgICB3aGlsZSAoKCplbmRzdHIgIT0gMCkgJiYgKCFJU19CTEFOSygqZW5kc3RyKSkpCisgICAgICAgICAgICBlbmRzdHIrKzsKKyAgICAgICAgY3Vyc3RyID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBjdXJzdHIsIGVuZHN0ciAtIGN1cnN0cik7CisgICAgICAgIGlmIChjdXJzdHIpIHsKKwkgICAgLyoKKwkgICAgKiBUT0RPOiBWYWxpZGF0ZSB0aGUgUU5hbWUuCisJICAgICovCisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfY3Vyc3RyVVRFUworICAgICAgICAgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFwcGx5IGN1cnN0cnV0ZSBzZXQgJXNcbiIsIGN1cnN0cik7CisjZW5kaWYKKyAgICAgICAgICAgIG5jbmFtZSA9IHhzbHRTcGxpdFFOYW1lKGN0eHQtPmRpY3QsIGN1cnN0ciwgJnByZWZpeCk7CisKKyAgICAgICAgICAgIHN0eWxlID0gY3R4dC0+c3R5bGU7CisKKyNpZmRlZiBXSVRIX0RFQlVHR0VSCisgICAgICAgICAgICBpZiAoKHN0eWxlICE9IE5VTEwpICYmCisJCShzdHlsZS0+YXR0cmlidXRlU2V0cyAhPSBOVUxMKSAmJgorCQkoY3R4dC0+ZGVidWdTdGF0dXMgIT0gWFNMVF9ERUJVR19OT05FKSkKKwkgICAgeworICAgICAgICAgICAgICAgIGF0dHJzID0KKyAgICAgICAgICAgICAgICAgICAgeG1sSGFzaExvb2t1cDIoc3R5bGUtPmF0dHJpYnV0ZVNldHMsIG5jbmFtZSwgcHJlZml4KTsKKyAgICAgICAgICAgICAgICBpZiAoKGF0dHJzICE9IE5VTEwpICYmIChhdHRycy0+YXR0ciAhPSBOVUxMKSkKKyAgICAgICAgICAgICAgICAgICAgeHNsSGFuZGxlRGVidWdnZXIoYXR0cnMtPmF0dHItPnBhcmVudCwgbm9kZSwgTlVMTCwKKwkJCWN0eHQpOworICAgICAgICAgICAgfQorI2VuZGlmCisJICAgIC8qCisJICAgICogTG9va3VwIHRoZSByZWZlcmVuY2VkIGN1cnN0cnV0ZS1zZXQuCisJICAgICovCisgICAgICAgICAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGF0dHJzID0KKyAgICAgICAgICAgICAgICAgICAgeG1sSGFzaExvb2t1cDIoc3R5bGUtPmF0dHJpYnV0ZVNldHMsIG5jbmFtZSwgcHJlZml4KTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoYXR0cnMgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cnMtPmF0dHIgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICAgICAgeHNsdEF0dHJpYnV0ZUludGVybmFsKGN0eHQsIG5vZGUsIGF0dHJzLT5hdHRyLAorCQkJICAgIGF0dHJzLT5hdHRyLT5wc3ZpLCAxKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBhdHRycyA9IGF0dHJzLT5uZXh0OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdHlsZSA9IHhzbHROZXh0SW1wb3J0KHN0eWxlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBjdXJzdHIgPSBlbmRzdHI7CisgICAgfQorfQorCisvKioKKyAqIHhzbHRGcmVlQXR0cmlidXRlU2V0c0hhc2hlczoKKyAqIEBzdHlsZTogYW4gWFNMVCBzdHlsZXNoZWV0CisgKgorICogRnJlZSB1cCB0aGUgbWVtb3J5IHVzZWQgYnkgYXR0cmlidXRlIHNldHMKKyAqLwordm9pZAoreHNsdEZyZWVBdHRyaWJ1dGVTZXRzSGFzaGVzKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKSB7CisgICAgaWYgKHN0eWxlLT5hdHRyaWJ1dGVTZXRzICE9IE5VTEwpCisJeG1sSGFzaEZyZWUoKHhtbEhhc2hUYWJsZVB0cikgc3R5bGUtPmF0dHJpYnV0ZVNldHMsCisJCSAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4c2x0RnJlZUF0dHJFbGVtTGlzdCk7CisgICAgc3R5bGUtPmF0dHJpYnV0ZVNldHMgPSBOVUxMOworfQpkaWZmIC0tZ2l0IGEvbGlieHNsdC9hdHRyaWJ1dGVzLmggYi9saWJ4c2x0L2F0dHJpYnV0ZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjFlYmIwCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9hdHRyaWJ1dGVzLmgKQEAgLTAsMCArMSwzOCBAQAorLyoKKyAqIFN1bW1hcnk6IGludGVyZmFjZSBmb3IgdGhlIFhTTFQgYXR0cmlidXRlIGhhbmRsaW5nCisgKiBEZXNjcmlwdGlvbjogdGhpcyBtb2R1bGUgaGFuZGxlcyB0aGUgc3BlY2lmaWNpdGllcyBvZiBhdHRyaWJ1dGUKKyAqICAgICAgICAgICAgICBhbmQgYXR0cmlidXRlIGdyb3VwcyBwcm9jZXNzaW5nLgorICoKKyAqIENvcHk6IFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBBdXRob3I6IERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVF9BVFRSSUJVVEVTX0hfXworI2RlZmluZSBfX1hNTF9YU0xUX0FUVFJJQlVURVNfSF9fCisKKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgInhzbHRleHBvcnRzLmgiCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJeHNsdFBhcnNlU3R5bGVzaGVldEF0dHJpYnV0ZVNldAkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSB4bWxOb2RlUHRyIGN1cik7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwgICAgCisJeHNsdEZyZWVBdHRyaWJ1dGVTZXRzSGFzaGVzCSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCisJeHNsdEFwcGx5QXR0cmlidXRlU2V0CQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIHhtbE5vZGVQdHIgaW5zdCwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKmF0dHJpYnV0ZXMpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQorCXhzbHRSZXNvbHZlU3R5bGVzaGVldEF0dHJpYnV0ZVNldCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSk7CisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19YTUxfWFNMVF9BVFRSSUJVVEVTX0hfXyAqLworCmRpZmYgLS1naXQgYS9saWJ4c2x0L2F0dHJ2dC5jIGIvbGlieHNsdC9hdHRydnQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZGEwOTEwCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9hdHRydnQuYwpAQCAtMCwwICsxLDM4NyBAQAorLyoKKyAqIGF0dHJ2dC5jOiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgWFNMIFRyYW5zZm9ybWF0aW9uIDEuMCBlbmdpbmUKKyAqICAgICAgICAgICBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUgaGFuZGxpbmcgcGFydC4KKyAqCisgKiBSZWZlcmVuY2VzOgorICogICBodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14c2x0LTE5OTkxMTE2CisgKgorICogICBNaWNoYWVsIEtheSAiWFNMVCBQcm9ncmFtbWVyJ3MgUmVmZXJlbmNlIiBwcCA2MzctNjQzCisgKiAgIFdyaXRpbmcgTXVsdGlwbGUgT3V0cHV0IEZpbGVzCisgKgorICogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIGRhbmllbEB2ZWlsbGFyZC5jb20KKyAqLworCisjZGVmaW5lIElOX0xJQlhTTFQKKyNpbmNsdWRlICJsaWJ4c2x0LmgiCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2luY2x1ZGUgPGxpYnhtbC94bWxtZW1vcnkuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aC5oPgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aEludGVybmFscy5oPgorI2luY2x1ZGUgInhzbHQuaCIKKyNpbmNsdWRlICJ4c2x0dXRpbHMuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisjaW5jbHVkZSAidGVtcGxhdGVzLmgiCisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKyNkZWZpbmUgV0lUSF9YU0xUX0RFQlVHX0FWVAorI2VuZGlmCisKKyNkZWZpbmUgTUFYX0FWVF9TRUcgMTAKKwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRBdHRyVlQgeHNsdEF0dHJWVDsKK3R5cGVkZWYgeHNsdEF0dHJWVCAqeHNsdEF0dHJWVFB0cjsKK3N0cnVjdCBfeHNsdEF0dHJWVCB7CisgICAgc3RydWN0IF94c2x0QXR0clZUICpuZXh0OyAvKiBuZXh0IHhzbHRBdHRyVlQgKi8KKyAgICBpbnQgbmJfc2VnOwkJLyogTnVtYmVyIG9mIHNlZ21lbnRzICovCisgICAgaW50IG1heF9zZWc7CS8qIG1heCBjYXBhY2l0eSBiZWZvcmUgcmUtYWxsb2MgbmVlZGVkICovCisgICAgaW50IHN0cnN0YXJ0OwkvKiBpcyB0aGUgc3RhcnQgYSBzdHJpbmcgKi8KKyAgICAvKgorICAgICAqIHRoZSBuYW1lc3BhY2VzIGluIHNjb3BlCisgICAgICovCisgICAgeG1sTnNQdHIgKm5zTGlzdDsKKyAgICBpbnQgbnNOcjsKKyAgICAvKgorICAgICAqIHRoZSBjb250ZW50IGlzIGFuIGFsdGVybmF0ZSBvZiBzdHJpbmcgYW5kIHhtbFhQYXRoQ29tcEV4cHJQdHIKKyAgICAgKi8KKyAgICB2b2lkICpzZWdtZW50c1tNQVhfQVZUX1NFR107Cit9OworCisvKioKKyAqIHhzbHROZXdBdHRyVlQ6CisgKiBAc3R5bGU6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKgorICogQnVpbGQgYSBuZXcgeHNsdEF0dHJWVCBzdHJ1Y3R1cmUKKyAqCisgKiBSZXR1cm5zIHRoZSBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3N0YXRpYyB4c2x0QXR0clZUUHRyCit4c2x0TmV3QXR0clZUKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKSB7CisgICAgeHNsdEF0dHJWVFB0ciBjdXI7CisKKyAgICBjdXIgPSAoeHNsdEF0dHJWVFB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0QXR0clZUKSk7CisgICAgaWYgKGN1ciA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBOVUxMLAorCQkieHNsdE5ld0F0dHJWVFB0ciA6IG1hbGxvYyBmYWlsZWRcbiIpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBtZW1zZXQoY3VyLCAwLCBzaXplb2YoeHNsdEF0dHJWVCkpOworCisgICAgY3VyLT5uYl9zZWcgPSAwOworICAgIGN1ci0+bWF4X3NlZyA9IE1BWF9BVlRfU0VHOworICAgIGN1ci0+c3Ryc3RhcnQgPSAwOworICAgIGN1ci0+bmV4dCA9IHN0eWxlLT5hdHRWVHM7CisgICAgLyoKKyAgICAgKiBOb3RlOiB0aGlzIHBvaW50ZXIgbWF5IGJlIGNoYW5nZWQgYnkgYSByZS1hbGxvYyB3aXRoaW4geHNsdENvbXBpbGVBdHRyLAorICAgICAqIHNvIHRoYXQgY29kZSBtYXkgY2hhbmdlIHRoZSBzdHlsZXNoZWV0IHBvaW50ZXIgYWxzbyEKKyAgICAgKi8KKyAgICBzdHlsZS0+YXR0VlRzID0gKHhzbHRBdHRyVlRQdHIpIGN1cjsKKworICAgIHJldHVybihjdXIpOworfQorCisvKioKKyAqIHhzbHRGcmVlQXR0clZUOgorICogQGF2dDogcG9pbnRlciB0byBhbiB4c2x0QXR0clZUIHN0cnVjdHVyZQorICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhc3NvY2lhdGVkIHRvIHRoZSBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRGcmVlQXR0clZUKHhzbHRBdHRyVlRQdHIgYXZ0KSB7CisgICAgaW50IGk7CisKKyAgICBpZiAoYXZ0ID09IE5VTEwpIHJldHVybjsKKworICAgIGlmIChhdnQtPnN0cnN0YXJ0ID09IDEpIHsKKwlmb3IgKGkgPSAwO2kgPCBhdnQtPm5iX3NlZzsgaSArPSAyKQorCSAgICBpZiAoYXZ0LT5zZWdtZW50c1tpXSAhPSBOVUxMKQorCQl4bWxGcmVlKCh4bWxDaGFyICopIGF2dC0+c2VnbWVudHNbaV0pOworCWZvciAoaSA9IDE7aSA8IGF2dC0+bmJfc2VnOyBpICs9IDIpCisJICAgIHhtbFhQYXRoRnJlZUNvbXBFeHByKCh4bWxYUGF0aENvbXBFeHByUHRyKSBhdnQtPnNlZ21lbnRzW2ldKTsKKyAgICB9IGVsc2UgeworCWZvciAoaSA9IDA7aSA8IGF2dC0+bmJfc2VnOyBpICs9IDIpCisJICAgIHhtbFhQYXRoRnJlZUNvbXBFeHByKCh4bWxYUGF0aENvbXBFeHByUHRyKSBhdnQtPnNlZ21lbnRzW2ldKTsKKwlmb3IgKGkgPSAxO2kgPCBhdnQtPm5iX3NlZzsgaSArPSAyKQorCSAgICBpZiAoYXZ0LT5zZWdtZW50c1tpXSAhPSBOVUxMKQorCQl4bWxGcmVlKCh4bWxDaGFyICopIGF2dC0+c2VnbWVudHNbaV0pOworICAgIH0KKyAgICBpZiAoYXZ0LT5uc0xpc3QgIT0gTlVMTCkKKyAgICAgICAgeG1sRnJlZShhdnQtPm5zTGlzdCk7CisgICAgeG1sRnJlZShhdnQpOworfQorCisvKioKKyAqIHhzbHRGcmVlQVZUTGlzdDoKKyAqIEBhdnQ6IHBvaW50ZXIgdG8gYW4gbGlzdCBvZiBBVlQgc3RydWN0dXJlcworICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhc3NvY2lhdGVkIHRvIHRoZSBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGVzCisgKi8KK3ZvaWQKK3hzbHRGcmVlQVZUTGlzdCh2b2lkICphdnQpIHsKKyAgICB4c2x0QXR0clZUUHRyIGN1ciA9ICh4c2x0QXR0clZUUHRyKSBhdnQsIG5leHQ7CisKKyAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKKyAgICAgICAgbmV4dCA9IGN1ci0+bmV4dDsKKwl4c2x0RnJlZUF0dHJWVChjdXIpOworCWN1ciA9IG5leHQ7CisgICAgfQorfQorLyoqCisgKiB4c2x0U2V0QXR0clZUc2VnbWVudDoKKyAqIEAgYXZ0OiBwb2ludGVyIHRvIGFuIHhzbHRBdHRyVlQgc3RydWN0dXJlCisgKiBAIHZhbDogdGhlIHZhbHVlIHRvIGJlIHNldCB0byB0aGUgbmV4dCBhdmFpbGFibGUgc2VnbWVudAorICoKKyAqIFdpdGhpbiB4c2x0Q29tcGlsZUF0dHIgdGhlcmUgYXJlIHNldmVyYWwgcGxhY2VzIHdoZXJlIGEgdmFsdWUKKyAqIG5lZWRzIHRvIGJlIGFkZGVkIHRvIHRoZSAnc2VnbWVudHMnIGFycmF5IHdpdGhpbiB0aGUgeHNsdEF0dHJWVAorICogc3RydWN0dXJlLCBhbmQgYXQgZWFjaCBwbGFjZSB0aGUgYWxsb2NhdGVkIHNpemUgbWF5IGhhdmUgdG8gYmUKKyAqIHJlLWFsbG9jYXRlZC4gIFRoaXMgcm91dGluZSB0YWtlcyBjYXJlIG9mIHRoYXQgc2l0dWF0aW9uLgorICoKKyAqIFJldHVybnMgdGhlIGF2dCBwb2ludGVyLCB3aGljaCBtYXkgaGF2ZSBiZWVuIGNoYW5nZWQgYnkgYSByZS1hbGxvYworICovCitzdGF0aWMgeHNsdEF0dHJWVFB0cgoreHNsdFNldEF0dHJWVHNlZ21lbnQoeHNsdEF0dHJWVFB0ciBhdnQsIHZvaWQgKnZhbCkgeworICAgIGlmIChhdnQtPm5iX3NlZyA+PSBhdnQtPm1heF9zZWcpIHsKKwlhdnQgPSAoeHNsdEF0dHJWVFB0cikgeG1sUmVhbGxvYyhhdnQsIHNpemVvZih4c2x0QXR0clZUKSArCisJICAgIAkJYXZ0LT5tYXhfc2VnICogc2l6ZW9mKHZvaWQgKikpOworCWlmIChhdnQgPT0gTlVMTCkgeworCSAgICByZXR1cm4gTlVMTDsKKwl9CisJbWVtc2V0KCZhdnQtPnNlZ21lbnRzW2F2dC0+bmJfc2VnXSwgMCwgTUFYX0FWVF9TRUcqc2l6ZW9mKHZvaWQgKikpOworCWF2dC0+bWF4X3NlZyArPSBNQVhfQVZUX1NFRzsKKyAgICB9CisgICAgYXZ0LT5zZWdtZW50c1thdnQtPm5iX3NlZysrXSA9IHZhbDsKKyAgICByZXR1cm4gYXZ0OworfQorCisvKioKKyAqIHhzbHRDb21waWxlQXR0cjoKKyAqIEBzdHlsZTogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBhdHRyOiB0aGUgYXR0cmlidXRlIGNvbWluZyBmcm9tIHRoZSBzdHlsZXNoZWV0LgorICoKKyAqIFByZWNvbXBpbGUgYW4gYXR0cmlidXRlIGluIGEgc3R5bGVzaGVldCwgYmFzaWNhbGx5IGl0IGNoZWNrcyBpZiBpdCBpcworICogYW4gYXR0cnVidXRlIHZhbHVlIHRlbXBsYXRlLCBhbmQgaWYgeWVzIGVzdGFibGlzaCBzb21lIHN0cnVjdHVyZXMgbmVlZGVkCisgKiB0byBwcm9jZXNzIGl0IGF0IHRyYW5zZm9ybWF0aW9uIHRpbWUuCisgKi8KK3ZvaWQKK3hzbHRDb21waWxlQXR0cih4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sQXR0clB0ciBhdHRyKSB7CisgICAgY29uc3QgeG1sQ2hhciAqc3RyOworICAgIGNvbnN0IHhtbENoYXIgKmN1cjsKKyAgICB4bWxDaGFyICpyZXQgPSBOVUxMOworICAgIHhtbENoYXIgKmV4cHIgPSBOVUxMOworICAgIHhzbHRBdHRyVlRQdHIgYXZ0OworICAgIGludCBpID0gMCwgbGFzdGF2dCA9IDA7CisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChhdHRyID09IE5VTEwpIHx8IChhdHRyLT5jaGlsZHJlbiA9PSBOVUxMKSkKKyAgICAgICAgcmV0dXJuOworICAgIGlmICgoYXR0ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX1RFWFRfTk9ERSkgfHwgCisgICAgICAgIChhdHRyLT5jaGlsZHJlbi0+bmV4dCAhPSBOVUxMKSkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGF0dHItPnBhcmVudCwKKwkgICAgIkF0dHJpYnV0ZSAnJXMnOiBUaGUgY29udGVudCBpcyBleHBlY3RlZCB0byBiZSBhIHNpbmdsZSB0ZXh0ICIKKwkgICAgIm5vZGUgd2hlbiBjb21waWxpbmcgYW4gQVZULlxuIiwgYXR0ci0+bmFtZSk7CisJc3R5bGUtPmVycm9ycysrOworCXJldHVybjsKKyAgICB9CisgICAgc3RyID0gYXR0ci0+Y2hpbGRyZW4tPmNvbnRlbnQ7CisgICAgaWYgKCh4bWxTdHJjaHIoc3RyLCAneycpID09IE5VTEwpICYmCisgICAgICAgICh4bWxTdHJjaHIoc3RyLCAnfScpID09IE5VTEwpKSByZXR1cm47CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfQVZUCisgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICAgICJGb3VuZCBBVlQgJXM6ICVzXG4iLCBhdHRyLT5uYW1lLCBzdHIpOworI2VuZGlmCisgICAgaWYgKGF0dHItPnBzdmkgIT0gTlVMTCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19BVlQKKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJIkFWVCAlczogYWxyZWFkeSBjb21waWxlZFxuIiwgYXR0ci0+bmFtZSk7CisjZW5kaWYKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICAvKgorICAgICogQ3JlYXRlIGEgbmV3IEFWVCBvYmplY3QuCisgICAgKi8KKyAgICBhdnQgPSB4c2x0TmV3QXR0clZUKHN0eWxlKTsKKyAgICBpZiAoYXZ0ID09IE5VTEwpCisJcmV0dXJuOworICAgIGF0dHItPnBzdmkgPSBhdnQ7CisKKyAgICBhdnQtPm5zTGlzdCA9IHhtbEdldE5zTGlzdChhdHRyLT5kb2MsIGF0dHItPnBhcmVudCk7CisgICAgaWYgKGF2dC0+bnNMaXN0ICE9IE5VTEwpIHsKKwl3aGlsZSAoYXZ0LT5uc0xpc3RbaV0gIT0gTlVMTCkKKwkgICAgaSsrOworICAgIH0KKyAgICBhdnQtPm5zTnIgPSBpOworCisgICAgY3VyID0gc3RyOworICAgIHdoaWxlICgqY3VyICE9IDApIHsKKwlpZiAoKmN1ciA9PSAneycpIHsKKwkgICAgaWYgKCooY3VyKzEpID09ICd7JykgewkvKiBlc2NhcGVkICd7JyAqLworCSAgICAgICAgY3VyKys7CisJCXJldCA9IHhtbFN0cm5jYXQocmV0LCBzdHIsIGN1ciAtIHN0cik7CisJCWN1cisrOworCQlzdHIgPSBjdXI7CisJCWNvbnRpbnVlOworCSAgICB9CisJICAgIGlmICgqKGN1cisxKSA9PSAnfScpIHsJLyogc2tpcCBlbXB0eSBBVlQgKi8KKwkJcmV0ID0geG1sU3RybmNhdChyZXQsIHN0ciwgY3VyIC0gc3RyKTsKKwkgICAgICAgIGN1ciArPSAyOworCQlzdHIgPSBjdXI7CisJCWNvbnRpbnVlOworCSAgICB9CisJICAgIGlmICgocmV0ICE9IE5VTEwpIHx8IChjdXIgLSBzdHIgPiAwKSkgeworCQlyZXQgPSB4bWxTdHJuY2F0KHJldCwgc3RyLCBjdXIgLSBzdHIpOworCQlzdHIgPSBjdXI7CisJCWlmIChhdnQtPm5iX3NlZyA9PSAwKQorCQkgICAgYXZ0LT5zdHJzdGFydCA9IDE7CisJCWlmICgoYXZ0ID0geHNsdFNldEF0dHJWVHNlZ21lbnQoYXZ0LCAodm9pZCAqKSByZXQpKSA9PSBOVUxMKQorCQkgICAgZ290byBlcnJvcjsKKwkJcmV0ID0gTlVMTDsKKwkJbGFzdGF2dCA9IDA7CisJICAgIH0KKworCSAgICBjdXIrKzsKKwkgICAgd2hpbGUgKCgqY3VyICE9IDApICYmICgqY3VyICE9ICd9JykpIHsKKwkJLyogTmVlZCB0byBjaGVjayBmb3IgbGl0ZXJhbCAoYnVnNTM5NzQxKSAqLworCQlpZiAoKCpjdXIgPT0gJ1wnJykgfHwgKCpjdXIgPT0gJyInKSkgeworCQkgICAgY2hhciBkZWxpbSA9ICooY3VyKyspOworCQkgICAgd2hpbGUgKCgqY3VyICE9IDApICYmICgqY3VyICE9IGRlbGltKSkgCisJCQljdXIrKzsKKwkJICAgIGlmICgqY3VyICE9IDApCisJCQljdXIrKzsJLyogc2tpcCB0aGUgZW5kaW5nIGRlbGltaXRlciAqLworCQl9IGVsc2UKKwkJICAgIGN1cisrOworCSAgICB9CisJICAgIGlmICgqY3VyID09IDApIHsKKwkgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgYXR0ci0+cGFyZW50LAorCQkgICAgICJBdHRyaWJ1dGUgJyVzJzogVGhlIEFWVCBoYXMgYW4gdW5tYXRjaGVkICd7Jy5cbiIsCisJCSAgICAgYXR0ci0+bmFtZSk7CisJCXN0eWxlLT5lcnJvcnMrKzsKKwkJZ290byBlcnJvcjsKKwkgICAgfQorCSAgICBzdHIrKzsKKwkgICAgZXhwciA9IHhtbFN0cm5kdXAoc3RyLCBjdXIgLSBzdHIpOworCSAgICBpZiAoZXhwciA9PSBOVUxMKSB7CisJCS8qCisJCSogVE9ETzogV2hhdCBuZWVkcyB0byBiZSBkb25lIGhlcmU/CisJCSovCisJICAgICAgICBYU0xUX1RPRE8KKwkJZ290byBlcnJvcjsKKwkgICAgfSBlbHNlIHsKKwkJeG1sWFBhdGhDb21wRXhwclB0ciBjb21wOworCisJCWNvbXAgPSB4c2x0WFBhdGhDb21waWxlKHN0eWxlLCBleHByKTsKKwkJaWYgKGNvbXAgPT0gTlVMTCkgeworCQkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBhdHRyLT5wYXJlbnQsCisJCQkgIkF0dHJpYnV0ZSAnJXMnOiBGYWlsZWQgdG8gY29tcGlsZSB0aGUgZXhwcmVzc2lvbiAiCisJCQkgIiclcycgaW4gdGhlIEFWVC5cbiIsIGF0dHItPm5hbWUsIGV4cHIpOworCQkgICAgc3R5bGUtPmVycm9ycysrOworCQkgICAgZ290byBlcnJvcjsKKwkJfQorCQlpZiAoYXZ0LT5uYl9zZWcgPT0gMCkKKwkJICAgIGF2dC0+c3Ryc3RhcnQgPSAwOworCQlpZiAobGFzdGF2dCA9PSAxKSB7CisJCSAgICBpZiAoKGF2dCA9IHhzbHRTZXRBdHRyVlRzZWdtZW50KGF2dCwgTlVMTCkpID09IE5VTEwpCisJCSAgICAgICAgZ290byBlcnJvcjsKKwkJfQorCQlpZiAoKGF2dCA9IHhzbHRTZXRBdHRyVlRzZWdtZW50KGF2dCwgKHZvaWQgKikgY29tcCkpID09IE5VTEwpCisJCSAgICBnb3RvIGVycm9yOworCQlsYXN0YXZ0ID0gMTsKKwkJeG1sRnJlZShleHByKTsKKwkJZXhwciA9IE5VTEw7CisJICAgIH0KKwkgICAgY3VyKys7CisJICAgIHN0ciA9IGN1cjsKKwl9IGVsc2UgaWYgKCpjdXIgPT0gJ30nKSB7CisJICAgIGN1cisrOworCSAgICBpZiAoKmN1ciA9PSAnfScpIHsJLyogZXNjYXBlZCAnfScgKi8KKwkJcmV0ID0geG1sU3RybmNhdChyZXQsIHN0ciwgY3VyIC0gc3RyKTsKKwkJY3VyKys7CisJCXN0ciA9IGN1cjsKKwkJY29udGludWU7CisJICAgIH0gZWxzZSB7CisJICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGF0dHItPnBhcmVudCwKKwkJICAgICAiQXR0cmlidXRlICclcyc6IFRoZSBBVlQgaGFzIGFuIHVubWF0Y2hlZCAnfScuXG4iLAorCQkgICAgIGF0dHItPm5hbWUpOworCQlnb3RvIGVycm9yOworCSAgICB9CisJfSBlbHNlCisJICAgIGN1cisrOworICAgIH0KKyAgICBpZiAoKHJldCAhPSBOVUxMKSB8fCAoY3VyIC0gc3RyID4gMCkpIHsKKwlyZXQgPSB4bWxTdHJuY2F0KHJldCwgc3RyLCBjdXIgLSBzdHIpOworCXN0ciA9IGN1cjsKKwlpZiAoYXZ0LT5uYl9zZWcgPT0gMCkKKwkgICAgYXZ0LT5zdHJzdGFydCA9IDE7CisJaWYgKChhdnQgPSB4c2x0U2V0QXR0clZUc2VnbWVudChhdnQsICh2b2lkICopIHJldCkpID09IE5VTEwpCisJICAgIGdvdG8gZXJyb3I7CisJcmV0ID0gTlVMTDsKKyAgICB9CisKK2Vycm9yOgorICAgIGlmIChhdnQgPT0gTlVMTCkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGF0dHItPnBhcmVudCwKKwkJInhzbHRDb21waWxlQXR0cjogbWFsbG9jIHByb2JsZW1cbiIpOworICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChhdHRyLT5wc3ZpICE9IGF2dCkgeyAgLyogbWF5IGhhdmUgY2hhbmdlZCBmcm9tIHJlYWxsb2MgKi8KKyAgICAgICAgICAgIGF0dHItPnBzdmkgPSBhdnQ7CisJICAgIC8qCisJICAgICAqIFRoaXMgaXMgYSAiaGFjayIsIGJ1dCBJIGNhbid0IHNlZSBhbnkgY2xlYW4gbWV0aG9kIG9mCisJICAgICAqIGRvaW5nIGl0LiAgSWYgYSByZS1hbGxvYyBoYXMgdGFrZW4gcGxhY2UsIHRoZW4gdGhlIHBvaW50ZXIKKwkgICAgICogZm9yIHRoaXMgQVZUIG1heSBoYXZlIGNoYW5nZWQuICBzdHlsZS0+YXR0VlRzIHdhcyBzZXQgYnkKKwkgICAgICogeHNsdE5ld0F0dHJWVCwgc28gaXQgbmVlZHMgdG8gYmUgcmUtc2V0IHRvIHRoZSBuZXcgdmFsdWUhCisJICAgICAqLworCSAgICBzdHlsZS0+YXR0VlRzID0gYXZ0OworCX0KKyAgICB9CisgICAgaWYgKHJldCAhPSBOVUxMKQorCXhtbEZyZWUocmV0KTsKKyAgICBpZiAoZXhwciAhPSBOVUxMKQorCXhtbEZyZWUoZXhwcik7Cit9CisKKworLyoqCisgKiB4c2x0RXZhbEFWVDoKKyAqIEBjdHh0OiB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAYXZ0OiB0aGUgcHJldm9tcGlsZWQgYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIGluZm8KKyAqIEBub2RlOiB0aGUgbm9kZSBob3N0aW5nIHRoZSBhdHRyaWJ1dGUKKyAqCisgKiBQcm9jZXNzIHRoZSBnaXZlbiBBVlQsIGFuZCByZXR1cm4gdGhlIG5ldyBzdHJpbmcgdmFsdWUuCisgKgorICogUmV0dXJucyB0aGUgY29tcHV0ZWQgc3RyaW5nIHZhbHVlIG9yIE5VTEwsIG11c3QgYmUgZGVhbGxvY2F0ZWQgYnkgdGhlCisgKiAgICAgICAgIGNhbGxlci4KKyAqLworeG1sQ2hhciAqCit4c2x0RXZhbEFWVCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB2b2lkICphdnQsIHhtbE5vZGVQdHIgbm9kZSkgeworICAgIHhtbENoYXIgKnJldCA9IE5VTEwsICp0bXA7CisgICAgeG1sWFBhdGhDb21wRXhwclB0ciBjb21wOworICAgIHhzbHRBdHRyVlRQdHIgY3VyID0gKHhzbHRBdHRyVlRQdHIpIGF2dDsKKyAgICBpbnQgaTsKKyAgICBpbnQgc3RyOworCisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChhdnQgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCisgICAgICAgIHJldHVybihOVUxMKTsKKyAgICBzdHIgPSBjdXItPnN0cnN0YXJ0OworICAgIGZvciAoaSA9IDA7aSA8IGN1ci0+bmJfc2VnO2krKykgeworICAgICAgICBpZiAoc3RyKSB7CisJICAgIHJldCA9IHhtbFN0cmNhdChyZXQsIChjb25zdCB4bWxDaGFyICopIGN1ci0+c2VnbWVudHNbaV0pOworCX0gZWxzZSB7CisJICAgIGNvbXAgPSAoeG1sWFBhdGhDb21wRXhwclB0cikgY3VyLT5zZWdtZW50c1tpXTsKKwkgICAgdG1wID0geHNsdEV2YWxYUGF0aFN0cmluZ05zKGN0eHQsIGNvbXAsIGN1ci0+bnNOciwgY3VyLT5uc0xpc3QpOworCSAgICBpZiAodG1wICE9IE5VTEwpIHsKKwkgICAgICAgIGlmIChyZXQgIT0gTlVMTCkgeworCQkgICAgcmV0ID0geG1sU3RyY2F0KHJldCwgdG1wKTsKKwkJICAgIHhtbEZyZWUodG1wKTsKKwkJfSBlbHNlIHsKKwkJICAgIHJldCA9IHRtcDsKKwkJfQorCSAgICB9CisJfQorCXN0ciA9ICFzdHI7CisgICAgfQorICAgIHJldHVybihyZXQpOworfQpkaWZmIC0tZ2l0IGEvbGlieHNsdC9kb2N1bWVudHMuYyBiL2xpYnhzbHQvZG9jdW1lbnRzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTI4Y2VmZQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQvZG9jdW1lbnRzLmMKQEAgLTAsMCArMSw0MzQgQEAKKy8qCisgKiBkb2N1bWVudHMuYzogSW1wbGVtZW50YXRpb24gb2YgdGhlIGRvY3VtZW50cyBoYW5kbGluZworICoKKyAqIFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBkYW5pZWxAdmVpbGxhcmQuY29tCisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CisjaW5jbHVkZSA8bGlieG1sL3RyZWUuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvaGFzaC5oPgorI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXIuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvcGFyc2VySW50ZXJuYWxzLmg+CisjaW5jbHVkZSAieHNsdC5oIgorI2luY2x1ZGUgInhzbHRJbnRlcm5hbHMuaCIKKyNpbmNsdWRlICJ4c2x0dXRpbHMuaCIKKyNpbmNsdWRlICJkb2N1bWVudHMuaCIKKyNpbmNsdWRlICJ0cmFuc2Zvcm0uaCIKKyNpbmNsdWRlICJpbXBvcnRzLmgiCisjaW5jbHVkZSAia2V5cy5oIgorI2luY2x1ZGUgInNlY3VyaXR5LmgiCisKKyNpZmRlZiBMSUJYTUxfWElOQ0xVREVfRU5BQkxFRAorI2luY2x1ZGUgPGxpYnhtbC94aW5jbHVkZS5oPgorI2VuZGlmCisKKyNkZWZpbmUgV0lUSF9YU0xUX0RFQlVHX0RPQ1VNRU5UUworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHCisjZGVmaW5lIFdJVEhfWFNMVF9ERUJVR19ET0NVTUVOVFMKKyNlbmRpZgorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAJCQkJCQkJCQkqCisgKiAJCUhvb2tzIGZvciB0aGUgZG9jdW1lbnQgbG9hZGVyCQkJCSoKKyAqIAkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdERvY0RlZmF1bHRMb2FkZXJGdW5jOgorICogQFVSSTogdGhlIFVSSSBvZiB0aGUgZG9jdW1lbnQgdG8gbG9hZAorICogQGRpY3Q6IHRoZSBkaWN0aW9uYXJ5IHRvIHVzZSB3aGVuIHBhcnNpbmcgdGhhdCBkb2N1bWVudAorICogQG9wdGlvbnM6IHBhcnNpbmcgb3B0aW9ucywgYSBzZXQgb2YgeG1sUGFyc2VyT3B0aW9uCisgKiBAY3R4dDogdGhlIGNvbnRleHQsIGVpdGhlciBhIHN0eWxlc2hlZXQgb3IgYSB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAdHlwZTogdGhlIHhzbHRMb2FkVHlwZSBpbmRpY2F0aW5nIHRoZSBraW5kIG9mIGxvYWRpbmcgcmVxdWlyZWQKKyAqCisgKiBEZWZhdWx0IGZ1bmN0aW9uIHRvIGxvYWQgZG9jdW1lbnQgbm90IHByb3ZpZGVkIGJ5IHRoZSBjb21waWxhdGlvbiBvcgorICogdHJhbnNmb3JtYXRpb24gQVBJIHRoZW1zZWx2ZSwgZm9yIGV4YW1wbGUgd2hlbiBhbiB4c2w6aW1wb3J0LAorICogeHNsOmluY2x1ZGUgaXMgZm91bmQgYXQgY29tcGlsYXRpb24gdGltZSBvciB3aGVuIGEgZG9jdW1lbnQoKQorICogY2FsbCBpcyBtYWRlIGF0IHJ1bnRpbWUuCisgKgorICogUmV0dXJucyB0aGUgcG9pbnRlciB0byB0aGUgZG9jdW1lbnQgKHdoaWNoIHdpbGwgYmUgbW9kaWZpZWQgYW5kCisgKiBmcmVlZCBieSB0aGUgZW5naW5lIGxhdGVyKSwgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yLgorICovCitzdGF0aWMgeG1sRG9jUHRyCit4c2x0RG9jRGVmYXVsdExvYWRlckZ1bmMoY29uc3QgeG1sQ2hhciAqIFVSSSwgeG1sRGljdFB0ciBkaWN0LCBpbnQgb3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjdHh0IEFUVFJJQlVURV9VTlVTRUQsCisJCQkgeHNsdExvYWRUeXBlIHR5cGUgQVRUUklCVVRFX1VOVVNFRCkKK3sKKyAgICB4bWxQYXJzZXJDdHh0UHRyIHBjdHh0OworICAgIHhtbFBhcnNlcklucHV0UHRyIGlucHV0U3RyZWFtOworICAgIHhtbERvY1B0ciBkb2M7CisKKyAgICBwY3R4dCA9IHhtbE5ld1BhcnNlckN0eHQoKTsKKyAgICBpZiAocGN0eHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuKE5VTEwpOworICAgIGlmICgoZGljdCAhPSBOVUxMKSAmJiAocGN0eHQtPmRpY3QgIT0gTlVMTCkpIHsKKyAgICAgICAgeG1sRGljdEZyZWUocGN0eHQtPmRpY3QpOworCXBjdHh0LT5kaWN0ID0gTlVMTDsKKyAgICB9CisgICAgaWYgKGRpY3QgIT0gTlVMTCkgeworCXBjdHh0LT5kaWN0ID0gZGljdDsKKwl4bWxEaWN0UmVmZXJlbmNlKHBjdHh0LT5kaWN0KTsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgIlJldXNpbmcgZGljdGlvbmFyeSBmb3IgZG9jdW1lbnRcbiIpOworI2VuZGlmCisgICAgfQorICAgIHhtbEN0eHRVc2VPcHRpb25zKHBjdHh0LCBvcHRpb25zKTsKKyAgICBpbnB1dFN0cmVhbSA9IHhtbExvYWRFeHRlcm5hbEVudGl0eSgoY29uc3QgY2hhciAqKSBVUkksIE5VTEwsIHBjdHh0KTsKKyAgICBpZiAoaW5wdXRTdHJlYW0gPT0gTlVMTCkgeworICAgICAgICB4bWxGcmVlUGFyc2VyQ3R4dChwY3R4dCk7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBpbnB1dFB1c2gocGN0eHQsIGlucHV0U3RyZWFtKTsKKyAgICBpZiAocGN0eHQtPmRpcmVjdG9yeSA9PSBOVUxMKQorICAgICAgICBwY3R4dC0+ZGlyZWN0b3J5ID0geG1sUGFyc2VyR2V0RGlyZWN0b3J5KChjb25zdCBjaGFyICopIFVSSSk7CisKKyAgICB4bWxQYXJzZURvY3VtZW50KHBjdHh0KTsKKworICAgIGlmIChwY3R4dC0+d2VsbEZvcm1lZCkgeworICAgICAgICBkb2MgPSBwY3R4dC0+bXlEb2M7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBkb2MgPSBOVUxMOworICAgICAgICB4bWxGcmVlRG9jKHBjdHh0LT5teURvYyk7CisgICAgICAgIHBjdHh0LT5teURvYyA9IE5VTEw7CisgICAgfQorICAgIHhtbEZyZWVQYXJzZXJDdHh0KHBjdHh0KTsKKworICAgIHJldHVybihkb2MpOworfQorCisKK3hzbHREb2NMb2FkZXJGdW5jIHhzbHREb2NEZWZhdWx0TG9hZGVyID0geHNsdERvY0RlZmF1bHRMb2FkZXJGdW5jOworCisvKioKKyAqIHhzbHRTZXRMb2FkZXJGdW5jOgorICogQGY6IHRoZSBuZXcgZnVuY3Rpb24gdG8gaGFuZGxlIGRvY3VtZW50IGxvYWRpbmcuCisgKgorICogU2V0IHRoZSBuZXcgZnVuY3Rpb24gdG8gbG9hZCBkb2N1bWVudCwgaWYgTlVMTCBpdCByZXNldHMgaXQgdG8gdGhlCisgKiBkZWZhdWx0IGZ1bmN0aW9uLgorICovCisgCit2b2lkCit4c2x0U2V0TG9hZGVyRnVuYyh4c2x0RG9jTG9hZGVyRnVuYyBmKSB7CisgICAgaWYgKGYgPT0gTlVMTCkKKyAgICAgICAgeHNsdERvY0RlZmF1bHRMb2FkZXIgPSB4c2x0RG9jRGVmYXVsdExvYWRlckZ1bmM7CisgICAgZWxzZQorICAgICAgICB4c2x0RG9jRGVmYXVsdExvYWRlciA9IGY7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICoJCQlNb2R1bGUgaW50ZXJmYWNlcwkJCQkqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdE5ld0RvY3VtZW50OgorICogQGN0eHQ6IGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dCAob3IgTlVMTCkKKyAqIEBkb2M6ICBhIHBhcnNlZCBYTUwgZG9jdW1lbnQKKyAqCisgKiBSZWdpc3RlciBhIG5ldyBkb2N1bWVudCwgYXBwbHkga2V5IGNvbXB1dGF0aW9ucworICoKKyAqIFJldHVybnMgYSBoYW5kbGVyIHRvIHRoZSBkb2N1bWVudAorICovCit4c2x0RG9jdW1lbnRQdHIJCit4c2x0TmV3RG9jdW1lbnQoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sRG9jUHRyIGRvYykgeworICAgIHhzbHREb2N1bWVudFB0ciBjdXI7CisKKyAgICBjdXIgPSAoeHNsdERvY3VtZW50UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhzbHREb2N1bWVudCkpOworICAgIGlmIChjdXIgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCAoeG1sTm9kZVB0cikgZG9jLAorCQkieHNsdE5ld0RvY3VtZW50IDogbWFsbG9jIGZhaWxlZFxuIik7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBtZW1zZXQoY3VyLCAwLCBzaXplb2YoeHNsdERvY3VtZW50KSk7CisgICAgY3VyLT5kb2MgPSBkb2M7CisgICAgaWYgKGN0eHQgIT0gTlVMTCkgeworICAgICAgICBpZiAoISBYU0xUX0lTX1JFU19UUkVFX0ZSQUcoZG9jKSkgeworCSAgICBjdXItPm5leHQgPSBjdHh0LT5kb2NMaXN0OworCSAgICBjdHh0LT5kb2NMaXN0ID0gY3VyOworCX0KKwkvKgorCSogQSBrZXkgd2l0aCBhIHNwZWNpZmljIG5hbWUgZm9yIGEgc3BlY2lmaWMgZG9jdW1lbnQKKwkqIHdpbGwgb25seSBiZSBjb21wdXRlZCBpZiB0aGVyZSdzIGEgY2FsbCB0byB0aGUga2V5KCkKKwkqIGZ1bmN0aW9uIHVzaW5nIHRoYXQgc3BlY2lmaWMgbmFtZSBmb3IgdGhhdCBzcGVjaWZpYworCSogZG9jdW1lbnQuIEkuZS4gY29tcHV0YXRpb24gb2Yga2V5cyB3aWxsIGJlIGRvbmUgaW4KKwkqIHhzbHRHZXRLZXkoKSAoa2V5cy5jKSBvbiBhbiBvbi1kZW1hbmQgYmFzaXMuCisJKgorCSogeHNsdEluaXRDdHh0S2V5cyhjdHh0LCBjdXIpOyBub3QgY2FsbGVkIGhlcmUgYW55bW9yZQorCSovCisgICAgfQorICAgIHJldHVybihjdXIpOworfQorCisvKioKKyAqIHhzbHROZXdTdHlsZURvY3VtZW50OgorICogQHN0eWxlOiBhbiBYU0xUIHN0eWxlIHNoZWV0CisgKiBAZG9jOiAgYSBwYXJzZWQgWE1MIGRvY3VtZW50CisgKgorICogUmVnaXN0ZXIgYSBuZXcgZG9jdW1lbnQsIGFwcGx5IGtleSBjb21wdXRhdGlvbnMKKyAqCisgKiBSZXR1cm5zIGEgaGFuZGxlciB0byB0aGUgZG9jdW1lbnQKKyAqLworeHNsdERvY3VtZW50UHRyCQoreHNsdE5ld1N0eWxlRG9jdW1lbnQoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbERvY1B0ciBkb2MpIHsKKyAgICB4c2x0RG9jdW1lbnRQdHIgY3VyOworCisgICAgY3VyID0gKHhzbHREb2N1bWVudFB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0RG9jdW1lbnQpKTsKKyAgICBpZiAoY3VyID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsICh4bWxOb2RlUHRyKSBkb2MsCisJCSJ4c2x0TmV3U3R5bGVEb2N1bWVudCA6IG1hbGxvYyBmYWlsZWRcbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KGN1ciwgMCwgc2l6ZW9mKHhzbHREb2N1bWVudCkpOworICAgIGN1ci0+ZG9jID0gZG9jOworICAgIGlmIChzdHlsZSAhPSBOVUxMKSB7CisJY3VyLT5uZXh0ID0gc3R5bGUtPmRvY0xpc3Q7CisJc3R5bGUtPmRvY0xpc3QgPSBjdXI7CisgICAgfQorICAgIHJldHVybihjdXIpOworfQorCisvKioKKyAqIHhzbHRGcmVlU3R5bGVEb2N1bWVudHM6CisgKiBAc3R5bGU6IGFuIFhTTFQgc3R5bGVzaGVldCAocmVwcmVzZW50aW5nIGEgc3R5bGVzaGVldC1sZXZlbCkKKyAqCisgKiBGcmVlcyB0aGUgbm9kZS10cmVlcyAoYW5kIHhzbHREb2N1bWVudCBzdHJ1Y3R1cmVzKSBvZiBhbGwKKyAqIHN0eWxlc2hlZXQtbW9kdWxlcyBvZiB0aGUgc3R5bGVzaGVldC1sZXZlbCByZXByZXNlbnRlZCBieQorICogdGhlIGdpdmVuIEBzdHlsZS4gCisgKi8KK3ZvaWQJCit4c2x0RnJlZVN0eWxlRG9jdW1lbnRzKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKSB7CisgICAgeHNsdERvY3VtZW50UHRyIGRvYywgY3VyOworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRF9YU0xUX05TQ09NUAorICAgIHhzbHROc01hcFB0ciBuc01hcDsKKyNlbmRpZgorICAgIAorICAgIGlmIChzdHlsZSA9PSBOVUxMKQorCXJldHVybjsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRF9YU0xUX05TQ09NUAorICAgIGlmIChYU0xUX0hBU19JTlRFUk5BTF9OU01BUChzdHlsZSkpCisJbnNNYXAgPSBYU0xUX0dFVF9JTlRFUk5BTF9OU01BUChzdHlsZSk7CisgICAgZWxzZQorCW5zTWFwID0gTlVMTDsgICAgCisjZW5kaWYgICAKKworICAgIGN1ciA9IHN0eWxlLT5kb2NMaXN0OworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCWRvYyA9IGN1cjsKKwljdXIgPSBjdXItPm5leHQ7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVEX1hTTFRfTlNDT01QCisJLyoKKwkqIFJlc3RvcmUgYWxsIGNoYW5nZWQgbmFtZXNwYWNlIFVSSXMgb2YgbnMtZGVjbHMuCisJKi8KKwlpZiAobnNNYXApCisJICAgIHhzbHRSZXN0b3JlRG9jdW1lbnROYW1lc3BhY2VzKG5zTWFwLCBkb2MtPmRvYyk7CisjZW5kaWYKKwl4c2x0RnJlZURvY3VtZW50S2V5cyhkb2MpOworCWlmICghZG9jLT5tYWluKQorCSAgICB4bWxGcmVlRG9jKGRvYy0+ZG9jKTsKKyAgICAgICAgeG1sRnJlZShkb2MpOworICAgIH0KK30KKworLyoqCisgKiB4c2x0RnJlZURvY3VtZW50czoKKyAqIEBjdHh0OiBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqCisgKiBGcmVlIHVwIGFsbCB0aGUgc3BhY2UgdXNlZCBieSB0aGUgbG9hZGVkIGRvY3VtZW50cworICovCit2b2lkCQoreHNsdEZyZWVEb2N1bWVudHMoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCkgeworICAgIHhzbHREb2N1bWVudFB0ciBkb2MsIGN1cjsKKworICAgIGN1ciA9IGN0eHQtPmRvY0xpc3Q7CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJZG9jID0gY3VyOworCWN1ciA9IGN1ci0+bmV4dDsKKwl4c2x0RnJlZURvY3VtZW50S2V5cyhkb2MpOworCWlmICghZG9jLT5tYWluKQorCSAgICB4bWxGcmVlRG9jKGRvYy0+ZG9jKTsKKyAgICAgICAgeG1sRnJlZShkb2MpOworICAgIH0KKyAgICBjdXIgPSBjdHh0LT5zdHlsZUxpc3Q7CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJZG9jID0gY3VyOworCWN1ciA9IGN1ci0+bmV4dDsKKwl4c2x0RnJlZURvY3VtZW50S2V5cyhkb2MpOworCWlmICghZG9jLT5tYWluKQorCSAgICB4bWxGcmVlRG9jKGRvYy0+ZG9jKTsKKyAgICAgICAgeG1sRnJlZShkb2MpOworICAgIH0KK30KKworLyoqCisgKiB4c2x0TG9hZERvY3VtZW50OgorICogQGN0eHQ6IGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQFVSSTogIHRoZSBjb21wdXRlZCBVUkkgb2YgdGhlIGRvY3VtZW50CisgKgorICogVHJ5IHRvIGxvYWQgYSBkb2N1bWVudCAobm90IGEgc3R5bGVzaGVldCkKKyAqIHdpdGhpbiB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogUmV0dXJucyB0aGUgbmV3IHhzbHREb2N1bWVudFB0ciBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworeHNsdERvY3VtZW50UHRyCQoreHNsdExvYWREb2N1bWVudCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICpVUkkpIHsKKyAgICB4c2x0RG9jdW1lbnRQdHIgcmV0OworICAgIHhtbERvY1B0ciBkb2M7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKFVSSSA9PSBOVUxMKSkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICAvKgorICAgICAqIFNlY3VyaXR5IGZyYW1ld29yayBjaGVjaworICAgICAqLworICAgIGlmIChjdHh0LT5zZWMgIT0gTlVMTCkgeworCWludCByZXM7CisJCisJcmVzID0geHNsdENoZWNrUmVhZChjdHh0LT5zZWMsIGN0eHQsIFVSSSk7CisJaWYgKHJlcyA9PSAwKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBOVUxMLAorCQkgInhzbHRMb2FkRG9jdW1lbnQ6IHJlYWQgcmlnaHRzIGZvciAlcyBkZW5pZWRcbiIsCisJCQkgICAgIFVSSSk7CisJICAgIHJldHVybihOVUxMKTsKKwl9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBXYWxrIHRoZSBjb250ZXh0IGxpc3QgdG8gZmluZCB0aGUgZG9jdW1lbnQgaWYgcHJlcGFyc2VkCisgICAgICovCisgICAgcmV0ID0gY3R4dC0+ZG9jTGlzdDsKKyAgICB3aGlsZSAocmV0ICE9IE5VTEwpIHsKKwlpZiAoKHJldC0+ZG9jICE9IE5VTEwpICYmIChyZXQtPmRvYy0+VVJMICE9IE5VTEwpICYmCisJICAgICh4bWxTdHJFcXVhbChyZXQtPmRvYy0+VVJMLCBVUkkpKSkKKwkgICAgcmV0dXJuKHJldCk7CisJcmV0ID0gcmV0LT5uZXh0OworICAgIH0KKworICAgIGRvYyA9IHhzbHREb2NEZWZhdWx0TG9hZGVyKFVSSSwgY3R4dC0+ZGljdCwgY3R4dC0+cGFyc2VyT3B0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBjdHh0LCBYU0xUX0xPQURfRE9DVU1FTlQpOworCisgICAgaWYgKGRvYyA9PSBOVUxMKQorCXJldHVybihOVUxMKTsKKworICAgIGlmIChjdHh0LT54aW5jbHVkZSAhPSAwKSB7CisjaWZkZWYgTElCWE1MX1hJTkNMVURFX0VOQUJMRUQKKyNpZiBMSUJYTUxfVkVSU0lPTiA+PSAyMDYwMworCXhtbFhJbmNsdWRlUHJvY2Vzc0ZsYWdzKGRvYywgY3R4dC0+cGFyc2VyT3B0aW9ucyk7CisjZWxzZQorCXhtbFhJbmNsdWRlUHJvY2Vzcyhkb2MpOworI2VuZGlmCisjZWxzZQorCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBOVUxMLAorCSAgICAieHNsdExvYWREb2N1bWVudCglcykgOiBYSW5jbHVkZSBwcm9jZXNzaW5nIG5vdCBjb21waWxlZCBpblxuIiwKKwkgICAgICAgICAgICAgICAgIFVSSSk7CisjZW5kaWYKKyAgICB9CisgICAgLyoKKyAgICAgKiBBcHBseSB3aGl0ZS1zcGFjZSBzdHJpcHBpbmcgaWYgYXNrZWQgZm9yCisgICAgICovCisgICAgaWYgKHhzbHROZWVkRWxlbVNwYWNlSGFuZGxpbmcoY3R4dCkpCisJeHNsdEFwcGx5U3RyaXBTcGFjZXMoY3R4dCwgeG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKSk7CisgICAgaWYgKGN0eHQtPmRlYnVnU3RhdHVzID09IFhTTFRfREVCVUdfTk9ORSkKKwl4bWxYUGF0aE9yZGVyRG9jRWxlbXMoZG9jKTsKKworICAgIHJldCA9IHhzbHROZXdEb2N1bWVudChjdHh0LCBkb2MpOworICAgIHJldHVybihyZXQpOworfQorCisvKioKKyAqIHhzbHRMb2FkU3R5bGVEb2N1bWVudDoKKyAqIEBzdHlsZTogYW4gWFNMVCBzdHlsZSBzaGVldAorICogQFVSSTogIHRoZSBjb21wdXRlZCBVUkkgb2YgdGhlIGRvY3VtZW50CisgKgorICogVHJ5IHRvIGxvYWQgYSBzdHlsZXNoZWV0IGRvY3VtZW50IHdpdGhpbiB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogUmV0dXJucyB0aGUgbmV3IHhzbHREb2N1bWVudFB0ciBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworeHNsdERvY3VtZW50UHRyCQoreHNsdExvYWRTdHlsZURvY3VtZW50KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCBjb25zdCB4bWxDaGFyICpVUkkpIHsKKyAgICB4c2x0RG9jdW1lbnRQdHIgcmV0OworICAgIHhtbERvY1B0ciBkb2M7CisgICAgeHNsdFNlY3VyaXR5UHJlZnNQdHIgc2VjOworCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoVVJJID09IE5VTEwpKQorCXJldHVybihOVUxMKTsKKworICAgIC8qCisgICAgICogU2VjdXJpdHkgZnJhbWV3b3JrIGNoZWNrCisgICAgICovCisgICAgc2VjID0geHNsdEdldERlZmF1bHRTZWN1cml0eVByZWZzKCk7CisgICAgaWYgKHNlYyAhPSBOVUxMKSB7CisJaW50IHJlczsKKworCXJlcyA9IHhzbHRDaGVja1JlYWQoc2VjLCBOVUxMLCBVUkkpOworCWlmIChyZXMgPT0gMCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkJICJ4c2x0TG9hZFN0eWxlRG9jdW1lbnQ6IHJlYWQgcmlnaHRzIGZvciAlcyBkZW5pZWRcbiIsCisJCQkgICAgIFVSSSk7CisJICAgIHJldHVybihOVUxMKTsKKwl9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBXYWxrIHRoZSBjb250ZXh0IGxpc3QgdG8gZmluZCB0aGUgZG9jdW1lbnQgaWYgcHJlcGFyc2VkCisgICAgICovCisgICAgcmV0ID0gc3R5bGUtPmRvY0xpc3Q7CisgICAgd2hpbGUgKHJldCAhPSBOVUxMKSB7CisJaWYgKChyZXQtPmRvYyAhPSBOVUxMKSAmJiAocmV0LT5kb2MtPlVSTCAhPSBOVUxMKSAmJgorCSAgICAoeG1sU3RyRXF1YWwocmV0LT5kb2MtPlVSTCwgVVJJKSkpCisJICAgIHJldHVybihyZXQpOworCXJldCA9IHJldC0+bmV4dDsKKyAgICB9CisKKyAgICBkb2MgPSB4c2x0RG9jRGVmYXVsdExvYWRlcihVUkksIHN0eWxlLT5kaWN0LCBYU0xUX1BBUlNFX09QVElPTlMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKikgc3R5bGUsIFhTTFRfTE9BRF9TVFlMRVNIRUVUKTsKKyAgICBpZiAoZG9jID09IE5VTEwpCisJcmV0dXJuKE5VTEwpOworCisgICAgcmV0ID0geHNsdE5ld1N0eWxlRG9jdW1lbnQoc3R5bGUsIGRvYyk7CisgICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdEZpbmREb2N1bWVudDoKKyAqIEBjdHh0OiBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBkb2M6IGEgcGFyc2VkIFhNTCBkb2N1bWVudAorICoKKyAqIFRyeSB0byBmaW5kIGEgZG9jdW1lbnQgd2l0aGluIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQuCisgKiBUaGlzIHdpbGwgbm90IGZpbmQgZG9jdW1lbnQgaW5mb3MgZm9yIHRlbXBvcmFyeQorICogUmVzdWx0IFRyZWUgRnJhZ21lbnRzLgorICoKKyAqIFJldHVybnMgdGhlIGRlc2lyZWQgeHNsdERvY3VtZW50UHRyIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgorICovCit4c2x0RG9jdW1lbnRQdHIKK3hzbHRGaW5kRG9jdW1lbnQgKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbERvY1B0ciBkb2MpIHsKKyAgICB4c2x0RG9jdW1lbnRQdHIgcmV0OworCisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChkb2MgPT0gTlVMTCkpCisJcmV0dXJuKE5VTEwpOworCisgICAgLyoKKyAgICAgKiBXYWxrIHRoZSBjb250ZXh0IGxpc3QgdG8gZmluZCB0aGUgZG9jdW1lbnQKKyAgICAgKi8KKyAgICByZXQgPSBjdHh0LT5kb2NMaXN0OworICAgIHdoaWxlIChyZXQgIT0gTlVMTCkgeworCWlmIChyZXQtPmRvYyA9PSBkb2MpCisJICAgIHJldHVybihyZXQpOworCXJldCA9IHJldC0+bmV4dDsKKyAgICB9CisgICAgaWYgKGRvYyA9PSBjdHh0LT5zdHlsZS0+ZG9jKQorCXJldHVybihjdHh0LT5kb2N1bWVudCk7CisgICAgcmV0dXJuKE5VTEwpOworfQorCmRpZmYgLS1naXQgYS9saWJ4c2x0L2RvY3VtZW50cy5oIGIvbGlieHNsdC9kb2N1bWVudHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZWIxZjJhCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9kb2N1bWVudHMuaApAQCAtMCwwICsxLDkzIEBACisvKgorICogU3VtbWFyeTogaW50ZXJmYWNlIGZvciB0aGUgZG9jdW1lbnQgaGFuZGxpbmcKKyAqIERlc2NyaXB0aW9uOiBpbXBsZW1lbnRzIGRvY3VtZW50IGxvYWRpbmcgYW5kIGNhY2hlIChtdWx0aXBsZQorICogICAgICAgICAgICAgIGRvY3VtZW50KCkgcmVmZXJlbmNlIGZvciB0aGUgc2FtZSByZXNvdXJjZXMgbXVzdAorICogICAgICAgICAgICAgIGJlIGVxdWFsLgorICoKKyAqIENvcHk6IFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBBdXRob3I6IERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVF9ET0NVTUVOVFNfSF9fCisjZGVmaW5lIF9fWE1MX1hTTFRfRE9DVU1FTlRTX0hfXworCisjaW5jbHVkZSA8bGlieG1sL3RyZWUuaD4KKyNpbmNsdWRlICJ4c2x0ZXhwb3J0cy5oIgorI2luY2x1ZGUgInhzbHRJbnRlcm5hbHMuaCIKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCitYU0xUUFVCRlVOIHhzbHREb2N1bWVudFB0ciBYU0xUQ0FMTAkKKwkJeHNsdE5ld0RvY3VtZW50CQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIHhtbERvY1B0ciBkb2MpOworWFNMVFBVQkZVTiB4c2x0RG9jdW1lbnRQdHIgWFNMVENBTEwJCisgICAgCQl4c2x0TG9hZERvY3VtZW50CSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJKTsKK1hTTFRQVUJGVU4geHNsdERvY3VtZW50UHRyIFhTTFRDQUxMCQorICAgIAkJeHNsdEZpbmREb2N1bWVudAkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIHhtbERvY1B0ciBkb2MpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkKKyAgICAJCXhzbHRGcmVlRG9jdW1lbnRzCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KTsKKworWFNMVFBVQkZVTiB4c2x0RG9jdW1lbnRQdHIgWFNMVENBTEwJCisgICAgCQl4c2x0TG9hZFN0eWxlRG9jdW1lbnQJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJKTsKK1hTTFRQVUJGVU4geHNsdERvY3VtZW50UHRyIFhTTFRDQUxMCQorICAgIAkJeHNsdE5ld1N0eWxlRG9jdW1lbnQJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgeG1sRG9jUHRyIGRvYyk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQorICAgIAkJeHNsdEZyZWVTdHlsZURvY3VtZW50cwkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUpOworCisvKgorICogSG9va3MgZm9yIGRvY3VtZW50IGxvYWRpbmcKKyAqLworCisvKioKKyAqIHhzbHRMb2FkVHlwZToKKyAqCisgKiBFbnVtIGRlZmluaW5nIHRoZSBraW5kIG9mIGxvYWRlciByZXF1aXJlbWVudC4KKyAqLwordHlwZWRlZiBlbnVtIHsKKyAgICBYU0xUX0xPQURfU1RBUlQgPSAwLAkvKiBsb2FkaW5nIGZvciBhIHRvcCBzdHlsZXNoZWV0ICovCisgICAgWFNMVF9MT0FEX1NUWUxFU0hFRVQgPSAxLAkvKiBsb2FkaW5nIGZvciBhIHN0eWxlc2hlZXQgaW5jbHVkZS9pbXBvcnQgKi8KKyAgICBYU0xUX0xPQURfRE9DVU1FTlQgPSAyCS8qIGxvYWRpbmcgZG9jdW1lbnQgYXQgdHJhbnNmb3JtYXRpb24gdGltZSAqLworfSB4c2x0TG9hZFR5cGU7CisKKy8qKgorICogeHNsdERvY0xvYWRlckZ1bmM6CisgKiBAVVJJOiB0aGUgVVJJIG9mIHRoZSBkb2N1bWVudCB0byBsb2FkCisgKiBAZGljdDogdGhlIGRpY3Rpb25hcnkgdG8gdXNlIHdoZW4gcGFyc2luZyB0aGF0IGRvY3VtZW50CisgKiBAb3B0aW9uczogcGFyc2luZyBvcHRpb25zLCBhIHNldCBvZiB4bWxQYXJzZXJPcHRpb24KKyAqIEBjdHh0OiB0aGUgY29udGV4dCwgZWl0aGVyIGEgc3R5bGVzaGVldCBvciBhIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEB0eXBlOiB0aGUgeHNsdExvYWRUeXBlIGluZGljYXRpbmcgdGhlIGtpbmQgb2YgbG9hZGluZyByZXF1aXJlZAorICoKKyAqIEFuIHhzbHREb2NMb2FkZXJGdW5jIGlzIGEgc2lnbmF0dXJlIGZvciBhIGZ1bmN0aW9uIHdoaWNoIGNhbiBiZQorICogcmVnaXN0ZXJlZCB0byBsb2FkIGRvY3VtZW50IG5vdCBwcm92aWRlZCBieSB0aGUgY29tcGlsYXRpb24gb3IKKyAqIHRyYW5zZm9ybWF0aW9uIEFQSSB0aGVtc2VsdmUsIGZvciBleGFtcGxlIHdoZW4gYW4geHNsOmltcG9ydCwKKyAqIHhzbDppbmNsdWRlIGlzIGZvdW5kIGF0IGNvbXBpbGF0aW9uIHRpbWUgb3Igd2hlbiBhIGRvY3VtZW50KCkKKyAqIGNhbGwgaXMgbWFkZSBhdCBydW50aW1lLgorICoKKyAqIFJldHVybnMgdGhlIHBvaW50ZXIgdG8gdGhlIGRvY3VtZW50ICh3aGljaCB3aWxsIGJlIG1vZGlmaWVkIGFuZAorICogZnJlZWQgYnkgdGhlIGVuZ2luZSBsYXRlciksIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KKyAqLwordHlwZWRlZiB4bWxEb2NQdHIgKCp4c2x0RG9jTG9hZGVyRnVuYykJCShjb25zdCB4bWxDaGFyICpVUkksCisJCQkJCQkgeG1sRGljdFB0ciBkaWN0LAorCQkJCQkJIGludCBvcHRpb25zLAorCQkJCQkJIHZvaWQgKmN0eHQsCisJCQkJCQkgeHNsdExvYWRUeXBlIHR5cGUpOworCitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdFNldExvYWRlckZ1bmMJCSh4c2x0RG9jTG9hZGVyRnVuYyBmKTsKKworLyogdGhlIGxvYWRlciBtYXkgYmUgbmVlZGVkIGJ5IGV4dGVuc2lvbiBsaWJyYXJpZXMgc28gaXQgaXMgZXhwb3J0ZWQgKi8KK1hTTFRQVUJWQVIgeHNsdERvY0xvYWRlckZ1bmMgeHNsdERvY0RlZmF1bHRMb2FkZXI7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX0RPQ1VNRU5UU19IX18gKi8KKwpkaWZmIC0tZ2l0IGEvbGlieHNsdC9leHRlbnNpb25zLmMgYi9saWJ4c2x0L2V4dGVuc2lvbnMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MTg3YjdhCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9leHRlbnNpb25zLmMKQEAgLTAsMCArMSwyMzYxIEBACisvKgorICogZXh0ZW5zaW9ucy5jOiBJbXBsZW1ldGF0aW9uIG9mIHRoZSBleHRlbnNpb25zIHN1cHBvcnQKKyAqCisgKiBSZWZlcmVuY2U6CisgKiAgIGh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhzbHQtMTk5OTExMTYKKyAqCisgKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCisgKgorICogZGFuaWVsQHZlaWxsYXJkLmNvbQorICovCisKKyNkZWZpbmUgSU5fTElCWFNMVAorI2luY2x1ZGUgImxpYnhzbHQuaCIKKworI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPGxpbWl0cy5oPgorCisjaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgorI2luY2x1ZGUgPGxpYnhtbC90cmVlLmg+CisjaW5jbHVkZSA8bGlieG1sL2hhc2guaD4KKyNpbmNsdWRlIDxsaWJ4bWwveG1sZXJyb3IuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvcGFyc2VySW50ZXJuYWxzLmg+CisjaW5jbHVkZSA8bGlieG1sL3hwYXRoSW50ZXJuYWxzLmg+CisjaWZkZWYgV0lUSF9NT0RVTEVTCisjaW5jbHVkZSA8bGlieG1sL3htbG1vZHVsZS5oPgorI2VuZGlmCisjaW5jbHVkZSA8bGlieG1sL2xpc3QuaD4KKyNpbmNsdWRlIDxsaWJ4bWwveG1sSU8uaD4KKyNpbmNsdWRlICJ4c2x0LmgiCisjaW5jbHVkZSAieHNsdEludGVybmFscy5oIgorI2luY2x1ZGUgInhzbHR1dGlscy5oIgorI2luY2x1ZGUgImltcG9ydHMuaCIKKyNpbmNsdWRlICJleHRlbnNpb25zLmgiCisKKyNpZmRlZiBfV0lOMzIKKyNpbmNsdWRlIDxzdGRsaWIuaD4gICAgICAgICAgICAgLyogZm9yIF9NQVhfUEFUSCAqLworI2lmbmRlZiBQQVRIX01BWAorI2RlZmluZSBQQVRIX01BWCBfTUFYX1BBVEgKKyNlbmRpZgorI2VuZGlmCisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKyNkZWZpbmUgV0lUSF9YU0xUX0RFQlVHX0VYVEVOU0lPTlMKKyNlbmRpZgorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAJCQkJCQkJCQkqCisgKiAJCQlQcml2YXRlIFR5cGVzIGFuZCBHbG9iYWxzCQkJKgorICogCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRFeHREZWYgeHNsdEV4dERlZjsKK3R5cGVkZWYgeHNsdEV4dERlZiAqeHNsdEV4dERlZlB0cjsKK3N0cnVjdCBfeHNsdEV4dERlZiB7CisgICAgc3RydWN0IF94c2x0RXh0RGVmICpuZXh0OworICAgIHhtbENoYXIgKnByZWZpeDsKKyAgICB4bWxDaGFyICpVUkk7CisgICAgdm9pZCAqZGF0YTsKK307CisKK3R5cGVkZWYgc3RydWN0IF94c2x0RXh0TW9kdWxlIHhzbHRFeHRNb2R1bGU7Cit0eXBlZGVmIHhzbHRFeHRNb2R1bGUgKnhzbHRFeHRNb2R1bGVQdHI7CitzdHJ1Y3QgX3hzbHRFeHRNb2R1bGUgeworICAgIHhzbHRFeHRJbml0RnVuY3Rpb24gaW5pdEZ1bmM7CisgICAgeHNsdEV4dFNodXRkb3duRnVuY3Rpb24gc2h1dGRvd25GdW5jOworICAgIHhzbHRTdHlsZUV4dEluaXRGdW5jdGlvbiBzdHlsZUluaXRGdW5jOworICAgIHhzbHRTdHlsZUV4dFNodXRkb3duRnVuY3Rpb24gc3R5bGVTaHV0ZG93bkZ1bmM7Cit9OworCit0eXBlZGVmIHN0cnVjdCBfeHNsdEV4dERhdGEgeHNsdEV4dERhdGE7Cit0eXBlZGVmIHhzbHRFeHREYXRhICp4c2x0RXh0RGF0YVB0cjsKK3N0cnVjdCBfeHNsdEV4dERhdGEgeworICAgIHhzbHRFeHRNb2R1bGVQdHIgZXh0TW9kdWxlOworICAgIHZvaWQgKmV4dERhdGE7Cit9OworCit0eXBlZGVmIHN0cnVjdCBfeHNsdEV4dEVsZW1lbnQgeHNsdEV4dEVsZW1lbnQ7Cit0eXBlZGVmIHhzbHRFeHRFbGVtZW50ICp4c2x0RXh0RWxlbWVudFB0cjsKK3N0cnVjdCBfeHNsdEV4dEVsZW1lbnQgeworICAgIHhzbHRQcmVDb21wdXRlRnVuY3Rpb24gcHJlY29tcDsKKyAgICB4c2x0VHJhbnNmb3JtRnVuY3Rpb24gdHJhbnNmb3JtOworfTsKKworc3RhdGljIHhtbEhhc2hUYWJsZVB0ciB4c2x0RXh0ZW5zaW9uc0hhc2ggPSBOVUxMOworc3RhdGljIHhtbEhhc2hUYWJsZVB0ciB4c2x0RnVuY3Rpb25zSGFzaCA9IE5VTEw7CitzdGF0aWMgeG1sSGFzaFRhYmxlUHRyIHhzbHRFbGVtZW50c0hhc2ggPSBOVUxMOworc3RhdGljIHhtbEhhc2hUYWJsZVB0ciB4c2x0VG9wTGV2ZWxzSGFzaCA9IE5VTEw7CitzdGF0aWMgeG1sSGFzaFRhYmxlUHRyIHhzbHRNb2R1bGVIYXNoID0gTlVMTDsKK3N0YXRpYyB4bWxNdXRleFB0ciB4c2x0RXh0TXV0ZXggPSBOVUxMOworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAJCQkJCQkJCQkqCisgKiAJCQlUeXBlIGZ1bmN0aW9ucyAJCQkJCSoKKyAqIAkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdE5ld0V4dERlZjoKKyAqIEBwcmVmaXg6ICB0aGUgZXh0ZW5zaW9uIHByZWZpeAorICogQFVSSTogIHRoZSBuYW1lc3BhY2UgVVJJCisgKgorICogQ3JlYXRlIGEgbmV3IFhTTFQgRXh0RGVmCisgKgorICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHhzbHRFeHREZWZQdHIgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3N0YXRpYyB4c2x0RXh0RGVmUHRyCit4c2x0TmV3RXh0RGVmKGNvbnN0IHhtbENoYXIgKiBwcmVmaXgsIGNvbnN0IHhtbENoYXIgKiBVUkkpCit7CisgICAgeHNsdEV4dERlZlB0ciBjdXI7CisKKyAgICBjdXIgPSAoeHNsdEV4dERlZlB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0RXh0RGVmKSk7CisgICAgaWYgKGN1ciA9PSBOVUxMKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHROZXdFeHREZWYgOiBtYWxsb2MgZmFpbGVkXG4iKTsKKyAgICAgICAgcmV0dXJuIChOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KGN1ciwgMCwgc2l6ZW9mKHhzbHRFeHREZWYpKTsKKyAgICBpZiAocHJlZml4ICE9IE5VTEwpCisgICAgICAgIGN1ci0+cHJlZml4ID0geG1sU3RyZHVwKHByZWZpeCk7CisgICAgaWYgKFVSSSAhPSBOVUxMKQorICAgICAgICBjdXItPlVSSSA9IHhtbFN0cmR1cChVUkkpOworICAgIHJldHVybiAoY3VyKTsKK30KKworLyoqCisgKiB4c2x0RnJlZUV4dERlZjoKKyAqIEBleHRlbnNpb25kOiAgYW4gWFNMVCBleHRlbnNpb24gZGVmaW5pdGlvbgorICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgYnkgQGV4dGVuc2lvbmQKKyAqLworc3RhdGljIHZvaWQKK3hzbHRGcmVlRXh0RGVmKHhzbHRFeHREZWZQdHIgZXh0ZW5zaW9uZCkKK3sKKyAgICBpZiAoZXh0ZW5zaW9uZCA9PSBOVUxMKQorICAgICAgICByZXR1cm47CisgICAgaWYgKGV4dGVuc2lvbmQtPnByZWZpeCAhPSBOVUxMKQorICAgICAgICB4bWxGcmVlKGV4dGVuc2lvbmQtPnByZWZpeCk7CisgICAgaWYgKGV4dGVuc2lvbmQtPlVSSSAhPSBOVUxMKQorICAgICAgICB4bWxGcmVlKGV4dGVuc2lvbmQtPlVSSSk7CisgICAgeG1sRnJlZShleHRlbnNpb25kKTsKK30KKworLyoqCisgKiB4c2x0RnJlZUV4dERlZkxpc3Q6CisgKiBAZXh0ZW5zaW9uZDogIGFuIFhTTFQgZXh0ZW5zaW9uIGRlZmluaXRpb24gbGlzdAorICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgYnkgYWxsIHRoZSBlbGVtZW50cyBvZiBAZXh0ZW5zaW9uZAorICovCitzdGF0aWMgdm9pZAoreHNsdEZyZWVFeHREZWZMaXN0KHhzbHRFeHREZWZQdHIgZXh0ZW5zaW9uZCkKK3sKKyAgICB4c2x0RXh0RGVmUHRyIGN1cjsKKworICAgIHdoaWxlIChleHRlbnNpb25kICE9IE5VTEwpIHsKKyAgICAgICAgY3VyID0gZXh0ZW5zaW9uZDsKKyAgICAgICAgZXh0ZW5zaW9uZCA9IGV4dGVuc2lvbmQtPm5leHQ7CisgICAgICAgIHhzbHRGcmVlRXh0RGVmKGN1cik7CisgICAgfQorfQorCisvKioKKyAqIHhzbHROZXdFeHRNb2R1bGU6CisgKiBAaW5pdEZ1bmM6ICB0aGUgbW9kdWxlIGluaXRpYWxpemF0aW9uIGZ1bmN0aW9uCisgKiBAc2h1dGRvd25GdW5jOiAgdGhlIG1vZHVsZSBzaHV0ZG93biBmdW5jdGlvbgorICogQHN0eWxlSW5pdEZ1bmM6ICB0aGUgc3R5bGVzaGVldCBtb2R1bGUgZGF0YSBhbGxvY2F0b3IgZnVuY3Rpb24KKyAqIEBzdHlsZVNodXRkb3duRnVuYzogIHRoZSBzdHlsZXNoZWV0IG1vZHVsZSBkYXRhIGZyZWUgZnVuY3Rpb24KKyAqCisgKiBDcmVhdGUgYSBuZXcgWFNMVCBleHRlbnNpb24gbW9kdWxlCisgKgorICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHhzbHRFeHRNb2R1bGVQdHIgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3N0YXRpYyB4c2x0RXh0TW9kdWxlUHRyCit4c2x0TmV3RXh0TW9kdWxlKHhzbHRFeHRJbml0RnVuY3Rpb24gaW5pdEZ1bmMsCisgICAgICAgICAgICAgICAgIHhzbHRFeHRTaHV0ZG93bkZ1bmN0aW9uIHNodXRkb3duRnVuYywKKyAgICAgICAgICAgICAgICAgeHNsdFN0eWxlRXh0SW5pdEZ1bmN0aW9uIHN0eWxlSW5pdEZ1bmMsCisgICAgICAgICAgICAgICAgIHhzbHRTdHlsZUV4dFNodXRkb3duRnVuY3Rpb24gc3R5bGVTaHV0ZG93bkZ1bmMpCit7CisgICAgeHNsdEV4dE1vZHVsZVB0ciBjdXI7CisKKyAgICBjdXIgPSAoeHNsdEV4dE1vZHVsZVB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0RXh0TW9kdWxlKSk7CisgICAgaWYgKGN1ciA9PSBOVUxMKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHROZXdFeHRNb2R1bGUgOiBtYWxsb2MgZmFpbGVkXG4iKTsKKyAgICAgICAgcmV0dXJuIChOVUxMKTsKKyAgICB9CisgICAgY3VyLT5pbml0RnVuYyA9IGluaXRGdW5jOworICAgIGN1ci0+c2h1dGRvd25GdW5jID0gc2h1dGRvd25GdW5jOworICAgIGN1ci0+c3R5bGVJbml0RnVuYyA9IHN0eWxlSW5pdEZ1bmM7CisgICAgY3VyLT5zdHlsZVNodXRkb3duRnVuYyA9IHN0eWxlU2h1dGRvd25GdW5jOworICAgIHJldHVybiAoY3VyKTsKK30KKworLyoqCisgKiB4c2x0RnJlZUV4dE1vZHVsZToKKyAqIEBleHQ6ICBhbiBYU0xUIGV4dGVuc2lvbiBtb2R1bGUKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGJ5IEBleHQKKyAqLworc3RhdGljIHZvaWQKK3hzbHRGcmVlRXh0TW9kdWxlKHhzbHRFeHRNb2R1bGVQdHIgZXh0KQoreworICAgIGlmIChleHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworICAgIHhtbEZyZWUoZXh0KTsKK30KKworLyoqCisgKiB4c2x0TmV3RXh0RGF0YToKKyAqIEBleHRNb2R1bGU6ICB0aGUgbW9kdWxlCisgKiBAZXh0RGF0YTogIHRoZSBhc3NvY2lhdGVkIGRhdGEKKyAqCisgKiBDcmVhdGUgYSBuZXcgWFNMVCBleHRlbnNpb24gbW9kdWxlIGRhdGEgd3JhcHBlcgorICoKKyAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCB4c2x0RXh0RGF0YVB0ciBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworc3RhdGljIHhzbHRFeHREYXRhUHRyCit4c2x0TmV3RXh0RGF0YSh4c2x0RXh0TW9kdWxlUHRyIGV4dE1vZHVsZSwgdm9pZCAqZXh0RGF0YSkKK3sKKyAgICB4c2x0RXh0RGF0YVB0ciBjdXI7CisKKyAgICBpZiAoZXh0TW9kdWxlID09IE5VTEwpCisgICAgICAgIHJldHVybiAoTlVMTCk7CisgICAgY3VyID0gKHhzbHRFeHREYXRhUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhzbHRFeHREYXRhKSk7CisgICAgaWYgKGN1ciA9PSBOVUxMKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHROZXdFeHREYXRhIDogbWFsbG9jIGZhaWxlZFxuIik7CisgICAgICAgIHJldHVybiAoTlVMTCk7CisgICAgfQorICAgIGN1ci0+ZXh0TW9kdWxlID0gZXh0TW9kdWxlOworICAgIGN1ci0+ZXh0RGF0YSA9IGV4dERhdGE7CisgICAgcmV0dXJuIChjdXIpOworfQorCisvKioKKyAqIHhzbHRGcmVlRXh0RGF0YToKKyAqIEBleHQ6ICBhbiBYU0xUIGV4dGVuc2lvbiBtb2R1bGUgZGF0YSB3cmFwcGVyCisgKgorICogRnJlZSB1cCB0aGUgbWVtb3J5IGFsbG9jYXRlZCBieSBAZXh0CisgKi8KK3N0YXRpYyB2b2lkCit4c2x0RnJlZUV4dERhdGEoeHNsdEV4dERhdGFQdHIgZXh0KQoreworICAgIGlmIChleHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworICAgIHhtbEZyZWUoZXh0KTsKK30KKworLyoqCisgKiB4c2x0TmV3RXh0RWxlbWVudDoKKyAqIEBwcmVjb21wOiAgdGhlIHByZS1jb21wdXRhdGlvbiBmdW5jdGlvbgorICogQHRyYW5zZm9ybTogIHRoZSB0cmFuc2Zvcm1hdGlvbiBmdW5jdGlvbgorICoKKyAqIENyZWF0ZSBhIG5ldyBYU0xUIGV4dGVuc2lvbiBlbGVtZW50CisgKgorICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHhzbHRFeHRFbGVtZW50UHRyIG9yIE5VTEwgaW4gY2FzZSBvZgorICogZXJyb3IKKyAqLworc3RhdGljIHhzbHRFeHRFbGVtZW50UHRyCit4c2x0TmV3RXh0RWxlbWVudCh4c2x0UHJlQ29tcHV0ZUZ1bmN0aW9uIHByZWNvbXAsCisgICAgICAgICAgICAgICAgICB4c2x0VHJhbnNmb3JtRnVuY3Rpb24gdHJhbnNmb3JtKQoreworICAgIHhzbHRFeHRFbGVtZW50UHRyIGN1cjsKKworICAgIGlmICh0cmFuc2Zvcm0gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIChOVUxMKTsKKworICAgIGN1ciA9ICh4c2x0RXh0RWxlbWVudFB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0RXh0RWxlbWVudCkpOworICAgIGlmIChjdXIgPT0gTlVMTCkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0TmV3RXh0RWxlbWVudCA6IG1hbGxvYyBmYWlsZWRcbiIpOworICAgICAgICByZXR1cm4gKE5VTEwpOworICAgIH0KKyAgICBjdXItPnByZWNvbXAgPSBwcmVjb21wOworICAgIGN1ci0+dHJhbnNmb3JtID0gdHJhbnNmb3JtOworICAgIHJldHVybiAoY3VyKTsKK30KKworLyoqCisgKiB4c2x0RnJlZUV4dEVsZW1lbnQ6CisgKiBAZXh0OiBhbiBYU0xUIGV4dGVuc2lvbiBlbGVtZW50CisgKgorICogRnJlZXMgdXAgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgYnkgQGV4dAorICovCitzdGF0aWMgdm9pZAoreHNsdEZyZWVFeHRFbGVtZW50KHhzbHRFeHRFbGVtZW50UHRyIGV4dCkKK3sKKyAgICBpZiAoZXh0ID09IE5VTEwpCisgICAgICAgIHJldHVybjsKKyAgICB4bWxGcmVlKGV4dCk7Cit9CisKKworI2lmZGVmIFdJVEhfTU9EVUxFUwordHlwZWRlZiB2b2lkICgqZXhzbHRSZWdpc3RlckZ1bmN0aW9uKSAodm9pZCk7CisKKyNpZm5kZWYgUEFUSF9NQVgKKyNkZWZpbmUgUEFUSF9NQVggNDA5NgorI2VuZGlmCisKKy8qKgorICogeHNsdEV4dE1vZHVsZVJlZ2lzdGVyRHluYW1pYzoKKyAqIEBVUkk6ICB0aGUgZnVuY3Rpb24gb3IgZWxlbWVudCBuYW1lc3BhY2UgVVJJCisgKgorICogRHluYW1pY2FsbHkgbG9hZHMgYW4gZXh0ZW5zaW9uIHBsdWdpbiB3aGVuIGF2YWlsYWJsZS4KKyAqIAorICogVGhlIHBsdWdpbiBuYW1lIGlzIGRlcml2ZWQgZnJvbSB0aGUgVVJJIGJ5IHJlbW92aW5nIHRoZSAKKyAqIGluaXRpYWwgcHJvdG9jb2wgZGVzaWduYXRpb24sIGUuZy4gImh0dHA6Ly8iLCB0aGVuIGNvbnZlcnRpbmcKKyAqIHRoZSBjaGFyYWN0ZXJzICIuIiwgIi0iLCAiLyIsIGFuZCAiXCIgaW50byAiXyIsIHRoZSByZW1vdmluZworICogYW55IHRyYWlsaW5nICIvIiwgdGhlbiBjb25jYXRlbmF0aW5nIExJQlhNTF9NT0RVTEVfRVhURU5TSU9OLgorICogCisgKiBQbHVnaW5zIGFyZSBsb2FkZWQgZnJvbSB0aGUgZGlyZWN0b3J5IHNwZWNpZmllZCBieSB0aGUgCisgKiBlbnZpcm9ubWVudCB2YXJpYWJsZSBMSUJYU0xUX1BMVUdJTlNfUEFUSCwgb3IgaWYgTlVMTCwgCisgKiBieSBMSUJYU0xUX0RFRkFVTFRfUExVR0lOU19QQVRIKCkgd2hpY2ggaXMgZGV0ZXJtaW5lZCBhdAorICogY29tcGlsZSB0aW1lLgorICoKKyAqIFJldHVybnMgMCBpZiBzdWNjZXNzZnVsLCAtMSBpbiBjYXNlIG9mIGVycm9yLiAKKyAqLworCitzdGF0aWMgaW50Cit4c2x0RXh0TW9kdWxlUmVnaXN0ZXJEeW5hbWljKGNvbnN0IHhtbENoYXIgKiBVUkkpCit7CisKKyAgICB4bWxNb2R1bGVQdHIgbTsKKyAgICBleHNsdFJlZ2lzdGVyRnVuY3Rpb24gcmVnZnVuYzsKKyAgICB4bWxDaGFyICpleHRfbmFtZTsKKyAgICBjaGFyIG1vZHVsZV9maWxlbmFtZVtQQVRIX01BWF07CisgICAgY29uc3QgeG1sQ2hhciAqZXh0X2RpcmVjdG9yeSA9IE5VTEw7CisgICAgY29uc3QgeG1sQ2hhciAqcHJvdG9jb2wgPSBOVUxMOworICAgIHhtbENoYXIgKmksICpyZWdmdW5jX25hbWU7CisgICAgdm9pZCAqdnJlZ2Z1bmM7CisgICAgaW50IHJjOworCisgICAgLyogY2hlY2sgZm9yIGJhZCBpbnB1dHMgKi8KKyAgICBpZiAoVVJJID09IE5VTEwpCisgICAgICAgIHJldHVybiAoLTEpOworCisgICAgaWYgKE5VTEwgPT0geHNsdE1vZHVsZUhhc2gpIHsKKyAgICAgICAgeHNsdE1vZHVsZUhhc2ggPSB4bWxIYXNoQ3JlYXRlKDUpOworICAgICAgICBpZiAoeHNsdE1vZHVsZUhhc2ggPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAoLTEpOworICAgIH0KKworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgLyogaGF2ZSB3ZSBhdHRlbXB0ZWQgdG8gcmVnaXN0ZXIgdGhpcyBtb2R1bGUgYWxyZWFkeT8gKi8KKyAgICBpZiAoeG1sSGFzaExvb2t1cCh4c2x0TW9kdWxlSGFzaCwgVVJJKSAhPSBOVUxMKSB7CisgICAgICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisgICAgICAgIHJldHVybiAoLTEpOworICAgIH0KKyAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgLyogdHJhbnNmb3JtIGV4dGVuc2lvbiBuYW1lc3BhY2UgaW50byBhIG1vZHVsZSBuYW1lICovCisgICAgcHJvdG9jb2wgPSB4bWxTdHJzdHIoVVJJLCBCQURfQ0FTVCAiOi8vIik7CisgICAgaWYgKHByb3RvY29sID09IE5VTEwpIHsKKyAgICAgICAgZXh0X25hbWUgPSB4bWxTdHJkdXAoVVJJKTsKKyAgICB9IGVsc2UgeworICAgICAgICBleHRfbmFtZSA9IHhtbFN0cmR1cChwcm90b2NvbCArIDMpOworICAgIH0KKyAgICBpZiAoZXh0X25hbWUgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gKC0xKTsKKyAgICB9CisKKyAgICBpID0gZXh0X25hbWU7CisgICAgd2hpbGUgKCdcMCcgIT0gKmkpIHsKKyAgICAgICAgaWYgKCgnLycgPT0gKmkpIHx8ICgnXFwnID09ICppKSB8fCAoJy4nID09ICppKSB8fCAoJy0nID09ICppKSkKKyAgICAgICAgICAgICppID0gJ18nOworICAgICAgICBpKys7CisgICAgfQorCisgICAgaWYgKCooaSAtIDEpID09ICdfJykKKyAgICAgICAgKmkgPSAnXDAnOworCisgICAgLyogZGV0ZXJtaW5lIG1vZHVsZSBkaXJlY3RvcnkgKi8KKyAgICBleHRfZGlyZWN0b3J5ID0gKHhtbENoYXIgKikgZ2V0ZW52KCJMSUJYU0xUX1BMVUdJTlNfUEFUSCIpOworCisgICAgaWYgKE5VTEwgPT0gZXh0X2RpcmVjdG9yeSkgeworICAgICAgICBleHRfZGlyZWN0b3J5ID0gQkFEX0NBU1QgTElCWFNMVF9ERUZBVUxUX1BMVUdJTlNfUEFUSCgpOworCWlmIChOVUxMID09IGV4dF9kaXJlY3RvcnkpCisJICByZXR1cm4gKC0xKTsKKyAgICB9CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0VYVEVOU0lPTlMKKyAgICBlbHNlCisgICAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgICAgIkxJQlhTTFRfUExVR0lOU19QQVRIIGlzICVzXG4iLCBleHRfZGlyZWN0b3J5KTsKKyNlbmRpZgorCisgICAgLyogYnVpbGQgdGhlIG1vZHVsZSBmaWxlbmFtZSwgYW5kIGNvbmZpcm0gdGhlIG1vZHVsZSBleGlzdHMgKi8KKyAgICB4bWxTdHJQcmludGYoKHhtbENoYXIgKikgbW9kdWxlX2ZpbGVuYW1lLCBzaXplb2YobW9kdWxlX2ZpbGVuYW1lKSwKKyAgICAgICAgICAgICAgICAgQkFEX0NBU1QgIiVzLyVzJXMiLAorICAgICAgICAgICAgICAgICBleHRfZGlyZWN0b3J5LCBleHRfbmFtZSwgTElCWE1MX01PRFVMRV9FWFRFTlNJT04pOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0VYVEVOU0lPTlMKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgIkF0dGVtcHRpbmcgdG8gbG9hZCBwbHVnaW46ICVzIGZvciBVUkk6ICVzXG4iLCAKKyAgICAgICAgICAgICAgICAgICAgIG1vZHVsZV9maWxlbmFtZSwgVVJJKTsKKyNlbmRpZgorCisgICAgaWYgKDEgIT0geG1sQ2hlY2tGaWxlbmFtZShtb2R1bGVfZmlsZW5hbWUpKSB7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRVhURU5TSU9OUworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAieG1sQ2hlY2tGaWxlbmFtZSBmYWlsZWQgZm9yIHBsdWdpbjogJXNcbiIsIG1vZHVsZV9maWxlbmFtZSk7CisjZW5kaWYKKworICAgICAgICB4bWxGcmVlKGV4dF9uYW1lKTsKKyAgICAgICAgcmV0dXJuICgtMSk7CisgICAgfQorCisgICAgLyogYXR0ZW1wdCB0byBvcGVuIHRoZSBtb2R1bGUgKi8KKyAgICBtID0geG1sTW9kdWxlT3Blbihtb2R1bGVfZmlsZW5hbWUsIDApOworICAgIGlmIChOVUxMID09IG0pIHsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRFTlNJT05TCisJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICJ4bWxNb2R1bGVPcGVuIGZhaWxlZCBmb3IgcGx1Z2luOiAlc1xuIiwgbW9kdWxlX2ZpbGVuYW1lKTsKKyNlbmRpZgorCisgICAgICAgIHhtbEZyZWUoZXh0X25hbWUpOworICAgICAgICByZXR1cm4gKC0xKTsKKyAgICB9CisKKyAgICAvKiBjb25zdHJ1Y3QgaW5pdGlhbGl6YXRpb24gZnVuYyBuYW1lICovCisgICAgcmVnZnVuY19uYW1lID0geG1sU3RyZHVwKGV4dF9uYW1lKTsKKyAgICByZWdmdW5jX25hbWUgPSB4bWxTdHJjYXQocmVnZnVuY19uYW1lLCBCQURfQ0FTVCAiX2luaXQiKTsKKworICAgIHZyZWdmdW5jID0gTlVMTDsKKyAgICByYyA9IHhtbE1vZHVsZVN5bWJvbChtLCAoY29uc3QgY2hhciAqKSByZWdmdW5jX25hbWUsICZ2cmVnZnVuYyk7CisgICAgcmVnZnVuYyA9IHZyZWdmdW5jOworICAgIGlmICgwID09IHJjKSB7CisgICAgICAgIC8qCisJICogQ2FsbCB0aGUgbW9kdWxlJ3MgaW5pdCBmdW5jdGlvbi4gIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uCisJICogY2FsbHMgeHNsdFJlZ2lzdGVyRXh0TW9kdWxlRnVsbCB3aGljaCB3aWxsIGFkZCB0aGUgbW9kdWxlCisJICogdG8geHNsdEV4dGVuc2lvbnNIYXNoICh0b2dldGhlciB3aXRoIGl0J3MgZW50cnkgcG9pbnRzKS4KKwkgKi8KKyAgICAgICAgKCpyZWdmdW5jKSAoKTsKKworICAgICAgICAvKiByZWdpc3RlciB0aGlzIG1vZHVsZSBpbiBvdXIgaGFzaCAqLworICAgICAgICB4bWxNdXRleExvY2soeHNsdEV4dE11dGV4KTsKKyAgICAgICAgeG1sSGFzaEFkZEVudHJ5KHhzbHRNb2R1bGVIYXNoLCBVUkksICh2b2lkICopIG0pOworICAgICAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworICAgIH0gZWxzZSB7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRVhURU5TSU9OUworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAieG1sTW9kdWxlU3ltYm9sIGZhaWxlZCBmb3IgcGx1Z2luOiAlcywgcmVnZnVuYzogJXNcbiIsIAorICAgICAgICAgICAgICAgICAgICAgbW9kdWxlX2ZpbGVuYW1lLCByZWdmdW5jX25hbWUpOworI2VuZGlmCisKKyAgICAgICAgLyogaWYgcmVnZnVuYyBub3QgZm91bmQgdW5sb2FkIHRoZSBtb2R1bGUgaW1tZWRpYXRlbHkgKi8KKyAgICAgICAgeG1sTW9kdWxlQ2xvc2UobSk7CisgICAgfQorCisgICAgeG1sRnJlZShleHRfbmFtZSk7CisgICAgeG1sRnJlZShyZWdmdW5jX25hbWUpOworICAgIHJldHVybiAoTlVMTCA9PSByZWdmdW5jKSA/IC0xIDogMDsKK30KKyNlbHNlCitzdGF0aWMgaW50Cit4c2x0RXh0TW9kdWxlUmVnaXN0ZXJEeW5hbWljKGNvbnN0IHhtbENoYXIgKiBVUkkgQVRUUklCVVRFX1VOVVNFRCkKK3sKKyAgcmV0dXJuIC0xOworfQorI2VuZGlmCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJVGhlIHN0eWxlc2hlZXQgZXh0ZW5zaW9uIHByZWZpeGVzIGhhbmRsaW5nCQkqCisgKiAJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisKKy8qKgorICogeHNsdEZyZWVFeHRzOgorICogQHN0eWxlOiBhbiBYU0xUIHN0eWxlc2hlZXQKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgdXNlZCBieSBYU0xUIGV4dGVuc2lvbnMgaW4gYSBzdHlsZXNoZWV0CisgKi8KK3ZvaWQKK3hzbHRGcmVlRXh0cyh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkKK3sKKyAgICBpZiAoc3R5bGUtPm5zRGVmcyAhPSBOVUxMKQorICAgICAgICB4c2x0RnJlZUV4dERlZkxpc3QoKHhzbHRFeHREZWZQdHIpIHN0eWxlLT5uc0RlZnMpOworfQorCisvKioKKyAqIHhzbHRSZWdpc3RlckV4dFByZWZpeDoKKyAqIEBzdHlsZTogYW4gWFNMVCBzdHlsZXNoZWV0CisgKiBAcHJlZml4OiB0aGUgcHJlZml4IHVzZWQgKG9wdGlvbmFsKQorICogQFVSSTogdGhlIFVSSSBhc3NvY2lhdGVkIHRvIHRoZSBleHRlbnNpb24KKyAqIAorICogUmVnaXN0ZXJzIGFuIGV4dGVuc2lvbiBuYW1lc3BhY2UKKyAqIFRoaXMgaXMgY2FsbGVkIGZyb20geHNsdC5jIGR1cmluZyBjb21waWxlLXRpbWUuCisgKiBUaGUgZ2l2ZW4gcHJlZml4IGlzIG5vdCBuZWVkZWQuCisgKiBDYWxsZWQgYnk6CisgKiAgIHhzbHRQYXJzZUV4dEVsZW1QcmVmaXhlcygpIChuZXcgZnVuY3Rpb24pCisgKiAgIHhzbHRSZWdpc3RlckV4dFByZWZpeCgpIChvbGQgZnVuY3Rpb24pCisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgMSBpZiB0aGUgQFVSSSB3YXMgYWxyZWFkeQorICogICAgICAgICByZWdpc3RlcmVkIGFzIGFuIGV4dGVuc2lvbiBuYW1lc3BhY2UgYW5kCisgKiAgICAgICAgIC0xIGluIGNhc2Ugb2YgZmFpbHVyZQorICovCitpbnQKK3hzbHRSZWdpc3RlckV4dFByZWZpeCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogcHJlZml4LCBjb25zdCB4bWxDaGFyICogVVJJKQoreworICAgIHhzbHRFeHREZWZQdHIgZGVmLCByZXQ7CisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkpCisgICAgICAgIHJldHVybiAoLTEpOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0VYVEVOU0lPTlMKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJSZWdpc3RlcmluZyBleHRlbnNpb24gbmFtZXNwYWNlICclcycuXG4iLCBVUkkpOworI2VuZGlmCisgICAgZGVmID0gKHhzbHRFeHREZWZQdHIpIHN0eWxlLT5uc0RlZnM7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgLyoKKyAgICAqIFRoZSBleHRlbnNpb24gaXMgYXNzb2NpYXRlZCB3aXRoIGEgbmFtZXNwYWNlIG5hbWUuCisgICAgKi8KKyAgICB3aGlsZSAoZGVmICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKHhtbFN0ckVxdWFsKFVSSSwgZGVmLT5VUkkpKQorICAgICAgICAgICAgcmV0dXJuICgxKTsKKyAgICAgICAgZGVmID0gZGVmLT5uZXh0OworICAgIH0KKyNlbHNlCisgICAgd2hpbGUgKGRlZiAhPSBOVUxMKSB7CisgICAgICAgIGlmICh4bWxTdHJFcXVhbChwcmVmaXgsIGRlZi0+cHJlZml4KSkKKyAgICAgICAgICAgIHJldHVybiAoLTEpOworICAgICAgICBkZWYgPSBkZWYtPm5leHQ7CisgICAgfQorI2VuZGlmCisgICAgcmV0ID0geHNsdE5ld0V4dERlZihwcmVmaXgsIFVSSSk7CisgICAgaWYgKHJldCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKC0xKTsKKyAgICByZXQtPm5leHQgPSAoeHNsdEV4dERlZlB0cikgc3R5bGUtPm5zRGVmczsKKyAgICBzdHlsZS0+bnNEZWZzID0gcmV0OworCisgICAgLyoKKyAgICAgKiBjaGVjayB3aGV0aGVyIHRoZXJlIGlzIGFuIGV4dGVuc2lvbiBtb2R1bGUgd2l0aCBhIHN0eWxlc2hlZXQKKyAgICAgKiBpbml0aWFsaXphdGlvbiBmdW5jdGlvbi4KKyAgICAgKi8KKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICAvKgorICAgICogRG9uJ3QgaW5pdGlhbGl6ZSBtb2R1bGVzIGJhc2VkIG9uIHNwZWNpZmllZCBuYW1lc3BhY2VzIHZpYQorICAgICogdGhlIGF0dHJpYnV0ZSAiW3hzbDpdZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiLgorICAgICovCisjZWxzZQorICAgIGlmICh4c2x0RXh0ZW5zaW9uc0hhc2ggIT0gTlVMTCkgeworICAgICAgICB4c2x0RXh0TW9kdWxlUHRyIG1vZHVsZTsKKworICAgICAgICB4bWxNdXRleExvY2soeHNsdEV4dE11dGV4KTsKKyAgICAgICAgbW9kdWxlID0geG1sSGFzaExvb2t1cCh4c2x0RXh0ZW5zaW9uc0hhc2gsIFVSSSk7CisgICAgICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisgICAgICAgIGlmIChOVUxMID09IG1vZHVsZSkgeworICAgICAgICAgICAgaWYgKCF4c2x0RXh0TW9kdWxlUmVnaXN0ZXJEeW5hbWljKFVSSSkpIHsKKyAgICAgICAgICAgICAgICB4bWxNdXRleExvY2soeHNsdEV4dE11dGV4KTsKKyAgICAgICAgICAgICAgICBtb2R1bGUgPSB4bWxIYXNoTG9va3VwKHhzbHRFeHRlbnNpb25zSGFzaCwgVVJJKTsKKyAgICAgICAgICAgICAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChtb2R1bGUgIT0gTlVMTCkgeworICAgICAgICAgICAgeHNsdFN0eWxlR2V0RXh0RGF0YShzdHlsZSwgVVJJKTsKKyAgICAgICAgfQorICAgIH0KKyNlbmRpZgorICAgIHJldHVybiAoMCk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJVGhlIGV4dGVuc2lvbnMgbW9kdWxlcyBpbnRlcmZhY2VzCQkJKgorICogCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0UmVnaXN0ZXJFeHRGdW5jdGlvbjoKKyAqIEBjdHh0OiBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBuYW1lOiB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudAorICogQFVSSTogdGhlIFVSSSBhc3NvY2lhdGVkIHRvIHRoZSBlbGVtZW50CisgKiBAZnVuY3Rpb246IHRoZSBhY3R1YWwgaW1wbGVtZW50YXRpb24gd2hpY2ggc2hvdWxkIGJlIGNhbGxlZCAKKyAqCisgKiBSZWdpc3RlcnMgYW4gZXh0ZW5zaW9uIGZ1bmN0aW9uCisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgLTEgaW4gY2FzZSBvZiBmYWlsdXJlCisgKi8KK2ludAoreHNsdFJlZ2lzdGVyRXh0RnVuY3Rpb24oeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogVVJJLCB4bWxYUGF0aEZ1bmN0aW9uIGZ1bmN0aW9uKQoreworICAgIGludCByZXQ7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkgfHwKKyAgICAgICAgKFVSSSA9PSBOVUxMKSB8fCAoZnVuY3Rpb24gPT0gTlVMTCkpCisgICAgICAgIHJldHVybiAoLTEpOworICAgIGlmIChjdHh0LT54cGF0aEN0eHQgIT0gTlVMTCkgeworICAgICAgICB4bWxYUGF0aFJlZ2lzdGVyRnVuY05TKGN0eHQtPnhwYXRoQ3R4dCwgbmFtZSwgVVJJLCBmdW5jdGlvbik7CisgICAgfQorICAgIGlmIChjdHh0LT5leHRGdW5jdGlvbnMgPT0gTlVMTCkKKyAgICAgICAgY3R4dC0+ZXh0RnVuY3Rpb25zID0geG1sSGFzaENyZWF0ZSgxMCk7CisgICAgaWYgKGN0eHQtPmV4dEZ1bmN0aW9ucyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKC0xKTsKKworICAgIHJldCA9IHhtbEhhc2hBZGRFbnRyeTIoY3R4dC0+ZXh0RnVuY3Rpb25zLCBuYW1lLCBVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfQ0FTVF9GUFRSKGZ1bmN0aW9uKSk7CisKKyAgICByZXR1cm4ocmV0KTsKK30KKworLyoqCisgKiB4c2x0UmVnaXN0ZXJFeHRFbGVtZW50OgorICogQGN0eHQ6IGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQG5hbWU6IHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50CisgKiBAVVJJOiB0aGUgVVJJIGFzc29jaWF0ZWQgdG8gdGhlIGVsZW1lbnQKKyAqIEBmdW5jdGlvbjogdGhlIGFjdHVhbCBpbXBsZW1lbnRhdGlvbiB3aGljaCBzaG91bGQgYmUgY2FsbGVkIAorICoKKyAqIFJlZ2lzdGVycyBhbiBleHRlbnNpb24gZWxlbWVudAorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgZmFpbHVyZQorICovCitpbnQKK3hzbHRSZWdpc3RlckV4dEVsZW1lbnQoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBVUkksIHhzbHRUcmFuc2Zvcm1GdW5jdGlvbiBmdW5jdGlvbikKK3sKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkgfHwKKyAgICAgICAgKFVSSSA9PSBOVUxMKSB8fCAoZnVuY3Rpb24gPT0gTlVMTCkpCisgICAgICAgIHJldHVybiAoLTEpOworICAgIGlmIChjdHh0LT5leHRFbGVtZW50cyA9PSBOVUxMKQorICAgICAgICBjdHh0LT5leHRFbGVtZW50cyA9IHhtbEhhc2hDcmVhdGUoMTApOworICAgIGlmIChjdHh0LT5leHRFbGVtZW50cyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKC0xKTsKKyAgICByZXR1cm4gKHhtbEhhc2hBZGRFbnRyeTIKKyAgICAgICAgICAgIChjdHh0LT5leHRFbGVtZW50cywgbmFtZSwgVVJJLCBYTUxfQ0FTVF9GUFRSKGZ1bmN0aW9uKSkpOworfQorCisvKioKKyAqIHhzbHRGcmVlQ3R4dEV4dHM6CisgKiBAY3R4dDogYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogRnJlZSB0aGUgWFNMVCBleHRlbnNpb24gZGF0YQorICovCit2b2lkCit4c2x0RnJlZUN0eHRFeHRzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpCit7CisgICAgaWYgKGN0eHQtPmV4dEVsZW1lbnRzICE9IE5VTEwpCisgICAgICAgIHhtbEhhc2hGcmVlKGN0eHQtPmV4dEVsZW1lbnRzLCBOVUxMKTsKKyAgICBpZiAoY3R4dC0+ZXh0RnVuY3Rpb25zICE9IE5VTEwpCisgICAgICAgIHhtbEhhc2hGcmVlKGN0eHQtPmV4dEZ1bmN0aW9ucywgTlVMTCk7Cit9CisKKy8qKgorICogeHNsdFN0eWxlR2V0U3R5bGVzaGVldEV4dERhdGE6CisgKiBAc3R5bGU6IGFuIFhTTFQgc3R5bGVzaGVldAorICogQFVSSTogIHRoZSBVUkkgYXNzb2NpYXRlZCB0byB0aGUgZXhlbnNpb24gbW9kdWxlCisgKgorICogRmlyZXMgdGhlIGNvbXBpbGUtdGltZSBpbml0aWFsaXphdGlvbiBjYWxsYmFjaworICogb2YgYW4gZXh0ZW5zaW9uIG1vZHVsZSBhbmQgcmV0dXJucyBhIGNvbnRhaW5lcgorICogaG9sZGluZyB0aGUgdXNlci1kYXRhIChyZXRyaWV2ZWQgdmlhIHRoZSBjYWxsYmFjaykuCisgKgorICogUmV0dXJucyB0aGUgY3JlYXRlIG1vZHVsZS1kYXRhIGNvbnRhaW5lcgorICogICAgICAgICBvciBOVUxMIGlmIHN1Y2ggYSBtb2R1bGUgd2FzIG5vdCByZWdpc3RlcmVkLgorICovCitzdGF0aWMgeHNsdEV4dERhdGFQdHIKK3hzbHRTdHlsZUluaXRpYWxpemVTdHlsZXNoZWV0TW9kdWxlKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCSAgICAgY29uc3QgeG1sQ2hhciAqIFVSSSkKK3sKKyAgICB4c2x0RXh0RGF0YVB0ciBkYXRhQ29udGFpbmVyOworICAgIHZvaWQgKnVzZXJEYXRhID0gTlVMTDsKKyAgICB4c2x0RXh0TW9kdWxlUHRyIG1vZHVsZTsKKyAgICAKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkpCQorCXJldHVybihOVUxMKTsKKworICAgIGlmICh4c2x0RXh0ZW5zaW9uc0hhc2ggPT0gTlVMTCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRFTlNJT05TCisJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgIk5vdCByZWdpc3RlcmVkIGV4dGVuc2lvbiBtb2R1bGU6ICVzXG4iLCBVUkkpOworI2VuZGlmCisJcmV0dXJuKE5VTEwpOworICAgIH0KKworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgbW9kdWxlID0geG1sSGFzaExvb2t1cCh4c2x0RXh0ZW5zaW9uc0hhc2gsIFVSSSk7CisKKyAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgaWYgKG1vZHVsZSA9PSBOVUxMKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0VYVEVOU0lPTlMKKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAiTm90IHJlZ2lzdGVyZWQgZXh0ZW5zaW9uIG1vZHVsZTogJXNcbiIsIFVSSSk7CisjZW5kaWYKKwlyZXR1cm4gKE5VTEwpOworICAgIH0KKyAgICAvKgorICAgICogVGhlIHNwZWNpZmllZCBtb2R1bGUgd2FzIHJlZ2lzdGVyZWQgc28gaW5pdGlhbGl6ZSBpdC4KKyAgICAqLworICAgIGlmIChzdHlsZS0+ZXh0SW5mb3MgPT0gTlVMTCkgeworCXN0eWxlLT5leHRJbmZvcyA9IHhtbEhhc2hDcmVhdGUoMTApOworCWlmIChzdHlsZS0+ZXh0SW5mb3MgPT0gTlVMTCkKKwkgICAgcmV0dXJuIChOVUxMKTsKKyAgICB9CisgICAgLyoKKyAgICAqIEZpcmUgdGhlIGluaXRpYWxpemF0aW9uIGNhbGxiYWNrIGlmIGF2YWlsYWJsZS4KKyAgICAqLworICAgIGlmIChtb2R1bGUtPnN0eWxlSW5pdEZ1bmMgPT0gTlVMTCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRFTlNJT05TCisJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgIkluaXRpYWxpemluZyBtb2R1bGUgd2l0aCAqbm8qIGNhbGxiYWNrOiAlc1xuIiwgVVJJKTsKKyNlbmRpZgorICAgIH0gZWxzZSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0VYVEVOU0lPTlMKKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAiSW5pdGlhbGl6aW5nIG1vZHVsZSB3aXRoIGNhbGxiYWNrOiAlc1xuIiwgVVJJKTsKKyNlbmRpZgorCS8qCisJKiBGaXJlIHRoZSBpbml0aWFsaXphdGlvbiBjYWxsYmFjay4KKwkqLworCXVzZXJEYXRhID0gbW9kdWxlLT5zdHlsZUluaXRGdW5jKHN0eWxlLCBVUkkpOworICAgIH0gICAgCisgICAgLyoKKyAgICAqIFN0b3JlIHRoZSB1c2VyLWRhdGEgaW4gdGhlIGNvbnRleHQgb2YgdGhlIGdpdmVuIHN0eWxlc2hlZXQuCisgICAgKi8KKyAgICBkYXRhQ29udGFpbmVyID0geHNsdE5ld0V4dERhdGEobW9kdWxlLCB1c2VyRGF0YSk7CisgICAgaWYgKGRhdGFDb250YWluZXIgPT0gTlVMTCkKKwlyZXR1cm4gKE5VTEwpOworCisgICAgaWYgKHhtbEhhc2hBZGRFbnRyeShzdHlsZS0+ZXh0SW5mb3MsIFVSSSwKKwkodm9pZCAqKSBkYXRhQ29udGFpbmVyKSA8IDApCisgICAgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgTlVMTCwJICAgIAorCSAgICAiRmFpbGVkIHRvIHJlZ2lzdGVyIG1vZHVsZSAnJXMnLlxuIiwgVVJJKTsKKwlzdHlsZS0+ZXJyb3JzKys7CisJaWYgKG1vZHVsZS0+c3R5bGVTaHV0ZG93bkZ1bmMpCisJICAgIG1vZHVsZS0+c3R5bGVTaHV0ZG93bkZ1bmMoc3R5bGUsIFVSSSwgdXNlckRhdGEpOworCXhzbHRGcmVlRXh0RGF0YShkYXRhQ29udGFpbmVyKTsKKwlyZXR1cm4gKE5VTEwpOworICAgIH0KKworICAgIHJldHVybihkYXRhQ29udGFpbmVyKTsKK30KKworLyoqCisgKiB4c2x0U3R5bGVHZXRFeHREYXRhOgorICogQHN0eWxlOiBhbiBYU0xUIHN0eWxlc2hlZXQKKyAqIEBVUkk6ICB0aGUgVVJJIGFzc29jaWF0ZWQgdG8gdGhlIGV4ZW5zaW9uIG1vZHVsZQorICoKKyAqIFJldHJpZXZlIHRoZSBkYXRhIGFzc29jaWF0ZWQgdG8gdGhlIGV4dGVuc2lvbiBtb2R1bGUKKyAqIGluIHRoaXMgZ2l2ZW4gc3R5bGVzaGVldC4KKyAqIENhbGxlZCBieToKKyAqICAgeHNsdFJlZ2lzdGVyRXh0UHJlZml4KCksCisgKiAgICggeHNsdEV4dEVsZW1lbnRQcmVDb21wVGVzdCgpLCB4c2x0RXh0SW5pdFRlc3QgKQorICoKKyAqIFJldHVybnMgdGhlIHBvaW50ZXIgb3IgTlVMTCBpZiBub3QgcHJlc2VudAorICovCit2b2lkICoKK3hzbHRTdHlsZUdldEV4dERhdGEoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIGNvbnN0IHhtbENoYXIgKiBVUkkpCit7CisgICAgeHNsdEV4dERhdGFQdHIgZGF0YUNvbnRhaW5lciA9IE5VTEw7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgdG1wU3R5bGU7CisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkgfHwKKwkoeHNsdEV4dGVuc2lvbnNIYXNoID09IE5VTEwpKQorCXJldHVybiAoTlVMTCk7CisKKyAgICAKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICAvKgorICAgICogVGhpcyBpcyBpbnRlbmRlZCBmb3IgZ2xvYmFsIHN0b3JhZ2UsIHNvIG9ubHkgdGhlIG1haW4KKyAgICAqIHN0eWxlc2hlZXQgd2lsbCBob2xkIHRoZSBkYXRhLgorICAgICovCisgICAgdG1wU3R5bGUgPSBzdHlsZTsKKyAgICB3aGlsZSAodG1wU3R5bGUtPnBhcmVudCAhPSBOVUxMKQorCXRtcFN0eWxlID0gdG1wU3R5bGUtPnBhcmVudDsKKyAgICBpZiAodG1wU3R5bGUtPmV4dEluZm9zICE9IE5VTEwpIHsKKwlkYXRhQ29udGFpbmVyID0KKwkgICAgKHhzbHRFeHREYXRhUHRyKSB4bWxIYXNoTG9va3VwKHRtcFN0eWxlLT5leHRJbmZvcywgVVJJKTsKKwlpZiAoZGF0YUNvbnRhaW5lciAhPSBOVUxMKSB7CisJICAgIC8qCisJICAgICogVGhlIG1vZHVsZSB3YXMgYWxyZWFkeSBpbml0aWFsaXplZCBpbiB0aGUgY29udGV4dAorCSAgICAqIG9mIHRoaXMgc3R5bGVzaGVldDsganVzdCByZXR1cm4gdGhlIHVzZXItZGF0YSB0aGF0CisJICAgICogY29tZXMgd2l0aCBpdC4KKwkgICAgKi8KKwkgICAgcmV0dXJuKGRhdGFDb250YWluZXItPmV4dERhdGEpOworCX0KKyAgICB9CisjZWxzZQorICAgIC8qCisgICAgKiBPbGQgYmVoYXZpb3VyLgorICAgICovCisgICAgdG1wU3R5bGUgPSBzdHlsZTsKKyAgICB3aGlsZSAodG1wU3R5bGUgIT0gTlVMTCkgeworCWlmICh0bXBTdHlsZS0+ZXh0SW5mb3MgIT0gTlVMTCkgeworCSAgICBkYXRhQ29udGFpbmVyID0KKwkJKHhzbHRFeHREYXRhUHRyKSB4bWxIYXNoTG9va3VwKHRtcFN0eWxlLT5leHRJbmZvcywgVVJJKTsKKwkgICAgaWYgKGRhdGFDb250YWluZXIgIT0gTlVMTCkgeworCQlyZXR1cm4oZGF0YUNvbnRhaW5lci0+ZXh0RGF0YSk7CisJICAgIH0KKwl9CisJdG1wU3R5bGUgPSB4c2x0TmV4dEltcG9ydCh0bXBTdHlsZSk7CisgICAgfQorICAgIHRtcFN0eWxlID0gc3R5bGU7CisjZW5kaWYKKworICAgIGRhdGFDb250YWluZXIgPQorICAgICAgICB4c2x0U3R5bGVJbml0aWFsaXplU3R5bGVzaGVldE1vZHVsZSh0bXBTdHlsZSwgVVJJKTsKKyAgICBpZiAoZGF0YUNvbnRhaW5lciAhPSBOVUxMKQorCXJldHVybiAoZGF0YUNvbnRhaW5lci0+ZXh0RGF0YSk7CisgICAgcmV0dXJuKE5VTEwpOworfQorCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisvKioKKyAqIHhzbHRTdHlsZVN0eWxlc2hlZXRMZXZlbEdldEV4dERhdGE6CisgKiBAc3R5bGU6IGFuIFhTTFQgc3R5bGVzaGVldAorICogQFVSSTogIHRoZSBVUkkgYXNzb2NpYXRlZCB0byB0aGUgZXhlbnNpb24gbW9kdWxlCisgKgorICogUmV0cmlldmUgdGhlIGRhdGEgYXNzb2NpYXRlZCB0byB0aGUgZXh0ZW5zaW9uIG1vZHVsZSBpbiB0aGlzIGdpdmVuCisgKiBzdHlsZXNoZWV0LgorICoKKyAqIFJldHVybnMgdGhlIHBvaW50ZXIgb3IgTlVMTCBpZiBub3QgcHJlc2VudAorICovCit2b2lkICoKK3hzbHRTdHlsZVN0eWxlc2hlZXRMZXZlbEdldEV4dERhdGEoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJICAgY29uc3QgeG1sQ2hhciAqIFVSSSkKK3sKKyAgICB4c2x0RXh0RGF0YVB0ciBkYXRhQ29udGFpbmVyID0gTlVMTDsKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKFVSSSA9PSBOVUxMKSB8fAorCSh4c2x0RXh0ZW5zaW9uc0hhc2ggPT0gTlVMTCkpCisJcmV0dXJuIChOVUxMKTsKKworICAgIGlmIChzdHlsZS0+ZXh0SW5mb3MgIT0gTlVMTCkgeworCWRhdGFDb250YWluZXIgPSAoeHNsdEV4dERhdGFQdHIpIHhtbEhhc2hMb29rdXAoc3R5bGUtPmV4dEluZm9zLCBVUkkpOworCS8qCisJKiBUaGUgbW9kdWxlIHdhcyBhbHJlYWR5IGluaXRpYWxpemVkIGluIHRoZSBjb250ZXh0CisJKiBvZiB0aGlzIHN0eWxlc2hlZXQ7IGp1c3QgcmV0dXJuIHRoZSB1c2VyLWRhdGEgdGhhdAorCSogY29tZXMgd2l0aCBpdC4KKwkqLworCWlmIChkYXRhQ29udGFpbmVyKQorCSAgICByZXR1cm4oZGF0YUNvbnRhaW5lci0+ZXh0RGF0YSk7CisgICAgfSAgCisKKyAgICBkYXRhQ29udGFpbmVyID0KKyAgICAgICAgeHNsdFN0eWxlSW5pdGlhbGl6ZVN0eWxlc2hlZXRNb2R1bGUoc3R5bGUsIFVSSSk7CisgICAgaWYgKGRhdGFDb250YWluZXIgIT0gTlVMTCkKKwlyZXR1cm4gKGRhdGFDb250YWluZXItPmV4dERhdGEpOworICAgIHJldHVybihOVUxMKTsKK30KKyNlbmRpZgorCisvKioKKyAqIHhzbHRHZXRFeHREYXRhOgorICogQGN0eHQ6IGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQFVSSTogIHRoZSBVUkkgYXNzb2NpYXRlZCB0byB0aGUgZXhlbnNpb24gbW9kdWxlCisgKgorICogUmV0cmlldmUgdGhlIGRhdGEgYXNzb2NpYXRlZCB0byB0aGUgZXh0ZW5zaW9uIG1vZHVsZSBpbiB0aGlzIGdpdmVuCisgKiB0cmFuc2Zvcm1hdGlvbi4KKyAqCisgKiBSZXR1cm5zIHRoZSBwb2ludGVyIG9yIE5VTEwgaWYgbm90IHByZXNlbnQKKyAqLwordm9pZCAqCit4c2x0R2V0RXh0RGF0YSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogVVJJKQoreworICAgIHhzbHRFeHREYXRhUHRyIGRhdGE7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKFVSSSA9PSBOVUxMKSkKKyAgICAgICAgcmV0dXJuIChOVUxMKTsKKyAgICBpZiAoY3R4dC0+ZXh0SW5mb3MgPT0gTlVMTCkgeworICAgICAgICBjdHh0LT5leHRJbmZvcyA9IHhtbEhhc2hDcmVhdGUoMTApOworICAgICAgICBpZiAoY3R4dC0+ZXh0SW5mb3MgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CisgICAgICAgIGRhdGEgPSBOVUxMOworICAgIH0gZWxzZSB7CisgICAgICAgIGRhdGEgPSAoeHNsdEV4dERhdGFQdHIpIHhtbEhhc2hMb29rdXAoY3R4dC0+ZXh0SW5mb3MsIFVSSSk7CisgICAgfQorICAgIGlmIChkYXRhID09IE5VTEwpIHsKKyAgICAgICAgdm9pZCAqZXh0RGF0YTsKKyAgICAgICAgeHNsdEV4dE1vZHVsZVB0ciBtb2R1bGU7CisKKyAgICAgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICAgICAgbW9kdWxlID0geG1sSGFzaExvb2t1cCh4c2x0RXh0ZW5zaW9uc0hhc2gsIFVSSSk7CisKKyAgICAgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKKworICAgICAgICBpZiAobW9kdWxlID09IE5VTEwpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRVhURU5TSU9OUworICAgICAgICAgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vdCByZWdpc3RlcmVkIGV4dGVuc2lvbiBtb2R1bGU6ICVzXG4iLCBVUkkpOworI2VuZGlmCisgICAgICAgICAgICByZXR1cm4gKE5VTEwpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKG1vZHVsZS0+aW5pdEZ1bmMgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gKE5VTEwpOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0VYVEVOU0lPTlMKKyAgICAgICAgICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbml0aWFsaXppbmcgbW9kdWxlOiAlc1xuIiwgVVJJKTsKKyNlbmRpZgorCisgICAgICAgICAgICBleHREYXRhID0gbW9kdWxlLT5pbml0RnVuYyhjdHh0LCBVUkkpOworICAgICAgICAgICAgaWYgKGV4dERhdGEgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gKE5VTEwpOworCisgICAgICAgICAgICBkYXRhID0geHNsdE5ld0V4dERhdGEobW9kdWxlLCBleHREYXRhKTsKKyAgICAgICAgICAgIGlmIChkYXRhID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKKyAgICAgICAgICAgIGlmICh4bWxIYXNoQWRkRW50cnkoY3R4dC0+ZXh0SW5mb3MsIFVSSSwgKHZvaWQgKikgZGF0YSkgPCAwKSB7CisgICAgICAgICAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gcmVnaXN0ZXIgbW9kdWxlIGRhdGE6ICVzXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkkpOworICAgICAgICAgICAgICAgIGlmIChtb2R1bGUtPnNodXRkb3duRnVuYykKKyAgICAgICAgICAgICAgICAgICAgbW9kdWxlLT5zaHV0ZG93bkZ1bmMoY3R4dCwgVVJJLCBleHREYXRhKTsKKyAgICAgICAgICAgICAgICB4c2x0RnJlZUV4dERhdGEoZGF0YSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKGRhdGEtPmV4dERhdGEpOworfQorCit0eXBlZGVmIHN0cnVjdCBfeHNsdEluaXRFeHRDdHh0IHhzbHRJbml0RXh0Q3R4dDsKK3N0cnVjdCBfeHNsdEluaXRFeHRDdHh0IHsKKyAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0OworICAgIGludCByZXQ7Cit9OworCisvKioKKyAqIHhzbHRJbml0Q3R4dEV4dDoKKyAqIEBzdHlsZURhdGE6ICB0aGUgcmVnaXN0ZXJlZCBzdHlsZXNoZWV0IGRhdGEgZm9yIHRoZSBtb2R1bGUKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dCArIHRoZSByZXR1cm4gdmFsdWUKKyAqIEBVUkk6ICB0aGUgZXh0ZW5zaW9uIFVSSQorICoKKyAqIEluaXRpYWxpemVzIGFuIGV4dGVuc2lvbiBtb2R1bGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRJbml0Q3R4dEV4dCh4c2x0RXh0RGF0YVB0ciBzdHlsZURhdGEsIHhzbHRJbml0RXh0Q3R4dCAqIGN0eHQsCisgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIFVSSSkKK3sKKyAgICB4c2x0RXh0TW9kdWxlUHRyIG1vZHVsZTsKKyAgICB4c2x0RXh0RGF0YVB0ciBjdHh0RGF0YTsKKyAgICB2b2lkICpleHREYXRhOworCisgICAgaWYgKChzdHlsZURhdGEgPT0gTlVMTCkgfHwgKGN0eHQgPT0gTlVMTCkgfHwgKFVSSSA9PSBOVUxMKSB8fAorICAgICAgICAoY3R4dC0+cmV0ID09IC0xKSkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRFTlNJT05TCisgICAgICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRJbml0Q3R4dEV4dDogTlVMTCBwYXJhbSBvciBlcnJvclxuIik7CisjZW5kaWYKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBtb2R1bGUgPSBzdHlsZURhdGEtPmV4dE1vZHVsZTsKKyAgICBpZiAoKG1vZHVsZSA9PSBOVUxMKSB8fCAobW9kdWxlLT5pbml0RnVuYyA9PSBOVUxMKSkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRFTlNJT05TCisgICAgICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRJbml0Q3R4dEV4dDogbm8gbW9kdWxlIG9yIG5vIGluaXRGdW5jXG4iKTsKKyNlbmRpZgorICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgY3R4dERhdGEgPSAoeHNsdEV4dERhdGFQdHIpIHhtbEhhc2hMb29rdXAoY3R4dC0+Y3R4dC0+ZXh0SW5mb3MsIFVSSSk7CisgICAgaWYgKGN0eHREYXRhICE9IE5VTEwpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRVhURU5TSU9OUworICAgICAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0SW5pdEN0eHRFeHQ6IGFscmVhZHkgaW5pdGlhbGl6ZWRcbiIpOworI2VuZGlmCisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBleHREYXRhID0gbW9kdWxlLT5pbml0RnVuYyhjdHh0LT5jdHh0LCBVUkkpOworICAgIGlmIChleHREYXRhID09IE5VTEwpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRVhURU5TSU9OUworICAgICAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0SW5pdEN0eHRFeHQ6IG5vIGV4dERhdGFcbiIpOworI2VuZGlmCisgICAgfQorICAgIGN0eHREYXRhID0geHNsdE5ld0V4dERhdGEobW9kdWxlLCBleHREYXRhKTsKKyAgICBpZiAoY3R4dERhdGEgPT0gTlVMTCkgeworICAgICAgICBjdHh0LT5yZXQgPSAtMTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGlmIChjdHh0LT5jdHh0LT5leHRJbmZvcyA9PSBOVUxMKQorICAgICAgICBjdHh0LT5jdHh0LT5leHRJbmZvcyA9IHhtbEhhc2hDcmVhdGUoMTApOworICAgIGlmIChjdHh0LT5jdHh0LT5leHRJbmZvcyA9PSBOVUxMKSB7CisgICAgICAgIGN0eHQtPnJldCA9IC0xOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKHhtbEhhc2hBZGRFbnRyeShjdHh0LT5jdHh0LT5leHRJbmZvcywgVVJJLCBjdHh0RGF0YSkgPCAwKSB7CisgICAgICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byByZWdpc3RlciBtb2R1bGUgZGF0YTogJXNcbiIsIFVSSSk7CisgICAgICAgIGlmIChtb2R1bGUtPnNodXRkb3duRnVuYykKKyAgICAgICAgICAgIG1vZHVsZS0+c2h1dGRvd25GdW5jKGN0eHQtPmN0eHQsIFVSSSwgZXh0RGF0YSk7CisgICAgICAgIHhzbHRGcmVlRXh0RGF0YShjdHh0RGF0YSk7CisgICAgICAgIGN0eHQtPnJldCA9IC0xOworICAgICAgICByZXR1cm47CisgICAgfQorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRFTlNJT05TCisgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwgIlJlZ2lzdGVyZWQgbW9kdWxlICVzXG4iLAorICAgICAgICAgICAgICAgICAgICAgVVJJKTsKKyNlbmRpZgorICAgIGN0eHQtPnJldCsrOworfQorCisvKioKKyAqIHhzbHRJbml0Q3R4dEV4dHM6CisgKiBAY3R4dDogYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogSW5pdGlhbGl6ZSB0aGUgc2V0IG9mIG1vZHVsZXMgd2l0aCByZWdpc3RlcmVkIHN0eWxlc2hlZXQgZGF0YQorICoKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiBtb2R1bGVzIGluaXRpYWxpemVkIG9yIC0xIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworaW50Cit4c2x0SW5pdEN0eHRFeHRzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpCit7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CisgICAgeHNsdEluaXRFeHRDdHh0IGN0eDsKKworICAgIGlmIChjdHh0ID09IE5VTEwpCisgICAgICAgIHJldHVybiAoLTEpOworCisgICAgc3R5bGUgPSBjdHh0LT5zdHlsZTsKKyAgICBpZiAoc3R5bGUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuICgtMSk7CisKKyAgICBjdHguY3R4dCA9IGN0eHQ7CisgICAgY3R4LnJldCA9IDA7CisKKyAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworICAgICAgICBpZiAoc3R5bGUtPmV4dEluZm9zICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHhtbEhhc2hTY2FuKHN0eWxlLT5leHRJbmZvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lcikgeHNsdEluaXRDdHh0RXh0LCAmY3R4KTsKKyAgICAgICAgICAgIGlmIChjdHgucmV0ID09IC0xKQorICAgICAgICAgICAgICAgIHJldHVybiAoLTEpOworICAgICAgICB9CisgICAgICAgIHN0eWxlID0geHNsdE5leHRJbXBvcnQoc3R5bGUpOworICAgIH0KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRVhURU5TSU9OUworICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsICJSZWdpc3RlcmVkICVkIG1vZHVsZXNcbiIsCisgICAgICAgICAgICAgICAgICAgICBjdHgucmV0KTsKKyNlbmRpZgorICAgIHJldHVybiAoY3R4LnJldCk7Cit9CisKKy8qKgorICogeHNsdFNodXRkb3duQ3R4dEV4dDoKKyAqIEBkYXRhOiAgdGhlIHJlZ2lzdGVyZWQgZGF0YSBmb3IgdGhlIG1vZHVsZQorICogQGN0eHQ6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAVVJJOiAgdGhlIGV4dGVuc2lvbiBVUkkKKyAqCisgKiBTaHV0ZG93biBhbiBleHRlbnNpb24gbW9kdWxlIGxvYWRlZAorICovCitzdGF0aWMgdm9pZAoreHNsdFNodXRkb3duQ3R4dEV4dCh4c2x0RXh0RGF0YVB0ciBkYXRhLCB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogVVJJKQoreworICAgIHhzbHRFeHRNb2R1bGVQdHIgbW9kdWxlOworCisgICAgaWYgKChkYXRhID09IE5VTEwpIHx8IChjdHh0ID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkpCisgICAgICAgIHJldHVybjsKKyAgICBtb2R1bGUgPSBkYXRhLT5leHRNb2R1bGU7CisgICAgaWYgKChtb2R1bGUgPT0gTlVMTCkgfHwgKG1vZHVsZS0+c2h1dGRvd25GdW5jID09IE5VTEwpKQorICAgICAgICByZXR1cm47CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRVhURU5TSU9OUworICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAiU2h1dHRpbmcgZG93biBtb2R1bGUgOiAlc1xuIiwgVVJJKTsKKyNlbmRpZgorICAgIG1vZHVsZS0+c2h1dGRvd25GdW5jKGN0eHQsIFVSSSwgZGF0YS0+ZXh0RGF0YSk7Cit9CisKKy8qKgorICogeHNsdFNodXRkb3duQ3R4dEV4dHM6CisgKiBAY3R4dDogYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogU2h1dGRvd24gdGhlIHNldCBvZiBtb2R1bGVzIGxvYWRlZAorICovCit2b2lkCit4c2x0U2h1dGRvd25DdHh0RXh0cyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KQoreworICAgIGlmIChjdHh0ID09IE5VTEwpCisgICAgICAgIHJldHVybjsKKyAgICBpZiAoY3R4dC0+ZXh0SW5mb3MgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworICAgIHhtbEhhc2hTY2FuKGN0eHQtPmV4dEluZm9zLCAoeG1sSGFzaFNjYW5uZXIpIHhzbHRTaHV0ZG93bkN0eHRFeHQsCisgICAgICAgICAgICAgICAgY3R4dCk7CisgICAgeG1sSGFzaEZyZWUoY3R4dC0+ZXh0SW5mb3MsICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhzbHRGcmVlRXh0RGF0YSk7CisgICAgY3R4dC0+ZXh0SW5mb3MgPSBOVUxMOworfQorCisvKioKKyAqIHhzbHRTaHV0ZG93bkV4dDoKKyAqIEBkYXRhOiAgdGhlIHJlZ2lzdGVyZWQgZGF0YSBmb3IgdGhlIG1vZHVsZQorICogQGN0eHQ6ICB0aGUgWFNMVCBzdHlsZXNoZWV0CisgKiBAVVJJOiAgdGhlIGV4dGVuc2lvbiBVUkkKKyAqCisgKiBTaHV0ZG93biBhbiBleHRlbnNpb24gbW9kdWxlIGxvYWRlZAorICovCitzdGF0aWMgdm9pZAoreHNsdFNodXRkb3duRXh0KHhzbHRFeHREYXRhUHRyIGRhdGEsIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBVUkkpCit7CisgICAgeHNsdEV4dE1vZHVsZVB0ciBtb2R1bGU7CisKKyAgICBpZiAoKGRhdGEgPT0gTlVMTCkgfHwgKHN0eWxlID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkpCisgICAgICAgIHJldHVybjsKKyAgICBtb2R1bGUgPSBkYXRhLT5leHRNb2R1bGU7CisgICAgaWYgKChtb2R1bGUgPT0gTlVMTCkgfHwgKG1vZHVsZS0+c3R5bGVTaHV0ZG93bkZ1bmMgPT0gTlVMTCkpCisgICAgICAgIHJldHVybjsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRFTlNJT05TCisgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICJTaHV0dGluZyBkb3duIG1vZHVsZSA6ICVzXG4iLCBVUkkpOworI2VuZGlmCisgICAgbW9kdWxlLT5zdHlsZVNodXRkb3duRnVuYyhzdHlsZSwgVVJJLCBkYXRhLT5leHREYXRhKTsKKyAgICAvKgorICAgICogRG9uJ3QgcmVtb3ZlIHRoZSBlbnRyeSBmcm9tIHRoZSBoYXNoIHRhYmxlIGhlcmUsIHNpbmNlCisgICAgKiB0aGlzIHdpbGwgcHJvZHVjZSBzZWdmYXVsdHMgLSB0aGlzIGZpeGVzIGJ1ZyAjMzQwNjI0LgorICAgICoKKyAgICAqIHhtbEhhc2hSZW1vdmVFbnRyeShzdHlsZS0+ZXh0SW5mb3MsIFVSSSwKKyAgICAqICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeHNsdEZyZWVFeHREYXRhKTsKKyAgICAqLyAgICAKK30KKworLyoqCisgKiB4c2x0U2h1dGRvd25FeHRzOgorICogQHN0eWxlOiBhbiBYU0xUIHN0eWxlc2hlZXQKKyAqCisgKiBTaHV0ZG93biB0aGUgc2V0IG9mIG1vZHVsZXMgbG9hZGVkCisgKi8KK3ZvaWQKK3hzbHRTaHV0ZG93bkV4dHMoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUpCit7CisgICAgaWYgKHN0eWxlID09IE5VTEwpCisgICAgICAgIHJldHVybjsKKyAgICBpZiAoc3R5bGUtPmV4dEluZm9zID09IE5VTEwpCisgICAgICAgIHJldHVybjsKKyAgICB4bWxIYXNoU2NhbihzdHlsZS0+ZXh0SW5mb3MsICh4bWxIYXNoU2Nhbm5lcikgeHNsdFNodXRkb3duRXh0LCBzdHlsZSk7CisgICAgeG1sSGFzaEZyZWUoc3R5bGUtPmV4dEluZm9zLCAoeG1sSGFzaERlYWxsb2NhdG9yKSB4c2x0RnJlZUV4dERhdGEpOworICAgIHN0eWxlLT5leHRJbmZvcyA9IE5VTEw7Cit9CisKKy8qKgorICogeHNsdENoZWNrRXh0UHJlZml4OgorICogQHN0eWxlOiB0aGUgc3R5bGVzaGVldAorICogQFVSSTogdGhlIG5hbWVzcGFjZSBwcmVmaXggKHBvc3NpYmx5IE5VTEwpCisgKgorICogQ2hlY2sgaWYgdGhlIGdpdmVuIHByZWZpeCBpcyBvbmUgb2YgdGhlIGRlY2xhcmVkIGV4dGVuc2lvbnMuCisgKiBUaGlzIGlzIGludGVuZGVkIHRvIGJlIGNhbGxlZCBvbmx5IGF0IGNvbXBpbGUtdGltZS4KKyAqIENhbGxlZCBieToKKyAqICB4c2x0R2V0SW5oZXJpdGVkTnNMaXN0KCkgKHhzbHQuYykKKyAqICB4c2x0UGFyc2VUZW1wbGF0ZUNvbnRlbnQgKHhzbHQuYykKKyAqCisgKiBSZXR1cm5zIDEgaWYgdGhpcyBpcyBhbiBleHRlbnNpb24sIDAgb3RoZXJ3aXNlCisgKi8KK2ludAoreHNsdENoZWNrRXh0UHJlZml4KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCBjb25zdCB4bWxDaGFyICogVVJJKQoreyAgICAKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChzdHlsZS0+Y29tcEN0eHQgPT0gTlVMTCkgfHwKKwkoWFNMVF9DQ1RYVChzdHlsZSktPmlub2RlID09IE5VTEwpIHx8CisJKFhTTFRfQ0NUWFQoc3R5bGUpLT5pbm9kZS0+ZXh0RWxlbU5zID09IE5VTEwpKQorICAgICAgICByZXR1cm4gKDApOyAgICAKKyAgICAvKgorICAgICogTG9va3VwIHRoZSBleHRlbnNpb24gbmFtZXNwYWNlcyByZWdpc3RlcmVkCisgICAgKiBhdCB0aGUgY3VycmVudCBub2RlIGluIHRoZSBzdHlsZXNoZWV0J3MgdHJlZS4KKyAgICAqLworICAgIGlmIChYU0xUX0NDVFhUKHN0eWxlKS0+aW5vZGUtPmV4dEVsZW1OcyAhPSBOVUxMKSB7CisJaW50IGk7CisJeHNsdFBvaW50ZXJMaXN0UHRyIGxpc3QgPSBYU0xUX0NDVFhUKHN0eWxlKS0+aW5vZGUtPmV4dEVsZW1OczsKKworCWZvciAoaSA9IDA7IGkgPCBsaXN0LT5udW1iZXI7IGkrKykgeworCSAgICBpZiAoeG1sU3RyRXF1YWwoKGNvbnN0IHhtbENoYXIgKikgbGlzdC0+aXRlbXNbaV0sCisJCVVSSSkpCisJICAgIHsKKwkJcmV0dXJuKDEpOworCSAgICB9CSAgICAKKwl9CisgICAgfQorI2Vsc2UKKyAgICB4c2x0RXh0RGVmUHRyIGN1cjsKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKHN0eWxlLT5uc0RlZnMgPT0gTlVMTCkpCisgICAgICAgIHJldHVybiAoMCk7CisgICAgaWYgKFVSSSA9PSBOVUxMKQorICAgICAgICBVUkkgPSBCQURfQ0FTVCAiI2RlZmF1bHQiOworICAgIGN1ciA9ICh4c2x0RXh0RGVmUHRyKSBzdHlsZS0+bnNEZWZzOworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCS8qCisJKiBOT1RFOiBUaGlzIHdhcyBjaGFuZ2UgdG8gd29yayBvbiBuYW1lc3BhY2UgbmFtZXMgcmF0aGVyCisJKiB0aGFuIG5hbWVzcGFjZSBwcmVmaXhlcy4gVGhpcyBmaXhlcyBidWcgIzMzOTU4My4KKwkqIFRPRE86IENvbnNpZGVyIHJlbmFtaW5nIHRoZSBmaWVsZCAicHJlZml4IiBvZiB4c2x0RXh0RGVmCisJKiAgdG8gImhyZWYiLgorCSovCisgICAgICAgIGlmICh4bWxTdHJFcXVhbChVUkksIGN1ci0+cHJlZml4KSkKKyAgICAgICAgICAgIHJldHVybiAoMSk7CisgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKKyAgICB9CisjZW5kaWYKKyAgICByZXR1cm4gKDApOworfQorCisvKioKKyAqIHhzbHRDaGVja0V4dFVSSToKKyAqIEBzdHlsZTogdGhlIHN0eWxlc2hlZXQKKyAqIEBVUkk6IHRoZSBuYW1lc3BhY2UgVVJJIChwb3NzaWJseSBOVUxMKQorICoKKyAqIENoZWNrIGlmIHRoZSBnaXZlbiBwcmVmaXggaXMgb25lIG9mIHRoZSBkZWNsYXJlZCBleHRlbnNpb25zLgorICogVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBjYWxsZWQgb25seSBhdCBjb21waWxlLXRpbWUuCisgKiBDYWxsZWQgYnk6CisgKiAgeHNsdFByZWNvbXB1dGVTdHlsZXNoZWV0KCkgKHhzbHQuYykKKyAqICB4c2x0UGFyc2VUZW1wbGF0ZUNvbnRlbnQgKHhzbHQuYykKKyAqCisgKiBSZXR1cm5zIDEgaWYgdGhpcyBpcyBhbiBleHRlbnNpb24sIDAgb3RoZXJ3aXNlCisgKi8KK2ludAoreHNsdENoZWNrRXh0VVJJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCBjb25zdCB4bWxDaGFyICogVVJJKQoreworICAgIHhzbHRFeHREZWZQdHIgY3VyOworCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoc3R5bGUtPm5zRGVmcyA9PSBOVUxMKSkKKyAgICAgICAgcmV0dXJuICgwKTsKKyAgICBpZiAoVVJJID09IE5VTEwpCisgICAgICAgIHJldHVybiAoMCk7CisgICAgY3VyID0gKHhzbHRFeHREZWZQdHIpIHN0eWxlLT5uc0RlZnM7CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisgICAgICAgIGlmICh4bWxTdHJFcXVhbChVUkksIGN1ci0+VVJJKSkKKyAgICAgICAgICAgIHJldHVybiAoMSk7CisgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKKyAgICB9CisgICAgcmV0dXJuICgwKTsKK30KKworLyoqCisgKiB4c2x0UmVnaXN0ZXJFeHRNb2R1bGVGdWxsOgorICogQFVSSTogIFVSSSBhc3NvY2lhdGVkIHRvIHRoaXMgbW9kdWxlCisgKiBAaW5pdEZ1bmM6ICB0aGUgbW9kdWxlIGluaXRpYWxpemF0aW9uIGZ1bmN0aW9uCisgKiBAc2h1dGRvd25GdW5jOiAgdGhlIG1vZHVsZSBzaHV0ZG93biBmdW5jdGlvbgorICogQHN0eWxlSW5pdEZ1bmM6ICB0aGUgbW9kdWxlIGluaXRpYWxpemF0aW9uIGZ1bmN0aW9uCisgKiBAc3R5bGVTaHV0ZG93bkZ1bmM6ICB0aGUgbW9kdWxlIHNodXRkb3duIGZ1bmN0aW9uCisgKgorICogUmVnaXN0ZXIgYW4gWFNMVCBleHRlbnNpb24gbW9kdWxlIHRvIHRoZSBsaWJyYXJ5LgorICoKKyAqIFJldHVybnMgMCBpZiBzdWNlc3NmdWwsIC0xIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworaW50Cit4c2x0UmVnaXN0ZXJFeHRNb2R1bGVGdWxsKGNvbnN0IHhtbENoYXIgKiBVUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRFeHRJbml0RnVuY3Rpb24gaW5pdEZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRFeHRTaHV0ZG93bkZ1bmN0aW9uIHNodXRkb3duRnVuYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgeHNsdFN0eWxlRXh0SW5pdEZ1bmN0aW9uIHN0eWxlSW5pdEZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRTdHlsZUV4dFNodXRkb3duRnVuY3Rpb24gc3R5bGVTaHV0ZG93bkZ1bmMpCit7CisgICAgaW50IHJldDsKKyAgICB4c2x0RXh0TW9kdWxlUHRyIG1vZHVsZTsKKworICAgIGlmICgoVVJJID09IE5VTEwpIHx8IChpbml0RnVuYyA9PSBOVUxMKSkKKyAgICAgICAgcmV0dXJuICgtMSk7CisgICAgaWYgKHhzbHRFeHRlbnNpb25zSGFzaCA9PSBOVUxMKQorICAgICAgICB4c2x0RXh0ZW5zaW9uc0hhc2ggPSB4bWxIYXNoQ3JlYXRlKDEwKTsKKworICAgIGlmICh4c2x0RXh0ZW5zaW9uc0hhc2ggPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuICgtMSk7CisKKyAgICB4bWxNdXRleExvY2soeHNsdEV4dE11dGV4KTsKKworICAgIG1vZHVsZSA9IHhtbEhhc2hMb29rdXAoeHNsdEV4dGVuc2lvbnNIYXNoLCBVUkkpOworICAgIGlmIChtb2R1bGUgIT0gTlVMTCkgeworICAgICAgICBpZiAoKG1vZHVsZS0+aW5pdEZ1bmMgPT0gaW5pdEZ1bmMpICYmCisgICAgICAgICAgICAobW9kdWxlLT5zaHV0ZG93bkZ1bmMgPT0gc2h1dGRvd25GdW5jKSkKKyAgICAgICAgICAgIHJldCA9IDA7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldCA9IC0xOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorICAgIG1vZHVsZSA9IHhzbHROZXdFeHRNb2R1bGUoaW5pdEZ1bmMsIHNodXRkb3duRnVuYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlSW5pdEZ1bmMsIHN0eWxlU2h1dGRvd25GdW5jKTsKKyAgICBpZiAobW9kdWxlID09IE5VTEwpIHsKKyAgICAgICAgcmV0ID0gLTE7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisgICAgcmV0ID0geG1sSGFzaEFkZEVudHJ5KHhzbHRFeHRlbnNpb25zSGFzaCwgVVJJLCAodm9pZCAqKSBtb2R1bGUpOworCitkb25lOgorICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisgICAgcmV0dXJuIChyZXQpOworfQorCisvKioKKyAqIHhzbHRSZWdpc3RlckV4dE1vZHVsZToKKyAqIEBVUkk6ICBVUkkgYXNzb2NpYXRlZCB0byB0aGlzIG1vZHVsZQorICogQGluaXRGdW5jOiAgdGhlIG1vZHVsZSBpbml0aWFsaXphdGlvbiBmdW5jdGlvbgorICogQHNodXRkb3duRnVuYzogIHRoZSBtb2R1bGUgc2h1dGRvd24gZnVuY3Rpb24KKyAqCisgKiBSZWdpc3RlciBhbiBYU0xUIGV4dGVuc2lvbiBtb2R1bGUgdG8gdGhlIGxpYnJhcnkuCisgKgorICogUmV0dXJucyAwIGlmIHN1Y2Vzc2Z1bCwgLTEgaW4gY2FzZSBvZiBlcnJvcgorICovCitpbnQKK3hzbHRSZWdpc3RlckV4dE1vZHVsZShjb25zdCB4bWxDaGFyICogVVJJLAorICAgICAgICAgICAgICAgICAgICAgIHhzbHRFeHRJbml0RnVuY3Rpb24gaW5pdEZ1bmMsCisgICAgICAgICAgICAgICAgICAgICAgeHNsdEV4dFNodXRkb3duRnVuY3Rpb24gc2h1dGRvd25GdW5jKQoreworICAgIHJldHVybiB4c2x0UmVnaXN0ZXJFeHRNb2R1bGVGdWxsKFVSSSwgaW5pdEZ1bmMsIHNodXRkb3duRnVuYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKK30KKworLyoqCisgKiB4c2x0VW5yZWdpc3RlckV4dE1vZHVsZToKKyAqIEBVUkk6ICBVUkkgYXNzb2NpYXRlZCB0byB0aGlzIG1vZHVsZQorICoKKyAqIFVucmVnaXN0ZXIgYW4gWFNMVCBleHRlbnNpb24gbW9kdWxlIGZyb20gdGhlIGxpYnJhcnkuCisgKgorICogUmV0dXJucyAwIGlmIHN1Y2Vzc2Z1bCwgLTEgaW4gY2FzZSBvZiBlcnJvcgorICovCitpbnQKK3hzbHRVbnJlZ2lzdGVyRXh0TW9kdWxlKGNvbnN0IHhtbENoYXIgKiBVUkkpCit7CisgICAgaW50IHJldDsKKworICAgIGlmIChVUkkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuICgtMSk7CisgICAgaWYgKHhzbHRFeHRlbnNpb25zSGFzaCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKC0xKTsKKworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgcmV0ID0geG1sSGFzaFJlbW92ZUVudHJ5KHhzbHRFeHRlbnNpb25zSGFzaCwgVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4c2x0RnJlZUV4dE1vZHVsZSk7CisKKyAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgcmV0dXJuIChyZXQpOworfQorCisvKioKKyAqIHhzbHRVbnJlZ2lzdGVyQWxsRXh0TW9kdWxlczoKKyAqCisgKiBVbnJlZ2lzdGVyIGFsbCB0aGUgWFNMVCBleHRlbnNpb24gbW9kdWxlIGZyb20gdGhlIGxpYnJhcnkuCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0VW5yZWdpc3RlckFsbEV4dE1vZHVsZXModm9pZCkKK3sKKyAgICBpZiAoeHNsdEV4dGVuc2lvbnNIYXNoID09IE5VTEwpCisgICAgICAgIHJldHVybjsKKworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgeG1sSGFzaEZyZWUoeHNsdEV4dGVuc2lvbnNIYXNoLAorICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhzbHRGcmVlRXh0TW9kdWxlKTsKKyAgICB4c2x0RXh0ZW5zaW9uc0hhc2ggPSBOVUxMOworCisgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKK30KKworLyoqCisgKiB4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0OgorICogQGN0eHQ6ICBhbiBYUGF0aCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogUHJvdmlkZXMgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dCBmcm9tIHRoZSBYUGF0aCB0cmFuc2Zvcm1hdGlvbgorICogY29udGV4dC4gVGhpcyBpcyB1c2VmdWwgd2hlbiBhbiBYUGF0aCBmdW5jdGlvbiBpbiB0aGUgZXh0ZW5zaW9uIG1vZHVsZQorICogaXMgY2FsbGVkIGJ5IHRoZSBYUGF0aCBpbnRlcnByZXRlciBhbmQgdGhhdCB0aGUgWFNMVCBjb250ZXh0IGlzIG5lZWRlZAorICogZm9yIGV4YW1wbGUgdG8gcmV0cmlldmUgdGhlIGFzc29jaWF0ZWQgZGF0YSBwZXJ0YWluaW5nIHRvIHRoaXMgWFNMVAorICogdHJhbnNmb3JtYXRpb24uCisgKgorICogUmV0dXJucyB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KKyAqLworeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIKK3hzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQpCit7CisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChjdHh0LT5jb250ZXh0ID09IE5VTEwpKQorICAgICAgICByZXR1cm4gKE5VTEwpOworICAgIHJldHVybiAoY3R4dC0+Y29udGV4dC0+ZXh0cmEpOworfQorCisvKioKKyAqIHhzbHRSZWdpc3RlckV4dE1vZHVsZUZ1bmN0aW9uOgorICogQG5hbWU6ICB0aGUgZnVuY3Rpb24gbmFtZQorICogQFVSSTogIHRoZSBmdW5jdGlvbiBuYW1lc3BhY2UgVVJJCisgKiBAZnVuY3Rpb246ICB0aGUgZnVuY3Rpb24gY2FsbGJhY2sKKyAqCisgKiBSZWdpc3RlcnMgYW4gZXh0ZW5zaW9uIG1vZHVsZSBmdW5jdGlvbi4KKyAqCisgKiBSZXR1cm5zIDAgaWYgc3VjY2Vzc2Z1bCwgLTEgaW4gY2FzZSBvZiBlcnJvci4KKyAqLworaW50Cit4c2x0UmVnaXN0ZXJFeHRNb2R1bGVGdW5jdGlvbihjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIFVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFhQYXRoRnVuY3Rpb24gZnVuY3Rpb24pCit7CisgICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkgfHwgKGZ1bmN0aW9uID09IE5VTEwpKQorICAgICAgICByZXR1cm4gKC0xKTsKKworICAgIGlmICh4c2x0RnVuY3Rpb25zSGFzaCA9PSBOVUxMKQorICAgICAgICB4c2x0RnVuY3Rpb25zSGFzaCA9IHhtbEhhc2hDcmVhdGUoMTApOworICAgIGlmICh4c2x0RnVuY3Rpb25zSGFzaCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKC0xKTsKKworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgeG1sSGFzaFVwZGF0ZUVudHJ5Mih4c2x0RnVuY3Rpb25zSGFzaCwgbmFtZSwgVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgWE1MX0NBU1RfRlBUUihmdW5jdGlvbiksIE5VTEwpOworCisgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKKworICAgIHJldHVybiAoMCk7Cit9CisKKy8qKgorICogeHNsdEV4dE1vZHVsZUZ1bmN0aW9uTG9va3VwOgorICogQG5hbWU6ICB0aGUgZnVuY3Rpb24gbmFtZQorICogQFVSSTogIHRoZSBmdW5jdGlvbiBuYW1lc3BhY2UgVVJJCisgKgorICogTG9va3MgdXAgYW4gZXh0ZW5zaW9uIG1vZHVsZSBmdW5jdGlvbgorICoKKyAqIFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGZvdW5kLCBOVUxMIG90aGVyd2lzZS4KKyAqLworeG1sWFBhdGhGdW5jdGlvbgoreHNsdEV4dE1vZHVsZUZ1bmN0aW9uTG9va3VwKGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogVVJJKQoreworICAgIHhtbFhQYXRoRnVuY3Rpb24gcmV0OworCisgICAgaWYgKCh4c2x0RnVuY3Rpb25zSGFzaCA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSB8fCAoVVJJID09IE5VTEwpKQorICAgICAgICByZXR1cm4gKE5VTEwpOworCisgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICBYTUxfQ0FTVF9GUFRSKHJldCkgPSB4bWxIYXNoTG9va3VwMih4c2x0RnVuY3Rpb25zSGFzaCwgbmFtZSwgVVJJKTsKKworICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICAvKiBpZiBsb29rdXAgZmFpbHMsIGF0dGVtcHQgYSBkeW5hbWljIGxvYWQgb24gc3VwcG9ydGVkIHBsYXRmb3JtcyAqLworICAgIGlmIChOVUxMID09IHJldCkgeworICAgICAgICBpZiAoIXhzbHRFeHRNb2R1bGVSZWdpc3RlckR5bmFtaWMoVVJJKSkgeworICAgICAgICAgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICAgICAgICAgIFhNTF9DQVNUX0ZQVFIocmV0KSA9CisgICAgICAgICAgICAgICAgeG1sSGFzaExvb2t1cDIoeHNsdEZ1bmN0aW9uc0hhc2gsIG5hbWUsIFVSSSk7CisKKyAgICAgICAgICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gcmV0OworfQorCisvKioKKyAqIHhzbHRVbnJlZ2lzdGVyRXh0TW9kdWxlRnVuY3Rpb246CisgKiBAbmFtZTogIHRoZSBmdW5jdGlvbiBuYW1lCisgKiBAVVJJOiAgdGhlIGZ1bmN0aW9uIG5hbWVzcGFjZSBVUkkKKyAqCisgKiBVbnJlZ2lzdGVycyBhbiBleHRlbnNpb24gbW9kdWxlIGZ1bmN0aW9uCisgKgorICogUmV0dXJucyAwIGlmIHN1Y2Nlc3NmdWwsIC0xIGluIGNhc2Ugb2YgZXJyb3IuCisgKi8KK2ludAoreHNsdFVucmVnaXN0ZXJFeHRNb2R1bGVGdW5jdGlvbihjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIFVSSSkKK3sKKyAgICBpbnQgcmV0OworCisgICAgaWYgKCh4c2x0RnVuY3Rpb25zSGFzaCA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSB8fCAoVVJJID09IE5VTEwpKQorICAgICAgICByZXR1cm4gKC0xKTsKKworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgcmV0ID0geG1sSGFzaFJlbW92ZUVudHJ5Mih4c2x0RnVuY3Rpb25zSGFzaCwgbmFtZSwgVVJJLCBOVUxMKTsKKworICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICByZXR1cm4ocmV0KTsKK30KKworLyoqCisgKiB4c2x0VW5yZWdpc3RlckFsbEV4dE1vZHVsZUZ1bmN0aW9uOgorICoKKyAqIFVucmVnaXN0ZXJzIGFsbCBleHRlbnNpb24gbW9kdWxlIGZ1bmN0aW9uCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0VW5yZWdpc3RlckFsbEV4dE1vZHVsZUZ1bmN0aW9uKHZvaWQpCit7CisgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICB4bWxIYXNoRnJlZSh4c2x0RnVuY3Rpb25zSGFzaCwgTlVMTCk7CisgICAgeHNsdEZ1bmN0aW9uc0hhc2ggPSBOVUxMOworCisgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKK30KKworCisvKioKKyAqIHhzbHROZXdFbGVtUHJlQ29tcDoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIGVsZW1lbnQgbm9kZQorICogQGZ1bmN0aW9uOiB0aGUgdHJhbnNmb3JtIGZ1bmN0aW9uCisgKgorICogQ3JlYXRlcyBhbmQgaW5pdGlhbGl6ZXMgYW4gI3hzbHRFbGVtUHJlQ29tcAorICoKKyAqIFJldHVybnMgdGhlIG5ldyBhbmQgaW5pdGlhbGl6ZWQgI3hzbHRFbGVtUHJlQ29tcAorICovCit4c2x0RWxlbVByZUNvbXBQdHIKK3hzbHROZXdFbGVtUHJlQ29tcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBpbnN0LAorICAgICAgICAgICAgICAgICAgIHhzbHRUcmFuc2Zvcm1GdW5jdGlvbiBmdW5jdGlvbikKK3sKKyAgICB4c2x0RWxlbVByZUNvbXBQdHIgY3VyOworCisgICAgY3VyID0gKHhzbHRFbGVtUHJlQ29tcFB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0RWxlbVByZUNvbXApKTsKKyAgICBpZiAoY3VyID09IE5VTEwpIHsKKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHROZXdFeHRFbGVtZW50IDogbWFsbG9jIGZhaWxlZFxuIik7CisgICAgICAgIHJldHVybiAoTlVMTCk7CisgICAgfQorICAgIG1lbXNldChjdXIsIDAsIHNpemVvZih4c2x0RWxlbVByZUNvbXApKTsKKworICAgIHhzbHRJbml0RWxlbVByZUNvbXAoY3VyLCBzdHlsZSwgaW5zdCwgZnVuY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAoeHNsdEVsZW1QcmVDb21wRGVhbGxvY2F0b3IpIHhtbEZyZWUpOworCisgICAgcmV0dXJuIChjdXIpOworfQorCisvKioKKyAqIHhzbHRJbml0RWxlbVByZUNvbXA6CisgKiBAY29tcDogIGFuICN4c2x0RWxlbVByZUNvbXAgKG9yIGdlbmVyYWxseSBhIGRlcml2ZWQgc3RydWN0dXJlKQorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICogQGluc3Q6ICB0aGUgZWxlbWVudCBub2RlCisgKiBAZnVuY3Rpb246ICB0aGUgdHJhbnNmb3JtIGZ1bmN0aW9uCisgKiBAZnJlZUZ1bmM6ICB0aGUgQGNvbXAgZGVhbGxvY2F0b3IKKyAqCisgKiBJbml0aWFsaXplcyBhbiBleGlzdGluZyAjeHNsdEVsZW1QcmVDb21wIHN0cnVjdHVyZS4gVGhpcyBpcyB1c2VmdWxsCisgKiB3aGVuIGV4dGVuZGluZyBhbiAjeHNsdEVsZW1QcmVDb21wIHRvIHN0b3JlIHByZWNvbXB1dGVkIGRhdGEuCisgKiBUaGlzIGZ1bmN0aW9uIE1VU1QgYmUgY2FsbGVkIG9uIGFueSBleHRlbnNpb24gZWxlbWVudCBwcmVjb21wdXRlZAorICogZGF0YSBzdHJ1Y3QuCisgKi8KK3ZvaWQKK3hzbHRJbml0RWxlbVByZUNvbXAoeHNsdEVsZW1QcmVDb21wUHRyIGNvbXAsIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGluc3QsIHhzbHRUcmFuc2Zvcm1GdW5jdGlvbiBmdW5jdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgeHNsdEVsZW1QcmVDb21wRGVhbGxvY2F0b3IgZnJlZUZ1bmMpCit7CisgICAgY29tcC0+dHlwZSA9IFhTTFRfRlVOQ19FWFRFTlNJT047CisgICAgY29tcC0+ZnVuYyA9IGZ1bmN0aW9uOworICAgIGNvbXAtPmluc3QgPSBpbnN0OworICAgIGNvbXAtPmZyZWUgPSBmcmVlRnVuYzsKKworICAgIGNvbXAtPm5leHQgPSBzdHlsZS0+cHJlQ29tcHM7CisgICAgc3R5bGUtPnByZUNvbXBzID0gY29tcDsKK30KKworLyoqCisgKiB4c2x0UHJlQ29tcHV0ZUV4dE1vZHVsZUVsZW1lbnQ6CisgKiBAc3R5bGU6ICB0aGUgc3R5bGVzaGVldAorICogQGluc3Q6ICB0aGUgZWxlbWVudCBub2RlCisgKgorICogUHJlY29tcHV0ZXMgYW4gZXh0ZW5zaW9uIG1vZHVsZSBlbGVtZW50CisgKgorICogUmV0dXJucyB0aGUgcHJlY29tcHV0ZWQgZGF0YQorICovCit4c2x0RWxlbVByZUNvbXBQdHIKK3hzbHRQcmVDb21wdXRlRXh0TW9kdWxlRWxlbWVudCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBpbnN0KQoreworICAgIHhzbHRFeHRFbGVtZW50UHRyIGV4dDsKKyAgICB4c2x0RWxlbVByZUNvbXBQdHIgY29tcCA9IE5VTEw7CisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpIHx8CisgICAgICAgIChpbnN0LT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpIHx8IChpbnN0LT5ucyA9PSBOVUxMKSkKKyAgICAgICAgcmV0dXJuIChOVUxMKTsKKworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgZXh0ID0gKHhzbHRFeHRFbGVtZW50UHRyKQorICAgICAgICB4bWxIYXNoTG9va3VwMih4c2x0RWxlbWVudHNIYXNoLCBpbnN0LT5uYW1lLCBpbnN0LT5ucy0+aHJlZik7CisKKyAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgLyoKKyAgICAqIEVYVCBUT0RPOiBOb3cgd2hhdD8KKyAgICAqLworICAgIGlmIChleHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIChOVUxMKTsKKworICAgIGlmIChleHQtPnByZWNvbXAgIT0gTlVMTCkgeworCS8qCisJKiBSRVZJU0lUIFRPRE86IENoZWNrIGlmIHRoZSB0ZXh0IGJlbG93IGlzIGNvcnJlY3QuCisJKiBUaGlzIHdpbGwgcmV0dXJuIGEgeHNsdEVsZW1QcmVDb21wIHN0cnVjdHVyZSBvciBOVUxMLgorCSogMSkgSWYgdGhlIHRoZSBhdXRob3Igb2YgdGhlIGV4dGVuc2lvbiBuZWVkcyBhCisJKiAgY3VzdG9tIHN0cnVjdHVyZSB0byBob2xkIHRoZSBzcGVjaWZpYyB2YWx1ZXMgb2YKKwkqICB0aGlzIGV4dGVuc2lvbiwgaGUgd2lsbCBkZXJpdmUgYSBzdHJ1Y3R1cmUgYmFzZWQgb24KKwkqICB4c2x0RWxlbVByZUNvbXA7IHRodXMgd2Ugb2J2aW91c2x5ICpjYW5ub3QqIHJlZmFjdG9yCisJKiAgdGhlIHhzbHRFbGVtUHJlQ29tcCBzdHJ1Y3R1cmUsIHNpbmNlIGFsbCBhbHJlYWR5IGRlcml2ZWQKKwkqICB1c2VyLWRlZmluZWQgc3RydWN1cmVzIHdpbGwgYnJlYWsuCisJKiAgRXhhbXBsZTogRm9yIHRoZSBleHRlbnNpb24geHNsOmRvY3VtZW50LAorCSogICBpbiB4c2x0RG9jdW1lbnRDb21wKCkgKHByZXByb2MuYyksIHRoZSBzdHJ1Y3R1cmUKKwkqICAgeHNsdFN0eWxlSXRlbURvY3VtZW50IGlzIGFsbG9jYXRlZCwgZmlsbGVkIHdpdGgKKwkqICAgc3BlY2lmaWMgdmFsdWVzIGFuZCByZXR1cm5lZC4KKwkqIDIpIElmIHRoZSBhdXRob3IgbmVlZHMgbm8gdmFsdWVzIHRvIGJlIHN0b3JlZCBpbgorCSogIHRoaXMgc3RydWN0dXJlLCB0aGVuIGhlJ2xsIHJldHVybiBOVUxMOworCSovCisgICAgICAgIGNvbXAgPSBleHQtPnByZWNvbXAoc3R5bGUsIGluc3QsIGV4dC0+dHJhbnNmb3JtKTsKKyAgICB9CisgICAgaWYgKGNvbXAgPT0gTlVMTCkgeworCS8qCisJKiBEZWZhdWx0IGNyZWF0aW9uIG9mIGEgeHNsdEVsZW1QcmVDb21wIHN0cnVjdHVyZSwgaWYKKwkqIHRoZSBhdXRob3Igb2YgdGhpcyBleHRlbnNpb24gZGlkIG5vdCBjcmVhdGUgYSBjdXN0b20KKwkqIHN0cnVjdHVyZS4KKwkqLworICAgICAgICBjb21wID0geHNsdE5ld0VsZW1QcmVDb21wKHN0eWxlLCBpbnN0LCBleHQtPnRyYW5zZm9ybSk7CisgICAgfQorCisgICAgcmV0dXJuIChjb21wKTsKK30KKworLyoqCisgKiB4c2x0UmVnaXN0ZXJFeHRNb2R1bGVFbGVtZW50OgorICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lCisgKiBAVVJJOiAgdGhlIGVsZW1lbnQgbmFtZXNwYWNlIFVSSQorICogQHByZWNvbXA6ICB0aGUgcHJlLWNvbXB1dGF0aW9uIGNhbGxiYWNrCisgKiBAdHJhbnNmb3JtOiAgdGhlIHRyYW5zZm9ybWF0aW9uIGNhbGxiYWNrCisgKgorICogUmVnaXN0ZXJzIGFuIGV4dGVuc2lvbiBtb2R1bGUgZWxlbWVudC4KKyAqCisgKiBSZXR1cm5zIDAgaWYgc3VjY2Vzc2Z1bCwgLTEgaW4gY2FzZSBvZiBlcnJvci4KKyAqLworaW50Cit4c2x0UmVnaXN0ZXJFeHRNb2R1bGVFbGVtZW50KGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0UHJlQ29tcHV0ZUZ1bmN0aW9uIHByZWNvbXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRUcmFuc2Zvcm1GdW5jdGlvbiB0cmFuc2Zvcm0pCit7CisgICAgaW50IHJldDsKKworICAgIHhzbHRFeHRFbGVtZW50UHRyIGV4dDsKKworICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoVVJJID09IE5VTEwpIHx8ICh0cmFuc2Zvcm0gPT0gTlVMTCkpCisgICAgICAgIHJldHVybiAoLTEpOworCisgICAgaWYgKHhzbHRFbGVtZW50c0hhc2ggPT0gTlVMTCkKKyAgICAgICAgeHNsdEVsZW1lbnRzSGFzaCA9IHhtbEhhc2hDcmVhdGUoMTApOworICAgIGlmICh4c2x0RWxlbWVudHNIYXNoID09IE5VTEwpCisgICAgICAgIHJldHVybiAoLTEpOworCisgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICBleHQgPSB4c2x0TmV3RXh0RWxlbWVudChwcmVjb21wLCB0cmFuc2Zvcm0pOworICAgIGlmIChleHQgPT0gTlVMTCkgeworICAgICAgICByZXQgPSAtMTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworICAgIHhtbEhhc2hVcGRhdGVFbnRyeTIoeHNsdEVsZW1lbnRzSGFzaCwgbmFtZSwgVVJJLCAodm9pZCAqKSBleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4c2x0RnJlZUV4dEVsZW1lbnQpOworCitkb25lOgorICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICByZXR1cm4gKDApOworfQorCisvKioKKyAqIHhzbHRFeHRFbGVtZW50TG9va3VwOgorICogQGN0eHQ6ICBhbiBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lCisgKiBAVVJJOiAgdGhlIGVsZW1lbnQgbmFtZXNwYWNlIFVSSQorICoKKyAqIExvb2tzIHVwIGFuIGV4dGVuc2lvbiBlbGVtZW50LiBAY3R4dCBjYW4gYmUgTlVMTCB0byBzZWFyY2ggb25seSBpbgorICogbW9kdWxlIGVsZW1lbnRzLgorICoKKyAqIFJldHVybnMgdGhlIGVsZW1lbnQgY2FsbGJhY2sgb3IgTlVMTCBpZiBub3QgZm91bmQKKyAqLworeHNsdFRyYW5zZm9ybUZ1bmN0aW9uCit4c2x0RXh0RWxlbWVudExvb2t1cCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUsIGNvbnN0IHhtbENoYXIgKiBVUkkpCit7CisgICAgeHNsdFRyYW5zZm9ybUZ1bmN0aW9uIHJldDsKKworICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoVVJJID09IE5VTEwpKQorICAgICAgICByZXR1cm4gKE5VTEwpOworCisgICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT5leHRFbGVtZW50cyAhPSBOVUxMKSkgeworICAgICAgICBYTUxfQ0FTVF9GUFRSKHJldCkgPSB4bWxIYXNoTG9va3VwMihjdHh0LT5leHRFbGVtZW50cywgbmFtZSwgVVJJKTsKKyAgICAgICAgaWYgKHJldCAhPSBOVUxMKSB7CisgICAgICAgICAgICByZXR1cm4ocmV0KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldCA9IHhzbHRFeHRNb2R1bGVFbGVtZW50TG9va3VwKG5hbWUsIFVSSSk7CisKKyAgICByZXR1cm4gKHJldCk7Cit9CisKKy8qKgorICogeHNsdEV4dE1vZHVsZUVsZW1lbnRMb29rdXA6CisgKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUKKyAqIEBVUkk6ICB0aGUgZWxlbWVudCBuYW1lc3BhY2UgVVJJCisgKgorICogTG9va3MgdXAgYW4gZXh0ZW5zaW9uIG1vZHVsZSBlbGVtZW50CisgKgorICogUmV0dXJucyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gaWYgZm91bmQsIE5VTEwgb3RoZXJ3aXNlLgorICovCit4c2x0VHJhbnNmb3JtRnVuY3Rpb24KK3hzbHRFeHRNb2R1bGVFbGVtZW50TG9va3VwKGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogVVJJKQoreworICAgIHhzbHRFeHRFbGVtZW50UHRyIGV4dDsKKworICAgIGlmICgoeHNsdEVsZW1lbnRzSGFzaCA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSB8fCAoVVJJID09IE5VTEwpKQorICAgICAgICByZXR1cm4gKE5VTEwpOworCisgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICBleHQgPSAoeHNsdEV4dEVsZW1lbnRQdHIpIHhtbEhhc2hMb29rdXAyKHhzbHRFbGVtZW50c0hhc2gsIG5hbWUsIFVSSSk7CisKKyAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgLyoKKyAgICAgKiBpZiBmdW5jdGlvbiBsb29rdXAgZmFpbHMsIGF0dGVtcHQgYSBkeW5hbWljIGxvYWQgb24KKyAgICAgKiBzdXBwb3J0ZWQgcGxhdGZvcm1zCisgICAgICovCisgICAgaWYgKE5VTEwgPT0gZXh0KSB7CisgICAgICAgIGlmICgheHNsdEV4dE1vZHVsZVJlZ2lzdGVyRHluYW1pYyhVUkkpKSB7CisgICAgICAgICAgICB4bWxNdXRleExvY2soeHNsdEV4dE11dGV4KTsKKworICAgICAgICAgICAgZXh0ID0gKHhzbHRFeHRFbGVtZW50UHRyKQorCSAgICAgICAgICB4bWxIYXNoTG9va3VwMih4c2x0RWxlbWVudHNIYXNoLCBuYW1lLCBVUkkpOworCisgICAgICAgICAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKGV4dCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKE5VTEwpOworICAgIHJldHVybiAoZXh0LT50cmFuc2Zvcm0pOworfQorCisvKioKKyAqIHhzbHRFeHRNb2R1bGVFbGVtZW50UHJlQ29tcHV0ZUxvb2t1cDoKKyAqIEBuYW1lOiAgdGhlIGVsZW1lbnQgbmFtZQorICogQFVSSTogIHRoZSBlbGVtZW50IG5hbWVzcGFjZSBVUkkKKyAqCisgKiBMb29rcyB1cCBhbiBleHRlbnNpb24gbW9kdWxlIGVsZW1lbnQgcHJlLWNvbXB1dGF0aW9uIGZ1bmN0aW9uCisgKgorICogUmV0dXJucyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gaWYgZm91bmQsIE5VTEwgb3RoZXJ3aXNlLgorICovCit4c2x0UHJlQ29tcHV0ZUZ1bmN0aW9uCit4c2x0RXh0TW9kdWxlRWxlbWVudFByZUNvbXB1dGVMb29rdXAoY29uc3QgeG1sQ2hhciAqIG5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIFVSSSkKK3sKKyAgICB4c2x0RXh0RWxlbWVudFB0ciBleHQ7CisKKyAgICBpZiAoKHhzbHRFbGVtZW50c0hhc2ggPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkgfHwgKFVSSSA9PSBOVUxMKSkKKyAgICAgICAgcmV0dXJuIChOVUxMKTsKKworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgZXh0ID0gKHhzbHRFeHRFbGVtZW50UHRyKSB4bWxIYXNoTG9va3VwMih4c2x0RWxlbWVudHNIYXNoLCBuYW1lLCBVUkkpOworCisgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKKworICAgIGlmIChleHQgPT0gTlVMTCkgeworICAgICAgICBpZiAoIXhzbHRFeHRNb2R1bGVSZWdpc3RlckR5bmFtaWMoVVJJKSkgeworICAgICAgICAgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICAgICAgICAgIGV4dCA9ICh4c2x0RXh0RWxlbWVudFB0cikKKwkgICAgICAgICAgeG1sSGFzaExvb2t1cDIoeHNsdEVsZW1lbnRzSGFzaCwgbmFtZSwgVVJJKTsKKworICAgICAgICAgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChleHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIChOVUxMKTsKKyAgICByZXR1cm4gKGV4dC0+cHJlY29tcCk7Cit9CisKKy8qKgorICogeHNsdFVucmVnaXN0ZXJFeHRNb2R1bGVFbGVtZW50OgorICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lCisgKiBAVVJJOiAgdGhlIGVsZW1lbnQgbmFtZXNwYWNlIFVSSQorICoKKyAqIFVucmVnaXN0ZXJzIGFuIGV4dGVuc2lvbiBtb2R1bGUgZWxlbWVudAorICoKKyAqIFJldHVybnMgMCBpZiBzdWNjZXNzZnVsLCAtMSBpbiBjYXNlIG9mIGVycm9yLgorICovCitpbnQKK3hzbHRVbnJlZ2lzdGVyRXh0TW9kdWxlRWxlbWVudChjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIFVSSSkKK3sKKyAgICBpbnQgcmV0OworCisgICAgaWYgKCh4c2x0RWxlbWVudHNIYXNoID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkpCisgICAgICAgIHJldHVybiAoLTEpOworCisgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICByZXQgPSB4bWxIYXNoUmVtb3ZlRW50cnkyKHhzbHRFbGVtZW50c0hhc2gsIG5hbWUsIFVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhzbHRGcmVlRXh0RWxlbWVudCk7CisKKyAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdFVucmVnaXN0ZXJBbGxFeHRNb2R1bGVFbGVtZW50OgorICoKKyAqIFVucmVnaXN0ZXJzIGFsbCBleHRlbnNpb24gbW9kdWxlIGVsZW1lbnQKKyAqLworc3RhdGljIHZvaWQKK3hzbHRVbnJlZ2lzdGVyQWxsRXh0TW9kdWxlRWxlbWVudCh2b2lkKQoreworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgeG1sSGFzaEZyZWUoeHNsdEVsZW1lbnRzSGFzaCwgKHhtbEhhc2hEZWFsbG9jYXRvcikgeHNsdEZyZWVFeHRFbGVtZW50KTsKKyAgICB4c2x0RWxlbWVudHNIYXNoID0gTlVMTDsKKworICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7Cit9CisKKy8qKgorICogeHNsdFJlZ2lzdGVyRXh0TW9kdWxlVG9wTGV2ZWw6CisgKiBAbmFtZTogIHRoZSB0b3AtbGV2ZWwgZWxlbWVudCBuYW1lCisgKiBAVVJJOiAgdGhlIHRvcC1sZXZlbCBlbGVtZW50IG5hbWVzcGFjZSBVUkkKKyAqIEBmdW5jdGlvbjogIHRoZSB0b3AtbGV2ZWwgZWxlbWVudCBjYWxsYmFjaworICoKKyAqIFJlZ2lzdGVycyBhbiBleHRlbnNpb24gbW9kdWxlIHRvcC1sZXZlbCBlbGVtZW50LgorICoKKyAqIFJldHVybnMgMCBpZiBzdWNjZXNzZnVsLCAtMSBpbiBjYXNlIG9mIGVycm9yLgorICovCitpbnQKK3hzbHRSZWdpc3RlckV4dE1vZHVsZVRvcExldmVsKGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeHNsdFRvcExldmVsRnVuY3Rpb24gZnVuY3Rpb24pCit7CisgICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkgfHwgKGZ1bmN0aW9uID09IE5VTEwpKQorICAgICAgICByZXR1cm4gKC0xKTsKKworICAgIGlmICh4c2x0VG9wTGV2ZWxzSGFzaCA9PSBOVUxMKQorICAgICAgICB4c2x0VG9wTGV2ZWxzSGFzaCA9IHhtbEhhc2hDcmVhdGUoMTApOworICAgIGlmICh4c2x0VG9wTGV2ZWxzSGFzaCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKC0xKTsKKworICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworCisgICAgeG1sSGFzaFVwZGF0ZUVudHJ5Mih4c2x0VG9wTGV2ZWxzSGFzaCwgbmFtZSwgVVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgWE1MX0NBU1RfRlBUUihmdW5jdGlvbiksIE5VTEwpOworCisgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKKworICAgIHJldHVybiAoMCk7Cit9CisKKy8qKgorICogeHNsdEV4dE1vZHVsZVRvcExldmVsTG9va3VwOgorICogQG5hbWU6ICB0aGUgdG9wLWxldmVsIGVsZW1lbnQgbmFtZQorICogQFVSSTogIHRoZSB0b3AtbGV2ZWwgZWxlbWVudCBuYW1lc3BhY2UgVVJJCisgKgorICogTG9va3MgdXAgYW4gZXh0ZW5zaW9uIG1vZHVsZSB0b3AtbGV2ZWwgZWxlbWVudAorICoKKyAqIFJldHVybnMgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGlmIGZvdW5kLCBOVUxMIG90aGVyd2lzZS4KKyAqLworeHNsdFRvcExldmVsRnVuY3Rpb24KK3hzbHRFeHRNb2R1bGVUb3BMZXZlbExvb2t1cChjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIFVSSSkKK3sKKyAgICB4c2x0VG9wTGV2ZWxGdW5jdGlvbiByZXQ7CisKKyAgICBpZiAoKHhzbHRUb3BMZXZlbHNIYXNoID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkpCisgICAgICAgIHJldHVybiAoTlVMTCk7CisKKyAgICB4bWxNdXRleExvY2soeHNsdEV4dE11dGV4KTsKKworICAgIFhNTF9DQVNUX0ZQVFIocmV0KSA9IHhtbEhhc2hMb29rdXAyKHhzbHRUb3BMZXZlbHNIYXNoLCBuYW1lLCBVUkkpOworCisgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKKworICAgIC8qIGlmIGxvb2t1cCBmYWlscywgYXR0ZW1wdCBhIGR5bmFtaWMgbG9hZCBvbiBzdXBwb3J0ZWQgcGxhdGZvcm1zICovCisgICAgaWYgKE5VTEwgPT0gcmV0KSB7CisgICAgICAgIGlmICgheHNsdEV4dE1vZHVsZVJlZ2lzdGVyRHluYW1pYyhVUkkpKSB7CisgICAgICAgICAgICB4bWxNdXRleExvY2soeHNsdEV4dE11dGV4KTsKKworICAgICAgICAgICAgWE1MX0NBU1RfRlBUUihyZXQpID0geG1sSGFzaExvb2t1cDIoeHNsdFRvcExldmVsc0hhc2gsIG5hbWUsIFVSSSk7CisKKyAgICAgICAgICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gKHJldCk7Cit9CisKKy8qKgorICogeHNsdFVucmVnaXN0ZXJFeHRNb2R1bGVUb3BMZXZlbDoKKyAqIEBuYW1lOiAgdGhlIHRvcC1sZXZlbCBlbGVtZW50IG5hbWUKKyAqIEBVUkk6ICB0aGUgdG9wLWxldmVsIGVsZW1lbnQgbmFtZXNwYWNlIFVSSQorICoKKyAqIFVucmVnaXN0ZXJzIGFuIGV4dGVuc2lvbiBtb2R1bGUgdG9wLWxldmVsIGVsZW1lbnQKKyAqCisgKiBSZXR1cm5zIDAgaWYgc3VjY2Vzc2Z1bCwgLTEgaW4gY2FzZSBvZiBlcnJvci4KKyAqLworaW50Cit4c2x0VW5yZWdpc3RlckV4dE1vZHVsZVRvcExldmVsKGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogVVJJKQoreworICAgIGludCByZXQ7CisKKyAgICBpZiAoKHhzbHRUb3BMZXZlbHNIYXNoID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpIHx8IChVUkkgPT0gTlVMTCkpCisgICAgICAgIHJldHVybiAoLTEpOworCisgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisKKyAgICByZXQgPSB4bWxIYXNoUmVtb3ZlRW50cnkyKHhzbHRUb3BMZXZlbHNIYXNoLCBuYW1lLCBVUkksIE5VTEwpOworCisgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKKworICAgIHJldHVybihyZXQpOworfQorCisvKioKKyAqIHhzbHRVbnJlZ2lzdGVyQWxsRXh0TW9kdWxlVG9wTGV2ZWw6CisgKgorICogVW5yZWdpc3RlcnMgYWxsIGV4dGVuc2lvbiBtb2R1bGUgZnVuY3Rpb24KKyAqLworc3RhdGljIHZvaWQKK3hzbHRVbnJlZ2lzdGVyQWxsRXh0TW9kdWxlVG9wTGV2ZWwodm9pZCkKK3sKKyAgICB4bWxNdXRleExvY2soeHNsdEV4dE11dGV4KTsKKworICAgIHhtbEhhc2hGcmVlKHhzbHRUb3BMZXZlbHNIYXNoLCBOVUxMKTsKKyAgICB4c2x0VG9wTGV2ZWxzSGFzaCA9IE5VTEw7CisKKyAgICB4bWxNdXRleFVubG9jayh4c2x0RXh0TXV0ZXgpOworfQorCisvKioKKyAqIHhzbHRHZXRFeHRJbmZvOgorICogQHN0eWxlOiAgcG9pbnRlciB0byBhIHN0eWxlc2hlZXQKKyAqIEBVUkk6ICAgIHRoZSBuYW1lc3BhY2UgVVJJIGRlc2lyZWQKKyAqCisgKiBsb29rcyB1cCBVUkkgaW4gZXh0SW5mb3Mgb2YgdGhlIHN0eWxlc2hlZXQKKyAqCisgKiByZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgaGFzaCB0YWJsZSBpZiBmb3VuZCwgZWxzZSBOVUxMCisgKi8KK3htbEhhc2hUYWJsZVB0cgoreHNsdEdldEV4dEluZm8oeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIGNvbnN0IHhtbENoYXIgKiBVUkkpCit7CisgICAgeHNsdEV4dERhdGFQdHIgZGF0YTsKKworICAgIC8qCisgICAgKiBUT0RPOiBXaHkgZG8gd2UgaGF2ZSBhIHJldHVybiB0eXBlIG9mIHhtbEhhc2hUYWJsZVB0cj8KKyAgICAqICAgSXMgdGhlIHVzZXItYWxsb2NhdGVkIGRhdGEgZm9yIGV4dGVuc2lvbiBtb2R1bGVzIGV4cGVjdGVkCisgICAgKiAgIHRvIGJlIGEgeG1sSGFzaFRhYmxlUHRyIG9ubHk/IE9yIGlzIHRoaXMgaW50ZW5kZWQgZm9yCisgICAgKiAgIHRoZSBFWFNMVCBtb2R1bGUgb25seT8KKyAgICAqLworCisgICAgaWYgKHN0eWxlICE9IE5VTEwgJiYgc3R5bGUtPmV4dEluZm9zICE9IE5VTEwpIHsKKyAgICAgICAgZGF0YSA9IHhtbEhhc2hMb29rdXAoc3R5bGUtPmV4dEluZm9zLCBVUkkpOworICAgICAgICBpZiAoZGF0YSAhPSBOVUxMICYmIGRhdGEtPmV4dERhdGEgIT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBkYXRhLT5leHREYXRhOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogCQkJCQkJCQkJKgorICogCQlUZXN0IG1vZHVsZSBodHRwOi8veG1sc29mdC5vcmcvWFNMVC8JCQkqCisgKiAJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAJCQkJCQkJCQkqCisgKiAJCVRlc3Qgb2YgdGhlIGV4dGVuc2lvbiBtb2R1bGUgQVBJCQkJKgorICogCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIHhtbENoYXIgKnRlc3REYXRhID0gTlVMTDsKK3N0YXRpYyB4bWxDaGFyICp0ZXN0U3R5bGVEYXRhID0gTlVMTDsKKworLyoqCisgKiB4c2x0RXh0RnVuY3Rpb25UZXN0OgorICogQGN0eHQ6ICB0aGUgWFBhdGggUGFyc2VyIGNvbnRleHQKKyAqIEBuYXJnczogIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzCisgKgorICogZnVuY3Rpb24gbGlieHNsdDp0ZXN0KCkgZm9yIHRlc3RpbmcgdGhlIGV4dGVuc2lvbnMgc3VwcG9ydC4KKyAqLworc3RhdGljIHZvaWQKK3hzbHRFeHRGdW5jdGlvblRlc3QoeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQsCisgICAgICAgICAgICAgICAgICAgIGludCBuYXJncyBBVFRSSUJVVEVfVU5VU0VEKQoreworICAgIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIHRjdHh0OworICAgIHZvaWQgKmRhdGEgPSBOVUxMOworCisgICAgdGN0eHQgPSB4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpOworCisgICAgaWYgKHRlc3REYXRhID09IE5VTEwpIHsKKyAgICAgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEV4dEZ1bmN0aW9uVGVzdDogbm90IGluaXRpYWxpemVkLCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiIGNhbGxpbmcgeHNsdEdldEV4dERhdGFcbiIpOworICAgICAgICBkYXRhID0geHNsdEdldEV4dERhdGEodGN0eHQsIChjb25zdCB4bWxDaGFyICopIFhTTFRfREVGQVVMVF9VUkwpOworICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKSB7CisgICAgICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IodGN0eHQsIE5VTEwsIE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRFbGVtZW50VGVzdDogbm90IGluaXRpYWxpemVkXG4iKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAodGN0eHQgPT0gTlVMTCkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoeHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dChjdHh0KSwgTlVMTCwgTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0RXh0RnVuY3Rpb25UZXN0OiBmYWlsZWQgdG8gZ2V0IHRoZSB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0XG4iKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoZGF0YSA9PSBOVUxMKQorICAgICAgICBkYXRhID0geHNsdEdldEV4dERhdGEodGN0eHQsIChjb25zdCB4bWxDaGFyICopIFhTTFRfREVGQVVMVF9VUkwpOworICAgIGlmIChkYXRhID09IE5VTEwpIHsKKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEV4dEZ1bmN0aW9uVGVzdDogZmFpbGVkIHRvIGdldCBtb2R1bGUgZGF0YVxuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGRhdGEgIT0gdGVzdERhdGEpIHsKKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEV4dEZ1bmN0aW9uVGVzdDogZ290IHdyb25nIG1vZHVsZSBkYXRhXG4iKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRlVOQ1RJT04KKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgImxpYnhzbHQ6dGVzdCgpIGNhbGxlZCB3aXRoICVkIGFyZ3NcbiIsIG5hcmdzKTsKKyNlbmRpZgorfQorCisvKioKKyAqIHhzbHRFeHRFbGVtZW50UHJlQ29tcFRlc3Q6CisgKiBAc3R5bGU6ICB0aGUgc3R5bGVzaGVldAorICogQGluc3Q6ICB0aGUgaW5zdHJ1Y3Rpb24gaW4gdGhlIHN0eWxlc2hlZXQKKyAqCisgKiBQcm9jZXNzIGEgbGlieHNsdDp0ZXN0IG5vZGUKKyAqLworc3RhdGljIHhzbHRFbGVtUHJlQ29tcFB0cgoreHNsdEV4dEVsZW1lbnRQcmVDb21wVGVzdCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBpbnN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0VHJhbnNmb3JtRnVuY3Rpb24gZnVuY3Rpb24pCit7CisgICAgeHNsdEVsZW1QcmVDb21wUHRyIHJldDsKKworICAgIGlmIChzdHlsZSA9PSBOVUxMKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBpbnN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRFbGVtZW50VGVzdDogbm8gdHJhbnNmb3JtYXRpb24gY29udGV4dFxuIik7CisgICAgICAgIHJldHVybiAoTlVMTCk7CisgICAgfQorICAgIGlmICh0ZXN0U3R5bGVEYXRhID09IE5VTEwpIHsKKyAgICAgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEV4dEVsZW1lbnRQcmVDb21wVGVzdDogbm90IGluaXRpYWxpemVkLCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiIGNhbGxpbmcgeHNsdFN0eWxlR2V0RXh0RGF0YVxuIik7CisgICAgICAgIHhzbHRTdHlsZUdldEV4dERhdGEoc3R5bGUsIChjb25zdCB4bWxDaGFyICopIFhTTFRfREVGQVVMVF9VUkwpOworICAgICAgICBpZiAodGVzdFN0eWxlRGF0YSA9PSBOVUxMKSB7CisgICAgICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRFbGVtZW50UHJlQ29tcFRlc3Q6IG5vdCBpbml0aWFsaXplZFxuIik7CisgICAgICAgICAgICBpZiAoc3R5bGUgIT0gTlVMTCkKKyAgICAgICAgICAgICAgICBzdHlsZS0+ZXJyb3JzKys7CisgICAgICAgICAgICByZXR1cm4gKE5VTEwpOworICAgICAgICB9CisgICAgfQorICAgIGlmIChpbnN0ID09IE5VTEwpIHsKKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRFbGVtZW50UHJlQ29tcFRlc3Q6IG5vIGluc3RydWN0aW9uXG4iKTsKKyAgICAgICAgaWYgKHN0eWxlICE9IE5VTEwpCisgICAgICAgICAgICBzdHlsZS0+ZXJyb3JzKys7CisgICAgICAgIHJldHVybiAoTlVMTCk7CisgICAgfQorICAgIHJldCA9IHhzbHROZXdFbGVtUHJlQ29tcChzdHlsZSwgaW5zdCwgZnVuY3Rpb24pOworICAgIHJldHVybiAocmV0KTsKK30KKworLyoqCisgKiB4c2x0RXh0RWxlbWVudFRlc3Q6CisgKiBAY3R4dDogIGFuIFhTTFQgcHJvY2Vzc2luZyBjb250ZXh0CisgKiBAbm9kZTogIFRoZSBjdXJyZW50IG5vZGUKKyAqIEBpbnN0OiAgdGhlIGluc3RydWN0aW9uIGluIHRoZSBzdHlsZXNoZWV0CisgKiBAY29tcDogIHByZWNvbXB1dGVkIGluZm9ybWF0aW9ucworICoKKyAqIFByb2Nlc3MgYSBsaWJ4c2x0OnRlc3Qgbm9kZQorICovCitzdGF0aWMgdm9pZAoreHNsdEV4dEVsZW1lbnRUZXN0KHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKKyAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGluc3QsCisgICAgICAgICAgICAgICAgICAgeHNsdEVsZW1QcmVDb21wUHRyIGNvbXAgQVRUUklCVVRFX1VOVVNFRCkKK3sKKyAgICB4bWxOb2RlUHRyIGNvbW1lbnROb2RlOworCisgICAgaWYgKHRlc3REYXRhID09IE5VTEwpIHsKKyAgICAgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEV4dEVsZW1lbnRUZXN0OiBub3QgaW5pdGlhbGl6ZWQsIgorICAgICAgICAgICAgICAgICAgICAgICAgICIgY2FsbGluZyB4c2x0R2V0RXh0RGF0YVxuIik7CisgICAgICAgIHhzbHRHZXRFeHREYXRhKGN0eHQsIChjb25zdCB4bWxDaGFyICopIFhTTFRfREVGQVVMVF9VUkwpOworICAgICAgICBpZiAodGVzdERhdGEgPT0gTlVMTCkgeworICAgICAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRFbGVtZW50VGVzdDogbm90IGluaXRpYWxpemVkXG4iKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoY3R4dCA9PSBOVUxMKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRFbGVtZW50VGVzdDogbm8gdHJhbnNmb3JtYXRpb24gY29udGV4dFxuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKG5vZGUgPT0gTlVMTCkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0RXh0RWxlbWVudFRlc3Q6IG5vIGN1cnJlbnQgbm9kZVxuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGluc3QgPT0gTlVMTCkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0RXh0RWxlbWVudFRlc3Q6IG5vIGluc3RydWN0aW9uXG4iKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoY3R4dC0+aW5zZXJ0ID09IE5VTEwpIHsKKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEV4dEVsZW1lbnRUZXN0OiBubyBpbnNlcnRpb24gcG9pbnRcbiIpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGNvbW1lbnROb2RlID0geG1sTmV3Q29tbWVudCgoY29uc3QgeG1sQ2hhciAqKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGlieHNsdDp0ZXN0IGVsZW1lbnQgdGVzdCB3b3JrZWQiKTsKKyAgICB4bWxBZGRDaGlsZChjdHh0LT5pbnNlcnQsIGNvbW1lbnROb2RlKTsKK30KKworLyoqCisgKiB4c2x0RXh0SW5pdFRlc3Q6CisgKiBAY3R4dDogIGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQFVSSTogIHRoZSBuYW1lc3BhY2UgVVJJIGZvciB0aGUgZXh0ZW5zaW9uCisgKgorICogQSBmdW5jdGlvbiBjYWxsZWQgYXQgaW5pdGlhbGl6YXRpb24gdGltZSBvZiBhbiBYU0xUIGV4dGVuc2lvbiBtb2R1bGUKKyAqCisgKiBSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgbW9kdWxlIHNwZWNpZmljIGRhdGEgZm9yIHRoaXMgdHJhbnNmb3JtYXRpb24KKyAqLworc3RhdGljIHZvaWQgKgoreHNsdEV4dEluaXRUZXN0KHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBVUkkpCit7CisgICAgaWYgKHRlc3RTdHlsZURhdGEgPT0gTlVMTCkgeworICAgICAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0RXh0SW5pdFRlc3Q6IG5vdCBpbml0aWFsaXplZCwiCisgICAgICAgICAgICAgICAgICAgICAgICAgIiBjYWxsaW5nIHhzbHRTdHlsZUdldEV4dERhdGFcbiIpOworICAgICAgICB0ZXN0U3R5bGVEYXRhID0geHNsdFN0eWxlR2V0RXh0RGF0YShjdHh0LT5zdHlsZSwgVVJJKTsKKyAgICAgICAgaWYgKHRlc3RTdHlsZURhdGEgPT0gTlVMTCkgeworICAgICAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRJbml0VGVzdDogbm90IGluaXRpYWxpemVkXG4iKTsKKyAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKHRlc3REYXRhICE9IE5VTEwpIHsKKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEV4dEluaXRUZXN0OiBhbHJlYWR5IGluaXRpYWxpemVkXG4iKTsKKyAgICAgICAgcmV0dXJuIChOVUxMKTsKKyAgICB9CisgICAgdGVzdERhdGEgPSAodm9pZCAqKSAidGVzdCBkYXRhIjsKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgIlJlZ2lzdGVyZWQgdGVzdCBtb2R1bGUgOiAlc1xuIiwgVVJJKTsKKyAgICByZXR1cm4gKHRlc3REYXRhKTsKK30KKworCisvKioKKyAqIHhzbHRFeHRTaHV0ZG93blRlc3Q6CisgKiBAY3R4dDogIGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQFVSSTogIHRoZSBuYW1lc3BhY2UgVVJJIGZvciB0aGUgZXh0ZW5zaW9uCisgKiBAZGF0YTogIHRoZSBkYXRhIGFzc29jaWF0ZWQgdG8gdGhpcyBtb2R1bGUKKyAqCisgKiBBIGZ1bmN0aW9uIGNhbGxlZCBhdCBzaHV0ZG93biB0aW1lIG9mIGFuIFhTTFQgZXh0ZW5zaW9uIG1vZHVsZQorICovCitzdGF0aWMgdm9pZAoreHNsdEV4dFNodXRkb3duVGVzdCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogVVJJLCB2b2lkICpkYXRhKQoreworICAgIGlmICh0ZXN0RGF0YSA9PSBOVUxMKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRTaHV0ZG93blRlc3Q6IG5vdCBpbml0aWFsaXplZFxuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGRhdGEgIT0gdGVzdERhdGEpIHsKKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEV4dFNodXRkb3duVGVzdDogd3JvbmcgZGF0YVxuIik7CisgICAgfQorICAgIHRlc3REYXRhID0gTlVMTDsKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgIlVucmVnaXN0ZXJlZCB0ZXN0IG1vZHVsZSA6ICVzXG4iLCBVUkkpOworfQorCisvKioKKyAqIHhzbHRFeHRTdHlsZUluaXRUZXN0OgorICogQHN0eWxlOiAgYW4gWFNMVCBzdHlsZXNoZWV0CisgKiBAVVJJOiAgdGhlIG5hbWVzcGFjZSBVUkkgZm9yIHRoZSBleHRlbnNpb24KKyAqCisgKiBBIGZ1bmN0aW9uIGNhbGxlZCBhdCBpbml0aWFsaXphdGlvbiB0aW1lIG9mIGFuIFhTTFQgZXh0ZW5zaW9uIG1vZHVsZQorICoKKyAqIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBtb2R1bGUgc3BlY2lmaWMgZGF0YSBmb3IgdGhpcyB0cmFuc2Zvcm1hdGlvbgorICovCitzdGF0aWMgdm9pZCAqCit4c2x0RXh0U3R5bGVJbml0VGVzdCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSBBVFRSSUJVVEVfVU5VU0VELAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIFVSSSkKK3sKKyAgICBpZiAodGVzdFN0eWxlRGF0YSAhPSBOVUxMKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRJbml0VGVzdDogYWxyZWFkeSBpbml0aWFsaXplZFxuIik7CisgICAgICAgIHJldHVybiAoTlVMTCk7CisgICAgfQorICAgIHRlc3RTdHlsZURhdGEgPSAodm9pZCAqKSAidGVzdCBkYXRhIjsKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgIlJlZ2lzdGVyZWQgdGVzdCBtb2R1bGUgOiAlc1xuIiwgVVJJKTsKKyAgICByZXR1cm4gKHRlc3RTdHlsZURhdGEpOworfQorCisKKy8qKgorICogeHNsdEV4dFN0eWxlU2h1dGRvd25UZXN0OgorICogQHN0eWxlOiAgYW4gWFNMVCBzdHlsZXNoZWV0CisgKiBAVVJJOiAgdGhlIG5hbWVzcGFjZSBVUkkgZm9yIHRoZSBleHRlbnNpb24KKyAqIEBkYXRhOiAgdGhlIGRhdGEgYXNzb2NpYXRlZCB0byB0aGlzIG1vZHVsZQorICoKKyAqIEEgZnVuY3Rpb24gY2FsbGVkIGF0IHNodXRkb3duIHRpbWUgb2YgYW4gWFNMVCBleHRlbnNpb24gbW9kdWxlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0RXh0U3R5bGVTaHV0ZG93blRlc3QoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUgQVRUUklCVVRFX1VOVVNFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogVVJJLCB2b2lkICpkYXRhKQoreworICAgIGlmICh0ZXN0U3R5bGVEYXRhID09IE5VTEwpIHsKKyAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEV4dFNodXRkb3duVGVzdDogbm90IGluaXRpYWxpemVkXG4iKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoZGF0YSAhPSB0ZXN0U3R5bGVEYXRhKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRFeHRTaHV0ZG93blRlc3Q6IHdyb25nIGRhdGFcbiIpOworICAgIH0KKyAgICB0ZXN0U3R5bGVEYXRhID0gTlVMTDsKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgIlVucmVnaXN0ZXJlZCB0ZXN0IG1vZHVsZSA6ICVzXG4iLCBVUkkpOworfQorCisvKioKKyAqIHhzbHRSZWdpc3RlclRlc3RNb2R1bGU6CisgKgorICogUmVnaXN0ZXJzIHRoZSB0ZXN0IG1vZHVsZQorICovCit2b2lkCit4c2x0UmVnaXN0ZXJUZXN0TW9kdWxlKHZvaWQpCit7CisgICAgeHNsdEluaXRHbG9iYWxzKCk7CisgICAgeHNsdFJlZ2lzdGVyRXh0TW9kdWxlRnVsbCgoY29uc3QgeG1sQ2hhciAqKSBYU0xUX0RFRkFVTFRfVVJMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeHNsdEV4dEluaXRUZXN0LCB4c2x0RXh0U2h1dGRvd25UZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeHNsdEV4dFN0eWxlSW5pdFRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0RXh0U3R5bGVTaHV0ZG93blRlc3QpOworICAgIHhzbHRSZWdpc3RlckV4dE1vZHVsZUZ1bmN0aW9uKChjb25zdCB4bWxDaGFyICopICJ0ZXN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgeG1sQ2hhciAqKSBYU0xUX0RFRkFVTFRfVVJMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRFeHRGdW5jdGlvblRlc3QpOworICAgIHhzbHRSZWdpc3RlckV4dE1vZHVsZUVsZW1lbnQoKGNvbnN0IHhtbENoYXIgKikgInRlc3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IHhtbENoYXIgKikgWFNMVF9ERUZBVUxUX1VSTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRFeHRFbGVtZW50UHJlQ29tcFRlc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0RXh0RWxlbWVudFRlc3QpOworfQorCitzdGF0aWMgdm9pZAoreHNsdEhhc2hTY2FubmVyTW9kdWxlRnJlZSh2b2lkICpwYXlsb2FkIEFUVFJJQlVURV9VTlVTRUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmRhdGEgQVRUUklCVVRFX1VOVVNFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKK3sKKyNpZmRlZiBXSVRIX01PRFVMRVMKKyAgICB4bWxNb2R1bGVDbG9zZShwYXlsb2FkKTsKKyNlbmRpZgorfQorCisvKioKKyAqIHhzbHRJbml0R2xvYmFsczoKKyAqCisgKiBJbml0aWFsaXplIHRoZSBnbG9iYWwgdmFyaWFibGVzIGZvciBleHRlbnNpb25zCisgKi8KK3ZvaWQKK3hzbHRJbml0R2xvYmFscyh2b2lkKQoreworICAgIGlmICh4c2x0RXh0TXV0ZXggPT0gTlVMTCkgeworICAgICAgICB4c2x0RXh0TXV0ZXggPSB4bWxOZXdNdXRleCgpOworICAgIH0KK30KKworLyoqCisgKiB4c2x0Q2xlYW51cEdsb2JhbHM6CisgKgorICogVW5yZWdpc3RlciBhbGwgZ2xvYmFsIHZhcmlhYmxlcyBzZXQgdXAgYnkgdGhlIFhTTFQgbGlicmFyeQorICovCit2b2lkCit4c2x0Q2xlYW51cEdsb2JhbHModm9pZCkKK3sKKyAgICB4c2x0VW5yZWdpc3RlckFsbEV4dE1vZHVsZXMoKTsKKyAgICB4c2x0VW5yZWdpc3RlckFsbEV4dE1vZHVsZUZ1bmN0aW9uKCk7CisgICAgeHNsdFVucmVnaXN0ZXJBbGxFeHRNb2R1bGVFbGVtZW50KCk7CisgICAgeHNsdFVucmVnaXN0ZXJBbGxFeHRNb2R1bGVUb3BMZXZlbCgpOworCisgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisgICAgLyogY2xlYW51cCBkeW5hbWljIG1vZHVsZSBoYXNoICovCisgICAgaWYgKE5VTEwgIT0geHNsdE1vZHVsZUhhc2gpIHsKKyAgICAgICAgeG1sSGFzaFNjYW4oeHNsdE1vZHVsZUhhc2gsIHhzbHRIYXNoU2Nhbm5lck1vZHVsZUZyZWUsIDApOworICAgICAgICB4bWxIYXNoRnJlZSh4c2x0TW9kdWxlSGFzaCwgTlVMTCk7CisgICAgICAgIHhzbHRNb2R1bGVIYXNoID0gTlVMTDsKKyAgICB9CisgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKKworICAgIHhtbEZyZWVNdXRleCh4c2x0RXh0TXV0ZXgpOworICAgIHhzbHRFeHRNdXRleCA9IE5VTEw7CisgICAgeHNsdFVuaW5pdCgpOworfQorCitzdGF0aWMgdm9pZAoreHNsdERlYnVnRHVtcEV4dGVuc2lvbnNDYWxsYmFjayh2b2lkICpmdW5jdGlvbiBBVFRSSUJVVEVfVU5VU0VELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFICogb3V0cHV0LCBjb25zdCB4bWxDaGFyICogbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIFVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5vdF91c2VkIEFUVFJJQlVURV9VTlVTRUQpCit7CisgICAgaWYgKCFuYW1lIHx8ICFVUkkpCisgICAgICAgIHJldHVybjsKKyAgICBmcHJpbnRmKG91dHB1dCwgInslc30lc1xuIiwgVVJJLCBuYW1lKTsKK30KKworc3RhdGljIHZvaWQKK3hzbHREZWJ1Z0R1bXBFeHRNb2R1bGVzQ2FsbGJhY2sodm9pZCAqZnVuY3Rpb24gQVRUUklCVVRFX1VOVVNFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRSAqIG91dHB1dCwgY29uc3QgeG1sQ2hhciAqIFVSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5vdF91c2VkIEFUVFJJQlVURV9VTlVTRUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBub3RfdXNlZDIgQVRUUklCVVRFX1VOVVNFRCkKK3sKKyAgICBpZiAoIVVSSSkKKyAgICAgICAgcmV0dXJuOworICAgIGZwcmludGYob3V0cHV0LCAiJXNcbiIsIFVSSSk7Cit9CisKKy8qKgorICogeHNsdERlYnVnRHVtcEV4dGVuc2lvbnM6CisgKiBAb3V0cHV0OiAgdGhlIEZJTEUgKiBmb3IgdGhlIG91dHB1dCwgaWYgTlVMTCBzdGRvdXQgaXMgdXNlZAorICoKKyAqIER1bXBzIGEgbGlzdCBvZiB0aGUgcmVnaXN0ZXJlZCBYU0xUIGV4dGVuc2lvbiBmdW5jdGlvbnMgYW5kIGVsZW1lbnRzCisgKi8KK3ZvaWQKK3hzbHREZWJ1Z0R1bXBFeHRlbnNpb25zKEZJTEUgKiBvdXRwdXQpCit7CisgICAgaWYgKG91dHB1dCA9PSBOVUxMKQorICAgICAgICBvdXRwdXQgPSBzdGRvdXQ7CisgICAgZnByaW50ZihvdXRwdXQsCisgICAgICAgICAgICAiUmVnaXN0ZXJlZCBYU0xUIEV4dGVuc2lvbnNcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKKyAgICBpZiAoIXhzbHRGdW5jdGlvbnNIYXNoKQorICAgICAgICBmcHJpbnRmKG91dHB1dCwgIk5vIHJlZ2lzdGVyZWQgZXh0ZW5zaW9uIGZ1bmN0aW9uc1xuIik7CisgICAgZWxzZSB7CisgICAgICAgIGZwcmludGYob3V0cHV0LCAiUmVnaXN0ZXJlZCBFeHRlbnNpb24gRnVuY3Rpb25zOlxuIik7CisgICAgICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworICAgICAgICB4bWxIYXNoU2NhbkZ1bGwoeHNsdEZ1bmN0aW9uc0hhc2gsCisgICAgICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXJGdWxsKQorICAgICAgICAgICAgICAgICAgICAgICAgeHNsdERlYnVnRHVtcEV4dGVuc2lvbnNDYWxsYmFjaywgb3V0cHV0KTsKKyAgICAgICAgeG1sTXV0ZXhVbmxvY2soeHNsdEV4dE11dGV4KTsKKyAgICB9CisgICAgaWYgKCF4c2x0RWxlbWVudHNIYXNoKQorICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlxuTm8gcmVnaXN0ZXJlZCBleHRlbnNpb24gZWxlbWVudHNcbiIpOworICAgIGVsc2UgeworICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlxuUmVnaXN0ZXJlZCBFeHRlbnNpb24gRWxlbWVudHM6XG4iKTsKKyAgICAgICAgeG1sTXV0ZXhMb2NrKHhzbHRFeHRNdXRleCk7CisgICAgICAgIHhtbEhhc2hTY2FuRnVsbCh4c2x0RWxlbWVudHNIYXNoLAorICAgICAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyRnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHhzbHREZWJ1Z0R1bXBFeHRlbnNpb25zQ2FsbGJhY2ssIG91dHB1dCk7CisgICAgICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisgICAgfQorICAgIGlmICgheHNsdEV4dGVuc2lvbnNIYXNoKQorICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlxuTm8gcmVnaXN0ZXJlZCBleHRlbnNpb24gbW9kdWxlc1xuIik7CisgICAgZWxzZSB7CisgICAgICAgIGZwcmludGYob3V0cHV0LCAiXG5SZWdpc3RlcmVkIEV4dGVuc2lvbiBNb2R1bGVzOlxuIik7CisgICAgICAgIHhtbE11dGV4TG9jayh4c2x0RXh0TXV0ZXgpOworICAgICAgICB4bWxIYXNoU2NhbkZ1bGwoeHNsdEV4dGVuc2lvbnNIYXNoLAorICAgICAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyRnVsbCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHhzbHREZWJ1Z0R1bXBFeHRNb2R1bGVzQ2FsbGJhY2ssIG91dHB1dCk7CisgICAgICAgIHhtbE11dGV4VW5sb2NrKHhzbHRFeHRNdXRleCk7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9saWJ4c2x0L2V4dGVuc2lvbnMuaCBiL2xpYnhzbHQvZXh0ZW5zaW9ucy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwMDc3OWMKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L2V4dGVuc2lvbnMuaApAQCAtMCwwICsxLDI2MiBAQAorLyoKKyAqIFN1bW1hcnk6IGludGVyZmFjZSBmb3IgdGhlIGV4dGVuc2lvbiBzdXBwb3J0CisgKiBEZXNjcmlwdGlvbjogVGhpcyBwcm92aWRlIHRoZSBBUEkgbmVlZGVkIGZvciBzaW1wbGUgYW5kIG1vZHVsZQorICogICAgICAgICAgICAgIGV4dGVuc2lvbiBzdXBwb3J0LgorICoKKyAqIENvcHk6IFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBBdXRob3I6IERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVF9FWFRFTlNJT05fSF9fCisjZGVmaW5lIF9fWE1MX1hTTFRfRVhURU5TSU9OX0hfXworCisjaW5jbHVkZSA8bGlieG1sL3hwYXRoLmg+CisjaW5jbHVkZSAieHNsdGV4cG9ydHMuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyoqCisgKiBFeHRlbnNpb24gTW9kdWxlcyBBUEkuCisgKi8KKworLyoqCisgKiB4c2x0SW5pdEdsb2JhbHM6CisgKgorICogSW5pdGlhbGl6ZSB0aGUgZ2xvYmFsIHZhcmlhYmxlcyBmb3IgZXh0ZW5zaW9ucworICoKKyAqLworCitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdEluaXRHbG9iYWxzICAgICAgICAgICAgICAgICAodm9pZCk7CisKKy8qKgorICogeHNsdFN0eWxlRXh0SW5pdEZ1bmN0aW9uOgorICogQGN0eHQ6ICBhbiBYU0xUIHN0eWxlc2hlZXQKKyAqIEBVUkk6ICB0aGUgbmFtZXNwYWNlIFVSSSBmb3IgdGhlIGV4dGVuc2lvbgorICoKKyAqIEEgZnVuY3Rpb24gY2FsbGVkIGF0IGluaXRpYWxpemF0aW9uIHRpbWUgb2YgYW4gWFNMVCBleHRlbnNpb24gbW9kdWxlLgorICoKKyAqIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBtb2R1bGUgc3BlY2lmaWMgZGF0YSBmb3IgdGhpcyB0cmFuc2Zvcm1hdGlvbi4KKyAqLwordHlwZWRlZiB2b2lkICogKCp4c2x0U3R5bGVFeHRJbml0RnVuY3Rpb24pCSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKwkJCQkJCSBjb25zdCB4bWxDaGFyICpVUkkpOworCisvKioKKyAqIHhzbHRTdHlsZUV4dFNodXRkb3duRnVuY3Rpb246CisgKiBAY3R4dDogIGFuIFhTTFQgc3R5bGVzaGVldAorICogQFVSSTogIHRoZSBuYW1lc3BhY2UgVVJJIGZvciB0aGUgZXh0ZW5zaW9uCisgKiBAZGF0YTogIHRoZSBkYXRhIGFzc29jaWF0ZWQgdG8gdGhpcyBtb2R1bGUKKyAqCisgKiBBIGZ1bmN0aW9uIGNhbGxlZCBhdCBzaHV0ZG93biB0aW1lIG9mIGFuIFhTTFQgZXh0ZW5zaW9uIG1vZHVsZS4KKyAqLwordHlwZWRlZiB2b2lkICgqeHNsdFN0eWxlRXh0U2h1dGRvd25GdW5jdGlvbikJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkJIGNvbnN0IHhtbENoYXIgKlVSSSwKKwkJCQkJCSB2b2lkICpkYXRhKTsKKworLyoqCisgKiB4c2x0RXh0SW5pdEZ1bmN0aW9uOgorICogQGN0eHQ6ICBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBVUkk6ICB0aGUgbmFtZXNwYWNlIFVSSSBmb3IgdGhlIGV4dGVuc2lvbgorICoKKyAqIEEgZnVuY3Rpb24gY2FsbGVkIGF0IGluaXRpYWxpemF0aW9uIHRpbWUgb2YgYW4gWFNMVCBleHRlbnNpb24gbW9kdWxlLgorICoKKyAqIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBtb2R1bGUgc3BlY2lmaWMgZGF0YSBmb3IgdGhpcyB0cmFuc2Zvcm1hdGlvbi4KKyAqLwordHlwZWRlZiB2b2lkICogKCp4c2x0RXh0SW5pdEZ1bmN0aW9uKQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKlVSSSk7CisKKy8qKgorICogeHNsdEV4dFNodXRkb3duRnVuY3Rpb246CisgKiBAY3R4dDogIGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQFVSSTogIHRoZSBuYW1lc3BhY2UgVVJJIGZvciB0aGUgZXh0ZW5zaW9uCisgKiBAZGF0YTogIHRoZSBkYXRhIGFzc29jaWF0ZWQgdG8gdGhpcyBtb2R1bGUKKyAqCisgKiBBIGZ1bmN0aW9uIGNhbGxlZCBhdCBzaHV0ZG93biB0aW1lIG9mIGFuIFhTTFQgZXh0ZW5zaW9uIG1vZHVsZS4KKyAqLwordHlwZWRlZiB2b2lkICgqeHNsdEV4dFNodXRkb3duRnVuY3Rpb24pICh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJLAorCQkJCQkgdm9pZCAqZGF0YSk7CisKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCXhzbHRSZWdpc3RlckV4dE1vZHVsZQkoY29uc3QgeG1sQ2hhciAqVVJJLAorCQkJCQkgeHNsdEV4dEluaXRGdW5jdGlvbiBpbml0RnVuYywKKwkJCQkJIHhzbHRFeHRTaHV0ZG93bkZ1bmN0aW9uIHNodXRkb3duRnVuYyk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQl4c2x0UmVnaXN0ZXJFeHRNb2R1bGVGdWxsCisJCQkJCShjb25zdCB4bWxDaGFyICogVVJJLAorCQkJCQkgeHNsdEV4dEluaXRGdW5jdGlvbiBpbml0RnVuYywKKwkJCQkJIHhzbHRFeHRTaHV0ZG93bkZ1bmN0aW9uIHNodXRkb3duRnVuYywKKwkJCQkJIHhzbHRTdHlsZUV4dEluaXRGdW5jdGlvbiBzdHlsZUluaXRGdW5jLAorCQkJCQkgeHNsdFN0eWxlRXh0U2h1dGRvd25GdW5jdGlvbiBzdHlsZVNodXRkb3duRnVuYyk7CisKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCXhzbHRVbnJlZ2lzdGVyRXh0TW9kdWxlCShjb25zdCB4bWxDaGFyICogVVJJKTsKKworWFNMVFBVQkZVTiB2b2lkICogWFNMVENBTEwKKwkJeHNsdEdldEV4dERhdGEJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJKTsKKworWFNMVFBVQkZVTiB2b2lkICogWFNMVENBTEwKKwkJeHNsdFN0eWxlR2V0RXh0RGF0YQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSBjb25zdCB4bWxDaGFyICpVUkkpOworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorWFNMVFBVQkZVTiB2b2lkICogWFNMVENBTEwKKwkJeHNsdFN0eWxlU3R5bGVzaGVldExldmVsR2V0RXh0RGF0YSgKKwkJCQkJIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqIFVSSSk7CisjZW5kaWYKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0U2h1dGRvd25DdHh0RXh0cwkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCk7CisKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0U2h1dGRvd25FeHRzCSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSk7CisKK1hTTFRQVUJGVU4geHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgWFNMVENBTEwKKwkJeHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dAorCQkJCQkoeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQpOworCisvKgorICogZXh0ZW5zaW9uIGZ1bmN0aW9ucworKi8KK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCXhzbHRSZWdpc3RlckV4dE1vZHVsZUZ1bmN0aW9uCisJCQkJCShjb25zdCB4bWxDaGFyICpuYW1lLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJLAorCQkJCQkgeG1sWFBhdGhGdW5jdGlvbiBmdW5jdGlvbik7CitYU0xUUFVCRlVOIHhtbFhQYXRoRnVuY3Rpb24gWFNMVENBTEwKKwl4c2x0RXh0TW9kdWxlRnVuY3Rpb25Mb29rdXAJKGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCQkJCSBjb25zdCB4bWxDaGFyICpVUkkpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwKKwkJeHNsdFVucmVnaXN0ZXJFeHRNb2R1bGVGdW5jdGlvbgorCQkJCQkoY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKlVSSSk7CisKKy8qCisgKiBleHRlbnNpb24gZWxlbWVudHMKKyAqLwordHlwZWRlZiB4c2x0RWxlbVByZUNvbXBQdHIgKCp4c2x0UHJlQ29tcHV0ZUZ1bmN0aW9uKQorCQkJCQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0VHJhbnNmb3JtRnVuY3Rpb24gZnVuY3Rpb24pOworCitYU0xUUFVCRlVOIHhzbHRFbGVtUHJlQ29tcFB0ciBYU0xUQ0FMTAorCQl4c2x0TmV3RWxlbVByZUNvbXAJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgeG1sTm9kZVB0ciBpbnN0LAorCQkJCQkgeHNsdFRyYW5zZm9ybUZ1bmN0aW9uIGZ1bmN0aW9uKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0SW5pdEVsZW1QcmVDb21wCSh4c2x0RWxlbVByZUNvbXBQdHIgY29tcCwKKwkJCQkJIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgeG1sTm9kZVB0ciBpbnN0LAorCQkJCQkgeHNsdFRyYW5zZm9ybUZ1bmN0aW9uIGZ1bmN0aW9uLAorCQkJCQkgeHNsdEVsZW1QcmVDb21wRGVhbGxvY2F0b3IgZnJlZUZ1bmMpOworCitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQl4c2x0UmVnaXN0ZXJFeHRNb2R1bGVFbGVtZW50CisJCQkJCShjb25zdCB4bWxDaGFyICpuYW1lLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJLAorCQkJCQkgeHNsdFByZUNvbXB1dGVGdW5jdGlvbiBwcmVjb21wLAorCQkJCQkgeHNsdFRyYW5zZm9ybUZ1bmN0aW9uIHRyYW5zZm9ybSk7CitYU0xUUFVCRlVOIHhzbHRUcmFuc2Zvcm1GdW5jdGlvbiBYU0xUQ0FMTAorCQl4c2x0RXh0RWxlbWVudExvb2t1cAkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCQkJCSBjb25zdCB4bWxDaGFyICpVUkkpOworWFNMVFBVQkZVTiB4c2x0VHJhbnNmb3JtRnVuY3Rpb24gWFNMVENBTEwKKwkJeHNsdEV4dE1vZHVsZUVsZW1lbnRMb29rdXAKKwkJCQkJKGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCQkJCSBjb25zdCB4bWxDaGFyICpVUkkpOworWFNMVFBVQkZVTiB4c2x0UHJlQ29tcHV0ZUZ1bmN0aW9uIFhTTFRDQUxMCisJCXhzbHRFeHRNb2R1bGVFbGVtZW50UHJlQ29tcHV0ZUxvb2t1cAorCQkJCQkoY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKlVSSSk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQl4c2x0VW5yZWdpc3RlckV4dE1vZHVsZUVsZW1lbnQKKwkJCQkJKGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCQkJCSBjb25zdCB4bWxDaGFyICpVUkkpOworCisvKgorICogdG9wLWxldmVsIGVsZW1lbnRzCisgKi8KK3R5cGVkZWYgdm9pZCAoKnhzbHRUb3BMZXZlbEZ1bmN0aW9uKQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QpOworCitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQl4c2x0UmVnaXN0ZXJFeHRNb2R1bGVUb3BMZXZlbAorCQkJCQkoY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKlVSSSwKKwkJCQkJIHhzbHRUb3BMZXZlbEZ1bmN0aW9uIGZ1bmN0aW9uKTsKK1hTTFRQVUJGVU4geHNsdFRvcExldmVsRnVuY3Rpb24gWFNMVENBTEwKKwkJeHNsdEV4dE1vZHVsZVRvcExldmVsTG9va3VwCisJCQkJCShjb25zdCB4bWxDaGFyICpuYW1lLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCXhzbHRVbnJlZ2lzdGVyRXh0TW9kdWxlVG9wTGV2ZWwKKwkJCQkJKGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCQkJCSBjb25zdCB4bWxDaGFyICpVUkkpOworCisKKy8qIFRoZXNlIDIgZnVuY3Rpb25zIGFyZSBkZXByZWNhdGVkIGZvciB1c2Ugd2l0aGluIG1vZHVsZXMuICovCitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQl4c2x0UmVnaXN0ZXJFeHRGdW5jdGlvbgkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCQkJCSBjb25zdCB4bWxDaGFyICpVUkksCisJCQkJCSB4bWxYUGF0aEZ1bmN0aW9uIGZ1bmN0aW9uKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCXhzbHRSZWdpc3RlckV4dEVsZW1lbnQJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCSBjb25zdCB4bWxDaGFyICpuYW1lLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJLAorCQkJCQkgeHNsdFRyYW5zZm9ybUZ1bmN0aW9uIGZ1bmN0aW9uKTsKKworLyoKKyAqIEV4dGVuc2lvbiBQcmVmaXggaGFuZGxpbmcgQVBJLgorICogVGhvc2UgYXJlIHVzZWQgYnkgdGhlIFhTTFQgKHByZSlwcm9jZXNzb3IuCisgKi8KKworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwKKwkJeHNsdFJlZ2lzdGVyRXh0UHJlZml4CSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKnByZWZpeCwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKlVSSSk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQl4c2x0Q2hlY2tFeHRQcmVmaXgJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCXhzbHRDaGVja0V4dFVSSQkJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCXhzbHRJbml0Q3R4dEV4dHMJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRGcmVlQ3R4dEV4dHMJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRGcmVlRXh0cwkJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKTsKKworWFNMVFBVQkZVTiB4c2x0RWxlbVByZUNvbXBQdHIgWFNMVENBTEwKKwkJeHNsdFByZUNvbXB1dGVFeHRNb2R1bGVFbGVtZW50CisJCQkJCSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKwkJCQkJIHhtbE5vZGVQdHIgaW5zdCk7CisvKgorICogRXh0ZW5zaW9uIEluZm9zIGFjY2Vzcy4KKyAqIFVzZWQgYnkgZXhzbHQgaW5pdGlhbGlzYXRpb24KKyAqLworCitYU0xUUFVCRlVOIHhtbEhhc2hUYWJsZVB0ciBYU0xUQ0FMTAorCQl4c2x0R2V0RXh0SW5mbwkJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqVVJJKTsKKworLyoqCisgKiBUZXN0IG1vZHVsZSBodHRwOi8veG1sc29mdC5vcmcvWFNMVC8KKyAqLworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRSZWdpc3RlclRlc3RNb2R1bGUJKHZvaWQpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHREZWJ1Z0R1bXBFeHRlbnNpb25zCShGSUxFICogb3V0cHV0KTsKKworCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19YTUxfWFNMVF9FWFRFTlNJT05fSF9fICovCisKZGlmZiAtLWdpdCBhL2xpYnhzbHQvZXh0cmEuYyBiL2xpYnhzbHQvZXh0cmEuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYTBmNTQ3Ci0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9leHRyYS5jCkBAIC0wLDAgKzEsMzI5IEBACisvKgorICogZXh0cmEuYzogSW1wbGVtZW50YXRpb24gb2Ygbm9uLXN0YW5kYXJkIGZlYXR1cmVzCisgKgorICogUmVmZXJlbmNlOgorICogICBNaWNoYWVsIEtheSAiWFNMVCBQcm9ncmFtbWVyJ3MgUmVmZXJlbmNlIiBwcCA2MzctNjQzCisgKiAgIFRoZSBub2RlLXNldCgpIGV4dGVuc2lvbiBmdW5jdGlvbgorICoKKyAqIFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBkYW5pZWxAdmVpbGxhcmQuY29tCisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaWZkZWYgSEFWRV9USU1FX0gKKyNpbmNsdWRlIDx0aW1lLmg+CisjZW5kaWYKKyNpZmRlZiBIQVZFX1NURExJQl9ICisjaW5jbHVkZSA8c3RkbGliLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGxpYnhtbC94bWxtZW1vcnkuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgPGxpYnhtbC9oYXNoLmg+CisjaW5jbHVkZSA8bGlieG1sL3htbGVycm9yLmg+CisjaW5jbHVkZSA8bGlieG1sL3BhcnNlckludGVybmFscy5oPgorI2luY2x1ZGUgInhzbHQuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisjaW5jbHVkZSAieHNsdHV0aWxzLmgiCisjaW5jbHVkZSAiZXh0ZW5zaW9ucy5oIgorI2luY2x1ZGUgInZhcmlhYmxlcy5oIgorI2luY2x1ZGUgInRyYW5zZm9ybS5oIgorI2luY2x1ZGUgImV4dHJhLmgiCisjaW5jbHVkZSAicHJlcHJvYy5oIgorCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHCisjZGVmaW5lIFdJVEhfWFNMVF9ERUJVR19FWFRSQQorI2VuZGlmCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJSGFuZGxpbmcgb2YgWFNMVCBkZWJ1Z2dpbmcJCQkJKgorICogCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0RGVidWc6CisgKiBAY3R4dDogIGFuIFhTTFQgcHJvY2Vzc2luZyBjb250ZXh0CisgKiBAbm9kZTogIFRoZSBjdXJyZW50IG5vZGUKKyAqIEBpbnN0OiAgdGhlIGluc3RydWN0aW9uIGluIHRoZSBzdHlsZXNoZWV0CisgKiBAY29tcDogIHByZWNvbXB1dGVkIGluZm9ybWF0aW9ucworICoKKyAqIFByb2Nlc3MgYW4gZGVidWcgbm9kZQorICovCit2b2lkCit4c2x0RGVidWcoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlIEFUVFJJQlVURV9VTlVTRUQsCisgICAgICAgICAgeG1sTm9kZVB0ciBpbnN0IEFUVFJJQlVURV9VTlVTRUQsCisgICAgICAgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wIEFUVFJJQlVURV9VTlVTRUQpCit7CisgICAgaW50IGksIGo7CisKKyAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LCAiVGVtcGxhdGVzOlxuIik7CisgICAgZm9yIChpID0gMCwgaiA9IGN0eHQtPnRlbXBsTnIgLSAxOyAoKGkgPCAxNSkgJiYgKGogPj0gMCkpOyBpKyssIGotLSkgeworICAgICAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LCAiIyVkICIsIGkpOworICAgICAgICBpZiAoY3R4dC0+dGVtcGxUYWJbal0tPm5hbWUgIT0gTlVMTCkKKyAgICAgICAgICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsICJuYW1lICVzICIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnRlbXBsVGFiW2pdLT5uYW1lKTsKKyAgICAgICAgaWYgKGN0eHQtPnRlbXBsVGFiW2pdLT5tYXRjaCAhPSBOVUxMKQorICAgICAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwgIm5hbWUgJXMgIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+dGVtcGxUYWJbal0tPm1hdGNoKTsKKyAgICAgICAgaWYgKGN0eHQtPnRlbXBsVGFiW2pdLT5tb2RlICE9IE5VTEwpCisgICAgICAgICAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LCAibmFtZSAlcyAiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT50ZW1wbFRhYltqXS0+bW9kZSk7CisgICAgICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsICJcbiIpOworICAgIH0KKyAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LCAiVmFyaWFibGVzOlxuIik7CisgICAgZm9yIChpID0gMCwgaiA9IGN0eHQtPnZhcnNOciAtIDE7ICgoaSA8IDE1KSAmJiAoaiA+PSAwKSk7IGkrKywgai0tKSB7CisgICAgICAgIHhzbHRTdGFja0VsZW1QdHIgY3VyOworCisgICAgICAgIGlmIChjdHh0LT52YXJzVGFiW2pdID09IE5VTEwpCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwgIiMlZFxuIiwgaSk7CisgICAgICAgIGN1ciA9IGN0eHQtPnZhcnNUYWJbal07CisgICAgICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKGN1ci0+Y29tcCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb3JydXB0ZWQgISEhXG4iKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VyLT5jb21wLT50eXBlID09IFhTTFRfRlVOQ19QQVJBTSkgeworICAgICAgICAgICAgICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsICJwYXJhbSAiKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VyLT5jb21wLT50eXBlID09IFhTTFRfRlVOQ19WQVJJQUJMRSkgeworICAgICAgICAgICAgICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsICJ2YXIgIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY3VyLT5uYW1lICE9IE5VTEwpCisgICAgICAgICAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwgIiVzICIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXItPm5hbWUpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsICJub25hbWUgISEhISIpOworI2lmZGVmIExJQlhNTF9ERUJVR19FTkFCTEVECisgICAgICAgICAgICBpZiAoY3VyLT52YWx1ZSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgeG1sWFBhdGhEZWJ1Z0R1bXBPYmplY3Qoc3Rkb3V0LCBjdXItPnZhbHVlLCAxKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwgIk5VTEwgISEhISIpOworICAgICAgICAgICAgfQorI2VuZGlmCisgICAgICAgICAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LCAiXG4iKTsKKyAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKKyAgICAgICAgfQorCisgICAgfQorfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAJCQkJCQkJCQkqCisgKiAJCUNsYXNzaWMgZXh0ZW5zaW9ucyBhcyBkZXNjcmliZWQgYnkgTS4gS2F5CQkqCisgKiAJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHRGdW5jdGlvbk5vZGVTZXQ6CisgKiBAY3R4dDogIHRoZSBYUGF0aCBQYXJzZXIgY29udGV4dAorICogQG5hcmdzOiAgdGhlIG51bWJlciBvZiBhcmd1bWVudHMKKyAqCisgKiBJbXBsZW1lbnQgdGhlIG5vZGUtc2V0KCkgWFNMVCBmdW5jdGlvbgorICogICBub2RlLXNldCBub2RlLXNldChyZXN1bHQtdHJlZSkKKyAqCisgKiBUaGlzIGZ1bmN0aW9uIGlzIGF2YWlsYWJsZSBpbiBsaWJ4c2x0LCBzYXhvbiBvciB4dCBuYW1lc3BhY2UuCisgKi8KK3ZvaWQKK3hzbHRGdW5jdGlvbk5vZGVTZXQoeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQsIGludCBuYXJncyl7CisgICAgaWYgKG5hcmdzICE9IDEpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoeHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dChjdHh0KSwgTlVMTCwgTlVMTCwKKwkJIm5vZGUtc2V0KCkgOiBleHBlY3RzIG9uZSByZXN1bHQtdHJlZSBhcmdcbiIpOworCWN0eHQtPmVycm9yID0gWFBBVEhfSU5WQUxJRF9BUklUWTsKKwlyZXR1cm47CisgICAgfQorICAgIGlmICgoY3R4dC0+dmFsdWUgPT0gTlVMTCkgfHwKKwkoKGN0eHQtPnZhbHVlLT50eXBlICE9IFhQQVRIX1hTTFRfVFJFRSkgJiYKKwkgKGN0eHQtPnZhbHVlLT50eXBlICE9IFhQQVRIX05PREVTRVQpKSkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcih4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpLCBOVUxMLCBOVUxMLAorCSAgICAibm9kZS1zZXQoKSBpbnZhbGlkIGFyZyBleHBlY3RpbmcgYSByZXN1bHQgdHJlZVxuIik7CisJY3R4dC0+ZXJyb3IgPSBYUEFUSF9JTlZBTElEX1RZUEU7CisJcmV0dXJuOworICAgIH0KKyAgICBpZiAoY3R4dC0+dmFsdWUtPnR5cGUgPT0gWFBBVEhfWFNMVF9UUkVFKSB7CisJY3R4dC0+dmFsdWUtPnR5cGUgPSBYUEFUSF9OT0RFU0VUOworICAgIH0KK30KKworCisvKgorICogT2theSB0aGUgZm9sbG93aW5nIHJlYWxseSBzZWVtcyB1bnBvcnRhYmxlIGFuZCBzaW5jZSBpdCdzIG5vdAorICogcGFydCBvZiBhbnkgc3RhbmRhcmQgSSdtIG5vdCB0b28gYXNoYW1lZCB0byBkbyB0aGlzCisgKi8KKyNpZiBkZWZpbmVkKGxpbnV4KSB8fCBkZWZpbmVkKF9fc3VuKQorI2lmIGRlZmluZWQoSEFWRV9NS1RJTUUpICYmIGRlZmluZWQoSEFWRV9MT0NBTFRJTUUpICYmIGRlZmluZWQoSEFWRV9BU0NUSU1FKQorI2RlZmluZSBXSVRIX0xPQ0FMVElNRQorCisvKioKKyAqIHhzbHRGdW5jdGlvbkxvY2FsVGltZToKKyAqIEBjdHh0OiAgdGhlIFhQYXRoIFBhcnNlciBjb250ZXh0CisgKiBAbmFyZ3M6ICB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cworICoKKyAqIEltcGxlbWVudCB0aGUgbG9jYWxUaW1lIFhTTFQgZnVuY3Rpb24gdXNlZCBieSBOT1JNCisgKiAgIHN0cmluZyBsb2NhbFRpbWUoPz8/KQorICoKKyAqIFRoaXMgZnVuY3Rpb24gaXMgYXZhaWxhYmxlIGluIE5vcm0ncyBleHRlbnNpb24gbmFtZXNwYWNlCisgKiBDb2RlIChhbmQgY29tbWVudHMpIGNvbnRyaWJ1dGVkIGJ5IE5vcm0KKyAqLworc3RhdGljIHZvaWQKK3hzbHRGdW5jdGlvbkxvY2FsVGltZSh4bWxYUGF0aFBhcnNlckNvbnRleHRQdHIgY3R4dCwgaW50IG5hcmdzKSB7CisgICAgeG1sWFBhdGhPYmplY3RQdHIgb2JqOworICAgIGNoYXIgKnN0cjsKKyAgICBjaGFyIGRpZ2l0c1s1XTsKKyAgICBjaGFyIHJlc3VsdFsyOV07CisgICAgbG9uZyBpbnQgZmllbGQ7CisgICAgdGltZV90IGdtdCwgbG10OworICAgIHN0cnVjdCB0bSBnbXRfdG07CisgICAgc3RydWN0IHRtICpsb2NhbF90bTsKKyAKKyAgICBpZiAobmFyZ3MgIT0gMSkgeworICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcih4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpLCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICJsb2NhbFRpbWUoKSA6IGludmFsaWQgbnVtYmVyIG9mIGFyZ3MgJWRcbiIsIG5hcmdzKTsKKyAgICAgICBjdHh0LT5lcnJvciA9IFhQQVRIX0lOVkFMSURfQVJJVFk7CisgICAgICAgcmV0dXJuOworICAgIH0KKyAKKyAgICBvYmogPSB2YWx1ZVBvcChjdHh0KTsKKworICAgIGlmIChvYmotPnR5cGUgIT0gWFBBVEhfU1RSSU5HKSB7CisJb2JqID0geG1sWFBhdGhDb252ZXJ0U3RyaW5nKG9iaik7CisgICAgfQorICAgIGlmIChvYmogPT0gTlVMTCkgeworCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld1N0cmluZygoY29uc3QgeG1sQ2hhciAqKSIiKSk7CisJcmV0dXJuOworICAgIH0KKyAgICAKKyAgICBzdHIgPSAoY2hhciAqKSBvYmotPnN0cmluZ3ZhbDsKKworICAgIC8qIHN0ciA9ICIkRGF0ZSQiICovCisgICAgbWVtc2V0KGRpZ2l0cywgMCwgc2l6ZW9mKGRpZ2l0cykpOworICAgIHN0cm5jcHkoZGlnaXRzLCBzdHIrNywgNCk7CisgICAgZmllbGQgPSBzdHJ0b2woZGlnaXRzLCBOVUxMLCAxMCk7CisgICAgZ210X3RtLnRtX3llYXIgPSBmaWVsZCAtIDE5MDA7CisKKyAgICBtZW1zZXQoZGlnaXRzLCAwLCBzaXplb2YoZGlnaXRzKSk7CisgICAgc3RybmNweShkaWdpdHMsIHN0cisxMiwgMik7CisgICAgZmllbGQgPSBzdHJ0b2woZGlnaXRzLCBOVUxMLCAxMCk7CisgICAgZ210X3RtLnRtX21vbiA9IGZpZWxkIC0gMTsKKworICAgIG1lbXNldChkaWdpdHMsIDAsIHNpemVvZihkaWdpdHMpKTsKKyAgICBzdHJuY3B5KGRpZ2l0cywgc3RyKzE1LCAyKTsKKyAgICBmaWVsZCA9IHN0cnRvbChkaWdpdHMsIE5VTEwsIDEwKTsKKyAgICBnbXRfdG0udG1fbWRheSA9IGZpZWxkOworCisgICAgbWVtc2V0KGRpZ2l0cywgMCwgc2l6ZW9mKGRpZ2l0cykpOworICAgIHN0cm5jcHkoZGlnaXRzLCBzdHIrMTgsIDIpOworICAgIGZpZWxkID0gc3RydG9sKGRpZ2l0cywgTlVMTCwgMTApOworICAgIGdtdF90bS50bV9ob3VyID0gZmllbGQ7CisKKyAgICBtZW1zZXQoZGlnaXRzLCAwLCBzaXplb2YoZGlnaXRzKSk7CisgICAgc3RybmNweShkaWdpdHMsIHN0cisyMSwgMik7CisgICAgZmllbGQgPSBzdHJ0b2woZGlnaXRzLCBOVUxMLCAxMCk7CisgICAgZ210X3RtLnRtX21pbiA9IGZpZWxkOworCisgICAgbWVtc2V0KGRpZ2l0cywgMCwgc2l6ZW9mKGRpZ2l0cykpOworICAgIHN0cm5jcHkoZGlnaXRzLCBzdHIrMjQsIDIpOworICAgIGZpZWxkID0gc3RydG9sKGRpZ2l0cywgTlVMTCwgMTApOworICAgIGdtdF90bS50bV9zZWMgPSBmaWVsZDsKKworICAgIC8qIE5vdyB0dXJuIGdtdF90bSBpbnRvIGEgdGltZS4gKi8KKyAgICBnbXQgPSBta3RpbWUoJmdtdF90bSk7CisKKworICAgIC8qCisgICAgICogRklYTUU6IGl0J3MgYmVlbiB0b28gbG9uZyBzaW5jZSBJIGRpZCBtYW51YWwgbWVtb3J5IG1hbmFnZW1lbnQuCisgICAgICogKEkgc3dvcmUgbmV2ZXIgdG8gZG8gaXQgYWdhaW4uKSBEb2VzIHRoaXMgaW50cm9kdWNlIGEgbWVtb3J5IGxlYWs/CisgICAgICovCisgICAgbG9jYWxfdG0gPSBsb2NhbHRpbWUoJmdtdCk7CisKKyAgICAvKgorICAgICAqIENhbGxpbmcgbG9jYWx0aW1lKCkgaGFzIHRoZSBzaWRlLWVmZmVjdCBvZiBzZXR0aW5nIHRpbWV6b25lLgorICAgICAqIEFmdGVyIHdlIGtub3cgdGhlIHRpbWV6b25lLCB3ZSBjYW4gYWRqdXN0IGZvciBpdAorICAgICAqLworICAgIGxtdCA9IGdtdCAtIHRpbWV6b25lOworCisgICAgLyoKKyAgICAgKiBGSVhNRTogaXQncyBiZWVuIHRvbyBsb25nIHNpbmNlIEkgZGlkIG1hbnVhbCBtZW1vcnkgbWFuYWdlbWVudC4KKyAgICAgKiAoSSBzd29yZSBuZXZlciB0byBkbyBpdCBhZ2Fpbi4pIERvZXMgdGhpcyBpbnRyb2R1Y2UgYSBtZW1vcnkgbGVhaz8KKyAgICAgKi8KKyAgICBsb2NhbF90bSA9IGxvY2FsdGltZSgmbG10KTsKKworICAgIC8qCisgICAgICogTm93IGNvbnZlcnQgbG9jYWxfdG0gYmFjayBpbnRvIGEgc3RyaW5nLiBUaGlzIGRvZXNuJ3QgaW50cm9kdWNlCisgICAgICogYSBtZW1vcnkgbGVhaywgc28gc2F5cyBhc2N0aW1lKDMpLgorICAgICAqLworCisgICAgc3RyID0gYXNjdGltZShsb2NhbF90bSk7ICAgICAgICAgICAvKiAiVHVlIEp1biAyNiAwNTowMjoxNiAyMDAxIiAqLworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogIDAxMjM0NTY3ODkgMTIzNDU2Nzg5IDEyMyAqLworCisgICAgbWVtc2V0KHJlc3VsdCwgMCwgc2l6ZW9mKHJlc3VsdCkpOyAvKiAiVGh1LCAyNiBKdW4gMjAwMSIgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICAwMTIzNDU2Nzg5IDEyMzQ1ICovCisKKyAgICBzdHJuY3B5KHJlc3VsdCwgc3RyLCAyMCk7CisgICAgc3RyY3B5KHJlc3VsdCsyMCwgIj8/PyIpOyAgICAgICAgICAvKiB0em5hbWUgZG9lc24ndCB3b3JrLCBmYWtlIGl0ICovCisgICAgc3RybmNweShyZXN1bHQrMjMsIHN0cisxOSwgNSk7CisKKyAgICAvKiBPaywgbm93IHJlc3VsdCBjb250YWlucyB0aGUgc3RyaW5nIEkgd2FudCB0byBzZW5kIGJhY2suICovCisgICAgdmFsdWVQdXNoKGN0eHQsIHhtbFhQYXRoTmV3U3RyaW5nKCh4bWxDaGFyICopcmVzdWx0KSk7Cit9CisjZW5kaWYKKyNlbmRpZiAvKiBsaW51eCBvciBzdW4gKi8KKworCisvKioKKyAqIHhzbHRSZWdpc3RlckV4dHJhczoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICoKKyAqIFJlZ2lzdGVycyB0aGUgYnVpbHQtaW4gZXh0ZW5zaW9ucy4gVGhpcyBmdW5jdGlvbiBpcyBkZXByZWNhdGVkLCB1c2UKKyAqIHhzbHRSZWdpc3RlckFsbEV4dHJhcyBpbnN0ZWFkLgorICovCit2b2lkCit4c2x0UmVnaXN0ZXJFeHRyYXMoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCBBVFRSSUJVVEVfVU5VU0VEKSB7CisgICAgeHNsdFJlZ2lzdGVyQWxsRXh0cmFzKCk7Cit9CisKKy8qKgorICogeHNsdFJlZ2lzdGVyQWxsRXh0cmFzOgorICoKKyAqIFJlZ2lzdGVycyB0aGUgYnVpbHQtaW4gZXh0ZW5zaW9ucworICovCit2b2lkCit4c2x0UmVnaXN0ZXJBbGxFeHRyYXMgKHZvaWQpIHsKKyAgICB4c2x0UmVnaXN0ZXJFeHRNb2R1bGVGdW5jdGlvbigoY29uc3QgeG1sQ2hhciAqKSAibm9kZS1zZXQiLAorCQkJCSAgWFNMVF9MSUJYU0xUX05BTUVTUEFDRSwKKwkJCQkgIHhzbHRGdW5jdGlvbk5vZGVTZXQpOworICAgIHhzbHRSZWdpc3RlckV4dE1vZHVsZUZ1bmN0aW9uKChjb25zdCB4bWxDaGFyICopICJub2RlLXNldCIsCisJCQkJICBYU0xUX1NBWE9OX05BTUVTUEFDRSwKKwkJCQkgIHhzbHRGdW5jdGlvbk5vZGVTZXQpOworICAgIHhzbHRSZWdpc3RlckV4dE1vZHVsZUZ1bmN0aW9uKChjb25zdCB4bWxDaGFyICopICJub2RlLXNldCIsCisJCQkJICBYU0xUX1hUX05BTUVTUEFDRSwKKwkJCQkgIHhzbHRGdW5jdGlvbk5vZGVTZXQpOworI2lmZGVmIFdJVEhfTE9DQUxUSU1FCisgICAgeHNsdFJlZ2lzdGVyRXh0TW9kdWxlRnVuY3Rpb24oKGNvbnN0IHhtbENoYXIgKikgImxvY2FsVGltZSIsCisJCQkJICBYU0xUX05PUk1fU0FYT05fTkFNRVNQQUNFLAorCQkJCSAgeHNsdEZ1bmN0aW9uTG9jYWxUaW1lKTsKKyNlbmRpZgorICAgIHhzbHRSZWdpc3RlckV4dE1vZHVsZUVsZW1lbnQoKGNvbnN0IHhtbENoYXIgKikgImRlYnVnIiwKKwkJCQkgWFNMVF9MSUJYU0xUX05BTUVTUEFDRSwKKwkJCQkgTlVMTCwKKwkJCQkgKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdERlYnVnKTsKKyAgICB4c2x0UmVnaXN0ZXJFeHRNb2R1bGVFbGVtZW50KChjb25zdCB4bWxDaGFyICopICJvdXRwdXQiLAorCQkJCSBYU0xUX1NBWE9OX05BTUVTUEFDRSwKKwkJCQkgeHNsdERvY3VtZW50Q29tcCwKKwkJCQkgKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdERvY3VtZW50RWxlbSk7CisgICAgeHNsdFJlZ2lzdGVyRXh0TW9kdWxlRWxlbWVudCgoY29uc3QgeG1sQ2hhciAqKSAid3JpdGUiLAorCQkJCSBYU0xUX1hBTEFOX05BTUVTUEFDRSwKKwkJCQkgeHNsdERvY3VtZW50Q29tcCwKKwkJCQkgKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdERvY3VtZW50RWxlbSk7CisgICAgeHNsdFJlZ2lzdGVyRXh0TW9kdWxlRWxlbWVudCgoY29uc3QgeG1sQ2hhciAqKSAiZG9jdW1lbnQiLAorCQkJCSBYU0xUX1hUX05BTUVTUEFDRSwKKwkJCQkgeHNsdERvY3VtZW50Q29tcCwKKwkJCQkgKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdERvY3VtZW50RWxlbSk7CisgICAgeHNsdFJlZ2lzdGVyRXh0TW9kdWxlRWxlbWVudCgoY29uc3QgeG1sQ2hhciAqKSAiZG9jdW1lbnQiLAorCQkJCSBYU0xUX05BTUVTUEFDRSwKKwkJCQkgeHNsdERvY3VtZW50Q29tcCwKKwkJCQkgKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdERvY3VtZW50RWxlbSk7Cit9CmRpZmYgLS1naXQgYS9saWJ4c2x0L2V4dHJhLmggYi9saWJ4c2x0L2V4dHJhLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTllOTMyYgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQvZXh0cmEuaApAQCAtMCwwICsxLDgwIEBACisvKgorICogU3VtbWFyeTogaW50ZXJmYWNlIGZvciB0aGUgbm9uLXN0YW5kYXJkIGZlYXR1cmVzCisgKiBEZXNjcmlwdGlvbjogaW1wbGVtZW50IHNvbWUgZXh0ZW5zaW9uIG91dHNpZGUgdGhlIFhTTFQgbmFtZXNwYWNlCisgKiAgICAgICAgICAgICAgYnV0IG5vdCBFWFNMVCB3aXRoIGlzIGluIGEgZGlmZmVyZW50IGxpYnJhcnkuCisgKgorICogQ29weTogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIEF1dGhvcjogRGFuaWVsIFZlaWxsYXJkCisgKi8KKworI2lmbmRlZiBfX1hNTF9YU0xUX0VYVFJBX0hfXworI2RlZmluZSBfX1hNTF9YU0xUX0VYVFJBX0hfXworCisjaW5jbHVkZSA8bGlieG1sL3hwYXRoLmg+CisjaW5jbHVkZSAieHNsdGV4cG9ydHMuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyoqCisgKiBYU0xUX0xJQlhTTFRfTkFNRVNQQUNFOgorICoKKyAqIFRoaXMgaXMgdGhlIGxpYnhzbHQgbmFtZXNwYWNlIGZvciBzcGVjaWZpYyBleHRlbnNpb25zLgorICovCisjZGVmaW5lIFhTTFRfTElCWFNMVF9OQU1FU1BBQ0UgKCh4bWxDaGFyICopICJodHRwOi8veG1sc29mdC5vcmcvWFNMVC9uYW1lc3BhY2UiKQorCisvKioKKyAqIFhTTFRfU0FYT05fTkFNRVNQQUNFOgorICoKKyAqIFRoaXMgaXMgTWljaGFlbCBLYXkncyBTYXhvbiBwcm9jZXNzb3IgbmFtZXNwYWNlIGZvciBleHRlbnNpb25zLgorICovCisjZGVmaW5lIFhTTFRfU0FYT05fTkFNRVNQQUNFICgoeG1sQ2hhciAqKSAiaHR0cDovL2ljbC5jb20vc2F4b24iKQorCisvKioKKyAqIFhTTFRfWFRfTkFNRVNQQUNFOgorICoKKyAqIFRoaXMgaXMgSmFtZXMgQ2xhcmsncyBYVCBwcm9jZXNzb3IgbmFtZXNwYWNlIGZvciBleHRlbnNpb25zLgorICovCisjZGVmaW5lIFhTTFRfWFRfTkFNRVNQQUNFICgoeG1sQ2hhciAqKSAiaHR0cDovL3d3dy5qY2xhcmsuY29tL3h0IikKKworLyoqCisgKiBYU0xUX1hBTEFOX05BTUVTUEFDRToKKyAqCisgKiBUaGlzIGlzIHRoZSBBcGFjaGUgcHJvamVjdCBYQUxBTiBwcm9jZXNzb3IgbmFtZXNwYWNlIGZvciBleHRlbnNpb25zLgorICovCisjZGVmaW5lIFhTTFRfWEFMQU5fTkFNRVNQQUNFICgoeG1sQ2hhciAqKQlcCisJICAgICAgICAgICAgICAgICAgICAgICAgIm9yZy5hcGFjaGUueGFsYW4ueHNsdC5leHRlbnNpb25zLlJlZGlyZWN0IikKKworLyoqCisgKiBYU0xUX05PUk1fU0FYT05fTkFNRVNQQUNFOgorICoKKyAqIFRoaXMgaXMgTm9ybSdzIG5hbWVzcGFjZSBmb3IgU0FYT04gZXh0ZW5zaW9ucy4KKyAqLworI2RlZmluZSBYU0xUX05PUk1fU0FYT05fTkFNRVNQQUNFICgoeG1sQ2hhciAqKQlcCisJImh0dHA6Ly9ud2Fsc2guY29tL3hzbHQvZXh0L2NvbS5ud2Fsc2guc2F4b24uQ1ZTIikKKworCitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdEZ1bmN0aW9uTm9kZVNldAkoeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQsCisJCQkJCSBpbnQgbmFyZ3MpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkKKwkJeHNsdERlYnVnCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIHhtbE5vZGVQdHIgaW5zdCwKKwkJCQkJIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCk7CisKKworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkKKwkJeHNsdFJlZ2lzdGVyRXh0cmFzCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisJCXhzbHRSZWdpc3RlckFsbEV4dHJhcwkodm9pZCk7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX0VYVFJBX0hfXyAqLworCmRpZmYgLS1naXQgYS9saWJ4c2x0L2Z1bmN0aW9ucy5jIGIvbGlieHNsdC9mdW5jdGlvbnMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NzIwYzdhCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9mdW5jdGlvbnMuYwpAQCAtMCwwICsxLDk3NSBAQAorLyoKKyAqIGZ1bmN0aW9ucy5jOiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgWFNMVCBleHRyYSBmdW5jdGlvbnMKKyAqCisgKiBSZWZlcmVuY2U6CisgKiAgIGh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhzbHQtMTk5OTExMTYKKyAqCisgKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCisgKgorICogZGFuaWVsQHZlaWxsYXJkLmNvbQorICogQmpvcm4gUmVlc2UgPGJyZWVzZUB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQ+IGZvciBudW1iZXIgZm9ybWF0dGluZworICovCisKKyNkZWZpbmUgSU5fTElCWFNMVAorI2luY2x1ZGUgImxpYnhzbHQuaCIKKworI2luY2x1ZGUgPHN0cmluZy5oPgorCisjaWZkZWYgSEFWRV9TWVNfVFlQRVNfSAorI2luY2x1ZGUgPHN5cy90eXBlcy5oPgorI2VuZGlmCisjaWZkZWYgSEFWRV9DVFlQRV9ICisjaW5jbHVkZSA8Y3R5cGUuaD4KKyNlbmRpZgorCisjaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgorI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXIuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgPGxpYnhtbC92YWxpZC5oPgorI2luY2x1ZGUgPGxpYnhtbC9oYXNoLmg+CisjaW5jbHVkZSA8bGlieG1sL3htbGVycm9yLmg+CisjaW5jbHVkZSA8bGlieG1sL3hwYXRoLmg+CisjaW5jbHVkZSA8bGlieG1sL3hwYXRoSW50ZXJuYWxzLmg+CisjaW5jbHVkZSA8bGlieG1sL3BhcnNlckludGVybmFscy5oPgorI2luY2x1ZGUgPGxpYnhtbC91cmkuaD4KKyNpbmNsdWRlIDxsaWJ4bWwveHBvaW50ZXIuaD4KKyNpbmNsdWRlICJ4c2x0LmgiCisjaW5jbHVkZSAieHNsdEludGVybmFscy5oIgorI2luY2x1ZGUgInhzbHR1dGlscy5oIgorI2luY2x1ZGUgImZ1bmN0aW9ucy5oIgorI2luY2x1ZGUgImV4dGVuc2lvbnMuaCIKKyNpbmNsdWRlICJudW1iZXJzSW50ZXJuYWxzLmgiCisjaW5jbHVkZSAia2V5cy5oIgorI2luY2x1ZGUgImRvY3VtZW50cy5oIgorCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHCisjZGVmaW5lIFdJVEhfWFNMVF9ERUJVR19GVU5DVElPTgorI2VuZGlmCisKKy8qCisgKiBTb21lIHZlcnNpb25zIG9mIERvY0Jvb2sgWFNMIHVzZSB0aGUgdmVuZG9yIHN0cmluZyB0byBkZXRlY3QKKyAqIHN1cHBvcnRpbmcgY2h1bmtpbmcsIHRoaXMgaXMgYSB3b3JrYXJvdW5kIHRvIGJlIGNvbnNpZGVyZWQKKyAqIGluIHRoZSBsaXN0IG9mIGRlY2VudCBYU0xUIHByb2Nlc3NvcnMgPGdyaW4vPgorICovCisjZGVmaW5lIERPQ0JPT0tfWFNMX0hBQ0sKKworLyoqCisgKiB4c2x0WFBhdGhGdW5jdGlvbkxvb2t1cDoKKyAqIEBjdHh0OiAgYSB2b2lkICogYnV0IHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQgYWN0dWFsbHkKKyAqIEBuYW1lOiAgdGhlIGZ1bmN0aW9uIG5hbWUKKyAqIEBuc191cmk6ICB0aGUgZnVuY3Rpb24gbmFtZXNwYWNlIFVSSQorICoKKyAqIFRoaXMgaXMgdGhlIGVudHJ5IHBvaW50IHdoZW4gYSBmdW5jdGlvbiBpcyBuZWVkZWQgYnkgdGhlIFhQYXRoCisgKiBpbnRlcnByZXRvci4KKyAqCisgKiBSZXR1cm5zIHRoZSBjYWxsYmFjayBmdW5jdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZAorICovCit4bWxYUGF0aEZ1bmN0aW9uCit4c2x0WFBhdGhGdW5jdGlvbkxvb2t1cCAoeG1sWFBhdGhDb250ZXh0UHRyIGN0eHQsCisJCQkgY29uc3QgeG1sQ2hhciAqbmFtZSwgY29uc3QgeG1sQ2hhciAqbnNfdXJpKSB7CisgICAgeG1sWFBhdGhGdW5jdGlvbiByZXQ7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkgfHwgKG5zX3VyaSA9PSBOVUxMKSkKKwlyZXR1cm4gKE5VTEwpOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0ZVTkNUSU9OCisgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICJMb29rdXAgZnVuY3Rpb24geyVzfSVzXG4iLCBuc191cmksIG5hbWUpOworI2VuZGlmCisKKyAgICAvKiBnaXZlIHByaW9yaXR5IHRvIGNvbnRleHQtbGV2ZWwgZnVuY3Rpb25zICovCisgICAgLyoKKyAgICByZXQgPSAoeG1sWFBhdGhGdW5jdGlvbikgeG1sSGFzaExvb2t1cDIoY3R4dC0+ZnVuY0hhc2gsIG5hbWUsIG5zX3VyaSk7CisgICAgKi8KKyAgICBYTUxfQ0FTVF9GUFRSKHJldCkgPSB4bWxIYXNoTG9va3VwMihjdHh0LT5mdW5jSGFzaCwgbmFtZSwgbnNfdXJpKTsKKworICAgIGlmIChyZXQgPT0gTlVMTCkKKwlyZXQgPSB4c2x0RXh0TW9kdWxlRnVuY3Rpb25Mb29rdXAobmFtZSwgbnNfdXJpKTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19GVU5DVElPTgorICAgIGlmIChyZXQgIT0gTlVMTCkKKyAgICAgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICJmb3VuZCBmdW5jdGlvbiAlc1xuIiwgbmFtZSk7CisjZW5kaWYKKyAgICByZXR1cm4ocmV0KTsKK30KKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkJTW9kdWxlIGludGVyZmFjZXMJCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitzdGF0aWMgdm9pZAoreHNsdERvY3VtZW50RnVuY3Rpb25Mb2FkRG9jdW1lbnQoeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQsIHhtbENoYXIqIFVSSSkKK3sKKyAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciB0Y3R4dDsKKyAgICB4bWxVUklQdHIgdXJpOworICAgIHhtbENoYXIgKmZyYWdtZW50OworICAgIHhzbHREb2N1bWVudFB0ciBpZG9jOyAvKiBkb2N1bWVudCBpbmZvICovCisgICAgeG1sRG9jUHRyIGRvYzsKKyAgICB4bWxYUGF0aENvbnRleHRQdHIgeHB0cmN0eHQgPSBOVUxMOworICAgIHhtbFhQYXRoT2JqZWN0UHRyIHJlc09iaiA9IE5VTEw7CisKKyAgICB0Y3R4dCA9IHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCk7CisgICAgaWYgKHRjdHh0ID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkgICAgImRvY3VtZW50KCkgOiBpbnRlcm5hbCBlcnJvciB0Y3R4dCA9PSBOVUxMXG4iKTsKKwl2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdOb2RlU2V0KE5VTEwpKTsKKwlyZXR1cm47CisgICAgfSAKKwkKKyAgICB1cmkgPSB4bWxQYXJzZVVSSSgoY29uc3QgY2hhciAqKSBVUkkpOworICAgIGlmICh1cmkgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcih0Y3R4dCwgTlVMTCwgTlVMTCwKKwkgICAgImRvY3VtZW50KCkgOiBmYWlsZWQgdG8gcGFyc2UgVVJJXG4iKTsKKwl2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdOb2RlU2V0KE5VTEwpKTsKKwlyZXR1cm47CisgICAgfSAKKyAgICAKKyAgICAvKgorICAgICAqIGNoZWNrIGZvciBhbmQgcmVtb3ZlIGZyYWdtZW50IGlkZW50aWZpZXIKKyAgICAgKi8KKyAgICBmcmFnbWVudCA9ICh4bWxDaGFyICopdXJpLT5mcmFnbWVudDsKKyAgICBpZiAoZnJhZ21lbnQgIT0gTlVMTCkgeworICAgICAgICB4bWxDaGFyICpuZXdVUkk7CisJdXJpLT5mcmFnbWVudCA9IE5VTEw7CisJbmV3VVJJID0geG1sU2F2ZVVyaSh1cmkpOworCWlkb2MgPSB4c2x0TG9hZERvY3VtZW50KHRjdHh0LCBuZXdVUkkpOworCXhtbEZyZWUobmV3VVJJKTsKKyAgICB9IGVsc2UKKwlpZG9jID0geHNsdExvYWREb2N1bWVudCh0Y3R4dCwgVVJJKTsKKyAgICB4bWxGcmVlVVJJKHVyaSk7CisgICAgCisgICAgaWYgKGlkb2MgPT0gTlVMTCkgeworCWlmICgoVVJJID09IE5VTEwpIHx8CisJICAgIChVUklbMF0gPT0gJyMnKSB8fAorCSAgICAoKHRjdHh0LT5zdHlsZS0+ZG9jICE9IE5VTEwpICYmCisJICAgICh4bWxTdHJFcXVhbCh0Y3R4dC0+c3R5bGUtPmRvYy0+VVJMLCBVUkkpKSkpIAorCXsKKwkgICAgLyoKKwkgICAgKiBUaGlzIHNlbGVjdHMgdGhlIHN0eWxlc2hlZXQncyBkb2MgaXRzZWxmLgorCSAgICAqLworCSAgICBkb2MgPSB0Y3R4dC0+c3R5bGUtPmRvYzsKKwl9IGVsc2UgeworCSAgICB2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdOb2RlU2V0KE5VTEwpKTsKKworCSAgICBpZiAoZnJhZ21lbnQgIT0gTlVMTCkKKwkJeG1sRnJlZShmcmFnbWVudCk7CisKKwkgICAgcmV0dXJuOworCX0KKyAgICB9IGVsc2UKKwlkb2MgPSBpZG9jLT5kb2M7CisKKyAgICBpZiAoZnJhZ21lbnQgPT0gTlVMTCkgeworCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld05vZGVTZXQoKHhtbE5vZGVQdHIpIGRvYykpOworCXJldHVybjsKKyAgICB9CisJCisgICAgLyogdXNlIFhQb2ludGVyIG9mIEhUTUwgbG9jYXRpb24gZm9yIGZyYWdtZW50IElEICovCisjaWZkZWYgTElCWE1MX1hQVFJfRU5BQkxFRAorICAgIHhwdHJjdHh0ID0geG1sWFB0ck5ld0NvbnRleHQoZG9jLCBOVUxMLCBOVUxMKTsKKyAgICBpZiAoeHB0cmN0eHQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcih0Y3R4dCwgTlVMTCwgTlVMTCwKKwkgICAgImRvY3VtZW50KCkgOiBpbnRlcm5hbCBlcnJvciB4cHRyY3R4dCA9PSBOVUxMXG4iKTsKKwlnb3RvIG91dF9mcmFnbWVudDsKKyAgICB9CisKKyAgICByZXNPYmogPSB4bWxYUHRyRXZhbChmcmFnbWVudCwgeHB0cmN0eHQpOworICAgIHhtbFhQYXRoRnJlZUNvbnRleHQoeHB0cmN0eHQpOworI2VuZGlmCisgICAgeG1sRnJlZShmcmFnbWVudCk7CQorCisgICAgaWYgKHJlc09iaiA9PSBOVUxMKQorCWdvdG8gb3V0X2ZyYWdtZW50OworCQorICAgIHN3aXRjaCAocmVzT2JqLT50eXBlKSB7CisJY2FzZSBYUEFUSF9OT0RFU0VUOgorCSAgICBicmVhazsKKwljYXNlIFhQQVRIX1VOREVGSU5FRDoKKwljYXNlIFhQQVRIX0JPT0xFQU46CisJY2FzZSBYUEFUSF9OVU1CRVI6CisJY2FzZSBYUEFUSF9TVFJJTkc6CisJY2FzZSBYUEFUSF9QT0lOVDoKKwljYXNlIFhQQVRIX1VTRVJTOgorCWNhc2UgWFBBVEhfWFNMVF9UUkVFOgorCWNhc2UgWFBBVEhfUkFOR0U6CisJY2FzZSBYUEFUSF9MT0NBVElPTlNFVDoKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKHRjdHh0LCBOVUxMLCBOVUxMLAorCQkiZG9jdW1lbnQoKSA6IFhQb2ludGVyIGRvZXMgbm90IHNlbGVjdCBhIG5vZGUgc2V0OiAjJXNcbiIsIAorCQlmcmFnbWVudCk7CisJZ290byBvdXRfb2JqZWN0OworICAgIH0KKyAgICAKKyAgICB2YWx1ZVB1c2goY3R4dCwgcmVzT2JqKTsKKyAgICByZXR1cm47CisKK291dF9vYmplY3Q6CisgICAgeG1sWFBhdGhGcmVlT2JqZWN0KHJlc09iaik7CisKK291dF9mcmFnbWVudDoKKyAgICB2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdOb2RlU2V0KE5VTEwpKTsKK30KKworLyoqCisgKiB4c2x0RG9jdW1lbnRGdW5jdGlvbjoKKyAqIEBjdHh0OiAgdGhlIFhQYXRoIFBhcnNlciBjb250ZXh0CisgKiBAbmFyZ3M6ICB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cworICoKKyAqIEltcGxlbWVudCB0aGUgZG9jdW1lbnQoKSBYU0xUIGZ1bmN0aW9uCisgKiAgIG5vZGUtc2V0IGRvY3VtZW50KG9iamVjdCwgbm9kZS1zZXQ/KQorICovCit2b2lkCit4c2x0RG9jdW1lbnRGdW5jdGlvbih4bWxYUGF0aFBhcnNlckNvbnRleHRQdHIgY3R4dCwgaW50IG5hcmdzKQoreworICAgIHhtbFhQYXRoT2JqZWN0UHRyIG9iaiwgb2JqMiA9IE5VTEw7CisgICAgeG1sQ2hhciAqYmFzZSA9IE5VTEwsICpVUkk7CisKKworICAgIGlmICgobmFyZ3MgPCAxKSB8fCAobmFyZ3MgPiAyKSkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoeHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dChjdHh0KSwgTlVMTCwgTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiZG9jdW1lbnQoKSA6IGludmFsaWQgbnVtYmVyIG9mIGFyZ3MgJWRcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgbmFyZ3MpOworICAgICAgICBjdHh0LT5lcnJvciA9IFhQQVRIX0lOVkFMSURfQVJJVFk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKGN0eHQtPnZhbHVlID09IE5VTEwpIHsKKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgImRvY3VtZW50KCkgOiBpbnZhbGlkIGFyZyB2YWx1ZVxuIik7CisgICAgICAgIGN0eHQtPmVycm9yID0gWFBBVEhfSU5WQUxJRF9UWVBFOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKG5hcmdzID09IDIpIHsKKyAgICAgICAgaWYgKGN0eHQtPnZhbHVlLT50eXBlICE9IFhQQVRIX05PREVTRVQpIHsKKyAgICAgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcih4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpLCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZG9jdW1lbnQoKSA6IGludmFsaWQgYXJnIGV4cGVjdGluZyBhIG5vZGVzZXRcbiIpOworICAgICAgICAgICAgY3R4dC0+ZXJyb3IgPSBYUEFUSF9JTlZBTElEX1RZUEU7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBvYmoyID0gdmFsdWVQb3AoY3R4dCk7CisgICAgfQorCisgICAgaWYgKGN0eHQtPnZhbHVlLT50eXBlID09IFhQQVRIX05PREVTRVQpIHsKKyAgICAgICAgaW50IGk7CisgICAgICAgIHhtbFhQYXRoT2JqZWN0UHRyIG5ld29iaiwgcmV0OworCisgICAgICAgIG9iaiA9IHZhbHVlUG9wKGN0eHQpOworICAgICAgICByZXQgPSB4bWxYUGF0aE5ld05vZGVTZXQoTlVMTCk7CisKKyAgICAgICAgaWYgKG9iai0+bm9kZXNldHZhbCkgeworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG9iai0+bm9kZXNldHZhbC0+bm9kZU5yOyBpKyspIHsKKyAgICAgICAgICAgICAgICB2YWx1ZVB1c2goY3R4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sWFBhdGhOZXdOb2RlU2V0KG9iai0+bm9kZXNldHZhbC0+bm9kZVRhYltpXSkpOworICAgICAgICAgICAgICAgIHhtbFhQYXRoU3RyaW5nRnVuY3Rpb24oY3R4dCwgMSk7CisgICAgICAgICAgICAgICAgaWYgKG5hcmdzID09IDIpIHsKKyAgICAgICAgICAgICAgICAgICAgdmFsdWVQdXNoKGN0eHQsIHhtbFhQYXRoT2JqZWN0Q29weShvYmoyKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgdmFsdWVQdXNoKGN0eHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxYUGF0aE5ld05vZGVTZXQob2JqLT5ub2Rlc2V0dmFsLT4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlVGFiW2ldKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHhzbHREb2N1bWVudEZ1bmN0aW9uKGN0eHQsIDIpOworICAgICAgICAgICAgICAgIG5ld29iaiA9IHZhbHVlUG9wKGN0eHQpOworICAgICAgICAgICAgICAgIHJldC0+bm9kZXNldHZhbCA9IHhtbFhQYXRoTm9kZVNldE1lcmdlKHJldC0+bm9kZXNldHZhbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdvYmotPm5vZGVzZXR2YWwpOworICAgICAgICAgICAgICAgIHhtbFhQYXRoRnJlZU9iamVjdChuZXdvYmopOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgeG1sWFBhdGhGcmVlT2JqZWN0KG9iaik7CisgICAgICAgIGlmIChvYmoyICE9IE5VTEwpCisgICAgICAgICAgICB4bWxYUGF0aEZyZWVPYmplY3Qob2JqMik7CisgICAgICAgIHZhbHVlUHVzaChjdHh0LCByZXQpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIC8qCisgICAgICogTWFrZSBzdXJlIGl0J3MgY29udmVydGVkIHRvIGEgc3RyaW5nCisgICAgICovCisgICAgeG1sWFBhdGhTdHJpbmdGdW5jdGlvbihjdHh0LCAxKTsKKyAgICBpZiAoY3R4dC0+dmFsdWUtPnR5cGUgIT0gWFBBVEhfU1RSSU5HKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcih4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpLCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICJkb2N1bWVudCgpIDogaW52YWxpZCBhcmcgZXhwZWN0aW5nIGEgc3RyaW5nXG4iKTsKKyAgICAgICAgY3R4dC0+ZXJyb3IgPSBYUEFUSF9JTlZBTElEX1RZUEU7CisgICAgICAgIGlmIChvYmoyICE9IE5VTEwpCisgICAgICAgICAgICB4bWxYUGF0aEZyZWVPYmplY3Qob2JqMik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgb2JqID0gdmFsdWVQb3AoY3R4dCk7CisgICAgaWYgKG9iai0+c3RyaW5ndmFsID09IE5VTEwpIHsKKyAgICAgICAgdmFsdWVQdXNoKGN0eHQsIHhtbFhQYXRoTmV3Tm9kZVNldChOVUxMKSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKChvYmoyICE9IE5VTEwpICYmIChvYmoyLT5ub2Rlc2V0dmFsICE9IE5VTEwpICYmCisgICAgICAgICAgICAob2JqMi0+bm9kZXNldHZhbC0+bm9kZU5yID4gMCkgJiYKKyAgICAgICAgICAgIElTX1hTTFRfUkVBTF9OT0RFKG9iajItPm5vZGVzZXR2YWwtPm5vZGVUYWJbMF0pKSB7CisgICAgICAgICAgICB4bWxOb2RlUHRyIHRhcmdldDsKKworICAgICAgICAgICAgdGFyZ2V0ID0gb2JqMi0+bm9kZXNldHZhbC0+bm9kZVRhYlswXTsKKyAgICAgICAgICAgIGlmICgodGFyZ2V0LT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgfHwKKwkgICAgICAgICh0YXJnZXQtPnR5cGUgPT0gWE1MX1BJX05PREUpKSB7CisgICAgICAgICAgICAgICAgdGFyZ2V0ID0gKCh4bWxBdHRyUHRyKSB0YXJnZXQpLT5wYXJlbnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBiYXNlID0geG1sTm9kZUdldEJhc2UodGFyZ2V0LT5kb2MsIHRhcmdldCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciB0Y3R4dDsKKworICAgICAgICAgICAgdGN0eHQgPSB4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpOworICAgICAgICAgICAgaWYgKCh0Y3R4dCAhPSBOVUxMKSAmJiAodGN0eHQtPmluc3QgIT0gTlVMTCkpIHsKKyAgICAgICAgICAgICAgICBiYXNlID0geG1sTm9kZUdldEJhc2UodGN0eHQtPmluc3QtPmRvYywgdGN0eHQtPmluc3QpOworICAgICAgICAgICAgfSBlbHNlIGlmICgodGN0eHQgIT0gTlVMTCkgJiYgKHRjdHh0LT5zdHlsZSAhPSBOVUxMKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAodGN0eHQtPnN0eWxlLT5kb2MgIT0gTlVMTCkpIHsKKyAgICAgICAgICAgICAgICBiYXNlID0geG1sTm9kZUdldEJhc2UodGN0eHQtPnN0eWxlLT5kb2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh4bWxOb2RlUHRyKSB0Y3R4dC0+c3R5bGUtPmRvYyk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgVVJJID0geG1sQnVpbGRVUkkob2JqLT5zdHJpbmd2YWwsIGJhc2UpOworICAgICAgICBpZiAoYmFzZSAhPSBOVUxMKQorICAgICAgICAgICAgeG1sRnJlZShiYXNlKTsKKyAgICAgICAgaWYgKFVSSSA9PSBOVUxMKSB7CisgICAgICAgICAgICB2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdOb2RlU2V0KE5VTEwpKTsKKyAgICAgICAgfSBlbHNlIHsKKwkgICAgeHNsdERvY3VtZW50RnVuY3Rpb25Mb2FkRG9jdW1lbnQoIGN0eHQsIFVSSSApOworCSAgICB4bWxGcmVlKFVSSSk7CisJfQorICAgIH0KKyAgICB4bWxYUGF0aEZyZWVPYmplY3Qob2JqKTsKKyAgICBpZiAob2JqMiAhPSBOVUxMKQorICAgICAgICB4bWxYUGF0aEZyZWVPYmplY3Qob2JqMik7Cit9CisKKy8qKgorICogeHNsdEtleUZ1bmN0aW9uOgorICogQGN0eHQ6ICB0aGUgWFBhdGggUGFyc2VyIGNvbnRleHQKKyAqIEBuYXJnczogIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzCisgKgorICogSW1wbGVtZW50IHRoZSBrZXkoKSBYU0xUIGZ1bmN0aW9uCisgKiAgIG5vZGUtc2V0IGtleShzdHJpbmcsIG9iamVjdCkKKyAqLwordm9pZAoreHNsdEtleUZ1bmN0aW9uKHhtbFhQYXRoUGFyc2VyQ29udGV4dFB0ciBjdHh0LCBpbnQgbmFyZ3MpeyAgICAKKyAgICB4bWxYUGF0aE9iamVjdFB0ciBvYmoxLCBvYmoyOyAgICAKKyAgICAKKyAgICBpZiAobmFyZ3MgIT0gMikgeworCXhzbHRUcmFuc2Zvcm1FcnJvcih4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpLCBOVUxMLCBOVUxMLAorCQkia2V5KCkgOiBleHBlY3RzIHR3byBhcmd1bWVudHNcbiIpOworCWN0eHQtPmVycm9yID0gWFBBVEhfSU5WQUxJRF9BUklUWTsKKwlyZXR1cm47CisgICAgfSAgICAKKworICAgIC8qCisgICAgKiBHZXQgdGhlIGtleSdzIHZhbHVlLgorICAgICovCisgICAgb2JqMiA9IHZhbHVlUG9wKGN0eHQpOworICAgIHhtbFhQYXRoU3RyaW5nRnVuY3Rpb24oY3R4dCwgMSk7CisgICAgaWYgKChvYmoyID09IE5VTEwpIHx8CisJKGN0eHQtPnZhbHVlID09IE5VTEwpIHx8IChjdHh0LT52YWx1ZS0+dHlwZSAhPSBYUEFUSF9TVFJJTkcpKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisJICAgICJrZXkoKSA6IGludmFsaWQgYXJnIGV4cGVjdGluZyBhIHN0cmluZ1xuIik7CisJY3R4dC0+ZXJyb3IgPSBYUEFUSF9JTlZBTElEX1RZUEU7CisJeG1sWFBhdGhGcmVlT2JqZWN0KG9iajIpOworCisJcmV0dXJuOworICAgIH0KKyAgICAvKgorICAgICogR2V0IHRoZSBrZXkncyBuYW1lLgorICAgICovCisgICAgb2JqMSA9IHZhbHVlUG9wKGN0eHQpOyAgICAKKworICAgIGlmICgob2JqMi0+dHlwZSA9PSBYUEFUSF9OT0RFU0VUKSB8fCAob2JqMi0+dHlwZSA9PSBYUEFUSF9YU0xUX1RSRUUpKSB7CisJaW50IGk7CisJeG1sWFBhdGhPYmplY3RQdHIgbmV3b2JqLCByZXQ7CisKKwlyZXQgPSB4bWxYUGF0aE5ld05vZGVTZXQoTlVMTCk7CisKKwlpZiAob2JqMi0+bm9kZXNldHZhbCAhPSBOVUxMKSB7CisJICAgIGZvciAoaSA9IDA7IGkgPCBvYmoyLT5ub2Rlc2V0dmFsLT5ub2RlTnI7IGkrKykgeworCQl2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhPYmplY3RDb3B5KG9iajEpKTsKKwkJdmFsdWVQdXNoKGN0eHQsCisJCQkgIHhtbFhQYXRoTmV3Tm9kZVNldChvYmoyLT5ub2Rlc2V0dmFsLT5ub2RlVGFiW2ldKSk7CisJCXhtbFhQYXRoU3RyaW5nRnVuY3Rpb24oY3R4dCwgMSk7CisJCXhzbHRLZXlGdW5jdGlvbihjdHh0LCAyKTsKKwkJbmV3b2JqID0gdmFsdWVQb3AoY3R4dCk7CisJCXJldC0+bm9kZXNldHZhbCA9IHhtbFhQYXRoTm9kZVNldE1lcmdlKHJldC0+bm9kZXNldHZhbCwKKwkJCQkJCSAgICAgICBuZXdvYmotPm5vZGVzZXR2YWwpOworCQl4bWxYUGF0aEZyZWVPYmplY3QobmV3b2JqKTsKKwkgICAgfQorCX0KKwl2YWx1ZVB1c2goY3R4dCwgcmV0KTsKKyAgICB9IGVsc2UgeworCXhtbE5vZGVTZXRQdHIgbm9kZWxpc3QgPSBOVUxMOworCXhtbENoYXIgKmtleSA9IE5VTEwsICp2YWx1ZTsKKwljb25zdCB4bWxDaGFyICprZXlVUkk7CisJeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgdGN0eHQ7ICAgCisJeG1sQ2hhciAqcW5hbWUsICpwcmVmaXg7CisJeG1sWFBhdGhDb250ZXh0UHRyIHhwY3R4dCA9IGN0eHQtPmNvbnRleHQ7CisJeG1sTm9kZVB0ciB0bXBOb2RlID0gTlVMTDsKKwl4c2x0RG9jdW1lbnRQdHIgb2xkRG9jSW5mbzsKKworCXRjdHh0ID0geHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dChjdHh0KTsKKworCW9sZERvY0luZm8gPSB0Y3R4dC0+ZG9jdW1lbnQ7CisKKwlpZiAoeHBjdHh0LT5ub2RlID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKHRjdHh0LCBOVUxMLCB0Y3R4dC0+aW5zdCwKKwkJIkludGVybmFsIGVycm9yIGluIHhzbHRLZXlGdW5jdGlvbigpOiAiCisJCSJUaGUgY29udGV4dCBub2RlIGlzIG5vdCBzZXQgb24gdGhlIFhQYXRoIGNvbnRleHQuXG4iKTsKKwkgICAgdGN0eHQtPnN0YXRlID0gWFNMVF9TVEFURV9TVE9QUEVEOworCSAgICBnb3RvIGVycm9yOworCX0JCisJLyoKKwkgKiBHZXQgdGhlIGFzc29jaWF0ZWQgbmFtZXNwYWNlIFVSSSBpZiBxdWFsaWZpZWQgbmFtZQorCSAqLworCXFuYW1lID0gb2JqMS0+c3RyaW5ndmFsOworCWtleSA9IHhtbFNwbGl0UU5hbWUyKHFuYW1lLCAmcHJlZml4KTsKKwlpZiAoa2V5ID09IE5VTEwpIHsKKwkgICAga2V5ID0geG1sU3RyZHVwKG9iajEtPnN0cmluZ3ZhbCk7CisJICAgIGtleVVSSSA9IE5VTEw7CisJICAgIGlmIChwcmVmaXggIT0gTlVMTCkKKwkJeG1sRnJlZShwcmVmaXgpOworCX0gZWxzZSB7CisJICAgIGlmIChwcmVmaXggIT0gTlVMTCkgeworCQlrZXlVUkkgPSB4bWxYUGF0aE5zTG9va3VwKHhwY3R4dCwgcHJlZml4KTsKKwkJaWYgKGtleVVSSSA9PSBOVUxMKSB7CisJCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IodGN0eHQsIE5VTEwsIHRjdHh0LT5pbnN0LAorCQkJImtleSgpIDogcHJlZml4ICVzIGlzIG5vdCBib3VuZFxuIiwgcHJlZml4KTsKKwkJICAgIC8qCisJCSAgICAqIFRPRE86IFNob3VsZG4ndCB3ZSBzdG9wIGhlcmU/CisJCSAgICAqLworCQl9CisJCXhtbEZyZWUocHJlZml4KTsKKwkgICAgfSBlbHNlIHsKKwkJa2V5VVJJID0gTlVMTDsKKwkgICAgfQorCX0KKworCS8qCisJICogRm9yY2UgY29udmVyc2lvbiBvZiBmaXJzdCBhcmcgdG8gc3RyaW5nCisJICovCisJdmFsdWVQdXNoKGN0eHQsIG9iajIpOworCXhtbFhQYXRoU3RyaW5nRnVuY3Rpb24oY3R4dCwgMSk7CisJaWYgKChjdHh0LT52YWx1ZSA9PSBOVUxMKSB8fCAoY3R4dC0+dmFsdWUtPnR5cGUgIT0gWFBBVEhfU1RSSU5HKSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IodGN0eHQsIE5VTEwsIHRjdHh0LT5pbnN0LAorCQkia2V5KCkgOiBpbnZhbGlkIGFyZyBleHBlY3RpbmcgYSBzdHJpbmdcbiIpOworCSAgICBjdHh0LT5lcnJvciA9IFhQQVRIX0lOVkFMSURfVFlQRTsKKwkgICAgZ290byBlcnJvcjsKKwl9CisJb2JqMiA9IHZhbHVlUG9wKGN0eHQpOworCXZhbHVlID0gb2JqMi0+c3RyaW5ndmFsOworCQorCS8qCisJKiBXZSBuZWVkIHRvIGVuc3VyZSB0aGF0IGN0eHQtPmRvY3VtZW50IGlzIGF2YWlsYWJsZSBmb3IKKwkqIHhzbHRHZXRLZXkoKS4KKwkqIEZpcnN0IGZpbmQgdGhlIHJlbGV2YW50IGRvYywgd2hpY2ggaXMgdGhlIGNvbnRleHQgbm9kZSdzCisJKiBvd25lciBkb2M7IHVzaW5nIGNvbnRleHQtPmRvYyBpcyBub3Qgc2FmZSwgc2luY2UKKwkqIHRoZSBkb2MgY291bGQgaGF2ZSBiZWVuIGFjcXVpcmVkIHZpYSB0aGUgZG9jdW1lbnQoKSBmdW5jdGlvbiwKKwkqIG9yIHRoZSBkb2MgbWlnaHQgYmUgYSBSZXN1bHQgVHJlZSBGcmFnbWVudC4KKwkqIEZVVFVSRSBJTkZPOiBJbiBYU0xUIDIuMCB0aGUga2V5KCkgZnVuY3Rpb24gdGFrZXMgYW4gYWRkaXRpb25hbAorCSogYXJndW1lbnQgaW5kaWNhdGluZyB0aGUgZG9jIHRvIHVzZS4KKwkqLwkKKwlpZiAoeHBjdHh0LT5ub2RlLT50eXBlID09IFhNTF9OQU1FU1BBQ0VfREVDTCkgeworCSAgICAvKgorCSAgICAqIFJFVklTSVQ6IFRoaXMgaXMgYSBsaWJ4bWwgaGFjayEgQ2hlY2sgeHBhdGguYyBmb3IgZGV0YWlscy4KKwkgICAgKiBUaGUgWFBhdGggbW9kdWxlIHNldHMgdGhlIG93bmVyIGVsZW1lbnQgb2YgYSBucy1ub2RlIG9uCisJICAgICogdGhlIG5zLT5uZXh0IGZpZWxkLgorCSAgICAqLworCSAgICBpZiAoKCgoeG1sTnNQdHIpIHhwY3R4dC0+bm9kZSktPm5leHQgIT0gTlVMTCkgJiYKKwkJKCgoeG1sTnNQdHIpIHhwY3R4dC0+bm9kZSktPm5leHQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkpCisJICAgIHsKKwkJdG1wTm9kZSA9ICh4bWxOb2RlUHRyKSAoKHhtbE5zUHRyKSB4cGN0eHQtPm5vZGUpLT5uZXh0OworCSAgICB9CisJfSBlbHNlCisJICAgIHRtcE5vZGUgPSB4cGN0eHQtPm5vZGU7CisKKwlpZiAoKHRtcE5vZGUgPT0gTlVMTCkgfHwgKHRtcE5vZGUtPmRvYyA9PSBOVUxMKSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IodGN0eHQsIE5VTEwsIHRjdHh0LT5pbnN0LAorCQkiSW50ZXJuYWwgZXJyb3IgaW4geHNsdEtleUZ1bmN0aW9uKCk6ICIKKwkJIkNvdWxkbid0IGdldCB0aGUgZG9jIG9mIHRoZSBYUGF0aCBjb250ZXh0IG5vZGUuXG4iKTsKKwkgICAgZ290byBlcnJvcjsKKwl9CisKKwlpZiAoKHRjdHh0LT5kb2N1bWVudCA9PSBOVUxMKSB8fAorCSAgICAodGN0eHQtPmRvY3VtZW50LT5kb2MgIT0gdG1wTm9kZS0+ZG9jKSkKKwl7CSAgIAorCSAgICBpZiAodG1wTm9kZS0+ZG9jLT5uYW1lICYmICh0bXBOb2RlLT5kb2MtPm5hbWVbMF0gPT0gJyAnKSkgeworCQkvKgorCQkqIFRoaXMgaXMgYSBSZXN1bHQgVHJlZSBGcmFnbWVudC4KKwkJKi8KKwkJaWYgKHRtcE5vZGUtPmRvYy0+X3ByaXZhdGUgPT0gTlVMTCkgeworCQkgICAgdG1wTm9kZS0+ZG9jLT5fcHJpdmF0ZSA9IHhzbHROZXdEb2N1bWVudCh0Y3R4dCwgdG1wTm9kZS0+ZG9jKTsKKwkJICAgIGlmICh0bXBOb2RlLT5kb2MtPl9wcml2YXRlID09IE5VTEwpCisJCQlnb3RvIGVycm9yOworCQl9CisJCXRjdHh0LT5kb2N1bWVudCA9ICh4c2x0RG9jdW1lbnRQdHIpIHRtcE5vZGUtPmRvYy0+X3ByaXZhdGU7CQkKKwkgICAgfSBlbHNlIHsKKwkJLyoKKwkJKiBNYXkgYmUgdGhlIGluaXRpYWwgc291cmNlIGRvYyBvciBhIGRvYyBhY3F1aXJlZCB2aWEgdGhlCisJCSogZG9jdW1lbnQoKSBmdW5jdGlvbi4KKwkJKi8KKwkJdGN0eHQtPmRvY3VtZW50ID0geHNsdEZpbmREb2N1bWVudCh0Y3R4dCwgdG1wTm9kZS0+ZG9jKTsKKwkgICAgfQorCSAgICBpZiAodGN0eHQtPmRvY3VtZW50ID09IE5VTEwpIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKHRjdHh0LCBOVUxMLCB0Y3R4dC0+aW5zdCwKKwkJICAgICJJbnRlcm5hbCBlcnJvciBpbiB4c2x0S2V5RnVuY3Rpb24oKTogIgorCQkgICAgIkNvdWxkIG5vdCBnZXQgdGhlIGRvY3VtZW50IGluZm8gb2YgYSBjb250ZXh0IGRvYy5cbiIpOworCQl0Y3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisJCWdvdG8gZXJyb3I7CisJICAgIH0KKwl9CisJLyoKKwkqIEdldC9jb21wdXRlIHRoZSBrZXkgdmFsdWUuCisJKi8KKwlub2RlbGlzdCA9IHhzbHRHZXRLZXkodGN0eHQsIGtleSwga2V5VVJJLCB2YWx1ZSk7CisKK2Vycm9yOgkKKwl0Y3R4dC0+ZG9jdW1lbnQgPSBvbGREb2NJbmZvOworCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aFdyYXBOb2RlU2V0KAorCSAgICB4bWxYUGF0aE5vZGVTZXRNZXJnZShOVUxMLCBub2RlbGlzdCkpKTsKKwlpZiAoa2V5ICE9IE5VTEwpCisJICAgIHhtbEZyZWUoa2V5KTsKKyAgICB9ICAgIAorCisgICAgaWYgKG9iajEgIT0gTlVMTCkKKwl4bWxYUGF0aEZyZWVPYmplY3Qob2JqMSk7CisgICAgaWYgKG9iajIgIT0gTlVMTCkKKwl4bWxYUGF0aEZyZWVPYmplY3Qob2JqMik7ICAgIAorfQorCisvKioKKyAqIHhzbHRVbnBhcnNlZEVudGl0eVVSSUZ1bmN0aW9uOgorICogQGN0eHQ6ICB0aGUgWFBhdGggUGFyc2VyIGNvbnRleHQKKyAqIEBuYXJnczogIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzCisgKgorICogSW1wbGVtZW50IHRoZSB1bnBhcnNlZC1lbnRpdHktdXJpKCkgWFNMVCBmdW5jdGlvbgorICogICBzdHJpbmcgdW5wYXJzZWQtZW50aXR5LXVyaShzdHJpbmcpCisgKi8KK3ZvaWQKK3hzbHRVbnBhcnNlZEVudGl0eVVSSUZ1bmN0aW9uKHhtbFhQYXRoUGFyc2VyQ29udGV4dFB0ciBjdHh0LCBpbnQgbmFyZ3MpeworICAgIHhtbFhQYXRoT2JqZWN0UHRyIG9iajsKKyAgICB4bWxDaGFyICpzdHI7CisKKyAgICBpZiAoKG5hcmdzICE9IDEpIHx8IChjdHh0LT52YWx1ZSA9PSBOVUxMKSkgeworICAgICAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LAorCQkidW5wYXJzZWQtZW50aXR5LXVyaSgpIDogZXhwZWN0cyBvbmUgc3RyaW5nIGFyZ1xuIik7CisJY3R4dC0+ZXJyb3IgPSBYUEFUSF9JTlZBTElEX0FSSVRZOworCXJldHVybjsKKyAgICB9CisgICAgb2JqID0gdmFsdWVQb3AoY3R4dCk7CisgICAgaWYgKG9iai0+dHlwZSAhPSBYUEFUSF9TVFJJTkcpIHsKKwlvYmogPSB4bWxYUGF0aENvbnZlcnRTdHJpbmcob2JqKTsKKyAgICB9CisKKyAgICBzdHIgPSBvYmotPnN0cmluZ3ZhbDsKKyAgICBpZiAoc3RyID09IE5VTEwpIHsKKwl2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdTdHJpbmcoKGNvbnN0IHhtbENoYXIgKikiIikpOworICAgIH0gZWxzZSB7CisJeG1sRW50aXR5UHRyIGVudGl0eTsKKworCWVudGl0eSA9IHhtbEdldERvY0VudGl0eShjdHh0LT5jb250ZXh0LT5kb2MsIHN0cik7CisJaWYgKGVudGl0eSA9PSBOVUxMKSB7CisJICAgIHZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld1N0cmluZygoY29uc3QgeG1sQ2hhciAqKSIiKSk7CisJfSBlbHNlIHsKKwkgICAgaWYgKGVudGl0eS0+VVJJICE9IE5VTEwpCisJCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld1N0cmluZyhlbnRpdHktPlVSSSkpOworCSAgICBlbHNlCisJCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld1N0cmluZygoY29uc3QgeG1sQ2hhciAqKSIiKSk7CisJfQorICAgIH0KKyAgICB4bWxYUGF0aEZyZWVPYmplY3Qob2JqKTsKK30KKworLyoqCisgKiB4c2x0Rm9ybWF0TnVtYmVyRnVuY3Rpb246CisgKiBAY3R4dDogIHRoZSBYUGF0aCBQYXJzZXIgY29udGV4dAorICogQG5hcmdzOiAgdGhlIG51bWJlciBvZiBhcmd1bWVudHMKKyAqCisgKiBJbXBsZW1lbnQgdGhlIGZvcm1hdC1udW1iZXIoKSBYU0xUIGZ1bmN0aW9uCisgKiAgIHN0cmluZyBmb3JtYXQtbnVtYmVyKG51bWJlciwgc3RyaW5nLCBzdHJpbmc/KQorICovCit2b2lkCit4c2x0Rm9ybWF0TnVtYmVyRnVuY3Rpb24oeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQsIGludCBuYXJncykKK3sKKyAgICB4bWxYUGF0aE9iamVjdFB0ciBudW1iZXJPYmogPSBOVUxMOworICAgIHhtbFhQYXRoT2JqZWN0UHRyIGZvcm1hdE9iaiA9IE5VTEw7CisgICAgeG1sWFBhdGhPYmplY3RQdHIgZGVjaW1hbE9iaiA9IE5VTEw7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc2hlZXQ7CisgICAgeHNsdERlY2ltYWxGb3JtYXRQdHIgZm9ybWF0VmFsdWVzOworICAgIHhtbENoYXIgKnJlc3VsdDsKKyAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciB0Y3R4dDsKKworICAgIHRjdHh0ID0geHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dChjdHh0KTsKKyAgICBpZiAodGN0eHQgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgc2hlZXQgPSB0Y3R4dC0+c3R5bGU7CisgICAgaWYgKHNoZWV0ID09IE5VTEwpCisJcmV0dXJuOworICAgIGZvcm1hdFZhbHVlcyA9IHNoZWV0LT5kZWNpbWFsRm9ybWF0OworICAgIAorICAgIHN3aXRjaCAobmFyZ3MpIHsKKyAgICBjYXNlIDM6CisJQ0FTVF9UT19TVFJJTkc7CisJZGVjaW1hbE9iaiA9IHZhbHVlUG9wKGN0eHQpOworCWZvcm1hdFZhbHVlcyA9IHhzbHREZWNpbWFsRm9ybWF0R2V0QnlOYW1lKHNoZWV0LCBkZWNpbWFsT2JqLT5zdHJpbmd2YWwpOworCWlmIChmb3JtYXRWYWx1ZXMgPT0gTlVMTCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IodGN0eHQsIE5VTEwsIE5VTEwsCisJCSAgICAiZm9ybWF0LW51bWJlcigpIDogdW5kZWNsYXJlZCBkZWNpbWFsIGZvcm1hdCAnJXMnXG4iLCAKKwkJICAgIGRlY2ltYWxPYmotPnN0cmluZ3ZhbCk7CisJfQorCS8qIEludGVudGlvbmFsIGZhbGwtdGhyb3VnaCAqLworICAgIGNhc2UgMjoKKwlDQVNUX1RPX1NUUklORzsKKwlmb3JtYXRPYmogPSB2YWx1ZVBvcChjdHh0KTsKKwlDQVNUX1RPX05VTUJFUjsKKwludW1iZXJPYmogPSB2YWx1ZVBvcChjdHh0KTsKKwlicmVhazsKKyAgICBkZWZhdWx0OgorCVhQX0VSUk9SKFhQQVRIX0lOVkFMSURfQVJJVFkpOworICAgIH0KKworICAgIGlmIChmb3JtYXRWYWx1ZXMgIT0gTlVMTCkgeworCWlmICh4c2x0Rm9ybWF0TnVtYmVyQ29udmVyc2lvbihmb3JtYXRWYWx1ZXMsCisJCQkJICAgICAgIGZvcm1hdE9iai0+c3RyaW5ndmFsLAorCQkJCSAgICAgICBudW1iZXJPYmotPmZsb2F0dmFsLAorCQkJCSAgICAgICAmcmVzdWx0KSA9PSBYUEFUSF9FWFBSRVNTSU9OX09LKSB7CisJICAgIHZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld1N0cmluZyhyZXN1bHQpKTsKKwkgICAgeG1sRnJlZShyZXN1bHQpOworCX0KKyAgICB9CisKKyAgICB4bWxYUGF0aEZyZWVPYmplY3QobnVtYmVyT2JqKTsKKyAgICB4bWxYUGF0aEZyZWVPYmplY3QoZm9ybWF0T2JqKTsKKyAgICB4bWxYUGF0aEZyZWVPYmplY3QoZGVjaW1hbE9iaik7Cit9CisKKy8qKgorICogeHNsdEdlbmVyYXRlSWRGdW5jdGlvbjoKKyAqIEBjdHh0OiAgdGhlIFhQYXRoIFBhcnNlciBjb250ZXh0CisgKiBAbmFyZ3M6ICB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cworICoKKyAqIEltcGxlbWVudCB0aGUgZ2VuZXJhdGUtaWQoKSBYU0xUIGZ1bmN0aW9uCisgKiAgIHN0cmluZyBnZW5lcmF0ZS1pZChub2RlLXNldD8pCisgKi8KK3ZvaWQKK3hzbHRHZW5lcmF0ZUlkRnVuY3Rpb24oeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQsIGludCBuYXJncyl7CisgICAgeG1sTm9kZVB0ciBjdXIgPSBOVUxMOworICAgIHVuc2lnbmVkIGxvbmcgdmFsOworICAgIHhtbENoYXIgc3RyWzIwXTsKKworICAgIGlmIChuYXJncyA9PSAwKSB7CisJY3VyID0gY3R4dC0+Y29udGV4dC0+bm9kZTsKKyAgICB9IGVsc2UgaWYgKG5hcmdzID09IDEpIHsKKwl4bWxYUGF0aE9iamVjdFB0ciBvYmo7CisJeG1sTm9kZVNldFB0ciBub2RlbGlzdDsKKwlpbnQgaSwgcmV0OworCisJaWYgKChjdHh0LT52YWx1ZSA9PSBOVUxMKSB8fCAoY3R4dC0+dmFsdWUtPnR5cGUgIT0gWFBBVEhfTk9ERVNFVCkpIHsKKwkgICAgY3R4dC0+ZXJyb3IgPSBYUEFUSF9JTlZBTElEX1RZUEU7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcih4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpLCBOVUxMLCBOVUxMLAorCQkiZ2VuZXJhdGUtaWQoKSA6IGludmFsaWQgYXJnIGV4cGVjdGluZyBhIG5vZGUtc2V0XG4iKTsKKwkgICAgcmV0dXJuOworCX0KKwlvYmogPSB2YWx1ZVBvcChjdHh0KTsKKwlub2RlbGlzdCA9IG9iai0+bm9kZXNldHZhbDsKKwlpZiAoKG5vZGVsaXN0ID09IE5VTEwpIHx8IChub2RlbGlzdC0+bm9kZU5yIDw9IDApKSB7CisJICAgIHhtbFhQYXRoRnJlZU9iamVjdChvYmopOworCSAgICB2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdDU3RyaW5nKCIiKSk7CisJICAgIHJldHVybjsKKwl9CisJY3VyID0gbm9kZWxpc3QtPm5vZGVUYWJbMF07CisJZm9yIChpID0gMTtpIDwgbm9kZWxpc3QtPm5vZGVOcjtpKyspIHsKKwkgICAgcmV0ID0geG1sWFBhdGhDbXBOb2RlcyhjdXIsIG5vZGVsaXN0LT5ub2RlVGFiW2ldKTsKKwkgICAgaWYgKHJldCA9PSAtMSkKKwkgICAgICAgIGN1ciA9IG5vZGVsaXN0LT5ub2RlVGFiW2ldOworCX0KKwl4bWxYUGF0aEZyZWVPYmplY3Qob2JqKTsKKyAgICB9IGVsc2UgeworCXhzbHRUcmFuc2Zvcm1FcnJvcih4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpLCBOVUxMLCBOVUxMLAorCQkiZ2VuZXJhdGUtaWQoKSA6IGludmFsaWQgbnVtYmVyIG9mIGFyZ3MgJWRcbiIsIG5hcmdzKTsKKwljdHh0LT5lcnJvciA9IFhQQVRIX0lOVkFMSURfQVJJVFk7CisJcmV0dXJuOworICAgIH0KKyAgICAvKgorICAgICAqIE9rYXkgdGhpcyBpcyB1Z2x5IGJ1dCBzaG91bGQgd29yaywgdXNlIHRoZSBOb2RlUHRyIGFkZHJlc3MKKyAgICAgKiB0byBmb3JnZSB0aGUgSUQKKyAgICAgKi8KKyAgICB2YWwgPSAodW5zaWduZWQgbG9uZykoKGNoYXIgKiljdXIgLSAoY2hhciAqKTApOworICAgIHZhbCAvPSBzaXplb2YoeG1sTm9kZSk7CisgICAgc3ByaW50ZigoY2hhciAqKXN0ciwgImlkJWxkIiwgdmFsKTsKKyAgICB2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdTdHJpbmcoc3RyKSk7Cit9CisKKy8qKgorICogeHNsdFN5c3RlbVByb3BlcnR5RnVuY3Rpb246CisgKiBAY3R4dDogIHRoZSBYUGF0aCBQYXJzZXIgY29udGV4dAorICogQG5hcmdzOiAgdGhlIG51bWJlciBvZiBhcmd1bWVudHMKKyAqCisgKiBJbXBsZW1lbnQgdGhlIHN5c3RlbS1wcm9wZXJ0eSgpIFhTTFQgZnVuY3Rpb24KKyAqICAgb2JqZWN0IHN5c3RlbS1wcm9wZXJ0eShzdHJpbmcpCisgKi8KK3ZvaWQKK3hzbHRTeXN0ZW1Qcm9wZXJ0eUZ1bmN0aW9uKHhtbFhQYXRoUGFyc2VyQ29udGV4dFB0ciBjdHh0LCBpbnQgbmFyZ3MpeworICAgIHhtbFhQYXRoT2JqZWN0UHRyIG9iajsKKyAgICB4bWxDaGFyICpwcmVmaXgsICpuYW1lOworICAgIGNvbnN0IHhtbENoYXIgKm5zVVJJID0gTlVMTDsKKworICAgIGlmIChuYXJncyAhPSAxKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisJCSJzeXN0ZW0tcHJvcGVydHkoKSA6IGV4cGVjdHMgb25lIHN0cmluZyBhcmdcbiIpOworCWN0eHQtPmVycm9yID0gWFBBVEhfSU5WQUxJRF9BUklUWTsKKwlyZXR1cm47CisgICAgfQorICAgIGlmICgoY3R4dC0+dmFsdWUgPT0gTlVMTCkgfHwgKGN0eHQtPnZhbHVlLT50eXBlICE9IFhQQVRIX1NUUklORykpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoeHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dChjdHh0KSwgTlVMTCwgTlVMTCwKKwkgICAgInN5c3RlbS1wcm9wZXJ0eSgpIDogaW52YWxpZCBhcmcgZXhwZWN0aW5nIGEgc3RyaW5nXG4iKTsKKwljdHh0LT5lcnJvciA9IFhQQVRIX0lOVkFMSURfVFlQRTsKKwlyZXR1cm47CisgICAgfQorICAgIG9iaiA9IHZhbHVlUG9wKGN0eHQpOworICAgIGlmIChvYmotPnN0cmluZ3ZhbCA9PSBOVUxMKSB7CisJdmFsdWVQdXNoKGN0eHQsIHhtbFhQYXRoTmV3U3RyaW5nKChjb25zdCB4bWxDaGFyICopIiIpKTsKKyAgICB9IGVsc2UgeworCW5hbWUgPSB4bWxTcGxpdFFOYW1lMihvYmotPnN0cmluZ3ZhbCwgJnByZWZpeCk7CisJaWYgKG5hbWUgPT0gTlVMTCkgeworCSAgICBuYW1lID0geG1sU3RyZHVwKG9iai0+c3RyaW5ndmFsKTsKKwl9IGVsc2UgeworCSAgICBuc1VSSSA9IHhtbFhQYXRoTnNMb29rdXAoY3R4dC0+Y29udGV4dCwgcHJlZml4KTsKKwkgICAgaWYgKG5zVVJJID09IE5VTEwpIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisJCSAgICAic3lzdGVtLXByb3BlcnR5KCkgOiBwcmVmaXggJXMgaXMgbm90IGJvdW5kXG4iLCBwcmVmaXgpOworCSAgICB9CisJfQorCisJaWYgKHhtbFN0ckVxdWFsKG5zVVJJLCBYU0xUX05BTUVTUEFDRSkpIHsKKyNpZmRlZiBET0NCT09LX1hTTF9IQUNLCisJICAgIGlmICh4bWxTdHJFcXVhbChuYW1lLCAoY29uc3QgeG1sQ2hhciAqKSJ2ZW5kb3IiKSkgeworCQl4c2x0U3R5bGVzaGVldFB0ciBzaGVldDsKKwkJeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgdGN0eHQ7CisKKwkJdGN0eHQgPSB4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpOworCQlpZiAoKHRjdHh0ICE9IE5VTEwpICYmICh0Y3R4dC0+aW5zdCAhPSBOVUxMKSAmJgorCQkgICAgKHhtbFN0ckVxdWFsKHRjdHh0LT5pbnN0LT5uYW1lLCBCQURfQ0FTVCAidmFyaWFibGUiKSkgJiYKKwkJICAgICh0Y3R4dC0+aW5zdC0+cGFyZW50ICE9IE5VTEwpICYmCisJCSAgICAoeG1sU3RyRXF1YWwodGN0eHQtPmluc3QtPnBhcmVudC0+bmFtZSwKKwkJCQkgQkFEX0NBU1QgInRlbXBsYXRlIikpKQorCQkgICAgc2hlZXQgPSB0Y3R4dC0+c3R5bGU7CisJCWVsc2UKKwkJICAgIHNoZWV0ID0gTlVMTDsKKwkJaWYgKChzaGVldCAhPSBOVUxMKSAmJiAoc2hlZXQtPmRvYyAhPSBOVUxMKSAmJgorCQkgICAgKHNoZWV0LT5kb2MtPlVSTCAhPSBOVUxMKSAmJgorCQkgICAgKHhtbFN0cnN0cihzaGVldC0+ZG9jLT5VUkwsCisJCQkgICAgICAgKGNvbnN0IHhtbENoYXIgKikiY2h1bmsiKSAhPSBOVUxMKSkgeworCQkgICAgdmFsdWVQdXNoKGN0eHQsIHhtbFhQYXRoTmV3U3RyaW5nKAorCQkJKGNvbnN0IHhtbENoYXIgKikibGlieHNsdCAoU0FYT04gNi4yIGNvbXBhdGlibGUpIikpOworCisJCX0gZWxzZSB7CisJCSAgICB2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdTdHJpbmcoCisJCQkoY29uc3QgeG1sQ2hhciAqKVhTTFRfREVGQVVMVF9WRU5ET1IpKTsKKwkJfQorCSAgICB9IGVsc2UKKyNlbHNlCisJICAgIGlmICh4bWxTdHJFcXVhbChuYW1lLCAoY29uc3QgeG1sQ2hhciAqKSJ2ZW5kb3IiKSkgeworCQl2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdTdHJpbmcoCisJCQkgIChjb25zdCB4bWxDaGFyICopWFNMVF9ERUZBVUxUX1ZFTkRPUikpOworCSAgICB9IGVsc2UKKyNlbmRpZgorCSAgICBpZiAoeG1sU3RyRXF1YWwobmFtZSwgKGNvbnN0IHhtbENoYXIgKikidmVyc2lvbiIpKSB7CisJCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld1N0cmluZygKKwkJICAgIChjb25zdCB4bWxDaGFyICopWFNMVF9ERUZBVUxUX1ZFUlNJT04pKTsKKwkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChuYW1lLCAoY29uc3QgeG1sQ2hhciAqKSJ2ZW5kb3ItdXJsIikpIHsKKwkJdmFsdWVQdXNoKGN0eHQsIHhtbFhQYXRoTmV3U3RyaW5nKAorCQkgICAgKGNvbnN0IHhtbENoYXIgKilYU0xUX0RFRkFVTFRfVVJMKSk7CisJICAgIH0gZWxzZSB7CisJCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld1N0cmluZygoY29uc3QgeG1sQ2hhciAqKSIiKSk7CisJICAgIH0KKwl9CisJaWYgKG5hbWUgIT0gTlVMTCkKKwkgICAgeG1sRnJlZShuYW1lKTsKKwlpZiAocHJlZml4ICE9IE5VTEwpCisJICAgIHhtbEZyZWUocHJlZml4KTsKKyAgICB9CisgICAgeG1sWFBhdGhGcmVlT2JqZWN0KG9iaik7Cit9CisKKy8qKgorICogeHNsdEVsZW1lbnRBdmFpbGFibGVGdW5jdGlvbjoKKyAqIEBjdHh0OiAgdGhlIFhQYXRoIFBhcnNlciBjb250ZXh0CisgKiBAbmFyZ3M6ICB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cworICoKKyAqIEltcGxlbWVudCB0aGUgZWxlbWVudC1hdmFpbGFibGUoKSBYU0xUIGZ1bmN0aW9uCisgKiAgIGJvb2xlYW4gZWxlbWVudC1hdmFpbGFibGUoc3RyaW5nKQorICovCit2b2lkCit4c2x0RWxlbWVudEF2YWlsYWJsZUZ1bmN0aW9uKHhtbFhQYXRoUGFyc2VyQ29udGV4dFB0ciBjdHh0LCBpbnQgbmFyZ3MpeworICAgIHhtbFhQYXRoT2JqZWN0UHRyIG9iajsKKyAgICB4bWxDaGFyICpwcmVmaXgsICpuYW1lOworICAgIGNvbnN0IHhtbENoYXIgKm5zVVJJID0gTlVMTDsKKyAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciB0Y3R4dDsKKworICAgIGlmIChuYXJncyAhPSAxKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisJCSJlbGVtZW50LWF2YWlsYWJsZSgpIDogZXhwZWN0cyBvbmUgc3RyaW5nIGFyZ1xuIik7CisJY3R4dC0+ZXJyb3IgPSBYUEFUSF9JTlZBTElEX0FSSVRZOworCXJldHVybjsKKyAgICB9CisgICAgeG1sWFBhdGhTdHJpbmdGdW5jdGlvbihjdHh0LCAxKTsKKyAgICBpZiAoKGN0eHQtPnZhbHVlID09IE5VTEwpIHx8IChjdHh0LT52YWx1ZS0+dHlwZSAhPSBYUEFUSF9TVFJJTkcpKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisJICAgICJlbGVtZW50LWF2YWlsYWJsZSgpIDogaW52YWxpZCBhcmcgZXhwZWN0aW5nIGEgc3RyaW5nXG4iKTsKKwljdHh0LT5lcnJvciA9IFhQQVRIX0lOVkFMSURfVFlQRTsKKwlyZXR1cm47CisgICAgfQorICAgIG9iaiA9IHZhbHVlUG9wKGN0eHQpOworICAgIHRjdHh0ID0geHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dChjdHh0KTsKKyAgICBpZiAodGN0eHQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcih4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpLCBOVUxMLCBOVUxMLAorCQkiZWxlbWVudC1hdmFpbGFibGUoKSA6IGludGVybmFsIGVycm9yIHRjdHh0ID09IE5VTExcbiIpOworCXhtbFhQYXRoRnJlZU9iamVjdChvYmopOworCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld0Jvb2xlYW4oMCkpOworCXJldHVybjsKKyAgICB9CisKKworICAgIG5hbWUgPSB4bWxTcGxpdFFOYW1lMihvYmotPnN0cmluZ3ZhbCwgJnByZWZpeCk7CisgICAgaWYgKG5hbWUgPT0gTlVMTCkgeworCXhtbE5zUHRyIG5zOworCisJbmFtZSA9IHhtbFN0cmR1cChvYmotPnN0cmluZ3ZhbCk7CisJbnMgPSB4bWxTZWFyY2hOcyh0Y3R4dC0+aW5zdC0+ZG9jLCB0Y3R4dC0+aW5zdCwgTlVMTCk7CisJaWYgKG5zICE9IE5VTEwpIG5zVVJJID0geG1sU3RyZHVwKG5zLT5ocmVmKTsKKyAgICB9IGVsc2UgeworCW5zVVJJID0geG1sWFBhdGhOc0xvb2t1cChjdHh0LT5jb250ZXh0LCBwcmVmaXgpOworCWlmIChuc1VSSSA9PSBOVUxMKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcih4c2x0WFBhdGhHZXRUcmFuc2Zvcm1Db250ZXh0KGN0eHQpLCBOVUxMLCBOVUxMLAorCQkiZWxlbWVudC1hdmFpbGFibGUoKSA6IHByZWZpeCAlcyBpcyBub3QgYm91bmRcbiIsIHByZWZpeCk7CisJfQorICAgIH0KKworICAgIGlmICh4c2x0RXh0RWxlbWVudExvb2t1cCh0Y3R4dCwgbmFtZSwgbnNVUkkpICE9IE5VTEwpIHsKKwl2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdCb29sZWFuKDEpKTsKKyAgICB9IGVsc2UgeworCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld0Jvb2xlYW4oMCkpOworICAgIH0KKworICAgIHhtbFhQYXRoRnJlZU9iamVjdChvYmopOworICAgIGlmIChuYW1lICE9IE5VTEwpCisJeG1sRnJlZShuYW1lKTsKKyAgICBpZiAocHJlZml4ICE9IE5VTEwpCisJeG1sRnJlZShwcmVmaXgpOworfQorCisvKioKKyAqIHhzbHRGdW5jdGlvbkF2YWlsYWJsZUZ1bmN0aW9uOgorICogQGN0eHQ6ICB0aGUgWFBhdGggUGFyc2VyIGNvbnRleHQKKyAqIEBuYXJnczogIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzCisgKgorICogSW1wbGVtZW50IHRoZSBmdW5jdGlvbi1hdmFpbGFibGUoKSBYU0xUIGZ1bmN0aW9uCisgKiAgIGJvb2xlYW4gZnVuY3Rpb24tYXZhaWxhYmxlKHN0cmluZykKKyAqLwordm9pZAoreHNsdEZ1bmN0aW9uQXZhaWxhYmxlRnVuY3Rpb24oeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQsIGludCBuYXJncyl7CisgICAgeG1sWFBhdGhPYmplY3RQdHIgb2JqOworICAgIHhtbENoYXIgKnByZWZpeCwgKm5hbWU7CisgICAgY29uc3QgeG1sQ2hhciAqbnNVUkkgPSBOVUxMOworCisgICAgaWYgKG5hcmdzICE9IDEpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoeHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dChjdHh0KSwgTlVMTCwgTlVMTCwKKwkJImZ1bmN0aW9uLWF2YWlsYWJsZSgpIDogZXhwZWN0cyBvbmUgc3RyaW5nIGFyZ1xuIik7CisJY3R4dC0+ZXJyb3IgPSBYUEFUSF9JTlZBTElEX0FSSVRZOworCXJldHVybjsKKyAgICB9CisgICAgeG1sWFBhdGhTdHJpbmdGdW5jdGlvbihjdHh0LCAxKTsKKyAgICBpZiAoKGN0eHQtPnZhbHVlID09IE5VTEwpIHx8IChjdHh0LT52YWx1ZS0+dHlwZSAhPSBYUEFUSF9TVFJJTkcpKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisJICAgICJmdW5jdGlvbi1hdmFpbGFibGUoKSA6IGludmFsaWQgYXJnIGV4cGVjdGluZyBhIHN0cmluZ1xuIik7CisJY3R4dC0+ZXJyb3IgPSBYUEFUSF9JTlZBTElEX1RZUEU7CisJcmV0dXJuOworICAgIH0KKyAgICBvYmogPSB2YWx1ZVBvcChjdHh0KTsKKworICAgIG5hbWUgPSB4bWxTcGxpdFFOYW1lMihvYmotPnN0cmluZ3ZhbCwgJnByZWZpeCk7CisgICAgaWYgKG5hbWUgPT0gTlVMTCkgeworCW5hbWUgPSB4bWxTdHJkdXAob2JqLT5zdHJpbmd2YWwpOworICAgIH0gZWxzZSB7CisJbnNVUkkgPSB4bWxYUGF0aE5zTG9va3VwKGN0eHQtPmNvbnRleHQsIHByZWZpeCk7CisJaWYgKG5zVVJJID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisJCSJmdW5jdGlvbi1hdmFpbGFibGUoKSA6IHByZWZpeCAlcyBpcyBub3QgYm91bmRcbiIsIHByZWZpeCk7CisJfQorICAgIH0KKworICAgIGlmICh4bWxYUGF0aEZ1bmN0aW9uTG9va3VwTlMoY3R4dC0+Y29udGV4dCwgbmFtZSwgbnNVUkkpICE9IE5VTEwpIHsKKwl2YWx1ZVB1c2goY3R4dCwgeG1sWFBhdGhOZXdCb29sZWFuKDEpKTsKKyAgICB9IGVsc2UgeworCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld0Jvb2xlYW4oMCkpOworICAgIH0KKworICAgIHhtbFhQYXRoRnJlZU9iamVjdChvYmopOworICAgIGlmIChuYW1lICE9IE5VTEwpCisJeG1sRnJlZShuYW1lKTsKKyAgICBpZiAocHJlZml4ICE9IE5VTEwpCisJeG1sRnJlZShwcmVmaXgpOworfQorCisvKioKKyAqIHhzbHRDdXJyZW50RnVuY3Rpb246CisgKiBAY3R4dDogIHRoZSBYUGF0aCBQYXJzZXIgY29udGV4dAorICogQG5hcmdzOiAgdGhlIG51bWJlciBvZiBhcmd1bWVudHMKKyAqCisgKiBJbXBsZW1lbnQgdGhlIGN1cnJlbnQoKSBYU0xUIGZ1bmN0aW9uCisgKiAgIG5vZGUtc2V0IGN1cnJlbnQoKQorICovCitzdGF0aWMgdm9pZAoreHNsdEN1cnJlbnRGdW5jdGlvbih4bWxYUGF0aFBhcnNlckNvbnRleHRQdHIgY3R4dCwgaW50IG5hcmdzKXsKKyAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciB0Y3R4dDsKKworICAgIGlmIChuYXJncyAhPSAwKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCksIE5VTEwsIE5VTEwsCisJCSJjdXJyZW50KCkgOiBmdW5jdGlvbiB1c2VzIG5vIGFyZ3VtZW50XG4iKTsKKwljdHh0LT5lcnJvciA9IFhQQVRIX0lOVkFMSURfQVJJVFk7CisJcmV0dXJuOworICAgIH0KKyAgICB0Y3R4dCA9IHhzbHRYUGF0aEdldFRyYW5zZm9ybUNvbnRleHQoY3R4dCk7CisgICAgaWYgKHRjdHh0ID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoeHNsdFhQYXRoR2V0VHJhbnNmb3JtQ29udGV4dChjdHh0KSwgTlVMTCwgTlVMTCwKKwkJImN1cnJlbnQoKSA6IGludGVybmFsIGVycm9yIHRjdHh0ID09IE5VTExcbiIpOworCXZhbHVlUHVzaChjdHh0LCB4bWxYUGF0aE5ld05vZGVTZXQoTlVMTCkpOworICAgIH0gZWxzZSB7CisJdmFsdWVQdXNoKGN0eHQsIHhtbFhQYXRoTmV3Tm9kZVNldCh0Y3R4dC0+bm9kZSkpOyAvKiBjdXJyZW50ICovCisgICAgfQorfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAJCQkJCQkJCQkqCisgKiAJCVJlZ2lzdHJhdGlvbiBvZiBYU0xUIGFuZCBsaWJ4c2x0IGZ1bmN0aW9ucwkJKgorICogCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0UmVnaXN0ZXJBbGxGdW5jdGlvbnM6CisgKiBAY3R4dDogIHRoZSBYUGF0aCBjb250ZXh0CisgKgorICogUmVnaXN0ZXJzIGFsbCBkZWZhdWx0IFhTTFQgZnVuY3Rpb25zIGluIHRoaXMgY29udGV4dAorICovCit2b2lkCit4c2x0UmVnaXN0ZXJBbGxGdW5jdGlvbnMoeG1sWFBhdGhDb250ZXh0UHRyIGN0eHQpCit7CisgICAgeG1sWFBhdGhSZWdpc3RlckZ1bmMoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgImN1cnJlbnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRDdXJyZW50RnVuY3Rpb24pOworICAgIHhtbFhQYXRoUmVnaXN0ZXJGdW5jKGN0eHQsIChjb25zdCB4bWxDaGFyICopICJkb2N1bWVudCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgeHNsdERvY3VtZW50RnVuY3Rpb24pOworICAgIHhtbFhQYXRoUmVnaXN0ZXJGdW5jKGN0eHQsIChjb25zdCB4bWxDaGFyICopICJrZXkiLCB4c2x0S2V5RnVuY3Rpb24pOworICAgIHhtbFhQYXRoUmVnaXN0ZXJGdW5jKGN0eHQsIChjb25zdCB4bWxDaGFyICopICJ1bnBhcnNlZC1lbnRpdHktdXJpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0VW5wYXJzZWRFbnRpdHlVUklGdW5jdGlvbik7CisgICAgeG1sWFBhdGhSZWdpc3RlckZ1bmMoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgImZvcm1hdC1udW1iZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRGb3JtYXROdW1iZXJGdW5jdGlvbik7CisgICAgeG1sWFBhdGhSZWdpc3RlckZ1bmMoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgImdlbmVyYXRlLWlkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0R2VuZXJhdGVJZEZ1bmN0aW9uKTsKKyAgICB4bWxYUGF0aFJlZ2lzdGVyRnVuYyhjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAic3lzdGVtLXByb3BlcnR5IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0U3lzdGVtUHJvcGVydHlGdW5jdGlvbik7CisgICAgeG1sWFBhdGhSZWdpc3RlckZ1bmMoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgImVsZW1lbnQtYXZhaWxhYmxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0RWxlbWVudEF2YWlsYWJsZUZ1bmN0aW9uKTsKKyAgICB4bWxYUGF0aFJlZ2lzdGVyRnVuYyhjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAiZnVuY3Rpb24tYXZhaWxhYmxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0RnVuY3Rpb25BdmFpbGFibGVGdW5jdGlvbik7Cit9CmRpZmYgLS1naXQgYS9saWJ4c2x0L2Z1bmN0aW9ucy5oIGIvbGlieHNsdC9mdW5jdGlvbnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYWE0OTQxCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9mdW5jdGlvbnMuaApAQCAtMCwwICsxLDc4IEBACisvKgorICogU3VtbWFyeTogaW50ZXJmYWNlIGZvciB0aGUgWFNMVCBmdW5jdGlvbnMgbm90IGZyb20gWFBhdGgKKyAqIERlc2NyaXB0aW9uOiBhIHNldCBvZiBleHRyYSBmdW5jdGlvbnMgY29taW5nIGZyb20gWFNMVCBidXQgbm90IGluIFhQYXRoCisgKgorICogQ29weTogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIEF1dGhvcjogRGFuaWVsIFZlaWxsYXJkIGFuZCBCam9ybiBSZWVzZSA8YnJlZXNlQHVzZXJzLnNvdXJjZWZvcmdlLm5ldD4KKyAqLworCisjaWZuZGVmIF9fWE1MX1hTTFRfRlVOQ1RJT05TX0hfXworI2RlZmluZSBfX1hNTF9YU0xUX0ZVTkNUSU9OU19IX18KKworI2luY2x1ZGUgPGxpYnhtbC94cGF0aC5oPgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aEludGVybmFscy5oPgorI2luY2x1ZGUgInhzbHRleHBvcnRzLmgiCisjaW5jbHVkZSAieHNsdEludGVybmFscy5oIgorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qKgorICogWFNMVF9SRUdJU1RFUl9GVU5DVElPTl9MT09LVVA6CisgKgorICogUmVnaXN0ZXJpbmcgbWFjcm8sIG5vdCBnZW5lcmFsIHB1cnBvc2UgYXQgYWxsIGJ1dCB1c2VkIGluIGRpZmZlcmVudCBtb2R1bGVzLgorICovCisjZGVmaW5lIFhTTFRfUkVHSVNURVJfRlVOQ1RJT05fTE9PS1VQKGN0eHQpCQkJXAorICAgIHhtbFhQYXRoUmVnaXN0ZXJGdW5jTG9va3VwKChjdHh0KS0+eHBhdGhDdHh0LAkJXAorCSh4bWxYUGF0aEZ1bmNMb29rdXBGdW5jKSB4c2x0WFBhdGhGdW5jdGlvbkxvb2t1cCwJXAorCSh2b2lkICopKGN0eHQtPnhwYXRoQ3R4dCkpOworCitYU0xUUFVCRlVOIHhtbFhQYXRoRnVuY3Rpb24gWFNMVENBTEwKKwl4c2x0WFBhdGhGdW5jdGlvbkxvb2t1cAkJKHhtbFhQYXRoQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKm5zX3VyaSk7CisKKy8qCisgKiBJbnRlcmZhY2VzIGZvciB0aGUgZnVuY3Rpb25zIGltcGxlbWVudGF0aW9ucy4KKyAqLworCitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCisJeHNsdERvY3VtZW50RnVuY3Rpb24JCSh4bWxYUGF0aFBhcnNlckNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIGludCBuYXJncyk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCisJeHNsdEtleUZ1bmN0aW9uCQkJKHhtbFhQYXRoUGFyc2VyQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgaW50IG5hcmdzKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkKKwl4c2x0VW5wYXJzZWRFbnRpdHlVUklGdW5jdGlvbgkoeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQsCisJCQkJCSBpbnQgbmFyZ3MpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQorCXhzbHRGb3JtYXROdW1iZXJGdW5jdGlvbgkoeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIGN0eHQsCisJCQkJCSBpbnQgbmFyZ3MpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQorCXhzbHRHZW5lcmF0ZUlkRnVuY3Rpb24JCSh4bWxYUGF0aFBhcnNlckNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIGludCBuYXJncyk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCisJeHNsdFN5c3RlbVByb3BlcnR5RnVuY3Rpb24JKHhtbFhQYXRoUGFyc2VyQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgaW50IG5hcmdzKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkKKwl4c2x0RWxlbWVudEF2YWlsYWJsZUZ1bmN0aW9uCSh4bWxYUGF0aFBhcnNlckNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIGludCBuYXJncyk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCisJeHNsdEZ1bmN0aW9uQXZhaWxhYmxlRnVuY3Rpb24JKHhtbFhQYXRoUGFyc2VyQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgaW50IG5hcmdzKTsKKworLyoKKyAqIEFuZCB0aGUgcmVnaXN0cmF0aW9uCisgKi8KKworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQorCXhzbHRSZWdpc3RlckFsbEZ1bmN0aW9ucwkoeG1sWFBhdGhDb250ZXh0UHRyIGN0eHQpOworCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19YTUxfWFNMVF9GVU5DVElPTlNfSF9fICovCisKZGlmZiAtLWdpdCBhL2xpYnhzbHQvaW1wb3J0cy5jIGIvbGlieHNsdC9pbXBvcnRzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjM1MzhhYgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQvaW1wb3J0cy5jCkBAIC0wLDAgKzEsNDE5IEBACisvKgorICogaW1wb3J0cy5jOiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgWFNMVCBpbXBvcnRzCisgKgorICogUmVmZXJlbmNlOgorICogICBodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14c2x0LTE5OTkxMTE2CisgKgorICogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIGRhbmllbEB2ZWlsbGFyZC5jb20KKyAqLworCisjZGVmaW5lIElOX0xJQlhTTFQKKyNpbmNsdWRlICJsaWJ4c2x0LmgiCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2lmZGVmIEhBVkVfU1lTX1RZUEVTX0gKKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfTUFUSF9ICisjaW5jbHVkZSA8bWF0aC5oPgorI2VuZGlmCisjaWZkZWYgSEFWRV9GTE9BVF9ICisjaW5jbHVkZSA8ZmxvYXQuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfSUVFRUZQX0gKKyNpbmNsdWRlIDxpZWVlZnAuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfTkFOX0gKKyNpbmNsdWRlIDxuYW4uaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfQ1RZUEVfSAorI2luY2x1ZGUgPGN0eXBlLmg+CisjZW5kaWYKKworI2luY2x1ZGUgPGxpYnhtbC94bWxtZW1vcnkuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgPGxpYnhtbC9oYXNoLmg+CisjaW5jbHVkZSA8bGlieG1sL3htbGVycm9yLmg+CisjaW5jbHVkZSA8bGlieG1sL3VyaS5oPgorI2luY2x1ZGUgInhzbHQuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisjaW5jbHVkZSAieHNsdHV0aWxzLmgiCisjaW5jbHVkZSAicHJlcHJvYy5oIgorI2luY2x1ZGUgImltcG9ydHMuaCIKKyNpbmNsdWRlICJkb2N1bWVudHMuaCIKKyNpbmNsdWRlICJzZWN1cml0eS5oIgorI2luY2x1ZGUgInBhdHRlcm4uaCIKKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkJTW9kdWxlIGludGVyZmFjZXMJCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqCisgKiB4c2x0Rml4SW1wb3J0ZWRDb21wU3RlcHM6CisgKiBAbWFzdGVyOiB0aGUgIm1hc3RlciIgc3R5bGVzaGVldAorICogQHN0eWxlOiB0aGUgc3R5bGVzaGVldCBiZWluZyBpbXBvcnRlZCBieSB0aGUgbWFzdGVyCisgKgorICogbm9ybWFsaXplIHRoZSBjb21wIHN0ZXBzIGZvciB0aGUgc3R5bGVzaGVldCBiZWluZyBpbXBvcnRlZAorICogYnkgdGhlIG1hc3RlciwgdG9nZXRoZXIgd2l0aCBhbnkgaW1wb3J0cyB3aXRoaW4gdGhhdC4gCisgKgorICovCitzdGF0aWMgdm9pZCB4c2x0Rml4SW1wb3J0ZWRDb21wU3RlcHMoeHNsdFN0eWxlc2hlZXRQdHIgbWFzdGVyLCAKKwkJCXhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKSB7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgcmVzOworICAgIHhtbEhhc2hTY2FuKHN0eWxlLT50ZW1wbGF0ZXNIYXNoLAorCSAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lcikgeHNsdE5vcm1hbGl6ZUNvbXBTdGVwcywgbWFzdGVyKTsKKyAgICBtYXN0ZXItPmV4dHJhc05yICs9IHN0eWxlLT5leHRyYXNOcjsKKyAgICBmb3IgKHJlcyA9IHN0eWxlLT5pbXBvcnRzOyByZXMgIT0gTlVMTDsgcmVzID0gcmVzLT5uZXh0KSB7CisgICAgICAgIHhzbHRGaXhJbXBvcnRlZENvbXBTdGVwcyhtYXN0ZXIsIHJlcyk7CisgICAgfQorfQorCisvKioKKyAqIHhzbHRQYXJzZVN0eWxlc2hlZXRJbXBvcnQ6CisgKiBAc3R5bGU6ICB0aGUgWFNMVCBzdHlsZXNoZWV0CisgKiBAY3VyOiAgdGhlIGltcG9ydCBlbGVtZW50CisgKgorICogcGFyc2UgYW4gWFNMVCBzdHlsZXNoZWV0IGltcG9ydCBlbGVtZW50CisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcyAtMSBpbiBjYXNlIG9mIGZhaWx1cmUuCisgKi8KKworaW50Cit4c2x0UGFyc2VTdHlsZXNoZWV0SW1wb3J0KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGN1cikgeworICAgIGludCByZXQgPSAtMTsKKyAgICB4bWxEb2NQdHIgaW1wb3J0ID0gTlVMTDsKKyAgICB4bWxDaGFyICpiYXNlID0gTlVMTDsKKyAgICB4bWxDaGFyICp1cmlSZWYgPSBOVUxMOworICAgIHhtbENoYXIgKlVSSSA9IE5VTEw7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgcmVzOworICAgIHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYzsKKworICAgIGlmICgoY3VyID09IE5VTEwpIHx8IChzdHlsZSA9PSBOVUxMKSkKKwlyZXR1cm4gKHJldCk7CisKKyAgICB1cmlSZWYgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSJocmVmIiwgTlVMTCk7CisgICAgaWYgKHVyaVJlZiA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICJ4c2w6aW1wb3J0IDogbWlzc2luZyBocmVmIGF0dHJpYnV0ZVxuIik7CisJZ290byBlcnJvcjsKKyAgICB9CisKKyAgICBiYXNlID0geG1sTm9kZUdldEJhc2Uoc3R5bGUtPmRvYywgY3VyKTsKKyAgICBVUkkgPSB4bWxCdWlsZFVSSSh1cmlSZWYsIGJhc2UpOworICAgIGlmIChVUkkgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCSAgICAieHNsOmltcG9ydCA6IGludmFsaWQgVVJJIHJlZmVyZW5jZSAlc1xuIiwgdXJpUmVmKTsKKwlnb3RvIGVycm9yOworICAgIH0KKworICAgIHJlcyA9IHN0eWxlOworICAgIHdoaWxlIChyZXMgIT0gTlVMTCkgeworICAgICAgICBpZiAocmVzLT5kb2MgPT0gTlVMTCkKKwkgICAgYnJlYWs7CisJaWYgKHhtbFN0ckVxdWFsKHJlcy0+ZG9jLT5VUkwsIFVSSSkpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICAgICJ4c2w6aW1wb3J0IDogcmVjdXJzaW9uIGRldGVjdGVkIG9uIGltcG9ydGVkIFVSTCAlc1xuIiwgVVJJKTsKKwkgICAgZ290byBlcnJvcjsKKwl9CisJcmVzID0gcmVzLT5wYXJlbnQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBTZWN1cml0eSBmcmFtZXdvcmsgY2hlY2sKKyAgICAgKi8KKyAgICBzZWMgPSB4c2x0R2V0RGVmYXVsdFNlY3VyaXR5UHJlZnMoKTsKKyAgICBpZiAoc2VjICE9IE5VTEwpIHsKKwlpbnQgc2VjcmVzOworCisJc2VjcmVzID0geHNsdENoZWNrUmVhZChzZWMsIE5VTEwsIFVSSSk7CisJaWYgKHNlY3JlcyA9PSAwKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkgInhzbDppbXBvcnQ6IHJlYWQgcmlnaHRzIGZvciAlcyBkZW5pZWRcbiIsCisJCQkgICAgIFVSSSk7CisJICAgIGdvdG8gZXJyb3I7CisJfQorICAgIH0KKworICAgIGltcG9ydCA9IHhzbHREb2NEZWZhdWx0TG9hZGVyKFVSSSwgc3R5bGUtPmRpY3QsIFhTTFRfUEFSU0VfT1BUSU9OUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBzdHlsZSwgWFNMVF9MT0FEX1NUWUxFU0hFRVQpOworICAgIGlmIChpbXBvcnQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCSAgICAieHNsOmltcG9ydCA6IHVuYWJsZSB0byBsb2FkICVzXG4iLCBVUkkpOworCWdvdG8gZXJyb3I7CisgICAgfQorCisgICAgcmVzID0geHNsdFBhcnNlU3R5bGVzaGVldEltcG9ydGVkRG9jKGltcG9ydCwgc3R5bGUpOworICAgIGlmIChyZXMgIT0gTlVMTCkgeworCXJlcy0+bmV4dCA9IHN0eWxlLT5pbXBvcnRzOworCXN0eWxlLT5pbXBvcnRzID0gcmVzOworCWlmIChzdHlsZS0+cGFyZW50ID09IE5VTEwpIHsKKwkgICAgeHNsdEZpeEltcG9ydGVkQ29tcFN0ZXBzKHN0eWxlLCByZXMpOworCX0KKwlyZXQgPSAwOworICAgIH0gZWxzZSB7CisJeG1sRnJlZURvYyhpbXBvcnQpOworCX0KKworZXJyb3I6CisgICAgaWYgKHVyaVJlZiAhPSBOVUxMKQorCXhtbEZyZWUodXJpUmVmKTsKKyAgICBpZiAoYmFzZSAhPSBOVUxMKQorCXhtbEZyZWUoYmFzZSk7CisgICAgaWYgKFVSSSAhPSBOVUxMKQorCXhtbEZyZWUoVVJJKTsKKworICAgIHJldHVybiAocmV0KTsKK30KKworLyoqCisgKiB4c2x0UGFyc2VTdHlsZXNoZWV0SW5jbHVkZToKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBjdXI6ICB0aGUgaW5jbHVkZSBub2RlCisgKgorICogcGFyc2UgYW4gWFNMVCBzdHlsZXNoZWV0IGluY2x1ZGUgZWxlbWVudAorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MgLTEgaW4gY2FzZSBvZiBmYWlsdXJlCisgKi8KKworaW50Cit4c2x0UGFyc2VTdHlsZXNoZWV0SW5jbHVkZSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBjdXIpIHsKKyAgICBpbnQgcmV0ID0gLTE7CisgICAgeG1sRG9jUHRyIG9sZERvYzsKKyAgICB4bWxDaGFyICpiYXNlID0gTlVMTDsKKyAgICB4bWxDaGFyICp1cmlSZWYgPSBOVUxMOworICAgIHhtbENoYXIgKlVSSSA9IE5VTEw7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgcmVzdWx0OworICAgIHhzbHREb2N1bWVudFB0ciBpbmNsdWRlOworICAgIHhzbHREb2N1bWVudFB0ciBkb2NwdHI7CisgICAgaW50IG9sZE5vcHJlcHJvYzsKKworICAgIGlmICgoY3VyID09IE5VTEwpIHx8IChzdHlsZSA9PSBOVUxMKSkKKwlyZXR1cm4gKHJldCk7CisKKyAgICB1cmlSZWYgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSJocmVmIiwgTlVMTCk7CisgICAgaWYgKHVyaVJlZiA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICJ4c2w6aW5jbHVkZSA6IG1pc3NpbmcgaHJlZiBhdHRyaWJ1dGVcbiIpOworCWdvdG8gZXJyb3I7CisgICAgfQorCisgICAgYmFzZSA9IHhtbE5vZGVHZXRCYXNlKHN0eWxlLT5kb2MsIGN1cik7CisgICAgVVJJID0geG1sQnVpbGRVUkkodXJpUmVmLCBiYXNlKTsKKyAgICBpZiAoVVJJID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkgICAgInhzbDppbmNsdWRlIDogaW52YWxpZCBVUkkgcmVmZXJlbmNlICVzXG4iLCB1cmlSZWYpOworCWdvdG8gZXJyb3I7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBpbiBvcmRlciB0byBkZXRlY3QgcmVjdXJzaW9uLCB3ZSBjaGVjayBhbGwgcHJldmlvdXNseSBpbmNsdWRlZAorICAgICAqIHN0eWxlc2hlZXRzLgorICAgICAqLworICAgIGRvY3B0ciA9IHN0eWxlLT5pbmNsdWRlczsKKyAgICB3aGlsZSAoZG9jcHRyICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKHhtbFN0ckVxdWFsKGRvY3B0ci0+ZG9jLT5VUkwsIFVSSSkpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICAgICAieHNsOmluY2x1ZGUgOiByZWN1cnNpb24gZGV0ZWN0ZWQgb24gaW5jbHVkZWQgVVJMICVzXG4iLCBVUkkpOworCSAgICBnb3RvIGVycm9yOworCX0KKwlkb2NwdHIgPSBkb2NwdHItPmluY2x1ZGVzOworICAgIH0KKworICAgIGluY2x1ZGUgPSB4c2x0TG9hZFN0eWxlRG9jdW1lbnQoc3R5bGUsIFVSSSk7CisgICAgaWYgKGluY2x1ZGUgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCSAgICAieHNsOmluY2x1ZGUgOiB1bmFibGUgdG8gbG9hZCAlc1xuIiwgVVJJKTsKKwlnb3RvIGVycm9yOworICAgIH0KKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQgICAgCisgICAgaWYgKElTX1hTTFRfRUxFTV9GQVNUKGN1cikgJiYgKGN1ci0+cHN2aSAhPSBOVUxMKSkgeworCSgoeHNsdFN0eWxlSXRlbUluY2x1ZGVQdHIpIGN1ci0+cHN2aSktPmluY2x1ZGUgPSBpbmNsdWRlOworICAgIH0gZWxzZSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICJJbnRlcm5hbCBlcnJvcjogKHhzbHRQYXJzZVN0eWxlc2hlZXRJbmNsdWRlKSAiCisJICAgICJUaGUgeHNsOmluY2x1ZGUgZWxlbWVudCB3YXMgbm90IGNvbXBpbGVkLlxuIiwgVVJJKTsKKwlzdHlsZS0+ZXJyb3JzKys7CisgICAgfQorI2VuZGlmCisgICAgb2xkRG9jID0gc3R5bGUtPmRvYzsKKyAgICBzdHlsZS0+ZG9jID0gaW5jbHVkZS0+ZG9jOworICAgIC8qIGNoYWluIHRvIHN0eWxlc2hlZXQgZm9yIHJlY3Vyc2lvbiBjaGVja2luZyAqLworICAgIGluY2x1ZGUtPmluY2x1ZGVzID0gc3R5bGUtPmluY2x1ZGVzOworICAgIHN0eWxlLT5pbmNsdWRlcyA9IGluY2x1ZGU7CisgICAgb2xkTm9wcmVwcm9jID0gc3R5bGUtPm5vcHJlcHJvYzsKKyAgICBzdHlsZS0+bm9wcmVwcm9jID0gaW5jbHVkZS0+cHJlcHJvYzsKKyAgICAvKgorICAgICogVE9ETzogVGhpcyB3aWxsIGNoYW5nZSBzb21lIHZhbHVlcyBvZiB0aGUKKyAgICAqICBpbmNsdWRpbmcgc3R5bGVzaGVldCB3aXRoIGV2ZXJ5IGluY2x1ZGVkIG1vZHVsZQorICAgICogIChlLmcuIGV4Y2x1ZGVkLXJlc3VsdC1wcmVmaXhlcykKKyAgICAqICBXZSBuZWVkIHRvIHN0cmljdGx5IHNlcGVyYXRlIHN1Y2ggc3R5bGVzaGVldC1vd25lZCB2YWx1ZXMuCisgICAgKi8KKyAgICByZXN1bHQgPSB4c2x0UGFyc2VTdHlsZXNoZWV0UHJvY2VzcyhzdHlsZSwgaW5jbHVkZS0+ZG9jKTsKKyAgICBzdHlsZS0+bm9wcmVwcm9jID0gb2xkTm9wcmVwcm9jOworICAgIGluY2x1ZGUtPnByZXByb2MgPSAxOworICAgIHN0eWxlLT5pbmNsdWRlcyA9IGluY2x1ZGUtPmluY2x1ZGVzOworICAgIHN0eWxlLT5kb2MgPSBvbGREb2M7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisJcmV0ID0gLTE7CisJZ290byBlcnJvcjsKKyAgICB9CisgICAgcmV0ID0gMDsKKworZXJyb3I6CisgICAgaWYgKHVyaVJlZiAhPSBOVUxMKQorCXhtbEZyZWUodXJpUmVmKTsKKyAgICBpZiAoYmFzZSAhPSBOVUxMKQorCXhtbEZyZWUoYmFzZSk7CisgICAgaWYgKFVSSSAhPSBOVUxMKQorCXhtbEZyZWUoVVJJKTsKKworICAgIHJldHVybiAocmV0KTsKK30KKworLyoqCisgKiB4c2x0TmV4dEltcG9ydDoKKyAqIEBjdXI6ICB0aGUgY3VycmVudCBYU0xUIHN0eWxlc2hlZXQKKyAqCisgKiBGaW5kIHRoZSBuZXh0IHN0eWxlc2hlZXQgaW4gaW1wb3J0IHByZWNlZGVuY2UuCisgKgorICogUmV0dXJucyB0aGUgbmV4dCBzdHlsZXNoZWV0IG9yIE5VTEwgaWYgaXQgd2FzIHRoZSBsYXN0IG9uZQorICovCisKK3hzbHRTdHlsZXNoZWV0UHRyCit4c2x0TmV4dEltcG9ydCh4c2x0U3R5bGVzaGVldFB0ciBjdXIpIHsKKyAgICBpZiAoY3VyID09IE5VTEwpCisJcmV0dXJuKE5VTEwpOworICAgIGlmIChjdXItPmltcG9ydHMgIT0gTlVMTCkKKwlyZXR1cm4oY3VyLT5pbXBvcnRzKTsKKyAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpCisJcmV0dXJuKGN1ci0+bmV4dCkgOworICAgIGRvIHsKKwljdXIgPSBjdXItPnBhcmVudDsKKwlpZiAoY3VyID09IE5VTEwpIGJyZWFrOworCWlmIChjdXItPm5leHQgIT0gTlVMTCkgcmV0dXJuKGN1ci0+bmV4dCk7CisgICAgfSB3aGlsZSAoY3VyICE9IE5VTEwpOworICAgIHJldHVybihjdXIpOworfQorCisvKioKKyAqIHhzbHROZWVkRWxlbVNwYWNlSGFuZGxpbmc6CisgKiBAY3R4dDogIGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICoKKyAqIENoZWNrcyB3aGV0aGVyIHRoYXQgc3R5bGVzaGVldCByZXF1aXJlcyB3aGl0ZS1zcGFjZSBzdHJpcHBpbmcKKyAqCisgKiBSZXR1cm5zIDEgaWYgc3BhY2Ugc2hvdWxkIGJlIHN0cmlwcGVkLCAwIGlmIG5vdAorICovCisKK2ludAoreHNsdE5lZWRFbGVtU3BhY2VIYW5kbGluZyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KSB7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CisKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorCXJldHVybigwKTsKKyAgICBzdHlsZSA9IGN0eHQtPnN0eWxlOworICAgIHdoaWxlIChzdHlsZSAhPSBOVUxMKSB7CisJaWYgKHN0eWxlLT5zdHJpcFNwYWNlcyAhPSBOVUxMKQorCSAgICByZXR1cm4oMSk7CisJc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisgICAgfQorICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0RmluZEVsZW1TcGFjZUhhbmRsaW5nOgorICogQGN0eHQ6ICBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBub2RlOiAgYW4gWE1MIG5vZGUKKyAqCisgKiBGaW5kIHN0cmlwLXNwYWNlIG9yIHByZXNlcnZlLXNwYWNlIGluZm9ybWF0aW9ucyBmb3IgYW4gZWxlbWVudAorICogcmVzcGVjdCB0aGUgaW1wb3J0IHByZWNlZGVuY2Ugb3IgdGhlIHdpbGRjYXJkcworICoKKyAqIFJldHVybnMgMSBpZiBzcGFjZSBzaG91bGQgYmUgc3RyaXBwZWQsIDAgaWYgbm90LCBhbmQgMiBpZiBldmVyeXRoaW5nCisgKiAgICAgICAgIHNob3VsZCBiZSBDRFRBVEEgd3JhcHBlZC4KKyAqLworCitpbnQKK3hzbHRGaW5kRWxlbVNwYWNlSGFuZGxpbmcoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKSB7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CisgICAgY29uc3QgeG1sQ2hhciAqdmFsOworCisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQorCXJldHVybigwKTsKKyAgICBzdHlsZSA9IGN0eHQtPnN0eWxlOworICAgIHdoaWxlIChzdHlsZSAhPSBOVUxMKSB7CisJaWYgKG5vZGUtPm5zICE9IE5VTEwpIHsKKwkgICAgdmFsID0gKGNvbnN0IHhtbENoYXIgKikKKwkgICAgICB4bWxIYXNoTG9va3VwMihzdHlsZS0+c3RyaXBTcGFjZXMsIG5vZGUtPm5hbWUsIG5vZGUtPm5zLT5ocmVmKTsKKyAgICAgICAgICAgIGlmICh2YWwgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIHZhbCA9IChjb25zdCB4bWxDaGFyICopCisgICAgICAgICAgICAgICAgICAgIHhtbEhhc2hMb29rdXAyKHN0eWxlLT5zdHJpcFNwYWNlcywgQkFEX0NBU1QgIioiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLT5ucy0+aHJlZik7CisgICAgICAgICAgICB9CisJfSBlbHNlIHsKKwkgICAgdmFsID0gKGNvbnN0IHhtbENoYXIgKikKKwkJICB4bWxIYXNoTG9va3VwMihzdHlsZS0+c3RyaXBTcGFjZXMsIG5vZGUtPm5hbWUsIE5VTEwpOworCX0KKwlpZiAodmFsICE9IE5VTEwpIHsKKwkgICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgKHhtbENoYXIgKikgInN0cmlwIikpCisJCXJldHVybigxKTsKKwkgICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgKHhtbENoYXIgKikgInByZXNlcnZlIikpCisJCXJldHVybigwKTsKKwl9CisJaWYgKHN0eWxlLT5zdHJpcEFsbCA9PSAxKQorCSAgICByZXR1cm4oMSk7CisJaWYgKHN0eWxlLT5zdHJpcEFsbCA9PSAtMSkKKwkgICAgcmV0dXJuKDApOworCisJc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisgICAgfQorICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0RmluZFRlbXBsYXRlOgorICogQGN0eHQ6ICBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBuYW1lOiB0aGUgdGVtcGxhdGUgbmFtZQorICogQG5hbWVVUkk6IHRoZSB0ZW1wbGF0ZSBuYW1lIFVSSQorICoKKyAqIEZpbmRzIHRoZSBuYW1lZCB0ZW1wbGF0ZSwgYXBwbHkgaW1wb3J0IHByZWNlZGVuY2UgcnVsZS4KKyAqIFJFVklTSVQgVE9ETzogV2UnbGwgY2hhbmdlIHRoZSBuYW1lVVJJIGZpZWxkcyBvZgorICogIHRlbXBsYXRlcyB0byBiZSBpbiB0aGUgc3RyaW5nIGRpY3QsIHNvIGlmIHRoZQorICogIHNwZWNpZmllZCBAbmFtZVVSSSBpcyBpbiB0aGUgc2FtZSBkaWN0LCB0aGVuIHVzZSBwb2ludGVyCisgKiAgY29tcGFyaXNvbi4gQ2hlY2sgaWYgdGhpcyBjYW4gYmUgZG9uZSBpbiBhIHNhbmUgd2F5LgorICogIE1heWJlIHRoaXMgZnVuY3Rpb24gaXMgbm90IG5lZWRlZCBpbnRlcm5hbGx5IGF0CisgKiAgdHJhbnNmb3JtYXRpb24tdGltZSBpZiB3ZSBoYXJkLXdpcmUgdGhlIGNhbGxlZCB0ZW1wbGF0ZXMKKyAqICB0byB0aGUgY2FsbGVyLgorICoKKyAqIFJldHVybnMgdGhlIHhzbHRUZW1wbGF0ZVB0ciBvciBOVUxMIGlmIG5vdCBmb3VuZAorICovCit4c2x0VGVtcGxhdGVQdHIKK3hzbHRGaW5kVGVtcGxhdGUoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkgICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lVVJJKSB7CisgICAgeHNsdFRlbXBsYXRlUHRyIGN1cjsKKyAgICB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZTsKKworICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKKwlyZXR1cm4oTlVMTCk7CisgICAgc3R5bGUgPSBjdHh0LT5zdHlsZTsKKyAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworCWN1ciA9IHN0eWxlLT50ZW1wbGF0ZXM7CisJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJICAgIGlmICh4bWxTdHJFcXVhbChuYW1lLCBjdXItPm5hbWUpKSB7CisJCWlmICgoKG5hbWVVUkkgPT0gTlVMTCkgJiYgKGN1ci0+bmFtZVVSSSA9PSBOVUxMKSkgfHwKKwkJICAgICgobmFtZVVSSSAhPSBOVUxMKSAmJiAoY3VyLT5uYW1lVVJJICE9IE5VTEwpICYmCisJCSAgICAgKHhtbFN0ckVxdWFsKG5hbWVVUkksIGN1ci0+bmFtZVVSSSkpKSkgeworCQkgICAgcmV0dXJuKGN1cik7CisJCX0KKwkgICAgfQorCSAgICBjdXIgPSBjdXItPm5leHQ7CisJfQorCisJc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisgICAgfQorICAgIHJldHVybihOVUxMKTsKK30KKwpkaWZmIC0tZ2l0IGEvbGlieHNsdC9pbXBvcnRzLmggYi9saWJ4c2x0L2ltcG9ydHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zODY1NmYxCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9pbXBvcnRzLmgKQEAgLTAsMCArMSw3NSBAQAorLyoKKyAqIFN1bW1hcnk6IGludGVyZmFjZSBmb3IgdGhlIFhTTFQgaW1wb3J0IHN1cHBvcnQKKyAqIERlc2NyaXB0aW9uOiBtYWNyb3MgYW5kIGZ1Y3Rpb25zIG5lZWRlZCB0byBpbXBsZW1lbnQgYW5kCisgKiAgICAgICAgICAgICAgYWNjZXNzIHRoZSBpbXBvcnQgdHJlZQorICoKKyAqIENvcHk6IFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBBdXRob3I6IERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVF9JTVBPUlRTX0hfXworI2RlZmluZSBfX1hNTF9YU0xUX0lNUE9SVFNfSF9fCisKKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgInhzbHRleHBvcnRzLmgiCisjaW5jbHVkZSAieHNsdEludGVybmFscy5oIgorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qKgorICogWFNMVF9HRVRfSU1QT1JUX1BUUjoKKyAqCisgKiBBIG1hY3JvIHRvIGltcG9ydCBwb2ludGVycyBmcm9tIHRoZSBzdHlsZXNoZWV0IGNhc2NhZGluZyBvcmRlci4KKyAqLworI2RlZmluZSBYU0xUX0dFVF9JTVBPUlRfUFRSKHJlcywgc3R5bGUsIG5hbWUpIHsJCQlcCisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3QgPSBzdHlsZTsJCQkJXAorICAgIHJlcyA9IE5VTEw7CQkJCQkJCVwKKyAgICB3aGlsZSAoc3QgIT0gTlVMTCkgewkJCQkJXAorCWlmIChzdC0+bmFtZSAhPSBOVUxMKSB7IHJlcyA9IHN0LT5uYW1lOyBicmVhazsgfQlcCisJc3QgPSB4c2x0TmV4dEltcG9ydChzdCk7CQkJCVwKKyAgICB9fQorCisvKioKKyAqIFhTTFRfR0VUX0lNUE9SVF9JTlQ6CisgKgorICogQSBtYWNybyB0byBpbXBvcnQgaW50ZXJnZXJzIGZyb20gdGhlIHN0eWxlc2hlZXQgY2FzY2FkaW5nIG9yZGVyLgorICovCisjZGVmaW5lIFhTTFRfR0VUX0lNUE9SVF9JTlQocmVzLCBzdHlsZSwgbmFtZSkgewkJCVwKKyAgICB4c2x0U3R5bGVzaGVldFB0ciBzdCA9IHN0eWxlOwkJCQlcCisgICAgcmVzID0gLTE7CQkJCQkJCVwKKyAgICB3aGlsZSAoc3QgIT0gTlVMTCkgewkJCQkJXAorCWlmIChzdC0+bmFtZSAhPSAtMSkgeyByZXMgPSBzdC0+bmFtZTsgYnJlYWs7IH0JXAorCXN0ID0geHNsdE5leHRJbXBvcnQoc3QpOwkJCQlcCisgICAgfX0KKworLyoKKyAqIE1vZHVsZSBpbnRlcmZhY2VzCisgKi8KK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkJCisJCQl4c2x0UGFyc2VTdHlsZXNoZWV0SW1wb3J0KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkJICB4bWxOb2RlUHRyIGN1cik7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCQorCQkJeHNsdFBhcnNlU3R5bGVzaGVldEluY2x1ZGUKKwkJCQkJCSAoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCQkgIHhtbE5vZGVQdHIgY3VyKTsKK1hTTFRQVUJGVU4geHNsdFN0eWxlc2hlZXRQdHIgWFNMVENBTEwJCisJCQl4c2x0TmV4dEltcG9ydAkJICh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCQorCQkJeHNsdE5lZWRFbGVtU3BhY2VIYW5kbGluZyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkJCisJCQl4c2x0RmluZEVsZW1TcGFjZUhhbmRsaW5nKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgIHhtbE5vZGVQdHIgbm9kZSk7CitYU0xUUFVCRlVOIHhzbHRUZW1wbGF0ZVB0ciBYU0xUQ0FMTAkJCisJCQl4c2x0RmluZFRlbXBsYXRlCSAoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSAgY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkJCQkJCSAgY29uc3QgeG1sQ2hhciAqbmFtZVVSSSk7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX0lNUE9SVFNfSF9fICovCisKZGlmZiAtLWdpdCBhL2xpYnhzbHQva2V5cy5jIGIvbGlieHNsdC9rZXlzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDI4YWVhNgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQva2V5cy5jCkBAIC0wLDAgKzEsOTE5IEBACisvKgorICoga2V5cy5jOiBJbXBsZW1ldGF0aW9uIG9mIHRoZSBrZXlzIHN1cHBvcnQKKyAqCisgKiBSZWZlcmVuY2U6CisgKiAgIGh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhzbHQtMTk5OTExMTYKKyAqCisgKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCisgKgorICogZGFuaWVsQHZlaWxsYXJkLmNvbQorICovCisKKyNkZWZpbmUgSU5fTElCWFNMVAorI2luY2x1ZGUgImxpYnhzbHQuaCIKKworI2luY2x1ZGUgPHN0cmluZy5oPgorCisjaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgorI2luY2x1ZGUgPGxpYnhtbC90cmVlLmg+CisjaW5jbHVkZSA8bGlieG1sL3ZhbGlkLmg+CisjaW5jbHVkZSA8bGlieG1sL2hhc2guaD4KKyNpbmNsdWRlIDxsaWJ4bWwveG1sZXJyb3IuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvcGFyc2VySW50ZXJuYWxzLmg+CisjaW5jbHVkZSA8bGlieG1sL3hwYXRoSW50ZXJuYWxzLmg+CisjaW5jbHVkZSAieHNsdC5oIgorI2luY2x1ZGUgInhzbHRJbnRlcm5hbHMuaCIKKyNpbmNsdWRlICJ4c2x0dXRpbHMuaCIKKyNpbmNsdWRlICJpbXBvcnRzLmgiCisjaW5jbHVkZSAidGVtcGxhdGVzLmgiCisjaW5jbHVkZSAia2V5cy5oIgorCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHCisjZGVmaW5lIFdJVEhfWFNMVF9ERUJVR19LRVlTCisjZW5kaWYKKworc3RhdGljIGludAoreHNsdEluaXREb2NLZXlUYWJsZSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICpuYW1lLAorICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lVVJJKTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogCQkJCQkJCQkJKgorICogCQkJVHlwZSBmdW5jdGlvbnMgCQkJCQkqCisgKiAJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHROZXdLZXlEZWY6CisgKiBAbmFtZTogIHRoZSBrZXkgbmFtZSBvciBOVUxMCisgKiBAbmFtZVVSSTogIHRoZSBuYW1lIFVSSSBvciBOVUxMCisgKgorICogQ3JlYXRlIGEgbmV3IFhTTFQgS2V5RGVmCisgKgorICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHhzbHRLZXlEZWZQdHIgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3N0YXRpYyB4c2x0S2V5RGVmUHRyCit4c2x0TmV3S2V5RGVmKGNvbnN0IHhtbENoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKm5hbWVVUkkpIHsKKyAgICB4c2x0S2V5RGVmUHRyIGN1cjsKKworICAgIGN1ciA9ICh4c2x0S2V5RGVmUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhzbHRLZXlEZWYpKTsKKyAgICBpZiAoY3VyID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkJInhzbHROZXdLZXlEZWYgOiBtYWxsb2MgZmFpbGVkXG4iKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIG1lbXNldChjdXIsIDAsIHNpemVvZih4c2x0S2V5RGVmKSk7CisgICAgaWYgKG5hbWUgIT0gTlVMTCkKKwljdXItPm5hbWUgPSB4bWxTdHJkdXAobmFtZSk7CisgICAgaWYgKG5hbWVVUkkgIT0gTlVMTCkKKwljdXItPm5hbWVVUkkgPSB4bWxTdHJkdXAobmFtZVVSSSk7CisgICAgY3VyLT5uc0xpc3QgPSBOVUxMOworICAgIHJldHVybihjdXIpOworfQorCisvKioKKyAqIHhzbHRGcmVlS2V5RGVmOgorICogQGtleWQ6ICBhbiBYU0xUIGtleSBkZWZpbml0aW9uCisgKgorICogRnJlZSB1cCB0aGUgbWVtb3J5IGFsbG9jYXRlZCBieSBAa2V5ZAorICovCitzdGF0aWMgdm9pZAoreHNsdEZyZWVLZXlEZWYoeHNsdEtleURlZlB0ciBrZXlkKSB7CisgICAgaWYgKGtleWQgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaWYgKGtleWQtPmNvbXAgIT0gTlVMTCkKKwl4bWxYUGF0aEZyZWVDb21wRXhwcihrZXlkLT5jb21wKTsKKyAgICBpZiAoa2V5ZC0+dXNlY29tcCAhPSBOVUxMKQorCXhtbFhQYXRoRnJlZUNvbXBFeHByKGtleWQtPnVzZWNvbXApOworICAgIGlmIChrZXlkLT5uYW1lICE9IE5VTEwpCisJeG1sRnJlZShrZXlkLT5uYW1lKTsKKyAgICBpZiAoa2V5ZC0+bmFtZVVSSSAhPSBOVUxMKQorCXhtbEZyZWUoa2V5ZC0+bmFtZVVSSSk7CisgICAgaWYgKGtleWQtPm1hdGNoICE9IE5VTEwpCisJeG1sRnJlZShrZXlkLT5tYXRjaCk7CisgICAgaWYgKGtleWQtPnVzZSAhPSBOVUxMKQorCXhtbEZyZWUoa2V5ZC0+dXNlKTsKKyAgICBpZiAoa2V5ZC0+bnNMaXN0ICE9IE5VTEwpCisgICAgICAgIHhtbEZyZWUoa2V5ZC0+bnNMaXN0KTsKKyAgICBtZW1zZXQoa2V5ZCwgLTEsIHNpemVvZih4c2x0S2V5RGVmKSk7CisgICAgeG1sRnJlZShrZXlkKTsKK30KKworLyoqCisgKiB4c2x0RnJlZUtleURlZkxpc3Q6CisgKiBAa2V5ZDogIGFuIFhTTFQga2V5IGRlZmluaXRpb24gbGlzdAorICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgYnkgYWxsIHRoZSBlbGVtZW50cyBvZiBAa2V5ZAorICovCitzdGF0aWMgdm9pZAoreHNsdEZyZWVLZXlEZWZMaXN0KHhzbHRLZXlEZWZQdHIga2V5ZCkgeworICAgIHhzbHRLZXlEZWZQdHIgY3VyOworCisgICAgd2hpbGUgKGtleWQgIT0gTlVMTCkgeworCWN1ciA9IGtleWQ7CisJa2V5ZCA9IGtleWQtPm5leHQ7CisJeHNsdEZyZWVLZXlEZWYoY3VyKTsKKyAgICB9Cit9CisKKy8qKgorICogeHNsdE5ld0tleVRhYmxlOgorICogQG5hbWU6ICB0aGUga2V5IG5hbWUgb3IgTlVMTAorICogQG5hbWVVUkk6ICB0aGUgbmFtZSBVUkkgb3IgTlVMTAorICoKKyAqIENyZWF0ZSBhIG5ldyBYU0xUIEtleVRhYmxlCisgKgorICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHhzbHRLZXlUYWJsZVB0ciBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworc3RhdGljIHhzbHRLZXlUYWJsZVB0cgoreHNsdE5ld0tleVRhYmxlKGNvbnN0IHhtbENoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKm5hbWVVUkkpIHsKKyAgICB4c2x0S2V5VGFibGVQdHIgY3VyOworCisgICAgY3VyID0gKHhzbHRLZXlUYWJsZVB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0S2V5VGFibGUpKTsKKyAgICBpZiAoY3VyID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkJInhzbHROZXdLZXlUYWJsZSA6IG1hbGxvYyBmYWlsZWRcbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KGN1ciwgMCwgc2l6ZW9mKHhzbHRLZXlUYWJsZSkpOworICAgIGlmIChuYW1lICE9IE5VTEwpCisJY3VyLT5uYW1lID0geG1sU3RyZHVwKG5hbWUpOworICAgIGlmIChuYW1lVVJJICE9IE5VTEwpCisJY3VyLT5uYW1lVVJJID0geG1sU3RyZHVwKG5hbWVVUkkpOworICAgIGN1ci0+a2V5cyA9IHhtbEhhc2hDcmVhdGUoMCk7CisgICAgcmV0dXJuKGN1cik7Cit9CisKKy8qKgorICogeHNsdEZyZWVLZXlUYWJsZToKKyAqIEBrZXl0OiAgYW4gWFNMVCBrZXkgdGFibGUKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGJ5IEBrZXl0CisgKi8KK3N0YXRpYyB2b2lkCit4c2x0RnJlZUtleVRhYmxlKHhzbHRLZXlUYWJsZVB0ciBrZXl0KSB7CisgICAgaWYgKGtleXQgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaWYgKGtleXQtPm5hbWUgIT0gTlVMTCkKKwl4bWxGcmVlKGtleXQtPm5hbWUpOworICAgIGlmIChrZXl0LT5uYW1lVVJJICE9IE5VTEwpCisJeG1sRnJlZShrZXl0LT5uYW1lVVJJKTsKKyAgICBpZiAoa2V5dC0+a2V5cyAhPSBOVUxMKQorCXhtbEhhc2hGcmVlKGtleXQtPmtleXMsIAorCQkgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sWFBhdGhGcmVlTm9kZVNldCk7CisgICAgbWVtc2V0KGtleXQsIC0xLCBzaXplb2YoeHNsdEtleVRhYmxlKSk7CisgICAgeG1sRnJlZShrZXl0KTsKK30KKworLyoqCisgKiB4c2x0RnJlZUtleVRhYmxlTGlzdDoKKyAqIEBrZXl0OiAgYW4gWFNMVCBrZXkgdGFibGUgbGlzdAorICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgYnkgYWxsIHRoZSBlbGVtZW50cyBvZiBAa2V5dAorICovCitzdGF0aWMgdm9pZAoreHNsdEZyZWVLZXlUYWJsZUxpc3QoeHNsdEtleVRhYmxlUHRyIGtleXQpIHsKKyAgICB4c2x0S2V5VGFibGVQdHIgY3VyOworCisgICAgd2hpbGUgKGtleXQgIT0gTlVMTCkgeworCWN1ciA9IGtleXQ7CisJa2V5dCA9IGtleXQtPm5leHQ7CisJeHNsdEZyZWVLZXlUYWJsZShjdXIpOworICAgIH0KK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogCQkJCQkJCQkJKgorICogCQlUaGUgaW50ZXJwcmV0ZXIgZm9yIHRoZSBwcmVjb21waWxlZCBwYXR0ZXJucwkJKgorICogCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworCisvKioKKyAqIHhzbHRGcmVlS2V5czoKKyAqIEBzdHlsZTogYW4gWFNMVCBzdHlsZXNoZWV0CisgKgorICogRnJlZSB1cCB0aGUgbWVtb3J5IHVzZWQgYnkgWFNMVCBrZXlzIGluIGEgc3R5bGVzaGVldAorICovCit2b2lkCit4c2x0RnJlZUtleXMoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUpIHsKKyAgICBpZiAoc3R5bGUtPmtleXMpCisJeHNsdEZyZWVLZXlEZWZMaXN0KCh4c2x0S2V5RGVmUHRyKSBzdHlsZS0+a2V5cyk7Cit9CisKKy8qKgorICogc2tpcFN0cmluZzoKKyAqIEBjdXI6IHRoZSBjdXJyZW50IHBvaW50ZXIKKyAqIEBlbmQ6IHRoZSBjdXJyZW50IG9mZnNldAorICoKKyAqIHNraXAgYSBzdHJpbmcgZGVsaW1pdGVkIGJ5ICIgb3IgJworICoKKyAqIFJldHVybnMgdGhlIGJ5dGUgYWZ0ZXIgdGhlIHN0cmluZyBvciAtMSBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3N0YXRpYyBpbnQKK3NraXBTdHJpbmcoY29uc3QgeG1sQ2hhciAqY3VyLCBpbnQgZW5kKSB7CisgICAgeG1sQ2hhciBsaW1pdDsKKworICAgIGlmICgoY3VyID09IE5VTEwpIHx8IChlbmQgPCAwKSkgcmV0dXJuKC0xKTsKKyAgICBpZiAoKGN1cltlbmRdID09ICdcJycpIHx8IChjdXJbZW5kXSA9PSAnIicpKSBsaW1pdCA9IGN1cltlbmRdOworICAgIGVsc2UgcmV0dXJuKGVuZCk7CisgICAgZW5kKys7CisgICAgd2hpbGUgKGN1cltlbmRdICE9IDApIHsKKyAgICAgICAgaWYgKGN1cltlbmRdID09IGxpbWl0KQorCSAgICByZXR1cm4oZW5kICsgMSk7CisJZW5kKys7CisgICAgfQorICAgIHJldHVybigtMSk7Cit9CisKKy8qKgorICogc2tpcFByZWRpY2F0ZToKKyAqIEBjdXI6IHRoZSBjdXJyZW50IHBvaW50ZXIKKyAqIEBlbmQ6IHRoZSBjdXJyZW50IG9mZnNldAorICoKKyAqIHNraXAgYSBwcmVkaWNhdGUKKyAqCisgKiBSZXR1cm5zIHRoZSBieXRlIGFmdGVyIHRoZSBwcmVkaWNhdGUgb3IgLTEgaW4gY2FzZSBvZiBlcnJvcgorICovCitzdGF0aWMgaW50Citza2lwUHJlZGljYXRlKGNvbnN0IHhtbENoYXIgKmN1ciwgaW50IGVuZCkgeworICAgIGlmICgoY3VyID09IE5VTEwpIHx8IChlbmQgPCAwKSkgcmV0dXJuKC0xKTsKKyAgICBpZiAoY3VyW2VuZF0gIT0gJ1snKSByZXR1cm4oZW5kKTsKKyAgICBlbmQrKzsKKyAgICB3aGlsZSAoY3VyW2VuZF0gIT0gMCkgeworICAgICAgICBpZiAoKGN1cltlbmRdID09ICdcJycpIHx8IChjdXJbZW5kXSA9PSAnIicpKSB7CisJICAgIGVuZCA9IHNraXBTdHJpbmcoY3VyLCBlbmQpOworCSAgICBpZiAoZW5kIDw9IDApCisJICAgICAgICByZXR1cm4oLTEpOworCSAgICBjb250aW51ZTsKKwl9IGVsc2UgaWYgKGN1cltlbmRdID09ICdbJykgeworCSAgICBlbmQgPSBza2lwUHJlZGljYXRlKGN1ciwgZW5kKTsKKwkgICAgaWYgKGVuZCA8PSAwKQorCSAgICAgICAgcmV0dXJuKC0xKTsKKwkgICAgY29udGludWU7CisJfSBlbHNlIGlmIChjdXJbZW5kXSA9PSAnXScpCisJICAgIHJldHVybihlbmQgKyAxKTsKKwllbmQrKzsKKyAgICB9CisgICAgcmV0dXJuKC0xKTsKK30KKworLyoqCisgKiB4c2x0QWRkS2V5OgorICogQHN0eWxlOiBhbiBYU0xUIHN0eWxlc2hlZXQKKyAqIEBuYW1lOiAgdGhlIGtleSBuYW1lIG9yIE5VTEwKKyAqIEBuYW1lVVJJOiAgdGhlIG5hbWUgVVJJIG9yIE5VTEwKKyAqIEBtYXRjaDogIHRoZSBtYXRjaCB2YWx1ZQorICogQHVzZTogIHRoZSB1c2UgdmFsdWUKKyAqIEBpbnN0OiB0aGUga2V5IGluc3RydWN0aW9uCisgKgorICogYWRkIGEga2V5IGRlZmluaXRpb24gdG8gYSBzdHlsZXNoZWV0CisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgYW5kIC0xIGluIGNhc2Ugb2YgZmFpbHVyZS4KKyAqLworaW50Cit4c2x0QWRkS2V5KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCBjb25zdCB4bWxDaGFyICpuYW1lLAorCSAgIGNvbnN0IHhtbENoYXIgKm5hbWVVUkksIGNvbnN0IHhtbENoYXIgKm1hdGNoLAorCSAgIGNvbnN0IHhtbENoYXIgKnVzZSwgeG1sTm9kZVB0ciBpbnN0KSB7CisgICAgeHNsdEtleURlZlB0ciBrZXk7CisgICAgeG1sQ2hhciAqcGF0dGVybiA9IE5VTEw7CisgICAgaW50IGN1cnJlbnQsIGVuZCwgc3RhcnQsIGkgPSAwOworCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSB8fCAobWF0Y2ggPT0gTlVMTCkgfHwgKHVzZSA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0tFWVMKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJBZGQga2V5ICVzLCBtYXRjaCAlcywgdXNlICVzXG4iLCBuYW1lLCBtYXRjaCwgdXNlKTsKKyNlbmRpZgorCisgICAga2V5ID0geHNsdE5ld0tleURlZihuYW1lLCBuYW1lVVJJKTsKKyAgICBrZXktPm1hdGNoID0geG1sU3RyZHVwKG1hdGNoKTsKKyAgICBrZXktPnVzZSA9IHhtbFN0cmR1cCh1c2UpOworICAgIGtleS0+aW5zdCA9IGluc3Q7CisgICAga2V5LT5uc0xpc3QgPSB4bWxHZXROc0xpc3QoaW5zdC0+ZG9jLCBpbnN0KTsKKyAgICBpZiAoa2V5LT5uc0xpc3QgIT0gTlVMTCkgeworICAgICAgICB3aGlsZSAoa2V5LT5uc0xpc3RbaV0gIT0gTlVMTCkKKwkgICAgaSsrOworICAgIH0KKyAgICBrZXktPm5zTnIgPSBpOworCisgICAgLyoKKyAgICAgKiBTcGxpdCB0aGUgfCBhbmQgcmVnaXN0ZXIgaXQgYXMgYXMgbWFueSBrZXlzCisgICAgICovCisgICAgY3VycmVudCA9IGVuZCA9IDA7CisgICAgd2hpbGUgKG1hdGNoW2N1cnJlbnRdICE9IDApIHsKKwlzdGFydCA9IGN1cnJlbnQ7CisJd2hpbGUgKElTX0JMQU5LX0NIKG1hdGNoW2N1cnJlbnRdKSkKKwkgICAgY3VycmVudCsrOworCWVuZCA9IGN1cnJlbnQ7CisJd2hpbGUgKChtYXRjaFtlbmRdICE9IDApICYmIChtYXRjaFtlbmRdICE9ICd8JykpIHsKKwkgICAgaWYgKG1hdGNoW2VuZF0gPT0gJ1snKSB7CisJICAgICAgICBlbmQgPSBza2lwUHJlZGljYXRlKG1hdGNoLCBlbmQpOworCQlpZiAoZW5kIDw9IDApIHsKKwkJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkJICAgICAgICAgICAgICAgICAgICAgICAia2V5IHBhdHRlcm4gaXMgbWFsZm9ybWVkOiAlcyIsCisJCQkJICAgICAgIGtleS0+bWF0Y2gpOworCQkgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKwkJICAgIGdvdG8gZXJyb3I7CisJCX0KKwkgICAgfSBlbHNlCisJCWVuZCsrOworCX0KKwlpZiAoY3VycmVudCA9PSBlbmQpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkJICAgICAgICJrZXkgcGF0dGVybiBpcyBlbXB0eVxuIik7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJICAgIGdvdG8gZXJyb3I7CisJfQorCWlmIChtYXRjaFtzdGFydF0gIT0gJy8nKSB7CisJICAgIHBhdHRlcm4gPSB4bWxTdHJjYXQocGF0dGVybiwgKHhtbENoYXIgKikiLy8iKTsKKwkgICAgaWYgKHBhdHRlcm4gPT0gTlVMTCkgeworCQlpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPmVycm9ycysrOworCQlnb3RvIGVycm9yOworCSAgICB9CisJfQorCXBhdHRlcm4gPSB4bWxTdHJuY2F0KHBhdHRlcm4sICZtYXRjaFtzdGFydF0sIGVuZCAtIHN0YXJ0KTsKKwlpZiAocGF0dGVybiA9PSBOVUxMKSB7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJICAgIGdvdG8gZXJyb3I7CisJfQorCisJaWYgKG1hdGNoW2VuZF0gPT0gJ3wnKSB7CisJICAgIHBhdHRlcm4gPSB4bWxTdHJjYXQocGF0dGVybiwgKHhtbENoYXIgKikifCIpOworCSAgICBlbmQrKzsKKwl9CisJY3VycmVudCA9IGVuZDsKKyAgICB9CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0tFWVMKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSIgICByZXN1bHRpbmcgcGF0dGVybiAlc1xuIiwgcGF0dGVybik7CisjZW5kaWYKKyAgICAvKgorICAgICogWFNMVC0xOiAiSXQgaXMgYW4gZXJyb3IgZm9yIHRoZSB2YWx1ZSBvZiBlaXRoZXIgdGhlIHVzZQorICAgICogIGF0dHJpYnV0ZSBvciB0aGUgbWF0Y2ggYXR0cmlidXRlIHRvIGNvbnRhaW4gYQorICAgICogIFZhcmlhYmxlUmVmZXJlbmNlLiIKKyAgICAqIFRPRE86IFdlIHNob3VsZCByZXBvcnQgYSB2YXJpYWJsZS1yZWZlcmVuY2UgYXQgY29tcGlsZS10aW1lLgorICAgICogICBNYXliZSBhIHNlYXJjaCBmb3IgIiQiLCBpZiBpdCBvY2N1cnMgb3V0c2lkZSBvZiBxdW90YXRpb24KKyAgICAqICAgbWFya3MsIGNvdWxkIGJlIHN1ZmZpY2llbnQuCisgICAgKi8KKyAgICBrZXktPmNvbXAgPSB4c2x0WFBhdGhDb21waWxlKHN0eWxlLCBwYXR0ZXJuKTsKKyAgICBpZiAoa2V5LT5jb21wID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCSJ4c2w6a2V5IDogWFBhdGggcGF0dGVybiBjb21waWxhdGlvbiBmYWlsZWQgJyVzJ1xuIiwKKwkJICAgICAgICAgcGF0dGVybik7CisJaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKyAgICB9CisgICAga2V5LT51c2Vjb21wID0geHNsdFhQYXRoQ29tcGlsZShzdHlsZSwgdXNlKTsKKyAgICBpZiAoa2V5LT51c2Vjb21wID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCSJ4c2w6a2V5IDogWFBhdGggcGF0dGVybiBjb21waWxhdGlvbiBmYWlsZWQgJyVzJ1xuIiwKKwkJICAgICAgICAgdXNlKTsKKwlpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPmVycm9ycysrOworICAgIH0KKworICAgIC8qCisgICAgICogU29tZXRpbWVzIHRoZSBzdHlsZXNoZWV0IHdyaXRlciB1c2UgdGhlIG9yZGVyIHRvIGVhc2UgdGhlCisgICAgICogcmVzb2x1dGlvbiBvZiBrZXlzIHdoZW4gdGhleSBhcmUgZGVwZW5kYW50LCBrZWVwIHRoZSBwcm92aWRlZAorICAgICAqIG9yZGVyIHNvIGFkZCB0aGUgbmV3IG9uZSBhdCB0aGUgZW5kLgorICAgICAqLworICAgIGlmIChzdHlsZS0+a2V5cyA9PSBOVUxMKSB7CisJc3R5bGUtPmtleXMgPSBrZXk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgeHNsdEtleURlZlB0ciBwcmV2ID0gc3R5bGUtPmtleXM7CisKKwl3aGlsZSAocHJldi0+bmV4dCAhPSBOVUxMKQorCSAgICBwcmV2ID0gcHJldi0+bmV4dDsKKworCXByZXYtPm5leHQgPSBrZXk7CisgICAgfQorICAgIGtleS0+bmV4dCA9IE5VTEw7CisKK2Vycm9yOgorICAgIGlmIChwYXR0ZXJuICE9IE5VTEwpCisJeG1sRnJlZShwYXR0ZXJuKTsKKyAgICByZXR1cm4oMCk7Cit9CisKKy8qKgorICogeHNsdEdldEtleToKKyAqIEBjdHh0OiBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBuYW1lOiAgdGhlIGtleSBuYW1lIG9yIE5VTEwKKyAqIEBuYW1lVVJJOiAgdGhlIG5hbWUgVVJJIG9yIE5VTEwKKyAqIEB2YWx1ZTogIHRoZSBrZXkgdmFsdWUgdG8gbG9vayBmb3IKKyAqCisgKiBMb29rcyB1cCBhIGtleSBvZiB0aGUgaW4gY3VycmVudCBzb3VyY2UgZG9jICh0aGUgZG9jdW1lbnQgaW5mbworICogb24gQGN0eHQtPmRvY3VtZW50KS4gQ29tcHV0ZXMgdGhlIGtleSBpZiBub3QgYWxyZWFkeSBkb25lCisgKiBmb3IgdGhlIGN1cnJlbnQgc291cmNlIGRvYy4KKyAqCisgKiBSZXR1cm5zIHRoZSBub2Rlc2V0IHJlc3VsdGluZyBmcm9tIHRoZSBxdWVyeSBvciBOVUxMCisgKi8KK3htbE5vZGVTZXRQdHIKK3hzbHRHZXRLZXkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkgICBjb25zdCB4bWxDaGFyICpuYW1lVVJJLCBjb25zdCB4bWxDaGFyICp2YWx1ZSkgeworICAgIHhtbE5vZGVTZXRQdHIgcmV0OworICAgIHhzbHRLZXlUYWJsZVB0ciB0YWJsZTsKKyAgICBpbnQgaW5pdF90YWJsZSA9IDA7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkgfHwgKHZhbHVlID09IE5VTEwpIHx8CisJKGN0eHQtPmRvY3VtZW50ID09IE5VTEwpKQorCXJldHVybihOVUxMKTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19LRVlTCisgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkiR2V0IGtleSAlcywgdmFsdWUgJXNcbiIsIG5hbWUsIHZhbHVlKTsKKyNlbmRpZgorCisgICAgLyoKKyAgICAgKiBrZXlzIGFyZSBjb21wdXRlZCBvbmx5IG9uLWRlbWFuZCBvbiBmaXJzdCBrZXkgYWNjZXNzIGZvciBhIGRvY3VtZW50CisgICAgICovCisgICAgaWYgKChjdHh0LT5kb2N1bWVudC0+bmJLZXlzQ29tcHV0ZWQgPCBjdHh0LT5uYktleXMpICYmCisgICAgICAgIChjdHh0LT5rZXlJbml0TGV2ZWwgPT0gMCkpIHsKKyAgICAgICAgLyoKKwkgKiBJZiBub24tcmVjdXJzaXZlIGJlaGF2aW91ciwganVzdCB0cnkgdG8gaW5pdGlhbGl6ZSBhbGwga2V5cworCSAqLworCWlmICh4c2x0SW5pdEFsbERvY0tleXMoY3R4dCkpCisJICAgIHJldHVybihOVUxMKTsKKyAgICB9CisKK3JldHJ5OgorICAgIHRhYmxlID0gKHhzbHRLZXlUYWJsZVB0cikgY3R4dC0+ZG9jdW1lbnQtPmtleXM7CisgICAgd2hpbGUgKHRhYmxlICE9IE5VTEwpIHsKKwlpZiAoKChuYW1lVVJJICE9IE5VTEwpID09ICh0YWJsZS0+bmFtZVVSSSAhPSBOVUxMKSkgJiYKKwkgICAgeG1sU3RyRXF1YWwodGFibGUtPm5hbWUsIG5hbWUpICYmCisJICAgIHhtbFN0ckVxdWFsKHRhYmxlLT5uYW1lVVJJLCBuYW1lVVJJKSkKKwl7CisJICAgIHJldCA9ICh4bWxOb2RlU2V0UHRyKXhtbEhhc2hMb29rdXAodGFibGUtPmtleXMsIHZhbHVlKTsKKwkgICAgcmV0dXJuKHJldCk7CisJfQorCXRhYmxlID0gdGFibGUtPm5leHQ7CisgICAgfQorCisgICAgaWYgKChjdHh0LT5rZXlJbml0TGV2ZWwgIT0gMCkgJiYgKGluaXRfdGFibGUgPT0gMCkpIHsKKyAgICAgICAgLyoKKwkgKiBBcHBhcmVudGx5IG9uZSBrZXkgaXMgcmVjdXJzaXZlIGFuZCB0aGlzIG9uZSBpcyBuZWVkZWQsCisJICogaW5pdGlhbGl6ZSBqdXN0IGl0LCB0aGF0IHRpbWUgYW5kIHJldHJ5CisJICovCisgICAgICAgIHhzbHRJbml0RG9jS2V5VGFibGUoY3R4dCwgbmFtZSwgbmFtZVVSSSk7CisJaW5pdF90YWJsZSA9IDE7CisJZ290byByZXRyeTsKKyAgICB9CisKKyAgICByZXR1cm4oTlVMTCk7Cit9CisKKworLyoqCisgKiB4c2x0SW5pdERvY0tleVRhYmxlOgorICoKKyAqIElOVEVSTkFMIFJPVVRJTkUgT05MWQorICoKKyAqIENoZWNrIGlmIGFueSBrZXlzIG9uIHRoZSBjdXJyZW50IGRvY3VtZW50IG5lZWQgdG8gYmUgY29tcHV0ZWQKKyAqLworc3RhdGljIGludAoreHNsdEluaXREb2NLZXlUYWJsZSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICpuYW1lLAorICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lVVJJKQoreworICAgIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlOworICAgIHhzbHRLZXlEZWZQdHIga2V5ZCA9IE5VTEw7CisgICAgaW50IGZvdW5kID0gMDsKKworI2lmZGVmIEtFWV9JTklUX0RFQlVHCitmcHJpbnRmKHN0ZGVyciwgInhzbHRJbml0RG9jS2V5VGFibGUgJXNcbiIsIG5hbWUpOworI2VuZGlmCisKKyAgICBzdHlsZSA9IGN0eHQtPnN0eWxlOworICAgIHdoaWxlIChzdHlsZSAhPSBOVUxMKSB7CisJa2V5ZCA9ICh4c2x0S2V5RGVmUHRyKSBzdHlsZS0+a2V5czsKKwl3aGlsZSAoa2V5ZCAhPSBOVUxMKSB7CisJICAgIGlmICgoKGtleWQtPm5hbWVVUkkgIT0gTlVMTCkgPT0KKwkJIChuYW1lVVJJICE9IE5VTEwpKSAmJgorCQl4bWxTdHJFcXVhbChrZXlkLT5uYW1lLCBuYW1lKSAmJgorCQl4bWxTdHJFcXVhbChrZXlkLT5uYW1lVVJJLCBuYW1lVVJJKSkKKwkgICAgeworCQl4c2x0SW5pdEN0eHRLZXkoY3R4dCwgY3R4dC0+ZG9jdW1lbnQsIGtleWQpOworCQlpZiAoY3R4dC0+ZG9jdW1lbnQtPm5iS2V5c0NvbXB1dGVkID09IGN0eHQtPm5iS2V5cykKKwkJICAgIHJldHVybigwKTsKKwkJZm91bmQgPSAxOworCSAgICB9CisJICAgIGtleWQgPSBrZXlkLT5uZXh0OworCX0KKwlzdHlsZSA9IHhzbHROZXh0SW1wb3J0KHN0eWxlKTsKKyAgICB9CisgICAgaWYgKGZvdW5kID09IDApIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfS0VZUworCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0tFWVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0SW5pdERvY0tleVRhYmxlOiBkaWQgbm90IGZvdW5kICVzXG4iLCBuYW1lKSk7CisjZW5kaWYKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwga2V5ZD8ga2V5ZC0+aW5zdCA6IE5VTEwsCisJICAgICJGYWlsZWQgdG8gZmluZCBrZXkgZGVmaW5pdGlvbiBmb3IgJXNcbiIsIG5hbWUpOworCWN0eHQtPnN0YXRlID0gWFNMVF9TVEFURV9TVE9QUEVEOworICAgICAgICByZXR1cm4oLTEpOworICAgIH0KKyNpZmRlZiBLRVlfSU5JVF9ERUJVRworZnByaW50ZihzdGRlcnIsICJ4c2x0SW5pdERvY0tleVRhYmxlICVzIGRvbmVcbiIsIG5hbWUpOworI2VuZGlmCisgICAgcmV0dXJuKDApOworfQorCisvKioKKyAqIHhzbHRJbml0QWxsRG9jS2V5czoKKyAqIEBjdHh0OiB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogSU5URVJOQUwgUk9VVElORSBPTkxZCisgKgorICogQ2hlY2sgaWYgYW55IGtleXMgb24gdGhlIGN1cnJlbnQgZG9jdW1lbnQgbmVlZCB0byBiZSBjb21wdXRlZAorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgZmFpbHVyZQorICovCitpbnQKK3hzbHRJbml0QWxsRG9jS2V5cyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KQoreworICAgIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlOworICAgIHhzbHRLZXlEZWZQdHIga2V5ZDsKKyAgICB4c2x0S2V5VGFibGVQdHIgdGFibGU7CisKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorCXJldHVybigtMSk7CisKKyNpZmRlZiBLRVlfSU5JVF9ERUJVRworZnByaW50ZihzdGRlcnIsICJ4c2x0SW5pdEFsbERvY0tleXMgJWQgJWRcbiIsCisgICAgICAgIGN0eHQtPmRvY3VtZW50LT5uYktleXNDb21wdXRlZCwgY3R4dC0+bmJLZXlzKTsKKyNlbmRpZgorCisgICAgaWYgKGN0eHQtPmRvY3VtZW50LT5uYktleXNDb21wdXRlZCA9PSBjdHh0LT5uYktleXMpCisJcmV0dXJuKDApOworCisKKyAgICAvKgorICAgICogVE9ETzogVGhpcyBjb3VsZCBiZSBmdXJ0aGVyIG9wdGltaXplZAorICAgICovCisgICAgc3R5bGUgPSBjdHh0LT5zdHlsZTsKKyAgICB3aGlsZSAoc3R5bGUpIHsKKwlrZXlkID0gKHhzbHRLZXlEZWZQdHIpIHN0eWxlLT5rZXlzOworCXdoaWxlIChrZXlkICE9IE5VTEwpIHsKKyNpZmRlZiBLRVlfSU5JVF9ERUJVRworZnByaW50ZihzdGRlcnIsICJJbml0IGtleSAlc1xuIiwga2V5ZC0+bmFtZSk7CisjZW5kaWYKKwkgICAgLyoKKwkgICAgKiBDaGVjayBpZiBrZXlzIHdpdGggdGhpcyBRTmFtZSBoYXZlIGJlZW4gYWxyZWFkeQorCSAgICAqIGNvbXB1dGVkLgorCSAgICAqLworCSAgICB0YWJsZSA9ICh4c2x0S2V5VGFibGVQdHIpIGN0eHQtPmRvY3VtZW50LT5rZXlzOworCSAgICB3aGlsZSAodGFibGUpIHsKKwkJaWYgKCgoa2V5ZC0+bmFtZVVSSSAhPSBOVUxMKSA9PSAodGFibGUtPm5hbWVVUkkgIT0gTlVMTCkpICYmCisJCSAgICB4bWxTdHJFcXVhbChrZXlkLT5uYW1lLCB0YWJsZS0+bmFtZSkgJiYKKwkJICAgIHhtbFN0ckVxdWFsKGtleWQtPm5hbWVVUkksIHRhYmxlLT5uYW1lVVJJKSkKKwkJeworCQkgICAgYnJlYWs7CisJCX0KKwkJdGFibGUgPSB0YWJsZS0+bmV4dDsKKwkgICAgfQorCSAgICBpZiAodGFibGUgPT0gTlVMTCkgeworCQkvKgorCQkqIEtleXMgd2l0aCB0aGlzIFFOYW1lIGhhdmUgbm90IGJlZW4geWV0IGNvbXB1dGVkLgorCQkqLworCQl4c2x0SW5pdERvY0tleVRhYmxlKGN0eHQsIGtleWQtPm5hbWUsIGtleWQtPm5hbWVVUkkpOworCSAgICB9CisJICAgIGtleWQgPSBrZXlkLT5uZXh0OworCX0KKwlzdHlsZSA9IHhzbHROZXh0SW1wb3J0KHN0eWxlKTsKKyAgICB9CisjaWZkZWYgS0VZX0lOSVRfREVCVUcKK2ZwcmludGYoc3RkZXJyLCAieHNsdEluaXRBbGxEb2NLZXlzOiBkb25lXG4iKTsKKyNlbmRpZgorICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0SW5pdEN0eHRLZXk6CisgKiBAY3R4dDogYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAaWRvYzogIHRoZSBkb2N1bWVudCBpbmZvcm1hdGlvbiAoaG9sZHMga2V5IHZhbHVlcykKKyAqIEBrZXlEZWY6IHRoZSBrZXkgZGVmaW5pdGlvbgorICoKKyAqIENvbXB1dGVzIHRoZSBrZXkgdGFibGVzIHRoaXMga2V5IGFuZCBmb3IgdGhlIGN1cnJlbnQgaW5wdXQgZG9jdW1lbnQuCisgKgorICogUmV0dXJuczogMCBvbiBzdWNjZXNzLCAtMSBvbiBlcnJvcgorICovCitpbnQKK3hzbHRJbml0Q3R4dEtleSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4c2x0RG9jdW1lbnRQdHIgaWRvYywKKwkgICAgICAgIHhzbHRLZXlEZWZQdHIga2V5RGVmKQoreworICAgIGludCBpLCBsZW4sIGs7CisgICAgeG1sTm9kZVNldFB0ciBtYXRjaExpc3QgPSBOVUxMLCBrZXlsaXN0OworICAgIHhtbFhQYXRoT2JqZWN0UHRyIG1hdGNoUmVzID0gTlVMTCwgdXNlUmVzID0gTlVMTDsKKyAgICB4bWxDaGFyICpzdHIgPSBOVUxMOworICAgIHhzbHRLZXlUYWJsZVB0ciB0YWJsZTsKKyAgICB4bWxOb2RlUHRyIG9sZEluc3QsIGN1cjsKKyAgICB4bWxOb2RlUHRyIG9sZENvbnRleHROb2RlOworICAgIHhzbHREb2N1bWVudFB0ciBvbGREb2NJbmZvOworICAgIGludAlvbGRYUFBvcywgb2xkWFBTaXplOworICAgIHhtbERvY1B0ciBvbGRYUERvYzsKKyAgICBpbnQgb2xkWFBOc05yOworICAgIHhtbE5zUHRyICpvbGRYUE5hbWVzcGFjZXM7CisgICAgeG1sWFBhdGhDb250ZXh0UHRyIHhwY3R4dDsKKworI2lmZGVmIEtFWV9JTklUX0RFQlVHCitmcHJpbnRmKHN0ZGVyciwgInhzbHRJbml0Q3R4dEtleSAlcyA6ICVkXG4iLCBrZXlEZWYtPm5hbWUsIGN0eHQtPmtleUluaXRMZXZlbCk7CisjZW5kaWYKKworICAgIGlmICgoa2V5RGVmLT5jb21wID09IE5VTEwpIHx8IChrZXlEZWYtPnVzZWNvbXAgPT0gTlVMTCkpCisJcmV0dXJuKC0xKTsKKworICAgIC8qCisgICAgICogRGV0ZWN0IHJlY3Vyc2l2ZSBrZXlzCisgICAgICovCisgICAgaWYgKGN0eHQtPmtleUluaXRMZXZlbCA+IGN0eHQtPm5iS2V5cykgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19LRVlTCisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfS0VZUywKKwkgICAgICAgICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAgICAieHNsdEluaXRDdHh0S2V5OiBrZXkgZGVmaW5pdGlvbiBvZiAlcyBpcyByZWN1cnNpdmVcbiIsCisJCSAgICAgICBrZXlEZWYtPm5hbWUpKTsKKyNlbmRpZgorCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBrZXlEZWYtPmluc3QsCisJICAgICJLZXkgZGVmaW5pdGlvbiBmb3IgJXMgaXMgcmVjdXJzaXZlXG4iLCBrZXlEZWYtPm5hbWUpOworCWN0eHQtPnN0YXRlID0gWFNMVF9TVEFURV9TVE9QUEVEOworICAgICAgICByZXR1cm4oLTEpOworICAgIH0KKyAgICBjdHh0LT5rZXlJbml0TGV2ZWwrKzsKKworICAgIHhwY3R4dCA9IGN0eHQtPnhwYXRoQ3R4dDsKKyAgICBpZG9jLT5uYktleXNDb21wdXRlZCsrOworICAgIC8qCisgICAgKiBTYXZlIGNvbnRleHQgc3RhdGUuCisgICAgKi8KKyAgICBvbGRJbnN0ID0gY3R4dC0+aW5zdDsKKyAgICBvbGREb2NJbmZvID0gY3R4dC0+ZG9jdW1lbnQ7CisgICAgb2xkQ29udGV4dE5vZGUgPSBjdHh0LT5ub2RlOworCisgICAgb2xkWFBEb2MgPSB4cGN0eHQtPmRvYzsKKyAgICBvbGRYUFBvcyA9IHhwY3R4dC0+cHJveGltaXR5UG9zaXRpb247CisgICAgb2xkWFBTaXplID0geHBjdHh0LT5jb250ZXh0U2l6ZTsKKyAgICBvbGRYUE5zTnIgPSB4cGN0eHQtPm5zTnI7CisgICAgb2xkWFBOYW1lc3BhY2VzID0geHBjdHh0LT5uYW1lc3BhY2VzOworCisgICAgLyoKKyAgICAqIFNldCB1cCBjb250ZXh0cy4KKyAgICAqLworICAgIGN0eHQtPmRvY3VtZW50ID0gaWRvYzsKKyAgICBjdHh0LT5ub2RlID0gKHhtbE5vZGVQdHIpIGlkb2MtPmRvYzsKKyAgICBjdHh0LT5pbnN0ID0ga2V5RGVmLT5pbnN0OworCisgICAgeHBjdHh0LT5kb2MgPSBpZG9jLT5kb2M7CisgICAgeHBjdHh0LT5ub2RlID0gKHhtbE5vZGVQdHIpIGlkb2MtPmRvYzsKKyAgICAvKiBUT0RPIDogY2xhcmlmeSB0aGUgdXNlIG9mIG5hbWVzcGFjZXMgaW4ga2V5cyBldmFsdWF0aW9uICovCisgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0ga2V5RGVmLT5uc0xpc3Q7CisgICAgeHBjdHh0LT5uc05yID0ga2V5RGVmLT5uc05yOworCisgICAgLyoKKyAgICAqIEV2YWx1YXRlIHRoZSAnbWF0Y2gnIGV4cHJlc3Npb24gb2YgdGhlIHhzbDprZXkuCisgICAgKiBUT0RPOiBUaGUgJ21hdGNoJyBpcyBhICpwYXR0ZXJuKi4KKyAgICAqLworICAgIG1hdGNoUmVzID0geG1sWFBhdGhDb21waWxlZEV2YWwoa2V5RGVmLT5jb21wLCB4cGN0eHQpOworICAgIGlmIChtYXRjaFJlcyA9PSBOVUxMKSB7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfS0VZUworCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0tFWVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0SW5pdEN0eHRLZXk6ICVzIGV2YWx1YXRpb24gZmFpbGVkXG4iLCBrZXlEZWYtPm1hdGNoKSk7CisjZW5kaWYKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwga2V5RGVmLT5pbnN0LAorCSAgICAiRmFpbGVkIHRvIGV2YWx1YXRlIHRoZSAnbWF0Y2gnIGV4cHJlc3Npb24uXG4iKTsKKwljdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwlnb3RvIGVycm9yOworICAgIH0gZWxzZSB7CisJaWYgKG1hdGNoUmVzLT50eXBlID09IFhQQVRIX05PREVTRVQpIHsKKwkgICAgbWF0Y2hMaXN0ID0gbWF0Y2hSZXMtPm5vZGVzZXR2YWw7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfS0VZUworCSAgICBpZiAobWF0Y2hMaXN0ICE9IE5VTEwpCisJCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0tFWVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICAgICAieHNsdEluaXRDdHh0S2V5OiAlcyBldmFsdWF0ZXMgdG8gJWQgbm9kZXNcbiIsCisJCQkJIGtleURlZi0+bWF0Y2gsIG1hdGNoTGlzdC0+bm9kZU5yKSk7CisjZW5kaWYKKwl9IGVsc2UgeworCSAgICAvKgorCSAgICAqIElzIG5vdCBhIG5vZGUgc2V0LCBidXQgbXVzdCBiZS4KKwkgICAgKi8KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfS0VZUworCSAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9LRVlTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAieHNsdEluaXRDdHh0S2V5OiAlcyBpcyBub3QgYSBub2RlIHNldFxuIiwga2V5RGVmLT5tYXRjaCkpOworI2VuZGlmCisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBrZXlEZWYtPmluc3QsCisJCSJUaGUgJ21hdGNoJyBleHByZXNzaW9uIGRpZCBub3QgZXZhbHVhdGUgdG8gYSBub2RlIHNldC5cbiIpOworCSAgICBjdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwkgICAgZ290byBlcnJvcjsKKwl9CisgICAgfQorICAgIGlmICgobWF0Y2hMaXN0ID09IE5VTEwpIHx8IChtYXRjaExpc3QtPm5vZGVOciA8PSAwKSkKKwlnb3RvIGV4aXQ7CisKKyAgICAvKioKKyAgICAgKiBNdWx0aXBsZSBrZXkgZGVmaW5pdGlvbnMgZm9yIHRoZSBzYW1lIG5hbWUgYXJlIGFsbG93ZWQsIHNvCisgICAgICogd2UgbXVzdCBjaGVjayBpZiB0aGUga2V5IGlzIGFscmVhZHkgcHJlc2VudCBmb3IgdGhpcyBkb2MKKyAgICAgKi8KKyAgICB0YWJsZSA9ICh4c2x0S2V5VGFibGVQdHIpIGlkb2MtPmtleXM7CisgICAgd2hpbGUgKHRhYmxlICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKHhtbFN0ckVxdWFsKHRhYmxlLT5uYW1lLCBrZXlEZWYtPm5hbWUpICYmCisJICAgICgoKGtleURlZi0+bmFtZVVSSSA9PSBOVUxMKSAmJiAodGFibGUtPm5hbWVVUkkgPT0gTlVMTCkpIHx8CisJICAgICAoKGtleURlZi0+bmFtZVVSSSAhPSBOVUxMKSAmJiAodGFibGUtPm5hbWVVUkkgIT0gTlVMTCkgJiYKKwkgICAgICAoeG1sU3RyRXF1YWwodGFibGUtPm5hbWVVUkksIGtleURlZi0+bmFtZVVSSSkpKSkpCisJICAgIGJyZWFrOworCXRhYmxlID0gdGFibGUtPm5leHQ7CisgICAgfQorICAgIC8qKgorICAgICAqIElmIHRoZSBrZXkgd2FzIG5vdCBwcmV2aW91c2x5IGRlZmluZWQsIGNyZWF0ZSBpdCBub3cgYW5kCisgICAgICogY2hhaW4gaXQgdG8gdGhlIGxpc3Qgb2Yga2V5cyBmb3IgdGhlIGRvYworICAgICAqLworICAgIGlmICh0YWJsZSA9PSBOVUxMKSB7CisgICAgICAgIHRhYmxlID0geHNsdE5ld0tleVRhYmxlKGtleURlZi0+bmFtZSwga2V5RGVmLT5uYW1lVVJJKTsKKyAgICAgICAgaWYgKHRhYmxlID09IE5VTEwpCisJICAgIGdvdG8gZXJyb3I7CisgICAgICAgIHRhYmxlLT5uZXh0ID0gaWRvYy0+a2V5czsKKyAgICAgICAgaWRvYy0+a2V5cyA9IHRhYmxlOworICAgIH0KKworICAgIC8qCisgICAgKiBTUEVDIFhTTFQgMS4wIChYU0xUIDIuMCBkb2VzIG5vdCBjbGFyaWZ5IHRoZSBjb250ZXh0IHNpemUhKQorICAgICogIi4uLnRoZSB1c2UgYXR0cmlidXRlIG9mIHRoZSB4c2w6a2V5IGVsZW1lbnQgaXMgZXZhbHVhdGVkIHdpdGggeCBhcworICAgICIgIHRoZSBjdXJyZW50IG5vZGUgYW5kIHdpdGggYSBub2RlIGxpc3QgY29udGFpbmluZyBqdXN0IHggYXMgdGhlCisgICAgKiAgY3VycmVudCBub2RlIGxpc3QiCisgICAgKi8KKyAgICB4cGN0eHQtPmNvbnRleHRTaXplID0gMTsKKyAgICB4cGN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gMTsKKworICAgIGZvciAoaSA9IDA7IGkgPCBtYXRjaExpc3QtPm5vZGVOcjsgaSsrKSB7CisJY3VyID0gbWF0Y2hMaXN0LT5ub2RlVGFiW2ldOworCWlmICghIElTX1hTTFRfUkVBTF9OT0RFKGN1cikpCisJICAgIGNvbnRpbnVlOworCXhwY3R4dC0+bm9kZSA9IGN1cjsKKwkvKgorCSogUHJvY2VzcyB0aGUgJ3VzZScgb2YgdGhlIHhzbDprZXkuCisJKiBTUEVDIFhTTFQgMS4wOgorCSogIlRoZSB1c2UgYXR0cmlidXRlIGlzIGFuIGV4cHJlc3Npb24gc3BlY2lmeWluZyB0aGUgdmFsdWVzIG9mCisJKiAgdGhlIGtleTsgdGhlIGV4cHJlc3Npb24gaXMgZXZhbHVhdGVkIG9uY2UgZm9yIGVhY2ggbm9kZSB0aGF0CisJKiAgbWF0Y2hlcyB0aGUgcGF0dGVybi4iCisJKi8KKwlpZiAodXNlUmVzICE9IE5VTEwpCisJICAgIHhtbFhQYXRoRnJlZU9iamVjdCh1c2VSZXMpOworCXVzZVJlcyA9IHhtbFhQYXRoQ29tcGlsZWRFdmFsKGtleURlZi0+dXNlY29tcCwgeHBjdHh0KTsKKwlpZiAodXNlUmVzID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGtleURlZi0+aW5zdCwKKwkJIkZhaWxlZCB0byBldmFsdWF0ZSB0aGUgJ3VzZScgZXhwcmVzc2lvbi5cbiIpOworCSAgICBjdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwkgICAgYnJlYWs7CisJfQorCWlmICh1c2VSZXMtPnR5cGUgPT0gWFBBVEhfTk9ERVNFVCkgeworCSAgICBpZiAoKHVzZVJlcy0+bm9kZXNldHZhbCAhPSBOVUxMKSAmJgorCQkodXNlUmVzLT5ub2Rlc2V0dmFsLT5ub2RlTnIgIT0gMCkpCisJICAgIHsKKwkJbGVuID0gdXNlUmVzLT5ub2Rlc2V0dmFsLT5ub2RlTnI7CisJCXN0ciA9IHhtbFhQYXRoQ2FzdE5vZGVUb1N0cmluZyh1c2VSZXMtPm5vZGVzZXR2YWwtPm5vZGVUYWJbMF0pOworCSAgICB9IGVsc2UgeworCQljb250aW51ZTsKKwkgICAgfQorCX0gZWxzZSB7CisJICAgIGxlbiA9IDE7CisJICAgIGlmICh1c2VSZXMtPnR5cGUgPT0gWFBBVEhfU1RSSU5HKSB7CisJCS8qCisJCSogQ29uc3VtZSB0aGUgc3RyaW5nIHZhbHVlLgorCQkqLworCQlzdHIgPSB1c2VSZXMtPnN0cmluZ3ZhbDsKKwkJdXNlUmVzLT5zdHJpbmd2YWwgPSBOVUxMOworCSAgICB9IGVsc2UgeworCQlzdHIgPSB4bWxYUGF0aENhc3RUb1N0cmluZyh1c2VSZXMpOworCSAgICB9CisJfQorCS8qCisJKiBQcm9jZXNzIGFsbCBzdHJpbmdzLgorCSovCisJayA9IDA7CisJd2hpbGUgKDEpIHsKKwkgICAgaWYgKHN0ciA9PSBOVUxMKQorCQlnb3RvIG5leHRfc3RyaW5nOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0tFWVMKKwkgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfS0VZUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkieHNsOmtleSA6IG5vZGUgYXNzb2NpYXRlZCB0byAoJyVzJywgJyVzJylcbiIsIGtleURlZi0+bmFtZSwgc3RyKSk7CisjZW5kaWYKKworCSAgICBrZXlsaXN0ID0geG1sSGFzaExvb2t1cCh0YWJsZS0+a2V5cywgc3RyKTsKKwkgICAgaWYgKGtleWxpc3QgPT0gTlVMTCkgeworCQlrZXlsaXN0ID0geG1sWFBhdGhOb2RlU2V0Q3JlYXRlKGN1cik7CisJCWlmIChrZXlsaXN0ID09IE5VTEwpCisJCSAgICBnb3RvIGVycm9yOworCQl4bWxIYXNoQWRkRW50cnkodGFibGUtPmtleXMsIHN0ciwga2V5bGlzdCk7CisJICAgIH0gZWxzZSB7CisJCS8qCisJCSogVE9ETzogSG93IGRvIHdlIGtub3cgaWYgdGhpcyBmdW5jdGlvbiBmYWlsZWQ/CisJCSovCisJCXhtbFhQYXRoTm9kZVNldEFkZChrZXlsaXN0LCBjdXIpOworCSAgICB9CisJICAgIHN3aXRjaCAoY3VyLT50eXBlKSB7CisJCWNhc2UgWE1MX0VMRU1FTlRfTk9ERToKKwkJY2FzZSBYTUxfVEVYVF9OT0RFOgorCQljYXNlIFhNTF9DREFUQV9TRUNUSU9OX05PREU6CisJCWNhc2UgWE1MX1BJX05PREU6CisJCWNhc2UgWE1MX0NPTU1FTlRfTk9ERToKKwkJICAgIGN1ci0+cHN2aSA9IGtleURlZjsKKwkJICAgIGJyZWFrOworCQljYXNlIFhNTF9BVFRSSUJVVEVfTk9ERToKKwkJICAgICgoeG1sQXR0clB0cikgY3VyKS0+cHN2aSA9IGtleURlZjsKKwkJICAgIGJyZWFrOworCQljYXNlIFhNTF9ET0NVTUVOVF9OT0RFOgorCQljYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CisJCSAgICAoKHhtbERvY1B0cikgY3VyKS0+cHN2aSA9IGtleURlZjsKKwkJICAgIGJyZWFrOworCQlkZWZhdWx0OgorCQkgICAgYnJlYWs7CisJICAgIH0KKwkgICAgeG1sRnJlZShzdHIpOworCSAgICBzdHIgPSBOVUxMOworCituZXh0X3N0cmluZzoKKwkgICAgaysrOworCSAgICBpZiAoayA+PSBsZW4pCisJCWJyZWFrOworCSAgICBzdHIgPSB4bWxYUGF0aENhc3ROb2RlVG9TdHJpbmcodXNlUmVzLT5ub2Rlc2V0dmFsLT5ub2RlVGFiW2tdKTsKKwl9CisgICAgfQorCitleGl0OgorZXJyb3I6CisgICAgY3R4dC0+a2V5SW5pdExldmVsLS07CisgICAgLyoKKyAgICAqIFJlc3RvcmUgY29udGV4dCBzdGF0ZS4KKyAgICAqLworICAgIHhwY3R4dC0+ZG9jID0gb2xkWFBEb2M7CisgICAgeHBjdHh0LT5uc05yID0gb2xkWFBOc05yOworICAgIHhwY3R4dC0+bmFtZXNwYWNlcyA9IG9sZFhQTmFtZXNwYWNlczsKKyAgICB4cGN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gb2xkWFBQb3M7CisgICAgeHBjdHh0LT5jb250ZXh0U2l6ZSA9IG9sZFhQU2l6ZTsKKworICAgIGN0eHQtPm5vZGUgPSBvbGRDb250ZXh0Tm9kZTsKKyAgICBjdHh0LT5kb2N1bWVudCA9IG9sZERvY0luZm87CisgICAgY3R4dC0+aW5zdCA9IG9sZEluc3Q7CisKKyAgICBpZiAoc3RyKQorCXhtbEZyZWUoc3RyKTsKKyAgICBpZiAodXNlUmVzICE9IE5VTEwpCisJeG1sWFBhdGhGcmVlT2JqZWN0KHVzZVJlcyk7CisgICAgaWYgKG1hdGNoUmVzICE9IE5VTEwpCisJeG1sWFBhdGhGcmVlT2JqZWN0KG1hdGNoUmVzKTsKKyAgICByZXR1cm4oMCk7Cit9CisKKy8qKgorICogeHNsdEluaXRDdHh0S2V5czoKKyAqIEBjdHh0OiAgYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAaWRvYzogIGEgZG9jdW1lbnQgaW5mbworICoKKyAqIENvbXB1dGVzIGFsbCB0aGUga2V5cyB0YWJsZXMgZm9yIHRoZSBjdXJyZW50IGlucHV0IGRvY3VtZW50LgorICogU2hvdWxkIGJlIGRvbmUgYmVmb3JlIGdsb2JhbCB2YXJpYmFsZXMgYXJlIGluaXRpYWxpemVkLgorICogTk9URTogTm90IHVzZWQgYW55bW9yZSBpbiB0aGUgcmVmYWN0b3JlZCBjb2RlLgorICovCit2b2lkCit4c2x0SW5pdEN0eHRLZXlzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhzbHREb2N1bWVudFB0ciBpZG9jKSB7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CisgICAgeHNsdEtleURlZlB0ciBrZXlEZWY7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGlkb2MgPT0gTlVMTCkpCisJcmV0dXJuOworCisjaWZkZWYgS0VZX0lOSVRfREVCVUcKK2ZwcmludGYoc3RkZXJyLCAieHNsdEluaXRDdHh0S2V5cyBvbiBkb2N1bWVudFxuIik7CisjZW5kaWYKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19LRVlTCisgICAgaWYgKChpZG9jLT5kb2MgIT0gTlVMTCkgJiYgKGlkb2MtPmRvYy0+VVJMICE9IE5VTEwpKQorCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0tFWVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwgIkluaXRpYWxpemluZyBrZXlzIG9uICVzXG4iLAorCQkgICAgIGlkb2MtPmRvYy0+VVJMKSk7CisjZW5kaWYKKyAgICBzdHlsZSA9IGN0eHQtPnN0eWxlOworICAgIHdoaWxlIChzdHlsZSAhPSBOVUxMKSB7CisJa2V5RGVmID0gKHhzbHRLZXlEZWZQdHIpIHN0eWxlLT5rZXlzOworCXdoaWxlIChrZXlEZWYgIT0gTlVMTCkgeworCSAgICB4c2x0SW5pdEN0eHRLZXkoY3R4dCwgaWRvYywga2V5RGVmKTsKKworCSAgICBrZXlEZWYgPSBrZXlEZWYtPm5leHQ7CisJfQorCisJc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisgICAgfQorCisjaWZkZWYgS0VZX0lOSVRfREVCVUcKK2ZwcmludGYoc3RkZXJyLCAieHNsdEluaXRDdHh0S2V5cyBvbiBkb2N1bWVudDogZG9uZVxuIik7CisjZW5kaWYKKworfQorCisvKioKKyAqIHhzbHRGcmVlRG9jdW1lbnRLZXlzOgorICogQGlkb2M6IGEgWFNMVCBkb2N1bWVudAorICoKKyAqIEZyZWUgdGhlIGtleXMgYXNzb2NpYXRlZCB0byBhIGRvY3VtZW50CisgKi8KK3ZvaWQKK3hzbHRGcmVlRG9jdW1lbnRLZXlzKHhzbHREb2N1bWVudFB0ciBpZG9jKSB7CisgICAgaWYgKGlkb2MgIT0gTlVMTCkKKyAgICAgICAgeHNsdEZyZWVLZXlUYWJsZUxpc3QoaWRvYy0+a2V5cyk7Cit9CisKZGlmZiAtLWdpdCBhL2xpYnhzbHQva2V5cy5oIGIvbGlieHNsdC9rZXlzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTE4MmJhYQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQva2V5cy5oCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBTdW1tYXJ5OiAgaW50ZXJmYWNlIGZvciB0aGUga2V5IG1hdGNoaW5nIHVzZWQgaW4ga2V5KCkgYW5kIHRlbXBsYXRlIG1hdGNoZXMuCisgKiBEZXNjcmlwdGlvbjogaW1wbGVtZW50YXRpb24gb2YgdGhlIGtleSBtZWNoYW5pbXMuCisgKgorICogQ29weTogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIEF1dGhvcjogRGFuaWVsIFZlaWxsYXJkCisgKi8KKworI2lmbmRlZiBfX1hNTF9YU0xUX0tFWV9IX18KKyNkZWZpbmUgX19YTUxfWFNMVF9LRVlfSF9fCisKKyNpbmNsdWRlIDxsaWJ4bWwveHBhdGguaD4KKyNpbmNsdWRlICJ4c2x0ZXhwb3J0cy5oIgorI2luY2x1ZGUgInhzbHRJbnRlcm5hbHMuaCIKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvKioKKyAqIE5PREVfSVNfS0VZRUQ6CisgKgorICogY2hlY2sgZm9yIGJpdCAxNSBzZXQKKyAqLworI2RlZmluZSBOT0RFX0lTX0tFWUVEICgxID4+IDE1KQorCitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQl4c2x0QWRkS2V5CQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSBjb25zdCB4bWxDaGFyICpuYW1lLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqbmFtZVVSSSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKm1hdGNoLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqdXNlLAorCQkJCQkgeG1sTm9kZVB0ciBpbnN0KTsKK1hTTFRQVUJGVU4geG1sTm9kZVNldFB0ciBYU0xUQ0FMTAkKKwkJeHNsdEdldEtleQkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCSBjb25zdCB4bWxDaGFyICpuYW1lLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqbmFtZVVSSSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKnZhbHVlKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisJCXhzbHRJbml0Q3R4dEtleXMJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCSB4c2x0RG9jdW1lbnRQdHIgZG9jKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisJCXhzbHRGcmVlS2V5cwkJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisJCXhzbHRGcmVlRG9jdW1lbnRLZXlzCSh4c2x0RG9jdW1lbnRQdHIgZG9jKTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9CisjZW5kaWYKKworI2VuZGlmIC8qIF9fWE1MX1hTTFRfSF9fICovCisKZGlmZiAtLWdpdCBhL2xpYnhzbHQvbGlieHNsdC5oIGIvbGlieHNsdC9saWJ4c2x0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmI5ZjUyYQotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQvbGlieHNsdC5oCkBAIC0wLDAgKzEsMzAgQEAKKy8qCisgKiBTdW1tYXJ5OiBpbnRlcm5hbCBoZWFkZXIgb25seSB1c2VkIGR1cmluZyB0aGUgY29tcGlsYXRpb24gb2YgbGlieHNsdAorICogRGVzY3JpcHRpb246IGludGVybmFsIGhlYWRlciBvbmx5IHVzZWQgZHVyaW5nIHRoZSBjb21waWxhdGlvbiBvZiBsaWJ4c2x0CisgKgorICogQ29weTogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIEF1dGhvcjogRGFuaWVsIFZlaWxsYXJkCisgKi8KKworI2lmbmRlZiBfX1hTTFRfTElCWFNMVF9IX18KKyNkZWZpbmUgX19YU0xUX0xJQlhTTFRfSF9fCisKKyNpZiBkZWZpbmVkKFdJTjMyKSAmJiAhZGVmaW5lZCAoX19DWUdXSU5fXykgJiYgIWRlZmluZWQgKF9fTUlOR1czMl9fKQorI2luY2x1ZGUgPHdpbjMyY29uZmlnLmg+CisjZWxzZQorI2luY2x1ZGUgImNvbmZpZy5oIgorI2VuZGlmCisKKyNpbmNsdWRlIDxsaWJ4c2x0L3hzbHRjb25maWcuaD4KKyNpbmNsdWRlIDxsaWJ4bWwveG1sdmVyc2lvbi5oPgorCisjaWYgIWRlZmluZWQgTElCWFNMVF9QVUJMSUMKKyNpZiAoZGVmaW5lZCAoX19DWUdXSU5fXykgfHwgZGVmaW5lZCBfTVNDX1ZFUikgJiYgIWRlZmluZWQgSU5fTElCWFNMVCAmJiAhZGVmaW5lZCBMSUJYU0xUX1NUQVRJQworI2RlZmluZSBMSUJYU0xUX1BVQkxJQyBfX2RlY2xzcGVjKGRsbGltcG9ydCkKKyNlbHNlCisjZGVmaW5lIExJQlhTTFRfUFVCTElDIAorI2VuZGlmCisjZW5kaWYKKworI2VuZGlmIC8qICEgX19YU0xUX0xJQlhTTFRfSF9fICovCmRpZmYgLS1naXQgYS9saWJ4c2x0L25hbWVzcGFjZXMuYyBiL2xpYnhzbHQvbmFtZXNwYWNlcy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlMzg5MWYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L25hbWVzcGFjZXMuYwpAQCAtMCwwICsxLDg1MSBAQAorLyoKKyAqIG5hbWVzcGFjZXMuYzogSW1wbGVtZW50YXRpb24gb2YgdGhlIFhTTFQgbmFtZXNwYWNlcyBoYW5kbGluZworICoKKyAqIFJlZmVyZW5jZToKKyAqICAgaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteHNsdC0xOTk5MTExNgorICoKKyAqIFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBkYW5pZWxAdmVpbGxhcmQuY29tCisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpZmRlZiBIQVZFX1NZU19UWVBFU19ICisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjZW5kaWYKKyNpZmRlZiBIQVZFX01BVEhfSAorI2luY2x1ZGUgPG1hdGguaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfRkxPQVRfSAorI2luY2x1ZGUgPGZsb2F0Lmg+CisjZW5kaWYKKyNpZmRlZiBIQVZFX0lFRUVGUF9ICisjaW5jbHVkZSA8aWVlZWZwLmg+CisjZW5kaWYKKyNpZmRlZiBIQVZFX05BTl9ICisjaW5jbHVkZSA8bmFuLmg+CisjZW5kaWYKKyNpZmRlZiBIQVZFX0NUWVBFX0gKKyNpbmNsdWRlIDxjdHlwZS5oPgorI2VuZGlmCisjaWZuZGVmCVhTTFRfTkVFRF9UUklPCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNlbHNlCisjaW5jbHVkZSA8dHJpby5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CisjaW5jbHVkZSA8bGlieG1sL3RyZWUuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvaGFzaC5oPgorI2luY2x1ZGUgPGxpYnhtbC94bWxlcnJvci5oPgorI2luY2x1ZGUgPGxpYnhtbC91cmkuaD4KKyNpbmNsdWRlICJ4c2x0LmgiCisjaW5jbHVkZSAieHNsdEludGVybmFscy5oIgorI2luY2x1ZGUgInhzbHR1dGlscy5oIgorI2luY2x1ZGUgIm5hbWVzcGFjZXMuaCIKKyNpbmNsdWRlICJpbXBvcnRzLmgiCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICoJCQlNb2R1bGUgaW50ZXJmYWNlcwkJCQkqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQgIAorc3RhdGljIHhzbHROc0FsaWFzUHRyCit4c2x0TmV3TnNBbGlhcyh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0KQoreworICAgIHhzbHROc0FsaWFzUHRyIHJldDsKKworICAgIGlmIChjY3R4dCA9PSBOVUxMKQorCXJldHVybihOVUxMKTsKKworICAgIHJldCA9ICh4c2x0TnNBbGlhc1B0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0TnNBbGlhcykpOworICAgIGlmIChyZXQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIE5VTEwsCisJICAgICJJbnRlcm5hbCBlcnJvciBpbiB4c2x0TmV3TnNBbGlhcygpOiBNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQuXG4iKTsKKwljY3R4dC0+c3R5bGUtPmVycm9ycysrOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhzbHROc0FsaWFzKSk7ICAgIAorICAgIC8qCisgICAgKiBUT0RPOiBTdG9yZSB0aGUgaXRlbSBhdCBjdXJyZW50IHN0eWxlc2hlZXQtbGV2ZWwuCisgICAgKi8KKyAgICByZXQtPm5leHQgPSBjY3R4dC0+bnNBbGlhc2VzOworICAgIGNjdHh0LT5uc0FsaWFzZXMgPSByZXQ7ICAgICAgIAorCisgICAgcmV0dXJuKHJldCk7Cit9CisjZW5kaWYgLyogWFNMVF9SRUZBQ1RPUkVEICovCisvKioKKyAqIHhzbHROYW1lc3BhY2VBbGlhczoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBub2RlOiAgdGhlIHhzbDpuYW1lc3BhY2UtYWxpYXMgbm9kZQorICoKKyAqIFJlYWQgdGhlIHN0eWxlc2hlZXQtcHJlZml4IGFuZCByZXN1bHQtcHJlZml4IGF0dHJpYnV0ZXMsIHJlZ2lzdGVyCisgKiB0aGVtIGFzIHdlbGwgYXMgdGhlIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlLgorICovCit2b2lkCit4c2x0TmFtZXNwYWNlQWxpYXMoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgbm9kZSkKK3sKKyAgICB4bWxDaGFyICpyZXN1bHRQcmVmaXggPSBOVUxMOworICAgIHhtbENoYXIgKnN0eWxlUHJlZml4ID0gTlVMTDsKKyAgICB4bWxOc1B0ciBsaXRlcmFsTnMgPSBOVUxMOworICAgIHhtbE5zUHRyIHRhcmdldE5zID0gTlVMTDsKKyAKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQgCisgICAgeHNsdE5zQWxpYXNQdHIgYWxpYXM7CisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQorCXJldHVybjsKKworICAgIC8qCisgICAgKiBTUEVDIFhTTFQgMS4wOgorICAgICogICJJZiBhIG5hbWVzcGFjZSBVUkkgaXMgZGVjbGFyZWQgdG8gYmUgYW4gYWxpYXMgZm9yIG11bHRpcGxlCisgICAgKiAgZGlmZmVyZW50IG5hbWVzcGFjZSBVUklzLCB0aGVuIHRoZSBkZWNsYXJhdGlvbiB3aXRoIHRoZSBoaWdoZXN0CisgICAgKiAgaW1wb3J0IHByZWNlZGVuY2UgaXMgdXNlZC4gSXQgaXMgYW4gZXJyb3IgaWYgdGhlcmUgaXMgbW9yZSB0aGFuCisgICAgKiAgb25lIHN1Y2ggZGVjbGFyYXRpb24uIEFuIFhTTFQgcHJvY2Vzc29yIG1heSBzaWduYWwgdGhlIGVycm9yOworICAgICogIGlmIGl0IGRvZXMgbm90IHNpZ25hbCB0aGUgZXJyb3IsIGl0IG11c3QgcmVjb3ZlciBieSBjaG9vc2luZywKKyAgICAqICBmcm9tIGFtb25nc3QgdGhlIGRlY2xhcmF0aW9ucyB3aXRoIHRoZSBoaWdoZXN0IGltcG9ydCBwcmVjZWRlbmNlLAorICAgICogIHRoZSBvbmUgdGhhdCBvY2N1cnMgbGFzdCBpbiB0aGUgc3R5bGVzaGVldC4iCisgICAgKgorICAgICogU1BFQyBUT0RPOiBDaGVjayBmb3IgdGhlIGVycm9ycyBtZW50aW9uZWQgYWJvdmUuCisgICAgKi8KKyAgICAvKgorICAgICogTk9URSB0aGF0IHRoZSBYU0xUIDIuMCBhbHNvICpkb2VzKiB1c2UgdGhlIE5VTEwgbmFtZXNwYWNlIGlmCisgICAgKiAgIiNkZWZhdWx0IiBpcyB1c2VkIGFuZCB0aGVyZSdzIG5vIGRlZmF1bHQgbmFtZXNwYWNlIGlzIHNjb3BlLgorICAgICogIEkuZS4sIHRoaXMgaXMgKm5vdCogYW4gZXJyb3IuIAorICAgICogIE1vc3QgWFNMVCAxLjAgaW1wbGVtZW50YXRpb25zIHdvcmsgdGhpcyB3YXkuCisgICAgKiAgVGhlIFhTTFQgMS4wIHNwZWMgaGFzIG5vdGhpbmcgdG8gc2F5IG9uIHRoZSBzdWJqZWN0LiAKKyAgICAqLworICAgIC8qCisgICAgKiBBdHRyaWJ1dGUgInN0eWxlc2hlZXQtcHJlZml4Ii4KKyAgICAqLworICAgIHN0eWxlUHJlZml4ID0geG1sR2V0TnNQcm9wKG5vZGUsIChjb25zdCB4bWxDaGFyICopInN0eWxlc2hlZXQtcHJlZml4IiwgTlVMTCk7CisgICAgaWYgKHN0eWxlUHJlZml4ID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIG5vZGUsCisJICAgICJUaGUgYXR0cmlidXRlICdzdHlsZXNoZWV0LXByZWZpeCcgaXMgbWlzc2luZy5cbiIpOworCXJldHVybjsKKyAgICB9CisgICAgaWYgKHhtbFN0ckVxdWFsKHN0eWxlUHJlZml4LCAoY29uc3QgeG1sQ2hhciAqKSIjZGVmYXVsdCIpKQorCWxpdGVyYWxOcyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgTlVMTCk7CQorICAgIGVsc2UgeworCWxpdGVyYWxOcyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgc3R5bGVQcmVmaXgpOworCWlmIChsaXRlcmFsTnMgPT0gTlVMTCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIG5vZGUsCisJICAgICAgICAiQXR0cmlidXRlICdzdHlsZXNoZWV0LXByZWZpeCc6IFRoZXJlJ3Mgbm8gbmFtZXNwYWNlICIKKwkJImRlY2xhcmF0aW9uIGluIHNjb3BlIGZvciB0aGUgcHJlZml4ICclcycuXG4iLAorCQkgICAgc3R5bGVQcmVmaXgpOworCSAgICBnb3RvIGVycm9yOworCX0KKyAgICB9CisgICAgLyoKKyAgICAqIEF0dHJpYnV0ZSAicmVzdWx0LXByZWZpeCIuCisgICAgKi8KKyAgICByZXN1bHRQcmVmaXggPSB4bWxHZXROc1Byb3Aobm9kZSwgKGNvbnN0IHhtbENoYXIgKikicmVzdWx0LXByZWZpeCIsIE5VTEwpOworICAgIGlmIChyZXN1bHRQcmVmaXggPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgbm9kZSwKKwkgICAgIlRoZSBhdHRyaWJ1dGUgJ3Jlc3VsdC1wcmVmaXgnIGlzIG1pc3NpbmcuXG4iKTsKKwlnb3RvIGVycm9yOworICAgIH0gICAgICAgIAorICAgIGlmICh4bWxTdHJFcXVhbChyZXN1bHRQcmVmaXgsIChjb25zdCB4bWxDaGFyICopIiNkZWZhdWx0IikpCisJdGFyZ2V0TnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIE5VTEwpOworICAgIGVsc2UgeworCXRhcmdldE5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCByZXN1bHRQcmVmaXgpOworCisgICAgICAgIGlmICh0YXJnZXROcyA9PSBOVUxMKSB7CisJICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBub2RlLAorCSAgICAgICAgIkF0dHJpYnV0ZSAncmVzdWx0LXByZWZpeCc6IFRoZXJlJ3Mgbm8gbmFtZXNwYWNlICIKKwkJImRlY2xhcmF0aW9uIGluIHNjb3BlIGZvciB0aGUgcHJlZml4ICclcycuXG4iLAorCQkgICAgc3R5bGVQcmVmaXgpOworCSAgICBnb3RvIGVycm9yOworCX0KKyAgICB9CisgICAgLyoKKyAgICAgKgorICAgICAqIFNhbWUgYWxpYXMgZm9yIG11bHRpcGxlIGRpZmZlcmVudCB0YXJnZXQgbmFtZXNwYWNlIFVSSXM6CisgICAgICogIFRPRE86IFRoZSBvbmUgd2l0aCB0aGUgaGlnaGVzdCBpbXBvcnQgcHJlY2VkZW5jZSBpcyB1c2VkLgorICAgICAqICBFeGFtcGxlOgorICAgICAqICA8eHNsOm5hbWVzcGFjZS1hbGlhcyBzdHlsZXNoZWV0LXByZWZpeD0iZm9vIgorICAgICAqICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQtcHJlZml4PSJiYXIiLz4KKyAgICAgKgorICAgICAqICA8eHNsOm5hbWVzcGFjZS1hbGlhcyBzdHlsZXNoZWV0LXByZWZpeD0iZm9vIgorICAgICAqICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQtcHJlZml4PSJ6YXIiLz4KKyAgICAgKgorICAgICAqIFNhbWUgdGFyZ2V0IG5hbWVzcGFjZSBVUkkgZm9yIG11bHRpcGxlIGRpZmZlcmVudCBhbGlhc2VzOgorICAgICAqICBBbGwgYWxpYXMtZGVmaW5pdGlvbnMgd2lsbCBiZSB1c2VkLgorICAgICAqICBFeGFtcGxlOgorICAgICAqICA8eHNsOm5hbWVzcGFjZS1hbGlhcyBzdHlsZXNoZWV0LXByZWZpeD0iYmFyIgorICAgICAqICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQtcHJlZml4PSJmb28iLz4KKyAgICAgKgorICAgICAqICA8eHNsOm5hbWVzcGFjZS1hbGlhcyBzdHlsZXNoZWV0LXByZWZpeD0iemFyIgorICAgICAqICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQtcHJlZml4PSJmb28iLz4KKyAgICAgKiBDYXNlcyB1c2luZyAjZGVmYXVsdDoKKyAgICAgKiAgPHhzbDpuYW1lc3BhY2UtYWxpYXMgc3R5bGVzaGVldC1wcmVmaXg9IiNkZWZhdWx0IgorICAgICAqICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQtcHJlZml4PSIjZGVmYXVsdCIvPgorICAgICAqICBUT0RPOiBIYXMgdGhpcyBhbiBlZmZlY3QgYXQgYWxsPworICAgICAqCisgICAgICogIDx4c2w6bmFtZXNwYWNlLWFsaWFzIHN0eWxlc2hlZXQtcHJlZml4PSJmb28iCisgICAgICogICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC1wcmVmaXg9IiNkZWZhdWx0Ii8+CisgICAgICogIEZyb20gbmFtZXNwYWNlIHRvIG5vIG5hbWVzcGFjZS4KKyAgICAgKgorICAgICAqICA8eHNsOm5hbWVzcGFjZS1hbGlhcyBzdHlsZXNoZWV0LXByZWZpeD0iI2RlZmF1bHQiCisgICAgICogICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC1wcmVmaXg9ImZvbyIvPgorICAgICAqICBGcm9tIG5vIG5hbWVzcGFjZSB0byBuYW1lc3BhY2UuCisgICAgICovCisgICAgCisJCisgICAgIC8qCisgICAgICogU3RvcmUgdGhlIG5zLW5vZGUgaW4gdGhlIGFsaWFzLW9iamVjdC4KKyAgICAqLworICAgIGFsaWFzID0geHNsdE5ld05zQWxpYXMoWFNMVF9DQ1RYVChzdHlsZSkpOworICAgIGlmIChhbGlhcyA9PSBOVUxMKQorCXJldHVybjsKKyAgICBhbGlhcy0+bGl0ZXJhbE5zID0gbGl0ZXJhbE5zOworICAgIGFsaWFzLT50YXJnZXROcyA9IHRhcmdldE5zOworICAgIFhTTFRfQ0NUWFQoc3R5bGUpLT5oYXNOc0FsaWFzZXMgPSAxOworCisKKyNlbHNlIC8qIFhTTFRfUkVGQUNUT1JFRCAqLworICAgIGNvbnN0IHhtbENoYXIgKmxpdGVyYWxOc05hbWU7CisgICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TnNOYW1lOworICAgIAorCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICBzdHlsZVByZWZpeCA9IHhtbEdldE5zUHJvcChub2RlLCAoY29uc3QgeG1sQ2hhciAqKSJzdHlsZXNoZWV0LXByZWZpeCIsIE5VTEwpOworICAgIGlmIChzdHlsZVByZWZpeCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBub2RlLAorCSAgICAibmFtZXNwYWNlLWFsaWFzOiBzdHlsZXNoZWV0LXByZWZpeCBhdHRyaWJ1dGUgbWlzc2luZ1xuIik7CisJcmV0dXJuOworICAgIH0KKyAgICByZXN1bHRQcmVmaXggPSB4bWxHZXROc1Byb3Aobm9kZSwgKGNvbnN0IHhtbENoYXIgKikicmVzdWx0LXByZWZpeCIsIE5VTEwpOworICAgIGlmIChyZXN1bHRQcmVmaXggPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgbm9kZSwKKwkgICAgIm5hbWVzcGFjZS1hbGlhczogcmVzdWx0LXByZWZpeCBhdHRyaWJ1dGUgbWlzc2luZ1xuIik7CisJZ290byBlcnJvcjsKKyAgICB9CisgICAgCisgICAgaWYgKHhtbFN0ckVxdWFsKHN0eWxlUHJlZml4LCAoY29uc3QgeG1sQ2hhciAqKSIjZGVmYXVsdCIpKSB7CisJbGl0ZXJhbE5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCBOVUxMKTsKKwlpZiAobGl0ZXJhbE5zID09IE5VTEwpIHsKKwkgICAgbGl0ZXJhbE5zTmFtZSA9IE5VTEw7CisJfSBlbHNlCisJICAgIGxpdGVyYWxOc05hbWUgPSBsaXRlcmFsTnMtPmhyZWY7IC8qIFllcyAtIHNldCBmb3IgbnNBbGlhcyB0YWJsZSAqLworICAgIH0gZWxzZSB7CisJbGl0ZXJhbE5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCBzdHlsZVByZWZpeCk7CisgCisJaWYgKChsaXRlcmFsTnMgPT0gTlVMTCkgfHwgKGxpdGVyYWxOcy0+aHJlZiA9PSBOVUxMKSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIG5vZGUsCisJICAgICAgICAibmFtZXNwYWNlLWFsaWFzOiBwcmVmaXggJXMgbm90IGJvdW5kIHRvIGFueSBuYW1lc3BhY2VcbiIsCisJCQkJCXN0eWxlUHJlZml4KTsKKwkgICAgZ290byBlcnJvcjsKKwl9IGVsc2UKKwkgICAgbGl0ZXJhbE5zTmFtZSA9IGxpdGVyYWxOcy0+aHJlZjsKKyAgICB9CisKKyAgICAvKgorICAgICAqIFdoZW4gIiNkZWZhdWx0IiBpcyB1c2VkIGZvciByZXN1bHQsIGlmIGEgZGVmYXVsdCBuYW1lc3BhY2UgaGFzIG5vdAorICAgICAqIGJlZW4gZXhwbGljaXRseSBkZWNsYXJlZCB0aGUgc3BlY2lhbCB2YWx1ZSBVTkRFRklORURfREVGQVVMVF9OUyBpcworICAgICAqIHB1dCBpbnRvIHRoZSBuc0FsaWFzZXMgdGFibGUKKyAgICAgKi8KKyAgICBpZiAoeG1sU3RyRXF1YWwocmVzdWx0UHJlZml4LCAoY29uc3QgeG1sQ2hhciAqKSIjZGVmYXVsdCIpKSB7CisJdGFyZ2V0TnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIE5VTEwpOworCWlmICh0YXJnZXROcyA9PSBOVUxMKSB7CisJICAgIHRhcmdldE5zTmFtZSA9IFVOREVGSU5FRF9ERUZBVUxUX05TOworCX0gZWxzZQorCSAgICB0YXJnZXROc05hbWUgPSB0YXJnZXROcy0+aHJlZjsKKyAgICB9IGVsc2UgeworCXRhcmdldE5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCByZXN1bHRQcmVmaXgpOworCisgICAgICAgIGlmICgodGFyZ2V0TnMgPT0gTlVMTCkgfHwgKHRhcmdldE5zLT5ocmVmID09IE5VTEwpKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgbm9kZSwKKwkgICAgICAgICJuYW1lc3BhY2UtYWxpYXM6IHByZWZpeCAlcyBub3QgYm91bmQgdG8gYW55IG5hbWVzcGFjZVxuIiwKKwkJCQkJcmVzdWx0UHJlZml4KTsKKwkgICAgZ290byBlcnJvcjsKKwl9IGVsc2UKKwkgICAgdGFyZ2V0TnNOYW1lID0gdGFyZ2V0TnMtPmhyZWY7CisgICAgfQorICAgIC8qCisgICAgICogU3BlY2lhbCBjYXNlOiBpZiAjZGVmYXVsdCBpcyB1c2VkIGZvcgorICAgICAqICB0aGUgc3R5bGVzaGVldC1wcmVmaXggKGxpdGVyYWwgbmFtZXNwYWNlKSBhbmQgdGhlcmUncyBubyBkZWZhdWx0CisgICAgICogIG5hbWVzcGFjZSBpbiBzY29wZSwgd2UnbGwgdXNlIHN0eWxlLT5kZWZhdWx0QWxpYXMgZm9yIHRoaXMuCisgICAgICovICAgCisgICAgaWYgKGxpdGVyYWxOc05hbWUgPT0gTlVMTCkgeworICAgICAgICBpZiAodGFyZ2V0TnMgIT0gTlVMTCkgeworCSAgICAvKgorCSAgICAqIEJVRyBUT0RPOiBJcyBpdCBub3Qgc3VmZmljaWVudCB0byBoYXZlIG9ubHkgMSBmaWVsZCBmb3IKKwkgICAgKiAgdGhpcywgc2luY2Ugc3Vic2VxdWVudGx5IGFsaWFzIGRlY2xhcmF0aW9ucyB3aWxsCisJICAgICogIG92ZXJ3cml0ZSB0aGlzLgkgICAgCisJICAgICogIEV4YW1wbGU6CisJICAgICogICA8eHNsOm5hbWVzcGFjZS1hbGlhcyByZXN1bHQtcHJlZml4PSJmb28iCisJICAgICogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZXNoZWV0LXByZWZpeD0iI2RlZmF1bHQiLz4KKwkgICAgKiAgIDx4c2w6bmFtZXNwYWNlLWFsaWFzIHJlc3VsdC1wcmVmaXg9ImJhciIKKwkgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlc2hlZXQtcHJlZml4PSIjZGVmYXVsdCIvPgorCSAgICAqICBUaGUgbWFwcGluZyBmb3IgImZvbyIgd29uJ3QgYmUgdmlzaWJsZSBhbnltb3JlLgorCSAgICAqLworICAgICAgICAgICAgc3R5bGUtPmRlZmF1bHRBbGlhcyA9IHRhcmdldE5zLT5ocmVmOworCX0KKyAgICB9IGVsc2UgeworICAgICAgICBpZiAoc3R5bGUtPm5zQWxpYXNlcyA9PSBOVUxMKQorCSAgICBzdHlsZS0+bnNBbGlhc2VzID0geG1sSGFzaENyZWF0ZSgxMCk7CisgICAgICAgIGlmIChzdHlsZS0+bnNBbGlhc2VzID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBub2RlLAorCSAgICAgICAgIm5hbWVzcGFjZS1hbGlhczogY2Fubm90IGNyZWF0ZSBoYXNoIHRhYmxlXG4iKTsKKwkgICAgZ290byBlcnJvcjsKKyAgICAgICAgfQorCXhtbEhhc2hBZGRFbnRyeSgoeG1sSGFzaFRhYmxlUHRyKSBzdHlsZS0+bnNBbGlhc2VzLAorCSAgICBsaXRlcmFsTnNOYW1lLCAodm9pZCAqKSB0YXJnZXROc05hbWUpOworICAgIH0KKyNlbmRpZiAvKiBlbHNlIG9mIFhTTFRfUkVGQUNUT1JFRCAqLworCitlcnJvcjoKKyAgICBpZiAoc3R5bGVQcmVmaXggIT0gTlVMTCkKKwl4bWxGcmVlKHN0eWxlUHJlZml4KTsKKyAgICBpZiAocmVzdWx0UHJlZml4ICE9IE5VTEwpCisJeG1sRnJlZShyZXN1bHRQcmVmaXgpOworfQorCisvKioKKyAqIHhzbHRHZXRTcGVjaWFsTmFtZXNwYWNlOgorICogQGN0eHQ6ICB0aGUgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQGludm9jTm9kZTogdGhlIGludm9raW5nIG5vZGU7IGUuZy4gYSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50L2F0dHI7CisgKiAgICAgICAgICAgICBvbmx5IHVzZWQgZm9yIGVycm9yIHJlcG9ydHMKKyAqIEBuc05hbWU6ICB0aGUgbmFtZXNwYWNlIG5hbWUgKG9yIE5VTEwpCisgKiBAbnNQcmVmaXg6ICB0aGUgc3VnZ2VzdGVkIG5hbWVzcGFjZSBwcmVmaXggKG9yIE5VTEwpCisgKiBAdGFyZ2V0OiAgdGhlIHJlc3VsdCBlbGVtZW50IG9uIHdoaWNoIHRvIGFuY2hvciBhIG5hbWVzcGFjZQorICoKKyAqIEZpbmQgYSBtYXRjaGluZyAocHJlZml4IGFuZCBucy1uYW1lKSBucy1kZWNsYXJhdGlvbgorICogZm9yIHRoZSByZXF1ZXN0ZWQgQG5zTmFtZSBhbmQgQG5zUHJlZml4IGluIHRoZSByZXN1bHQgdHJlZS4KKyAqIElmIG5vbmUgaXMgZm91bmQgdGhlbiBhIG5ldyBucy1kZWNsYXJhdGlvbiB3aWxsIGJlCisgKiBhZGRlZCB0byBAcmVzdWx0RWxlbS4gSWYsIGluIHRoaXMgY2FzZSwgdGhlIGdpdmVuIHByZWZpeCBpcworICogYWxyZWFkeSBpbiB1c2UsIHRoZW4gYSBucy1kZWNsYXJhdGlvbiB3aXRoIGEgbW9kaWZpZWQgbnMtcHJlZml4CisgKiBiZSB3ZSBjcmVhdGVkLiBOb3RlIHRoYXQgdGhpcyBmdW5jdGlvbidzIHByaW9yaXR5IGlzIHRvCisgKiBwcmVzZXJ2ZSBucy1wcmVmaXhlczsgaXQgd2lsbCBvbmx5IGNoYW5nZSBhIHByZWZpeCBpZiB0aGVyZSdzCisgKiBhIG5hbWVzcGFjZSBjbGFzaC4KKyAqIElmIGJvdGggQG5zTmFtZSBhbmQgQG5zUHJlZml4IGFyZSBOVUxMLCB0aGVuIHRoaXMgd2lsbCB0cnkgdG8KKyAqICJ1bmRlY2xhcmUiIGEgZGVmYXVsdCBuYW1lc3BhY2UgYnkgZGVjbGFyaW5nIGFuIHhtbG5zPSIiLgorICoKKyAqIFJldHVybnMgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gb3IgTlVMTC4KKyAqLworeG1sTnNQdHIKK3hzbHRHZXRTcGVjaWFsTmFtZXNwYWNlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgaW52b2NOb2RlLAorCQljb25zdCB4bWxDaGFyICpuc05hbWUsIGNvbnN0IHhtbENoYXIgKm5zUHJlZml4LAorCQl4bWxOb2RlUHRyIHRhcmdldCkKK3sKKyAgICB4bWxOc1B0ciBuczsKKyAgICBpbnQgcHJlZml4T2NjdXBpZWQgPSAwOworCisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0YXJnZXQgPT0gTlVMTCkgfHwKKwkodGFyZ2V0LT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpKQorCXJldHVybihOVUxMKTsKKworICAgIC8qCisgICAgKiBOT1RFOiBOYW1lc3BhY2UgZXhjbHVzaW9uIGFuZCBucy1hbGlhc2luZyBpcyBwZXJmb3JtZWQgYXQKKyAgICAqICBjb21waWxhdGlvbi10aW1lIGluIHRoZSByZWZhY3RvcmVkIGNvZGU7IHNvIHRoaXMgbmVlZCBub3QgYmUgZG9uZQorICAgICogIGhlcmUgKGl0IHdhcyBpbiB0aGUgb2xkIGNvZGUpLgorICAgICogTk9URTogQGludm9jTm9kZSB3YXMgbmFtZWQgQGN1ciBpbiB0aGUgb2xkIGNvZGUgYW5kIHdhcyBkb2N1bWVudGVkIHRvCisgICAgKiAgYmUgYW4gaW5wdXQgbm9kZTsgc2luY2UgaXQgd2FzIG9ubHkgdXNlZCB0byBhbmNob3IgYW4gZXJyb3IgcmVwb3J0CisgICAgKiAgc29tZXdoZXJlLCB3ZSBjYW4gc2FmZWx5IGNoYW5nZSB0aGlzIHRvIEBpbnZvY05vZGUsIHdoaWNoIG5vdworICAgICogIHdpbGwgYmUgdGhlIFhTTFQgaW5zdHJ1Y3Rpb24gKGFsc28gYSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50L2F0dHJpYnV0ZSksCisgICAgKiAgd2hpY2ggd2FzIHJlc3BvbnNpYmxlIGZvciB0aGlzIGNhbGwuCisgICAgKi8KKyAgICAvKgorICAgICogT1BUSU1JWkUgVE9ETzogVGhpcyBhbGwgY291bGQgYmUgb3B0aW1pemVkIGJ5IGtlZXBpbmcgdHJhY2sgb2YKKyAgICAqICB0aGUgbnMtZGVjbHMgY3VycmVudGx5IGluLXNjb3BlIHZpYSBhIHNwZWNpYWxpemVkIGNvbnRleHQuCisgICAgKi8gICAgCisgICAgaWYgKChuc1ByZWZpeCA9PSBOVUxMKSAmJiAoKG5zTmFtZSA9PSBOVUxMKSB8fCAobnNOYW1lWzBdID09IDApKSkgeworCS8qCisJKiBOT1RFOiB0aGUgInVuZGVjbGFyYXRpb24iIG9mIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSB3YXMKKwkqIHBhcnQgb2YgdGhlIGxvZ2ljIG9mIHRoZSBvbGQgeHNsdEdldFNwZWNpYWxOYW1lc3BhY2UoKSBjb2RlLAorCSogc28gd2UnbGwga2VlcCB0aGF0IG1lY2hhbmlzbS4KKwkqIFJlbGF0ZWQgdG8gdGhlIG9sZCBjb2RlOiBidWcgIzMwMjAyMDoKKwkqLworCS8qCisJKiBPUFRJTUlaRSBUT0RPOiBUaGlzIGFsbCBjb3VsZCBiZSBvcHRpbWl6ZWQgYnkga2VlcGluZyB0cmFjayBvZgorCSogIHRoZSBucy1kZWNscyBjdXJyZW50bHkgaW4tc2NvcGUgdmlhIGEgc3BlY2lhbGl6ZWQgY29udGV4dC4KKwkqLworCS8qCisJKiBTZWFyY2ggb24gdGhlIHJlc3VsdCBlbGVtZW50IGl0c2VsZi4KKwkqLworCWlmICh0YXJnZXQtPm5zRGVmICE9IE5VTEwpIHsKKwkgICAgbnMgPSB0YXJnZXQtPm5zRGVmOworCSAgICBkbyB7CisJCWlmIChucy0+cHJlZml4ID09IE5VTEwpIHsKKwkJICAgIGlmICgobnMtPmhyZWYgIT0gTlVMTCkgJiYgKG5zLT5ocmVmWzBdICE9IDApKSB7CisJCQkvKgorCQkJKiBSYWlzZSBhIG5hbWVzcGFjZSBub3JtYWxpemF0aW9uIGVycm9yLgorCQkJKi8KKwkJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnZvY05vZGUsCisJCQkgICAgIk5hbWVzcGFjZSBub3JtYWxpemF0aW9uIGVycm9yOiBDYW5ub3QgdW5kZWNsYXJlICIKKwkJCSAgICAidGhlIGRlZmF1bHQgbmFtZXNwYWNlLCBzaW5jZSB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgIgorCQkJICAgICInJXMnIGlzIGFscmVhZHkgZGVjbGFyZWQgb24gdGhlIHJlc3VsdCBlbGVtZW50ICIKKwkJCSAgICAiJyVzJy5cbiIsIG5zLT5ocmVmLCB0YXJnZXQtPm5hbWUpOworCQkJcmV0dXJuKE5VTEwpOworCQkgICAgfSBlbHNlIHsKKwkJCS8qCisJCQkqIFRoZSBkZWZhdWx0IG5hbWVzcGFjZSB3YXMgdW5kZWNsYXJlZCBvbiB0aGUKKwkJCSogcmVzdWx0IGVsZW1lbnQuCisJCQkqLworCQkJcmV0dXJuKE5VTEwpOworCQkgICAgfQorCQkgICAgYnJlYWs7CisJCX0KKwkJbnMgPSBucy0+bmV4dDsKKwkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CisJfQkKKwlpZiAoKHRhcmdldC0+cGFyZW50ICE9IE5VTEwpICYmCisJICAgICh0YXJnZXQtPnBhcmVudC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSkKKwl7CisJICAgIC8qCisJICAgICogVGhlIHBhcmVudCBlbGVtZW50IGlzIGluIG5vIG5hbWVzcGFjZSwgc28gYXNzdW1lCisJICAgICogdGhhdCB0aGVyZSBpcyBubyBkZWZhdWx0IG5hbWVzcGFjZSBpbiBzY29wZS4KKwkgICAgKi8KKwkgICAgaWYgKHRhcmdldC0+cGFyZW50LT5ucyA9PSBOVUxMKQorCQlyZXR1cm4oTlVMTCk7CisJICAgIAorCSAgICBucyA9IHhtbFNlYXJjaE5zKHRhcmdldC0+ZG9jLCB0YXJnZXQtPnBhcmVudCwKKwkJTlVMTCk7CisJICAgIC8qCisJICAgICogRmluZSBpZiB0aGVyZSdzIG5vIGRlZmF1bHQgbnMgaXMgc2NvcGUsIG9yIGlmIHRoZQorCSAgICAqIGRlZmF1bHQgbnMgd2FzIHVuZGVjbGFyZWQuCisJICAgICovCisJICAgIGlmICgobnMgPT0gTlVMTCkgfHwgKG5zLT5ocmVmID09IE5VTEwpIHx8IChucy0+aHJlZlswXSA9PSAwKSkKKwkJcmV0dXJuKE5VTEwpOworCSAgICAKKwkgICAgLyoKKwkgICAgKiBVbmRlY2xhcmUgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLgorCSAgICAqLworCSAgICB4bWxOZXdOcyh0YXJnZXQsIEJBRF9DQVNUICIiLCBOVUxMKTsKKwkgICAgLyogVE9ETzogQ2hlY2sgcmVzdWx0ICovCQorCSAgICByZXR1cm4oTlVMTCk7CisJfQorCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgLyoKKyAgICAqIEhhbmRsZSB0aGUgWE1MIG5hbWVzcGFjZS4KKyAgICAqIFFVRVNUSU9OOiBJcyB0aGlzIGZhc3RlciB0aGFuIHVzaW5nIHhtbFN0ckVxdWFsKCkgYW55d2F5PworICAgICovCisgICAgaWYgKChuc1ByZWZpeCAhPSBOVUxMKSAmJgorCShuc1ByZWZpeFswXSA9PSAneCcpICYmIChuc1ByZWZpeFsxXSA9PSAnbScpICYmCisJKG5zUHJlZml4WzJdID09ICdsJykgJiYgKG5zUHJlZml4WzNdID09IDApKQorICAgIHsKKwlyZXR1cm4oeG1sU2VhcmNoTnModGFyZ2V0LT5kb2MsIHRhcmdldCwgbnNQcmVmaXgpKTsKKyAgICB9CisgICAgLyoKKyAgICAqIEZpcnN0OiBzZWFyY2ggb24gdGhlIHJlc3VsdCBlbGVtZW50IGl0c2VsZi4KKyAgICAqLworICAgIGlmICh0YXJnZXQtPm5zRGVmICE9IE5VTEwpIHsKKwlucyA9IHRhcmdldC0+bnNEZWY7CisJZG8geworCSAgICBpZiAoKG5zLT5wcmVmaXggPT0gTlVMTCkgPT0gKG5zUHJlZml4ID09IE5VTEwpKSB7CisJCWlmIChucy0+cHJlZml4ID09IG5zUHJlZml4KSB7CisJCSAgICBpZiAoeG1sU3RyRXF1YWwobnMtPmhyZWYsIG5zTmFtZSkpCisJCQlyZXR1cm4obnMpOworCQkgICAgcHJlZml4T2NjdXBpZWQgPSAxOworCQkgICAgYnJlYWs7CisJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobnMtPnByZWZpeCwgbnNQcmVmaXgpKSB7CisJCSAgICBpZiAoeG1sU3RyRXF1YWwobnMtPmhyZWYsIG5zTmFtZSkpCisJCQlyZXR1cm4obnMpOworCQkgICAgcHJlZml4T2NjdXBpZWQgPSAxOworCQkgICAgYnJlYWs7CisJCX0KKwkgICAgfQorCSAgICBucyA9IG5zLT5uZXh0OworCX0gd2hpbGUgKG5zICE9IE5VTEwpOworICAgIH0KKyAgICBpZiAocHJlZml4T2NjdXBpZWQpIHsKKwkvKgorCSogSWYgdGhlIG5zLXByZWZpeCBpcyBvY2N1cGllZCBieSBhbiBvdGhlciBucy1kZWNsIG9uIHRoZQorCSogcmVzdWx0IGVsZW1lbnQsIHRoZW4gdGhpcyBtZWFuczoKKwkqIDEpIFRoZSBkZXNpcmVkIHByZWZpeCBpcyBzaGFkb3dlZAorCSogMikgVGhlcmUncyBubyB3YXkgYXJvdW5kIGNoYW5naW5nIHRoZSBwcmVmaXgJCisJKgorCSogVHJ5IGEgZGVzcGVyYXRlIHNlYXJjaCBmb3IgYW4gaW4tc2NvcGUgbnMtZGVjbAorCSogd2l0aCBhIG1hdGNoaW5nIG5zLW5hbWUgYmVmb3JlIHdlIHVzZSB0aGUgbGFzdCBvcHRpb24sCisJKiB3aGljaCBpcyB0byByZWNyZWF0ZSB0aGUgbnMtZGVjbCB3aXRoIGEgbW9kaWZpZWQgcHJlZml4LgorCSovCisJbnMgPSB4bWxTZWFyY2hOc0J5SHJlZih0YXJnZXQtPmRvYywgdGFyZ2V0LCBuc05hbWUpOworCWlmIChucyAhPSBOVUxMKQorCSAgICByZXR1cm4obnMpOworCisJLyoKKwkqIEZhbGxiYWNrIHRvIGNoYW5naW5nIHRoZSBwcmVmaXguCisJKi8gICAgCisgICAgfSBlbHNlIGlmICgodGFyZ2V0LT5wYXJlbnQgIT0gTlVMTCkgJiYKKwkodGFyZ2V0LT5wYXJlbnQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkpCisgICAgeworCS8qCisJKiBUcnkgdG8gZmluZCBhIG1hdGNoaW5nIG5zLWRlY2wgaW4gdGhlIGFuY2VzdG9yLWF4aXMuCisJKgorCSogQ2hlY2sgdGhlIGNvbW1vbiBjYXNlOiBUaGUgcGFyZW50IGVsZW1lbnQgb2YgdGhlIGN1cnJlbnQKKwkqIHJlc3VsdCBlbGVtZW50IGlzIGluIHRoZSBzYW1lIG5hbWVzcGFjZSAod2l0aCBhbiBlcXVhbCBucy1wcmVmaXgpLgorCSovICAgICAKKwlpZiAoKHRhcmdldC0+cGFyZW50LT5ucyAhPSBOVUxMKSAmJgorCSAgICAoKHRhcmdldC0+cGFyZW50LT5ucy0+cHJlZml4ICE9IE5VTEwpID09IChuc1ByZWZpeCAhPSBOVUxMKSkpCisJeworCSAgICBucyA9IHRhcmdldC0+cGFyZW50LT5uczsKKwkgICAgCisJICAgIGlmIChuc1ByZWZpeCA9PSBOVUxMKSB7CisJCWlmICh4bWxTdHJFcXVhbChucy0+aHJlZiwgbnNOYW1lKSkKKwkJICAgIHJldHVybihucyk7CisJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobnMtPnByZWZpeCwgbnNQcmVmaXgpICYmCisJCXhtbFN0ckVxdWFsKG5zLT5ocmVmLCBuc05hbWUpKQorCSAgICB7CisJCXJldHVybihucyk7CisJICAgIH0KKwl9CisJLyoKKwkqIExvb2t1cCB0aGUgcmVtYWluaW5nIGluLXNjb3BlIG5hbWVzcGFjZXMuCisJKi8gICAgCisJbnMgPSB4bWxTZWFyY2hOcyh0YXJnZXQtPmRvYywgdGFyZ2V0LT5wYXJlbnQsIG5zUHJlZml4KTsKKwlpZiAobnMgIT0gTlVMTCkgeworCSAgICBpZiAoeG1sU3RyRXF1YWwobnMtPmhyZWYsIG5zTmFtZSkpCisJCXJldHVybihucyk7CSAgICAKKwkgICAgLyoKKwkgICAgKiBOb3cgY2hlY2sgZm9yIGEgbmFzdHkgY2FzZTogV2UgbmVlZCB0byBlbnN1cmUgdGhhdCB0aGUgbmV3CisJICAgICogbnMtZGVjbCB3b24ndCBzaGFkb3cgYSBwcmVmaXggaW4tdXNlIGJ5IGFuIGV4aXN0aW5nIGF0dHJpYnV0ZS4KKwkgICAgKiA8Zm9vIHhtbG5zOmE9InVybjp0ZXN0OmEiPgorCSAgICAqICAgPGJhciBhOmE9InZhbC1hIj4KKwkgICAgKiAgICAgPHhzbDphdHRyaWJ1dGUgeG1sbnM6YT0idXJuOnRlc3Q6YiIgbmFtZT0iYTpiIj4KKwkgICAgKiAgICAgICAgdmFsLWI8L3hzbDphdHRyaWJ1dGU+CisJICAgICogICA8L2Jhcj4KKwkgICAgKiA8L2Zvbz4KKwkgICAgKi8KKwkgICAgaWYgKHRhcmdldC0+cHJvcGVydGllcykgeworCQl4bWxBdHRyUHRyIGF0dHIgPSB0YXJnZXQtPnByb3BlcnRpZXM7CisJCWRvIHsKKwkJICAgIGlmICgoYXR0ci0+bnMpICYmCisJCQl4bWxTdHJFcXVhbChhdHRyLT5ucy0+cHJlZml4LCBuc1ByZWZpeCkpCisJCSAgICB7CisJCQkvKgorCQkJKiBCYWQsIHRoaXMgcHJlZml4IGlzIGFscmVhZHkgaW4gdXNlLgorCQkJKiBTaW5jZSB3ZSdsbCBjaGFuZ2UgdGhlIHByZWZpeCBhbnl3YXksIHRyeQorCQkJKiBhIHNlYXJjaCBmb3IgYSBtYXRjaGluZyBucy1kZWNsIGJhc2VkIG9uIHRoZQorCQkJKiBuYW1lc3BhY2UgbmFtZS4KKwkJCSovCisJCQlucyA9IHhtbFNlYXJjaE5zQnlIcmVmKHRhcmdldC0+ZG9jLCB0YXJnZXQsIG5zTmFtZSk7CisJCQlpZiAobnMgIT0gTlVMTCkKKwkJCSAgICByZXR1cm4obnMpOworCQkJZ290byBkZWNsYXJlX25ld19wcmVmaXg7CisJCSAgICB9CisJCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKKwkJfSB3aGlsZSAoYXR0ciAhPSBOVUxMKTsKKwkgICAgfQorCX0gZWxzZSB7CisJICAgIC8qCisJICAgICogRWl0aGVyIG5vIG1hdGNoaW5nIG5zLXByZWZpeCB3YXMgZm91bmQgb3IgdGhlIG5hbWVzcGFjZSBpcworCSAgICAqIHNoYWRvd2VkLgorCSAgICAqIENyZWF0ZSBhIG5ldyBucy1kZWNsIG9uIHRoZSBjdXJyZW50IHJlc3VsdCBlbGVtZW50LgorCSAgICAqCisJICAgICogSG1tLCB3ZSBjb3VsZCBhbHNvIHRyeSB0byByZXVzZSBhbiBpbi1zY29wZQorCSAgICAqIG5hbWVzcGFjZSB3aXRoIGEgbWF0Y2hpbmcgbnMtbmFtZSBidXQgYSBkaWZmZXJlbnQKKwkgICAgKiBucy1wcmVmaXguCisJICAgICogV2hhdCBoYXMgaGlnaGVyIHByaW9yaXR5PworCSAgICAqICAxKSBJZiBrZWVwaW5nIHRoZSBwcmVmaXg6IGNyZWF0ZSBhIG5ldyBucy1kZWNsLgorCSAgICAqICAyKSBJZiByZXVzYWw6IGZpcnN0IGxvb2t1cCBucy1uYW1lczsgdGhlbiBmYWxsYmFjaworCSAgICAqICAgICB0byBjcmVhdGlvbiBvZiBhIG5ldyBucy1kZWNsLgorCSAgICAqIFJFVklTSVQ6IHRoaXMgY3VycmVudGx5IHVzZXMgY2FzZSAxKSBhbHRob3VnaAorCSAgICAqICB0aGUgb2xkIHdheSB3YXMgdXNlIHhtbFNlYXJjaE5zQnlIcmVmKCkgYW5kIHRvIGxldCBjaGFuZ2UKKwkgICAgKiAgdGhlIHByZWZpeC4KKwkgICAgKi8KKyNpZiAwCisJICAgIG5zID0geG1sU2VhcmNoTnNCeUhyZWYodGFyZ2V0LT5kb2MsIHRhcmdldCwgbnNOYW1lKTsKKwkgICAgaWYgKG5zICE9IE5VTEwpCisJCXJldHVybihucyk7CisjZW5kaWYKKwl9CisJLyoKKwkqIENyZWF0ZSB0aGUgbnMtZGVjbCBvbiB0aGUgY3VycmVudCByZXN1bHQgZWxlbWVudC4KKwkqLworCW5zID0geG1sTmV3TnModGFyZ2V0LCBuc05hbWUsIG5zUHJlZml4KTsKKwkvKiBUT0RPOiBjaGVjayBlcnJvcnMgKi8KKwlyZXR1cm4obnMpOworICAgIH0gZWxzZSB7CisJLyoKKwkqIFRoaXMgaXMgZWl0aGVyIHRoZSByb290IG9mIHRoZSB0cmVlIG9yIHNvbWV0aGluZyB3ZWlyZCBpcyBnb2luZyBvbi4KKwkqLworCW5zID0geG1sTmV3TnModGFyZ2V0LCBuc05hbWUsIG5zUHJlZml4KTsKKwkvKiBUT0RPOiBDaGVjayByZXN1bHQgKi8KKwlyZXR1cm4obnMpOworICAgIH0KKworZGVjbGFyZV9uZXdfcHJlZml4OgorICAgIC8qCisgICAgKiBGYWxsYmFjazogd2UgbmVlZCB0byBnZW5lcmF0ZSBhIG5ldyBwcmVmaXggYW5kIGRlY2xhcmUgdGhlIG5hbWVzcGFjZQorICAgICogb24gdGhlIHJlc3VsdCBlbGVtZW50LgorICAgICovCisgICAgeworCXhtbENoYXIgcHJlZlszMF07CisJaW50IGNvdW50ZXIgPSAxOworCisJaWYgKG5zUHJlZml4ID09IE5VTEwpIHsKKwkgICAgbnNQcmVmaXggPSAibnMiOworCX0KKworCWRvIHsKKwkgICAgc25wcmludGYoKGNoYXIgKikgcHJlZiwgMzAsICIlc18lZCIsIG5zUHJlZml4LCBjb3VudGVyKyspOworCSAgICBucyA9IHhtbFNlYXJjaE5zKHRhcmdldC0+ZG9jLCB0YXJnZXQsIEJBRF9DQVNUIHByZWYpOworCSAgICBpZiAoY291bnRlciA+IDEwMDApIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGludm9jTm9kZSwKKwkJICAgICJJbnRlcm5hbCBlcnJvciBpbiB4c2x0QWNxdWlyZVJlc3VsdEluU2NvcGVOcygpOiAiCisJCSAgICAiRmFpbGVkIHRvIGNvbXB1dGUgYSB1bmlxdWUgbnMtcHJlZml4IGZvciB0aGUgIgorCQkgICAgImdlbmVyYXRlZCBlbGVtZW50Iik7CisJCXJldHVybihOVUxMKTsKKwkgICAgfQorCX0gd2hpbGUgKG5zICE9IE5VTEwpOworCW5zID0geG1sTmV3TnModGFyZ2V0LCBuc05hbWUsIEJBRF9DQVNUIHByZWYpOworCS8qIFRPRE86IENoZWNrIHJlc3VsdCAqLworCXJldHVybihucyk7CisgICAgfQorICAgIHJldHVybihOVUxMKTsKK30KKworLyoqCisgKiB4c2x0R2V0TmFtZXNwYWNlOgorICogQGN0eHQ6ICBhIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBjdXI6ICB0aGUgaW5wdXQgbm9kZQorICogQG5zOiAgdGhlIG5hbWVzcGFjZQorICogQG91dDogIHRoZSBvdXRwdXQgbm9kZSAob3IgaXRzIHBhcmVudCkKKyAqCisgKiBGaW5kIGEgbWF0Y2hpbmcgKHByZWZpeCBhbmQgbnMtbmFtZSkgbnMtZGVjbGFyYXRpb24KKyAqIGZvciB0aGUgcmVxdWVzdGVkIEBucy0+cHJlZml4IGFuZCBAbnMtPmhyZWYgaW4gdGhlIHJlc3VsdCB0cmVlLgorICogSWYgbm9uZSBpcyBmb3VuZCB0aGVuIGEgbmV3IG5zLWRlY2xhcmF0aW9uIHdpbGwgYmUKKyAqIGFkZGVkIHRvIEByZXN1bHRFbGVtLiBJZiwgaW4gdGhpcyBjYXNlLCB0aGUgZ2l2ZW4gcHJlZml4IGlzCisgKiBhbHJlYWR5IGluIHVzZSwgdGhlbiBhIG5zLWRlY2xhcmF0aW9uIHdpdGggYSBtb2RpZmllZCBucy1wcmVmaXgKKyAqIGJlIHdlIGNyZWF0ZWQuCisgKgorICogQ2FsbGVkIGJ5OgorICogIC0geHNsdENvcHlQcm9wTGlzdCgpICgqbm90KiAgYW55bW9yZSkKKyAqICAtIHhzbHRTaGFsbG93Q29weUVsZW1lbnQoKQorICogIC0geHNsdENvcHlUcmVlSW50ZXJuYWwoKSAoKm5vdCogIGFueW1vcmUpCisgKiAgLSB4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yKCkgKCpub3QqIGluIHRoZSByZWZhY3RvcmVkIGNvZGUpLAorICogIC0geHNsdEVsZW1lbnQoKSAoKm5vdCogYW55bW9yZSkKKyAqCisgKiBSZXR1cm5zIGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZgorICogICAgICAgICBuYW1lc3BhY2UgZml4dXAgZmFpbHVyZXMgb3IgQVBJIG9yIGludGVybmFsIGVycm9ycy4KKyAqLworeG1sTnNQdHIKK3hzbHRHZXROYW1lc3BhY2UoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBjdXIsIHhtbE5zUHRyIG5zLAorCSAgICAgICAgIHhtbE5vZGVQdHIgb3V0KQoreyAgICAKKyAgICAKKyAgICBpZiAobnMgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICAvKgorICAgICogTmFtZXNwYWNlIGV4Y2x1c2lvbiBhbmQgbnMtYWxpYXNpbmcgaXMgcGVyZm9ybWVkIGF0CisgICAgKiBjb21waWxhdGlvbi10aW1lIGluIHRoZSByZWZhY3RvcmVkIGNvZGUuCisgICAgKiBBZGRpdGlvbmFsbHksIGFsaWFzaW5nIGlzIG5vdCBpbnRlbmRlZCBmb3Igbm9uIExpdGVyYWwKKyAgICAqIFJlc3VsdCBFbGVtZW50cy4KKyAgICAqLworICAgIHJldHVybih4c2x0R2V0U3BlY2lhbE5hbWVzcGFjZShjdHh0LCBjdXIsIG5zLT5ocmVmLCBucy0+cHJlZml4LCBvdXQpKTsKKyNlbHNlCisgICAgeworCXhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlOworCWNvbnN0IHhtbENoYXIgKlVSSSA9IE5VTEw7IC8qIHRoZSByZXBsYWNlbWVudCBVUkkgKi8KKworCWlmICgoY3R4dCA9PSBOVUxMKSB8fCAoY3VyID09IE5VTEwpIHx8IChvdXQgPT0gTlVMTCkpCisJICAgIHJldHVybihOVUxMKTsKKworCXN0eWxlID0gY3R4dC0+c3R5bGU7CisJd2hpbGUgKHN0eWxlICE9IE5VTEwpIHsKKwkgICAgaWYgKHN0eWxlLT5uc0FsaWFzZXMgIT0gTlVMTCkKKwkJVVJJID0gKGNvbnN0IHhtbENoYXIgKikgCisJCXhtbEhhc2hMb29rdXAoc3R5bGUtPm5zQWxpYXNlcywgbnMtPmhyZWYpOworCSAgICBpZiAoVVJJICE9IE5VTEwpCisJCWJyZWFrOworCSAgICAKKwkgICAgc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisJfQorCQorCQorCWlmIChVUkkgPT0gVU5ERUZJTkVEX0RFRkFVTFRfTlMpIHsKKwkgICAgcmV0dXJuKHhzbHRHZXRTcGVjaWFsTmFtZXNwYWNlKGN0eHQsIGN1ciwgTlVMTCwgTlVMTCwgb3V0KSk7CisjaWYgMAorCSAgICAvKgorCSAgICAqIFRPRE86IFJlbW92ZWQsIHNpbmNlIHdyb25nLiBJZiB0aGVyZSB3YXMgbm8gZGVmYXVsdAorCSAgICAqIG5hbWVzcGFjZSBpbiB0aGUgc3R5bGVzaGVldCB0aGVuIHRoaXMgbXVzdCByZXNvbHZlIHRvCisJICAgICogdGhlIE5VTEwgbmFtZXNwYWNlLgorCSAgICAqLworCSAgICB4bWxOc1B0ciBkZmx0OwkgICAgCisJICAgIGRmbHQgPSB4bWxTZWFyY2hOcyhjdXItPmRvYywgY3VyLCBOVUxMKTsKKwkgICAgaWYgKGRmbHQgIT0gTlVMTCkKKwkJVVJJID0gZGZsdC0+aHJlZjsKKwkgICAgZWxzZQorCQlyZXR1cm4gTlVMTDsKKyNlbmRpZgorCX0gZWxzZSBpZiAoVVJJID09IE5VTEwpCisJICAgIFVSSSA9IG5zLT5ocmVmOworCisJcmV0dXJuKHhzbHRHZXRTcGVjaWFsTmFtZXNwYWNlKGN0eHQsIGN1ciwgVVJJLCBucy0+cHJlZml4LCBvdXQpKTsKKyAgICB9CisjZW5kaWYKK30KKworLyoqCisgKiB4c2x0R2V0UGxhaW5OYW1lc3BhY2U6CisgKiBAY3R4dDogIGEgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQGN1cjogIHRoZSBpbnB1dCBub2RlCisgKiBAbnM6ICB0aGUgbmFtZXNwYWNlCisgKiBAb3V0OiAgdGhlIHJlc3VsdCBlbGVtZW50CisgKgorICogT2Jzb2xldGUuIAorICogKk5vdCogY2FsbGVkIGJ5IGFueSBMaWJ4c2x0L0xpYmV4c2x0IGZ1bmN0aW9uLgorICogRXhhY2x0eSB0aGUgc2FtZSBhcyB4c2x0R2V0TmFtZXNwYWNlKCkuIAorICoKKyAqIFJldHVybnMgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mCisgKiAgICAgICAgIG5hbWVzcGFjZSBmaXh1cCBmYWlsdXJlcyBvciBBUEkgb3IgaW50ZXJuYWwgZXJyb3JzLgorICovCit4bWxOc1B0cgoreHNsdEdldFBsYWluTmFtZXNwYWNlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgY3VyLAorICAgICAgICAgICAgICAgICAgICAgIHhtbE5zUHRyIG5zLCB4bWxOb2RlUHRyIG91dCkKK3sgICAgCisgICAgcmV0dXJuKHhzbHRHZXROYW1lc3BhY2UoY3R4dCwgY3VyLCBucywgb3V0KSk7Cit9CisKKy8qKgorICogeHNsdENvcHlOYW1lc3BhY2VMaXN0OgorICogQGN0eHQ6ICBhIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBub2RlOiAgdGhlIHRhcmdldCBub2RlCisgKiBAY3VyOiAgdGhlIGZpcnN0IG5hbWVzcGFjZQorICoKKyAqIERvIGEgY29weSBvZiBhbiBuYW1lc3BhY2UgbGlzdC4gSWYgQG5vZGUgaXMgbm9uLU5VTEwgdGhlCisgKiBuZXcgbmFtZXNwYWNlcyBhcmUgYWRkZWQgYXV0b21hdGljYWxseS4gVGhpcyBoYW5kbGVzIG5hbWVzcGFjZXMKKyAqIGFsaWFzZXMuCisgKiBUaGlzIGZ1bmN0aW9uIGlzIGludGVuZGVkIG9ubHkgZm9yICppbnRlcm5hbCogdXNlIGF0CisgKiB0cmFuc2Zvcm1hdGlvbi10aW1lIGZvciBjb3B5aW5nIG5zLWRlY2xhcmF0aW9ucyBvZiBMaXRlcmFsCisgKiBSZXN1bHQgRWxlbWVudHMuCisgKiAKKyAqIENhbGxlZCBieToKKyAqICAgeHNsdENvcHlUcmVlSW50ZXJuYWwoKSAodHJhbnNmb3JtLmMpCisgKiAgIHhzbHRTaGFsbG93Q29weUVsZW0oKSAodHJhbnNmb3JtLmMpCisgKgorICogUkVWSVNJVDogVGhpcyBmdW5jdGlvbiB3b24ndCBiZSB1c2VkIGluIHRoZSByZWZhY3RvcmVkIGNvZGUuCisgKgorICogUmV0dXJuczogYSBuZXcgeG1sTnNQdHIsIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KKyAqLworeG1sTnNQdHIKK3hzbHRDb3B5TmFtZXNwYWNlTGlzdCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJICAgICAgICAgICAgICB4bWxOc1B0ciBjdXIpIHsKKyAgICB4bWxOc1B0ciByZXQgPSBOVUxMLCB0bXA7CisgICAgeG1sTnNQdHIgcCA9IE5VTEwscTsgICAgCisKKyAgICBpZiAoY3VyID09IE5VTEwpCisJcmV0dXJuKE5VTEwpOworICAgIGlmIChjdXItPnR5cGUgIT0gWE1MX05BTUVTUEFDRV9ERUNMKQorCXJldHVybihOVUxMKTsKKworICAgIC8qCisgICAgICogT25lIGNhbiBhZGQgbmFtZXNwYWNlcyBvbmx5IG9uIGVsZW1lbnQgbm9kZXMKKyAgICAgKi8KKyAgICBpZiAoKG5vZGUgIT0gTlVMTCkgJiYgKG5vZGUtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkpCisJbm9kZSA9IE5VTEw7CisKKyAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKKwlpZiAoY3VyLT50eXBlICE9IFhNTF9OQU1FU1BBQ0VfREVDTCkKKwkgICAgYnJlYWs7CisKKwkvKgorCSAqIEF2b2lkIGR1cGxpY2F0aW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHRyZWUgaWYKKwkgKiBhIG1hdGNoaW5nIGRlY2xhcmF0aW9uIGlzIGluIHNjb3BlLgorCSAqLworCWlmIChub2RlICE9IE5VTEwpIHsKKwkgICAgaWYgKChub2RlLT5ucyAhPSBOVUxMKSAmJgorCQkoeG1sU3RyRXF1YWwobm9kZS0+bnMtPnByZWZpeCwgY3VyLT5wcmVmaXgpKSAmJgorICAgICAgICAJKHhtbFN0ckVxdWFsKG5vZGUtPm5zLT5ocmVmLCBjdXItPmhyZWYpKSkgeworCQljdXIgPSBjdXItPm5leHQ7CisJCWNvbnRpbnVlOworCSAgICB9CisJICAgIHRtcCA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgY3VyLT5wcmVmaXgpOworCSAgICBpZiAoKHRtcCAhPSBOVUxMKSAmJiAoeG1sU3RyRXF1YWwodG1wLT5ocmVmLCBjdXItPmhyZWYpKSkgeworCQljdXIgPSBjdXItPm5leHQ7CisJCWNvbnRpbnVlOworCSAgICB9CisJfQorI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCS8qCisJKiBOYW1lc3BhY2UgZXhjbHVzaW9uIGFuZCBucy1hbGlhc2luZyBpcyBwZXJmb3JtZWQgYXQKKwkqIGNvbXBpbGF0aW9uLXRpbWUgaW4gdGhlIHJlZmFjdG9yZWQgY29kZS4KKwkqLworCXEgPSB4bWxOZXdOcyhub2RlLCBjdXItPmhyZWYsIGN1ci0+cHJlZml4KTsKKwlpZiAocCA9PSBOVUxMKSB7CisJICAgIHJldCA9IHAgPSBxOworCX0gZWxzZSB7CisJICAgIHAtPm5leHQgPSBxOworCSAgICBwID0gcTsKKwl9CisjZWxzZQorCS8qCisJKiBUT0RPOiBSZW1vdmUgdGhpcyBpZiB0aGUgcmVmYWN0b3JlZCBjb2RlIGdldHMgZW5hYmxlZC4KKwkqLworCWlmICgheG1sU3RyRXF1YWwoY3VyLT5ocmVmLCBYU0xUX05BTUVTUEFDRSkpIHsKKwkgICAgY29uc3QgeG1sQ2hhciAqVVJJOworCSAgICAvKiBUT0RPIGFwcGx5IGNhc2NhZGluZyAqLworCSAgICBVUkkgPSAoY29uc3QgeG1sQ2hhciAqKSB4bWxIYXNoTG9va3VwKGN0eHQtPnN0eWxlLT5uc0FsaWFzZXMsCisJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXItPmhyZWYpOworCSAgICBpZiAoVVJJID09IFVOREVGSU5FRF9ERUZBVUxUX05TKQorCSAgICAgICAgY29udGludWU7CisJICAgIGlmIChVUkkgIT0gTlVMTCkgeworCQlxID0geG1sTmV3TnMobm9kZSwgVVJJLCBjdXItPnByZWZpeCk7CisJICAgIH0gZWxzZSB7CisJCXEgPSB4bWxOZXdOcyhub2RlLCBjdXItPmhyZWYsIGN1ci0+cHJlZml4KTsKKwkgICAgfQorCSAgICBpZiAocCA9PSBOVUxMKSB7CisJCXJldCA9IHAgPSBxOworCSAgICB9IGVsc2UgeworCQlwLT5uZXh0ID0gcTsKKwkJcCA9IHE7CisJICAgIH0KKwl9CisjZW5kaWYKKwljdXIgPSBjdXItPm5leHQ7CisgICAgfQorICAgIHJldHVybihyZXQpOworfQorCisvKioKKyAqIHhzbHRDb3B5TmFtZXNwYWNlOgorICogQGN0eHQ6ICBhIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBlbGVtOiAgdGhlIHRhcmdldCBlbGVtZW50IG5vZGUKKyAqIEBuczogIHRoZSBuYW1lc3BhY2Ugbm9kZQorICoKKyAqIENvcGllcyBhIG5hbWVzcGFjZSBub2RlIChkZWNsYXJhdGlvbikuIElmIEBlbGVtIGlzIG5vdCBOVUxMLAorICogdGhlbiB0aGUgbmV3IG5hbWVzcGFjZSB3aWxsIGJlIGRlY2xhcmVkIG9uIEBlbGVtLgorICoKKyAqIFJldHVybnM6IGEgbmV3IHhtbE5zUHRyLCBvciBOVUxMIGluIGNhc2Ugb2YgYW4gZXJyb3IuCisgKi8KK3htbE5zUHRyCit4c2x0Q29weU5hbWVzcGFjZSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0IEFUVFJJQlVURV9VTlVTRUQsCisJCSAgeG1sTm9kZVB0ciBlbGVtLCB4bWxOc1B0ciBucykKK3sgICAgCisgICAgaWYgKChucyA9PSBOVUxMKSB8fCAobnMtPnR5cGUgIT0gWE1MX05BTUVTUEFDRV9ERUNMKSkKKwlyZXR1cm4oTlVMTCk7CisgICAgLyoKKyAgICAgKiBPbmUgY2FuIGFkZCBuYW1lc3BhY2VzIG9ubHkgb24gZWxlbWVudCBub2RlcworICAgICAqLworICAgIGlmICgoZWxlbSAhPSBOVUxMKSAmJiAoZWxlbS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSkKKwlyZXR1cm4oeG1sTmV3TnMoTlVMTCwgbnMtPmhyZWYsIG5zLT5wcmVmaXgpKTsKKyAgICBlbHNlCisJcmV0dXJuKHhtbE5ld05zKGVsZW0sIG5zLT5ocmVmLCBucy0+cHJlZml4KSk7Cit9CisKKworLyoqCisgKiB4c2x0RnJlZU5hbWVzcGFjZUFsaWFzSGFzaGVzOgorICogQHN0eWxlOiBhbiBYU0xUIHN0eWxlc2hlZXQKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgdXNlZCBieSBuYW1lc3BhY2VzIGFsaWFzZXMKKyAqLwordm9pZAoreHNsdEZyZWVOYW1lc3BhY2VBbGlhc0hhc2hlcyh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkgeworICAgIGlmIChzdHlsZS0+bnNBbGlhc2VzICE9IE5VTEwpCisJeG1sSGFzaEZyZWUoKHhtbEhhc2hUYWJsZVB0cikgc3R5bGUtPm5zQWxpYXNlcywgTlVMTCk7CisgICAgc3R5bGUtPm5zQWxpYXNlcyA9IE5VTEw7Cit9CmRpZmYgLS1naXQgYS9saWJ4c2x0L25hbWVzcGFjZXMuaCBiL2xpYnhzbHQvbmFtZXNwYWNlcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiZGE1OTYKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L25hbWVzcGFjZXMuaApAQCAtMCwwICsxLDY4IEBACisvKgorICogU3VtbWFyeTogaW50ZXJmYWNlIGZvciB0aGUgWFNMVCBuYW1lc3BhY2UgaGFuZGxpbmcKKyAqIERlc2NyaXB0aW9uOiBzZXQgb2YgZnVuY3Rpb24gZWFzaW5nIHRoZSBwcm9jZXNzaW5nIGFuZCBnZW5lcmF0aW9uCisgKiAgICAgICAgICAgICAgb2YgbmFtZXNwYWNlIG5vZGVzIGluIFhTTFQuCisgKgorICogQ29weTogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIEF1dGhvcjogRGFuaWVsIFZlaWxsYXJkCisgKi8KKworI2lmbmRlZiBfX1hNTF9YU0xUX05BTUVTUEFDRVNfSF9fCisjZGVmaW5lIF9fWE1MX1hTTFRfTkFNRVNQQUNFU19IX18KKworI2luY2x1ZGUgPGxpYnhtbC90cmVlLmg+CisjaW5jbHVkZSAieHNsdGV4cG9ydHMuaCIKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvKgorICogVXNlZCB3aXRoaW4gbnNBbGlhc2VzIGhhc2h0YWJsZSB3aGVuIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSBpcyByZXF1aXJlZAorICogYnV0IGl0J3Mgbm90IGJlZW4gZXhwbGljaXRseSBkZWZpbmVkCisgKi8KKy8qKgorICogVU5ERUZJTkVEX0RFRkFVTFRfTlM6CisgKgorICogU3BlY2lhbCB2YWx1ZSBmb3IgdW5kZWZpbmVkIG5hbWVzcGFjZSwgaW50ZXJuYWwKKyAqLworI2RlZmluZQlVTkRFRklORURfREVGQVVMVF9OUwkoY29uc3QgeG1sQ2hhciAqKSAtMUwKKworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHROYW1lc3BhY2VBbGlhcwkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSB4bWxOb2RlUHRyIG5vZGUpOworWFNMVFBVQkZVTiB4bWxOc1B0ciBYU0xUQ0FMTAkKKwkJeHNsdEdldE5hbWVzcGFjZQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIHhtbE5vZGVQdHIgY3VyLAorCQkJCQkgeG1sTnNQdHIgbnMsCisJCQkJCSB4bWxOb2RlUHRyIG91dCk7CitYU0xUUFVCRlVOIHhtbE5zUHRyIFhTTFRDQUxMCQorCQl4c2x0R2V0UGxhaW5OYW1lc3BhY2UJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCSB4bWxOb2RlUHRyIGN1ciwKKwkJCQkJIHhtbE5zUHRyIG5zLAorCQkJCQkgeG1sTm9kZVB0ciBvdXQpOworWFNMVFBVQkZVTiB4bWxOc1B0ciBYU0xUQ0FMTAkKKwkJeHNsdEdldFNwZWNpYWxOYW1lc3BhY2UJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCSB4bWxOb2RlUHRyIGN1ciwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKlVSSSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKnByZWZpeCwKKwkJCQkJIHhtbE5vZGVQdHIgb3V0KTsKK1hTTFRQVUJGVU4geG1sTnNQdHIgWFNMVENBTEwJCisJCXhzbHRDb3B5TmFtZXNwYWNlCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgeG1sTm9kZVB0ciBlbGVtLAorCQkJCQkgeG1sTnNQdHIgbnMpOworWFNMVFBVQkZVTiB4bWxOc1B0ciBYU0xUQ0FMTAkKKwkJeHNsdENvcHlOYW1lc3BhY2VMaXN0CSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgeG1sTm9kZVB0ciBub2RlLAorCQkJCQkgeG1sTnNQdHIgY3VyKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisJCXhzbHRGcmVlTmFtZXNwYWNlQWxpYXNIYXNoZXMKKwkJCQkJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9CisjZW5kaWYKKworI2VuZGlmIC8qIF9fWE1MX1hTTFRfTkFNRVNQQUNFU19IX18gKi8KKwpkaWZmIC0tZ2l0IGEvbGlieHNsdC9udW1iZXJzLmMgYi9saWJ4c2x0L251bWJlcnMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjgzY2E4Ci0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9udW1iZXJzLmMKQEAgLTAsMCArMSwxMzUxIEBACisvKgorICogbnVtYmVycy5jOiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgWFNMVCBudW1iZXIgZnVuY3Rpb25zCisgKgorICogUmVmZXJlbmNlOgorICogICBodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy14c2x0LTE5OTkxMTE2CisgKgorICogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIGRhbmllbEB2ZWlsbGFyZC5jb20KKyAqIEJqb3JuIFJlZXNlIDxicmVlc2VAdXNlcnMuc291cmNlZm9yZ2UubmV0PgorICovCisKKyNkZWZpbmUgSU5fTElCWFNMVAorI2luY2x1ZGUgImxpYnhzbHQuaCIKKworI2luY2x1ZGUgPG1hdGguaD4KKyNpbmNsdWRlIDxsaW1pdHMuaD4KKyNpbmNsdWRlIDxmbG9hdC5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCisjaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgorI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KKyNpbmNsdWRlIDxsaWJ4bWwveHBhdGguaD4KKyNpbmNsdWRlIDxsaWJ4bWwveHBhdGhJbnRlcm5hbHMuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvZW5jb2RpbmcuaD4KKyNpbmNsdWRlICJ4c2x0dXRpbHMuaCIKKyNpbmNsdWRlICJwYXR0ZXJuLmgiCisjaW5jbHVkZSAidGVtcGxhdGVzLmgiCisjaW5jbHVkZSAidHJhbnNmb3JtLmgiCisjaW5jbHVkZSAibnVtYmVyc0ludGVybmFscy5oIgorCisjaWZuZGVmIEZBTFNFCisjIGRlZmluZSBGQUxTRSAoMCA9PSAxKQorIyBkZWZpbmUgVFJVRSAoMSA9PSAxKQorI2VuZGlmCisKKyNkZWZpbmUgU1lNQk9MX1FVT1RFCQkoKHhtbENoYXIpJ1wnJykKKworI2RlZmluZSBERUZBVUxUX1RPS0VOCQkoeG1sQ2hhciknMCcKKyNkZWZpbmUgREVGQVVMVF9TRVBBUkFUT1IJIi4iCisKKyNkZWZpbmUgTUFYX1RPS0VOUwkJMTAyNAorCit0eXBlZGVmIHN0cnVjdCBfeHNsdEZvcm1hdFRva2VuIHhzbHRGb3JtYXRUb2tlbjsKK3R5cGVkZWYgeHNsdEZvcm1hdFRva2VuICp4c2x0Rm9ybWF0VG9rZW5QdHI7CitzdHJ1Y3QgX3hzbHRGb3JtYXRUb2tlbiB7CisgICAgeG1sQ2hhcgkqc2VwYXJhdG9yOworICAgIHhtbENoYXIJIHRva2VuOworICAgIGludAkJIHdpZHRoOworfTsKKwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRGb3JtYXQgeHNsdEZvcm1hdDsKK3R5cGVkZWYgeHNsdEZvcm1hdCAqeHNsdEZvcm1hdFB0cjsKK3N0cnVjdCBfeHNsdEZvcm1hdCB7CisgICAgeG1sQ2hhcgkJKnN0YXJ0OworICAgIHhzbHRGb3JtYXRUb2tlbgkgdG9rZW5zW01BWF9UT0tFTlNdOworICAgIGludAkJCSBuVG9rZW5zOworICAgIHhtbENoYXIJCSplbmQ7Cit9OworCitzdGF0aWMgY2hhciBhbHBoYV91cHBlcl9saXN0W10gPSAiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiOworc3RhdGljIGNoYXIgYWxwaGFfbG93ZXJfbGlzdFtdID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6IjsKK3N0YXRpYyB4c2x0Rm9ybWF0VG9rZW4gZGVmYXVsdF90b2tlbjsKKworLyoKKyAqICoqKiogU3RhcnQgdGVtcCBpbnNlcnQgKioqKgorICoKKyAqIFRoZSBmb2xsb3dpbmcgdHdvIHJvdXRpbmVzICh4c2x0VVRGOFNpemUgYW5kIHhzbHRVVEY4Q2hhcmNtcCkKKyAqIHdpbGwgYmUgcmVwbGFjZWQgd2l0aCBjYWxscyB0byB0aGUgY29ycmVzcG9uZGluZyBsaWJ4bWwgcm91dGluZXMKKyAqIGF0IGEgbGF0ZXIgZGF0ZSAod2hlbiBvdGhlciBpbnRlci1saWJyYXJ5IGRlcGVuZGVuY2llcyByZXF1aXJlIGl0KQorICovCisKKy8qKgorICogeHNsdFVURjhTaXplOgorICogQHV0ZjogcG9pbnRlciB0byB0aGUgVVRGOCBjaGFyYWN0ZXIKKyAqCisgKiByZXR1cm5zIHRoZSBudW1iZXJzIG9mIGJ5dGVzIGluIHRoZSBjaGFyYWN0ZXIsIC0xIG9uIGZvcm1hdCBlcnJvcgorICovCitzdGF0aWMgaW50Cit4c2x0VVRGOFNpemUoeG1sQ2hhciAqdXRmKSB7CisgICAgeG1sQ2hhciBtYXNrOworICAgIGludCBsZW47CisKKyAgICBpZiAodXRmID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoKnV0ZiA8IDB4ODApCisgICAgICAgIHJldHVybiAxOworICAgIC8qIGNoZWNrIHZhbGlkIFVURjggY2hhcmFjdGVyICovCisgICAgaWYgKCEoKnV0ZiAmIDB4NDApKQorICAgICAgICByZXR1cm4gLTE7CisgICAgLyogZGV0ZXJtaW5lIG51bWJlciBvZiBieXRlcyBpbiBjaGFyICovCisgICAgbGVuID0gMjsKKyAgICBmb3IgKG1hc2s9MHgyMDsgbWFzayAhPSAwOyBtYXNrPj49MSkgeworICAgICAgICBpZiAoISgqdXRmICYgbWFzaykpCisgICAgICAgICAgICByZXR1cm4gbGVuOworICAgICAgICBsZW4rKzsKKyAgICB9CisgICAgcmV0dXJuIC0xOworfQorCisvKioKKyAqIHhzbHRVVEY4Q2hhcmNtcAorICogQHV0ZjE6IHBvaW50ZXIgdG8gZmlyc3QgVVRGOCBjaGFyCisgKiBAdXRmMjogcG9pbnRlciB0byBzZWNvbmQgVVRGOCBjaGFyCisgKgorICogcmV0dXJucyByZXN1bHQgb2YgY29tcGFyaW5nIHRoZSB0d28gVUNTNCB2YWx1ZXMKKyAqIGFzIHdpdGggeG1sU3RybmNtcAorICovCitzdGF0aWMgaW50Cit4c2x0VVRGOENoYXJjbXAoeG1sQ2hhciAqdXRmMSwgeG1sQ2hhciAqdXRmMikgeworCisgICAgaWYgKHV0ZjEgPT0gTlVMTCApIHsKKyAgICAgICAgaWYgKHV0ZjIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiB4bWxTdHJuY21wKHV0ZjEsIHV0ZjIsIHhzbHRVVEY4U2l6ZSh1dGYxKSk7Cit9CisKKy8qKioqKiBTdG9wIHRlbXAgaW5zZXJ0ICoqKioqLworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJCVV0aWxpdHkgZnVuY3Rpb25zCQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworI2RlZmluZSBJU19TUEVDSUFMKHNlbGYsbGV0dGVyKQkJCVwKKyAgICAoKHhzbHRVVEY4Q2hhcmNtcCgobGV0dGVyKSwgKHNlbGYpLT56ZXJvRGlnaXQpID09IDApCSAgICB8fAlcCisgICAgICh4c2x0VVRGOENoYXJjbXAoKGxldHRlciksIChzZWxmKS0+ZGlnaXQpID09IDApCSAgICB8fAlcCisgICAgICh4c2x0VVRGOENoYXJjbXAoKGxldHRlciksIChzZWxmKS0+ZGVjaW1hbFBvaW50KSA9PSAwKSAgfHwJXAorICAgICAoeHNsdFVURjhDaGFyY21wKChsZXR0ZXIpLCAoc2VsZiktPmdyb3VwaW5nKSA9PSAwKQkgICAgfHwJXAorICAgICAoeHNsdFVURjhDaGFyY21wKChsZXR0ZXIpLCAoc2VsZiktPnBhdHRlcm5TZXBhcmF0b3IpID09IDApKQorCisjZGVmaW5lIElTX0RJR0lUX1pFUk8oeCkgeHNsdElzRGlnaXRaZXJvKHgpCisjZGVmaW5lIElTX0RJR0lUX09ORSh4KSB4c2x0SXNEaWdpdFplcm8oKHhtbENoYXIpKHgpLTEpCisKK3N0YXRpYyBpbnQKK3hzbHRJc0RpZ2l0WmVybyh1bnNpZ25lZCBpbnQgY2gpCit7CisgICAgLyoKKyAgICAgKiBSZWZlcmVuY2U6IGZ0cDovL2Z0cC51bmljb2RlLm9yZy9QdWJsaWMvVU5JREFUQS9Vbmljb2RlRGF0YS50eHQKKyAgICAgKi8KKyAgICBzd2l0Y2ggKGNoKSB7CisgICAgY2FzZSAweDAwMzA6IGNhc2UgMHgwNjYwOiBjYXNlIDB4MDZGMDogY2FzZSAweDA5NjY6CisgICAgY2FzZSAweDA5RTY6IGNhc2UgMHgwQTY2OiBjYXNlIDB4MEFFNjogY2FzZSAweDBCNjY6CisgICAgY2FzZSAweDBDNjY6IGNhc2UgMHgwQ0U2OiBjYXNlIDB4MEQ2NjogY2FzZSAweDBFNTA6CisgICAgY2FzZSAweDBFNjA6IGNhc2UgMHgwRjIwOiBjYXNlIDB4MTA0MDogY2FzZSAweDE3RTA6CisgICAgY2FzZSAweDE4MTA6IGNhc2UgMHhGRjEwOgorCXJldHVybiBUUlVFOworICAgIGRlZmF1bHQ6CisJcmV0dXJuIEZBTFNFOworICAgIH0KK30KKworc3RhdGljIHZvaWQKK3hzbHROdW1iZXJGb3JtYXREZWNpbWFsKHhtbEJ1ZmZlclB0ciBidWZmZXIsCisJCQlkb3VibGUgbnVtYmVyLAorCQkJaW50IGRpZ2l0X3plcm8sCisJCQlpbnQgd2lkdGgsCisJCQlpbnQgZGlnaXRzUGVyR3JvdXAsCisJCQlpbnQgZ3JvdXBpbmdDaGFyYWN0ZXIsCisJCQlpbnQgZ3JvdXBpbmdDaGFyYWN0ZXJMZW4pCit7CisgICAgLyoKKyAgICAgKiBUaGlzIHVzZWQgdG8gYmUKKyAgICAgKiAgeG1sQ2hhciB0ZW1wX3N0cmluZ1tzaXplb2YoZG91YmxlKSAqIENIQVJfQklUICogc2l6ZW9mKHhtbENoYXIpICsgNF07CisgICAgICogd2hpY2ggd291bGQgYmUgbGVuZ3RoIDY4IG9uIHg4NiBhcmNoLiAgSXQgd2FzIGNoYW5nZWQgdG8gYmUgYSBsb25nZXIsCisgICAgICogZml4ZWQgbGVuZ3RoIGluIG9yZGVyIHRvIHRyeSB0byBjYXRlciBmb3IgKHJlYXNvbmFibGUpIFVURjgKKyAgICAgKiBzZXBhcmF0b3JzIGFuZCBudW1lcmljIGNoYXJhY3RlcnMuICBUaGUgbWF4IFVURjggY2hhciBzaXplIHdpbGwgYmUKKyAgICAgKiA2IG9yIGxlc3MsIHNvIHRoZSB2YWx1ZSB1c2VkIFs1MDBdIHNob3VsZCBiZSAqbXVjaCogbGFyZ2VyIHRoYW4gbmVlZGVkCisgICAgICovCisgICAgeG1sQ2hhciB0ZW1wX3N0cmluZ1s1MDBdOworICAgIHhtbENoYXIgKnBvaW50ZXI7CisgICAgeG1sQ2hhciB0ZW1wX2NoYXJbNl07CisgICAgaW50IGk7CisgICAgaW50IHZhbDsKKyAgICBpbnQgbGVuOworCisgICAgLyogQnVpbGQgYnVmZmVyIGZyb20gYmFjayAqLworICAgIHBvaW50ZXIgPSAmdGVtcF9zdHJpbmdbc2l6ZW9mKHRlbXBfc3RyaW5nKV0gLSAxOwkvKiBsYXN0IGNoYXIgKi8KKyAgICAqcG9pbnRlciA9IDA7CisgICAgaSA9IDA7CisgICAgd2hpbGUgKHBvaW50ZXIgPiB0ZW1wX3N0cmluZykgeworCWlmICgoaSA+PSB3aWR0aCkgJiYgKGZhYnMobnVtYmVyKSA8IDEuMCkpCisJICAgIGJyZWFrOyAvKiBmb3IgKi8KKwlpZiAoKGkgPiAwKSAmJiAoZ3JvdXBpbmdDaGFyYWN0ZXIgIT0gMCkgJiYKKwkgICAgKGRpZ2l0c1Blckdyb3VwID4gMCkgJiYKKwkgICAgKChpICUgZGlnaXRzUGVyR3JvdXApID09IDApKSB7CisJICAgIGlmIChwb2ludGVyIC0gZ3JvdXBpbmdDaGFyYWN0ZXJMZW4gPCB0ZW1wX3N0cmluZykgeworCSAgICAgICAgaSA9IC0xOwkJLyogZmxhZyBlcnJvciAqLworCQlicmVhazsKKwkgICAgfQorCSAgICBwb2ludGVyIC09IGdyb3VwaW5nQ2hhcmFjdGVyTGVuOworCSAgICB4bWxDb3B5Q2hhck11bHRpQnl0ZShwb2ludGVyLCBncm91cGluZ0NoYXJhY3Rlcik7CisJfQorCQorCXZhbCA9IGRpZ2l0X3plcm8gKyAoaW50KWZtb2QobnVtYmVyLCAxMC4wKTsKKwlpZiAodmFsIDwgMHg4MCkgewkJCS8qIHNob3J0Y3V0IGlmIEFTQ0lJICovCisJICAgIGlmIChwb2ludGVyIDw9IHRlbXBfc3RyaW5nKSB7CS8qIENoZWNrIGVub3VnaCByb29tICovCisJICAgICAgICBpID0gLTE7CisJCWJyZWFrOworCSAgICB9CisJICAgICooLS1wb2ludGVyKSA9IHZhbDsKKwl9CisJZWxzZSB7CisJLyogCisJICogSGVyZSB3ZSBoYXZlIGEgbXVsdGlieXRlIGNoYXJhY3Rlci4gIEl0J3MgYSBsaXR0bGUgbWVzc3ksCisJICogYmVjYXVzZSB1bnRpbCB3ZSBnZW5lcmF0ZSB0aGUgY2hhciB3ZSBkb24ndCBrbm93IGhvdyBsb25nCisJICogaXQgaXMuICBTbywgd2UgZ2VuZXJhdGUgaXQgaW50byB0aGUgYnVmZmVyIHRlbXBfY2hhciwgdGhlbgorCSAqIGNvcHkgZnJvbSB0aGVyZSBpbnRvIHRlbXBfc3RyaW5nLgorCSAqLworCSAgICBsZW4gPSB4bWxDb3B5Q2hhck11bHRpQnl0ZSh0ZW1wX2NoYXIsIHZhbCk7CisJICAgIGlmICggKHBvaW50ZXIgLSBsZW4pIDwgdGVtcF9zdHJpbmcgKSB7CisJICAgICAgICBpID0gLTE7CisJCWJyZWFrOworCSAgICB9CisJICAgIHBvaW50ZXIgLT0gbGVuOworCSAgICBtZW1jcHkocG9pbnRlciwgdGVtcF9jaGFyLCBsZW4pOworCX0KKwludW1iZXIgLz0gMTAuMDsKKwkrK2k7CisgICAgfQorICAgIGlmIChpIDwgMCkKKyAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkJInhzbHROdW1iZXJGb3JtYXREZWNpbWFsOiBJbnRlcm5hbCBidWZmZXIgc2l6ZSBleGNlZWRlZCIpOworICAgIHhtbEJ1ZmZlckNhdChidWZmZXIsIHBvaW50ZXIpOworfQorCitzdGF0aWMgdm9pZAoreHNsdE51bWJlckZvcm1hdEFscGhhKHhtbEJ1ZmZlclB0ciBidWZmZXIsCisJCSAgICAgIGRvdWJsZSBudW1iZXIsCisJCSAgICAgIGludCBpc191cHBlcikKK3sKKyAgICBjaGFyIHRlbXBfc3RyaW5nW3NpemVvZihkb3VibGUpICogQ0hBUl9CSVQgKiBzaXplb2YoeG1sQ2hhcikgKyAxXTsKKyAgICBjaGFyICpwb2ludGVyOworICAgIGludCBpOworICAgIGNoYXIgKmFscGhhX2xpc3Q7CisgICAgZG91YmxlIGFscGhhX3NpemUgPSAoZG91YmxlKShzaXplb2YoYWxwaGFfdXBwZXJfbGlzdCkgLSAxKTsKKworICAgIC8qIEJ1aWxkIGJ1ZmZlciBmcm9tIGJhY2sgKi8KKyAgICBwb2ludGVyID0gJnRlbXBfc3RyaW5nW3NpemVvZih0ZW1wX3N0cmluZyldOworICAgICooLS1wb2ludGVyKSA9IDA7CisgICAgYWxwaGFfbGlzdCA9IChpc191cHBlcikgPyBhbHBoYV91cHBlcl9saXN0IDogYWxwaGFfbG93ZXJfbGlzdDsKKyAgICAKKyAgICBmb3IgKGkgPSAxOyBpIDwgKGludClzaXplb2YodGVtcF9zdHJpbmcpOyBpKyspIHsKKwludW1iZXItLTsKKwkqKC0tcG9pbnRlcikgPSBhbHBoYV9saXN0WygoaW50KWZtb2QobnVtYmVyLCBhbHBoYV9zaXplKSldOworCW51bWJlciAvPSBhbHBoYV9zaXplOworCWlmIChmYWJzKG51bWJlcikgPCAxLjApCisJICAgIGJyZWFrOyAvKiBmb3IgKi8KKyAgICB9CisgICAgeG1sQnVmZmVyQ0NhdChidWZmZXIsIHBvaW50ZXIpOworfQorCitzdGF0aWMgdm9pZAoreHNsdE51bWJlckZvcm1hdFJvbWFuKHhtbEJ1ZmZlclB0ciBidWZmZXIsCisJCSAgICAgIGRvdWJsZSBudW1iZXIsCisJCSAgICAgIGludCBpc191cHBlcikKK3sKKyAgICAvKgorICAgICAqIEJhc2VkIG9uIGFuIGV4YW1wbGUgYnkgSmltIFdhbHNoCisgICAgICovCisgICAgd2hpbGUgKG51bWJlciA+PSAxMDAwLjApIHsKKwl4bWxCdWZmZXJDQ2F0KGJ1ZmZlciwgKGlzX3VwcGVyKSA/ICJNIiA6ICJtIik7CisJbnVtYmVyIC09IDEwMDAuMDsKKyAgICB9CisgICAgaWYgKG51bWJlciA+PSA5MDAuMCkgeworCXhtbEJ1ZmZlckNDYXQoYnVmZmVyLCAoaXNfdXBwZXIpID8gIkNNIiA6ICJjbSIpOworCW51bWJlciAtPSA5MDAuMDsKKyAgICB9CisgICAgd2hpbGUgKG51bWJlciA+PSA1MDAuMCkgeworCXhtbEJ1ZmZlckNDYXQoYnVmZmVyLCAoaXNfdXBwZXIpID8gIkQiIDogImQiKTsKKwludW1iZXIgLT0gNTAwLjA7CisgICAgfQorICAgIGlmIChudW1iZXIgPj0gNDAwLjApIHsKKwl4bWxCdWZmZXJDQ2F0KGJ1ZmZlciwgKGlzX3VwcGVyKSA/ICJDRCIgOiAiY2QiKTsKKwludW1iZXIgLT0gNDAwLjA7CisgICAgfQorICAgIHdoaWxlIChudW1iZXIgPj0gMTAwLjApIHsKKwl4bWxCdWZmZXJDQ2F0KGJ1ZmZlciwgKGlzX3VwcGVyKSA/ICJDIiA6ICJjIik7CisJbnVtYmVyIC09IDEwMC4wOworICAgIH0KKyAgICBpZiAobnVtYmVyID49IDkwLjApIHsKKwl4bWxCdWZmZXJDQ2F0KGJ1ZmZlciwgKGlzX3VwcGVyKSA/ICJYQyIgOiAieGMiKTsKKwludW1iZXIgLT0gOTAuMDsKKyAgICB9CisgICAgd2hpbGUgKG51bWJlciA+PSA1MC4wKSB7CisJeG1sQnVmZmVyQ0NhdChidWZmZXIsIChpc191cHBlcikgPyAiTCIgOiAibCIpOworCW51bWJlciAtPSA1MC4wOworICAgIH0KKyAgICBpZiAobnVtYmVyID49IDQwLjApIHsKKwl4bWxCdWZmZXJDQ2F0KGJ1ZmZlciwgKGlzX3VwcGVyKSA/ICJYTCIgOiAieGwiKTsKKwludW1iZXIgLT0gNDAuMDsKKyAgICB9CisgICAgd2hpbGUgKG51bWJlciA+PSAxMC4wKSB7CisJeG1sQnVmZmVyQ0NhdChidWZmZXIsIChpc191cHBlcikgPyAiWCIgOiAieCIpOworCW51bWJlciAtPSAxMC4wOworICAgIH0KKyAgICBpZiAobnVtYmVyID49IDkuMCkgeworCXhtbEJ1ZmZlckNDYXQoYnVmZmVyLCAoaXNfdXBwZXIpID8gIklYIiA6ICJpeCIpOworCW51bWJlciAtPSA5LjA7CisgICAgfQorICAgIHdoaWxlIChudW1iZXIgPj0gNS4wKSB7CisJeG1sQnVmZmVyQ0NhdChidWZmZXIsIChpc191cHBlcikgPyAiViIgOiAidiIpOworCW51bWJlciAtPSA1LjA7CisgICAgfQorICAgIGlmIChudW1iZXIgPj0gNC4wKSB7CisJeG1sQnVmZmVyQ0NhdChidWZmZXIsIChpc191cHBlcikgPyAiSVYiIDogIml2Iik7CisJbnVtYmVyIC09IDQuMDsKKyAgICB9CisgICAgd2hpbGUgKG51bWJlciA+PSAxLjApIHsKKwl4bWxCdWZmZXJDQ2F0KGJ1ZmZlciwgKGlzX3VwcGVyKSA/ICJJIiA6ICJpIik7CisJbnVtYmVyLS07CisgICAgfQorfQorCitzdGF0aWMgdm9pZAoreHNsdE51bWJlckZvcm1hdFRva2VuaXplKGNvbnN0IHhtbENoYXIgKmZvcm1hdCwKKwkJCSB4c2x0Rm9ybWF0UHRyIHRva2VucykKK3sKKyAgICBpbnQgaXggPSAwOworICAgIGludCBqOworICAgIGludCB2YWw7CisgICAgaW50IGxlbjsKKworICAgIGRlZmF1bHRfdG9rZW4udG9rZW4gPSBERUZBVUxUX1RPS0VOOworICAgIGRlZmF1bHRfdG9rZW4ud2lkdGggPSAxOworICAgIGRlZmF1bHRfdG9rZW4uc2VwYXJhdG9yID0gQkFEX0NBU1QoREVGQVVMVF9TRVBBUkFUT1IpOworCisKKyAgICB0b2tlbnMtPnN0YXJ0ID0gTlVMTDsKKyAgICB0b2tlbnMtPnRva2Vuc1swXS5zZXBhcmF0b3IgPSBOVUxMOworICAgIHRva2Vucy0+ZW5kID0gTlVMTDsKKworICAgIC8qCisgICAgICogSW5zZXJ0IGluaXRpYWwgbm9uLWFscGhhbnVtZXJpYyB0b2tlbi4KKyAgICAgKiBUaGVyZSBpcyBhbHdheXMgc3VjaCBhIHRva2VuIGluIHRoZSBsaXN0LCBldmVuIGlmIE5VTEwKKyAgICAgKi8KKyAgICB3aGlsZSAoISAoSVNfTEVUVEVSKHZhbD14bWxTdHJpbmdDdXJyZW50Q2hhcihOVUxMLCBmb3JtYXQraXgsICZsZW4pKSB8fAorICAgIAkgICAgICBJU19ESUdJVCh2YWwpKSApIHsKKwlpZiAoZm9ybWF0W2l4XSA9PSAwKQkJLyogaWYgZW5kIG9mIGZvcm1hdCBzdHJpbmcgKi8KKwkgICAgYnJlYWs7IC8qIHdoaWxlICovCisJaXggKz0gbGVuOworICAgIH0KKyAgICBpZiAoaXggPiAwKQorCXRva2Vucy0+c3RhcnQgPSB4bWxTdHJuZHVwKGZvcm1hdCwgaXgpOworCisKKyAgICBmb3IgKHRva2Vucy0+blRva2VucyA9IDA7IHRva2Vucy0+blRva2VucyA8IE1BWF9UT0tFTlM7CisJIHRva2Vucy0+blRva2VucysrKSB7CisJaWYgKGZvcm1hdFtpeF0gPT0gMCkKKwkgICAgYnJlYWs7IC8qIGZvciAqLworCisJLyoKKwkgKiBzZXBhcmF0b3IgaGFzIGFscmVhZHkgYmVlbiBwYXJzZWQgKGV4Y2VwdCBmb3IgdGhlIGZpcnN0CisJICogbnVtYmVyKSBpbiB0b2tlbnMtPmVuZCwgcmVjb3ZlciBpdC4KKwkgKi8KKwlpZiAodG9rZW5zLT5uVG9rZW5zID4gMCkgeworCSAgICB0b2tlbnMtPnRva2Vuc1t0b2tlbnMtPm5Ub2tlbnNdLnNlcGFyYXRvciA9IHRva2Vucy0+ZW5kOworCSAgICB0b2tlbnMtPmVuZCA9IE5VTEw7CisJfQorCisJdmFsID0geG1sU3RyaW5nQ3VycmVudENoYXIoTlVMTCwgZm9ybWF0K2l4LCAmbGVuKTsKKwlpZiAoSVNfRElHSVRfT05FKHZhbCkgfHwKKwkJIElTX0RJR0lUX1pFUk8odmFsKSkgeworCSAgICB0b2tlbnMtPnRva2Vuc1t0b2tlbnMtPm5Ub2tlbnNdLndpZHRoID0gMTsKKwkgICAgd2hpbGUgKElTX0RJR0lUX1pFUk8odmFsKSkgeworCQl0b2tlbnMtPnRva2Vuc1t0b2tlbnMtPm5Ub2tlbnNdLndpZHRoKys7CisJCWl4ICs9IGxlbjsKKwkJdmFsID0geG1sU3RyaW5nQ3VycmVudENoYXIoTlVMTCwgZm9ybWF0K2l4LCAmbGVuKTsKKwkgICAgfQorCSAgICBpZiAoSVNfRElHSVRfT05FKHZhbCkpIHsKKwkJdG9rZW5zLT50b2tlbnNbdG9rZW5zLT5uVG9rZW5zXS50b2tlbiA9IHZhbCAtIDE7CisJCWl4ICs9IGxlbjsKKwkJdmFsID0geG1sU3RyaW5nQ3VycmVudENoYXIoTlVMTCwgZm9ybWF0K2l4LCAmbGVuKTsKKwkgICAgfQorCX0gZWxzZSBpZiAoICh2YWwgPT0gKHhtbENoYXIpJ0EnKSB8fAorCQkgICAgKHZhbCA9PSAoeG1sQ2hhciknYScpIHx8CisJCSAgICAodmFsID09ICh4bWxDaGFyKSdJJykgfHwKKwkJICAgICh2YWwgPT0gKHhtbENoYXIpJ2knKSApIHsKKwkgICAgdG9rZW5zLT50b2tlbnNbdG9rZW5zLT5uVG9rZW5zXS50b2tlbiA9IHZhbDsKKwkgICAgaXggKz0gbGVuOworCSAgICB2YWwgPSB4bWxTdHJpbmdDdXJyZW50Q2hhcihOVUxMLCBmb3JtYXQraXgsICZsZW4pOworCX0gZWxzZSB7CisJICAgIC8qIFhTTFQgc2VjdGlvbiA3LjcKKwkgICAgICogIkFueSBvdGhlciBmb3JtYXQgdG9rZW4gaW5kaWNhdGVzIGEgbnVtYmVyaW5nIHNlcXVlbmNlCisJICAgICAqICB0aGF0IHN0YXJ0cyB3aXRoIHRoYXQgdG9rZW4uIElmIGFuIGltcGxlbWVudGF0aW9uIGRvZXMKKwkgICAgICogIG5vdCBzdXBwb3J0IGEgbnVtYmVyaW5nIHNlcXVlbmNlIHRoYXQgc3RhcnRzIHdpdGggdGhhdAorCSAgICAgKiAgdG9rZW4sIGl0IG11c3QgdXNlIGEgZm9ybWF0IHRva2VuIG9mIDEuIgorCSAgICAgKi8KKwkgICAgdG9rZW5zLT50b2tlbnNbdG9rZW5zLT5uVG9rZW5zXS50b2tlbiA9ICh4bWxDaGFyKScwJzsKKwkgICAgdG9rZW5zLT50b2tlbnNbdG9rZW5zLT5uVG9rZW5zXS53aWR0aCA9IDE7CisJfQorCS8qCisJICogU2tpcCBvdmVyIHJlbWFpbmluZyBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBmcm9tIHRoZSBOZAorCSAqIChOdW1iZXIsIGRlY2ltYWwgZGlnaXQpLCBObCAoTnVtYmVyLCBsZXR0ZXIpLCBObyAoTnVtYmVyLAorCSAqIG90aGVyKSwgTHUgKExldHRlciwgdXBwZXJjYXNlKSwgTGwgKExldHRlciwgbG93ZXJjYXNlKSwgTHQKKwkgKiAoTGV0dGVycywgdGl0bGVjYXNlKSwgTG0gKExldHRlcnMsIG1vZGlmaWVycyksIGFuZCBMbworCSAqIChMZXR0ZXJzLCBvdGhlciAodW5jYXNlZCkpIFVuaWNvZGUgY2F0ZWdvcmllcy4gVGhpcyBoYXBwZW5zCisJICogdG8gY29ycmVzcG9uZCB0byB0aGUgTGV0dGVyIGFuZCBEaWdpdCBjbGFzc2VzIGZyb20gWE1MIChhbmQKKwkgKiBvbmUgd29uZGVycyB3aHkgWFNMVCBkb2Vzbid0IHJlZmVyIHRvIHRoZXNlIGluc3RlYWQpLgorCSAqLworCXdoaWxlIChJU19MRVRURVIodmFsKSB8fCBJU19ESUdJVCh2YWwpKSB7CisJICAgIGl4ICs9IGxlbjsKKwkgICAgdmFsID0geG1sU3RyaW5nQ3VycmVudENoYXIoTlVMTCwgZm9ybWF0K2l4LCAmbGVuKTsKKwl9CisKKwkvKgorCSAqIEluc2VydCB0ZW1wb3Jhcnkgbm9uLWFscGhhbnVtZXJpYyBmaW5hbCB0b29rZW4uCisJICovCisJaiA9IGl4OworCXdoaWxlICghIChJU19MRVRURVIodmFsKSB8fCBJU19ESUdJVCh2YWwpKSkgeworCSAgICBpZiAodmFsID09IDApCisJCWJyZWFrOyAvKiB3aGlsZSAqLworCSAgICBpeCArPSBsZW47CisJICAgIHZhbCA9IHhtbFN0cmluZ0N1cnJlbnRDaGFyKE5VTEwsIGZvcm1hdCtpeCwgJmxlbik7CisJfQorCWlmIChpeCA+IGopCisJICAgIHRva2Vucy0+ZW5kID0geG1sU3RybmR1cCgmZm9ybWF0W2pdLCBpeCAtIGopOworICAgIH0KK30KKworc3RhdGljIHZvaWQKK3hzbHROdW1iZXJGb3JtYXRJbnNlcnROdW1iZXJzKHhzbHROdW1iZXJEYXRhUHRyIGRhdGEsCisJCQkgICAgICBkb3VibGUgKm51bWJlcnMsCisJCQkgICAgICBpbnQgbnVtYmVyc19tYXgsCisJCQkgICAgICB4c2x0Rm9ybWF0UHRyIHRva2VucywKKwkJCSAgICAgIHhtbEJ1ZmZlclB0ciBidWZmZXIpCit7CisgICAgaW50IGkgPSAwOworICAgIGRvdWJsZSBudW1iZXI7CisgICAgeHNsdEZvcm1hdFRva2VuUHRyIHRva2VuOworCisgICAgLyoKKyAgICAgKiBIYW5kbGUgaW5pdGlhbCBub24tYWxwaGFudW1lcmljIHRva2VuCisgICAgICovCisgICAgaWYgKHRva2Vucy0+c3RhcnQgIT0gTlVMTCkKKwkgeG1sQnVmZmVyQ2F0KGJ1ZmZlciwgdG9rZW5zLT5zdGFydCk7CisKKyAgICBmb3IgKGkgPSAwOyBpIDwgbnVtYmVyc19tYXg7IGkrKykgeworCS8qIEluc2VydCBudW1iZXIgKi8KKwludW1iZXIgPSBudW1iZXJzWyhudW1iZXJzX21heCAtIDEpIC0gaV07CisJaWYgKGkgPCB0b2tlbnMtPm5Ub2tlbnMpIHsKKwkgIC8qCisJICAgKiBUaGUgIm4idGggZm9ybWF0IHRva2VuIHdpbGwgYmUgdXNlZCB0byBmb3JtYXQgdGhlICJuInRoCisJICAgKiBudW1iZXIgaW4gdGhlIGxpc3QKKwkgICAqLworCSAgdG9rZW4gPSAmKHRva2Vucy0+dG9rZW5zW2ldKTsKKwl9IGVsc2UgaWYgKHRva2Vucy0+blRva2VucyA+IDApIHsKKwkgIC8qCisJICAgKiBJZiB0aGVyZSBhcmUgbW9yZSBudW1iZXJzIHRoYW4gZm9ybWF0IHRva2VucywgdGhlbiB0aGUKKwkgICAqIGxhc3QgZm9ybWF0IHRva2VuIHdpbGwgYmUgdXNlZCB0byBmb3JtYXQgdGhlIHJlbWFpbmluZworCSAgICogbnVtYmVycy4KKwkgICAqLworCSAgdG9rZW4gPSAmKHRva2Vucy0+dG9rZW5zW3Rva2Vucy0+blRva2VucyAtIDFdKTsKKwl9IGVsc2UgeworCSAgLyoKKwkgICAqIElmIHRoZXJlIGFyZSBubyBmb3JtYXQgdG9rZW5zLCB0aGVuIGEgZm9ybWF0IHRva2VuIG9mCisJICAgKiAxIGlzIHVzZWQgdG8gZm9ybWF0IGFsbCBudW1iZXJzLgorCSAgICovCisJICB0b2tlbiA9ICZkZWZhdWx0X3Rva2VuOworCX0KKworCS8qIFByaW50IHNlcGFyYXRvciwgZXhjZXB0IGZvciB0aGUgZmlyc3QgbnVtYmVyICovCisJaWYgKGkgPiAwKSB7CisJICAgIGlmICh0b2tlbi0+c2VwYXJhdG9yICE9IE5VTEwpCisJCXhtbEJ1ZmZlckNhdChidWZmZXIsIHRva2VuLT5zZXBhcmF0b3IpOworCSAgICBlbHNlCisJCXhtbEJ1ZmZlckNDYXQoYnVmZmVyLCBERUZBVUxUX1NFUEFSQVRPUik7CisJfQorCisJc3dpdGNoICh4bWxYUGF0aElzSW5mKG51bWJlcikpIHsKKwljYXNlIC0xOgorCSAgICB4bWxCdWZmZXJDQ2F0KGJ1ZmZlciwgIi1JbmZpbml0eSIpOworCSAgICBicmVhazsKKwljYXNlIDE6CisJICAgIHhtbEJ1ZmZlckNDYXQoYnVmZmVyLCAiSW5maW5pdHkiKTsKKwkgICAgYnJlYWs7CisJZGVmYXVsdDoKKwkgICAgaWYgKHhtbFhQYXRoSXNOYU4obnVtYmVyKSkgeworCQl4bWxCdWZmZXJDQ2F0KGJ1ZmZlciwgIk5hTiIpOworCSAgICB9IGVsc2UgeworCisJCXN3aXRjaCAodG9rZW4tPnRva2VuKSB7CisJCWNhc2UgJ0EnOgorCQkgICAgeHNsdE51bWJlckZvcm1hdEFscGhhKGJ1ZmZlciwKKwkJCQkJICBudW1iZXIsCisJCQkJCSAgVFJVRSk7CisKKwkJICAgIGJyZWFrOworCQljYXNlICdhJzoKKwkJICAgIHhzbHROdW1iZXJGb3JtYXRBbHBoYShidWZmZXIsCisJCQkJCSAgbnVtYmVyLAorCQkJCQkgIEZBTFNFKTsKKworCQkgICAgYnJlYWs7CisJCWNhc2UgJ0knOgorCQkgICAgeHNsdE51bWJlckZvcm1hdFJvbWFuKGJ1ZmZlciwKKwkJCQkJICBudW1iZXIsCisJCQkJCSAgVFJVRSk7CisKKwkJICAgIGJyZWFrOworCQljYXNlICdpJzoKKwkJICAgIHhzbHROdW1iZXJGb3JtYXRSb21hbihidWZmZXIsCisJCQkJCSAgbnVtYmVyLAorCQkJCQkgIEZBTFNFKTsKKworCQkgICAgYnJlYWs7CisJCWRlZmF1bHQ6CisJCSAgICBpZiAoSVNfRElHSVRfWkVSTyh0b2tlbi0+dG9rZW4pKSB7CisJCQl4c2x0TnVtYmVyRm9ybWF0RGVjaW1hbChidWZmZXIsCisJCQkJCQludW1iZXIsCisJCQkJCQl0b2tlbi0+dG9rZW4sCisJCQkJCQl0b2tlbi0+d2lkdGgsCisJCQkJCQlkYXRhLT5kaWdpdHNQZXJHcm91cCwKKwkJCQkJCWRhdGEtPmdyb3VwaW5nQ2hhcmFjdGVyLAorCQkJCQkJZGF0YS0+Z3JvdXBpbmdDaGFyYWN0ZXJMZW4pOworCQkgICAgfQorCQkgICAgYnJlYWs7CisJCX0KKwkgICAgfQorCisJfQorICAgIH0KKworICAgIC8qCisgICAgICogSGFuZGxlIGZpbmFsIG5vbi1hbHBoYW51bWVyaWMgdG9rZW4KKyAgICAgKi8KKyAgICBpZiAodG9rZW5zLT5lbmQgIT0gTlVMTCkKKwkgeG1sQnVmZmVyQ2F0KGJ1ZmZlciwgdG9rZW5zLT5lbmQpOworCit9CisKK3N0YXRpYyBpbnQKK3hzbHROdW1iZXJGb3JtYXRHZXRBbnlMZXZlbCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjb250ZXh0LAorCQkJICAgIHhtbE5vZGVQdHIgbm9kZSwKKwkJCSAgICBjb25zdCB4bWxDaGFyICpjb3VudCwKKwkJCSAgICBjb25zdCB4bWxDaGFyICpmcm9tLAorCQkJICAgIGRvdWJsZSAqYXJyYXksCisJCQkgICAgeG1sRG9jUHRyIGRvYywKKwkJCSAgICB4bWxOb2RlUHRyIGVsZW0pCit7CisgICAgaW50IGFtb3VudCA9IDA7CisgICAgaW50IGNudCA9IDA7CisgICAgeG1sTm9kZVB0ciBjdXI7CisgICAgeHNsdENvbXBNYXRjaFB0ciBjb3VudFBhdCA9IE5VTEw7CisgICAgeHNsdENvbXBNYXRjaFB0ciBmcm9tUGF0ID0gTlVMTDsKKworICAgIGlmIChjb3VudCAhPSBOVUxMKQorCWNvdW50UGF0ID0geHNsdENvbXBpbGVQYXR0ZXJuKGNvdW50LCBkb2MsIGVsZW0sIE5VTEwsIGNvbnRleHQpOworICAgIGlmIChmcm9tICE9IE5VTEwpCisJZnJvbVBhdCA9IHhzbHRDb21waWxlUGF0dGVybihmcm9tLCBkb2MsIGVsZW0sIE5VTEwsIGNvbnRleHQpOworCQorICAgIC8qIHNlbGVjdCB0aGUgc3RhcnRpbmcgbm9kZSAqLworICAgIHN3aXRjaCAobm9kZS0+dHlwZSkgeworCWNhc2UgWE1MX0VMRU1FTlRfTk9ERToKKwkgICAgY3VyID0gbm9kZTsKKwkgICAgYnJlYWs7CisJY2FzZSBYTUxfQVRUUklCVVRFX05PREU6CisJICAgIGN1ciA9ICgoeG1sQXR0clB0cikgbm9kZSktPnBhcmVudDsKKwkgICAgYnJlYWs7CisJY2FzZSBYTUxfVEVYVF9OT0RFOgorCWNhc2UgWE1MX1BJX05PREU6CisJY2FzZSBYTUxfQ09NTUVOVF9OT0RFOgorCSAgICBjdXIgPSBub2RlLT5wYXJlbnQ7CisJICAgIGJyZWFrOworCWRlZmF1bHQ6CisJICAgIGN1ciA9IE5VTEw7CisJICAgIGJyZWFrOworICAgIH0KKworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCS8qIHByb2Nlc3MgY3VycmVudCBub2RlICovCisJaWYgKGNvdW50ID09IE5VTEwpIHsKKwkgICAgaWYgKChub2RlLT50eXBlID09IGN1ci0+dHlwZSkgJiYKKwkJLyogRklYTUU6IG11c3QgdXNlIGV4cGFuZGVkLW5hbWUgaW5zdGVhZCBvZiBsb2NhbCBuYW1lICovCisJCXhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIGN1ci0+bmFtZSkpIHsKKwkJICAgIGlmICgobm9kZS0+bnMgPT0gY3VyLT5ucykgfHwKKwkJICAgICAgICAoKG5vZGUtPm5zICE9IE5VTEwpICYmCisJCQkgKGN1ci0+bnMgIT0gTlVMTCkgJiYKKwkJICAgICAgICAgKHhtbFN0ckVxdWFsKG5vZGUtPm5zLT5ocmVmLAorCQkgICAgICAgICAgICAgY3VyLT5ucy0+aHJlZikgKSkpCisJCSAgICAgICAgY250Kys7CisJICAgIH0KKwl9IGVsc2UgeworCSAgICBpZiAoeHNsdFRlc3RDb21wTWF0Y2hMaXN0KGNvbnRleHQsIGN1ciwgY291bnRQYXQpKQorCQljbnQrKzsKKwl9CisJaWYgKChmcm9tICE9IE5VTEwpICYmCisJICAgIHhzbHRUZXN0Q29tcE1hdGNoTGlzdChjb250ZXh0LCBjdXIsIGZyb21QYXQpKSB7CisJICAgIGJyZWFrOyAvKiB3aGlsZSAqLworCX0KKworCS8qIFNraXAgdG8gbmV4dCBwcmVjZWRpbmcgb3IgYW5jZXN0b3IgKi8KKwlpZiAoKGN1ci0+dHlwZSA9PSBYTUxfRE9DVU1FTlRfTk9ERSkgfHwKKyNpZmRlZiBMSUJYTUxfRE9DQl9FTkFCTEVECisgICAgICAgICAgICAoY3VyLT50eXBlID09IFhNTF9ET0NCX0RPQ1VNRU5UX05PREUpIHx8CisjZW5kaWYKKyAgICAgICAgICAgIChjdXItPnR5cGUgPT0gWE1MX0hUTUxfRE9DVU1FTlRfTk9ERSkpCisJICAgIGJyZWFrOyAvKiB3aGlsZSAqLworCisJd2hpbGUgKChjdXItPnByZXYgIT0gTlVMTCkgJiYgKChjdXItPnByZXYtPnR5cGUgPT0gWE1MX0RURF9OT0RFKSB8fAorCSAgICAgICAoY3VyLT5wcmV2LT50eXBlID09IFhNTF9YSU5DTFVERV9TVEFSVCkgfHwKKwkgICAgICAgKGN1ci0+cHJldi0+dHlwZSA9PSBYTUxfWElOQ0xVREVfRU5EKSkpCisJICAgIGN1ciA9IGN1ci0+cHJldjsKKwlpZiAoY3VyLT5wcmV2ICE9IE5VTEwpIHsKKwkgICAgZm9yIChjdXIgPSBjdXItPnByZXY7IGN1ci0+bGFzdCAhPSBOVUxMOyBjdXIgPSBjdXItPmxhc3QpOworCX0gZWxzZSB7CisJICAgIGN1ciA9IGN1ci0+cGFyZW50OworCX0KKworICAgIH0KKworICAgIGFycmF5W2Ftb3VudCsrXSA9IChkb3VibGUpIGNudDsKKworICAgIGlmIChjb3VudFBhdCAhPSBOVUxMKQorCXhzbHRGcmVlQ29tcE1hdGNoTGlzdChjb3VudFBhdCk7CisgICAgaWYgKGZyb21QYXQgIT0gTlVMTCkKKwl4c2x0RnJlZUNvbXBNYXRjaExpc3QoZnJvbVBhdCk7CisgICAgcmV0dXJuKGFtb3VudCk7Cit9CisKK3N0YXRpYyBpbnQKK3hzbHROdW1iZXJGb3JtYXRHZXRNdWx0aXBsZUxldmVsKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGNvbnRleHQsCisJCQkJIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkgY29uc3QgeG1sQ2hhciAqY291bnQsCisJCQkJIGNvbnN0IHhtbENoYXIgKmZyb20sCisJCQkJIGRvdWJsZSAqYXJyYXksCisJCQkJIGludCBtYXgsCisJCQkJIHhtbERvY1B0ciBkb2MsCisJCQkJIHhtbE5vZGVQdHIgZWxlbSkKK3sKKyAgICBpbnQgYW1vdW50ID0gMDsKKyAgICBpbnQgY250OworICAgIHhtbE5vZGVQdHIgYW5jZXN0b3I7CisgICAgeG1sTm9kZVB0ciBwcmVjZWRpbmc7CisgICAgeG1sWFBhdGhQYXJzZXJDb250ZXh0UHRyIHBhcnNlcjsKKyAgICB4c2x0Q29tcE1hdGNoUHRyIGNvdW50UGF0OworICAgIHhzbHRDb21wTWF0Y2hQdHIgZnJvbVBhdDsKKworICAgIGlmIChjb3VudCAhPSBOVUxMKQorCWNvdW50UGF0ID0geHNsdENvbXBpbGVQYXR0ZXJuKGNvdW50LCBkb2MsIGVsZW0sIE5VTEwsIGNvbnRleHQpOworICAgIGVsc2UKKwljb3VudFBhdCA9IE5VTEw7CisgICAgaWYgKGZyb20gIT0gTlVMTCkKKwlmcm9tUGF0ID0geHNsdENvbXBpbGVQYXR0ZXJuKGZyb20sIGRvYywgZWxlbSwgTlVMTCwgY29udGV4dCk7CisgICAgZWxzZQorCWZyb21QYXQgPSBOVUxMOworICAgIGNvbnRleHQtPnhwYXRoQ3R4dC0+bm9kZSA9IG5vZGU7CisgICAgcGFyc2VyID0geG1sWFBhdGhOZXdQYXJzZXJDb250ZXh0KE5VTEwsIGNvbnRleHQtPnhwYXRoQ3R4dCk7CisgICAgaWYgKHBhcnNlcikgeworCS8qIGFuY2VzdG9yLW9yLXNlbGY6OipbY291bnRdICovCisJZm9yIChhbmNlc3RvciA9IG5vZGU7CisJICAgICAoYW5jZXN0b3IgIT0gTlVMTCkgJiYgKGFuY2VzdG9yLT50eXBlICE9IFhNTF9ET0NVTUVOVF9OT0RFKTsKKwkgICAgIGFuY2VzdG9yID0geG1sWFBhdGhOZXh0QW5jZXN0b3IocGFyc2VyLCBhbmNlc3RvcikpIHsKKwkgICAgCisJICAgIGlmICgoZnJvbSAhPSBOVUxMKSAmJgorCQl4c2x0VGVzdENvbXBNYXRjaExpc3QoY29udGV4dCwgYW5jZXN0b3IsIGZyb21QYXQpKQorCQlicmVhazsgLyogZm9yICovCisJICAgIAorCSAgICBpZiAoKGNvdW50ID09IE5VTEwgJiYgbm9kZS0+dHlwZSA9PSBhbmNlc3Rvci0+dHlwZSAmJiAKKwkJeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgYW5jZXN0b3ItPm5hbWUpKSB8fAorCQl4c2x0VGVzdENvbXBNYXRjaExpc3QoY29udGV4dCwgYW5jZXN0b3IsIGNvdW50UGF0KSkgeworCQkvKiBjb3VudChwcmVjZWRpbmctc2libGluZzo6KikgKi8KKwkJY250ID0gMDsKKwkJZm9yIChwcmVjZWRpbmcgPSBhbmNlc3RvcjsKKwkJICAgICBwcmVjZWRpbmcgIT0gTlVMTDsKKwkJICAgICBwcmVjZWRpbmcgPSAKKwkJICAgICAgICB4bWxYUGF0aE5leHRQcmVjZWRpbmdTaWJsaW5nKHBhcnNlciwgcHJlY2VkaW5nKSkgeworCQkgICAgaWYgKGNvdW50ID09IE5VTEwpIHsKKwkJCWlmICgocHJlY2VkaW5nLT50eXBlID09IGFuY2VzdG9yLT50eXBlKSAmJgorCQkJICAgIHhtbFN0ckVxdWFsKHByZWNlZGluZy0+bmFtZSwgYW5jZXN0b3ItPm5hbWUpKXsKKwkJCSAgICBpZiAoKHByZWNlZGluZy0+bnMgPT0gYW5jZXN0b3ItPm5zKSB8fAorCQkJICAgICAgICAoKHByZWNlZGluZy0+bnMgIT0gTlVMTCkgJiYKKwkJCQkgKGFuY2VzdG9yLT5ucyAhPSBOVUxMKSAmJgorCQkJICAgICAgICAgKHhtbFN0ckVxdWFsKHByZWNlZGluZy0+bnMtPmhyZWYsCisJCQkgICAgICAgICAgICAgYW5jZXN0b3ItPm5zLT5ocmVmKSApKSkKKwkJCSAgICAgICAgY250Kys7CisJCQl9CisJCSAgICB9IGVsc2UgeworCQkJaWYgKHhzbHRUZXN0Q29tcE1hdGNoTGlzdChjb250ZXh0LCBwcmVjZWRpbmcsCisJCQkJICAgICAgICAgICAgICAgICAgY291bnRQYXQpKQorCQkJICAgIGNudCsrOworCQkgICAgfQorCQl9CisJCWFycmF5W2Ftb3VudCsrXSA9IChkb3VibGUpY250OworCQlpZiAoYW1vdW50ID49IG1heCkKKwkJICAgIGJyZWFrOyAvKiBmb3IgKi8KKwkgICAgfQorCX0KKwl4bWxYUGF0aEZyZWVQYXJzZXJDb250ZXh0KHBhcnNlcik7CisgICAgfQorICAgIHhzbHRGcmVlQ29tcE1hdGNoTGlzdChjb3VudFBhdCk7CisgICAgeHNsdEZyZWVDb21wTWF0Y2hMaXN0KGZyb21QYXQpOworICAgIHJldHVybiBhbW91bnQ7Cit9CisKK3N0YXRpYyBpbnQKK3hzbHROdW1iZXJGb3JtYXRHZXRWYWx1ZSh4bWxYUGF0aENvbnRleHRQdHIgY29udGV4dCwKKwkJCSB4bWxOb2RlUHRyIG5vZGUsCisJCQkgY29uc3QgeG1sQ2hhciAqdmFsdWUsCisJCQkgZG91YmxlICpudW1iZXIpCit7CisgICAgaW50IGFtb3VudCA9IDA7CisgICAgeG1sQnVmZmVyUHRyIHBhdHRlcm47CisgICAgeG1sWFBhdGhPYmplY3RQdHIgb2JqOworICAgIAorICAgIHBhdHRlcm4gPSB4bWxCdWZmZXJDcmVhdGUoKTsKKyAgICBpZiAocGF0dGVybiAhPSBOVUxMKSB7CisJeG1sQnVmZmVyQ0NhdChwYXR0ZXJuLCAibnVtYmVyKCIpOworCXhtbEJ1ZmZlckNhdChwYXR0ZXJuLCB2YWx1ZSk7CisJeG1sQnVmZmVyQ0NhdChwYXR0ZXJuLCAiKSIpOworCWNvbnRleHQtPm5vZGUgPSBub2RlOworCW9iaiA9IHhtbFhQYXRoRXZhbEV4cHJlc3Npb24oeG1sQnVmZmVyQ29udGVudChwYXR0ZXJuKSwKKwkJCQkgICAgIGNvbnRleHQpOworCWlmIChvYmogIT0gTlVMTCkgeworCSAgICAqbnVtYmVyID0gb2JqLT5mbG9hdHZhbDsKKwkgICAgYW1vdW50Kys7CisJICAgIHhtbFhQYXRoRnJlZU9iamVjdChvYmopOworCX0KKwl4bWxCdWZmZXJGcmVlKHBhdHRlcm4pOworICAgIH0KKyAgICByZXR1cm4gYW1vdW50OworfQorCisvKioKKyAqIHhzbHROdW1iZXJGb3JtYXQ6CisgKiBAY3R4dDogdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQGRhdGE6IHRoZSBmb3JtYXR0aW5nIGluZm9ybWF0aW9ucworICogQG5vZGU6IHRoZSBkYXRhIHRvIGZvcm1hdAorICoKKyAqIENvbnZlcnQgb25lIG51bWJlci4KKyAqLwordm9pZAoreHNsdE51bWJlckZvcm1hdCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkgeHNsdE51bWJlckRhdGFQdHIgZGF0YSwKKwkJIHhtbE5vZGVQdHIgbm9kZSkKK3sKKyAgICB4bWxCdWZmZXJQdHIgb3V0cHV0ID0gTlVMTDsKKyAgICBpbnQgYW1vdW50LCBpOworICAgIGRvdWJsZSBudW1iZXI7CisgICAgeHNsdEZvcm1hdCB0b2tlbnM7CisgICAgaW50IHRlbXBmb3JtYXQgPSAwOworCisgICAgaWYgKChkYXRhLT5mb3JtYXQgPT0gTlVMTCkgJiYgKGRhdGEtPmhhc19mb3JtYXQgIT0gMCkpIHsKKwlkYXRhLT5mb3JtYXQgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIGRhdGEtPm5vZGUsCisJCQkJCSAgICAgKGNvbnN0IHhtbENoYXIgKikgImZvcm1hdCIsCisJCQkJCSAgICAgWFNMVF9OQU1FU1BBQ0UpOworCXRlbXBmb3JtYXQgPSAxOworICAgIH0KKyAgICBpZiAoZGF0YS0+Zm9ybWF0ID09IE5VTEwpIHsKKwlyZXR1cm47CisgICAgfQorCisgICAgb3V0cHV0ID0geG1sQnVmZmVyQ3JlYXRlKCk7CisgICAgaWYgKG91dHB1dCA9PSBOVUxMKQorCWdvdG8gWFNMVF9OVU1CRVJfRk9STUFUX0VORDsKKworICAgIHhzbHROdW1iZXJGb3JtYXRUb2tlbml6ZShkYXRhLT5mb3JtYXQsICZ0b2tlbnMpOworCisgICAgLyoKKyAgICAgKiBFdmFsdWF0ZSB0aGUgWFBhdGggZXhwcmVzc2lvbiB0byBmaW5kIHRoZSB2YWx1ZShzKQorICAgICAqLworICAgIGlmIChkYXRhLT52YWx1ZSkgeworCWFtb3VudCA9IHhzbHROdW1iZXJGb3JtYXRHZXRWYWx1ZShjdHh0LT54cGF0aEN0eHQsCisJCQkJCSAgbm9kZSwKKwkJCQkJICBkYXRhLT52YWx1ZSwKKwkJCQkJICAmbnVtYmVyKTsKKwlpZiAoYW1vdW50ID09IDEpIHsKKwkgICAgeHNsdE51bWJlckZvcm1hdEluc2VydE51bWJlcnMoZGF0YSwKKwkJCQkJICAmbnVtYmVyLAorCQkJCQkgIDEsCisJCQkJCSAgJnRva2VucywKKwkJCQkJICBvdXRwdXQpOworCX0KKwkKKyAgICB9IGVsc2UgaWYgKGRhdGEtPmxldmVsKSB7CisJCisJaWYgKHhtbFN0ckVxdWFsKGRhdGEtPmxldmVsLCAoY29uc3QgeG1sQ2hhciAqKSAic2luZ2xlIikpIHsKKwkgICAgYW1vdW50ID0geHNsdE51bWJlckZvcm1hdEdldE11bHRpcGxlTGV2ZWwoY3R4dCwKKwkJCQkJCSAgICAgIG5vZGUsCisJCQkJCQkgICAgICBkYXRhLT5jb3VudCwKKwkJCQkJCSAgICAgIGRhdGEtPmZyb20sCisJCQkJCQkgICAgICAmbnVtYmVyLAorCQkJCQkJICAgICAgMSwKKwkJCQkJCSAgICAgIGRhdGEtPmRvYywKKwkJCQkJCSAgICAgIGRhdGEtPm5vZGUpOworCSAgICBpZiAoYW1vdW50ID09IDEpIHsKKwkJeHNsdE51bWJlckZvcm1hdEluc2VydE51bWJlcnMoZGF0YSwKKwkJCQkJICAgICAgJm51bWJlciwKKwkJCQkJICAgICAgMSwKKwkJCQkJICAgICAgJnRva2VucywKKwkJCQkJICAgICAgb3V0cHV0KTsKKwkgICAgfQorCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoZGF0YS0+bGV2ZWwsIChjb25zdCB4bWxDaGFyICopICJtdWx0aXBsZSIpKSB7CisJICAgIGRvdWJsZSBudW1hcnJheVsxMDI0XTsKKwkgICAgaW50IG1heCA9IHNpemVvZihudW1hcnJheSkvc2l6ZW9mKG51bWFycmF5WzBdKTsKKwkgICAgYW1vdW50ID0geHNsdE51bWJlckZvcm1hdEdldE11bHRpcGxlTGV2ZWwoY3R4dCwKKwkJCQkJCSAgICAgIG5vZGUsCisJCQkJCQkgICAgICBkYXRhLT5jb3VudCwKKwkJCQkJCSAgICAgIGRhdGEtPmZyb20sCisJCQkJCQkgICAgICBudW1hcnJheSwKKwkJCQkJCSAgICAgIG1heCwKKwkJCQkJCSAgICAgIGRhdGEtPmRvYywKKwkJCQkJCSAgICAgIGRhdGEtPm5vZGUpOworCSAgICBpZiAoYW1vdW50ID4gMCkgeworCQl4c2x0TnVtYmVyRm9ybWF0SW5zZXJ0TnVtYmVycyhkYXRhLAorCQkJCQkgICAgICBudW1hcnJheSwKKwkJCQkJICAgICAgYW1vdW50LAorCQkJCQkgICAgICAmdG9rZW5zLAorCQkJCQkgICAgICBvdXRwdXQpOworCSAgICB9CisJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChkYXRhLT5sZXZlbCwgKGNvbnN0IHhtbENoYXIgKikgImFueSIpKSB7CisJICAgIGFtb3VudCA9IHhzbHROdW1iZXJGb3JtYXRHZXRBbnlMZXZlbChjdHh0LAorCQkJCQkJIG5vZGUsCisJCQkJCQkgZGF0YS0+Y291bnQsCisJCQkJCQkgZGF0YS0+ZnJvbSwKKwkJCQkJCSAmbnVtYmVyLCAKKwkJCQkJCSBkYXRhLT5kb2MsCisJCQkJCQkgZGF0YS0+bm9kZSk7CisJICAgIGlmIChhbW91bnQgPiAwKSB7CisJCXhzbHROdW1iZXJGb3JtYXRJbnNlcnROdW1iZXJzKGRhdGEsCisJCQkJCSAgICAgICZudW1iZXIsCisJCQkJCSAgICAgIDEsCisJCQkJCSAgICAgICZ0b2tlbnMsCisJCQkJCSAgICAgIG91dHB1dCk7CisJICAgIH0KKwl9CisgICAgfQorICAgIC8qIEluc2VydCBudW1iZXIgYXMgdGV4dCBub2RlICovCisgICAgeHNsdENvcHlUZXh0U3RyaW5nKGN0eHQsIGN0eHQtPmluc2VydCwgeG1sQnVmZmVyQ29udGVudChvdXRwdXQpLCAwKTsKKworICAgIGlmICh0b2tlbnMuc3RhcnQgIT0gTlVMTCkKKwl4bWxGcmVlKHRva2Vucy5zdGFydCk7CisgICAgaWYgKHRva2Vucy5lbmQgIT0gTlVMTCkKKwl4bWxGcmVlKHRva2Vucy5lbmQpOworICAgIGZvciAoaSA9IDA7aSA8IHRva2Vucy5uVG9rZW5zO2krKykgeworCWlmICh0b2tlbnMudG9rZW5zW2ldLnNlcGFyYXRvciAhPSBOVUxMKQorCSAgICB4bWxGcmVlKHRva2Vucy50b2tlbnNbaV0uc2VwYXJhdG9yKTsKKyAgICB9CisgICAgCitYU0xUX05VTUJFUl9GT1JNQVRfRU5EOgorICAgIGlmICh0ZW1wZm9ybWF0ID09IDEpIHsKKwkvKiBUaGUgZm9ybWF0IG5lZWQgdG8gYmUgcmVjb21wdXRlZCBlYWNoIHRpbWUgKi8KKwlkYXRhLT5mb3JtYXQgPSBOVUxMOworICAgIH0KKyAgICBpZiAob3V0cHV0ICE9IE5VTEwpCisJeG1sQnVmZmVyRnJlZShvdXRwdXQpOworfQorCitzdGF0aWMgaW50Cit4c2x0Rm9ybWF0TnVtYmVyUHJlU3VmZml4KHhzbHREZWNpbWFsRm9ybWF0UHRyIHNlbGYsIHhtbENoYXIgKipmb3JtYXQsIHhzbHRGb3JtYXROdW1iZXJJbmZvUHRyIGluZm8pCit7CisgICAgaW50CWNvdW50PTA7CS8qIHdpbGwgaG9sZCB0b3RhbCBsZW5ndGggb2YgcHJlZml4L3N1ZmZpeCAqLworICAgIGludCBsZW47CisKKyAgICB3aGlsZSAoMSkgeworCS8qIAorCSAqIHByZWZpeCAvIHN1ZmZpeCBlbmRzIGF0IGVuZCBvZiBzdHJpbmcgb3IgYXQgCisJICogZmlyc3QgJ3NwZWNpYWwnIGNoYXJhY3RlciAKKwkgKi8KKwlpZiAoKipmb3JtYXQgPT0gMCkKKwkgICAgcmV0dXJuIGNvdW50OworCS8qIGlmIG5leHQgY2hhcmFjdGVyICdlc2NhcGVkJyBqdXN0IGNvdW50IGl0ICovCisJaWYgKCoqZm9ybWF0ID09IFNZTUJPTF9RVU9URSkgeworCSAgICBpZiAoKisrKCpmb3JtYXQpID09IDApCisJCXJldHVybiAtMTsKKwl9CisJZWxzZSBpZiAoSVNfU1BFQ0lBTChzZWxmLCAqZm9ybWF0KSkKKwkgICAgcmV0dXJuIGNvdW50OworCS8qCisJICogZWxzZSB0cmVhdCBwZXJjZW50L3Blci1taWxsZSBhcyBzcGVjaWFsIGNhc2VzLAorCSAqIGRlcGVuZGluZyBvbiB3aGV0aGVyICt2ZSBvciAtdmUgCisJICovCisJZWxzZSB7CisJICAgIC8qCisJICAgICAqIGZvciArdmUgcHJlZml4L3N1ZmZpeCwgYWxsb3cgb25seSBhIAorCSAgICAgKiBzaW5nbGUgb2NjdXJlbmNlIG9mIGVpdGhlciAKKwkgICAgICovCisJICAgIGlmICh4c2x0VVRGOENoYXJjbXAoKmZvcm1hdCwgc2VsZi0+cGVyY2VudCkgPT0gMCkgeworCQlpZiAoaW5mby0+aXNfbXVsdGlwbGllcl9zZXQpCisJCSAgICByZXR1cm4gLTE7CisJCWluZm8tPm11bHRpcGxpZXIgPSAxMDA7CisJCWluZm8tPmlzX211bHRpcGxpZXJfc2V0ID0gVFJVRTsKKwkgICAgfSBlbHNlIGlmICh4c2x0VVRGOENoYXJjbXAoKmZvcm1hdCwgc2VsZi0+cGVybWlsbGUpID09IDApIHsKKwkJaWYgKGluZm8tPmlzX211bHRpcGxpZXJfc2V0KQorCQkgICAgcmV0dXJuIC0xOworCQlpbmZvLT5tdWx0aXBsaWVyID0gMTAwMDsKKwkJaW5mby0+aXNfbXVsdGlwbGllcl9zZXQgPSBUUlVFOworCSAgICB9CisJfQorCQorCWlmICgobGVuPXhzbHRVVEY4U2l6ZSgqZm9ybWF0KSkgPCAxKQorCSAgICByZXR1cm4gLTE7CisJY291bnQgKz0gbGVuOworCSpmb3JtYXQgKz0gbGVuOworICAgIH0KK30KKwkgICAgCisvKioKKyAqIHhzbHRGb3JtYXROdW1iZXJDb252ZXJzaW9uOgorICogQHNlbGY6IHRoZSBkZWNpbWFsIGZvcm1hdAorICogQGZvcm1hdDogdGhlIGZvcm1hdCByZXF1ZXN0ZWQKKyAqIEBudW1iZXI6IHRoZSB2YWx1ZSB0byBmb3JtYXQKKyAqIEByZXN1bHQ6IHRoZSBwbGFjZSB0byBvdXB1dCB0aGUgcmVzdWx0CisgKgorICogZm9ybWF0LW51bWJlcigpIHVzZXMgdGhlIEpESyAxLjEgRGVjaW1hbEZvcm1hdCBjbGFzczoKKyAqCisgKiBodHRwOi8vamF2YS5zdW4uY29tL3Byb2R1Y3RzL2pkay8xLjEvZG9jcy9hcGkvamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQuaHRtbAorICoKKyAqIFN0cnVjdHVyZToKKyAqCisgKiAgIHBhdHRlcm4gICAgOj0gc3VicGF0dGVybns7c3VicGF0dGVybn0KKyAqICAgc3VicGF0dGVybiA6PSB7cHJlZml4fWludGVnZXJ7LmZyYWN0aW9ufXtzdWZmaXh9CisgKiAgIHByZWZpeCAgICAgOj0gJ1xcdTAwMDAnLi4nXFx1RkZGRCcgLSBzcGVjaWFsQ2hhcmFjdGVycworICogICBzdWZmaXggICAgIDo9ICdcXHUwMDAwJy4uJ1xcdUZGRkQnIC0gc3BlY2lhbENoYXJhY3RlcnMKKyAqICAgaW50ZWdlciAgICA6PSAnIycqICcwJyogJzAnCisgKiAgIGZyYWN0aW9uICAgOj0gJzAnKiAnIycqCisgKgorICogICBOb3RhdGlvbjoKKyAqICAgIFgqICAgICAgIDAgb3IgbW9yZSBpbnN0YW5jZXMgb2YgWAorICogICAgKFggfCBZKSAgZWl0aGVyIFggb3IgWS4KKyAqICAgIFguLlkgICAgIGFueSBjaGFyYWN0ZXIgZnJvbSBYIHVwIHRvIFksIGluY2x1c2l2ZS4KKyAqICAgIFMgLSBUICAgIGNoYXJhY3RlcnMgaW4gUywgZXhjZXB0IHRob3NlIGluIFQKKyAqCisgKiBTcGVjaWFsIENoYXJhY3RlcnM6CisgKgorICogICBTeW1ib2wgTWVhbmluZworICogICAwICAgICAgYSBkaWdpdAorICogICAjICAgICAgYSBkaWdpdCwgemVybyBzaG93cyBhcyBhYnNlbnQKKyAqICAgLiAgICAgIHBsYWNlaG9sZGVyIGZvciBkZWNpbWFsIHNlcGFyYXRvcgorICogICAsICAgICAgcGxhY2Vob2xkZXIgZm9yIGdyb3VwaW5nIHNlcGFyYXRvci4KKyAqICAgOyAgICAgIHNlcGFyYXRlcyBmb3JtYXRzLgorICogICAtICAgICAgZGVmYXVsdCBuZWdhdGl2ZSBwcmVmaXguCisgKiAgICUgICAgICBtdWx0aXBseSBieSAxMDAgYW5kIHNob3cgYXMgcGVyY2VudGFnZQorICogICA/ICAgICAgbXVsdGlwbHkgYnkgMTAwMCBhbmQgc2hvdyBhcyBwZXIgbWlsbGUKKyAqICAgWCAgICAgIGFueSBvdGhlciBjaGFyYWN0ZXJzIGNhbiBiZSB1c2VkIGluIHRoZSBwcmVmaXggb3Igc3VmZml4CisgKiAgICcgICAgICB1c2VkIHRvIHF1b3RlIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBhIHByZWZpeCBvciBzdWZmaXguCisgKgorICogUmV0dXJucyBhIHBvc3NpYmxlIFhQYXRoIGVycm9yCisgKi8KK3htbFhQYXRoRXJyb3IKK3hzbHRGb3JtYXROdW1iZXJDb252ZXJzaW9uKHhzbHREZWNpbWFsRm9ybWF0UHRyIHNlbGYsCisJCQkgICB4bWxDaGFyICpmb3JtYXQsCisJCQkgICBkb3VibGUgbnVtYmVyLAorCQkJICAgeG1sQ2hhciAqKnJlc3VsdCkKK3sKKyAgICB4bWxYUGF0aEVycm9yIHN0YXR1cyA9IFhQQVRIX0VYUFJFU1NJT05fT0s7CisgICAgeG1sQnVmZmVyUHRyIGJ1ZmZlcjsKKyAgICB4bWxDaGFyICp0aGVfZm9ybWF0LCAqcHJlZml4ID0gTlVMTCwgKnN1ZmZpeCA9IE5VTEw7CisgICAgeG1sQ2hhciAqbnByZWZpeCwgKm5zdWZmaXggPSBOVUxMOworICAgIHhtbENoYXIgcGNoYXI7CisgICAgaW50CSAgICBwcmVmaXhfbGVuZ3RoLCBzdWZmaXhfbGVuZ3RoID0gMCwgbnByZWZpeF9sZW5ndGgsIG5zdWZmaXhfbGVuZ3RoOworICAgIGRvdWJsZSAgc2NhbGU7CisgICAgaW50CSAgICBqLCBsZW47CisgICAgaW50ICAgICBzZWxmX2dyb3VwaW5nX2xlbjsKKyAgICB4c2x0Rm9ybWF0TnVtYmVySW5mbyBmb3JtYXRfaW5mbzsKKyAgICAvKiAKKyAgICAgKiBkZWxheWVkX211bHRpcGxpZXIgYWxsb3dzIGEgJ3RyYWlsaW5nJyBwZXJjZW50IG9yCisgICAgICogcGVybWlsbGUgdG8gYmUgdHJlYXRlZCBhcyBzdWZmaXggCisgICAgICovCisgICAgaW50CQlkZWxheWVkX211bHRpcGxpZXIgPSAwOworICAgIC8qIGZsYWcgdG8gc2hvdyBubyAtdmUgZm9ybWF0IHByZXNlbnQgZm9yIC12ZSBudW1iZXIgKi8KKyAgICBjaGFyCWRlZmF1bHRfc2lnbiA9IDA7CisgICAgLyogZmxhZyB0byBzaG93IGVycm9yIGZvdW5kLCBzaG91bGQgdXNlIGRlZmF1bHQgZm9ybWF0ICovCisgICAgY2hhcglmb3VuZF9lcnJvciA9IDA7CisKKyAgICBpZiAoeG1sU3RybGVuKGZvcm1hdCkgPD0gMCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorICAgICAgICAgICAgICAgICJ4c2x0Rm9ybWF0TnVtYmVyQ29udmVyc2lvbiA6ICIKKwkJIkludmFsaWQgZm9ybWF0ICgwLWxlbmd0aClcbiIpOworICAgIH0KKyAgICAqcmVzdWx0ID0gTlVMTDsKKyAgICBzd2l0Y2ggKHhtbFhQYXRoSXNJbmYobnVtYmVyKSkgeworCWNhc2UgLTE6CisJICAgIGlmIChzZWxmLT5taW51c1NpZ24gPT0gTlVMTCkKKwkJKnJlc3VsdCA9IHhtbFN0cmR1cChCQURfQ0FTVCAiLSIpOworCSAgICBlbHNlCisJCSpyZXN1bHQgPSB4bWxTdHJkdXAoc2VsZi0+bWludXNTaWduKTsKKwkgICAgLyogbm8tYnJlYWsgb24gcHVycG9zZSAqLworCWNhc2UgMToKKwkgICAgaWYgKChzZWxmID09IE5VTEwpIHx8IChzZWxmLT5pbmZpbml0eSA9PSBOVUxMKSkKKwkJKnJlc3VsdCA9IHhtbFN0cmNhdCgqcmVzdWx0LCBCQURfQ0FTVCAiSW5maW5pdHkiKTsKKwkgICAgZWxzZQorCQkqcmVzdWx0ID0geG1sU3RyY2F0KCpyZXN1bHQsIHNlbGYtPmluZmluaXR5KTsKKwkgICAgcmV0dXJuKHN0YXR1cyk7CisJZGVmYXVsdDoKKwkgICAgaWYgKHhtbFhQYXRoSXNOYU4obnVtYmVyKSkgeworCQlpZiAoKHNlbGYgPT0gTlVMTCkgfHwgKHNlbGYtPm5vTnVtYmVyID09IE5VTEwpKQorCQkgICAgKnJlc3VsdCA9IHhtbFN0cmR1cChCQURfQ0FTVCAiTmFOIik7CisJCWVsc2UKKwkJICAgICpyZXN1bHQgPSB4bWxTdHJkdXAoc2VsZi0+bm9OdW1iZXIpOworCQlyZXR1cm4oc3RhdHVzKTsKKwkgICAgfQorICAgIH0KKworICAgIGJ1ZmZlciA9IHhtbEJ1ZmZlckNyZWF0ZSgpOworICAgIGlmIChidWZmZXIgPT0gTlVMTCkgeworCXJldHVybiBYUEFUSF9NRU1PUllfRVJST1I7CisgICAgfQorCisgICAgZm9ybWF0X2luZm8uaW50ZWdlcl9oYXNoID0gMDsKKyAgICBmb3JtYXRfaW5mby5pbnRlZ2VyX2RpZ2l0cyA9IDA7CisgICAgZm9ybWF0X2luZm8uZnJhY19kaWdpdHMgPSAwOworICAgIGZvcm1hdF9pbmZvLmZyYWNfaGFzaCA9IDA7CisgICAgZm9ybWF0X2luZm8uZ3JvdXAgPSAtMTsKKyAgICBmb3JtYXRfaW5mby5tdWx0aXBsaWVyID0gMTsKKyAgICBmb3JtYXRfaW5mby5hZGRfZGVjaW1hbCA9IEZBTFNFOworICAgIGZvcm1hdF9pbmZvLmlzX211bHRpcGxpZXJfc2V0ID0gRkFMU0U7CisgICAgZm9ybWF0X2luZm8uaXNfbmVnYXRpdmVfcGF0dGVybiA9IEZBTFNFOworCisgICAgdGhlX2Zvcm1hdCA9IGZvcm1hdDsKKworICAgIC8qCisgICAgICogRmlyc3Qgd2UgcHJvY2VzcyB0aGUgK3ZlIHBhdHRlcm4gdG8gZ2V0IHBlcmNlbnQgLyBwZXJtaWxsZSwKKyAgICAgKiBhcyB3ZWxsIGFzIG1haW4gZm9ybWF0IAorICAgICAqLworICAgIHByZWZpeCA9IHRoZV9mb3JtYXQ7CisgICAgcHJlZml4X2xlbmd0aCA9IHhzbHRGb3JtYXROdW1iZXJQcmVTdWZmaXgoc2VsZiwgJnRoZV9mb3JtYXQsICZmb3JtYXRfaW5mbyk7CisgICAgaWYgKHByZWZpeF9sZW5ndGggPCAwKSB7CisJZm91bmRfZXJyb3IgPSAxOworCWdvdG8gT1VUUFVUX05VTUJFUjsKKyAgICB9CisKKyAgICAvKiAKKyAgICAgKiBIZXJlIHdlIHByb2Nlc3MgdGhlICJudW1iZXIiIHBhcnQgb2YgdGhlIGZvcm1hdC4gIEl0IGdldHMgCisgICAgICogYSBsaXR0bGUgbWVzc3kgYmVjYXVzZSBvZiB0aGUgcGVyY2VudC9wZXItbWlsbGUgLSBpZiB0aGF0CisgICAgICogYXBwZWFycyBhdCB0aGUgZW5kLCBpdCBtYXkgYmUgcGFydCBvZiB0aGUgc3VmZml4IGluc3RlYWQgCisgICAgICogb2YgcGFydCBvZiB0aGUgbnVtYmVyLCBzbyB0aGUgdmFyaWFibGUgZGVsYXllZF9tdWx0aXBsaWVyIAorICAgICAqIGlzIHVzZWQgdG8gaGFuZGxlIGl0IAorICAgICAqLworICAgIHNlbGZfZ3JvdXBpbmdfbGVuID0geG1sU3RybGVuKHNlbGYtPmdyb3VwaW5nKTsKKyAgICB3aGlsZSAoKCp0aGVfZm9ybWF0ICE9IDApICYmCisJICAgKHhzbHRVVEY4Q2hhcmNtcCh0aGVfZm9ybWF0LCBzZWxmLT5kZWNpbWFsUG9pbnQpICE9IDApICYmCisJICAgKHhzbHRVVEY4Q2hhcmNtcCh0aGVfZm9ybWF0LCBzZWxmLT5wYXR0ZXJuU2VwYXJhdG9yKSAhPSAwKSkgeworCQorCWlmIChkZWxheWVkX211bHRpcGxpZXIgIT0gMCkgeworCSAgICBmb3JtYXRfaW5mby5tdWx0aXBsaWVyID0gZGVsYXllZF9tdWx0aXBsaWVyOworCSAgICBmb3JtYXRfaW5mby5pc19tdWx0aXBsaWVyX3NldCA9IFRSVUU7CisJICAgIGRlbGF5ZWRfbXVsdGlwbGllciA9IDA7CisJfQorCWlmICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgc2VsZi0+ZGlnaXQpID09IDApIHsKKwkgICAgaWYgKGZvcm1hdF9pbmZvLmludGVnZXJfZGlnaXRzID4gMCkgeworCQlmb3VuZF9lcnJvciA9IDE7CisJCWdvdG8gT1VUUFVUX05VTUJFUjsKKwkgICAgfQorCSAgICBmb3JtYXRfaW5mby5pbnRlZ2VyX2hhc2grKzsKKwkgICAgaWYgKGZvcm1hdF9pbmZvLmdyb3VwID49IDApCisJCWZvcm1hdF9pbmZvLmdyb3VwKys7CisJfSBlbHNlIGlmICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgc2VsZi0+emVyb0RpZ2l0KSA9PSAwKSB7CisJICAgIGZvcm1hdF9pbmZvLmludGVnZXJfZGlnaXRzKys7CisJICAgIGlmIChmb3JtYXRfaW5mby5ncm91cCA+PSAwKQorCQlmb3JtYXRfaW5mby5ncm91cCsrOworCX0gZWxzZSBpZiAoKHNlbGZfZ3JvdXBpbmdfbGVuID4gMCkgJiYKKwkgICAgKCF4bWxTdHJuY21wKHRoZV9mb3JtYXQsIHNlbGYtPmdyb3VwaW5nLCBzZWxmX2dyb3VwaW5nX2xlbikpKSB7CisJICAgIC8qIFJlc2V0IGdyb3VwIGNvdW50ICovCisJICAgIGZvcm1hdF9pbmZvLmdyb3VwID0gMDsKKwkgICAgdGhlX2Zvcm1hdCArPSBzZWxmX2dyb3VwaW5nX2xlbjsKKwkgICAgY29udGludWU7CisJfSBlbHNlIGlmICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgc2VsZi0+cGVyY2VudCkgPT0gMCkgeworCSAgICBpZiAoZm9ybWF0X2luZm8uaXNfbXVsdGlwbGllcl9zZXQpIHsKKwkJZm91bmRfZXJyb3IgPSAxOworCQlnb3RvIE9VVFBVVF9OVU1CRVI7CisJICAgIH0KKwkgICAgZGVsYXllZF9tdWx0aXBsaWVyID0gMTAwOworCX0gZWxzZSAgaWYgKHhzbHRVVEY4Q2hhcmNtcCh0aGVfZm9ybWF0LCBzZWxmLT5wZXJtaWxsZSkgPT0gMCkgeworCSAgICBpZiAoZm9ybWF0X2luZm8uaXNfbXVsdGlwbGllcl9zZXQpIHsKKwkJZm91bmRfZXJyb3IgPSAxOworCQlnb3RvIE9VVFBVVF9OVU1CRVI7CisJICAgIH0KKwkgICAgZGVsYXllZF9tdWx0aXBsaWVyID0gMTAwMDsKKwl9IGVsc2UKKwkgICAgYnJlYWs7IC8qIHdoaWxlICovCisJCisJaWYgKChsZW49eHNsdFVURjhTaXplKHRoZV9mb3JtYXQpKSA8IDEpIHsKKwkgICAgZm91bmRfZXJyb3IgPSAxOworCSAgICBnb3RvIE9VVFBVVF9OVU1CRVI7CisJfQorCXRoZV9mb3JtYXQgKz0gbGVuOworCisgICAgfQorCisgICAgLyogV2UgaGF2ZSBmaW5pc2hlZCB0aGUgaW50ZWdlciBwYXJ0LCBub3cgd29yayBvbiBmcmFjdGlvbiAqLworICAgIGlmICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgc2VsZi0+ZGVjaW1hbFBvaW50KSA9PSAwKSB7CisgICAgICAgIGZvcm1hdF9pbmZvLmFkZF9kZWNpbWFsID0gVFJVRTsKKwl0aGVfZm9ybWF0ICs9IHhzbHRVVEY4U2l6ZSh0aGVfZm9ybWF0KTsJLyogU2tpcCBvdmVyIHRoZSBkZWNpbWFsICovCisgICAgfQorICAgIAorICAgIHdoaWxlICgqdGhlX2Zvcm1hdCAhPSAwKSB7CisJCisJaWYgKHhzbHRVVEY4Q2hhcmNtcCh0aGVfZm9ybWF0LCBzZWxmLT56ZXJvRGlnaXQpID09IDApIHsKKwkgICAgaWYgKGZvcm1hdF9pbmZvLmZyYWNfaGFzaCAhPSAwKSB7CisJCWZvdW5kX2Vycm9yID0gMTsKKwkJZ290byBPVVRQVVRfTlVNQkVSOworCSAgICB9CisJICAgIGZvcm1hdF9pbmZvLmZyYWNfZGlnaXRzKys7CisJfSBlbHNlIGlmICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgc2VsZi0+ZGlnaXQpID09IDApIHsKKwkgICAgZm9ybWF0X2luZm8uZnJhY19oYXNoKys7CisJfSBlbHNlIGlmICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgc2VsZi0+cGVyY2VudCkgPT0gMCkgeworCSAgICBpZiAoZm9ybWF0X2luZm8uaXNfbXVsdGlwbGllcl9zZXQpIHsKKwkJZm91bmRfZXJyb3IgPSAxOworCQlnb3RvIE9VVFBVVF9OVU1CRVI7CisJICAgIH0KKwkgICAgZGVsYXllZF9tdWx0aXBsaWVyID0gMTAwOworCSAgICBpZiAoKGxlbiA9IHhzbHRVVEY4U2l6ZSh0aGVfZm9ybWF0KSkgPCAxKSB7CisJICAgICAgICBmb3VuZF9lcnJvciA9IDE7CisJCWdvdG8gT1VUUFVUX05VTUJFUjsKKwkgICAgfQorCSAgICB0aGVfZm9ybWF0ICs9IGxlbjsKKwkgICAgY29udGludWU7IC8qIHdoaWxlICovCisJfSBlbHNlIGlmICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgc2VsZi0+cGVybWlsbGUpID09IDApIHsKKwkgICAgaWYgKGZvcm1hdF9pbmZvLmlzX211bHRpcGxpZXJfc2V0KSB7CisJCWZvdW5kX2Vycm9yID0gMTsKKwkJZ290byBPVVRQVVRfTlVNQkVSOworCSAgICB9CisJICAgIGRlbGF5ZWRfbXVsdGlwbGllciA9IDEwMDA7CisJICAgIGlmICAoKGxlbiA9IHhzbHRVVEY4U2l6ZSh0aGVfZm9ybWF0KSkgPCAxKSB7CisJICAgICAgICBmb3VuZF9lcnJvciA9IDE7CisJCWdvdG8gT1VUUFVUX05VTUJFUjsKKwkgICAgfQorCSAgICB0aGVfZm9ybWF0ICs9IGxlbjsKKwkgICAgY29udGludWU7IC8qIHdoaWxlICovCisJfSBlbHNlIGlmICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgc2VsZi0+Z3JvdXBpbmcpICE9IDApIHsKKwkgICAgYnJlYWs7IC8qIHdoaWxlICovCisJfQorCWlmICgobGVuID0geHNsdFVURjhTaXplKHRoZV9mb3JtYXQpKSA8IDEpIHsKKwkgICAgZm91bmRfZXJyb3IgPSAxOworCSAgICBnb3RvIE9VVFBVVF9OVU1CRVI7CisJfQorCXRoZV9mb3JtYXQgKz0gbGVuOworCWlmIChkZWxheWVkX211bHRpcGxpZXIgIT0gMCkgeworCSAgICBmb3JtYXRfaW5mby5tdWx0aXBsaWVyID0gZGVsYXllZF9tdWx0aXBsaWVyOworCSAgICBkZWxheWVkX211bHRpcGxpZXIgPSAwOworCSAgICBmb3JtYXRfaW5mby5pc19tdWx0aXBsaWVyX3NldCA9IFRSVUU7CisJfQorICAgIH0KKworICAgIC8qIAorICAgICAqIElmIGRlbGF5ZWRfbXVsdGlwbGllciBpcyBzZXQgYWZ0ZXIgcHJvY2Vzc2luZyB0aGUgCisgICAgICogIm51bWJlciIgcGFydCwgc2hvdWxkIGJlIGluIHN1ZmZpeCAKKyAgICAgKi8KKyAgICBpZiAoZGVsYXllZF9tdWx0aXBsaWVyICE9IDApIHsKKwl0aGVfZm9ybWF0IC09IGxlbjsKKwlkZWxheWVkX211bHRpcGxpZXIgPSAwOworICAgIH0KKworICAgIHN1ZmZpeCA9IHRoZV9mb3JtYXQ7CisgICAgc3VmZml4X2xlbmd0aCA9IHhzbHRGb3JtYXROdW1iZXJQcmVTdWZmaXgoc2VsZiwgJnRoZV9mb3JtYXQsICZmb3JtYXRfaW5mbyk7CisgICAgaWYgKCAoc3VmZml4X2xlbmd0aCA8IDApIHx8CisJICgoKnRoZV9mb3JtYXQgIT0gMCkgJiYgCisJICAoeHNsdFVURjhDaGFyY21wKHRoZV9mb3JtYXQsIHNlbGYtPnBhdHRlcm5TZXBhcmF0b3IpICE9IDApKSApIHsKKwlmb3VuZF9lcnJvciA9IDE7CisJZ290byBPVVRQVVRfTlVNQkVSOworICAgIH0KKworICAgIC8qCisgICAgICogV2UgaGF2ZSBwcm9jZXNzZWQgdGhlICt2ZSBwcmVmaXgsIG51bWJlciBwYXJ0IGFuZCArdmUgc3VmZml4LgorICAgICAqIElmIHRoZSBudW1iZXIgaXMgLXZlLCB3ZSBtdXN0IHN1YnN0aXR1dGUgdGhlIC12ZSBwcmVmaXggLyBzdWZmaXgKKyAgICAgKi8KKyAgICBpZiAobnVtYmVyIDwgMCkgeworICAgICAgICAvKgorCSAqIE5vdGUgdGhhdCBqIGlzIHRoZSBudW1iZXIgb2YgVVRGOCBjaGFycyBiZWZvcmUgdGhlIHNlcGFyYXRvciwKKwkgKiBub3QgdGhlIG51bWJlciBvZiBieXRlcyEgKGJ1ZyAxNTE5NzUpCisJICovCisgICAgICAgIGogPSAgeG1sVVRGOFN0cmxvYyhmb3JtYXQsIHNlbGYtPnBhdHRlcm5TZXBhcmF0b3IpOworCWlmIChqIDwgMCkgeworCS8qIE5vIC12ZSBwYXR0ZXJuIHByZXNlbnQsIHNvIHVzZSBkZWZhdWx0IHNpZ25pbmcgKi8KKwkgICAgZGVmYXVsdF9zaWduID0gMTsKKwl9CisJZWxzZSB7CisJICAgIC8qIFNraXAgb3ZlciBwYXR0ZXJuIHNlcGFyYXRvciAoYWNjb3VudGluZyBmb3IgVVRGOCkgKi8KKwkgICAgdGhlX2Zvcm1hdCA9ICh4bWxDaGFyICopeG1sVVRGOFN0cnBvcyhmb3JtYXQsIGogKyAxKTsKKwkgICAgLyogCisJICAgICAqIEZsYWcgY2hhbmdlcyBpbnRlcnByZXRhdGlvbiBvZiBwZXJjZW50L3Blcm1pbGxlIAorCSAgICAgKiBpbiAtdmUgcGF0dGVybiAKKwkgICAgICovCisJICAgIGZvcm1hdF9pbmZvLmlzX25lZ2F0aXZlX3BhdHRlcm4gPSBUUlVFOworCSAgICBmb3JtYXRfaW5mby5pc19tdWx0aXBsaWVyX3NldCA9IEZBTFNFOworCisJICAgIC8qIEZpcnN0IGRvIHRoZSAtdmUgcHJlZml4ICovCisJICAgIG5wcmVmaXggPSB0aGVfZm9ybWF0OworCSAgICBucHJlZml4X2xlbmd0aCA9IHhzbHRGb3JtYXROdW1iZXJQcmVTdWZmaXgoc2VsZiwgCisJICAgIAkJCQkmdGhlX2Zvcm1hdCwgJmZvcm1hdF9pbmZvKTsKKwkgICAgaWYgKG5wcmVmaXhfbGVuZ3RoPDApIHsKKwkJZm91bmRfZXJyb3IgPSAxOworCQlnb3RvIE9VVFBVVF9OVU1CRVI7CisJICAgIH0KKworCSAgICB3aGlsZSAoKnRoZV9mb3JtYXQgIT0gMCkgeworCQlpZiAoICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgKHNlbGYpLT5wZXJjZW50KSA9PSAwKSB8fAorCQkgICAgICh4c2x0VVRGOENoYXJjbXAodGhlX2Zvcm1hdCwgKHNlbGYpLT5wZXJtaWxsZSk9PSAwKSApIHsKKwkJICAgIGlmIChmb3JtYXRfaW5mby5pc19tdWx0aXBsaWVyX3NldCkgeworCQkJZm91bmRfZXJyb3IgPSAxOworCQkJZ290byBPVVRQVVRfTlVNQkVSOworCQkgICAgfQorCQkgICAgZm9ybWF0X2luZm8uaXNfbXVsdGlwbGllcl9zZXQgPSBUUlVFOworCQkgICAgZGVsYXllZF9tdWx0aXBsaWVyID0gMTsKKwkJfQorCQllbHNlIGlmIChJU19TUEVDSUFMKHNlbGYsIHRoZV9mb3JtYXQpKQorCQkgICAgZGVsYXllZF9tdWx0aXBsaWVyID0gMDsKKwkJZWxzZQorCQkgICAgYnJlYWs7IC8qIHdoaWxlICovCisJCWlmICgobGVuID0geHNsdFVURjhTaXplKHRoZV9mb3JtYXQpKSA8IDEpIHsKKwkJICAgIGZvdW5kX2Vycm9yID0gMTsKKwkJICAgIGdvdG8gT1VUUFVUX05VTUJFUjsKKwkJfQorCQl0aGVfZm9ybWF0ICs9IGxlbjsKKwkgICAgfQorCSAgICBpZiAoZGVsYXllZF9tdWx0aXBsaWVyICE9IDApIHsKKwkJZm9ybWF0X2luZm8uaXNfbXVsdGlwbGllcl9zZXQgPSBGQUxTRTsKKwkJdGhlX2Zvcm1hdCAtPSBsZW47CisJICAgIH0KKworCSAgICAvKiBGaW5hbGx5IGRvIHRoZSAtdmUgc3VmZml4ICovCisJICAgIGlmICgqdGhlX2Zvcm1hdCAhPSAwKSB7CisJCW5zdWZmaXggPSB0aGVfZm9ybWF0OworCQluc3VmZml4X2xlbmd0aCA9IHhzbHRGb3JtYXROdW1iZXJQcmVTdWZmaXgoc2VsZiwgCisJCQkJCSZ0aGVfZm9ybWF0LCAmZm9ybWF0X2luZm8pOworCQlpZiAobnN1ZmZpeF9sZW5ndGggPCAwKSB7CisJCSAgICBmb3VuZF9lcnJvciA9IDE7CisJCSAgICBnb3RvIE9VVFBVVF9OVU1CRVI7CisJCX0KKwkgICAgfQorCSAgICBlbHNlCisJCW5zdWZmaXhfbGVuZ3RoID0gMDsKKwkgICAgaWYgKCp0aGVfZm9ybWF0ICE9IDApIHsKKwkJZm91bmRfZXJyb3IgPSAxOworCQlnb3RvIE9VVFBVVF9OVU1CRVI7CisJICAgIH0KKwkgICAgLyoKKwkgICAgICogSGVyZSdzIGFub3RoZXIgSmF2YSBwZWN1bGlhcml0eToKKwkgICAgICogaWYgLXZlIHByZWZpeC9zdWZmaXggPT0gK3ZlIG9uZXMsIGRpc2NhcmQgJiB1c2UgZGVmYXVsdAorCSAgICAgKi8KKwkgICAgaWYgKChucHJlZml4X2xlbmd0aCAhPSBwcmVmaXhfbGVuZ3RoKSB8fAorCSAgICAJKG5zdWZmaXhfbGVuZ3RoICE9IHN1ZmZpeF9sZW5ndGgpIHx8CisJCSgobnByZWZpeF9sZW5ndGggPiAwKSAmJiAKKwkJICh4bWxTdHJuY21wKG5wcmVmaXgsIHByZWZpeCwgcHJlZml4X2xlbmd0aCkgIT0wICkpIHx8CisJCSgobnN1ZmZpeF9sZW5ndGggPiAwKSAmJiAKKwkJICh4bWxTdHJuY21wKG5zdWZmaXgsIHN1ZmZpeCwgc3VmZml4X2xlbmd0aCkgIT0wICkpKSB7CisJIAlwcmVmaXggPSBucHJlZml4OworCQlwcmVmaXhfbGVuZ3RoID0gbnByZWZpeF9sZW5ndGg7CisJCXN1ZmZpeCA9IG5zdWZmaXg7CisJCXN1ZmZpeF9sZW5ndGggPSBuc3VmZml4X2xlbmd0aDsKKwkgICAgfSAvKiBlbHNlIHsKKwkJZGVmYXVsdF9zaWduID0gMTsKKwkgICAgfQorCSAgICAqLworCX0KKyAgICB9CisKK09VVFBVVF9OVU1CRVI6CisgICAgaWYgKGZvdW5kX2Vycm9yICE9IDApIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKyAgICAgICAgICAgICAgICAieHNsdEZvcm1hdE51bWJlckNvbnZlcnNpb24gOiAiCisJCSJlcnJvciBpbiBmb3JtYXQgc3RyaW5nICclcycsIHVzaW5nIGRlZmF1bHRcbiIsIGZvcm1hdCk7CisJZGVmYXVsdF9zaWduID0gKG51bWJlciA8IDAuMCkgPyAxIDogMDsKKwlwcmVmaXhfbGVuZ3RoID0gc3VmZml4X2xlbmd0aCA9IDA7CisJZm9ybWF0X2luZm8uaW50ZWdlcl9oYXNoID0gMDsKKwlmb3JtYXRfaW5mby5pbnRlZ2VyX2RpZ2l0cyA9IDE7CisJZm9ybWF0X2luZm8uZnJhY19kaWdpdHMgPSAxOworCWZvcm1hdF9pbmZvLmZyYWNfaGFzaCA9IDQ7CisJZm9ybWF0X2luZm8uZ3JvdXAgPSAtMTsKKwlmb3JtYXRfaW5mby5tdWx0aXBsaWVyID0gMTsKKwlmb3JtYXRfaW5mby5hZGRfZGVjaW1hbCA9IFRSVUU7CisgICAgfQorCisgICAgLyogUmVhZHkgdG8gb3V0cHV0IG91ciBudW1iZXIuICBGaXJzdCBzZWUgaWYgImRlZmF1bHQgc2lnbiIgaXMgcmVxdWlyZWQgKi8KKyAgICBpZiAoZGVmYXVsdF9zaWduICE9IDApCisJeG1sQnVmZmVyQWRkKGJ1ZmZlciwgc2VsZi0+bWludXNTaWduLCB4c2x0VVRGOFNpemUoc2VsZi0+bWludXNTaWduKSk7CisKKyAgICAvKiBQdXQgdGhlIHByZWZpeCBpbnRvIHRoZSBidWZmZXIgKi8KKyAgICBmb3IgKGogPSAwOyBqIDwgcHJlZml4X2xlbmd0aDsgaisrKSB7CisJaWYgKChwY2hhciA9ICpwcmVmaXgrKykgPT0gU1lNQk9MX1FVT1RFKSB7CisJICAgIGxlbiA9IHhzbHRVVEY4U2l6ZShwcmVmaXgpOworCSAgICB4bWxCdWZmZXJBZGQoYnVmZmVyLCBwcmVmaXgsIGxlbik7CisJICAgIHByZWZpeCArPSBsZW47CisJICAgIGogKz0gbGVuIC0gMTsJLyogbGVuZ3RoIG9mIHN5bWJvbCBsZXNzIGxlbmd0aCBvZiBxdW90ZSAqLworCX0gZWxzZQorCSAgICB4bWxCdWZmZXJBZGQoYnVmZmVyLCAmcGNoYXIsIDEpOworICAgIH0KKworICAgIC8qIE5leHQgZG8gdGhlIGludGVnZXIgcGFydCBvZiB0aGUgbnVtYmVyICovCisgICAgbnVtYmVyID0gZmFicyhudW1iZXIpICogKGRvdWJsZSlmb3JtYXRfaW5mby5tdWx0aXBsaWVyOworICAgIHNjYWxlID0gcG93KDEwLjAsIChkb3VibGUpKGZvcm1hdF9pbmZvLmZyYWNfZGlnaXRzICsgZm9ybWF0X2luZm8uZnJhY19oYXNoKSk7CisgICAgbnVtYmVyID0gZmxvb3IoKHNjYWxlICogbnVtYmVyICsgMC41KSkgLyBzY2FsZTsKKyAgICBpZiAoKHNlbGYtPmdyb3VwaW5nICE9IE5VTEwpICYmIAorICAgICAgICAoc2VsZi0+Z3JvdXBpbmdbMF0gIT0gMCkpIHsKKwkKKwlsZW4gPSB4bWxTdHJsZW4oc2VsZi0+Z3JvdXBpbmcpOworCXBjaGFyID0geHNsdEdldFVURjhDaGFyKHNlbGYtPmdyb3VwaW5nLCAmbGVuKTsKKwl4c2x0TnVtYmVyRm9ybWF0RGVjaW1hbChidWZmZXIsIGZsb29yKG51bWJlciksIHNlbGYtPnplcm9EaWdpdFswXSwKKwkJCQlmb3JtYXRfaW5mby5pbnRlZ2VyX2RpZ2l0cywKKwkJCQlmb3JtYXRfaW5mby5ncm91cCwKKwkJCQlwY2hhciwgbGVuKTsKKyAgICB9IGVsc2UKKwl4c2x0TnVtYmVyRm9ybWF0RGVjaW1hbChidWZmZXIsIGZsb29yKG51bWJlciksIHNlbGYtPnplcm9EaWdpdFswXSwKKwkJCQlmb3JtYXRfaW5mby5pbnRlZ2VyX2RpZ2l0cywKKwkJCQlmb3JtYXRfaW5mby5ncm91cCwKKwkJCQknLCcsIDEpOworCisgICAgLyogU3BlY2lhbCBjYXNlOiBqYXZhIHRyZWF0cyAnLiMnIGxpa2UgJy4wJywgJy4jIycgbGlrZSAnLjAjJywgZXRjLiAqLworICAgIGlmICgoZm9ybWF0X2luZm8uaW50ZWdlcl9kaWdpdHMgKyBmb3JtYXRfaW5mby5pbnRlZ2VyX2hhc2ggKworCSBmb3JtYXRfaW5mby5mcmFjX2RpZ2l0cyA9PSAwKSAmJiAoZm9ybWF0X2luZm8uZnJhY19oYXNoID4gMCkpIHsKKyAgICAgICAgKytmb3JtYXRfaW5mby5mcmFjX2RpZ2l0czsKKwktLWZvcm1hdF9pbmZvLmZyYWNfaGFzaDsKKyAgICB9CisKKyAgICAvKiBBZGQgbGVhZGluZyB6ZXJvLCBpZiByZXF1aXJlZCAqLworICAgIGlmICgoZmxvb3IobnVtYmVyKSA9PSAwKSAmJgorCShmb3JtYXRfaW5mby5pbnRlZ2VyX2RpZ2l0cyArIGZvcm1hdF9pbmZvLmZyYWNfZGlnaXRzID09IDApKSB7CisgICAgICAgIHhtbEJ1ZmZlckFkZChidWZmZXIsIHNlbGYtPnplcm9EaWdpdCwgeHNsdFVURjhTaXplKHNlbGYtPnplcm9EaWdpdCkpOworICAgIH0KKworICAgIC8qIE5leHQgdGhlIGZyYWN0aW9uYWwgcGFydCwgaWYgcmVxdWlyZWQgKi8KKyAgICBpZiAoZm9ybWF0X2luZm8uZnJhY19kaWdpdHMgKyBmb3JtYXRfaW5mby5mcmFjX2hhc2ggPT0gMCkgeworICAgICAgICBpZiAoZm9ybWF0X2luZm8uYWRkX2RlY2ltYWwpCisJICAgIHhtbEJ1ZmZlckFkZChidWZmZXIsIHNlbGYtPmRlY2ltYWxQb2ludCwgCisJICAgIAkJIHhzbHRVVEY4U2l6ZShzZWxmLT5kZWNpbWFsUG9pbnQpKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICBudW1iZXIgLT0gZmxvb3IobnVtYmVyKTsKKwlpZiAoKG51bWJlciAhPSAwKSB8fCAoZm9ybWF0X2luZm8uZnJhY19kaWdpdHMgIT0gMCkpIHsKKwkgICAgeG1sQnVmZmVyQWRkKGJ1ZmZlciwgc2VsZi0+ZGVjaW1hbFBvaW50LAorCSAgICAJCSB4c2x0VVRGOFNpemUoc2VsZi0+ZGVjaW1hbFBvaW50KSk7CisJICAgIG51bWJlciA9IGZsb29yKHNjYWxlICogbnVtYmVyICsgMC41KTsKKwkgICAgZm9yIChqID0gZm9ybWF0X2luZm8uZnJhY19oYXNoOyBqID4gMDsgai0tKSB7CisJCWlmIChmbW9kKG51bWJlciwgMTAuMCkgPj0gMS4wKQorCQkgICAgYnJlYWs7IC8qIGZvciAqLworCQludW1iZXIgLz0gMTAuMDsKKwkgICAgfQorCSAgICB4c2x0TnVtYmVyRm9ybWF0RGVjaW1hbChidWZmZXIsIGZsb29yKG51bWJlciksIHNlbGYtPnplcm9EaWdpdFswXSwKKwkJCQlmb3JtYXRfaW5mby5mcmFjX2RpZ2l0cyArIGosCisJCQkJMCwgMCwgMCk7CisJfQorICAgIH0KKyAgICAvKiBQdXQgdGhlIHN1ZmZpeCBpbnRvIHRoZSBidWZmZXIgKi8KKyAgICBmb3IgKGogPSAwOyBqIDwgc3VmZml4X2xlbmd0aDsgaisrKSB7CisJaWYgKChwY2hhciA9ICpzdWZmaXgrKykgPT0gU1lNQk9MX1FVT1RFKSB7CisgICAgICAgICAgICBsZW4gPSB4c2x0VVRGOFNpemUoc3VmZml4KTsKKwkgICAgeG1sQnVmZmVyQWRkKGJ1ZmZlciwgc3VmZml4LCBsZW4pOworCSAgICBzdWZmaXggKz0gbGVuOworCSAgICBqICs9IGxlbiAtIDE7CS8qIGxlbmd0aCBvZiBzeW1ib2wgbGVzcyBsZW5ndGggb2YgZXNjYXBlICovCisJfSBlbHNlCisJICAgIHhtbEJ1ZmZlckFkZChidWZmZXIsICZwY2hhciwgMSk7CisgICAgfQorCisgICAgKnJlc3VsdCA9IHhtbFN0cmR1cCh4bWxCdWZmZXJDb250ZW50KGJ1ZmZlcikpOworICAgIHhtbEJ1ZmZlckZyZWUoYnVmZmVyKTsKKyAgICByZXR1cm4gc3RhdHVzOworfQorCmRpZmYgLS1naXQgYS9saWJ4c2x0L251bWJlcnNJbnRlcm5hbHMuaCBiL2xpYnhzbHQvbnVtYmVyc0ludGVybmFscy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiM2NiMTcKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L251bWJlcnNJbnRlcm5hbHMuaApAQCAtMCwwICsxLDY5IEBACisvKgorICogU3VtbWFyeTogSW1wbGVtZW50YXRpb24gb2YgdGhlIFhTTFQgbnVtYmVyIGZ1bmN0aW9ucworICogRGVzY3JpcHRpb246IEltcGxlbWVudGF0aW9uIG9mIHRoZSBYU0xUIG51bWJlciBmdW5jdGlvbnMKKyAqCisgKiBDb3B5OiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCisgKgorICogQXV0aG9yOiBCam9ybiBSZWVzZSA8YnJlZXNlQHVzZXJzLnNvdXJjZWZvcmdlLm5ldD4gYW5kIERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVF9OVU1CRVJTSU5URVJOQUxTX0hfXworI2RlZmluZSBfX1hNTF9YU0xUX05VTUJFUlNJTlRFUk5BTFNfSF9fCisKKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgInhzbHRleHBvcnRzLmgiCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyoqCisgKiB4c2x0TnVtYmVyRGF0YToKKyAqCisgKiBUaGlzIGRhdGEgc3RydWN0dXJlIGlzIGp1c3QgYSB3cmFwcGVyIHRvIHBhc3MgeHNsOm51bWJlciBkYXRhIGluLgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdE51bWJlckRhdGEgeHNsdE51bWJlckRhdGE7Cit0eXBlZGVmIHhzbHROdW1iZXJEYXRhICp4c2x0TnVtYmVyRGF0YVB0cjsKKyAgICAKK3N0cnVjdCBfeHNsdE51bWJlckRhdGEgeworICAgIGNvbnN0IHhtbENoYXIgKmxldmVsOworICAgIGNvbnN0IHhtbENoYXIgKmNvdW50OworICAgIGNvbnN0IHhtbENoYXIgKmZyb207CisgICAgY29uc3QgeG1sQ2hhciAqdmFsdWU7CisgICAgY29uc3QgeG1sQ2hhciAqZm9ybWF0OworICAgIGludCBoYXNfZm9ybWF0OworICAgIGludCBkaWdpdHNQZXJHcm91cDsKKyAgICBpbnQgZ3JvdXBpbmdDaGFyYWN0ZXI7CisgICAgaW50IGdyb3VwaW5nQ2hhcmFjdGVyTGVuOworICAgIHhtbERvY1B0ciBkb2M7CisgICAgeG1sTm9kZVB0ciBub2RlOworCisgICAgLyoKKyAgICAgKiBhY2NlbGVyYXRvcnMKKyAgICAgKi8KK307CisKKy8qKgorICogeHNsdEZvcm1hdE51bWJlckluZm8sOgorICoKKyAqIFRoaXMgZGF0YSBzdHJ1Y3R1cmUgbGlzdHMgdGhlIHZhcmlvdXMgcGFyYW1ldGVycyBuZWVkZWQgdG8gZm9ybWF0IG51bWJlcnMuCisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0Rm9ybWF0TnVtYmVySW5mbyB4c2x0Rm9ybWF0TnVtYmVySW5mbzsKK3R5cGVkZWYgeHNsdEZvcm1hdE51bWJlckluZm8gKnhzbHRGb3JtYXROdW1iZXJJbmZvUHRyOworCitzdHJ1Y3QgX3hzbHRGb3JtYXROdW1iZXJJbmZvIHsKKyAgICBpbnQJICAgIGludGVnZXJfaGFzaDsJLyogTnVtYmVyIG9mICcjJyBpbiBpbnRlZ2VyIHBhcnQgKi8KKyAgICBpbnQJICAgIGludGVnZXJfZGlnaXRzOwkvKiBOdW1iZXIgb2YgJzAnIGluIGludGVnZXIgcGFydCAqLworICAgIGludAkgICAgZnJhY19kaWdpdHM7CS8qIE51bWJlciBvZiAnMCcgaW4gZnJhY3Rpb25hbCBwYXJ0ICovCisgICAgaW50CSAgICBmcmFjX2hhc2g7CQkvKiBOdW1iZXIgb2YgJyMnIGluIGZyYWN0aW9uYWwgcGFydCAqLworICAgIGludAkgICAgZ3JvdXA7CQkvKiBOdW1iZXIgb2YgY2hhcnMgcGVyIGRpc3BsYXkgJ2dyb3VwJyAqLworICAgIGludCAgICAgbXVsdGlwbGllcjsJCS8qIFNjYWxpbmcgZm9yIHBlcmNlbnQgb3IgcGVybWlsbGUgKi8KKyAgICBjaGFyICAgIGFkZF9kZWNpbWFsOwkvKiBGbGFnIGZvciB3aGV0aGVyIGRlY2ltYWwgcG9pbnQgYXBwZWFycyBpbiBwYXR0ZXJuICovCisgICAgY2hhciAgICBpc19tdWx0aXBsaWVyX3NldDsJLyogRmxhZyB0byBjYXRjaCBtdWx0aXBsZSBvY2N1cmVuY2VzIG9mIHBlcmNlbnQvcGVybWlsbGUgKi8KKyAgICBjaGFyICAgIGlzX25lZ2F0aXZlX3BhdHRlcm47LyogRmxhZyBmb3IgcHJvY2Vzc2luZyAtdmUgcHJlZml4L3N1ZmZpeCAqLworfTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9CisjZW5kaWYKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX05VTUJFUlNJTlRFUk5BTFNfSF9fICovCmRpZmYgLS1naXQgYS9saWJ4c2x0L3BhdHRlcm4uYyBiL2xpYnhzbHQvcGF0dGVybi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjZTc0ZTMKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L3BhdHRlcm4uYwpAQCAtMCwwICsxLDI1MDkgQEAKKy8qCisgKiBwYXR0ZXJuLmM6IEltcGxlbWV0YXRpb24gb2YgdGhlIHRlbXBsYXRlIG1hdGNoIGNvbXBpbGF0aW9uIGFuZCBsb29rdXAKKyAqCisgKiBSZWZlcmVuY2U6CisgKiAgIGh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhzbHQtMTk5OTExMTYKKyAqCisgKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCisgKgorICogZGFuaWVsQHZlaWxsYXJkLmNvbQorICovCisKKy8qCisgKiBUT0RPOiBoYW5kbGUgcGF0aG9sb2dpY2FsIGNhc2VzIGxpa2UgKlsqW0BhPSJiIl1dCisgKiBUT0RPOiBkZXRlY3QgW251bWJlcl0gYXQgY29tcGlsYXRpb24sIG9wdGltaXplIGFjY29yZGluZ2x5CisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CisjaW5jbHVkZSA8bGlieG1sL3RyZWUuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdmFsaWQuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvaGFzaC5oPgorI2luY2x1ZGUgPGxpYnhtbC94bWxlcnJvci5oPgorI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KKyNpbmNsdWRlICJ4c2x0LmgiCisjaW5jbHVkZSAieHNsdEludGVybmFscy5oIgorI2luY2x1ZGUgInhzbHR1dGlscy5oIgorI2luY2x1ZGUgImltcG9ydHMuaCIKKyNpbmNsdWRlICJ0ZW1wbGF0ZXMuaCIKKyNpbmNsdWRlICJrZXlzLmgiCisjaW5jbHVkZSAicGF0dGVybi5oIgorI2luY2x1ZGUgImRvY3VtZW50cy5oIgorCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHCisjZGVmaW5lIFdJVEhfWFNMVF9ERUJVR19QQVRURVJOCisjZW5kaWYKKworLyoKKyAqIFR5cGVzIGFyZSBwcml2YXRlOgorICovCisKK3R5cGVkZWYgZW51bSB7CisgICAgWFNMVF9PUF9FTkQ9MCwKKyAgICBYU0xUX09QX1JPT1QsCisgICAgWFNMVF9PUF9FTEVNLAorICAgIFhTTFRfT1BfQVRUUiwKKyAgICBYU0xUX09QX1BBUkVOVCwKKyAgICBYU0xUX09QX0FOQ0VTVE9SLAorICAgIFhTTFRfT1BfSUQsCisgICAgWFNMVF9PUF9LRVksCisgICAgWFNMVF9PUF9OUywKKyAgICBYU0xUX09QX0FMTCwKKyAgICBYU0xUX09QX1BJLAorICAgIFhTTFRfT1BfQ09NTUVOVCwKKyAgICBYU0xUX09QX1RFWFQsCisgICAgWFNMVF9PUF9OT0RFLAorICAgIFhTTFRfT1BfUFJFRElDQVRFCit9IHhzbHRPcDsKKwordHlwZWRlZiBlbnVtIHsKKyAgICBBWElTX0NISUxEPTEsCisgICAgQVhJU19BVFRSSUJVVEUKK30geHNsdEF4aXM7CisKK3R5cGVkZWYgc3RydWN0IF94c2x0U3RlcFN0YXRlIHhzbHRTdGVwU3RhdGU7Cit0eXBlZGVmIHhzbHRTdGVwU3RhdGUgKnhzbHRTdGVwU3RhdGVQdHI7CitzdHJ1Y3QgX3hzbHRTdGVwU3RhdGUgeworICAgIGludCBzdGVwOworICAgIHhtbE5vZGVQdHIgbm9kZTsKK307CisKK3R5cGVkZWYgc3RydWN0IF94c2x0U3RlcFN0YXRlcyB4c2x0U3RlcFN0YXRlczsKK3R5cGVkZWYgeHNsdFN0ZXBTdGF0ZXMgKnhzbHRTdGVwU3RhdGVzUHRyOworc3RydWN0IF94c2x0U3RlcFN0YXRlcyB7CisgICAgaW50IG5ic3RhdGVzOworICAgIGludCBtYXhzdGF0ZXM7CisgICAgeHNsdFN0ZXBTdGF0ZVB0ciBzdGF0ZXM7Cit9OworCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0ZXBPcCB4c2x0U3RlcE9wOwordHlwZWRlZiB4c2x0U3RlcE9wICp4c2x0U3RlcE9wUHRyOworc3RydWN0IF94c2x0U3RlcE9wIHsKKyAgICB4c2x0T3Agb3A7CisgICAgeG1sQ2hhciAqdmFsdWU7CisgICAgeG1sQ2hhciAqdmFsdWUyOworICAgIHhtbENoYXIgKnZhbHVlMzsKKyAgICB4bWxYUGF0aENvbXBFeHByUHRyIGNvbXA7CisgICAgLyoKKyAgICAgKiBPcHRpbWlzYXRpb25zIGZvciBjb3VudAorICAgICAqLworICAgIGludCAgICAgICAgcHJldmlvdXNFeHRyYTsKKyAgICBpbnQgICAgICAgIGluZGV4RXh0cmE7CisgICAgaW50ICAgICAgICBsZW5FeHRyYTsKK307CisKK3N0cnVjdCBfeHNsdENvbXBNYXRjaCB7CisgICAgc3RydWN0IF94c2x0Q29tcE1hdGNoICpuZXh0OyAvKiBzaWJsaW5ncyBpbiB0aGUgbmFtZSBoYXNoICovCisgICAgZmxvYXQgcHJpb3JpdHk7ICAgICAgICAgICAgICAvKiB0aGUgcHJpb3JpdHkgKi8KKyAgICBjb25zdCB4bWxDaGFyICpwYXR0ZXJuOyAgICAgICAvKiB0aGUgcGF0dGVybiAqLworICAgIGNvbnN0IHhtbENoYXIgKm1vZGU7ICAgICAgICAgLyogdGhlIG1vZGUgKi8KKyAgICBjb25zdCB4bWxDaGFyICptb2RlVVJJOyAgICAgIC8qIHRoZSBtb2RlIFVSSSAqLworICAgIHhzbHRUZW1wbGF0ZVB0ciB0ZW1wbGF0ZTsgICAgLyogdGhlIGFzc29jaWF0ZWQgdGVtcGxhdGUgKi8KKworICAgIGludCBkaXJlY3Q7CisgICAgLyogVE9ETyBmaXggdGhlIHN0YXRpY2FsbHkgYWxsb2NhdGVkIHNpemUgc3RlcHNbXSAqLworICAgIGludCBuYlN0ZXA7CisgICAgaW50IG1heFN0ZXA7CisgICAgeG1sTnNQdHIgKm5zTGlzdDsJCS8qIHRoZSBuYW1lc3BhY2VzIGluIHNjb3BlICovCisgICAgaW50IG5zTnI7CQkJLyogdGhlIG51bWJlciBvZiBuYW1lc3BhY2VzIGluIHNjb3BlICovCisgICAgeHNsdFN0ZXBPcFB0ciBzdGVwczsgICAgICAgIC8qIG9wcyBmb3IgY29tcHV0YXRpb24gKi8KK307CisKK3R5cGVkZWYgc3RydWN0IF94c2x0UGFyc2VyQ29udGV4dCB4c2x0UGFyc2VyQ29udGV4dDsKK3R5cGVkZWYgeHNsdFBhcnNlckNvbnRleHQgKnhzbHRQYXJzZXJDb250ZXh0UHRyOworc3RydWN0IF94c2x0UGFyc2VyQ29udGV4dCB7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CQkvKiB0aGUgc3R5bGVzaGVldCAqLworICAgIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQ7CS8qIHRoZSB0cmFuc2Zvcm1hdGlvbiBvciBOVUxMICovCisgICAgY29uc3QgeG1sQ2hhciAqY3VyOwkJCS8qIHRoZSBjdXJyZW50IGNoYXIgYmVpbmcgcGFyc2VkICovCisgICAgY29uc3QgeG1sQ2hhciAqYmFzZTsJCS8qIHRoZSBmdWxsIGV4cHJlc3Npb24gKi8KKyAgICB4bWxEb2NQdHIgICAgICBkb2M7CQkJLyogdGhlIHNvdXJjZSBkb2N1bWVudCAqLworICAgIHhtbE5vZGVQdHIgICAgZWxlbTsJCQkvKiB0aGUgc291cmNlIGVsZW1lbnQgKi8KKyAgICBpbnQgZXJyb3I7CQkJCS8qIGVycm9yIGNvZGUgKi8KKyAgICB4c2x0Q29tcE1hdGNoUHRyIGNvbXA7CQkvKiB0aGUgcmVzdWx0ICovCit9OworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAJCQkJCQkJCQkqCisgKiAJCQlUeXBlIGZ1bmN0aW9ucyAJCQkJCSoKKyAqIAkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdE5ld0NvbXBNYXRjaDoKKyAqCisgKiBDcmVhdGUgYSBuZXcgWFNMVCBDb21wTWF0Y2gKKyAqCisgKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgeHNsdENvbXBNYXRjaFB0ciBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworc3RhdGljIHhzbHRDb21wTWF0Y2hQdHIKK3hzbHROZXdDb21wTWF0Y2godm9pZCkgeworICAgIHhzbHRDb21wTWF0Y2hQdHIgY3VyOworCisgICAgY3VyID0gKHhzbHRDb21wTWF0Y2hQdHIpIHhtbE1hbGxvYyhzaXplb2YoeHNsdENvbXBNYXRjaCkpOworICAgIGlmIChjdXIgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkieHNsdE5ld0NvbXBNYXRjaCA6IG91dCBvZiBtZW1vcnkgZXJyb3JcbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KGN1ciwgMCwgc2l6ZW9mKHhzbHRDb21wTWF0Y2gpKTsKKyAgICBjdXItPm1heFN0ZXAgPSAxMDsKKyAgICBjdXItPm5iU3RlcCA9IDA7CisgICAgY3VyLT4gc3RlcHMgPSAoeHNsdFN0ZXBPcFB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0U3RlcE9wKSAqCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ci0+bWF4U3RlcCk7CisgICAgaWYgKGN1ci0+c3RlcHMgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkieHNsdE5ld0NvbXBNYXRjaCA6IG91dCBvZiBtZW1vcnkgZXJyb3JcbiIpOworCXhtbEZyZWUoY3VyKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIGN1ci0+bnNOciA9IDA7CisgICAgY3VyLT5uc0xpc3QgPSBOVUxMOworICAgIGN1ci0+ZGlyZWN0ID0gMDsKKyAgICByZXR1cm4oY3VyKTsKK30KKworLyoqCisgKiB4c2x0RnJlZUNvbXBNYXRjaDoKKyAqIEBjb21wOiAgYW4gWFNMVCBjb21wCisgKgorICogRnJlZSB1cCB0aGUgbWVtb3J5IGFsbG9jYXRlZCBieSBAY29tcAorICovCitzdGF0aWMgdm9pZAoreHNsdEZyZWVDb21wTWF0Y2goeHNsdENvbXBNYXRjaFB0ciBjb21wKSB7CisgICAgeHNsdFN0ZXBPcFB0ciBvcDsKKyAgICBpbnQgaTsKKworICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworICAgIGlmIChjb21wLT5wYXR0ZXJuICE9IE5VTEwpCisJeG1sRnJlZSgoeG1sQ2hhciAqKWNvbXAtPnBhdHRlcm4pOworICAgIGlmIChjb21wLT5uc0xpc3QgIT0gTlVMTCkKKwl4bWxGcmVlKGNvbXAtPm5zTGlzdCk7CisgICAgZm9yIChpID0gMDtpIDwgY29tcC0+bmJTdGVwO2krKykgeworCW9wID0gJmNvbXAtPnN0ZXBzW2ldOworCWlmIChvcC0+dmFsdWUgIT0gTlVMTCkKKwkgICAgeG1sRnJlZShvcC0+dmFsdWUpOworCWlmIChvcC0+dmFsdWUyICE9IE5VTEwpCisJICAgIHhtbEZyZWUob3AtPnZhbHVlMik7CisJaWYgKG9wLT52YWx1ZTMgIT0gTlVMTCkKKwkgICAgeG1sRnJlZShvcC0+dmFsdWUzKTsKKwlpZiAob3AtPmNvbXAgIT0gTlVMTCkKKwkgICAgeG1sWFBhdGhGcmVlQ29tcEV4cHIob3AtPmNvbXApOworICAgIH0KKyAgICB4bWxGcmVlKGNvbXAtPnN0ZXBzKTsKKyAgICBtZW1zZXQoY29tcCwgLTEsIHNpemVvZih4c2x0Q29tcE1hdGNoKSk7CisgICAgeG1sRnJlZShjb21wKTsKK30KKworLyoqCisgKiB4c2x0RnJlZUNvbXBNYXRjaExpc3Q6CisgKiBAY29tcDogIGFuIFhTTFQgY29tcCBsaXN0CisgKgorICogRnJlZSB1cCB0aGUgbWVtb3J5IGFsbG9jYXRlZCBieSBhbGwgdGhlIGVsZW1lbnRzIG9mIEBjb21wCisgKi8KK3ZvaWQKK3hzbHRGcmVlQ29tcE1hdGNoTGlzdCh4c2x0Q29tcE1hdGNoUHRyIGNvbXApIHsKKyAgICB4c2x0Q29tcE1hdGNoUHRyIGN1cjsKKworICAgIHdoaWxlIChjb21wICE9IE5VTEwpIHsKKwljdXIgPSBjb21wOworCWNvbXAgPSBjb21wLT5uZXh0OworCXhzbHRGcmVlQ29tcE1hdGNoKGN1cik7CisgICAgfQorfQorCisvKioKKyAqIHhzbHROb3JtYWxpemVDb21wU3RlcHM6CisgKiBAcGF5bG9hZDogcG9pbnRlciB0byB0ZW1wbGF0ZSBoYXNoIHRhYmxlIGVudHJ5CisgKiBAZGF0YTogcG9pbnRlciB0byB0aGUgc3R5bGVzaGVldAorICogQG5hbWU6IHRlbXBsYXRlIG1hdGNoIG5hbWUKKyAqCisgKiBUaGlzIGlzIGEgaGFzaHRhYmxlIHNjYW5uZXIgZnVuY3Rpb24gdG8gbm9ybWFsaXplIHRoZSBjb21waWxlZAorICogc3RlcHMgb2YgYW4gaW1wb3J0ZWQgc3R5bGVzaGVldC4KKyAqLwordm9pZCB4c2x0Tm9ybWFsaXplQ29tcFN0ZXBzKHZvaWQgKnBheWxvYWQsCisgICAgICAgIHZvaWQgKmRhdGEsIGNvbnN0IHhtbENoYXIgKm5hbWUgQVRUUklCVVRFX1VOVVNFRCkgeworICAgIHhzbHRDb21wTWF0Y2hQdHIgY29tcCA9IHBheWxvYWQ7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUgPSBkYXRhOworICAgIGludCBpeDsKKworICAgIGZvciAoaXggPSAwOyBpeCA8IGNvbXAtPm5iU3RlcDsgaXgrKykgeworICAgICAgICBjb21wLT5zdGVwc1tpeF0ucHJldmlvdXNFeHRyYSArPSBzdHlsZS0+ZXh0cmFzTnI7CisgICAgICAgIGNvbXAtPnN0ZXBzW2l4XS5pbmRleEV4dHJhICs9IHN0eWxlLT5leHRyYXNOcjsKKyAgICAgICAgY29tcC0+c3RlcHNbaXhdLmxlbkV4dHJhICs9IHN0eWxlLT5leHRyYXNOcjsKKyAgICB9Cit9CisKKy8qKgorICogeHNsdE5ld1BhcnNlckNvbnRleHQ6CisgKiBAc3R5bGU6ICB0aGUgc3R5bGVzaGVldAorICogQGN0eHQ6ICB0aGUgdHJhbnNmb3JtYXRpb24gY29udGV4dCwgaWYgZG9uZSBhdCBydW4tdGltZQorICoKKyAqIENyZWF0ZSBhIG5ldyBYU0xUIFBhcnNlckNvbnRleHQKKyAqCisgKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgeHNsdFBhcnNlckNvbnRleHRQdHIgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3N0YXRpYyB4c2x0UGFyc2VyQ29udGV4dFB0cgoreHNsdE5ld1BhcnNlckNvbnRleHQoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpIHsKKyAgICB4c2x0UGFyc2VyQ29udGV4dFB0ciBjdXI7CisKKyAgICBjdXIgPSAoeHNsdFBhcnNlckNvbnRleHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeHNsdFBhcnNlckNvbnRleHQpKTsKKyAgICBpZiAoY3VyID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkJInhzbHROZXdQYXJzZXJDb250ZXh0IDogbWFsbG9jIGZhaWxlZFxuIik7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBtZW1zZXQoY3VyLCAwLCBzaXplb2YoeHNsdFBhcnNlckNvbnRleHQpKTsKKyAgICBjdXItPnN0eWxlID0gc3R5bGU7CisgICAgY3VyLT5jdHh0ID0gY3R4dDsKKyAgICByZXR1cm4oY3VyKTsKK30KKworLyoqCisgKiB4c2x0RnJlZVBhcnNlckNvbnRleHQ6CisgKiBAY3R4dDogIGFuIFhTTFQgcGFyc2VyIGNvbnRleHQKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGJ5IEBjdHh0CisgKi8KK3N0YXRpYyB2b2lkCit4c2x0RnJlZVBhcnNlckNvbnRleHQoeHNsdFBhcnNlckNvbnRleHRQdHIgY3R4dCkgeworICAgIGlmIChjdHh0ID09IE5VTEwpCisJcmV0dXJuOworICAgIG1lbXNldChjdHh0LCAtMSwgc2l6ZW9mKHhzbHRQYXJzZXJDb250ZXh0KSk7CisgICAgeG1sRnJlZShjdHh0KTsKK30KKworLyoqCisgKiB4c2x0Q29tcE1hdGNoQWRkOgorICogQGNvbXA6ICB0aGUgY29tcGlsZWQgbWF0Y2ggZXhwcmVzc2lvbgorICogQG9wOiAgYW4gb3AKKyAqIEB2YWx1ZTogIHRoZSBmaXJzdCB2YWx1ZQorICogQHZhbHVlMjogIHRoZSBzZWNvbmQgdmFsdWUKKyAqIEBub3ZhcjogIGZsYWcgdG8gc2V0IFhNTF9YUEFUSF9OT1ZBUgorICoKKyAqIEFkZCBhbiBzdGVwIHRvIGFuIFhTTFQgQ29tcGlsZWQgTWF0Y2gKKyAqCisgKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZmFpbHVyZSwgMCBvdGhlcndpc2UuCisgKi8KK3N0YXRpYyBpbnQKK3hzbHRDb21wTWF0Y2hBZGQoeHNsdFBhcnNlckNvbnRleHRQdHIgY3R4dCwgeHNsdENvbXBNYXRjaFB0ciBjb21wLAorICAgICAgICAgICAgICAgICB4c2x0T3Agb3AsIHhtbENoYXIgKiB2YWx1ZSwgeG1sQ2hhciAqIHZhbHVlMiwgaW50IG5vdmFyKQoreworICAgIGlmIChjb21wLT5uYlN0ZXAgPj0gY29tcC0+bWF4U3RlcCkgeworICAgICAgICB4c2x0U3RlcE9wUHRyIHRtcDsKKworCXRtcCA9ICh4c2x0U3RlcE9wUHRyKSB4bWxSZWFsbG9jKGNvbXAtPnN0ZXBzLCBjb21wLT5tYXhTdGVwICogMiAqCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHhzbHRTdGVwT3ApKTsKKwlpZiAodG1wID09IE5VTEwpIHsKKwkgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkgICAgICJ4c2x0Q29tcE1hdGNoQWRkOiBtZW1vcnkgcmUtYWxsb2NhdGlvbiBmYWlsdXJlLlxuIik7CisJICAgIGlmIChjdHh0LT5zdHlsZSAhPSBOVUxMKQorCQljdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJICAgIHJldHVybiAoLTEpOworCX0KKyAgICAgICAgY29tcC0+bWF4U3RlcCAqPSAyOworCWNvbXAtPnN0ZXBzID0gdG1wOworICAgIH0KKyAgICBjb21wLT5zdGVwc1tjb21wLT5uYlN0ZXBdLm9wID0gb3A7CisgICAgY29tcC0+c3RlcHNbY29tcC0+bmJTdGVwXS52YWx1ZSA9IHZhbHVlOworICAgIGNvbXAtPnN0ZXBzW2NvbXAtPm5iU3RlcF0udmFsdWUyID0gdmFsdWUyOworICAgIGNvbXAtPnN0ZXBzW2NvbXAtPm5iU3RlcF0udmFsdWUzID0gTlVMTDsKKyAgICBjb21wLT5zdGVwc1tjb21wLT5uYlN0ZXBdLmNvbXAgPSBOVUxMOworICAgIGlmIChjdHh0LT5jdHh0ICE9IE5VTEwpIHsKKwljb21wLT5zdGVwc1tjb21wLT5uYlN0ZXBdLnByZXZpb3VzRXh0cmEgPQorCSAgICB4c2x0QWxsb2NhdGVFeHRyYUN0eHQoY3R4dC0+Y3R4dCk7CisJY29tcC0+c3RlcHNbY29tcC0+bmJTdGVwXS5pbmRleEV4dHJhID0KKwkgICAgeHNsdEFsbG9jYXRlRXh0cmFDdHh0KGN0eHQtPmN0eHQpOworCWNvbXAtPnN0ZXBzW2NvbXAtPm5iU3RlcF0ubGVuRXh0cmEgPQorCSAgICB4c2x0QWxsb2NhdGVFeHRyYUN0eHQoY3R4dC0+Y3R4dCk7CisgICAgfSBlbHNlIHsKKwljb21wLT5zdGVwc1tjb21wLT5uYlN0ZXBdLnByZXZpb3VzRXh0cmEgPQorCSAgICB4c2x0QWxsb2NhdGVFeHRyYShjdHh0LT5zdHlsZSk7CisJY29tcC0+c3RlcHNbY29tcC0+bmJTdGVwXS5pbmRleEV4dHJhID0KKwkgICAgeHNsdEFsbG9jYXRlRXh0cmEoY3R4dC0+c3R5bGUpOworCWNvbXAtPnN0ZXBzW2NvbXAtPm5iU3RlcF0ubGVuRXh0cmEgPQorCSAgICB4c2x0QWxsb2NhdGVFeHRyYShjdHh0LT5zdHlsZSk7CisgICAgfQorICAgIGlmIChvcCA9PSBYU0xUX09QX1BSRURJQ0FURSkgeworCXhtbFhQYXRoQ29udGV4dFB0ciB4Y3R4dDsKKworCWlmIChjdHh0LT5zdHlsZSAhPSBOVUxMKQorCSAgICB4Y3R4dCA9IHhtbFhQYXRoTmV3Q29udGV4dChjdHh0LT5zdHlsZS0+ZG9jKTsKKwllbHNlCisJICAgIHhjdHh0ID0geG1sWFBhdGhOZXdDb250ZXh0KE5VTEwpOworI2lmZGVmIFhNTF9YUEFUSF9OT1ZBUgorCWlmIChub3ZhciAhPSAwKQorCSAgICB4Y3R4dC0+ZmxhZ3MgPSBYTUxfWFBBVEhfTk9WQVI7CisjZW5kaWYKKwlpZiAoY3R4dC0+c3R5bGUgIT0gTlVMTCkKKwkgICAgeGN0eHQtPmRpY3QgPSBjdHh0LT5zdHlsZS0+ZGljdDsKKwljb21wLT5zdGVwc1tjb21wLT5uYlN0ZXBdLmNvbXAgPSB4bWxYUGF0aEN0eHRDb21waWxlKHhjdHh0LCB2YWx1ZSk7CisJeG1sWFBhdGhGcmVlQ29udGV4dCh4Y3R4dCk7CisJaWYgKGNvbXAtPnN0ZXBzW2NvbXAtPm5iU3RlcF0uY29tcCA9PSBOVUxMKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjdHh0LT5zdHlsZSwgY3R4dC0+ZWxlbSwKKwkJICAgICJGYWlsZWQgdG8gY29tcGlsZSBwcmVkaWNhdGVcbiIpOworCSAgICBpZiAoY3R4dC0+c3R5bGUgIT0gTlVMTCkKKwkJY3R4dC0+c3R5bGUtPmVycm9ycysrOworCX0KKyAgICB9CisgICAgY29tcC0+bmJTdGVwKys7CisgICAgcmV0dXJuICgwKTsKK30KKworLyoqCisgKiB4c2x0U3dhcFRvcENvbXBNYXRjaDoKKyAqIEBjb21wOiAgdGhlIGNvbXBpbGVkIG1hdGNoIGV4cHJlc3Npb24KKyAqCisgKiByZXZlcnNlIHRoZSB0d28gdG9wIHN0ZXBzLgorICovCitzdGF0aWMgdm9pZAoreHNsdFN3YXBUb3BDb21wTWF0Y2goeHNsdENvbXBNYXRjaFB0ciBjb21wKSB7CisgICAgaW50IGk7CisgICAgaW50IGogPSBjb21wLT5uYlN0ZXAgLSAxOworCisgICAgaWYgKGogPiAwKSB7CisJcmVnaXN0ZXIgeG1sQ2hhciAqdG1wOworCXJlZ2lzdGVyIHhzbHRPcCBvcDsKKwlyZWdpc3RlciB4bWxYUGF0aENvbXBFeHByUHRyIGV4cHI7IAorCXJlZ2lzdGVyIGludCB0OworCWkgPSBqIC0gMTsKKwl0bXAgPSBjb21wLT5zdGVwc1tpXS52YWx1ZTsKKwljb21wLT5zdGVwc1tpXS52YWx1ZSA9IGNvbXAtPnN0ZXBzW2pdLnZhbHVlOworCWNvbXAtPnN0ZXBzW2pdLnZhbHVlID0gdG1wOworCXRtcCA9IGNvbXAtPnN0ZXBzW2ldLnZhbHVlMjsKKwljb21wLT5zdGVwc1tpXS52YWx1ZTIgPSBjb21wLT5zdGVwc1tqXS52YWx1ZTI7CisJY29tcC0+c3RlcHNbal0udmFsdWUyID0gdG1wOworCXRtcCA9IGNvbXAtPnN0ZXBzW2ldLnZhbHVlMzsKKwljb21wLT5zdGVwc1tpXS52YWx1ZTMgPSBjb21wLT5zdGVwc1tqXS52YWx1ZTM7CisJY29tcC0+c3RlcHNbal0udmFsdWUzID0gdG1wOworCW9wID0gY29tcC0+c3RlcHNbaV0ub3A7CisJY29tcC0+c3RlcHNbaV0ub3AgPSBjb21wLT5zdGVwc1tqXS5vcDsKKwljb21wLT5zdGVwc1tqXS5vcCA9IG9wOworCWV4cHIgPSBjb21wLT5zdGVwc1tpXS5jb21wOworCWNvbXAtPnN0ZXBzW2ldLmNvbXAgPSBjb21wLT5zdGVwc1tqXS5jb21wOworCWNvbXAtPnN0ZXBzW2pdLmNvbXAgPSBleHByOworCXQgPSBjb21wLT5zdGVwc1tpXS5wcmV2aW91c0V4dHJhOworCWNvbXAtPnN0ZXBzW2ldLnByZXZpb3VzRXh0cmEgPSBjb21wLT5zdGVwc1tqXS5wcmV2aW91c0V4dHJhOworCWNvbXAtPnN0ZXBzW2pdLnByZXZpb3VzRXh0cmEgPSB0OworCXQgPSBjb21wLT5zdGVwc1tpXS5pbmRleEV4dHJhOworCWNvbXAtPnN0ZXBzW2ldLmluZGV4RXh0cmEgPSBjb21wLT5zdGVwc1tqXS5pbmRleEV4dHJhOworCWNvbXAtPnN0ZXBzW2pdLmluZGV4RXh0cmEgPSB0OworCXQgPSBjb21wLT5zdGVwc1tpXS5sZW5FeHRyYTsKKwljb21wLT5zdGVwc1tpXS5sZW5FeHRyYSA9IGNvbXAtPnN0ZXBzW2pdLmxlbkV4dHJhOworCWNvbXAtPnN0ZXBzW2pdLmxlbkV4dHJhID0gdDsKKyAgICB9Cit9CisKKy8qKgorICogeHNsdFJldmVyc2VDb21wTWF0Y2g6CisgKiBAY3R4dDogdGhlIHBhcnNlciBjb250ZXh0CisgKiBAY29tcDogIHRoZSBjb21waWxlZCBtYXRjaCBleHByZXNzaW9uCisgKgorICogcmV2ZXJzZSBhbGwgdGhlIHN0YWNrIG9mIGV4cHJlc3Npb25zCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0UmV2ZXJzZUNvbXBNYXRjaCh4c2x0UGFyc2VyQ29udGV4dFB0ciBjdHh0LCB4c2x0Q29tcE1hdGNoUHRyIGNvbXApIHsKKyAgICBpbnQgaSA9IDA7CisgICAgaW50IGogPSBjb21wLT5uYlN0ZXAgLSAxOworCisgICAgd2hpbGUgKGogPiBpKSB7CisJcmVnaXN0ZXIgeG1sQ2hhciAqdG1wOworCXJlZ2lzdGVyIHhzbHRPcCBvcDsKKwlyZWdpc3RlciB4bWxYUGF0aENvbXBFeHByUHRyIGV4cHI7CisJcmVnaXN0ZXIgaW50IHQ7CisKKwl0bXAgPSBjb21wLT5zdGVwc1tpXS52YWx1ZTsKKwljb21wLT5zdGVwc1tpXS52YWx1ZSA9IGNvbXAtPnN0ZXBzW2pdLnZhbHVlOworCWNvbXAtPnN0ZXBzW2pdLnZhbHVlID0gdG1wOworCXRtcCA9IGNvbXAtPnN0ZXBzW2ldLnZhbHVlMjsKKwljb21wLT5zdGVwc1tpXS52YWx1ZTIgPSBjb21wLT5zdGVwc1tqXS52YWx1ZTI7CisJY29tcC0+c3RlcHNbal0udmFsdWUyID0gdG1wOworCXRtcCA9IGNvbXAtPnN0ZXBzW2ldLnZhbHVlMzsKKwljb21wLT5zdGVwc1tpXS52YWx1ZTMgPSBjb21wLT5zdGVwc1tqXS52YWx1ZTM7CisJY29tcC0+c3RlcHNbal0udmFsdWUzID0gdG1wOworCW9wID0gY29tcC0+c3RlcHNbaV0ub3A7CisJY29tcC0+c3RlcHNbaV0ub3AgPSBjb21wLT5zdGVwc1tqXS5vcDsKKwljb21wLT5zdGVwc1tqXS5vcCA9IG9wOworCWV4cHIgPSBjb21wLT5zdGVwc1tpXS5jb21wOworCWNvbXAtPnN0ZXBzW2ldLmNvbXAgPSBjb21wLT5zdGVwc1tqXS5jb21wOworCWNvbXAtPnN0ZXBzW2pdLmNvbXAgPSBleHByOworCXQgPSBjb21wLT5zdGVwc1tpXS5wcmV2aW91c0V4dHJhOworCWNvbXAtPnN0ZXBzW2ldLnByZXZpb3VzRXh0cmEgPSBjb21wLT5zdGVwc1tqXS5wcmV2aW91c0V4dHJhOworCWNvbXAtPnN0ZXBzW2pdLnByZXZpb3VzRXh0cmEgPSB0OworCXQgPSBjb21wLT5zdGVwc1tpXS5pbmRleEV4dHJhOworCWNvbXAtPnN0ZXBzW2ldLmluZGV4RXh0cmEgPSBjb21wLT5zdGVwc1tqXS5pbmRleEV4dHJhOworCWNvbXAtPnN0ZXBzW2pdLmluZGV4RXh0cmEgPSB0OworCXQgPSBjb21wLT5zdGVwc1tpXS5sZW5FeHRyYTsKKwljb21wLT5zdGVwc1tpXS5sZW5FeHRyYSA9IGNvbXAtPnN0ZXBzW2pdLmxlbkV4dHJhOworCWNvbXAtPnN0ZXBzW2pdLmxlbkV4dHJhID0gdDsKKwlqLS07CisJaSsrOworICAgIH0KKyAgICB4c2x0Q29tcE1hdGNoQWRkKGN0eHQsIGNvbXAsIFhTTFRfT1BfRU5ELCBOVUxMLCBOVUxMLCAwKTsKKworICAgIC8qCisgICAgICogZGV0ZWN0IGNvbnNlY3V0aXZlIFhTTFRfT1BfUFJFRElDQVRFIGluZGljYXRpbmcgYSBkaXJlY3QKKyAgICAgKiBtYXRjaGluZyBzaG91bGQgYmUgZG9uZS4KKyAgICAgKi8KKyAgICBmb3IgKGkgPSAwO2kgPCBjb21wLT5uYlN0ZXAgLSAxO2krKykgeworICAgICAgICBpZiAoKGNvbXAtPnN0ZXBzW2ldLm9wID09IFhTTFRfT1BfUFJFRElDQVRFKSAmJgorCSAgICAoY29tcC0+c3RlcHNbaSArIDFdLm9wID09IFhTTFRfT1BfUFJFRElDQVRFKSkgeworCisJICAgIGNvbXAtPmRpcmVjdCA9IDE7CisJICAgIGlmIChjb21wLT5wYXR0ZXJuWzBdICE9ICcvJykgeworCQl4bWxDaGFyICpxdWVyeTsKKworCQlxdWVyeSA9IHhtbFN0cmR1cCgoY29uc3QgeG1sQ2hhciAqKSIvLyIpOworCQlxdWVyeSA9IHhtbFN0cmNhdChxdWVyeSwgY29tcC0+cGF0dGVybik7CisKKwkJeG1sRnJlZSgoeG1sQ2hhciAqKSBjb21wLT5wYXR0ZXJuKTsKKwkJY29tcC0+cGF0dGVybiA9IHF1ZXJ5OworCSAgICB9CisJICAgIGJyZWFrOworCX0KKyAgICB9Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJVGhlIGludGVycHJldGVyIGZvciB0aGUgcHJlY29tcGlsZWQgcGF0dGVybnMJCSoKKyAqIAkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3N0YXRpYyBpbnQKK3hzbHRQYXRQdXNoU3RhdGUoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeHNsdFN0ZXBTdGF0ZXMgKnN0YXRlcywKKyAgICAgICAgICAgICAgICAgaW50IHN0ZXAsIHhtbE5vZGVQdHIgbm9kZSkgeworICAgIGlmICgoc3RhdGVzLT5zdGF0ZXMgPT0gTlVMTCkgfHwgKHN0YXRlcy0+bWF4c3RhdGVzIDw9IDApKSB7CisgICAgICAgIHN0YXRlcy0+bWF4c3RhdGVzID0gNDsKKwlzdGF0ZXMtPm5ic3RhdGVzID0gMDsKKwlzdGF0ZXMtPnN0YXRlcyA9IHhtbE1hbGxvYyg0ICogc2l6ZW9mKHhzbHRTdGVwU3RhdGUpKTsKKyAgICB9CisgICAgZWxzZSBpZiAoc3RhdGVzLT5tYXhzdGF0ZXMgPD0gc3RhdGVzLT5uYnN0YXRlcykgeworICAgICAgICB4c2x0U3RlcFN0YXRlICp0bXA7CisKKwl0bXAgPSAoeHNsdFN0ZXBTdGF0ZVB0cikgeG1sUmVhbGxvYyhzdGF0ZXMtPnN0YXRlcywKKwkJCSAgICAgICAyICogc3RhdGVzLT5tYXhzdGF0ZXMgKiBzaXplb2YoeHNsdFN0ZXBTdGF0ZSkpOworCWlmICh0bXAgPT0gTlVMTCkgeworCSAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LAorCSAgICAgInhzbHRQYXRQdXNoU3RhdGU6IG1lbW9yeSByZS1hbGxvY2F0aW9uIGZhaWx1cmUuXG4iKTsKKwkgICAgY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisJICAgIHJldHVybigtMSk7CisJfQorCXN0YXRlcy0+c3RhdGVzID0gdG1wOworCXN0YXRlcy0+bWF4c3RhdGVzICo9IDI7CisgICAgfQorICAgIHN0YXRlcy0+c3RhdGVzW3N0YXRlcy0+bmJzdGF0ZXNdLnN0ZXAgPSBzdGVwOworICAgIHN0YXRlcy0+c3RhdGVzW3N0YXRlcy0+bmJzdGF0ZXMrK10ubm9kZSA9IG5vZGU7CisjaWYgMAorICAgIGZwcmludGYoc3RkZXJyLCAiUHVzaDogJWQsICVzXG4iLCBzdGVwLCBub2RlLT5uYW1lKTsKKyNlbmRpZgorICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0VGVzdENvbXBNYXRjaERpcmVjdDoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQGNvbXA6IHRoZSBwcmVjb21waWxlZCBwYXR0ZXJuCisgKiBAbm9kZTogYSBub2RlCisgKiBAbnNMaXN0OiB0aGUgbmFtZXNwYWNlcyBpbiBzY29wZQorICogQG5zTnI6IHRoZSBudW1iZXIgb2YgbmFtZXNwYWNlcyBpbiBzY29wZQorICoKKyAqIFRlc3Qgd2hldGhlciB0aGUgbm9kZSBtYXRjaGVzIHRoZSBwYXR0ZXJuLCBkbyBhIGRpcmVjdCBldmFsdXRhdGlvbgorICogYW5kIG5vdCBhIHN0ZXAgYnkgc3RlcCBldmFsdWF0aW9uLgorICoKKyAqIFJldHVybnMgMSBpZiBpdCBtYXRjaGVzLCAwIGlmIGl0IGRvZXNuJ3QgYW5kIC0xIGluIGNhc2Ugb2YgZmFpbHVyZQorICovCitzdGF0aWMgaW50Cit4c2x0VGVzdENvbXBNYXRjaERpcmVjdCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4c2x0Q29tcE1hdGNoUHRyIGNvbXAsCisJICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgeG1sTnNQdHIgKm5zTGlzdCwgaW50IG5zTnIpIHsKKyAgICB4c2x0U3RlcE9wUHRyIHNlbCA9IE5VTEw7CisgICAgeG1sRG9jUHRyIHByZXZkb2M7CisgICAgeG1sRG9jUHRyIGRvYzsKKyAgICB4bWxYUGF0aE9iamVjdFB0ciBsaXN0OworICAgIGludCBpeCwgajsKKyAgICBpbnQgbm9jYWNoZSA9IDA7CisgICAgaW50IGlzUlZUOworCisgICAgZG9jID0gbm9kZS0+ZG9jOworICAgIGlmIChYU0xUX0lTX1JFU19UUkVFX0ZSQUcoZG9jKSkKKwlpc1JWVCA9IDE7CisgICAgZWxzZQorCWlzUlZUID0gMDsKKyAgICBzZWwgPSAmY29tcC0+c3RlcHNbMF07IC8qIHN0b3JlIGV4dHJhIGluIGZpcnN0IHN0ZXAgYXJiaXRyYXJpbHkgKi8KKworICAgIHByZXZkb2MgPSAoeG1sRG9jUHRyKQorCVhTTFRfUlVOVElNRV9FWFRSQShjdHh0LCBzZWwtPnByZXZpb3VzRXh0cmEsIHB0cik7CisgICAgaXggPSBYU0xUX1JVTlRJTUVfRVhUUkEoY3R4dCwgc2VsLT5pbmRleEV4dHJhLCBpdmFsKTsKKyAgICBsaXN0ID0gKHhtbFhQYXRoT2JqZWN0UHRyKQorCVhTTFRfUlVOVElNRV9FWFRSQV9MU1QoY3R4dCwgc2VsLT5sZW5FeHRyYSk7CisgICAgCisgICAgaWYgKChsaXN0ID09IE5VTEwpIHx8IChwcmV2ZG9jICE9IGRvYykpIHsKKwl4bWxYUGF0aE9iamVjdFB0ciBuZXdsaXN0OworCXhtbE5vZGVQdHIgcGFyZW50ID0gbm9kZS0+cGFyZW50OworCXhtbERvY1B0ciBvbGRkb2M7CisJeG1sTm9kZVB0ciBvbGRub2RlOworCWludCBvbGROc05yOworCXhtbE5zUHRyICpvbGROYW1lc3BhY2VzOworCisJb2xkbm9kZSA9IGN0eHQtPnhwYXRoQ3R4dC0+bm9kZTsKKwlvbGRkb2MgPSBjdHh0LT54cGF0aEN0eHQtPmRvYzsKKwlvbGROc05yID0gY3R4dC0+eHBhdGhDdHh0LT5uc05yOworCW9sZE5hbWVzcGFjZXMgPSBjdHh0LT54cGF0aEN0eHQtPm5hbWVzcGFjZXM7CisJY3R4dC0+eHBhdGhDdHh0LT5ub2RlID0gbm9kZTsKKwljdHh0LT54cGF0aEN0eHQtPmRvYyA9IGRvYzsKKwljdHh0LT54cGF0aEN0eHQtPm5hbWVzcGFjZXMgPSBuc0xpc3Q7CisJY3R4dC0+eHBhdGhDdHh0LT5uc05yID0gbnNOcjsKKwluZXdsaXN0ID0geG1sWFBhdGhFdmFsKGNvbXAtPnBhdHRlcm4sIGN0eHQtPnhwYXRoQ3R4dCk7CisJY3R4dC0+eHBhdGhDdHh0LT5ub2RlID0gb2xkbm9kZTsKKwljdHh0LT54cGF0aEN0eHQtPmRvYyA9IG9sZGRvYzsKKwljdHh0LT54cGF0aEN0eHQtPm5hbWVzcGFjZXMgPSBvbGROYW1lc3BhY2VzOworCWN0eHQtPnhwYXRoQ3R4dC0+bnNOciA9IG9sZE5zTnI7CisJaWYgKG5ld2xpc3QgPT0gTlVMTCkKKwkgICAgcmV0dXJuKC0xKTsKKwlpZiAobmV3bGlzdC0+dHlwZSAhPSBYUEFUSF9OT0RFU0VUKSB7CisJICAgIHhtbFhQYXRoRnJlZU9iamVjdChuZXdsaXN0KTsKKwkgICAgcmV0dXJuKC0xKTsKKwl9CisJaXggPSAwOworCisJaWYgKChwYXJlbnQgPT0gTlVMTCkgfHwgKG5vZGUtPmRvYyA9PSBOVUxMKSB8fCBpc1JWVCkKKwkgICAgbm9jYWNoZSA9IDE7CisJCisJaWYgKG5vY2FjaGUgPT0gMCkgeworCSAgICBpZiAobGlzdCAhPSBOVUxMKQorCQl4bWxYUGF0aEZyZWVPYmplY3QobGlzdCk7CisJICAgIGxpc3QgPSBuZXdsaXN0OworCisJICAgIFhTTFRfUlVOVElNRV9FWFRSQV9MU1QoY3R4dCwgc2VsLT5sZW5FeHRyYSkgPQorCQkodm9pZCAqKSBsaXN0OworCSAgICBYU0xUX1JVTlRJTUVfRVhUUkEoY3R4dCwgc2VsLT5wcmV2aW91c0V4dHJhLCBwdHIpID0KKwkJKHZvaWQgKikgZG9jOworCSAgICBYU0xUX1JVTlRJTUVfRVhUUkEoY3R4dCwgc2VsLT5pbmRleEV4dHJhLCBpdmFsKSA9CisJCTA7CisJICAgIFhTTFRfUlVOVElNRV9FWFRSQV9GUkVFKGN0eHQsIHNlbC0+bGVuRXh0cmEpID0KKwkJKHhtbEZyZWVGdW5jKSB4bWxYUGF0aEZyZWVPYmplY3Q7CisJfSBlbHNlCisJICAgIGxpc3QgPSBuZXdsaXN0OworICAgIH0KKyAgICBpZiAoKGxpc3QtPm5vZGVzZXR2YWwgPT0gTlVMTCkgfHwKKwkobGlzdC0+bm9kZXNldHZhbC0+bm9kZU5yIDw9IDApKSB7CisJaWYgKG5vY2FjaGUgPT0gMSkKKwkgICAgeG1sWFBhdGhGcmVlT2JqZWN0KGxpc3QpOworCXJldHVybigwKTsKKyAgICB9CisgICAgLyogVE9ETzogc3RvcmUgdGhlIGluZGV4IGFuZCB1c2UgaXQgZm9yIHRoZSBzY2FuICovCisgICAgaWYgKGl4ID09IDApIHsKKwlmb3IgKGogPSAwO2ogPCBsaXN0LT5ub2Rlc2V0dmFsLT5ub2RlTnI7aisrKSB7CisJICAgIGlmIChsaXN0LT5ub2Rlc2V0dmFsLT5ub2RlVGFiW2pdID09IG5vZGUpIHsKKwkJaWYgKG5vY2FjaGUgPT0gMSkKKwkJICAgIHhtbFhQYXRoRnJlZU9iamVjdChsaXN0KTsKKwkJcmV0dXJuKDEpOworCSAgICB9CisJfQorICAgIH0gZWxzZSB7CisgICAgfQorICAgIGlmIChub2NhY2hlID09IDEpCisJeG1sWFBhdGhGcmVlT2JqZWN0KGxpc3QpOworICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0VGVzdENvbXBNYXRjaDoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQGNvbXA6IHRoZSBwcmVjb21waWxlZCBwYXR0ZXJuCisgKiBAbm9kZTogYSBub2RlCisgKiBAbW9kZTogIHRoZSBtb2RlIG5hbWUgb3IgTlVMTAorICogQG1vZGVVUkk6ICB0aGUgbW9kZSBVUkkgb3IgTlVMTAorICoKKyAqIFRlc3Qgd2hldGhlciB0aGUgbm9kZSBtYXRjaGVzIHRoZSBwYXR0ZXJuCisgKgorICogUmV0dXJucyAxIGlmIGl0IG1hdGNoZXMsIDAgaWYgaXQgZG9lc24ndCBhbmQgLTEgaW4gY2FzZSBvZiBmYWlsdXJlCisgKi8KK3N0YXRpYyBpbnQKK3hzbHRUZXN0Q29tcE1hdGNoKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhzbHRDb21wTWF0Y2hQdHIgY29tcCwKKwkgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBjb25zdCB4bWxDaGFyICptb2RlLAorCQkgIGNvbnN0IHhtbENoYXIgKm1vZGVVUkkpIHsKKyAgICBpbnQgaTsKKyAgICB4c2x0U3RlcE9wUHRyIHN0ZXAsIHNlbCA9IE5VTEw7CisgICAgeHNsdFN0ZXBTdGF0ZXMgc3RhdGVzID0gezAsIDAsIE5VTEx9OyAvKiAvLyBtYXkgcmVxdWlyZSBiYWNrdHJhY2sgKi8KKworICAgIGlmICgoY29tcCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSB8fCAoY3R4dCA9PSBOVUxMKSkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBub2RlLAorCQkieHNsdFRlc3RDb21wTWF0Y2g6IG51bGwgYXJnXG4iKTsKKyAgICAgICAgcmV0dXJuKC0xKTsKKyAgICB9CisgICAgaWYgKG1vZGUgIT0gTlVMTCkgeworCWlmIChjb21wLT5tb2RlID09IE5VTEwpCisJICAgIHJldHVybigwKTsKKwkvKgorCSAqIGJvdGggbW9kZSBzdHJpbmdzIG11c3QgYmUgaW50ZXJuZWQgb24gdGhlIHN0eWxlc2hlZXQgZGljdGlvbmFyeQorCSAqLworCWlmIChjb21wLT5tb2RlICE9IG1vZGUpCisJICAgIHJldHVybigwKTsKKyAgICB9IGVsc2UgeworCWlmIChjb21wLT5tb2RlICE9IE5VTEwpCisJICAgIHJldHVybigwKTsKKyAgICB9CisgICAgaWYgKG1vZGVVUkkgIT0gTlVMTCkgeworCWlmIChjb21wLT5tb2RlVVJJID09IE5VTEwpCisJICAgIHJldHVybigwKTsKKwkvKgorCSAqIGJvdGggbW9kZVVSSSBzdHJpbmdzIG11c3QgYmUgaW50ZXJuZWQgb24gdGhlIHN0eWxlc2hlZXQgZGljdGlvbmFyeQorCSAqLworCWlmIChjb21wLT5tb2RlVVJJICE9IG1vZGVVUkkpCisJICAgIHJldHVybigwKTsKKyAgICB9IGVsc2UgeworCWlmIChjb21wLT5tb2RlVVJJICE9IE5VTEwpCisJICAgIHJldHVybigwKTsKKyAgICB9CisKKyAgICBpID0gMDsKK3Jlc3RhcnQ6CisgICAgZm9yICg7aSA8IGNvbXAtPm5iU3RlcDtpKyspIHsKKwlzdGVwID0gJmNvbXAtPnN0ZXBzW2ldOworCWlmIChzdGVwLT5vcCAhPSBYU0xUX09QX1BSRURJQ0FURSkKKwkgICAgc2VsID0gc3RlcDsKKwlzd2l0Y2ggKHN0ZXAtPm9wKSB7CisgICAgICAgICAgICBjYXNlIFhTTFRfT1BfRU5EOgorCQlnb3RvIGZvdW5kOworICAgICAgICAgICAgY2FzZSBYU0xUX09QX1JPT1Q6CisJCWlmICgobm9kZS0+dHlwZSA9PSBYTUxfRE9DVU1FTlRfTk9ERSkgfHwKKyNpZmRlZiBMSUJYTUxfRE9DQl9FTkFCTEVECisJCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfRE9DQl9ET0NVTUVOVF9OT0RFKSB8fAorI2VuZGlmCisJCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFKSkKKwkJICAgIGNvbnRpbnVlOworCQlpZiAoKG5vZGUtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYgKG5vZGUtPm5hbWVbMF0gPT0gJyAnKSkKKwkJICAgIGNvbnRpbnVlOworCQlnb3RvIHJvbGxiYWNrOworICAgICAgICAgICAgY2FzZSBYU0xUX09QX0VMRU06CisJCWlmIChub2RlLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpCisJCSAgICBnb3RvIHJvbGxiYWNrOworCQlpZiAoc3RlcC0+dmFsdWUgPT0gTlVMTCkKKwkJICAgIGNvbnRpbnVlOworCQlpZiAoc3RlcC0+dmFsdWVbMF0gIT0gbm9kZS0+bmFtZVswXSkKKwkJICAgIGdvdG8gcm9sbGJhY2s7CisJCWlmICgheG1sU3RyRXF1YWwoc3RlcC0+dmFsdWUsIG5vZGUtPm5hbWUpKQorCQkgICAgZ290byByb2xsYmFjazsKKworCQkvKiBOYW1lc3BhY2UgdGVzdCAqLworCQlpZiAobm9kZS0+bnMgPT0gTlVMTCkgeworCQkgICAgaWYgKHN0ZXAtPnZhbHVlMiAhPSBOVUxMKQorCQkJZ290byByb2xsYmFjazsKKwkJfSBlbHNlIGlmIChub2RlLT5ucy0+aHJlZiAhPSBOVUxMKSB7CisJCSAgICBpZiAoc3RlcC0+dmFsdWUyID09IE5VTEwpCisJCQlnb3RvIHJvbGxiYWNrOworCQkgICAgaWYgKCF4bWxTdHJFcXVhbChzdGVwLT52YWx1ZTIsIG5vZGUtPm5zLT5ocmVmKSkKKwkJCWdvdG8gcm9sbGJhY2s7CisJCX0KKwkJY29udGludWU7CisgICAgICAgICAgICBjYXNlIFhTTFRfT1BfQVRUUjoKKwkJaWYgKG5vZGUtPnR5cGUgIT0gWE1MX0FUVFJJQlVURV9OT0RFKQorCQkgICAgZ290byByb2xsYmFjazsKKwkJaWYgKHN0ZXAtPnZhbHVlICE9IE5VTEwpIHsKKwkJICAgIGlmIChzdGVwLT52YWx1ZVswXSAhPSBub2RlLT5uYW1lWzBdKQorCQkJZ290byByb2xsYmFjazsKKwkJICAgIGlmICgheG1sU3RyRXF1YWwoc3RlcC0+dmFsdWUsIG5vZGUtPm5hbWUpKQorCQkJZ290byByb2xsYmFjazsKKwkJfQorCQkvKiBOYW1lc3BhY2UgdGVzdCAqLworCQlpZiAobm9kZS0+bnMgPT0gTlVMTCkgeworCQkgICAgaWYgKHN0ZXAtPnZhbHVlMiAhPSBOVUxMKQorCQkJZ290byByb2xsYmFjazsKKwkJfSBlbHNlIGlmIChzdGVwLT52YWx1ZTIgIT0gTlVMTCkgeworCQkgICAgaWYgKCF4bWxTdHJFcXVhbChzdGVwLT52YWx1ZTIsIG5vZGUtPm5zLT5ocmVmKSkKKwkJCWdvdG8gcm9sbGJhY2s7CisJCX0KKwkJY29udGludWU7CisgICAgICAgICAgICBjYXNlIFhTTFRfT1BfUEFSRU5UOgorCQlpZiAoKG5vZGUtPnR5cGUgPT0gWE1MX0RPQ1VNRU5UX05PREUpIHx8CisJCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFKSB8fAorI2lmZGVmIExJQlhNTF9ET0NCX0VOQUJMRUQKKwkJICAgIChub2RlLT50eXBlID09IFhNTF9ET0NCX0RPQ1VNRU5UX05PREUpIHx8CisjZW5kaWYKKwkJICAgIChub2RlLT50eXBlID09IFhNTF9OQU1FU1BBQ0VfREVDTCkpCisJCSAgICBnb3RvIHJvbGxiYWNrOworCQlub2RlID0gbm9kZS0+cGFyZW50OworCQlpZiAobm9kZSA9PSBOVUxMKQorCQkgICAgZ290byByb2xsYmFjazsKKwkJaWYgKHN0ZXAtPnZhbHVlID09IE5VTEwpCisJCSAgICBjb250aW51ZTsKKwkJaWYgKHN0ZXAtPnZhbHVlWzBdICE9IG5vZGUtPm5hbWVbMF0pCisJCSAgICBnb3RvIHJvbGxiYWNrOworCQlpZiAoIXhtbFN0ckVxdWFsKHN0ZXAtPnZhbHVlLCBub2RlLT5uYW1lKSkKKwkJICAgIGdvdG8gcm9sbGJhY2s7CisJCS8qIE5hbWVzcGFjZSB0ZXN0ICovCisJCWlmIChub2RlLT5ucyA9PSBOVUxMKSB7CisJCSAgICBpZiAoc3RlcC0+dmFsdWUyICE9IE5VTEwpCisJCQlnb3RvIHJvbGxiYWNrOworCQl9IGVsc2UgaWYgKG5vZGUtPm5zLT5ocmVmICE9IE5VTEwpIHsKKwkJICAgIGlmIChzdGVwLT52YWx1ZTIgPT0gTlVMTCkKKwkJCWdvdG8gcm9sbGJhY2s7CisJCSAgICBpZiAoIXhtbFN0ckVxdWFsKHN0ZXAtPnZhbHVlMiwgbm9kZS0+bnMtPmhyZWYpKQorCQkJZ290byByb2xsYmFjazsKKwkJfQorCQljb250aW51ZTsKKyAgICAgICAgICAgIGNhc2UgWFNMVF9PUF9BTkNFU1RPUjoKKwkJLyogVE9ETzogaW1wbGVtZW50IGNvYWxlc2Npbmcgb2YgQU5DRVNUT1IvTk9ERSBvcHMgKi8KKwkJaWYgKHN0ZXAtPnZhbHVlID09IE5VTEwpIHsKKwkJICAgIHN0ZXAgPSAmY29tcC0+c3RlcHNbaSsxXTsKKwkJICAgIGlmIChzdGVwLT5vcCA9PSBYU0xUX09QX1JPT1QpCisJCQlnb3RvIGZvdW5kOworCQkgICAgLyogYWRkZWQgTlMsIElEIGFuZCBLRVkgYXMgYSByZXN1bHQgb2YgYnVnIDE2ODIwOCAqLworCQkgICAgaWYgKChzdGVwLT5vcCAhPSBYU0xUX09QX0VMRU0pICYmIAorCQkJKHN0ZXAtPm9wICE9IFhTTFRfT1BfQUxMKSAmJiAKKwkJCShzdGVwLT5vcCAhPSBYU0xUX09QX05TKSAmJgorCQkJKHN0ZXAtPm9wICE9IFhTTFRfT1BfSUQpICYmCisJCQkoc3RlcC0+b3AgIT0gWFNMVF9PUF9LRVkpKQorCQkJZ290byByb2xsYmFjazsKKwkJfQorCQlpZiAobm9kZSA9PSBOVUxMKQorCQkgICAgZ290byByb2xsYmFjazsKKwkJaWYgKChub2RlLT50eXBlID09IFhNTF9ET0NVTUVOVF9OT0RFKSB8fAorCQkgICAgKG5vZGUtPnR5cGUgPT0gWE1MX0hUTUxfRE9DVU1FTlRfTk9ERSkgfHwKKyNpZmRlZiBMSUJYTUxfRE9DQl9FTkFCTEVECisJCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfRE9DQl9ET0NVTUVOVF9OT0RFKSB8fAorI2VuZGlmCisJCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfTkFNRVNQQUNFX0RFQ0wpKQorCQkgICAgZ290byByb2xsYmFjazsKKwkJbm9kZSA9IG5vZGUtPnBhcmVudDsKKwkJaWYgKChzdGVwLT5vcCAhPSBYU0xUX09QX0VMRU0pICYmIHN0ZXAtPm9wICE9IFhTTFRfT1BfQUxMKSB7CisJCSAgICB4c2x0UGF0UHVzaFN0YXRlKGN0eHQsICZzdGF0ZXMsIGksIG5vZGUpOworCQkgICAgY29udGludWU7CisJCX0KKwkJaSsrOworCQlpZiAoc3RlcC0+dmFsdWUgPT0gTlVMTCkgeworCQkgICAgeHNsdFBhdFB1c2hTdGF0ZShjdHh0LCAmc3RhdGVzLCBpIC0gMSwgbm9kZSk7CisJCSAgICBjb250aW51ZTsKKwkJfQorCQl3aGlsZSAobm9kZSAhPSBOVUxMKSB7CisJCSAgICBpZiAoKG5vZGUtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKKwkJCShzdGVwLT52YWx1ZVswXSA9PSBub2RlLT5uYW1lWzBdKSAmJgorCQkJKHhtbFN0ckVxdWFsKHN0ZXAtPnZhbHVlLCBub2RlLT5uYW1lKSkpIHsKKwkJCS8qIE5hbWVzcGFjZSB0ZXN0ICovCisJCQlpZiAobm9kZS0+bnMgPT0gTlVMTCkgeworCQkJICAgIGlmIChzdGVwLT52YWx1ZTIgPT0gTlVMTCkKKwkJCQlicmVhazsKKwkJCX0gZWxzZSBpZiAobm9kZS0+bnMtPmhyZWYgIT0gTlVMTCkgeworCQkJICAgIGlmICgoc3RlcC0+dmFsdWUyICE9IE5VTEwpICYmCisJCQkgICAgICAgICh4bWxTdHJFcXVhbChzdGVwLT52YWx1ZTIsIG5vZGUtPm5zLT5ocmVmKSkpCisJCQkJYnJlYWs7CisJCQl9CisJCSAgICB9CisJCSAgICBub2RlID0gbm9kZS0+cGFyZW50OworCQl9CisJCWlmIChub2RlID09IE5VTEwpCisJCSAgICBnb3RvIHJvbGxiYWNrOworCQl4c2x0UGF0UHVzaFN0YXRlKGN0eHQsICZzdGF0ZXMsIGkgLSAxLCBub2RlKTsKKwkJY29udGludWU7CisgICAgICAgICAgICBjYXNlIFhTTFRfT1BfSUQ6IHsKKwkJLyogVE9ETyBIYW5kbGUgSURzIGRlY2VudGx5LCBtdXN0IGJlIGRvbmUgZGlmZmVyZW50bHkgKi8KKwkJeG1sQXR0clB0ciBpZDsKKworCQlpZiAobm9kZS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKQorCQkgICAgZ290byByb2xsYmFjazsKKworCQlpZCA9IHhtbEdldElEKG5vZGUtPmRvYywgc3RlcC0+dmFsdWUpOworCQlpZiAoKGlkID09IE5VTEwpIHx8IChpZC0+cGFyZW50ICE9IG5vZGUpKQorCQkgICAgZ290byByb2xsYmFjazsKKwkJYnJlYWs7CisJICAgIH0KKyAgICAgICAgICAgIGNhc2UgWFNMVF9PUF9LRVk6IHsKKwkJeG1sTm9kZVNldFB0ciBsaXN0OworCQlpbnQgaW5keDsKKworCQlsaXN0ID0geHNsdEdldEtleShjdHh0LCBzdGVwLT52YWx1ZSwKKwkJCSAgICAgICAgICBzdGVwLT52YWx1ZTMsIHN0ZXAtPnZhbHVlMik7CisJCWlmIChsaXN0ID09IE5VTEwpCisJCSAgICBnb3RvIHJvbGxiYWNrOworCQlmb3IgKGluZHggPSAwO2luZHggPCBsaXN0LT5ub2RlTnI7aW5keCsrKQorCQkgICAgaWYgKGxpc3QtPm5vZGVUYWJbaW5keF0gPT0gbm9kZSkKKwkJCWJyZWFrOworCQlpZiAoaW5keCA+PSBsaXN0LT5ub2RlTnIpCisJCSAgICBnb3RvIHJvbGxiYWNrOworCQlicmVhazsKKwkgICAgfQorICAgICAgICAgICAgY2FzZSBYU0xUX09QX05TOgorCQlpZiAobm9kZS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKQorCQkgICAgZ290byByb2xsYmFjazsKKwkJaWYgKG5vZGUtPm5zID09IE5VTEwpIHsKKwkJICAgIGlmIChzdGVwLT52YWx1ZSAhPSBOVUxMKQorCQkJZ290byByb2xsYmFjazsKKwkJfSBlbHNlIGlmIChub2RlLT5ucy0+aHJlZiAhPSBOVUxMKSB7CisJCSAgICBpZiAoc3RlcC0+dmFsdWUgPT0gTlVMTCkKKwkJCWdvdG8gcm9sbGJhY2s7CisJCSAgICBpZiAoIXhtbFN0ckVxdWFsKHN0ZXAtPnZhbHVlLCBub2RlLT5ucy0+aHJlZikpCisJCQlnb3RvIHJvbGxiYWNrOworCQl9CisJCWJyZWFrOworICAgICAgICAgICAgY2FzZSBYU0xUX09QX0FMTDoKKwkJaWYgKG5vZGUtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkKKwkJICAgIGdvdG8gcm9sbGJhY2s7CisJCWJyZWFrOworCSAgICBjYXNlIFhTTFRfT1BfUFJFRElDQVRFOiB7CisJCXhtbE5vZGVQdHIgb2xkTm9kZTsKKwkJeG1sRG9jUHRyIGRvYzsKKwkJaW50IG9sZENTLCBvbGRDUDsKKwkJaW50IHBvcyA9IDAsIGxlbiA9IDA7CisJCWludCBpc1JWVDsKKworCQkvKgorCQkgKiB3aGVuIHRoZXJlIGlzIGNhc2NhZGluZyBYU0xUX09QX1BSRURJQ0FURSwgdGhlbiB1c2UgYQorCQkgKiBkaXJlY3QgY29tcHV0YXRpb24gYXBwcm9hY2guIEl0J3Mgbm90IGRvbmUgZGlyZWN0bHkKKwkJICogYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcm91dGluZSB0byBmaWx0ZXIgb3V0IGFzIG11Y2gKKwkJICogYXMgcG9zc2libGUgdGhpcyBjb3N0bHkgY29tcHV0YXRpb24uCisJCSAqLworCQlpZiAoY29tcC0+ZGlyZWN0KSB7CisJCSAgICBpZiAoc3RhdGVzLnN0YXRlcyAhPSBOVUxMKSB7CisJCQkvKiBGcmVlIHRoZSByb2xsYmFjayBzdGF0ZXMgKi8KKwkJCXhtbEZyZWUoc3RhdGVzLnN0YXRlcyk7CisJCSAgICB9CisJCSAgICByZXR1cm4oeHNsdFRlc3RDb21wTWF0Y2hEaXJlY3QoY3R4dCwgY29tcCwgbm9kZSwKKwkJICAgIAkJCQkgICBjb21wLT5uc0xpc3QsIGNvbXAtPm5zTnIpKTsKKwkJfQorCisJCWRvYyA9IG5vZGUtPmRvYzsKKwkJaWYgKFhTTFRfSVNfUkVTX1RSRUVfRlJBRyhkb2MpKQorCQkgICAgaXNSVlQgPSAxOworCQllbHNlCisJCSAgICBpc1JWVCA9IDA7CisKKwkJLyoKKwkJICogRGVwZW5kaW5nIG9uIHRoZSBsYXN0IHNlbGVjdGlvbiwgb25lIG1heSBuZWVkIHRvCisJCSAqIHJlY29tcHV0ZSBjb250ZXh0U2l6ZSBhbmQgcHJveGltaXR5UG9zaXRpb24uCisJCSAqLworCQlvbGRDUyA9IGN0eHQtPnhwYXRoQ3R4dC0+Y29udGV4dFNpemU7CisJCW9sZENQID0gY3R4dC0+eHBhdGhDdHh0LT5wcm94aW1pdHlQb3NpdGlvbjsKKwkJaWYgKChzZWwgIT0gTlVMTCkgJiYKKwkJICAgIChzZWwtPm9wID09IFhTTFRfT1BfRUxFTSkgJiYKKwkJICAgIChzZWwtPnZhbHVlICE9IE5VTEwpICYmCisJCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSAmJgorCQkgICAgKG5vZGUtPnBhcmVudCAhPSBOVUxMKSkgeworCQkgICAgeG1sTm9kZVB0ciBwcmV2aW91czsKKwkJICAgIGludCBpeCwgbm9jYWNoZSA9IDA7CisKKwkJICAgIHByZXZpb3VzID0gKHhtbE5vZGVQdHIpCisJCQlYU0xUX1JVTlRJTUVfRVhUUkEoY3R4dCwgc2VsLT5wcmV2aW91c0V4dHJhLCBwdHIpOworCQkgICAgaXggPSBYU0xUX1JVTlRJTUVfRVhUUkEoY3R4dCwgc2VsLT5pbmRleEV4dHJhLCBpdmFsKTsKKwkJICAgIGlmICgocHJldmlvdXMgIT0gTlVMTCkgJiYKKwkJCShwcmV2aW91cy0+cGFyZW50ID09IG5vZGUtPnBhcmVudCkpIHsKKwkJCS8qCisJCQkgKiBqdXN0IHdhbGsgYmFjayB0byBhZGp1c3QgdGhlIGluZGV4CisJCQkgKi8KKwkJCWludCBpbmR4ID0gMDsKKwkJCXhtbE5vZGVQdHIgc2libGluZyA9IG5vZGU7CisKKwkJCXdoaWxlIChzaWJsaW5nICE9IE5VTEwpIHsKKwkJCSAgICBpZiAoc2libGluZyA9PSBwcmV2aW91cykKKwkJCQlicmVhazsKKwkJCSAgICBpZiAoKHByZXZpb3VzLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpICYmCisJCQkJKHByZXZpb3VzLT5uYW1lICE9IE5VTEwpICYmCisJCQkJKHNpYmxpbmctPm5hbWUgIT0gTlVMTCkgJiYKKwkJCQkocHJldmlvdXMtPm5hbWVbMF0gPT0gc2libGluZy0+bmFtZVswXSkgJiYKKwkJCQkoeG1sU3RyRXF1YWwocHJldmlvdXMtPm5hbWUsIHNpYmxpbmctPm5hbWUpKSkKKwkJCSAgICB7CisJCQkJaWYgKChzZWwtPnZhbHVlMiA9PSBOVUxMKSB8fAorCQkJCSAgICAoKHNpYmxpbmctPm5zICE9IE5VTEwpICYmCisJCQkJICAgICAoeG1sU3RyRXF1YWwoc2VsLT52YWx1ZTIsCisJCQkJCQkgIHNpYmxpbmctPm5zLT5ocmVmKSkpKQorCQkJCSAgICBpbmR4Kys7CisJCQkgICAgfQorCQkJICAgIHNpYmxpbmcgPSBzaWJsaW5nLT5wcmV2OworCQkJfQorCQkJaWYgKHNpYmxpbmcgPT0gTlVMTCkgeworCQkJICAgIC8qIGh1bSBnb2luZyBiYWNrd2FyZCBpbiBkb2N1bWVudCBvcmRlciAuLi4gKi8KKwkJCSAgICBpbmR4ID0gMDsKKwkJCSAgICBzaWJsaW5nID0gbm9kZTsKKwkJCSAgICB3aGlsZSAoc2libGluZyAhPSBOVUxMKSB7CisJCQkJaWYgKHNpYmxpbmcgPT0gcHJldmlvdXMpCisJCQkJICAgIGJyZWFrOworCQkJCWlmICgocHJldmlvdXMtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKKwkJCQkgICAgKHByZXZpb3VzLT5uYW1lICE9IE5VTEwpICYmCisJCQkJICAgIChzaWJsaW5nLT5uYW1lICE9IE5VTEwpICYmCisJCQkJICAgIChwcmV2aW91cy0+bmFtZVswXSA9PSBzaWJsaW5nLT5uYW1lWzBdKSAmJgorCQkJCSAgICAoeG1sU3RyRXF1YWwocHJldmlvdXMtPm5hbWUsIHNpYmxpbmctPm5hbWUpKSkKKwkJCQl7CisJCQkJICAgIGlmICgoc2VsLT52YWx1ZTIgPT0gTlVMTCkgfHwKKwkJCQkJKChzaWJsaW5nLT5ucyAhPSBOVUxMKSAmJgorCQkJCQkoeG1sU3RyRXF1YWwoc2VsLT52YWx1ZTIsCisJCQkJCXNpYmxpbmctPm5zLT5ocmVmKSkpKQorCQkJCSAgICB7CisJCQkJCWluZHgtLTsKKwkJCQkgICAgfQorCQkJCX0KKwkJCQlzaWJsaW5nID0gc2libGluZy0+bmV4dDsKKwkJCSAgICB9CisJCQl9CisJCQlpZiAoc2libGluZyAhPSBOVUxMKSB7CisJCQkgICAgcG9zID0gaXggKyBpbmR4OworCQkJICAgIC8qCisJCQkgICAgICogSWYgdGhlIG5vZGUgaXMgaW4gYSBWYWx1ZSBUcmVlIHdlIG5lZWQgdG8KKwkJCSAgICAgKiBzYXZlIGxlbiwgYnV0IGNhbm5vdCBjYWNoZSB0aGUgbm9kZSEKKwkJCSAgICAgKiAoYnVncyAxNTMxMzcgYW5kIDE1ODg0MCkKKwkJCSAgICAgKi8KKwkJCSAgICBpZiAobm9kZS0+ZG9jICE9IE5VTEwpIHsKKwkJCQlsZW4gPSBYU0xUX1JVTlRJTUVfRVhUUkEoY3R4dCwKKwkJCQkgICAgICAgIHNlbC0+bGVuRXh0cmEsIGl2YWwpOworCQkJCWlmICghaXNSVlQpIHsKKwkJCQkgICAgWFNMVF9SVU5USU1FX0VYVFJBKGN0eHQsCisJCQkJCXNlbC0+cHJldmlvdXNFeHRyYSwgcHRyKSA9IG5vZGU7CisJCQkJICAgIFhTTFRfUlVOVElNRV9FWFRSQShjdHh0LAorCQkJCSAgICAgICAgc2VsLT5pbmRleEV4dHJhLCBpdmFsKSA9IHBvczsKKwkJCQl9CisJCQkgICAgfQorCQkJICAgIGl4ID0gcG9zOworCQkJfSBlbHNlCisJCQkgICAgcG9zID0gMDsKKwkJICAgIH0gZWxzZSB7CisJCQkvKgorCQkJICogcmVjb21wdXRlIHRoZSBpbmRleAorCQkJICovCisJCQl4bWxOb2RlUHRyIHBhcmVudCA9IG5vZGUtPnBhcmVudDsKKwkJCXhtbE5vZGVQdHIgc2libGluZ3MgPSBOVUxMOworCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50KSBzaWJsaW5ncyA9IHBhcmVudC0+Y2hpbGRyZW47CisKKwkJCXdoaWxlIChzaWJsaW5ncyAhPSBOVUxMKSB7CisJCQkgICAgaWYgKHNpYmxpbmdzLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKKwkJCQlpZiAoc2libGluZ3MgPT0gbm9kZSkgeworCQkJCSAgICBsZW4rKzsKKwkJCQkgICAgcG9zID0gbGVuOworCQkJCX0gZWxzZSBpZiAoKG5vZGUtPm5hbWUgIT0gTlVMTCkgJiYKKwkJCQkJICAgKHNpYmxpbmdzLT5uYW1lICE9IE5VTEwpICYmCisJCQkJICAgIChub2RlLT5uYW1lWzBdID09IHNpYmxpbmdzLT5uYW1lWzBdKSAmJgorCQkJCSAgICAoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgc2libGluZ3MtPm5hbWUpKSkgeworCQkJCSAgICBpZiAoKHNlbC0+dmFsdWUyID09IE5VTEwpIHx8CisJCQkJCSgoc2libGluZ3MtPm5zICE9IE5VTEwpICYmCisJCQkJCSAoeG1sU3RyRXF1YWwoc2VsLT52YWx1ZTIsCisJCQkJCQkgICAgICBzaWJsaW5ncy0+bnMtPmhyZWYpKSkpCisJCQkJCWxlbisrOworCQkJCX0KKwkJCSAgICB9CisJCQkgICAgc2libGluZ3MgPSBzaWJsaW5ncy0+bmV4dDsKKwkJCX0KKwkJCWlmICgocGFyZW50ID09IE5VTEwpIHx8IChub2RlLT5kb2MgPT0gTlVMTCkpCisJCQkgICAgbm9jYWNoZSA9IDE7CisJCQllbHNlIHsKKwkJCSAgICB3aGlsZSAocGFyZW50LT5wYXJlbnQgIT0gTlVMTCkKKwkJCQlwYXJlbnQgPSBwYXJlbnQtPnBhcmVudDsKKwkJCSAgICBpZiAoKChwYXJlbnQtPnR5cGUgIT0gWE1MX0RPQ1VNRU5UX05PREUpICYmCisJCQkJIChwYXJlbnQtPnR5cGUgIT0gWE1MX0hUTUxfRE9DVU1FTlRfTk9ERSkpIHx8CisJCQkJIChwYXJlbnQgIT0gKHhtbE5vZGVQdHIpIG5vZGUtPmRvYykpCisJCQkJbm9jYWNoZSA9IDE7CisJCQl9CisJCSAgICB9CisJCSAgICBpZiAocG9zICE9IDApIHsKKwkJCWN0eHQtPnhwYXRoQ3R4dC0+Y29udGV4dFNpemUgPSBsZW47CisJCQljdHh0LT54cGF0aEN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gcG9zOworCQkJLyoKKwkJCSAqIElmIHRoZSBub2RlIGlzIGluIGEgVmFsdWUgVHJlZSB3ZSBjYW5ub3QKKwkJCSAqIGNhY2hlIGl0ICEKKwkJCSAqLworCQkJaWYgKCghaXNSVlQpICYmIChub2RlLT5kb2MgIT0gTlVMTCkgJiYKKwkJCSAgICAobm9jYWNoZSA9PSAwKSkgeworCQkJICAgIFhTTFRfUlVOVElNRV9FWFRSQShjdHh0LCBzZWwtPnByZXZpb3VzRXh0cmEsIHB0cikgPQorCQkJCW5vZGU7CisJCQkgICAgWFNMVF9SVU5USU1FX0VYVFJBKGN0eHQsIHNlbC0+aW5kZXhFeHRyYSwgaXZhbCkgPQorCQkJCXBvczsKKwkJCSAgICBYU0xUX1JVTlRJTUVfRVhUUkEoY3R4dCwgc2VsLT5sZW5FeHRyYSwgaXZhbCkgPQorCQkJCWxlbjsKKwkJCX0KKwkJICAgIH0KKwkJfSBlbHNlIGlmICgoc2VsICE9IE5VTEwpICYmIChzZWwtPm9wID09IFhTTFRfT1BfQUxMKSAmJgorCQkJICAgKG5vZGUtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkpIHsKKwkJICAgIHhtbE5vZGVQdHIgcHJldmlvdXM7CisJCSAgICBpbnQgaXgsIG5vY2FjaGUgPSAwOworCisJCSAgICBwcmV2aW91cyA9ICh4bWxOb2RlUHRyKQorCQkJWFNMVF9SVU5USU1FX0VYVFJBKGN0eHQsIHNlbC0+cHJldmlvdXNFeHRyYSwgcHRyKTsKKwkJICAgIGl4ID0gWFNMVF9SVU5USU1FX0VYVFJBKGN0eHQsIHNlbC0+aW5kZXhFeHRyYSwgaXZhbCk7CisJCSAgICBpZiAoKHByZXZpb3VzICE9IE5VTEwpICYmCisJCQkocHJldmlvdXMtPnBhcmVudCA9PSBub2RlLT5wYXJlbnQpKSB7CisJCQkvKgorCQkJICoganVzdCB3YWxrIGJhY2sgdG8gYWRqdXN0IHRoZSBpbmRleAorCQkJICovCisJCQlpbnQgaW5keCA9IDA7CisJCQl4bWxOb2RlUHRyIHNpYmxpbmcgPSBub2RlOworCisJCQl3aGlsZSAoc2libGluZyAhPSBOVUxMKSB7CisJCQkgICAgaWYgKHNpYmxpbmcgPT0gcHJldmlvdXMpCisJCQkJYnJlYWs7CisJCQkgICAgaWYgKHNpYmxpbmctPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkKKwkJCQlpbmR4Kys7CisJCQkgICAgc2libGluZyA9IHNpYmxpbmctPnByZXY7CisJCQl9CisJCQlpZiAoc2libGluZyA9PSBOVUxMKSB7CisJCQkgICAgLyogaHVtIGdvaW5nIGJhY2t3YXJkIGluIGRvY3VtZW50IG9yZGVyIC4uLiAqLworCQkJICAgIGluZHggPSAwOworCQkJICAgIHNpYmxpbmcgPSBub2RlOworCQkJICAgIHdoaWxlIChzaWJsaW5nICE9IE5VTEwpIHsKKwkJCQlpZiAoc2libGluZyA9PSBwcmV2aW91cykKKwkJCQkgICAgYnJlYWs7CisJCQkJaWYgKHNpYmxpbmctPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkKKwkJCQkgICAgaW5keC0tOworCQkJCXNpYmxpbmcgPSBzaWJsaW5nLT5uZXh0OworCQkJICAgIH0KKwkJCX0KKwkJCWlmIChzaWJsaW5nICE9IE5VTEwpIHsKKwkJCSAgICBwb3MgPSBpeCArIGluZHg7CisJCQkgICAgLyoKKwkJCSAgICAgKiBJZiB0aGUgbm9kZSBpcyBpbiBhIFZhbHVlIFRyZWUgd2UgY2Fubm90CisJCQkgICAgICogY2FjaGUgaXQgIQorCQkJICAgICAqLworCQkJICAgIGlmICgobm9kZS0+ZG9jICE9IE5VTEwpICYmICFpc1JWVCkgeworCQkJCWxlbiA9IFhTTFRfUlVOVElNRV9FWFRSQShjdHh0LAorCQkJCSAgICAgICAgc2VsLT5sZW5FeHRyYSwgaXZhbCk7CisJCQkJWFNMVF9SVU5USU1FX0VYVFJBKGN0eHQsCisJCQkJCXNlbC0+cHJldmlvdXNFeHRyYSwgcHRyKSA9IG5vZGU7CisJCQkJWFNMVF9SVU5USU1FX0VYVFJBKGN0eHQsCisJCQkJCXNlbC0+aW5kZXhFeHRyYSwgaXZhbCkgPSBwb3M7CisJCQkgICAgfQorCQkJfSBlbHNlCisJCQkgICAgcG9zID0gMDsKKwkJICAgIH0gZWxzZSB7CisJCQkvKgorCQkJICogcmVjb21wdXRlIHRoZSBpbmRleAorCQkJICovCisJCQl4bWxOb2RlUHRyIHBhcmVudCA9IG5vZGUtPnBhcmVudDsKKwkJCXhtbE5vZGVQdHIgc2libGluZ3MgPSBOVUxMOworCisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50KSBzaWJsaW5ncyA9IHBhcmVudC0+Y2hpbGRyZW47CisKKwkJCXdoaWxlIChzaWJsaW5ncyAhPSBOVUxMKSB7CisJCQkgICAgaWYgKHNpYmxpbmdzLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKKwkJCQlsZW4rKzsKKwkJCQlpZiAoc2libGluZ3MgPT0gbm9kZSkgeworCQkJCSAgICBwb3MgPSBsZW47CisJCQkJfQorCQkJICAgIH0KKwkJCSAgICBzaWJsaW5ncyA9IHNpYmxpbmdzLT5uZXh0OworCQkJfQorCQkJaWYgKChwYXJlbnQgPT0gTlVMTCkgfHwgKG5vZGUtPmRvYyA9PSBOVUxMKSkKKwkJCSAgICBub2NhY2hlID0gMTsKKwkJCWVsc2UgeworCQkJICAgIHdoaWxlIChwYXJlbnQtPnBhcmVudCAhPSBOVUxMKQorCQkJCXBhcmVudCA9IHBhcmVudC0+cGFyZW50OworCQkJICAgIGlmICgoKHBhcmVudC0+dHlwZSAhPSBYTUxfRE9DVU1FTlRfTk9ERSkgJiYKKwkJCQkgKHBhcmVudC0+dHlwZSAhPSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFKSkgfHwKKwkJCQkgKHBhcmVudCAhPSAoeG1sTm9kZVB0cikgbm9kZS0+ZG9jKSkKKwkJCQlub2NhY2hlID0gMTsKKwkJCX0KKwkJICAgIH0KKwkJICAgIGlmIChwb3MgIT0gMCkgeworCQkJY3R4dC0+eHBhdGhDdHh0LT5jb250ZXh0U2l6ZSA9IGxlbjsKKwkJCWN0eHQtPnhwYXRoQ3R4dC0+cHJveGltaXR5UG9zaXRpb24gPSBwb3M7CisJCQkvKgorCQkJICogSWYgdGhlIG5vZGUgaXMgaW4gYSBWYWx1ZSBUcmVlIHdlIGNhbm5vdAorCQkJICogY2FjaGUgaXQgIQorCQkJICovCisJCQlpZiAoKG5vZGUtPmRvYyAhPSBOVUxMKSAmJiAobm9jYWNoZSA9PSAwKSAmJiAhaXNSVlQpIHsKKwkJCSAgICBYU0xUX1JVTlRJTUVfRVhUUkEoY3R4dCwgc2VsLT5wcmV2aW91c0V4dHJhLCBwdHIpID0KKwkJCQlub2RlOworCQkJICAgIFhTTFRfUlVOVElNRV9FWFRSQShjdHh0LCBzZWwtPmluZGV4RXh0cmEsIGl2YWwpID0KKwkJCQlwb3M7CisJCQkgICAgWFNMVF9SVU5USU1FX0VYVFJBKGN0eHQsIHNlbC0+bGVuRXh0cmEsIGl2YWwpID0KKwkJCQlsZW47CisJCQl9CisJCSAgICB9CisJCX0KKwkJb2xkTm9kZSA9IGN0eHQtPm5vZGU7CisJCWN0eHQtPm5vZGUgPSBub2RlOworCisJCWlmIChzdGVwLT52YWx1ZSA9PSBOVUxMKQorCQkgICAgZ290byB3cm9uZ19pbmRleDsKKwkJaWYgKHN0ZXAtPmNvbXAgPT0gTlVMTCkKKwkJICAgIGdvdG8gd3JvbmdfaW5kZXg7CisKKwkJaWYgKCF4c2x0RXZhbFhQYXRoUHJlZGljYXRlKGN0eHQsIHN0ZXAtPmNvbXAsIGNvbXAtPm5zTGlzdCwKKwkJCSAgICAgICAgICAgICAgICAgICAgY29tcC0+bnNOcikpCisJCSAgICBnb3RvIHdyb25nX2luZGV4OworCisJCWlmIChwb3MgIT0gMCkgeworCQkgICAgY3R4dC0+eHBhdGhDdHh0LT5jb250ZXh0U2l6ZSA9IG9sZENTOworCQkgICAgY3R4dC0+eHBhdGhDdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IG9sZENQOworCQl9CisJCWN0eHQtPm5vZGUgPSBvbGROb2RlOworCQlicmVhazsKK3dyb25nX2luZGV4OgorCQlpZiAocG9zICE9IDApIHsKKwkJICAgIGN0eHQtPnhwYXRoQ3R4dC0+Y29udGV4dFNpemUgPSBvbGRDUzsKKwkJICAgIGN0eHQtPnhwYXRoQ3R4dC0+cHJveGltaXR5UG9zaXRpb24gPSBvbGRDUDsKKwkJfQorCQljdHh0LT5ub2RlID0gb2xkTm9kZTsKKwkJZ290byByb2xsYmFjazsKKwkgICAgfQorICAgICAgICAgICAgY2FzZSBYU0xUX09QX1BJOgorCQlpZiAobm9kZS0+dHlwZSAhPSBYTUxfUElfTk9ERSkKKwkJICAgIGdvdG8gcm9sbGJhY2s7CisJCWlmIChzdGVwLT52YWx1ZSAhPSBOVUxMKSB7CisJCSAgICBpZiAoIXhtbFN0ckVxdWFsKHN0ZXAtPnZhbHVlLCBub2RlLT5uYW1lKSkKKwkJCWdvdG8gcm9sbGJhY2s7CisJCX0KKwkJYnJlYWs7CisgICAgICAgICAgICBjYXNlIFhTTFRfT1BfQ09NTUVOVDoKKwkJaWYgKG5vZGUtPnR5cGUgIT0gWE1MX0NPTU1FTlRfTk9ERSkKKwkJICAgIGdvdG8gcm9sbGJhY2s7CisJCWJyZWFrOworICAgICAgICAgICAgY2FzZSBYU0xUX09QX1RFWFQ6CisJCWlmICgobm9kZS0+dHlwZSAhPSBYTUxfVEVYVF9OT0RFKSAmJgorCQkgICAgKG5vZGUtPnR5cGUgIT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpCisJCSAgICBnb3RvIHJvbGxiYWNrOworCQlicmVhazsKKyAgICAgICAgICAgIGNhc2UgWFNMVF9PUF9OT0RFOgorCQlzd2l0Y2ggKG5vZGUtPnR5cGUpIHsKKwkJICAgIGNhc2UgWE1MX0VMRU1FTlRfTk9ERToKKwkJICAgIGNhc2UgWE1MX0NEQVRBX1NFQ1RJT05fTk9ERToKKwkJICAgIGNhc2UgWE1MX1BJX05PREU6CisJCSAgICBjYXNlIFhNTF9DT01NRU5UX05PREU6CisJCSAgICBjYXNlIFhNTF9URVhUX05PREU6CisJCQlicmVhazsKKwkJICAgIGRlZmF1bHQ6CisJCQlnb3RvIHJvbGxiYWNrOworCQl9CisJCWJyZWFrOworCX0KKyAgICB9Citmb3VuZDoKKyAgICBpZiAoc3RhdGVzLnN0YXRlcyAhPSBOVUxMKSB7CisgICAgICAgIC8qIEZyZWUgdGhlIHJvbGxiYWNrIHN0YXRlcyAqLworCXhtbEZyZWUoc3RhdGVzLnN0YXRlcyk7CisgICAgfQorICAgIHJldHVybigxKTsKK3JvbGxiYWNrOgorICAgIC8qIGdvdCBhbiBlcnJvciB0cnkgdG8gcm9sbGJhY2sgKi8KKyAgICBpZiAoc3RhdGVzLnN0YXRlcyA9PSBOVUxMKQorCXJldHVybigwKTsKKyAgICBpZiAoc3RhdGVzLm5ic3RhdGVzIDw9IDApIHsKKwl4bWxGcmVlKHN0YXRlcy5zdGF0ZXMpOworCXJldHVybigwKTsKKyAgICB9CisgICAgc3RhdGVzLm5ic3RhdGVzLS07CisgICAgaSA9IHN0YXRlcy5zdGF0ZXNbc3RhdGVzLm5ic3RhdGVzXS5zdGVwOworICAgIG5vZGUgPSBzdGF0ZXMuc3RhdGVzW3N0YXRlcy5uYnN0YXRlc10ubm9kZTsKKyNpZiAwCisgICAgZnByaW50ZihzdGRlcnIsICJQb3A6ICVkLCAlc1xuIiwgaSwgbm9kZS0+bmFtZSk7CisjZW5kaWYKKyAgICBnb3RvIHJlc3RhcnQ7Cit9CisKKy8qKgorICogeHNsdFRlc3RDb21wTWF0Y2hMaXN0OgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAbm9kZTogYSBub2RlCisgKiBAY29tcDogdGhlIHByZWNvbXBpbGVkIHBhdHRlcm4gbGlzdAorICoKKyAqIFRlc3Qgd2hldGhlciB0aGUgbm9kZSBtYXRjaGVzIG9uZSBvZiB0aGUgcGF0dGVybnMgaW4gdGhlIGxpc3QKKyAqCisgKiBSZXR1cm5zIDEgaWYgaXQgbWF0Y2hlcywgMCBpZiBpdCBkb2Vzbid0IGFuZCAtMSBpbiBjYXNlIG9mIGZhaWx1cmUKKyAqLworaW50Cit4c2x0VGVzdENvbXBNYXRjaExpc3QoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAorCSAgICAgICAgICAgICAgeHNsdENvbXBNYXRjaFB0ciBjb21wKSB7CisgICAgaW50IHJldDsKKworICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworICAgIHdoaWxlIChjb21wICE9IE5VTEwpIHsKKwlyZXQgPSB4c2x0VGVzdENvbXBNYXRjaChjdHh0LCBjb21wLCBub2RlLCBOVUxMLCBOVUxMKTsKKwlpZiAocmV0ID09IDEpCisJICAgIHJldHVybigxKTsKKwljb21wID0gY29tcC0+bmV4dDsKKyAgICB9CisgICAgcmV0dXJuKDApOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkJRGVkaWNhdGVkIHBhcnNlciBmb3IgdGVtcGxhdGVzCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisjZGVmaW5lIENVUiAoKmN0eHQtPmN1cikKKyNkZWZpbmUgU0tJUCh2YWwpIGN0eHQtPmN1ciArPSAodmFsKQorI2RlZmluZSBOWFQodmFsKSBjdHh0LT5jdXJbKHZhbCldCisjZGVmaW5lIENVUl9QVFIgY3R4dC0+Y3VyCisKKyNkZWZpbmUgU0tJUF9CTEFOS1MgCQkJCQkJCVwKKyAgICB3aGlsZSAoSVNfQkxBTktfQ0goQ1VSKSkgTkVYVAorCisjZGVmaW5lIENVUlJFTlQgKCpjdHh0LT5jdXIpCisjZGVmaW5lIE5FWFQgKCgqY3R4dC0+Y3VyKSA/ICBjdHh0LT5jdXIrKzogY3R4dC0+Y3VyKQorCisKKyNkZWZpbmUgUFVTSChvcCwgdmFsLCB2YWwyLCBub3ZhcikgCQkJCQkJXAorICAgIGlmICh4c2x0Q29tcE1hdGNoQWRkKGN0eHQsIGN0eHQtPmNvbXAsIChvcCksICh2YWwpLCAodmFsMiksIChub3ZhcikpKSBnb3RvIGVycm9yOworCisjZGVmaW5lIFNXQVAoKSAJCQkJCQlcCisgICAgeHNsdFN3YXBUb3BDb21wTWF0Y2goY3R4dC0+Y29tcCk7CisKKyNkZWZpbmUgWFNMVF9FUlJPUihYKQkJCQkJCQlcCisgICAgeyB4c2x0RXJyb3IoY3R4dCwgX19GSUxFX18sIF9fTElORV9fLCBYKTsJCQlcCisgICAgICBjdHh0LT5lcnJvciA9IChYKTsgcmV0dXJuOyB9CisKKyNkZWZpbmUgWFNMVF9FUlJPUjAoWCkJCQkJCQkJXAorICAgIHsgeHNsdEVycm9yKGN0eHQsIF9fRklMRV9fLCBfX0xJTkVfXywgWCk7CQkJXAorICAgICAgY3R4dC0+ZXJyb3IgPSAoWCk7IHJldHVybigwKTsgfQorCisvKioKKyAqIHhzbHRTY2FuTGl0ZXJhbDoKKyAqIEBjdHh0OiAgdGhlIFhQYXRoIFBhcnNlciBjb250ZXh0CisgKgorICogUGFyc2UgYW4gWFBhdGggTGl0dGVyYWw6CisgKgorICogWzI5XSBMaXRlcmFsIDo6PSAnIicgW14iXSogJyInCisgKiAgICAgICAgICAgICAgICB8ICInIiBbXiddKiAiJyIKKyAqCisgKiBSZXR1cm5zIHRoZSBMaXRlcmFsIHBhcnNlZCBvciBOVUxMCisgKi8KKworc3RhdGljIHhtbENoYXIgKgoreHNsdFNjYW5MaXRlcmFsKHhzbHRQYXJzZXJDb250ZXh0UHRyIGN0eHQpIHsKKyAgICBjb25zdCB4bWxDaGFyICpxLCAqY3VyOworICAgIHhtbENoYXIgKnJldCA9IE5VTEw7CisgICAgaW50IHZhbCwgbGVuOworCisgICAgU0tJUF9CTEFOS1M7CisgICAgaWYgKENVUiA9PSAnIicpIHsKKyAgICAgICAgTkVYVDsKKwljdXIgPSBxID0gQ1VSX1BUUjsKKwl2YWwgPSB4bWxTdHJpbmdDdXJyZW50Q2hhcihOVUxMLCBjdXIsICZsZW4pOworCXdoaWxlICgoSVNfQ0hBUih2YWwpKSAmJiAodmFsICE9ICciJykpIHsKKwkgICAgY3VyICs9IGxlbjsKKwkgICAgdmFsID0geG1sU3RyaW5nQ3VycmVudENoYXIoTlVMTCwgY3VyLCAmbGVuKTsKKwl9CisJaWYgKCFJU19DSEFSKHZhbCkpIHsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCSAgICByZXR1cm4oTlVMTCk7CisJfSBlbHNlIHsKKwkgICAgcmV0ID0geG1sU3RybmR1cChxLCBjdXIgLSBxKTsKKyAgICAgICAgfQorCWN1ciArPSBsZW47CisJQ1VSX1BUUiA9IGN1cjsKKyAgICB9IGVsc2UgaWYgKENVUiA9PSAnXCcnKSB7CisgICAgICAgIE5FWFQ7CisJY3VyID0gcSA9IENVUl9QVFI7CisJdmFsID0geG1sU3RyaW5nQ3VycmVudENoYXIoTlVMTCwgY3VyLCAmbGVuKTsKKwl3aGlsZSAoKElTX0NIQVIodmFsKSkgJiYgKHZhbCAhPSAnXCcnKSkgeworCSAgICBjdXIgKz0gbGVuOworCSAgICB2YWwgPSB4bWxTdHJpbmdDdXJyZW50Q2hhcihOVUxMLCBjdXIsICZsZW4pOworCX0KKwlpZiAoIUlTX0NIQVIodmFsKSkgeworCSAgICBjdHh0LT5lcnJvciA9IDE7CisJICAgIHJldHVybihOVUxMKTsKKwl9IGVsc2UgeworCSAgICByZXQgPSB4bWxTdHJuZHVwKHEsIGN1ciAtIHEpOworICAgICAgICB9CisJY3VyICs9IGxlbjsKKwlDVVJfUFRSID0gY3VyOworICAgIH0gZWxzZSB7CisJLyogWFBfRVJST1IoWFBBVEhfU1RBUlRfTElURVJBTF9FUlJPUik7ICovCisJY3R4dC0+ZXJyb3IgPSAxOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdFNjYW5OQ05hbWU6CisgKiBAY3R4dDogIHRoZSBYUGF0aCBQYXJzZXIgY29udGV4dAorICoKKyAqIFBhcnNlcyBhIG5vbiBxdWFsaWZpZWQgbmFtZQorICoKKyAqIFJldHVybnMgdGhlIE5hbWUgcGFyc2VkIG9yIE5VTEwKKyAqLworCitzdGF0aWMgeG1sQ2hhciAqCit4c2x0U2Nhbk5DTmFtZSh4c2x0UGFyc2VyQ29udGV4dFB0ciBjdHh0KSB7CisgICAgY29uc3QgeG1sQ2hhciAqcSwgKmN1cjsKKyAgICB4bWxDaGFyICpyZXQgPSBOVUxMOworICAgIGludCB2YWwsIGxlbjsKKworICAgIFNLSVBfQkxBTktTOworCisgICAgY3VyID0gcSA9IENVUl9QVFI7CisgICAgdmFsID0geG1sU3RyaW5nQ3VycmVudENoYXIoTlVMTCwgY3VyLCAmbGVuKTsKKyAgICBpZiAoIUlTX0xFVFRFUih2YWwpICYmICh2YWwgIT0gJ18nKSkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICB3aGlsZSAoKElTX0xFVFRFUih2YWwpKSB8fCAoSVNfRElHSVQodmFsKSkgfHwKKyAgICAgICAgICAgKHZhbCA9PSAnLicpIHx8ICh2YWwgPT0gJy0nKSB8fAorCSAgICh2YWwgPT0gJ18nKSB8fAorCSAgIChJU19DT01CSU5JTkcodmFsKSkgfHwKKwkgICAoSVNfRVhURU5ERVIodmFsKSkpIHsKKwljdXIgKz0gbGVuOworCXZhbCA9IHhtbFN0cmluZ0N1cnJlbnRDaGFyKE5VTEwsIGN1ciwgJmxlbik7CisgICAgfQorICAgIHJldCA9IHhtbFN0cm5kdXAocSwgY3VyIC0gcSk7CisgICAgQ1VSX1BUUiA9IGN1cjsKKyAgICByZXR1cm4ocmV0KTsKK30KKworLyoKKyAqIHhzbHRDb21waWxlSWRLZXlQYXR0ZXJuOgorICogQGN0eHQ6ICB0aGUgY29tcGlsYXRpb24gY29udGV4dAorICogQG5hbWU6ICBhIHByZXBhcnNlZCBuYW1lCisgKiBAYWlkOiAgd2hldGhlciBpZC9rZXkgYXJlIGFsbG93ZWQgdGhlcmUKKyAqIEBub3ZhcjogIGZsYWcgdG8gcHJvaGliaXQgeHNsdCB2YXIKKyAqCisgKiBDb21waWxlIHRoZSBYU0xUIExvY2F0aW9uSWRLZXlQYXR0ZXJuCisgKiBbM10gSWRLZXlQYXR0ZXJuIDo6PSAnaWQnICcoJyBMaXRlcmFsICcpJworICogICAgICAgICAgICAgICAgICAgIHwgJ2tleScgJygnIExpdGVyYWwgJywnIExpdGVyYWwgJyknCisgKgorICogYWxzbyBoYW5kbGUgTm9kZVR5cGUgYW5kIFBJIGZyb206CisgKgorICogWzddICBOb2RlVGVzdCA6Oj0gTmFtZVRlc3QKKyAqICAgICAgICAgICAgICAgICB8IE5vZGVUeXBlICcoJyAnKScKKyAqICAgICAgICAgICAgICAgICB8ICdwcm9jZXNzaW5nLWluc3RydWN0aW9uJyAnKCcgTGl0ZXJhbCAnKScKKyAqLworc3RhdGljIHZvaWQKK3hzbHRDb21waWxlSWRLZXlQYXR0ZXJuKHhzbHRQYXJzZXJDb250ZXh0UHRyIGN0eHQsIHhtbENoYXIgKm5hbWUsCisJCWludCBhaWQsIGludCBub3ZhciwgeHNsdEF4aXMgYXhpcykgeworICAgIHhtbENoYXIgKmxpdCA9IE5VTEw7CisgICAgeG1sQ2hhciAqbGl0MiA9IE5VTEw7CisKKyAgICBpZiAoQ1VSICE9ICcoJykgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkieHNsdENvbXBpbGVJZEtleVBhdHRlcm4gOiAoIGV4cGVjdGVkXG4iKTsKKwljdHh0LT5lcnJvciA9IDE7CisJcmV0dXJuOworICAgIH0KKyAgICBpZiAoKGFpZCkgJiYgKHhtbFN0ckVxdWFsKG5hbWUsIChjb25zdCB4bWxDaGFyICopImlkIikpKSB7CisJaWYgKGF4aXMgIT0gMCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkJICAgICJ4c2x0Q29tcGlsZUlkS2V5UGF0dGVybiA6IE5vZGVUZXN0IGV4cGVjdGVkXG4iKTsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCSAgICByZXR1cm47CisJfQorCU5FWFQ7CisJU0tJUF9CTEFOS1M7CisgICAgICAgIGxpdCA9IHhzbHRTY2FuTGl0ZXJhbChjdHh0KTsKKwlpZiAoY3R4dC0+ZXJyb3IpCisJICAgIHJldHVybjsKKwlTS0lQX0JMQU5LUzsKKwlpZiAoQ1VSICE9ICcpJykgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkJICAgICJ4c2x0Q29tcGlsZUlkS2V5UGF0dGVybiA6ICkgZXhwZWN0ZWRcbiIpOworCSAgICBjdHh0LT5lcnJvciA9IDE7CisJICAgIHJldHVybjsKKwl9CisJTkVYVDsKKwlQVVNIKFhTTFRfT1BfSUQsIGxpdCwgTlVMTCwgbm92YXIpOworICAgIH0gZWxzZSBpZiAoKGFpZCkgJiYgKHhtbFN0ckVxdWFsKG5hbWUsIChjb25zdCB4bWxDaGFyICopImtleSIpKSkgeworCWlmIChheGlzICE9IDApIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSAgICAieHNsdENvbXBpbGVJZEtleVBhdHRlcm4gOiBOb2RlVGVzdCBleHBlY3RlZFxuIik7CisJICAgIGN0eHQtPmVycm9yID0gMTsKKwkgICAgcmV0dXJuOworCX0KKwlORVhUOworCVNLSVBfQkxBTktTOworICAgICAgICBsaXQgPSB4c2x0U2NhbkxpdGVyYWwoY3R4dCk7CisJaWYgKGN0eHQtPmVycm9yKQorCSAgICByZXR1cm47CisJU0tJUF9CTEFOS1M7CisJaWYgKENVUiAhPSAnLCcpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSAgICAieHNsdENvbXBpbGVJZEtleVBhdHRlcm4gOiAsIGV4cGVjdGVkXG4iKTsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCSAgICByZXR1cm47CisJfQorCU5FWFQ7CisJU0tJUF9CTEFOS1M7CisgICAgICAgIGxpdDIgPSB4c2x0U2NhbkxpdGVyYWwoY3R4dCk7CisJaWYgKGN0eHQtPmVycm9yKQorCSAgICByZXR1cm47CisJU0tJUF9CTEFOS1M7CisJaWYgKENVUiAhPSAnKScpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSAgICAieHNsdENvbXBpbGVJZEtleVBhdHRlcm4gOiApIGV4cGVjdGVkXG4iKTsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCSAgICByZXR1cm47CisJfQorCU5FWFQ7CisJLyogVVJHRU5UIFRPRE86IHN1cHBvcnQgbmFtZXNwYWNlIGluIGtleXMgKi8KKwlQVVNIKFhTTFRfT1BfS0VZLCBsaXQsIGxpdDIsIG5vdmFyKTsKKyAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKG5hbWUsIChjb25zdCB4bWxDaGFyICopInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iKSkgeworCU5FWFQ7CisJU0tJUF9CTEFOS1M7CisJaWYgKENVUiAhPSAnKScpIHsKKwkgICAgbGl0ID0geHNsdFNjYW5MaXRlcmFsKGN0eHQpOworCSAgICBpZiAoY3R4dC0+ZXJyb3IpCisJCXJldHVybjsKKwkgICAgU0tJUF9CTEFOS1M7CisJICAgIGlmIChDVVIgIT0gJyknKSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkJInhzbHRDb21waWxlSWRLZXlQYXR0ZXJuIDogKSBleHBlY3RlZFxuIik7CisJCWN0eHQtPmVycm9yID0gMTsKKwkJcmV0dXJuOworCSAgICB9CisJfQorCU5FWFQ7CisJUFVTSChYU0xUX09QX1BJLCBsaXQsIE5VTEwsIG5vdmFyKTsKKyAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKG5hbWUsIChjb25zdCB4bWxDaGFyICopInRleHQiKSkgeworCU5FWFQ7CisJU0tJUF9CTEFOS1M7CisJaWYgKENVUiAhPSAnKScpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSAgICAieHNsdENvbXBpbGVJZEtleVBhdHRlcm4gOiApIGV4cGVjdGVkXG4iKTsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCSAgICByZXR1cm47CisJfQorCU5FWFQ7CisJUFVTSChYU0xUX09QX1RFWFQsIE5VTEwsIE5VTEwsIG5vdmFyKTsKKyAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKG5hbWUsIChjb25zdCB4bWxDaGFyICopImNvbW1lbnQiKSkgeworCU5FWFQ7CisJU0tJUF9CTEFOS1M7CisJaWYgKENVUiAhPSAnKScpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSAgICAieHNsdENvbXBpbGVJZEtleVBhdHRlcm4gOiApIGV4cGVjdGVkXG4iKTsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCSAgICByZXR1cm47CisJfQorCU5FWFQ7CisJUFVTSChYU0xUX09QX0NPTU1FTlQsIE5VTEwsIE5VTEwsIG5vdmFyKTsKKyAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKG5hbWUsIChjb25zdCB4bWxDaGFyICopIm5vZGUiKSkgeworCU5FWFQ7CisJU0tJUF9CTEFOS1M7CisJaWYgKENVUiAhPSAnKScpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSAgICAieHNsdENvbXBpbGVJZEtleVBhdHRlcm4gOiApIGV4cGVjdGVkXG4iKTsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCSAgICByZXR1cm47CisJfQorCU5FWFQ7CisJaWYgKGF4aXMgPT0gQVhJU19BVFRSSUJVVEUpIHsKKwkgICAgUFVTSChYU0xUX09QX0FUVFIsIE5VTEwsIE5VTEwsIG5vdmFyKTsKKwl9CisJZWxzZSB7CisJICAgIFBVU0goWFNMVF9PUF9OT0RFLCBOVUxMLCBOVUxMLCBub3Zhcik7CisJfQorICAgIH0gZWxzZSBpZiAoYWlkKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJICAgICJ4c2x0Q29tcGlsZUlkS2V5UGF0dGVybiA6IGV4cGVjdGluZyAna2V5JyBvciAnaWQnIG9yIG5vZGUgdHlwZVxuIik7CisJY3R4dC0+ZXJyb3IgPSAxOworCXJldHVybjsKKyAgICB9IGVsc2UgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCSAgICAieHNsdENvbXBpbGVJZEtleVBhdHRlcm4gOiBub2RlIHR5cGVcbiIpOworCWN0eHQtPmVycm9yID0gMTsKKwlyZXR1cm47CisgICAgfQorZXJyb3I6CisgICAgaWYgKG5hbWUgIT0gTlVMTCkKKwl4bWxGcmVlKG5hbWUpOworfQorCisvKioKKyAqIHhzbHRDb21waWxlU3RlcFBhdHRlcm46CisgKiBAY3R4dDogIHRoZSBjb21waWxhdGlvbiBjb250ZXh0CisgKiBAdG9rZW46ICBhIHBvc2libGUgcHJlY29tcGlsZWQgbmFtZQorICogQG5vdmFyOiBmbGFnIHRvIHByb2hpYml0IHhzbHQgdmFyaWFibGVzIGZyb20gcGF0dGVybgorICoKKyAqIENvbXBpbGUgdGhlIFhTTFQgU3RlcFBhdHRlcm4gYW5kIGdlbmVyYXRlcyBhIHByZWNvbXBpbGVkCisgKiBmb3JtIHN1aXRhYmxlIGZvciBmYXN0IG1hdGNoaW5nLgorICoKKyAqIFs1XSBTdGVwUGF0dGVybiA6Oj0gQ2hpbGRPckF0dHJpYnV0ZUF4aXNTcGVjaWZpZXIgTm9kZVRlc3QgUHJlZGljYXRlKiAKKyAqIFs2XSBDaGlsZE9yQXR0cmlidXRlQXhpc1NwZWNpZmllciA6Oj0gQWJicmV2aWF0ZWRBeGlzU3BlY2lmaWVyCisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICgnY2hpbGQnIHwgJ2F0dHJpYnV0ZScpICc6OicKKyAqIGZyb20gWFBhdGgKKyAqIFs3XSAgTm9kZVRlc3QgOjo9IE5hbWVUZXN0CisgKiAgICAgICAgICAgICAgICAgfCBOb2RlVHlwZSAnKCcgJyknCisgKiAgICAgICAgICAgICAgICAgfCAncHJvY2Vzc2luZy1pbnN0cnVjdGlvbicgJygnIExpdGVyYWwgJyknCisgKiBbOF0gUHJlZGljYXRlIDo6PSAnWycgUHJlZGljYXRlRXhwciAnXScKKyAqIFs5XSBQcmVkaWNhdGVFeHByIDo6PSBFeHByCisgKiBbMTNdIEFiYnJldmlhdGVkQXhpc1NwZWNpZmllciA6Oj0gJ0AnPworICogWzM3XSBOYW1lVGVzdCA6Oj0gJyonIHwgTkNOYW1lICc6JyAnKicgfCBRTmFtZQorICovCisKK3N0YXRpYyB2b2lkCit4c2x0Q29tcGlsZVN0ZXBQYXR0ZXJuKHhzbHRQYXJzZXJDb250ZXh0UHRyIGN0eHQsIHhtbENoYXIgKnRva2VuLCBpbnQgbm92YXIpIHsKKyAgICB4bWxDaGFyICpuYW1lID0gTlVMTDsKKyAgICBjb25zdCB4bWxDaGFyICpVUkkgPSBOVUxMOworICAgIHhtbENoYXIgKlVSTCA9IE5VTEw7CisgICAgaW50IGxldmVsOworICAgIHhzbHRBeGlzIGF4aXMgPSAwOworCisgICAgU0tJUF9CTEFOS1M7CisgICAgaWYgKCh0b2tlbiA9PSBOVUxMKSAmJiAoQ1VSID09ICdAJykpIHsKKwlORVhUOworICAgICAgICBheGlzID0gQVhJU19BVFRSSUJVVEU7CisgICAgfQorcGFyc2Vfbm9kZV90ZXN0OgorICAgIGlmICh0b2tlbiA9PSBOVUxMKQorCXRva2VuID0geHNsdFNjYW5OQ05hbWUoY3R4dCk7CisgICAgaWYgKHRva2VuID09IE5VTEwpIHsKKwlpZiAoQ1VSID09ICcqJykgeworCSAgICBORVhUOworCSAgICBpZiAoYXhpcyA9PSBBWElTX0FUVFJJQlVURSkgeworICAgICAgICAgICAgICAgIFBVU0goWFNMVF9PUF9BVFRSLCBOVUxMLCBOVUxMLCBub3Zhcik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBQVVNIKFhTTFRfT1BfQUxMLCBOVUxMLCBOVUxMLCBub3Zhcik7CisgICAgICAgICAgICB9CisJICAgIGdvdG8gcGFyc2VfcHJlZGljYXRlOworCX0gZWxzZSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkgICAgInhzbHRDb21waWxlU3RlcFBhdHRlcm4gOiBOYW1lIGV4cGVjdGVkXG4iKTsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCSAgICBnb3RvIGVycm9yOworCX0KKyAgICB9CisKKworICAgIFNLSVBfQkxBTktTOworICAgIGlmIChDVVIgPT0gJygnKSB7CisJeHNsdENvbXBpbGVJZEtleVBhdHRlcm4oY3R4dCwgdG9rZW4sIDAsIG5vdmFyLCBheGlzKTsKKwlpZiAoY3R4dC0+ZXJyb3IpCisJICAgIGdvdG8gZXJyb3I7CisgICAgfSBlbHNlIGlmIChDVVIgPT0gJzonKSB7CisJTkVYVDsKKwlpZiAoQ1VSICE9ICc6JykgeworCSAgICB4bWxDaGFyICpwcmVmaXggPSB0b2tlbjsKKwkgICAgeG1sTnNQdHIgbnM7CisKKwkgICAgLyoKKwkgICAgICogVGhpcyBpcyBhIG5hbWVzcGFjZSBtYXRjaAorCSAgICAgKi8KKwkgICAgdG9rZW4gPSB4c2x0U2Nhbk5DTmFtZShjdHh0KTsKKwkgICAgbnMgPSB4bWxTZWFyY2hOcyhjdHh0LT5kb2MsIGN0eHQtPmVsZW0sIHByZWZpeCk7CisJICAgIGlmIChucyA9PSBOVUxMKSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCSAgICAieHNsdENvbXBpbGVTdGVwUGF0dGVybiA6IG5vIG5hbWVzcGFjZSBib3VuZCB0byBwcmVmaXggJXNcbiIsCisJCQkJIHByZWZpeCk7CisJCXhtbEZyZWUocHJlZml4KTsKKwkJY3R4dC0+ZXJyb3IgPSAxOworCQlnb3RvIGVycm9yOworCSAgICB9IGVsc2UgeworCQlVUkwgPSB4bWxTdHJkdXAobnMtPmhyZWYpOworCSAgICB9CisJICAgIHhtbEZyZWUocHJlZml4KTsKKwkgICAgaWYgKHRva2VuID09IE5VTEwpIHsKKwkJaWYgKENVUiA9PSAnKicpIHsKKwkJICAgIE5FWFQ7CisgICAgICAgICAgICAgICAgICAgIGlmIChheGlzID09IEFYSVNfQVRUUklCVVRFKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBQVVNIKFhTTFRfT1BfQVRUUiwgTlVMTCwgVVJMLCBub3Zhcik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBQVVNIKFhTTFRfT1BfTlMsIFVSTCwgTlVMTCwgbm92YXIpOworICAgICAgICAgICAgICAgICAgICB9CisJCX0gZWxzZSB7CisJCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkJCSAgICAieHNsdENvbXBpbGVTdGVwUGF0dGVybiA6IE5hbWUgZXhwZWN0ZWRcbiIpOworCQkgICAgY3R4dC0+ZXJyb3IgPSAxOworCQkgICAgZ290byBlcnJvcjsKKwkJfQorCSAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChheGlzID09IEFYSVNfQVRUUklCVVRFKSB7CisgICAgICAgICAgICAgICAgICAgIFBVU0goWFNMVF9PUF9BVFRSLCB0b2tlbiwgVVJMLCBub3Zhcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICBQVVNIKFhTTFRfT1BfRUxFTSwgdG9rZW4sIFVSTCwgbm92YXIpOworICAgICAgICAgICAgICAgIH0KKwkgICAgfQorCX0gZWxzZSB7CisJICAgIGlmIChheGlzICE9IDApIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSAgICAieHNsdENvbXBpbGVTdGVwUGF0dGVybiA6IE5vZGVUZXN0IGV4cGVjdGVkXG4iKTsKKwkJY3R4dC0+ZXJyb3IgPSAxOworCQlnb3RvIGVycm9yOworCSAgICB9CisJICAgIE5FWFQ7CisJICAgIGlmICh4bWxTdHJFcXVhbCh0b2tlbiwgKGNvbnN0IHhtbENoYXIgKikgImNoaWxkIikpIHsKKwkgICAgICAgIGF4aXMgPSBBWElTX0NISUxEOworCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKHRva2VuLCAoY29uc3QgeG1sQ2hhciAqKSAiYXR0cmlidXRlIikpIHsKKwkgICAgICAgIGF4aXMgPSBBWElTX0FUVFJJQlVURTsKKwkgICAgfSBlbHNlIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSAgICAieHNsdENvbXBpbGVTdGVwUGF0dGVybiA6ICdjaGlsZCcgb3IgJ2F0dHJpYnV0ZScgZXhwZWN0ZWRcbiIpOworCQljdHh0LT5lcnJvciA9IDE7CisJCWdvdG8gZXJyb3I7CisJICAgIH0KKwkgICAgeG1sRnJlZSh0b2tlbik7CisgICAgICAgICAgICBTS0lQX0JMQU5LUzsKKyAgICAgICAgICAgIHRva2VuID0geHNsdFNjYW5OQ05hbWUoY3R4dCk7CisJICAgIGdvdG8gcGFyc2Vfbm9kZV90ZXN0OworCX0KKyAgICB9IGVsc2UgeworCVVSSSA9IHhzbHRHZXRRTmFtZVVSSShjdHh0LT5lbGVtLCAmdG9rZW4pOworCWlmICh0b2tlbiA9PSBOVUxMKSB7CisJICAgIGN0eHQtPmVycm9yID0gMTsKKwkgICAgZ290byBlcnJvcjsKKwl9CisJaWYgKFVSSSAhPSBOVUxMKQorCSAgICBVUkwgPSB4bWxTdHJkdXAoVVJJKTsKKyAgICAgICAgaWYgKGF4aXMgPT0gQVhJU19BVFRSSUJVVEUpIHsKKyAgICAgICAgICAgIFBVU0goWFNMVF9PUF9BVFRSLCB0b2tlbiwgVVJMLCBub3Zhcik7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBQVVNIKFhTTFRfT1BfRUxFTSwgdG9rZW4sIFVSTCwgbm92YXIpOworICAgICAgICB9CisgICAgfQorcGFyc2VfcHJlZGljYXRlOgorICAgIFNLSVBfQkxBTktTOworICAgIGxldmVsID0gMDsKKyAgICB3aGlsZSAoQ1VSID09ICdbJykgeworCWNvbnN0IHhtbENoYXIgKnE7CisJeG1sQ2hhciAqcmV0ID0gTlVMTDsKKworCWxldmVsKys7CisJTkVYVDsKKwlxID0gQ1VSX1BUUjsKKwl3aGlsZSAoQ1VSICE9IDApIHsKKwkgICAgLyogU2tpcCBvdmVyIG5lc3RlZCBwcmVkaWNhdGVzICovCisJICAgIGlmIChDVVIgPT0gJ1snKQorCQlsZXZlbCsrOworCSAgICBlbHNlIGlmIChDVVIgPT0gJ10nKSB7CisJCWxldmVsLS07CisJCWlmIChsZXZlbCA9PSAwKQorCQkgICAgYnJlYWs7CisJICAgIH0gZWxzZSBpZiAoQ1VSID09ICciJykgeworCQlORVhUOworCQl3aGlsZSAoKENVUiAhPSAwKSAmJiAoQ1VSICE9ICciJykpCisJCSAgICBORVhUOworCSAgICB9IGVsc2UgaWYgKENVUiA9PSAnXCcnKSB7CisJCU5FWFQ7CisJCXdoaWxlICgoQ1VSICE9IDApICYmIChDVVIgIT0gJ1wnJykpCisJCSAgICBORVhUOworCSAgICB9CisJICAgIE5FWFQ7CisJfQorCWlmIChDVVIgPT0gMCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkJICAgICJ4c2x0Q29tcGlsZVN0ZXBQYXR0ZXJuIDogJ10nIGV4cGVjdGVkXG4iKTsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCSAgICByZXR1cm47CisgICAgICAgIH0KKwlyZXQgPSB4bWxTdHJuZHVwKHEsIENVUl9QVFIgLSBxKTsKKwlQVVNIKFhTTFRfT1BfUFJFRElDQVRFLCByZXQsIE5VTEwsIG5vdmFyKTsKKwkvKiBwdXNoIHRoZSBwcmVkaWNhdGUgbG93ZXIgdGhhbiBsb2NhbCB0ZXN0ICovCisJU1dBUCgpOworCU5FWFQ7CisJU0tJUF9CTEFOS1M7CisgICAgfQorICAgIHJldHVybjsKK2Vycm9yOgorICAgIGlmICh0b2tlbiAhPSBOVUxMKQorCXhtbEZyZWUodG9rZW4pOworICAgIGlmIChuYW1lICE9IE5VTEwpCisJeG1sRnJlZShuYW1lKTsKK30KKworLyoqCisgKiB4c2x0Q29tcGlsZVJlbGF0aXZlUGF0aFBhdHRlcm46CisgKiBAY29tcDogIHRoZSBjb21waWxhdGlvbiBjb250ZXh0CisgKiBAdG9rZW46ICBhIHBvc2libGUgcHJlY29tcGlsZWQgbmFtZQorICogQG5vdmFyOiAgZmxhZyB0byBwcm9oaWJpdCB4c2x0IHZhcmlhYmxlcworICoKKyAqIENvbXBpbGUgdGhlIFhTTFQgUmVsYXRpdmVQYXRoUGF0dGVybiBhbmQgZ2VuZXJhdGVzIGEgcHJlY29tcGlsZWQKKyAqIGZvcm0gc3VpdGFibGUgZm9yIGZhc3QgbWF0Y2hpbmcuCisgKgorICogWzRdIFJlbGF0aXZlUGF0aFBhdHRlcm4gOjo9IFN0ZXBQYXR0ZXJuCisgKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUmVsYXRpdmVQYXRoUGF0dGVybiAnLycgU3RlcFBhdHRlcm4KKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBSZWxhdGl2ZVBhdGhQYXR0ZXJuICcvLycgU3RlcFBhdHRlcm4KKyAqLworc3RhdGljIHZvaWQKK3hzbHRDb21waWxlUmVsYXRpdmVQYXRoUGF0dGVybih4c2x0UGFyc2VyQ29udGV4dFB0ciBjdHh0LCB4bWxDaGFyICp0b2tlbiwgaW50IG5vdmFyKSB7CisgICAgeHNsdENvbXBpbGVTdGVwUGF0dGVybihjdHh0LCB0b2tlbiwgbm92YXIpOworICAgIGlmIChjdHh0LT5lcnJvcikKKwlnb3RvIGVycm9yOworICAgIFNLSVBfQkxBTktTOworICAgIHdoaWxlICgoQ1VSICE9IDApICYmIChDVVIgIT0gJ3wnKSkgeworCWlmICgoQ1VSID09ICcvJykgJiYgKE5YVCgxKSA9PSAnLycpKSB7CisJICAgIFBVU0goWFNMVF9PUF9BTkNFU1RPUiwgTlVMTCwgTlVMTCwgbm92YXIpOworCSAgICBORVhUOworCSAgICBORVhUOworCSAgICBTS0lQX0JMQU5LUzsKKwkgICAgeHNsdENvbXBpbGVTdGVwUGF0dGVybihjdHh0LCBOVUxMLCBub3Zhcik7CisJfSBlbHNlIGlmIChDVVIgPT0gJy8nKSB7CisJICAgIFBVU0goWFNMVF9PUF9QQVJFTlQsIE5VTEwsIE5VTEwsIG5vdmFyKTsKKwkgICAgTkVYVDsKKwkgICAgU0tJUF9CTEFOS1M7CisJICAgIGlmICgoQ1VSICE9IDApICYmIChDVVIgIT0gJ3wnKSkgeworCQl4c2x0Q29tcGlsZVJlbGF0aXZlUGF0aFBhdHRlcm4oY3R4dCwgTlVMTCwgbm92YXIpOworCSAgICB9CisJfSBlbHNlIHsKKwkgICAgY3R4dC0+ZXJyb3IgPSAxOworCX0KKwlpZiAoY3R4dC0+ZXJyb3IpCisJICAgIGdvdG8gZXJyb3I7CisJU0tJUF9CTEFOS1M7CisgICAgfQorZXJyb3I6CisgICAgcmV0dXJuOworfQorCisvKioKKyAqIHhzbHRDb21waWxlTG9jYXRpb25QYXRoUGF0dGVybjoKKyAqIEBjdHh0OiAgdGhlIGNvbXBpbGF0aW9uIGNvbnRleHQKKyAqIEBub3ZhcjogIGZsYWcgdG8gcHJvaGliaXQgeHNsdCB2YXJpYWJsZXMKKyAqCisgKiBDb21waWxlIHRoZSBYU0xUIExvY2F0aW9uUGF0aFBhdHRlcm4gYW5kIGdlbmVyYXRlcyBhIHByZWNvbXBpbGVkCisgKiBmb3JtIHN1aXRhYmxlIGZvciBmYXN0IG1hdGNoaW5nLgorICoKKyAqIFsyXSBMb2NhdGlvblBhdGhQYXR0ZXJuIDo6PSAnLycgUmVsYXRpdmVQYXRoUGF0dGVybj8KKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBJZEtleVBhdHRlcm4gKCgnLycgfCAnLy8nKSBSZWxhdGl2ZVBhdGhQYXR0ZXJuKT8KKyAqICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAnLy8nPyBSZWxhdGl2ZVBhdGhQYXR0ZXJuCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0Q29tcGlsZUxvY2F0aW9uUGF0aFBhdHRlcm4oeHNsdFBhcnNlckNvbnRleHRQdHIgY3R4dCwgaW50IG5vdmFyKSB7CisgICAgU0tJUF9CTEFOS1M7CisgICAgaWYgKChDVVIgPT0gJy8nKSAmJiAoTlhUKDEpID09ICcvJykpIHsKKwkvKgorCSAqIHNpbmNlIHdlIHJldmVyc2UgdGhlIHF1ZXJ5CisJICogYSBsZWFkaW5nIC8vIGNhbiBiZSBzYWZlbHkgaWdub3JlZAorCSAqLworCU5FWFQ7CisJTkVYVDsKKwljdHh0LT5jb21wLT5wcmlvcml0eSA9IDAuNTsJLyogJy8vJyBtZWFucyBub3QgMCBwcmlvcml0eSAqLworCXhzbHRDb21waWxlUmVsYXRpdmVQYXRoUGF0dGVybihjdHh0LCBOVUxMLCBub3Zhcik7CisgICAgfSBlbHNlIGlmIChDVVIgPT0gJy8nKSB7CisJLyoKKwkgKiBXZSBuZWVkIHRvIGZpbmQgcm9vdCBhcyB0aGUgcGFyZW50CisJICovCisJTkVYVDsKKwlTS0lQX0JMQU5LUzsKKwlQVVNIKFhTTFRfT1BfUk9PVCwgTlVMTCwgTlVMTCwgbm92YXIpOworCWlmICgoQ1VSICE9IDApICYmIChDVVIgIT0gJ3wnKSkgeworCSAgICBQVVNIKFhTTFRfT1BfUEFSRU5ULCBOVUxMLCBOVUxMLCBub3Zhcik7CisJICAgIHhzbHRDb21waWxlUmVsYXRpdmVQYXRoUGF0dGVybihjdHh0LCBOVUxMLCBub3Zhcik7CisJfQorICAgIH0gZWxzZSBpZiAoQ1VSID09ICcqJykgeworCXhzbHRDb21waWxlUmVsYXRpdmVQYXRoUGF0dGVybihjdHh0LCBOVUxMLCBub3Zhcik7CisgICAgfSBlbHNlIGlmIChDVVIgPT0gJ0AnKSB7CisJeHNsdENvbXBpbGVSZWxhdGl2ZVBhdGhQYXR0ZXJuKGN0eHQsIE5VTEwsIG5vdmFyKTsKKyAgICB9IGVsc2UgeworCXhtbENoYXIgKm5hbWU7CisJbmFtZSA9IHhzbHRTY2FuTkNOYW1lKGN0eHQpOworCWlmIChuYW1lID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSAgICAieHNsdENvbXBpbGVMb2NhdGlvblBhdGhQYXR0ZXJuIDogTmFtZSBleHBlY3RlZFxuIik7CisJICAgIGN0eHQtPmVycm9yID0gMTsKKwkgICAgcmV0dXJuOworCX0KKwlTS0lQX0JMQU5LUzsKKwlpZiAoKENVUiA9PSAnKCcpICYmICF4bWxYUGF0aElzTm9kZVR5cGUobmFtZSkpIHsKKwkgICAgeHNsdENvbXBpbGVJZEtleVBhdHRlcm4oY3R4dCwgbmFtZSwgMSwgbm92YXIsIDApOworCSAgICBpZiAoKENVUiA9PSAnLycpICYmIChOWFQoMSkgPT0gJy8nKSkgeworCQlQVVNIKFhTTFRfT1BfQU5DRVNUT1IsIE5VTEwsIE5VTEwsIG5vdmFyKTsKKwkJTkVYVDsKKwkJTkVYVDsKKwkJU0tJUF9CTEFOS1M7CisJCXhzbHRDb21waWxlUmVsYXRpdmVQYXRoUGF0dGVybihjdHh0LCBOVUxMLCBub3Zhcik7CisJICAgIH0gZWxzZSBpZiAoQ1VSID09ICcvJykgeworCQlQVVNIKFhTTFRfT1BfUEFSRU5ULCBOVUxMLCBOVUxMLCBub3Zhcik7CisJCU5FWFQ7CisJCVNLSVBfQkxBTktTOworCQl4c2x0Q29tcGlsZVJlbGF0aXZlUGF0aFBhdHRlcm4oY3R4dCwgTlVMTCwgbm92YXIpOworCSAgICB9CisJICAgIHJldHVybjsKKwl9CisJeHNsdENvbXBpbGVSZWxhdGl2ZVBhdGhQYXR0ZXJuKGN0eHQsIG5hbWUsIG5vdmFyKTsKKyAgICB9CitlcnJvcjoKKyAgICByZXR1cm47Cit9CisKKy8qKgorICogeHNsdENvbXBpbGVQYXR0ZXJuSW50ZXJuYWw6CisgKiBAcGF0dGVybjogYW4gWFNMVCBwYXR0ZXJuCisgKiBAZG9jOiAgdGhlIGNvbnRhaW5pbmcgZG9jdW1lbnQKKyAqIEBub2RlOiAgdGhlIGNvbnRhaW5pbmcgZWxlbWVudAorICogQHN0eWxlOiAgdGhlIHN0eWxlc2hlZXQKKyAqIEBydW50aW1lOiAgdGhlIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQsIGlmIGRvbmUgYXQgcnVuLXRpbWUKKyAqIEBub3ZhcjogIGZsYWcgdG8gcHJvaGliaXQgeHNsdCB2YXJpYWJsZXMKKyAqCisgKiBDb21waWxlIHRoZSBYU0xUIHBhdHRlcm4gYW5kIGdlbmVyYXRlcyBhIGxpc3Qgb2YgcHJlY29tcGlsZWQgZm9ybSBzdWl0YWJsZQorICogZm9yIGZhc3QgbWF0Y2hpbmcuCisgKgorICogWzFdIFBhdHRlcm4gOjo9IExvY2F0aW9uUGF0aFBhdHRlcm4gfCBQYXR0ZXJuICd8JyBMb2NhdGlvblBhdGhQYXR0ZXJuCisgKgorICogUmV0dXJucyB0aGUgZ2VuZXJhdGVkIHBhdHRlcm4gbGlzdCBvciBOVUxMIGluIGNhc2Ugb2YgZmFpbHVyZQorICovCisKK3N0YXRpYyB4c2x0Q29tcE1hdGNoUHRyCit4c2x0Q29tcGlsZVBhdHRlcm5JbnRlcm5hbChjb25zdCB4bWxDaGFyICpwYXR0ZXJuLCB4bWxEb2NQdHIgZG9jLAorCSAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKwkJICAgeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgcnVudGltZSwgaW50IG5vdmFyKSB7CisgICAgeHNsdFBhcnNlckNvbnRleHRQdHIgY3R4dCA9IE5VTEw7CisgICAgeHNsdENvbXBNYXRjaFB0ciBlbGVtZW50LCBmaXJzdCA9IE5VTEwsIHByZXZpb3VzID0gTlVMTDsKKyAgICBpbnQgY3VycmVudCwgc3RhcnQsIGVuZCwgbGV2ZWwsIGo7CisKKyAgICBpZiAocGF0dGVybiA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIG5vZGUsCisJCQkgInhzbHRDb21waWxlUGF0dGVybiA6IE5VTEwgcGF0dGVyblxuIik7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKworICAgIGN0eHQgPSB4c2x0TmV3UGFyc2VyQ29udGV4dChzdHlsZSwgcnVudGltZSk7CisgICAgaWYgKGN0eHQgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisgICAgY3R4dC0+ZG9jID0gZG9jOworICAgIGN0eHQtPmVsZW0gPSBub2RlOworICAgIGN1cnJlbnQgPSBlbmQgPSAwOworICAgIHdoaWxlIChwYXR0ZXJuW2N1cnJlbnRdICE9IDApIHsKKwlzdGFydCA9IGN1cnJlbnQ7CisJd2hpbGUgKElTX0JMQU5LX0NIKHBhdHRlcm5bY3VycmVudF0pKQorCSAgICBjdXJyZW50Kys7CisJZW5kID0gY3VycmVudDsKKwlsZXZlbCA9IDA7CisJd2hpbGUgKChwYXR0ZXJuW2VuZF0gIT0gMCkgJiYgKChwYXR0ZXJuW2VuZF0gIT0gJ3wnKSB8fCAobGV2ZWwgIT0gMCkpKSB7CisJICAgIGlmIChwYXR0ZXJuW2VuZF0gPT0gJ1snKQorCQlsZXZlbCsrOworCSAgICBlbHNlIGlmIChwYXR0ZXJuW2VuZF0gPT0gJ10nKQorCQlsZXZlbC0tOworCSAgICBlbHNlIGlmIChwYXR0ZXJuW2VuZF0gPT0gJ1wnJykgeworCQllbmQrKzsKKwkJd2hpbGUgKChwYXR0ZXJuW2VuZF0gIT0gMCkgJiYgKHBhdHRlcm5bZW5kXSAhPSAnXCcnKSkKKwkJICAgIGVuZCsrOworCSAgICB9IGVsc2UgaWYgKHBhdHRlcm5bZW5kXSA9PSAnIicpIHsKKwkJZW5kKys7CisJCXdoaWxlICgocGF0dGVybltlbmRdICE9IDApICYmIChwYXR0ZXJuW2VuZF0gIT0gJyInKSkKKwkJICAgIGVuZCsrOworCSAgICB9CisJICAgIGVuZCsrOworCX0KKwlpZiAoY3VycmVudCA9PSBlbmQpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIG5vZGUsCisJCQkgICAgICJ4c2x0Q29tcGlsZVBhdHRlcm4gOiBOVUxMIHBhdHRlcm5cbiIpOworCSAgICBnb3RvIGVycm9yOworCX0KKwllbGVtZW50ID0geHNsdE5ld0NvbXBNYXRjaCgpOworCWlmIChlbGVtZW50ID09IE5VTEwpIHsKKwkgICAgZ290byBlcnJvcjsKKwl9CisJaWYgKGZpcnN0ID09IE5VTEwpCisJICAgIGZpcnN0ID0gZWxlbWVudDsKKwllbHNlIGlmIChwcmV2aW91cyAhPSBOVUxMKQorCSAgICBwcmV2aW91cy0+bmV4dCA9IGVsZW1lbnQ7CisJcHJldmlvdXMgPSBlbGVtZW50OworCisJY3R4dC0+Y29tcCA9IGVsZW1lbnQ7CisJY3R4dC0+YmFzZSA9IHhtbFN0cm5kdXAoJnBhdHRlcm5bc3RhcnRdLCBlbmQgLSBzdGFydCk7CisJaWYgKGN0eHQtPmJhc2UgPT0gTlVMTCkKKwkgICAgZ290byBlcnJvcjsKKwljdHh0LT5jdXIgPSAmKGN0eHQtPmJhc2UpW2N1cnJlbnQgLSBzdGFydF07CisJZWxlbWVudC0+cGF0dGVybiA9IGN0eHQtPmJhc2U7CisJZWxlbWVudC0+bnNMaXN0ID0geG1sR2V0TnNMaXN0KGRvYywgbm9kZSk7CisJaiA9IDA7CisJaWYgKGVsZW1lbnQtPm5zTGlzdCAhPSBOVUxMKSB7CisJICAgIHdoaWxlIChlbGVtZW50LT5uc0xpc3Rbal0gIT0gTlVMTCkKKwkJaisrOworCX0KKwllbGVtZW50LT5uc05yID0gajsKKworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBVFRFUk4KKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJICJ4c2x0Q29tcGlsZVBhdHRlcm4gOiBwYXJzaW5nICclcydcbiIsCisJCQkgZWxlbWVudC0+cGF0dGVybik7CisjZW5kaWYKKwkvKgorCSBQcmVzZXQgZGVmYXVsdCBwcmlvcml0eSB0byBiZSB6ZXJvLgorCSBUaGlzIG1heSBiZSBjaGFuZ2VkIGJ5IHhzbHRDb21waWxlTG9jYXRpb25QYXRoUGF0dGVybi4KKwkgKi8KKwllbGVtZW50LT5wcmlvcml0eSA9IDA7CisJeHNsdENvbXBpbGVMb2NhdGlvblBhdGhQYXR0ZXJuKGN0eHQsIG5vdmFyKTsKKwlpZiAoY3R4dC0+ZXJyb3IpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBub2RlLAorCQkJICAgICAieHNsdENvbXBpbGVQYXR0ZXJuIDogZmFpbGVkIHRvIGNvbXBpbGUgJyVzJ1xuIiwKKwkJCSAgICAgZWxlbWVudC0+cGF0dGVybik7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJICAgIGdvdG8gZXJyb3I7CisJfQorCisJLyoKKwkgKiBSZXZlcnNlIGZvciBmYXN0ZXIgaW50ZXJwcmV0YXRpb24uCisJICovCisJeHNsdFJldmVyc2VDb21wTWF0Y2goY3R4dCwgZWxlbWVudCk7CisKKwkvKgorCSAqIFNldC11cCB0aGUgcHJpb3JpdHkKKwkgKi8KKwlpZiAoZWxlbWVudC0+cHJpb3JpdHkgPT0gMCkgewkvKiBpZiBub3QgeWV0IGRldGVybWluZWQgKi8KKwkgICAgaWYgKCgoZWxlbWVudC0+c3RlcHNbMF0ub3AgPT0gWFNMVF9PUF9FTEVNKSB8fAorCQkgKGVsZW1lbnQtPnN0ZXBzWzBdLm9wID09IFhTTFRfT1BfQVRUUikgfHwKKwkJIChlbGVtZW50LT5zdGVwc1swXS5vcCA9PSBYU0xUX09QX1BJKSkgJiYKKwkJKGVsZW1lbnQtPnN0ZXBzWzBdLnZhbHVlICE9IE5VTEwpICYmCisJCShlbGVtZW50LT5zdGVwc1sxXS5vcCA9PSBYU0xUX09QX0VORCkpIHsKKwkJOwkvKiBwcmV2aW91c2x5IHByZXNldCAqLworCSAgICB9IGVsc2UgaWYgKChlbGVtZW50LT5zdGVwc1swXS5vcCA9PSBYU0xUX09QX0FUVFIpICYmCisJCSAgICAgICAoZWxlbWVudC0+c3RlcHNbMF0udmFsdWUyICE9IE5VTEwpICYmCisJCSAgICAgICAoZWxlbWVudC0+c3RlcHNbMV0ub3AgPT0gWFNMVF9PUF9FTkQpKSB7CisJCQllbGVtZW50LT5wcmlvcml0eSA9IC0wLjI1OworCSAgICB9IGVsc2UgaWYgKChlbGVtZW50LT5zdGVwc1swXS5vcCA9PSBYU0xUX09QX05TKSAmJgorCQkgICAgICAgKGVsZW1lbnQtPnN0ZXBzWzBdLnZhbHVlICE9IE5VTEwpICYmCisJCSAgICAgICAoZWxlbWVudC0+c3RlcHNbMV0ub3AgPT0gWFNMVF9PUF9FTkQpKSB7CisJCQllbGVtZW50LT5wcmlvcml0eSA9IC0wLjI1OworCSAgICB9IGVsc2UgaWYgKChlbGVtZW50LT5zdGVwc1swXS5vcCA9PSBYU0xUX09QX0FUVFIpICYmCisJCSAgICAgICAoZWxlbWVudC0+c3RlcHNbMF0udmFsdWUgPT0gTlVMTCkgJiYKKwkJICAgICAgIChlbGVtZW50LT5zdGVwc1swXS52YWx1ZTIgPT0gTlVMTCkgJiYKKwkJICAgICAgIChlbGVtZW50LT5zdGVwc1sxXS5vcCA9PSBYU0xUX09QX0VORCkpIHsKKwkJCWVsZW1lbnQtPnByaW9yaXR5ID0gLTAuNTsKKwkgICAgfSBlbHNlIGlmICgoKGVsZW1lbnQtPnN0ZXBzWzBdLm9wID09IFhTTFRfT1BfUEkpIHx8CisJCSAgICAgICAoZWxlbWVudC0+c3RlcHNbMF0ub3AgPT0gWFNMVF9PUF9URVhUKSB8fAorCQkgICAgICAgKGVsZW1lbnQtPnN0ZXBzWzBdLm9wID09IFhTTFRfT1BfQUxMKSB8fAorCQkgICAgICAgKGVsZW1lbnQtPnN0ZXBzWzBdLm9wID09IFhTTFRfT1BfTk9ERSkgfHwKKwkJICAgICAgIChlbGVtZW50LT5zdGVwc1swXS5vcCA9PSBYU0xUX09QX0NPTU1FTlQpKSAmJgorCQkgICAgICAgKGVsZW1lbnQtPnN0ZXBzWzFdLm9wID09IFhTTFRfT1BfRU5EKSkgeworCQkJZWxlbWVudC0+cHJpb3JpdHkgPSAtMC41OworCSAgICB9IGVsc2UgeworCQllbGVtZW50LT5wcmlvcml0eSA9IDAuNTsKKwkgICAgfQorCX0KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFUVEVSTgorCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAgInhzbHRDb21waWxlUGF0dGVybiA6IHBhcnNlZCAlcywgZGVmYXVsdCBwcmlvcml0eSAlZlxuIiwKKwkJCSBlbGVtZW50LT5wYXR0ZXJuLCBlbGVtZW50LT5wcmlvcml0eSk7CisjZW5kaWYKKwlpZiAocGF0dGVybltlbmRdID09ICd8JykKKwkgICAgZW5kKys7CisJY3VycmVudCA9IGVuZDsKKyAgICB9CisgICAgaWYgKGVuZCA9PSAwKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBub2RlLAorCQkJICJ4c2x0Q29tcGlsZVBhdHRlcm4gOiBOVUxMIHBhdHRlcm5cbiIpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJZ290byBlcnJvcjsKKyAgICB9CisKKyAgICB4c2x0RnJlZVBhcnNlckNvbnRleHQoY3R4dCk7CisgICAgcmV0dXJuKGZpcnN0KTsKKworZXJyb3I6CisgICAgaWYgKGN0eHQgIT0gTlVMTCkKKwl4c2x0RnJlZVBhcnNlckNvbnRleHQoY3R4dCk7CisgICAgaWYgKGZpcnN0ICE9IE5VTEwpCisJeHNsdEZyZWVDb21wTWF0Y2hMaXN0KGZpcnN0KTsKKyAgICByZXR1cm4oTlVMTCk7Cit9CisKKy8qKgorICogeHNsdENvbXBpbGVQYXR0ZXJuOgorICogQHBhdHRlcm46IGFuIFhTTFQgcGF0dGVybgorICogQGRvYzogIHRoZSBjb250YWluaW5nIGRvY3VtZW50CisgKiBAbm9kZTogIHRoZSBjb250YWluaW5nIGVsZW1lbnQKKyAqIEBzdHlsZTogIHRoZSBzdHlsZXNoZWV0CisgKiBAcnVudGltZTogIHRoZSB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0LCBpZiBkb25lIGF0IHJ1bi10aW1lCisgKgorICogQ29tcGlsZSB0aGUgWFNMVCBwYXR0ZXJuIGFuZCBnZW5lcmF0ZXMgYSBsaXN0IG9mIHByZWNvbXBpbGVkIGZvcm0gc3VpdGFibGUKKyAqIGZvciBmYXN0IG1hdGNoaW5nLgorICoKKyAqIFsxXSBQYXR0ZXJuIDo6PSBMb2NhdGlvblBhdGhQYXR0ZXJuIHwgUGF0dGVybiAnfCcgTG9jYXRpb25QYXRoUGF0dGVybgorICoKKyAqIFJldHVybnMgdGhlIGdlbmVyYXRlZCBwYXR0ZXJuIGxpc3Qgb3IgTlVMTCBpbiBjYXNlIG9mIGZhaWx1cmUKKyAqLworCit4c2x0Q29tcE1hdGNoUHRyCit4c2x0Q29tcGlsZVBhdHRlcm4oY29uc3QgeG1sQ2hhciAqcGF0dGVybiwgeG1sRG9jUHRyIGRvYywKKwkgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCSAgIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIHJ1bnRpbWUpIHsKKyAgICByZXR1cm4gKHhzbHRDb21waWxlUGF0dGVybkludGVybmFsKHBhdHRlcm4sIGRvYywgbm9kZSwgc3R5bGUsIHJ1bnRpbWUsIDApKTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJCU1vZHVsZSBpbnRlcmZhY2VzCQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0QWRkVGVtcGxhdGU6CisgKiBAc3R5bGU6IGFuIFhTTFQgc3R5bGVzaGVldAorICogQGN1cjogYW4gWFNMVCB0ZW1wbGF0ZQorICogQG1vZGU6ICB0aGUgbW9kZSBuYW1lIG9yIE5VTEwKKyAqIEBtb2RlVVJJOiAgdGhlIG1vZGUgVVJJIG9yIE5VTEwKKyAqCisgKiBSZWdpc3RlciB0aGUgWFNMVCBwYXR0ZXJuIGFzc29jaWF0ZWQgdG8gQGN1cgorICoKKyAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBvdGhlcndpc2UKKyAqLworaW50Cit4c2x0QWRkVGVtcGxhdGUoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhzbHRUZW1wbGF0ZVB0ciBjdXIsCisJICAgICAgICBjb25zdCB4bWxDaGFyICptb2RlLCBjb25zdCB4bWxDaGFyICptb2RlVVJJKSB7CisgICAgeHNsdENvbXBNYXRjaFB0ciBwYXQsIGxpc3QsIG5leHQ7CisgICAgLyoKKyAgICAgKiAndG9wJyB3aWxsIHBvaW50IHRvIHN0eWxlLT54eHhNYXRjaCBwdHIgLSBkZWNsYXJpbmcgYXMgJ3ZvaWQnCisgICAgICogIGF2b2lkcyBnY2MgJ3R5cGUtcHVubmVkIHBvaW50ZXInIHdhcm5pbmcuCisgICAgICovCisgICAgdm9pZCAqKnRvcCA9IE5VTEw7CisgICAgY29uc3QgeG1sQ2hhciAqbmFtZSA9IE5VTEw7CisgICAgZmxvYXQgcHJpb3JpdHk7ICAgICAgICAgICAgICAvKiB0aGUgcHJpb3JpdHkgKi8KKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGN1ciA9PSBOVUxMKSB8fCAoY3VyLT5tYXRjaCA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworCisgICAgcHJpb3JpdHkgPSBjdXItPnByaW9yaXR5OworICAgIHBhdCA9IHhzbHRDb21waWxlUGF0dGVybkludGVybmFsKGN1ci0+bWF0Y2gsIHN0eWxlLT5kb2MsIGN1ci0+ZWxlbSwKKwkJICAgIHN0eWxlLCBOVUxMLCAxKTsKKyAgICBpZiAocGF0ID09IE5VTEwpCisgICAgCXJldHVybigtMSk7CisgICAgd2hpbGUgKHBhdCkgeworCW5leHQgPSBwYXQtPm5leHQ7CisJcGF0LT5uZXh0ID0gTlVMTDsKKwluYW1lID0gTlVMTDsKKwkKKwlwYXQtPnRlbXBsYXRlID0gY3VyOworCWlmIChtb2RlICE9IE5VTEwpCisJICAgIHBhdC0+bW9kZSA9IHhtbERpY3RMb29rdXAoc3R5bGUtPmRpY3QsIG1vZGUsIC0xKTsKKwlpZiAobW9kZVVSSSAhPSBOVUxMKQorCSAgICBwYXQtPm1vZGVVUkkgPSB4bWxEaWN0TG9va3VwKHN0eWxlLT5kaWN0LCBtb2RlVVJJLCAtMSk7CisJaWYgKHByaW9yaXR5ICE9IFhTTFRfUEFUX05PX1BSSU9SSVRZKQorCSAgICBwYXQtPnByaW9yaXR5ID0gcHJpb3JpdHk7CisKKwkvKgorCSAqIGluc2VydCBpdCBpbiB0aGUgaGFzaCB0YWJsZSBsaXN0IGNvcnJlc3BvbmRpbmcgdG8gaXRzIGxvb2t1cCBuYW1lCisJICovCisJc3dpdGNoIChwYXQtPnN0ZXBzWzBdLm9wKSB7CisgICAgICAgIGNhc2UgWFNMVF9PUF9BVFRSOgorCSAgICBpZiAocGF0LT5zdGVwc1swXS52YWx1ZSAhPSBOVUxMKQorCQluYW1lID0gcGF0LT5zdGVwc1swXS52YWx1ZTsKKwkgICAgZWxzZQorCQl0b3AgPSAmKHN0eWxlLT5hdHRyTWF0Y2gpOworCSAgICBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX09QX1BBUkVOVDoKKyAgICAgICAgY2FzZSBYU0xUX09QX0FOQ0VTVE9SOgorCSAgICB0b3AgPSAmKHN0eWxlLT5lbGVtTWF0Y2gpOworCSAgICBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX09QX1JPT1Q6CisJICAgIHRvcCA9ICYoc3R5bGUtPnJvb3RNYXRjaCk7CisJICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfT1BfS0VZOgorCSAgICB0b3AgPSAmKHN0eWxlLT5rZXlNYXRjaCk7CisJICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfT1BfSUQ6CisJICAgIC8qIFRPRE8gb3B0aW1pemUgSUQgISEhICovCisgICAgICAgIGNhc2UgWFNMVF9PUF9OUzoKKyAgICAgICAgY2FzZSBYU0xUX09QX0FMTDoKKwkgICAgdG9wID0gJihzdHlsZS0+ZWxlbU1hdGNoKTsKKwkgICAgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9PUF9FTkQ6CisJY2FzZSBYU0xUX09QX1BSRURJQ0FURToKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBOVUxMLAorCQkJICAgICAieHNsdEFkZFRlbXBsYXRlOiBpbnZhbGlkIGNvbXBpbGVkIHBhdHRlcm5cbiIpOworCSAgICB4c2x0RnJlZUNvbXBNYXRjaChwYXQpOworCSAgICByZXR1cm4oLTEpOworCSAgICAvKgorCSAgICAgKiBUT0RPOiBzb21lIGZsYWdzIGF0IHRoZSB0b3AgbGV2ZWwgYWJvdXQgdHlwZSBiYXNlZCBwYXR0ZXJucworCSAgICAgKiAgICAgICB3b3VsZCBiZSBmYXN0ZXIgdGhhbiBpbmNsdXNpb24gaW4gdGhlIGhhc2ggdGFibGUuCisJICAgICAqLworCWNhc2UgWFNMVF9PUF9QSToKKwkgICAgaWYgKHBhdC0+c3RlcHNbMF0udmFsdWUgIT0gTlVMTCkKKwkJbmFtZSA9IHBhdC0+c3RlcHNbMF0udmFsdWU7CisJICAgIGVsc2UKKwkJdG9wID0gJihzdHlsZS0+cGlNYXRjaCk7CisJICAgIGJyZWFrOworCWNhc2UgWFNMVF9PUF9DT01NRU5UOgorCSAgICB0b3AgPSAmKHN0eWxlLT5jb21tZW50TWF0Y2gpOworCSAgICBicmVhazsKKwljYXNlIFhTTFRfT1BfVEVYVDoKKwkgICAgdG9wID0gJihzdHlsZS0+dGV4dE1hdGNoKTsKKwkgICAgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9PUF9FTEVNOgorCWNhc2UgWFNMVF9PUF9OT0RFOgorCSAgICBpZiAocGF0LT5zdGVwc1swXS52YWx1ZSAhPSBOVUxMKQorCQluYW1lID0gcGF0LT5zdGVwc1swXS52YWx1ZTsKKwkgICAgZWxzZQorCQl0b3AgPSAmKHN0eWxlLT5lbGVtTWF0Y2gpOworCSAgICBicmVhazsKKwl9CisJaWYgKG5hbWUgIT0gTlVMTCkgeworCSAgICBpZiAoc3R5bGUtPnRlbXBsYXRlc0hhc2ggPT0gTlVMTCkgeworCQlzdHlsZS0+dGVtcGxhdGVzSGFzaCA9IHhtbEhhc2hDcmVhdGUoMTAyNCk7CisJCWlmIChzdHlsZS0+dGVtcGxhdGVzSGFzaCA9PSBOVUxMKSB7CisJCSAgICB4c2x0RnJlZUNvbXBNYXRjaChwYXQpOworCQkgICAgcmV0dXJuKC0xKTsKKwkJfQorCQl4bWxIYXNoQWRkRW50cnkzKHN0eWxlLT50ZW1wbGF0ZXNIYXNoLCBuYW1lLCBtb2RlLCBtb2RlVVJJLCBwYXQpOworCSAgICB9IGVsc2UgeworCQlsaXN0ID0gKHhzbHRDb21wTWF0Y2hQdHIpIHhtbEhhc2hMb29rdXAzKHN0eWxlLT50ZW1wbGF0ZXNIYXNoLAorCQkJCQkJCSBuYW1lLCBtb2RlLCBtb2RlVVJJKTsKKwkJaWYgKGxpc3QgPT0gTlVMTCkgeworCQkgICAgeG1sSGFzaEFkZEVudHJ5MyhzdHlsZS0+dGVtcGxhdGVzSGFzaCwgbmFtZSwKKwkJCQkgICAgIG1vZGUsIG1vZGVVUkksIHBhdCk7CisJCX0gZWxzZSB7CisJCSAgICAvKgorCQkgICAgICogTm90ZSAnPD0nIHNpbmNlIG9uZSBtdXN0IGNob29zZSBhbW9uZyB0aGUgbWF0Y2hpbmcKKwkJICAgICAqIHRlbXBsYXRlIHJ1bGVzIHRoYXQgYXJlIGxlZnQsIHRoZSBvbmUgdGhhdCBvY2N1cnMKKwkJICAgICAqIGxhc3QgaW4gdGhlIHN0eWxlc2hlZXQKKwkJICAgICAqLworCQkgICAgaWYgKGxpc3QtPnByaW9yaXR5IDw9IHBhdC0+cHJpb3JpdHkpIHsKKwkJCXBhdC0+bmV4dCA9IGxpc3Q7CisJCQl4bWxIYXNoVXBkYXRlRW50cnkzKHN0eWxlLT50ZW1wbGF0ZXNIYXNoLCBuYW1lLAorCQkJCQkgICAgbW9kZSwgbW9kZVVSSSwgcGF0LCBOVUxMKTsKKwkJICAgIH0gZWxzZSB7CisJCQl3aGlsZSAobGlzdC0+bmV4dCAhPSBOVUxMKSB7CisJCQkgICAgaWYgKGxpc3QtPm5leHQtPnByaW9yaXR5IDw9IHBhdC0+cHJpb3JpdHkpCisJCQkJYnJlYWs7CisJCQkgICAgbGlzdCA9IGxpc3QtPm5leHQ7CisJCQl9CisJCQlwYXQtPm5leHQgPSBsaXN0LT5uZXh0OworCQkJbGlzdC0+bmV4dCA9IHBhdDsKKwkJICAgIH0KKwkJfQorCSAgICB9CisJfSBlbHNlIGlmICh0b3AgIT0gTlVMTCkgeworCSAgICBsaXN0ID0gKnRvcDsKKwkgICAgaWYgKGxpc3QgPT0gTlVMTCkgeworCQkqdG9wID0gcGF0OworCQlwYXQtPm5leHQgPSBOVUxMOworCSAgICB9IGVsc2UgaWYgKGxpc3QtPnByaW9yaXR5IDw9IHBhdC0+cHJpb3JpdHkpIHsKKwkJcGF0LT5uZXh0ID0gbGlzdDsKKwkJKnRvcCA9IHBhdDsKKwkgICAgfSBlbHNlIHsKKwkJd2hpbGUgKGxpc3QtPm5leHQgIT0gTlVMTCkgeworCQkgICAgaWYgKGxpc3QtPm5leHQtPnByaW9yaXR5IDw9IHBhdC0+cHJpb3JpdHkpCisJCQlicmVhazsKKwkJICAgIGxpc3QgPSBsaXN0LT5uZXh0OworCQl9CisJCXBhdC0+bmV4dCA9IGxpc3QtPm5leHQ7CisJCWxpc3QtPm5leHQgPSBwYXQ7CisJICAgIH0KKwl9IGVsc2UgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIE5VTEwsCisJCQkgICAgICJ4c2x0QWRkVGVtcGxhdGU6IGludmFsaWQgY29tcGlsZWQgcGF0dGVyblxuIik7CisJICAgIHhzbHRGcmVlQ29tcE1hdGNoKHBhdCk7CisJICAgIHJldHVybigtMSk7CisJfQorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVRURVJOCisJaWYgKG1vZGUpCisJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkgImFkZGVkIHBhdHRlcm4gOiAnJXMnIG1vZGUgJyVzJyBwcmlvcml0eSAlZlxuIiwKKwkJCSAgICAgcGF0LT5wYXR0ZXJuLCBwYXQtPm1vZGUsIHBhdC0+cHJpb3JpdHkpOworCWVsc2UKKwkgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSAiYWRkZWQgcGF0dGVybiA6ICclcycgcHJpb3JpdHkgJWZcbiIsCisJCQkgICAgIHBhdC0+cGF0dGVybiwgcGF0LT5wcmlvcml0eSk7CisjZW5kaWYKKworCXBhdCA9IG5leHQ7CisgICAgfQorICAgIHJldHVybigwKTsKK30KKworc3RhdGljIGludAoreHNsdENvbXB1dGVBbGxLZXlzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgY29udGV4dE5vZGUpCit7CisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChjb250ZXh0Tm9kZSA9PSBOVUxMKSkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjdHh0LT5pbnN0LAorCSAgICAiSW50ZXJuYWwgZXJyb3IgaW4geHNsdENvbXB1dGVBbGxLZXlzKCk6ICIKKwkgICAgIkJhZCBhcmd1bWVudHMuXG4iKTsKKwlyZXR1cm4oLTEpOworICAgIH0KKworICAgIGlmIChjdHh0LT5kb2N1bWVudCA9PSBOVUxMKSB7CisJLyoKKwkqIFRoZSBkb2N1bWVudCBpbmZvIHdpbGwgb25seSBiZSBOVUxMIGlmIHdlIGhhdmUgYSBSVEYuCisJKi8KKwlpZiAoY29udGV4dE5vZGUtPmRvYy0+X3ByaXZhdGUgIT0gTlVMTCkKKwkgICAgZ290byBkb2NfaW5mb19taXNtYXRjaDsKKwkvKgorCSogT24tZGVtYW5kIGNyZWF0aW9uIG9mIHRoZSBkb2N1bWVudCBpbmZvIChuZWVkZWQgZm9yIGtleXMpLgorCSovCisJY3R4dC0+ZG9jdW1lbnQgPSB4c2x0TmV3RG9jdW1lbnQoY3R4dCwgY29udGV4dE5vZGUtPmRvYyk7CisJaWYgKGN0eHQtPmRvY3VtZW50ID09IE5VTEwpCisJICAgIHJldHVybigtMSk7CisgICAgfQorICAgIHJldHVybiB4c2x0SW5pdEFsbERvY0tleXMoY3R4dCk7CisKK2RvY19pbmZvX21pc21hdGNoOgorICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjdHh0LT5pbnN0LAorCSJJbnRlcm5hbCBlcnJvciBpbiB4c2x0Q29tcHV0ZUFsbEtleXMoKTogIgorCSJUaGUgY29udGV4dCdzIGRvY3VtZW50IGluZm8gZG9lc24ndCBtYXRjaCB0aGUgIgorCSJkb2N1bWVudCBpbmZvIG9mIHRoZSBjdXJyZW50IHJlc3VsdCB0cmVlLlxuIik7CisgICAgY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisgICAgcmV0dXJuKC0xKTsKK30KKworLyoqCisgKiB4c2x0R2V0VGVtcGxhdGU6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBub2RlOiAgdGhlIG5vZGUgYmVpbmcgcHJvY2Vzc2VkCisgKiBAc3R5bGU6ICB0aGUgY3VycmVudCBzdHlsZQorICoKKyAqIEZpbmRzIHRoZSB0ZW1wbGF0ZSBhcHBseWluZyB0byB0aGlzIG5vZGUsIGlmIEBzdHlsZSBpcyBub24tTlVMTAorICogaXQgbWVhbnMgb25lIG5lZWRzIHRvIGxvb2sgZm9yIHRoZSBuZXh0IGltcG9ydGVkIHRlbXBsYXRlIGluIHNjb3BlLgorICoKKyAqIFJldHVybnMgdGhlIHhzbHRUZW1wbGF0ZVB0ciBvciBOVUxMIGlmIG5vdCBmb3VuZAorICovCit4c2x0VGVtcGxhdGVQdHIKK3hzbHRHZXRUZW1wbGF0ZSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJICAgICAgICB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkKK3sKKyAgICB4c2x0U3R5bGVzaGVldFB0ciBjdXJzdHlsZTsKKyAgICB4c2x0VGVtcGxhdGVQdHIgcmV0ID0gTlVMTDsKKyAgICBjb25zdCB4bWxDaGFyICpuYW1lID0gTlVMTDsKKyAgICB4c2x0Q29tcE1hdGNoUHRyIGxpc3QgPSBOVUxMOworICAgIGZsb2F0IHByaW9yaXR5OworICAgIGludCBrZXllZCA9IDA7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCisJcmV0dXJuKE5VTEwpOworCisgICAgaWYgKHN0eWxlID09IE5VTEwpIHsKKwljdXJzdHlsZSA9IGN0eHQtPnN0eWxlOworICAgIH0gZWxzZSB7CisJY3Vyc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisgICAgfQorCisgICAgd2hpbGUgKChjdXJzdHlsZSAhPSBOVUxMKSAmJiAoY3Vyc3R5bGUgIT0gc3R5bGUpKSB7CisJcHJpb3JpdHkgPSBYU0xUX1BBVF9OT19QUklPUklUWTsKKwkvKiBUT0RPIDogaGFuZGxlIElEcy9rZXlzIGhlcmUgISAqLworCWlmIChjdXJzdHlsZS0+dGVtcGxhdGVzSGFzaCAhPSBOVUxMKSB7CisJICAgIC8qCisJICAgICAqIFVzZSB0aGUgdG9wIG5hbWUgYXMgc2VsZWN0b3IKKwkgICAgICovCisJICAgIHN3aXRjaCAobm9kZS0+dHlwZSkgeworCQljYXNlIFhNTF9FTEVNRU5UX05PREU6CisJCSAgICBpZiAobm9kZS0+bmFtZVswXSA9PSAnICcpCisJCQlicmVhazsKKwkJY2FzZSBYTUxfQVRUUklCVVRFX05PREU6CisJCWNhc2UgWE1MX1BJX05PREU6CisJCSAgICBuYW1lID0gbm9kZS0+bmFtZTsKKwkJICAgIGJyZWFrOworCQljYXNlIFhNTF9ET0NVTUVOVF9OT0RFOgorCQljYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CisJCWNhc2UgWE1MX1RFWFRfTk9ERToKKwkJY2FzZSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFOgorCQljYXNlIFhNTF9DT01NRU5UX05PREU6CisJCWNhc2UgWE1MX0VOVElUWV9SRUZfTk9ERToKKwkJY2FzZSBYTUxfRU5USVRZX05PREU6CisJCWNhc2UgWE1MX0RPQ1VNRU5UX1RZUEVfTk9ERToKKwkJY2FzZSBYTUxfRE9DVU1FTlRfRlJBR19OT0RFOgorCQljYXNlIFhNTF9OT1RBVElPTl9OT0RFOgorCQljYXNlIFhNTF9EVERfTk9ERToKKwkJY2FzZSBYTUxfRUxFTUVOVF9ERUNMOgorCQljYXNlIFhNTF9BVFRSSUJVVEVfREVDTDoKKwkJY2FzZSBYTUxfRU5USVRZX0RFQ0w6CisJCWNhc2UgWE1MX05BTUVTUEFDRV9ERUNMOgorCQljYXNlIFhNTF9YSU5DTFVERV9TVEFSVDoKKwkJY2FzZSBYTUxfWElOQ0xVREVfRU5EOgorCQkgICAgYnJlYWs7CisJCWRlZmF1bHQ6CisJCSAgICByZXR1cm4oTlVMTCk7CisKKwkgICAgfQorCX0KKwlpZiAobmFtZSAhPSBOVUxMKSB7CisJICAgIC8qCisJICAgICAqIGZpbmQgdGhlIGxpc3Qgb2YgYXBwbGljYWJsZSBleHByZXNzaW9ucyBiYXNlZCBvbiB0aGUgbmFtZQorCSAgICAgKi8KKwkgICAgbGlzdCA9ICh4c2x0Q29tcE1hdGNoUHRyKSB4bWxIYXNoTG9va3VwMyhjdXJzdHlsZS0+dGVtcGxhdGVzSGFzaCwKKwkJCQkJICAgICBuYW1lLCBjdHh0LT5tb2RlLCBjdHh0LT5tb2RlVVJJKTsKKwl9IGVsc2UKKwkgICAgbGlzdCA9IE5VTEw7CisJd2hpbGUgKGxpc3QgIT0gTlVMTCkgeworCSAgICBpZiAoeHNsdFRlc3RDb21wTWF0Y2goY3R4dCwgbGlzdCwgbm9kZSwKKwkJCSAgICAgICAgICBjdHh0LT5tb2RlLCBjdHh0LT5tb2RlVVJJKSkgeworCQlyZXQgPSBsaXN0LT50ZW1wbGF0ZTsKKwkJcHJpb3JpdHkgPSBsaXN0LT5wcmlvcml0eTsKKwkJYnJlYWs7CisJICAgIH0KKwkgICAgbGlzdCA9IGxpc3QtPm5leHQ7CisJfQorCWxpc3QgPSBOVUxMOworCisJLyoKKwkgKiBmaW5kIGFsdGVybmF0ZSBnZW5lcmljIG1hdGNoZXMKKwkgKi8KKwlzd2l0Y2ggKG5vZGUtPnR5cGUpIHsKKwkgICAgY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgorCQlpZiAobm9kZS0+bmFtZVswXSA9PSAnICcpCisJCSAgICBsaXN0ID0gY3Vyc3R5bGUtPnJvb3RNYXRjaDsKKwkJZWxzZQorCQkgICAgbGlzdCA9IGN1cnN0eWxlLT5lbGVtTWF0Y2g7CisJCWlmIChub2RlLT5wc3ZpICE9IE5VTEwpIGtleWVkID0gMTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWE1MX0FUVFJJQlVURV9OT0RFOiB7CisJICAgICAgICB4bWxBdHRyUHRyIGF0dHI7CisKKwkJbGlzdCA9IGN1cnN0eWxlLT5hdHRyTWF0Y2g7CisJCWF0dHIgPSAoeG1sQXR0clB0cikgbm9kZTsKKwkJaWYgKGF0dHItPnBzdmkgIT0gTlVMTCkga2V5ZWQgPSAxOworCQlicmVhazsKKwkgICAgfQorCSAgICBjYXNlIFhNTF9QSV9OT0RFOgorCQlsaXN0ID0gY3Vyc3R5bGUtPnBpTWF0Y2g7CisJCWlmIChub2RlLT5wc3ZpICE9IE5VTEwpIGtleWVkID0gMTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX05PREU6CisJICAgIGNhc2UgWE1MX0hUTUxfRE9DVU1FTlRfTk9ERTogeworCSAgICAgICAgeG1sRG9jUHRyIGRvYzsKKworCQlsaXN0ID0gY3Vyc3R5bGUtPnJvb3RNYXRjaDsKKwkJZG9jID0gKHhtbERvY1B0cikgbm9kZTsKKwkJaWYgKGRvYy0+cHN2aSAhPSBOVUxMKSBrZXllZCA9IDE7CisJCWJyZWFrOworCSAgICB9CisJICAgIGNhc2UgWE1MX1RFWFRfTk9ERToKKwkgICAgY2FzZSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFOgorCQlsaXN0ID0gY3Vyc3R5bGUtPnRleHRNYXRjaDsKKwkJaWYgKG5vZGUtPnBzdmkgIT0gTlVMTCkga2V5ZWQgPSAxOworCQlicmVhazsKKwkgICAgY2FzZSBYTUxfQ09NTUVOVF9OT0RFOgorCQlsaXN0ID0gY3Vyc3R5bGUtPmNvbW1lbnRNYXRjaDsKKwkJaWYgKG5vZGUtPnBzdmkgIT0gTlVMTCkga2V5ZWQgPSAxOworCQlicmVhazsKKwkgICAgY2FzZSBYTUxfRU5USVRZX1JFRl9OT0RFOgorCSAgICBjYXNlIFhNTF9FTlRJVFlfTk9ERToKKwkgICAgY2FzZSBYTUxfRE9DVU1FTlRfVFlQRV9OT0RFOgorCSAgICBjYXNlIFhNTF9ET0NVTUVOVF9GUkFHX05PREU6CisJICAgIGNhc2UgWE1MX05PVEFUSU9OX05PREU6CisJICAgIGNhc2UgWE1MX0RURF9OT0RFOgorCSAgICBjYXNlIFhNTF9FTEVNRU5UX0RFQ0w6CisJICAgIGNhc2UgWE1MX0FUVFJJQlVURV9ERUNMOgorCSAgICBjYXNlIFhNTF9FTlRJVFlfREVDTDoKKwkgICAgY2FzZSBYTUxfTkFNRVNQQUNFX0RFQ0w6CisJICAgIGNhc2UgWE1MX1hJTkNMVURFX1NUQVJUOgorCSAgICBjYXNlIFhNTF9YSU5DTFVERV9FTkQ6CisJCWJyZWFrOworCSAgICBkZWZhdWx0OgorCQlicmVhazsKKwl9CisJd2hpbGUgKChsaXN0ICE9IE5VTEwpICYmCisJICAgICAgICgocmV0ID09IE5VTEwpICB8fCAobGlzdC0+cHJpb3JpdHkgPiBwcmlvcml0eSkpKSB7CisJICAgIGlmICh4c2x0VGVzdENvbXBNYXRjaChjdHh0LCBsaXN0LCBub2RlLAorCQkJICAgICAgICAgIGN0eHQtPm1vZGUsIGN0eHQtPm1vZGVVUkkpKSB7CisJCXJldCA9IGxpc3QtPnRlbXBsYXRlOworCQlwcmlvcml0eSA9IGxpc3QtPnByaW9yaXR5OworCQlicmVhazsKKwkgICAgfQorCSAgICBsaXN0ID0gbGlzdC0+bmV4dDsKKwl9CisJLyoKKwkgKiBTb21lIG9mIHRoZSB0ZXN0cyBmb3IgZWxlbWVudHMgY2FuIGFsc28gYXBwbHkgdG8gZG9jdW1lbnRzCisJICovCisJaWYgKChub2RlLT50eXBlID09IFhNTF9ET0NVTUVOVF9OT0RFKSB8fAorCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFKSB8fAorCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSkgeworCSAgICBsaXN0ID0gY3Vyc3R5bGUtPmVsZW1NYXRjaDsKKwkgICAgd2hpbGUgKChsaXN0ICE9IE5VTEwpICYmCisJCSAgICgocmV0ID09IE5VTEwpICB8fCAobGlzdC0+cHJpb3JpdHkgPiBwcmlvcml0eSkpKSB7CisJCWlmICh4c2x0VGVzdENvbXBNYXRjaChjdHh0LCBsaXN0LCBub2RlLAorCQkJCSAgICAgIGN0eHQtPm1vZGUsIGN0eHQtPm1vZGVVUkkpKSB7CisJCSAgICByZXQgPSBsaXN0LT50ZW1wbGF0ZTsKKwkJICAgIHByaW9yaXR5ID0gbGlzdC0+cHJpb3JpdHk7CisJCSAgICBicmVhazsKKwkJfQorCQlsaXN0ID0gbGlzdC0+bmV4dDsKKwkgICAgfQorCX0gZWxzZSBpZiAoKG5vZGUtPnR5cGUgPT0gWE1MX1BJX05PREUpIHx8CisJCSAgIChub2RlLT50eXBlID09IFhNTF9DT01NRU5UX05PREUpKSB7CisJICAgIGxpc3QgPSBjdXJzdHlsZS0+ZWxlbU1hdGNoOworCSAgICB3aGlsZSAoKGxpc3QgIT0gTlVMTCkgJiYKKwkJICAgKChyZXQgPT0gTlVMTCkgIHx8IChsaXN0LT5wcmlvcml0eSA+IHByaW9yaXR5KSkpIHsKKwkJaWYgKHhzbHRUZXN0Q29tcE1hdGNoKGN0eHQsIGxpc3QsIG5vZGUsCisJCQkJICAgICAgY3R4dC0+bW9kZSwgY3R4dC0+bW9kZVVSSSkpIHsKKwkJICAgIHJldCA9IGxpc3QtPnRlbXBsYXRlOworCQkgICAgcHJpb3JpdHkgPSBsaXN0LT5wcmlvcml0eTsKKwkJICAgIGJyZWFrOworCQl9CisJCWxpc3QgPSBsaXN0LT5uZXh0OworCSAgICB9CisJfQorCitrZXllZF9tYXRjaDoKKwlpZiAoa2V5ZWQpIHsKKwkgICAgbGlzdCA9IGN1cnN0eWxlLT5rZXlNYXRjaDsKKwkgICAgd2hpbGUgKChsaXN0ICE9IE5VTEwpICYmCisJCSAgICgocmV0ID09IE5VTEwpICB8fCAobGlzdC0+cHJpb3JpdHkgPiBwcmlvcml0eSkpKSB7CisJCWlmICh4c2x0VGVzdENvbXBNYXRjaChjdHh0LCBsaXN0LCBub2RlLAorCQkJCSAgICAgIGN0eHQtPm1vZGUsIGN0eHQtPm1vZGVVUkkpKSB7CisJCSAgICByZXQgPSBsaXN0LT50ZW1wbGF0ZTsKKwkJICAgIHByaW9yaXR5ID0gbGlzdC0+cHJpb3JpdHk7CisJCSAgICBicmVhazsKKwkJfQorCQlsaXN0ID0gbGlzdC0+bmV4dDsKKwkgICAgfQorCX0KKwllbHNlIGlmIChjdHh0LT5oYXNUZW1wbEtleVBhdHRlcm5zICYmCisJICAgICgoY3R4dC0+ZG9jdW1lbnQgPT0gTlVMTCkgfHwKKwkgICAgIChjdHh0LT5kb2N1bWVudC0+bmJLZXlzQ29tcHV0ZWQgPCBjdHh0LT5uYktleXMpKSkKKwl7CisJICAgIC8qCisJICAgICogQ29tcHV0ZSBhbGwgcmVtYWluaW5nIGtleXMgZm9yIHRoaXMgZG9jdW1lbnQuCisJICAgICoKKwkgICAgKiBSRVZJU0lUIFRPRE86IEkgdGhpbmsgdGhpcyBjb3VsZCBiZSBmdXJ0aGVyIG9wdGltaXplZC4KKwkgICAgKi8KKwkgICAgaWYgKHhzbHRDb21wdXRlQWxsS2V5cyhjdHh0LCBub2RlKSA9PSAtMSkKKwkJZ290byBlcnJvcjsKKworCSAgICBzd2l0Y2ggKG5vZGUtPnR5cGUpIHsKKwkJY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgkJICAgIAorCQkgICAgaWYgKG5vZGUtPnBzdmkgIT0gTlVMTCkga2V5ZWQgPSAxOworCQkgICAgYnJlYWs7CisJCWNhc2UgWE1MX0FUVFJJQlVURV9OT0RFOgorCQkgICAgaWYgKCgoeG1sQXR0clB0cikgbm9kZSktPnBzdmkgIT0gTlVMTCkga2V5ZWQgPSAxOworCQkgICAgYnJlYWs7CisJCWNhc2UgWE1MX1RFWFRfTk9ERToKKwkJY2FzZSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFOgorCQljYXNlIFhNTF9DT01NRU5UX05PREU6CisJCWNhc2UgWE1MX1BJX05PREU6CQkKKwkJICAgIGlmIChub2RlLT5wc3ZpICE9IE5VTEwpIGtleWVkID0gMTsKKwkJICAgIGJyZWFrOworCQljYXNlIFhNTF9ET0NVTUVOVF9OT0RFOgorCQljYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CisJCSAgICBpZiAoKCh4bWxEb2NQdHIpIG5vZGUpLT5wc3ZpICE9IE5VTEwpIGtleWVkID0gMTsKKwkJICAgIGJyZWFrOwkJCisJCWRlZmF1bHQ6CisJCSAgICBicmVhazsKKwkgICAgfQorCSAgICBpZiAoa2V5ZWQpCisJCWdvdG8ga2V5ZWRfbWF0Y2g7CisJfQorCWlmIChyZXQgIT0gTlVMTCkKKwkgICAgcmV0dXJuKHJldCk7CisKKwkvKgorCSAqIEN5Y2xlIG9uIG5leHQgY3Vyc3R5bGVzaGVldCBpbXBvcnQuCisJICovCisJY3Vyc3R5bGUgPSB4c2x0TmV4dEltcG9ydChjdXJzdHlsZSk7CisgICAgfQorCitlcnJvcjoKKyAgICByZXR1cm4oTlVMTCk7Cit9CisKKy8qKgorICogeHNsdENsZWFudXBUZW1wbGF0ZXM6CisgKiBAc3R5bGU6IGFuIFhTTFQgc3R5bGVzaGVldAorICoKKyAqIENsZWFudXAgdGhlIHN0YXRlIG9mIHRoZSB0ZW1wbGF0ZXMgdXNlZCBieSB0aGUgc3R5bGVzaGVldCBhbmQKKyAqIHRoZSBvbmVzIGl0IGltcG9ydHMuCisgKi8KK3ZvaWQKK3hzbHRDbGVhbnVwVGVtcGxhdGVzKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlIEFUVFJJQlVURV9VTlVTRUQpIHsKK30KKworLyoqCisgKiB4c2x0RnJlZVRlbXBsYXRlSGFzaGVzOgorICogQHN0eWxlOiBhbiBYU0xUIHN0eWxlc2hlZXQKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgdXNlZCBieSB4c2x0QWRkVGVtcGxhdGUveHNsdEdldFRlbXBsYXRlIG1lY2hhbmlzbQorICovCit2b2lkCit4c2x0RnJlZVRlbXBsYXRlSGFzaGVzKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKSB7CisgICAgaWYgKHN0eWxlLT50ZW1wbGF0ZXNIYXNoICE9IE5VTEwpCisJeG1sSGFzaEZyZWUoKHhtbEhhc2hUYWJsZVB0cikgc3R5bGUtPnRlbXBsYXRlc0hhc2gsCisJCSAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4c2x0RnJlZUNvbXBNYXRjaExpc3QpOworICAgIGlmIChzdHlsZS0+cm9vdE1hdGNoICE9IE5VTEwpCisgICAgICAgIHhzbHRGcmVlQ29tcE1hdGNoTGlzdChzdHlsZS0+cm9vdE1hdGNoKTsKKyAgICBpZiAoc3R5bGUtPmtleU1hdGNoICE9IE5VTEwpCisgICAgICAgIHhzbHRGcmVlQ29tcE1hdGNoTGlzdChzdHlsZS0+a2V5TWF0Y2gpOworICAgIGlmIChzdHlsZS0+ZWxlbU1hdGNoICE9IE5VTEwpCisgICAgICAgIHhzbHRGcmVlQ29tcE1hdGNoTGlzdChzdHlsZS0+ZWxlbU1hdGNoKTsKKyAgICBpZiAoc3R5bGUtPmF0dHJNYXRjaCAhPSBOVUxMKQorICAgICAgICB4c2x0RnJlZUNvbXBNYXRjaExpc3Qoc3R5bGUtPmF0dHJNYXRjaCk7CisgICAgaWYgKHN0eWxlLT5wYXJlbnRNYXRjaCAhPSBOVUxMKQorICAgICAgICB4c2x0RnJlZUNvbXBNYXRjaExpc3Qoc3R5bGUtPnBhcmVudE1hdGNoKTsKKyAgICBpZiAoc3R5bGUtPnRleHRNYXRjaCAhPSBOVUxMKQorICAgICAgICB4c2x0RnJlZUNvbXBNYXRjaExpc3Qoc3R5bGUtPnRleHRNYXRjaCk7CisgICAgaWYgKHN0eWxlLT5waU1hdGNoICE9IE5VTEwpCisgICAgICAgIHhzbHRGcmVlQ29tcE1hdGNoTGlzdChzdHlsZS0+cGlNYXRjaCk7CisgICAgaWYgKHN0eWxlLT5jb21tZW50TWF0Y2ggIT0gTlVMTCkKKyAgICAgICAgeHNsdEZyZWVDb21wTWF0Y2hMaXN0KHN0eWxlLT5jb21tZW50TWF0Y2gpOworfQorCmRpZmYgLS1naXQgYS9saWJ4c2x0L3BhdHRlcm4uaCBiL2xpYnhzbHQvcGF0dGVybi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViMjFiZTMKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L3BhdHRlcm4uaApAQCAtMCwwICsxLDgxIEBACisvKgorICogU3VtbWFyeTogaW50ZXJmYWNlIGZvciB0aGUgcGF0dGVybiBtYXRjaGluZyB1c2VkIGluIHRlbXBsYXRlIG1hdGNoZXMuCisgKiBEZXNjcmlwdGlvbjogdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBsb29rdXAgb2YgdGhlIHJpZ2h0IHRlbXBsYXRlCisgKiAgICAgICAgICAgICAgZm9yIGEgZ2l2ZW4gbm9kZSBtdXN0IGJlIHJlYWxseSBmYXN0IGluIG9yZGVyIHRvIGtlZXAKKyAqICAgICAgICAgICAgICBkZWNlbnQgcGVyZm9ybWFuY2VzLgorICoKKyAqIENvcHk6IFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBBdXRob3I6IERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVF9QQVRURVJOX0hfXworI2RlZmluZSBfX1hNTF9YU0xUX1BBVFRFUk5fSF9fCisKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisjaW5jbHVkZSAieHNsdGV4cG9ydHMuaCIKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvKioKKyAqIHhzbHRDb21wTWF0Y2g6CisgKgorICogRGF0YSBzdHJ1Y3R1cmUgdXNlZCBmb3IgdGhlIGltcGxlbWVudGF0aW9uIG9mIHBhdHRlcm5zLgorICogSXQgaXMga2VwdCBwcml2YXRlIChpbiBwYXR0ZXJuLmMpLgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdENvbXBNYXRjaCB4c2x0Q29tcE1hdGNoOwordHlwZWRlZiB4c2x0Q29tcE1hdGNoICp4c2x0Q29tcE1hdGNoUHRyOworCisvKgorICogUGF0dGVybiByZWxhdGVkIGludGVyZmFjZXMuCisgKi8KKworWFNMVFBVQkZVTiB4c2x0Q29tcE1hdGNoUHRyIFhTTFRDQUxMCisJCXhzbHRDb21waWxlUGF0dGVybgkoY29uc3QgeG1sQ2hhciAqcGF0dGVybiwKKwkJCQkJIHhtbERvY1B0ciBkb2MsCisJCQkJCSB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKwkJCQkJIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIHJ1bnRpbWUpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRGcmVlQ29tcE1hdGNoTGlzdAkoeHNsdENvbXBNYXRjaFB0ciBjb21wKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCXhzbHRUZXN0Q29tcE1hdGNoTGlzdAkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIHhzbHRDb21wTWF0Y2hQdHIgY29tcCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdE5vcm1hbGl6ZUNvbXBTdGVwcwkodm9pZCAqcGF5bG9hZCwKKwkJCQkJIHZvaWQgKmRhdGEsCisJCQkJCSBjb25zdCB4bWxDaGFyICpuYW1lKTsKKworLyoKKyAqIFRlbXBsYXRlIHJlbGF0ZWQgaW50ZXJmYWNlcy4KKyAqLworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwKKwkJeHNsdEFkZFRlbXBsYXRlCQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSB4c2x0VGVtcGxhdGVQdHIgY3VyLAorCQkJCQkgY29uc3QgeG1sQ2hhciAqbW9kZSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKm1vZGVVUkkpOworWFNMVFBVQkZVTiB4c2x0VGVtcGxhdGVQdHIgWFNMVENBTEwKKwkJeHNsdEdldFRlbXBsYXRlCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0RnJlZVRlbXBsYXRlSGFzaGVzCSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdENsZWFudXBUZW1wbGF0ZXMJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKTsKKworI2lmIDAKK2ludAkJeHNsdE1hdGNoUGF0dGVybgkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIGNvbnN0IHhtbENoYXIgKnBhdHRlcm4sCisJCQkJCSB4bWxEb2NQdHIgY3R4dGRvYywKKwkJCQkJIHhtbE5vZGVQdHIgY3R4dG5vZGUpOworI2VuZGlmCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19YTUxfWFNMVF9QQVRURVJOX0hfXyAqLworCmRpZmYgLS1naXQgYS9saWJ4c2x0L3ByZXByb2MuYyBiL2xpYnhzbHQvcHJlcHJvYy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0N2Q4MDkKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L3ByZXByb2MuYwpAQCAtMCwwICsxLDIzNTAgQEAKKy8qCisgKiBwcmVwcm9jLmM6IFByZXByb2Nlc3Npbmcgb2Ygc3R5bGUgb3BlcmF0aW9ucworICoKKyAqIFJlZmVyZW5jZXM6CisgKiAgIGh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLXhzbHQtMTk5OTExMTYKKyAqCisgKiAgIE1pY2hhZWwgS2F5ICJYU0xUIFByb2dyYW1tZXIncyBSZWZlcmVuY2UiIHBwIDYzNy02NDMKKyAqICAgV3JpdGluZyBNdWx0aXBsZSBPdXRwdXQgRmlsZXMKKyAqCisgKiAgIFhTTFQtMS4xIFdvcmtpbmcgRHJhZnQKKyAqICAgaHR0cDovL3d3dy53My5vcmcvVFIveHNsdDExI211bHRpcGxlLW91dHB1dAorICoKKyAqIFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBkYW5pZWxAdmVpbGxhcmQuY29tCisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CisjaW5jbHVkZSA8bGlieG1sL3BhcnNlci5oPgorI2luY2x1ZGUgPGxpYnhtbC90cmVlLmg+CisjaW5jbHVkZSA8bGlieG1sL3ZhbGlkLmg+CisjaW5jbHVkZSA8bGlieG1sL2hhc2guaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdXJpLmg+CisjaW5jbHVkZSA8bGlieG1sL2VuY29kaW5nLmg+CisjaW5jbHVkZSA8bGlieG1sL3htbGVycm9yLmg+CisjaW5jbHVkZSAieHNsdC5oIgorI2luY2x1ZGUgInhzbHR1dGlscy5oIgorI2luY2x1ZGUgInhzbHRJbnRlcm5hbHMuaCIKKyNpbmNsdWRlICJ0cmFuc2Zvcm0uaCIKKyNpbmNsdWRlICJ0ZW1wbGF0ZXMuaCIKKyNpbmNsdWRlICJ2YXJpYWJsZXMuaCIKKyNpbmNsdWRlICJudW1iZXJzSW50ZXJuYWxzLmgiCisjaW5jbHVkZSAicHJlcHJvYy5oIgorI2luY2x1ZGUgImV4dHJhLmgiCisjaW5jbHVkZSAiaW1wb3J0cy5oIgorI2luY2x1ZGUgImV4dGVuc2lvbnMuaCIKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworI2RlZmluZSBXSVRIX1hTTFRfREVCVUdfUFJFUFJPQworI2VuZGlmCisKK2NvbnN0IHhtbENoYXIgKnhzbHRFeHRNYXJrZXIgPSAoY29uc3QgeG1sQ2hhciAqKSAiRXh0ZW5zaW9uIEVsZW1lbnQiOworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkJR3JhbW1hciBjaGVja3MJCQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIC8qCisgICAgKiBHcmFtbWFyIGNoZWNrcyBhcmUgbm93IHBlcmZvcm1lZCBpbiB4c2x0LmMuCisgICAgKi8KKyNlbHNlCisvKioKKyAqIHhzbHRDaGVja1RvcExldmVsRWxlbWVudDoKKyAqIEBzdHlsZTogdGhlIFhTTFQgc3R5bGVzaGVldAorICogQGluc3Q6IHRoZSBYU0xUIGluc3RydWN0aW9uCisgKiBAZXJyOiByYWlzZSBhbiBlcnJvciBvciBub3QKKyAqCisgKiBDaGVjayB0aGF0IHRoZSBpbnN0cnVjdGlvbiBpcyBpbnN0YW5jaWF0ZWQgYXMgYSB0b3AgbGV2ZWwgZWxlbWVudC4KKyAqCisgKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgZmFpbGVkIGFuZCAxIGluIGNhc2Ugb2Ygc3VjY2VzcworICovCitzdGF0aWMgaW50Cit4c2x0Q2hlY2tUb3BMZXZlbEVsZW1lbnQoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgaW5zdCwgaW50IGVycikgeworICAgIHhtbE5vZGVQdHIgcGFyZW50OworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkgfHwgKGluc3QtPm5zID09IE5VTEwpKQorICAgICAgICByZXR1cm4oLTEpOworICAgIAorICAgIHBhcmVudCA9IGluc3QtPnBhcmVudDsKKyAgICBpZiAocGFyZW50ID09IE5VTEwpIHsKKyAgICAgICAgaWYgKGVycikgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCSAgICAiaW50ZXJuYWwgcHJvYmxlbTogZWxlbWVudCBoYXMgbm8gcGFyZW50XG4iKTsKKwkgICAgc3R5bGUtPmVycm9ycysrOworCX0KKwlyZXR1cm4oMCk7CisgICAgfQorICAgIGlmICgocGFyZW50LT5ucyA9PSBOVUxMKSB8fCAocGFyZW50LT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpIHx8CisgICAgICAgICgocGFyZW50LT5ucyAhPSBpbnN0LT5ucykgJiYKKwkgKCF4bWxTdHJFcXVhbChwYXJlbnQtPm5zLT5ocmVmLCBpbnN0LT5ucy0+aHJlZikpKSB8fAorCSgoIXhtbFN0ckVxdWFsKHBhcmVudC0+bmFtZSwgQkFEX0NBU1QgInN0eWxlc2hlZXQiKSkgJiYKKwkgKCF4bWxTdHJFcXVhbChwYXJlbnQtPm5hbWUsIEJBRF9DQVNUICJ0cmFuc2Zvcm0iKSkpKSB7CisJaWYgKGVycikgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCSAgICAiZWxlbWVudCAlcyBvbmx5IGFsbG93ZWQgYXMgY2hpbGQgb2Ygc3R5bGVzaGVldFxuIiwKKwkJCSAgICAgICBpbnN0LT5uYW1lKTsKKwkgICAgc3R5bGUtPmVycm9ycysrOworCX0KKwlyZXR1cm4oMCk7CisgICAgfQorICAgIHJldHVybigxKTsKK30KKworLyoqCisgKiB4c2x0Q2hlY2tJbnN0cnVjdGlvbkVsZW1lbnQ6CisgKiBAc3R5bGU6IHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiB0aGUgWFNMVCBpbnN0cnVjdGlvbgorICoKKyAqIENoZWNrIHRoYXQgdGhlIGluc3RydWN0aW9uIGlzIGluc3RhbmNpYXRlZCBhcyBhbiBpbnN0cnVjdGlvbiBlbGVtZW50LgorICovCitzdGF0aWMgdm9pZAoreHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyAgICB4bWxOb2RlUHRyIHBhcmVudDsKKyAgICBpbnQgaGFzX2V4dDsKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkgfHwgKGluc3QtPm5zID09IE5VTEwpIHx8CisgICAgICAgIChzdHlsZS0+bGl0ZXJhbF9yZXN1bHQpKQorICAgICAgICByZXR1cm47CisKKyAgICBoYXNfZXh0ID0gKHN0eWxlLT5leHRJbmZvcyAhPSBOVUxMKTsKKyAgICAKKyAgICBwYXJlbnQgPSBpbnN0LT5wYXJlbnQ7CisgICAgaWYgKHBhcmVudCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkiaW50ZXJuYWwgcHJvYmxlbTogZWxlbWVudCBoYXMgbm8gcGFyZW50XG4iKTsKKwlzdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuOworICAgIH0KKyAgICB3aGlsZSAoKHBhcmVudCAhPSBOVUxMKSAmJiAocGFyZW50LT50eXBlICE9IFhNTF9ET0NVTUVOVF9OT0RFKSkgeworICAgICAgICBpZiAoKChwYXJlbnQtPm5zID09IGluc3QtPm5zKSB8fAorCSAgICAgKChwYXJlbnQtPm5zICE9IE5VTEwpICYmCisJICAgICAgKHhtbFN0ckVxdWFsKHBhcmVudC0+bnMtPmhyZWYsIGluc3QtPm5zLT5ocmVmKSkpKSAmJgorCSAgICAoKHhtbFN0ckVxdWFsKHBhcmVudC0+bmFtZSwgQkFEX0NBU1QgInRlbXBsYXRlIikpIHx8CisJICAgICAoeG1sU3RyRXF1YWwocGFyZW50LT5uYW1lLCBCQURfQ0FTVCAicGFyYW0iKSkgfHwKKwkgICAgICh4bWxTdHJFcXVhbChwYXJlbnQtPm5hbWUsIEJBRF9DQVNUICJhdHRyaWJ1dGUiKSkgfHwKKwkgICAgICh4bWxTdHJFcXVhbChwYXJlbnQtPm5hbWUsIEJBRF9DQVNUICJ2YXJpYWJsZSIpKSkpIHsKKwkgICAgcmV0dXJuOworCX0KKworCS8qCisJICogaWYgd2UgYXJlIHdpdGhpbiBhbiBleHRlbnNpb24gZWxlbWVudCBhbGwgYmV0cyBhcmUgb2ZmCisJICogYWJvdXQgdGhlIHNlbWFudGljIHRoZXJlIGUuZy4geHNsOnBhcmFtIHdpdGhpbiBmdW5jOmZ1bmN0aW9uCisJICovCisJaWYgKChoYXNfZXh0KSAmJiAocGFyZW50LT5ucyAhPSBOVUxMKSAmJgorCSAgICAoeG1sSGFzaExvb2t1cChzdHlsZS0+ZXh0SW5mb3MsIHBhcmVudC0+bnMtPmhyZWYpICE9IE5VTEwpKQorCSAgICByZXR1cm47CisJCisgICAgICAgIHBhcmVudCA9IHBhcmVudC0+cGFyZW50OworICAgIH0KKyAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJICAgICJlbGVtZW50ICVzIG9ubHkgYWxsb3dlZCB3aXRoaW4gYSB0ZW1wbGF0ZSwgdmFyaWFibGUgb3IgcGFyYW1cbiIsCisJCSAgICAgICAgICAgaW5zdC0+bmFtZSk7CisgICAgc3R5bGUtPmVycm9ycysrOworfQorCisvKioKKyAqIHhzbHRDaGVja1BhcmVudEVsZW1lbnQ6CisgKiBAc3R5bGU6IHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiB0aGUgWFNMVCBpbnN0cnVjdGlvbgorICogQGFsbG93MTogYWxsb3dlZCBwYXJlbnQxCisgKiBAYWxsb3cyOiBhbGxvd2VkIHBhcmVudDIKKyAqCisgKiBDaGVjayB0aGF0IHRoZSBpbnN0cnVjdGlvbiBpcyBpbnN0YW5jaWF0ZWQgYXMgdGhlIGNoaWxkcmUgb2Ygb25lIG9mIHRoZQorICogcG9zc2libGUgcGFyZW50cy4KKyAqLworc3RhdGljIHZvaWQKK3hzbHRDaGVja1BhcmVudEVsZW1lbnQoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgaW5zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqYWxsb3cxLCBjb25zdCB4bWxDaGFyICphbGxvdzIpIHsKKyAgICB4bWxOb2RlUHRyIHBhcmVudDsKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkgfHwgKGluc3QtPm5zID09IE5VTEwpIHx8CisgICAgICAgIChzdHlsZS0+bGl0ZXJhbF9yZXN1bHQpKQorICAgICAgICByZXR1cm47CisKKyAgICBwYXJlbnQgPSBpbnN0LT5wYXJlbnQ7CisgICAgaWYgKHBhcmVudCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkiaW50ZXJuYWwgcHJvYmxlbTogZWxlbWVudCBoYXMgbm8gcGFyZW50XG4iKTsKKwlzdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuOworICAgIH0KKyAgICBpZiAoKChwYXJlbnQtPm5zID09IGluc3QtPm5zKSB8fAorCSAoKHBhcmVudC0+bnMgIT0gTlVMTCkgJiYKKwkgICh4bWxTdHJFcXVhbChwYXJlbnQtPm5zLT5ocmVmLCBpbnN0LT5ucy0+aHJlZikpKSkgJiYKKwkoKHhtbFN0ckVxdWFsKHBhcmVudC0+bmFtZSwgYWxsb3cxKSkgfHwKKwkgKHhtbFN0ckVxdWFsKHBhcmVudC0+bmFtZSwgYWxsb3cyKSkpKSB7CisJcmV0dXJuOworICAgIH0KKworICAgIGlmIChzdHlsZS0+ZXh0SW5mb3MgIT0gTlVMTCkgeworCXdoaWxlICgocGFyZW50ICE9IE5VTEwpICYmIChwYXJlbnQtPnR5cGUgIT0gWE1MX0RPQ1VNRU5UX05PREUpKSB7CisJICAgIC8qCisJICAgICAqIGlmIHdlIGFyZSB3aXRoaW4gYW4gZXh0ZW5zaW9uIGVsZW1lbnQgYWxsIGJldHMgYXJlIG9mZgorCSAgICAgKiBhYm91dCB0aGUgc2VtYW50aWMgdGhlcmUgZS5nLiB4c2w6cGFyYW0gd2l0aGluIGZ1bmM6ZnVuY3Rpb24KKwkgICAgICovCisJICAgIGlmICgocGFyZW50LT5ucyAhPSBOVUxMKSAmJgorCQkoeG1sSGFzaExvb2t1cChzdHlsZS0+ZXh0SW5mb3MsIHBhcmVudC0+bnMtPmhyZWYpICE9IE5VTEwpKQorCQlyZXR1cm47CisJICAgIAorCSAgICBwYXJlbnQgPSBwYXJlbnQtPnBhcmVudDsKKwl9CisgICAgfQorICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkJICAgICAgICJlbGVtZW50ICVzIGlzIG5vdCBhbGxvd2VkIHdpdGhpbiB0aGF0IGNvbnRleHRcbiIsCisJCSAgICAgICBpbnN0LT5uYW1lKTsKKyAgICBzdHlsZS0+ZXJyb3JzKys7Cit9CisjZW5kaWYKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJCWhhbmRsaW5nIG9mIHByZWNvbXB1dGVkIGRhdGEJCQkqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdE5ld1N0eWxlUHJlQ29tcDoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEB0eXBlOiAgdGhlIGNvbnN0cnVjdCB0eXBlCisgKgorICogQ3JlYXRlIGEgbmV3IFhTTFQgU3R5bGUgcHJlY29tcHV0ZWQgYmxvY2sKKyAqCisgKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3BlY2lhbGl6ZWQgc3RydWN0dXJlCisgKiAgICAgICAgIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgorICovCitzdGF0aWMgeHNsdFN0eWxlUHJlQ29tcFB0cgoreHNsdE5ld1N0eWxlUHJlQ29tcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeHNsdFN0eWxlVHlwZSB0eXBlKSB7CisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjdXI7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgc2l6ZV90IHNpemU7CisjZW5kaWYKKworICAgIGlmIChzdHlsZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4oTlVMTCk7CisgICAKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICAvKgorICAgICogVVJHRU5UIFRPRE86IFVzZSBzcGVjaWFsaXplZCBmYWN0b3J5IGZ1bmN0aW9ucyBpbiBvcmRlcgorICAgICogICB0byBhdm9pZCB0aGlzIHVnbGluZXNzLgorICAgICovCisgICAgc3dpdGNoICh0eXBlKSB7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0NPUFk6CisgICAgICAgICAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1Db3B5KTsgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX1NPUlQ6CisgICAgICAgICAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1Tb3J0KTsgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX1RFWFQ6CisgICAgICAgICAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1UZXh0KTsgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0VMRU1FTlQ6CisgICAgICAgICAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1FbGVtZW50KTsgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0FUVFJJQlVURToKKyAgICAgICAgICAgIHNpemUgPSBzaXplb2YoeHNsdFN0eWxlSXRlbUF0dHJpYnV0ZSk7IGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19DT01NRU5UOgorICAgICAgICAgICAgc2l6ZSA9IHNpemVvZih4c2x0U3R5bGVJdGVtQ29tbWVudCk7IGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19QSToKKyAgICAgICAgICAgIHNpemUgPSBzaXplb2YoeHNsdFN0eWxlSXRlbVBJKTsgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0NPUFlPRjoKKyAgICAgICAgICAgIHNpemUgPSBzaXplb2YoeHNsdFN0eWxlSXRlbUNvcHlPZik7IGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19WQUxVRU9GOgorICAgICAgICAgICAgc2l6ZSA9IHNpemVvZih4c2x0U3R5bGVJdGVtVmFsdWVPZik7IGJyZWFrOzsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfTlVNQkVSOgorICAgICAgICAgICAgc2l6ZSA9IHNpemVvZih4c2x0U3R5bGVJdGVtTnVtYmVyKTsgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0FQUExZSU1QT1JUUzoKKyAgICAgICAgICAgIHNpemUgPSBzaXplb2YoeHNsdFN0eWxlSXRlbUFwcGx5SW1wb3J0cyk7IGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19DQUxMVEVNUExBVEU6CisgICAgICAgICAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1DYWxsVGVtcGxhdGUpOyBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfQVBQTFlURU1QTEFURVM6CisgICAgICAgICAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1BcHBseVRlbXBsYXRlcyk7IGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19DSE9PU0U6CisgICAgICAgICAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1DaG9vc2UpOyBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfSUY6CisgICAgICAgICAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1JZik7IGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19GT1JFQUNIOgorICAgICAgICAgICAgc2l6ZSA9IHNpemVvZih4c2x0U3R5bGVJdGVtRm9yRWFjaCk7IGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19ET0NVTUVOVDoKKyAgICAgICAgICAgIHNpemUgPSBzaXplb2YoeHNsdFN0eWxlSXRlbURvY3VtZW50KTsgYnJlYWs7CisJY2FzZSBYU0xUX0ZVTkNfV0lUSFBBUkFNOgorCSAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1XaXRoUGFyYW0pOyBicmVhazsKKwljYXNlIFhTTFRfRlVOQ19QQVJBTToKKwkgICAgc2l6ZSA9IHNpemVvZih4c2x0U3R5bGVJdGVtUGFyYW0pOyBicmVhazsKKwljYXNlIFhTTFRfRlVOQ19WQVJJQUJMRToKKwkgICAgc2l6ZSA9IHNpemVvZih4c2x0U3R5bGVJdGVtVmFyaWFibGUpOyBicmVhazsKKwljYXNlIFhTTFRfRlVOQ19XSEVOOgorCSAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1XaGVuKTsgYnJlYWs7CisJY2FzZSBYU0xUX0ZVTkNfT1RIRVJXSVNFOgorCSAgICBzaXplID0gc2l6ZW9mKHhzbHRTdHlsZUl0ZW1PdGhlcndpc2UpOyBicmVhazsKKwlkZWZhdWx0OgkKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBOVUxMLAorCQkgICAgInhzbHROZXdTdHlsZVByZUNvbXAgOiBpbnZhbGlkIHR5cGUgJWRcbiIsIHR5cGUpOworCSAgICBzdHlsZS0+ZXJyb3JzKys7CisJICAgIHJldHVybihOVUxMKTsKKyAgICB9CisgICAgLyoKKyAgICAqIENyZWF0ZSB0aGUgc3RydWN0dXJlLgorICAgICovCisgICAgY3VyID0gKHhzbHRTdHlsZVByZUNvbXBQdHIpIHhtbE1hbGxvYyhzaXplKTsKKyAgICBpZiAoY3VyID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIE5VTEwsCisJCSJ4c2x0TmV3U3R5bGVQcmVDb21wIDogbWFsbG9jIGZhaWxlZFxuIik7CisJc3R5bGUtPmVycm9ycysrOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KGN1ciwgMCwgc2l6ZSk7CisKKyNlbHNlIC8qIFhTTFRfUkVGQUNUT1JFRCAqLworICAgIC8qCisgICAgKiBPbGQgYmVoYXZpb3VyLgorICAgICovCisgICAgY3VyID0gKHhzbHRTdHlsZVByZUNvbXBQdHIpIHhtbE1hbGxvYyhzaXplb2YoeHNsdFN0eWxlUHJlQ29tcCkpOworICAgIGlmIChjdXIgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgTlVMTCwKKwkJInhzbHROZXdTdHlsZVByZUNvbXAgOiBtYWxsb2MgZmFpbGVkXG4iKTsKKwlzdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBtZW1zZXQoY3VyLCAwLCBzaXplb2YoeHNsdFN0eWxlUHJlQ29tcCkpOworI2VuZGlmIC8qIFhTTFRfUkVGQUNUT1JFRCAqLworCisgICAgLyoKKyAgICAqIFVSR0VOVCBUT0RPOiBCZXR0ZXIgdG8gbW92ZSB0aGlzIHRvIHNwZXppYWxpemVkIGZhY3RvcnkgZnVuY3Rpb25zLgorICAgICovCisgICAgY3VyLT50eXBlID0gdHlwZTsKKyAgICBzd2l0Y2ggKGN1ci0+dHlwZSkgeworICAgICAgICBjYXNlIFhTTFRfRlVOQ19DT1BZOgorICAgICAgICAgICAgY3VyLT5mdW5jID0gKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdENvcHk7YnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX1NPUlQ6CisgICAgICAgICAgICBjdXItPmZ1bmMgPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0U29ydDticmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfVEVYVDoKKyAgICAgICAgICAgIGN1ci0+ZnVuYyA9ICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRUZXh0O2JyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19FTEVNRU5UOgorICAgICAgICAgICAgY3VyLT5mdW5jID0gKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdEVsZW1lbnQ7YnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0FUVFJJQlVURToKKyAgICAgICAgICAgIGN1ci0+ZnVuYyA9ICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRBdHRyaWJ1dGU7YnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0NPTU1FTlQ6CisgICAgICAgICAgICBjdXItPmZ1bmMgPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0Q29tbWVudDticmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfUEk6CisgICAgICAgICAgICBjdXItPmZ1bmMgPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0UHJvY2Vzc2luZ0luc3RydWN0aW9uOworCSAgICBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfQ09QWU9GOgorICAgICAgICAgICAgY3VyLT5mdW5jID0gKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdENvcHlPZjticmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfVkFMVUVPRjoKKyAgICAgICAgICAgIGN1ci0+ZnVuYyA9ICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRWYWx1ZU9mO2JyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19OVU1CRVI6CisgICAgICAgICAgICBjdXItPmZ1bmMgPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0TnVtYmVyO2JyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19BUFBMWUlNUE9SVFM6CisgICAgICAgICAgICBjdXItPmZ1bmMgPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0QXBwbHlJbXBvcnRzO2JyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19DQUxMVEVNUExBVEU6CisgICAgICAgICAgICBjdXItPmZ1bmMgPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0Q2FsbFRlbXBsYXRlO2JyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19BUFBMWVRFTVBMQVRFUzoKKyAgICAgICAgICAgIGN1ci0+ZnVuYyA9ICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRBcHBseVRlbXBsYXRlczticmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfQ0hPT1NFOgorICAgICAgICAgICAgY3VyLT5mdW5jID0gKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdENob29zZTticmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfSUY6CisgICAgICAgICAgICBjdXItPmZ1bmMgPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0SWY7YnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0ZPUkVBQ0g6CisgICAgICAgICAgICBjdXItPmZ1bmMgPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0Rm9yRWFjaDticmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfRE9DVU1FTlQ6CisgICAgICAgICAgICBjdXItPmZ1bmMgPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0RG9jdW1lbnRFbGVtO2JyZWFrOworCWNhc2UgWFNMVF9GVU5DX1dJVEhQQVJBTToKKwljYXNlIFhTTFRfRlVOQ19QQVJBTToJICAgIAorCWNhc2UgWFNMVF9GVU5DX1ZBUklBQkxFOgkgICAgCisJY2FzZSBYU0xUX0ZVTkNfV0hFTjoKKwkgICAgYnJlYWs7CisJZGVmYXVsdDoKKwlpZiAoY3VyLT5mdW5jID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBOVUxMLAorCQkgICAgInhzbHROZXdTdHlsZVByZUNvbXAgOiBubyBmdW5jdGlvbiBmb3IgdHlwZSAlZFxuIiwgdHlwZSk7CisJICAgIHN0eWxlLT5lcnJvcnMrKzsKKwl9CisgICAgfQorICAgIGN1ci0+bmV4dCA9IHN0eWxlLT5wcmVDb21wczsKKyAgICBzdHlsZS0+cHJlQ29tcHMgPSAoeHNsdEVsZW1QcmVDb21wUHRyKSBjdXI7CisKKyAgICByZXR1cm4oY3VyKTsKK30KKworLyoqCisgKiB4c2x0RnJlZVN0eWxlUHJlQ29tcDoKKyAqIEBjb21wOiAgYW4gWFNMVCBTdHlsZSBwcmVjb21wdXRlZCBibG9jaworICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgYnkgQGNvbXAKKyAqLworc3RhdGljIHZvaWQKK3hzbHRGcmVlU3R5bGVQcmVDb21wKHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCkgeworICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIC8qCisgICAgKiBVUkdFTlQgVE9ETzogSW1wbGVtZW50IGRlc3RydWN0b3JzLgorICAgICovCisgICAgc3dpdGNoIChjb21wLT50eXBlKSB7CisJY2FzZSBYU0xUX0ZVTkNfTElURVJBTF9SRVNVTFRfRUxFTUVOVDoKKwkgICAgYnJlYWs7CisJY2FzZSBYU0xUX0ZVTkNfQ09QWToKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19TT1JUOiB7CisJCXhzbHRTdHlsZUl0ZW1Tb3J0UHRyIGl0ZW0gPSAoeHNsdFN0eWxlSXRlbVNvcnRQdHIpIGNvbXA7CisJCWlmIChpdGVtLT5sb2NhbGUgIT0gKHhzbHRMb2NhbGUpMCkKKwkJICAgIHhzbHRGcmVlTG9jYWxlKGl0ZW0tPmxvY2FsZSk7CisJCWlmIChpdGVtLT5jb21wICE9IE5VTEwpCisJCSAgICB4bWxYUGF0aEZyZWVDb21wRXhwcihpdGVtLT5jb21wKTsKKwkgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX1RFWFQ6CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfRUxFTUVOVDoKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19BVFRSSUJVVEU6CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfQ09NTUVOVDoKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19QSToKKwkgICAgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0NPUFlPRjogeworCQl4c2x0U3R5bGVJdGVtQ29weU9mUHRyIGl0ZW0gPSAoeHNsdFN0eWxlSXRlbUNvcHlPZlB0cikgY29tcDsKKwkJaWYgKGl0ZW0tPmNvbXAgIT0gTlVMTCkKKwkJICAgIHhtbFhQYXRoRnJlZUNvbXBFeHByKGl0ZW0tPmNvbXApOworCSAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfVkFMVUVPRjogeworCQl4c2x0U3R5bGVJdGVtVmFsdWVPZlB0ciBpdGVtID0gKHhzbHRTdHlsZUl0ZW1WYWx1ZU9mUHRyKSBjb21wOworCQlpZiAoaXRlbS0+Y29tcCAhPSBOVUxMKQorCQkgICAgeG1sWFBhdGhGcmVlQ29tcEV4cHIoaXRlbS0+Y29tcCk7CisJICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19OVU1CRVI6CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfQVBQTFlJTVBPUlRTOgorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgWFNMVF9GVU5DX0NBTExURU1QTEFURToKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19BUFBMWVRFTVBMQVRFUzogeworCQl4c2x0U3R5bGVJdGVtQXBwbHlUZW1wbGF0ZXNQdHIgaXRlbSA9CisJCSAgICAoeHNsdFN0eWxlSXRlbUFwcGx5VGVtcGxhdGVzUHRyKSBjb21wOworCQlpZiAoaXRlbS0+Y29tcCAhPSBOVUxMKQorCQkgICAgeG1sWFBhdGhGcmVlQ29tcEV4cHIoaXRlbS0+Y29tcCk7CisJICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19DSE9PU0U6CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBYU0xUX0ZVTkNfSUY6IHsKKwkJeHNsdFN0eWxlSXRlbUlmUHRyIGl0ZW0gPSAoeHNsdFN0eWxlSXRlbUlmUHRyKSBjb21wOworCQlpZiAoaXRlbS0+Y29tcCAhPSBOVUxMKQorCQkgICAgeG1sWFBhdGhGcmVlQ29tcEV4cHIoaXRlbS0+Y29tcCk7CisJICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19GT1JFQUNIOiB7CisJCXhzbHRTdHlsZUl0ZW1Gb3JFYWNoUHRyIGl0ZW0gPQorCQkgICAgKHhzbHRTdHlsZUl0ZW1Gb3JFYWNoUHRyKSBjb21wOworCQlpZiAoaXRlbS0+Y29tcCAhPSBOVUxMKQorCQkgICAgeG1sWFBhdGhGcmVlQ29tcEV4cHIoaXRlbS0+Y29tcCk7CisJICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFhTTFRfRlVOQ19ET0NVTUVOVDoKKyAgICAgICAgICAgIGJyZWFrOworCWNhc2UgWFNMVF9GVU5DX1dJVEhQQVJBTTogeworCQl4c2x0U3R5bGVJdGVtV2l0aFBhcmFtUHRyIGl0ZW0gPQorCQkgICAgKHhzbHRTdHlsZUl0ZW1XaXRoUGFyYW1QdHIpIGNvbXA7CisJCWlmIChpdGVtLT5jb21wICE9IE5VTEwpCisJCSAgICB4bWxYUGF0aEZyZWVDb21wRXhwcihpdGVtLT5jb21wKTsKKwkgICAgfQorCSAgICBicmVhazsKKwljYXNlIFhTTFRfRlVOQ19QQVJBTTogeworCQl4c2x0U3R5bGVJdGVtUGFyYW1QdHIgaXRlbSA9CisJCSAgICAoeHNsdFN0eWxlSXRlbVBhcmFtUHRyKSBjb21wOworCQlpZiAoaXRlbS0+Y29tcCAhPSBOVUxMKQorCQkgICAgeG1sWFBhdGhGcmVlQ29tcEV4cHIoaXRlbS0+Y29tcCk7CisJICAgIH0KKwkgICAgYnJlYWs7CisJY2FzZSBYU0xUX0ZVTkNfVkFSSUFCTEU6IHsKKwkJeHNsdFN0eWxlSXRlbVZhcmlhYmxlUHRyIGl0ZW0gPQorCQkgICAgKHhzbHRTdHlsZUl0ZW1WYXJpYWJsZVB0cikgY29tcDsKKwkJaWYgKGl0ZW0tPmNvbXAgIT0gTlVMTCkKKwkJICAgIHhtbFhQYXRoRnJlZUNvbXBFeHByKGl0ZW0tPmNvbXApOworCSAgICB9CisJICAgIGJyZWFrOworCWNhc2UgWFNMVF9GVU5DX1dIRU46IHsKKwkJeHNsdFN0eWxlSXRlbVdoZW5QdHIgaXRlbSA9CisJCSAgICAoeHNsdFN0eWxlSXRlbVdoZW5QdHIpIGNvbXA7CisJCWlmIChpdGVtLT5jb21wICE9IE5VTEwpCisJCSAgICB4bWxYUGF0aEZyZWVDb21wRXhwcihpdGVtLT5jb21wKTsKKwkgICAgfQorCSAgICBicmVhazsKKwljYXNlIFhTTFRfRlVOQ19PVEhFUldJU0U6CSAgICAKKwljYXNlIFhTTFRfRlVOQ19GQUxMQkFDSzoKKwljYXNlIFhTTFRfRlVOQ19NRVNTQUdFOgorCWNhc2UgWFNMVF9GVU5DX0lOQ0xVREU6CisJY2FzZSBYU0xUX0ZVTkNfQVRUUlNFVDoKKwkKKwkgICAgYnJlYWs7CisJZGVmYXVsdDoKKwkgICAgLyogVE9ETzogUmFpc2UgZXJyb3IuICovCisJICAgIGJyZWFrOworICAgIH0KKyNlbHNlICAgIAorICAgIGlmIChjb21wLT5sb2NhbGUgIT0gKHhzbHRMb2NhbGUpMCkKKwl4c2x0RnJlZUxvY2FsZShjb21wLT5sb2NhbGUpOworICAgIGlmIChjb21wLT5jb21wICE9IE5VTEwpCisJeG1sWFBhdGhGcmVlQ29tcEV4cHIoY29tcC0+Y29tcCk7CisgICAgaWYgKGNvbXAtPm5zTGlzdCAhPSBOVUxMKQorCXhtbEZyZWUoY29tcC0+bnNMaXN0KTsKKyNlbmRpZgorCisgICAgeG1sRnJlZShjb21wKTsKK30KKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkgICAgWFNMVC0xLjEgZXh0ZW5zaW9ucwkJCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHREb2N1bWVudENvbXA6CisgKiBAc3R5bGU6ICB0aGUgWFNMVCBzdHlsZXNoZWV0CisgKiBAaW5zdDogIHRoZSBpbnN0cnVjdGlvbiBpbiB0aGUgc3R5bGVzaGVldAorICogQGZ1bmN0aW9uOiAgdW51c2VkCisgKgorICogUHJlIHByb2Nlc3MgYW4gWFNMVC0xLjEgZG9jdW1lbnQgZWxlbWVudAorICoKKyAqIFJldHVybnMgYSBwcmVjb21waWxlZCBkYXRhIHN0cnVjdHVyZSBmb3IgdGhlIGVsZW1lbnQKKyAqLworeHNsdEVsZW1QcmVDb21wUHRyCit4c2x0RG9jdW1lbnRDb21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QsCisJCSB4c2x0VHJhbnNmb3JtRnVuY3Rpb24gZnVuY3Rpb24gQVRUUklCVVRFX1VOVVNFRCkgeworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1Eb2N1bWVudFB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKyAgICBjb25zdCB4bWxDaGFyICpmaWxlbmFtZSA9IE5VTEw7CisKKyAgICAvKgorICAgICogQXMgb2YgMjAwNi0wMy0zMCwgdGhpcyBmdW5jdGlvbiBpcyBjdXJyZW50bHkgZGVmaW5lZCBpbiBMaWJ4c2x0CisgICAgKiB0byBiZSB1c2VkIGZvcjoKKyAgICAqIChpbiBsaWJ4c2x0L2V4dHJhLmMpCisgICAgKiAib3V0cHV0IiBpbiBYU0xUX1NBWE9OX05BTUVTUEFDRQorICAgICogIndyaXRlIiBYU0xUX1hBTEFOX05BTUVTUEFDRQorICAgICogImRvY3VtZW50IiBYU0xUX1hUX05BTUVTUEFDRQorICAgICogImRvY3VtZW50IiBYU0xUX05BTUVTUEFDRSAoZnJvbSB0aGUgYWJhbmRvbmVkIG9sZCB3b3JraW5nCisgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmFmdCBvZiBYU0xUIDEuMSkKKyAgICAqIChpbiBsaWJleHNsdC9jb21tb24uYykKKyAgICAqICJkb2N1bWVudCIgaW4gRVhTTFRfQ09NTU9OX05BTUVTUEFDRQorICAgICovCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgY29tcCA9ICh4c2x0U3R5bGVJdGVtRG9jdW1lbnRQdHIpCisJeHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX0RPQ1VNRU5UKTsKKyNlbHNlCisgICAgY29tcCA9IHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19ET0NVTUVOVCk7CisjZW5kaWYKKyAgICAKKyAgICBpZiAoY29tcCA9PSBOVUxMKQorCXJldHVybiAoTlVMTCk7CisgICAgY29tcC0+aW5zdCA9IGluc3Q7CisgICAgY29tcC0+dmVyMTEgPSAwOworCisgICAgaWYgKHhtbFN0ckVxdWFsKGluc3QtPm5hbWUsIChjb25zdCB4bWxDaGFyICopICJvdXRwdXQiKSkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRSQQorCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICJGb3VuZCBzYXhvbjpvdXRwdXQgZXh0ZW5zaW9uXG4iKTsKKyNlbmRpZgorCS8qCisJKiBUaGUgZWxlbWVudCAib3V0cHV0IiBpcyBpbiB0aGUgbmFtZXNwYWNlIFhTTFRfU0FYT05fTkFNRVNQQUNFCisJKiAgIChodHRwOi8vaWNsLmNvbS9zYXhvbikKKwkqIFRoZSBAZmlsZSBpcyBpbiBubyBuYW1lc3BhY2U7IGl0IGlzIGFuIEFWVC4KKwkqICAgKGh0dHA6Ly93d3cuY29tcHV0ZXJ3aXphcmRzLmNvbS9zYXhvbi9kb2MvZXh0ZW5zaW9ucy5odG1sI3NheG9uOm91dHB1dCkKKwkqCisJKiBUT0RPOiBEbyB3ZSBuZWVkIG5vdCB0byBjaGVjayB0aGUgbmFtZXNwYWNlIGhlcmU/CisJKi8KKwlmaWxlbmFtZSA9IHhzbHRFdmFsU3RhdGljQXR0clZhbHVlVGVtcGxhdGUoc3R5bGUsIGluc3QsCisJCQkgKGNvbnN0IHhtbENoYXIgKikiZmlsZSIsCisJCQkgTlVMTCwgJmNvbXAtPmhhc19maWxlbmFtZSk7CisgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChpbnN0LT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSAid3JpdGUiKSkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRSQQorCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICJGb3VuZCB4YWxhbjp3cml0ZSBleHRlbnNpb25cbiIpOworI2VuZGlmCisJLyogdGhlIGZpbGVuYW1lIG5lZWQgdG8gYmUgaW50ZXJwcmV0ZWQgKi8KKwkvKgorCSogVE9ETzogSXMgImZpbGVuYW1lIG5lZWQgdG8gYmUgaW50ZXJwcmV0ZWQiIG1lYW50IHRvIGJlIGEgdG9kbz8KKwkqICAgV2hlcmUgd2lsbCBiZSB0aGUgZmlsZW5hbWUgb2YgeGFsYW46d3JpdGUgYmUgcHJvY2Vzc2VkPworCSoKKwkqIFRPRE86IERvIHdlIG5lZWQgbm90IHRvIGNoZWNrIHRoZSBuYW1lc3BhY2UgaGVyZT8KKwkqICAgVGhlIGV4dGVuc2lvbiBucyBpcyAiaHR0cDovL3htbC5hcGFjaGUub3JnL3hhbGFuL3JlZGlyZWN0Ii4KKwkqICAgU2VlIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi1qL2V4dGVuc2lvbnNsaWIuaHRtbC4KKwkqLworICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaW5zdC0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgImRvY3VtZW50IikpIHsKKwlpZiAoaW5zdC0+bnMgIT0gTlVMTCkgeworCSAgICBpZiAoeG1sU3RyRXF1YWwoaW5zdC0+bnMtPmhyZWYsIFhTTFRfTkFNRVNQQUNFKSkgeworCQkvKgorCQkqIE1hcmsgdGhlIGluc3RydWN0aW9uIGFzIGJlaW5nIG9mCisJCSogWFNMVCB2ZXJzaW9uIDEuMSAoYWJhbmRvbmVkKS4KKwkJKi8KKwkJY29tcC0+dmVyMTEgPSAxOworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRSQQorCQl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgIkZvdW5kIHhzbHQxMTpkb2N1bWVudCBjb25zdHJ1Y3RcbiIpOworI2VuZGlmCSAgICAJCQorCSAgICB9IGVsc2UgewkJCisJCWlmICh4bWxTdHJFcXVhbChpbnN0LT5ucy0+aHJlZiwKKwkJICAgIChjb25zdCB4bWxDaGFyICopImh0dHA6Ly9leHNsdC5vcmcvY29tbW9uIikpIHsKKwkJICAgIC8qIEVYU0xULiAqLworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRSQQorCQkgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSJGb3VuZCBleHNsdDpkb2N1bWVudCBleHRlbnNpb25cbiIpOworI2VuZGlmCisJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaW5zdC0+bnMtPmhyZWYsIFhTTFRfWFRfTkFNRVNQQUNFKSkgeworCQkgICAgLyogSmFtZXMgQ2xhcmsncyBYVC4gKi8KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRVhUUkEKKwkJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkiRm91bmQgeHQ6ZG9jdW1lbnQgZXh0ZW5zaW9uXG4iKTsKKyNlbmRpZgorCQl9CisJICAgIH0KKwl9CisJLyoKKwkqIFRoZSBlbGVtZW50ICJkb2N1bWVudCIgaXMgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZQorCSogZm9sbG93aW5nIG5hbWVzcGFjZXM6CisJKgorCSogMSkgWFNMVF9OQU1FU1BBQ0UgKGh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSB2ZXJzaW9uIDEuMSkKKwkqICAgIDwhRUxFTUVOVCB4c2w6ZG9jdW1lbnQgJXRlbXBsYXRlOz4KKwkqICAgIDwhQVRUTElTVCB4c2w6ZG9jdW1lbnQKKwkqICAgICAgIGhyZWYgJWF2dDsgI1JFUVVJUkVECisJKiAgICBAaHJlZiBpcyBhbiBBVlQKKwkqICAgIElNUE9SVEFOVDogeHNsOmRvY3VtZW50IHdhcyBpbiB0aGUgYWJhbmRvbmVkIFhTTFQgMS4xIGRyYWZ0LAorCSogICAgaXQgd2FzIHJlbW92ZWQgYW5kIGlzbid0IGF2YWlsYWJsZSBpbiBYU0xUIDEuMSBhbnltb3JlLgorCSogICAgSW4gWFNMVCAyLjAgaXQgd2FzIHJlbmFtZWQgdG8geHNsOnJlc3VsdC1kb2N1bWVudC4KKwkqCisJKiAgIEFsbCBvdGhlciBhdHRyaWJ1dGVzIGFyZSBpZGVudGljYWwgdG8gdGhlIGF0dHJpYnV0ZXMKKwkqICAgb24geHNsOm91dHB1dAorCSoKKwkqIDIpIEVYU0xUX0NPTU1PTl9OQU1FU1BBQ0UgKGh0dHA6Ly9leHNsdC5vcmcvY29tbW9uKQorCSogICAgPGV4c2w6ZG9jdW1lbnQKKwkqICAgICAgIGhyZWYgPSB7IHVyaS1yZWZlcmVuY2UgfQorCSogICAgVE9ETzogaXMgQGhyZWYgaXMgYW4gQVZUPworCSoKKwkqIDMpIFhTTFRfWFRfTkFNRVNQQUNFIChodHRwOi8vd3d3LmpjbGFyay5jb20veHQpCisJKiAgICAgRXhhbXBsZTogPHh0OmRvY3VtZW50IG1ldGhvZD0ieG1sIiBocmVmPSJteUZpbGUueG1sIj4KKwkqICAgIFRPRE86IGlzIEBocmVmIGlzIGFuIEFWVD8KKwkqCQkKKwkqIEluIGFsbCBjYXNlcyBAaHJlZiBpcyBpbiBubyBuYW1lc3BhY2UuCisJKi8KKwlmaWxlbmFtZSA9IHhzbHRFdmFsU3RhdGljQXR0clZhbHVlVGVtcGxhdGUoc3R5bGUsIGluc3QsCisJICAgIChjb25zdCB4bWxDaGFyICopImhyZWYiLCBOVUxMLCAmY29tcC0+aGFzX2ZpbGVuYW1lKTsKKyAgICB9CQkKKyAgICBpZiAoIWNvbXAtPmhhc19maWxlbmFtZSkgeworCWdvdG8gZXJyb3I7CisgICAgfQorICAgIGNvbXAtPmZpbGVuYW1lID0gZmlsZW5hbWU7CisKK2Vycm9yOgorICAgIHJldHVybiAoKHhzbHRFbGVtUHJlQ29tcFB0cikgY29tcCk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICoJCU1vc3Qgb2YgdGhlIFhTTFQtMS4wIHRyYW5zZm9ybWF0aW9ucwkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0U29ydENvbXA6CisgKiBAc3R5bGU6ICB0aGUgWFNMVCBzdHlsZXNoZWV0CisgKiBAaW5zdDogIHRoZSB4c2x0IHNvcnQgbm9kZQorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgc29ydCBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCitzdGF0aWMgdm9pZAoreHNsdFNvcnRDb21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtU29ydFB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpKQorCXJldHVybjsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIGNvbXAgPSAoeHNsdFN0eWxlSXRlbVNvcnRQdHIpIHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19TT1JUKTsKKyNlbHNlCisgICAgY29tcCA9IHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19TT1JUKTsKKyNlbmRpZgorICAgIAorICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworICAgIGluc3QtPnBzdmkgPSBjb21wOworICAgIGNvbXAtPmluc3QgPSBpbnN0OworCisgICAgY29tcC0+c3R5cGUgPSB4c2x0RXZhbFN0YXRpY0F0dHJWYWx1ZVRlbXBsYXRlKHN0eWxlLCBpbnN0LAorCQkJIChjb25zdCB4bWxDaGFyICopImRhdGEtdHlwZSIsCisJCQkgTlVMTCwgJmNvbXAtPmhhc19zdHlwZSk7CisgICAgaWYgKGNvbXAtPnN0eXBlICE9IE5VTEwpIHsKKwlpZiAoeG1sU3RyRXF1YWwoY29tcC0+c3R5cGUsIChjb25zdCB4bWxDaGFyICopICJ0ZXh0IikpCisJICAgIGNvbXAtPm51bWJlciA9IDA7CisJZWxzZSBpZiAoeG1sU3RyRXF1YWwoY29tcC0+c3R5cGUsIChjb25zdCB4bWxDaGFyICopICJudW1iZXIiKSkKKwkgICAgY29tcC0+bnVtYmVyID0gMTsKKwllbHNlIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkgInhzbHRTb3J0Q29tcDogbm8gc3VwcG9ydCBmb3IgZGF0YS10eXBlID0gJXNcbiIsIGNvbXAtPnN0eXBlKTsKKwkgICAgY29tcC0+bnVtYmVyID0gMDsgLyogdXNlIGRlZmF1bHQgKi8KKwkgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT53YXJuaW5ncysrOworCX0KKyAgICB9CisgICAgY29tcC0+b3JkZXIgPSB4c2x0RXZhbFN0YXRpY0F0dHJWYWx1ZVRlbXBsYXRlKHN0eWxlLCBpbnN0LAorCQkJICAgICAgKGNvbnN0IHhtbENoYXIgKikib3JkZXIiLAorCQkJICAgICAgTlVMTCwgJmNvbXAtPmhhc19vcmRlcik7CisgICAgaWYgKGNvbXAtPm9yZGVyICE9IE5VTEwpIHsKKwlpZiAoeG1sU3RyRXF1YWwoY29tcC0+b3JkZXIsIChjb25zdCB4bWxDaGFyICopICJhc2NlbmRpbmciKSkKKwkgICAgY29tcC0+ZGVzY2VuZGluZyA9IDA7CisJZWxzZSBpZiAoeG1sU3RyRXF1YWwoY29tcC0+b3JkZXIsIChjb25zdCB4bWxDaGFyICopICJkZXNjZW5kaW5nIikpCisJICAgIGNvbXAtPmRlc2NlbmRpbmcgPSAxOworCWVsc2UgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCSAieHNsdFNvcnRDb21wOiBpbnZhbGlkIHZhbHVlICVzIGZvciBvcmRlclxuIiwgY29tcC0+b3JkZXIpOworCSAgICBjb21wLT5kZXNjZW5kaW5nID0gMDsgLyogdXNlIGRlZmF1bHQgKi8KKwkgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT53YXJuaW5ncysrOworCX0KKyAgICB9CisgICAgY29tcC0+Y2FzZV9vcmRlciA9IHhzbHRFdmFsU3RhdGljQXR0clZhbHVlVGVtcGxhdGUoc3R5bGUsIGluc3QsCisJCQkgICAgICAoY29uc3QgeG1sQ2hhciAqKSJjYXNlLW9yZGVyIiwKKwkJCSAgICAgIE5VTEwsICZjb21wLT5oYXNfdXNlKTsKKyAgICBpZiAoY29tcC0+Y2FzZV9vcmRlciAhPSBOVUxMKSB7CisJaWYgKHhtbFN0ckVxdWFsKGNvbXAtPmNhc2Vfb3JkZXIsIChjb25zdCB4bWxDaGFyICopICJ1cHBlci1maXJzdCIpKQorCSAgICBjb21wLT5sb3dlcl9maXJzdCA9IDA7CisJZWxzZSBpZiAoeG1sU3RyRXF1YWwoY29tcC0+Y2FzZV9vcmRlciwgKGNvbnN0IHhtbENoYXIgKikgImxvd2VyLWZpcnN0IikpCisJICAgIGNvbXAtPmxvd2VyX2ZpcnN0ID0gMTsKKwllbHNlIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkgInhzbHRTb3J0Q29tcDogaW52YWxpZCB2YWx1ZSAlcyBmb3Igb3JkZXJcbiIsIGNvbXAtPm9yZGVyKTsKKwkgICAgY29tcC0+bG93ZXJfZmlyc3QgPSAwOyAvKiB1c2UgZGVmYXVsdCAqLworCSAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPndhcm5pbmdzKys7CisJfQorICAgIH0KKworICAgIGNvbXAtPmxhbmcgPSB4c2x0RXZhbFN0YXRpY0F0dHJWYWx1ZVRlbXBsYXRlKHN0eWxlLCBpbnN0LAorCQkJCSAoY29uc3QgeG1sQ2hhciAqKSJsYW5nIiwKKwkJCQkgTlVMTCwgJmNvbXAtPmhhc19sYW5nKTsKKyAgICBpZiAoY29tcC0+bGFuZyAhPSBOVUxMKSB7CisJY29tcC0+bG9jYWxlID0geHNsdE5ld0xvY2FsZShjb21wLT5sYW5nKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGNvbXAtPmxvY2FsZSA9ICh4c2x0TG9jYWxlKTA7CisgICAgfQorCisgICAgY29tcC0+c2VsZWN0ID0geHNsdEdldENOc1Byb3Aoc3R5bGUsIGluc3QsKGNvbnN0IHhtbENoYXIgKikic2VsZWN0IiwgWFNMVF9OQU1FU1BBQ0UpOworICAgIGlmIChjb21wLT5zZWxlY3QgPT0gTlVMTCkgeworCS8qCisJICogVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIHNlbGVjdCBhdHRyaWJ1dGUgaXMgLiwgd2hpY2ggd2lsbAorCSAqIGNhdXNlIHRoZSBzdHJpbmctdmFsdWUgb2YgdGhlIGN1cnJlbnQgbm9kZSB0byBiZSB1c2VkIGFzCisJICogdGhlIHNvcnQga2V5LgorCSAqLworCWNvbXAtPnNlbGVjdCA9IHhtbERpY3RMb29rdXAoc3R5bGUtPmRpY3QsIEJBRF9DQVNUICIuIiwgMSk7CisgICAgfQorICAgIGNvbXAtPmNvbXAgPSB4c2x0WFBhdGhDb21waWxlKHN0eWxlLCBjb21wLT5zZWxlY3QpOworICAgIGlmIChjb21wLT5jb21wID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJICAgICAieHNsdFNvcnRDb21wOiBjb3VsZCBub3QgY29tcGlsZSBzZWxlY3QgZXhwcmVzc2lvbiAnJXMnXG4iLAorCSAgICAgICAgICAgICAgICAgY29tcC0+c2VsZWN0KTsKKwlpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPmVycm9ycysrOworICAgIH0KKyAgICBpZiAoaW5zdC0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkieHNsOnNvcnQgOiBpcyBub3QgZW1wdHlcbiIpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisgICAgfQorfQorCisvKioKKyAqIHhzbHRDb3B5Q29tcDoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIHhzbHQgY29weSBub2RlCisgKgorICogUHJvY2VzcyB0aGUgeHNsdCBjb3B5IG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0Q29weUNvbXAoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgaW5zdCkgeworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1Db3B5UHRyIGNvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcDsKKyNlbmRpZgorCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgY29tcCA9ICh4c2x0U3R5bGVJdGVtQ29weVB0cikgeHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX0NPUFkpOworI2Vsc2UKKyAgICBjb21wID0geHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX0NPUFkpOworI2VuZGlmCisgICAgCisgICAgaWYgKGNvbXAgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaW5zdC0+cHN2aSA9IGNvbXA7CisgICAgY29tcC0+aW5zdCA9IGluc3Q7CisKKworICAgIGNvbXAtPnVzZSA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBpbnN0LCAoY29uc3QgeG1sQ2hhciAqKSJ1c2UtYXR0cmlidXRlLXNldHMiLAorCQkJCSAgICBYU0xUX05BTUVTUEFDRSk7CisgICAgaWYgKGNvbXAtPnVzZSA9PSBOVUxMKQorCWNvbXAtPmhhc191c2UgPSAwOworICAgIGVsc2UKKwljb21wLT5oYXNfdXNlID0gMTsKK30KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIC8qIEVuYWJsZSBpZiBldmVyIG5lZWRlZCBmb3IgeHNsOnRleHQuICovCisjZWxzZQorLyoqCisgKiB4c2x0VGV4dENvbXA6CisgKiBAc3R5bGU6IGFuIFhTTFQgY29tcGlsZWQgc3R5bGVzaGVldAorICogQGluc3Q6ICB0aGUgeHNsdCB0ZXh0IG5vZGUKKyAqCisgKiBUT0RPOiBUaGlzIGZ1bmN0aW9uIGlzIG9ic29sZXRlLCBzaW5jZSB4c2w6dGV4dCB3b24ndAorICogIGJlIGNvbXBpbGVkLCBidXQgcmVtb3ZlZCBmcm9tIHRoZSB0cmVlLgorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgdGV4dCBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCitzdGF0aWMgdm9pZAoreHNsdFRleHRDb21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtVGV4dFB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKyAgICBjb25zdCB4bWxDaGFyICpwcm9wOworCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICBjb21wID0gKHhzbHRTdHlsZUl0ZW1UZXh0UHRyKSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfVEVYVCk7CisjZWxzZQorICAgIGNvbXAgPSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfVEVYVCk7CisjZW5kaWYgICAgCisgICAgaWYgKGNvbXAgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaW5zdC0+cHN2aSA9IGNvbXA7CisgICAgY29tcC0+aW5zdCA9IGluc3Q7CisgICAgY29tcC0+bm9lc2NhcGUgPSAwOworCisgICAgcHJvcCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBpbnN0LAorCSAgICAoY29uc3QgeG1sQ2hhciAqKSJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIsCisJCQlYU0xUX05BTUVTUEFDRSk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWlmICh4bWxTdHJFcXVhbChwcm9wLCAoY29uc3QgeG1sQ2hhciAqKSJ5ZXMiKSkgeworCSAgICBjb21wLT5ub2VzY2FwZSA9IDE7CisJfSBlbHNlIGlmICgheG1sU3RyRXF1YWwocHJvcCwKKwkgICAgKGNvbnN0IHhtbENoYXIgKikibm8iKSl7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkJInhzbDp0ZXh0OiBkaXNhYmxlLW91dHB1dC1lc2NhcGluZyBhbGxvd3Mgb25seSB5ZXMgb3Igbm9cbiIpOworCSAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPndhcm5pbmdzKys7CisJfQorICAgIH0KK30KKyNlbmRpZiAvKiBlbHNlIG9mIFhTTFRfUkVGQUNUT1JFRCAqLworCisvKioKKyAqIHhzbHRFbGVtZW50Q29tcDoKKyAqIEBzdHlsZTogYW4gWFNMVCBjb21waWxlZCBzdHlsZXNoZWV0CisgKiBAaW5zdDogIHRoZSB4c2x0IGVsZW1lbnQgbm9kZQorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgZWxlbWVudCBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCitzdGF0aWMgdm9pZAoreHNsdEVsZW1lbnRDb21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtRWxlbWVudFB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIC8qCisgICAgKiA8eHNsOmVsZW1lbnQKKyAgICAqICAgbmFtZSA9IHsgcW5hbWUgfQorICAgICogICBuYW1lc3BhY2UgPSB7IHVyaS1yZWZlcmVuY2UgfQorICAgICogICB1c2UtYXR0cmlidXRlLXNldHMgPSBxbmFtZXM+CisgICAgKiAgIDwhLS0gQ29udGVudDogdGVtcGxhdGUgLS0+CisgICAgKiA8L3hzbDplbGVtZW50PgorICAgICovCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICBjb21wID0gKHhzbHRTdHlsZUl0ZW1FbGVtZW50UHRyKSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfRUxFTUVOVCk7CisjZWxzZQorICAgIGNvbXAgPSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfRUxFTUVOVCk7CisjZW5kaWYKKworICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworICAgIGluc3QtPnBzdmkgPSBjb21wOworICAgIGNvbXAtPmluc3QgPSBpbnN0OworCisgICAgLyoKKyAgICAqIEF0dHJpYnV0ZSAibmFtZSIuCisgICAgKi8KKyAgICAvKgorICAgICogVE9ETzogUHJlY29tcGlsZSB0aGUgQVZULiBTZWUgYnVnICMzNDQ4OTQuCisgICAgKi8KKyAgICBjb21wLT5uYW1lID0geHNsdEV2YWxTdGF0aWNBdHRyVmFsdWVUZW1wbGF0ZShzdHlsZSwgaW5zdCwKKwkoY29uc3QgeG1sQ2hhciAqKSJuYW1lIiwgTlVMTCwgJmNvbXAtPmhhc19uYW1lKTsKKyAgICBpZiAoISBjb21wLT5oYXNfbmFtZSkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkgICAgInhzbDplbGVtZW50OiBUaGUgYXR0cmlidXRlICduYW1lJyBpcyBtaXNzaW5nLlxuIik7CisJc3R5bGUtPmVycm9ycysrOworCWdvdG8gZXJyb3I7CisgICAgfQorICAgIC8qCisgICAgKiBBdHRyaWJ1dGUgIm5hbWVzcGFjZSIuCisgICAgKi8KKyAgICAvKgorICAgICogVE9ETzogUHJlY29tcGlsZSB0aGUgQVZULiBTZWUgYnVnICMzNDQ4OTQuCisgICAgKi8KKyAgICBjb21wLT5ucyA9IHhzbHRFdmFsU3RhdGljQXR0clZhbHVlVGVtcGxhdGUoc3R5bGUsIGluc3QsCisJKGNvbnN0IHhtbENoYXIgKikibmFtZXNwYWNlIiwgTlVMTCwgJmNvbXAtPmhhc19ucyk7CisgICAgCisgICAgaWYgKGNvbXAtPm5hbWUgIT0gTlVMTCkgewkKKwlpZiAoeG1sVmFsaWRhdGVRTmFtZShjb21wLT5uYW1lLCAwKSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCSJ4c2w6ZWxlbWVudDogVGhlIHZhbHVlICclcycgb2YgdGhlIGF0dHJpYnV0ZSAnbmFtZScgaXMgIgorCQkibm90IGEgdmFsaWQgUU5hbWUuXG4iLCBjb21wLT5uYW1lKTsKKwkgICAgc3R5bGUtPmVycm9ycysrOworCX0gZWxzZSB7CisJICAgIGNvbnN0IHhtbENoYXIgKnByZWZpeCA9IE5VTEwsICpuYW1lOworCisJICAgIG5hbWUgPSB4c2x0U3BsaXRRTmFtZShzdHlsZS0+ZGljdCwgY29tcC0+bmFtZSwgJnByZWZpeCk7CisJICAgIGlmIChjb21wLT5oYXNfbnMgPT0gMCkgewkgICAgCisJCXhtbE5zUHRyIG5zOworCisJCS8qCisJCSogU1BFQyBYU0xUIDEuMDoKKwkJKiAgIklmIHRoZSBuYW1lc3BhY2UgYXR0cmlidXRlIGlzIG5vdCBwcmVzZW50LCB0aGVuIHRoZSBRTmFtZSBpcworCQkqICBleHBhbmRlZCBpbnRvIGFuIGV4cGFuZGVkLW5hbWUgdXNpbmcgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMKKwkJKiAgaW4gZWZmZWN0IGZvciB0aGUgeHNsOmVsZW1lbnQgZWxlbWVudCwgaW5jbHVkaW5nIGFueSBkZWZhdWx0CisJCSogIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KKwkJKi8JCQorCQlucyA9IHhtbFNlYXJjaE5zKGluc3QtPmRvYywgaW5zdCwgcHJlZml4KTsKKwkJaWYgKG5zICE9IE5VTEwpIHsKKwkJICAgIGNvbXAtPm5zID0geG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKKwkJICAgIGNvbXAtPmhhc19ucyA9IDE7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisJCSAgICBjb21wLT5uc1ByZWZpeCA9IHByZWZpeDsKKwkJICAgIGNvbXAtPm5hbWUgPSBuYW1lOworI2VuZGlmCisJCX0gZWxzZSBpZiAocHJlZml4ICE9IE5VTEwpIHsKKwkJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkJCSJ4c2w6ZWxlbWVudDogVGhlIHByZWZpeGVkIFFOYW1lICclcycgIgorCQkJImhhcyBubyBuYW1lc3BhY2UgYmluZGluZyBpbiBzY29wZSBpbiB0aGUgIgorCQkJInN0eWxlc2hlZXQ7IHRoaXMgaXMgYW4gZXJyb3IsIHNpbmNlIHRoZSBuYW1lc3BhY2Ugd2FzICIKKwkJCSJub3Qgc3BlY2lmaWVkIGJ5IHRoZSBpbnN0cnVjdGlvbiBpdHNlbGYuXG4iLCBjb21wLT5uYW1lKTsKKwkJICAgIHN0eWxlLT5lcnJvcnMrKzsKKwkJfQorCSAgICB9CSAgICAKKwkgICAgaWYgKChwcmVmaXggIT0gTlVMTCkgJiYKKwkJKCF4bWxTdHJuY2FzZWNtcChwcmVmaXgsICh4bWxDaGFyICopInhtbCIsIDMpKSkKKwkgICAgeworCQkvKgorCQkqIE1hcmsgaXMgdG8gYmUgc2tpcHBlZC4KKwkJKi8KKwkJY29tcC0+aGFzX25hbWUgPSAwOwkJCisJICAgIH0KKwl9CisgICAgfSAgICAKKyAgICAvKgorICAgICogQXR0cmlidXRlICJ1c2UtYXR0cmlidXRlLXNldHMiLAorICAgICovCisgICAgY29tcC0+dXNlID0geHNsdEV2YWxTdGF0aWNBdHRyVmFsdWVUZW1wbGF0ZShzdHlsZSwgaW5zdCwKKwkJICAgICAgIChjb25zdCB4bWxDaGFyICopInVzZS1hdHRyaWJ1dGUtc2V0cyIsCisJCSAgICAgICBOVUxMLCAmY29tcC0+aGFzX3VzZSk7CisKK2Vycm9yOiAgICAKKyAgICByZXR1cm47Cit9CisKKy8qKgorICogeHNsdEF0dHJpYnV0ZUNvbXA6CisgKiBAc3R5bGU6IGFuIFhTTFQgY29tcGlsZWQgc3R5bGVzaGVldAorICogQGluc3Q6ICB0aGUgeHNsdCBhdHRyaWJ1dGUgbm9kZQorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgYXR0cmlidXRlIG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0QXR0cmlidXRlQ29tcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBpbnN0KSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbUF0dHJpYnV0ZVB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIC8qCisgICAgKiA8eHNsOmF0dHJpYnV0ZQorICAgICogICBuYW1lID0geyBxbmFtZSB9CisgICAgKiAgIG5hbWVzcGFjZSA9IHsgdXJpLXJlZmVyZW5jZSB9PgorICAgICogICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICAgICogPC94c2w6YXR0cmlidXRlPgorICAgICovCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICBjb21wID0gKHhzbHRTdHlsZUl0ZW1BdHRyaWJ1dGVQdHIpIHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsCisJWFNMVF9GVU5DX0FUVFJJQlVURSk7CisjZWxzZQorICAgIGNvbXAgPSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfQVRUUklCVVRFKTsKKyNlbmRpZgorICAgIAorICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworICAgIGluc3QtPnBzdmkgPSBjb21wOworICAgIGNvbXAtPmluc3QgPSBpbnN0OworCisgICAgLyoKKyAgICAqIEF0dHJpYnV0ZSAibmFtZSIuCisgICAgKi8KKyAgICAvKgorICAgICogVE9ETzogUHJlY29tcGlsZSB0aGUgQVZULiBTZWUgYnVnICMzNDQ4OTQuCisgICAgKi8KKyAgICBjb21wLT5uYW1lID0geHNsdEV2YWxTdGF0aWNBdHRyVmFsdWVUZW1wbGF0ZShzdHlsZSwgaW5zdCwKKwkJCQkgKGNvbnN0IHhtbENoYXIgKikibmFtZSIsCisJCQkJIE5VTEwsICZjb21wLT5oYXNfbmFtZSk7CisgICAgaWYgKCEgY29tcC0+aGFzX25hbWUpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJICAgICJYU0xULWF0dHJpYnV0ZTogVGhlIGF0dHJpYnV0ZSAnbmFtZScgaXMgbWlzc2luZy5cbiIpOworCXN0eWxlLT5lcnJvcnMrKzsKKwlyZXR1cm47CisgICAgfSAgICAKKyAgICAvKgorICAgICogQXR0cmlidXRlICJuYW1lc3BhY2UiLgorICAgICovCisgICAgLyoKKyAgICAqIFRPRE86IFByZWNvbXBpbGUgdGhlIEFWVC4gU2VlIGJ1ZyAjMzQ0ODk0LgorICAgICovCisgICAgY29tcC0+bnMgPSB4c2x0RXZhbFN0YXRpY0F0dHJWYWx1ZVRlbXBsYXRlKHN0eWxlLCBpbnN0LAorCShjb25zdCB4bWxDaGFyICopIm5hbWVzcGFjZSIsCisJTlVMTCwgJmNvbXAtPmhhc19ucyk7CisKKyAgICBpZiAoY29tcC0+bmFtZSAhPSBOVUxMKSB7CisJaWYgKHhtbFZhbGlkYXRlUU5hbWUoY29tcC0+bmFtZSwgMCkpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkieHNsOmF0dHJpYnV0ZTogVGhlIHZhbHVlICclcycgb2YgdGhlIGF0dHJpYnV0ZSAnbmFtZScgaXMgIgorCQkibm90IGEgdmFsaWQgUU5hbWUuXG4iLCBjb21wLT5uYW1lKTsKKwkgICAgc3R5bGUtPmVycm9ycysrOworCX0gZWxzZSB7CisJICAgIGNvbnN0IHhtbENoYXIgKnByZWZpeCA9IE5VTEwsICpuYW1lOworCisJICAgIG5hbWUgPSB4c2x0U3BsaXRRTmFtZShzdHlsZS0+ZGljdCwgY29tcC0+bmFtZSwgJnByZWZpeCk7CisJICAgIGlmIChwcmVmaXggIT0gTlVMTCkgeworCQlpZiAoY29tcC0+aGFzX25zID09IDApIHsKKwkJICAgIHhtbE5zUHRyIG5zOworCisJCSAgICAvKgorCQkgICAgKiBTUEVDIFhTTFQgMS4wOgorCQkgICAgKiAgIklmIHRoZSBuYW1lc3BhY2UgYXR0cmlidXRlIGlzIG5vdCBwcmVzZW50LCB0aGVuIHRoZQorCQkgICAgKiAgUU5hbWUgaXMgZXhwYW5kZWQgaW50byBhbiBleHBhbmRlZC1uYW1lIHVzaW5nIHRoZQorCQkgICAgKiAgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBpbiBlZmZlY3QgZm9yIHRoZSB4c2w6ZWxlbWVudAorCQkgICAgKiAgZWxlbWVudCwgaW5jbHVkaW5nIGFueSBkZWZhdWx0IG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KKwkJICAgICovCSAgICAJICAgIAorCQkgICAgbnMgPSB4bWxTZWFyY2hOcyhpbnN0LT5kb2MsIGluc3QsIHByZWZpeCk7CisJCSAgICBpZiAobnMgIT0gTlVMTCkgeworCQkJY29tcC0+bnMgPSB4bWxEaWN0TG9va3VwKHN0eWxlLT5kaWN0LCBucy0+aHJlZiwgLTEpOworCQkJY29tcC0+aGFzX25zID0gMTsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwkJCWNvbXAtPm5zUHJlZml4ID0gcHJlZml4OworCQkJY29tcC0+bmFtZSA9IG5hbWU7CisjZW5kaWYKKwkJICAgIH0gZWxzZSB7CisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCQkgICAgInhzbDphdHRyaWJ1dGU6IFRoZSBwcmVmaXhlZCBRTmFtZSAnJXMnICIKKwkJCSAgICAiaGFzIG5vIG5hbWVzcGFjZSBiaW5kaW5nIGluIHNjb3BlIGluIHRoZSAiCisJCQkgICAgInN0eWxlc2hlZXQ7IHRoaXMgaXMgYW4gZXJyb3IsIHNpbmNlIHRoZSAiCisJCQkgICAgIm5hbWVzcGFjZSB3YXMgbm90IHNwZWNpZmllZCBieSB0aGUgaW5zdHJ1Y3Rpb24gIgorCQkJICAgICJpdHNlbGYuXG4iLCBjb21wLT5uYW1lKTsKKwkJCXN0eWxlLT5lcnJvcnMrKzsKKwkJICAgIH0KKwkJfQorCQlpZiAoIXhtbFN0cm5jYXNlY21wKHByZWZpeCwgKHhtbENoYXIgKikgInhtbG5zIiwgNSkpIHsKKwkJICAgIC8qCisJCSAgICAqIFNQRUMgWFNMVCAxLjA6CisJCSAgICAqICAiSXQgaXMgYW4gZXJyb3IgaWYgdGhlIHN0cmluZyB0aGF0IHJlc3VsdHMgZnJvbQorCQkgICAgKiAgaW5zdGFudGlhdGluZyB0aGUgYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIGlzIG5vdCBhCisJCSAgICAqICBRTmFtZSBvciBpcyB0aGUgc3RyaW5nIHhtbG5zLiBBbiBYU0xUIHByb2Nlc3NvciBtYXkKKwkJICAgICogIHNpZ25hbCB0aGUgZXJyb3I7IGlmIGl0IGRvZXMgbm90IHNpZ25hbCB0aGUgZXJyb3IsCisJCSAgICAqICBpdCBtdXN0IHJlY292ZXIgYnkgbm90IGFkZGluZyB0aGUgYXR0cmlidXRlIHRvIHRoZQorCQkgICAgKiAgcmVzdWx0IHRyZWUuIgorCQkgICAgKgorCQkgICAgKiBSZWplY3QgYSBwcmVmaXggb2YgInhtbG5zIi4gTWFyayB0byBiZSBza2lwcGVkLgorCQkgICAgKi8KKwkJICAgIGNvbXAtPmhhc19uYW1lID0gMDsKKwkJICAgIAorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJInhzbHRBdHRyaWJ1dGU6IHhtbG5zIHByZWZpeCBmb3JiaWRkZW5cbiIpOworI2VuZGlmCQkgICAgCisJCSAgICByZXR1cm47CisJCX0KKwkJCisJICAgIH0KKwl9CQorICAgIH0KK30KKworLyoqCisgKiB4c2x0Q29tbWVudENvbXA6CisgKiBAc3R5bGU6IGFuIFhTTFQgY29tcGlsZWQgc3R5bGVzaGVldAorICogQGluc3Q6ICB0aGUgeHNsdCBjb21tZW50IG5vZGUKKyAqCisgKiBQcm9jZXNzIHRoZSB4c2x0IGNvbW1lbnQgbm9kZSBvbiB0aGUgc291cmNlIG5vZGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRDb21tZW50Q29tcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBpbnN0KSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbUNvbW1lbnRQdHIgY29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wOworI2VuZGlmCisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpKQorCXJldHVybjsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIGNvbXAgPSAoeHNsdFN0eWxlSXRlbUNvbW1lbnRQdHIpIHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19DT01NRU5UKTsKKyNlbHNlCisgICAgY29tcCA9IHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19DT01NRU5UKTsKKyNlbmRpZgorCisgICAgaWYgKGNvbXAgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaW5zdC0+cHN2aSA9IGNvbXA7CisgICAgY29tcC0+aW5zdCA9IGluc3Q7Cit9CisKKy8qKgorICogeHNsdFByb2Nlc3NpbmdJbnN0cnVjdGlvbkNvbXA6CisgKiBAc3R5bGU6IGFuIFhTTFQgY29tcGlsZWQgc3R5bGVzaGVldAorICogQGluc3Q6ICB0aGUgeHNsdCBwcm9jZXNzaW5nLWluc3RydWN0aW9uIG5vZGUKKyAqCisgKiBQcm9jZXNzIHRoZSB4c2x0IHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gbm9kZSBvbiB0aGUgc291cmNlIG5vZGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25Db21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtUElQdHIgY29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wOworI2VuZGlmCisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpKQorCXJldHVybjsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIGNvbXAgPSAoeHNsdFN0eWxlSXRlbVBJUHRyKSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfUEkpOworI2Vsc2UKKyAgICBjb21wID0geHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX1BJKTsKKyNlbmRpZgorCisgICAgaWYgKGNvbXAgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaW5zdC0+cHN2aSA9IGNvbXA7CisgICAgY29tcC0+aW5zdCA9IGluc3Q7CisKKyAgICBjb21wLT5uYW1lID0geHNsdEV2YWxTdGF0aWNBdHRyVmFsdWVUZW1wbGF0ZShzdHlsZSwgaW5zdCwKKwkJCQkgKGNvbnN0IHhtbENoYXIgKikibmFtZSIsCisJCQkJIFhTTFRfTkFNRVNQQUNFLCAmY29tcC0+aGFzX25hbWUpOworfQorCisvKioKKyAqIHhzbHRDb3B5T2ZDb21wOgorICogQHN0eWxlOiBhbiBYU0xUIGNvbXBpbGVkIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIHhzbHQgY29weS1vZiBub2RlCisgKgorICogUHJvY2VzcyB0aGUgeHNsdCBjb3B5LW9mIG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0Q29weU9mQ29tcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBpbnN0KSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbUNvcHlPZlB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkpCisJcmV0dXJuOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgY29tcCA9ICh4c2x0U3R5bGVJdGVtQ29weU9mUHRyKSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfQ09QWU9GKTsKKyNlbHNlCisgICAgY29tcCA9IHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19DT1BZT0YpOworI2VuZGlmCisKKyAgICBpZiAoY29tcCA9PSBOVUxMKQorCXJldHVybjsKKyAgICBpbnN0LT5wc3ZpID0gY29tcDsKKyAgICBjb21wLT5pbnN0ID0gaW5zdDsKKworICAgIGNvbXAtPnNlbGVjdCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBpbnN0LCAoY29uc3QgeG1sQ2hhciAqKSJzZWxlY3QiLAorCSAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRfTkFNRVNQQUNFKTsKKyAgICBpZiAoY29tcC0+c2VsZWN0ID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJICAgICAieHNsOmNvcHktb2YgOiBzZWxlY3QgaXMgbWlzc2luZ1xuIik7CisJaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKwlyZXR1cm47CisgICAgfQorICAgIGNvbXAtPmNvbXAgPSB4c2x0WFBhdGhDb21waWxlKHN0eWxlLCBjb21wLT5zZWxlY3QpOworICAgIGlmIChjb21wLT5jb21wID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJICAgICAieHNsOmNvcHktb2YgOiBjb3VsZCBub3QgY29tcGlsZSBzZWxlY3QgZXhwcmVzc2lvbiAnJXMnXG4iLAorCSAgICAgICAgICAgICAgICAgY29tcC0+c2VsZWN0KTsKKwlpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPmVycm9ycysrOworICAgIH0KK30KKworLyoqCisgKiB4c2x0VmFsdWVPZkNvbXA6CisgKiBAc3R5bGU6IGFuIFhTTFQgY29tcGlsZWQgc3R5bGVzaGVldAorICogQGluc3Q6ICB0aGUgeHNsdCB2YWx1ZS1vZiBub2RlCisgKgorICogUHJvY2VzcyB0aGUgeHNsdCB2YWx1ZS1vZiBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCitzdGF0aWMgdm9pZAoreHNsdFZhbHVlT2ZDb21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtVmFsdWVPZlB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKyAgICBjb25zdCB4bWxDaGFyICpwcm9wOworCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICBjb21wID0gKHhzbHRTdHlsZUl0ZW1WYWx1ZU9mUHRyKSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfVkFMVUVPRik7CisjZWxzZQorICAgIGNvbXAgPSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfVkFMVUVPRik7CisjZW5kaWYKKworICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworICAgIGluc3QtPnBzdmkgPSBjb21wOworICAgIGNvbXAtPmluc3QgPSBpbnN0OworCisgICAgcHJvcCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBpbnN0LAorCSAgICAoY29uc3QgeG1sQ2hhciAqKSJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIsCisJCQlYU0xUX05BTUVTUEFDRSk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWlmICh4bWxTdHJFcXVhbChwcm9wLCAoY29uc3QgeG1sQ2hhciAqKSJ5ZXMiKSkgeworCSAgICBjb21wLT5ub2VzY2FwZSA9IDE7CisJfSBlbHNlIGlmICgheG1sU3RyRXF1YWwocHJvcCwKKwkJCQkoY29uc3QgeG1sQ2hhciAqKSJubyIpKXsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorInhzbDp2YWx1ZS1vZiA6IGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGFsbG93cyBvbmx5IHllcyBvciBub1xuIik7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKwl9CisgICAgfQorICAgIGNvbXAtPnNlbGVjdCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBpbnN0LCAoY29uc3QgeG1sQ2hhciAqKSJzZWxlY3QiLAorCSAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRfTkFNRVNQQUNFKTsKKyAgICBpZiAoY29tcC0+c2VsZWN0ID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJICAgICAieHNsOnZhbHVlLW9mIDogc2VsZWN0IGlzIG1pc3NpbmdcbiIpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuOworICAgIH0KKyAgICBjb21wLT5jb21wID0geHNsdFhQYXRoQ29tcGlsZShzdHlsZSwgY29tcC0+c2VsZWN0KTsKKyAgICBpZiAoY29tcC0+Y29tcCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCSAgICAgInhzbDp2YWx1ZS1vZiA6IGNvdWxkIG5vdCBjb21waWxlIHNlbGVjdCBleHByZXNzaW9uICclcydcbiIsCisJICAgICAgICAgICAgICAgICBjb21wLT5zZWxlY3QpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisgICAgfQorfQorCitzdGF0aWMgdm9pZAoreHNsdEdldFFOYW1lUHJvcGVydHkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgaW5zdCwKKwkJICAgICBjb25zdCB4bWxDaGFyICpwcm9wTmFtZSwKKwkJICAgICBpbnQgbWFuZGF0b3J5LAorCQkgICAgIGludCAqaGFzUHJvcCwgY29uc3QgeG1sQ2hhciAqKm5zTmFtZSwKKwkJICAgICBjb25zdCB4bWxDaGFyKiogbG9jYWxOYW1lKQoreworICAgIGNvbnN0IHhtbENoYXIgKnByb3A7CisKKyAgICBpZiAobnNOYW1lKQorCSpuc05hbWUgPSBOVUxMOworICAgIGlmIChsb2NhbE5hbWUpCisJKmxvY2FsTmFtZSA9IE5VTEw7CisgICAgaWYgKGhhc1Byb3ApCisJKmhhc1Byb3AgPSAwOworCisgICAgcHJvcCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBpbnN0LCBwcm9wTmFtZSwgWFNMVF9OQU1FU1BBQ0UpOworICAgIGlmIChwcm9wID09IE5VTEwpIHsKKwlpZiAobWFuZGF0b3J5KSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkJIlRoZSBhdHRyaWJ1dGUgJyVzJyBpcyBtaXNzaW5nLlxuIiwgcHJvcE5hbWUpOworCSAgICBzdHlsZS0+ZXJyb3JzKys7CisJICAgIHJldHVybjsKKwl9CisgICAgfSBlbHNlIHsKKyAgICAgICAgY29uc3QgeG1sQ2hhciAqVVJJOworCisJaWYgKHhtbFZhbGlkYXRlUU5hbWUocHJvcCwgMCkpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkiVGhlIHZhbHVlICclcycgb2YgdGhlIGF0dHJpYnV0ZSAiCisJCSInJXMnIGlzIG5vdCBhIHZhbGlkIFFOYW1lLlxuIiwgcHJvcCwgcHJvcE5hbWUpOworCSAgICBzdHlsZS0+ZXJyb3JzKys7CisJICAgIHJldHVybjsKKwl9IGVsc2UgeworCSAgICAvKgorCSAgICAqIEBwcm9wIHdpbGwgYmUgaW4gdGhlIHN0cmluZyBkaWN0IGFmdGVyd2FyZHMsIEBVUkkgbm90LgorCSAgICAqLworCSAgICBVUkkgPSB4c2x0R2V0UU5hbWVVUkkyKHN0eWxlLCBpbnN0LCAmcHJvcCk7CisJICAgIGlmIChwcm9wID09IE5VTEwpIHsKKwkJc3R5bGUtPmVycm9ycysrOworCSAgICB9IGVsc2UgeworCQkqbG9jYWxOYW1lID0gcHJvcDsKKwkJaWYgKGhhc1Byb3ApCisJCSAgICAqaGFzUHJvcCA9IDE7CisJCWlmIChVUkkgIT0gTlVMTCkgeworCQkgICAgLyoKKwkJICAgICogRml4ZXMgYnVnICMzMDg0NDE6IFB1dCB0aGUgbnMtbmFtZSBpbiB0aGUgZGljdAorCQkgICAgKiBpbiBvcmRlciB0byBwb2ludGVyIGNvbXBhcmUgbmFtZXMgZHVyaW5nIFhQYXRoJ3MKKwkJICAgICogdmFyaWFibGUgbG9va3VwLgorCQkgICAgKi8KKwkJICAgIGlmIChuc05hbWUpCisJCQkqbnNOYW1lID0geG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgVVJJLCAtMSk7CisJCSAgICAvKiBjb21wLT5oYXNfbnMgPSAxOyAqLworCQl9CisJICAgIH0KKwl9CisgICAgfQorICAgIHJldHVybjsKK30KKworLyoqCisgKiB4c2x0V2l0aFBhcmFtQ29tcDoKKyAqIEBzdHlsZTogYW4gWFNMVCBjb21waWxlZCBzdHlsZXNoZWV0CisgKiBAaW5zdDogIHRoZSB4c2x0IHdpdGgtcGFyYW0gbm9kZQorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgd2l0aC1wYXJhbSBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICogQWxsb3dlZCBwYXJlbnRzOiB4c2w6Y2FsbC10ZW1wbGF0ZSwgeHNsOmFwcGx5LXRlbXBsYXRlcy4KKyAqIDx4c2w6d2l0aC1wYXJhbQorICogIG5hbWUgPSBxbmFtZQorICogIHNlbGVjdCA9IGV4cHJlc3Npb24+CisgKiAgPCEtLSBDb250ZW50OiB0ZW1wbGF0ZSAtLT4KKyAqIDwveHNsOndpdGgtcGFyYW0+CisgKi8KK3N0YXRpYyB2b2lkCit4c2x0V2l0aFBhcmFtQ29tcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBpbnN0KSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbVdpdGhQYXJhbVB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkpCisJcmV0dXJuOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgY29tcCA9ICh4c2x0U3R5bGVJdGVtV2l0aFBhcmFtUHRyKSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfV0lUSFBBUkFNKTsKKyNlbHNlCisgICAgY29tcCA9IHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19XSVRIUEFSQU0pOworI2VuZGlmCisKKyAgICBpZiAoY29tcCA9PSBOVUxMKQorCXJldHVybjsKKyAgICBpbnN0LT5wc3ZpID0gY29tcDsKKyAgICBjb21wLT5pbnN0ID0gaW5zdDsKKworICAgIC8qCisgICAgKiBBdHRyaWJ1dGUgIm5hbWUiLgorICAgICovCisgICAgeHNsdEdldFFOYW1lUHJvcGVydHkoc3R5bGUsIGluc3QsIEJBRF9DQVNUICJuYW1lIiwKKwkxLCAmKGNvbXAtPmhhc19uYW1lKSwgJihjb21wLT5ucyksICYoY29tcC0+bmFtZSkpOworICAgIGlmIChjb21wLT5ucykKKwljb21wLT5oYXNfbnMgPSAxOworICAgIC8qCisgICAgKiBBdHRyaWJ1dGUgInNlbGVjdCIuCisgICAgKi8KKyAgICBjb21wLT5zZWxlY3QgPSB4c2x0R2V0Q05zUHJvcChzdHlsZSwgaW5zdCwgKGNvbnN0IHhtbENoYXIgKikic2VsZWN0IiwKKwkgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSk7CisgICAgaWYgKGNvbXAtPnNlbGVjdCAhPSBOVUxMKSB7CisJY29tcC0+Y29tcCA9IHhzbHRYUGF0aENvbXBpbGUoc3R5bGUsIGNvbXAtPnNlbGVjdCk7CisJaWYgKGNvbXAtPmNvbXAgPT0gTlVMTCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCSAiWFNMVC13aXRoLXBhcmFtOiBGYWlsZWQgdG8gY29tcGlsZSBzZWxlY3QgIgorCQkgImV4cHJlc3Npb24gJyVzJ1xuIiwgY29tcC0+c2VsZWN0KTsKKwkgICAgc3R5bGUtPmVycm9ycysrOworCX0KKwlpZiAoaW5zdC0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCSJYU0xULXdpdGgtcGFyYW06IFRoZSBjb250ZW50IHNob3VsZCBiZSBlbXB0eSBzaW5jZSAiCisJCSJ0aGUgYXR0cmlidXRlIHNlbGVjdCBpcyBwcmVzZW50LlxuIik7CisJICAgIHN0eWxlLT53YXJuaW5ncysrOworCX0KKyAgICB9Cit9CisKKy8qKgorICogeHNsdE51bWJlckNvbXA6CisgKiBAc3R5bGU6IGFuIFhTTFQgY29tcGlsZWQgc3R5bGVzaGVldAorICogQGN1cjogICB0aGUgeHNsdCBudW1iZXIgbm9kZQorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgbnVtYmVyIG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0TnVtYmVyQ29tcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBjdXIpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtTnVtYmVyUHRyIGNvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcDsKKyNlbmRpZgorICAgIGNvbnN0IHhtbENoYXIgKnByb3A7CisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChjdXIgPT0gTlVMTCkpCisJcmV0dXJuOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgY29tcCA9ICh4c2x0U3R5bGVJdGVtTnVtYmVyUHRyKSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfTlVNQkVSKTsKKyNlbHNlCisgICAgY29tcCA9IHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19OVU1CRVIpOworI2VuZGlmCisKKyAgICBpZiAoY29tcCA9PSBOVUxMKQorCXJldHVybjsKKyAgICBjdXItPnBzdmkgPSBjb21wOworCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoY3VyID09IE5VTEwpKQorCXJldHVybjsKKworICAgIGNvbXAtPm51bWRhdGEuZG9jID0gY3VyLT5kb2M7CisgICAgY29tcC0+bnVtZGF0YS5ub2RlID0gY3VyOworICAgIGNvbXAtPm51bWRhdGEudmFsdWUgPSB4c2x0R2V0Q05zUHJvcChzdHlsZSwgY3VyLCAoY29uc3QgeG1sQ2hhciAqKSJ2YWx1ZSIsCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSk7CisgICAgCisgICAgcHJvcCA9IHhzbHRFdmFsU3RhdGljQXR0clZhbHVlVGVtcGxhdGUoc3R5bGUsIGN1ciwKKwkJCSAoY29uc3QgeG1sQ2hhciAqKSJmb3JtYXQiLAorCQkJIFhTTFRfTkFNRVNQQUNFLCAmY29tcC0+bnVtZGF0YS5oYXNfZm9ybWF0KTsKKyAgICBpZiAoY29tcC0+bnVtZGF0YS5oYXNfZm9ybWF0ID09IDApIHsKKwljb21wLT5udW1kYXRhLmZvcm1hdCA9IHhtbERpY3RMb29rdXAoc3R5bGUtPmRpY3QsIEJBRF9DQVNUICIiICwgMCk7CisgICAgfSBlbHNlIHsKKwljb21wLT5udW1kYXRhLmZvcm1hdCA9IHByb3A7CisgICAgfQorCisgICAgY29tcC0+bnVtZGF0YS5jb3VudCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBjdXIsIChjb25zdCB4bWxDaGFyICopImNvdW50IiwKKwkJCQkJWFNMVF9OQU1FU1BBQ0UpOworICAgIGNvbXAtPm51bWRhdGEuZnJvbSA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBjdXIsIChjb25zdCB4bWxDaGFyICopImZyb20iLAorCQkJCQlYU0xUX05BTUVTUEFDRSk7CisgICAgCisgICAgcHJvcCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBjdXIsIChjb25zdCB4bWxDaGFyICopImxldmVsIiwgWFNMVF9OQU1FU1BBQ0UpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKwlpZiAoeG1sU3RyRXF1YWwocHJvcCwgQkFEX0NBU1QoInNpbmdsZSIpKSB8fAorCSAgICB4bWxTdHJFcXVhbChwcm9wLCBCQURfQ0FTVCgibXVsdGlwbGUiKSkgfHwKKwkgICAgeG1sU3RyRXF1YWwocHJvcCwgQkFEX0NBU1QoImFueSIpKSkgeworCSAgICBjb21wLT5udW1kYXRhLmxldmVsID0gcHJvcDsKKwl9IGVsc2UgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkJCSAieHNsOm51bWJlciA6IGludmFsaWQgdmFsdWUgJXMgZm9yIGxldmVsXG4iLCBwcm9wKTsKKwkgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT53YXJuaW5ncysrOworCX0KKyAgICB9CisgICAgCisgICAgcHJvcCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBjdXIsIChjb25zdCB4bWxDaGFyICopImxhbmciLCBYU0xUX05BTUVTUEFDRSk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkJICJ4c2w6bnVtYmVyIDogbGFuZyBhdHRyaWJ1dGUgbm90IGltcGxlbWVudGVkXG4iKTsKKwlYU0xUX1RPRE87IC8qIHhzbDpudW1iZXIgbGFuZyBhdHRyaWJ1dGUgKi8KKyAgICB9CisgICAgCisgICAgcHJvcCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBjdXIsIChjb25zdCB4bWxDaGFyICopImxldHRlci12YWx1ZSIsIFhTTFRfTkFNRVNQQUNFKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJaWYgKHhtbFN0ckVxdWFsKHByb3AsIEJBRF9DQVNUKCJhbHBoYWJldGljIikpKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCQkgInhzbDpudW1iZXIgOiBsZXR0ZXItdmFsdWUgJ2FscGhhYmV0aWMnIG5vdCBpbXBsZW1lbnRlZFxuIik7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKwkgICAgWFNMVF9UT0RPOyAvKiB4c2w6bnVtYmVyIGxldHRlci12YWx1ZSBhdHRyaWJ1dGUgYWxwaGFiZXRpYyAqLworCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwocHJvcCwgQkFEX0NBU1QoInRyYWRpdGlvbmFsIikpKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCQkgInhzbDpudW1iZXIgOiBsZXR0ZXItdmFsdWUgJ3RyYWRpdGlvbmFsJyBub3QgaW1wbGVtZW50ZWRcbiIpOworCSAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPndhcm5pbmdzKys7CisJICAgIFhTTFRfVE9ETzsgLyogeHNsOm51bWJlciBsZXR0ZXItdmFsdWUgYXR0cmlidXRlIHRyYWRpdGlvbmFsICovCisJfSBlbHNlIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJCSAgICAgInhzbDpudW1iZXIgOiBpbnZhbGlkIHZhbHVlICVzIGZvciBsZXR0ZXItdmFsdWVcbiIsIHByb3ApOworCSAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPndhcm5pbmdzKys7CisJfQorICAgIH0KKyAgICAKKyAgICBwcm9wID0geHNsdEdldENOc1Byb3Aoc3R5bGUsIGN1ciwgKGNvbnN0IHhtbENoYXIgKikiZ3JvdXBpbmctc2VwYXJhdG9yIiwKKwkgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKyAgICAgICAgY29tcC0+bnVtZGF0YS5ncm91cGluZ0NoYXJhY3RlckxlbiA9IHhtbFN0cmxlbihwcm9wKTsKKwljb21wLT5udW1kYXRhLmdyb3VwaW5nQ2hhcmFjdGVyID0KKwkgICAgeHNsdEdldFVURjhDaGFyKHByb3AsICYoY29tcC0+bnVtZGF0YS5ncm91cGluZ0NoYXJhY3RlckxlbikpOworICAgIH0KKyAgICAKKyAgICBwcm9wID0geHNsdEdldENOc1Byb3Aoc3R5bGUsIGN1ciwgKGNvbnN0IHhtbENoYXIgKikiZ3JvdXBpbmctc2l6ZSIsIFhTTFRfTkFNRVNQQUNFKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJc3NjYW5mKChjaGFyICopcHJvcCwgIiVkIiwgJmNvbXAtPm51bWRhdGEuZGlnaXRzUGVyR3JvdXApOworICAgIH0gZWxzZSB7CisJY29tcC0+bnVtZGF0YS5ncm91cGluZ0NoYXJhY3RlciA9IDA7CisgICAgfQorCisgICAgLyogU2V0IGRlZmF1bHQgdmFsdWVzICovCisgICAgaWYgKGNvbXAtPm51bWRhdGEudmFsdWUgPT0gTlVMTCkgeworCWlmIChjb21wLT5udW1kYXRhLmxldmVsID09IE5VTEwpIHsKKwkgICAgY29tcC0+bnVtZGF0YS5sZXZlbCA9IHhtbERpY3RMb29rdXAoc3R5bGUtPmRpY3QsCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJBRF9DQVNUInNpbmdsZSIsIDYpOworCX0KKyAgICB9CisgICAgCit9CisKKy8qKgorICogeHNsdEFwcGx5SW1wb3J0c0NvbXA6CisgKiBAc3R5bGU6IGFuIFhTTFQgY29tcGlsZWQgc3R5bGVzaGVldAorICogQGluc3Q6ICB0aGUgeHNsdCBhcHBseS1pbXBvcnRzIG5vZGUKKyAqCisgKiBQcm9jZXNzIHRoZSB4c2x0IGFwcGx5LWltcG9ydHMgbm9kZSBvbiB0aGUgc291cmNlIG5vZGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRBcHBseUltcG9ydHNDb21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtQXBwbHlJbXBvcnRzUHRyIGNvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcDsKKyNlbmRpZgorCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICBjb21wID0gKHhzbHRTdHlsZUl0ZW1BcHBseUltcG9ydHNQdHIpIHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19BUFBMWUlNUE9SVFMpOworI2Vsc2UKKyAgICBjb21wID0geHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX0FQUExZSU1QT1JUUyk7CisjZW5kaWYKKworICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworICAgIGluc3QtPnBzdmkgPSBjb21wOworICAgIGNvbXAtPmluc3QgPSBpbnN0OworfQorCisvKioKKyAqIHhzbHRDYWxsVGVtcGxhdGVDb21wOgorICogQHN0eWxlOiBhbiBYU0xUIGNvbXBpbGVkIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIHhzbHQgY2FsbC10ZW1wbGF0ZSBub2RlCisgKgorICogUHJvY2VzcyB0aGUgeHNsdCBjYWxsLXRlbXBsYXRlIG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0Q2FsbFRlbXBsYXRlQ29tcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBpbnN0KSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbUNhbGxUZW1wbGF0ZVB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkpCisJcmV0dXJuOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgY29tcCA9ICh4c2x0U3R5bGVJdGVtQ2FsbFRlbXBsYXRlUHRyKQorCXhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19DQUxMVEVNUExBVEUpOworI2Vsc2UKKyAgICBjb21wID0geHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX0NBTExURU1QTEFURSk7CisjZW5kaWYKKworICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworICAgIGluc3QtPnBzdmkgPSBjb21wOworICAgIGNvbXAtPmluc3QgPSBpbnN0OworCisgICAgLyoKKyAgICAgKiBBdHRyaWJ1dGUgIm5hbWUiLgorICAgICAqLworICAgIHhzbHRHZXRRTmFtZVByb3BlcnR5KHN0eWxlLCBpbnN0LCBCQURfQ0FTVCAibmFtZSIsCisJMSwgJihjb21wLT5oYXNfbmFtZSksICYoY29tcC0+bnMpLCAmKGNvbXAtPm5hbWUpKTsKKyAgICBpZiAoY29tcC0+bnMpCisJY29tcC0+aGFzX25zID0gMTsKK30KKworLyoqCisgKiB4c2x0QXBwbHlUZW1wbGF0ZXNDb21wOgorICogQHN0eWxlOiBhbiBYU0xUIGNvbXBpbGVkIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIGFwcGx5LXRlbXBsYXRlcyBub2RlCisgKgorICogUHJvY2VzcyB0aGUgYXBwbHktdGVtcGxhdGVzIG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0QXBwbHlUZW1wbGF0ZXNDb21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtQXBwbHlUZW1wbGF0ZXNQdHIgY29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wOworI2VuZGlmCisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpKQorCXJldHVybjsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIGNvbXAgPSAoeHNsdFN0eWxlSXRlbUFwcGx5VGVtcGxhdGVzUHRyKQorCXhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19BUFBMWVRFTVBMQVRFUyk7CisjZWxzZQorICAgIGNvbXAgPSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfQVBQTFlURU1QTEFURVMpOworI2VuZGlmCisKKyAgICBpZiAoY29tcCA9PSBOVUxMKQorCXJldHVybjsKKyAgICBpbnN0LT5wc3ZpID0gY29tcDsKKyAgICBjb21wLT5pbnN0ID0gaW5zdDsKKworICAgIC8qCisgICAgICogQXR0cmlidXRlICJtb2RlIi4KKyAgICAgKi8KKyAgICB4c2x0R2V0UU5hbWVQcm9wZXJ0eShzdHlsZSwgaW5zdCwgQkFEX0NBU1QgIm1vZGUiLAorCTAsIE5VTEwsICYoY29tcC0+bW9kZVVSSSksICYoY29tcC0+bW9kZSkpOworICAgIC8qCisgICAgKiBBdHRyaWJ1dGUgInNlbGVjdCIuCisgICAgKi8KKyAgICBjb21wLT5zZWxlY3QgPSB4c2x0R2V0Q05zUHJvcChzdHlsZSwgaW5zdCwgQkFEX0NBU1QgInNlbGVjdCIsCisJWFNMVF9OQU1FU1BBQ0UpOworICAgIGlmIChjb21wLT5zZWxlY3QgIT0gTlVMTCkgeworCWNvbXAtPmNvbXAgPSB4c2x0WFBhdGhDb21waWxlKHN0eWxlLCBjb21wLT5zZWxlY3QpOworCWlmIChjb21wLT5jb21wID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkiWFNMVC1hcHBseS10ZW1wbGF0ZXM6IGNvdWxkIG5vdCBjb21waWxlIHNlbGVjdCAiCisJCSJleHByZXNzaW9uICclcydcbiIsIGNvbXAtPnNlbGVjdCk7CisJICAgICBzdHlsZS0+ZXJyb3JzKys7CisJfQorICAgIH0KKyAgICAvKiBUT0RPOiBoYW5kbGUgKG9yIHNraXApIHRoZSB4c2w6c29ydCBhbmQgeHNsOndpdGgtcGFyYW0gKi8KK30KKworLyoqCisgKiB4c2x0Q2hvb3NlQ29tcDoKKyAqIEBzdHlsZTogYW4gWFNMVCBjb21waWxlZCBzdHlsZXNoZWV0CisgKiBAaW5zdDogIHRoZSB4c2x0IGNob29zZSBub2RlCisgKgorICogUHJvY2VzcyB0aGUgeHNsdCBjaG9vc2Ugbm9kZSBvbiB0aGUgc291cmNlIG5vZGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRDaG9vc2VDb21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtQ2hvb3NlUHRyIGNvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcDsKKyNlbmRpZgorCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICBjb21wID0gKHhzbHRTdHlsZUl0ZW1DaG9vc2VQdHIpCisJeHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX0NIT09TRSk7CisjZWxzZQorICAgIGNvbXAgPSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfQ0hPT1NFKTsKKyNlbmRpZgorCisgICAgaWYgKGNvbXAgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaW5zdC0+cHN2aSA9IGNvbXA7CisgICAgY29tcC0+aW5zdCA9IGluc3Q7Cit9CisKKy8qKgorICogeHNsdElmQ29tcDoKKyAqIEBzdHlsZTogYW4gWFNMVCBjb21waWxlZCBzdHlsZXNoZWV0CisgKiBAaW5zdDogIHRoZSB4c2x0IGlmIG5vZGUKKyAqCisgKiBQcm9jZXNzIHRoZSB4c2x0IGlmIG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0SWZDb21wKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtSWZQdHIgY29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wOworI2VuZGlmCisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpKQorCXJldHVybjsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIGNvbXAgPSAoeHNsdFN0eWxlSXRlbUlmUHRyKQorCXhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19JRik7CisjZWxzZQorICAgIGNvbXAgPSB4c2x0TmV3U3R5bGVQcmVDb21wKHN0eWxlLCBYU0xUX0ZVTkNfSUYpOworI2VuZGlmCisKKyAgICBpZiAoY29tcCA9PSBOVUxMKQorCXJldHVybjsKKyAgICBpbnN0LT5wc3ZpID0gY29tcDsKKyAgICBjb21wLT5pbnN0ID0gaW5zdDsKKworICAgIGNvbXAtPnRlc3QgPSB4c2x0R2V0Q05zUHJvcChzdHlsZSwgaW5zdCwgKGNvbnN0IHhtbENoYXIgKikidGVzdCIsIFhTTFRfTkFNRVNQQUNFKTsKKyAgICBpZiAoY29tcC0+dGVzdCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCSAgICAgInhzbDppZiA6IHRlc3QgaXMgbm90IGRlZmluZWRcbiIpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuOworICAgIH0KKyAgICBjb21wLT5jb21wID0geHNsdFhQYXRoQ29tcGlsZShzdHlsZSwgY29tcC0+dGVzdCk7CisgICAgaWYgKGNvbXAtPmNvbXAgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkgICAgICJ4c2w6aWYgOiBjb3VsZCBub3QgY29tcGlsZSB0ZXN0IGV4cHJlc3Npb24gJyVzJ1xuIiwKKwkgICAgICAgICAgICAgICAgIGNvbXAtPnRlc3QpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisgICAgfQorfQorCisvKioKKyAqIHhzbHRXaGVuQ29tcDoKKyAqIEBzdHlsZTogYW4gWFNMVCBjb21waWxlZCBzdHlsZXNoZWV0CisgKiBAaW5zdDogIHRoZSB4c2x0IGlmIG5vZGUKKyAqCisgKiBQcm9jZXNzIHRoZSB4c2x0IGlmIG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0V2hlbkNvbXAoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgaW5zdCkgeworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1XaGVuUHRyIGNvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcDsKKyNlbmRpZgorCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICBjb21wID0gKHhzbHRTdHlsZUl0ZW1XaGVuUHRyKQorCXhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19XSEVOKTsKKyNlbHNlCisgICAgY29tcCA9IHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19XSEVOKTsKKyNlbmRpZgorCisgICAgaWYgKGNvbXAgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaW5zdC0+cHN2aSA9IGNvbXA7CisgICAgY29tcC0+aW5zdCA9IGluc3Q7CisKKyAgICBjb21wLT50ZXN0ID0geHNsdEdldENOc1Byb3Aoc3R5bGUsIGluc3QsIChjb25zdCB4bWxDaGFyICopInRlc3QiLCBYU0xUX05BTUVTUEFDRSk7CisgICAgaWYgKGNvbXAtPnRlc3QgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkgICAgICJ4c2w6d2hlbiA6IHRlc3QgaXMgbm90IGRlZmluZWRcbiIpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuOworICAgIH0KKyAgICBjb21wLT5jb21wID0geHNsdFhQYXRoQ29tcGlsZShzdHlsZSwgY29tcC0+dGVzdCk7CisgICAgaWYgKGNvbXAtPmNvbXAgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkgICAgICJ4c2w6d2hlbiA6IGNvdWxkIG5vdCBjb21waWxlIHRlc3QgZXhwcmVzc2lvbiAnJXMnXG4iLAorCSAgICAgICAgICAgICAgICAgY29tcC0+dGVzdCk7CisJaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKyAgICB9Cit9CisKKy8qKgorICogeHNsdEZvckVhY2hDb21wOgorICogQHN0eWxlOiBhbiBYU0xUIGNvbXBpbGVkIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIHhzbHQgZm9yLWVhY2ggbm9kZQorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgZm9yLWVhY2ggbm9kZSBvbiB0aGUgc291cmNlIG5vZGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRGb3JFYWNoQ29tcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBpbnN0KSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbUZvckVhY2hQdHIgY29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wOworI2VuZGlmCisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpKQorCXJldHVybjsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIGNvbXAgPSAoeHNsdFN0eWxlSXRlbUZvckVhY2hQdHIpCisJeHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX0ZPUkVBQ0gpOworI2Vsc2UKKyAgICBjb21wID0geHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX0ZPUkVBQ0gpOworI2VuZGlmCisKKyAgICBpZiAoY29tcCA9PSBOVUxMKQorCXJldHVybjsKKyAgICBpbnN0LT5wc3ZpID0gY29tcDsKKyAgICBjb21wLT5pbnN0ID0gaW5zdDsKKworICAgIGNvbXAtPnNlbGVjdCA9IHhzbHRHZXRDTnNQcm9wKHN0eWxlLCBpbnN0LCAoY29uc3QgeG1sQ2hhciAqKSJzZWxlY3QiLAorCSAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRfTkFNRVNQQUNFKTsKKyAgICBpZiAoY29tcC0+c2VsZWN0ID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGluc3QsCisJCSJ4c2w6Zm9yLWVhY2ggOiBzZWxlY3QgaXMgbWlzc2luZ1xuIik7CisJaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKyAgICB9IGVsc2UgeworCWNvbXAtPmNvbXAgPSB4c2x0WFBhdGhDb21waWxlKHN0eWxlLCBjb21wLT5zZWxlY3QpOworCWlmIChjb21wLT5jb21wID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorICAgICAieHNsOmZvci1lYWNoIDogY291bGQgbm90IGNvbXBpbGUgc2VsZWN0IGV4cHJlc3Npb24gJyVzJ1xuIiwKKwkJCSAgICAgY29tcC0+c2VsZWN0KTsKKwkgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKwl9CisgICAgfQorICAgIC8qIFRPRE86IGhhbmRsZSBhbmQgc2tpcCB0aGUgeHNsOnNvcnQgKi8KK30KKworLyoqCisgKiB4c2x0VmFyaWFibGVDb21wOgorICogQHN0eWxlOiBhbiBYU0xUIGNvbXBpbGVkIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIHhzbHQgdmFyaWFibGUgbm9kZQorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgdmFyaWFibGUgbm9kZSBvbiB0aGUgc291cmNlIG5vZGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRWYXJpYWJsZUNvbXAoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgaW5zdCkgeworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1WYXJpYWJsZVB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkpCisJcmV0dXJuOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgY29tcCA9ICh4c2x0U3R5bGVJdGVtVmFyaWFibGVQdHIpCisJeHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX1ZBUklBQkxFKTsKKyNlbHNlCisgICAgY29tcCA9IHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19WQVJJQUJMRSk7CisjZW5kaWYKKworICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworCisgICAgaW5zdC0+cHN2aSA9IGNvbXA7CisgICAgY29tcC0+aW5zdCA9IGluc3Q7CisgICAgLyoKKyAgICAgKiBUaGUgZnVsbCB0ZW1wbGF0ZSByZXNvbHV0aW9uIGNhbiBiZSBkb25lIHN0YXRpY2FsbHkKKyAgICAgKi8KKworICAgIC8qCisgICAgKiBBdHRyaWJ1dGUgIm5hbWUiLgorICAgICovCisgICAgeHNsdEdldFFOYW1lUHJvcGVydHkoc3R5bGUsIGluc3QsIEJBRF9DQVNUICJuYW1lIiwKKwkxLCAmKGNvbXAtPmhhc19uYW1lKSwgJihjb21wLT5ucyksICYoY29tcC0+bmFtZSkpOworICAgIGlmIChjb21wLT5ucykKKwljb21wLT5oYXNfbnMgPSAxOyAgICAKKyAgICAvKgorICAgICogQXR0cmlidXRlICJzZWxlY3QiLgorICAgICovCisgICAgY29tcC0+c2VsZWN0ID0geHNsdEdldENOc1Byb3Aoc3R5bGUsIGluc3QsIChjb25zdCB4bWxDaGFyICopInNlbGVjdCIsCisJICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UpOworICAgIGlmIChjb21wLT5zZWxlY3QgIT0gTlVMTCkgeworCWNvbXAtPmNvbXAgPSB4c2x0WFBhdGhDb21waWxlKHN0eWxlLCBjb21wLT5zZWxlY3QpOworCWlmIChjb21wLT5jb21wID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkiWFNMVC12YXJpYWJsZTogRmFpbGVkIHRvIGNvbXBpbGUgdGhlIFhQYXRoIGV4cHJlc3Npb24gJyVzJy5cbiIsCisJCWNvbXAtPnNlbGVjdCk7CisJICAgIHN0eWxlLT5lcnJvcnMrKzsKKwl9CisJaWYgKGluc3QtPmNoaWxkcmVuICE9IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkiWFNMVC12YXJpYWJsZTogVGhlIG11c3QgYmUgbm8gY2hpbGQgbm9kZXMsIHNpbmNlIHRoZSAiCisJCSJhdHRyaWJ1dGUgJ3NlbGVjdCcgd2FzIHNwZWNpZmllZC5cbiIpOworCSAgICBzdHlsZS0+ZXJyb3JzKys7CisJfQorICAgIH0KK30KKworLyoqCisgKiB4c2x0UGFyYW1Db21wOgorICogQHN0eWxlOiBhbiBYU0xUIGNvbXBpbGVkIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIHhzbHQgcGFyYW0gbm9kZQorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgcGFyYW0gbm9kZSBvbiB0aGUgc291cmNlIG5vZGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRQYXJhbUNvbXAoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgaW5zdCkgeworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1QYXJhbVB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkpCisJcmV0dXJuOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgY29tcCA9ICh4c2x0U3R5bGVJdGVtUGFyYW1QdHIpCisJeHNsdE5ld1N0eWxlUHJlQ29tcChzdHlsZSwgWFNMVF9GVU5DX1BBUkFNKTsKKyNlbHNlCisgICAgY29tcCA9IHhzbHROZXdTdHlsZVByZUNvbXAoc3R5bGUsIFhTTFRfRlVOQ19QQVJBTSk7CisjZW5kaWYKKworICAgIGlmIChjb21wID09IE5VTEwpCisJcmV0dXJuOworICAgIGluc3QtPnBzdmkgPSBjb21wOworICAgIGNvbXAtPmluc3QgPSBpbnN0OworCisgICAgLyoKKyAgICAgKiBBdHRyaWJ1dGUgIm5hbWUiLgorICAgICAqLworICAgIHhzbHRHZXRRTmFtZVByb3BlcnR5KHN0eWxlLCBpbnN0LCBCQURfQ0FTVCAibmFtZSIsCisJMSwgJihjb21wLT5oYXNfbmFtZSksICYoY29tcC0+bnMpLCAmKGNvbXAtPm5hbWUpKTsKKyAgICBpZiAoY29tcC0+bnMpCisJY29tcC0+aGFzX25zID0gMTsKKyAgICAvKgorICAgICogQXR0cmlidXRlICJzZWxlY3QiLgorICAgICovCisgICAgY29tcC0+c2VsZWN0ID0geHNsdEdldENOc1Byb3Aoc3R5bGUsIGluc3QsIChjb25zdCB4bWxDaGFyICopInNlbGVjdCIsCisJICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UpOworICAgIGlmIChjb21wLT5zZWxlY3QgIT0gTlVMTCkgeworCWNvbXAtPmNvbXAgPSB4c2x0WFBhdGhDb21waWxlKHN0eWxlLCBjb21wLT5zZWxlY3QpOworCWlmIChjb21wLT5jb21wID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkiWFNMVC1wYXJhbTogY291bGQgbm90IGNvbXBpbGUgc2VsZWN0IGV4cHJlc3Npb24gJyVzJy5cbiIsCisJCWNvbXAtPnNlbGVjdCk7CisJICAgIHN0eWxlLT5lcnJvcnMrKzsKKwl9CisJaWYgKGluc3QtPmNoaWxkcmVuICE9IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBpbnN0LAorCQkiWFNMVC1wYXJhbTogVGhlIGNvbnRlbnQgc2hvdWxkIGJlIGVtcHR5IHNpbmNlIHRoZSAiCisJCSJhdHRyaWJ1dGUgJ3NlbGVjdCcgaXMgcHJlc2VudC5cbiIpOworCSAgICBzdHlsZS0+d2FybmluZ3MrKzsKKwl9CisgICAgfQorfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkgICAgR2VuZXJpYyBpbnRlcmZhY2UJCQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0RnJlZVN0eWxlUHJlQ29tcHM6CisgKiBAc3R5bGU6ICBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGJ5IGFsbCBwcmVjb21wdXRlZCBibG9ja3MKKyAqLwordm9pZAoreHNsdEZyZWVTdHlsZVByZUNvbXBzKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKSB7CisgICAgeHNsdEVsZW1QcmVDb21wUHRyIGN1ciwgbmV4dDsKKworICAgIGlmIChzdHlsZSA9PSBOVUxMKQorCXJldHVybjsgICAgICAgIAorICAgIAorICAgIGN1ciA9IHN0eWxlLT5wcmVDb21wczsKKyAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKKwluZXh0ID0gY3VyLT5uZXh0OwkJCisJaWYgKGN1ci0+dHlwZSA9PSBYU0xUX0ZVTkNfRVhURU5TSU9OKQorCSAgICBjdXItPmZyZWUoY3VyKTsKKwllbHNlCisJICAgIHhzbHRGcmVlU3R5bGVQcmVDb21wKCh4c2x0U3R5bGVQcmVDb21wUHRyKSBjdXIpOworCWN1ciA9IG5leHQ7CisgICAgfQorfQorCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisKKy8qKgorICogeHNsdFN0eWxlUHJlQ29tcHV0ZToKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBub2RlOiAgdGhlIGVsZW1lbnQgaW4gdGhlIFhTTFQgbmFtZXNwYWNlCisgKgorICogUHJlY29tcHV0ZSBhbiBYU0xUIGVsZW1lbnQuCisgKiBUaGlzIGV4cGVjdHMgdGhlIHR5cGUgb2YgdGhlIGVsZW1lbnQgdG8gYmUgYWxyZWFkeQorICogc2V0IGluIHN0eWxlLT5jb21wQ3R4dC0+aW5vZGUtPnR5cGU7CisgKi8KK3ZvaWQKK3hzbHRTdHlsZVByZUNvbXB1dGUoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgbm9kZSkgeworICAgIC8qICAgIAorICAgICogVGhlIHhzbHRYU0xURWxlbU1hcmtlciBtYXJrZXIgd2FzIHNldCBiZWZvcmVoYW5kIGJ5CisgICAgKiAgdGhlIHBhcnNpbmcgbWVjaGFuaXNtIGZvciBhbGwgZWxlbWVudHMgaW4gdGhlIFhTTFQgbmFtZXNwYWNlLgorICAgICovCisgICAgaWYgKHN0eWxlID09IE5VTEwpIHsKKwlpZiAobm9kZSAhPSBOVUxMKQorCSAgICBub2RlLT5wc3ZpID0gTlVMTDsKKwlyZXR1cm47CisgICAgfQorICAgIGlmIChub2RlID09IE5VTEwpCisJcmV0dXJuOworICAgIGlmICghIElTX1hTTFRfRUxFTV9GQVNUKG5vZGUpKQorCXJldHVybjsKKworICAgIG5vZGUtPnBzdmkgPSBOVUxMOworICAgIGlmIChYU0xUX0NDVFhUKHN0eWxlKS0+aW5vZGUtPnR5cGUgIT0gMCkgeworCXN3aXRjaCAoWFNMVF9DQ1RYVChzdHlsZSktPmlub2RlLT50eXBlKSB7CisJICAgIGNhc2UgWFNMVF9GVU5DX0FQUExZVEVNUExBVEVTOgorCQl4c2x0QXBwbHlUZW1wbGF0ZXNDb21wKHN0eWxlLCBub2RlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWFNMVF9GVU5DX1dJVEhQQVJBTToJCQkgICAKKwkJeHNsdFdpdGhQYXJhbUNvbXAoc3R5bGUsIG5vZGUpOworCQlicmVhazsKKwkgICAgY2FzZSBYU0xUX0ZVTkNfVkFMVUVPRjoJICAgIAorCQl4c2x0VmFsdWVPZkNvbXAoc3R5bGUsIG5vZGUpOworCQlicmVhazsKKwkgICAgY2FzZSBYU0xUX0ZVTkNfQ09QWToJICAgIAorCQl4c2x0Q29weUNvbXAoc3R5bGUsIG5vZGUpOworCQlicmVhazsKKwkgICAgY2FzZSBYU0xUX0ZVTkNfQ09QWU9GOgorCQl4c2x0Q29weU9mQ29tcChzdHlsZSwgbm9kZSk7CisJCWJyZWFrOworCSAgICBjYXNlIFhTTFRfRlVOQ19JRjoJICAgIAorCQl4c2x0SWZDb21wKHN0eWxlLCBub2RlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWFNMVF9GVU5DX0NIT09TRToJICAgIAorCQl4c2x0Q2hvb3NlQ29tcChzdHlsZSwgbm9kZSk7CisJCWJyZWFrOworCSAgICBjYXNlIFhTTFRfRlVOQ19XSEVOOgkgICAgCisJCXhzbHRXaGVuQ29tcChzdHlsZSwgbm9kZSk7CisJCWJyZWFrOworCSAgICBjYXNlIFhTTFRfRlVOQ19PVEhFUldJU0U6CSAgICAKKwkJLyogTk9QIHlldCAqLworCQlyZXR1cm47CisJICAgIGNhc2UgWFNMVF9GVU5DX0ZPUkVBQ0g6CSAgICAKKwkJeHNsdEZvckVhY2hDb21wKHN0eWxlLCBub2RlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWFNMVF9GVU5DX0FQUExZSU1QT1JUUzoJICAgIAorCQl4c2x0QXBwbHlJbXBvcnRzQ29tcChzdHlsZSwgbm9kZSk7CisJCWJyZWFrOworCSAgICBjYXNlIFhTTFRfRlVOQ19BVFRSSUJVVEU6CSAgICAKKwkJeHNsdEF0dHJpYnV0ZUNvbXAoc3R5bGUsIG5vZGUpOworCQlicmVhazsKKwkgICAgY2FzZSBYU0xUX0ZVTkNfRUxFTUVOVDoJICAgIAorCQl4c2x0RWxlbWVudENvbXAoc3R5bGUsIG5vZGUpOworCQlicmVhazsKKwkgICAgY2FzZSBYU0xUX0ZVTkNfU09SVDoJICAgIAorCQl4c2x0U29ydENvbXAoc3R5bGUsIG5vZGUpOworCQlicmVhazsKKwkgICAgY2FzZSBYU0xUX0ZVTkNfQ09NTUVOVDoJICAgIAorCQl4c2x0Q29tbWVudENvbXAoc3R5bGUsIG5vZGUpOworCQlicmVhazsKKwkgICAgY2FzZSBYU0xUX0ZVTkNfTlVNQkVSOgkgICAgCisJCXhzbHROdW1iZXJDb21wKHN0eWxlLCBub2RlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWFNMVF9GVU5DX1BJOgkgICAgCisJCXhzbHRQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25Db21wKHN0eWxlLCBub2RlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWFNMVF9GVU5DX0NBTExURU1QTEFURToJICAgIAorCQl4c2x0Q2FsbFRlbXBsYXRlQ29tcChzdHlsZSwgbm9kZSk7CisJCWJyZWFrOworCSAgICBjYXNlIFhTTFRfRlVOQ19QQVJBTToJICAgIAorCQl4c2x0UGFyYW1Db21wKHN0eWxlLCBub2RlKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWFNMVF9GVU5DX1ZBUklBQkxFOgkgICAgCisJCXhzbHRWYXJpYWJsZUNvbXAoc3R5bGUsIG5vZGUpOworCQlicmVhazsKKwkgICAgY2FzZSBYU0xUX0ZVTkNfRkFMTEJBQ0s6CSAgICAKKwkJLyogTk9QIHlldCAqLworCQlyZXR1cm47CisJICAgIGNhc2UgWFNMVF9GVU5DX0RPQ1VNRU5UOgkgICAgCisJCS8qIFRoZSBleHRyYSBvbmUgKi8KKwkJbm9kZS0+cHN2aSA9ICh2b2lkICopIHhzbHREb2N1bWVudENvbXAoc3R5bGUsIG5vZGUsCisJCSAgICAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0RG9jdW1lbnRFbGVtKTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWFNMVF9GVU5DX01FU1NBR0U6CisJCS8qIE5PUCB5ZXQgKi8KKwkJcmV0dXJuOworCSAgICBkZWZhdWx0OgorCQkvKgorCQkqIE5PVEUgdGhhdCB4c2w6dGV4dCwgeHNsOnRlbXBsYXRlLCB4c2w6c3R5bGVzaGVldCwKKwkJKiAgeHNsOnRyYW5zZm9ybSwgeHNsOmltcG9ydCwgeHNsOmluY2x1ZGUgYXJlIG5vdCBleHBlY3RlZAorCQkqICB0byBiZSBoYW5kZWQgb3ZlciB0byB0aGlzIGZ1bmN0aW9uLgorCQkqLworCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIG5vZGUsCisJCSAgICAiSW50ZXJuYWwgZXJyb3I6ICh4c2x0U3R5bGVQcmVDb21wdXRlKSBjYW5ub3QgaGFuZGxlICIKKwkJICAgICJ0aGUgWFNMVCBlbGVtZW50ICclcycuXG4iLCBub2RlLT5uYW1lKTsKKwkJc3R5bGUtPmVycm9ycysrOworCQlyZXR1cm47CisJfQorICAgIH0gZWxzZSB7CisJLyoKKwkqIEZhbGxiYWNrIHRvIHN0cmluZyBjb21wYXJpc29uLgorCSovCQorCWlmIChJU19YU0xUX05BTUUobm9kZSwgImFwcGx5LXRlbXBsYXRlcyIpKSB7CisJICAgIHhzbHRBcHBseVRlbXBsYXRlc0NvbXAoc3R5bGUsIG5vZGUpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJ3aXRoLXBhcmFtIikpIHsKKwkgICAgeHNsdFdpdGhQYXJhbUNvbXAoc3R5bGUsIG5vZGUpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJ2YWx1ZS1vZiIpKSB7CisJICAgIHhzbHRWYWx1ZU9mQ29tcChzdHlsZSwgbm9kZSk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImNvcHkiKSkgeworCSAgICB4c2x0Q29weUNvbXAoc3R5bGUsIG5vZGUpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJjb3B5LW9mIikpIHsKKwkgICAgeHNsdENvcHlPZkNvbXAoc3R5bGUsIG5vZGUpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJpZiIpKSB7CisJICAgIHhzbHRJZkNvbXAoc3R5bGUsIG5vZGUpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJjaG9vc2UiKSkgeworCSAgICB4c2x0Q2hvb3NlQ29tcChzdHlsZSwgbm9kZSk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgIndoZW4iKSkgeworCSAgICB4c2x0V2hlbkNvbXAoc3R5bGUsIG5vZGUpOwkKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShub2RlLCAib3RoZXJ3aXNlIikpIHsKKwkgICAgLyogTk9QIHlldCAqLworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImZvci1lYWNoIikpIHsKKwkgICAgeHNsdEZvckVhY2hDb21wKHN0eWxlLCBub2RlKTsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShub2RlLCAiYXBwbHktaW1wb3J0cyIpKSB7CisJICAgIHhzbHRBcHBseUltcG9ydHNDb21wKHN0eWxlLCBub2RlKTsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShub2RlLCAiYXR0cmlidXRlIikpIHsKKwkgICAgeHNsdEF0dHJpYnV0ZUNvbXAoc3R5bGUsIG5vZGUpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJlbGVtZW50IikpIHsKKwkgICAgeHNsdEVsZW1lbnRDb21wKHN0eWxlLCBub2RlKTsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShub2RlLCAic29ydCIpKSB7CisJICAgIHhzbHRTb3J0Q29tcChzdHlsZSwgbm9kZSk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImNvbW1lbnQiKSkgeworCSAgICB4c2x0Q29tbWVudENvbXAoc3R5bGUsIG5vZGUpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJudW1iZXIiKSkgeworCSAgICB4c2x0TnVtYmVyQ29tcChzdHlsZSwgbm9kZSk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iKSkgeworCSAgICB4c2x0UHJvY2Vzc2luZ0luc3RydWN0aW9uQ29tcChzdHlsZSwgbm9kZSk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImNhbGwtdGVtcGxhdGUiKSkgeworCSAgICB4c2x0Q2FsbFRlbXBsYXRlQ29tcChzdHlsZSwgbm9kZSk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgInBhcmFtIikpIHsKKwkgICAgeHNsdFBhcmFtQ29tcChzdHlsZSwgbm9kZSk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgInZhcmlhYmxlIikpIHsKKwkgICAgeHNsdFZhcmlhYmxlQ29tcChzdHlsZSwgbm9kZSk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImZhbGxiYWNrIikpIHsKKwkgICAgLyogTk9QIHlldCAqLworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImRvY3VtZW50IikpIHsKKwkgICAgLyogVGhlIGV4dHJhIG9uZSAqLworCSAgICBub2RlLT5wc3ZpID0gKHZvaWQgKikgeHNsdERvY3VtZW50Q29tcChzdHlsZSwgbm9kZSwKKwkJKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdERvY3VtZW50RWxlbSk7CQorCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJvdXRwdXQiKSkgeworCSAgICAvKiBUb3AtbGV2ZWwgKi8KKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJwcmVzZXJ2ZS1zcGFjZSIpKSB7CisJICAgIC8qIFRvcC1sZXZlbCAqLworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgInN0cmlwLXNwYWNlIikpIHsKKwkgICAgLyogVG9wLWxldmVsICovCisJICAgIHJldHVybjsJCisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImtleSIpKSB7CisJICAgIC8qIFRvcC1sZXZlbCAqLworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgIm1lc3NhZ2UiKSkgeworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImF0dHJpYnV0ZS1zZXQiKSkgeworCSAgICAvKiBUb3AtbGV2ZWwgKi8KKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJuYW1lc3BhY2UtYWxpYXMiKSkgeworCSAgICAvKiBUb3AtbGV2ZWwgKi8KKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJkZWNpbWFsLWZvcm1hdCIpKSB7CisJICAgIC8qIFRvcC1sZXZlbCAqLworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImluY2x1ZGUiKSkgeworCSAgICAvKiBUb3AtbGV2ZWwgKi8JICAgIAkgICAgCisJfSBlbHNlIHsKKwkgICAgLyoKKwkgICAgKiBOT1RFIHRoYXQgeHNsOnRleHQsIHhzbDp0ZW1wbGF0ZSwgeHNsOnN0eWxlc2hlZXQsCisJICAgICogIHhzbDp0cmFuc2Zvcm0sIHhzbDppbXBvcnQsIHhzbDppbmNsdWRlIGFyZSBub3QgZXhwZWN0ZWQKKwkgICAgKiAgdG8gYmUgaGFuZGVkIG92ZXIgdG8gdGhpcyBmdW5jdGlvbi4KKwkgICAgKi8KKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBub2RlLAorCQkiSW50ZXJuYWwgZXJyb3I6ICh4c2x0U3R5bGVQcmVDb21wdXRlKSBjYW5ub3QgaGFuZGxlICIKKwkJInRoZSBYU0xUIGVsZW1lbnQgJyVzJy5cbiIsIG5vZGUtPm5hbWUpOworCQlzdHlsZS0+ZXJyb3JzKys7CisJICAgIHJldHVybjsKKwl9CQorICAgIH0KKyAgICAvKgorICAgICogQXNzaWduIHRoZSBjdXJyZW50IGxpc3Qgb2YgaW4tc2NvcGUgbmFtZXNwYWNlcyB0byB0aGUKKyAgICAqIGl0ZW0uIFRoaXMgaXMgbmVlZGVkIGZvciBYUGF0aCBleHByZXNzaW9ucy4KKyAgICAqLworICAgIGlmIChub2RlLT5wc3ZpICE9IE5VTEwpIHsKKwkoKHhzbHRTdHlsZVByZUNvbXBQdHIpIG5vZGUtPnBzdmkpLT5pblNjb3BlTnMgPQorCSAgICBYU0xUX0NDVFhUKHN0eWxlKS0+aW5vZGUtPmluU2NvcGVOczsKKyAgICB9Cit9CisKKyNlbHNlCisKKy8qKgorICogeHNsdFN0eWxlUHJlQ29tcHV0ZToKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIGluc3RydWN0aW9uIGluIHRoZSBzdHlsZXNoZWV0CisgKgorICogUHJlY29tcHV0ZSBhbiBYU0xUIHN0eWxlc2hlZXQgZWxlbWVudAorICovCit2b2lkCit4c2x0U3R5bGVQcmVDb21wdXRlKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QpIHsKKyAgICAvKgorICAgICogVVJHRU5UIFRPRE86IE5vcm1hbGx5IGluc3QtPnBzdmkgU2hvdWxkIG5ldmVyIGJlIHJlc2VydmVkIGhlcmUsCisgICAgKiAgIEJVVDogc2luY2UgaWYgd2UgaW5jbHVkZSB0aGUgc2FtZSBzdHlsZXNoZWV0IGZyb20KKyAgICAqICAgbXVsdGlwbGUgaW1wb3J0cywgdGhlbiB0aGUgc3R5bGVzaGVldCB3aWxsIGJlIHBhcnNlZAorICAgICogICBhZ2Fpbi4gV2Ugc2ltcGx5IG11c3Qgbm90IHRyeSB0byBjb21wdXRlIHRoZSBzdHlsZXNoZWV0IGFnYWluLgorICAgICogVE9ETzogR2V0IHRvIHRoZSBwb2ludCB3aGVyZSB3ZSBkb24ndCBuZWVkIHRvIHF1ZXJ5IHRoZQorICAgICogICBuYW1lc3BhY2UtIGFuZCBsb2NhbC1uYW1lIG9mIHRoZSBub2RlLCBidXQgY2FuIGV2YWx1YXRlIHRoaXMKKyAgICAqICAgdXNpbmcgY2N0eHQtPnN0eWxlLT5pbm9kZS0+Y2F0ZWdvcnk7CisgICAgKi8KKyAgICBpZiAoaW5zdC0+cHN2aSAhPSBOVUxMKQorCXJldHVybjsKKworICAgIGlmIChJU19YU0xUX0VMRU0oaW5zdCkpIHsKKwl4c2x0U3R5bGVQcmVDb21wUHRyIGN1cjsKKworCWlmIChJU19YU0xUX05BTUUoaW5zdCwgImFwcGx5LXRlbXBsYXRlcyIpKSB7CisJICAgIHhzbHRDaGVja0luc3RydWN0aW9uRWxlbWVudChzdHlsZSwgaW5zdCk7CisJICAgIHhzbHRBcHBseVRlbXBsYXRlc0NvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJ3aXRoLXBhcmFtIikpIHsKKwkgICAgeHNsdENoZWNrUGFyZW50RWxlbWVudChzdHlsZSwgaW5zdCwgQkFEX0NBU1QgImFwcGx5LXRlbXBsYXRlcyIsCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgQkFEX0NBU1QgImNhbGwtdGVtcGxhdGUiKTsKKwkgICAgeHNsdFdpdGhQYXJhbUNvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJ2YWx1ZS1vZiIpKSB7CisJICAgIHhzbHRDaGVja0luc3RydWN0aW9uRWxlbWVudChzdHlsZSwgaW5zdCk7CisJICAgIHhzbHRWYWx1ZU9mQ29tcChzdHlsZSwgaW5zdCk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoaW5zdCwgImNvcHkiKSkgeworCSAgICB4c2x0Q2hlY2tJbnN0cnVjdGlvbkVsZW1lbnQoc3R5bGUsIGluc3QpOworCSAgICB4c2x0Q29weUNvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJjb3B5LW9mIikpIHsKKwkgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgeHNsdENvcHlPZkNvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJpZiIpKSB7CisJICAgIHhzbHRDaGVja0luc3RydWN0aW9uRWxlbWVudChzdHlsZSwgaW5zdCk7CisJICAgIHhzbHRJZkNvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJ3aGVuIikpIHsKKwkgICAgeHNsdENoZWNrUGFyZW50RWxlbWVudChzdHlsZSwgaW5zdCwgQkFEX0NBU1QgImNob29zZSIsIE5VTEwpOworCSAgICB4c2x0V2hlbkNvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJjaG9vc2UiKSkgeworCSAgICB4c2x0Q2hlY2tJbnN0cnVjdGlvbkVsZW1lbnQoc3R5bGUsIGluc3QpOworCSAgICB4c2x0Q2hvb3NlQ29tcChzdHlsZSwgaW5zdCk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoaW5zdCwgImZvci1lYWNoIikpIHsKKwkgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgeHNsdEZvckVhY2hDb21wKHN0eWxlLCBpbnN0KTsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShpbnN0LCAiYXBwbHktaW1wb3J0cyIpKSB7CisJICAgIHhzbHRDaGVja0luc3RydWN0aW9uRWxlbWVudChzdHlsZSwgaW5zdCk7CisJICAgIHhzbHRBcHBseUltcG9ydHNDb21wKHN0eWxlLCBpbnN0KTsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShpbnN0LCAiYXR0cmlidXRlIikpIHsKKwkgICAgeG1sTm9kZVB0ciBwYXJlbnQgPSBpbnN0LT5wYXJlbnQ7CisKKwkgICAgaWYgKChwYXJlbnQgPT0gTlVMTCkgfHwgKHBhcmVudC0+bnMgPT0gTlVMTCkgfHwKKwkJKChwYXJlbnQtPm5zICE9IGluc3QtPm5zKSAmJgorCQkgKCF4bWxTdHJFcXVhbChwYXJlbnQtPm5zLT5ocmVmLCBpbnN0LT5ucy0+aHJlZikpKSB8fAorCQkoIXhtbFN0ckVxdWFsKHBhcmVudC0+bmFtZSwgQkFEX0NBU1QgImF0dHJpYnV0ZS1zZXQiKSkpIHsKKwkJeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgfQorCSAgICB4c2x0QXR0cmlidXRlQ29tcChzdHlsZSwgaW5zdCk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoaW5zdCwgImVsZW1lbnQiKSkgeworCSAgICB4c2x0Q2hlY2tJbnN0cnVjdGlvbkVsZW1lbnQoc3R5bGUsIGluc3QpOworCSAgICB4c2x0RWxlbWVudENvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJ0ZXh0IikpIHsKKwkgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgeHNsdFRleHRDb21wKHN0eWxlLCBpbnN0KTsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShpbnN0LCAic29ydCIpKSB7CisJICAgIHhzbHRDaGVja1BhcmVudEVsZW1lbnQoc3R5bGUsIGluc3QsIEJBRF9DQVNUICJhcHBseS10ZW1wbGF0ZXMiLAorCSAgICAgICAgICAgICAgICAgICAgICAgICAgIEJBRF9DQVNUICJmb3ItZWFjaCIpOworCSAgICB4c2x0U29ydENvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJjb21tZW50IikpIHsKKwkgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgeHNsdENvbW1lbnRDb21wKHN0eWxlLCBpbnN0KTsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShpbnN0LCAibnVtYmVyIikpIHsKKwkgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgeHNsdE51bWJlckNvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIikpIHsKKwkgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgeHNsdFByb2Nlc3NpbmdJbnN0cnVjdGlvbkNvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJjYWxsLXRlbXBsYXRlIikpIHsKKwkgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgeHNsdENhbGxUZW1wbGF0ZUNvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJwYXJhbSIpKSB7CSAgIAorCSAgICBpZiAoeHNsdENoZWNrVG9wTGV2ZWxFbGVtZW50KHN0eWxlLCBpbnN0LCAwKSA9PSAwKQorCSAgICAgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgeHNsdFBhcmFtQ29tcChzdHlsZSwgaW5zdCk7CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoaW5zdCwgInZhcmlhYmxlIikpIHsKKwkgICAgaWYgKHhzbHRDaGVja1RvcExldmVsRWxlbWVudChzdHlsZSwgaW5zdCwgMCkgPT0gMCkKKwkgICAgICAgIHhzbHRDaGVja0luc3RydWN0aW9uRWxlbWVudChzdHlsZSwgaW5zdCk7CisJICAgIHhzbHRWYXJpYWJsZUNvbXAoc3R5bGUsIGluc3QpOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJvdGhlcndpc2UiKSkgeworCSAgICB4c2x0Q2hlY2tQYXJlbnRFbGVtZW50KHN0eWxlLCBpbnN0LCBCQURfQ0FTVCAiY2hvb3NlIiwgTlVMTCk7CisJICAgIHhzbHRDaGVja0luc3RydWN0aW9uRWxlbWVudChzdHlsZSwgaW5zdCk7CisJICAgIHJldHVybjsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShpbnN0LCAidGVtcGxhdGUiKSkgeworCSAgICB4c2x0Q2hlY2tUb3BMZXZlbEVsZW1lbnQoc3R5bGUsIGluc3QsIDEpOworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoaW5zdCwgIm91dHB1dCIpKSB7CisJICAgIHhzbHRDaGVja1RvcExldmVsRWxlbWVudChzdHlsZSwgaW5zdCwgMSk7CisJICAgIHJldHVybjsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShpbnN0LCAicHJlc2VydmUtc3BhY2UiKSkgeworCSAgICB4c2x0Q2hlY2tUb3BMZXZlbEVsZW1lbnQoc3R5bGUsIGluc3QsIDEpOworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoaW5zdCwgInN0cmlwLXNwYWNlIikpIHsKKwkgICAgeHNsdENoZWNrVG9wTGV2ZWxFbGVtZW50KHN0eWxlLCBpbnN0LCAxKTsKKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoKElTX1hTTFRfTkFNRShpbnN0LCAic3R5bGVzaGVldCIpKSB8fAorCSAgICAgICAgICAgKElTX1hTTFRfTkFNRShpbnN0LCAidHJhbnNmb3JtIikpKSB7CisJICAgIHhtbE5vZGVQdHIgcGFyZW50ID0gaW5zdC0+cGFyZW50OworCisJICAgIGlmICgocGFyZW50ID09IE5VTEwpIHx8IChwYXJlbnQtPnR5cGUgIT0gWE1MX0RPQ1VNRU5UX05PREUpKSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkJICAgICJlbGVtZW50ICVzIG9ubHkgYWxsb3dlZCBvbmx5IGFzIHJvb3QgZWxlbWVudFxuIiwKKwkJCQkgICBpbnN0LT5uYW1lKTsKKwkJc3R5bGUtPmVycm9ycysrOworCSAgICB9CisJICAgIHJldHVybjsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShpbnN0LCAia2V5IikpIHsKKwkgICAgeHNsdENoZWNrVG9wTGV2ZWxFbGVtZW50KHN0eWxlLCBpbnN0LCAxKTsKKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJtZXNzYWdlIikpIHsKKwkgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJhdHRyaWJ1dGUtc2V0IikpIHsKKwkgICAgeHNsdENoZWNrVG9wTGV2ZWxFbGVtZW50KHN0eWxlLCBpbnN0LCAxKTsKKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJuYW1lc3BhY2UtYWxpYXMiKSkgeworCSAgICB4c2x0Q2hlY2tUb3BMZXZlbEVsZW1lbnQoc3R5bGUsIGluc3QsIDEpOworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoaW5zdCwgImluY2x1ZGUiKSkgeworCSAgICB4c2x0Q2hlY2tUb3BMZXZlbEVsZW1lbnQoc3R5bGUsIGluc3QsIDEpOworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoaW5zdCwgImltcG9ydCIpKSB7CisJICAgIHhzbHRDaGVja1RvcExldmVsRWxlbWVudChzdHlsZSwgaW5zdCwgMSk7CisJICAgIHJldHVybjsKKwl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShpbnN0LCAiZGVjaW1hbC1mb3JtYXQiKSkgeworCSAgICB4c2x0Q2hlY2tUb3BMZXZlbEVsZW1lbnQoc3R5bGUsIGluc3QsIDEpOworCSAgICByZXR1cm47CisJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoaW5zdCwgImZhbGxiYWNrIikpIHsKKwkgICAgeHNsdENoZWNrSW5zdHJ1Y3Rpb25FbGVtZW50KHN0eWxlLCBpbnN0KTsKKwkgICAgcmV0dXJuOworCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGluc3QsICJkb2N1bWVudCIpKSB7CisJICAgIHhzbHRDaGVja0luc3RydWN0aW9uRWxlbWVudChzdHlsZSwgaW5zdCk7CisJICAgIGluc3QtPnBzdmkgPSAodm9pZCAqKSB4c2x0RG9jdW1lbnRDb21wKHN0eWxlLCBpbnN0LAorCQkJCSh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHREb2N1bWVudEVsZW0pOworCX0gZWxzZSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgaW5zdCwKKwkJICJ4c2x0U3R5bGVQcmVDb21wdXRlOiB1bmtub3duIHhzbDolc1xuIiwgaW5zdC0+bmFtZSk7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKwl9CisJCisJY3VyID0gKHhzbHRTdHlsZVByZUNvbXBQdHIpIGluc3QtPnBzdmk7CisJLyoKKwkqIEEgbnMtbGlzdCBpcyBidWlsZCBmb3IgZXZlcnkgWFNMVCBpdGVtIGluIHRoZQorCSogbm9kZS10cmVlLiBUaGlzIGlzIG5lZWRlZCBmb3IgWFBhdGggZXhwcmVzc2lvbnMuCisJKi8KKwlpZiAoY3VyICE9IE5VTEwpIHsKKwkgICAgaW50IGkgPSAwOworCisJICAgIGN1ci0+bnNMaXN0ID0geG1sR2V0TnNMaXN0KGluc3QtPmRvYywgaW5zdCk7CisgICAgICAgICAgICBpZiAoY3VyLT5uc0xpc3QgIT0gTlVMTCkgeworCQl3aGlsZSAoY3VyLT5uc0xpc3RbaV0gIT0gTlVMTCkKKwkJICAgIGkrKzsKKwkgICAgfQorCSAgICBjdXItPm5zTnIgPSBpOworCX0KKyAgICB9IGVsc2UgeworCWluc3QtPnBzdmkgPQorCSAgICAodm9pZCAqKSB4c2x0UHJlQ29tcHV0ZUV4dE1vZHVsZUVsZW1lbnQoc3R5bGUsIGluc3QpOworCisJLyoKKwkgKiBVbmtub3duIGVsZW1lbnQsIG1heWJlIHJlZ2lzdGVyZWQgYXQgdGhlIGNvbnRleHQKKwkgKiBsZXZlbC4gTWFyayBpdCBmb3IgbGF0ZXIgcmVjb2duaXRpb24uCisJICovCisJaWYgKGluc3QtPnBzdmkgPT0gTlVMTCkKKwkgICAgaW5zdC0+cHN2aSA9ICh2b2lkICopIHhzbHRFeHRNYXJrZXI7CisgICAgfQorfQorI2VuZGlmIC8qIFhTTFRfUkVGQUNUT1JFRCAqLwpkaWZmIC0tZ2l0IGEvbGlieHNsdC9wcmVwcm9jLmggYi9saWJ4c2x0L3ByZXByb2MuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjdiMzg5Ci0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9wcmVwcm9jLmgKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIFN1bW1hcnk6IHByZWNvbXB1dGluZyBzdHlsZXNoZWV0cworICogRGVzY3JpcHRpb246IHRoaXMgaXMgdGhlIGNvbXBpbGF0aW9uIHBoYXNlLCB3aGVyZSBtb3N0IG9mIHRoZQorICogICAgICAgICAgICAgIHN0eWxlc2hlZXQgaXMgImNvbXBpbGVkIiBpbnRvIGZhc3RlciB0byB1c2UgZGF0YS4KKyAqCisgKiBDb3B5OiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCisgKgorICogQXV0aG9yOiBEYW5pZWwgVmVpbGxhcmQKKyAqLworCisjaWZuZGVmIF9fWE1MX1hTTFRfUFJFQ09NUF9IX18KKyNkZWZpbmUgX19YTUxfWFNMVF9QUkVDT01QX0hfXworCisjaW5jbHVkZSA8bGlieG1sL3RyZWUuaD4KKyNpbmNsdWRlICJ4c2x0ZXhwb3J0cy5oIgorI2luY2x1ZGUgInhzbHRJbnRlcm5hbHMuaCIKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvKgorICogSW50ZXJmYWNlcworICovCitleHRlcm4gY29uc3QgeG1sQ2hhciAqeHNsdEV4dE1hcmtlcjsKKworWFNMVFBVQkZVTiB4c2x0RWxlbVByZUNvbXBQdHIgWFNMVENBTEwgCisJCXhzbHREb2N1bWVudENvbXAJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgeG1sTm9kZVB0ciBpbnN0LAorCQkJCQkgeHNsdFRyYW5zZm9ybUZ1bmN0aW9uIGZ1bmN0aW9uKTsKKworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkKKwkJeHNsdFN0eWxlUHJlQ29tcHV0ZQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkKKwkJeHNsdEZyZWVTdHlsZVByZUNvbXBzCSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSk7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX1BSRUNPTVBfSF9fICovCisKZGlmZiAtLWdpdCBhL2xpYnhzbHQvc2VjdXJpdHkuYyBiL2xpYnhzbHQvc2VjdXJpdHkuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzY2Y2Y3Ci0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9zZWN1cml0eS5jCkBAIC0wLDAgKzEsNDgwIEBACisvKgorICogc2VjdXJpdHkuYzogSW1wbGVtZW50YXRpb24gb2YgdGhlIFhTTFQgc2VjdXJpdHkgZnJhbWV3b3JrCisgKgorICogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIGRhbmllbEB2ZWlsbGFyZC5jb20KKyAqLworCisjZGVmaW5lIElOX0xJQlhTTFQKKyNpbmNsdWRlICJsaWJ4c2x0LmgiCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2lmZGVmIEhBVkVfU1lTX1RZUEVTX0gKKyNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfU1lTX1NUQVRfSAorI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CisjZW5kaWYKKworI2lmZGVmIEhBVkVfTUFUSF9ICisjaW5jbHVkZSA8bWF0aC5oPgorI2VuZGlmCisjaWZkZWYgSEFWRV9GTE9BVF9ICisjaW5jbHVkZSA8ZmxvYXQuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfSUVFRUZQX0gKKyNpbmNsdWRlIDxpZWVlZnAuaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfTkFOX0gKKyNpbmNsdWRlIDxuYW4uaD4KKyNlbmRpZgorI2lmZGVmIEhBVkVfQ1RZUEVfSAorI2luY2x1ZGUgPGN0eXBlLmg+CisjZW5kaWYKKworI2lmIGRlZmluZWQoV0lOMzIpICYmICFkZWZpbmVkKF9fQ1lHV0lOX18pCisjaW5jbHVkZSA8d2luZG93cy5oPgorI2lmbmRlZiBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUworI2RlZmluZSBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUyAoKERXT1JEKS0xKQorI2VuZGlmCisjZW5kaWYKKworI2lmbmRlZiBIQVZFX1NUQVQKKyMgIGlmZGVmIEhBVkVfX1NUQVQKKyAgICAgLyogTVMgQyBsaWJyYXJ5IHNlZW1zIHRvIGRlZmluZSBzdGF0IGFuZCBfc3RhdC4gVGhlIGRlZmluaXRpb24KKyAgICAgICogICAgICAgICBpcyBpZGVudGljYWwuIFN0aWxsLCBtYXBwaW5nIHRoZW0gdG8gZWFjaCBvdGhlciBjYXVzZXMgYSB3YXJuaW5nLiAqLworIyAgICBpZm5kZWYgX01TQ19WRVIKKyMgICAgICBkZWZpbmUgc3RhdCh4LHkpIF9zdGF0KHgseSkKKyMgICAgZW5kaWYKKyMgICAgZGVmaW5lIEhBVkVfU1RBVAorIyAgZW5kaWYKKyNlbmRpZgorCisjaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgorI2luY2x1ZGUgPGxpYnhtbC90cmVlLmg+CisjaW5jbHVkZSA8bGlieG1sL3VyaS5oPgorI2luY2x1ZGUgInhzbHQuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisjaW5jbHVkZSAieHNsdHV0aWxzLmgiCisjaW5jbHVkZSAiZXh0ZW5zaW9ucy5oIgorI2luY2x1ZGUgInNlY3VyaXR5LmgiCisKKworc3RydWN0IF94c2x0U2VjdXJpdHlQcmVmcyB7CisgICAgeHNsdFNlY3VyaXR5Q2hlY2sgcmVhZEZpbGU7CisgICAgeHNsdFNlY3VyaXR5Q2hlY2sgY3JlYXRlRmlsZTsKKyAgICB4c2x0U2VjdXJpdHlDaGVjayBjcmVhdGVEaXI7CisgICAgeHNsdFNlY3VyaXR5Q2hlY2sgcmVhZE5ldDsKKyAgICB4c2x0U2VjdXJpdHlDaGVjayB3cml0ZU5ldDsKK307CisKK3N0YXRpYyB4c2x0U2VjdXJpdHlQcmVmc1B0ciB4c2x0RGVmYXVsdFNlY3VyaXR5UHJlZnMgPSBOVUxMOworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkJTW9kdWxlIGludGVyZmFjZXMJCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHROZXdTZWN1cml0eVByZWZzOgorICoKKyAqIENyZWF0ZSBhIG5ldyBzZWN1cml0eSBwcmVmZXJlbmNlIGJsb2NrCisgKgorICogUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIG5ldyBibG9jayBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworeHNsdFNlY3VyaXR5UHJlZnNQdHIKK3hzbHROZXdTZWN1cml0eVByZWZzKHZvaWQpIHsKKyAgICB4c2x0U2VjdXJpdHlQcmVmc1B0ciByZXQ7CisKKyAgICB4c2x0SW5pdEdsb2JhbHMoKTsKKworICAgIHJldCA9ICh4c2x0U2VjdXJpdHlQcmVmc1B0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0U2VjdXJpdHlQcmVmcykpOworICAgIGlmIChyZXQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkieHNsdE5ld1NlY3VyaXR5UHJlZnMgOiBtYWxsb2MgZmFpbGVkXG4iKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4c2x0U2VjdXJpdHlQcmVmcykpOworICAgIHJldHVybihyZXQpOworfQorCisvKioKKyAqIHhzbHRGcmVlU2VjdXJpdHlQcmVmczoKKyAqIEBzZWM6ICB0aGUgc2VjdXJpdHkgYmxvY2sgdG8gZnJlZQorICoKKyAqIEZyZWUgdXAgYSBzZWN1cml0eSBwcmVmZXJlbmNlIGJsb2NrCisgKi8KK3ZvaWQKK3hzbHRGcmVlU2VjdXJpdHlQcmVmcyh4c2x0U2VjdXJpdHlQcmVmc1B0ciBzZWMpIHsKKyAgICBpZiAoc2VjID09IE5VTEwpCisJcmV0dXJuOworICAgIHhtbEZyZWUoc2VjKTsKK30KKworLyoqCisgKiB4c2x0U2V0U2VjdXJpdHlQcmVmczoKKyAqIEBzZWM6ICB0aGUgc2VjdXJpdHkgYmxvY2sgdG8gdXBkYXRlCisgKiBAb3B0aW9uOiAgdGhlIG9wdGlvbiB0byB1cGRhdGUKKyAqIEBmdW5jOiAgdGhlIHVzZXIgY2FsbGJhY2sgdG8gdXNlIGZvciB0aGlzIG9wdGlvbgorICoKKyAqIFVwZGF0ZSB0aGUgc2VjdXJpdHkgb3B0aW9uIHRvIHVzZSB0aGUgbmV3IGNhbGxiYWNrIGNoZWNraW5nIGZ1bmN0aW9uCisgKgorICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIG90aGVyd2lzZQorICovCitpbnQKK3hzbHRTZXRTZWN1cml0eVByZWZzKHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYywgeHNsdFNlY3VyaXR5T3B0aW9uIG9wdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgIHhzbHRTZWN1cml0eUNoZWNrIGZ1bmMpIHsKKyAgICB4c2x0SW5pdEdsb2JhbHMoKTsKKyAgICBpZiAoc2VjID09IE5VTEwpCisJcmV0dXJuKC0xKTsKKyAgICBzd2l0Y2ggKG9wdGlvbikgeworICAgICAgICBjYXNlIFhTTFRfU0VDUFJFRl9SRUFEX0ZJTEU6CisgICAgICAgICAgICBzZWMtPnJlYWRGaWxlID0gZnVuYzsgcmV0dXJuKDApOworICAgICAgICBjYXNlIFhTTFRfU0VDUFJFRl9XUklURV9GSUxFOgorICAgICAgICAgICAgc2VjLT5jcmVhdGVGaWxlID0gZnVuYzsgcmV0dXJuKDApOworICAgICAgICBjYXNlIFhTTFRfU0VDUFJFRl9DUkVBVEVfRElSRUNUT1JZOgorICAgICAgICAgICAgc2VjLT5jcmVhdGVEaXIgPSBmdW5jOyByZXR1cm4oMCk7CisgICAgICAgIGNhc2UgWFNMVF9TRUNQUkVGX1JFQURfTkVUV09SSzoKKyAgICAgICAgICAgIHNlYy0+cmVhZE5ldCA9IGZ1bmM7IHJldHVybigwKTsKKyAgICAgICAgY2FzZSBYU0xUX1NFQ1BSRUZfV1JJVEVfTkVUV09SSzoKKyAgICAgICAgICAgIHNlYy0+d3JpdGVOZXQgPSBmdW5jOyByZXR1cm4oMCk7CisgICAgfQorICAgIHJldHVybigtMSk7Cit9CisKKy8qKgorICogeHNsdEdldFNlY3VyaXR5UHJlZnM6CisgKiBAc2VjOiAgdGhlIHNlY3VyaXR5IGJsb2NrIHRvIHVwZGF0ZQorICogQG9wdGlvbjogIHRoZSBvcHRpb24gdG8gbG9va3VwCisgKgorICogTG9va3VwIHRoZSBzZWN1cml0eSBvcHRpb24gdG8gZ2V0IHRoZSBjYWxsYmFjayBjaGVja2luZyBmdW5jdGlvbgorICoKKyAqIFJldHVybnMgTlVMTCBpZiBub3QgZm91bmQsIHRoZSBmdW5jdGlvbiBvdGhlcndpc2UKKyAqLworeHNsdFNlY3VyaXR5Q2hlY2sKK3hzbHRHZXRTZWN1cml0eVByZWZzKHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYywgeHNsdFNlY3VyaXR5T3B0aW9uIG9wdGlvbikgeworICAgIGlmIChzZWMgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisgICAgc3dpdGNoIChvcHRpb24pIHsKKyAgICAgICAgY2FzZSBYU0xUX1NFQ1BSRUZfUkVBRF9GSUxFOgorICAgICAgICAgICAgcmV0dXJuKHNlYy0+cmVhZEZpbGUpOworICAgICAgICBjYXNlIFhTTFRfU0VDUFJFRl9XUklURV9GSUxFOgorICAgICAgICAgICAgcmV0dXJuKHNlYy0+Y3JlYXRlRmlsZSk7CisgICAgICAgIGNhc2UgWFNMVF9TRUNQUkVGX0NSRUFURV9ESVJFQ1RPUlk6CisgICAgICAgICAgICByZXR1cm4oc2VjLT5jcmVhdGVEaXIpOworICAgICAgICBjYXNlIFhTTFRfU0VDUFJFRl9SRUFEX05FVFdPUks6CisgICAgICAgICAgICByZXR1cm4oc2VjLT5yZWFkTmV0KTsKKyAgICAgICAgY2FzZSBYU0xUX1NFQ1BSRUZfV1JJVEVfTkVUV09SSzoKKyAgICAgICAgICAgIHJldHVybihzZWMtPndyaXRlTmV0KTsKKyAgICB9CisgICAgcmV0dXJuKE5VTEwpOworfQorCisvKioKKyAqIHhzbHRTZXREZWZhdWx0U2VjdXJpdHlQcmVmczoKKyAqIEBzZWM6ICB0aGUgc2VjdXJpdHkgYmxvY2sgdG8gdXNlCisgKgorICogU2V0IHRoZSBkZWZhdWx0IHNlY3VyaXR5IHByZWZlcmVuY2UgYXBwbGljYXRpb24td2lkZQorICovCit2b2lkCit4c2x0U2V0RGVmYXVsdFNlY3VyaXR5UHJlZnMoeHNsdFNlY3VyaXR5UHJlZnNQdHIgc2VjKSB7CisgICAgCisgICAgeHNsdERlZmF1bHRTZWN1cml0eVByZWZzID0gc2VjOworfQorCisvKioKKyAqIHhzbHRHZXREZWZhdWx0U2VjdXJpdHlQcmVmczoKKyAqCisgKiBHZXQgdGhlIGRlZmF1bHQgc2VjdXJpdHkgcHJlZmVyZW5jZSBhcHBsaWNhdGlvbi13aWRlCisgKgorICogUmV0dXJucyB0aGUgY3VycmVudCB4c2x0U2VjdXJpdHlQcmVmc1B0ciBpbiB1c2Ugb3IgTlVMTCBpZiBub25lCisgKi8KK3hzbHRTZWN1cml0eVByZWZzUHRyCit4c2x0R2V0RGVmYXVsdFNlY3VyaXR5UHJlZnModm9pZCkgeworICAgIHJldHVybih4c2x0RGVmYXVsdFNlY3VyaXR5UHJlZnMpOworfQorCisvKioKKyAqIHhzbHRTZXRDdHh0U2VjdXJpdHlQcmVmczoKKyAqIEBzZWM6ICB0aGUgc2VjdXJpdHkgYmxvY2sgdG8gdXNlCisgKiBAY3R4dDogIGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICoKKyAqIFNldCB0aGUgc2VjdXJpdHkgcHJlZmVyZW5jZSBmb3IgYSBzcGVjaWZpYyB0cmFuc2Zvcm1hdGlvbgorICoKKyAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBvdGhlcndpc2UKKyAqLworaW50ICAgICAgICAgICAgICAgICAgICAKK3hzbHRTZXRDdHh0U2VjdXJpdHlQcmVmcyh4c2x0U2VjdXJpdHlQcmVmc1B0ciBzZWMsCisJICAgICAgICAgICAgICAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KSB7CisgICAgaWYgKGN0eHQgPT0gTlVMTCkKKwlyZXR1cm4oLTEpOworICAgIGN0eHQtPnNlYyA9ICh2b2lkICopIHNlYzsKKyAgICByZXR1cm4oMCk7Cit9CisKKworLyoqCisgKiB4c2x0U2VjdXJpdHlBbGxvdzoKKyAqIEBzZWM6ICB0aGUgc2VjdXJpdHkgYmxvY2sgdG8gdXNlCisgKiBAY3R4dDogIGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQHZhbHVlOiAgdW51c2VkCisgKgorICogRnVuY3Rpb24gdXNlZCB0byBhbHdheXMgYWxsb3cgYW4gb3BlcmF0aW9uCisgKgorICogUmV0dXJucyAxIGFsd2F5cworICovCitpbnQKK3hzbHRTZWN1cml0eUFsbG93KHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYyBBVFRSSUJVVEVfVU5VU0VELAorCSAgICAgICAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0IEFUVFJJQlVURV9VTlVTRUQsCisJCSAgY29uc3QgY2hhciAqdmFsdWUgQVRUUklCVVRFX1VOVVNFRCkgeworICAgIHJldHVybigxKTsKK30KKworLyoqCisgKiB4c2x0U2VjdXJpdHlGb3JiaWQ6CisgKiBAc2VjOiAgdGhlIHNlY3VyaXR5IGJsb2NrIHRvIHVzZQorICogQGN0eHQ6ICBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEB2YWx1ZTogIHVudXNlZAorICoKKyAqIEZ1bmN0aW9uIHVzZWQgdG8gYWx3YXlzIGZvcmJpZCBhbiBvcGVyYXRpb24KKyAqCisgKiBSZXR1cm5zIDAgYWx3YXlzCisgKi8KK2ludAoreHNsdFNlY3VyaXR5Rm9yYmlkKHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYyBBVFRSSUJVVEVfVU5VU0VELAorCSAgICAgICAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0IEFUVFJJQlVURV9VTlVTRUQsCisJCSAgY29uc3QgY2hhciAqdmFsdWUgQVRUUklCVVRFX1VOVVNFRCkgeworICAgIHJldHVybigwKTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJCUludGVybmFsIGludGVyZmFjZXMJCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHRDaGVja0ZpbGVuYW1lCisgKiBAcGF0aDogIHRoZSBwYXRoIHRvIGNoZWNrCisgKgorICogZnVuY3Rpb24gY2hlY2tzIHRvIHNlZSBpZiBAcGF0aCBpcyBhIHZhbGlkIHNvdXJjZQorICogKGZpbGUsIHNvY2tldC4uLikgZm9yIFhNTC4KKyAqCisgKiBUT0RPOiByZW1vdmUgYXQgc29tZSBwb2ludCAhISEKKyAqIExvY2FsIGNvcHkgb2YgeG1sQ2hlY2tGaWxlbmFtZSB0byBhdm9pZCBhIGhhcmQgZGVwZW5kZW5jeSBvbgorICogYSBuZXcgdmVyc2lvbiBvZiBsaWJ4bWwyIAorICoKKyAqIGlmIHN0YXQgaXMgbm90IGF2YWlsYWJsZSBvbiB0aGUgdGFyZ2V0IG1hY2hpbmUsCisgKiByZXR1cm5zIDEuICBpZiBzdGF0IGZhaWxzLCByZXR1cm5zIDAgKGlmIGNhbGxpbmcKKyAqIHN0YXQgb24gdGhlIGZpbGVuYW1lIGZhaWxzLCBpdCBjYW4ndCBiZSByaWdodCkuCisgKiBpZiBzdGF0IHN1Y2NlZWRzIGFuZCB0aGUgZmlsZSBpcyBhIGRpcmVjdG9yeSwKKyAqIHJldHVybnMgMi4gIG90aGVyd2lzZSByZXR1cm5zIDEuCisgKi8KKworc3RhdGljIGludAoreHNsdENoZWNrRmlsZW5hbWUgKGNvbnN0IGNoYXIgKnBhdGgpCit7CisjaWZkZWYgSEFWRV9TVEFUCisgICAgc3RydWN0IHN0YXQgc3RhdF9idWZmZXI7CisjaWYgZGVmaW5lZChXSU4zMikgJiYgIWRlZmluZWQoX19DWUdXSU5fXykKKyAgICBEV09SRCBkd0F0dHJzOworCisgICAgZHdBdHRycyA9IEdldEZpbGVBdHRyaWJ1dGVzKHBhdGgpOyAKKyAgICBpZiAoZHdBdHRycyAhPSBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUykgeworICAgICAgICBpZiAoZHdBdHRycyAmIEZJTEVfQVRUUklCVVRFX0RJUkVDVE9SWSkgeworICAgICAgICAgICAgcmV0dXJuIDI7CisJCX0KKyAgICB9CisjZW5kaWYKKworICAgIGlmIChzdGF0KHBhdGgsICZzdGF0X2J1ZmZlcikgPT0gLTEpCisgICAgICAgIHJldHVybiAwOworCisjaWZkZWYgU19JU0RJUgorICAgIGlmIChTX0lTRElSKHN0YXRfYnVmZmVyLnN0X21vZGUpKSB7CisgICAgICAgIHJldHVybiAyOworICAgIH0KKyNlbmRpZgorI2VuZGlmCisgICAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQKK3hzbHRDaGVja1dyaXRlUGF0aCh4c2x0U2VjdXJpdHlQcmVmc1B0ciBzZWMsCisJCSAgIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCSAgIGNvbnN0IGNoYXIgKnBhdGgpCit7CisgICAgaW50IHJldDsKKyAgICB4c2x0U2VjdXJpdHlDaGVjayBjaGVjazsKKyAgICBjaGFyICpkaXJlY3Rvcnk7CisKKyAgICBjaGVjayA9IHhzbHRHZXRTZWN1cml0eVByZWZzKHNlYywgWFNMVF9TRUNQUkVGX1dSSVRFX0ZJTEUpOworICAgIGlmIChjaGVjayAhPSBOVUxMKSB7CisJcmV0ID0gY2hlY2soc2VjLCBjdHh0LCBwYXRoKTsKKwlpZiAocmV0ID09IDApIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIE5VTEwsCisJCQkgICAgICAgIkZpbGUgd3JpdGUgZm9yICVzIHJlZnVzZWRcbiIsIHBhdGgpOworCSAgICByZXR1cm4oMCk7CisJfQorICAgIH0KKworICAgIGRpcmVjdG9yeSA9IHhtbFBhcnNlckdldERpcmVjdG9yeSAocGF0aCk7CisKKyAgICBpZiAoZGlyZWN0b3J5ICE9IE5VTEwpIHsKKwlyZXQgPSB4c2x0Q2hlY2tGaWxlbmFtZShkaXJlY3RvcnkpOworCWlmIChyZXQgPT0gMCkgeworCSAgICAvKgorCSAgICAgKiBUaGUgZGlyZWN0b3J5IGRvZXNuJ3QgZXhpc3QgY2hlY2sgZm9yIGNyZWF0aW9uCisJICAgICAqLworCSAgICBjaGVjayA9IHhzbHRHZXRTZWN1cml0eVByZWZzKHNlYywKKwkJCQkJIFhTTFRfU0VDUFJFRl9DUkVBVEVfRElSRUNUT1JZKTsKKwkgICAgaWYgKGNoZWNrICE9IE5VTEwpIHsKKwkJcmV0ID0gY2hlY2soc2VjLCBjdHh0LCBkaXJlY3RvcnkpOworCQlpZiAocmV0ID09IDApIHsKKwkJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBOVUxMLAorCQkJCSAgICAgICAiRGlyZWN0b3J5IGNyZWF0aW9uIGZvciAlcyByZWZ1c2VkXG4iLAorCQkJCSAgICAgICBwYXRoKTsKKwkJICAgIHhtbEZyZWUoZGlyZWN0b3J5KTsKKwkJICAgIHJldHVybigwKTsKKwkJfQorCSAgICB9CisJICAgIHJldCA9IHhzbHRDaGVja1dyaXRlUGF0aChzZWMsIGN0eHQsIGRpcmVjdG9yeSk7CisJICAgIGlmIChyZXQgPT0gMSkKKwkJcmV0ID0gbWtkaXIoZGlyZWN0b3J5LCAwNzU1KTsKKwl9CisJeG1sRnJlZShkaXJlY3RvcnkpOworCWlmIChyZXQgPCAwKQorCSAgICByZXR1cm4ocmV0KTsKKyAgICB9CisKKyAgICByZXR1cm4oMSk7Cit9CisKKy8qKgorICogeHNsdENoZWNrV3JpdGU6CisgKiBAc2VjOiAgdGhlIHNlY3VyaXR5IG9wdGlvbnMKKyAqIEBjdHh0OiAgYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAVVJMOiAgdGhlIHJlc291cmNlIHRvIGJlIHdyaXR0ZW4KKyAqCisgKiBDaGVjayBpZiB0aGUgcmVzb3VyY2UgaXMgYWxsb3dlZCB0byBiZSB3cml0dGVuLCBpZiBuZWNlc3NhcnkgbWFrZXMKKyAqIHNvbWUgcHJlbGltaW5hcnkgd29yayBsaWtlIGNyZWF0aW5nIGRpcmVjdG9yaWVzCisgKgorICogUmV0dXJuIDEgaWYgd3JpdGUgaXMgYWxsb3dlZCwgMCBpZiBub3QgYW5kIC0xIGluIGNhc2Ugb3IgZXJyb3IuCisgKi8KK2ludAoreHNsdENoZWNrV3JpdGUoeHNsdFNlY3VyaXR5UHJlZnNQdHIgc2VjLAorCSAgICAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICpVUkwpIHsKKyAgICBpbnQgcmV0OworICAgIHhtbFVSSVB0ciB1cmk7CisgICAgeHNsdFNlY3VyaXR5Q2hlY2sgY2hlY2s7CisKKyAgICB1cmkgPSB4bWxQYXJzZVVSSSgoY29uc3QgY2hhciAqKVVSTCk7CisgICAgaWYgKHVyaSA9PSBOVUxMKSB7CisgICAgICAgIHVyaSA9IHhtbENyZWF0ZVVSSSgpOworCWlmICh1cmkgPT0gTlVMTCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgTlVMTCwKKwkgICAgICJ4c2x0Q2hlY2tXcml0ZTogb3V0IG9mIG1lbW9yeSBmb3IgJXNcbiIsIFVSTCk7CisJICAgIHJldHVybigtMSk7CisJfQorCXVyaS0+cGF0aCA9IChjaGFyICopeG1sU3RyZHVwKFVSTCk7CisgICAgfQorICAgIGlmICgodXJpLT5zY2hlbWUgPT0gTlVMTCkgfHwKKwkoeG1sU3RyRXF1YWwoQkFEX0NBU1QgdXJpLT5zY2hlbWUsIEJBRF9DQVNUICJmaWxlIikpKSB7CisKKyNpZiBkZWZpbmVkKFdJTjMyKSAmJiAhZGVmaW5lZChfX0NZR1dJTl9fKQorICAgIGlmICgodXJpLT5wYXRoKSYmKHVyaS0+cGF0aFswXT09Jy8nKSYmCisgICAgICAgICh1cmktPnBhdGhbMV0hPSdcMCcpJiYodXJpLT5wYXRoWzJdPT0nOicpKQorICAgIHJldCA9IHhzbHRDaGVja1dyaXRlUGF0aChzZWMsIGN0eHQsIHVyaS0+cGF0aCsxKTsKKyAgICBlbHNlCisjZW5kaWYKKworCS8qCisJICogQ2hlY2sgaWYgd2UgYXJlIGFsbG93ZWQgdG8gd3JpdGUgdGhpcyBmaWxlCisJICovCisJcmV0ID0geHNsdENoZWNrV3JpdGVQYXRoKHNlYywgY3R4dCwgdXJpLT5wYXRoKTsKKwlpZiAocmV0IDw9IDApIHsKKwkgICAgeG1sRnJlZVVSSSh1cmkpOworCSAgICByZXR1cm4ocmV0KTsKKwl9CisgICAgfSBlbHNlIHsKKwkvKgorCSAqIENoZWNrIGlmIHdlIGFyZSBhbGxvd2VkIHRvIHdyaXRlIHRoaXMgbmV0d29yayByZXNvdXJjZQorCSAqLworCWNoZWNrID0geHNsdEdldFNlY3VyaXR5UHJlZnMoc2VjLCBYU0xUX1NFQ1BSRUZfV1JJVEVfTkVUV09SSyk7CisJaWYgKGNoZWNrICE9IE5VTEwpIHsKKwkgICAgcmV0ID0gY2hlY2soc2VjLCBjdHh0LCAoY29uc3QgY2hhciAqKVVSTCk7CisJICAgIGlmIChyZXQgPT0gMCkgeworCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgTlVMTCwKKwkJCSAgICAgIkZpbGUgd3JpdGUgZm9yICVzIHJlZnVzZWRcbiIsIFVSTCk7CisJCXhtbEZyZWVVUkkodXJpKTsKKwkJcmV0dXJuKDApOworCSAgICB9CisJfQorICAgIH0KKyAgICB4bWxGcmVlVVJJKHVyaSk7CisgICAgcmV0dXJuKDEpOworfQorCisKKy8qKgorICogeHNsdENoZWNrUmVhZDoKKyAqIEBzZWM6ICB0aGUgc2VjdXJpdHkgb3B0aW9ucworICogQGN0eHQ6IGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQFVSTDogIHRoZSByZXNvdXJjZSB0byBiZSByZWFkCisgKgorICogQ2hlY2sgaWYgdGhlIHJlc291cmNlIGlzIGFsbG93ZWQgdG8gYmUgcmVhZAorICoKKyAqIFJldHVybiAxIGlmIHJlYWQgaXMgYWxsb3dlZCwgMCBpZiBub3QgYW5kIC0xIGluIGNhc2Ugb3IgZXJyb3IuCisgKi8KK2ludAoreHNsdENoZWNrUmVhZCh4c2x0U2VjdXJpdHlQcmVmc1B0ciBzZWMsCisJICAgICAgeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqVVJMKSB7CisgICAgaW50IHJldDsKKyAgICB4bWxVUklQdHIgdXJpOworICAgIHhzbHRTZWN1cml0eUNoZWNrIGNoZWNrOworCisgICAgdXJpID0geG1sUGFyc2VVUkkoKGNvbnN0IGNoYXIgKilVUkwpOworICAgIGlmICh1cmkgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBOVUxMLAorCSAieHNsdENoZWNrUmVhZDogVVJMIHBhcnNpbmcgZmFpbGVkIGZvciAlc1xuIiwKKwkJCSBVUkwpOworCXJldHVybigtMSk7CisgICAgfQorICAgIGlmICgodXJpLT5zY2hlbWUgPT0gTlVMTCkgfHwKKwkoeG1sU3RyRXF1YWwoQkFEX0NBU1QgdXJpLT5zY2hlbWUsIEJBRF9DQVNUICJmaWxlIikpKSB7CisKKwkvKgorCSAqIENoZWNrIGlmIHdlIGFyZSBhbGxvd2VkIHRvIHJlYWQgdGhpcyBmaWxlCisJICovCisJY2hlY2sgPSB4c2x0R2V0U2VjdXJpdHlQcmVmcyhzZWMsIFhTTFRfU0VDUFJFRl9SRUFEX0ZJTEUpOworCWlmIChjaGVjayAhPSBOVUxMKSB7CisJICAgIHJldCA9IGNoZWNrKHNlYywgY3R4dCwgdXJpLT5wYXRoKTsKKwkgICAgaWYgKHJldCA9PSAwKSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBOVUxMLAorCQkJICAgICAiTG9jYWwgZmlsZSByZWFkIGZvciAlcyByZWZ1c2VkXG4iLCBVUkwpOworCQl4bWxGcmVlVVJJKHVyaSk7CisJCXJldHVybigwKTsKKwkgICAgfQorCX0KKyAgICB9IGVsc2UgeworCS8qCisJICogQ2hlY2sgaWYgd2UgYXJlIGFsbG93ZWQgdG8gd3JpdGUgdGhpcyBuZXR3b3JrIHJlc291cmNlCisJICovCisJY2hlY2sgPSB4c2x0R2V0U2VjdXJpdHlQcmVmcyhzZWMsIFhTTFRfU0VDUFJFRl9SRUFEX05FVFdPUkspOworCWlmIChjaGVjayAhPSBOVUxMKSB7CisJICAgIHJldCA9IGNoZWNrKHNlYywgY3R4dCwgKGNvbnN0IGNoYXIgKilVUkwpOworCSAgICBpZiAocmV0ID09IDApIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIE5VTEwsCisJCQkgICAgICJOZXR3b3JrIGZpbGUgcmVhZCBmb3IgJXMgcmVmdXNlZFxuIiwgVVJMKTsKKwkJeG1sRnJlZVVSSSh1cmkpOworCQlyZXR1cm4oMCk7CisJICAgIH0KKwl9CisgICAgfQorICAgIHhtbEZyZWVVUkkodXJpKTsKKyAgICByZXR1cm4oMSk7Cit9CisKZGlmZiAtLWdpdCBhL2xpYnhzbHQvc2VjdXJpdHkuaCBiL2xpYnhzbHQvc2VjdXJpdHkuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNTJjMGFlCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC9zZWN1cml0eS5oCkBAIC0wLDAgKzEsMTA0IEBACisvKgorICogU3VtbWFyeTogaW50ZXJmYWNlIGZvciB0aGUgbGlieHNsdCBzZWN1cml0eSBmcmFtZXdvcmsKKyAqIERlc2NyaXB0aW9uOiB0aGUgbGlieHNsdCBzZWN1cml0eSBmcmFtZXdvcmsgYWxsb3cgdG8gcmVzdHJpY3QKKyAqICAgICAgICAgICAgICB0aGUgYWNjZXNzIHRvIG5ldyByZXNvdXJjZXMgKGZpbGUgb3IgVVJMKSBmcm9tCisgKiAgICAgICAgICAgICAgdGhlIHN0eWxlc2hlZXQgYXQgcnVudGltZS4KKyAqCisgKiBDb3B5OiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCisgKgorICogQXV0aG9yOiBEYW5pZWwgVmVpbGxhcmQKKyAqLworCisjaWZuZGVmIF9fWE1MX1hTTFRfU0VDVVJJVFlfSF9fCisjZGVmaW5lIF9fWE1MX1hTTFRfU0VDVVJJVFlfSF9fCisKKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgInhzbHRleHBvcnRzLmgiCisjaW5jbHVkZSAieHNsdEludGVybmFscy5oIgorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qKgorICogeHNsdFNlY3VyaXR5UHJlZjoKKyAqCisgKiBzdHJ1Y3R1cmUgdG8gaW5kaWNhdGUgdGhlIHByZWZlcmVuY2VzIGZvciBzZWN1cml0eSBpbiB0aGUgWFNMVAorICogdHJhbnNmb3JtYXRpb24uCisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0U2VjdXJpdHlQcmVmcyB4c2x0U2VjdXJpdHlQcmVmczsKK3R5cGVkZWYgeHNsdFNlY3VyaXR5UHJlZnMgKnhzbHRTZWN1cml0eVByZWZzUHRyOworCisvKioKKyAqIHhzbHRTZWN1cml0eU9wdGlvbjoKKyAqCisgKiB0aGUgc2V0IG9mIG9wdGlvbiB0aGF0IGNhbiBiZSBjb25maWd1cmVkCisgKi8KK3R5cGVkZWYgZW51bSB7CisgICAgWFNMVF9TRUNQUkVGX1JFQURfRklMRSA9IDEsCisgICAgWFNMVF9TRUNQUkVGX1dSSVRFX0ZJTEUsCisgICAgWFNMVF9TRUNQUkVGX0NSRUFURV9ESVJFQ1RPUlksCisgICAgWFNMVF9TRUNQUkVGX1JFQURfTkVUV09SSywKKyAgICBYU0xUX1NFQ1BSRUZfV1JJVEVfTkVUV09SSworfSB4c2x0U2VjdXJpdHlPcHRpb247CisKKy8qKgorICogeHNsdFNlY3VyaXR5Q2hlY2s6CisgKgorICogVXNlciBwcm92aWRlZCBmdW5jdGlvbiB0byBjaGVjayB0aGUgdmFsdWUgb2YgYSBzdHJpbmcgbGlrZSBhIGZpbGUKKyAqIHBhdGggb3IgYW4gVVJMIC4uLgorICovCit0eXBlZGVmIGludCAoKnhzbHRTZWN1cml0eUNoZWNrKQkoeHNsdFNlY3VyaXR5UHJlZnNQdHIgc2VjLAorCQkJCQkgeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJIGNvbnN0IGNoYXIgKnZhbHVlKTsKKworLyoKKyAqIE1vZHVsZSBpbnRlcmZhY2VzCisgKi8KK1hTTFRQVUJGVU4geHNsdFNlY3VyaXR5UHJlZnNQdHIgWFNMVENBTEwJCisJCSAgICB4c2x0TmV3U2VjdXJpdHlQcmVmcwkodm9pZCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQkKKwkJICAgIHhzbHRGcmVlU2VjdXJpdHlQcmVmcwkoeHNsdFNlY3VyaXR5UHJlZnNQdHIgc2VjKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkJCisJCSAgICB4c2x0U2V0U2VjdXJpdHlQcmVmcwkoeHNsdFNlY3VyaXR5UHJlZnNQdHIgc2VjLAorCQkJCQkJIHhzbHRTZWN1cml0eU9wdGlvbiBvcHRpb24sCisJCQkJCQkgeHNsdFNlY3VyaXR5Q2hlY2sgZnVuYyk7CitYU0xUUFVCRlVOIHhzbHRTZWN1cml0eUNoZWNrIFhTTFRDQUxMCQorCQkgICAgeHNsdEdldFNlY3VyaXR5UHJlZnMJKHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYywKKwkJCQkJCSB4c2x0U2VjdXJpdHlPcHRpb24gb3B0aW9uKTsKKworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkJCisJCSAgICB4c2x0U2V0RGVmYXVsdFNlY3VyaXR5UHJlZnMJKHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYyk7CitYU0xUUFVCRlVOIHhzbHRTZWN1cml0eVByZWZzUHRyIFhTTFRDQUxMCQorCQkgICAgeHNsdEdldERlZmF1bHRTZWN1cml0eVByZWZzCSh2b2lkKTsKKworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwJCQkKKwkJICAgIHhzbHRTZXRDdHh0U2VjdXJpdHlQcmVmcwkoeHNsdFNlY3VyaXR5UHJlZnNQdHIgc2VjLAorCQkJCQkJIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpOworCitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCQorCQkgICAgeHNsdFNlY3VyaXR5QWxsb3cJCSh4c2x0U2VjdXJpdHlQcmVmc1B0ciBzZWMsCisJCQkJCQkgeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSBjb25zdCBjaGFyICp2YWx1ZSk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkKKwkJICAgIHhzbHRTZWN1cml0eUZvcmJpZAkJKHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYywKKwkJCQkJCSB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIGNvbnN0IGNoYXIgKnZhbHVlKTsKKy8qCisgKiBpbnRlcm5hbCBpbnRlcmZhY2VzCisgKi8KK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkJCisJCSAgICB4c2x0Q2hlY2tXcml0ZQkJKHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYywKKwkJCQkJCSB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIGNvbnN0IHhtbENoYXIgKlVSTCk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCQorCQkgICAgeHNsdENoZWNrUmVhZAkJKHhzbHRTZWN1cml0eVByZWZzUHRyIHNlYywKKwkJCQkJCSB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIGNvbnN0IHhtbENoYXIgKlVSTCk7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX1NFQ1VSSVRZX0hfXyAqLworCmRpZmYgLS1naXQgYS9saWJ4c2x0L3RlbXBsYXRlcy5jIGIvbGlieHNsdC90ZW1wbGF0ZXMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjI1MGRjCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC90ZW1wbGF0ZXMuYwpAQCAtMCwwICsxLDgyNSBAQAorLyoKKyAqIHRlbXBsYXRlcy5jOiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgdGVtcGxhdGUgcHJvY2Vzc2luZworICoKKyAqIFJlZmVyZW5jZToKKyAqICAgaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteHNsdC0xOTk5MTExNgorICoKKyAqIFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBkYW5pZWxAdmVpbGxhcmQuY29tCisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CisjaW5jbHVkZSA8bGlieG1sL2dsb2JhbHMuaD4KKyNpbmNsdWRlIDxsaWJ4bWwveG1sZXJyb3IuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdHJlZS5oPgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aEludGVybmFscy5oPgorI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KKyNpbmNsdWRlICJ4c2x0LmgiCisjaW5jbHVkZSAieHNsdEludGVybmFscy5oIgorI2luY2x1ZGUgInhzbHR1dGlscy5oIgorI2luY2x1ZGUgInZhcmlhYmxlcy5oIgorI2luY2x1ZGUgImZ1bmN0aW9ucy5oIgorI2luY2x1ZGUgInRlbXBsYXRlcy5oIgorI2luY2x1ZGUgInRyYW5zZm9ybS5oIgorI2luY2x1ZGUgIm5hbWVzcGFjZXMuaCIKKyNpbmNsdWRlICJhdHRyaWJ1dGVzLmgiCisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKyNkZWZpbmUgV0lUSF9YU0xUX0RFQlVHX1RFTVBMQVRFUworI2VuZGlmCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICoJCQlNb2R1bGUgaW50ZXJmYWNlcwkJCQkqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisgCisvKioKKyAqIHhzbHRFdmFsWFBhdGhQcmVkaWNhdGU6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBjb21wOiAgdGhlIFhQYXRoIGNvbXBpbGVkIGV4cHJlc3Npb24KKyAqIEBuc0xpc3Q6ICB0aGUgbmFtZXNwYWNlcyBpbiBzY29wZQorICogQG5zTnI6ICB0aGUgbnVtYmVyIG9mIG5hbWVzcGFjZXMgaW4gc2NvcGUKKyAqCisgKiBQcm9jZXNzIHRoZSBleHByZXNzaW9uIHVzaW5nIFhQYXRoIGFuZCBldmFsdWF0ZSB0aGUgcmVzdWx0IGFzCisgKiBhbiBYUGF0aCBwcmVkaWNhdGUKKyAqCisgKiBSZXR1cm5zIDEgaXMgdGhlIHByZWRpY2F0ZSB3YXMgdHJ1ZSwgMCBvdGhlcndpc2UKKyAqLworaW50Cit4c2x0RXZhbFhQYXRoUHJlZGljYXRlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbFhQYXRoQ29tcEV4cHJQdHIgY29tcCwKKwkJICAgICAgIHhtbE5zUHRyICpuc0xpc3QsIGludCBuc05yKSB7CisgICAgaW50IHJldDsKKyAgICB4bWxYUGF0aE9iamVjdFB0ciByZXM7CisgICAgaW50IG9sZE5zTnI7CisgICAgeG1sTnNQdHIgKm9sZE5hbWVzcGFjZXM7CisgICAgeG1sTm9kZVB0ciBvbGRJbnN0OworICAgIGludCBvbGRQcm94aW1pdHlQb3NpdGlvbiwgb2xkQ29udGV4dFNpemU7CisKKyAgICBvbGRDb250ZXh0U2l6ZSA9IGN0eHQtPnhwYXRoQ3R4dC0+Y29udGV4dFNpemU7CisgICAgb2xkUHJveGltaXR5UG9zaXRpb24gPSBjdHh0LT54cGF0aEN0eHQtPnByb3hpbWl0eVBvc2l0aW9uOworICAgIG9sZE5zTnIgPSBjdHh0LT54cGF0aEN0eHQtPm5zTnI7CisgICAgb2xkTmFtZXNwYWNlcyA9IGN0eHQtPnhwYXRoQ3R4dC0+bmFtZXNwYWNlczsKKyAgICBvbGRJbnN0ID0gY3R4dC0+aW5zdDsKKworICAgIGN0eHQtPnhwYXRoQ3R4dC0+bm9kZSA9IGN0eHQtPm5vZGU7CisgICAgY3R4dC0+eHBhdGhDdHh0LT5uYW1lc3BhY2VzID0gbnNMaXN0OworICAgIGN0eHQtPnhwYXRoQ3R4dC0+bnNOciA9IG5zTnI7CisKKyAgICByZXMgPSB4bWxYUGF0aENvbXBpbGVkRXZhbChjb21wLCBjdHh0LT54cGF0aEN0eHQpOworCisgICAgaWYgKHJlcyAhPSBOVUxMKSB7CisJcmV0ID0geG1sWFBhdGhFdmFsUHJlZGljYXRlKGN0eHQtPnhwYXRoQ3R4dCwgcmVzKTsKKwl4bWxYUGF0aEZyZWVPYmplY3QocmVzKTsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfVEVNUExBVEVTCisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfVEVNUExBVEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdEV2YWxYUGF0aFByZWRpY2F0ZTogcmV0dXJucyAlZFxuIiwgcmV0KSk7CisjZW5kaWYKKyAgICB9IGVsc2UgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19URU1QTEFURVMKKwlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9URU1QTEFURVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0RXZhbFhQYXRoUHJlZGljYXRlOiBmYWlsZWRcbiIpKTsKKyNlbmRpZgorCWN0eHQtPnN0YXRlID0gWFNMVF9TVEFURV9TVE9QUEVEOworCXJldCA9IDA7CisgICAgfQorICAgIGN0eHQtPnhwYXRoQ3R4dC0+bnNOciA9IG9sZE5zTnI7CisKKyAgICBjdHh0LT54cGF0aEN0eHQtPm5hbWVzcGFjZXMgPSBvbGROYW1lc3BhY2VzOworICAgIGN0eHQtPmluc3QgPSBvbGRJbnN0OworICAgIGN0eHQtPnhwYXRoQ3R4dC0+Y29udGV4dFNpemUgPSBvbGRDb250ZXh0U2l6ZTsKKyAgICBjdHh0LT54cGF0aEN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gb2xkUHJveGltaXR5UG9zaXRpb247CisKKyAgICByZXR1cm4ocmV0KTsKK30KKworLyoqCisgKiB4c2x0RXZhbFhQYXRoU3RyaW5nTnM6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBjb21wOiAgdGhlIGNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24KKyAqIEBuc05yOiAgdGhlIG51bWJlciBvZiBuYW1lc3BhY2VzIGluIHRoZSBsaXN0CisgKiBAbnNMaXN0OiAgdGhlIGxpc3Qgb2YgaW4tc2NvcGUgbmFtZXNwYWNlcyB0byB1c2UKKyAqCisgKiBQcm9jZXNzIHRoZSBleHByZXNzaW9uIHVzaW5nIFhQYXRoLCBhbGxvd2luZyB0byBwYXNzIGEgbmFtZXNwYWNlIG1hcHBpbmcKKyAqIGNvbnRleHQgYW5kIGdldCBhIHN0cmluZworICoKKyAqIFJldHVybnMgdGhlIGNvbXB1dGVkIHN0cmluZyB2YWx1ZSBvciBOVUxMLCBtdXN0IGJlIGRlYWxsb2NhdGVkIGJ5IHRoZQorICogICAgY2FsbGVyLgorICovCit4bWxDaGFyICoKK3hzbHRFdmFsWFBhdGhTdHJpbmdOcyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxYUGF0aENvbXBFeHByUHRyIGNvbXAsCisJICAgICAgICAgICAgICBpbnQgbnNOciwgeG1sTnNQdHIgKm5zTGlzdCkgeworICAgIHhtbENoYXIgKnJldCA9IE5VTEw7CisgICAgeG1sWFBhdGhPYmplY3RQdHIgcmVzOworICAgIHhtbE5vZGVQdHIgb2xkSW5zdDsKKyAgICB4bWxOb2RlUHRyIG9sZE5vZGU7CisgICAgaW50CW9sZFBvcywgb2xkU2l6ZTsKKyAgICBpbnQgb2xkTnNOcjsKKyAgICB4bWxOc1B0ciAqb2xkTmFtZXNwYWNlczsKKworICAgIG9sZEluc3QgPSBjdHh0LT5pbnN0OworICAgIG9sZE5vZGUgPSBjdHh0LT5ub2RlOworICAgIG9sZFBvcyA9IGN0eHQtPnhwYXRoQ3R4dC0+cHJveGltaXR5UG9zaXRpb247CisgICAgb2xkU2l6ZSA9IGN0eHQtPnhwYXRoQ3R4dC0+Y29udGV4dFNpemU7CisgICAgb2xkTnNOciA9IGN0eHQtPnhwYXRoQ3R4dC0+bnNOcjsKKyAgICBvbGROYW1lc3BhY2VzID0gY3R4dC0+eHBhdGhDdHh0LT5uYW1lc3BhY2VzOworCisgICAgY3R4dC0+eHBhdGhDdHh0LT5ub2RlID0gY3R4dC0+bm9kZTsKKyAgICAvKiBUT0RPOiBkbyB3ZSBuZWVkIHRvIHByb3BhZ2F0ZSB0aGUgbmFtZXNwYWNlcyBoZXJlID8gKi8KKyAgICBjdHh0LT54cGF0aEN0eHQtPm5hbWVzcGFjZXMgPSBuc0xpc3Q7CisgICAgY3R4dC0+eHBhdGhDdHh0LT5uc05yID0gbnNOcjsKKyAgICByZXMgPSB4bWxYUGF0aENvbXBpbGVkRXZhbChjb21wLCBjdHh0LT54cGF0aEN0eHQpOworICAgIGlmIChyZXMgIT0gTlVMTCkgeworCWlmIChyZXMtPnR5cGUgIT0gWFBBVEhfU1RSSU5HKQorCSAgICByZXMgPSB4bWxYUGF0aENvbnZlcnRTdHJpbmcocmVzKTsKKwlpZiAocmVzLT50eXBlID09IFhQQVRIX1NUUklORykgeworICAgICAgICAgICAgcmV0ID0gcmVzLT5zdHJpbmd2YWw7CisJICAgIHJlcy0+c3RyaW5ndmFsID0gTlVMTDsKKwl9IGVsc2UgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgTlVMTCwKKwkJICJ4cGF0aCA6IHN0cmluZygpIGZ1bmN0aW9uIGRpZG4ndCByZXR1cm4gYSBTdHJpbmdcbiIpOworCX0KKwl4bWxYUGF0aEZyZWVPYmplY3QocmVzKTsKKyAgICB9IGVsc2UgeworCWN0eHQtPnN0YXRlID0gWFNMVF9TVEFURV9TVE9QUEVEOworICAgIH0KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfVEVNUExBVEVTCisgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfVEVNUExBVEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICJ4c2x0RXZhbFhQYXRoU3RyaW5nOiByZXR1cm5zICVzXG4iLCByZXQpKTsKKyNlbmRpZgorICAgIGN0eHQtPmluc3QgPSBvbGRJbnN0OworICAgIGN0eHQtPm5vZGUgPSBvbGROb2RlOworICAgIGN0eHQtPnhwYXRoQ3R4dC0+Y29udGV4dFNpemUgPSBvbGRTaXplOworICAgIGN0eHQtPnhwYXRoQ3R4dC0+cHJveGltaXR5UG9zaXRpb24gPSBvbGRQb3M7CisgICAgY3R4dC0+eHBhdGhDdHh0LT5uc05yID0gb2xkTnNOcjsKKyAgICBjdHh0LT54cGF0aEN0eHQtPm5hbWVzcGFjZXMgPSBvbGROYW1lc3BhY2VzOworICAgIHJldHVybihyZXQpOworfQorCisvKioKKyAqIHhzbHRFdmFsWFBhdGhTdHJpbmc6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBjb21wOiAgdGhlIGNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24KKyAqCisgKiBQcm9jZXNzIHRoZSBleHByZXNzaW9uIHVzaW5nIFhQYXRoIGFuZCBnZXQgYSBzdHJpbmcKKyAqCisgKiBSZXR1cm5zIHRoZSBjb21wdXRlZCBzdHJpbmcgdmFsdWUgb3IgTlVMTCwgbXVzdCBiZSBkZWFsbG9jYXRlZCBieSB0aGUKKyAqICAgIGNhbGxlci4KKyAqLworeG1sQ2hhciAqCit4c2x0RXZhbFhQYXRoU3RyaW5nKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbFhQYXRoQ29tcEV4cHJQdHIgY29tcCkgeworICAgIHJldHVybih4c2x0RXZhbFhQYXRoU3RyaW5nTnMoY3R4dCwgY29tcCwgMCwgTlVMTCkpOworfQorCisvKioKKyAqIHhzbHRFdmFsVGVtcGxhdGVTdHJpbmc6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBjb250ZXh0Tm9kZTogIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlCisgKiBAaW5zdDogIHRoZSBYU0xUIGluc3RydWN0aW9uICh4c2w6Y29tbWVudCwgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24pCisgKgorICogUHJvY2Vzc2VzIHRoZSBzZXF1ZW5jZSBjb25zdHJ1Y3RvciBvZiB0aGUgZ2l2ZW4gaW5zdHJ1Y3Rpb24gb24KKyAqIEBjb250ZXh0Tm9kZSBhbmQgY29udmVydHMgdGhlIHJlc3VsdGluZyB0cmVlIHRvIGEgc3RyaW5nLgorICogVGhpcyBpcyBuZWVkZWQgYnkgZS5nLiB4c2w6Y29tbWVudCBhbmQgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24uCisgKgorICogUmV0dXJucyB0aGUgY29tcHV0ZWQgc3RyaW5nIHZhbHVlIG9yIE5VTEw7IGl0J3MgdXAgdG8gdGhlIGNhbGxlciB0bworICogICAgICAgICBmcmVlIHRoZSByZXN1bHQuCisgKi8KK3htbENoYXIgKgoreHNsdEV2YWxUZW1wbGF0ZVN0cmluZyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkgICAgICAgeG1sTm9kZVB0ciBjb250ZXh0Tm9kZSwKKwkgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGluc3QpCit7CisgICAgeG1sTm9kZVB0ciBvbGRJbnNlcnQsIGluc2VydCA9IE5VTEw7CisgICAgeG1sQ2hhciAqcmV0OworCisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChjb250ZXh0Tm9kZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICBpZiAoaW5zdC0+Y2hpbGRyZW4gPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICAvKgorICAgICogVGhpcyBjcmVhdGVzIGEgdGVtcG9yYXJ5IGVsZW1lbnQtbm9kZSB0byBhZGQgdGhlIHJlc3VsdGluZworICAgICogdGV4dCBjb250ZW50IHRvLgorICAgICogT1BUSU1JWkUgVE9ETzogS2VlcCBzdWNoIGFuIGVsZW1lbnQtbm9kZSBpbiB0aGUgdHJhbnNmb3JtYXRpb24KKyAgICAqICBjb250ZXh0IHRvIGF2b2lkIGNyZWF0aW5nIGl0IGV2ZXJ5IHRpbWUuCisgICAgKi8KKyAgICBpbnNlcnQgPSB4bWxOZXdEb2NOb2RlKGN0eHQtPm91dHB1dCwgTlVMTCwKKwkgICAgICAgICAgICAgICAgICAgKGNvbnN0IHhtbENoYXIgKikiZmFrZSIsIE5VTEwpOworICAgIGlmIChpbnNlcnQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjb250ZXh0Tm9kZSwKKwkJIkZhaWxlZCB0byBjcmVhdGUgdGVtcG9yYXJ5IG5vZGVcbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgb2xkSW5zZXJ0ID0gY3R4dC0+aW5zZXJ0OworICAgIGN0eHQtPmluc2VydCA9IGluc2VydDsKKyAgICAvKgorICAgICogT1BUSU1JWkUgVE9ETzogaWYgaW5zdC0+Y2hpbGRyZW4gY29uc2lzdHMgb25seSBvZiB0ZXh0LW5vZGVzLgorICAgICovCisgICAgeHNsdEFwcGx5T25lVGVtcGxhdGUoY3R4dCwgY29udGV4dE5vZGUsIGluc3QtPmNoaWxkcmVuLCBOVUxMLCBOVUxMKTsKKworICAgIGN0eHQtPmluc2VydCA9IG9sZEluc2VydDsKKworICAgIHJldCA9IHhtbE5vZGVHZXRDb250ZW50KGluc2VydCk7CisgICAgaWYgKGluc2VydCAhPSBOVUxMKQorCXhtbEZyZWVOb2RlKGluc2VydCk7CisgICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdEF0dHJUZW1wbGF0ZVZhbHVlUHJvY2Vzc05vZGU6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBzdHI6ICB0aGUgYXR0cmlidXRlIHRlbXBsYXRlIG5vZGUgdmFsdWUKKyAqIEBpbnN0OiAgdGhlIGluc3RydWN0aW9uIChvciBMUkUpIGluIHRoZSBzdHlsZXNoZWV0IGhvbGRpbmcgdGhlCisgKiAgICAgICAgIGF0dHJpYnV0ZSB3aXRoIGFuIEFWVAorICoKKyAqIFByb2Nlc3MgdGhlIGdpdmVuIHN0cmluZywgYWxsb3dpbmcgdG8gcGFzcyBhIG5hbWVzcGFjZSBtYXBwaW5nCisgKiBjb250ZXh0IGFuZCByZXR1cm4gdGhlIG5ldyBzdHJpbmcgdmFsdWUuCisgKgorICogQ2FsbGVkIGJ5OgorICogIC0geHNsdEF0dHJUZW1wbGF0ZVZhbHVlUHJvY2VzcygpICh0ZW1wbGF0ZXMuYykKKyAqICAtIHhzbHRFdmFsQXR0clZhbHVlVGVtcGxhdGUoKSAodGVtcGxhdGVzLmMpCisgKgorICogUVVFU1RJT046IFdoeSBpcyB0aGlzIGZ1bmN0aW9uIHB1YmxpYz8gSXQgaXMgbm90IHVzZWQgb3V0c2lkZQorICogIG9mIHRlbXBsYXRlcy5jLgorICoKKyAqIFJldHVybnMgdGhlIGNvbXB1dGVkIHN0cmluZyB2YWx1ZSBvciBOVUxMLCBtdXN0IGJlIGRlYWxsb2NhdGVkIGJ5IHRoZQorICogICAgY2FsbGVyLgorICovCit4bWxDaGFyICoKK3hzbHRBdHRyVGVtcGxhdGVWYWx1ZVByb2Nlc3NOb2RlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJICBjb25zdCB4bWxDaGFyICpzdHIsIHhtbE5vZGVQdHIgaW5zdCkKK3sKKyAgICB4bWxDaGFyICpyZXQgPSBOVUxMOworICAgIGNvbnN0IHhtbENoYXIgKmN1cjsKKyAgICB4bWxDaGFyICpleHByLCAqdmFsOworICAgIHhtbE5zUHRyICpuc0xpc3QgPSBOVUxMOworICAgIGludCBuc05yID0gMDsKKworICAgIGlmIChzdHIgPT0gTlVMTCkgcmV0dXJuKE5VTEwpOworICAgIGlmICgqc3RyID09IDApCisJcmV0dXJuKHhtbFN0cm5kdXAoKHhtbENoYXIgKikiIiwgMCkpOworCisgICAgY3VyID0gc3RyOworICAgIHdoaWxlICgqY3VyICE9IDApIHsKKwlpZiAoKmN1ciA9PSAneycpIHsKKwkgICAgaWYgKCooY3VyKzEpID09ICd7JykgewkvKiBlc2NhcGVkICd7JyAqLworCSAgICAgICAgY3VyKys7CisJCXJldCA9IHhtbFN0cm5jYXQocmV0LCBzdHIsIGN1ciAtIHN0cik7CisJCWN1cisrOworCQlzdHIgPSBjdXI7CisJCWNvbnRpbnVlOworCSAgICB9CisJICAgIHJldCA9IHhtbFN0cm5jYXQocmV0LCBzdHIsIGN1ciAtIHN0cik7CisJICAgIHN0ciA9IGN1cjsKKwkgICAgY3VyKys7CisJICAgIHdoaWxlICgoKmN1ciAhPSAwKSAmJiAoKmN1ciAhPSAnfScpKSBjdXIrKzsKKwkgICAgaWYgKCpjdXIgPT0gMCkgeworCSAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCQkieHNsdEF0dHJUZW1wbGF0ZVZhbHVlUHJvY2Vzc05vZGU6IHVubWF0Y2hlZCAneydcbiIpOworCQlyZXQgPSB4bWxTdHJuY2F0KHJldCwgc3RyLCBjdXIgLSBzdHIpOworCQlyZXR1cm4ocmV0KTsKKwkgICAgfQorCSAgICBzdHIrKzsKKwkgICAgZXhwciA9IHhtbFN0cm5kdXAoc3RyLCBjdXIgLSBzdHIpOworCSAgICBpZiAoZXhwciA9PSBOVUxMKQorCQlyZXR1cm4ocmV0KTsKKwkgICAgZWxzZSBpZiAoKmV4cHIgPT0gJ3snKSB7CisJCXJldCA9IHhtbFN0cmNhdChyZXQsIGV4cHIpOworCQl4bWxGcmVlKGV4cHIpOworCSAgICB9IGVsc2UgeworCQl4bWxYUGF0aENvbXBFeHByUHRyIGNvbXA7CisJCS8qCisJCSAqIFRPRE86IGtlZXAgcHJlY29tcGlsZWQgZm9ybSBhcm91bmQKKwkJICovCisJCWlmICgobnNMaXN0ID09IE5VTEwpICYmIChpbnN0ICE9IE5VTEwpKSB7CisJCSAgICBpbnQgaSA9IDA7CisKKwkJICAgIG5zTGlzdCA9IHhtbEdldE5zTGlzdChpbnN0LT5kb2MsIGluc3QpOworCQkgICAgaWYgKG5zTGlzdCAhPSBOVUxMKSB7CisJCQl3aGlsZSAobnNMaXN0W2ldICE9IE5VTEwpCisJCQkgICAgaSsrOworCQkJbnNOciA9IGk7CisJCSAgICB9CisJCX0KKwkJY29tcCA9IHhtbFhQYXRoQ29tcGlsZShleHByKTsKKyAgICAgICAgICAgICAgICB2YWwgPSB4c2x0RXZhbFhQYXRoU3RyaW5nTnMoY3R4dCwgY29tcCwgbnNOciwgbnNMaXN0KTsKKwkJeG1sWFBhdGhGcmVlQ29tcEV4cHIoY29tcCk7CisJCXhtbEZyZWUoZXhwcik7CisJCWlmICh2YWwgIT0gTlVMTCkgeworCQkgICAgcmV0ID0geG1sU3RyY2F0KHJldCwgdmFsKTsKKwkJICAgIHhtbEZyZWUodmFsKTsKKwkJfQorCSAgICB9CisJICAgIGN1cisrOworCSAgICBzdHIgPSBjdXI7CisJfSBlbHNlIGlmICgqY3VyID09ICd9JykgeworCSAgICBjdXIrKzsKKwkgICAgaWYgKCpjdXIgPT0gJ30nKSB7CS8qIGVzY2FwZWQgJ30nICovCisJCXJldCA9IHhtbFN0cm5jYXQocmV0LCBzdHIsIGN1ciAtIHN0cik7CisJCWN1cisrOworCQlzdHIgPSBjdXI7CisJCWNvbnRpbnVlOworCSAgICB9IGVsc2UgeworCSAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCSAgICAgInhzbHRBdHRyVGVtcGxhdGVWYWx1ZVByb2Nlc3NOb2RlOiB1bm1hdGNoZWQgJ30nXG4iKTsKKwkgICAgfQorCX0gZWxzZQorCSAgICBjdXIrKzsKKyAgICB9CisgICAgaWYgKGN1ciAhPSBzdHIpIHsKKwlyZXQgPSB4bWxTdHJuY2F0KHJldCwgc3RyLCBjdXIgLSBzdHIpOworICAgIH0KKworICAgIGlmIChuc0xpc3QgIT0gTlVMTCkKKwl4bWxGcmVlKG5zTGlzdCk7CisKKyAgICByZXR1cm4ocmV0KTsKK30KKworLyoqCisgKiB4c2x0QXR0clRlbXBsYXRlVmFsdWVQcm9jZXNzOgorICogQGN0eHQ6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAc3RyOiAgdGhlIGF0dHJpYnV0ZSB0ZW1wbGF0ZSBub2RlIHZhbHVlCisgKgorICogUHJvY2VzcyB0aGUgZ2l2ZW4gbm9kZSBhbmQgcmV0dXJuIHRoZSBuZXcgc3RyaW5nIHZhbHVlLgorICoKKyAqIFJldHVybnMgdGhlIGNvbXB1dGVkIHN0cmluZyB2YWx1ZSBvciBOVUxMLCBtdXN0IGJlIGRlYWxsb2NhdGVkIGJ5IHRoZQorICogICAgY2FsbGVyLgorICovCit4bWxDaGFyICoKK3hzbHRBdHRyVGVtcGxhdGVWYWx1ZVByb2Nlc3MoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqc3RyKSB7CisgICAgcmV0dXJuKHhzbHRBdHRyVGVtcGxhdGVWYWx1ZVByb2Nlc3NOb2RlKGN0eHQsIHN0ciwgTlVMTCkpOworfQorCisvKioKKyAqIHhzbHRFdmFsQXR0clZhbHVlVGVtcGxhdGU6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBpbnN0OiAgdGhlIGluc3RydWN0aW9uIChvciBMUkUpIGluIHRoZSBzdHlsZXNoZWV0IGhvbGRpbmcgdGhlCisgKiAgICAgICAgIGF0dHJpYnV0ZSB3aXRoIGFuIEFWVAorICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIFFOYW1lCisgKiBAbnM6ICB0aGUgYXR0cmlidXRlIG5hbWVzcGFjZSBVUkkKKyAqCisgKiBFdmFsdWF0ZSBhIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZSwgaS5lLiB0aGUgYXR0cmlidXRlIHZhbHVlIGNhbgorICogY29udGFpbiBleHByZXNzaW9ucyBjb250YWluZWQgaW4gY3VybHkgYnJhY2VzICh7fSkgYW5kIHRob3NlIGFyZQorICogc3Vic3RpdHV0ZWQgYnkgdGhleSBjb21wdXRlZCB2YWx1ZS4KKyAqCisgKiBSZXR1cm5zIHRoZSBjb21wdXRlZCBzdHJpbmcgdmFsdWUgb3IgTlVMTCwgbXVzdCBiZSBkZWFsbG9jYXRlZCBieSB0aGUKKyAqICAgIGNhbGxlci4KKyAqLworeG1sQ2hhciAqCit4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgaW5zdCwKKwkgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lLCBjb25zdCB4bWxDaGFyICpucykKK3sKKyAgICB4bWxDaGFyICpyZXQ7CisgICAgeG1sQ2hhciAqZXhwcjsKKworICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICBleHByID0geHNsdEdldE5zUHJvcChpbnN0LCBuYW1lLCBucyk7CisgICAgaWYgKGV4cHIgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICAvKgorICAgICAqIFRPRE86IHRob3VnaCBub3cge30gaXMgZGV0ZWN0ZWQgYWhlYWQsIGl0IHdvdWxkIHN0aWxsIGJlIGdvb2QgdG8KKyAgICAgKiAgICAgICBvcHRpbWl6ZSBib3RoIGZ1bmN0aW9ucyB0byBrZWVwIHRoZSBzcGxpdHRlZCB2YWx1ZSBpZiB0aGUKKyAgICAgKiAgICAgICBhdHRyaWJ1dGUgY29udGVudCBhbmQgdGhlIFhQYXRoIHByZWNvbXBpbGVkIGV4cHJlc3Npb25zIGFyb3VuZAorICAgICAqLworCisgICAgcmV0ID0geHNsdEF0dHJUZW1wbGF0ZVZhbHVlUHJvY2Vzc05vZGUoY3R4dCwgZXhwciwgaW5zdCk7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1RFTVBMQVRFUworICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1RFTVBMQVRFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAieHNsdEV2YWxBdHRyVmFsdWVUZW1wbGF0ZTogJXMgcmV0dXJucyAlc1xuIiwgZXhwciwgcmV0KSk7CisjZW5kaWYKKyAgICBpZiAoZXhwciAhPSBOVUxMKQorCXhtbEZyZWUoZXhwcik7CisgICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdEV2YWxTdGF0aWNBdHRyVmFsdWVUZW1wbGF0ZToKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBpbnN0OiAgdGhlIGluc3RydWN0aW9uIChvciBMUkUpIGluIHRoZSBzdHlsZXNoZWV0IGhvbGRpbmcgdGhlCisgKiAgICAgICAgIGF0dHJpYnV0ZSB3aXRoIGFuIEFWVAorICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIE5hbWUKKyAqIEBuczogIHRoZSBhdHRyaWJ1dGUgbmFtZXNwYWNlIFVSSQorICogQGZvdW5kOiAgaW5kaWNhdG9yIHdoZXRoZXIgdGhlIGF0dHJpYnV0ZSBpcyBwcmVzZW50CisgKgorICogQ2hlY2sgaWYgYW4gYXR0cmlidXRlIHZhbHVlIHRlbXBsYXRlIGhhcyBhIHN0YXRpYyB2YWx1ZSwgaS5lLiB0aGUKKyAqIGF0dHJpYnV0ZSB2YWx1ZSBkb2VzIG5vdCBjb250YWluIGV4cHJlc3Npb25zIGNvbnRhaW5lZCBpbiBjdXJseSBicmFjZXMgKHt9KQorICoKKyAqIFJldHVybnMgdGhlIHN0YXRpYyBzdHJpbmcgdmFsdWUgb3IgTlVMTCwgbXVzdCBiZSBkZWFsbG9jYXRlZCBieSB0aGUKKyAqICAgIGNhbGxlci4KKyAqLworY29uc3QgeG1sQ2hhciAqCit4c2x0RXZhbFN0YXRpY0F0dHJWYWx1ZVRlbXBsYXRlKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGluc3QsCisJCQljb25zdCB4bWxDaGFyICpuYW1lLCBjb25zdCB4bWxDaGFyICpucywgaW50ICpmb3VuZCkgeworICAgIGNvbnN0IHhtbENoYXIgKnJldDsKKyAgICB4bWxDaGFyICpleHByOworCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICBleHByID0geHNsdEdldE5zUHJvcChpbnN0LCBuYW1lLCBucyk7CisgICAgaWYgKGV4cHIgPT0gTlVMTCkgeworCSpmb3VuZCA9IDA7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICAqZm91bmQgPSAxOworCisgICAgcmV0ID0geG1sU3RyY2hyKGV4cHIsICd7Jyk7CisgICAgaWYgKHJldCAhPSBOVUxMKSB7CisJeG1sRnJlZShleHByKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIHJldCA9IHhtbERpY3RMb29rdXAoc3R5bGUtPmRpY3QsIGV4cHIsIC0xKTsKKyAgICB4bWxGcmVlKGV4cHIpOworICAgIHJldHVybihyZXQpOworfQorCisvKioKKyAqIHhzbHRBdHRyVGVtcGxhdGVQcm9jZXNzOgorICogQGN0eHQ6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAdGFyZ2V0OiAgdGhlIGVsZW1lbnQgd2hlcmUgdGhlIGF0dHJpYnV0ZSB3aWxsIGJlIGdyYWZ0ZWQKKyAqIEBhdHRyOiAgdGhlIGF0dHJpYnV0ZSBub2RlIG9mIGEgbGl0ZXJhbCByZXN1bHQgZWxlbWVudAorICoKKyAqIFByb2Nlc3Mgb25lIGF0dHJpYnV0ZSBvZiBhIExpdGVyYWwgUmVzdWx0IEVsZW1lbnQgKGluIHRoZSBzdHlsZXNoZWV0KS4KKyAqIEV2YWx1YXRlcyBBdHRyaWJ1dGUgVmFsdWUgVGVtcGxhdGVzIGFuZCBjb3BpZXMgdGhlIGF0dHJpYnV0ZSBvdmVyIHRvCisgKiB0aGUgcmVzdWx0IGVsZW1lbnQuCisgKiBUaGlzIGRvZXMgKm5vdCogcHJvY2VzcyBhdHRyaWJ1dGUgc2V0cyAoeHNsOnVzZS1hdHRyaWJ1dGUtc2V0KS4KKyAqIAorICoKKyAqIFJldHVybnMgdGhlIGdlbmVyYXRlZCBhdHRyaWJ1dGUgbm9kZS4KKyAqLworeG1sQXR0clB0cgoreHNsdEF0dHJUZW1wbGF0ZVByb2Nlc3MoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciB0YXJnZXQsCisJICAgICAgICAgICAgICAgIHhtbEF0dHJQdHIgYXR0cikKK3sKKyAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKKyAgICB4bWxBdHRyUHRyIHJldDsKKworICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoYXR0ciA9PSBOVUxMKSB8fCAodGFyZ2V0ID09IE5VTEwpKQorCXJldHVybihOVUxMKTsKKyAgICAKKyAgICBpZiAoYXR0ci0+dHlwZSAhPSBYTUxfQVRUUklCVVRFX05PREUpCisJcmV0dXJuKE5VTEwpOworCisgICAgLyoKKyAgICAqIFNraXAgYWxsIFhTTFQgYXR0cmlidXRlcy4KKyAgICAqLworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRCAgICAKKyAgICBpZiAoYXR0ci0+cHN2aSA9PSB4c2x0WFNMVEF0dHJNYXJrZXIpCisJcmV0dXJuKE5VTEwpOworI2Vsc2UKKyAgICBpZiAoKGF0dHItPm5zICE9IE5VTEwpICYmIHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCBYU0xUX05BTUVTUEFDRSkpCisJcmV0dXJuKE5VTEwpOworI2VuZGlmCisgICAgLyoKKyAgICAqIEdldCB0aGUgdmFsdWUuCisgICAgKi8KKyAgICBpZiAoYXR0ci0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCWlmICgoYXR0ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX1RFWFRfTk9ERSkgfHwKKwkgICAgKGF0dHItPmNoaWxkcmVuLT5uZXh0ICE9IE5VTEwpKQorCXsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGF0dHItPnBhcmVudCwKKwkJIkludGVybmFsIGVycm9yOiBUaGUgY2hpbGRyZW4gb2YgYW4gYXR0cmlidXRlIG5vZGUgb2YgYSAiCisJCSJsaXRlcmFsIHJlc3VsdCBlbGVtZW50IGFyZSBub3QgaW4gdGhlIGV4cGVjdGVkIGZvcm0uXG4iKTsKKwkgICAgcmV0dXJuKE5VTEwpOworCX0KKwl2YWx1ZSA9IGF0dHItPmNoaWxkcmVuLT5jb250ZW50OworCWlmICh2YWx1ZSA9PSBOVUxMKQorCSAgICB2YWx1ZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgQkFEX0NBU1QgIiIsIDApOworICAgIH0gZWxzZQorCXZhbHVlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBCQURfQ0FTVCAiIiwgMCk7CisgICAgLyoKKyAgICAqIE92ZXJ3cml0ZSBkdXBsaWNhdGVzLgorICAgICovCisgICAgcmV0ID0gdGFyZ2V0LT5wcm9wZXJ0aWVzOworICAgIHdoaWxlIChyZXQgIT0gTlVMTCkgeworICAgICAgICBpZiAoKChhdHRyLT5ucyAhPSBOVUxMKSA9PSAocmV0LT5ucyAhPSBOVUxMKSkgJiYKKwkgICAgeG1sU3RyRXF1YWwocmV0LT5uYW1lLCBhdHRyLT5uYW1lKSAmJgorCSAgICAoKGF0dHItPm5zID09IE5VTEwpIHx8IHhtbFN0ckVxdWFsKHJldC0+bnMtPmhyZWYsIGF0dHItPm5zLT5ocmVmKSkpCisJeworCSAgICBicmVhazsKKwl9CisgICAgICAgIHJldCA9IHJldC0+bmV4dDsKKyAgICB9CisgICAgaWYgKHJldCAhPSBOVUxMKSB7CQorICAgICAgICAvKiBmcmVlIHRoZSBleGlzdGluZyB2YWx1ZSAqLworCXhtbEZyZWVOb2RlTGlzdChyZXQtPmNoaWxkcmVuKTsKKwlyZXQtPmNoaWxkcmVuID0gcmV0LT5sYXN0ID0gTlVMTDsKKwkvKgorCSogQWRqdXN0IG5zLXByZWZpeCBpZiBuZWVkZWQuCisJKi8KKwlpZiAoKHJldC0+bnMgIT0gTlVMTCkgJiYKKwkgICAgKCEgeG1sU3RyRXF1YWwocmV0LT5ucy0+cHJlZml4LCBhdHRyLT5ucy0+cHJlZml4KSkpCisJeworCSAgICByZXQtPm5zID0geHNsdEdldE5hbWVzcGFjZShjdHh0LCBhdHRyLT5wYXJlbnQsIGF0dHItPm5zLCB0YXJnZXQpOworCX0KKyAgICB9IGVsc2UgeworICAgICAgICAvKiBjcmVhdGUgYSBuZXcgYXR0cmlidXRlICovCisJaWYgKGF0dHItPm5zICE9IE5VTEwpCisJICAgIHJldCA9IHhtbE5ld05zUHJvcCh0YXJnZXQsCisJCXhzbHRHZXROYW1lc3BhY2UoY3R4dCwgYXR0ci0+cGFyZW50LCBhdHRyLT5ucywgdGFyZ2V0KSwKKwkJICAgIGF0dHItPm5hbWUsIE5VTEwpOworCWVsc2UKKwkgICAgcmV0ID0geG1sTmV3TnNQcm9wKHRhcmdldCwgTlVMTCwgYXR0ci0+bmFtZSwgTlVMTCk7CQorICAgIH0KKyAgICAvKgorICAgICogU2V0IHRoZSB2YWx1ZS4KKyAgICAqLworICAgIGlmIChyZXQgIT0gTlVMTCkgeworICAgICAgICB4bWxOb2RlUHRyIHRleHQ7CisKKyAgICAgICAgdGV4dCA9IHhtbE5ld1RleHQoTlVMTCk7CisJaWYgKHRleHQgIT0gTlVMTCkgeworCSAgICByZXQtPmxhc3QgPSByZXQtPmNoaWxkcmVuID0gdGV4dDsKKwkgICAgdGV4dC0+cGFyZW50ID0gKHhtbE5vZGVQdHIpIHJldDsKKwkgICAgdGV4dC0+ZG9jID0gcmV0LT5kb2M7CisKKwkgICAgaWYgKGF0dHItPnBzdmkgIT0gTlVMTCkgeworCQkvKgorCQkqIEV2YWx1YXRlIHRoZSBBdHRyaWJ1dGUgVmFsdWUgVGVtcGxhdGUuCisJCSovCisJCXhtbENoYXIgKnZhbDsKKwkJdmFsID0geHNsdEV2YWxBVlQoY3R4dCwgYXR0ci0+cHN2aSwgYXR0ci0+cGFyZW50KTsKKwkJaWYgKHZhbCA9PSBOVUxMKSB7CisJCSAgICAvKgorCQkgICAgKiBUT0RPOiBEYW1uLCB3ZSBuZWVkIGFuIGVhc3kgbWVjaGFuaXNtIHRvIHJlcG9ydAorCQkgICAgKiBxdWFsaWZpZWQgbmFtZXMhCisJCSAgICAqLworCQkgICAgaWYgKGF0dHItPm5zKSB7CisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgYXR0ci0+cGFyZW50LAorCQkJICAgICJJbnRlcm5hbCBlcnJvcjogRmFpbGVkIHRvIGV2YWx1YXRlIHRoZSBBVlQgIgorCQkJICAgICJvZiBhdHRyaWJ1dGUgJ3slc30lcycuXG4iLAorCQkJICAgIGF0dHItPm5zLT5ocmVmLCBhdHRyLT5uYW1lKTsKKwkJICAgIH0gZWxzZSB7CisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgYXR0ci0+cGFyZW50LAorCQkJICAgICJJbnRlcm5hbCBlcnJvcjogRmFpbGVkIHRvIGV2YWx1YXRlIHRoZSBBVlQgIgorCQkJICAgICJvZiBhdHRyaWJ1dGUgJyVzJy5cbiIsCisJCQkgICAgYXR0ci0+bmFtZSk7CisJCSAgICB9CisJCSAgICB0ZXh0LT5jb250ZW50ID0geG1sU3RyZHVwKEJBRF9DQVNUICIiKTsKKwkJfSBlbHNlIHsKKwkJICAgIHRleHQtPmNvbnRlbnQgPSB2YWw7CisJCX0KKwkgICAgfSBlbHNlIGlmICgoY3R4dC0+aW50ZXJuYWxpemVkKSAmJiAodGFyZ2V0ICE9IE5VTEwpICYmCisJICAgICAgICAgICAgICAgKHRhcmdldC0+ZG9jICE9IE5VTEwpICYmCisJCSAgICAgICAodGFyZ2V0LT5kb2MtPmRpY3QgPT0gY3R4dC0+ZGljdCkpIHsKKwkJdGV4dC0+Y29udGVudCA9ICh4bWxDaGFyICopIHZhbHVlOworCSAgICB9IGVsc2UgeworCQl0ZXh0LT5jb250ZW50ID0geG1sU3RyZHVwKHZhbHVlKTsKKwkgICAgfQorCX0KKyAgICB9IGVsc2UgeworCWlmIChhdHRyLT5ucykgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgYXR0ci0+cGFyZW50LAorCSAgICAJIkludGVybmFsIGVycm9yOiBGYWlsZWQgdG8gY3JlYXRlIGF0dHJpYnV0ZSAneyVzfSVzJy5cbiIsCisJCWF0dHItPm5zLT5ocmVmLCBhdHRyLT5uYW1lKTsKKwl9IGVsc2UgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgYXR0ci0+cGFyZW50LAorCSAgICAJIkludGVybmFsIGVycm9yOiBGYWlsZWQgdG8gY3JlYXRlIGF0dHJpYnV0ZSAnJXMnLlxuIiwKKwkJYXR0ci0+bmFtZSk7CisJfQorICAgIH0KKyAgICByZXR1cm4ocmV0KTsKK30KKworCisvKioKKyAqIHhzbHRBdHRyTGlzdFRlbXBsYXRlUHJvY2VzczoKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQHRhcmdldDogIHRoZSBlbGVtZW50IHdoZXJlIHRoZSBhdHRyaWJ1dGVzIHdpbGwgYmUgZ3JhZnRlZAorICogQGF0dHJzOiAgdGhlIGZpcnN0IGF0dHJpYnV0ZQorICoKKyAqIFByb2Nlc3NlcyBhbGwgYXR0cmlidXRlcyBvZiBhIExpdGVyYWwgUmVzdWx0IEVsZW1lbnQuCisgKiBBdHRyaWJ1dGUgcmVmZXJlbmNlcyBhcmUgYXBwbGllZCB2aWEgeHNsOnVzZS1hdHRyaWJ1dGUtc2V0CisgKiBhdHRyaWJ1dGVzLgorICogQ29waWVzIGFsbCBub24gWFNMVC1hdHRyaWJ1dGVzIG92ZXIgdG8gdGhlIEB0YXJnZXQgZWxlbWVudAorICogYW5kIGV2YWx1YXRlcyBBdHRyaWJ1dGUgVmFsdWUgVGVtcGxhdGVzLgorICoKKyAqIENhbGxlZCBieSB4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yKCkgKHRyYW5zZm9ybS5jKS4KKyAqCisgKiBSZXR1cm5zIGEgbmV3IGxpc3Qgb2YgYXR0cmlidXRlIG5vZGVzLCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCisgKiAgICAgICAgIChEb24ndCBhc3NpZ24gdGhlIHJlc3VsdCB0byBAdGFyZ2V0LT5wcm9wZXJ0aWVzOyBpZgorICogICAgICAgICB0aGUgcmVzdWx0IGlzIE5VTEwsIHlvdSdsbCBnZXQgbWVtb3J5IGxlYWtzLCBzaW5jZSB0aGUKKyAqICAgICAgICAgYXR0cmlidXRlcyB3aWxsIGJlIGRpc2F0dGFjaGVkLikKKyAqLworeG1sQXR0clB0cgoreHNsdEF0dHJMaXN0VGVtcGxhdGVQcm9jZXNzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIAorCSAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciB0YXJnZXQsIHhtbEF0dHJQdHIgYXR0cnMpCit7CisgICAgeG1sQXR0clB0ciBhdHRyLCBjb3B5LCBsYXN0OworICAgIHhtbE5vZGVQdHIgb2xkSW5zZXJ0LCB0ZXh0OworICAgIHhtbE5zUHRyIG9yaWdOcyA9IE5VTEwsIGNvcHlOcyA9IE5VTEw7CisgICAgY29uc3QgeG1sQ2hhciAqdmFsdWU7CisgICAgeG1sQ2hhciAqdmFsdWVBVlQ7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHRhcmdldCA9PSBOVUxMKSB8fCAoYXR0cnMgPT0gTlVMTCkpCisJcmV0dXJuKE5VTEwpOworCisgICAgb2xkSW5zZXJ0ID0gY3R4dC0+aW5zZXJ0OworICAgIGN0eHQtPmluc2VydCA9IHRhcmdldDsgICAgICAgIAorCisgICAgLyoKKyAgICAqIEluc3RhbnRpYXRlIExSRS1hdHRyaWJ1dGVzLgorICAgICovCisgICAgaWYgKHRhcmdldC0+cHJvcGVydGllcykgeworCWxhc3QgPSB0YXJnZXQtPnByb3BlcnRpZXM7CisJd2hpbGUgKGxhc3QtPm5leHQgIT0gTlVMTCkKKwkgICAgbGFzdCA9IGxhc3QtPm5leHQ7CisgICAgfSBlbHNlIHsKKwlsYXN0ID0gTlVMTDsKKyAgICB9CisgICAgYXR0ciA9IGF0dHJzOworICAgIGRvIHsKKwkvKgorCSogU2tpcCBYU0xUIGF0dHJpYnV0ZXMuCisJKi8KKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwlpZiAoYXR0ci0+cHN2aSA9PSB4c2x0WFNMVEF0dHJNYXJrZXIpIHsKKwkgICAgZ290byBuZXh0X2F0dHJpYnV0ZTsKKwl9CisjZWxzZQorCWlmICgoYXR0ci0+bnMgIT0gTlVMTCkgJiYKKwkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIFhTTFRfTkFNRVNQQUNFKSkKKwl7CisJICAgIGdvdG8gbmV4dF9hdHRyaWJ1dGU7CisJfQorI2VuZGlmCisJLyoKKwkqIEdldCB0aGUgdmFsdWUuCisJKi8KKwlpZiAoYXR0ci0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCSAgICBpZiAoKGF0dHItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9URVhUX05PREUpIHx8CisJCShhdHRyLT5jaGlsZHJlbi0+bmV4dCAhPSBOVUxMKSkKKwkgICAgeworCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgYXR0ci0+cGFyZW50LAorCQkgICAgIkludGVybmFsIGVycm9yOiBUaGUgY2hpbGRyZW4gb2YgYW4gYXR0cmlidXRlIG5vZGUgb2YgYSAiCisJCSAgICAibGl0ZXJhbCByZXN1bHQgZWxlbWVudCBhcmUgbm90IGluIHRoZSBleHBlY3RlZCBmb3JtLlxuIik7CisJCWdvdG8gZXJyb3I7CisJICAgIH0KKwkgICAgdmFsdWUgPSBhdHRyLT5jaGlsZHJlbi0+Y29udGVudDsKKwkgICAgaWYgKHZhbHVlID09IE5VTEwpCisJCXZhbHVlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBCQURfQ0FTVCAiIiwgMCk7CisJfSBlbHNlCisJICAgIHZhbHVlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBCQURfQ0FTVCAiIiwgMCk7CisKKwkvKgorCSogQ3JlYXRlIGEgbmV3IGF0dHJpYnV0ZS4KKwkqLworCWNvcHkgPSB4bWxOZXdEb2NQcm9wKHRhcmdldC0+ZG9jLCBhdHRyLT5uYW1lLCBOVUxMKTsKKwlpZiAoY29weSA9PSBOVUxMKSB7CisJICAgIGlmIChhdHRyLT5ucykgeworCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgYXR0ci0+cGFyZW50LAorCQkgICAgIkludGVybmFsIGVycm9yOiBGYWlsZWQgdG8gY3JlYXRlIGF0dHJpYnV0ZSAneyVzfSVzJy5cbiIsCisJCSAgICBhdHRyLT5ucy0+aHJlZiwgYXR0ci0+bmFtZSk7CisJICAgIH0gZWxzZSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBhdHRyLT5wYXJlbnQsCisJCSAgICAiSW50ZXJuYWwgZXJyb3I6IEZhaWxlZCB0byBjcmVhdGUgYXR0cmlidXRlICclcycuXG4iLAorCQkgICAgYXR0ci0+bmFtZSk7CisJICAgIH0KKwkgICAgZ290byBlcnJvcjsKKwl9CisJLyoKKwkqIEF0dGFjaCBpdCB0byB0aGUgdGFyZ2V0IGVsZW1lbnQuCisJKi8KKwljb3B5LT5wYXJlbnQgPSB0YXJnZXQ7CisJaWYgKGxhc3QgPT0gTlVMTCkgeworCSAgICB0YXJnZXQtPnByb3BlcnRpZXMgPSBjb3B5OworCSAgICBsYXN0ID0gY29weTsKKwl9IGVsc2UgeworCSAgICBsYXN0LT5uZXh0ID0gY29weTsKKwkgICAgY29weS0+cHJldiA9IGxhc3Q7CisJICAgIGxhc3QgPSBjb3B5OworCX0KKwkvKgorCSogU2V0IHRoZSBuYW1lc3BhY2UuIEF2b2lkIGxvb2t1cHMgb2Ygc2FtZSBuYW1lc3BhY2VzLgorCSovCisJaWYgKGF0dHItPm5zICE9IG9yaWdOcykgeworCSAgICBvcmlnTnMgPSBhdHRyLT5uczsKKwkgICAgaWYgKGF0dHItPm5zICE9IE5VTEwpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwkJY29weU5zID0geHNsdEdldFNwZWNpYWxOYW1lc3BhY2UoY3R4dCwgYXR0ci0+cGFyZW50LAorCQkgICAgYXR0ci0+bnMtPmhyZWYsIGF0dHItPm5zLT5wcmVmaXgsIHRhcmdldCk7CisjZWxzZQorCQljb3B5TnMgPSB4c2x0R2V0TmFtZXNwYWNlKGN0eHQsIGF0dHItPnBhcmVudCwKKwkJICAgIGF0dHItPm5zLCB0YXJnZXQpOworI2VuZGlmCisJCWlmIChjb3B5TnMgPT0gTlVMTCkKKwkJICAgIGdvdG8gZXJyb3I7CisJICAgIH0gZWxzZQorCQljb3B5TnMgPSBOVUxMOworCX0KKwljb3B5LT5ucyA9IGNvcHlOczsKKworCS8qCisJKiBTZXQgdGhlIHZhbHVlLgorCSovCisJdGV4dCA9IHhtbE5ld1RleHQoTlVMTCk7CisJaWYgKHRleHQgIT0gTlVMTCkgeworCSAgICBjb3B5LT5sYXN0ID0gY29weS0+Y2hpbGRyZW4gPSB0ZXh0OworCSAgICB0ZXh0LT5wYXJlbnQgPSAoeG1sTm9kZVB0cikgY29weTsKKwkgICAgdGV4dC0+ZG9jID0gY29weS0+ZG9jOworCisJICAgIGlmIChhdHRyLT5wc3ZpICE9IE5VTEwpIHsKKwkJLyoKKwkJKiBFdmFsdWF0ZSB0aGUgQXR0cmlidXRlIFZhbHVlIFRlbXBsYXRlLgorCQkqLworCQl2YWx1ZUFWVCA9IHhzbHRFdmFsQVZUKGN0eHQsIGF0dHItPnBzdmksIGF0dHItPnBhcmVudCk7CisJCWlmICh2YWx1ZUFWVCA9PSBOVUxMKSB7CisJCSAgICAvKgorCQkgICAgKiBUT0RPOiBEYW1uLCB3ZSBuZWVkIGFuIGVhc3kgbWVjaGFuaXNtIHRvIHJlcG9ydAorCQkgICAgKiBxdWFsaWZpZWQgbmFtZXMhCisJCSAgICAqLworCQkgICAgaWYgKGF0dHItPm5zKSB7CisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgYXR0ci0+cGFyZW50LAorCQkJICAgICJJbnRlcm5hbCBlcnJvcjogRmFpbGVkIHRvIGV2YWx1YXRlIHRoZSBBVlQgIgorCQkJICAgICJvZiBhdHRyaWJ1dGUgJ3slc30lcycuXG4iLAorCQkJICAgIGF0dHItPm5zLT5ocmVmLCBhdHRyLT5uYW1lKTsKKwkJICAgIH0gZWxzZSB7CisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgYXR0ci0+cGFyZW50LAorCQkJICAgICJJbnRlcm5hbCBlcnJvcjogRmFpbGVkIHRvIGV2YWx1YXRlIHRoZSBBVlQgIgorCQkJICAgICJvZiBhdHRyaWJ1dGUgJyVzJy5cbiIsCisJCQkgICAgYXR0ci0+bmFtZSk7CisJCSAgICB9CisJCSAgICB0ZXh0LT5jb250ZW50ID0geG1sU3RyZHVwKEJBRF9DQVNUICIiKTsKKwkJICAgIGdvdG8gZXJyb3I7CisJCX0gZWxzZSB7CisJCSAgICB0ZXh0LT5jb250ZW50ID0gdmFsdWVBVlQ7CisJCX0KKwkgICAgfSBlbHNlIGlmICgoY3R4dC0+aW50ZXJuYWxpemVkKSAmJgorCQkodGFyZ2V0LT5kb2MgIT0gTlVMTCkgJiYKKwkJKHRhcmdldC0+ZG9jLT5kaWN0ID09IGN0eHQtPmRpY3QpKQorCSAgICB7CisJCXRleHQtPmNvbnRlbnQgPSAoeG1sQ2hhciAqKSB2YWx1ZTsKKwkgICAgfSBlbHNlIHsKKwkJdGV4dC0+Y29udGVudCA9IHhtbFN0cmR1cCh2YWx1ZSk7CisJICAgIH0KKyAgICAgICAgICAgIGlmICgoY29weSAhPSBOVUxMKSAmJiAodGV4dCAhPSBOVUxMKSAmJgorICAgICAgICAgICAgICAgICh4bWxJc0lEKGNvcHktPmRvYywgY29weS0+cGFyZW50LCBjb3B5KSkpCisgICAgICAgICAgICAgICAgeG1sQWRkSUQoTlVMTCwgY29weS0+ZG9jLCB0ZXh0LT5jb250ZW50LCBjb3B5KTsKKwl9CisKK25leHRfYXR0cmlidXRlOgorCWF0dHIgPSBhdHRyLT5uZXh0OworICAgIH0gd2hpbGUgKGF0dHIgIT0gTlVMTCk7CisKKyAgICAvKgorICAgICogQXBwbHkgYXR0cmlidXRlLXNldHMuCisgICAgKiBUaGUgY3JlYXRpb24gb2Ygc3VjaCBhdHRyaWJ1dGVzIHdpbGwgbm90IG92ZXJ3cml0ZSBhbnkgZXhpc3RpbmcKKyAgICAqIGF0dHJpYnV0ZS4KKyAgICAqLworICAgIGF0dHIgPSBhdHRyczsKKyAgICBkbyB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisJaWYgKChhdHRyLT5wc3ZpID09IHhzbHRYU0xUQXR0ck1hcmtlcikgJiYKKwkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikidXNlLWF0dHJpYnV0ZS1zZXRzIikpCisJeworCSAgICB4c2x0QXBwbHlBdHRyaWJ1dGVTZXQoY3R4dCwgY3R4dC0+bm9kZSwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwpOworCX0KKyNlbHNlCisJaWYgKChhdHRyLT5ucyAhPSBOVUxMKSAmJgorCSAgICB4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSJ1c2UtYXR0cmlidXRlLXNldHMiKSAmJgorCSAgICB4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgWFNMVF9OQU1FU1BBQ0UpKQorCXsKKwkgICAgeHNsdEFwcGx5QXR0cmlidXRlU2V0KGN0eHQsIGN0eHQtPm5vZGUsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMKTsKKwl9CisjZW5kaWYKKwlhdHRyID0gYXR0ci0+bmV4dDsKKyAgICB9IHdoaWxlIChhdHRyICE9IE5VTEwpOworCisgICAgY3R4dC0+aW5zZXJ0ID0gb2xkSW5zZXJ0OworICAgIHJldHVybih0YXJnZXQtPnByb3BlcnRpZXMpOworCitlcnJvcjoKKyAgICBjdHh0LT5pbnNlcnQgPSBvbGRJbnNlcnQ7CisgICAgcmV0dXJuKE5VTEwpOworfQorCisKKy8qKgorICogeHNsdFRlbXBsYXRlUHJvY2VzczoKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQG5vZGU6ICB0aGUgYXR0cmlidXRlIHRlbXBsYXRlIG5vZGUKKyAqCisgKiBPYnNvbGV0ZS4gRG9uJ3QgdXNlIGl0LgorICoKKyAqIFJldHVybnMgTlVMTC4KKyAqLworeG1sTm9kZVB0ciAqCit4c2x0VGVtcGxhdGVQcm9jZXNzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQgQVRUUklCVVRFX1VOVVNFRCwgeG1sTm9kZVB0ciBub2RlKSB7CisgICAgaWYgKG5vZGUgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisgICAgCisgICAgcmV0dXJuKDApOworfQorCisKZGlmZiAtLWdpdCBhL2xpYnhzbHQvdGVtcGxhdGVzLmggYi9saWJ4c2x0L3RlbXBsYXRlcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4YWRmZGIKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L3RlbXBsYXRlcy5oCkBAIC0wLDAgKzEsNzcgQEAKKy8qCisgKiBTdW1tYXJ5OiBpbnRlcmZhY2UgZm9yIHRoZSB0ZW1wbGF0ZSBwcm9jZXNzaW5nCisgKiBEZXNjcmlwdGlvbjogVGhpcyBzZXQgb2Ygcm91dGluZSBlbmNhcHN1bGF0ZXMgWFBhdGggY2FsbHMKKyAqICAgICAgICAgICAgICBhbmQgQXR0cmlidXRlIFZhbHVlIFRlbXBsYXRlcyBldmFsdWF0aW9uLgorICoKKyAqIENvcHk6IFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBBdXRob3I6IERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVF9URU1QTEFURVNfSF9fCisjZGVmaW5lIF9fWE1MX1hTTFRfVEVNUExBVEVTX0hfXworCisjaW5jbHVkZSA8bGlieG1sL3hwYXRoLmg+CisjaW5jbHVkZSA8bGlieG1sL3hwYXRoSW50ZXJuYWxzLmg+CisjaW5jbHVkZSAieHNsdGV4cG9ydHMuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwJCQorCQl4c2x0RXZhbFhQYXRoUHJlZGljYXRlCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4bWxYUGF0aENvbXBFeHByUHRyIGNvbXAsCisJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5zUHRyICpuc0xpc3QsCisJCQkJCQkgaW50IG5zTnIpOworWFNMVFBVQkZVTiB4bWxDaGFyICogWFNMVENBTEwJCisJCXhzbHRFdmFsVGVtcGxhdGVTdHJpbmcJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHhtbE5vZGVQdHIgY29udGV4dE5vZGUsCisJCQkJCQkgeG1sTm9kZVB0ciBpbnN0KTsKK1hTTFRQVUJGVU4geG1sQ2hhciAqIFhTTFRDQUxMCQorCQl4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJCSBjb25zdCB4bWxDaGFyICpuYW1lLAorCQkJCQkJIGNvbnN0IHhtbENoYXIgKm5zKTsKK1hTTFRQVUJGVU4gY29uc3QgeG1sQ2hhciAqIFhTTFRDQUxMCQorCQl4c2x0RXZhbFN0YXRpY0F0dHJWYWx1ZVRlbXBsYXRlCSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKwkJCQkJCSB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCQkgY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkJCQkJCSBjb25zdCB4bWxDaGFyICpucywKKwkJCQkJCSBpbnQgKmZvdW5kKTsKKworLyogVE9ETzogdGhpcyBpcyBvYnZpb3VzbHkgYnJva2VuIC4uLiB0aGUgbmFtZXNwYWNlcyBzaG91bGQgYmUgcGFzc2VkIHRvbyAhICovCitYU0xUUFVCRlVOIHhtbENoYXIgKiBYU0xUQ0FMTAkKKwkJeHNsdEV2YWxYUGF0aFN0cmluZwkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgeG1sWFBhdGhDb21wRXhwclB0ciBjb21wKTsKK1hTTFRQVUJGVU4geG1sQ2hhciAqIFhTTFRDQUxMCQorCQl4c2x0RXZhbFhQYXRoU3RyaW5nTnMJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHhtbFhQYXRoQ29tcEV4cHJQdHIgY29tcCwKKwkJCQkJCSBpbnQgbnNOciwKKwkJCQkJCSB4bWxOc1B0ciAqbnNMaXN0KTsKKworWFNMVFBVQkZVTiB4bWxOb2RlUHRyICogWFNMVENBTEwJCisJCXhzbHRUZW1wbGF0ZVByb2Nlc3MJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHhtbE5vZGVQdHIgbm9kZSk7CitYU0xUUFVCRlVOIHhtbEF0dHJQdHIgWFNMVENBTEwJCisJCXhzbHRBdHRyTGlzdFRlbXBsYXRlUHJvY2VzcwkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4bWxOb2RlUHRyIHRhcmdldCwKKwkJCQkJCSB4bWxBdHRyUHRyIGN1cik7CitYU0xUUFVCRlVOIHhtbEF0dHJQdHIgWFNMVENBTEwJCisJCXhzbHRBdHRyVGVtcGxhdGVQcm9jZXNzCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4bWxOb2RlUHRyIHRhcmdldCwKKwkJCQkJCSB4bWxBdHRyUHRyIGF0dHIpOworWFNMVFBVQkZVTiB4bWxDaGFyICogWFNMVENBTEwJCisJCXhzbHRBdHRyVGVtcGxhdGVWYWx1ZVByb2Nlc3MJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgY29uc3QgeG1sQ2hhciogYXR0cik7CitYU0xUUFVCRlVOIHhtbENoYXIgKiBYU0xUQ0FMTAkKKwkJeHNsdEF0dHJUZW1wbGF0ZVZhbHVlUHJvY2Vzc05vZGUoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSBjb25zdCB4bWxDaGFyKiBzdHIsCisJCQkJCQkgeG1sTm9kZVB0ciBub2RlKTsKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX1RFTVBMQVRFU19IX18gKi8KKwpkaWZmIC0tZ2l0IGEvbGlieHNsdC90cmFuc2Zvcm0uYyBiL2xpYnhzbHQvdHJhbnNmb3JtLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTRjYTQxZAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQvdHJhbnNmb3JtLmMKQEAgLTAsMCArMSw2NDc1IEBACisvKgorICogdHJhbnNmb3JtLmM6IEltcGxlbWVudGF0aW9uIG9mIHRoZSBYU0wgVHJhbnNmb3JtYXRpb24gMS4wIGVuZ2luZQorICogICAgICAgICAgICAgIHRyYW5zZm9ybSBwYXJ0LCBpLmUuIGFwcGx5aW5nIGEgU3R5bGVzaGVldCB0byBhIGRvY3VtZW50CisgKgorICogUmVmZXJlbmNlczoKKyAqICAgaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteHNsdC0xOTk5MTExNgorICoKKyAqICAgTWljaGFlbCBLYXkgIlhTTFQgUHJvZ3JhbW1lcidzIFJlZmVyZW5jZSIgcHAgNjM3LTY0MworICogICBXcml0aW5nIE11bHRpcGxlIE91dHB1dCBGaWxlcworICoKKyAqICAgWFNMVC0xLjEgV29ya2luZyBEcmFmdAorICogICBodHRwOi8vd3d3LnczLm9yZy9UUi94c2x0MTEjbXVsdGlwbGUtb3V0cHV0CisgKgorICogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIGRhbmllbEB2ZWlsbGFyZC5jb20KKyAqLworCisjZGVmaW5lIElOX0xJQlhTTFQKKyNpbmNsdWRlICJsaWJ4c2x0LmgiCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2luY2x1ZGUgPGxpYnhtbC94bWxtZW1vcnkuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvcGFyc2VyLmg+CisjaW5jbHVkZSA8bGlieG1sL3RyZWUuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdmFsaWQuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvaGFzaC5oPgorI2luY2x1ZGUgPGxpYnhtbC9lbmNvZGluZy5oPgorI2luY2x1ZGUgPGxpYnhtbC94bWxlcnJvci5oPgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aC5oPgorI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KKyNpbmNsdWRlIDxsaWJ4bWwveHBhdGhJbnRlcm5hbHMuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvSFRNTHRyZWUuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvZGVidWdYTUwuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdXJpLmg+CisjaW5jbHVkZSAieHNsdC5oIgorI2luY2x1ZGUgInhzbHRJbnRlcm5hbHMuaCIKKyNpbmNsdWRlICJ4c2x0dXRpbHMuaCIKKyNpbmNsdWRlICJwYXR0ZXJuLmgiCisjaW5jbHVkZSAidHJhbnNmb3JtLmgiCisjaW5jbHVkZSAidmFyaWFibGVzLmgiCisjaW5jbHVkZSAibnVtYmVyc0ludGVybmFscy5oIgorI2luY2x1ZGUgIm5hbWVzcGFjZXMuaCIKKyNpbmNsdWRlICJhdHRyaWJ1dGVzLmgiCisjaW5jbHVkZSAidGVtcGxhdGVzLmgiCisjaW5jbHVkZSAiaW1wb3J0cy5oIgorI2luY2x1ZGUgImtleXMuaCIKKyNpbmNsdWRlICJkb2N1bWVudHMuaCIKKyNpbmNsdWRlICJleHRlbnNpb25zLmgiCisjaW5jbHVkZSAiZXh0cmEuaCIKKyNpbmNsdWRlICJwcmVwcm9jLmgiCisjaW5jbHVkZSAic2VjdXJpdHkuaCIKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworI2RlZmluZSBXSVRIX1hTTFRfREVCVUdfRVhUUkEKKyNkZWZpbmUgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKyNlbmRpZgorCisjZGVmaW5lIFhTTFRfR0VORVJBVEVfSFRNTF9ET0NUWVBFCisjaWZkZWYgWFNMVF9HRU5FUkFURV9IVE1MX0RPQ1RZUEUKK3N0YXRpYyBpbnQgeHNsdEdldEhUTUxJRHMoY29uc3QgeG1sQ2hhciAqdmVyc2lvbiwgY29uc3QgeG1sQ2hhciAqKnB1YmxpY0lELAorCQkJICBjb25zdCB4bWxDaGFyICoqc3lzdGVtSUQpOworI2VuZGlmCisKK2ludCB4c2x0TWF4RGVwdGggPSAzMDAwOworCisvKgorICogVXNlZnVsIG1hY3JvcworICovCisKKyNpZm5kZWYgRkFMU0UKKyMgZGVmaW5lIEZBTFNFICgwID09IDEpCisjIGRlZmluZSBUUlVFICghRkFMU0UpCisjZW5kaWYKKworI2RlZmluZSBJU19CTEFOS19OT0RFKG4pCQkJCQkJXAorICAgICgoKG4pLT50eXBlID09IFhNTF9URVhUX05PREUpICYmICh4c2x0SXNCbGFuaygobiktPmNvbnRlbnQpKSkKKworCisvKgorKiBGb3J3YXJkIGRlY2xhcmF0aW9ucworKi8KKworc3RhdGljIHhtbE5zUHRyCit4c2x0Q29weU5hbWVzcGFjZUxpc3RJbnRlcm5hbCh4bWxOb2RlUHRyIG5vZGUsIHhtbE5zUHRyIGN1cik7CisKK3N0YXRpYyB4bWxOb2RlUHRyCit4c2x0Q29weVRyZWVJbnRlcm5hbCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkgICAgIHhtbE5vZGVQdHIgaW52b2NOb2RlLAorCQkgICAgIHhtbE5vZGVQdHIgbm9kZSwKKwkJICAgICB4bWxOb2RlUHRyIGluc2VydCwgaW50IGlzTFJFLCBpbnQgdG9wRWxlbVZpc2l0ZWQpOworCitzdGF0aWMgdm9pZAoreHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3Rvcih4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJICAgICB4bWxOb2RlUHRyIGNvbnRleHROb2RlLCB4bWxOb2RlUHRyIGxpc3QsCisJCQkgICAgIHhzbHRUZW1wbGF0ZVB0ciB0ZW1wbCk7CisKK3N0YXRpYyB2b2lkCit4c2x0QXBwbHlYU0xUVGVtcGxhdGUoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJICAgICAgeG1sTm9kZVB0ciBjb250ZXh0Tm9kZSwKKwkJICAgICAgeG1sTm9kZVB0ciBsaXN0LAorCQkgICAgICB4c2x0VGVtcGxhdGVQdHIgdGVtcGwsCisJCSAgICAgIHhzbHRTdGFja0VsZW1QdHIgd2l0aFBhcmFtcyk7CisKKy8qKgorICogdGVtcGxQdXNoOgorICogQGN0eHQ6IHRoZSB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAdmFsdWU6ICB0aGUgdGVtcGxhdGUgdG8gcHVzaCBvbiB0aGUgc3RhY2sKKyAqCisgKiBQdXNoIGEgdGVtcGxhdGUgb24gdGhlIHN0YWNrCisgKgorICogUmV0dXJucyB0aGUgbmV3IGluZGV4IGluIHRoZSBzdGFjayBvciAwIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworc3RhdGljIGludAordGVtcGxQdXNoKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhzbHRUZW1wbGF0ZVB0ciB2YWx1ZSkKK3sKKyAgICBpZiAoY3R4dC0+dGVtcGxNYXggPT0gMCkgeworICAgICAgICBjdHh0LT50ZW1wbE1heCA9IDQ7CisgICAgICAgIGN0eHQtPnRlbXBsVGFiID0KKyAgICAgICAgICAgICh4c2x0VGVtcGxhdGVQdHIgKikgeG1sTWFsbG9jKGN0eHQtPnRlbXBsTWF4ICoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihjdHh0LT50ZW1wbFRhYlswXSkpOworICAgICAgICBpZiAoY3R4dC0+dGVtcGxUYWIgPT0gTlVMTCkgeworICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJtYWxsb2MgZmFpbGVkICFcbiIpOworICAgICAgICAgICAgcmV0dXJuICgwKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoY3R4dC0+dGVtcGxOciA+PSBjdHh0LT50ZW1wbE1heCkgeworICAgICAgICBjdHh0LT50ZW1wbE1heCAqPSAyOworICAgICAgICBjdHh0LT50ZW1wbFRhYiA9CisgICAgICAgICAgICAoeHNsdFRlbXBsYXRlUHRyICopIHhtbFJlYWxsb2MoY3R4dC0+dGVtcGxUYWIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+dGVtcGxNYXggKgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihjdHh0LT50ZW1wbFRhYlswXSkpOworICAgICAgICBpZiAoY3R4dC0+dGVtcGxUYWIgPT0gTlVMTCkgeworICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJyZWFsbG9jIGZhaWxlZCAhXG4iKTsKKyAgICAgICAgICAgIHJldHVybiAoMCk7CisgICAgICAgIH0KKyAgICB9CisgICAgY3R4dC0+dGVtcGxUYWJbY3R4dC0+dGVtcGxOcl0gPSB2YWx1ZTsKKyAgICBjdHh0LT50ZW1wbCA9IHZhbHVlOworICAgIHJldHVybiAoY3R4dC0+dGVtcGxOcisrKTsKK30KKy8qKgorICogdGVtcGxQb3A6CisgKiBAY3R4dDogdGhlIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqCisgKiBQb3AgYSB0ZW1wbGF0ZSB2YWx1ZSBmcm9tIHRoZSBzdGFjaworICoKKyAqIFJldHVybnMgdGhlIHN0b3JlZCB0ZW1wbGF0ZSB2YWx1ZQorICovCitzdGF0aWMgeHNsdFRlbXBsYXRlUHRyCit0ZW1wbFBvcCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KQoreworICAgIHhzbHRUZW1wbGF0ZVB0ciByZXQ7CisKKyAgICBpZiAoY3R4dC0+dGVtcGxOciA8PSAwKQorICAgICAgICByZXR1cm4gKDApOworICAgIGN0eHQtPnRlbXBsTnItLTsKKyAgICBpZiAoY3R4dC0+dGVtcGxOciA+IDApCisgICAgICAgIGN0eHQtPnRlbXBsID0gY3R4dC0+dGVtcGxUYWJbY3R4dC0+dGVtcGxOciAtIDFdOworICAgIGVsc2UKKyAgICAgICAgY3R4dC0+dGVtcGwgPSAoeHNsdFRlbXBsYXRlUHRyKSAwOworICAgIHJldCA9IGN0eHQtPnRlbXBsVGFiW2N0eHQtPnRlbXBsTnJdOworICAgIGN0eHQtPnRlbXBsVGFiW2N0eHQtPnRlbXBsTnJdID0gMDsKKyAgICByZXR1cm4gKHJldCk7Cit9CisKKy8qKgorICogeHNsdExvY2FsVmFyaWFibGVQb3A6CisgKiBAY3R4dDogdGhlIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBsaW1pdE5yOiBudW1iZXIgb2YgdmFyaWFibGVzIHdoaWNoIHNob3VsZCByZW1haW4KKyAqIEBsZXZlbDogdGhlIGRlcHRoIGluIHRoZSB4c2w6dGVtcGxhdGUncyB0cmVlCisgKgorICogUG9wcyBhbGwgdmFyaWFibGUgdmFsdWVzIGF0IHRoZSBnaXZlbiBAZGVwdGggZnJvbSB0aGUgc3RhY2suCisgKgorICogUmV0dXJucyB0aGUgc3RvcmVkIHZhcmlhYmxlIHZhbHVlCisgKiAqKk5PVEU6KioKKyAqIFRoaXMgaXMgYW4gaW50ZXJuYWwgcm91dGluZSBhbmQgc2hvdWxkIG5vdCBiZSBjYWxsZWQgYnkgdXNlcnMhCisgKi8KK3ZvaWQKK3hzbHRMb2NhbFZhcmlhYmxlUG9wKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIGludCBsaW1pdE5yLCBpbnQgbGV2ZWwpCit7CisgICAgeHNsdFN0YWNrRWxlbVB0ciB2YXJpYWJsZTsKKworICAgIGlmIChjdHh0LT52YXJzTnIgPD0gMCkKKyAgICAgICAgcmV0dXJuOworCisgICAgZG8geworCWlmIChjdHh0LT52YXJzTnIgPD0gbGltaXROcikKKwkgICAgYnJlYWs7CisJdmFyaWFibGUgPSBjdHh0LT52YXJzVGFiW2N0eHQtPnZhcnNOciAtIDFdOworCWlmICh2YXJpYWJsZS0+bGV2ZWwgPD0gbGV2ZWwpCisJICAgIGJyZWFrOworCWlmICh2YXJpYWJsZS0+bGV2ZWwgPj0gMCkKKwkgICAgeHNsdEZyZWVTdGFja0VsZW1MaXN0KHZhcmlhYmxlKTsKKwljdHh0LT52YXJzTnItLTsKKyAgICB9IHdoaWxlIChjdHh0LT52YXJzTnIgIT0gMCk7CisgICAgaWYgKGN0eHQtPnZhcnNOciA+IDApCisgICAgICAgIGN0eHQtPnZhcnMgPSBjdHh0LT52YXJzVGFiW2N0eHQtPnZhcnNOciAtIDFdOworICAgIGVsc2UKKyAgICAgICAgY3R4dC0+dmFycyA9IE5VTEw7Cit9CisKKy8qKgorICogeHNsdFRlbXBsYXRlUGFyYW1zQ2xlYW51cDoKKyAqCisgKiBSZW1vdmVzIHhzbDpwYXJhbSBhbmQgeHNsOndpdGgtcGFyYW0gaXRlbXMgZnJvbSB0aGUKKyAqIHZhcmlhYmxlLXN0YWNrLiBPbmx5IHhzbDp3aXRoLXBhcmFtIGl0ZW1zIGFyZSBub3QgZnJlZWQuCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0VGVtcGxhdGVQYXJhbXNDbGVhbnVwKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpCit7CisgICAgeHNsdFN0YWNrRWxlbVB0ciBwYXJhbTsKKworICAgIGZvciAoOyBjdHh0LT52YXJzTnIgPiBjdHh0LT52YXJzQmFzZTsgY3R4dC0+dmFyc05yLS0pIHsKKwlwYXJhbSA9IGN0eHQtPnZhcnNUYWJbY3R4dC0+dmFyc05yIC0xXTsKKwkvKgorCSogRnJlZSB4c2w6cGFyYW0gaXRlbXMuCisJKiB4c2w6d2l0aC1wYXJhbSBpdGVtcyB3aWxsIGhhdmUgYSBsZXZlbCBvZiAtMSBvciAtMi4KKwkqLworCWlmIChwYXJhbS0+bGV2ZWwgPj0gMCkgeworCSAgICB4c2x0RnJlZVN0YWNrRWxlbUxpc3QocGFyYW0pOworCX0KKyAgICB9CisgICAgaWYgKGN0eHQtPnZhcnNOciA+IDApCisgICAgICAgIGN0eHQtPnZhcnMgPSBjdHh0LT52YXJzVGFiW2N0eHQtPnZhcnNOciAtIDFdOworICAgIGVsc2UKKyAgICAgICAgY3R4dC0+dmFycyA9IE5VTEw7Cit9CisKKy8qKgorICogcHJvZlB1c2g6CisgKiBAY3R4dDogdGhlIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEB2YWx1ZTogIHRoZSBwcm9maWxpbmcgdmFsdWUgdG8gcHVzaCBvbiB0aGUgc3RhY2sKKyAqCisgKiBQdXNoIGEgcHJvZmlsaW5nIHZhbHVlIG9uIHRoZSBzdGFjaworICoKKyAqIFJldHVybnMgdGhlIG5ldyBpbmRleCBpbiB0aGUgc3RhY2sgb3IgMCBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3N0YXRpYyBpbnQKK3Byb2ZQdXNoKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIGxvbmcgdmFsdWUpCit7CisgICAgaWYgKGN0eHQtPnByb2ZNYXggPT0gMCkgeworICAgICAgICBjdHh0LT5wcm9mTWF4ID0gNDsKKyAgICAgICAgY3R4dC0+cHJvZlRhYiA9CisgICAgICAgICAgICAobG9uZyAqKSB4bWxNYWxsb2MoY3R4dC0+cHJvZk1heCAqIHNpemVvZihjdHh0LT5wcm9mVGFiWzBdKSk7CisgICAgICAgIGlmIChjdHh0LT5wcm9mVGFiID09IE5VTEwpIHsKKyAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWFsbG9jIGZhaWxlZCAhXG4iKTsKKyAgICAgICAgICAgIHJldHVybiAoMCk7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKGN0eHQtPnByb2ZOciA+PSBjdHh0LT5wcm9mTWF4KSB7CisgICAgICAgIGN0eHQtPnByb2ZNYXggKj0gMjsKKyAgICAgICAgY3R4dC0+cHJvZlRhYiA9CisgICAgICAgICAgICAobG9uZyAqKSB4bWxSZWFsbG9jKGN0eHQtPnByb2ZUYWIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnByb2ZNYXggKiBzaXplb2YoY3R4dC0+cHJvZlRhYlswXSkpOworICAgICAgICBpZiAoY3R4dC0+cHJvZlRhYiA9PSBOVUxMKSB7CisgICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgInJlYWxsb2MgZmFpbGVkICFcbiIpOworICAgICAgICAgICAgcmV0dXJuICgwKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBjdHh0LT5wcm9mVGFiW2N0eHQtPnByb2ZOcl0gPSB2YWx1ZTsKKyAgICBjdHh0LT5wcm9mID0gdmFsdWU7CisgICAgcmV0dXJuIChjdHh0LT5wcm9mTnIrKyk7Cit9CisvKioKKyAqIHByb2ZQb3A6CisgKiBAY3R4dDogdGhlIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqCisgKiBQb3AgYSBwcm9maWxpbmcgdmFsdWUgZnJvbSB0aGUgc3RhY2sKKyAqCisgKiBSZXR1cm5zIHRoZSBzdG9yZWQgcHJvZmlsaW5nIHZhbHVlCisgKi8KK3N0YXRpYyBsb25nCitwcm9mUG9wKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpCit7CisgICAgbG9uZyByZXQ7CisKKyAgICBpZiAoY3R4dC0+cHJvZk5yIDw9IDApCisgICAgICAgIHJldHVybiAoMCk7CisgICAgY3R4dC0+cHJvZk5yLS07CisgICAgaWYgKGN0eHQtPnByb2ZOciA+IDApCisgICAgICAgIGN0eHQtPnByb2YgPSBjdHh0LT5wcm9mVGFiW2N0eHQtPnByb2ZOciAtIDFdOworICAgIGVsc2UKKyAgICAgICAgY3R4dC0+cHJvZiA9IChsb25nKSAwOworICAgIHJldCA9IGN0eHQtPnByb2ZUYWJbY3R4dC0+cHJvZk5yXTsKKyAgICBjdHh0LT5wcm9mVGFiW2N0eHQtPnByb2ZOcl0gPSAwOworICAgIHJldHVybiAocmV0KTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJCVhJbmNsdWRlIGRlZmF1bHQgc2V0dGluZ3MJCQkqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3N0YXRpYyBpbnQgeHNsdERvWEluY2x1ZGVEZWZhdWx0ID0gMDsKKworLyoqCisgKiB4c2x0U2V0WEluY2x1ZGVEZWZhdWx0OgorICogQHhpbmNsdWRlOiB3aGV0aGVyIHRvIGRvIFhJbmNsdWRlIHByb2Nlc3NpbmcKKyAqCisgKiBTZXQgd2hldGhlciBYSW5jbHVkZSBzaG91bGQgYmUgcHJvY2Vzc2VkIG9uIGRvY3VtZW50IGJlaW5nIGxvYWRlZCBieSBkZWZhdWx0CisgKi8KK3ZvaWQKK3hzbHRTZXRYSW5jbHVkZURlZmF1bHQoaW50IHhpbmNsdWRlKSB7CisgICAgeHNsdERvWEluY2x1ZGVEZWZhdWx0ID0gKHhpbmNsdWRlICE9IDApOworfQorCisvKioKKyAqIHhzbHRHZXRYSW5jbHVkZURlZmF1bHQ6CisgKgorICogUHJvdmlkZXMgdGhlIGRlZmF1bHQgc3RhdGUgZm9yIFhJbmNsdWRlIHByb2Nlc3NpbmcKKyAqCisgKiBSZXR1cm5zIDAgaWYgdGhlcmUgaXMgbm8gcHJvY2Vzc2luZyAxIG90aGVyd2lzZQorICovCitpbnQKK3hzbHRHZXRYSW5jbHVkZURlZmF1bHQodm9pZCkgeworICAgIHJldHVybih4c2x0RG9YSW5jbHVkZURlZmF1bHQpOworfQorCit1bnNpZ25lZCBsb25nIHhzbHREZWZhdWx0VHJhY2UgPSAodW5zaWduZWQgbG9uZykgWFNMVF9UUkFDRV9BTEw7CisKKy8qKgorICogeHNsdERlYnVnU2V0RGVmYXVsdFRyYWNlOgorICogQHZhbDogdHJhY2luZyBsZXZlbCBtYXNrCisgKgorICogU2V0IHRoZSBkZWZhdWx0IGRlYnVnIHRyYWNpbmcgbGV2ZWwgbWFzaworICovCit2b2lkIHhzbHREZWJ1Z1NldERlZmF1bHRUcmFjZSh4c2x0RGVidWdUcmFjZUNvZGVzIHZhbCkgeworCXhzbHREZWZhdWx0VHJhY2UgPSB2YWw7Cit9CisKKy8qKgorICogeHNsdERlYnVnR2V0RGVmYXVsdFRyYWNlOgorICoKKyAqIEdldCB0aGUgY3VycmVudCBkZWZhdWx0IGRlYnVnIHRyYWNpbmcgbGV2ZWwgbWFzaworICoKKyAqIFJldHVybnMgdGhlIGN1cnJlbnQgZGVmYXVsdCBkZWJ1ZyB0cmFjaW5nIGxldmVsIG1hc2sKKyAqLworeHNsdERlYnVnVHJhY2VDb2RlcyB4c2x0RGVidWdHZXREZWZhdWx0VHJhY2UoKSB7CisJcmV0dXJuIHhzbHREZWZhdWx0VHJhY2U7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICoJCQlIYW5kbGluZyBvZiBUcmFuc2Zvcm1hdGlvbiBDb250ZXh0cwkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitzdGF0aWMgeHNsdFRyYW5zZm9ybUNhY2hlUHRyCit4c2x0VHJhbnNmb3JtQ2FjaGVDcmVhdGUodm9pZCkKK3sKKyAgICB4c2x0VHJhbnNmb3JtQ2FjaGVQdHIgcmV0OworCisgICAgcmV0ID0gKHhzbHRUcmFuc2Zvcm1DYWNoZVB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0VHJhbnNmb3JtQ2FjaGUpKTsKKyAgICBpZiAocmV0ID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwKKwkgICAgInhzbHRUcmFuc2Zvcm1DYWNoZUNyZWF0ZSA6IG1hbGxvYyBmYWlsZWRcbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhzbHRUcmFuc2Zvcm1DYWNoZSkpOworICAgIHJldHVybihyZXQpOworfQorCitzdGF0aWMgdm9pZAoreHNsdFRyYW5zZm9ybUNhY2hlRnJlZSh4c2x0VHJhbnNmb3JtQ2FjaGVQdHIgY2FjaGUpCit7CisgICAgaWYgKGNhY2hlID09IE5VTEwpCisJcmV0dXJuOworICAgIC8qCisgICAgKiBGcmVlIHRyZWUgZnJhZ21lbnRzLgorICAgICovCisgICAgaWYgKGNhY2hlLT5SVlQpIHsKKwl4bWxEb2NQdHIgdG1wLCBjdXIgPSBjYWNoZS0+UlZUOworCXdoaWxlIChjdXIpIHsKKwkgICAgdG1wID0gY3VyOworCSAgICBjdXIgPSAoeG1sRG9jUHRyKSBjdXItPm5leHQ7CisJICAgIGlmICh0bXAtPl9wcml2YXRlICE9IE5VTEwpIHsKKwkJLyoKKwkJKiBUcmVlIHRoZSBkb2N1bWVudCBpbmZvLgorCQkqLworCQl4c2x0RnJlZURvY3VtZW50S2V5cygoeHNsdERvY3VtZW50UHRyKSB0bXAtPl9wcml2YXRlKTsKKwkJeG1sRnJlZSh0bXAtPl9wcml2YXRlKTsKKwkgICAgfQorCSAgICB4bWxGcmVlRG9jKHRtcCk7CisJfQorICAgIH0KKyAgICAvKgorICAgICogRnJlZSB2YXJzL3BhcmFtcy4KKyAgICAqLworICAgIGlmIChjYWNoZS0+c3RhY2tJdGVtcykgeworCXhzbHRTdGFja0VsZW1QdHIgdG1wLCBjdXIgPSBjYWNoZS0+c3RhY2tJdGVtczsKKwl3aGlsZSAoY3VyKSB7CisJICAgIHRtcCA9IGN1cjsKKwkgICAgY3VyID0gY3VyLT5uZXh0OworCSAgICAvKgorCSAgICAqIFJFVklTSVQgVE9ETzogU2hvdWxkIGJlIGNhbGwgYSBkZXN0cnVjdGlvbi1mdW5jdGlvbgorCSAgICAqIGluc3RlYWQ/CisJICAgICovCisJICAgIHhtbEZyZWUodG1wKTsKKwl9CisgICAgfQorICAgIHhtbEZyZWUoY2FjaGUpOworfQorCisvKioKKyAqIHhzbHROZXdUcmFuc2Zvcm1Db250ZXh0OgorICogQHN0eWxlOiAgYSBwYXJzZWQgWFNMVCBzdHlsZXNoZWV0CisgKiBAZG9jOiAgdGhlIGlucHV0IGRvY3VtZW50CisgKgorICogQ3JlYXRlIGEgbmV3IFhTTFQgVHJhbnNmb3JtQ29udGV4dAorICoKKyAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIKK3hzbHROZXdUcmFuc2Zvcm1Db250ZXh0KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxEb2NQdHIgZG9jKSB7CisgICAgeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3VyOworICAgIHhzbHREb2N1bWVudFB0ciBkb2N1OworICAgIGludCBpOworCisgICAgeHNsdEluaXRHbG9iYWxzKCk7CisKKyAgICBjdXIgPSAoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeHNsdFRyYW5zZm9ybUNvbnRleHQpKTsKKyAgICBpZiAoY3VyID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpZG9jLAorCQkieHNsdE5ld1RyYW5zZm9ybUNvbnRleHQgOiBtYWxsb2MgZmFpbGVkXG4iKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIG1lbXNldChjdXIsIDAsIHNpemVvZih4c2x0VHJhbnNmb3JtQ29udGV4dCkpOworCisgICAgY3VyLT5jYWNoZSA9IHhzbHRUcmFuc2Zvcm1DYWNoZUNyZWF0ZSgpOworICAgIGlmIChjdXItPmNhY2hlID09IE5VTEwpCisJZ290byBpbnRlcm5hbF9lcnI7CisgICAgLyoKKyAgICAgKiBzZXR1cCBvZiB0aGUgZGljdGlvbmFyeSBtdXN0IGJlIGRvbmUgZWFybHkgYXMgc29tZSBvZiB0aGUKKyAgICAgKiBwcm9jZXNzaW5nIGxhdGVyIGxpa2Uga2V5IGhhbmRsaW5nIG1heSBuZWVkIGl0LgorICAgICAqLworICAgIGN1ci0+ZGljdCA9IHhtbERpY3RDcmVhdGVTdWIoc3R5bGUtPmRpY3QpOworICAgIGN1ci0+aW50ZXJuYWxpemVkID0gKChzdHlsZS0+aW50ZXJuYWxpemVkKSAmJiAoY3VyLT5kaWN0ICE9IE5VTEwpKTsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgIkNyZWF0aW5nIHN1Yi1kaWN0aW9uYXJ5IGZyb20gc3R5bGVzaGVldCBmb3IgdHJhbnNmb3JtYXRpb25cbiIpOworI2VuZGlmCisKKyAgICAvKgorICAgICAqIGluaXRpYWxpemUgdGhlIHRlbXBsYXRlIHN0YWNrCisgICAgICovCisgICAgY3VyLT50ZW1wbFRhYiA9ICh4c2x0VGVtcGxhdGVQdHIgKikKKwkgICAgICAgIHhtbE1hbGxvYygxMCAqIHNpemVvZih4c2x0VGVtcGxhdGVQdHIpKTsKKyAgICBpZiAoY3VyLT50ZW1wbFRhYiA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBkb2MsCisJCSJ4c2x0TmV3VHJhbnNmb3JtQ29udGV4dDogb3V0IG9mIG1lbW9yeVxuIik7CisJZ290byBpbnRlcm5hbF9lcnI7CisgICAgfQorICAgIGN1ci0+dGVtcGxOciA9IDA7CisgICAgY3VyLT50ZW1wbE1heCA9IDU7CisgICAgY3VyLT50ZW1wbCA9IE5VTEw7CisKKyAgICAvKgorICAgICAqIGluaXRpYWxpemUgdGhlIHZhcmlhYmxlcyBzdGFjaworICAgICAqLworICAgIGN1ci0+dmFyc1RhYiA9ICh4c2x0U3RhY2tFbGVtUHRyICopCisJICAgICAgICB4bWxNYWxsb2MoMTAgKiBzaXplb2YoeHNsdFN0YWNrRWxlbVB0cikpOworICAgIGlmIChjdXItPnZhcnNUYWIgPT0gTlVMTCkgeworICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKKwkJInhzbHROZXdUcmFuc2Zvcm1Db250ZXh0OiBvdXQgb2YgbWVtb3J5XG4iKTsKKwlnb3RvIGludGVybmFsX2VycjsKKyAgICB9CisgICAgY3VyLT52YXJzTnIgPSAwOworICAgIGN1ci0+dmFyc01heCA9IDEwOworICAgIGN1ci0+dmFycyA9IE5VTEw7CisgICAgY3VyLT52YXJzQmFzZSA9IDA7CisKKyAgICAvKgorICAgICAqIHRoZSBwcm9maWxpbmcgc3RhY2sgaXMgbm90IGluaXRpYWxpemVkIGJ5IGRlZmF1bHQKKyAgICAgKi8KKyAgICBjdXItPnByb2ZUYWIgPSBOVUxMOworICAgIGN1ci0+cHJvZk5yID0gMDsKKyAgICBjdXItPnByb2ZNYXggPSAwOworICAgIGN1ci0+cHJvZiA9IDA7CisKKyAgICBjdXItPnN0eWxlID0gc3R5bGU7CisgICAgeG1sWFBhdGhJbml0KCk7CisgICAgY3VyLT54cGF0aEN0eHQgPSB4bWxYUGF0aE5ld0NvbnRleHQoZG9jKTsKKyAgICBpZiAoY3VyLT54cGF0aEN0eHQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgZG9jLAorCQkieHNsdE5ld1RyYW5zZm9ybUNvbnRleHQgOiB4bWxYUGF0aE5ld0NvbnRleHQgZmFpbGVkXG4iKTsKKwlnb3RvIGludGVybmFsX2VycjsKKyAgICB9CisgICAgLyoKKyAgICAqIENyZWF0ZSBhbiBYUGF0aCBjYWNoZS4KKyAgICAqLworICAgIGlmICh4bWxYUGF0aENvbnRleHRTZXRDYWNoZShjdXItPnhwYXRoQ3R4dCwgMSwgLTEsIDApID09IC0xKQorCWdvdG8gaW50ZXJuYWxfZXJyOworICAgIC8qCisgICAgICogSW5pdGlhbGl6ZSB0aGUgZXh0cmFzIGFycmF5CisgICAgICovCisgICAgaWYgKHN0eWxlLT5leHRyYXNOciAhPSAwKSB7CisJY3VyLT5leHRyYXNNYXggPSBzdHlsZS0+ZXh0cmFzTnIgKyAyMDsKKwljdXItPmV4dHJhcyA9ICh4c2x0UnVudGltZUV4dHJhUHRyKQorCSAgICB4bWxNYWxsb2MoY3VyLT5leHRyYXNNYXggKiBzaXplb2YoeHNsdFJ1bnRpbWVFeHRyYSkpOworCWlmIChjdXItPmV4dHJhcyA9PSBOVUxMKSB7CisJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAorCQkgICAgInhzbHROZXdUcmFuc2Zvcm1Db250ZXh0OiBvdXQgb2YgbWVtb3J5XG4iKTsKKwkgICAgZ290byBpbnRlcm5hbF9lcnI7CisJfQorCWN1ci0+ZXh0cmFzTnIgPSBzdHlsZS0+ZXh0cmFzTnI7CisJZm9yIChpID0gMDtpIDwgY3VyLT5leHRyYXNNYXg7aSsrKSB7CisJICAgIGN1ci0+ZXh0cmFzW2ldLmluZm8gPSBOVUxMOworCSAgICBjdXItPmV4dHJhc1tpXS5kZWFsbG9jYXRlID0gTlVMTDsKKwkgICAgY3VyLT5leHRyYXNbaV0udmFsLnB0ciA9IE5VTEw7CisJfQorICAgIH0gZWxzZSB7CisJY3VyLT5leHRyYXMgPSBOVUxMOworCWN1ci0+ZXh0cmFzTnIgPSAwOworCWN1ci0+ZXh0cmFzTWF4ID0gMDsKKyAgICB9CisKKyAgICBYU0xUX1JFR0lTVEVSX1ZBUklBQkxFX0xPT0tVUChjdXIpOworICAgIFhTTFRfUkVHSVNURVJfRlVOQ1RJT05fTE9PS1VQKGN1cik7CisgICAgY3VyLT54cGF0aEN0eHQtPm5zSGFzaCA9IHN0eWxlLT5uc0hhc2g7CisgICAgLyoKKyAgICAgKiBJbml0aWFsaXplIHRoZSByZWdpc3RlcmVkIGV4dGVybmFsIG1vZHVsZXMKKyAgICAgKi8KKyAgICB4c2x0SW5pdEN0eHRFeHRzKGN1cik7CisgICAgLyoKKyAgICAgKiBTZXR1cCBkb2N1bWVudCBlbGVtZW50IG9yZGVyaW5nIGZvciBsYXRlciBlZmZpY2llbmNpZXMKKyAgICAgKiAoYnVnIDEzMzI4OSkKKyAgICAgKi8KKyAgICBpZiAoeHNsRGVidWdTdGF0dXMgPT0gWFNMVF9ERUJVR19OT05FKQorICAgICAgICB4bWxYUGF0aE9yZGVyRG9jRWxlbXMoZG9jKTsKKyAgICAvKgorICAgICAqIE11c3Qgc2V0IHBhcnNlck9wdGlvbnMgYmVmb3JlIGNhbGxpbmcgeHNsdE5ld0RvY3VtZW50CisgICAgICogKGJ1ZyAxNjQ1MzApCisgICAgICovCisgICAgY3VyLT5wYXJzZXJPcHRpb25zID0gWFNMVF9QQVJTRV9PUFRJT05TOworICAgIGRvY3UgPSB4c2x0TmV3RG9jdW1lbnQoY3VyLCBkb2MpOworICAgIGlmIChkb2N1ID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3VyLCBOVUxMLCAoeG1sTm9kZVB0cilkb2MsCisJCSJ4c2x0TmV3VHJhbnNmb3JtQ29udGV4dCA6IHhzbHROZXdEb2N1bWVudCBmYWlsZWRcbiIpOworCWdvdG8gaW50ZXJuYWxfZXJyOworICAgIH0KKyAgICBkb2N1LT5tYWluID0gMTsKKyAgICBjdXItPmRvY3VtZW50ID0gZG9jdTsKKyAgICBjdXItPmluc3QgPSBOVUxMOworICAgIGN1ci0+b3V0cHV0RmlsZSA9IE5VTEw7CisgICAgY3VyLT5zZWMgPSB4c2x0R2V0RGVmYXVsdFNlY3VyaXR5UHJlZnMoKTsKKyAgICBjdXItPmRlYnVnU3RhdHVzID0geHNsRGVidWdTdGF0dXM7CisgICAgY3VyLT50cmFjZUNvZGUgPSAodW5zaWduZWQgbG9uZyopICZ4c2x0RGVmYXVsdFRyYWNlOworICAgIGN1ci0+eGluY2x1ZGUgPSB4c2x0R2V0WEluY2x1ZGVEZWZhdWx0KCk7CisgICAgY3VyLT5rZXlJbml0TGV2ZWwgPSAwOworCisgICAgcmV0dXJuKGN1cik7CisKK2ludGVybmFsX2VycjoKKyAgICBpZiAoY3VyICE9IE5VTEwpCisJeHNsdEZyZWVUcmFuc2Zvcm1Db250ZXh0KGN1cik7CisgICAgcmV0dXJuKE5VTEwpOworfQorCisvKioKKyAqIHhzbHRGcmVlVHJhbnNmb3JtQ29udGV4dDoKKyAqIEBjdHh0OiAgYW4gWFNMVCBwYXJzZXIgY29udGV4dAorICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgYnkgQGN0eHQKKyAqLwordm9pZAoreHNsdEZyZWVUcmFuc2Zvcm1Db250ZXh0KHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpIHsKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorCXJldHVybjsKKworICAgIC8qCisgICAgICogU2h1dGRvd24gdGhlIGV4dGVuc2lvbiBtb2R1bGVzIGFzc29jaWF0ZWQgdG8gdGhlIHN0eWxlc2hlZXQKKyAgICAgKiB1c2VkIGlmIG5lZWRlZC4KKyAgICAgKi8KKyAgICB4c2x0U2h1dGRvd25DdHh0RXh0cyhjdHh0KTsKKworICAgIGlmIChjdHh0LT54cGF0aEN0eHQgIT0gTlVMTCkgeworCWN0eHQtPnhwYXRoQ3R4dC0+bnNIYXNoID0gTlVMTDsKKwl4bWxYUGF0aEZyZWVDb250ZXh0KGN0eHQtPnhwYXRoQ3R4dCk7CisgICAgfQorICAgIGlmIChjdHh0LT50ZW1wbFRhYiAhPSBOVUxMKQorCXhtbEZyZWUoY3R4dC0+dGVtcGxUYWIpOworICAgIGlmIChjdHh0LT52YXJzVGFiICE9IE5VTEwpCisJeG1sRnJlZShjdHh0LT52YXJzVGFiKTsKKyAgICBpZiAoY3R4dC0+cHJvZlRhYiAhPSBOVUxMKQorCXhtbEZyZWUoY3R4dC0+cHJvZlRhYik7CisgICAgaWYgKChjdHh0LT5leHRyYXNOciA+IDApICYmIChjdHh0LT5leHRyYXMgIT0gTlVMTCkpIHsKKwlpbnQgaTsKKworCWZvciAoaSA9IDA7aSA8IGN0eHQtPmV4dHJhc05yO2krKykgeworCSAgICBpZiAoKGN0eHQtPmV4dHJhc1tpXS5kZWFsbG9jYXRlICE9IE5VTEwpICYmCisJCShjdHh0LT5leHRyYXNbaV0uaW5mbyAhPSBOVUxMKSkKKwkJY3R4dC0+ZXh0cmFzW2ldLmRlYWxsb2NhdGUoY3R4dC0+ZXh0cmFzW2ldLmluZm8pOworCX0KKwl4bWxGcmVlKGN0eHQtPmV4dHJhcyk7CisgICAgfQorICAgIHhzbHRGcmVlR2xvYmFsVmFyaWFibGVzKGN0eHQpOworICAgIHhzbHRGcmVlRG9jdW1lbnRzKGN0eHQpOworICAgIHhzbHRGcmVlQ3R4dEV4dHMoY3R4dCk7CisgICAgeHNsdEZyZWVSVlRzKGN0eHQpOworICAgIHhzbHRUcmFuc2Zvcm1DYWNoZUZyZWUoY3R4dC0+Y2FjaGUpOworICAgIHhtbERpY3RGcmVlKGN0eHQtPmRpY3QpOworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAiZnJlZWluZyB0cmFuc2Zvcm1hdGlvbiBkaWN0aW9uYXJ5XG4iKTsKKyNlbmRpZgorICAgIG1lbXNldChjdHh0LCAtMSwgc2l6ZW9mKHhzbHRUcmFuc2Zvcm1Db250ZXh0KSk7CisgICAgeG1sRnJlZShjdHh0KTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJCUNvcHkgb2YgTm9kZXMgaW4gYW4gWFNMVCBmYXNoaW9uCQkqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3htbE5vZGVQdHIgeHNsdENvcHlUcmVlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIHhtbE5vZGVQdHIgaW5zZXJ0LCBpbnQgbGl0ZXJhbCk7CisKKy8qKgorICogeHNsdEFkZENoaWxkOgorICogQHBhcmVudDogIHRoZSBwYXJlbnQgbm9kZQorICogQGN1cjogIHRoZSBjaGlsZCBub2RlCisgKgorICogV3JhcHBlciB2ZXJzaW9uIG9mIHhtbEFkZENoaWxkIHdpdGggYSBtb3JlIGNvbnNpc3RlbnQgYmVoYXZpb3VyIG9uCisgKiBlcnJvci4gT25lIGV4cGVjdCB0aGUgdXNlIHRvIGJlIGNoaWxkID0geHNsdEFkZENoaWxkKHBhcmVudCwgY2hpbGQpOworICogYW5kIHRoZSByb3V0aW5lIHdpbGwgdGFrZSBjYXJlIG9mIG5vdCBsZWFraW5nIG9uIGVycm9ycyBvciBub2RlIG1lcmdlCisgKgorICogUmV0dXJucyB0aGUgY2hpbGQgaXMgc3VjY2Vzc2Z1bGx5IGF0dGFjaGVkIG9yIE5VTEwgaWYgbWVyZ2VkIG9yIGZyZWVkCisgKi8KK3N0YXRpYyB4bWxOb2RlUHRyCit4c2x0QWRkQ2hpbGQoeG1sTm9kZVB0ciBwYXJlbnQsIHhtbE5vZGVQdHIgY3VyKSB7CisgICB4bWxOb2RlUHRyIHJldDsKKworICAgaWYgKChjdXIgPT0gTlVMTCkgfHwgKHBhcmVudCA9PSBOVUxMKSkKKyAgICAgICByZXR1cm4oTlVMTCk7CisgICBpZiAocGFyZW50ID09IE5VTEwpIHsKKyAgICAgICB4bWxGcmVlTm9kZShjdXIpOworICAgICAgIHJldHVybihOVUxMKTsKKyAgIH0KKyAgIHJldCA9IHhtbEFkZENoaWxkKHBhcmVudCwgY3VyKTsKKworICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdEFkZFRleHRTdHJpbmc6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEB0YXJnZXQ6ICB0aGUgdGV4dCBub2RlIHdoZXJlIHRoZSB0ZXh0IHdpbGwgYmUgYXR0YWNoZWQKKyAqIEBzdHJpbmc6ICB0aGUgdGV4dCBzdHJpbmcKKyAqIEBsZW46ICB0aGUgc3RyaW5nIGxlbmd0aCBpbiBieXRlCisgKgorICogRXh0ZW5kIHRoZSBjdXJyZW50IHRleHQgbm9kZSB3aXRoIHRoZSBuZXcgc3RyaW5nLCBpdCBoYW5kbGVzIGNvYWxlc2NpbmcKKyAqCisgKiBSZXR1cm5zOiB0aGUgdGV4dCBub2RlCisgKi8KK3N0YXRpYyB4bWxOb2RlUHRyCit4c2x0QWRkVGV4dFN0cmluZyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIHRhcmdldCwKKwkJICBjb25zdCB4bWxDaGFyICpzdHJpbmcsIGludCBsZW4pIHsKKyAgICAvKgorICAgICAqIG9wdGltaXphdGlvbgorICAgICAqLworICAgIGlmICgobGVuIDw9IDApIHx8IChzdHJpbmcgPT0gTlVMTCkgfHwgKHRhcmdldCA9PSBOVUxMKSkKKyAgICAgICAgcmV0dXJuKHRhcmdldCk7CisKKyAgICBpZiAoY3R4dC0+bGFzdHRleHQgPT0gdGFyZ2V0LT5jb250ZW50KSB7CisKKwlpZiAoY3R4dC0+bGFzdHR1c2UgKyBsZW4gPj0gY3R4dC0+bGFzdHRzaXplKSB7CisJICAgIHhtbENoYXIgKm5ld2J1ZjsKKwkgICAgaW50IHNpemU7CisKKwkgICAgc2l6ZSA9IGN0eHQtPmxhc3R0c2l6ZSArIGxlbiArIDEwMDsKKwkgICAgc2l6ZSAqPSAyOworCSAgICBuZXdidWYgPSAoeG1sQ2hhciAqKSB4bWxSZWFsbG9jKHRhcmdldC0+Y29udGVudCxzaXplKTsKKwkgICAgaWYgKG5ld2J1ZiA9PSBOVUxMKSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCB0YXJnZXQsCisJCSAieHNsdENvcHlUZXh0OiB0ZXh0IGFsbG9jYXRpb24gZmFpbGVkXG4iKTsKKwkJcmV0dXJuKE5VTEwpOworCSAgICB9CisJICAgIGN0eHQtPmxhc3R0c2l6ZSA9IHNpemU7CisJICAgIGN0eHQtPmxhc3R0ZXh0ID0gbmV3YnVmOworCSAgICB0YXJnZXQtPmNvbnRlbnQgPSBuZXdidWY7CisJfQorCW1lbWNweSgmKHRhcmdldC0+Y29udGVudFtjdHh0LT5sYXN0dHVzZV0pLCBzdHJpbmcsIGxlbik7CisJY3R4dC0+bGFzdHR1c2UgKz0gbGVuOworCXRhcmdldC0+Y29udGVudFtjdHh0LT5sYXN0dHVzZV0gPSAwOworICAgIH0gZWxzZSB7CisJeG1sTm9kZUFkZENvbnRlbnQodGFyZ2V0LCBzdHJpbmcpOworCWN0eHQtPmxhc3R0ZXh0ID0gdGFyZ2V0LT5jb250ZW50OworCWxlbiA9IHhtbFN0cmxlbih0YXJnZXQtPmNvbnRlbnQpOworCWN0eHQtPmxhc3R0c2l6ZSA9IGxlbjsKKwljdHh0LT5sYXN0dHVzZSA9IGxlbjsKKyAgICB9CisgICAgcmV0dXJuKHRhcmdldCk7Cit9CisKKy8qKgorICogeHNsdENvcHlUZXh0U3RyaW5nOgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAdGFyZ2V0OiAgdGhlIGVsZW1lbnQgd2hlcmUgdGhlIHRleHQgd2lsbCBiZSBhdHRhY2hlZAorICogQHN0cmluZzogIHRoZSB0ZXh0IHN0cmluZworICogQG5vZXNjYXBlOiAgc2hvdWxkIGRpc2FibGUtZXNjYXBpbmcgYmUgYWN0aXZhdGVkIGZvciB0aGlzIHRleHQgbm9kZS4KKyAqCisgKiBBZGRzIEBzdHJpbmcgdG8gYSBuZXdseSBjcmVhdGVkIG9yIGFuIGV4aXN0ZW50IHRleHQgbm9kZSBjaGlsZCBvZgorICogQHRhcmdldC4KKyAqCisgKiBSZXR1cm5zOiB0aGUgdGV4dCBub2RlLCB3aGVyZSB0aGUgdGV4dCBjb250ZW50IG9mIEBjdXIgaXMgY29waWVkIHRvLgorICogICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIEFQSSBvciBpbnRlcm5hbCBlcnJvcnMuCisgKi8KK3htbE5vZGVQdHIKK3hzbHRDb3B5VGV4dFN0cmluZyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIHRhcmdldCwKKwkgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKnN0cmluZywgaW50IG5vZXNjYXBlKQoreworICAgIHhtbE5vZGVQdHIgY29weTsKKyAgICBpbnQgbGVuOworCisgICAgaWYgKHN0cmluZyA9PSBOVUxMKQorCXJldHVybihOVUxMKTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQ09QWV9URVhULHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAgInhzbHRDb3B5VGV4dFN0cmluZzogY29weSB0ZXh0ICVzXG4iLAorCQkgICAgIHN0cmluZykpOworI2VuZGlmCisKKyAgICAvKgorICAgICogUGxheSBzYXZlIGFuZCByZXNldCB0aGUgbWVyZ2luZyBtZWNoYW5pc20gZm9yIGV2ZXJ5IG5ldworICAgICogdGFyZ2V0IG5vZGUuCisgICAgKi8KKyAgICBpZiAoKHRhcmdldCA9PSBOVUxMKSB8fCAodGFyZ2V0LT5jaGlsZHJlbiA9PSBOVUxMKSkgeworCWN0eHQtPmxhc3R0ZXh0ID0gTlVMTDsKKyAgICB9CisKKyAgICAvKiBoYW5kbGUgY29hbGVzY2luZyBvZiB0ZXh0IG5vZGVzIGhlcmUgKi8KKyAgICBsZW4gPSB4bWxTdHJsZW4oc3RyaW5nKTsKKyAgICBpZiAoKGN0eHQtPnR5cGUgPT0gWFNMVF9PVVRQVVRfWE1MKSAmJgorCShjdHh0LT5zdHlsZS0+Y2RhdGFTZWN0aW9uICE9IE5VTEwpICYmCisJKHRhcmdldCAhPSBOVUxMKSAmJgorCSh0YXJnZXQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKKwkoKCh0YXJnZXQtPm5zID09IE5VTEwpICYmCisJICAoeG1sSGFzaExvb2t1cDIoY3R4dC0+c3R5bGUtPmNkYXRhU2VjdGlvbiwKKwkJICAgICAgICAgIHRhcmdldC0+bmFtZSwgTlVMTCkgIT0gTlVMTCkpIHx8CisJICgodGFyZ2V0LT5ucyAhPSBOVUxMKSAmJgorCSAgKHhtbEhhc2hMb29rdXAyKGN0eHQtPnN0eWxlLT5jZGF0YVNlY3Rpb24sCisJICAgICAgICAgICAgICAgICAgdGFyZ2V0LT5uYW1lLCB0YXJnZXQtPm5zLT5ocmVmKSAhPSBOVUxMKSkpKQorICAgIHsKKwkvKgorCSogUHJvY2VzcyAiY2RhdGEtc2VjdGlvbi1lbGVtZW50cyIuCisJKi8KKwlpZiAoKHRhcmdldC0+bGFzdCAhPSBOVUxMKSAmJgorCSAgICAodGFyZ2V0LT5sYXN0LT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKQorCXsKKwkgICAgcmV0dXJuKHhzbHRBZGRUZXh0U3RyaW5nKGN0eHQsIHRhcmdldC0+bGFzdCwgc3RyaW5nLCBsZW4pKTsKKwl9CisJY29weSA9IHhtbE5ld0NEYXRhQmxvY2soY3R4dC0+b3V0cHV0LCBzdHJpbmcsIGxlbik7CisgICAgfSBlbHNlIGlmIChub2VzY2FwZSkgeworCS8qCisJKiBQcm9jZXNzICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIuCisJKi8KKwlpZiAoKHRhcmdldCAhPSBOVUxMKSAmJiAodGFyZ2V0LT5sYXN0ICE9IE5VTEwpICYmCisJICAgICh0YXJnZXQtPmxhc3QtPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgJiYKKwkgICAgKHRhcmdldC0+bGFzdC0+bmFtZSA9PSB4bWxTdHJpbmdUZXh0Tm9lbmMpKQorCXsKKwkgICAgcmV0dXJuKHhzbHRBZGRUZXh0U3RyaW5nKGN0eHQsIHRhcmdldC0+bGFzdCwgc3RyaW5nLCBsZW4pKTsKKwl9CisJY29weSA9IHhtbE5ld1RleHRMZW4oc3RyaW5nLCBsZW4pOworCWlmIChjb3B5ICE9IE5VTEwpCisJICAgIGNvcHktPm5hbWUgPSB4bWxTdHJpbmdUZXh0Tm9lbmM7CisgICAgfSBlbHNlIHsKKwkvKgorCSogRGVmYXVsdCBwcm9jZXNzaW5nLgorCSovCisJaWYgKCh0YXJnZXQgIT0gTlVMTCkgJiYgKHRhcmdldC0+bGFzdCAhPSBOVUxMKSAmJgorCSAgICAodGFyZ2V0LT5sYXN0LT50eXBlID09IFhNTF9URVhUX05PREUpICYmCisJICAgICh0YXJnZXQtPmxhc3QtPm5hbWUgPT0geG1sU3RyaW5nVGV4dCkpIHsKKwkgICAgcmV0dXJuKHhzbHRBZGRUZXh0U3RyaW5nKGN0eHQsIHRhcmdldC0+bGFzdCwgc3RyaW5nLCBsZW4pKTsKKwl9CisJY29weSA9IHhtbE5ld1RleHRMZW4oc3RyaW5nLCBsZW4pOworICAgIH0KKyAgICBpZiAoY29weSAhPSBOVUxMKSB7CisJaWYgKHRhcmdldCAhPSBOVUxMKQorCSAgICBjb3B5ID0geHNsdEFkZENoaWxkKHRhcmdldCwgY29weSk7CisJY3R4dC0+bGFzdHRleHQgPSBjb3B5LT5jb250ZW50OworCWN0eHQtPmxhc3R0c2l6ZSA9IGxlbjsKKwljdHh0LT5sYXN0dHVzZSA9IGxlbjsKKyAgICB9IGVsc2UgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCB0YXJnZXQsCisJCQkgInhzbHRDb3B5VGV4dFN0cmluZzogdGV4dCBjb3B5IGZhaWxlZFxuIik7CisJY3R4dC0+bGFzdHRleHQgPSBOVUxMOworICAgIH0KKyAgICByZXR1cm4oY29weSk7Cit9CisKKy8qKgorICogeHNsdENvcHlUZXh0OgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAdGFyZ2V0OiAgdGhlIGVsZW1lbnQgd2hlcmUgdGhlIHRleHQgd2lsbCBiZSBhdHRhY2hlZAorICogQGN1cjogIHRoZSB0ZXh0IG9yIENEQVRBIG5vZGUKKyAqIEBpbnRlcm5lZDogIHRoZSBzdHJpbmcgaXMgaW4gdGhlIHRhcmdldCBkb2MgZGljdGlvbmFyeQorICoKKyAqIENvcHkgdGhlIHRleHQgY29udGVudCBvZiBAY3VyIGFuZCBhcHBlbmQgaXQgdG8gQHRhcmdldCdzIGNoaWxkcmVuLgorICoKKyAqIFJldHVybnM6IHRoZSB0ZXh0IG5vZGUsIHdoZXJlIHRoZSB0ZXh0IGNvbnRlbnQgb2YgQGN1ciBpcyBjb3BpZWQgdG8uCisgKiAgICAgICAgICBOVUxMIGluIGNhc2Ugb2YgQVBJIG9yIGludGVybmFsIGVycm9ycy4KKyAqLworc3RhdGljIHhtbE5vZGVQdHIKK3hzbHRDb3B5VGV4dCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIHRhcmdldCwKKwkgICAgIHhtbE5vZGVQdHIgY3VyLCBpbnQgaW50ZXJuZWQpCit7CisgICAgeG1sTm9kZVB0ciBjb3B5OworCisgICAgaWYgKChjdXItPnR5cGUgIT0gWE1MX1RFWFRfTk9ERSkgJiYKKwkoY3VyLT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKQorCXJldHVybihOVUxMKTsKKyAgICBpZiAoY3VyLT5jb250ZW50ID09IE5VTEwpCisJcmV0dXJuKE5VTEwpOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKyAgICBpZiAoY3VyLT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpIHsKKwlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DT1BZX1RFWFQseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSAieHNsdENvcHlUZXh0OiBjb3B5IENEQVRBIHRleHQgJXNcbiIsCisJCQkgY3VyLT5jb250ZW50KSk7CisgICAgfSBlbHNlIGlmIChjdXItPm5hbWUgPT0geG1sU3RyaW5nVGV4dE5vZW5jKSB7CisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQ09QWV9URVhULHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAgInhzbHRDb3B5VGV4dDogY29weSB1bmVzY2FwZWQgdGV4dCAlc1xuIiwKKwkJCSBjdXItPmNvbnRlbnQpKTsKKyAgICB9IGVsc2UgeworCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0NPUFlfVEVYVCx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJICJ4c2x0Q29weVRleHQ6IGNvcHkgdGV4dCAlc1xuIiwKKwkJCSBjdXItPmNvbnRlbnQpKTsKKyAgICB9CisjZW5kaWYKKworICAgIC8qCisgICAgKiBQbGF5IHNhdmUgYW5kIHJlc2V0IHRoZSBtZXJnaW5nIG1lY2hhbmlzbSBmb3IgZXZlcnkgbmV3CisgICAgKiB0YXJnZXQgbm9kZS4KKyAgICAqLworICAgIGlmICgodGFyZ2V0ID09IE5VTEwpIHx8ICh0YXJnZXQtPmNoaWxkcmVuID09IE5VTEwpKSB7CisJY3R4dC0+bGFzdHRleHQgPSBOVUxMOworICAgIH0KKworICAgIGlmICgoY3R4dC0+c3R5bGUtPmNkYXRhU2VjdGlvbiAhPSBOVUxMKSAmJgorCShjdHh0LT50eXBlID09IFhTTFRfT1VUUFVUX1hNTCkgJiYKKwkodGFyZ2V0ICE9IE5VTEwpICYmCisJKHRhcmdldC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSAmJgorCSgoKHRhcmdldC0+bnMgPT0gTlVMTCkgJiYKKwkgICh4bWxIYXNoTG9va3VwMihjdHh0LT5zdHlsZS0+Y2RhdGFTZWN0aW9uLAorCQkgICAgICAgICAgdGFyZ2V0LT5uYW1lLCBOVUxMKSAhPSBOVUxMKSkgfHwKKwkgKCh0YXJnZXQtPm5zICE9IE5VTEwpICYmCisJICAoeG1sSGFzaExvb2t1cDIoY3R4dC0+c3R5bGUtPmNkYXRhU2VjdGlvbiwKKwkgICAgICAgICAgICAgICAgICB0YXJnZXQtPm5hbWUsIHRhcmdldC0+bnMtPmhyZWYpICE9IE5VTEwpKSkpCisgICAgeworCS8qCisJKiBQcm9jZXNzICJjZGF0YS1zZWN0aW9uLWVsZW1lbnRzIi4KKwkqLworCS8qCisJKiBPUFRJTUlaRSBUT0RPOiB4c2x0Q29weVRleHQoKSBpcyBhbHNvIHVzZWQgZm9yIGF0dHJpYnV0ZSBjb250ZW50LgorCSovCisJLyoKKwkqIFRPRE86IFNpbmNlIHRoaXMgZG9lc24ndCBtZXJnZSBhZGphY2VudCBDREFUQS1zZWN0aW9uIG5vZGVzLAorCSogd2UnbGwgZ2V0OiA8IVtDREFUQVt4XV0+PCFDREFUQVt5XV0+LgorCSogVE9ETzogUmVwb3J0ZWQgaW4gIzMyMTUwNS4KKwkqLworCWlmICgodGFyZ2V0LT5sYXN0ICE9IE5VTEwpICYmCisJICAgICAodGFyZ2V0LT5sYXN0LT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKQorCXsKKwkgICAgLyoKKwkgICAgKiBBcHBlbmQgdG8gZXhpc3RpbmcgQ0RBVEEtc2VjdGlvbiBub2RlLgorCSAgICAqLworCSAgICBjb3B5ID0geHNsdEFkZFRleHRTdHJpbmcoY3R4dCwgdGFyZ2V0LT5sYXN0LCBjdXItPmNvbnRlbnQsCisJCXhtbFN0cmxlbihjdXItPmNvbnRlbnQpKTsKKwkgICAgZ290byBleGl0OworCX0gZWxzZSB7CisJICAgIHVuc2lnbmVkIGludCBsZW47CisKKwkgICAgbGVuID0geG1sU3RybGVuKGN1ci0+Y29udGVudCk7CisJICAgIGNvcHkgPSB4bWxOZXdDRGF0YUJsb2NrKGN0eHQtPm91dHB1dCwgY3VyLT5jb250ZW50LCBsZW4pOworCSAgICBpZiAoY29weSA9PSBOVUxMKQorCQlnb3RvIGV4aXQ7CisJICAgIGN0eHQtPmxhc3R0ZXh0ID0gY29weS0+Y29udGVudDsKKwkgICAgY3R4dC0+bGFzdHRzaXplID0gbGVuOworCSAgICBjdHh0LT5sYXN0dHVzZSA9IGxlbjsKKwl9CisgICAgfSBlbHNlIGlmICgodGFyZ2V0ICE9IE5VTEwpICYmCisJKHRhcmdldC0+bGFzdCAhPSBOVUxMKSAmJgorCS8qIGJvdGggZXNjYXBlZCBvciBib3RoIG5vbi1lc2NhcGVkIHRleHQtbm9kZXMgKi8KKwkoKCh0YXJnZXQtPmxhc3QtPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgJiYKKwkodGFyZ2V0LT5sYXN0LT5uYW1lID09IGN1ci0+bmFtZSkpIHx8CisgICAgICAgIC8qIG5vbi1lc2NhcGVkIHRleHQgbm9kZXMgYW5kIENEQVRBLXNlY3Rpb24gbm9kZXMgKi8KKwkoKCh0YXJnZXQtPmxhc3QtPnR5cGUgPT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkgJiYKKwkoY3VyLT5uYW1lID09IHhtbFN0cmluZ1RleHROb2VuYykpKSkpCisgICAgeworCS8qCisJICogd2UgYXJlIGFwcGVuZGluZyB0byBhbiBleGlzdGluZyB0ZXh0IG5vZGUKKwkgKi8KKwljb3B5ID0geHNsdEFkZFRleHRTdHJpbmcoY3R4dCwgdGFyZ2V0LT5sYXN0LCBjdXItPmNvbnRlbnQsCisJICAgIHhtbFN0cmxlbihjdXItPmNvbnRlbnQpKTsKKwlnb3RvIGV4aXQ7CisgICAgfSBlbHNlIGlmICgoaW50ZXJuZWQpICYmICh0YXJnZXQgIT0gTlVMTCkgJiYKKwkodGFyZ2V0LT5kb2MgIT0gTlVMTCkgJiYKKwkodGFyZ2V0LT5kb2MtPmRpY3QgPT0gY3R4dC0+ZGljdCkpCisgICAgeworCS8qCisJKiBUT0RPOiBETyB3ZSB3YW50IHRvIHVzZSB0aGlzIGFsc28gZm9yICJ0ZXh0IiBvdXRwdXQ/CisJKi8KKyAgICAgICAgY29weSA9IHhtbE5ld1RleHRMZW4oTlVMTCwgMCk7CisJaWYgKGNvcHkgPT0gTlVMTCkKKwkgICAgZ290byBleGl0OworCWlmIChjdXItPm5hbWUgPT0geG1sU3RyaW5nVGV4dE5vZW5jKQorCSAgICBjb3B5LT5uYW1lID0geG1sU3RyaW5nVGV4dE5vZW5jOworCisJLyoKKwkgKiBNdXN0IGNvbmZpcm0gdGhhdCBjb250ZW50IGlzIGluIGRpY3QgKGJ1ZyAzMDI4MjEpCisJICogVE9ETzogVGhpcyBjaGVjayBzaG91bGQgYmUgbm90IG5lZWRlZCBmb3IgdGV4dCBjb21pbmcKKwkgKiBmcm9tIHRoZSBzdHlsZXNoZWV0cworCSAqLworCWlmICh4bWxEaWN0T3ducyhjdHh0LT5kaWN0LCBjdXItPmNvbnRlbnQpKQorCSAgICBjb3B5LT5jb250ZW50ID0gY3VyLT5jb250ZW50OworCWVsc2UgeworCSAgICBpZiAoKGNvcHktPmNvbnRlbnQgPSB4bWxTdHJkdXAoY3VyLT5jb250ZW50KSkgPT0gTlVMTCkKKwkJcmV0dXJuIE5VTEw7CisJfQorICAgIH0gZWxzZSB7CisgICAgICAgIC8qCisJICogbm9ybWFsIHByb2Nlc3NpbmcuIGtlZXAgY291bnRlcnMgdG8gZXh0ZW5kIHRoZSB0ZXh0IG5vZGUKKwkgKiBpbiB4c2x0QWRkVGV4dFN0cmluZyBpZiBuZWVkZWQuCisJICovCisgICAgICAgIHVuc2lnbmVkIGludCBsZW47CisKKwlsZW4gPSB4bWxTdHJsZW4oY3VyLT5jb250ZW50KTsKKwljb3B5ID0geG1sTmV3VGV4dExlbihjdXItPmNvbnRlbnQsIGxlbik7CisJaWYgKGNvcHkgPT0gTlVMTCkKKwkgICAgZ290byBleGl0OworCWlmIChjdXItPm5hbWUgPT0geG1sU3RyaW5nVGV4dE5vZW5jKQorCSAgICBjb3B5LT5uYW1lID0geG1sU3RyaW5nVGV4dE5vZW5jOworCWN0eHQtPmxhc3R0ZXh0ID0gY29weS0+Y29udGVudDsKKwljdHh0LT5sYXN0dHNpemUgPSBsZW47CisJY3R4dC0+bGFzdHR1c2UgPSBsZW47CisgICAgfQorICAgIGlmIChjb3B5ICE9IE5VTEwpIHsKKwlpZiAodGFyZ2V0ICE9IE5VTEwpIHsKKwkgICAgY29weS0+ZG9jID0gdGFyZ2V0LT5kb2M7CisJICAgIC8qCisJICAgICogTUFZQkUgVE9ETzogTWF5YmUgd2Ugc2hvdWxkIHJlc2V0IHRoZSBjdHh0LT5sYXN0dGV4dCBoZXJlCisJICAgICogIHRvIGVuc3VyZSB0aGF0IHRoZSBvcHRpbWl6ZWQgdGV4dC1tZXJnaW5nIG1lY2hhbmlzbQorCSAgICAqICB3b24ndCBpbnRlcmZlcmUgd2l0aCBub3JtYWwgbm9kZS1tZXJnaW5nIGluIGFueSBjYXNlLgorCSAgICAqLworCSAgICBjb3B5ID0geHNsdEFkZENoaWxkKHRhcmdldCwgY29weSk7CisJfQorICAgIH0gZWxzZSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIHRhcmdldCwKKwkJCSAieHNsdENvcHlUZXh0OiB0ZXh0IGNvcHkgZmFpbGVkXG4iKTsKKyAgICB9CisKK2V4aXQ6CisgICAgaWYgKChjb3B5ID09IE5VTEwpIHx8IChjb3B5LT5jb250ZW50ID09IE5VTEwpKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIHRhcmdldCwKKwkgICAgIkludGVybmFsIGVycm9yIGluIHhzbHRDb3B5VGV4dCgpOiAiCisJICAgICJGYWlsZWQgdG8gY29weSB0aGUgc3RyaW5nLlxuIik7CisJY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisgICAgfQorICAgIHJldHVybihjb3B5KTsKK30KKworLyoqCisgKiB4c2x0U2hhbGxvd0NvcHlBdHRyOgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAaW52b2NOb2RlOiByZXNwb25zaWJsZSBub2RlIGluIHRoZSBzdHlsZXNoZWV0OyB1c2VkIGZvciBlcnJvciByZXBvcnRzCisgKiBAdGFyZ2V0OiAgdGhlIGVsZW1lbnQgd2hlcmUgdGhlIGF0dHJpYnV0ZSB3aWxsIGJlIGdyYWZ0ZWQKKyAqIEBhdHRyOiB0aGUgYXR0cmlidXRlIHRvIGJlIGNvcGllZAorICoKKyAqIERvIGEgY29weSBvZiBhbiBhdHRyaWJ1dGUuCisgKiBDYWxsZWQgYnk6CisgKiAgLSB4c2x0Q29weVRyZWVJbnRlcm5hbCgpCisgKiAgLSB4c2x0Q29weU9mKCkKKyAqICAtIHhzbHRDb3B5KCkKKyAqCisgKiBSZXR1cm5zOiBhIG5ldyB4bWxBdHRyUHRyLCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCisgKi8KK3N0YXRpYyB4bWxBdHRyUHRyCit4c2x0U2hhbGxvd0NvcHlBdHRyKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgaW52b2NOb2RlLAorCSAgICAgeG1sTm9kZVB0ciB0YXJnZXQsIHhtbEF0dHJQdHIgYXR0cikKK3sKKyAgICB4bWxBdHRyUHRyIGNvcHk7CisgICAgeG1sQ2hhciAqdmFsdWU7CisKKyAgICBpZiAoYXR0ciA9PSBOVUxMKQorCXJldHVybihOVUxMKTsKKworICAgIGlmICh0YXJnZXQtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnZvY05vZGUsCisJICAgICJDYW5ub3QgYWRkIGFuIGF0dHJpYnV0ZSBub2RlIHRvIGEgbm9uLWVsZW1lbnQgbm9kZS5cbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisKKyAgICBpZiAodGFyZ2V0LT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGludm9jTm9kZSwKKwkgICAgIkF0dHJpYnV0ZSBub2RlcyBtdXN0IGJlIGFkZGVkIGJlZm9yZSAiCisJICAgICJhbnkgY2hpbGQgbm9kZXMgdG8gYW4gZWxlbWVudC5cbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisKKyAgICB2YWx1ZSA9IHhtbE5vZGVMaXN0R2V0U3RyaW5nKGF0dHItPmRvYywgYXR0ci0+Y2hpbGRyZW4sIDEpOworICAgIGlmIChhdHRyLT5ucyAhPSBOVUxMKSB7CisJeG1sTnNQdHIgbnM7CisKKwlucyA9IHhzbHRHZXRTcGVjaWFsTmFtZXNwYWNlKGN0eHQsIGludm9jTm9kZSwKKwkgICAgYXR0ci0+bnMtPmhyZWYsIGF0dHItPm5zLT5wcmVmaXgsIHRhcmdldCk7CisJaWYgKG5zID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGludm9jTm9kZSwKKwkJIk5hbWVzcGFjZSBmaXh1cCBlcnJvcjogRmFpbGVkIHRvIGFjcXVpcmUgYW4gaW4tc2NvcGUgIgorCQkibmFtZXNwYWNlIGJpbmRpbmcgb2YgdGhlIGNvcGllZCBhdHRyaWJ1dGUgJ3slc30lcycuXG4iLAorCQlhdHRyLT5ucy0+aHJlZiwgYXR0ci0+bmFtZSk7CisJICAgIC8qCisJICAgICogVE9ETzogU2hvdWxkIHdlIGp1c3Qgc3RvcCBoZXJlPworCSAgICAqLworCX0KKwkvKgorCSogTm90ZSB0aGF0IHhtbFNldE5zUHJvcCgpIHdpbGwgdGFrZSBjYXJlIG9mIGR1cGxpY2F0ZXMKKwkqIGFuZCBhc3NpZ25zIHRoZSBuZXcgbmFtZXNwYWNlIGV2ZW4gdG8gYSBkdXBsaWNhdGUuCisJKi8KKwljb3B5ID0geG1sU2V0TnNQcm9wKHRhcmdldCwgbnMsIGF0dHItPm5hbWUsIHZhbHVlKTsKKyAgICB9IGVsc2UgeworCWNvcHkgPSB4bWxTZXROc1Byb3AodGFyZ2V0LCBOVUxMLCBhdHRyLT5uYW1lLCB2YWx1ZSk7CisgICAgfQorICAgIGlmICh2YWx1ZSAhPSBOVUxMKQorCXhtbEZyZWUodmFsdWUpOworCisgICAgaWYgKGNvcHkgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisKKyNpZiAwCisgICAgLyoKKyAgICAqIE5PVEU6IFRoaXMgd2FzIG9wdGltaXplZCBhY2NvcmRpbmcgdG8gYnVnICMzNDI2OTUuCisgICAgKiBUT0RPOiBDYW4gdGhpcyBmdXJ0aGVyIGJlIG9wdGltaXplZCwgaWYgc291cmNlIGFuZCB0YXJnZXQKKyAgICAqICBzaGFyZSB0aGUgc2FtZSBkaWN0IGFuZCBhdHRyLT5jaGlsZHJlbiBpcyBqdXN0IDEgdGV4dCBub2RlCisgICAgKiAgd2hpY2ggaXMgaW4gdGhlIGRpY3Q/IEhvdyBwcm9iYWJsZSBpcyBzdWNoIGEgY2FzZT8KKyAgICAqLworICAgIC8qCisgICAgKiBUT0RPOiBEbyB3ZSBuZWVkIHRvIGNyZWF0ZSBhbiBlbXB0eSB0ZXh0IG5vZGUgaWYgdGhlIHZhbHVlCisgICAgKiAgaXMgdGhlIGVtcHR5IHN0cmluZz8KKyAgICAqLworICAgIHZhbHVlID0geG1sTm9kZUxpc3RHZXRTdHJpbmcoYXR0ci0+ZG9jLCBhdHRyLT5jaGlsZHJlbiwgMSk7CisgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKwl0eHROb2RlID0geG1sTmV3RG9jVGV4dCh0YXJnZXQtPmRvYywgTlVMTCk7CisJaWYgKHR4dE5vZGUgPT0gTlVMTCkKKwkgICAgcmV0dXJuKE5VTEwpOworCWlmICgodGFyZ2V0LT5kb2MgIT0gTlVMTCkgJiYKKwkgICAgKHRhcmdldC0+ZG9jLT5kaWN0ICE9IE5VTEwpKQorCXsKKwkgICAgdHh0Tm9kZS0+Y29udGVudCA9CisJCSh4bWxDaGFyICopIHhtbERpY3RMb29rdXAodGFyZ2V0LT5kb2MtPmRpY3QsCisJCSAgICBCQURfQ0FTVCB2YWx1ZSwgLTEpOworCSAgICB4bWxGcmVlKHZhbHVlKTsKKwl9IGVsc2UKKwkgICAgdHh0Tm9kZS0+Y29udGVudCA9IHZhbHVlOworCWNvcHktPmNoaWxkcmVuID0gdHh0Tm9kZTsKKyAgICB9CisjZW5kaWYKKworICAgIHJldHVybihjb3B5KTsKK30KKworLyoqCisgKiB4c2x0Q29weUF0dHJMaXN0Tm9PdmVyd3JpdGU6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBpbnZvY05vZGU6IHJlc3BvbnNpYmxlIG5vZGUgaW4gdGhlIHN0eWxlc2hlZXQ7IHVzZWQgZm9yIGVycm9yIHJlcG9ydHMKKyAqIEB0YXJnZXQ6ICB0aGUgZWxlbWVudCB3aGVyZSB0aGUgbmV3IGF0dHJpYnV0ZXMgd2lsbCBiZSBncmFmdGVkCisgKiBAYXR0cjogIHRoZSBmaXJzdCBhdHRyaWJ1dGUgaW4gdGhlIGxpc3QgdG8gYmUgY29waWVkCisgKgorICogQ29waWVzIGEgbGlzdCBvZiBhdHRyaWJ1dGUgbm9kZXMsIHN0YXJ0aW5nIHdpdGggQGF0dHIsIG92ZXIgdG8gdGhlCisgKiBAdGFyZ2V0IGVsZW1lbnQgbm9kZS4KKyAqCisgKiBDYWxsZWQgYnk6CisgKiAgLSB4c2x0Q29weVRyZWVJbnRlcm5hbCgpCisgKgorICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MgYW5kIC0xIG9uIGVycm9ycyBhbmQgaW50ZXJuYWwgZXJyb3JzLgorICovCitzdGF0aWMgaW50Cit4c2x0Q29weUF0dHJMaXN0Tm9PdmVyd3JpdGUoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCSAgICB4bWxOb2RlUHRyIGludm9jTm9kZSwKKwkJCSAgICB4bWxOb2RlUHRyIHRhcmdldCwgeG1sQXR0clB0ciBhdHRyKQoreworICAgIHhtbEF0dHJQdHIgY29weTsKKyAgICB4bWxOc1B0ciBvcmlnTnMgPSBOVUxMLCBjb3B5TnMgPSBOVUxMOworICAgIHhtbENoYXIgKnZhbHVlOworCisgICAgLyoKKyAgICAqIERvbid0IHVzZSB4bWxDb3B5UHJvcCgpIGhlcmUsIHNpbmNlIGl0IHdpbGwgdHJ5IHRvCisgICAgKiByZWNvbmNpbGlhdGUgbmFtZXNwYWNlcy4KKyAgICAqLworICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKKwkvKgorCSogRmluZCBhIG5hbWVzcGFjZSBub2RlIGluIHRoZSB0cmVlIG9mIEB0YXJnZXQuCisJKiBBdm9pZCBzZWFyY2hpbmcgZm9yIHRoZSBzYW1lIG5zLgorCSovCisJaWYgKGF0dHItPm5zICE9IG9yaWdOcykgeworCSAgICBvcmlnTnMgPSBhdHRyLT5uczsKKwkgICAgaWYgKGF0dHItPm5zICE9IE5VTEwpIHsKKwkJY29weU5zID0geHNsdEdldFNwZWNpYWxOYW1lc3BhY2UoY3R4dCwgaW52b2NOb2RlLAorCQkgICAgYXR0ci0+bnMtPmhyZWYsIGF0dHItPm5zLT5wcmVmaXgsIHRhcmdldCk7CisJCWlmIChjb3B5TnMgPT0gTlVMTCkKKwkJICAgIHJldHVybigtMSk7CisJICAgIH0gZWxzZQorCQljb3B5TnMgPSBOVUxMOworCX0KKwkvKgorCSAqIElmIGF0dHJpYnV0ZSBoYXMgYSB2YWx1ZSwgd2UgbmVlZCB0byBjb3B5IGl0ICh3YXRjaGluZyBvdXQKKwkgKiBmb3IgcG9zc2libGUgZW50aXRpZXMpCisJICovCisJaWYgKChhdHRyLT5jaGlsZHJlbikgJiYgKGF0dHItPmNoaWxkcmVuLT50eXBlID09IFhNTF9URVhUX05PREUpICYmCisgICAgICAgICAgICAoYXR0ci0+Y2hpbGRyZW4tPm5leHQgPT0gTlVMTCkpIHsKKyAgICAgICAgICAgIGNvcHkgPSB4bWxOZXdOc1Byb3AodGFyZ2V0LCBjb3B5TnMsIGF0dHItPm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHItPmNoaWxkcmVuLT5jb250ZW50KTsKKyAgICAgICAgfSBlbHNlIGlmIChhdHRyLT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJICAgIHZhbHVlID0geG1sTm9kZUxpc3RHZXRTdHJpbmcoYXR0ci0+ZG9jLCBhdHRyLT5jaGlsZHJlbiwgMSk7CisgICAgICAgICAgICBjb3B5ID0geG1sTmV3TnNQcm9wKHRhcmdldCwgY29weU5zLCBhdHRyLT5uYW1lLCBCQURfQ0FTVCB2YWx1ZSk7CisJICAgIHhtbEZyZWUodmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgY29weSA9IHhtbE5ld05zUHJvcCh0YXJnZXQsIGNvcHlOcywgYXR0ci0+bmFtZSwgTlVMTCk7CisgICAgICAgIH0KKworCWlmIChjb3B5ID09IE5VTEwpCisJICAgIHJldHVybigtMSk7CisKKwlhdHRyID0gYXR0ci0+bmV4dDsKKyAgICB9CisgICAgcmV0dXJuKDApOworfQorCisvKioKKyAqIHhzbHRTaGFsbG93Q29weUVsZW06CisgKiBAY3R4dDogIHRoZSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQG5vZGU6ICB0aGUgZWxlbWVudCBub2RlIGluIHRoZSBzb3VyY2UgdHJlZQorICogICAgICAgICBvciB0aGUgTGl0ZXJhbCBSZXN1bHQgRWxlbWVudAorICogQGluc2VydDogIHRoZSBwYXJlbnQgaW4gdGhlIHJlc3VsdCB0cmVlCisgKiBAaXNMUkU6IGlmIEBub2RlIGlzIGEgTGl0ZXJhbCBSZXN1bHQgRWxlbWVudAorICoKKyAqIE1ha2UgYSBjb3B5IG9mIHRoZSBlbGVtZW50IG5vZGUgQG5vZGUKKyAqIGFuZCBpbnNlcnQgaXQgYXMgbGFzdCBjaGlsZCBvZiBAaW5zZXJ0LgorICoKKyAqIFVSR0VOVCBUT0RPOiBUaGUgcHJvYmxlbSB3aXRoIHRoaXMgb25lIChmb3IgdGhlIG5vbi1yZWZhY3RvcmVkIGNvZGUpCisgKiBpcyB0aGF0IGl0IGlzIHVzZWQgZm9yIGJvdGgsIExpdGVyYWwgUmVzdWx0IEVsZW1lbnRzICphbmQqCisgKiBjb3B5aW5nIGlucHV0IG5vZGVzLgorICoKKyAqIEJJRyBOT1RFOiBUaGlzIGlzIG9ubHkgY2FsbGVkIGZvciBYTUxfRUxFTUVOVF9OT0RFcy4KKyAqCisgKiBDYWxsZWQgZnJvbToKKyAqICAgeHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcigpCisgKiAgICAoZm9yIExpdGVyYWwgUmVzdWx0IEVsZW1lbnRzIC0gd2hpY2ggaXMgYSBwcm9ibGVtKQorICogICB4c2x0Q29weSgpIChmb3Igc2hhbGxvdy1jb3B5aW5nIGVsZW1lbnRzIHZpYSB4c2w6Y29weSkKKyAqCisgKiBSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgbmV3IG5vZGUsIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgorICovCitzdGF0aWMgeG1sTm9kZVB0cgoreHNsdFNoYWxsb3dDb3B5RWxlbSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJCSAgICB4bWxOb2RlUHRyIGluc2VydCwgaW50IGlzTFJFKQoreworICAgIHhtbE5vZGVQdHIgY29weTsKKworICAgIGlmICgobm9kZS0+dHlwZSA9PSBYTUxfRFREX05PREUpIHx8IChpbnNlcnQgPT0gTlVMTCkpCisJcmV0dXJuKE5VTEwpOworICAgIGlmICgobm9kZS0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB8fAorCShub2RlLT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKQorCXJldHVybih4c2x0Q29weVRleHQoY3R4dCwgaW5zZXJ0LCBub2RlLCAwKSk7CisKKyAgICBjb3B5ID0geG1sRG9jQ29weU5vZGUobm9kZSwgaW5zZXJ0LT5kb2MsIDApOworICAgIGlmIChjb3B5ICE9IE5VTEwpIHsKKwljb3B5LT5kb2MgPSBjdHh0LT5vdXRwdXQ7CisJY29weSA9IHhzbHRBZGRDaGlsZChpbnNlcnQsIGNvcHkpOworCisJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgeworCSAgICAvKgorCSAgICAgKiBBZGQgbmFtZXNwYWNlcyBhcyB0aGV5IGFyZSBuZWVkZWQKKwkgICAgICovCisJICAgIGlmIChub2RlLT5uc0RlZiAhPSBOVUxMKSB7CisJCS8qCisJCSogVE9ETzogUmVtb3ZlIHRoZSBMUkUgY2FzZSBpbiB0aGUgcmVmYWN0b3JlZCBjb2RlCisJCSogZ2V0cyBlbmFibGVkLgorCQkqLworCQlpZiAoaXNMUkUpCisJCSAgICB4c2x0Q29weU5hbWVzcGFjZUxpc3QoY3R4dCwgY29weSwgbm9kZS0+bnNEZWYpOworCQllbHNlCisJCSAgICB4c2x0Q29weU5hbWVzcGFjZUxpc3RJbnRlcm5hbChjb3B5LCBub2RlLT5uc0RlZik7CisJICAgIH0KKworCSAgICAvKgorCSAgICAqIFVSR0VOVCBUT0RPOiBUaGUgcHJvYmxlbSB3aXRoIHRoaXMgaXMgdGhhdCBpdCBkb2VzIG5vdAorCSAgICAqICBjb3B5IG92ZXIgYWxsIG5hbWVzcGFjZSBub2RlcyBpbiBzY29wZS4KKwkgICAgKiAgVGhlIGRhbW4gdGhpbmcgYWJvdXQgdGhpcyBpcywgdGhhdCB3ZSB3b3VsZCBuZWVkIHRvCisJICAgICogIHVzZSB0aGUgeG1sR2V0TnNMaXN0KCksIGZvciBldmVyeSBzaW5nbGUgbm9kZTsgdGhpcyBpcworCSAgICAqICBhbHNvIGRvbmUgaW4geHNsdENvcHlUcmVlSW50ZXJuYWwoKSwgYnV0IG9ubHkgZm9yIHRoZSB0b3Agbm9kZS4KKwkgICAgKi8KKwkgICAgaWYgKG5vZGUtPm5zICE9IE5VTEwpIHsKKwkJaWYgKGlzTFJFKSB7CisJCSAgICAvKgorCQkgICAgKiBSRVZJU0lUIFRPRE86IFNpbmNlIHRoZSBub24tcmVmYWN0b3JlZCBjb2RlIHN0aWxsIGRvZXMKKwkJICAgICogIG5zLWFsaWFzaW5nLCB3ZSBuZWVkIHRvIGNhbGwgeHNsdEdldE5hbWVzcGFjZSgpIGhlcmUuCisJCSAgICAqICBSZW1vdmUgdGhpcyB3aGVuIHJlYWR5LgorCQkgICAgKi8KKwkJICAgIGNvcHktPm5zID0geHNsdEdldE5hbWVzcGFjZShjdHh0LCBub2RlLCBub2RlLT5ucywgY29weSk7CisJCX0gZWxzZSB7CisJCSAgICBjb3B5LT5ucyA9IHhzbHRHZXRTcGVjaWFsTmFtZXNwYWNlKGN0eHQsCisJCQlub2RlLCBub2RlLT5ucy0+aHJlZiwgbm9kZS0+bnMtPnByZWZpeCwgY29weSk7CisKKwkJfQorCSAgICB9IGVsc2UgaWYgKChpbnNlcnQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKKwkJICAgICAgIChpbnNlcnQtPm5zICE9IE5VTEwpKQorCSAgICB7CisJCS8qCisJCSogIlVuZGVjbGFyZSIgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLgorCQkqLworCQl4c2x0R2V0U3BlY2lhbE5hbWVzcGFjZShjdHh0LCBub2RlLCBOVUxMLCBOVUxMLCBjb3B5KTsKKwkgICAgfQorCX0KKyAgICB9IGVsc2UgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBub2RlLAorCQkieHNsdFNoYWxsb3dDb3B5RWxlbTogY29weSAlcyBmYWlsZWRcbiIsIG5vZGUtPm5hbWUpOworICAgIH0KKyAgICByZXR1cm4oY29weSk7Cit9CisKKy8qKgorICogeHNsdENvcHlUcmVlTGlzdDoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQGludm9jTm9kZTogcmVzcG9uc2libGUgbm9kZSBpbiB0aGUgc3R5bGVzaGVldDsgdXNlZCBmb3IgZXJyb3IgcmVwb3J0cworICogQGxpc3Q6ICB0aGUgbGlzdCBvZiBlbGVtZW50IG5vZGVzIGluIHRoZSBzb3VyY2UgdHJlZS4KKyAqIEBpbnNlcnQ6ICB0aGUgcGFyZW50IGluIHRoZSByZXN1bHQgdHJlZS4KKyAqIEBpc0xSRTogIGlzIHRoaXMgYSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50IGxpc3QKKyAqIEB0b3BFbGVtVmlzaXRlZDogaW5kaWNhdGVzIGlmIGEgdG9wLW1vc3QgZWxlbWVudCB3YXMgYWxyZWFkeSBwcm9jZXNzZWQKKyAqCisgKiBNYWtlIGEgY29weSBvZiB0aGUgZnVsbCBsaXN0IG9mIHRyZWUgQGxpc3QKKyAqIGFuZCBpbnNlcnQgaXQgYXMgbGFzdCBjaGlsZHJlbiBvZiBAaW5zZXJ0CisgKgorICogTk9URTogTm90IHRvIGJlIHVzZWQgZm9yIExpdGVyYWwgUmVzdWx0IEVsZW1lbnRzLgorICoKKyAqIFVzZWQgYnk6CisgKiAgLSB4c2x0Q29weU9mKCkKKyAqCisgKiBSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgbmV3IGxpc3QsIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgorICovCitzdGF0aWMgeG1sTm9kZVB0cgoreHNsdENvcHlUcmVlTGlzdCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGludm9jTm9kZSwKKwkJIHhtbE5vZGVQdHIgbGlzdCwKKwkJIHhtbE5vZGVQdHIgaW5zZXJ0LCBpbnQgaXNMUkUsIGludCB0b3BFbGVtVmlzaXRlZCkKK3sKKyAgICB4bWxOb2RlUHRyIGNvcHksIHJldCA9IE5VTEw7CisKKyAgICB3aGlsZSAobGlzdCAhPSBOVUxMKSB7CisJY29weSA9IHhzbHRDb3B5VHJlZUludGVybmFsKGN0eHQsIGludm9jTm9kZSwKKwkgICAgbGlzdCwgaW5zZXJ0LCBpc0xSRSwgdG9wRWxlbVZpc2l0ZWQpOworCWlmIChjb3B5ICE9IE5VTEwpIHsKKwkgICAgaWYgKHJldCA9PSBOVUxMKSB7CisJCXJldCA9IGNvcHk7CisJICAgIH0KKwl9CisJbGlzdCA9IGxpc3QtPm5leHQ7CisgICAgfQorICAgIHJldHVybihyZXQpOworfQorCisvKioKKyAqIHhzbHRDb3B5TmFtZXNwYWNlTGlzdEludGVybmFsOgorICogQG5vZGU6ICB0aGUgdGFyZ2V0IG5vZGUKKyAqIEBjdXI6ICB0aGUgZmlyc3QgbmFtZXNwYWNlCisgKgorICogRG8gYSBjb3B5IG9mIGEgbmFtZXNwYWNlIGxpc3QuIElmIEBub2RlIGlzIG5vbi1OVUxMIHRoZQorICogbmV3IG5hbWVzcGFjZXMgYXJlIGFkZGVkIGF1dG9tYXRpY2FsbHkuCisgKiBDYWxsZWQgYnk6CisgKiAgIHhzbHRDb3B5VHJlZUludGVybmFsKCkKKyAqCisgKiBRVUVTVElPTjogV2hhdCBpcyB0aGUgZXhhY3QgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoaXMgZnVuY3Rpb24KKyAqICBhbmQgeHNsdENvcHlOYW1lc3BhY2VMaXN0KCkgaW4gIm5hbWVzcGFjZXMuYyI/CisgKiBBTlNXRVI6IHhzbHRDb3B5TmFtZXNwYWNlTGlzdCgpIHRyaWVzIHRvIGFwcGx5IG5zLWFsaWFzZXMuCisgKgorICogUmV0dXJuczogYSBuZXcgeG1sTnNQdHIsIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KKyAqLworc3RhdGljIHhtbE5zUHRyCit4c2x0Q29weU5hbWVzcGFjZUxpc3RJbnRlcm5hbCh4bWxOb2RlUHRyIGVsZW0sIHhtbE5zUHRyIG5zKSB7CisgICAgeG1sTnNQdHIgcmV0ID0gTlVMTDsKKyAgICB4bWxOc1B0ciBwID0gTlVMTCwgcSwgbHVOczsKKworICAgIGlmIChucyA9PSBOVUxMKQorCXJldHVybihOVUxMKTsKKyAgICAvKgorICAgICAqIE9uZSBjYW4gYWRkIG5hbWVzcGFjZXMgb25seSBvbiBlbGVtZW50IG5vZGVzCisgICAgICovCisgICAgaWYgKChlbGVtICE9IE5VTEwpICYmIChlbGVtLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpKQorCWVsZW0gPSBOVUxMOworCisgICAgZG8geworCWlmIChucy0+dHlwZSAhPSBYTUxfTkFNRVNQQUNFX0RFQ0wpCisJICAgIGJyZWFrOworCS8qCisJICogQXZvaWQgZHVwbGljYXRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBvbiB0aGUgdHJlZS4KKwkgKi8KKwlpZiAoZWxlbSAhPSBOVUxMKSB7CisJICAgIGlmICgoZWxlbS0+bnMgIT0gTlVMTCkgJiYKKwkJeG1sU3RyRXF1YWwoZWxlbS0+bnMtPnByZWZpeCwgbnMtPnByZWZpeCkgJiYKKwkJeG1sU3RyRXF1YWwoZWxlbS0+bnMtPmhyZWYsIG5zLT5ocmVmKSkKKwkgICAgeworCQlucyA9IG5zLT5uZXh0OworCQljb250aW51ZTsKKwkgICAgfQorCSAgICBsdU5zID0geG1sU2VhcmNoTnMoZWxlbS0+ZG9jLCBlbGVtLCBucy0+cHJlZml4KTsKKwkgICAgaWYgKChsdU5zICE9IE5VTEwpICYmICh4bWxTdHJFcXVhbChsdU5zLT5ocmVmLCBucy0+aHJlZikpKQorCSAgICB7CisJCW5zID0gbnMtPm5leHQ7CisJCWNvbnRpbnVlOworCSAgICB9CisJfQorCXEgPSB4bWxOZXdOcyhlbGVtLCBucy0+aHJlZiwgbnMtPnByZWZpeCk7CisJaWYgKHAgPT0gTlVMTCkgeworCSAgICByZXQgPSBwID0gcTsKKwl9IGVsc2UgaWYgKHEgIT0gTlVMTCkgeworCSAgICBwLT5uZXh0ID0gcTsKKwkgICAgcCA9IHE7CisJfQorCW5zID0gbnMtPm5leHQ7CisgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CisgICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdFNoYWxsb3dDb3B5TnNOb2RlOgorICogQGN0eHQ6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAaW52b2NOb2RlOiByZXNwb25zaWJsZSBub2RlIGluIHRoZSBzdHlsZXNoZWV0OyB1c2VkIGZvciBlcnJvciByZXBvcnRzCisgKiBAaW5zZXJ0OiAgdGhlIHRhcmdldCBlbGVtZW50IG5vZGUgaW4gdGhlIHJlc3VsdCB0cmVlCisgKiBAbnM6IHRoZSBuYW1lc3BhY2Ugbm9kZQorICoKKyAqIFRoaXMgaXMgdXNlZCBmb3IgY29weWluZyBucy1ub2RlcyB3aXRoIHhzbDpjb3B5LW9mIGFuZCB4c2w6Y29weS4KKyAqCisgKiBSZXR1cm5zIGEgbmV3L2V4aXN0aW5nIG5zLW5vZGUsIG9yIE5VTEwuCisgKi8KK3N0YXRpYyB4bWxOc1B0cgoreHNsdFNoYWxsb3dDb3B5TnNOb2RlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCSAgICAgIHhtbE5vZGVQdHIgaW52b2NOb2RlLAorCQkgICAgICB4bWxOb2RlUHRyIGluc2VydCwKKwkJICAgICAgeG1sTnNQdHIgbnMpCit7CisgICAgLyoKKyAgICAgKiBUT0RPOiBDb250cmFyeSB0byBoZWFkZXIgY29tbWVudHMsIHRoaXMgaXMgZGVjbGFyZWQgYXMgaW50LgorICAgICAqIGJlIG1vZGlmaWVkIHRvIHJldHVybiBhIG5vZGUgcG9pbnRlciwgb3IgTlVMTCBpZiBhbnkgZXJyb3IKKyAgICAgKi8KKyAgICB4bWxOc1B0ciB0bXBuczsKKworICAgIGlmICgoaW5zZXJ0ID09IE5VTEwpIHx8IChpbnNlcnQtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkpCisJcmV0dXJuKE5VTEwpOworCisgICAgaWYgKGluc2VydC0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnZvY05vZGUsCisJICAgICJOYW1lc3BhY2Ugbm9kZXMgbXVzdCBiZSBhZGRlZCBiZWZvcmUgIgorCSAgICAiYW55IGNoaWxkIG5vZGVzIGFyZSBhZGRlZCB0byBhbiBlbGVtZW50LlxuIik7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICAvKgorICAgICAqIEJJRyBOT1RFOiBYYWxhbi1KIHNpbXBseSBvdmVyd3JpdGVzIGFueSBucy1kZWNscyB3aXRoCisgICAgICogYW4gZXF1YWwgcHJlZml4LiBXZSBkZWZpbml0aXZlbHkgd29uJ3QgZG8gdGhhdC4KKyAgICAgKgorICAgICAqIE1TWE1MIDQuMCBhbmQgdGhlIC5ORVQgaWdub3JlcyBucy1kZWNscyBmb3Igd2hpY2ggYW4KKyAgICAgKiBlcXVhbCBwcmVmaXggaXMgYWxyZWFkeSBpbiB1c2UuCisgICAgICoKKyAgICAgKiBTYXhvbiByYWlzZXMgYW4gZXJyb3IgbGlrZToKKyAgICAgKiAibmV0LnNmLnNheG9uLnhwYXRoLkR5bmFtaWNFcnJvcjogQ2Fubm90IGNyZWF0ZSB0d28gbmFtZXNwYWNlCisgICAgICogbm9kZXMgd2l0aCB0aGUgc2FtZSBuYW1lIi4KKyAgICAgKgorICAgICAqIE5PVEU6IFdlJ2xsIGN1cnJlbnRseSBmb2xsb3cgTVNYTUwgaGVyZS4KKyAgICAgKiBSRVZJU0lUIFRPRE86IENoZWNrIGlmIGl0J3MgYmV0dGVyIHRvIGZvbGxvdyBTYXhvbiBoZXJlLgorICAgICAqLworICAgIGlmIChucy0+cHJlZml4ID09IE5VTEwpIHsKKwkvKgorCSogSWYgd2UgYXJlIGFkZGluZyBucy1ub2RlcyB0byBhbiBlbGVtZW50IHVzaW5nIGUuZy4KKwkqIDx4c2w6Y29weS1vZiBzZWxlY3Q9Ii9mb28vbmFtZXNwYWNlOjoqIj4sIHRoZW4gd2UgbmVlZAorCSogdG8gZW5zdXJlIHRoYXQgd2UgZG9uJ3QgaW5jb3JyZWN0bHkgZGVjbGFyZSBhIGRlZmF1bHQKKwkqIG5hbWVzcGFjZSBvbiBhbiBlbGVtZW50IGluIG5vIG5hbWVzcGFjZSwgd2hpY2ggb3RoZXJ3aXNlCisJKiB3b3VsZCBtb3ZlIHRoZSBlbGVtZW50IGluY29ycmVjdGx5IGludG8gYSBuYW1lc3BhY2UsIGlmCisJKiB0aGUgbm9kZSB0cmVlIGlzIHNlcmlhbGl6ZWQuCisJKi8KKwlpZiAoaW5zZXJ0LT5ucyA9PSBOVUxMKQorCSAgICBnb3RvIG9jY3VwaWVkOworICAgIH0gZWxzZSBpZiAoKG5zLT5wcmVmaXhbMF0gPT0gJ3gnKSAmJgorCXhtbFN0ckVxdWFsKG5zLT5wcmVmaXgsIEJBRF9DQVNUICJ4bWwiKSkKKyAgICB7CisJLyoKKwkqIFRoZSBYTUwgbmFtZXNwYWNlIGlzIGJ1aWx0IGluLgorCSovCisJcmV0dXJuKE5VTEwpOworICAgIH0KKworICAgIGlmIChpbnNlcnQtPm5zRGVmICE9IE5VTEwpIHsKKwl0bXBucyA9IGluc2VydC0+bnNEZWY7CisJZG8geworCSAgICBpZiAoKHRtcG5zLT5wcmVmaXggPT0gTlVMTCkgPT0gKG5zLT5wcmVmaXggPT0gTlVMTCkpIHsKKwkJaWYgKCh0bXBucy0+cHJlZml4ID09IG5zLT5wcmVmaXgpIHx8CisJCSAgICB4bWxTdHJFcXVhbCh0bXBucy0+cHJlZml4LCBucy0+cHJlZml4KSkKKwkJeworCQkgICAgLyoKKwkJICAgICogU2FtZSBwcmVmaXguCisJCSAgICAqLworCQkgICAgaWYgKHhtbFN0ckVxdWFsKHRtcG5zLT5ocmVmLCBucy0+aHJlZikpCisJCQlyZXR1cm4oTlVMTCk7CisJCSAgICBnb3RvIG9jY3VwaWVkOworCQl9CisJICAgIH0KKwkgICAgdG1wbnMgPSB0bXBucy0+bmV4dDsKKwl9IHdoaWxlICh0bXBucyAhPSBOVUxMKTsKKyAgICB9CisgICAgdG1wbnMgPSB4bWxTZWFyY2hOcyhpbnNlcnQtPmRvYywgaW5zZXJ0LCBucy0+cHJlZml4KTsKKyAgICBpZiAoKHRtcG5zICE9IE5VTEwpICYmIHhtbFN0ckVxdWFsKHRtcG5zLT5ocmVmLCBucy0+aHJlZikpCisJcmV0dXJuKE5VTEwpOworICAgIC8qCisgICAgKiBEZWNsYXJlIGEgbmV3IG5hbWVzcGFjZS4KKyAgICAqIFRPRE86IFRoZSBwcm9ibGVtICh3cnQgZWZmaWNpZW5jeSkgd2l0aCB0aGlzIHhtbE5ld05zKCkgaXMKKyAgICAqIHRoYXQgaXQgd2lsbCBhZ2FpbiBzZWFyY2ggdGhlIGFscmVhZHkgZGVjbGFyZWQgbmFtZXNwYWNlcworICAgICogZm9yIGEgZHVwbGljYXRlIDotLworICAgICovCisgICAgcmV0dXJuKHhtbE5ld05zKGluc2VydCwgbnMtPmhyZWYsIG5zLT5wcmVmaXgpKTsKKworb2NjdXBpZWQ6CisgICAgLyoKKyAgICAqIFRPRE86IFdlIGNvdWxkIGFzIHdlbGwgcmFpc2UgYW4gZXJyb3IgaGVyZSAobGlrZSBTYXhvbiBkb2VzKSwKKyAgICAqIG9yIGF0IGxlYXN0IGdlbmVyYXRlIGEgd2FybmluZy4KKyAgICAqLworICAgIHJldHVybihOVUxMKTsKK30KKworLyoqCisgKiB4c2x0Q29weVRyZWVJbnRlcm5hbDoKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQGludm9jTm9kZTogcmVzcG9uc2libGUgbm9kZSBpbiB0aGUgc3R5bGVzaGVldDsgdXNlZCBmb3IgZXJyb3IgcmVwb3J0cworICogQG5vZGU6ICB0aGUgZWxlbWVudCBub2RlIGluIHRoZSBzb3VyY2UgdHJlZQorICogQGluc2VydDogIHRoZSBwYXJlbnQgaW4gdGhlIHJlc3VsdCB0cmVlCisgKiBAaXNMUkU6ICBpbmRpY2F0ZXMgaWYgQG5vZGUgaXMgYSBMaXRlcmFsIFJlc3VsdCBFbGVtZW50CisgKiBAdG9wRWxlbVZpc2l0ZWQ6IGluZGljYXRlcyBpZiBhIHRvcC1tb3N0IGVsZW1lbnQgd2FzIGFscmVhZHkgcHJvY2Vzc2VkCisgKgorICogTWFrZSBhIGNvcHkgb2YgdGhlIGZ1bGwgdHJlZSB1bmRlciB0aGUgZWxlbWVudCBub2RlIEBub2RlCisgKiBhbmQgaW5zZXJ0IGl0IGFzIGxhc3QgY2hpbGQgb2YgQGluc2VydAorICoKKyAqIE5PVEU6IE5vdCB0byBiZSB1c2VkIGZvciBMaXRlcmFsIFJlc3VsdCBFbGVtZW50cy4KKyAqCisgKiBVc2VkIGJ5OgorICogIC0geHNsdENvcHlPZigpCisgKgorICogUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIG5ldyB0cmVlLCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworc3RhdGljIHhtbE5vZGVQdHIKK3hzbHRDb3B5VHJlZUludGVybmFsKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCSAgICAgeG1sTm9kZVB0ciBpbnZvY05vZGUsCisJCSAgICAgeG1sTm9kZVB0ciBub2RlLAorCQkgICAgIHhtbE5vZGVQdHIgaW5zZXJ0LCBpbnQgaXNMUkUsIGludCB0b3BFbGVtVmlzaXRlZCkKK3sKKyAgICB4bWxOb2RlUHRyIGNvcHk7CisKKyAgICBpZiAobm9kZSA9PSBOVUxMKQorCXJldHVybihOVUxMKTsKKyAgICBzd2l0Y2ggKG5vZGUtPnR5cGUpIHsKKyAgICAgICAgY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgorICAgICAgICBjYXNlIFhNTF9FTlRJVFlfUkVGX05PREU6CisgICAgICAgIGNhc2UgWE1MX0VOVElUWV9OT0RFOgorICAgICAgICBjYXNlIFhNTF9QSV9OT0RFOgorICAgICAgICBjYXNlIFhNTF9DT01NRU5UX05PREU6CisgICAgICAgIGNhc2UgWE1MX0RPQ1VNRU5UX05PREU6CisgICAgICAgIGNhc2UgWE1MX0hUTUxfRE9DVU1FTlRfTk9ERToKKyNpZmRlZiBMSUJYTUxfRE9DQl9FTkFCTEVECisgICAgICAgIGNhc2UgWE1MX0RPQ0JfRE9DVU1FTlRfTk9ERToKKyNlbmRpZgorCSAgICBicmVhazsKKyAgICAgICAgY2FzZSBYTUxfVEVYVF9OT0RFOiB7CisJICAgIGludCBub2VuYyA9IChub2RlLT5uYW1lID09IHhtbFN0cmluZ1RleHROb2VuYyk7CisJICAgIHJldHVybih4c2x0Q29weVRleHRTdHJpbmcoY3R4dCwgaW5zZXJ0LCBub2RlLT5jb250ZW50LCBub2VuYykpOworCSAgICB9CisgICAgICAgIGNhc2UgWE1MX0NEQVRBX1NFQ1RJT05fTk9ERToKKwkgICAgcmV0dXJuKHhzbHRDb3B5VGV4dFN0cmluZyhjdHh0LCBpbnNlcnQsIG5vZGUtPmNvbnRlbnQsIDApKTsKKyAgICAgICAgY2FzZSBYTUxfQVRUUklCVVRFX05PREU6CisJICAgIHJldHVybigoeG1sTm9kZVB0cikKKwkJeHNsdFNoYWxsb3dDb3B5QXR0cihjdHh0LCBpbnZvY05vZGUsIGluc2VydCwgKHhtbEF0dHJQdHIpIG5vZGUpKTsKKyAgICAgICAgY2FzZSBYTUxfTkFNRVNQQUNFX0RFQ0w6CisJICAgIHJldHVybigoeG1sTm9kZVB0cikgeHNsdFNoYWxsb3dDb3B5TnNOb2RlKGN0eHQsIGludm9jTm9kZSwKKwkJaW5zZXJ0LCAoeG1sTnNQdHIpIG5vZGUpKTsKKworICAgICAgICBjYXNlIFhNTF9ET0NVTUVOVF9UWVBFX05PREU6CisgICAgICAgIGNhc2UgWE1MX0RPQ1VNRU5UX0ZSQUdfTk9ERToKKyAgICAgICAgY2FzZSBYTUxfTk9UQVRJT05fTk9ERToKKyAgICAgICAgY2FzZSBYTUxfRFREX05PREU6CisgICAgICAgIGNhc2UgWE1MX0VMRU1FTlRfREVDTDoKKyAgICAgICAgY2FzZSBYTUxfQVRUUklCVVRFX0RFQ0w6CisgICAgICAgIGNhc2UgWE1MX0VOVElUWV9ERUNMOgorICAgICAgICBjYXNlIFhNTF9YSU5DTFVERV9TVEFSVDoKKyAgICAgICAgY2FzZSBYTUxfWElOQ0xVREVfRU5EOgorICAgICAgICAgICAgcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBpZiAoWFNMVF9JU19SRVNfVFJFRV9GUkFHKG5vZGUpKSB7CisJaWYgKG5vZGUtPmNoaWxkcmVuICE9IE5VTEwpCisJICAgIGNvcHkgPSB4c2x0Q29weVRyZWVMaXN0KGN0eHQsIGludm9jTm9kZSwKKwkJbm9kZS0+Y2hpbGRyZW4sIGluc2VydCwgMCwgMCk7CisJZWxzZQorCSAgICBjb3B5ID0gTlVMTDsKKwlyZXR1cm4oY29weSk7CisgICAgfQorICAgIGNvcHkgPSB4bWxEb2NDb3B5Tm9kZShub2RlLCBpbnNlcnQtPmRvYywgMCk7CisgICAgaWYgKGNvcHkgIT0gTlVMTCkgeworCWNvcHktPmRvYyA9IGN0eHQtPm91dHB1dDsKKwljb3B5ID0geHNsdEFkZENoaWxkKGluc2VydCwgY29weSk7CisJLyoKKwkgKiBUaGUgbm9kZSBtYXkgaGF2ZSBiZWVuIGNvYWxlc2NlZCBpbnRvIGFub3RoZXIgdGV4dCBub2RlLgorCSAqLworCWlmIChpbnNlcnQtPmxhc3QgIT0gY29weSkKKwkgICAgcmV0dXJuKGluc2VydC0+bGFzdCk7CisJY29weS0+bmV4dCA9IE5VTEw7CisKKwlpZiAobm9kZS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CisJICAgIC8qCisJICAgICogQ29weSBpbi1zY29wZSBuYW1lc3BhY2Ugbm9kZXMuCisJICAgICoKKwkgICAgKiBSRVZJU0lUOiBTaW5jZSB3ZSB0cnkgdG8gcmV1c2UgZXhpc3RpbmcgaW4tc2NvcGUgbnMtZGVjbHMgYnkKKwkgICAgKiAgdXNpbmcgeG1sU2VhcmNoTnNCeUhyZWYoKSwgdGhpcyB3aWxsIGV2ZW50dWFsbHkgY2hhbmdlCisJICAgICogIHRoZSBwcmVmaXggb2YgYW4gb3JpZ2luYWwgbnMtYmluZGluZzsgdGh1cyBpdCBtaWdodAorCSAgICAqICBicmVhayBRTmFtZXMgaW4gZWxlbWVudC9hdHRyaWJ1dGUgY29udGVudC4KKwkgICAgKiBPUFRJTUlaRSBUT0RPOiBJZiB3ZSBoYWQgYSB4bWxOc1B0ciAqIG9uIHRoZSB0cmFuc2Zvcm1hdGlvbgorCSAgICAqICBjb250ZXh0LCBwbHVzIGEgbnMtbG9va3VwIGZ1bmN0aW9uLCB3aGljaCB3cml0ZXMgZGlyZWN0bHkKKwkgICAgKiAgdG8gYSBnaXZlbiBsaXN0LCB0aGVuIHdlIHdvdWxkbid0IG5lZWQgdG8gY3JlYXRlL2ZyZWUgdGhlCisJICAgICogIG5zTGlzdCBldmVyeSB0aW1lLgorCSAgICAqLworCSAgICBpZiAoKHRvcEVsZW1WaXNpdGVkID09IDApICYmCisJCShub2RlLT5wYXJlbnQgIT0gTlVMTCkgJiYKKwkJKG5vZGUtPnBhcmVudC0+dHlwZSAhPSBYTUxfRE9DVU1FTlRfTk9ERSkgJiYKKwkJKG5vZGUtPnBhcmVudC0+dHlwZSAhPSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFKSkKKwkgICAgeworCQl4bWxOc1B0ciAqbnNMaXN0LCAqY3VybnMsIG5zOworCisJCS8qCisJCSogSWYgdGhpcyBpcyBhIHRvcC1tb3N0IGVsZW1lbnQgaW4gYSB0cmVlIHRvIGJlCisJCSogY29waWVkLCB0aGVuIHdlIG5lZWQgdG8gZW5zdXJlIHRoYXQgYWxsIGluLXNjb3BlCisJCSogbmFtZXNwYWNlcyBhcmUgY29waWVkIG92ZXIuIEZvciBub2RlcyBkZWVwZXIgaW4gdGhlCisJCSogdHJlZSwgaXQgaXMgc3VmZmljaWVudCB0byByZWNvbmNpbGUgb25seSB0aGUgbnMtZGVjbHMKKwkJKiAobm9kZS0+bnNEZWYgZW50cmllcykuCisJCSovCisKKwkJbnNMaXN0ID0geG1sR2V0TnNMaXN0KG5vZGUtPmRvYywgbm9kZSk7CisJCWlmIChuc0xpc3QgIT0gTlVMTCkgeworCQkgICAgY3VybnMgPSBuc0xpc3Q7CisJCSAgICBkbyB7CisJCQkvKgorCQkJKiBTZWFyY2ggYnkgcHJlZml4IGZpcnN0IGluIG9yZGVyIHRvIGJyZWFrIGFzIGxlc3MKKwkJCSogUU5hbWVzIGluIGVsZW1lbnQvYXR0cmlidXRlIGNvbnRlbnQgYXMgcG9zc2libGUuCisJCQkqLworCQkJbnMgPSB4bWxTZWFyY2hOcyhpbnNlcnQtPmRvYywgaW5zZXJ0LAorCQkJICAgICgqY3VybnMpLT5wcmVmaXgpOworCisJCQlpZiAoKG5zID09IE5VTEwpIHx8CisJCQkgICAgKCEgeG1sU3RyRXF1YWwobnMtPmhyZWYsICgqY3VybnMpLT5ocmVmKSkpCisJCQl7CisJCQkgICAgbnMgPSBOVUxMOworCQkJICAgIC8qCisJCQkgICAgKiBTZWFyY2ggYnkgbmFtZXNwYWNlIG5hbWUuCisJCQkgICAgKiBSRVZJU0lUIFRPRE86IEN1cnJlbnRseSBkaXNhYmxlZC4KKwkJCSAgICAqLworI2lmIDAKKwkJCSAgICBucyA9IHhtbFNlYXJjaE5zQnlIcmVmKGluc2VydC0+ZG9jLAorCQkJCWluc2VydCwgKCpjdXJucyktPmhyZWYpOworI2VuZGlmCisJCQl9CisJCQlpZiAobnMgPT0gTlVMTCkgeworCQkJICAgIC8qCisJCQkgICAgKiBEZWNsYXJlIGEgbmV3IG5hbWVzcGFjZSBvbiB0aGUgY29waWVkIGVsZW1lbnQuCisJCQkgICAgKi8KKwkJCSAgICBucyA9IHhtbE5ld05zKGNvcHksICgqY3VybnMpLT5ocmVmLAorCQkJCSgqY3VybnMpLT5wcmVmaXgpOworCQkJICAgIC8qIFRPRE86IEhhbmRsZSBlcnJvcnMgKi8KKwkJCX0KKwkJCWlmIChub2RlLT5ucyA9PSAqY3VybnMpIHsKKwkJCSAgICAvKgorCQkJICAgICogSWYgdGhpcyB3YXMgdGhlIG9yaWdpbmFsJ3MgbmFtZXNwYWNlIHRoZW4gc2V0CisJCQkgICAgKiB0aGUgZ2VuZXJhdGVkIGNvdW50ZXJwYXJ0IG9uIHRoZSBjb3B5LgorCQkJICAgICovCisJCQkgICAgY29weS0+bnMgPSBuczsKKwkJCX0KKwkJCWN1cm5zKys7CisJCSAgICB9IHdoaWxlICgqY3VybnMgIT0gTlVMTCk7CisJCSAgICB4bWxGcmVlKG5zTGlzdCk7CisJCX0KKwkgICAgfSBlbHNlIGlmIChub2RlLT5uc0RlZiAhPSBOVUxMKSB7CisJCS8qCisJCSogQ29weSBvdmVyIGFsbCBuYW1lc3BhY2UgZGVjbGFyYXRpb24gYXR0cmlidXRlcy4KKwkJKi8KKwkJaWYgKG5vZGUtPm5zRGVmICE9IE5VTEwpIHsKKwkJICAgIGlmIChpc0xSRSkKKwkJCXhzbHRDb3B5TmFtZXNwYWNlTGlzdChjdHh0LCBjb3B5LCBub2RlLT5uc0RlZik7CisJCSAgICBlbHNlCisJCQl4c2x0Q29weU5hbWVzcGFjZUxpc3RJbnRlcm5hbChjb3B5LCBub2RlLT5uc0RlZik7CisJCX0KKwkgICAgfQorCSAgICAvKgorCSAgICAqIFNldCB0aGUgbmFtZXNwYWNlLgorCSAgICAqLworCSAgICBpZiAobm9kZS0+bnMgIT0gTlVMTCkgeworCQlpZiAoY29weS0+bnMgPT0gTlVMTCkgeworCQkgICAgLyoKKwkJICAgICogVGhpcyB3aWxsIG1hcCBjb3B5LT5ucyB0byBvbmUgb2YgdGhlIG5ld2x5IGNyZWF0ZWQKKwkJICAgICogaW4tc2NvcGUgbnMtZGVjbHMsIE9SIGNyZWF0ZSBhIG5ldyBucy1kZWNsIG9uIEBjb3B5LgorCQkgICAgKi8KKwkJICAgIGNvcHktPm5zID0geHNsdEdldFNwZWNpYWxOYW1lc3BhY2UoY3R4dCwgaW52b2NOb2RlLAorCQkJbm9kZS0+bnMtPmhyZWYsIG5vZGUtPm5zLT5wcmVmaXgsIGNvcHkpOworCQl9CisJICAgIH0gZWxzZSBpZiAoKGluc2VydC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSAmJgorCQkoaW5zZXJ0LT5ucyAhPSBOVUxMKSkKKwkgICAgeworCQkvKgorCQkqICJVbmRlY2xhcmUiIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSBvbiBAY29weSB3aXRoIHhtbG5zPSIiLgorCQkqLworCQl4c2x0R2V0U3BlY2lhbE5hbWVzcGFjZShjdHh0LCBpbnZvY05vZGUsIE5VTEwsIE5VTEwsIGNvcHkpOworCSAgICB9CisJICAgIC8qCisJICAgICogQ29weSBhdHRyaWJ1dGUgbm9kZXMuCisJICAgICovCisJICAgIGlmIChub2RlLT5wcm9wZXJ0aWVzICE9IE5VTEwpIHsKKwkJeHNsdENvcHlBdHRyTGlzdE5vT3ZlcndyaXRlKGN0eHQsIGludm9jTm9kZSwKKwkJICAgIGNvcHksIG5vZGUtPnByb3BlcnRpZXMpOworCSAgICB9CisJICAgIGlmICh0b3BFbGVtVmlzaXRlZCA9PSAwKQorCQl0b3BFbGVtVmlzaXRlZCA9IDE7CisJfQorCS8qCisJKiBDb3B5IHRoZSBzdWJ0cmVlLgorCSovCisJaWYgKG5vZGUtPmNoaWxkcmVuICE9IE5VTEwpIHsKKwkgICAgeHNsdENvcHlUcmVlTGlzdChjdHh0LCBpbnZvY05vZGUsCisJCW5vZGUtPmNoaWxkcmVuLCBjb3B5LCBpc0xSRSwgdG9wRWxlbVZpc2l0ZWQpOworCX0KKyAgICB9IGVsc2UgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnZvY05vZGUsCisJICAgICJ4c2x0Q29weVRyZWVJbnRlcm5hbDogQ29weWluZyBvZiAnJXMnIGZhaWxlZC5cbiIsIG5vZGUtPm5hbWUpOworICAgIH0KKyAgICByZXR1cm4oY29weSk7Cit9CisKKy8qKgorICogeHNsdENvcHlUcmVlOgorICogQGN0eHQ6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAbm9kZTogIHRoZSBlbGVtZW50IG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlCisgKiBAaW5zZXJ0OiAgdGhlIHBhcmVudCBpbiB0aGUgcmVzdWx0IHRyZWUKKyAqIEBsaXRlcmFsOiAgaW5kaWNhdGVzIGlmIEBub2RlIGlzIGEgTGl0ZXJhbCBSZXN1bHQgRWxlbWVudAorICoKKyAqIE1ha2UgYSBjb3B5IG9mIHRoZSBmdWxsIHRyZWUgdW5kZXIgdGhlIGVsZW1lbnQgbm9kZSBAbm9kZQorICogYW5kIGluc2VydCBpdCBhcyBsYXN0IGNoaWxkIG9mIEBpbnNlcnQKKyAqIEZvciBsaXRlcmFsIHJlc3VsdCBlbGVtZW50LCBzb21lIG9mIHRoZSBuYW1lc3BhY2VzIG1heSBub3QgYmUgY29waWVkCisgKiBvdmVyIGFjY29yZGluZyB0byBzZWN0aW9uIDcuMS4KKyAqIFRPRE86IFdoeSBpcyB0aGlzIGEgcHVibGljIGZ1bmN0aW9uPworICoKKyAqIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBuZXcgdHJlZSwgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3htbE5vZGVQdHIKK3hzbHRDb3B5VHJlZSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJICAgICB4bWxOb2RlUHRyIGluc2VydCwgaW50IGxpdGVyYWwpCit7CisgICAgcmV0dXJuKHhzbHRDb3B5VHJlZUludGVybmFsKGN0eHQsIG5vZGUsIG5vZGUsIGluc2VydCwgbGl0ZXJhbCwgMCkpOworCit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICoJCUVycm9yL2ZhbGxiYWNrIHByb2Nlc3NpbmcJCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHRBcHBseUZhbGxiYWNrczoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQG5vZGU6ICB0aGUgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUuCisgKiBAaW5zdDogIHRoZSBub2RlIGdlbmVyYXRpbmcgdGhlIGVycm9yCisgKgorICogUHJvY2VzcyBwb3NzaWJsZSB4c2w6ZmFsbGJhY2sgbm9kZXMgcHJlc2VudCB1bmRlciBAaW5zdAorICoKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiB4c2w6ZmFsbGJhY2sgZWxlbWVudCBmb3VuZCBhbmQgcHJvY2Vzc2VkCisgKi8KK3N0YXRpYyBpbnQKK3hzbHRBcHBseUZhbGxiYWNrcyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJICAgICAgICAgICB4bWxOb2RlUHRyIGluc3QpIHsKKworICAgIHhtbE5vZGVQdHIgY2hpbGQ7CisgICAgaW50IHJldCA9IDA7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkgfHwKKwkoaW5zdC0+Y2hpbGRyZW4gPT0gTlVMTCkpCisJcmV0dXJuKDApOworCisgICAgY2hpbGQgPSBpbnN0LT5jaGlsZHJlbjsKKyAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgeworICAgICAgICBpZiAoKElTX1hTTFRfRUxFTShjaGlsZCkpICYmCisgICAgICAgICAgICAoeG1sU3RyRXF1YWwoY2hpbGQtPm5hbWUsIEJBRF9DQVNUICJmYWxsYmFjayIpKSkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkgICAgICJhcHBseWluZyB4c2w6ZmFsbGJhY2tcbiIpOworI2VuZGlmCisJICAgIHJldCsrOworCSAgICB4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yKGN0eHQsIG5vZGUsIGNoaWxkLT5jaGlsZHJlbiwKKwkJTlVMTCk7CisJfQorCWNoaWxkID0gY2hpbGQtPm5leHQ7CisgICAgfQorICAgIHJldHVybihyZXQpOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkJRGVmYXVsdCBwcm9jZXNzaW5nCQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0RGVmYXVsdFByb2Nlc3NPbmVOb2RlOgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAbm9kZTogIHRoZSBub2RlIGluIHRoZSBzb3VyY2UgdHJlZS4KKyAqIEBwYXJhbXM6IGV4dHJhIHBhcmFtZXRlcnMgcGFzc2VkIHRvIHRoZSB0ZW1wbGF0ZSBpZiBhbnkKKyAqCisgKiBQcm9jZXNzIHRoZSBzb3VyY2Ugbm9kZSB3aXRoIHRoZSBkZWZhdWx0IGJ1aWx0LWluIHRlbXBsYXRlIHJ1bGU6CisgKiA8eHNsOnRlbXBsYXRlIG1hdGNoPSIqfC8iPgorICogICA8eHNsOmFwcGx5LXRlbXBsYXRlcy8+CisgKiA8L3hzbDp0ZW1wbGF0ZT4KKyAqCisgKiBhbmQKKyAqCisgKiA8eHNsOnRlbXBsYXRlIG1hdGNoPSJ0ZXh0KCl8QCoiPgorICogICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iLiIvPgorICogPC94c2w6dGVtcGxhdGU+CisgKgorICogTm90ZSBhbHNvIHRoYXQgbmFtZXNwYWNlIGRlY2xhcmF0aW9ucyBhcmUgY29waWVkIGRpcmVjdGx5OgorICoKKyAqIHRoZSBidWlsdC1pbiB0ZW1wbGF0ZSBydWxlIGlzIHRoZSBvbmx5IHRlbXBsYXRlIHJ1bGUgdGhhdCBpcyBhcHBsaWVkCisgKiBmb3IgbmFtZXNwYWNlIG5vZGVzLgorICovCitzdGF0aWMgdm9pZAoreHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJCQkgIHhzbHRTdGFja0VsZW1QdHIgcGFyYW1zKSB7CisgICAgeG1sTm9kZVB0ciBjb3B5OworICAgIHhtbE5vZGVQdHIgZGVsZXRlID0gTlVMTCwgY3VyOworICAgIGludCBuYmNoaWxkID0gMCwgb2xkU2l6ZTsKKyAgICBpbnQgY2hpbGRubyA9IDAsIG9sZFBvczsKKyAgICB4c2x0VGVtcGxhdGVQdHIgdGVtcGxhdGU7CisKKyAgICBDSEVDS19TVE9QUEVEOworICAgIC8qCisgICAgICogSGFuZGxpbmcgb2YgbGVhdmVzCisgICAgICovCisgICAgc3dpdGNoIChub2RlLT50eXBlKSB7CisJY2FzZSBYTUxfRE9DVU1FTlRfTk9ERToKKwljYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CisJY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgorCSAgICBicmVhazsKKwljYXNlIFhNTF9DREFUQV9TRUNUSU9OX05PREU6CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwkgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUFJPQ0VTU19OT0RFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZTogY29weSBDREFUQSAlc1xuIiwKKwkJbm9kZS0+Y29udGVudCkpOworI2VuZGlmCisJICAgIGNvcHkgPSB4c2x0Q29weVRleHQoY3R4dCwgY3R4dC0+aW5zZXJ0LCBub2RlLCAwKTsKKwkgICAgaWYgKGNvcHkgPT0gTlVMTCkgeworCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgbm9kZSwKKwkJICJ4c2x0RGVmYXVsdFByb2Nlc3NPbmVOb2RlOiBjZGF0YSBjb3B5IGZhaWxlZFxuIik7CisJICAgIH0KKwkgICAgcmV0dXJuOworCWNhc2UgWE1MX1RFWFRfTk9ERToKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCSAgICBpZiAobm9kZS0+Y29udGVudCA9PSBOVUxMKSB7CisJCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1BST0NFU1NfTk9ERSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgInhzbHREZWZhdWx0UHJvY2Vzc09uZU5vZGU6IGNvcHkgZW1wdHkgdGV4dFxuIikpOworCQlyZXR1cm47CisJICAgIH0gZWxzZSB7CisJCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1BST0NFU1NfTk9ERSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgInhzbHREZWZhdWx0UHJvY2Vzc09uZU5vZGU6IGNvcHkgdGV4dCAlc1xuIiwKKwkJCW5vZGUtPmNvbnRlbnQpKTsKKyAgICAgICAgICAgIH0KKyNlbmRpZgorCSAgICBjb3B5ID0geHNsdENvcHlUZXh0KGN0eHQsIGN0eHQtPmluc2VydCwgbm9kZSwgMCk7CisJICAgIGlmIChjb3B5ID09IE5VTEwpIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIG5vZGUsCisJCSAieHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZTogdGV4dCBjb3B5IGZhaWxlZFxuIik7CisJICAgIH0KKwkgICAgcmV0dXJuOworCWNhc2UgWE1MX0FUVFJJQlVURV9OT0RFOgorCSAgICBjdXIgPSBub2RlLT5jaGlsZHJlbjsKKwkgICAgd2hpbGUgKChjdXIgIT0gTlVMTCkgJiYgKGN1ci0+dHlwZSAhPSBYTUxfVEVYVF9OT0RFKSkKKwkJY3VyID0gY3VyLT5uZXh0OworCSAgICBpZiAoY3VyID09IE5VTEwpIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIG5vZGUsCisJCSAieHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZTogbm8gdGV4dCBmb3IgYXR0cmlidXRlXG4iKTsKKwkgICAgfSBlbHNlIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQlpZiAoY3VyLT5jb250ZW50ID09IE5VTEwpIHsKKwkJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1BST0NFU1NfTk9ERSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgICJ4c2x0RGVmYXVsdFByb2Nlc3NPbmVOb2RlOiBjb3B5IGVtcHR5IHRleHRcbiIpKTsKKwkJfSBlbHNlIHsKKwkJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1BST0NFU1NfTk9ERSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgICJ4c2x0RGVmYXVsdFByb2Nlc3NPbmVOb2RlOiBjb3B5IHRleHQgJXNcbiIsCisJCQljdXItPmNvbnRlbnQpKTsKKyAgICAgICAgICAgICAgICB9CisjZW5kaWYKKwkJY29weSA9IHhzbHRDb3B5VGV4dChjdHh0LCBjdHh0LT5pbnNlcnQsIGN1ciwgMCk7CisJCWlmIChjb3B5ID09IE5VTEwpIHsKKwkJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBub2RlLAorCQkgICAgICJ4c2x0RGVmYXVsdFByb2Nlc3NPbmVOb2RlOiB0ZXh0IGNvcHkgZmFpbGVkXG4iKTsKKwkJfQorCSAgICB9CisJICAgIHJldHVybjsKKwlkZWZhdWx0OgorCSAgICByZXR1cm47CisgICAgfQorICAgIC8qCisgICAgICogSGFuZGxpbmcgb2YgRWxlbWVudHM6IGZpcnN0IHBhc3MsIGNsZWFudXAgYW5kIGNvdW50aW5nCisgICAgICovCisgICAgY3VyID0gbm9kZS0+Y2hpbGRyZW47CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJc3dpdGNoIChjdXItPnR5cGUpIHsKKwkgICAgY2FzZSBYTUxfVEVYVF9OT0RFOgorCSAgICBjYXNlIFhNTF9DREFUQV9TRUNUSU9OX05PREU6CisJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX05PREU6CisJICAgIGNhc2UgWE1MX0hUTUxfRE9DVU1FTlRfTk9ERToKKwkgICAgY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgorCSAgICBjYXNlIFhNTF9QSV9OT0RFOgorCSAgICBjYXNlIFhNTF9DT01NRU5UX05PREU6CisJCW5iY2hpbGQrKzsKKwkJYnJlYWs7CisgICAgICAgICAgICBjYXNlIFhNTF9EVERfTk9ERToKKwkJLyogVW5saW5rIHRoZSBEVEQsIGl0J3Mgc3RpbGwgcmVhY2hhYmxlIHVzaW5nIGRvYy0+aW50U3Vic2V0ICovCisJCWlmIChjdXItPm5leHQgIT0gTlVMTCkKKwkJICAgIGN1ci0+bmV4dC0+cHJldiA9IGN1ci0+cHJldjsKKwkJaWYgKGN1ci0+cHJldiAhPSBOVUxMKQorCQkgICAgY3VyLT5wcmV2LT5uZXh0ID0gY3VyLT5uZXh0OworCQlicmVhazsKKwkgICAgZGVmYXVsdDoKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9QUk9DRVNTX05PREUseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICJ4c2x0RGVmYXVsdFByb2Nlc3NPbmVOb2RlOiBza2lwcGluZyBub2RlIHR5cGUgJWRcbiIsCisJCSAgICAgICAgICAgICAgICAgY3VyLT50eXBlKSk7CisjZW5kaWYKKwkJZGVsZXRlID0gY3VyOworCX0KKwljdXIgPSBjdXItPm5leHQ7CisJaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwkgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUFJPQ0VTU19OT0RFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAieHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZTogcmVtb3ZpbmcgaWdub3JhYmxlIGJsYW5rIG5vZGVcbiIpKTsKKyNlbmRpZgorCSAgICB4bWxVbmxpbmtOb2RlKGRlbGV0ZSk7CisJICAgIHhtbEZyZWVOb2RlKGRlbGV0ZSk7CisJICAgIGRlbGV0ZSA9IE5VTEw7CisJfQorICAgIH0KKyAgICBpZiAoZGVsZXRlICE9IE5VTEwpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1BST0NFU1NfTk9ERSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgInhzbHREZWZhdWx0UHJvY2Vzc09uZU5vZGU6IHJlbW92aW5nIGlnbm9yYWJsZSBibGFuayBub2RlXG4iKSk7CisjZW5kaWYKKwl4bWxVbmxpbmtOb2RlKGRlbGV0ZSk7CisJeG1sRnJlZU5vZGUoZGVsZXRlKTsKKwlkZWxldGUgPSBOVUxMOworICAgIH0KKworICAgIC8qCisgICAgICogSGFuZGxpbmcgb2YgRWxlbWVudHM6IHNlY29uZCBwYXNzLCBhY3R1YWwgcHJvY2Vzc2luZworICAgICAqLworICAgIG9sZFNpemUgPSBjdHh0LT54cGF0aEN0eHQtPmNvbnRleHRTaXplOworICAgIG9sZFBvcyA9IGN0eHQtPnhwYXRoQ3R4dC0+cHJveGltaXR5UG9zaXRpb247CisgICAgY3VyID0gbm9kZS0+Y2hpbGRyZW47CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJY2hpbGRubysrOworCXN3aXRjaCAoY3VyLT50eXBlKSB7CisJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX05PREU6CisJICAgIGNhc2UgWE1MX0hUTUxfRE9DVU1FTlRfTk9ERToKKwkgICAgY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgorCQljdHh0LT54cGF0aEN0eHQtPmNvbnRleHRTaXplID0gbmJjaGlsZDsKKwkJY3R4dC0+eHBhdGhDdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IGNoaWxkbm87CisJCXhzbHRQcm9jZXNzT25lTm9kZShjdHh0LCBjdXIsIHBhcmFtcyk7CisJCWJyZWFrOworCSAgICBjYXNlIFhNTF9DREFUQV9TRUNUSU9OX05PREU6CisJCXRlbXBsYXRlID0geHNsdEdldFRlbXBsYXRlKGN0eHQsIGN1ciwgTlVMTCk7CisJCWlmICh0ZW1wbGF0ZSkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJCSAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9QUk9DRVNTX05PREUseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICJ4c2x0RGVmYXVsdFByb2Nlc3NPbmVOb2RlOiBhcHBseWluZyB0ZW1wbGF0ZSBmb3IgQ0RBVEEgJXNcbiIsCisJCQkJICAgICBjdXItPmNvbnRlbnQpKTsKKyNlbmRpZgorCQkgICAgLyoKKwkJICAgICogSW5zdGFudGlhdGUgdGhlIHhzbDp0ZW1wbGF0ZS4KKwkJICAgICovCisJCSAgICB4c2x0QXBwbHlYU0xUVGVtcGxhdGUoY3R4dCwgY3VyLCB0ZW1wbGF0ZS0+Y29udGVudCwKKwkJCXRlbXBsYXRlLCBwYXJhbXMpOworCQl9IGVsc2UgLyogaWYgKGN0eHQtPm1vZGUgPT0gTlVMTCkgKi8geworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJCSAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9QUk9DRVNTX05PREUseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICAgICAieHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZTogY29weSBDREFUQSAlc1xuIiwKKwkJCQkgICAgIGN1ci0+Y29udGVudCkpOworI2VuZGlmCisJCSAgICBjb3B5ID0geHNsdENvcHlUZXh0KGN0eHQsIGN0eHQtPmluc2VydCwgY3VyLCAwKTsKKwkJICAgIGlmIChjb3B5ID09IE5VTEwpIHsKKwkJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjdXIsCisJCQkgICAgInhzbHREZWZhdWx0UHJvY2Vzc09uZU5vZGU6IGNkYXRhIGNvcHkgZmFpbGVkXG4iKTsKKwkJICAgIH0KKwkJfQorCQlicmVhazsKKwkgICAgY2FzZSBYTUxfVEVYVF9OT0RFOgorCQl0ZW1wbGF0ZSA9IHhzbHRHZXRUZW1wbGF0ZShjdHh0LCBjdXIsIE5VTEwpOworCQlpZiAodGVtcGxhdGUpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQkgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUFJPQ0VTU19OT0RFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZTogYXBwbHlpbmcgdGVtcGxhdGUgZm9yIHRleHQgJXNcbiIsCisJCQkJICAgICBjdXItPmNvbnRlbnQpKTsKKyNlbmRpZgorCQkgICAgY3R4dC0+eHBhdGhDdHh0LT5jb250ZXh0U2l6ZSA9IG5iY2hpbGQ7CisJCSAgICBjdHh0LT54cGF0aEN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gY2hpbGRubzsKKwkJICAgIC8qCisJCSAgICAqIEluc3RhbnRpYXRlIHRoZSB4c2w6dGVtcGxhdGUuCisJCSAgICAqLworCQkgICAgeHNsdEFwcGx5WFNMVFRlbXBsYXRlKGN0eHQsIGN1ciwgdGVtcGxhdGUtPmNvbnRlbnQsCisJCQl0ZW1wbGF0ZSwgcGFyYW1zKTsKKwkJfSBlbHNlIC8qIGlmIChjdHh0LT5tb2RlID09IE5VTEwpICovIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQkgICAgaWYgKGN1ci0+Y29udGVudCA9PSBOVUxMKSB7CisJCQlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9QUk9DRVNTX05PREUseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSAieHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZTogY29weSBlbXB0eSB0ZXh0XG4iKSk7CisJCSAgICB9IGVsc2UgeworCQkJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUFJPQ0VTU19OT0RFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAgInhzbHREZWZhdWx0UHJvY2Vzc09uZU5vZGU6IGNvcHkgdGV4dCAlc1xuIiwKKwkJCQkJIGN1ci0+Y29udGVudCkpOworICAgICAgICAgICAgICAgICAgICB9CisjZW5kaWYKKwkJICAgIGNvcHkgPSB4c2x0Q29weVRleHQoY3R4dCwgY3R4dC0+aW5zZXJ0LCBjdXIsIDApOworCQkgICAgaWYgKGNvcHkgPT0gTlVMTCkgeworCQkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGN1ciwKKwkJCSAgICAieHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZTogdGV4dCBjb3B5IGZhaWxlZFxuIik7CisJCSAgICB9CisJCX0KKwkJYnJlYWs7CisJICAgIGNhc2UgWE1MX1BJX05PREU6CisJICAgIGNhc2UgWE1MX0NPTU1FTlRfTk9ERToKKwkJdGVtcGxhdGUgPSB4c2x0R2V0VGVtcGxhdGUoY3R4dCwgY3VyLCBOVUxMKTsKKwkJaWYgKHRlbXBsYXRlKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwkJICAgIGlmIChjdXItPnR5cGUgPT0gWE1MX1BJX05PREUpIHsKKwkJCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1BST0NFU1NfTk9ERSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgICJ4c2x0RGVmYXVsdFByb2Nlc3NPbmVOb2RlOiB0ZW1wbGF0ZSBmb3VuZCBmb3IgUEkgJXNcbiIsCisJCQkgICAgICAgICAgICAgICAgIGN1ci0+bmFtZSkpOworCQkgICAgfSBlbHNlIGlmIChjdXItPnR5cGUgPT0gWE1MX0NPTU1FTlRfTk9ERSkgeworCQkJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUFJPQ0VTU19OT0RFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAgInhzbHREZWZhdWx0UHJvY2Vzc09uZU5vZGU6IHRlbXBsYXRlIGZvdW5kIGZvciBjb21tZW50XG4iKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyNlbmRpZgorCQkgICAgY3R4dC0+eHBhdGhDdHh0LT5jb250ZXh0U2l6ZSA9IG5iY2hpbGQ7CisJCSAgICBjdHh0LT54cGF0aEN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gY2hpbGRubzsKKwkJICAgIC8qCisJCSAgICAqIEluc3RhbnRpYXRlIHRoZSB4c2w6dGVtcGxhdGUuCisJCSAgICAqLworCQkgICAgeHNsdEFwcGx5WFNMVFRlbXBsYXRlKGN0eHQsIGN1ciwgdGVtcGxhdGUtPmNvbnRlbnQsCisJCQl0ZW1wbGF0ZSwgcGFyYW1zKTsKKwkJfQorCQlicmVhazsKKwkgICAgZGVmYXVsdDoKKwkJYnJlYWs7CisJfQorCWN1ciA9IGN1ci0+bmV4dDsKKyAgICB9CisgICAgY3R4dC0+eHBhdGhDdHh0LT5jb250ZXh0U2l6ZSA9IG9sZFNpemU7CisgICAgY3R4dC0+eHBhdGhDdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IG9sZFBvczsKK30KKworLyoqCisgKiB4c2x0UHJvY2Vzc09uZU5vZGU6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBjb250ZXh0Tm9kZTogIHRoZSAiY3VycmVudCBub2RlIiBpbiB0aGUgc291cmNlIHRyZWUKKyAqIEB3aXRoUGFyYW1zOiAgZXh0cmEgcGFyYW1ldGVycyAoZS5nLiB4c2w6d2l0aC1wYXJhbSkgcGFzc2VkIHRvIHRoZQorICogICAgICAgICAgICAgICB0ZW1wbGF0ZSBpZiBhbnkKKyAqCisgKiBQcm9jZXNzIHRoZSBzb3VyY2Ugbm9kZS4KKyAqLwordm9pZAoreHNsdFByb2Nlc3NPbmVOb2RlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgY29udGV4dE5vZGUsCisJICAgICAgICAgICB4c2x0U3RhY2tFbGVtUHRyIHdpdGhQYXJhbXMpCit7CisgICAgeHNsdFRlbXBsYXRlUHRyIHRlbXBsOworICAgIHhtbE5vZGVQdHIgb2xkTm9kZTsKKworICAgIHRlbXBsID0geHNsdEdldFRlbXBsYXRlKGN0eHQsIGNvbnRleHROb2RlLCBOVUxMKTsKKyAgICAvKgorICAgICAqIElmIG5vIHRlbXBsYXRlIGlzIGZvdW5kLCBhcHBseSB0aGUgZGVmYXVsdCBydWxlLgorICAgICAqLworICAgIGlmICh0ZW1wbCA9PSBOVUxMKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwlpZiAoY29udGV4dE5vZGUtPnR5cGUgPT0gWE1MX0RPQ1VNRU5UX05PREUpIHsKKwkgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUFJPQ0VTU19OT0RFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdFByb2Nlc3NPbmVOb2RlOiBubyB0ZW1wbGF0ZSBmb3VuZCBmb3IgL1xuIikpOworCX0gZWxzZSBpZiAoY29udGV4dE5vZGUtPnR5cGUgPT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkgeworCSAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9QUk9DRVNTX05PREUseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0UHJvY2Vzc09uZU5vZGU6IG5vIHRlbXBsYXRlIGZvdW5kIGZvciBDREFUQVxuIikpOworCX0gZWxzZSBpZiAoY29udGV4dE5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7CisJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1BST0NFU1NfTk9ERSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgInhzbHRQcm9jZXNzT25lTm9kZTogbm8gdGVtcGxhdGUgZm91bmQgZm9yIGF0dHJpYnV0ZSAlc1xuIiwKKwkgICAgICAgICAgICAgICAgICAgICAoKHhtbEF0dHJQdHIpIGNvbnRleHROb2RlKS0+bmFtZSkpOworCX0gZWxzZSAgeworCSAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9QUk9DRVNTX05PREUseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0UHJvY2Vzc09uZU5vZGU6IG5vIHRlbXBsYXRlIGZvdW5kIGZvciAlc1xuIiwgY29udGV4dE5vZGUtPm5hbWUpKTsKKyAgICAgICAgfQorI2VuZGlmCisJb2xkTm9kZSA9IGN0eHQtPm5vZGU7CisJY3R4dC0+bm9kZSA9IGNvbnRleHROb2RlOworCXhzbHREZWZhdWx0UHJvY2Vzc09uZU5vZGUoY3R4dCwgY29udGV4dE5vZGUsIHdpdGhQYXJhbXMpOworCWN0eHQtPm5vZGUgPSBvbGROb2RlOworCXJldHVybjsKKyAgICB9CisKKyAgICBpZiAoY29udGV4dE5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7CisJeHNsdFRlbXBsYXRlUHRyIG9sZEN1clRlbXBSdWxlID0gY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZTsKKwkvKgorCSogU2V0IHRoZSAiY3VycmVudCB0ZW1wbGF0ZSBydWxlIi4KKwkqLworCWN0eHQtPmN1cnJlbnRUZW1wbGF0ZVJ1bGUgPSB0ZW1wbDsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUFJPQ0VTU19OT0RFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdFByb2Nlc3NPbmVOb2RlOiBhcHBseWluZyB0ZW1wbGF0ZSAnJXMnIGZvciBhdHRyaWJ1dGUgJXNcbiIsCisJICAgICAgICAgICAgICAgICB0ZW1wbC0+bWF0Y2gsIGNvbnRleHROb2RlLT5uYW1lKSk7CisjZW5kaWYKKwl4c2x0QXBwbHlYU0xUVGVtcGxhdGUoY3R4dCwgY29udGV4dE5vZGUsIHRlbXBsLT5jb250ZW50LCB0ZW1wbCwgd2l0aFBhcmFtcyk7CisKKwljdHh0LT5jdXJyZW50VGVtcGxhdGVSdWxlID0gb2xkQ3VyVGVtcFJ1bGU7CisgICAgfSBlbHNlIHsKKwl4c2x0VGVtcGxhdGVQdHIgb2xkQ3VyVGVtcFJ1bGUgPSBjdHh0LT5jdXJyZW50VGVtcGxhdGVSdWxlOworCS8qCisJKiBTZXQgdGhlICJjdXJyZW50IHRlbXBsYXRlIHJ1bGUiLgorCSovCisJY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZSA9IHRlbXBsOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwlpZiAoY29udGV4dE5vZGUtPnR5cGUgPT0gWE1MX0RPQ1VNRU5UX05PREUpIHsKKwkgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUFJPQ0VTU19OT0RFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdFByb2Nlc3NPbmVOb2RlOiBhcHBseWluZyB0ZW1wbGF0ZSAnJXMnIGZvciAvXG4iLAorCSAgICAgICAgICAgICAgICAgICAgIHRlbXBsLT5tYXRjaCkpOworCX0gZWxzZSB7CisJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1BST0NFU1NfTk9ERSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgInhzbHRQcm9jZXNzT25lTm9kZTogYXBwbHlpbmcgdGVtcGxhdGUgJyVzJyBmb3IgJXNcbiIsCisJICAgICAgICAgICAgICAgICAgICAgdGVtcGwtPm1hdGNoLCBjb250ZXh0Tm9kZS0+bmFtZSkpOworICAgICAgICB9CisjZW5kaWYKKwl4c2x0QXBwbHlYU0xUVGVtcGxhdGUoY3R4dCwgY29udGV4dE5vZGUsIHRlbXBsLT5jb250ZW50LCB0ZW1wbCwgd2l0aFBhcmFtcyk7CisKKwljdHh0LT5jdXJyZW50VGVtcGxhdGVSdWxlID0gb2xkQ3VyVGVtcFJ1bGU7CisgICAgfQorfQorCitzdGF0aWMgeG1sTm9kZVB0cgoreHNsdERlYnVnZ2VyU3RhcnRTZXF1ZW5jZUNvbnN0cnVjdG9yKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJICAgICB4bWxOb2RlUHRyIGNvbnRleHROb2RlLAorCQkJCSAgICAgeG1sTm9kZVB0ciBsaXN0LAorCQkJCSAgICAgeHNsdFRlbXBsYXRlUHRyIHRlbXBsLAorCQkJCSAgICAgaW50ICphZGRDYWxsUmVzdWx0KQoreworICAgIHhtbE5vZGVQdHIgZGVidWdlZE5vZGUgPSBOVUxMOworCisgICAgaWYgKGN0eHQtPmRlYnVnU3RhdHVzICE9IFhTTFRfREVCVUdfTk9ORSkgeworICAgICAgICBpZiAodGVtcGwpIHsKKyAgICAgICAgICAgICphZGRDYWxsUmVzdWx0ID0geHNsQWRkQ2FsbCh0ZW1wbCwgdGVtcGwtPmVsZW0pOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgKmFkZENhbGxSZXN1bHQgPSB4c2xBZGRDYWxsKE5VTEwsIGxpc3QpOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoY3R4dC0+ZGVidWdTdGF0dXMpIHsKKyAgICAgICAgICAgIGNhc2UgWFNMVF9ERUJVR19SVU5fUkVTVEFSVDoKKyAgICAgICAgICAgIGNhc2UgWFNMVF9ERUJVR19RVUlUOgorICAgICAgICAgICAgICAgIGlmICgqYWRkQ2FsbFJlc3VsdCkKKyAgICAgICAgICAgICAgICAgICAgeHNsRHJvcENhbGwoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4oTlVMTCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHRlbXBsKSB7CisgICAgICAgICAgICB4c2xIYW5kbGVEZWJ1Z2dlcih0ZW1wbC0+ZWxlbSwgY29udGV4dE5vZGUsIHRlbXBsLCBjdHh0KTsKKyAgICAgICAgICAgIGRlYnVnZWROb2RlID0gdGVtcGwtPmVsZW07CisgICAgICAgIH0gZWxzZSBpZiAobGlzdCkgeworICAgICAgICAgICAgeHNsSGFuZGxlRGVidWdnZXIobGlzdCwgY29udGV4dE5vZGUsIHRlbXBsLCBjdHh0KTsKKyAgICAgICAgICAgIGRlYnVnZWROb2RlID0gbGlzdDsKKyAgICAgICAgfSBlbHNlIGlmIChjdHh0LT5pbnN0KSB7CisgICAgICAgICAgICB4c2xIYW5kbGVEZWJ1Z2dlcihjdHh0LT5pbnN0LCBjb250ZXh0Tm9kZSwgdGVtcGwsIGN0eHQpOworICAgICAgICAgICAgZGVidWdlZE5vZGUgPSBjdHh0LT5pbnN0OworICAgICAgICB9CisgICAgfQorICAgIHJldHVybihkZWJ1Z2VkTm9kZSk7Cit9CisKKy8qKgorICogeHNsdExvY2FsVmFyaWFibGVQdXNoOgorICogQGN0eHQ6IHRoZSB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAdmFyaWFibGU6IHZhcmlhYmxlIHRvIGJlIHB1c2hlZCB0byB0aGUgdmFyaWFibGUgc3RhY2sKKyAqIEBsZXZlbDogbmV3IHZhbHVlIGZvciB2YXJpYWJsZSdzIGxldmVsCisgKgorICogUGxhY2VzIHRoZSB2YXJpYWJsZSBvbnRvIHRoZSBsb2NhbCB2YXJpYWJsZSBzdGFjaworICoKKyAqIFJldHVybnM6IDAgZm9yIHN1Y2Nlc3MsIC0xIGZvciBhbnkgZXJyb3IKKyAqICoqTk9URToqKgorICogVGhpcyBpcyBhbiBpbnRlcm5hbCByb3V0aW5lIGFuZCBzaG91bGQgbm90IGJlIGNhbGxlZCBieSB1c2VycyEKKyAqLworaW50Cit4c2x0TG9jYWxWYXJpYWJsZVB1c2goeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJICAgICAgeHNsdFN0YWNrRWxlbVB0ciB2YXJpYWJsZSwKKwkJICAgICAgaW50IGxldmVsKQoreworICAgIGlmIChjdHh0LT52YXJzTWF4ID09IDApIHsKKwljdHh0LT52YXJzTWF4ID0gMTA7CisJY3R4dC0+dmFyc1RhYiA9CisJICAgICh4c2x0U3RhY2tFbGVtUHRyICopIHhtbE1hbGxvYyhjdHh0LT52YXJzTWF4ICoKKwkgICAgc2l6ZW9mKGN0eHQtPnZhcnNUYWJbMF0pKTsKKwlpZiAoY3R4dC0+dmFyc1RhYiA9PSBOVUxMKSB7CisJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWFsbG9jIGZhaWxlZCAhXG4iKTsKKwkgICAgcmV0dXJuICgtMSk7CisJfQorICAgIH0KKyAgICBpZiAoY3R4dC0+dmFyc05yID49IGN0eHQtPnZhcnNNYXgpIHsKKwljdHh0LT52YXJzTWF4ICo9IDI7CisJY3R4dC0+dmFyc1RhYiA9CisJICAgICh4c2x0U3RhY2tFbGVtUHRyICopIHhtbFJlYWxsb2MoY3R4dC0+dmFyc1RhYiwKKwkgICAgY3R4dC0+dmFyc01heCAqCisJICAgIHNpemVvZihjdHh0LT52YXJzVGFiWzBdKSk7CisJaWYgKGN0eHQtPnZhcnNUYWIgPT0gTlVMTCkgeworCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgInJlYWxsb2MgZmFpbGVkICFcbiIpOworCSAgICByZXR1cm4gKC0xKTsKKwl9CisgICAgfQorICAgIGN0eHQtPnZhcnNUYWJbY3R4dC0+dmFyc05yKytdID0gdmFyaWFibGU7CisgICAgY3R4dC0+dmFycyA9IHZhcmlhYmxlOworICAgIHZhcmlhYmxlLT5sZXZlbCA9IGxldmVsOworICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0UmVsZWFzZUxvY2FsUlZUczoKKyAqCisgKiBGcmFnbWVudHMgd2hpY2ggYXJlIHJlc3VsdHMgb2YgZXh0ZW5zaW9uIGluc3RydWN0aW9ucworICogYXJlIHByZXNlcnZlZDsgYWxsIG90aGVyIGZyYWdtZW50cyBhcmUgZnJlZWQvY2FjaGVkLgorICovCitzdGF0aWMgdm9pZAoreHNsdFJlbGVhc2VMb2NhbFJWVHMoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sRG9jUHRyIGJhc2UpCit7CisgICAgeG1sRG9jUHRyIGN1ciA9IGN0eHQtPmxvY2FsUlZULCB0bXA7CisKKyAgICB3aGlsZSAoKGN1ciAhPSBOVUxMKSAmJiAoY3VyICE9IGJhc2UpKSB7CisJaWYgKGN1ci0+cHN2aSA9PSAodm9pZCAqKSAoKGxvbmcpIDEpKSB7CisJICAgIGN1ciA9ICh4bWxEb2NQdHIpIGN1ci0+bmV4dDsKKwl9IGVsc2UgeworCSAgICB0bXAgPSBjdXI7CisJICAgIGN1ciA9ICh4bWxEb2NQdHIpIGN1ci0+bmV4dDsKKworCSAgICBpZiAodG1wID09IGN0eHQtPmxvY2FsUlZUKQorCQljdHh0LT5sb2NhbFJWVCA9IGN1cjsKKworCSAgICAvKgorCSAgICAqIFdlIG5lZWQgY3R4dC0+bG9jYWxSVlRCYXNlIGZvciBleHRlbnNpb24gaW5zdHJ1Y3Rpb25zCisJICAgICogd2hpY2ggcmV0dXJuIHZhbHVlcyAobGlrZSBFWFNMVCdzIGZ1bmN0aW9uKS4KKwkgICAgKi8KKwkgICAgaWYgKHRtcCA9PSBjdHh0LT5sb2NhbFJWVEJhc2UpCisJCWN0eHQtPmxvY2FsUlZUQmFzZSA9IGN1cjsKKworCSAgICBpZiAodG1wLT5wcmV2KQorCQl0bXAtPnByZXYtPm5leHQgPSAoeG1sTm9kZVB0cikgY3VyOworCSAgICBpZiAoY3VyKQorCQljdXItPnByZXYgPSB0bXAtPnByZXY7CisJICAgIHhzbHRSZWxlYXNlUlZUKGN0eHQsIHRtcCk7CisJfQorICAgIH0KK30KKworLyoqCisgKiB4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yOgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAY29udGV4dE5vZGU6ICB0aGUgImN1cnJlbnQgbm9kZSIgaW4gdGhlIHNvdXJjZSB0cmVlCisgKiBAbGlzdDogIHRoZSBub2RlcyBvZiBhIHNlcXVlbmNlIGNvbnN0cnVjdG9yOworICogICAgICAgICAocGx1cyBsZWFkaW5nIHhzbDpwYXJhbSBlbGVtZW50cykKKyAqIEB0ZW1wbDogdGhlIGNvbXBpbGVkIHhzbDp0ZW1wbGF0ZSAob3B0aW9uYWwpCisgKgorICogUHJvY2Vzc2VzIGEgc2VxdWVuY2UgY29uc3RydWN0b3IuCisgKgorICogTk9URTogY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZSB3YXMgaW50cm9kdWNlZCB0byByZWZsZWN0IHRoZQorICogc2VtYW50aWNzIG9mICJjdXJyZW50IHRlbXBsYXRlIHJ1bGUiLiBJLmUuIHRoZSBmaWVsZCBjdHh0LT50ZW1wbAorICogaXMgbm90IGludGVuZGVkIHRvIHJlZmxlY3QgdGhpcywgdGh1cyBhbHdheXMgcHVzaGVkIG9udG8gdGhlCisgKiB0ZW1wbGF0ZSBzdGFjay4KKyAqLworc3RhdGljIHZvaWQKK3hzbHRBcHBseVNlcXVlbmNlQ29uc3RydWN0b3IoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCSAgICAgeG1sTm9kZVB0ciBjb250ZXh0Tm9kZSwgeG1sTm9kZVB0ciBsaXN0LAorCQkJICAgICB4c2x0VGVtcGxhdGVQdHIgdGVtcGwpCit7CisgICAgeG1sTm9kZVB0ciBvbGRJbnNlcnQsIG9sZEluc3QsIG9sZEN1ckluc3QsIG9sZENvbnRleHROb2RlOworICAgIHhtbE5vZGVQdHIgY3VyLCBpbnNlcnQsIGNvcHkgPSBOVUxMOworICAgIGludCBsZXZlbCA9IDAsIG9sZFZhcnNOcjsKKyAgICB4bWxEb2NQdHIgb2xkTG9jYWxGcmFnbWVudFRvcCwgb2xkTG9jYWxGcmFnbWVudEJhc2U7CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGluZm87CisjZW5kaWYKKworI2lmZGVmIFdJVEhfREVCVUdHRVIKKyAgICBpbnQgYWRkQ2FsbFJlc3VsdCA9IDA7CisgICAgeG1sTm9kZVB0ciBkZWJ1Z2dlZE5vZGUgPSBOVUxMOworI2VuZGlmCisKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorCXJldHVybjsKKworI2lmZGVmIFdJVEhfREVCVUdHRVIKKyAgICBpZiAoY3R4dC0+ZGVidWdTdGF0dXMgIT0gWFNMVF9ERUJVR19OT05FKSB7CisJZGVidWdnZWROb2RlID0KKwkgICAgeHNsdERlYnVnZ2VyU3RhcnRTZXF1ZW5jZUNvbnN0cnVjdG9yKGN0eHQsIGNvbnRleHROb2RlLAorCQlsaXN0LCB0ZW1wbCwgJmFkZENhbGxSZXN1bHQpOworCWlmIChkZWJ1Z2dlZE5vZGUgPT0gTlVMTCkKKwkgICAgcmV0dXJuOworICAgIH0KKyNlbmRpZgorCisgICAgaWYgKGxpc3QgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworICAgIENIRUNLX1NUT1BQRUQ7CisKKyAgICBvbGRMb2NhbEZyYWdtZW50VG9wID0gY3R4dC0+bG9jYWxSVlQ7CisgICAgb2xkSW5zZXJ0ID0gaW5zZXJ0ID0gY3R4dC0+aW5zZXJ0OworICAgIG9sZEluc3QgPSBvbGRDdXJJbnN0ID0gY3R4dC0+aW5zdDsKKyAgICBvbGRDb250ZXh0Tm9kZSA9IGN0eHQtPm5vZGU7CisgICAgLyoKKyAgICAqIFNhdmUgY3VycmVudCBudW1iZXIgb2YgdmFyaWFibGVzIG9uIHRoZSBzdGFjazsgbmV3IHZhcnMgYXJlIHBvcHBlZCB3aGVuCisgICAgKiBleGl0aW5nLgorICAgICovCisgICAgb2xkVmFyc05yID0gY3R4dC0+dmFyc05yOworICAgIC8qCisgICAgKiBQcm9jZXNzIHRoZSBzZXF1ZW5jZSBjb25zdHJ1Y3Rvci4KKyAgICAqLworICAgIGN1ciA9IGxpc3Q7CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisgICAgICAgIGN0eHQtPmluc3QgPSBjdXI7CisKKyNpZmRlZiBXSVRIX0RFQlVHR0VSCisgICAgICAgIHN3aXRjaCAoY3R4dC0+ZGVidWdTdGF0dXMpIHsKKyAgICAgICAgICAgIGNhc2UgWFNMVF9ERUJVR19SVU5fUkVTVEFSVDoKKyAgICAgICAgICAgIGNhc2UgWFNMVF9ERUJVR19RVUlUOgorICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIH0KKyNlbmRpZgorICAgICAgICAvKgorICAgICAgICAgKiBUZXN0OyB3ZSBtdXN0IGhhdmUgYSB2YWxpZCBpbnNlcnRpb24gcG9pbnQuCisgICAgICAgICAqLworICAgICAgICBpZiAoaW5zZXJ0ID09IE5VTEwpIHsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgICAgICAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9BUFBMWV9URU1QTEFURSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcjogaW5zZXJ0ID09IE5VTEwgIVxuIikpOworI2VuZGlmCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB9CisKKyNpZmRlZiBXSVRIX0RFQlVHR0VSCisgICAgICAgIGlmICgoY3R4dC0+ZGVidWdTdGF0dXMgIT0gWFNMVF9ERUJVR19OT05FKSAmJiAoZGVidWdnZWROb2RlICE9IGN1cikpCisgICAgICAgICAgICB4c2xIYW5kbGVEZWJ1Z2dlcihjdXIsIGNvbnRleHROb2RlLCB0ZW1wbCwgY3R4dCk7CisjZW5kaWYKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCWlmIChjdXItPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgeworCSAgICBpbmZvID0gKHhzbHRTdHlsZVByZUNvbXBQdHIpIGN1ci0+cHN2aTsKKwkgICAgLyoKKwkgICAgKiBXZSBleHBlY3QgYSBjb21waWxlZCByZXByZXNlbnRhdGlvbiBvbjoKKwkgICAgKiAxKSBYU0xUIGluc3RydWN0aW9ucyBvZiB0aGlzIFhTTFQgdmVyc2lvbiAoMS4wKQorCSAgICAqICAgICh3aXRoIGEgZmV3IGV4Y2VwdGlvbnMpCisJICAgICogMikgTGl0ZXJhbCByZXN1bHQgZWxlbWVudHMKKwkgICAgKiAzKSBFeHRlbnNpb24gaW5zdHJ1Y3Rpb25zCisJICAgICogNCkgWFNMVCBpbnN0cnVjdGlvbnMgb2YgZnV0dXJlIFhTTFQgdmVyc2lvbnMKKwkgICAgKiAgICAoZm9yd2FyZHMtY29tcGF0aWJsZSBtb2RlKS4KKwkgICAgKi8KKwkgICAgaWYgKGluZm8gPT0gTlVMTCkgeworCQkvKgorCQkqIEhhbmRsZSB0aGUgcmFyZSBjYXNlcyB3aGVyZSB3ZSBkb24ndCBleHBlY3QgYSBjb21waWxlZAorCQkqIHJlcHJlc2VudGF0aW9uIG9uIGFuIFhTTFQgZWxlbWVudC4KKwkJKi8KKwkJaWYgKElTX1hTTFRfRUxFTV9GQVNUKGN1cikgJiYgSVNfWFNMVF9OQU1FKGN1ciwgIm1lc3NhZ2UiKSkgeworCQkgICAgeHNsdE1lc3NhZ2UoY3R4dCwgY29udGV4dE5vZGUsIGN1cik7CisJCSAgICBnb3RvIHNraXBfY2hpbGRyZW47CisJCX0KKwkJLyoKKwkJKiBTb21ldGhpbmcgcmVhbGx5IHdlbnQgd3Jvbmc6CisJCSovCisJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjdXIsCisJCSAgICAiSW50ZXJuYWwgZXJyb3IgaW4geHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcigpOiAiCisJCSAgICAiVGhlIGVsZW1lbnQgJyVzJyBpbiB0aGUgc3R5bGVzaGVldCBoYXMgbm8gY29tcGlsZWQgIgorCQkgICAgInJlcHJlc2VudGF0aW9uLlxuIiwKKwkJICAgIGN1ci0+bmFtZSk7CisgICAgICAgICAgICAgICAgZ290byBza2lwX2NoaWxkcmVuOworICAgICAgICAgICAgfQorCisJICAgIGlmIChpbmZvLT50eXBlID09IFhTTFRfRlVOQ19MSVRFUkFMX1JFU1VMVF9FTEVNRU5UKSB7CisJCXhzbHRTdHlsZUl0ZW1MUkVsZW1lbnRJbmZvUHRyIGxySW5mbyA9CisJCSAgICAoeHNsdFN0eWxlSXRlbUxSRWxlbWVudEluZm9QdHIpIGluZm87CisJCS8qCisJCSogTGl0ZXJhbCByZXN1bHQgZWxlbWVudHMKKwkJKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCQkqLworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJCVhTTFRfVFJBQ0UoY3R4dCwgWFNMVF9UUkFDRV9BUFBMWV9URU1QTEFURSwKKwkJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcjogY29weSBsaXRlcmFsIHJlc3VsdCAiCisJCSAgICAiZWxlbWVudCAnJXMnXG4iLCBjdXItPm5hbWUpKTsKKyNlbmRpZgorCQkvKgorCQkqIENvcHkgdGhlIHJhdyBlbGVtZW50LW5vZGUuCisJCSogT0xEOiBpZiAoKGNvcHkgPSB4c2x0U2hhbGxvd0NvcHlFbGVtKGN0eHQsIGN1ciwgaW5zZXJ0KSkKKwkJKiAgICAgPT0gTlVMTCkKKwkJKiAgIGdvdG8gZXJyb3I7CisJCSovCisJCWNvcHkgPSB4bWxEb2NDb3B5Tm9kZShjdXIsIGluc2VydC0+ZG9jLCAwKTsKKwkJaWYgKGNvcHkgPT0gTlVMTCkgeworCQkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGN1ciwKKwkJCSJJbnRlcm5hbCBlcnJvciBpbiB4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yKCk6ICIKKwkJCSJGYWlsZWQgdG8gY29weSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50ICclcycuXG4iLAorCQkJY3VyLT5uYW1lKTsKKwkJICAgIGdvdG8gZXJyb3I7CisJCX0gZWxzZSB7CisJCSAgICAvKgorCQkgICAgKiBBZGQgdGhlIGVsZW1lbnQtbm9kZSB0byB0aGUgcmVzdWx0IHRyZWUuCisJCSAgICAqLworCQkgICAgY29weS0+ZG9jID0gY3R4dC0+b3V0cHV0OworCQkgICAgY29weSA9IHhzbHRBZGRDaGlsZChpbnNlcnQsIGNvcHkpOworCQkgICAgLyoKKwkJICAgICogQ3JlYXRlIGVmZmVjdGl2ZSBuYW1lc3BhY2VzIGRlY2xhcmF0aW9ucy4KKwkJICAgICogT0xEOiB4c2x0Q29weU5hbWVzcGFjZUxpc3QoY3R4dCwgY29weSwgY3VyLT5uc0RlZik7CisJCSAgICAqLworCQkgICAgaWYgKGxySW5mby0+ZWZmZWN0aXZlTnMgIT0gTlVMTCkgeworCQkJeHNsdEVmZmVjdGl2ZU5zUHRyIGVmZk5zID0gbHJJbmZvLT5lZmZlY3RpdmVOczsKKwkJCXhtbE5zUHRyIG5zLCBsYXN0bnMgPSBOVUxMOworCisJCQl3aGlsZSAoZWZmTnMgIT0gTlVMTCkgeworCQkJICAgIC8qCisJCQkgICAgKiBBdm9pZCBnZW5lcmF0aW5nIHJlZHVuZGFudCBuYW1lc3BhY2UKKwkJCSAgICAqIGRlY2xhcmF0aW9uczsgdGh1cyBsb29rdXAgaWYgdGhlcmUgaXMgYWxyZWFkeQorCQkJICAgICogc3VjaCBhIG5zLWRlY2wgaW4gdGhlIHJlc3VsdC4KKwkJCSAgICAqLworCQkJICAgIG5zID0geG1sU2VhcmNoTnMoY29weS0+ZG9jLCBjb3B5LCBlZmZOcy0+cHJlZml4KTsKKwkJCSAgICBpZiAoKG5zICE9IE5VTEwpICYmCisJCQkJKHhtbFN0ckVxdWFsKG5zLT5ocmVmLCBlZmZOcy0+bnNOYW1lKSkpCisJCQkgICAgeworCQkJCWVmZk5zID0gZWZmTnMtPm5leHQ7CisJCQkJY29udGludWU7CisJCQkgICAgfQorCQkJICAgIG5zID0geG1sTmV3TnMoY29weSwgZWZmTnMtPm5zTmFtZSwgZWZmTnMtPnByZWZpeCk7CisJCQkgICAgaWYgKG5zID09IE5VTEwpIHsKKwkJCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgY3VyLAorCQkJCSAgICAiSW50ZXJuYWwgZXJyb3IgaW4gIgorCQkJCSAgICAieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcigpOiAiCisJCQkJICAgICJGYWlsZWQgdG8gY29weSBhIG5hbWVzcGFjZSAiCisJCQkJICAgICJkZWNsYXJhdGlvbi5cbiIpOworCQkJCWdvdG8gZXJyb3I7CisJCQkgICAgfQorCisJCQkgICAgaWYgKGxhc3RucyA9PSBOVUxMKQorCQkJCWNvcHktPm5zRGVmID0gbnM7CisJCQkgICAgZWxzZQorCQkJCWxhc3Rucy0+bmV4dCA9bnM7CisJCQkgICAgbGFzdG5zID0gbnM7CisKKwkJCSAgICBlZmZOcyA9IGVmZk5zLT5uZXh0OworCQkJfQorCisJCSAgICB9CisJCSAgICAvKgorCQkgICAgKiBOT1RFIHRoYXQgd2UgZG9uJ3QgbmVlZCB0byBhcHBseSBucy1hbGlzaW5nOiB0aGlzIHdhcworCQkgICAgKiAgYWxyZWFkeSBkb25lIGF0IGNvbXBpbGUtdGltZS4KKwkJICAgICovCisJCSAgICBpZiAoY3VyLT5ucyAhPSBOVUxMKSB7CisJCQkvKgorCQkJKiBJZiB0aGVyZSdzIG5vIHN1Y2ggbnMtZGVjbCBpbiB0aGUgcmVzdWx0IHRyZWUsCisJCQkqIHRoZW4geHNsdEdldFNwZWNpYWxOYW1lc3BhY2UoKSB3aWxsCisJCQkqIGNyZWF0ZSBhIG5zLWRlY2wgb24gdGhlIGNvcGllZCBub2RlLgorCQkJKi8KKwkJCWNvcHktPm5zID0geHNsdEdldFNwZWNpYWxOYW1lc3BhY2UoY3R4dCwgY3VyLAorCQkJICAgIGN1ci0+bnMtPmhyZWYsIGN1ci0+bnMtPnByZWZpeCwgY29weSk7CisJCSAgICB9IGVsc2UgeworCQkJLyoKKwkJCSogVW5kZWNsYXJlIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSBpZiBuZWVkZWQuCisJCQkqIFRoaXMgY2FuIGJlIHNraXBwZWQsIGlmIHRoZSByZXN1bHQgZWxlbWVudCBoYXMKKwkJCSogIG5vIG5zLWRlY2xzLCBpbiB3aGljaCBjYXNlIHRoZSByZXN1bHQgZWxlbWVudAorCQkJKiAgb2J2aW91c2x5IGRvZXMgbm90IGRlY2xhcmUgYSBkZWZhdWx0IG5hbWVzcGFjZTsKKwkJCSogIEFORCB0aGVyZSdzIGVpdGhlciBubyBwYXJlbnQsIG9yIHRoZSBwYXJlbnQKKwkJCSogIGVsZW1lbnQgaXMgaW4gbm8gbmFtZXNwYWNlOyB0aGlzIG1lYW5zIHRoZXJlJ3Mgbm8KKwkJCSogIGRlZmF1bHQgbmFtZXNwYWNlIGlzIHNjb3BlIHRvIGNhcmUgYWJvdXQuCisJCQkqCisJCQkqIFJFVklTSVQ6IFRoaXMgbWlnaHQgcmVzdWx0IGluIG1hc3NpdmUKKwkJCSogIGdlbmVyYXRpb24gb2YgbnMtZGVjbHMgaWYgbm9kZXMgaW4gYSBkZWZhdWx0CisJCQkqICBuYW1lc3BhY2VzIGFyZSBtaXhlZCB3aXRoIG5vZGVzIGluIG5vIG5hbWVzcGFjZS4KKwkJCSoKKwkJCSovCisJCQlpZiAoY29weS0+bnNEZWYgfHwKKwkJCSAgICAoKGluc2VydCAhPSBOVUxMKSAmJgorCQkJICAgICAoaW5zZXJ0LT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpICYmCisJCQkgICAgIChpbnNlcnQtPm5zICE9IE5VTEwpKSkKKwkJCXsKKwkJCSAgICB4c2x0R2V0U3BlY2lhbE5hbWVzcGFjZShjdHh0LCBjdXIsCisJCQkJTlVMTCwgTlVMTCwgY29weSk7CisJCQl9CisJCSAgICB9CisJCX0KKwkJLyoKKwkJKiBTUEVDIFhTTFQgMi4wICJFYWNoIGF0dHJpYnV0ZSBvZiB0aGUgbGl0ZXJhbCByZXN1bHQKKwkJKiAgZWxlbWVudCwgb3RoZXIgdGhhbiBhbiBhdHRyaWJ1dGUgaW4gdGhlIFhTTFQgbmFtZXNwYWNlLAorCQkqICBpcyBwcm9jZXNzZWQgdG8gcHJvZHVjZSBhbiBhdHRyaWJ1dGUgZm9yIHRoZSBlbGVtZW50IGluCisJCSogIHRoZSByZXN1bHQgdHJlZS4iCisJCSogTk9URTogU2VlIGJ1ZyAjMzQxMzI1LgorCQkqLworCQlpZiAoY3VyLT5wcm9wZXJ0aWVzICE9IE5VTEwpIHsKKwkJICAgIHhzbHRBdHRyTGlzdFRlbXBsYXRlUHJvY2VzcyhjdHh0LCBjb3B5LCBjdXItPnByb3BlcnRpZXMpOworCQl9CisJICAgIH0gZWxzZSBpZiAoSVNfWFNMVF9FTEVNX0ZBU1QoY3VyKSkgeworCQkvKgorCQkqIFhTTFQgaW5zdHJ1Y3Rpb25zCisJCSogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwkJKi8KKwkJaWYgKGluZm8tPnR5cGUgPT0gWFNMVF9GVU5DX1VOS09XTl9GT1JXQVJEU19DT01QQVQpIHsKKwkJICAgIC8qCisJCSAgICAqIFdlIGhpdCBhbiB1bmtub3duIFhTTFQgZWxlbWVudC4KKwkJICAgICogVHJ5IHRvIGFwcGx5IG9uZSBvZiB0aGUgZmFsbGJhY2sgY2FzZXMuCisJCSAgICAqLworCQkgICAgY3R4dC0+aW5zZXJ0ID0gaW5zZXJ0OworCQkgICAgaWYgKCF4c2x0QXBwbHlGYWxsYmFja3MoY3R4dCwgY29udGV4dE5vZGUsIGN1cikpIHsKKwkJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjdXIsCisJCQkgICAgIlRoZSBpcyBubyBmYWxsYmFjayBiZWhhdmlvdXIgZGVmaW5lZCBmb3IgIgorCQkJICAgICJ0aGUgdW5rbm93biBYU0xUIGVsZW1lbnQgJyVzJy5cbiIsCisJCQkgICAgY3VyLT5uYW1lKTsKKwkJICAgIH0KKwkJICAgIGN0eHQtPmluc2VydCA9IG9sZEluc2VydDsKKwkJfSBlbHNlIGlmIChpbmZvLT5mdW5jICE9IE5VTEwpIHsKKwkJICAgIC8qCisJCSAgICAqIEV4ZWN1dGUgdGhlIFhTTFQgaW5zdHJ1Y3Rpb24uCisJCSAgICAqLworCQkgICAgY3R4dC0+aW5zZXJ0ID0gaW5zZXJ0OworCisJCSAgICBpbmZvLT5mdW5jKGN0eHQsIGNvbnRleHROb2RlLCBjdXIsCisJCQkoeHNsdEVsZW1QcmVDb21wUHRyKSBpbmZvKTsKKworCQkgICAgLyoKKwkJICAgICogQ2xlYW51cCB0ZW1wb3JhcnkgdHJlZSBmcmFnbWVudHMuCisJCSAgICAqLworCQkgICAgaWYgKG9sZExvY2FsRnJhZ21lbnRUb3AgIT0gY3R4dC0+bG9jYWxSVlQpCisJCQl4c2x0UmVsZWFzZUxvY2FsUlZUcyhjdHh0LCBvbGRMb2NhbEZyYWdtZW50VG9wKTsKKworCQkgICAgY3R4dC0+aW5zZXJ0ID0gb2xkSW5zZXJ0OworCQl9IGVsc2UgaWYgKGluZm8tPnR5cGUgPT0gWFNMVF9GVU5DX1ZBUklBQkxFKSB7CisJCSAgICB4c2x0U3RhY2tFbGVtUHRyIHRtcHZhciA9IGN0eHQtPnZhcnM7CisKKwkJICAgIHhzbHRQYXJzZVN0eWxlc2hlZXRWYXJpYWJsZShjdHh0LCBjdXIpOworCisJCSAgICBpZiAodG1wdmFyICE9IGN0eHQtPnZhcnMpIHsKKwkJCS8qCisJCQkqIFRPRE86IFVzaW5nIGEgQHRtcHZhciBpcyBhbiBhbm5veWluZyB3b3JrYXJvdW5kLCBidXQKKwkJCSogIHRoZSBjdXJyZW50IG1lY2hhbmlzbXMgZG8gbm90IHByb3ZpZGUgYW55IG90aGVyIHdheQorCQkJKiAgb2Yga25vd2luZyBpZiB0aGUgdmFyIHdhcyByZWFsbHkgcHVzaGVkIG9udG8gdGhlCisJCQkqICBzdGFjay4KKwkJCSovCisJCQljdHh0LT52YXJzLT5sZXZlbCA9IGxldmVsOworCQkgICAgfQorCQl9IGVsc2UgaWYgKGluZm8tPnR5cGUgPT0gWFNMVF9GVU5DX01FU1NBR0UpIHsKKwkJICAgIC8qCisJCSAgICAqIFRPRE86IFdvbid0IGJlIGhpdCwgc2luY2Ugd2UgZG9uJ3QgY29tcGlsZSB4c2w6bWVzc2FnZS4KKwkJICAgICovCisJCSAgICB4c2x0TWVzc2FnZShjdHh0LCBjb250ZXh0Tm9kZSwgY3VyKTsKKwkJfSBlbHNlIHsKKwkJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjdXIsCisJCQkiVW5leHBlY3RlZCBYU0xUIGVsZW1lbnQgJyVzJy5cbiIsIGN1ci0+bmFtZSk7CisJCX0KKwkJZ290byBza2lwX2NoaWxkcmVuOworCisJICAgIH0gZWxzZSB7CisJCXhzbHRUcmFuc2Zvcm1GdW5jdGlvbiBmdW5jOworCQkvKgorCQkqIEV4dGVuc2lvbiBpbnRydWN0aW9ucyAoZWxlbWVudHMpCisJCSogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwkJKi8KKwkJaWYgKGN1ci0+cHN2aSA9PSB4c2x0RXh0TWFya2VyKSB7CisJCSAgICAvKgorCQkgICAgKiBUaGUgeHNsdEV4dE1hcmtlciB3YXMgc2V0IGR1cmluZyB0aGUgY29tcGlsYXRpb24KKwkJICAgICogb2YgZXh0ZW5zaW9uIGluc3RydWN0aW9ucyBpZiB0aGVyZSB3YXMgbm8gcmVnaXN0ZXJlZAorCQkgICAgKiBoYW5kbGVyIGZvciB0aGlzIHNwZWNpZmljIGV4dGVuc2lvbiBmdW5jdGlvbiBhdAorCQkgICAgKiBjb21waWxlLXRpbWUuCisJCSAgICAqIExpYnhzbHQgd2lsbCBub3cgbG9va3VwIGlmIGEgaGFuZGxlciBpcworCQkgICAgKiByZWdpc3RlcmVkIGluIHRoZSBjb250ZXh0IG9mIHRoaXMgdHJhbnNmb3JtYXRpb24uCisJCSAgICAqLworCQkgICAgZnVuYyA9ICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pCisJCQl4c2x0RXh0RWxlbWVudExvb2t1cChjdHh0LCBjdXItPm5hbWUsIGN1ci0+bnMtPmhyZWYpOworCQl9IGVsc2UKKwkJICAgIGZ1bmMgPSAoKHhzbHRFbGVtUHJlQ29tcFB0cikgY3VyLT5wc3ZpKS0+ZnVuYzsKKworCQlpZiAoZnVuYyA9PSBOVUxMKSB7CisJCSAgICAvKgorCQkgICAgKiBObyBoYW5kbGVyIGF2YWlsYWJsZS4KKwkJICAgICogVHJ5IHRvIGV4ZWN1dGUgZmFsbGJhY2sgYmVoYXZpb3VyIHZpYSB4c2w6ZmFsbGJhY2suCisJCSAgICAqLworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJCSAgICBYU0xUX1RSQUNFKGN0eHQsIFhTTFRfVFJBQ0VfQVBQTFlfVEVNUExBVEUsCisJCQl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJICAgICJ4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yOiB1bmtub3duIGV4dGVuc2lvbiAlc1xuIiwKKwkJCSAgICBjdXItPm5hbWUpKTsKKyNlbmRpZgorCQkgICAgY3R4dC0+aW5zZXJ0ID0gaW5zZXJ0OworCQkgICAgaWYgKCF4c2x0QXBwbHlGYWxsYmFja3MoY3R4dCwgY29udGV4dE5vZGUsIGN1cikpIHsKKwkJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjdXIsCisJCQkgICAgIlVua25vd24gZXh0ZW5zaW9uIGluc3RydWN0aW9uICd7JXN9JXMnLlxuIiwKKwkJCSAgICBjdXItPm5zLT5ocmVmLCBjdXItPm5hbWUpOworCQkgICAgfQorCQkgICAgY3R4dC0+aW5zZXJ0ID0gb2xkSW5zZXJ0OworCQl9IGVsc2UgeworCQkgICAgLyoKKwkJICAgICogRXhlY3V0ZSB0aGUgaGFuZGxlci1jYWxsYmFjay4KKwkJICAgICovCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwkJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0FQUExZX1RFTVBMQVRFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcjogZXh0ZW5zaW9uIGNvbnN0cnVjdCAlc1xuIiwKKwkJCWN1ci0+bmFtZSkpOworI2VuZGlmCisJCSAgICBjdHh0LT5pbnNlcnQgPSBpbnNlcnQ7CisJCSAgICAvKgorCQkgICAgKiBXZSBuZWVkIHRoZSBmcmFnbWVudCBiYXNlIGZvciBleHRlbnNpb24gaW5zdHJ1Y3Rpb25zCisJCSAgICAqIHdoaWNoIHJldHVybiB2YWx1ZXMgKGxpa2UgRVhTTFQncyBmdW5jdGlvbikuCisJCSAgICAqLworCQkgICAgb2xkTG9jYWxGcmFnbWVudEJhc2UgPSBjdHh0LT5sb2NhbFJWVEJhc2U7CisJCSAgICBjdHh0LT5sb2NhbFJWVEJhc2UgPSBOVUxMOworCisJCSAgICBmdW5jKGN0eHQsIGNvbnRleHROb2RlLCBjdXIsIGN1ci0+cHN2aSk7CisKKwkJICAgIGN0eHQtPmxvY2FsUlZUQmFzZSA9IG9sZExvY2FsRnJhZ21lbnRCYXNlOworCQkgICAgLyoKKwkJICAgICogQ2xlYW51cCB0ZW1wb3JhcnkgdHJlZSBmcmFnbWVudHMuCisJCSAgICAqLworCQkgICAgaWYgKG9sZExvY2FsRnJhZ21lbnRUb3AgIT0gY3R4dC0+bG9jYWxSVlQpCisJCQl4c2x0UmVsZWFzZUxvY2FsUlZUcyhjdHh0LCBvbGRMb2NhbEZyYWdtZW50VG9wKTsKKworCQkgICAgY3R4dC0+aW5zZXJ0ID0gb2xkSW5zZXJ0OworCQl9CisJCWdvdG8gc2tpcF9jaGlsZHJlbjsKKwkgICAgfQorCisJfSBlbHNlIGlmIChYU0xUX0lTX1RFWFRfTk9ERShjdXIpKSB7CisJICAgIC8qCisJICAgICogVGV4dAorCSAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCSAgICAqLworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgICAgICAgICBpZiAoY3VyLT5uYW1lID09IHhtbFN0cmluZ1RleHROb2VuYykgeworICAgICAgICAgICAgICAgIFhTTFRfVFJBQ0UoY3R4dCwgWFNMVF9UUkFDRV9BUFBMWV9URU1QTEFURSwKKwkJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcjogY29weSB1bmVzY2FwZWQgdGV4dCAnJXMnXG4iLAorCQkgICAgY3VyLT5jb250ZW50KSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIFhTTFRfVFJBQ0UoY3R4dCwgWFNMVF9UUkFDRV9BUFBMWV9URU1QTEFURSwKKwkJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcjogY29weSB0ZXh0ICclcydcbiIsCisJCSAgICBjdXItPmNvbnRlbnQpKTsKKyAgICAgICAgICAgIH0KKyNlbmRpZgorICAgICAgICAgICAgaWYgKHhzbHRDb3B5VGV4dChjdHh0LCBpbnNlcnQsIGN1ciwgY3R4dC0+aW50ZXJuYWxpemVkKSA9PSBOVUxMKQorCQlnb3RvIGVycm9yOworCX0KKworI2Vsc2UgLyogWFNMVF9SRUZBQ1RPUkVEICovCisKKyAgICAgICAgaWYgKElTX1hTTFRfRUxFTShjdXIpKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogVGhpcyBpcyBhbiBYU0xUIG5vZGUKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBpbmZvID0gKHhzbHRTdHlsZVByZUNvbXBQdHIpIGN1ci0+cHN2aTsKKworICAgICAgICAgICAgaWYgKGluZm8gPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGlmIChJU19YU0xUX05BTUUoY3VyLCAibWVzc2FnZSIpKSB7CisgICAgICAgICAgICAgICAgICAgIHhzbHRNZXNzYWdlKGN0eHQsIGNvbnRleHROb2RlLCBjdXIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICAgICAqIFRoYXQncyBhbiBlcnJvciB0cnkgdG8gYXBwbHkgb25lIG9mIHRoZSBmYWxsYmFjayBjYXNlcworICAgICAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICAgICAgY3R4dC0+aW5zZXJ0ID0gaW5zZXJ0OworICAgICAgICAgICAgICAgICAgICBpZiAoIXhzbHRBcHBseUZhbGxiYWNrcyhjdHh0LCBjb250ZXh0Tm9kZSwgY3VyKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkJCSAgICAieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcjogJXMgd2FzIG5vdCBjb21waWxlZFxuIiwKKwkJCSAgICBjdXItPm5hbWUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGN0eHQtPmluc2VydCA9IG9sZEluc2VydDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZ290byBza2lwX2NoaWxkcmVuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoaW5mby0+ZnVuYyAhPSBOVUxMKSB7CisJCW9sZEN1ckluc3QgPSBjdHh0LT5pbnN0OworCQljdHh0LT5pbnN0ID0gY3VyOworICAgICAgICAgICAgICAgIGN0eHQtPmluc2VydCA9IGluc2VydDsKKwkJb2xkTG9jYWxGcmFnbWVudEJhc2UgPSBjdHh0LT5sb2NhbFJWVEJhc2U7CisJCWN0eHQtPmxvY2FsUlZUQmFzZSA9IE5VTEw7CisKKyAgICAgICAgICAgICAgICBpbmZvLT5mdW5jKGN0eHQsIGNvbnRleHROb2RlLCBjdXIsICh4c2x0RWxlbVByZUNvbXBQdHIpIGluZm8pOworCisJCWN0eHQtPmxvY2FsUlZUQmFzZSA9IG9sZExvY2FsRnJhZ21lbnRCYXNlOworCQkvKgorCQkqIENsZWFudXAgdGVtcG9yYXJ5IHRyZWUgZnJhZ21lbnRzLgorCQkqLworCQlpZiAob2xkTG9jYWxGcmFnbWVudFRvcCAhPSBjdHh0LT5sb2NhbFJWVCkKKwkJICAgIHhzbHRSZWxlYXNlTG9jYWxSVlRzKGN0eHQsIG9sZExvY2FsRnJhZ21lbnRUb3ApOworCisgICAgICAgICAgICAgICAgY3R4dC0+aW5zZXJ0ID0gb2xkSW5zZXJ0OworCQljdHh0LT5pbnN0ID0gb2xkQ3VySW5zdDsKKyAgICAgICAgICAgICAgICBnb3RvIHNraXBfY2hpbGRyZW47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmIChJU19YU0xUX05BTUUoY3VyLCAidmFyaWFibGUiKSkgeworCQl4c2x0U3RhY2tFbGVtUHRyIHRtcHZhciA9IGN0eHQtPnZhcnM7CisKKwkJb2xkQ3VySW5zdCA9IGN0eHQtPmluc3Q7CisJCWN0eHQtPmluc3QgPSBjdXI7CisKKwkJeHNsdFBhcnNlU3R5bGVzaGVldFZhcmlhYmxlKGN0eHQsIGN1cik7CisKKwkJY3R4dC0+aW5zdCA9IG9sZEN1ckluc3Q7CisKKwkJaWYgKHRtcHZhciAhPSBjdHh0LT52YXJzKSB7CisJCSAgICAvKgorCQkgICAgKiBUT0RPOiBVc2luZyBhIEB0bXB2YXIgaXMgYW4gYW5ub3lpbmcgd29ya2Fyb3VuZCwgYnV0CisJCSAgICAqICB0aGUgY3VycmVudCBtZWNoYW5pc21zIGRvIG5vdCBwcm92aWRlIGFueSBvdGhlciB3YXkKKwkJICAgICogIG9mIGtub3dpbmcgaWYgdGhlIHZhciB3YXMgcmVhbGx5IHB1c2hlZCBvbnRvIHRoZQorCQkgICAgKiAgc3RhY2suCisJCSAgICAqLworCQkgICAgY3R4dC0+dmFycy0+bGV2ZWwgPSBsZXZlbDsKKwkJfQorICAgICAgICAgICAgfSBlbHNlIGlmIChJU19YU0xUX05BTUUoY3VyLCAibWVzc2FnZSIpKSB7CisgICAgICAgICAgICAgICAgeHNsdE1lc3NhZ2UoY3R4dCwgY29udGV4dE5vZGUsIGN1cik7CisgICAgICAgICAgICB9IGVsc2UgeworCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgY3VyLAorCQkgICAgIlVuZXhwZWN0ZWQgWFNMVCBlbGVtZW50ICclcycuXG4iLCBjdXItPm5hbWUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZ290byBza2lwX2NoaWxkcmVuOworICAgICAgICB9IGVsc2UgaWYgKChjdXItPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgfHwKKyAgICAgICAgICAgICAgICAgICAoY3VyLT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CisKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBUaGlzIHRleHQgY29tZXMgZnJvbSB0aGUgc3R5bGVzaGVldAorICAgICAgICAgICAgICogRm9yIHN0eWxlc2hlZXRzLCB0aGUgc2V0IG9mIHdoaXRlc3BhY2UtcHJlc2VydmluZworICAgICAgICAgICAgICogZWxlbWVudCBuYW1lcyBjb25zaXN0cyBvZiBqdXN0IHhzbDp0ZXh0LgorICAgICAgICAgICAgICovCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKyAgICAgICAgICAgIGlmIChjdXItPnR5cGUgPT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkgeworICAgICAgICAgICAgICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0FQUExZX1RFTVBMQVRFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcjogY29weSBDREFUQSB0ZXh0ICVzXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyLT5jb250ZW50KSk7CisgICAgICAgICAgICB9IGVsc2UgaWYgKGN1ci0+bmFtZSA9PSB4bWxTdHJpbmdUZXh0Tm9lbmMpIHsKKyAgICAgICAgICAgICAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9BUFBMWV9URU1QTEFURSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRBcHBseVNlcXVlbmNlQ29uc3RydWN0b3I6IGNvcHkgdW5lc2NhcGVkIHRleHQgJXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXItPmNvbnRlbnQpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQVBQTFlfVEVNUExBVEUseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yOiBjb3B5IHRleHQgJXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXItPmNvbnRlbnQpKTsKKyAgICAgICAgICAgIH0KKyNlbmRpZgorICAgICAgICAgICAgaWYgKHhzbHRDb3B5VGV4dChjdHh0LCBpbnNlcnQsIGN1ciwgY3R4dC0+aW50ZXJuYWxpemVkKSA9PSBOVUxMKQorCQlnb3RvIGVycm9yOworICAgICAgICB9IGVsc2UgaWYgKChjdXItPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKKyAgICAgICAgICAgICAgICAgICAoY3VyLT5ucyAhPSBOVUxMKSAmJiAoY3VyLT5wc3ZpICE9IE5VTEwpKSB7CisgICAgICAgICAgICB4c2x0VHJhbnNmb3JtRnVuY3Rpb24gZnVuY3Rpb247CisKKwkgICAgb2xkQ3VySW5zdCA9IGN0eHQtPmluc3Q7CisJICAgIGN0eHQtPmluc3QgPSBjdXI7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogRmxhZ2dlZCBhcyBhbiBleHRlbnNpb24gZWxlbWVudAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoY3VyLT5wc3ZpID09IHhzbHRFeHRNYXJrZXIpCisgICAgICAgICAgICAgICAgZnVuY3Rpb24gPSAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKQorICAgICAgICAgICAgICAgICAgICB4c2x0RXh0RWxlbWVudExvb2t1cChjdHh0LCBjdXItPm5hbWUsIGN1ci0+bnMtPmhyZWYpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIGZ1bmN0aW9uID0gKCh4c2x0RWxlbVByZUNvbXBQdHIpIGN1ci0+cHN2aSktPmZ1bmM7CisKKyAgICAgICAgICAgIGlmIChmdW5jdGlvbiA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBjaGlsZDsKKyAgICAgICAgICAgICAgICBpbnQgZm91bmQgPSAwOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKyAgICAgICAgICAgICAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9BUFBMWV9URU1QTEFURSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgInhzbHRBcHBseVNlcXVlbmNlQ29uc3RydWN0b3I6IHVua25vd24gZXh0ZW5zaW9uICVzXG4iLAorICAgICAgICAgICAgICAgICAgICBjdXItPm5hbWUpKTsKKyNlbmRpZgorICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICogU2VhcmNoIGlmIHRoZXJlIGFyZSBmYWxsYmFja3MKKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBjaGlsZCA9IGN1ci0+Y2hpbGRyZW47CisgICAgICAgICAgICAgICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKChJU19YU0xUX0VMRU0oY2hpbGQpKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgKElTX1hTTFRfTkFNRShjaGlsZCwgImZhbGxiYWNrIikpKQorCQkgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSAxOworICAgICAgICAgICAgICAgICAgICAgICAgeHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcihjdHh0LCBjb250ZXh0Tm9kZSwKKwkJCSAgICBjaGlsZC0+Y2hpbGRyZW4sIE5VTEwpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKCFmb3VuZCkgeworICAgICAgICAgICAgICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgY3VyLAorCQkJInhzbHRBcHBseVNlcXVlbmNlQ29uc3RydWN0b3I6IGZhaWxlZCB0byBmaW5kIGV4dGVuc2lvbiAlc1xuIiwKKwkJCWN1ci0+bmFtZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBlbHNlIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworICAgICAgICAgICAgICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0FQUExZX1RFTVBMQVRFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcjogZXh0ZW5zaW9uIGNvbnN0cnVjdCAlc1xuIiwKKyAgICAgICAgICAgICAgICAgICAgY3VyLT5uYW1lKSk7CisjZW5kaWYKKworICAgICAgICAgICAgICAgIGN0eHQtPmluc2VydCA9IGluc2VydDsKKwkJLyoKKwkJKiBXZSBuZWVkIHRoZSBmcmFnbWVudCBiYXNlIGZvciBleHRlbnNpb24gaW5zdHJ1Y3Rpb25zCisJCSogd2hpY2ggcmV0dXJuIHZhbHVlcyAobGlrZSBFWFNMVCdzIGZ1bmN0aW9uKS4KKwkJKi8KKwkJb2xkTG9jYWxGcmFnbWVudEJhc2UgPSBjdHh0LT5sb2NhbFJWVEJhc2U7CisJCWN0eHQtPmxvY2FsUlZUQmFzZSA9IE5VTEw7CisKKyAgICAgICAgICAgICAgICBmdW5jdGlvbihjdHh0LCBjb250ZXh0Tm9kZSwgY3VyLCBjdXItPnBzdmkpOworCQkvKgorCQkqIENsZWFudXAgdGVtcG9yYXJ5IHRyZWUgZnJhZ21lbnRzLgorCQkqLworCQlpZiAob2xkTG9jYWxGcmFnbWVudFRvcCAhPSBjdHh0LT5sb2NhbFJWVCkKKwkJICAgIHhzbHRSZWxlYXNlTG9jYWxSVlRzKGN0eHQsIG9sZExvY2FsRnJhZ21lbnRUb3ApOworCisJCWN0eHQtPmxvY2FsUlZUQmFzZSA9IG9sZExvY2FsRnJhZ21lbnRCYXNlOworICAgICAgICAgICAgICAgIGN0eHQtPmluc2VydCA9IG9sZEluc2VydDsKKworICAgICAgICAgICAgfQorCSAgICBjdHh0LT5pbnN0ID0gb2xkQ3VySW5zdDsKKyAgICAgICAgICAgIGdvdG8gc2tpcF9jaGlsZHJlbjsKKyAgICAgICAgfSBlbHNlIGlmIChjdXItPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgICAgICAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9BUFBMWV9URU1QTEFURSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkieHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcjogY29weSBub2RlICVzXG4iLAorICAgICAgICAgICAgICAgIGN1ci0+bmFtZSkpOworI2VuZGlmCisJICAgIG9sZEN1ckluc3QgPSBjdHh0LT5pbnN0OworCSAgICBjdHh0LT5pbnN0ID0gY3VyOworCisgICAgICAgICAgICBpZiAoKGNvcHkgPSB4c2x0U2hhbGxvd0NvcHlFbGVtKGN0eHQsIGN1ciwgaW5zZXJ0LCAxKSkgPT0gTlVMTCkKKwkJZ290byBlcnJvcjsKKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBBZGQgZXh0cmEgbmFtZXNwYWNlcyBpbmhlcml0ZWQgZnJvbSB0aGUgY3VycmVudCB0ZW1wbGF0ZQorICAgICAgICAgICAgICogaWYgd2UgYXJlIGluIHRoZSBmaXJzdCBsZXZlbCBjaGlsZHJlbiBhbmQgdGhpcyBpcyBhCisJICAgICAqICJyZWFsIiB0ZW1wbGF0ZS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaWYgKCh0ZW1wbCAhPSBOVUxMKSAmJiAob2xkSW5zZXJ0ID09IGluc2VydCkgJiYKKyAgICAgICAgICAgICAgICAoY3R4dC0+dGVtcGwgIT0gTlVMTCkgJiYgKGN0eHQtPnRlbXBsLT5pbmhlcml0ZWROcyAhPSBOVUxMKSkgeworICAgICAgICAgICAgICAgIGludCBpOworICAgICAgICAgICAgICAgIHhtbE5zUHRyIG5zLCByZXQ7CisKKyAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY3R4dC0+dGVtcGwtPmluaGVyaXRlZE5zTnI7IGkrKykgeworCQkgICAgY29uc3QgeG1sQ2hhciAqVVJJID0gTlVMTDsKKwkJICAgIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlOworICAgICAgICAgICAgICAgICAgICBucyA9IGN0eHQtPnRlbXBsLT5pbmhlcml0ZWROc1tpXTsKKworCQkgICAgLyogTm90ZSB0aGF0IHRoZSBYU0xUIG5hbWVzcGFjZSB3YXMgYWxyZWFkeSBleGNsdWRlZAorCQkgICAgKiBpbiB4c2x0R2V0SW5oZXJpdGVkTnNMaXN0KCkuCisJCSAgICAqLworI2lmIDAKKwkJICAgIGlmICh4bWxTdHJFcXVhbChucy0+aHJlZiwgWFNMVF9OQU1FU1BBQ0UpKQorCQkJY29udGludWU7CisjZW5kaWYKKwkJICAgIHN0eWxlID0gY3R4dC0+c3R5bGU7CisJCSAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworCQkJaWYgKHN0eWxlLT5uc0FsaWFzZXMgIT0gTlVMTCkKKwkJCSAgICBVUkkgPSAoY29uc3QgeG1sQ2hhciAqKQorCQkJCXhtbEhhc2hMb29rdXAoc3R5bGUtPm5zQWxpYXNlcywgbnMtPmhyZWYpOworCQkJaWYgKFVSSSAhPSBOVUxMKQorCQkJICAgIGJyZWFrOworCisJCQlzdHlsZSA9IHhzbHROZXh0SW1wb3J0KHN0eWxlKTsKKwkJICAgIH0KKwkJICAgIGlmIChVUkkgPT0gVU5ERUZJTkVEX0RFRkFVTFRfTlMpCisJCQljb250aW51ZTsKKwkJICAgIGlmIChVUkkgPT0gTlVMTCkKKwkJCVVSSSA9IG5zLT5ocmVmOworCQkgICAgLyoKKwkJICAgICogVE9ETzogVGhlIGZvbGxvd2luZyB3aWxsIHN0aWxsIGJlIGJ1Z2d5IGZvciB0aGUKKwkJICAgICogbm9uLXJlZmFjdG9yZWQgY29kZS4KKwkJICAgICovCisJCSAgICByZXQgPSB4bWxTZWFyY2hOcyhjb3B5LT5kb2MsIGNvcHksIG5zLT5wcmVmaXgpOworCQkgICAgaWYgKChyZXQgPT0gTlVMTCkgfHwgKCF4bWxTdHJFcXVhbChyZXQtPmhyZWYsIFVSSSkpKQorCQkgICAgeworCQkJeG1sTmV3TnMoY29weSwgVVJJLCBucy0+cHJlZml4KTsKKwkJICAgIH0KKyAgICAgICAgICAgICAgICB9CisJCWlmIChjb3B5LT5ucyAhPSBOVUxMKSB7CisJCSAgICAvKgorCQkgICAgICogRml4IHRoZSBub2RlIG5hbWVzcGFjZSBpZiBuZWVkZWQKKwkJICAgICAqLworCQkgICAgY29weS0+bnMgPSB4c2x0R2V0TmFtZXNwYWNlKGN0eHQsIGN1ciwgY29weS0+bnMsIGNvcHkpOworCQl9CisgICAgICAgICAgICB9CisJICAgIC8qCisgICAgICAgICAgICAgKiBhbGwgdGhlIGF0dHJpYnV0ZXMgYXJlIGRpcmVjdGx5IGluaGVyaXRlZAorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoY3VyLT5wcm9wZXJ0aWVzICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICB4c2x0QXR0ckxpc3RUZW1wbGF0ZVByb2Nlc3MoY3R4dCwgY29weSwgY3VyLT5wcm9wZXJ0aWVzKTsKKyAgICAgICAgICAgIH0KKwkgICAgY3R4dC0+aW5zdCA9IG9sZEN1ckluc3Q7CisgICAgICAgIH0KKyNlbmRpZiAvKiBlbHNlIG9mIFhTTFRfUkVGQUNUT1JFRCAqLworCisgICAgICAgIC8qCisgICAgICAgICAqIERlc2NlbmQgaW50byBjb250ZW50IGluIGRvY3VtZW50IG9yZGVyLgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKGN1ci0+Y2hpbGRyZW4gIT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9ERUNMKSB7CisgICAgICAgICAgICAgICAgY3VyID0gY3VyLT5jaGlsZHJlbjsKKwkJbGV2ZWwrKzsKKyAgICAgICAgICAgICAgICBpZiAoY29weSAhPSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBpbnNlcnQgPSBjb3B5OworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKK3NraXBfY2hpbGRyZW46CisJLyoKKwkqIElmIHhzbHQ6bWVzc2FnZSB3YXMganVzdCBwcm9jZXNzZWQsIHdlIG1pZ2h0IGhhdmUgaGl0IGEKKwkqIHRlcm1pbmF0ZT0neWVzJzsgaWYgc28sIHRoZW4gYnJlYWsgdGhlIGxvb3AgYW5kIGNsZWFuIHVwLgorCSogVE9ETzogRG8gd2UgbmVlZCB0byBjaGVjayB0aGlzIGFsc28gYmVmb3JlIHRyeWluZyB0byBkZXNjZW5kCisJKiAgaW50byB0aGUgY29udGVudD8KKwkqLworCWlmIChjdHh0LT5zdGF0ZSA9PSBYU0xUX1NUQVRFX1NUT1BQRUQpCisJICAgIGJyZWFrOworICAgICAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgZG8geworICAgICAgICAgICAgY3VyID0gY3VyLT5wYXJlbnQ7CisJICAgIGxldmVsLS07CisJICAgIC8qCisJICAgICogUG9wIHZhcmlhYmxlcy9wYXJhbXMgKHhzbDp2YXJpYWJsZSBhbmQgeHNsOnBhcmFtKS4KKwkgICAgKi8KKwkgICAgaWYgKChjdHh0LT52YXJzTnIgPiBvbGRWYXJzTnIpICYmIChjdHh0LT52YXJzLT5sZXZlbCA+IGxldmVsKSkgeworCQl4c2x0TG9jYWxWYXJpYWJsZVBvcChjdHh0LCBvbGRWYXJzTnIsIGxldmVsKTsKKwkgICAgfQorCisgICAgICAgICAgICBpbnNlcnQgPSBpbnNlcnQtPnBhcmVudDsKKyAgICAgICAgICAgIGlmIChjdXIgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGlmIChjdXIgPT0gbGlzdC0+cGFyZW50KSB7CisgICAgICAgICAgICAgICAgY3VyID0gTlVMTDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjdXItPm5leHQgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSB3aGlsZSAoY3VyICE9IE5VTEwpOworICAgIH0KKworZXJyb3I6CisgICAgLyoKKyAgICAqIEluIGNhc2Ugb2YgZXJyb3JzOiBwb3AgcmVtYWluaW5nIHZhcmlhYmxlcy4KKyAgICAqLworICAgIGlmIChjdHh0LT52YXJzTnIgPiBvbGRWYXJzTnIpCisJeHNsdExvY2FsVmFyaWFibGVQb3AoY3R4dCwgb2xkVmFyc05yLCAtMSk7CisKKyAgICBjdHh0LT5ub2RlID0gb2xkQ29udGV4dE5vZGU7CisgICAgY3R4dC0+aW5zdCA9IG9sZEluc3Q7CisgICAgY3R4dC0+aW5zZXJ0ID0gb2xkSW5zZXJ0OworCisjaWZkZWYgV0lUSF9ERUJVR0dFUgorICAgIGlmICgoY3R4dC0+ZGVidWdTdGF0dXMgIT0gWFNMVF9ERUJVR19OT05FKSAmJiAoYWRkQ2FsbFJlc3VsdCkpIHsKKyAgICAgICAgeHNsRHJvcENhbGwoKTsKKyAgICB9CisjZW5kaWYKK30KKworLyoKKyogeHNsdEFwcGx5WFNMVFRlbXBsYXRlOgorKiBAY3R4dDogIGEgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisqIEBjb250ZXh0Tm9kZTogIHRoZSBub2RlIGluIHRoZSBzb3VyY2UgdHJlZS4KKyogQGxpc3Q6ICB0aGUgbm9kZXMgb2YgYSBzZXF1ZW5jZSBjb25zdHJ1Y3RvcjsKKyogICAgICAgICAocGx1cyBsZWFkaW5nIHhzbDpwYXJhbSBlbGVtZW50cykKKyogQHRlbXBsOiB0aGUgY29tcGlsZWQgeHNsOnRlbXBsYXRlIGRlY2xhcmF0aW9uOworKiAgICAgICAgIE5VTEwgaWYgYSBzZXF1ZW5jZSBjb25zdHJ1Y3RvcgorKiBAd2l0aFBhcmFtczogIGEgc2V0IG9mIGNhbGxlci1wYXJhbWV0ZXJzICh4c2w6d2l0aC1wYXJhbSkgb3IgTlVMTAorKgorKiBDYWxsZWQgYnk6CisqIC0geHNsdEFwcGx5SW1wb3J0cygpCisqIC0geHNsdENhbGxUZW1wbGF0ZSgpCisqIC0geHNsdERlZmF1bHRQcm9jZXNzT25lTm9kZSgpCisqIC0geHNsdFByb2Nlc3NPbmVOb2RlKCkKKyovCitzdGF0aWMgdm9pZAoreHNsdEFwcGx5WFNMVFRlbXBsYXRlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCSAgICAgIHhtbE5vZGVQdHIgY29udGV4dE5vZGUsCisJCSAgICAgIHhtbE5vZGVQdHIgbGlzdCwKKwkJICAgICAgeHNsdFRlbXBsYXRlUHRyIHRlbXBsLAorCQkgICAgICB4c2x0U3RhY2tFbGVtUHRyIHdpdGhQYXJhbXMpCit7CisgICAgaW50IG9sZFZhcnNCYXNlID0gMDsKKyAgICBsb25nIHN0YXJ0ID0gMDsKKyAgICB4bWxOb2RlUHRyIGN1cjsKKyAgICB4c2x0U3RhY2tFbGVtUHRyIHRtcFBhcmFtID0gTlVMTDsKKyAgICB4bWxEb2NQdHIgb2xkVXNlckZyYWdtZW50VG9wLCBvbGRMb2NhbEZyYWdtZW50VG9wOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbVBhcmFtUHRyIGlwYXJhbTsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBpcGFyYW07CisjZW5kaWYKKworI2lmZGVmIFdJVEhfREVCVUdHRVIKKyAgICBpbnQgYWRkQ2FsbFJlc3VsdCA9IDA7CisjZW5kaWYKKworICAgIGlmIChjdHh0ID09IE5VTEwpCisJcmV0dXJuOworICAgIGlmICh0ZW1wbCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGxpc3QsCisJICAgICJ4c2x0QXBwbHlYU0xUVGVtcGxhdGU6IEJhZCBhcmd1bWVudHM7IEB0ZW1wbCBpcyBtYW5kYXRvcnkuXG4iKTsKKwlyZXR1cm47CisgICAgfQorCisjaWZkZWYgV0lUSF9ERUJVR0dFUgorICAgIGlmIChjdHh0LT5kZWJ1Z1N0YXR1cyAhPSBYU0xUX0RFQlVHX05PTkUpIHsKKwlpZiAoeHNsdERlYnVnZ2VyU3RhcnRTZXF1ZW5jZUNvbnN0cnVjdG9yKGN0eHQsIGNvbnRleHROb2RlLAorCQlsaXN0LCB0ZW1wbCwgJmFkZENhbGxSZXN1bHQpID09IE5VTEwpCisJICAgIHJldHVybjsKKyAgICB9CisjZW5kaWYKKworICAgIGlmIChsaXN0ID09IE5VTEwpCisgICAgICAgIHJldHVybjsKKyAgICBDSEVDS19TVE9QUEVEOworCisgICAgLyoKKyAgICAqIENoZWNrIGZvciBpbmZpbml0ZSByZWN1cnNpb246IHN0b3AgaWYgdGhlIG1heGltdW0gb2YgbmVzdGVkIHRlbXBsYXRlcworICAgICogaXMgZXhjY2VlZGVkLiBBZGp1c3QgeHNsdE1heERlcHRoIGlmIHlvdSBuZWVkIG1vcmUuCisgICAgKi8KKyAgICBpZiAoKChjdHh0LT50ZW1wbE5yID49IHhzbHRNYXhEZXB0aCkgfHwKKyAgICAgICAgKGN0eHQtPnZhcnNOciA+PSA1ICogeHNsdE1heERlcHRoKSkpCisgICAgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgbGlzdCwKKwkgICAgInhzbHRBcHBseVhTTFRUZW1wbGF0ZTogQSBwb3RlbnRpYWwgaW5maW5pdGUgdGVtcGxhdGUgcmVjdXJzaW9uICIKKwkgICAgIndhcyBkZXRlY3RlZC5cbiIKKwkgICAgIllvdSBjYW4gYWRqdXN0IHhzbHRNYXhEZXB0aCAoLS1tYXhkZXB0aCkgaW4gb3JkZXIgdG8gIgorCSAgICAicmFpc2UgdGhlIG1heGltdW0gbnVtYmVyIG9mIG5lc3RlZCB0ZW1wbGF0ZSBjYWxscyBhbmQgIgorCSAgICAidmFyaWFibGVzL3BhcmFtcyAoY3VycmVudGx5IHNldCB0byAlZCkuXG4iLAorCSAgICB4c2x0TWF4RGVwdGgpOworICAgICAgICB4c2x0RGVidWcoY3R4dCwgY29udGV4dE5vZGUsIGxpc3QsIE5VTEwpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgb2xkVXNlckZyYWdtZW50VG9wID0gY3R4dC0+dG1wUlZUOworICAgIGN0eHQtPnRtcFJWVCA9IE5VTEw7CisgICAgb2xkTG9jYWxGcmFnbWVudFRvcCA9IGN0eHQtPmxvY2FsUlZUOworCisgICAgLyoKKyAgICAqIEluaXRpYXRlIGEgZGlzdGluY3Qgc2NvcGUgb2YgbG9jYWwgcGFyYW1zL3ZhcmlhYmxlcy4KKyAgICAqLworICAgIG9sZFZhcnNCYXNlID0gY3R4dC0+dmFyc0Jhc2U7CisgICAgY3R4dC0+dmFyc0Jhc2UgPSBjdHh0LT52YXJzTnI7CisKKyAgICBjdHh0LT5ub2RlID0gY29udGV4dE5vZGU7CisgICAgaWYgKGN0eHQtPnByb2ZpbGUpIHsKKwl0ZW1wbC0+bmJDYWxscysrOworCXN0YXJ0ID0geHNsdFRpbWVzdGFtcCgpOworCXByb2ZQdXNoKGN0eHQsIDApOworICAgIH0KKyAgICAvKgorICAgICogUHVzaCB0aGUgeHNsOnRlbXBsYXRlIGRlY2xhcmF0aW9uIG9udG8gdGhlIHN0YWNrLgorICAgICovCisgICAgdGVtcGxQdXNoKGN0eHQsIHRlbXBsKTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgaWYgKHRlbXBsLT5uYW1lICE9IE5VTEwpCisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQVBQTFlfVEVNUExBVEUseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkiYXBwbHlpbmcgeHNsOnRlbXBsYXRlICclcydcbiIsIHRlbXBsLT5uYW1lKSk7CisjZW5kaWYKKyAgICAvKgorICAgICogUHJvY2VzcyB4c2w6cGFyYW0gaW5zdHJ1Y3Rpb25zIGFuZCBza2lwIHRob3NlIGVsZW1lbnRzIGZvcgorICAgICogZnVydGhlciBwcm9jZXNzaW5nLgorICAgICovCisgICAgY3VyID0gbGlzdDsKKyAgICBkbyB7CisJaWYgKGN1ci0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB7CisJICAgIGN1ciA9IGN1ci0+bmV4dDsKKwkgICAgY29udGludWU7CisJfQorCWlmICgoY3VyLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpIHx8CisJICAgIChjdXItPm5hbWVbMF0gIT0gJ3AnKSB8fAorCSAgICAoY3VyLT5wc3ZpID09IE5VTEwpIHx8CisJICAgICghIHhtbFN0ckVxdWFsKGN1ci0+bmFtZSwgQkFEX0NBU1QgInBhcmFtIikpIHx8CisJICAgICghIElTX1hTTFRfRUxFTShjdXIpKSkKKwl7CisJICAgIGJyZWFrOworCX0KKworCWxpc3QgPSBjdXItPm5leHQ7CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwlpcGFyYW0gPSAoeHNsdFN0eWxlSXRlbVBhcmFtUHRyKSBjdXItPnBzdmk7CisjZWxzZQorCWlwYXJhbSA9ICh4c2x0U3R5bGVQcmVDb21wUHRyKSBjdXItPnBzdmk7CisjZW5kaWYKKworCS8qCisJKiBTdWJzdGl0dXRlIHhzbDpwYXJhbSBmb3IgYSBnaXZlbiB4c2w6d2l0aC1wYXJhbS4KKwkqIFNpbmNlIHRoZSBYUGF0aCBleHByZXNzaW9uIHdpbGwgcmVmZXJlbmNlIHRoZSBwYXJhbXMvdmFycworCSogYnkgaW5kZXgsIHdlIG5lZWQgdG8gc2xvdCB0aGUgeHNsOndpdGgtcGFyYW1zIGluIHRoZQorCSogb3JkZXIgb2YgZW5jb3VudGVyZWQgeHNsOnBhcmFtcyB0byBrZWVwIHRoZSBzZXF1ZW5jZSBvZgorCSogcGFyYW1zL3ZhcmlhYmxlcyBpbiB0aGUgc3RhY2sgZXhhY3RseSBhcyBpdCB3YXMgYXQKKwkqIGNvbXBpbGUgdGltZSwKKwkqLworCXRtcFBhcmFtID0gTlVMTDsKKwlpZiAod2l0aFBhcmFtcykgeworCSAgICB0bXBQYXJhbSA9IHdpdGhQYXJhbXM7CisJICAgIGRvIHsKKwkJaWYgKCh0bXBQYXJhbS0+bmFtZSA9PSAoaXBhcmFtLT5uYW1lKSkgJiYKKwkJICAgICh0bXBQYXJhbS0+bmFtZVVSSSA9PSAoaXBhcmFtLT5ucykpKQorCQl7CisJCSAgICAvKgorCQkgICAgKiBQdXNoIHRoZSBjYWxsZXItcGFyYW1ldGVyLgorCQkgICAgKi8KKwkJICAgIHhzbHRMb2NhbFZhcmlhYmxlUHVzaChjdHh0LCB0bXBQYXJhbSwgLTEpOworCQkgICAgYnJlYWs7CisJCX0KKwkJdG1wUGFyYW0gPSB0bXBQYXJhbS0+bmV4dDsKKwkgICAgfSB3aGlsZSAodG1wUGFyYW0gIT0gTlVMTCk7CisJfQorCS8qCisJKiBQdXNoIHRoZSB4c2w6cGFyYW0uCisJKi8KKwlpZiAodG1wUGFyYW0gPT0gTlVMTCkgeworCSAgICAvKgorCSAgICAqIE5vdGUgdGhhdCB3ZSBtdXN0IGFzc3VtZSB0aGF0IHRoZSBhZGRlZCBwYXJhbWV0ZXIKKwkgICAgKiBoYXMgYSBAZGVwdGggb2YgMC4KKwkgICAgKi8KKwkgICAgeHNsdFBhcnNlU3R5bGVzaGVldFBhcmFtKGN0eHQsIGN1cik7CisJfQorCWN1ciA9IGN1ci0+bmV4dDsKKyAgICB9IHdoaWxlIChjdXIgIT0gTlVMTCk7CisgICAgLyoKKyAgICAqIFByb2Nlc3MgdGhlIHNlcXVlbmNlIGNvbnN0cnVjdG9yLgorICAgICovCisgICAgeHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcihjdHh0LCBjb250ZXh0Tm9kZSwgbGlzdCwgdGVtcGwpOworCisgICAgLyoKKyAgICAqIFJlbW92ZSByZW1haW5pbmcgeHNsOnBhcmFtIGFuZCB4c2w6d2l0aC1wYXJhbSBpdGVtcyBmcm9tCisgICAgKiB0aGUgc3RhY2suIERvbid0IGZyZWUgeHNsOndpdGgtcGFyYW0gaXRlbXMuCisgICAgKi8KKyAgICBpZiAoY3R4dC0+dmFyc05yID4gY3R4dC0+dmFyc0Jhc2UpCisJeHNsdFRlbXBsYXRlUGFyYW1zQ2xlYW51cChjdHh0KTsKKyAgICBjdHh0LT52YXJzQmFzZSA9IG9sZFZhcnNCYXNlOworCisgICAgLyoKKyAgICAqIENsZWFuIHVwIHJlbWFpbmluZyBsb2NhbCB0cmVlIGZyYWdtZW50cy4KKyAgICAqIFRoaXMgYWxzbyBmcmVlcyBmcmFnbWVudHMgd2hpY2ggYXJlIHRoZSByZXN1bHQgb2YKKyAgICAqIGV4dGVuc2lvbiBpbnN0cnVjdGlvbnMuIFNob3VsZCBub3JtYWxseSBub3QgYmUgaGl0OyBidXQKKyAgICAqIGp1c3QgZm9yIHRoZSBjYXNlIHhzbHRFeHRlbnNpb25JbnN0cnVjdGlvblJlc3VsdEZpbmFsaXplKCkKKyAgICAqIHdhcyBub3QgY2FsbGVkIGJ5IHRoZSBleHRlbnNpb24gYXV0aG9yLgorICAgICovCisgICAgaWYgKG9sZExvY2FsRnJhZ21lbnRUb3AgIT0gY3R4dC0+bG9jYWxSVlQpIHsKKwl4bWxEb2NQdHIgY3VyZG9jID0gY3R4dC0+bG9jYWxSVlQsIHRtcDsKKworCWRvIHsKKwkgICAgdG1wID0gY3VyZG9jOworCSAgICBjdXJkb2MgPSAoeG1sRG9jUHRyKSBjdXJkb2MtPm5leHQ7CisJICAgIC8qIE5lZWQgdG8gaG91c2VrZWVwIGxvY2FsUlZUQmFzZSAqLworCSAgICBpZiAodG1wID09IGN0eHQtPmxvY2FsUlZUQmFzZSkKKwkgICAgICAgIGN0eHQtPmxvY2FsUlZUQmFzZSA9IGN1cmRvYzsKKwkgICAgaWYgKHRtcC0+cHJldikKKwkJdG1wLT5wcmV2LT5uZXh0ID0gKHhtbE5vZGVQdHIpIGN1cmRvYzsKKwkgICAgaWYgKGN1cmRvYykKKwkJY3VyZG9jLT5wcmV2ID0gdG1wLT5wcmV2OworCSAgICB4c2x0UmVsZWFzZVJWVChjdHh0LCB0bXApOworCX0gd2hpbGUgKGN1cmRvYyAhPSBvbGRMb2NhbEZyYWdtZW50VG9wKTsKKyAgICB9CisgICAgY3R4dC0+bG9jYWxSVlQgPSBvbGRMb2NhbEZyYWdtZW50VG9wOworCisgICAgLyoKKyAgICAqIFJlbGVhc2UgdXNlci1jcmVhdGVkIGZyYWdtZW50cyBzdG9yZWQgaW4gdGhlIHNjb3BlCisgICAgKiBvZiB4c2w6dGVtcGxhdGUuIE5vdGUgdGhhdCB0aGlzIG1lY2hhbmlzbSBpcyBkZXByZWNhdGVkOgorICAgICogdXNlciBjb2RlIHNob3VsZCBub3cgdXNlIHhzbHRSZWdpc3RlckxvY2FsUlZUKCkgaW5zdGVhZAorICAgICogb2YgdGhlIG9ic29sZXRlIHhzbHRSZWdpc3RlclRtcFJWVCgpLgorICAgICovCisgICAgaWYgKGN0eHQtPnRtcFJWVCkgeworCXhtbERvY1B0ciBjdXJkb2MgPSBjdHh0LT50bXBSVlQsIHRtcDsKKworCXdoaWxlIChjdXJkb2MgIT0gTlVMTCkgeworCSAgICB0bXAgPSBjdXJkb2M7CisJICAgIGN1cmRvYyA9ICh4bWxEb2NQdHIpIGN1cmRvYy0+bmV4dDsKKwkgICAgeHNsdFJlbGVhc2VSVlQoY3R4dCwgdG1wKTsKKwl9CisgICAgfQorICAgIGN0eHQtPnRtcFJWVCA9IG9sZFVzZXJGcmFnbWVudFRvcDsKKworICAgIC8qCisgICAgKiBQb3AgdGhlIHhzbDp0ZW1wbGF0ZSBkZWNsYXJhdGlvbiBmcm9tIHRoZSBzdGFjay4KKyAgICAqLworICAgIHRlbXBsUG9wKGN0eHQpOworICAgIGlmIChjdHh0LT5wcm9maWxlKSB7CisJbG9uZyBzcGVudCwgY2hpbGQsIHRvdGFsLCBlbmQ7CisKKwllbmQgPSB4c2x0VGltZXN0YW1wKCk7CisJY2hpbGQgPSBwcm9mUG9wKGN0eHQpOworCXRvdGFsID0gZW5kIC0gc3RhcnQ7CisJc3BlbnQgPSB0b3RhbCAtIGNoaWxkOworCWlmIChzcGVudCA8PSAwKSB7CisJICAgIC8qCisJICAgICogTm90IHBvc3NpYmxlIHVubGVzcyB0aGUgb3JpZ2luYWwgY2FsaWJyYXRpb24gZmFpbGVkCisJICAgICogd2UgY2FuIHRyeSB0byBjb3JyZWN0IGl0IG9uIHRoZSBmbHkuCisJICAgICovCisJICAgIHhzbHRDYWxpYnJhdGVBZGp1c3Qoc3BlbnQpOworCSAgICBzcGVudCA9IDA7CisJfQorCisJdGVtcGwtPnRpbWUgKz0gc3BlbnQ7CisJaWYgKGN0eHQtPnByb2ZOciA+IDApCisJICAgIGN0eHQtPnByb2ZUYWJbY3R4dC0+cHJvZk5yIC0gMV0gKz0gdG90YWw7CisgICAgfQorCisjaWZkZWYgV0lUSF9ERUJVR0dFUgorICAgIGlmICgoY3R4dC0+ZGVidWdTdGF0dXMgIT0gWFNMVF9ERUJVR19OT05FKSAmJiAoYWRkQ2FsbFJlc3VsdCkpIHsKKyAgICAgICAgeHNsRHJvcENhbGwoKTsKKyAgICB9CisjZW5kaWYKK30KKworCisvKioKKyAqIHhzbHRBcHBseU9uZVRlbXBsYXRlOgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAY29udGV4dE5vZGU6ICB0aGUgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUuCisgKiBAbGlzdDogIHRoZSBub2RlcyBvZiBhIHNlcXVlbmNlIGNvbnN0cnVjdG9yCisgKiBAdGVtcGw6IG5vdCB1c2VkCisgKiBAcGFyYW1zOiAgYSBzZXQgb2YgcGFyYW1ldGVycyAoeHNsOnBhcmFtKSBvciBOVUxMCisgKgorICogUHJvY2Vzc2VzIGEgc2VxdWVuY2UgY29uc3RydWN0b3Igb24gdGhlIGN1cnJlbnQgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUuCisgKgorICogQHBhcmFtcyBhcmUgdGhlIGFscmVhZHkgY29tcHV0ZWQgdmFyaWFibGUgc3RhY2sgaXRlbXM7IHRoaXMgZnVuY3Rpb24KKyAqIHB1c2hlcyB0aGVtIG9uIHRoZSB2YXJpYWJsZSBzdGFjaywgYW5kIHBvcHMgdGhlbSBiZWZvcmUgZXhpdGluZzsgaXQncworICogbGVmdCB0byB0aGUgY2FsbGVyIHRvIGZyZWUgb3IgcmV1c2UgQHBhcmFtcyBhZnRlcndhcmRzLiBUaGUgaW5pdGlhbAorICogc3RhdGVzIG9mIHRoZSB2YXJpYWJsZSBzdGFjayB3aWxsIGFsd2F5cyBiZSByZXN0b3JlZCBiZWZvcmUgdGhpcworICogZnVuY3Rpb24gZXhpdHMuCisgKiBOT1RFIHRoYXQgdGhpcyBkb2VzICpub3QqIGluaXRpYXRlIGEgbmV3IGRpc3RpbmN0IHZhcmlhYmxlIHNjb3BlOyBpLmUuCisgKiB2YXJpYWJsZXMgYWxyZWFkeSBvbiB0aGUgc3RhY2sgYXJlIHZpc2libGUgdG8gdGhlIHByb2Nlc3MuIFRoZSBjYWxsZXIncworICogc2lkZSBuZWVkcyB0byBzdGFydCBhIG5ldyB2YXJpYWJsZSBzY29wZSBpZiBuZWVkZWQgKGUuZy4gaW4gZXhzbDpmdW5jdGlvbikuCisgKgorICogQHRlbXBsIGlzIG9ic29sZXRlIGFuZCBub3QgdXNlZCBhbnltb3JlIChlLmcuIDxleHNsdDpmdW5jdGlvbj4gZG9lcyBub3QKKyAqIHByb3ZpZGUgYSBAdGVtcGwpOyBhIG5vbi1OVUxMIEB0ZW1wbCBtaWdodCByYWlzZSBhbiBlcnJvciBpbiB0aGUgZnV0dXJlLgorICoKKyAqIEJJRyBOT1RFOiBUaGlzIGZ1bmN0aW9uIGlzIG5vdCBpbnRlbmRlZCB0byBwcm9jZXNzIHRoZSBjb250ZW50IG9mIGFuCisgKiB4c2w6dGVtcGxhdGU7IGl0IGRvZXMgbm90IGV4cGVjdCB4c2w6cGFyYW0gaW5zdHJ1Y3Rpb25zIGluIEBsaXN0IGFuZAorICogd2lsbCByZXBvcnQgZXJyb3JzIGlmIGZvdW5kLgorICoKKyAqIENhbGxlZCBieToKKyAqICAtIHhzbHRFdmFsVmFyaWFibGUoKSAodmFyaWFibGVzLmMpCisgKiAgLSBleHNsdEZ1bmNGdW5jdGlvbkZ1bmN0aW9uKCkgKGxpYmV4c2wvZnVuY3Rpb25zLmMpCisgKi8KK3ZvaWQKK3hzbHRBcHBseU9uZVRlbXBsYXRlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCSAgICAgeG1sTm9kZVB0ciBjb250ZXh0Tm9kZSwKKyAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbGlzdCwKKwkJICAgICB4c2x0VGVtcGxhdGVQdHIgdGVtcGwgQVRUUklCVVRFX1VOVVNFRCwKKyAgICAgICAgICAgICAgICAgICAgIHhzbHRTdGFja0VsZW1QdHIgcGFyYW1zKQoreworICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobGlzdCA9PSBOVUxMKSkKKwlyZXR1cm47CisgICAgQ0hFQ0tfU1RPUFBFRDsKKworICAgIGlmIChwYXJhbXMpIHsKKwkvKgorCSAqIFRoaXMgY29kZSBzaG91bGQgYmUgb2Jzb2xldGUgLSB3YXMgcHJldmlvdXNseSB1c2VkCisJICogYnkgbGliZXhzbHQvZnVuY3Rpb25zLmMsIGJ1dCBkdWUgdG8gYnVnIDM4MTMxOSB0aGUKKwkgKiBsb2dpYyB0aGVyZSB3YXMgY2hhbmdlZC4KKwkgKi8KKwlpbnQgb2xkVmFyc05yID0gY3R4dC0+dmFyc05yOworCisJLyoKKwkqIFB1c2ggdGhlIGdpdmVuIHhzbDpwYXJhbShzKSBvbnRvIHRoZSB2YXJpYWJsZSBzdGFjay4KKwkqLworCXdoaWxlIChwYXJhbXMgIT0gTlVMTCkgeworCSAgICB4c2x0TG9jYWxWYXJpYWJsZVB1c2goY3R4dCwgcGFyYW1zLCAtMSk7CisJICAgIHBhcmFtcyA9IHBhcmFtcy0+bmV4dDsKKwl9CisJeHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcihjdHh0LCBjb250ZXh0Tm9kZSwgbGlzdCwgdGVtcGwpOworCS8qCisJKiBQb3AgdGhlIGdpdmVuIHhzbDpwYXJhbShzKSBmcm9tIHRoZSBzdGFjayBidXQgZG9uJ3QgZnJlZSB0aGVtLgorCSovCisJeHNsdExvY2FsVmFyaWFibGVQb3AoY3R4dCwgb2xkVmFyc05yLCAtMik7CisgICAgfSBlbHNlCisJeHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcihjdHh0LCBjb250ZXh0Tm9kZSwgbGlzdCwgdGVtcGwpOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkgICAgWFNMVC0xLjEgZXh0ZW5zaW9ucwkJCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHREb2N1bWVudEVsZW06CisgKiBAY3R4dDogIGFuIFhTTFQgcHJvY2Vzc2luZyBjb250ZXh0CisgKiBAbm9kZTogIFRoZSBjdXJyZW50IG5vZGUKKyAqIEBpbnN0OiAgdGhlIGluc3RydWN0aW9uIGluIHRoZSBzdHlsZXNoZWV0CisgKiBAY2FzdGVkQ29tcDogIHByZWNvbXB1dGVkIGluZm9ybWF0aW9uCisgKgorICogUHJvY2VzcyBhbiBFWFNMVC9YU0xULTEuMSBkb2N1bWVudCBlbGVtZW50CisgKi8KK3ZvaWQKK3hzbHREb2N1bWVudEVsZW0oeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAorICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGluc3QsIHhzbHRTdHlsZVByZUNvbXBQdHIgY2FzdGVkQ29tcCkKK3sKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtRG9jdW1lbnRQdHIgY29tcCA9ICh4c2x0U3R5bGVJdGVtRG9jdW1lbnRQdHIpIGNhc3RlZENvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCA9IGNhc3RlZENvbXA7CisjZW5kaWYKKyAgICB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSA9IE5VTEw7CisgICAgaW50IHJldDsKKyAgICB4bWxDaGFyICpmaWxlbmFtZSA9IE5VTEwsICpwcm9wLCAqZWxlbWVudHM7CisgICAgeG1sQ2hhciAqZWxlbWVudCwgKmVuZDsKKyAgICB4bWxEb2NQdHIgcmVzID0gTlVMTDsKKyAgICB4bWxEb2NQdHIgb2xkT3V0cHV0OworICAgIHhtbE5vZGVQdHIgb2xkSW5zZXJ0LCByb290OworICAgIGNvbnN0IGNoYXIgKm9sZE91dHB1dEZpbGU7CisgICAgeHNsdE91dHB1dFR5cGUgb2xkVHlwZTsKKyAgICB4bWxDaGFyICpVUkwgPSBOVUxMOworICAgIGNvbnN0IHhtbENoYXIgKm1ldGhvZDsKKyAgICBjb25zdCB4bWxDaGFyICpkb2N0eXBlUHVibGljOworICAgIGNvbnN0IHhtbENoYXIgKmRvY3R5cGVTeXN0ZW07CisgICAgY29uc3QgeG1sQ2hhciAqdmVyc2lvbjsKKyAgICBjb25zdCB4bWxDaGFyICplbmNvZGluZzsKKworICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSB8fCAoY29tcCA9PSBOVUxMKSkKKyAgICAgICAgcmV0dXJuOworCisgICAgaWYgKGNvbXAtPmZpbGVuYW1lID09IE5VTEwpIHsKKworICAgICAgICBpZiAoeG1sU3RyRXF1YWwoaW5zdC0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgIm91dHB1dCIpKSB7CisJICAgIC8qCisJICAgICogVGhlIGVsZW1lbnQgIm91dHB1dCIgaXMgaW4gdGhlIG5hbWVzcGFjZSBYU0xUX1NBWE9OX05BTUVTUEFDRQorCSAgICAqICAgKGh0dHA6Ly9pY2wuY29tL3NheG9uKQorCSAgICAqIFRoZSBAZmlsZSBpcyBpbiBubyBuYW1lc3BhY2UuCisJICAgICovCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0VYVFJBCisgICAgICAgICAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRm91bmQgc2F4b246b3V0cHV0IGV4dGVuc2lvblxuIik7CisjZW5kaWYKKyAgICAgICAgICAgIFVSTCA9IHhzbHRFdmFsQXR0clZhbHVlVGVtcGxhdGUoY3R4dCwgaW5zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgeG1sQ2hhciAqKSAiZmlsZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9TQVhPTl9OQU1FU1BBQ0UpOworCisJICAgIGlmIChVUkwgPT0gTlVMTCkKKwkJVVJMID0geHNsdEV2YWxBdHRyVmFsdWVUZW1wbGF0ZShjdHh0LCBpbnN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb25zdCB4bWxDaGFyICopICJocmVmIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX1NBWE9OX05BTUVTUEFDRSk7CisgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaW5zdC0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgIndyaXRlIikpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfRVhUUkEKKyAgICAgICAgICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGb3VuZCB4YWxhbjp3cml0ZSBleHRlbnNpb25cbiIpOworI2VuZGlmCisgICAgICAgICAgICBVUkwgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIGluc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IHhtbENoYXIgKikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2VsZWN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX1hBTEFOX05BTUVTUEFDRSk7CisJICAgIGlmIChVUkwgIT0gTlVMTCkgeworCQl4bWxYUGF0aENvbXBFeHByUHRyIGNtcDsKKwkJeG1sQ2hhciAqdmFsOworCisJCS8qCisJCSAqIFRyeWluZyB0byBoYW5kbGUgYnVnICM1OTIxMgorCQkgKiBUaGUgdmFsdWUgb2YgdGhlICJzZWxlY3QiIGF0dHJpYnV0ZSBpcyBhbgorCQkgKiBYUGF0aCBleHByZXNzaW9uLgorCQkgKiAoc2VlIGh0dHA6Ly94bWwuYXBhY2hlLm9yZy94YWxhbi1qL2V4dGVuc2lvbnNsaWIuaHRtbCNyZWRpcmVjdCkKKwkJICovCisJCWNtcCA9IHhtbFhQYXRoQ29tcGlsZShVUkwpOworICAgICAgICAgICAgICAgIHZhbCA9IHhzbHRFdmFsWFBhdGhTdHJpbmcoY3R4dCwgY21wKTsKKwkJeG1sWFBhdGhGcmVlQ29tcEV4cHIoY21wKTsKKwkJeG1sRnJlZShVUkwpOworCQlVUkwgPSB2YWw7CisJICAgIH0KKwkgICAgaWYgKFVSTCA9PSBOVUxMKQorCQlVUkwgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIGluc3QsCisJCQkJCQkgICAgIChjb25zdCB4bWxDaGFyICopCisJCQkJCQkgICAgICJmaWxlIiwKKwkJCQkJCSAgICAgWFNMVF9YQUxBTl9OQU1FU1BBQ0UpOworCSAgICBpZiAoVVJMID09IE5VTEwpCisJCVVSTCA9IHhzbHRFdmFsQXR0clZhbHVlVGVtcGxhdGUoY3R4dCwgaW5zdCwKKwkJCQkJCSAgICAgKGNvbnN0IHhtbENoYXIgKikKKwkJCQkJCSAgICAgImhyZWYiLAorCQkJCQkJICAgICBYU0xUX1hBTEFOX05BTUVTUEFDRSk7CisgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaW5zdC0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgImRvY3VtZW50IikpIHsKKyAgICAgICAgICAgIFVSTCA9IHhzbHRFdmFsQXR0clZhbHVlVGVtcGxhdGUoY3R4dCwgaW5zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgeG1sQ2hhciAqKSAiaHJlZiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CisgICAgICAgIH0KKworICAgIH0gZWxzZSB7CisgICAgICAgIFVSTCA9IHhtbFN0cmR1cChjb21wLT5maWxlbmFtZSk7CisgICAgfQorCisgICAgaWYgKFVSTCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCSAgICAgICAgICJ4c2x0RG9jdW1lbnRFbGVtOiBocmVmL1VSSS1SZWZlcmVuY2Ugbm90IGZvdW5kXG4iKTsKKwlyZXR1cm47CisgICAgfQorCisgICAgLyoKKyAgICAgKiBJZiB0aGUgY29tcHV0YXRpb24gZmFpbGVkLCBpdCdzIGxpa2VseSB0aGF0IHRoZSBVUkwgd2Fzbid0IGVzY2FwZWQKKyAgICAgKi8KKyAgICBmaWxlbmFtZSA9IHhtbEJ1aWxkVVJJKFVSTCwgKGNvbnN0IHhtbENoYXIgKikgY3R4dC0+b3V0cHV0RmlsZSk7CisgICAgaWYgKGZpbGVuYW1lID09IE5VTEwpIHsKKwl4bWxDaGFyICplc2NVUkw7CisKKwllc2NVUkw9eG1sVVJJRXNjYXBlU3RyKFVSTCwgQkFEX0NBU1QgIjovLj8sIik7CisJaWYgKGVzY1VSTCAhPSBOVUxMKSB7CisJICAgIGZpbGVuYW1lID0geG1sQnVpbGRVUkkoZXNjVVJMLCAoY29uc3QgeG1sQ2hhciAqKSBjdHh0LT5vdXRwdXRGaWxlKTsKKwkgICAgeG1sRnJlZShlc2NVUkwpOworCX0KKyAgICB9CisKKyAgICBpZiAoZmlsZW5hbWUgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkgICAgICAgICAieHNsdERvY3VtZW50RWxlbTogVVJMIGNvbXB1dGF0aW9uIGZhaWxlZCBmb3IgJXNcbiIsCisJCQkgVVJMKTsKKwl4bWxGcmVlKFVSTCk7CisJcmV0dXJuOworICAgIH0KKworICAgIC8qCisgICAgICogU2VjdXJpdHkgY2hlY2tpbmc6IGNhbiB3ZSB3cml0ZSB0byB0aGlzIHJlc291cmNlCisgICAgICovCisgICAgaWYgKGN0eHQtPnNlYyAhPSBOVUxMKSB7CisJcmV0ID0geHNsdENoZWNrV3JpdGUoY3R4dC0+c2VjLCBjdHh0LCBmaWxlbmFtZSk7CisJaWYgKHJldCA9PSAwKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkgInhzbHREb2N1bWVudEVsZW06IHdyaXRlIHJpZ2h0cyBmb3IgJXMgZGVuaWVkXG4iLAorCQkJICAgICBmaWxlbmFtZSk7CisJICAgIHhtbEZyZWUoVVJMKTsKKwkgICAgeG1sRnJlZShmaWxlbmFtZSk7CisJICAgIHJldHVybjsKKwl9CisgICAgfQorCisgICAgb2xkT3V0cHV0RmlsZSA9IGN0eHQtPm91dHB1dEZpbGU7CisgICAgb2xkT3V0cHV0ID0gY3R4dC0+b3V0cHV0OworICAgIG9sZEluc2VydCA9IGN0eHQtPmluc2VydDsKKyAgICBvbGRUeXBlID0gY3R4dC0+dHlwZTsKKyAgICBjdHh0LT5vdXRwdXRGaWxlID0gKGNvbnN0IGNoYXIgKikgZmlsZW5hbWU7CisKKyAgICBzdHlsZSA9IHhzbHROZXdTdHlsZXNoZWV0KCk7CisgICAgaWYgKHN0eWxlID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAieHNsdERvY3VtZW50RWxlbTogb3V0IG9mIG1lbW9yeVxuIik7CisgICAgICAgIGdvdG8gZXJyb3I7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBWZXJzaW9uIGRlc2NyaWJlZCBpbiAxLjEgZHJhZnQgYWxsb3dzIGZ1bGwgcGFyYW1ldGVyaXphdGlvbgorICAgICAqIG9mIHRoZSBvdXRwdXQuCisgICAgICovCisgICAgcHJvcCA9IHhzbHRFdmFsQXR0clZhbHVlVGVtcGxhdGUoY3R4dCwgaW5zdCwKKwkJCQkgICAgIChjb25zdCB4bWxDaGFyICopICJ2ZXJzaW9uIiwKKwkJCQkgICAgIE5VTEwpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKwlpZiAoc3R5bGUtPnZlcnNpb24gIT0gTlVMTCkKKwkgICAgeG1sRnJlZShzdHlsZS0+dmVyc2lvbik7CisJc3R5bGUtPnZlcnNpb24gPSBwcm9wOworICAgIH0KKyAgICBwcm9wID0geHNsdEV2YWxBdHRyVmFsdWVUZW1wbGF0ZShjdHh0LCBpbnN0LAorCQkJCSAgICAgKGNvbnN0IHhtbENoYXIgKikgImVuY29kaW5nIiwKKwkJCQkgICAgIE5VTEwpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKwlpZiAoc3R5bGUtPmVuY29kaW5nICE9IE5VTEwpCisJICAgIHhtbEZyZWUoc3R5bGUtPmVuY29kaW5nKTsKKwlzdHlsZS0+ZW5jb2RpbmcgPSBwcm9wOworICAgIH0KKyAgICBwcm9wID0geHNsdEV2YWxBdHRyVmFsdWVUZW1wbGF0ZShjdHh0LCBpbnN0LAorCQkJCSAgICAgKGNvbnN0IHhtbENoYXIgKikgIm1ldGhvZCIsCisJCQkJICAgICBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJY29uc3QgeG1sQ2hhciAqVVJJOworCisJaWYgKHN0eWxlLT5tZXRob2QgIT0gTlVMTCkKKwkgICAgeG1sRnJlZShzdHlsZS0+bWV0aG9kKTsKKwlzdHlsZS0+bWV0aG9kID0gTlVMTDsKKwlpZiAoc3R5bGUtPm1ldGhvZFVSSSAhPSBOVUxMKQorCSAgICB4bWxGcmVlKHN0eWxlLT5tZXRob2RVUkkpOworCXN0eWxlLT5tZXRob2RVUkkgPSBOVUxMOworCisJVVJJID0geHNsdEdldFFOYW1lVVJJKGluc3QsICZwcm9wKTsKKwlpZiAocHJvcCA9PSBOVUxMKSB7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJfSBlbHNlIGlmIChVUkkgPT0gTlVMTCkgeworCSAgICBpZiAoKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJ4bWwiKSkgfHwKKwkJKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJodG1sIikpIHx8CisJCSh4bWxTdHJFcXVhbChwcm9wLCAoY29uc3QgeG1sQ2hhciAqKSAidGV4dCIpKSkgeworCQlzdHlsZS0+bWV0aG9kID0gcHJvcDsKKwkgICAgfSBlbHNlIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCQkJICJpbnZhbGlkIHZhbHVlIGZvciBtZXRob2Q6ICVzXG4iLCBwcm9wKTsKKwkJaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT53YXJuaW5ncysrOworCSAgICB9CisJfSBlbHNlIHsKKwkgICAgc3R5bGUtPm1ldGhvZCA9IHByb3A7CisJICAgIHN0eWxlLT5tZXRob2RVUkkgPSB4bWxTdHJkdXAoVVJJKTsKKwl9CisgICAgfQorICAgIHByb3AgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIGluc3QsCisJCQkJICAgICAoY29uc3QgeG1sQ2hhciAqKQorCQkJCSAgICAgImRvY3R5cGUtc3lzdGVtIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWlmIChzdHlsZS0+ZG9jdHlwZVN5c3RlbSAhPSBOVUxMKQorCSAgICB4bWxGcmVlKHN0eWxlLT5kb2N0eXBlU3lzdGVtKTsKKwlzdHlsZS0+ZG9jdHlwZVN5c3RlbSA9IHByb3A7CisgICAgfQorICAgIHByb3AgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIGluc3QsCisJCQkJICAgICAoY29uc3QgeG1sQ2hhciAqKQorCQkJCSAgICAgImRvY3R5cGUtcHVibGljIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWlmIChzdHlsZS0+ZG9jdHlwZVB1YmxpYyAhPSBOVUxMKQorCSAgICB4bWxGcmVlKHN0eWxlLT5kb2N0eXBlUHVibGljKTsKKwlzdHlsZS0+ZG9jdHlwZVB1YmxpYyA9IHByb3A7CisgICAgfQorICAgIHByb3AgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIGluc3QsCisJCQkJICAgICAoY29uc3QgeG1sQ2hhciAqKSAic3RhbmRhbG9uZSIsCisJCQkJICAgICBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJ5ZXMiKSkgeworCSAgICBzdHlsZS0+c3RhbmRhbG9uZSA9IDE7CisJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChwcm9wLCAoY29uc3QgeG1sQ2hhciAqKSAibm8iKSkgeworCSAgICBzdHlsZS0+c3RhbmRhbG9uZSA9IDA7CisJfSBlbHNlIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCQkgICAgICJpbnZhbGlkIHZhbHVlIGZvciBzdGFuZGFsb25lOiAlc1xuIiwKKwkJCSAgICAgcHJvcCk7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKwl9CisJeG1sRnJlZShwcm9wKTsKKyAgICB9CisKKyAgICBwcm9wID0geHNsdEV2YWxBdHRyVmFsdWVUZW1wbGF0ZShjdHh0LCBpbnN0LAorCQkJCSAgICAgKGNvbnN0IHhtbENoYXIgKikgImluZGVudCIsCisJCQkJICAgICBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJ5ZXMiKSkgeworCSAgICBzdHlsZS0+aW5kZW50ID0gMTsKKwl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJubyIpKSB7CisJICAgIHN0eWxlLT5pbmRlbnQgPSAwOworCX0gZWxzZSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkJICAgICAiaW52YWxpZCB2YWx1ZSBmb3IgaW5kZW50OiAlc1xuIiwgcHJvcCk7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKwl9CisJeG1sRnJlZShwcm9wKTsKKyAgICB9CisKKyAgICBwcm9wID0geHNsdEV2YWxBdHRyVmFsdWVUZW1wbGF0ZShjdHh0LCBpbnN0LAorCQkJCSAgICAgKGNvbnN0IHhtbENoYXIgKikKKwkJCQkgICAgICJvbWl0LXhtbC1kZWNsYXJhdGlvbiIsCisJCQkJICAgICBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJ5ZXMiKSkgeworCSAgICBzdHlsZS0+b21pdFhtbERlY2xhcmF0aW9uID0gMTsKKwl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJubyIpKSB7CisJICAgIHN0eWxlLT5vbWl0WG1sRGVjbGFyYXRpb24gPSAwOworCX0gZWxzZSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkJICAgICAiaW52YWxpZCB2YWx1ZSBmb3Igb21pdC14bWwtZGVjbGFyYXRpb246ICVzXG4iLAorCQkJICAgICBwcm9wKTsKKwkgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT53YXJuaW5ncysrOworCX0KKwl4bWxGcmVlKHByb3ApOworICAgIH0KKworICAgIGVsZW1lbnRzID0geHNsdEV2YWxBdHRyVmFsdWVUZW1wbGF0ZShjdHh0LCBpbnN0LAorCQkJCQkgKGNvbnN0IHhtbENoYXIgKikKKwkJCQkJICJjZGF0YS1zZWN0aW9uLWVsZW1lbnRzIiwKKwkJCQkJIE5VTEwpOworICAgIGlmIChlbGVtZW50cyAhPSBOVUxMKSB7CisJaWYgKHN0eWxlLT5zdHJpcFNwYWNlcyA9PSBOVUxMKQorCSAgICBzdHlsZS0+c3RyaXBTcGFjZXMgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKKwlpZiAoc3R5bGUtPnN0cmlwU3BhY2VzID09IE5VTEwpCisJICAgIHJldHVybjsKKworCWVsZW1lbnQgPSBlbGVtZW50czsKKwl3aGlsZSAoKmVsZW1lbnQgIT0gMCkgeworCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmVsZW1lbnQpKQorCQllbGVtZW50Kys7CisJICAgIGlmICgqZWxlbWVudCA9PSAwKQorCQlicmVhazsKKwkgICAgZW5kID0gZWxlbWVudDsKKwkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghSVNfQkxBTktfQ0goKmVuZCkpKQorCQllbmQrKzsKKwkgICAgZWxlbWVudCA9IHhtbFN0cm5kdXAoZWxlbWVudCwgZW5kIC0gZWxlbWVudCk7CisJICAgIGlmIChlbGVtZW50KSB7CisJCWNvbnN0IHhtbENoYXIgKlVSSTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkJICJhZGQgY2RhdGEgc2VjdGlvbiBvdXRwdXQgZWxlbWVudCAlc1xuIiwKKwkJCQkgZWxlbWVudCk7CisjZW5kaWYKKyAgICAgICAgICAgICAgICBVUkkgPSB4c2x0R2V0UU5hbWVVUkkoaW5zdCwgJmVsZW1lbnQpOworCisJCXhtbEhhc2hBZGRFbnRyeTIoc3R5bGUtPnN0cmlwU3BhY2VzLCBlbGVtZW50LCBVUkksCisJCQkgICAgICAgICh4bWxDaGFyICopICJjZGF0YSIpOworCQl4bWxGcmVlKGVsZW1lbnQpOworCSAgICB9CisJICAgIGVsZW1lbnQgPSBlbmQ7CisJfQorCXhtbEZyZWUoZWxlbWVudHMpOworICAgIH0KKworICAgIC8qCisgICAgICogQ3JlYXRlIGEgbmV3IGRvY3VtZW50IHRyZWUgYW5kIHByb2Nlc3MgdGhlIGVsZW1lbnQgdGVtcGxhdGUKKyAgICAgKi8KKyAgICBYU0xUX0dFVF9JTVBPUlRfUFRSKG1ldGhvZCwgc3R5bGUsIG1ldGhvZCkKKyAgICBYU0xUX0dFVF9JTVBPUlRfUFRSKGRvY3R5cGVQdWJsaWMsIHN0eWxlLCBkb2N0eXBlUHVibGljKQorICAgIFhTTFRfR0VUX0lNUE9SVF9QVFIoZG9jdHlwZVN5c3RlbSwgc3R5bGUsIGRvY3R5cGVTeXN0ZW0pCisgICAgWFNMVF9HRVRfSU1QT1JUX1BUUih2ZXJzaW9uLCBzdHlsZSwgdmVyc2lvbikKKyAgICBYU0xUX0dFVF9JTVBPUlRfUFRSKGVuY29kaW5nLCBzdHlsZSwgZW5jb2RpbmcpCisKKyAgICBpZiAoKG1ldGhvZCAhPSBOVUxMKSAmJgorCSgheG1sU3RyRXF1YWwobWV0aG9kLCAoY29uc3QgeG1sQ2hhciAqKSAieG1sIikpKSB7CisJaWYgKHhtbFN0ckVxdWFsKG1ldGhvZCwgKGNvbnN0IHhtbENoYXIgKikgImh0bWwiKSkgeworCSAgICBjdHh0LT50eXBlID0gWFNMVF9PVVRQVVRfSFRNTDsKKwkgICAgaWYgKCgoZG9jdHlwZVB1YmxpYyAhPSBOVUxMKSB8fCAoZG9jdHlwZVN5c3RlbSAhPSBOVUxMKSkpCisJCXJlcyA9IGh0bWxOZXdEb2MoZG9jdHlwZVN5c3RlbSwgZG9jdHlwZVB1YmxpYyk7CisJICAgIGVsc2UgeworCQlpZiAodmVyc2lvbiAhPSBOVUxMKSB7CisjaWZkZWYgWFNMVF9HRU5FUkFURV9IVE1MX0RPQ1RZUEUKKwkJICAgIHhzbHRHZXRIVE1MSURzKHZlcnNpb24sICZkb2N0eXBlUHVibGljLCAmZG9jdHlwZVN5c3RlbSk7CisjZW5kaWYKKyAgICAgICAgICAgICAgICB9CisJCXJlcyA9IGh0bWxOZXdEb2NOb0R0RChkb2N0eXBlU3lzdGVtLCBkb2N0eXBlUHVibGljKTsKKwkgICAgfQorCSAgICBpZiAocmVzID09IE5VTEwpCisJCWdvdG8gZXJyb3I7CisJICAgIHJlcy0+ZGljdCA9IGN0eHQtPmRpY3Q7CisJICAgIHhtbERpY3RSZWZlcmVuY2UocmVzLT5kaWN0KTsKKwl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKG1ldGhvZCwgKGNvbnN0IHhtbENoYXIgKikgInhodG1sIikpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJICAgICAieHNsdERvY3VtZW50RWxlbTogdW5zdXBwb3J0ZWQgbWV0aG9kIHhodG1sXG4iLAorCQkgICAgICAgICAgICAgc3R5bGUtPm1ldGhvZCk7CisJICAgIGN0eHQtPnR5cGUgPSBYU0xUX09VVFBVVF9IVE1MOworCSAgICByZXMgPSBodG1sTmV3RG9jTm9EdEQoZG9jdHlwZVN5c3RlbSwgZG9jdHlwZVB1YmxpYyk7CisJICAgIGlmIChyZXMgPT0gTlVMTCkKKwkJZ290byBlcnJvcjsKKwkgICAgcmVzLT5kaWN0ID0gY3R4dC0+ZGljdDsKKwkgICAgeG1sRGljdFJlZmVyZW5jZShyZXMtPmRpY3QpOworCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobWV0aG9kLCAoY29uc3QgeG1sQ2hhciAqKSAidGV4dCIpKSB7CisJICAgIGN0eHQtPnR5cGUgPSBYU0xUX09VVFBVVF9URVhUOworCSAgICByZXMgPSB4bWxOZXdEb2Moc3R5bGUtPnZlcnNpb24pOworCSAgICBpZiAocmVzID09IE5VTEwpCisJCWdvdG8gZXJyb3I7CisJICAgIHJlcy0+ZGljdCA9IGN0eHQtPmRpY3Q7CisJICAgIHhtbERpY3RSZWZlcmVuY2UocmVzLT5kaWN0KTsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKwkgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICJyZXVzaW5nIHRyYW5zZm9ybWF0aW9uIGRpY3QgZm9yIG91dHB1dFxuIik7CisjZW5kaWYKKwl9IGVsc2UgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkJCSAgICAgInhzbHREb2N1bWVudEVsZW06IHVuc3VwcG9ydGVkIG1ldGhvZCAlc1xuIiwKKwkJICAgICAgICAgICAgIHN0eWxlLT5tZXRob2QpOworCSAgICBnb3RvIGVycm9yOworCX0KKyAgICB9IGVsc2UgeworCWN0eHQtPnR5cGUgPSBYU0xUX09VVFBVVF9YTUw7CisJcmVzID0geG1sTmV3RG9jKHN0eWxlLT52ZXJzaW9uKTsKKwlpZiAocmVzID09IE5VTEwpCisJICAgIGdvdG8gZXJyb3I7CisJcmVzLT5kaWN0ID0gY3R4dC0+ZGljdDsKKwl4bWxEaWN0UmVmZXJlbmNlKHJlcy0+ZGljdCk7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHCisJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICJyZXVzaW5nIHRyYW5zZm9ybWF0aW9uIGRpY3QgZm9yIG91dHB1dFxuIik7CisjZW5kaWYKKyAgICB9CisgICAgcmVzLT5jaGFyc2V0ID0gWE1MX0NIQVJfRU5DT0RJTkdfVVRGODsKKyAgICBpZiAoZW5jb2RpbmcgIT0gTlVMTCkKKwlyZXMtPmVuY29kaW5nID0geG1sU3RyZHVwKGVuY29kaW5nKTsKKyAgICBjdHh0LT5vdXRwdXQgPSByZXM7CisgICAgY3R4dC0+aW5zZXJ0ID0gKHhtbE5vZGVQdHIpIHJlczsKKyAgICB4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yKGN0eHQsIG5vZGUsIGluc3QtPmNoaWxkcmVuLCBOVUxMKTsKKworICAgIC8qCisgICAgICogRG8gc29tZSBwb3N0IHByb2Nlc3Npbmcgd29yayBkZXBlbmRpbmcgb24gdGhlIGdlbmVyYXRlZCBvdXRwdXQKKyAgICAgKi8KKyAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQocmVzKTsKKyAgICBpZiAocm9vdCAhPSBOVUxMKSB7CisgICAgICAgIGNvbnN0IHhtbENoYXIgKmRvY3R5cGUgPSBOVUxMOworCisgICAgICAgIGlmICgocm9vdC0+bnMgIT0gTlVMTCkgJiYgKHJvb3QtPm5zLT5wcmVmaXggIT0gTlVMTCkpCisJICAgIGRvY3R5cGUgPSB4bWxEaWN0UUxvb2t1cChjdHh0LT5kaWN0LCByb290LT5ucy0+cHJlZml4LCByb290LT5uYW1lKTsKKwlpZiAoZG9jdHlwZSA9PSBOVUxMKQorCSAgICBkb2N0eXBlID0gcm9vdC0+bmFtZTsKKworICAgICAgICAvKgorICAgICAgICAgKiBBcHBseSB0aGUgZGVmYXVsdCBzZWxlY3Rpb24gb2YgdGhlIG1ldGhvZAorICAgICAgICAgKi8KKyAgICAgICAgaWYgKChtZXRob2QgPT0gTlVMTCkgJiYKKyAgICAgICAgICAgIChyb290LT5ucyA9PSBOVUxMKSAmJgorICAgICAgICAgICAgKCF4bWxTdHJjYXNlY21wKHJvb3QtPm5hbWUsIChjb25zdCB4bWxDaGFyICopICJodG1sIikpKSB7CisgICAgICAgICAgICB4bWxOb2RlUHRyIHRtcDsKKworICAgICAgICAgICAgdG1wID0gcmVzLT5jaGlsZHJlbjsKKyAgICAgICAgICAgIHdoaWxlICgodG1wICE9IE5VTEwpICYmICh0bXAgIT0gcm9vdCkpIHsKKyAgICAgICAgICAgICAgICBpZiAodG1wLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGlmICgodG1wLT50eXBlID09IFhNTF9URVhUX05PREUpICYmICgheG1sSXNCbGFua05vZGUodG1wKSkpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCQl0bXAgPSB0bXAtPm5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAodG1wID09IHJvb3QpIHsKKyAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gWFNMVF9PVVRQVVRfSFRNTDsKKyAgICAgICAgICAgICAgICByZXMtPnR5cGUgPSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFOworICAgICAgICAgICAgICAgIGlmICgoKGRvY3R5cGVQdWJsaWMgIT0gTlVMTCkgfHwgKGRvY3R5cGVTeXN0ZW0gIT0gTlVMTCkpKSB7CisgICAgICAgICAgICAgICAgICAgIHJlcy0+aW50U3Vic2V0ID0geG1sQ3JlYXRlSW50U3Vic2V0KHJlcywgZG9jdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdHlwZVB1YmxpYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdHlwZVN5c3RlbSk7CisjaWZkZWYgWFNMVF9HRU5FUkFURV9IVE1MX0RPQ1RZUEUKKwkJfSBlbHNlIGlmICh2ZXJzaW9uICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgeHNsdEdldEhUTUxJRHModmVyc2lvbiwgJmRvY3R5cGVQdWJsaWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkb2N0eXBlU3lzdGVtKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCgoZG9jdHlwZVB1YmxpYyAhPSBOVUxMKSB8fCAoZG9jdHlwZVN5c3RlbSAhPSBOVUxMKSkpCisgICAgICAgICAgICAgICAgICAgICAgICByZXMtPmludFN1YnNldCA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQ3JlYXRlSW50U3Vic2V0KHJlcywgZG9jdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdHlwZVB1YmxpYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdHlwZVN5c3RlbSk7CisjZW5kaWYKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgfQorICAgICAgICBpZiAoY3R4dC0+dHlwZSA9PSBYU0xUX09VVFBVVF9YTUwpIHsKKyAgICAgICAgICAgIFhTTFRfR0VUX0lNUE9SVF9QVFIoZG9jdHlwZVB1YmxpYywgc3R5bGUsIGRvY3R5cGVQdWJsaWMpCisgICAgICAgICAgICAgICAgWFNMVF9HRVRfSU1QT1JUX1BUUihkb2N0eXBlU3lzdGVtLCBzdHlsZSwgZG9jdHlwZVN5c3RlbSkKKyAgICAgICAgICAgICAgICBpZiAoKChkb2N0eXBlUHVibGljICE9IE5VTEwpIHx8IChkb2N0eXBlU3lzdGVtICE9IE5VTEwpKSkKKyAgICAgICAgICAgICAgICByZXMtPmludFN1YnNldCA9IHhtbENyZWF0ZUludFN1YnNldChyZXMsIGRvY3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdHlwZVB1YmxpYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N0eXBlU3lzdGVtKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qCisgICAgICogU2F2ZSB0aGUgcmVzdWx0CisgICAgICovCisgICAgcmV0ID0geHNsdFNhdmVSZXN1bHRUb0ZpbGVuYW1lKChjb25zdCBjaGFyICopIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMsIHN0eWxlLCAwKTsKKyAgICBpZiAocmV0IDwgMCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0RG9jdW1lbnRFbGVtOiB1bmFibGUgdG8gc2F2ZSB0byAlc1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSk7CisJY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX0VSUk9SOworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19FWFRSQQorICAgIH0gZWxzZSB7CisgICAgICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIldyb3RlICVkIGJ5dGVzIHRvICVzXG4iLCByZXQsIGZpbGVuYW1lKTsKKyNlbmRpZgorICAgIH0KKworICBlcnJvcjoKKyAgICBjdHh0LT5vdXRwdXQgPSBvbGRPdXRwdXQ7CisgICAgY3R4dC0+aW5zZXJ0ID0gb2xkSW5zZXJ0OworICAgIGN0eHQtPnR5cGUgPSBvbGRUeXBlOworICAgIGN0eHQtPm91dHB1dEZpbGUgPSBvbGRPdXRwdXRGaWxlOworICAgIGlmIChVUkwgIT0gTlVMTCkKKyAgICAgICAgeG1sRnJlZShVUkwpOworICAgIGlmIChmaWxlbmFtZSAhPSBOVUxMKQorICAgICAgICB4bWxGcmVlKGZpbGVuYW1lKTsKKyAgICBpZiAoc3R5bGUgIT0gTlVMTCkKKyAgICAgICAgeHNsdEZyZWVTdHlsZXNoZWV0KHN0eWxlKTsKKyAgICBpZiAocmVzICE9IE5VTEwpCisgICAgICAgIHhtbEZyZWVEb2MocmVzKTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJTW9zdCBvZiB0aGUgWFNMVC0xLjAgdHJhbnNmb3JtYXRpb25zCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHRTb3J0OgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAbm9kZTogIHRoZSBub2RlIGluIHRoZSBzb3VyY2UgdHJlZS4KKyAqIEBpbnN0OiAgdGhlIHhzbHQgc29ydCBub2RlCisgKiBAY29tcDogIHByZWNvbXB1dGVkIGluZm9ybWF0aW9uCisgKgorICogZnVuY3Rpb24gYXR0YWNoZWQgdG8geHNsOnNvcnQgbm9kZXMsIGJ1dCB0aGlzIHNob3VsZCBub3QgYmUKKyAqIGNhbGxlZCBkaXJlY3RseQorICovCit2b2lkCit4c2x0U29ydCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCXhtbE5vZGVQdHIgbm9kZSBBVFRSSUJVVEVfVU5VU0VELCB4bWxOb2RlUHRyIGluc3QsCisJeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wKSB7CisgICAgaWYgKGNvbXAgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAgInhzbDpzb3J0IDogY29tcGlsYXRpb24gZmFpbGVkXG4iKTsKKwlyZXR1cm47CisgICAgfQorICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAieHNsOnNvcnQgOiBpbXByb3BlciB1c2UgdGhpcyBzaG91bGQgbm90IGJlIHJlYWNoZWRcbiIpOworfQorCisvKioKKyAqIHhzbHRDb3B5OgorICogQGN0eHQ6ICBhbiBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQG5vZGU6ICB0aGUgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUKKyAqIEBpbnN0OiAgdGhlIGVsZW1lbnQgbm9kZSBvZiB0aGUgWFNMVC1jb3B5IGluc3RydWN0aW9uCisgKiBAY2FzdGVkQ29tcDogIGNvbXB1dGVkIGluZm9ybWF0aW9uIG9mIHRoZSBYU0xULWNvcHkgaW5zdHJ1Y3Rpb24KKyAqCisgKiBFeGVjdXRlIHRoZSBYU0xULWNvcHkgaW5zdHJ1Y3Rpb24gb24gdGhlIHNvdXJjZSBub2RlLgorICovCit2b2lkCit4c2x0Q29weSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJIHhtbE5vZGVQdHIgaW5zdCwgeHNsdFN0eWxlUHJlQ29tcFB0ciBjYXN0ZWRDb21wKQoreworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1Db3B5UHRyIGNvbXAgPSAoeHNsdFN0eWxlSXRlbUNvcHlQdHIpIGNhc3RlZENvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCA9IGNhc3RlZENvbXA7CisjZW5kaWYKKyAgICB4bWxOb2RlUHRyIGNvcHksIG9sZEluc2VydDsKKworICAgIG9sZEluc2VydCA9IGN0eHQtPmluc2VydDsKKyAgICBpZiAoY3R4dC0+aW5zZXJ0ICE9IE5VTEwpIHsKKwlzd2l0Y2ggKG5vZGUtPnR5cGUpIHsKKwkgICAgY2FzZSBYTUxfVEVYVF9OT0RFOgorCSAgICBjYXNlIFhNTF9DREFUQV9TRUNUSU9OX05PREU6CisJCS8qCisJCSAqIFRoaXMgdGV4dCBjb21lcyBmcm9tIHRoZSBzdHlsZXNoZWV0CisJCSAqIEZvciBzdHlsZXNoZWV0cywgdGhlIHNldCBvZiB3aGl0ZXNwYWNlLXByZXNlcnZpbmcKKwkJICogZWxlbWVudCBuYW1lcyBjb25zaXN0cyBvZiBqdXN0IHhzbDp0ZXh0LgorCQkgKi8KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQlpZiAobm9kZS0+dHlwZSA9PSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSB7CisJCSAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DT1BZLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkgInhzbHRDb3B5OiBDREFUQSB0ZXh0ICVzXG4iLCBub2RlLT5jb250ZW50KSk7CisJCX0gZWxzZSB7CisJCSAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DT1BZLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkgInhzbHRDb3B5OiB0ZXh0ICVzXG4iLCBub2RlLT5jb250ZW50KSk7CisgICAgICAgICAgICAgICAgfQorI2VuZGlmCisJCXhzbHRDb3B5VGV4dChjdHh0LCBjdHh0LT5pbnNlcnQsIG5vZGUsIDApOworCQlicmVhazsKKwkgICAgY2FzZSBYTUxfRE9DVU1FTlRfTk9ERToKKwkgICAgY2FzZSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFOgorCQlicmVhazsKKwkgICAgY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgorCQkvKgorCQkqIFJFVklTSVQgTk9URTogVGhlICJmYWtlIiBpcyBhIGRvYy1ub2RlLCBub3QgYW4gZWxlbWVudCBub2RlLgorCQkqIFJFTU9WRUQ6CisJCSogICBpZiAoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgQkFEX0NBU1QgIiBmYWtlIG5vZGUgbGlieHNsdCIpKQorCQkqICAgIHJldHVybjsKKwkJKi8KKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0NPUFkseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCQkgInhzbHRDb3B5OiBub2RlICVzXG4iLCBub2RlLT5uYW1lKSk7CisjZW5kaWYKKwkJY29weSA9IHhzbHRTaGFsbG93Q29weUVsZW0oY3R4dCwgbm9kZSwgY3R4dC0+aW5zZXJ0LCAwKTsKKwkJY3R4dC0+aW5zZXJ0ID0gY29weTsKKwkJaWYgKGNvbXAtPnVzZSAhPSBOVUxMKSB7CisJCSAgICB4c2x0QXBwbHlBdHRyaWJ1dGVTZXQoY3R4dCwgbm9kZSwgaW5zdCwgY29tcC0+dXNlKTsKKwkJfQorCQlicmVhazsKKwkgICAgY2FzZSBYTUxfQVRUUklCVVRFX05PREU6IHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DT1BZLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkJICJ4c2x0Q29weTogYXR0cmlidXRlICVzXG4iLCBub2RlLT5uYW1lKSk7CisjZW5kaWYKKwkJLyoKKwkJKiBSRVZJU0lUOiBXZSBjb3VsZCBhbHNvIHJhaXNlIGFuIGVycm9yIGlmIHRoZSBwYXJlbnQgaXMgbm90CisJCSogYW4gZWxlbWVudCBub2RlLgorCQkqIE9QVElNSVpFIFRPRE86IENhbiB3ZSBzZXQgdGhlIHZhbHVlL2NoaWxkcmVuIG9mIHRoZQorCQkqIGF0dHJpYnV0ZSB3aXRob3V0IGFuIGludGVybWVkaWF0ZSBjb3B5IG9mIHRoZSBzdHJpbmcgdmFsdWU/CisJCSovCisJCXhzbHRTaGFsbG93Q29weUF0dHIoY3R4dCwgaW5zdCwgY3R4dC0+aW5zZXJ0LCAoeG1sQXR0clB0cikgbm9kZSk7CisJCWJyZWFrOworCSAgICB9CisJICAgIGNhc2UgWE1MX1BJX05PREU6CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwkJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQ09QWSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJCSAieHNsdENvcHk6IFBJICVzXG4iLCBub2RlLT5uYW1lKSk7CisjZW5kaWYKKwkJY29weSA9IHhtbE5ld0RvY1BJKGN0eHQtPmluc2VydC0+ZG9jLCBub2RlLT5uYW1lLAorCQkgICAgICAgICAgICAgICAgICAgbm9kZS0+Y29udGVudCk7CisJCWNvcHkgPSB4c2x0QWRkQ2hpbGQoY3R4dC0+aW5zZXJ0LCBjb3B5KTsKKwkJYnJlYWs7CisJICAgIGNhc2UgWE1MX0NPTU1FTlRfTk9ERToKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DT1BZLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkJICJ4c2x0Q29weTogY29tbWVudFxuIikpOworI2VuZGlmCisJCWNvcHkgPSB4bWxOZXdDb21tZW50KG5vZGUtPmNvbnRlbnQpOworCQljb3B5ID0geHNsdEFkZENoaWxkKGN0eHQtPmluc2VydCwgY29weSk7CisJCWJyZWFrOworCSAgICBjYXNlIFhNTF9OQU1FU1BBQ0VfREVDTDoKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DT1BZLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkJICJ4c2x0Q29weTogbmFtZXNwYWNlIGRlY2xhcmF0aW9uXG4iKSk7CisjZW5kaWYKKwkJeHNsdFNoYWxsb3dDb3B5TnNOb2RlKGN0eHQsIGluc3QsIGN0eHQtPmluc2VydCwgKHhtbE5zUHRyKW5vZGUpOworCQlicmVhazsKKwkgICAgZGVmYXVsdDoKKwkJYnJlYWs7CisKKwl9CisgICAgfQorCisgICAgc3dpdGNoIChub2RlLT50eXBlKSB7CisJY2FzZSBYTUxfRE9DVU1FTlRfTk9ERToKKwljYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CisJY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgorCSAgICB4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yKGN0eHQsIGN0eHQtPm5vZGUsIGluc3QtPmNoaWxkcmVuLAorCQlOVUxMKTsKKwkgICAgYnJlYWs7CisJZGVmYXVsdDoKKwkgICAgYnJlYWs7CisgICAgfQorICAgIGN0eHQtPmluc2VydCA9IG9sZEluc2VydDsKK30KKworLyoqCisgKiB4c2x0VGV4dDoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQG5vZGU6ICB0aGUgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUuCisgKiBAaW5zdDogIHRoZSB4c2x0IHRleHQgbm9kZQorICogQGNvbXA6ICBwcmVjb21wdXRlZCBpbmZvcm1hdGlvbgorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgdGV4dCBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCit2b2lkCit4c2x0VGV4dCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUgQVRUUklCVVRFX1VOVVNFRCwKKwkgICAgeG1sTm9kZVB0ciBpbnN0LCB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXAgQVRUUklCVVRFX1VOVVNFRCkgeworICAgIGlmICgoaW5zdC0+Y2hpbGRyZW4gIT0gTlVMTCkgJiYgKGNvbXAgIT0gTlVMTCkpIHsKKwl4bWxOb2RlUHRyIHRleHQgPSBpbnN0LT5jaGlsZHJlbjsKKwl4bWxOb2RlUHRyIGNvcHk7CisKKwl3aGlsZSAodGV4dCAhPSBOVUxMKSB7CisJICAgIGlmICgodGV4dC0+dHlwZSAhPSBYTUxfVEVYVF9OT0RFKSAmJgorCSAgICAgICAgICh0ZXh0LT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkJCSAieHNsOnRleHQgY29udGVudCBwcm9ibGVtXG4iKTsKKwkJYnJlYWs7CisJICAgIH0KKwkgICAgY29weSA9IHhtbE5ld0RvY1RleHQoY3R4dC0+b3V0cHV0LCB0ZXh0LT5jb250ZW50KTsKKwkgICAgaWYgKHRleHQtPnR5cGUgIT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAgIkRpc2FibGUgZXNjYXBpbmc6ICVzXG4iLCB0ZXh0LT5jb250ZW50KTsKKyNlbmRpZgorCQljb3B5LT5uYW1lID0geG1sU3RyaW5nVGV4dE5vZW5jOworCSAgICB9CisJICAgIGNvcHkgPSB4c2x0QWRkQ2hpbGQoY3R4dC0+aW5zZXJ0LCBjb3B5KTsKKwkgICAgdGV4dCA9IHRleHQtPm5leHQ7CisJfQorICAgIH0KK30KKworLyoqCisgKiB4c2x0RWxlbWVudDoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQG5vZGU6ICB0aGUgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUuCisgKiBAaW5zdDogIHRoZSB4c2x0IGVsZW1lbnQgbm9kZQorICogQGNhc3RlZENvbXA6ICBwcmVjb21wdXRlZCBpbmZvcm1hdGlvbgorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgZWxlbWVudCBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCit2b2lkCit4c2x0RWxlbWVudCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJICAgIHhtbE5vZGVQdHIgaW5zdCwgeHNsdFN0eWxlUHJlQ29tcFB0ciBjYXN0ZWRDb21wKSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbUVsZW1lbnRQdHIgY29tcCA9ICh4c2x0U3R5bGVJdGVtRWxlbWVudFB0cikgY2FzdGVkQ29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wID0gY2FzdGVkQ29tcDsKKyNlbmRpZgorICAgIHhtbENoYXIgKnByb3AgPSBOVUxMOworICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsICpwcmVmaXggPSBOVUxMLCAqbnNOYW1lID0gTlVMTDsKKyAgICB4bWxOb2RlUHRyIGNvcHk7CisgICAgeG1sTm9kZVB0ciBvbGRJbnNlcnQ7CisKKyAgICBpZiAoY3R4dC0+aW5zZXJ0ID09IE5VTEwpCisJcmV0dXJuOworCisgICAgLyoKKyAgICAqIEEgY29tcC0+aGFzX25hbWUgPT0gMCBpbmRpY2F0ZXMgdGhhdCB3ZSBuZWVkIHRvIHNraXAgdGhpcyBpbnN0cnVjdGlvbiwKKyAgICAqIHNpbmNlIGl0IHdhcyBldmFsdWF0ZWQgdG8gYmUgaW52YWxpZCBhbHJlYWR5IGR1cmluZyBjb21waWxhdGlvbi4KKyAgICAqLworICAgIGlmICghY29tcC0+aGFzX25hbWUpCisgICAgICAgIHJldHVybjsKKworICAgIC8qCisgICAgICogc3RhY2sgYW5kIHNhdmVzCisgICAgICovCisgICAgb2xkSW5zZXJ0ID0gY3R4dC0+aW5zZXJ0OworCisgICAgaWYgKGNvbXAtPm5hbWUgPT0gTlVMTCkgeworCS8qIFRPRE86IGZpeCBhdHRyIGFjcXVpc2l0aW9uIHdydCB0byB0aGUgWFNMVCBuYW1lc3BhY2UgKi8KKyAgICAgICAgcHJvcCA9IHhzbHRFdmFsQXR0clZhbHVlVGVtcGxhdGUoY3R4dCwgaW5zdCwKKwkgICAgKGNvbnN0IHhtbENoYXIgKikgIm5hbWUiLCBYU0xUX05BTUVTUEFDRSk7CisgICAgICAgIGlmIChwcm9wID09IE5VTEwpIHsKKyAgICAgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkieHNsOmVsZW1lbnQ6IFRoZSBhdHRyaWJ1dGUgJ25hbWUnIGlzIG1pc3NpbmcuXG4iKTsKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgIH0KKwlpZiAoeG1sVmFsaWRhdGVRTmFtZShwcm9wLCAwKSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkJInhzbDplbGVtZW50OiBUaGUgZWZmZWN0aXZlIG5hbWUgJyVzJyBpcyBub3QgYSAiCisJCSJ2YWxpZCBRTmFtZS5cbiIsIHByb3ApOworCSAgICAvKiB3ZSBmYWxsIHRocm91Z2ggdG8gY2F0Y2ggYW55IGZ1cnRoZXIgZXJyb3JzLCBpZiBwb3NzaWJsZSAqLworCX0KKwluYW1lID0geHNsdFNwbGl0UU5hbWUoY3R4dC0+ZGljdCwgcHJvcCwgJnByZWZpeCk7CisJeG1sRnJlZShwcm9wKTsKKwlpZiAoKHByZWZpeCAhPSBOVUxMKSAmJgorCSAgICAoIXhtbFN0cm5jYXNlY21wKHByZWZpeCwgKHhtbENoYXIgKikieG1sIiwgMykpKQorCXsKKwkgICAgLyoKKwkgICAgKiBUT0RPOiBTaG91bGQgd2UgcmVhbGx5IGRpc2FsbG93IGFuICJ4bWwiIHByZWZpeD8KKwkgICAgKi8KKwkgICAgZ290byBlcnJvcjsKKwl9CisgICAgfSBlbHNlIHsKKwkvKgorCSogVGhlICJuYW1lIiB2YWx1ZSB3YXMgc3RhdGljLgorCSovCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisJcHJlZml4ID0gY29tcC0+bnNQcmVmaXg7CisJbmFtZSA9IGNvbXAtPm5hbWU7CisjZWxzZQorCW5hbWUgPSB4c2x0U3BsaXRRTmFtZShjdHh0LT5kaWN0LCBjb21wLT5uYW1lLCAmcHJlZml4KTsKKyNlbmRpZgorICAgIH0KKworICAgIC8qCisgICAgICogQ3JlYXRlIHRoZSBuZXcgZWxlbWVudAorICAgICAqLworICAgIGlmIChjdHh0LT5vdXRwdXQtPmRpY3QgPT0gY3R4dC0+ZGljdCkgeworCWNvcHkgPSB4bWxOZXdEb2NOb2RlRWF0TmFtZShjdHh0LT5vdXRwdXQsIE5VTEwsICh4bWxDaGFyICopbmFtZSwgTlVMTCk7CisgICAgfSBlbHNlIHsKKwljb3B5ID0geG1sTmV3RG9jTm9kZShjdHh0LT5vdXRwdXQsIE5VTEwsICh4bWxDaGFyICopbmFtZSwgTlVMTCk7CisgICAgfQorICAgIGlmIChjb3B5ID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkgICAgInhzbDplbGVtZW50IDogY3JlYXRpb24gb2YgJXMgZmFpbGVkXG4iLCBuYW1lKTsKKwlyZXR1cm47CisgICAgfQorICAgIGNvcHkgPSB4c2x0QWRkQ2hpbGQoY3R4dC0+aW5zZXJ0LCBjb3B5KTsKKworICAgIC8qCisgICAgKiBOYW1lc3BhY2UKKyAgICAqIC0tLS0tLS0tLQorICAgICovCisgICAgaWYgKGNvbXAtPmhhc19ucykgeworCWlmIChjb21wLT5ucyAhPSBOVUxMKSB7CisJICAgIC8qCisJICAgICogTm8gQVZUOyBqdXN0IHBsYWluIHRleHQgZm9yIHRoZSBuYW1lc3BhY2UgbmFtZS4KKwkgICAgKi8KKwkgICAgaWYgKGNvbXAtPm5zWzBdICE9IDApCisJCW5zTmFtZSA9IGNvbXAtPm5zOworCX0gZWxzZSB7CisJICAgIHhtbENoYXIgKnRtcE5zTmFtZTsKKwkgICAgLyoKKwkgICAgKiBFdmFsIHRoZSBBVlQuCisJICAgICovCisJICAgIC8qIFRPRE86IGNoZWNrIGF0dHIgYWNxdWlzaXRpb24gd3J0IHRvIHRoZSBYU0xUIG5hbWVzcGFjZSAqLworCSAgICB0bXBOc05hbWUgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIGluc3QsCisJCShjb25zdCB4bWxDaGFyICopICJuYW1lc3BhY2UiLCBYU0xUX05BTUVTUEFDRSk7CisJICAgIC8qCisJICAgICogU1BFQyBYU0xUIDEuMDoKKwkgICAgKiAgIklmIHRoZSBzdHJpbmcgaXMgZW1wdHksIHRoZW4gdGhlIGV4cGFuZGVkLW5hbWUgb2YgdGhlCisJICAgICogIGF0dHJpYnV0ZSBoYXMgYSBudWxsIG5hbWVzcGFjZSBVUkkuIgorCSAgICAqLworCSAgICBpZiAoKHRtcE5zTmFtZSAhPSBOVUxMKSAmJiAodG1wTnNOYW1lWzBdICE9IDApKQorCQluc05hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIEJBRF9DQVNUIHRtcE5zTmFtZSwgLTEpOworCSAgICB4bWxGcmVlKHRtcE5zTmFtZSk7CisJfTsKKyAgICB9IGVsc2UgeworCXhtbE5zUHRyIG5zOworCS8qCisJKiBTUEVDIFhTTFQgMS4wOgorCSogICJJZiB0aGUgbmFtZXNwYWNlIGF0dHJpYnV0ZSBpcyBub3QgcHJlc2VudCwgdGhlbiB0aGUgUU5hbWUgaXMKKwkqICBleHBhbmRlZCBpbnRvIGFuIGV4cGFuZGVkLW5hbWUgdXNpbmcgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMKKwkqICBpbiBlZmZlY3QgZm9yIHRoZSB4c2w6ZWxlbWVudCBlbGVtZW50LCBpbmNsdWRpbmcgYW55IGRlZmF1bHQKKwkqICBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCisJKi8KKwlucyA9IHhtbFNlYXJjaE5zKGluc3QtPmRvYywgaW5zdCwgcHJlZml4KTsKKwlpZiAobnMgPT0gTlVMTCkgeworCSAgICAvKgorCSAgICAqIFRPRE86IENoZWNrIHRoaXMgaW4gdGhlIGNvbXBpbGF0aW9uIGxheWVyIGluIGNhc2UgaXQncyBhCisJICAgICogc3RhdGljIHZhbHVlLgorCSAgICAqLworCSAgICBpZiAocHJlZml4ICE9IE5VTEwpIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCSAgICAieHNsOmVsZW1lbnQ6IFRoZSBRTmFtZSAnJXM6JXMnIGhhcyBubyAiCisJCSAgICAibmFtZXNwYWNlIGJpbmRpbmcgaW4gc2NvcGUgaW4gdGhlIHN0eWxlc2hlZXQ7ICIKKwkJICAgICJ0aGlzIGlzIGFuIGVycm9yLCBzaW5jZSB0aGUgbmFtZXNwYWNlIHdhcyBub3QgIgorCQkgICAgInNwZWNpZmllZCBieSB0aGUgaW5zdHJ1Y3Rpb24gaXRzZWxmLlxuIiwgcHJlZml4LCBuYW1lKTsKKwkgICAgfQorCX0gZWxzZQorCSAgICBuc05hbWUgPSBucy0+aHJlZjsKKyAgICB9CisgICAgLyoKKyAgICAqIEZpbmQvY3JlYXRlIGEgbWF0Y2hpbmcgbnMtZGVjbCBpbiB0aGUgcmVzdWx0IHRyZWUuCisgICAgKi8KKyAgICBpZiAobnNOYW1lICE9IE5VTEwpIHsKKwljb3B5LT5ucyA9IHhzbHRHZXRTcGVjaWFsTmFtZXNwYWNlKGN0eHQsIGluc3QsIG5zTmFtZSwgcHJlZml4LCBjb3B5KTsKKyAgICB9IGVsc2UgaWYgKChjb3B5LT5wYXJlbnQgIT0gTlVMTCkgJiYKKwkoY29weS0+cGFyZW50LT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpICYmCisJKGNvcHktPnBhcmVudC0+bnMgIT0gTlVMTCkpCisgICAgeworCS8qCisJKiAiVW5kZWNsYXJlIiB0aGUgZGVmYXVsdCBuYW1lc3BhY2UuCisJKi8KKwl4c2x0R2V0U3BlY2lhbE5hbWVzcGFjZShjdHh0LCBpbnN0LCBOVUxMLCBOVUxMLCBjb3B5KTsKKyAgICB9CisKKyAgICBjdHh0LT5pbnNlcnQgPSBjb3B5OworCisgICAgaWYgKGNvbXAtPmhhc191c2UpIHsKKwlpZiAoY29tcC0+dXNlICE9IE5VTEwpIHsKKwkgICAgeHNsdEFwcGx5QXR0cmlidXRlU2V0KGN0eHQsIG5vZGUsIGluc3QsIGNvbXAtPnVzZSk7CisJfSBlbHNlIHsKKwkgICAgeG1sQ2hhciAqYXR0clNldHMgPSBOVUxMOworCSAgICAvKgorCSAgICAqIEJVRyBUT0RPOiB1c2UtYXR0cmlidXRlLXNldHMgaXMgbm90IGEgdmFsdWUgdGVtcGxhdGUuCisJICAgICogIHVzZS1hdHRyaWJ1dGUtc2V0cyA9IHFuYW1lcworCSAgICAqLworCSAgICBhdHRyU2V0cyA9IHhzbHRFdmFsQXR0clZhbHVlVGVtcGxhdGUoY3R4dCwgaW5zdCwKKwkJKGNvbnN0IHhtbENoYXIgKikidXNlLWF0dHJpYnV0ZS1zZXRzIiwgTlVMTCk7CisJICAgIGlmIChhdHRyU2V0cyAhPSBOVUxMKSB7CisJCXhzbHRBcHBseUF0dHJpYnV0ZVNldChjdHh0LCBub2RlLCBpbnN0LCBhdHRyU2V0cyk7CisJCXhtbEZyZWUoYXR0clNldHMpOworCSAgICB9CisJfQorICAgIH0KKyAgICAvKgorICAgICogSW5zdGFudGlhdGUgdGhlIHNlcXVlbmNlIGNvbnN0cnVjdG9yLgorICAgICovCisgICAgaWYgKGluc3QtPmNoaWxkcmVuICE9IE5VTEwpCisJeHNsdEFwcGx5U2VxdWVuY2VDb25zdHJ1Y3RvcihjdHh0LCBjdHh0LT5ub2RlLCBpbnN0LT5jaGlsZHJlbiwKKwkgICAgTlVMTCk7CisKK2Vycm9yOgorICAgIGN0eHQtPmluc2VydCA9IG9sZEluc2VydDsKKyAgICByZXR1cm47Cit9CisKKworLyoqCisgKiB4c2x0Q29tbWVudDoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQG5vZGU6ICB0aGUgbm9kZSBpbiB0aGUgc291cmNlIHRyZWUuCisgKiBAaW5zdDogIHRoZSB4c2x0IGNvbW1lbnQgbm9kZQorICogQGNvbXA6ICBwcmVjb21wdXRlZCBpbmZvcm1hdGlvbgorICoKKyAqIFByb2Nlc3MgdGhlIHhzbHQgY29tbWVudCBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCit2b2lkCit4c2x0Q29tbWVudCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJICAgICAgICAgICB4bWxOb2RlUHRyIGluc3QsIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCBBVFRSSUJVVEVfVU5VU0VEKSB7CisgICAgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOworICAgIHhtbE5vZGVQdHIgY29tbWVudE5vZGU7CisgICAgaW50IGxlbjsKKworICAgIHZhbHVlID0geHNsdEV2YWxUZW1wbGF0ZVN0cmluZyhjdHh0LCBub2RlLCBpbnN0KTsKKyAgICAvKiBUT0RPOiB1c2Ugb3IgZ2VuZXJhdGUgdGhlIGNvbXBpbGVkIGZvcm0gKi8KKyAgICBsZW4gPSB4bWxTdHJsZW4odmFsdWUpOworICAgIGlmIChsZW4gPiAwKSB7CisgICAgICAgIGlmICgodmFsdWVbbGVuLTFdID09ICctJykgfHwKKwkgICAgKHhtbFN0cnN0cih2YWx1ZSwgQkFEX0NBU1QgIi0tIikpKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkgICAgInhzbDpjb21tZW50IDogJy0tJyBvciBlbmRpbmcgJy0nIG5vdCBhbGxvd2VkIGluIGNvbW1lbnRcbiIpOworCSAgICAvKiBmYWxsIHRocm91Z2ggdG8gdHJ5IHRvIGNhdGNoIGZ1cnRoZXIgZXJyb3JzICovCisJfQorICAgIH0KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQ09NTUVOVCx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgInhzbHRDb21tZW50OiBlbXB0eVxuIikpOworICAgIH0gZWxzZSB7CisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQ09NTUVOVCx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgInhzbHRDb21tZW50OiBjb250ZW50ICVzXG4iLCB2YWx1ZSkpOworICAgIH0KKyNlbmRpZgorCisgICAgY29tbWVudE5vZGUgPSB4bWxOZXdDb21tZW50KHZhbHVlKTsKKyAgICBjb21tZW50Tm9kZSA9IHhzbHRBZGRDaGlsZChjdHh0LT5pbnNlcnQsIGNvbW1lbnROb2RlKTsKKworICAgIGlmICh2YWx1ZSAhPSBOVUxMKQorCXhtbEZyZWUodmFsdWUpOworfQorCisvKioKKyAqIHhzbHRQcm9jZXNzaW5nSW5zdHJ1Y3Rpb246CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBub2RlOiAgdGhlIG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlLgorICogQGluc3Q6ICB0aGUgeHNsdCBwcm9jZXNzaW5nLWluc3RydWN0aW9uIG5vZGUKKyAqIEBjYXN0ZWRDb21wOiAgcHJlY29tcHV0ZWQgaW5mb3JtYXRpb24KKyAqCisgKiBQcm9jZXNzIHRoZSB4c2x0IHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24gbm9kZSBvbiB0aGUgc291cmNlIG5vZGUKKyAqLwordm9pZAoreHNsdFByb2Nlc3NpbmdJbnN0cnVjdGlvbih4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJICAgICAgICAgICB4bWxOb2RlUHRyIGluc3QsIHhzbHRTdHlsZVByZUNvbXBQdHIgY2FzdGVkQ29tcCkgeworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1QSVB0ciBjb21wID0gKHhzbHRTdHlsZUl0ZW1QSVB0cikgY2FzdGVkQ29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wID0gY2FzdGVkQ29tcDsKKyNlbmRpZgorICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CisgICAgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOworICAgIHhtbE5vZGVQdHIgcGk7CisKKworICAgIGlmIChjdHh0LT5pbnNlcnQgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaWYgKGNvbXAtPmhhc19uYW1lID09IDApCisJcmV0dXJuOworICAgIGlmIChjb21wLT5uYW1lID09IE5VTEwpIHsKKwluYW1lID0geHNsdEV2YWxBdHRyVmFsdWVUZW1wbGF0ZShjdHh0LCBpbnN0LAorCQkJICAgIChjb25zdCB4bWxDaGFyICopIm5hbWUiLCBOVUxMKTsKKwlpZiAobmFtZSA9PSBOVUxMKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkgInhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uIDogbmFtZSBpcyBtaXNzaW5nXG4iKTsKKwkgICAgZ290byBlcnJvcjsKKwl9CisgICAgfSBlbHNlIHsKKwluYW1lID0gY29tcC0+bmFtZTsKKyAgICB9CisgICAgLyogVE9ETzogY2hlY2sgdGhhdCBpdCdzIGJvdGggYW4gYW4gTkNOYW1lIGFuZCBhIFBJVGFyZ2V0LiAqLworCisKKyAgICB2YWx1ZSA9IHhzbHRFdmFsVGVtcGxhdGVTdHJpbmcoY3R4dCwgbm9kZSwgaW5zdCk7CisgICAgaWYgKHhtbFN0cnN0cih2YWx1ZSwgQkFEX0NBU1QgIj8+IikgIT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAgInhzbDpwcm9jZXNzaW5nLWluc3RydWN0aW9uOiAnPz4nIG5vdCBhbGxvd2VkIHdpdGhpbiBQSSBjb250ZW50XG4iKTsKKwlnb3RvIGVycm9yOworICAgIH0KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUEkseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0UHJvY2Vzc2luZ0luc3RydWN0aW9uOiAlcyBlbXB0eVxuIiwgbmFtZSkpOworICAgIH0gZWxzZSB7CisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfUEkseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0UHJvY2Vzc2luZ0luc3RydWN0aW9uOiAlcyBjb250ZW50ICVzXG4iLCBuYW1lLCB2YWx1ZSkpOworICAgIH0KKyNlbmRpZgorCisgICAgcGkgPSB4bWxOZXdEb2NQSShjdHh0LT5pbnNlcnQtPmRvYywgbmFtZSwgdmFsdWUpOworICAgIHBpID0geHNsdEFkZENoaWxkKGN0eHQtPmluc2VydCwgcGkpOworCitlcnJvcjoKKyAgICBpZiAoKG5hbWUgIT0gTlVMTCkgJiYgKG5hbWUgIT0gY29tcC0+bmFtZSkpCisgICAgICAgIHhtbEZyZWUoKHhtbENoYXIgKikgbmFtZSk7CisgICAgaWYgKHZhbHVlICE9IE5VTEwpCisJeG1sRnJlZSh2YWx1ZSk7Cit9CisKKy8qKgorICogeHNsdENvcHlPZjoKKyAqIEBjdHh0OiAgYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAbm9kZTogIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlCisgKiBAaW5zdDogIHRoZSBlbGVtZW50IG5vZGUgb2YgdGhlIFhTTFQgY29weS1vZiBpbnN0cnVjdGlvbgorICogQGNhc3RlZENvbXA6ICBwcmVjb21wdXRlZCBpbmZvcm1hdGlvbiBvZiB0aGUgWFNMVCBjb3B5LW9mIGluc3RydWN0aW9uCisgKgorICogUHJvY2VzcyB0aGUgWFNMVCBjb3B5LW9mIGluc3RydWN0aW9uLgorICovCit2b2lkCit4c2x0Q29weU9mKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKKwkgICAgICAgICAgIHhtbE5vZGVQdHIgaW5zdCwgeHNsdFN0eWxlUHJlQ29tcFB0ciBjYXN0ZWRDb21wKSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbUNvcHlPZlB0ciBjb21wID0gKHhzbHRTdHlsZUl0ZW1Db3B5T2ZQdHIpIGNhc3RlZENvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCA9IGNhc3RlZENvbXA7CisjZW5kaWYKKyAgICB4bWxYUGF0aE9iamVjdFB0ciByZXMgPSBOVUxMOworICAgIHhtbE5vZGVTZXRQdHIgbGlzdCA9IE5VTEw7CisgICAgaW50IGk7CisgICAgeG1sRG9jUHRyIG9sZFhQQ29udGV4dERvYzsKKyAgICB4bWxOc1B0ciAqb2xkWFBOYW1lc3BhY2VzOworICAgIHhtbE5vZGVQdHIgb2xkWFBDb250ZXh0Tm9kZTsKKyAgICBpbnQgb2xkWFBQcm94aW1pdHlQb3NpdGlvbiwgb2xkWFBDb250ZXh0U2l6ZSwgb2xkWFBOc05yOworICAgIHhtbFhQYXRoQ29udGV4dFB0ciB4cGN0eHQ7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkpCisJcmV0dXJuOworICAgIGlmICgoY29tcCA9PSBOVUxMKSB8fCAoY29tcC0+c2VsZWN0ID09IE5VTEwpIHx8IChjb21wLT5jb21wID09IE5VTEwpKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJICAgICAieHNsOmNvcHktb2YgOiBjb21waWxhdGlvbiBmYWlsZWRcbiIpOworCXJldHVybjsKKyAgICB9CisKKyAgICAgLyoKKyAgICAqIFNQRUMgWFNMVCAxLjA6CisgICAgKiAgIlRoZSB4c2w6Y29weS1vZiBlbGVtZW50IGNhbiBiZSB1c2VkIHRvIGluc2VydCBhIHJlc3VsdCB0cmVlCisgICAgKiAgZnJhZ21lbnQgaW50byB0aGUgcmVzdWx0IHRyZWUsIHdpdGhvdXQgZmlyc3QgY29udmVydGluZyBpdCB0bworICAgICogIGEgc3RyaW5nIGFzIHhzbDp2YWx1ZS1vZiBkb2VzIChzZWUgWzcuNi4xIEdlbmVyYXRpbmcgVGV4dCB3aXRoCisgICAgKiAgeHNsOnZhbHVlLW9mXSkuIFRoZSByZXF1aXJlZCBzZWxlY3QgYXR0cmlidXRlIGNvbnRhaW5zIGFuCisgICAgKiAgZXhwcmVzc2lvbi4gV2hlbiB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgdGhlIGV4cHJlc3Npb24gaXMgYQorICAgICogIHJlc3VsdCB0cmVlIGZyYWdtZW50LCB0aGUgY29tcGxldGUgZnJhZ21lbnQgaXMgY29waWVkIGludG8gdGhlCisgICAgKiAgcmVzdWx0IHRyZWUuIFdoZW4gdGhlIHJlc3VsdCBpcyBhIG5vZGUtc2V0LCBhbGwgdGhlIG5vZGVzIGluIHRoZQorICAgICogIHNldCBhcmUgY29waWVkIGluIGRvY3VtZW50IG9yZGVyIGludG8gdGhlIHJlc3VsdCB0cmVlOyBjb3B5aW5nCisgICAgKiAgYW4gZWxlbWVudCBub2RlIGNvcGllcyB0aGUgYXR0cmlidXRlIG5vZGVzLCBuYW1lc3BhY2Ugbm9kZXMgYW5kCisgICAgKiAgY2hpbGRyZW4gb2YgdGhlIGVsZW1lbnQgbm9kZSBhcyB3ZWxsIGFzIHRoZSBlbGVtZW50IG5vZGUgaXRzZWxmOworICAgICogIGEgcm9vdCBub2RlIGlzIGNvcGllZCBieSBjb3B5aW5nIGl0cyBjaGlsZHJlbi4gV2hlbiB0aGUgcmVzdWx0CisgICAgKiAgaXMgbmVpdGhlciBhIG5vZGUtc2V0IG5vciBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LCB0aGUgcmVzdWx0IGlzCisgICAgKiAgY29udmVydGVkIHRvIGEgc3RyaW5nIGFuZCB0aGVuIGluc2VydGVkIGludG8gdGhlIHJlc3VsdCB0cmVlLAorICAgICogIGFzIHdpdGggeHNsOnZhbHVlLW9mLgorICAgICovCisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0NPUFlfT0YseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgInhzbHRDb3B5T2Y6IHNlbGVjdCAlc1xuIiwgY29tcC0+c2VsZWN0KSk7CisjZW5kaWYKKworICAgIC8qCisgICAgKiBFdmFsdWF0ZSB0aGUgInNlbGVjdCIgZXhwcmVzc2lvbi4KKyAgICAqLworICAgIHhwY3R4dCA9IGN0eHQtPnhwYXRoQ3R4dDsKKyAgICBvbGRYUENvbnRleHREb2MgPSB4cGN0eHQtPmRvYzsKKyAgICBvbGRYUENvbnRleHROb2RlID0geHBjdHh0LT5ub2RlOworICAgIG9sZFhQUHJveGltaXR5UG9zaXRpb24gPSB4cGN0eHQtPnByb3hpbWl0eVBvc2l0aW9uOworICAgIG9sZFhQQ29udGV4dFNpemUgPSB4cGN0eHQtPmNvbnRleHRTaXplOworICAgIG9sZFhQTnNOciA9IHhwY3R4dC0+bnNOcjsKKyAgICBvbGRYUE5hbWVzcGFjZXMgPSB4cGN0eHQtPm5hbWVzcGFjZXM7CisKKyAgICB4cGN0eHQtPm5vZGUgPSBub2RlOworICAgIGlmIChjb21wICE9IE5VTEwpIHsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCWlmIChjb21wLT5pblNjb3BlTnMgIT0gTlVMTCkgeworCSAgICB4cGN0eHQtPm5hbWVzcGFjZXMgPSBjb21wLT5pblNjb3BlTnMtPmxpc3Q7CisJICAgIHhwY3R4dC0+bnNOciA9IGNvbXAtPmluU2NvcGVOcy0+eHBhdGhOdW1iZXI7CisJfSBlbHNlIHsKKwkgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwkgICAgeHBjdHh0LT5uc05yID0gMDsKKwl9CisjZWxzZQorCXhwY3R4dC0+bmFtZXNwYWNlcyA9IGNvbXAtPm5zTGlzdDsKKwl4cGN0eHQtPm5zTnIgPSBjb21wLT5uc05yOworI2VuZGlmCisgICAgfSBlbHNlIHsKKwl4cGN0eHQtPm5hbWVzcGFjZXMgPSBOVUxMOworCXhwY3R4dC0+bnNOciA9IDA7CisgICAgfQorCisgICAgcmVzID0geG1sWFBhdGhDb21waWxlZEV2YWwoY29tcC0+Y29tcCwgeHBjdHh0KTsKKworICAgIHhwY3R4dC0+ZG9jID0gb2xkWFBDb250ZXh0RG9jOworICAgIHhwY3R4dC0+bm9kZSA9IG9sZFhQQ29udGV4dE5vZGU7CisgICAgeHBjdHh0LT5jb250ZXh0U2l6ZSA9IG9sZFhQQ29udGV4dFNpemU7CisgICAgeHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IG9sZFhQUHJveGltaXR5UG9zaXRpb247CisgICAgeHBjdHh0LT5uc05yID0gb2xkWFBOc05yOworICAgIHhwY3R4dC0+bmFtZXNwYWNlcyA9IG9sZFhQTmFtZXNwYWNlczsKKworICAgIGlmIChyZXMgIT0gTlVMTCkgeworCWlmIChyZXMtPnR5cGUgPT0gWFBBVEhfTk9ERVNFVCkgeworCSAgICAvKgorCSAgICAqIE5vZGUtc2V0CisJICAgICogLS0tLS0tLS0KKwkgICAgKi8KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCSAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DT1BZX09GLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAieHNsdENvcHlPZjogcmVzdWx0IGlzIGEgbm9kZSBzZXRcbiIpKTsKKyNlbmRpZgorCSAgICBsaXN0ID0gcmVzLT5ub2Rlc2V0dmFsOworCSAgICBpZiAobGlzdCAhPSBOVUxMKSB7CisJCXhtbE5vZGVQdHIgY3VyOworCQkvKgorCQkqIFRoZSBsaXN0IGlzIGFscmVhZHkgc29ydGVkIGluIGRvY3VtZW50IG9yZGVyIGJ5IFhQYXRoLgorCQkqIEFwcGVuZCBldmVyeXRoaW5nIGluIHRoaXMgb3JkZXIgdW5kZXIgY3R4dC0+aW5zZXJ0LgorCQkqLworCQlmb3IgKGkgPSAwO2kgPCBsaXN0LT5ub2RlTnI7aSsrKSB7CisJCSAgICBjdXIgPSBsaXN0LT5ub2RlVGFiW2ldOworCQkgICAgaWYgKGN1ciA9PSBOVUxMKQorCQkJY29udGludWU7CisJCSAgICBpZiAoKGN1ci0+dHlwZSA9PSBYTUxfRE9DVU1FTlRfTk9ERSkgfHwKKwkJCShjdXItPnR5cGUgPT0gWE1MX0hUTUxfRE9DVU1FTlRfTk9ERSkpCisJCSAgICB7CisJCQl4c2x0Q29weVRyZWVMaXN0KGN0eHQsIGluc3QsCisJCQkgICAgY3VyLT5jaGlsZHJlbiwgY3R4dC0+aW5zZXJ0LCAwLCAwKTsKKwkJICAgIH0gZWxzZSBpZiAoY3VyLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgeworCQkJeHNsdFNoYWxsb3dDb3B5QXR0cihjdHh0LCBpbnN0LAorCQkJICAgIGN0eHQtPmluc2VydCwgKHhtbEF0dHJQdHIpIGN1cik7CisJCSAgICB9IGVsc2UgeworCQkJeHNsdENvcHlUcmVlSW50ZXJuYWwoY3R4dCwgaW5zdCwKKwkJCSAgICBjdXIsIGN0eHQtPmluc2VydCwgMCwgMCk7CisJCSAgICB9CisJCX0KKwkgICAgfQorCX0gZWxzZSBpZiAocmVzLT50eXBlID09IFhQQVRIX1hTTFRfVFJFRSkgeworCSAgICAvKgorCSAgICAqIFJlc3VsdCB0cmVlIGZyYWdtZW50CisJICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwkgICAgKiBFLmcuIHZpYSA8eHNsOnZhcmlhYmxlIC4uLj48Zm9vLz48L3hzbDp2YXJpYWJsZT4KKwkgICAgKiBOb3RlIHRoYXQgdGhlIHJvb3Qgbm9kZSBvZiBzdWNoIHRyZWVzIGlzIGFuIHhtbERvY1B0ciBpbiBMaWJ4c2x0LgorCSAgICAqLworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0NPUFlfT0YseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICJ4c2x0Q29weU9mOiByZXN1bHQgaXMgYSByZXN1bHQgdHJlZSBmcmFnbWVudFxuIikpOworI2VuZGlmCisJICAgIGxpc3QgPSByZXMtPm5vZGVzZXR2YWw7CisJICAgIGlmICgobGlzdCAhPSBOVUxMKSAmJiAobGlzdC0+bm9kZVRhYiAhPSBOVUxMKSAmJgorCQkobGlzdC0+bm9kZVRhYlswXSAhPSBOVUxMKSAmJgorCQkoSVNfWFNMVF9SRUFMX05PREUobGlzdC0+bm9kZVRhYlswXSkpKQorCSAgICB7CisJCXhzbHRDb3B5VHJlZUxpc3QoY3R4dCwgaW5zdCwKKwkJICAgIGxpc3QtPm5vZGVUYWJbMF0tPmNoaWxkcmVuLCBjdHh0LT5pbnNlcnQsIDAsIDApOworCSAgICB9CisJfSBlbHNlIHsKKwkgICAgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOworCSAgICAvKgorCSAgICAqIENvbnZlcnQgdG8gYSBzdHJpbmcuCisJICAgICovCisJICAgIHZhbHVlID0geG1sWFBhdGhDYXN0VG9TdHJpbmcocmVzKTsKKwkgICAgaWYgKHZhbHVlID09IE5VTEwpIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCSAgICAiSW50ZXJuYWwgZXJyb3IgaW4geHNsdENvcHlPZigpOiAiCisJCSAgICAiZmFpbGVkIHRvIGNhc3QgYW4gWFBhdGggb2JqZWN0IHRvIHN0cmluZy5cbiIpOworCQljdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKHZhbHVlWzBdICE9IDApIHsKKwkJICAgIC8qCisJCSAgICAqIEFwcGVuZCBjb250ZW50IGFzIHRleHQgbm9kZS4KKwkJICAgICovCisJCSAgICB4c2x0Q29weVRleHRTdHJpbmcoY3R4dCwgY3R4dC0+aW5zZXJ0LCB2YWx1ZSwgMCk7CisJCX0KKwkJeG1sRnJlZSh2YWx1ZSk7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DT1BZX09GLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAieHNsdENvcHlPZjogcmVzdWx0ICVzXG4iLCByZXMtPnN0cmluZ3ZhbCkpOworI2VuZGlmCisJICAgIH0KKwl9CisgICAgfSBlbHNlIHsKKwljdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKyAgICB9CisKKyAgICBpZiAocmVzICE9IE5VTEwpCisJeG1sWFBhdGhGcmVlT2JqZWN0KHJlcyk7Cit9CisKKy8qKgorICogeHNsdFZhbHVlT2Y6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBub2RlOiAgdGhlIG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlLgorICogQGluc3Q6ICB0aGUgeHNsdCB2YWx1ZS1vZiBub2RlCisgKiBAY2FzdGVkQ29tcDogIHByZWNvbXB1dGVkIGluZm9ybWF0aW9uCisgKgorICogUHJvY2VzcyB0aGUgeHNsdCB2YWx1ZS1vZiBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCit2b2lkCit4c2x0VmFsdWVPZih4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJICAgICAgICAgICB4bWxOb2RlUHRyIGluc3QsIHhzbHRTdHlsZVByZUNvbXBQdHIgY2FzdGVkQ29tcCkKK3sKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtVmFsdWVPZlB0ciBjb21wID0gKHhzbHRTdHlsZUl0ZW1WYWx1ZU9mUHRyKSBjYXN0ZWRDb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXAgPSBjYXN0ZWRDb21wOworI2VuZGlmCisgICAgeG1sWFBhdGhPYmplY3RQdHIgcmVzID0gTlVMTDsKKyAgICB4bWxOb2RlUHRyIGNvcHkgPSBOVUxMOworICAgIHhtbENoYXIgKnZhbHVlID0gTlVMTDsKKyAgICB4bWxEb2NQdHIgb2xkWFBDb250ZXh0RG9jOworICAgIHhtbE5zUHRyICpvbGRYUE5hbWVzcGFjZXM7CisgICAgeG1sTm9kZVB0ciBvbGRYUENvbnRleHROb2RlOworICAgIGludCBvbGRYUFByb3hpbWl0eVBvc2l0aW9uLCBvbGRYUENvbnRleHRTaXplLCBvbGRYUE5zTnI7CisgICAgeG1sWFBhdGhDb250ZXh0UHRyIHhwY3R4dDsKKworICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICBpZiAoKGNvbXAgPT0gTlVMTCkgfHwgKGNvbXAtPnNlbGVjdCA9PSBOVUxMKSB8fCAoY29tcC0+Y29tcCA9PSBOVUxMKSkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAiSW50ZXJuYWwgZXJyb3IgaW4geHNsdFZhbHVlT2YoKTogIgorCSAgICAiVGhlIFhTTFQgJ3ZhbHVlLW9mJyBpbnN0cnVjdGlvbiB3YXMgbm90IGNvbXBpbGVkLlxuIik7CisJcmV0dXJuOworICAgIH0KKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfVkFMVUVfT0YseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgInhzbHRWYWx1ZU9mOiBzZWxlY3QgJXNcbiIsIGNvbXAtPnNlbGVjdCkpOworI2VuZGlmCisKKyAgICB4cGN0eHQgPSBjdHh0LT54cGF0aEN0eHQ7CisgICAgb2xkWFBDb250ZXh0RG9jID0geHBjdHh0LT5kb2M7CisgICAgb2xkWFBDb250ZXh0Tm9kZSA9IHhwY3R4dC0+bm9kZTsKKyAgICBvbGRYUFByb3hpbWl0eVBvc2l0aW9uID0geHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbjsKKyAgICBvbGRYUENvbnRleHRTaXplID0geHBjdHh0LT5jb250ZXh0U2l6ZTsKKyAgICBvbGRYUE5zTnIgPSB4cGN0eHQtPm5zTnI7CisgICAgb2xkWFBOYW1lc3BhY2VzID0geHBjdHh0LT5uYW1lc3BhY2VzOworCisgICAgeHBjdHh0LT5ub2RlID0gbm9kZTsKKyAgICBpZiAoY29tcCAhPSBOVUxMKSB7CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwlpZiAoY29tcC0+aW5TY29wZU5zICE9IE5VTEwpIHsKKwkgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gY29tcC0+aW5TY29wZU5zLT5saXN0OworCSAgICB4cGN0eHQtPm5zTnIgPSBjb21wLT5pblNjb3BlTnMtPnhwYXRoTnVtYmVyOworCX0gZWxzZSB7CisJICAgIHhwY3R4dC0+bmFtZXNwYWNlcyA9IE5VTEw7CisJICAgIHhwY3R4dC0+bnNOciA9IDA7CisJfQorI2Vsc2UKKwl4cGN0eHQtPm5hbWVzcGFjZXMgPSBjb21wLT5uc0xpc3Q7CisJeHBjdHh0LT5uc05yID0gY29tcC0+bnNOcjsKKyNlbmRpZgorICAgIH0gZWxzZSB7CisJeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwl4cGN0eHQtPm5zTnIgPSAwOworICAgIH0KKworICAgIHJlcyA9IHhtbFhQYXRoQ29tcGlsZWRFdmFsKGNvbXAtPmNvbXAsIHhwY3R4dCk7CisKKyAgICB4cGN0eHQtPmRvYyA9IG9sZFhQQ29udGV4dERvYzsKKyAgICB4cGN0eHQtPm5vZGUgPSBvbGRYUENvbnRleHROb2RlOworICAgIHhwY3R4dC0+Y29udGV4dFNpemUgPSBvbGRYUENvbnRleHRTaXplOworICAgIHhwY3R4dC0+cHJveGltaXR5UG9zaXRpb24gPSBvbGRYUFByb3hpbWl0eVBvc2l0aW9uOworICAgIHhwY3R4dC0+bnNOciA9IG9sZFhQTnNOcjsKKyAgICB4cGN0eHQtPm5hbWVzcGFjZXMgPSBvbGRYUE5hbWVzcGFjZXM7CisKKyAgICAvKgorICAgICogQ2FzdCB0aGUgWFBhdGggb2JqZWN0IHRvIHN0cmluZy4KKyAgICAqLworICAgIGlmIChyZXMgIT0gTlVMTCkgeworCXZhbHVlID0geG1sWFBhdGhDYXN0VG9TdHJpbmcocmVzKTsKKwlpZiAodmFsdWUgPT0gTlVMTCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkJIkludGVybmFsIGVycm9yIGluIHhzbHRWYWx1ZU9mKCk6ICIKKwkJImZhaWxlZCB0byBjYXN0IGFuIFhQYXRoIG9iamVjdCB0byBzdHJpbmcuXG4iKTsKKwkgICAgY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisJICAgIGdvdG8gZXJyb3I7CisJfQorCWlmICh2YWx1ZVswXSAhPSAwKSB7CisJICAgIGNvcHkgPSB4c2x0Q29weVRleHRTdHJpbmcoY3R4dCwKKwkJY3R4dC0+aW5zZXJ0LCB2YWx1ZSwgY29tcC0+bm9lc2NhcGUpOworCX0KKyAgICB9IGVsc2UgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAiWFBhdGggZXZhbHVhdGlvbiByZXR1cm5lZCBubyByZXN1bHQuXG4iKTsKKwljdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwlnb3RvIGVycm9yOworICAgIH0KKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgaWYgKHZhbHVlKSB7CisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfVkFMVUVfT0YseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0VmFsdWVPZjogcmVzdWx0ICclcydcbiIsIHZhbHVlKSk7CisgICAgfQorI2VuZGlmCisKK2Vycm9yOgorICAgIGlmICh2YWx1ZSAhPSBOVUxMKQorCXhtbEZyZWUodmFsdWUpOworICAgIGlmIChyZXMgIT0gTlVMTCkKKwl4bWxYUGF0aEZyZWVPYmplY3QocmVzKTsKK30KKworLyoqCisgKiB4c2x0TnVtYmVyOgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAbm9kZTogIHRoZSBub2RlIGluIHRoZSBzb3VyY2UgdHJlZS4KKyAqIEBpbnN0OiAgdGhlIHhzbHQgbnVtYmVyIG5vZGUKKyAqIEBjYXN0ZWRDb21wOiAgcHJlY29tcHV0ZWQgaW5mb3JtYXRpb24KKyAqCisgKiBQcm9jZXNzIHRoZSB4c2x0IG51bWJlciBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCit2b2lkCit4c2x0TnVtYmVyKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKKwkgICB4bWxOb2RlUHRyIGluc3QsIHhzbHRTdHlsZVByZUNvbXBQdHIgY2FzdGVkQ29tcCkKK3sKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtTnVtYmVyUHRyIGNvbXAgPSAoeHNsdFN0eWxlSXRlbU51bWJlclB0cikgY2FzdGVkQ29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wID0gY2FzdGVkQ29tcDsKKyNlbmRpZgorICAgIGlmIChjb21wID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkgICAgICJ4c2w6bnVtYmVyIDogY29tcGlsYXRpb24gZmFpbGVkXG4iKTsKKwlyZXR1cm47CisgICAgfQorCisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpIHx8IChjb21wID09IE5VTEwpKQorCXJldHVybjsKKworICAgIGNvbXAtPm51bWRhdGEuZG9jID0gaW5zdC0+ZG9jOworICAgIGNvbXAtPm51bWRhdGEubm9kZSA9IGluc3Q7CisKKyAgICB4c2x0TnVtYmVyRm9ybWF0KGN0eHQsICZjb21wLT5udW1kYXRhLCBub2RlKTsKK30KKworLyoqCisgKiB4c2x0QXBwbHlJbXBvcnRzOgorICogQGN0eHQ6ICBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBjb250ZXh0Tm9kZTogIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlLgorICogQGluc3Q6ICB0aGUgZWxlbWVudCBub2RlIG9mIHRoZSBYU0xUICdhcHBseS1pbXBvcnRzJyBpbnN0cnVjdGlvbgorICogQGNvbXA6ICB0aGUgY29tcGlsZWQgaW5zdHJ1Y3Rpb24KKyAqCisgKiBQcm9jZXNzIHRoZSBYU0xUIGFwcGx5LWltcG9ydHMgZWxlbWVudC4KKyAqLwordm9pZAoreHNsdEFwcGx5SW1wb3J0cyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGNvbnRleHROb2RlLAorCSAgICAgICAgIHhtbE5vZGVQdHIgaW5zdCwKKwkJIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCBBVFRSSUJVVEVfVU5VU0VEKQoreworICAgIHhzbHRUZW1wbGF0ZVB0ciB0ZW1wbDsKKworICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICBpZiAoY29tcCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJICAgICJJbnRlcm5hbCBlcnJvciBpbiB4c2x0QXBwbHlJbXBvcnRzKCk6ICIKKwkgICAgIlRoZSBYU0xUICdhcHBseS1pbXBvcnRzJyBpbnN0cnVjdGlvbiB3YXMgbm90IGNvbXBpbGVkLlxuIik7CisJcmV0dXJuOworICAgIH0KKyAgICAvKgorICAgICogTk9URSB0aGF0IGN0eHQtPmN1cnJlbnRUZW1wbGF0ZVJ1bGUgYW5kIGN0eHQtPnRlbXBsIGlzIG5vdCB0aGUKKyAgICAqIHNhbWU7IHRoZSBmb3JtZXIgaXMgdGhlICJDdXJyZW50IFRlbXBsYXRlIFJ1bGUiIGFzIGRlZmluZWQgYnkgdGhlCisgICAgKiBYU0xUIHNwZWMsIHRoZSBsYXR0ZXIgaXMgc2ltcGx5IHRoZSB0ZW1wbGF0ZSBzdHJ1Y3QgYmVpbmcKKyAgICAqIGN1cnJlbnRseSBwcm9jZXNzZWQuCisgICAgKi8KKyAgICBpZiAoY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZSA9PSBOVUxMKSB7CisJLyoKKwkqIFNQRUMgWFNMVCAyLjA6CisJKiAiW0VSUiBYVERFMDU2MF0gSXQgaXMgYSBub24tcmVjb3ZlcmFibGUgZHluYW1pYyBlcnJvciBpZgorCSogIHhzbDphcHBseS1pbXBvcnRzIG9yIHhzbDpuZXh0LW1hdGNoIGlzIGV2YWx1YXRlZCB3aGVuIHRoZQorCSogIGN1cnJlbnQgdGVtcGxhdGUgcnVsZSBpcyBudWxsLiIKKwkqLworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAgIkl0IGlzIGFuIGVycm9yIHRvIGNhbGwgJ2FwcGx5LWltcG9ydHMnICIKKwkgICAgICJ3aGVuIHRoZXJlJ3Mgbm8gY3VycmVudCB0ZW1wbGF0ZSBydWxlLlxuIik7CisJcmV0dXJuOworICAgIH0KKyAgICAvKgorICAgICogVE9ETzogQ2hlY2sgaWYgdGhpcyBpcyBjb3JyZWN0LgorICAgICovCisgICAgdGVtcGwgPSB4c2x0R2V0VGVtcGxhdGUoY3R4dCwgY29udGV4dE5vZGUsCisJY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZS0+c3R5bGUpOworCisgICAgaWYgKHRlbXBsICE9IE5VTEwpIHsKKwl4c2x0VGVtcGxhdGVQdHIgb2xkQ3VyVGVtcGxSdWxlID0gY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZTsKKwkvKgorCSogU2V0IHRoZSBjdXJyZW50IHRlbXBsYXRlIHJ1bGUuCisJKi8KKwljdHh0LT5jdXJyZW50VGVtcGxhdGVSdWxlID0gdGVtcGw7CisJLyoKKwkqIFVSR0VOVCBUT0RPOiBOZWVkIHhzbDp3aXRoLXBhcmFtIGJlIGhhbmRsZWQgc29tZWhvdyBoZXJlPworCSovCisJeHNsdEFwcGx5WFNMVFRlbXBsYXRlKGN0eHQsIGNvbnRleHROb2RlLCB0ZW1wbC0+Y29udGVudCwKKwkgICAgdGVtcGwsIE5VTEwpOworCisJY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZSA9IG9sZEN1clRlbXBsUnVsZTsKKyAgICB9Cit9CisKKy8qKgorICogeHNsdENhbGxUZW1wbGF0ZToKKyAqIEBjdHh0OiAgYSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBub2RlOiAgdGhlICJjdXJyZW50IG5vZGUiIGluIHRoZSBzb3VyY2UgdHJlZQorICogQGluc3Q6ICB0aGUgWFNMVCAnY2FsbC10ZW1wbGF0ZScgaW5zdHJ1Y3Rpb24KKyAqIEBjYXN0ZWRDb21wOiAgdGhlIGNvbXBpbGVkIGluZm9ybWF0aW9uIG9mIHRoZSBpbnN0cnVjdGlvbgorICoKKyAqIFByb2Nlc3NlcyB0aGUgWFNMVCBjYWxsLXRlbXBsYXRlIGluc3RydWN0aW9uIG9uIHRoZSBzb3VyY2Ugbm9kZS4KKyAqLwordm9pZAoreHNsdENhbGxUZW1wbGF0ZSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCisJICAgICAgICAgICB4bWxOb2RlUHRyIGluc3QsIHhzbHRTdHlsZVByZUNvbXBQdHIgY2FzdGVkQ29tcCkKK3sKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtQ2FsbFRlbXBsYXRlUHRyIGNvbXAgPQorCSh4c2x0U3R5bGVJdGVtQ2FsbFRlbXBsYXRlUHRyKSBjYXN0ZWRDb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXAgPSBjYXN0ZWRDb21wOworI2VuZGlmCisgICAgeHNsdFN0YWNrRWxlbVB0ciB3aXRoUGFyYW1zID0gTlVMTDsKKworICAgIGlmIChjdHh0LT5pbnNlcnQgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgaWYgKGNvbXAgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAgIlRoZSBYU0xUICdjYWxsLXRlbXBsYXRlJyBpbnN0cnVjdGlvbiB3YXMgbm90IGNvbXBpbGVkLlxuIik7CisJcmV0dXJuOworICAgIH0KKworICAgIC8qCisgICAgICogVGhlIHRlbXBsYXRlIG11c3QgaGF2ZSBiZWVuIHByZWNvbXB1dGVkCisgICAgICovCisgICAgaWYgKGNvbXAtPnRlbXBsID09IE5VTEwpIHsKKwljb21wLT50ZW1wbCA9IHhzbHRGaW5kVGVtcGxhdGUoY3R4dCwgY29tcC0+bmFtZSwgY29tcC0+bnMpOworCWlmIChjb21wLT50ZW1wbCA9PSBOVUxMKSB7CisJICAgIGlmIChjb21wLT5ucyAhPSBOVUxMKSB7CisJICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkJCSJUaGUgY2FsbGVkIHRlbXBsYXRlICd7JXN9JXMnIHdhcyBub3QgZm91bmQuXG4iLAorCQkJY29tcC0+bnMsIGNvbXAtPm5hbWUpOworCSAgICB9IGVsc2UgeworCSAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCQkiVGhlIGNhbGxlZCB0ZW1wbGF0ZSAnJXMnIHdhcyBub3QgZm91bmQuXG4iLAorCQkJY29tcC0+bmFtZSk7CisJICAgIH0KKwkgICAgcmV0dXJuOworCX0KKyAgICB9CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworICAgIGlmICgoY29tcCAhPSBOVUxMKSAmJiAoY29tcC0+bmFtZSAhPSBOVUxMKSkKKwlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DQUxMX1RFTVBMQVRFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkgImNhbGwtdGVtcGxhdGU6IG5hbWUgJXNcbiIsIGNvbXAtPm5hbWUpKTsKKyNlbmRpZgorCisgICAgaWYgKGluc3QtPmNoaWxkcmVuKSB7CisJeG1sTm9kZVB0ciBjdXI7CisJeHNsdFN0YWNrRWxlbVB0ciBwYXJhbTsKKworCWN1ciA9IGluc3QtPmNoaWxkcmVuOworCXdoaWxlIChjdXIgIT0gTlVMTCkgeworI2lmZGVmIFdJVEhfREVCVUdHRVIKKwkgICAgaWYgKGN0eHQtPmRlYnVnU3RhdHVzICE9IFhTTFRfREVCVUdfTk9ORSkKKwkJeHNsSGFuZGxlRGVidWdnZXIoY3VyLCBub2RlLCBjb21wLT50ZW1wbCwgY3R4dCk7CisjZW5kaWYKKwkgICAgaWYgKGN0eHQtPnN0YXRlID09IFhTTFRfU1RBVEVfU1RPUFBFRCkgYnJlYWs7CisJICAgIC8qCisJICAgICogVE9ETzogVGhlICJ3aXRoLXBhcmFtInMgY291bGQgYmUgcGFydCBvZiB0aGUgImNhbGwtdGVtcGxhdGUiCisJICAgICogICBzdHJ1Y3R1cmUuIEF2b2lkIHRvICJzZWFyY2giIGZvciBwYXJhbXMgZHluYW1pY2FsbHkKKwkgICAgKiAgIGluIHRoZSBYTUwgdHJlZSBldmVyeSB0aW1lLgorCSAgICAqLworCSAgICBpZiAoSVNfWFNMVF9FTEVNKGN1cikpIHsKKwkJaWYgKElTX1hTTFRfTkFNRShjdXIsICJ3aXRoLXBhcmFtIikpIHsKKwkJICAgIHBhcmFtID0geHNsdFBhcnNlU3R5bGVzaGVldENhbGxlclBhcmFtKGN0eHQsIGN1cik7CisJCSAgICBpZiAocGFyYW0gIT0gTlVMTCkgeworCQkJcGFyYW0tPm5leHQgPSB3aXRoUGFyYW1zOworCQkJd2l0aFBhcmFtcyA9IHBhcmFtOworCQkgICAgfQorCQl9IGVsc2UgeworCQkgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkJCSJ4c2w6Y2FsbC10ZW1wbGF0ZTogbWlzcGxhY2VkIHhzbDolc1xuIiwgY3VyLT5uYW1lKTsKKwkJfQorCSAgICB9IGVsc2UgeworCQl4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LAorCQkgICAgInhzbDpjYWxsLXRlbXBsYXRlOiBtaXNwbGFjZWQgJXMgZWxlbWVudFxuIiwgY3VyLT5uYW1lKTsKKwkgICAgfQorCSAgICBjdXIgPSBjdXItPm5leHQ7CisJfQorICAgIH0KKyAgICAvKgorICAgICAqIENyZWF0ZSBhIG5ldyBmcmFtZSB1c2luZyB0aGUgcGFyYW1zIGZpcnN0CisgICAgICovCisgICAgeHNsdEFwcGx5WFNMVFRlbXBsYXRlKGN0eHQsIG5vZGUsIGNvbXAtPnRlbXBsLT5jb250ZW50LCBjb21wLT50ZW1wbCwKKwl3aXRoUGFyYW1zKTsKKyAgICBpZiAod2l0aFBhcmFtcyAhPSBOVUxMKQorCXhzbHRGcmVlU3RhY2tFbGVtTGlzdCh3aXRoUGFyYW1zKTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgaWYgKChjb21wICE9IE5VTEwpICYmIChjb21wLT5uYW1lICE9IE5VTEwpKQorCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0NBTExfVEVNUExBVEUseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSAiY2FsbC10ZW1wbGF0ZSByZXR1cm5lZDogbmFtZSAlc1xuIiwgY29tcC0+bmFtZSkpOworI2VuZGlmCit9CisKKy8qKgorICogeHNsdEFwcGx5VGVtcGxhdGVzOgorICogQGN0eHQ6ICBhIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQG5vZGU6ICB0aGUgJ2N1cnJlbnQgbm9kZScgaW4gdGhlIHNvdXJjZSB0cmVlCisgKiBAaW5zdDogIHRoZSBlbGVtZW50IG5vZGUgb2YgYW4gWFNMVCAnYXBwbHktdGVtcGxhdGVzJyBpbnN0cnVjdGlvbgorICogQGNhc3RlZENvbXA6ICB0aGUgY29tcGlsZWQgaW5zdHJ1Y3Rpb24KKyAqCisgKiBQcm9jZXNzZXMgdGhlIFhTTFQgJ2FwcGx5LXRlbXBsYXRlcycgaW5zdHJ1Y3Rpb24gb24gdGhlIGN1cnJlbnQgbm9kZS4KKyAqLwordm9pZAoreHNsdEFwcGx5VGVtcGxhdGVzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKKwkgICAgICAgICAgIHhtbE5vZGVQdHIgaW5zdCwgeHNsdFN0eWxlUHJlQ29tcFB0ciBjYXN0ZWRDb21wKQoreworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1BcHBseVRlbXBsYXRlc1B0ciBjb21wID0KKwkoeHNsdFN0eWxlSXRlbUFwcGx5VGVtcGxhdGVzUHRyKSBjYXN0ZWRDb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXAgPSBjYXN0ZWRDb21wOworI2VuZGlmCisgICAgaW50IGk7CisgICAgeG1sTm9kZVB0ciBjdXIsIGRlbE5vZGUgPSBOVUxMLCBvbGRDb250ZXh0Tm9kZTsKKyAgICB4bWxOb2RlU2V0UHRyIGxpc3QgPSBOVUxMLCBvbGRMaXN0OworICAgIHhzbHRTdGFja0VsZW1QdHIgd2l0aFBhcmFtcyA9IE5VTEw7CisgICAgaW50IG9sZFhQUHJveGltaXR5UG9zaXRpb24sIG9sZFhQQ29udGV4dFNpemUsIG9sZFhQTnNOcjsKKyAgICBjb25zdCB4bWxDaGFyICpvbGRNb2RlLCAqb2xkTW9kZVVSSTsKKyAgICB4bWxEb2NQdHIgb2xkWFBEb2M7CisgICAgeHNsdERvY3VtZW50UHRyIG9sZERvY0luZm87CisgICAgeG1sWFBhdGhDb250ZXh0UHRyIHhwY3R4dDsKKyAgICB4bWxOc1B0ciAqb2xkWFBOYW1lc3BhY2VzOworCisgICAgaWYgKGNvbXAgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAgInhzbDphcHBseS10ZW1wbGF0ZXMgOiBjb21waWxhdGlvbiBmYWlsZWRcbiIpOworCXJldHVybjsKKyAgICB9CisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpIHx8IChjb21wID09IE5VTEwpKQorCXJldHVybjsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgaWYgKChub2RlICE9IE5VTEwpICYmIChub2RlLT5uYW1lICE9IE5VTEwpKQorCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0FQUExZX1RFTVBMQVRFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgInhzbHRBcHBseVRlbXBsYXRlczogbm9kZTogJyVzJ1xuIiwgbm9kZS0+bmFtZSkpOworI2VuZGlmCisKKyAgICB4cGN0eHQgPSBjdHh0LT54cGF0aEN0eHQ7CisgICAgLyoKKyAgICAqIFNhdmUgY29udGV4dCBzdGF0ZXMuCisgICAgKi8KKyAgICBvbGRDb250ZXh0Tm9kZSA9IGN0eHQtPm5vZGU7CisgICAgb2xkTW9kZSA9IGN0eHQtPm1vZGU7CisgICAgb2xkTW9kZVVSSSA9IGN0eHQtPm1vZGVVUkk7CisgICAgb2xkRG9jSW5mbyA9IGN0eHQtPmRvY3VtZW50OworICAgIG9sZExpc3QgPSBjdHh0LT5ub2RlTGlzdDsKKworICAgIC8qCisgICAgICogVGhlIHhwYXRoIGNvbnRleHQgc2l6ZSBhbmQgcHJveGltaXR5IHBvc2l0aW9uLCBhcworICAgICAqIHdlbGwgYXMgdGhlIHhwYXRoIGFuZCBjb250ZXh0IGRvY3VtZW50cywgbWF5IGJlIGNoYW5nZWQKKyAgICAgKiBzbyB3ZSBzYXZlIHRoZWlyIGluaXRpYWwgc3RhdGUgYW5kIHdpbGwgcmVzdG9yZSBvbiBleGl0CisgICAgICovCisgICAgb2xkWFBDb250ZXh0U2l6ZSA9IHhwY3R4dC0+Y29udGV4dFNpemU7CisgICAgb2xkWFBQcm94aW1pdHlQb3NpdGlvbiA9IHhwY3R4dC0+cHJveGltaXR5UG9zaXRpb247CisgICAgb2xkWFBEb2MgPSB4cGN0eHQtPmRvYzsKKyAgICBvbGRYUE5zTnIgPSB4cGN0eHQtPm5zTnI7CisgICAgb2xkWFBOYW1lc3BhY2VzID0geHBjdHh0LT5uYW1lc3BhY2VzOworCisgICAgLyoKKyAgICAqIFNldCB1cCBjb250ZXh0cy4KKyAgICAqLworICAgIGN0eHQtPm1vZGUgPSBjb21wLT5tb2RlOworICAgIGN0eHQtPm1vZGVVUkkgPSBjb21wLT5tb2RlVVJJOworCisgICAgaWYgKGNvbXAtPnNlbGVjdCAhPSBOVUxMKSB7CisJeG1sWFBhdGhPYmplY3RQdHIgcmVzID0gTlVMTDsKKworCWlmIChjb21wLT5jb21wID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCSAieHNsOmFwcGx5LXRlbXBsYXRlcyA6IGNvbXBpbGF0aW9uIGZhaWxlZFxuIik7CisJICAgIGdvdG8gZXJyb3I7CisJfQorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQVBQTFlfVEVNUExBVEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdEFwcGx5VGVtcGxhdGVzOiBzZWxlY3QgJXNcbiIsIGNvbXAtPnNlbGVjdCkpOworI2VuZGlmCisKKwkvKgorCSogU2V0IHVwIFhQYXRoLgorCSovCisJeHBjdHh0LT5ub2RlID0gbm9kZTsgLyogU2V0IHRoZSAiY29udGV4dCBub2RlIiAqLworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCWlmIChjb21wLT5pblNjb3BlTnMgIT0gTlVMTCkgeworCSAgICB4cGN0eHQtPm5hbWVzcGFjZXMgPSBjb21wLT5pblNjb3BlTnMtPmxpc3Q7CisJICAgIHhwY3R4dC0+bnNOciA9IGNvbXAtPmluU2NvcGVOcy0+eHBhdGhOdW1iZXI7CisJfSBlbHNlIHsKKwkgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwkgICAgeHBjdHh0LT5uc05yID0gMDsKKwl9CisjZWxzZQorCXhwY3R4dC0+bmFtZXNwYWNlcyA9IGNvbXAtPm5zTGlzdDsKKwl4cGN0eHQtPm5zTnIgPSBjb21wLT5uc05yOworI2VuZGlmCisJcmVzID0geG1sWFBhdGhDb21waWxlZEV2YWwoY29tcC0+Y29tcCwgeHBjdHh0KTsKKworCXhwY3R4dC0+Y29udGV4dFNpemUgPSBvbGRYUENvbnRleHRTaXplOworCXhwY3R4dC0+cHJveGltaXR5UG9zaXRpb24gPSBvbGRYUFByb3hpbWl0eVBvc2l0aW9uOworCWlmIChyZXMgIT0gTlVMTCkgeworCSAgICBpZiAocmVzLT50eXBlID09IFhQQVRIX05PREVTRVQpIHsKKwkJbGlzdCA9IHJlcy0+bm9kZXNldHZhbDsgLyogY29uc3VtZSB0aGUgbm9kZSBzZXQgKi8KKwkJcmVzLT5ub2Rlc2V0dmFsID0gTlVMTDsKKwkgICAgfSBlbHNlIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJCSAgICAiVGhlICdzZWxlY3QnIGV4cHJlc3Npb24gZGlkIG5vdCBldmFsdWF0ZSB0byBhICIKKwkJICAgICJub2RlIHNldC5cbiIpOworCQljdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwkJeG1sWFBhdGhGcmVlT2JqZWN0KHJlcyk7CisJCWdvdG8gZXJyb3I7CisJICAgIH0KKwkgICAgeG1sWFBhdGhGcmVlT2JqZWN0KHJlcyk7CisJICAgIC8qCisJICAgICogTm90ZTogQW4geHNsOmFwcGx5LXRlbXBsYXRlcyB3aXRoIGEgJ3NlbGVjdCcgYXR0cmlidXRlLAorCSAgICAqIGNhbiBjaGFuZ2UgdGhlIGN1cnJlbnQgc291cmNlIGRvYy4KKwkgICAgKi8KKwl9IGVsc2UgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkJIkZhaWxlZCB0byBldmFsdWF0ZSB0aGUgJ3NlbGVjdCcgZXhwcmVzc2lvbi5cbiIpOworCSAgICBjdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwkgICAgZ290byBlcnJvcjsKKwl9CisJaWYgKGxpc3QgPT0gTlVMTCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0FQUExZX1RFTVBMQVRFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkieHNsdEFwcGx5VGVtcGxhdGVzOiBzZWxlY3QgZGlkbid0IGV2YWx1YXRlIHRvIGEgbm9kZSBsaXN0XG4iKSk7CisjZW5kaWYKKwkgICAgZ290byBleGl0OworCX0KKwkvKgorCSoKKwkqIE5PVEU6IFByZXZpb3VzbHkgYSBkb2N1bWVudCBpbmZvICh4c2x0RG9jdW1lbnQpIHdhcworCSogY3JlYXRlZCBhbmQgYXR0YWNoZWQgdG8gdGhlIFJlc3VsdCBUcmVlIEZyYWdtZW50LgorCSogQnV0IHN1Y2ggYSBkb2N1bWVudCBpbmZvIGlzIGNyZWF0ZWQgb24gZGVtYW5kIGluCisJKiB4c2x0S2V5RnVuY3Rpb24oKSAoZnVuY3Rpb25zLmMpLCBzbyB3ZSBuZWVkIHRvIGNyZWF0ZQorCSogaXQgaGVyZSBiZWZvcmVoYW5kLgorCSogSW4gb3JkZXIgdG8gdGFrZSBjYXJlIG9mIHBvdGVudGlhbCBrZXlzIHdlIG5lZWQgdG8KKwkqIGRvIHNvbWUgZXh0cmEgd29yayBmb3IgdGhlIGNhc2Ugd2hlbiBhIFJlc3VsdCBUcmVlIEZyYWdtZW50CisJKiBpcyBjb252ZXJ0ZWQgaW50byBhIG5vZGVzZXQgKGUuZy4gZXhzbHQ6bm9kZS1zZXQoKSkgOgorCSogV2UgYXR0YWNoIGEgInBzZXVkby1kb2MiICh4c2x0RG9jdW1lbnQpIHRvIF9wcml2YXRlLgorCSogVGhpcyB4c2x0RG9jdW1lbnQsIHRvZ2V0aGVyIHdpdGggdGhlIGtleXNldCwgd2lsbCBiZSBmcmVlZAorCSogd2hlbiB0aGUgUmVzdWx0IFRyZWUgRnJhZ21lbnQgaXMgZnJlZWQuCisJKgorCSovCisjaWYgMAorCWlmICgoY3R4dC0+bmJLZXlzID4gMCkgJiYKKwkgICAgKGxpc3QtPm5vZGVOciAhPSAwKSAmJgorCSAgICAobGlzdC0+bm9kZVRhYlswXS0+ZG9jICE9IE5VTEwpICYmCisJICAgIFhTTFRfSVNfUkVTX1RSRUVfRlJBRyhsaXN0LT5ub2RlVGFiWzBdLT5kb2MpKQorCXsKKwkgICAgLyoKKwkgICAgKiBOT1RFIHRoYXQgaXQncyBhbHNvIE9LIGlmIEBlZmZlY3RpdmVEb2NJbmZvIHdpbGwgYmUKKwkgICAgKiBzZXQgdG8gTlVMTC4KKwkgICAgKi8KKwkgICAgaXNSVEYgPSAxOworCSAgICBlZmZlY3RpdmVEb2NJbmZvID0gbGlzdC0+bm9kZVRhYlswXS0+ZG9jLT5fcHJpdmF0ZTsKKwl9CisjZW5kaWYKKyAgICB9IGVsc2UgeworCS8qCisJICogQnVpbGQgYW4gWFBhdGggbm9kZSBzZXQgd2l0aCB0aGUgY2hpbGRyZW4KKwkgKi8KKwlsaXN0ID0geG1sWFBhdGhOb2RlU2V0Q3JlYXRlKE5VTEwpOworCWlmIChsaXN0ID09IE5VTEwpCisJICAgIGdvdG8gZXJyb3I7CisJY3VyID0gbm9kZS0+Y2hpbGRyZW47CisJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJICAgIHN3aXRjaCAoY3VyLT50eXBlKSB7CisJCWNhc2UgWE1MX1RFWFRfTk9ERToKKwkJICAgIGlmICgoSVNfQkxBTktfTk9ERShjdXIpKSAmJgorCQkJKGN1ci0+cGFyZW50ICE9IE5VTEwpICYmCisJCQkoY3VyLT5wYXJlbnQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKKwkJCShjdHh0LT5zdHlsZS0+c3RyaXBTcGFjZXMgIT0gTlVMTCkpIHsKKwkJCWNvbnN0IHhtbENoYXIgKnZhbDsKKworCQkJaWYgKGN1ci0+cGFyZW50LT5ucyAhPSBOVUxMKSB7CisJCQkgICAgdmFsID0gKGNvbnN0IHhtbENoYXIgKikKKwkJCQkgIHhtbEhhc2hMb29rdXAyKGN0eHQtPnN0eWxlLT5zdHJpcFNwYWNlcywKKwkJCQkJCSBjdXItPnBhcmVudC0+bmFtZSwKKwkJCQkJCSBjdXItPnBhcmVudC0+bnMtPmhyZWYpOworCQkJICAgIGlmICh2YWwgPT0gTlVMTCkgeworCQkJCXZhbCA9IChjb25zdCB4bWxDaGFyICopCisJCQkJICB4bWxIYXNoTG9va3VwMihjdHh0LT5zdHlsZS0+c3RyaXBTcGFjZXMsCisJCQkJCQkgQkFEX0NBU1QgIioiLAorCQkJCQkJIGN1ci0+cGFyZW50LT5ucy0+aHJlZik7CisJCQkgICAgfQorCQkJfSBlbHNlIHsKKwkJCSAgICB2YWwgPSAoY29uc3QgeG1sQ2hhciAqKQorCQkJCSAgeG1sSGFzaExvb2t1cDIoY3R4dC0+c3R5bGUtPnN0cmlwU3BhY2VzLAorCQkJCQkJIGN1ci0+cGFyZW50LT5uYW1lLCBOVUxMKTsKKwkJCX0KKwkJCWlmICgodmFsICE9IE5VTEwpICYmCisJCQkgICAgKHhtbFN0ckVxdWFsKHZhbCwgKHhtbENoYXIgKikgInN0cmlwIikpKSB7CisJCQkgICAgZGVsTm9kZSA9IGN1cjsKKwkJCSAgICBicmVhazsKKwkJCX0KKwkJICAgIH0KKwkJICAgIC8qIG5vIGJyZWFrIG9uIHB1cnBvc2UgKi8KKwkJY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgorCQljYXNlIFhNTF9ET0NVTUVOVF9OT0RFOgorCQljYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CisJCWNhc2UgWE1MX0NEQVRBX1NFQ1RJT05fTk9ERToKKwkJY2FzZSBYTUxfUElfTk9ERToKKwkJY2FzZSBYTUxfQ09NTUVOVF9OT0RFOgorCQkgICAgeG1sWFBhdGhOb2RlU2V0QWRkVW5pcXVlKGxpc3QsIGN1cik7CisJCSAgICBicmVhazsKKwkJY2FzZSBYTUxfRFREX05PREU6CisJCSAgICAvKiBVbmxpbmsgdGhlIERURCwgaXQncyBzdGlsbCByZWFjaGFibGUKKwkJICAgICAqIHVzaW5nIGRvYy0+aW50U3Vic2V0ICovCisJCSAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpCisJCQljdXItPm5leHQtPnByZXYgPSBjdXItPnByZXY7CisJCSAgICBpZiAoY3VyLT5wcmV2ICE9IE5VTEwpCisJCQljdXItPnByZXYtPm5leHQgPSBjdXItPm5leHQ7CisJCSAgICBicmVhazsKKwkJZGVmYXVsdDoKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQkgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQVBQTFlfVEVNUExBVEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAgInhzbHRBcHBseVRlbXBsYXRlczogc2tpcHBpbmcgY3VyIHR5cGUgJWRcbiIsCisJCQkJICAgICBjdXItPnR5cGUpKTsKKyNlbmRpZgorCQkgICAgZGVsTm9kZSA9IGN1cjsKKwkgICAgfQorCSAgICBjdXIgPSBjdXItPm5leHQ7CisJICAgIGlmIChkZWxOb2RlICE9IE5VTEwpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9BUFBMWV9URU1QTEFURVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICAgICAieHNsdEFwcGx5VGVtcGxhdGVzOiByZW1vdmluZyBpZ25vcmFibGUgYmxhbmsgY3VyXG4iKSk7CisjZW5kaWYKKwkJeG1sVW5saW5rTm9kZShkZWxOb2RlKTsKKwkJeG1sRnJlZU5vZGUoZGVsTm9kZSk7CisJCWRlbE5vZGUgPSBOVUxMOworCSAgICB9CisJfQorICAgIH0KKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisgICAgaWYgKGxpc3QgIT0gTlVMTCkKKyAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9BUFBMWV9URU1QTEFURVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkieHNsdEFwcGx5VGVtcGxhdGVzOiBsaXN0IG9mICVkIG5vZGVzXG4iLCBsaXN0LT5ub2RlTnIpKTsKKyNlbmRpZgorCisgICAgaWYgKChsaXN0ID09IE5VTEwpIHx8IChsaXN0LT5ub2RlTnIgPT0gMCkpCisJZ290byBleGl0OworCisgICAgLyoKKyAgICAqIFNldCB0aGUgY29udGV4dCdzIG5vZGUgc2V0IGFuZCBzaXplOyB0aGlzIGlzIGFsc28gbmVlZGVkIGZvcgorICAgICogZm9yIHhzbHREb1NvcnRGdW5jdGlvbigpLgorICAgICovCisgICAgY3R4dC0+bm9kZUxpc3QgPSBsaXN0OworICAgIC8qCisgICAgKiBQcm9jZXNzIHhzbDp3aXRoLXBhcmFtIGFuZCB4c2w6c29ydCBpbnN0cnVjdGlvbnMuCisgICAgKiAoVGhlIGNvZGUgYmVjYW1lIHNvIHZlcmJvc2UganVzdCB0byBhdm9pZCB0aGUKKyAgICAqICB4bWxOb2RlUHRyIHNvcnRzW1hTTFRfTUFYX1NPUlRdIGlmIHRoZXJlJ3Mgbm8geHNsOnNvcnQpCisgICAgKiBCVUcgVE9ETzogV2UgYXJlIG5vdCB1c2luZyBuYW1lc3BhY2VkIHBvdGVudGlhbGx5IGRlZmluZWQgb24gdGhlCisgICAgKiB4c2w6c29ydCBvciB4c2w6d2l0aC1wYXJhbSBlbGVtZW50czsgWFBhdGggZXhwcmVzc2lvbiBtaWdodCBmYWlsLgorICAgICovCisgICAgaWYgKGluc3QtPmNoaWxkcmVuKSB7CisJeHNsdFN0YWNrRWxlbVB0ciBwYXJhbTsKKworCWN1ciA9IGluc3QtPmNoaWxkcmVuOworCXdoaWxlIChjdXIpIHsKKworI2lmZGVmIFdJVEhfREVCVUdHRVIKKwkgICAgaWYgKGN0eHQtPmRlYnVnU3RhdHVzICE9IFhTTFRfREVCVUdfTk9ORSkKKwkJeHNsSGFuZGxlRGVidWdnZXIoY3VyLCBub2RlLCBOVUxMLCBjdHh0KTsKKyNlbmRpZgorCSAgICBpZiAoY3R4dC0+c3RhdGUgPT0gWFNMVF9TVEFURV9TVE9QUEVEKQorCQlicmVhazsKKwkgICAgaWYgKGN1ci0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB7CisJCWN1ciA9IGN1ci0+bmV4dDsKKwkJY29udGludWU7CisJICAgIH0KKwkgICAgaWYgKCEgSVNfWFNMVF9FTEVNKGN1cikpCisJCWJyZWFrOworCSAgICBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgIndpdGgtcGFyYW0iKSkgeworCQlwYXJhbSA9IHhzbHRQYXJzZVN0eWxlc2hlZXRDYWxsZXJQYXJhbShjdHh0LCBjdXIpOworCQlpZiAocGFyYW0gIT0gTlVMTCkgeworCQkgICAgcGFyYW0tPm5leHQgPSB3aXRoUGFyYW1zOworCQkgICAgd2l0aFBhcmFtcyA9IHBhcmFtOworCQl9CisJICAgIH0KKwkgICAgaWYgKElTX1hTTFRfTkFNRShjdXIsICJzb3J0IikpIHsKKwkJeHNsdFRlbXBsYXRlUHRyIG9sZEN1clRlbXBSdWxlID0KKwkJICAgIGN0eHQtPmN1cnJlbnRUZW1wbGF0ZVJ1bGU7CisJCWludCBuYnNvcnRzID0gMDsKKwkJeG1sTm9kZVB0ciBzb3J0c1tYU0xUX01BWF9TT1JUXTsKKworCQlzb3J0c1tuYnNvcnRzKytdID0gY3VyOworCisJCXdoaWxlIChjdXIpIHsKKworI2lmZGVmIFdJVEhfREVCVUdHRVIKKwkJICAgIGlmIChjdHh0LT5kZWJ1Z1N0YXR1cyAhPSBYU0xUX0RFQlVHX05PTkUpCisJCQl4c2xIYW5kbGVEZWJ1Z2dlcihjdXIsIG5vZGUsIE5VTEwsIGN0eHQpOworI2VuZGlmCisJCSAgICBpZiAoY3R4dC0+c3RhdGUgPT0gWFNMVF9TVEFURV9TVE9QUEVEKQorCQkJYnJlYWs7CisKKwkJICAgIGlmIChjdXItPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgeworCQkJY3VyID0gY3VyLT5uZXh0OworCQkJY29udGludWU7CisJCSAgICB9CisKKwkJICAgIGlmICghIElTX1hTTFRfRUxFTShjdXIpKQorCQkJYnJlYWs7CisJCSAgICBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgIndpdGgtcGFyYW0iKSkgeworCQkJcGFyYW0gPSB4c2x0UGFyc2VTdHlsZXNoZWV0Q2FsbGVyUGFyYW0oY3R4dCwgY3VyKTsKKwkJCWlmIChwYXJhbSAhPSBOVUxMKSB7CisJCQkgICAgcGFyYW0tPm5leHQgPSB3aXRoUGFyYW1zOworCQkJICAgIHdpdGhQYXJhbXMgPSBwYXJhbTsKKwkJCX0KKwkJICAgIH0KKwkJICAgIGlmIChJU19YU0xUX05BTUUoY3VyLCAic29ydCIpKSB7CisJCQlpZiAobmJzb3J0cyA+PSBYU0xUX01BWF9TT1JUKSB7CisJCQkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGN1ciwKKwkJCQkiVGhlIG51bWJlciAoJWQpIG9mIHhzbDpzb3J0IGluc3RydWN0aW9ucyBleGNlZWRzIHRoZSAiCisJCQkJIm1heGltdW0gYWxsb3dlZCBieSB0aGlzIHByb2Nlc3NvcidzIHNldHRpbmdzLlxuIiwKKwkJCQluYnNvcnRzKTsKKwkJCSAgICBjdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwkJCSAgICBicmVhazsKKwkJCX0gZWxzZSB7CisJCQkgICAgc29ydHNbbmJzb3J0cysrXSA9IGN1cjsKKwkJCX0KKwkJICAgIH0KKwkJICAgIGN1ciA9IGN1ci0+bmV4dDsKKwkJfQorCQkvKgorCQkqIFRoZSAiY3VycmVudCB0ZW1wbGF0ZSBydWxlIiBpcyBjbGVhcmVkIGZvciB4c2w6c29ydC4KKwkJKi8KKwkJY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZSA9IE5VTEw7CisJCS8qCisJCSogU29ydC4KKwkJKi8KKwkJeHNsdERvU29ydEZ1bmN0aW9uKGN0eHQsIHNvcnRzLCBuYnNvcnRzKTsKKwkJY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZSA9IG9sZEN1clRlbXBSdWxlOworCQlicmVhazsKKwkgICAgfQorCSAgICBjdXIgPSBjdXItPm5leHQ7CisJfQorICAgIH0KKyAgICB4cGN0eHQtPmNvbnRleHRTaXplID0gbGlzdC0+bm9kZU5yOworICAgIC8qCisgICAgKiBBcHBseSB0ZW1wbGF0ZXMgZm9yIGFsbCBzZWxlY3RlZCBzb3VyY2Ugbm9kZXMuCisgICAgKi8KKyAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bm9kZU5yOyBpKyspIHsKKwljdXIgPSBsaXN0LT5ub2RlVGFiW2ldOworCS8qCisJKiBUaGUgbm9kZSBiZWNvbWVzIHRoZSAiY3VycmVudCBub2RlIi4KKwkqLworCWN0eHQtPm5vZGUgPSBjdXI7CisJLyoKKwkqIEFuIHhzbDphcHBseS10ZW1wbGF0ZXMgY2FuIGNoYW5nZSB0aGUgY3VycmVudCBjb250ZXh0IGRvYy4KKwkqIE9QVElNSVpFIFRPRE86IEdldCByaWQgb2YgdGhlIG5lZWQgdG8gc2V0IHRoZSBjb250ZXh0IGRvYy4KKwkqLworCWlmICgoY3VyLT50eXBlICE9IFhNTF9OQU1FU1BBQ0VfREVDTCkgJiYgKGN1ci0+ZG9jICE9IE5VTEwpKQorCSAgICB4cGN0eHQtPmRvYyA9IGN1ci0+ZG9jOworCisJeHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IGkgKyAxOworCS8qCisJKiBGaW5kIGFuZCBhcHBseSBhIHRlbXBsYXRlIGZvciB0aGlzIG5vZGUuCisJKi8KKwl4c2x0UHJvY2Vzc09uZU5vZGUoY3R4dCwgY3VyLCB3aXRoUGFyYW1zKTsKKyAgICB9CisKK2V4aXQ6CitlcnJvcjoKKyAgICAvKgorICAgICogRnJlZSB0aGUgcGFyYW1ldGVyIGxpc3QuCisgICAgKi8KKyAgICBpZiAod2l0aFBhcmFtcyAhPSBOVUxMKQorCXhzbHRGcmVlU3RhY2tFbGVtTGlzdCh3aXRoUGFyYW1zKTsKKyAgICBpZiAobGlzdCAhPSBOVUxMKQorCXhtbFhQYXRoRnJlZU5vZGVTZXQobGlzdCk7CisgICAgLyoKKyAgICAqIFJlc3RvcmUgY29udGV4dCBzdGF0ZXMuCisgICAgKi8KKyAgICB4cGN0eHQtPm5zTnIgPSBvbGRYUE5zTnI7CisgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gb2xkWFBOYW1lc3BhY2VzOworICAgIHhwY3R4dC0+ZG9jID0gb2xkWFBEb2M7CisgICAgeHBjdHh0LT5jb250ZXh0U2l6ZSA9IG9sZFhQQ29udGV4dFNpemU7CisgICAgeHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IG9sZFhQUHJveGltaXR5UG9zaXRpb247CisKKyAgICBjdHh0LT5kb2N1bWVudCA9IG9sZERvY0luZm87CisgICAgY3R4dC0+bm9kZUxpc3QgPSBvbGRMaXN0OworICAgIGN0eHQtPm5vZGUgPSBvbGRDb250ZXh0Tm9kZTsKKyAgICBjdHh0LT5tb2RlID0gb2xkTW9kZTsKKyAgICBjdHh0LT5tb2RlVVJJID0gb2xkTW9kZVVSSTsKK30KKworCisvKioKKyAqIHhzbHRDaG9vc2U6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBjb250ZXh0Tm9kZTogIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlCisgKiBAaW5zdDogIHRoZSB4c2w6Y2hvb3NlIGluc3RydWN0aW9uCisgKiBAY29tcDogIGNvbXBpbGVkIGluZm9ybWF0aW9uIG9mIHRoZSBpbnN0cnVjdGlvbgorICoKKyAqIFByb2Nlc3NlcyB0aGUgeHNsOmNob29zZSBpbnN0cnVjdGlvbiBvbiB0aGUgc291cmNlIG5vZGUuCisgKi8KK3ZvaWQKK3hzbHRDaG9vc2UoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBjb250ZXh0Tm9kZSwKKwkgICB4bWxOb2RlUHRyIGluc3QsIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCBBVFRSSUJVVEVfVU5VU0VEKQoreworICAgIHhtbE5vZGVQdHIgY3VyOworCisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChjb250ZXh0Tm9kZSA9PSBOVUxMKSB8fCAoaW5zdCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICAvKgorICAgICogVE9ETzogQ29udGVudCBtb2RlbCBjaGVja3Mgc2hvdWxkIGJlIGRvbmUgb25seSBhdCBjb21waWxhdGlvbgorICAgICogdGltZS4KKyAgICAqLworICAgIGN1ciA9IGluc3QtPmNoaWxkcmVuOworICAgIGlmIChjdXIgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAieHNsOmNob29zZTogVGhlIGluc3RydWN0aW9uIGhhcyBubyBjb250ZW50LlxuIik7CisJcmV0dXJuOworICAgIH0KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIC8qCisgICAgKiBXZSBkb24ndCBjaGVjayB0aGUgY29udGVudCBtb2RlbCBkdXJpbmcgdHJhbnNmb3JtYXRpb24uCisgICAgKi8KKyNlbHNlCisgICAgaWYgKCghIElTX1hTTFRfRUxFTShjdXIpKSB8fCAoISBJU19YU0xUX05BTUUoY3VyLCAid2hlbiIpKSkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAgInhzbDpjaG9vc2U6IHhzbDp3aGVuIGV4cGVjdGVkIGZpcnN0XG4iKTsKKwlyZXR1cm47CisgICAgfQorI2VuZGlmCisKKyAgICB7CisJaW50IHRlc3RSZXMgPSAwLCByZXMgPSAwOworCXhtbFhQYXRoQ29udGV4dFB0ciB4cGN0eHQgPSBjdHh0LT54cGF0aEN0eHQ7CisJeG1sRG9jUHRyIG9sZFhQQ29udGV4dERvYyA9IHhwY3R4dC0+ZG9jOworCWludCBvbGRYUFByb3hpbWl0eVBvc2l0aW9uID0geHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbjsKKwlpbnQgb2xkWFBDb250ZXh0U2l6ZSA9IHhwY3R4dC0+Y29udGV4dFNpemU7CisJeG1sTnNQdHIgKm9sZFhQTmFtZXNwYWNlcyA9IHhwY3R4dC0+bmFtZXNwYWNlczsKKwlpbnQgb2xkWFBOc05yID0geHBjdHh0LT5uc05yOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisJeHNsdFN0eWxlSXRlbVdoZW5QdHIgd2NvbXAgPSBOVUxMOworI2Vsc2UKKwl4c2x0U3R5bGVQcmVDb21wUHRyIHdjb21wID0gTlVMTDsKKyNlbmRpZgorCisJLyoKKwkqIFByb2Nlc3MgeHNsOndoZW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisJKi8KKwl3aGlsZSAoSVNfWFNMVF9FTEVNKGN1cikgJiYgSVNfWFNMVF9OQU1FKGN1ciwgIndoZW4iKSkgeworCSAgICB3Y29tcCA9IGN1ci0+cHN2aTsKKworCSAgICBpZiAoKHdjb21wID09IE5VTEwpIHx8ICh3Y29tcC0+dGVzdCA9PSBOVUxMKSB8fAorCQkod2NvbXAtPmNvbXAgPT0gTlVMTCkpCisJICAgIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGN1ciwKKwkJICAgICJJbnRlcm5hbCBlcnJvciBpbiB4c2x0Q2hvb3NlKCk6ICIKKwkJICAgICJUaGUgWFNMVCAnd2hlbicgaW5zdHJ1Y3Rpb24gd2FzIG5vdCBjb21waWxlZC5cbiIpOworCQlnb3RvIGVycm9yOworCSAgICB9CisKKworI2lmZGVmIFdJVEhfREVCVUdHRVIKKwkgICAgaWYgKHhzbERlYnVnU3RhdHVzICE9IFhTTFRfREVCVUdfTk9ORSkgeworCQkvKgorCQkqIFRPRE86IElzbid0IGNvbXAtPnRlbXBsIGFsd2F5cyBOVUxMIGZvciB4c2w6Y2hvb3NlPworCQkqLworCQl4c2xIYW5kbGVEZWJ1Z2dlcihjdXIsIGNvbnRleHROb2RlLCBOVUxMLCBjdHh0KTsKKwkgICAgfQorI2VuZGlmCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwkgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfQ0hPT1NFLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSJ4c2x0Q2hvb3NlOiB0ZXN0ICVzXG4iLCB3Y29tcC0+dGVzdCkpOworI2VuZGlmCisKKwkgICAgeHBjdHh0LT5ub2RlID0gY29udGV4dE5vZGU7CisJICAgIHhwY3R4dC0+ZG9jID0gb2xkWFBDb250ZXh0RG9jOworCSAgICB4cGN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gb2xkWFBQcm94aW1pdHlQb3NpdGlvbjsKKwkgICAgeHBjdHh0LT5jb250ZXh0U2l6ZSA9IG9sZFhQQ29udGV4dFNpemU7CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwkgICAgaWYgKHdjb21wLT5pblNjb3BlTnMgIT0gTlVMTCkgeworCQl4cGN0eHQtPm5hbWVzcGFjZXMgPSB3Y29tcC0+aW5TY29wZU5zLT5saXN0OworCQl4cGN0eHQtPm5zTnIgPSB3Y29tcC0+aW5TY29wZU5zLT54cGF0aE51bWJlcjsKKwkgICAgfSBlbHNlIHsKKwkJeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwkJeHBjdHh0LT5uc05yID0gMDsKKwkgICAgfQorI2Vsc2UKKwkgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gd2NvbXAtPm5zTGlzdDsKKwkgICAgeHBjdHh0LT5uc05yID0gd2NvbXAtPm5zTnI7CisjZW5kaWYKKworCisjaWZkZWYgWFNMVF9GQVNUX0lGCisJICAgIHJlcyA9IHhtbFhQYXRoQ29tcGlsZWRFdmFsVG9Cb29sZWFuKHdjb21wLT5jb21wLCB4cGN0eHQpOworCisJICAgIGlmIChyZXMgPT0gLTEpIHsKKwkJY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisJCWdvdG8gZXJyb3I7CisJICAgIH0KKwkgICAgdGVzdFJlcyA9IChyZXMgPT0gMSkgPyAxIDogMDsKKworI2Vsc2UgLyogWFNMVF9GQVNUX0lGICovCisKKwkgICAgcmVzID0geG1sWFBhdGhDb21waWxlZEV2YWwod2NvbXAtPmNvbXAsIHhwY3R4dCk7CisKKwkgICAgaWYgKHJlcyAhPSBOVUxMKSB7CisJCWlmIChyZXMtPnR5cGUgIT0gWFBBVEhfQk9PTEVBTikKKwkJICAgIHJlcyA9IHhtbFhQYXRoQ29udmVydEJvb2xlYW4ocmVzKTsKKwkJaWYgKHJlcy0+dHlwZSA9PSBYUEFUSF9CT09MRUFOKQorCQkgICAgdGVzdFJlcyA9IHJlcy0+Ym9vbHZhbDsKKwkJZWxzZSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwkJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0NIT09TRSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJInhzbHRDaG9vc2U6IHRlc3QgZGlkbid0IGV2YWx1YXRlIHRvIGEgYm9vbGVhblxuIikpOworI2VuZGlmCisJCSAgICBnb3RvIGVycm9yOworCQl9CisJCXhtbFhQYXRoRnJlZU9iamVjdChyZXMpOworCQlyZXMgPSBOVUxMOworCSAgICB9IGVsc2UgeworCQljdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwkJZ290byBlcnJvcjsKKwkgICAgfQorCisjZW5kaWYgLyogZWxzZSBvZiBYU0xUX0ZBU1RfSUYgKi8KKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0NIT09TRSx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkieHNsdENob29zZTogdGVzdCBldmFsdWF0ZSB0byAlZFxuIiwgdGVzdFJlcykpOworI2VuZGlmCisJICAgIGlmICh0ZXN0UmVzKQorCQlnb3RvIHRlc3RfaXNfdHJ1ZTsKKworCSAgICBjdXIgPSBjdXItPm5leHQ7CisJfQorCisJLyoKKwkqIFByb2Nlc3MgeHNsOm90aGVyd2lzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisJKi8KKwlpZiAoSVNfWFNMVF9FTEVNKGN1cikgJiYgSVNfWFNMVF9OQU1FKGN1ciwgIm90aGVyd2lzZSIpKSB7CisKKyNpZmRlZiBXSVRIX0RFQlVHR0VSCisJICAgIGlmICh4c2xEZWJ1Z1N0YXR1cyAhPSBYU0xUX0RFQlVHX05PTkUpCisJCXhzbEhhbmRsZURlYnVnZ2VyKGN1ciwgY29udGV4dE5vZGUsIE5VTEwsIGN0eHQpOworI2VuZGlmCisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCSAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9DSE9PU0UseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJImV2YWx1YXRpbmcgeHNsOm90aGVyd2lzZVxuIikpOworI2VuZGlmCisJICAgIGdvdG8gdGVzdF9pc190cnVlOworCX0KKwl4cGN0eHQtPm5vZGUgPSBjb250ZXh0Tm9kZTsKKwl4cGN0eHQtPmRvYyA9IG9sZFhQQ29udGV4dERvYzsKKwl4cGN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gb2xkWFBQcm94aW1pdHlQb3NpdGlvbjsKKwl4cGN0eHQtPmNvbnRleHRTaXplID0gb2xkWFBDb250ZXh0U2l6ZTsKKwl4cGN0eHQtPm5hbWVzcGFjZXMgPSBvbGRYUE5hbWVzcGFjZXM7CisJeHBjdHh0LT5uc05yID0gb2xkWFBOc05yOworCWdvdG8gZXhpdDsKKwordGVzdF9pc190cnVlOgorCisJeHBjdHh0LT5ub2RlID0gY29udGV4dE5vZGU7CisJeHBjdHh0LT5kb2MgPSBvbGRYUENvbnRleHREb2M7CisJeHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IG9sZFhQUHJveGltaXR5UG9zaXRpb247CisJeHBjdHh0LT5jb250ZXh0U2l6ZSA9IG9sZFhQQ29udGV4dFNpemU7CisJeHBjdHh0LT5uYW1lc3BhY2VzID0gb2xkWFBOYW1lc3BhY2VzOworCXhwY3R4dC0+bnNOciA9IG9sZFhQTnNOcjsKKwlnb3RvIHByb2Nlc3Nfc2VxdWVuY2U7CisgICAgfQorCitwcm9jZXNzX3NlcXVlbmNlOgorCisgICAgLyoKKyAgICAqIEluc3RhbnRpYXRlIHRoZSBzZXF1ZW5jZSBjb25zdHJ1Y3Rvci4KKyAgICAqLworICAgIHhzbHRBcHBseVNlcXVlbmNlQ29uc3RydWN0b3IoY3R4dCwgY3R4dC0+bm9kZSwgY3VyLT5jaGlsZHJlbiwKKwlOVUxMKTsKKworZXhpdDoKK2Vycm9yOgorICAgIHJldHVybjsKK30KKworLyoqCisgKiB4c2x0SWY6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBjb250ZXh0Tm9kZTogIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlCisgKiBAaW5zdDogIHRoZSB4c2w6aWYgaW5zdHJ1Y3Rpb24KKyAqIEBjYXN0ZWRDb21wOiAgY29tcGlsZWQgaW5mb3JtYXRpb24gb2YgdGhlIGluc3RydWN0aW9uCisgKgorICogUHJvY2Vzc2VzIHRoZSB4c2w6aWYgaW5zdHJ1Y3Rpb24gb24gdGhlIHNvdXJjZSBub2RlLgorICovCit2b2lkCit4c2x0SWYoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBjb250ZXh0Tm9kZSwKKwkgICAgICAgICAgIHhtbE5vZGVQdHIgaW5zdCwgeHNsdFN0eWxlUHJlQ29tcFB0ciBjYXN0ZWRDb21wKQoreworICAgIGludCByZXMgPSAwOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbUlmUHRyIGNvbXAgPSAoeHNsdFN0eWxlSXRlbUlmUHRyKSBjYXN0ZWRDb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXAgPSBjYXN0ZWRDb21wOworI2VuZGlmCisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGNvbnRleHROb2RlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpKQorCXJldHVybjsKKyAgICBpZiAoKGNvbXAgPT0gTlVMTCkgfHwgKGNvbXAtPnRlc3QgPT0gTlVMTCkgfHwgKGNvbXAtPmNvbXAgPT0gTlVMTCkpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkgICAgIkludGVybmFsIGVycm9yIGluIHhzbHRJZigpOiAiCisJICAgICJUaGUgWFNMVCAnaWYnIGluc3RydWN0aW9uIHdhcyBub3QgY29tcGlsZWQuXG4iKTsKKwlyZXR1cm47CisgICAgfQorCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKyAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9JRix4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAieHNsdElmOiB0ZXN0ICVzXG4iLCBjb21wLT50ZXN0KSk7CisjZW5kaWYKKworI2lmZGVmIFhTTFRfRkFTVF9JRgorICAgIHsKKwl4bWxYUGF0aENvbnRleHRQdHIgeHBjdHh0ID0gY3R4dC0+eHBhdGhDdHh0OworCXhtbERvY1B0ciBvbGRYUENvbnRleHREb2MgPSB4cGN0eHQtPmRvYzsKKwl4bWxOc1B0ciAqb2xkWFBOYW1lc3BhY2VzID0geHBjdHh0LT5uYW1lc3BhY2VzOworCXhtbE5vZGVQdHIgb2xkWFBDb250ZXh0Tm9kZSA9IHhwY3R4dC0+bm9kZTsKKwlpbnQgb2xkWFBQcm94aW1pdHlQb3NpdGlvbiA9IHhwY3R4dC0+cHJveGltaXR5UG9zaXRpb247CisJaW50IG9sZFhQQ29udGV4dFNpemUgPSB4cGN0eHQtPmNvbnRleHRTaXplOworCWludCBvbGRYUE5zTnIgPSB4cGN0eHQtPm5zTnI7CisJeG1sRG9jUHRyIG9sZExvY2FsRnJhZ21lbnRUb3AgPSBjdHh0LT5sb2NhbFJWVDsKKworCXhwY3R4dC0+bm9kZSA9IGNvbnRleHROb2RlOworCWlmIChjb21wICE9IE5VTEwpIHsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCSAgICBpZiAoY29tcC0+aW5TY29wZU5zICE9IE5VTEwpIHsKKwkJeHBjdHh0LT5uYW1lc3BhY2VzID0gY29tcC0+aW5TY29wZU5zLT5saXN0OworCQl4cGN0eHQtPm5zTnIgPSBjb21wLT5pblNjb3BlTnMtPnhwYXRoTnVtYmVyOworCSAgICB9IGVsc2UgeworCQl4cGN0eHQtPm5hbWVzcGFjZXMgPSBOVUxMOworCQl4cGN0eHQtPm5zTnIgPSAwOworCSAgICB9CisjZWxzZQorCSAgICB4cGN0eHQtPm5hbWVzcGFjZXMgPSBjb21wLT5uc0xpc3Q7CisJICAgIHhwY3R4dC0+bnNOciA9IGNvbXAtPm5zTnI7CisjZW5kaWYKKwl9IGVsc2UgeworCSAgICB4cGN0eHQtPm5hbWVzcGFjZXMgPSBOVUxMOworCSAgICB4cGN0eHQtPm5zTnIgPSAwOworCX0KKwkvKgorCSogVGhpcyBYUGF0aCBmdW5jdGlvbiBpcyBvcHRpbWl6ZWQgZm9yIGJvb2xlYW4gcmVzdWx0cy4KKwkqLworCXJlcyA9IHhtbFhQYXRoQ29tcGlsZWRFdmFsVG9Cb29sZWFuKGNvbXAtPmNvbXAsIHhwY3R4dCk7CisKKwkvKgorCSogQ2xlYW51cCBmcmFnbWVudHMgY3JlYXRlZCBkdXJpbmcgZXZhbHVhdGlvbiBvZiB0aGUKKwkqICJzZWxlY3QiIGV4cHJlc3Npb24uCisJKi8KKwlpZiAob2xkTG9jYWxGcmFnbWVudFRvcCAhPSBjdHh0LT5sb2NhbFJWVCkKKwkgICAgeHNsdFJlbGVhc2VMb2NhbFJWVHMoY3R4dCwgb2xkTG9jYWxGcmFnbWVudFRvcCk7CisKKwl4cGN0eHQtPmRvYyA9IG9sZFhQQ29udGV4dERvYzsKKwl4cGN0eHQtPm5vZGUgPSBvbGRYUENvbnRleHROb2RlOworCXhwY3R4dC0+Y29udGV4dFNpemUgPSBvbGRYUENvbnRleHRTaXplOworCXhwY3R4dC0+cHJveGltaXR5UG9zaXRpb24gPSBvbGRYUFByb3hpbWl0eVBvc2l0aW9uOworCXhwY3R4dC0+bnNOciA9IG9sZFhQTnNOcjsKKwl4cGN0eHQtPm5hbWVzcGFjZXMgPSBvbGRYUE5hbWVzcGFjZXM7CisgICAgfQorCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKyAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9JRix4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJ4c2x0SWY6IHRlc3QgZXZhbHVhdGUgdG8gJWRcbiIsIHJlcykpOworI2VuZGlmCisKKyAgICBpZiAocmVzID09IC0xKSB7CisJY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisJZ290byBlcnJvcjsKKyAgICB9CisgICAgaWYgKHJlcyA9PSAxKSB7CisJLyoKKwkqIEluc3RhbnRpYXRlIHRoZSBzZXF1ZW5jZSBjb25zdHJ1Y3RvciBvZiB4c2w6aWYuCisJKi8KKwl4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yKGN0eHQsCisJICAgIGNvbnRleHROb2RlLCBpbnN0LT5jaGlsZHJlbiwgTlVMTCk7CisgICAgfQorCisjZWxzZSAvKiBYU0xUX0ZBU1RfSUYgKi8KKyAgICB7CisJeG1sWFBhdGhPYmplY3RQdHIgeHBvYmogPSBOVUxMOworCS8qCisJKiBPTEQgQ09ERToKKwkqLworCXsKKwkgICAgeG1sWFBhdGhDb250ZXh0UHRyIHhwY3R4dCA9IGN0eHQtPnhwYXRoQ3R4dDsKKwkgICAgeG1sRG9jUHRyIG9sZFhQQ29udGV4dERvYyA9IHhwY3R4dC0+ZG9jOworCSAgICB4bWxOc1B0ciAqb2xkWFBOYW1lc3BhY2VzID0geHBjdHh0LT5uYW1lc3BhY2VzOworCSAgICB4bWxOb2RlUHRyIG9sZFhQQ29udGV4dE5vZGUgPSB4cGN0eHQtPm5vZGU7CisJICAgIGludCBvbGRYUFByb3hpbWl0eVBvc2l0aW9uID0geHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbjsKKwkgICAgaW50IG9sZFhQQ29udGV4dFNpemUgPSB4cGN0eHQtPmNvbnRleHRTaXplOworCSAgICBpbnQgb2xkWFBOc05yID0geHBjdHh0LT5uc05yOworCisJICAgIHhwY3R4dC0+bm9kZSA9IGNvbnRleHROb2RlOworCSAgICBpZiAoY29tcCAhPSBOVUxMKSB7CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwkJaWYgKGNvbXAtPmluU2NvcGVOcyAhPSBOVUxMKSB7CisJCSAgICB4cGN0eHQtPm5hbWVzcGFjZXMgPSBjb21wLT5pblNjb3BlTnMtPmxpc3Q7CisJCSAgICB4cGN0eHQtPm5zTnIgPSBjb21wLT5pblNjb3BlTnMtPnhwYXRoTnVtYmVyOworCQl9IGVsc2UgeworCQkgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwkJICAgIHhwY3R4dC0+bnNOciA9IDA7CisJCX0KKyNlbHNlCisJCXhwY3R4dC0+bmFtZXNwYWNlcyA9IGNvbXAtPm5zTGlzdDsKKwkJeHBjdHh0LT5uc05yID0gY29tcC0+bnNOcjsKKyNlbmRpZgorCSAgICB9IGVsc2UgeworCQl4cGN0eHQtPm5hbWVzcGFjZXMgPSBOVUxMOworCQl4cGN0eHQtPm5zTnIgPSAwOworCSAgICB9CisKKwkgICAgLyoKKwkgICAgKiBUaGlzIFhQYXRoIGZ1bmN0aW9uIGlzIG9wdGltaXplZCBmb3IgYm9vbGVhbiByZXN1bHRzLgorCSAgICAqLworCSAgICB4cG9iaiA9IHhtbFhQYXRoQ29tcGlsZWRFdmFsKGNvbXAtPmNvbXAsIHhwY3R4dCk7CisKKwkgICAgeHBjdHh0LT5kb2MgPSBvbGRYUENvbnRleHREb2M7CisJICAgIHhwY3R4dC0+bm9kZSA9IG9sZFhQQ29udGV4dE5vZGU7CisJICAgIHhwY3R4dC0+Y29udGV4dFNpemUgPSBvbGRYUENvbnRleHRTaXplOworCSAgICB4cGN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gb2xkWFBQcm94aW1pdHlQb3NpdGlvbjsKKwkgICAgeHBjdHh0LT5uc05yID0gb2xkWFBOc05yOworCSAgICB4cGN0eHQtPm5hbWVzcGFjZXMgPSBvbGRYUE5hbWVzcGFjZXM7CisJfQorCWlmICh4cG9iaiAhPSBOVUxMKSB7CisJICAgIGlmICh4cG9iai0+dHlwZSAhPSBYUEFUSF9CT09MRUFOKQorCQl4cG9iaiA9IHhtbFhQYXRoQ29udmVydEJvb2xlYW4oeHBvYmopOworCSAgICBpZiAoeHBvYmotPnR5cGUgPT0gWFBBVEhfQk9PTEVBTikgeworCQlyZXMgPSB4cG9iai0+Ym9vbHZhbDsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX0lGLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAieHNsdElmOiB0ZXN0IGV2YWx1YXRlIHRvICVkXG4iLCByZXMpKTsKKyNlbmRpZgorCQlpZiAocmVzKSB7CisJCSAgICB4c2x0QXBwbHlTZXF1ZW5jZUNvbnN0cnVjdG9yKGN0eHQsCisJCQljb250ZXh0Tm9kZSwgaW5zdC0+Y2hpbGRyZW4sIE5VTEwpOworCQl9CisJICAgIH0gZWxzZSB7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQlYU0xUX1RSQUNFKGN0eHQsIFhTTFRfVFJBQ0VfSUYsCisJCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgInhzbHRJZjogdGVzdCBkaWRuJ3QgZXZhbHVhdGUgdG8gYSBib29sZWFuXG4iKSk7CisjZW5kaWYKKwkJY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisJICAgIH0KKwkgICAgeG1sWFBhdGhGcmVlT2JqZWN0KHhwb2JqKTsKKwl9IGVsc2UgeworCSAgICBjdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwl9CisgICAgfQorI2VuZGlmIC8qIGVsc2Ugb2YgWFNMVF9GQVNUX0lGICovCisKK2Vycm9yOgorICAgIHJldHVybjsKK30KKworLyoqCisgKiB4c2x0Rm9yRWFjaDoKKyAqIEBjdHh0OiAgYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAY29udGV4dE5vZGU6ICB0aGUgImN1cnJlbnQgbm9kZSIgaW4gdGhlIHNvdXJjZSB0cmVlCisgKiBAaW5zdDogIHRoZSBlbGVtZW50IG5vZGUgb2YgdGhlIHhzbDpmb3ItZWFjaCBpbnN0cnVjdGlvbgorICogQGNhc3RlZENvbXA6ICB0aGUgY29tcGlsZWQgaW5mb3JtYXRpb24gb2YgdGhlIGluc3RydWN0aW9uCisgKgorICogUHJvY2VzcyB0aGUgeHNsdCBmb3ItZWFjaCBub2RlIG9uIHRoZSBzb3VyY2Ugbm9kZQorICovCit2b2lkCit4c2x0Rm9yRWFjaCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGNvbnRleHROb2RlLAorCSAgICB4bWxOb2RlUHRyIGluc3QsIHhzbHRTdHlsZVByZUNvbXBQdHIgY2FzdGVkQ29tcCkKK3sKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtRm9yRWFjaFB0ciBjb21wID0gKHhzbHRTdHlsZUl0ZW1Gb3JFYWNoUHRyKSBjYXN0ZWRDb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXAgPSBjYXN0ZWRDb21wOworI2VuZGlmCisgICAgaW50IGk7CisgICAgeG1sWFBhdGhPYmplY3RQdHIgcmVzID0gTlVMTDsKKyAgICB4bWxOb2RlUHRyIGN1ciwgY3VySW5zdDsKKyAgICB4bWxOb2RlU2V0UHRyIGxpc3QgPSBOVUxMOworICAgIHhtbE5vZGVTZXRQdHIgb2xkTGlzdDsKKyAgICBpbnQgb2xkWFBQcm94aW1pdHlQb3NpdGlvbiwgb2xkWFBDb250ZXh0U2l6ZTsKKyAgICB4bWxOb2RlUHRyIG9sZENvbnRleHROb2RlOworICAgIHhzbHRUZW1wbGF0ZVB0ciBvbGRDdXJUZW1wbFJ1bGU7CisgICAgeG1sRG9jUHRyIG9sZFhQRG9jOworICAgIHhzbHREb2N1bWVudFB0ciBvbGREb2NJbmZvOworICAgIHhtbFhQYXRoQ29udGV4dFB0ciB4cGN0eHQ7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGNvbnRleHROb2RlID09IE5VTEwpIHx8IChpbnN0ID09IE5VTEwpKSB7CisJeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkgICAgInhzbHRGb3JFYWNoKCk6IEJhZCBhcmd1bWVudHMuXG4iKTsKKwlyZXR1cm47CisgICAgfQorCisgICAgaWYgKGNvbXAgPT0gTlVMTCkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkgICAgIkludGVybmFsIGVycm9yIGluIHhzbHRGb3JFYWNoKCk6ICIKKwkgICAgIlRoZSBYU0xUICdmb3ItZWFjaCcgaW5zdHJ1Y3Rpb24gd2FzIG5vdCBjb21waWxlZC5cbiIpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmICgoY29tcC0+c2VsZWN0ID09IE5VTEwpIHx8IChjb21wLT5jb21wID09IE5VTEwpKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGluc3QsCisJICAgICJJbnRlcm5hbCBlcnJvciBpbiB4c2x0Rm9yRWFjaCgpOiAiCisJICAgICJUaGUgc2VsZWN0aW5nIGV4cHJlc3Npb24gb2YgdGhlIFhTTFQgJ2Zvci1lYWNoJyAiCisJICAgICJpbnN0cnVjdGlvbiB3YXMgbm90IGNvbXBpbGVkIGNvcnJlY3RseS5cbiIpOworCXJldHVybjsKKyAgICB9CisgICAgeHBjdHh0ID0gY3R4dC0+eHBhdGhDdHh0OworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKyAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9GT1JfRUFDSCx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAieHNsdEZvckVhY2g6IHNlbGVjdCAlc1xuIiwgY29tcC0+c2VsZWN0KSk7CisjZW5kaWYKKworICAgIC8qCisgICAgKiBTYXZlIGNvbnRleHQgc3RhdGVzLgorICAgICovCisgICAgb2xkRG9jSW5mbyA9IGN0eHQtPmRvY3VtZW50OworICAgIG9sZExpc3QgPSBjdHh0LT5ub2RlTGlzdDsKKyAgICBvbGRDb250ZXh0Tm9kZSA9IGN0eHQtPm5vZGU7CisgICAgLyoKKyAgICAqIFRoZSAiY3VycmVudCB0ZW1wbGF0ZSBydWxlIiBpcyBjbGVhcmVkIGZvciB0aGUgaW5zdGFudGlhdGlvbiBvZgorICAgICogeHNsOmZvci1lYWNoLgorICAgICovCisgICAgb2xkQ3VyVGVtcGxSdWxlID0gY3R4dC0+Y3VycmVudFRlbXBsYXRlUnVsZTsKKyAgICBjdHh0LT5jdXJyZW50VGVtcGxhdGVSdWxlID0gTlVMTDsKKworICAgIG9sZFhQRG9jID0geHBjdHh0LT5kb2M7CisgICAgb2xkWFBQcm94aW1pdHlQb3NpdGlvbiA9IHhwY3R4dC0+cHJveGltaXR5UG9zaXRpb247CisgICAgb2xkWFBDb250ZXh0U2l6ZSA9IHhwY3R4dC0+Y29udGV4dFNpemU7CisgICAgLyoKKyAgICAqIFNldCB1cCBYUGF0aC4KKyAgICAqLworICAgIHhwY3R4dC0+bm9kZSA9IGNvbnRleHROb2RlOworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIGlmIChjb21wLT5pblNjb3BlTnMgIT0gTlVMTCkgeworCXhwY3R4dC0+bmFtZXNwYWNlcyA9IGNvbXAtPmluU2NvcGVOcy0+bGlzdDsKKwl4cGN0eHQtPm5zTnIgPSBjb21wLT5pblNjb3BlTnMtPnhwYXRoTnVtYmVyOworICAgIH0gZWxzZSB7CisJeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwl4cGN0eHQtPm5zTnIgPSAwOworICAgIH0KKyNlbHNlCisgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gY29tcC0+bnNMaXN0OworICAgIHhwY3R4dC0+bnNOciA9IGNvbXAtPm5zTnI7CisjZW5kaWYKKworICAgIC8qCisgICAgKiBFdmFsdWF0ZSB0aGUgJ3NlbGVjdCcgZXhwcmVzc2lvbi4KKyAgICAqLworICAgIHJlcyA9IHhtbFhQYXRoQ29tcGlsZWRFdmFsKGNvbXAtPmNvbXAsIGN0eHQtPnhwYXRoQ3R4dCk7CisKKyAgICBpZiAocmVzICE9IE5VTEwpIHsKKwlpZiAocmVzLT50eXBlID09IFhQQVRIX05PREVTRVQpCisJICAgIGxpc3QgPSByZXMtPm5vZGVzZXR2YWw7CisJZWxzZSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCQkiVGhlICdzZWxlY3QnIGV4cHJlc3Npb24gZG9lcyBub3QgZXZhbHVhdGUgdG8gYSBub2RlIHNldC5cbiIpOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKwkgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfRk9SX0VBQ0gseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJInhzbHRGb3JFYWNoOiBzZWxlY3QgZGlkbid0IGV2YWx1YXRlIHRvIGEgbm9kZSBsaXN0XG4iKSk7CisjZW5kaWYKKwkgICAgZ290byBlcnJvcjsKKwl9CisgICAgfSBlbHNlIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkgICAgIkZhaWxlZCB0byBldmFsdWF0ZSB0aGUgJ3NlbGVjdCcgZXhwcmVzc2lvbi5cbiIpOworCWN0eHQtPnN0YXRlID0gWFNMVF9TVEFURV9TVE9QUEVEOworCWdvdG8gZXJyb3I7CisgICAgfQorCisgICAgaWYgKChsaXN0ID09IE5VTEwpIHx8IChsaXN0LT5ub2RlTnIgPD0gMCkpCisJZ290byBleGl0OworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKyAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9GT1JfRUFDSCx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJ4c2x0Rm9yRWFjaDogc2VsZWN0IGV2YWx1YXRlcyB0byAlZCBub2Rlc1xuIiwgbGlzdC0+bm9kZU5yKSk7CisjZW5kaWYKKworICAgIC8qCisgICAgKiBSZXN0b3JlIFhQYXRoIHN0YXRlcyBmb3IgdGhlICJjdXJyZW50IG5vZGUiLgorICAgICovCisgICAgeHBjdHh0LT5jb250ZXh0U2l6ZSA9IG9sZFhQQ29udGV4dFNpemU7CisgICAgeHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IG9sZFhQUHJveGltaXR5UG9zaXRpb247CisgICAgeHBjdHh0LT5ub2RlID0gY29udGV4dE5vZGU7CisKKyAgICAvKgorICAgICogU2V0IHRoZSBsaXN0OyB0aGlzIGhhcyB0byBiZSBkb25lIGFscmVhZHkgaGVyZSBmb3IgeHNsdERvU29ydEZ1bmN0aW9uKCkuCisgICAgKi8KKyAgICBjdHh0LT5ub2RlTGlzdCA9IGxpc3Q7CisgICAgLyoKKyAgICAqIEhhbmRsZSB4c2w6c29ydCBpbnN0cnVjdGlvbnMgYW5kIHNraXAgdGhlbSBmb3IgZnVydGhlciBwcm9jZXNzaW5nLgorICAgICogQlVHIFRPRE86IFdlIGFyZSBub3QgdXNpbmcgbmFtZXNwYWNlZCBwb3RlbnRpYWxseSBkZWZpbmVkIG9uIHRoZQorICAgICogeHNsOnNvcnQgZWxlbWVudDsgWFBhdGggZXhwcmVzc2lvbiBtaWdodCBmYWlsLgorICAgICovCisgICAgY3VySW5zdCA9IGluc3QtPmNoaWxkcmVuOworICAgIGlmIChJU19YU0xUX0VMRU0oY3VySW5zdCkgJiYgSVNfWFNMVF9OQU1FKGN1ckluc3QsICJzb3J0IikpIHsKKwlpbnQgbmJzb3J0cyA9IDA7CisJeG1sTm9kZVB0ciBzb3J0c1tYU0xUX01BWF9TT1JUXTsKKworCXNvcnRzW25ic29ydHMrK10gPSBjdXJJbnN0OworCisjaWZkZWYgV0lUSF9ERUJVR0dFUgorCWlmICh4c2xEZWJ1Z1N0YXR1cyAhPSBYU0xUX0RFQlVHX05PTkUpCisJICAgIHhzbEhhbmRsZURlYnVnZ2VyKGN1ckluc3QsIGNvbnRleHROb2RlLCBOVUxMLCBjdHh0KTsKKyNlbmRpZgorCisJY3VySW5zdCA9IGN1ckluc3QtPm5leHQ7CisJd2hpbGUgKElTX1hTTFRfRUxFTShjdXJJbnN0KSAmJiBJU19YU0xUX05BTUUoY3VySW5zdCwgInNvcnQiKSkgeworCSAgICBpZiAobmJzb3J0cyA+PSBYU0xUX01BWF9TT1JUKSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjdXJJbnN0LAorCQkgICAgIlRoZSBudW1iZXIgb2YgeHNsOnNvcnQgaW5zdHJ1Y3Rpb25zIGV4Y2VlZHMgdGhlICIKKwkJICAgICJtYXhpbXVtICglZCkgYWxsb3dlZCBieSB0aGlzIHByb2Nlc3Nvci5cbiIsCisJCSAgICBYU0xUX01BWF9TT1JUKTsKKwkJZ290byBlcnJvcjsKKwkgICAgfSBlbHNlIHsKKwkJc29ydHNbbmJzb3J0cysrXSA9IGN1ckluc3Q7CisJICAgIH0KKworI2lmZGVmIFdJVEhfREVCVUdHRVIKKwkgICAgaWYgKHhzbERlYnVnU3RhdHVzICE9IFhTTFRfREVCVUdfTk9ORSkKKwkJeHNsSGFuZGxlRGVidWdnZXIoY3VySW5zdCwgY29udGV4dE5vZGUsIE5VTEwsIGN0eHQpOworI2VuZGlmCisJICAgIGN1ckluc3QgPSBjdXJJbnN0LT5uZXh0OworCX0KKwl4c2x0RG9Tb3J0RnVuY3Rpb24oY3R4dCwgc29ydHMsIG5ic29ydHMpOworICAgIH0KKyAgICB4cGN0eHQtPmNvbnRleHRTaXplID0gbGlzdC0+bm9kZU5yOworICAgIC8qCisgICAgKiBJbnN0YW50aWF0ZSB0aGUgc2VxdWVuY2UgY29uc3RydWN0b3IgZm9yIGVhY2ggc2VsZWN0ZWQgbm9kZS4KKyAgICAqLworICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0LT5ub2RlTnI7IGkrKykgeworCWN1ciA9IGxpc3QtPm5vZGVUYWJbaV07CisJLyoKKwkqIFRoZSBzZWxlY3RlZCBub2RlIGJlY29tZXMgdGhlICJjdXJyZW50IG5vZGUiLgorCSovCisJY3R4dC0+bm9kZSA9IGN1cjsKKwkvKgorCSogQW4geHNsOmZvci1lYWNoIGNhbiBjaGFuZ2UgdGhlIGN1cnJlbnQgY29udGV4dCBkb2MuCisJKiBPUFRJTUlaRSBUT0RPOiBHZXQgcmlkIG9mIHRoZSBuZWVkIHRvIHNldCB0aGUgY29udGV4dCBkb2MuCisJKi8KKwlpZiAoKGN1ci0+dHlwZSAhPSBYTUxfTkFNRVNQQUNFX0RFQ0wpICYmIChjdXItPmRvYyAhPSBOVUxMKSkKKwkgICAgeHBjdHh0LT5kb2MgPSBjdXItPmRvYzsKKworCXhwY3R4dC0+cHJveGltaXR5UG9zaXRpb24gPSBpICsgMTsKKworCXhzbHRBcHBseVNlcXVlbmNlQ29uc3RydWN0b3IoY3R4dCwgY3VyLCBjdXJJbnN0LCBOVUxMKTsKKyAgICB9CisKK2V4aXQ6CitlcnJvcjoKKyAgICBpZiAocmVzICE9IE5VTEwpCisJeG1sWFBhdGhGcmVlT2JqZWN0KHJlcyk7CisgICAgLyoKKyAgICAqIFJlc3RvcmUgb2xkIHN0YXRlcy4KKyAgICAqLworICAgIGN0eHQtPmRvY3VtZW50ID0gb2xkRG9jSW5mbzsKKyAgICBjdHh0LT5ub2RlTGlzdCA9IG9sZExpc3Q7CisgICAgY3R4dC0+bm9kZSA9IG9sZENvbnRleHROb2RlOworICAgIGN0eHQtPmN1cnJlbnRUZW1wbGF0ZVJ1bGUgPSBvbGRDdXJUZW1wbFJ1bGU7CisKKyAgICB4cGN0eHQtPmRvYyA9IG9sZFhQRG9jOworICAgIHhwY3R4dC0+Y29udGV4dFNpemUgPSBvbGRYUENvbnRleHRTaXplOworICAgIHhwY3R4dC0+cHJveGltaXR5UG9zaXRpb24gPSBvbGRYUFByb3hpbWl0eVBvc2l0aW9uOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkJR2VuZXJpYyBpbnRlcmZhY2UJCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisjaWZkZWYgWFNMVF9HRU5FUkFURV9IVE1MX0RPQ1RZUEUKK3R5cGVkZWYgc3RydWN0IHhzbHRIVE1MVmVyc2lvbiB7CisgICAgY29uc3QgY2hhciAqdmVyc2lvbjsKKyAgICBjb25zdCBjaGFyICpwdWJsaWM7CisgICAgY29uc3QgY2hhciAqc3lzdGVtOworfSB4c2x0SFRNTFZlcnNpb247CisKK3N0YXRpYyB4c2x0SFRNTFZlcnNpb24geHNsdEhUTUxWZXJzaW9uc1tdID0geworICAgIHsgIjQuMDFmcmFtZSIsICItLy9XM0MvL0RURCBIVE1MIDQuMDEgRnJhbWVzZXQvL0VOIiwKKyAgICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0L2ZyYW1lc2V0LmR0ZCJ9LAorICAgIHsgIjQuMDFzdHJpY3QiLCAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxLy9FTiIsCisgICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMtaHRtbDQwMS0xOTk5MTIyNC9zdHJpY3QuZHRkIn0sCisgICAgeyAiNC4wMXRyYW5zIiwgIi0vL1czQy8vRFREIEhUTUwgNC4wMSBUcmFuc2l0aW9uYWwvL0VOIiwKKyAgICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi8xOTk5L1JFQy1odG1sNDAxLTE5OTkxMjI0L2xvb3NlLmR0ZCJ9LAorICAgIHsgIjQuMDEiLCAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIFRyYW5zaXRpb25hbC8vRU4iLAorICAgICAgImh0dHA6Ly93d3cudzMub3JnL1RSLzE5OTkvUkVDLWh0bWw0MDEtMTk5OTEyMjQvbG9vc2UuZHRkIn0sCisgICAgeyAiNC4wc3RyaWN0IiwgIi0vL1czQy8vRFREIEhUTUwgNC4wMS8vRU4iLAorICAgICAgImh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0L3N0cmljdC5kdGQifSwKKyAgICB7ICI0LjB0cmFucyIsICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFsLy9FTiIsCisgICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvbG9vc2UuZHRkIn0sCisgICAgeyAiNC4wZnJhbWUiLCAiLS8vVzNDLy9EVEQgSFRNTCA0LjAxIEZyYW1lc2V0Ly9FTiIsCisgICAgICAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQvZnJhbWVzZXQuZHRkIn0sCisgICAgeyAiNC4wIiwgIi0vL1czQy8vRFREIEhUTUwgNC4wMSBUcmFuc2l0aW9uYWwvL0VOIiwKKyAgICAgICJodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNC9sb29zZS5kdGQifSwKKyAgICB7ICIzLjIiLCAiLS8vVzNDLy9EVEQgSFRNTCAzLjIvL0VOIiwgTlVMTCB9Cit9OworCisvKioKKyAqIHhzbHRHZXRIVE1MSURzOgorICogQHZlcnNpb246ICB0aGUgdmVyc2lvbiBzdHJpbmcKKyAqIEBwdWJsaWNJRDogIHVzZWQgdG8gcmV0dXJuIHRoZSBwdWJsaWMgSUQKKyAqIEBzeXN0ZW1JRDogIHVzZWQgdG8gcmV0dXJuIHRoZSBzeXN0ZW0gSUQKKyAqCisgKiBSZXR1cm5zIC0xIGlmIG5vdCBmb3VuZCwgMCBvdGhlcndpc2UgYW5kIHRoZSBzeXN0ZW0gYW5kIHB1YmxpYworICogICAgICAgICBJZGVudGlmaWVyIGZvciB0aGlzIGdpdmVuIHZlcmlvbiBvZiBIVE1MCisgKi8KK3N0YXRpYyBpbnQKK3hzbHRHZXRIVE1MSURzKGNvbnN0IHhtbENoYXIgKnZlcnNpb24sIGNvbnN0IHhtbENoYXIgKipwdWJsaWNJRCwKKwkgICAgICAgICAgICBjb25zdCB4bWxDaGFyICoqc3lzdGVtSUQpIHsKKyAgICB1bnNpZ25lZCBpbnQgaTsKKyAgICBpZiAodmVyc2lvbiA9PSBOVUxMKQorCXJldHVybigtMSk7CisgICAgZm9yIChpID0gMDtpIDwgKHNpemVvZih4c2x0SFRNTFZlcnNpb25zKS9zaXplb2YoeHNsdEhUTUxWZXJzaW9uc1sxXSkpOworCSBpKyspIHsKKwlpZiAoIXhtbFN0cmNhc2VjbXAodmVyc2lvbiwKKwkJICAgICAgICAgICAoY29uc3QgeG1sQ2hhciAqKSB4c2x0SFRNTFZlcnNpb25zW2ldLnZlcnNpb24pKSB7CisJICAgIGlmIChwdWJsaWNJRCAhPSBOVUxMKQorCQkqcHVibGljSUQgPSAoY29uc3QgeG1sQ2hhciAqKSB4c2x0SFRNTFZlcnNpb25zW2ldLnB1YmxpYzsKKwkgICAgaWYgKHN5c3RlbUlEICE9IE5VTEwpCisJCSpzeXN0ZW1JRCA9IChjb25zdCB4bWxDaGFyICopIHhzbHRIVE1MVmVyc2lvbnNbaV0uc3lzdGVtOworCSAgICByZXR1cm4oMCk7CisJfQorICAgIH0KKyAgICByZXR1cm4oLTEpOworfQorI2VuZGlmCisKKy8qKgorICogeHNsdEFwcGx5U3RyaXBTcGFjZXM6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBub2RlOiAgdGhlIHJvb3Qgb2YgdGhlIFhNTCB0cmVlCisgKgorICogU3RyaXAgdGhlIHVud2FudGVkIGlnbm9yYWJsZSBzcGFjZXMgZnJvbSB0aGUgaW5wdXQgdHJlZQorICovCit2b2lkCit4c2x0QXBwbHlTdHJpcFNwYWNlcyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpIHsKKyAgICB4bWxOb2RlUHRyIGN1cnJlbnQ7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BST0NFU1MKKyAgICBpbnQgbmIgPSAwOworI2VuZGlmCisKKworICAgIGN1cnJlbnQgPSBub2RlOworICAgIHdoaWxlIChjdXJyZW50ICE9IE5VTEwpIHsKKwkvKgorCSAqIENsZWFudXAgY2hpbGRyZW4gZW1wdHkgbm9kZXMgaWYgYXNrZWQgZm9yCisJICovCisJaWYgKChJU19YU0xUX1JFQUxfTk9ERShjdXJyZW50KSkgJiYKKwkgICAgKGN1cnJlbnQtPmNoaWxkcmVuICE9IE5VTEwpICYmCisJICAgICh4c2x0RmluZEVsZW1TcGFjZUhhbmRsaW5nKGN0eHQsIGN1cnJlbnQpKSkgeworCSAgICB4bWxOb2RlUHRyIGRlbGV0ZSA9IE5VTEwsIGN1ciA9IGN1cnJlbnQtPmNoaWxkcmVuOworCisJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCQlpZiAoSVNfQkxBTktfTk9ERShjdXIpKQorCQkgICAgZGVsZXRlID0gY3VyOworCisJCWN1ciA9IGN1ci0+bmV4dDsKKwkJaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CisJCSAgICB4bWxVbmxpbmtOb2RlKGRlbGV0ZSk7CisJCSAgICB4bWxGcmVlTm9kZShkZWxldGUpOworCQkgICAgZGVsZXRlID0gTlVMTDsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQkgICAgbmIrKzsKKyNlbmRpZgorCQl9CisJICAgIH0KKwl9CisKKwkvKgorCSAqIFNraXAgdG8gbmV4dCBub2RlIGluIGRvY3VtZW50IG9yZGVyLgorCSAqLworCWlmIChub2RlLT50eXBlID09IFhNTF9FTlRJVFlfUkVGX05PREUpIHsKKwkgICAgLyogcHJvY2VzcyBkZWVwIGluIGVudGl0aWVzICovCisJICAgIHhzbHRBcHBseVN0cmlwU3BhY2VzKGN0eHQsIG5vZGUtPmNoaWxkcmVuKTsKKwl9CisJaWYgKChjdXJyZW50LT5jaGlsZHJlbiAhPSBOVUxMKSAmJgorICAgICAgICAgICAgKGN1cnJlbnQtPnR5cGUgIT0gWE1MX0VOVElUWV9SRUZfTk9ERSkpIHsKKwkgICAgY3VycmVudCA9IGN1cnJlbnQtPmNoaWxkcmVuOworCX0gZWxzZSBpZiAoY3VycmVudC0+bmV4dCAhPSBOVUxMKSB7CisJICAgIGN1cnJlbnQgPSBjdXJyZW50LT5uZXh0OworCX0gZWxzZSB7CisJICAgIGRvIHsKKwkJY3VycmVudCA9IGN1cnJlbnQtPnBhcmVudDsKKwkJaWYgKGN1cnJlbnQgPT0gTlVMTCkKKwkJICAgIGJyZWFrOworCQlpZiAoY3VycmVudCA9PSBub2RlKQorCQkgICAgZ290byBkb25lOworCQlpZiAoY3VycmVudC0+bmV4dCAhPSBOVUxMKSB7CisJCSAgICBjdXJyZW50ID0gY3VycmVudC0+bmV4dDsKKwkJICAgIGJyZWFrOworCQl9CisJICAgIH0gd2hpbGUgKGN1cnJlbnQgIT0gTlVMTCk7CisJfQorICAgIH0KKworZG9uZToKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1NUUklQX1NQQUNFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgInhzbHRBcHBseVN0cmlwU3BhY2VzOiByZW1vdmVkICVkIGlnbm9yYWJsZSBibGFuayBub2RlXG4iLCBuYikpOworI2VuZGlmCisgICAgcmV0dXJuOworfQorCitzdGF0aWMgaW50Cit4c2x0Q291bnRLZXlzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpCit7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CisgICAgeHNsdEtleURlZlB0ciBrZXlkOworCisgICAgaWYgKGN0eHQgPT0gTlVMTCkKKwlyZXR1cm4oLTEpOworCisgICAgLyoKKyAgICAqIERvIHdlIGhhdmUgdGhvc2UgbmFzdGx5IHRlbXBsYXRlcyB3aXRoIGEga2V5KCkgaW4gdGhlIG1hdGNoIHBhdHRlcm4/CisgICAgKi8KKyAgICBjdHh0LT5oYXNUZW1wbEtleVBhdHRlcm5zID0gMDsKKyAgICBzdHlsZSA9IGN0eHQtPnN0eWxlOworICAgIHdoaWxlIChzdHlsZSAhPSBOVUxMKSB7CisJaWYgKHN0eWxlLT5rZXlNYXRjaCAhPSBOVUxMKSB7CisJICAgIGN0eHQtPmhhc1RlbXBsS2V5UGF0dGVybnMgPSAxOworCSAgICBicmVhazsKKwl9CisJc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisgICAgfQorICAgIC8qCisgICAgKiBDb3VudCBudW1iZXIgb2Yga2V5IGRlY2xhcmF0aW9ucy4KKyAgICAqLworICAgIGN0eHQtPm5iS2V5cyA9IDA7CisgICAgc3R5bGUgPSBjdHh0LT5zdHlsZTsKKyAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworCWtleWQgPSBzdHlsZS0+a2V5czsKKwl3aGlsZSAoa2V5ZCkgeworCSAgICBjdHh0LT5uYktleXMrKzsKKwkgICAga2V5ZCA9IGtleWQtPm5leHQ7CisJfQorCXN0eWxlID0geHNsdE5leHRJbXBvcnQoc3R5bGUpOworICAgIH0KKyAgICByZXR1cm4oY3R4dC0+bmJLZXlzKTsKK30KKworLyoqCisgKiB4c2x0QXBwbHlTdHlsZXNoZWV0SW50ZXJuYWw6CisgKiBAc3R5bGU6ICBhIHBhcnNlZCBYU0xUIHN0eWxlc2hlZXQKKyAqIEBkb2M6ICBhIHBhcnNlZCBYTUwgZG9jdW1lbnQKKyAqIEBwYXJhbXM6ICBhIE5VTEwgdGVybWluYXRlZCBhcnJheSBvZiBwYXJhbWV0ZXJzIG5hbWVzL3ZhbHVlcyB0dXBsZXMKKyAqIEBvdXRwdXQ6ICB0aGUgdGFyZ2V0dGVkIG91dHB1dAorICogQHByb2ZpbGU6ICBwcm9maWxlIEZJTEUgKiBvdXRwdXQgb3IgTlVMTAorICogQHVzZXI6ICB1c2VyIHByb3ZpZGVkIHBhcmFtZXRlcgorICoKKyAqIEFwcGx5IHRoZSBzdHlsZXNoZWV0IHRvIHRoZSBkb2N1bWVudAorICogTk9URTogVGhpcyBtYXkgbGVhZCB0byBhIG5vbi13ZWxsZm9ybWVkIG91dHB1dCBYTUwgd2lzZSAhCisgKgorICogUmV0dXJucyB0aGUgcmVzdWx0IGRvY3VtZW50IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgorICovCitzdGF0aWMgeG1sRG9jUHRyCit4c2x0QXBwbHlTdHlsZXNoZWV0SW50ZXJuYWwoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbERvY1B0ciBkb2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqKnBhcmFtcywgY29uc3QgY2hhciAqb3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEUgKiBwcm9maWxlLCB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciB1c2VyQ3R4dCkKK3sKKyAgICB4bWxEb2NQdHIgcmVzID0gTlVMTDsKKyAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0ID0gTlVMTDsKKyAgICB4bWxOb2RlUHRyIHJvb3QsIG5vZGU7CisgICAgY29uc3QgeG1sQ2hhciAqbWV0aG9kOworICAgIGNvbnN0IHhtbENoYXIgKmRvY3R5cGVQdWJsaWM7CisgICAgY29uc3QgeG1sQ2hhciAqZG9jdHlwZVN5c3RlbTsKKyAgICBjb25zdCB4bWxDaGFyICp2ZXJzaW9uOworICAgIGNvbnN0IHhtbENoYXIgKmVuY29kaW5nOworICAgIHhzbHRTdGFja0VsZW1QdHIgdmFyaWFibGVzOworICAgIHhzbHRTdGFja0VsZW1QdHIgdnB0cjsKKworICAgIHhzbHRJbml0R2xvYmFscygpOworCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoZG9jID09IE5VTEwpKQorICAgICAgICByZXR1cm4gKE5VTEwpOworCisgICAgaWYgKHN0eWxlLT5pbnRlcm5hbGl6ZWQgPT0gMCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkgIlN0eWxlc2hlZXQgd2FzIG5vdCBmdWxseSBpbnRlcm5hbGl6ZWQgIVxuIik7CisjZW5kaWYKKyAgICB9CisgICAgaWYgKGRvYy0+aW50U3Vic2V0ICE9IE5VTEwpIHsKKwkvKgorCSAqIEF2b2lkIGhpdHRpbmcgdGhlIERURCB3aGVuIHNjYW5uaW5nIG5vZGVzCisJICogYnV0IGtlZXAgaXQgbGlua2VkIGFzIGRvYy0+aW50U3Vic2V0CisJICovCisJeG1sTm9kZVB0ciBjdXIgPSAoeG1sTm9kZVB0cikgZG9jLT5pbnRTdWJzZXQ7CisJaWYgKGN1ci0+bmV4dCAhPSBOVUxMKQorCSAgICBjdXItPm5leHQtPnByZXYgPSBjdXItPnByZXY7CisJaWYgKGN1ci0+cHJldiAhPSBOVUxMKQorCSAgICBjdXItPnByZXYtPm5leHQgPSBjdXItPm5leHQ7CisJaWYgKGRvYy0+Y2hpbGRyZW4gPT0gY3VyKQorCSAgICBkb2MtPmNoaWxkcmVuID0gY3VyLT5uZXh0OworCWlmIChkb2MtPmxhc3QgPT0gY3VyKQorCSAgICBkb2MtPmxhc3QgPSBjdXItPnByZXY7CisJY3VyLT5wcmV2ID0gY3VyLT5uZXh0ID0gTlVMTDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIENoZWNrIGZvciBYUGF0aCBkb2N1bWVudCBvcmRlciBhdmFpbGFiaWxpdHkKKyAgICAgKi8KKyAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKKyAgICBpZiAocm9vdCAhPSBOVUxMKSB7CisJaWYgKCgobG9uZykgcm9vdC0+Y29udGVudCkgPj0gMCAmJiAoeHNsRGVidWdTdGF0dXMgPT0gWFNMVF9ERUJVR19OT05FKSkKKwkgICAgeG1sWFBhdGhPcmRlckRvY0VsZW1zKGRvYyk7CisgICAgfQorCisgICAgaWYgKHVzZXJDdHh0ICE9IE5VTEwpCisJY3R4dCA9IHVzZXJDdHh0OworICAgIGVsc2UKKwljdHh0ID0geHNsdE5ld1RyYW5zZm9ybUNvbnRleHQoc3R5bGUsIGRvYyk7CisKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKE5VTEwpOworCisgICAgY3R4dC0+aW5pdGlhbENvbnRleHREb2MgPSBkb2M7CisgICAgY3R4dC0+aW5pdGlhbENvbnRleHROb2RlID0gKHhtbE5vZGVQdHIpIGRvYzsKKworICAgIGlmIChwcm9maWxlICE9IE5VTEwpCisgICAgICAgIGN0eHQtPnByb2ZpbGUgPSAxOworCisgICAgaWYgKG91dHB1dCAhPSBOVUxMKQorICAgICAgICBjdHh0LT5vdXRwdXRGaWxlID0gb3V0cHV0OworICAgIGVsc2UKKyAgICAgICAgY3R4dC0+b3V0cHV0RmlsZSA9IE5VTEw7CisKKyAgICAvKgorICAgICAqIGludGVybmFsaXplIHRoZSBtb2RlcyBpZiBuZWVkZWQKKyAgICAgKi8KKyAgICBpZiAoY3R4dC0+ZGljdCAhPSBOVUxMKSB7CisgICAgICAgIGlmIChjdHh0LT5tb2RlICE9IE5VTEwpCisJICAgIGN0eHQtPm1vZGUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIGN0eHQtPm1vZGUsIC0xKTsKKyAgICAgICAgaWYgKGN0eHQtPm1vZGVVUkkgIT0gTlVMTCkKKwkgICAgY3R4dC0+bW9kZVVSSSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgY3R4dC0+bW9kZVVSSSwgLTEpOworICAgIH0KKworICAgIFhTTFRfR0VUX0lNUE9SVF9QVFIobWV0aG9kLCBzdHlsZSwgbWV0aG9kKQorICAgIFhTTFRfR0VUX0lNUE9SVF9QVFIoZG9jdHlwZVB1YmxpYywgc3R5bGUsIGRvY3R5cGVQdWJsaWMpCisgICAgWFNMVF9HRVRfSU1QT1JUX1BUUihkb2N0eXBlU3lzdGVtLCBzdHlsZSwgZG9jdHlwZVN5c3RlbSkKKyAgICBYU0xUX0dFVF9JTVBPUlRfUFRSKHZlcnNpb24sIHN0eWxlLCB2ZXJzaW9uKQorICAgIFhTTFRfR0VUX0lNUE9SVF9QVFIoZW5jb2RpbmcsIHN0eWxlLCBlbmNvZGluZykKKworICAgIGlmICgobWV0aG9kICE9IE5VTEwpICYmCisJKCF4bWxTdHJFcXVhbChtZXRob2QsIChjb25zdCB4bWxDaGFyICopICJ4bWwiKSkpCisgICAgeworICAgICAgICBpZiAoeG1sU3RyRXF1YWwobWV0aG9kLCAoY29uc3QgeG1sQ2hhciAqKSAiaHRtbCIpKSB7CisgICAgICAgICAgICBjdHh0LT50eXBlID0gWFNMVF9PVVRQVVRfSFRNTDsKKyAgICAgICAgICAgIGlmICgoKGRvY3R5cGVQdWJsaWMgIT0gTlVMTCkgfHwgKGRvY3R5cGVTeXN0ZW0gIT0gTlVMTCkpKSB7CisgICAgICAgICAgICAgICAgcmVzID0gaHRtbE5ld0RvYyhkb2N0eXBlU3lzdGVtLCBkb2N0eXBlUHVibGljKTsKKwkgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBpZiAodmVyc2lvbiA9PSBOVUxMKSB7CisJCSAgICB4bWxEdGRQdHIgZHRkOworCisJCSAgICByZXMgPSBodG1sTmV3RG9jKE5VTEwsIE5VTEwpOworCQkgICAgLyoKKwkJICAgICogTWFrZSBzdXJlIG5vIERURCBub2RlIGlzIGdlbmVyYXRlZCBpbiB0aGlzIGNhc2UKKwkJICAgICovCisJCSAgICBpZiAocmVzICE9IE5VTEwpIHsKKwkJCWR0ZCA9IHhtbEdldEludFN1YnNldChyZXMpOworCQkJaWYgKGR0ZCAhPSBOVUxMKSB7CisJCQkgICAgeG1sVW5saW5rTm9kZSgoeG1sTm9kZVB0cikgZHRkKTsKKwkJCSAgICB4bWxGcmVlRHRkKGR0ZCk7CisJCQl9CisJCQlyZXMtPmludFN1YnNldCA9IE5VTEw7CisJCQlyZXMtPmV4dFN1YnNldCA9IE5VTEw7CisJCSAgICB9CisJCX0gZWxzZSB7CisKKyNpZmRlZiBYU0xUX0dFTkVSQVRFX0hUTUxfRE9DVFlQRQorCQkgICAgeHNsdEdldEhUTUxJRHModmVyc2lvbiwgJmRvY3R5cGVQdWJsaWMsICZkb2N0eXBlU3lzdGVtKTsKKyNlbmRpZgorCQkgICAgcmVzID0gaHRtbE5ld0RvYyhkb2N0eXBlU3lzdGVtLCBkb2N0eXBlUHVibGljKTsKKwkJfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisJICAgIHJlcy0+ZGljdCA9IGN0eHQtPmRpY3Q7CisJICAgIHhtbERpY3RSZWZlcmVuY2UocmVzLT5kaWN0KTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkicmV1c2luZyB0cmFuc2Zvcm1hdGlvbiBkaWN0IGZvciBvdXRwdXRcbiIpOworI2VuZGlmCisgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobWV0aG9kLCAoY29uc3QgeG1sQ2hhciAqKSAieGh0bWwiKSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgKHhtbE5vZGVQdHIpIGRvYywKKwkJInhzbHRBcHBseVN0eWxlc2hlZXRJbnRlcm5hbDogdW5zdXBwb3J0ZWQgbWV0aG9kIHhodG1sLCB1c2luZyBodG1sXG4iLAorCQlzdHlsZS0+bWV0aG9kKTsKKyAgICAgICAgICAgIGN0eHQtPnR5cGUgPSBYU0xUX09VVFBVVF9IVE1MOworICAgICAgICAgICAgcmVzID0gaHRtbE5ld0RvYyhkb2N0eXBlU3lzdGVtLCBkb2N0eXBlUHVibGljKTsKKyAgICAgICAgICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworCSAgICByZXMtPmRpY3QgPSBjdHh0LT5kaWN0OworCSAgICB4bWxEaWN0UmVmZXJlbmNlKHJlcy0+ZGljdCk7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKwkgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJInJldXNpbmcgdHJhbnNmb3JtYXRpb24gZGljdCBmb3Igb3V0cHV0XG4iKTsKKyNlbmRpZgorICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKG1ldGhvZCwgKGNvbnN0IHhtbENoYXIgKikgInRleHQiKSkgeworICAgICAgICAgICAgY3R4dC0+dHlwZSA9IFhTTFRfT1VUUFVUX1RFWFQ7CisgICAgICAgICAgICByZXMgPSB4bWxOZXdEb2Moc3R5bGUtPnZlcnNpb24pOworICAgICAgICAgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisJICAgIHJlcy0+ZGljdCA9IGN0eHQtPmRpY3Q7CisJICAgIHhtbERpY3RSZWZlcmVuY2UocmVzLT5kaWN0KTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkicmV1c2luZyB0cmFuc2Zvcm1hdGlvbiBkaWN0IGZvciBvdXRwdXRcbiIpOworI2VuZGlmCisgICAgICAgIH0gZWxzZSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCAoeG1sTm9kZVB0cikgZG9jLAorCQkieHNsdEFwcGx5U3R5bGVzaGVldEludGVybmFsOiB1bnN1cHBvcnRlZCBtZXRob2QgJXNcbiIsCisJCXN0eWxlLT5tZXRob2QpOworICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIGN0eHQtPnR5cGUgPSBYU0xUX09VVFBVVF9YTUw7CisgICAgICAgIHJlcyA9IHhtbE5ld0RvYyhzdHlsZS0+dmVyc2lvbik7CisgICAgICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisJcmVzLT5kaWN0ID0gY3R4dC0+ZGljdDsKKwl4bWxEaWN0UmVmZXJlbmNlKGN0eHQtPmRpY3QpOworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkgInJldXNpbmcgdHJhbnNmb3JtYXRpb24gZGljdCBmb3Igb3V0cHV0XG4iKTsKKyNlbmRpZgorICAgIH0KKyAgICByZXMtPmNoYXJzZXQgPSBYTUxfQ0hBUl9FTkNPRElOR19VVEY4OworICAgIGlmIChlbmNvZGluZyAhPSBOVUxMKQorICAgICAgICByZXMtPmVuY29kaW5nID0geG1sU3RyZHVwKGVuY29kaW5nKTsKKyAgICB2YXJpYWJsZXMgPSBzdHlsZS0+dmFyaWFibGVzOworCisgICAgLyoKKyAgICAgKiBTdGFydCB0aGUgZXZhbHVhdGlvbiwgZXZhbHVhdGUgdGhlIHBhcmFtcywgdGhlIHN0eWxlc2hlZXRzIGdsb2JhbHMKKyAgICAgKiBhbmQgc3RhcnQgYnkgcHJvY2Vzc2luZyB0aGUgdG9wIG5vZGUuCisgICAgICovCisgICAgaWYgKHhzbHROZWVkRWxlbVNwYWNlSGFuZGxpbmcoY3R4dCkpCisJeHNsdEFwcGx5U3RyaXBTcGFjZXMoY3R4dCwgeG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKSk7CisgICAgLyoKKyAgICAqIEV2YWx1YXRlIGdsb2JhbCBwYXJhbXMgYW5kIHVzZXItcHJvdmlkZWQgcGFyYW1zLgorICAgICovCisgICAgY3R4dC0+bm9kZSA9ICh4bWxOb2RlUHRyKSBkb2M7CisgICAgaWYgKGN0eHQtPmdsb2JhbFZhcnMgPT0gTlVMTCkKKwljdHh0LT5nbG9iYWxWYXJzID0geG1sSGFzaENyZWF0ZSgyMCk7CisgICAgaWYgKHBhcmFtcyAhPSBOVUxMKSB7CisgICAgICAgIHhzbHRFdmFsVXNlclBhcmFtcyhjdHh0LCBwYXJhbXMpOworICAgIH0KKworICAgIC8qIG5lZWQgdG8gYmUgY2FsbGVkIGJlZm9yZSBldmFsdWF0aW5nIGdsb2JhbCB2YXJpYWJsZXMgKi8KKyAgICB4c2x0Q291bnRLZXlzKGN0eHQpOworCisgICAgeHNsdEV2YWxHbG9iYWxWYXJpYWJsZXMoY3R4dCk7CisKKyAgICBjdHh0LT5ub2RlID0gKHhtbE5vZGVQdHIpIGRvYzsKKyAgICBjdHh0LT5vdXRwdXQgPSByZXM7CisgICAgY3R4dC0+aW5zZXJ0ID0gKHhtbE5vZGVQdHIpIHJlczsKKyAgICBjdHh0LT52YXJzQmFzZSA9IGN0eHQtPnZhcnNOciAtIDE7CisKKyAgICBjdHh0LT54cGF0aEN0eHQtPmNvbnRleHRTaXplID0gMTsKKyAgICBjdHh0LT54cGF0aEN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gMTsKKyAgICBjdHh0LT54cGF0aEN0eHQtPm5vZGUgPSBOVUxMOyAvKiBUT0RPOiBTZXQgdGhlIGNvbnRleHQgbm9kZSBoZXJlPyAqLworICAgIC8qCisgICAgKiBTdGFydCBwcm9jZXNzaW5nIHRoZSBzb3VyY2UgdHJlZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgICovCisgICAgeHNsdFByb2Nlc3NPbmVOb2RlKGN0eHQsIGN0eHQtPm5vZGUsIE5VTEwpOworICAgIC8qCisgICAgKiBSZW1vdmUgYWxsIHJlbWFpbmluZyB2YXJzIGZyb20gdGhlIHN0YWNrLgorICAgICovCisgICAgeHNsdExvY2FsVmFyaWFibGVQb3AoY3R4dCwgMCwgLTIpOworICAgIHhzbHRTaHV0ZG93bkN0eHRFeHRzKGN0eHQpOworCisgICAgeHNsdENsZWFudXBUZW1wbGF0ZXMoc3R5bGUpOyAvKiBUT0RPOiA8LSBzdHlsZSBzaG91bGQgYmUgcmVhZCBvbmx5ICovCisKKyAgICAvKgorICAgICAqIE5vdyBjbGVhbnVwIG91ciB2YXJpYWJsZXMgc28gc3R5bGVzaGVldCBjYW4gYmUgcmUtdXNlZAorICAgICAqCisgICAgICogVE9ETzogdGhpcyBpcyBub3QgbmVlZGVkIGFueW1vcmUgZ2xvYmFsIHZhcmlhYmxlcyBhcmUgY29waWVkCisgICAgICogICAgICAgYW5kIG5vdCBldmFsdWF0ZWQgZGlyZWN0bHkgYW55bW9yZSwga2VlcCB0aGlzIGFzIGEgY2hlY2sKKyAgICAgKi8KKyAgICBpZiAoc3R5bGUtPnZhcmlhYmxlcyAhPSB2YXJpYWJsZXMpIHsKKyAgICAgICAgdnB0ciA9IHN0eWxlLT52YXJpYWJsZXM7CisgICAgICAgIHdoaWxlICh2cHRyLT5uZXh0ICE9IHZhcmlhYmxlcykKKyAgICAgICAgICAgIHZwdHIgPSB2cHRyLT5uZXh0OworICAgICAgICB2cHRyLT5uZXh0ID0gTlVMTDsKKyAgICAgICAgeHNsdEZyZWVTdGFja0VsZW1MaXN0KHN0eWxlLT52YXJpYWJsZXMpOworICAgICAgICBzdHlsZS0+dmFyaWFibGVzID0gdmFyaWFibGVzOworICAgIH0KKyAgICB2cHRyID0gc3R5bGUtPnZhcmlhYmxlczsKKyAgICB3aGlsZSAodnB0ciAhPSBOVUxMKSB7CisgICAgICAgIGlmICh2cHRyLT5jb21wdXRlZCkgeworICAgICAgICAgICAgaWYgKHZwdHItPnZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICB4bWxYUGF0aEZyZWVPYmplY3QodnB0ci0+dmFsdWUpOworICAgICAgICAgICAgICAgIHZwdHItPnZhbHVlID0gTlVMTDsKKyAgICAgICAgICAgICAgICB2cHRyLT5jb21wdXRlZCA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgdnB0ciA9IHZwdHItPm5leHQ7CisgICAgfQorI2lmIDAKKyAgICAvKgorICAgICAqIGNvZGUgZGlzYWJsZWQgYnkgd21iOyBhd2FpdGluZyBrYidzIHJldmlldworICAgICAqIHByb2JsZW0gaXMgdGhhdCBnbG9iYWwgdmFyaWFibGUocykgbWF5IGNvbnRhaW4geHBhdGggb2JqZWN0cworICAgICAqIGZyb20gZG9jIGFzc29jaWF0ZWQgd2l0aCBSVlQsIHNvIGNhbid0IGJlIGZyZWVkIGF0IHRoaXMgcG9pbnQuCisgICAgICogeHNsdEZyZWVUcmFuc2Zvcm1Db250ZXh0IGluY2x1ZGVzIGEgY2FsbCB0byB4c2x0RnJlZVJWVHMsIHNvCisgICAgICogSSBhc3N1bWUgdGhpcyBzaG91bGRuJ3QgYmUgcmVxdWlyZWQgYXQgdGhpcyBwb2ludC4KKyAgICAgKi8KKyAgICAvKgorICAgICogRnJlZSBhbGwgcmVtYWluaW5nIHRyZWUgZnJhZ21lbnRzLgorICAgICovCisgICAgeHNsdEZyZWVSVlRzKGN0eHQpOworI2VuZGlmCisgICAgLyoKKyAgICAgKiBEbyBzb21lIHBvc3QgcHJvY2Vzc2luZyB3b3JrIGRlcGVuZGluZyBvbiB0aGUgZ2VuZXJhdGVkIG91dHB1dAorICAgICAqLworICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChyZXMpOworICAgIGlmIChyb290ICE9IE5VTEwpIHsKKyAgICAgICAgY29uc3QgeG1sQ2hhciAqZG9jdHlwZSA9IE5VTEw7CisKKyAgICAgICAgaWYgKChyb290LT5ucyAhPSBOVUxMKSAmJiAocm9vdC0+bnMtPnByZWZpeCAhPSBOVUxMKSkKKwkgICAgZG9jdHlwZSA9IHhtbERpY3RRTG9va3VwKGN0eHQtPmRpY3QsIHJvb3QtPm5zLT5wcmVmaXgsIHJvb3QtPm5hbWUpOworCWlmIChkb2N0eXBlID09IE5VTEwpCisJICAgIGRvY3R5cGUgPSByb290LT5uYW1lOworCisgICAgICAgIC8qCisgICAgICAgICAqIEFwcGx5IHRoZSBkZWZhdWx0IHNlbGVjdGlvbiBvZiB0aGUgbWV0aG9kCisgICAgICAgICAqLworICAgICAgICBpZiAoKG1ldGhvZCA9PSBOVUxMKSAmJgorICAgICAgICAgICAgKHJvb3QtPm5zID09IE5VTEwpICYmCisgICAgICAgICAgICAoIXhtbFN0cmNhc2VjbXAocm9vdC0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgImh0bWwiKSkpIHsKKyAgICAgICAgICAgIHhtbE5vZGVQdHIgdG1wOworCisgICAgICAgICAgICB0bXAgPSByZXMtPmNoaWxkcmVuOworICAgICAgICAgICAgd2hpbGUgKCh0bXAgIT0gTlVMTCkgJiYgKHRtcCAhPSByb290KSkgeworICAgICAgICAgICAgICAgIGlmICh0bXAtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgaWYgKCh0bXAtPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgJiYgKCF4bWxJc0JsYW5rTm9kZSh0bXApKSkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisJCXRtcCA9IHRtcC0+bmV4dDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh0bXAgPT0gcm9vdCkgeworICAgICAgICAgICAgICAgIGN0eHQtPnR5cGUgPSBYU0xUX09VVFBVVF9IVE1MOworCQkvKgorCQkqIFJFVklTSVQgVE9ETzogWE1MX0hUTUxfRE9DVU1FTlRfTk9ERSBpcyBzZXQgYWZ0ZXIgdGhlCisJCSogIHRyYW5zZm9ybWF0aW9uIG9uIHRoZSBkb2MsIGJ1dCBmdW5jdGlvbnMgbGlrZQorCQkqLworICAgICAgICAgICAgICAgIHJlcy0+dHlwZSA9IFhNTF9IVE1MX0RPQ1VNRU5UX05PREU7CisgICAgICAgICAgICAgICAgaWYgKCgoZG9jdHlwZVB1YmxpYyAhPSBOVUxMKSB8fCAoZG9jdHlwZVN5c3RlbSAhPSBOVUxMKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgcmVzLT5pbnRTdWJzZXQgPSB4bWxDcmVhdGVJbnRTdWJzZXQocmVzLCBkb2N0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N0eXBlUHVibGljLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N0eXBlU3lzdGVtKTsKKyNpZmRlZiBYU0xUX0dFTkVSQVRFX0hUTUxfRE9DVFlQRQorCQl9IGVsc2UgaWYgKHZlcnNpb24gIT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICB4c2x0R2V0SFRNTElEcyh2ZXJzaW9uLCAmZG9jdHlwZVB1YmxpYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRvY3R5cGVTeXN0ZW0pOworICAgICAgICAgICAgICAgICAgICBpZiAoKChkb2N0eXBlUHVibGljICE9IE5VTEwpIHx8IChkb2N0eXBlU3lzdGVtICE9IE5VTEwpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcy0+aW50U3Vic2V0ID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxDcmVhdGVJbnRTdWJzZXQocmVzLCBkb2N0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N0eXBlUHVibGljLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N0eXBlU3lzdGVtKTsKKyNlbmRpZgorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgICAgIGlmIChjdHh0LT50eXBlID09IFhTTFRfT1VUUFVUX1hNTCkgeworICAgICAgICAgICAgWFNMVF9HRVRfSU1QT1JUX1BUUihkb2N0eXBlUHVibGljLCBzdHlsZSwgZG9jdHlwZVB1YmxpYykKKyAgICAgICAgICAgIFhTTFRfR0VUX0lNUE9SVF9QVFIoZG9jdHlwZVN5c3RlbSwgc3R5bGUsIGRvY3R5cGVTeXN0ZW0pCisgICAgICAgICAgICBpZiAoKChkb2N0eXBlUHVibGljICE9IE5VTEwpIHx8IChkb2N0eXBlU3lzdGVtICE9IE5VTEwpKSkgeworCSAgICAgICAgeG1sTm9kZVB0ciBsYXN0OworCQkvKiBOZWVkIGEgc21hbGwgImhhY2siIGhlcmUgdG8gYXNzdXJlIERURCBjb21lcyBiZWZvcmUKKwkJICAgcG9zc2libGUgY29tbWVudCBub2RlcyAqLworCQlub2RlID0gcmVzLT5jaGlsZHJlbjsKKwkJbGFzdCA9IHJlcy0+bGFzdDsKKwkJcmVzLT5jaGlsZHJlbiA9IE5VTEw7CisJCXJlcy0+bGFzdCA9IE5VTEw7CisgICAgICAgICAgICAgICAgcmVzLT5pbnRTdWJzZXQgPSB4bWxDcmVhdGVJbnRTdWJzZXQocmVzLCBkb2N0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3R5cGVQdWJsaWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdHlwZVN5c3RlbSk7CisJCWlmIChyZXMtPmNoaWxkcmVuICE9IE5VTEwpIHsKKwkJICAgIHJlcy0+Y2hpbGRyZW4tPm5leHQgPSBub2RlOworCQkgICAgbm9kZS0+cHJldiA9IHJlcy0+Y2hpbGRyZW47CisJCSAgICByZXMtPmxhc3QgPSBsYXN0OworCQl9IGVsc2UgeworCQkgICAgcmVzLT5jaGlsZHJlbiA9IG5vZGU7CisJCSAgICByZXMtPmxhc3QgPSBsYXN0OworCQl9CisJICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICB4bWxYUGF0aEZyZWVOb2RlU2V0KGN0eHQtPm5vZGVMaXN0KTsKKyAgICBpZiAocHJvZmlsZSAhPSBOVUxMKSB7CisgICAgICAgIHhzbHRTYXZlUHJvZmlsaW5nKGN0eHQsIHByb2ZpbGUpOworICAgIH0KKworICAgIC8qCisgICAgICogQmUgcGVkYW50aWMuCisgICAgICovCisgICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT5zdGF0ZSA9PSBYU0xUX1NUQVRFX0VSUk9SKSkgeworCXhtbEZyZWVEb2MocmVzKTsKKwlyZXMgPSBOVUxMOworICAgIH0KKyAgICBpZiAoKHJlcyAhPSBOVUxMKSAmJiAoY3R4dCAhPSBOVUxMKSAmJiAob3V0cHV0ICE9IE5VTEwpKSB7CisJaW50IHJldDsKKworCXJldCA9IHhzbHRDaGVja1dyaXRlKGN0eHQtPnNlYywgY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgb3V0cHV0KTsKKwlpZiAocmV0ID09IDApIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIE5VTEwsCisJCSAgICAgInhzbHRBcHBseVN0eWxlc2hlZXQ6IGZvcmJpZGRlbiB0byBzYXZlIHRvICVzXG4iLAorCQkJICAgICAgIG91dHB1dCk7CisJfSBlbHNlIGlmIChyZXQgPCAwKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBOVUxMLAorCQkgICAgICJ4c2x0QXBwbHlTdHlsZXNoZWV0OiBzYXZpbmcgdG8gJXMgbWF5IG5vdCBiZSBwb3NzaWJsZVxuIiwKKwkJCSAgICAgICBvdXRwdXQpOworCX0KKyAgICB9CisKKyNpZmRlZiBYU0xUX0RFQlVHX1BST0ZJTEVfQ0FDSEUKKyAgICBwcmludGYoIiMgQ2FjaGU6XG4iKTsKKyAgICBwcmludGYoIiMgUmV1c2VkIHRyZWUgZnJhZ21lbnRzOiAlZFxuIiwgY3R4dC0+Y2FjaGUtPmRiZ1JldXNlZFJWVHMpOworICAgIHByaW50ZigiIyBSZXVzZWQgdmFyaWFibGVzICAgICA6ICVkXG4iLCBjdHh0LT5jYWNoZS0+ZGJnUmV1c2VkVmFycyk7CisjZW5kaWYKKworICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAodXNlckN0eHQgPT0gTlVMTCkpCisJeHNsdEZyZWVUcmFuc2Zvcm1Db250ZXh0KGN0eHQpOworCisgICAgcmV0dXJuIChyZXMpOworCitlcnJvcjoKKyAgICBpZiAocmVzICE9IE5VTEwpCisgICAgICAgIHhtbEZyZWVEb2MocmVzKTsKKworI2lmZGVmIFhTTFRfREVCVUdfUFJPRklMRV9DQUNIRQorICAgIHByaW50ZigiIyBDYWNoZTpcbiIpOworICAgIHByaW50ZigiIyBSZXVzZWQgdHJlZSBmcmFnbWVudHM6ICVkXG4iLCBjdHh0LT5jYWNoZS0+ZGJnUmV1c2VkUlZUcyk7CisgICAgcHJpbnRmKCIjIFJldXNlZCB2YXJpYWJsZXMgICAgIDogJWRcbiIsIGN0eHQtPmNhY2hlLT5kYmdSZXVzZWRWYXJzKTsKKyNlbmRpZgorCisgICAgaWYgKChjdHh0ICE9IE5VTEwpICYmICh1c2VyQ3R4dCA9PSBOVUxMKSkKKyAgICAgICAgeHNsdEZyZWVUcmFuc2Zvcm1Db250ZXh0KGN0eHQpOworICAgIHJldHVybiAoTlVMTCk7Cit9CisKKy8qKgorICogeHNsdEFwcGx5U3R5bGVzaGVldDoKKyAqIEBzdHlsZTogIGEgcGFyc2VkIFhTTFQgc3R5bGVzaGVldAorICogQGRvYzogIGEgcGFyc2VkIFhNTCBkb2N1bWVudAorICogQHBhcmFtczogIGEgTlVMTCB0ZXJtaW5hdGVkIGFycnkgb2YgcGFyYW1ldGVycyBuYW1lcy92YWx1ZXMgdHVwbGVzCisgKgorICogQXBwbHkgdGhlIHN0eWxlc2hlZXQgdG8gdGhlIGRvY3VtZW50CisgKiBOT1RFOiBUaGlzIG1heSBsZWFkIHRvIGEgbm9uLXdlbGxmb3JtZWQgb3V0cHV0IFhNTCB3aXNlICEKKyAqCisgKiBSZXR1cm5zIHRoZSByZXN1bHQgZG9jdW1lbnQgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3htbERvY1B0cgoreHNsdEFwcGx5U3R5bGVzaGVldCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sRG9jUHRyIGRvYywKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqKnBhcmFtcykKK3sKKyAgICByZXR1cm4gKHhzbHRBcHBseVN0eWxlc2hlZXRJbnRlcm5hbChzdHlsZSwgZG9jLCBwYXJhbXMsIE5VTEwsIE5VTEwsIE5VTEwpKTsKK30KKworLyoqCisgKiB4c2x0UHJvZmlsZVN0eWxlc2hlZXQ6CisgKiBAc3R5bGU6ICBhIHBhcnNlZCBYU0xUIHN0eWxlc2hlZXQKKyAqIEBkb2M6ICBhIHBhcnNlZCBYTUwgZG9jdW1lbnQKKyAqIEBwYXJhbXM6ICBhIE5VTEwgdGVybWluYXRlZCBhcnJ5IG9mIHBhcmFtZXRlcnMgbmFtZXMvdmFsdWVzIHR1cGxlcworICogQG91dHB1dDogIGEgRklMRSAqIGZvciB0aGUgcHJvZmlsaW5nIG91dHB1dAorICoKKyAqIEFwcGx5IHRoZSBzdHlsZXNoZWV0IHRvIHRoZSBkb2N1bWVudCBhbmQgZHVtcCB0aGUgcHJvZmlsaW5nIHRvCisgKiB0aGUgZ2l2ZW4gb3V0cHV0LgorICoKKyAqIFJldHVybnMgdGhlIHJlc3VsdCBkb2N1bWVudCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworeG1sRG9jUHRyCit4c2x0UHJvZmlsZVN0eWxlc2hlZXQoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbERvY1B0ciBkb2MsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqKnBhcmFtcywgRklMRSAqIG91dHB1dCkKK3sKKyAgICB4bWxEb2NQdHIgcmVzOworCisgICAgcmVzID0geHNsdEFwcGx5U3R5bGVzaGVldEludGVybmFsKHN0eWxlLCBkb2MsIHBhcmFtcywgTlVMTCwgb3V0cHV0LCBOVUxMKTsKKyAgICByZXR1cm4gKHJlcyk7Cit9CisKKy8qKgorICogeHNsdEFwcGx5U3R5bGVzaGVldFVzZXI6CisgKiBAc3R5bGU6ICBhIHBhcnNlZCBYU0xUIHN0eWxlc2hlZXQKKyAqIEBkb2M6ICBhIHBhcnNlZCBYTUwgZG9jdW1lbnQKKyAqIEBwYXJhbXM6ICBhIE5VTEwgdGVybWluYXRlZCBhcnJheSBvZiBwYXJhbWV0ZXJzIG5hbWVzL3ZhbHVlcyB0dXBsZXMKKyAqIEBvdXRwdXQ6ICB0aGUgdGFyZ2V0dGVkIG91dHB1dAorICogQHByb2ZpbGU6ICBwcm9maWxlIEZJTEUgKiBvdXRwdXQgb3IgTlVMTAorICogQHVzZXJDdHh0OiAgdXNlciBwcm92aWRlZCB0cmFuc2Zvcm0gY29udGV4dAorICoKKyAqIEFwcGx5IHRoZSBzdHlsZXNoZWV0IHRvIHRoZSBkb2N1bWVudCBhbmQgYWxsb3cgdGhlIHVzZXIgdG8gcHJvdmlkZQorICogaXRzIG93biB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0LgorICoKKyAqIFJldHVybnMgdGhlIHJlc3VsdCBkb2N1bWVudCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworeG1sRG9jUHRyCit4c2x0QXBwbHlTdHlsZXNoZWV0VXNlcih4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sRG9jUHRyIGRvYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICoqcGFyYW1zLCBjb25zdCBjaGFyICpvdXRwdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRSAqIHByb2ZpbGUsIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIHVzZXJDdHh0KQoreworICAgIHhtbERvY1B0ciByZXM7CisKKyAgICByZXMgPSB4c2x0QXBwbHlTdHlsZXNoZWV0SW50ZXJuYWwoc3R5bGUsIGRvYywgcGFyYW1zLCBvdXRwdXQsCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZmlsZSwgdXNlckN0eHQpOworICAgIHJldHVybiAocmVzKTsKK30KKworLyoqCisgKiB4c2x0UnVuU3R5bGVzaGVldFVzZXI6CisgKiBAc3R5bGU6ICBhIHBhcnNlZCBYU0xUIHN0eWxlc2hlZXQKKyAqIEBkb2M6ICBhIHBhcnNlZCBYTUwgZG9jdW1lbnQKKyAqIEBwYXJhbXM6ICBhIE5VTEwgdGVybWluYXRlZCBhcnJheSBvZiBwYXJhbWV0ZXJzIG5hbWVzL3ZhbHVlcyB0dXBsZXMKKyAqIEBvdXRwdXQ6ICB0aGUgVVJML2ZpbGVuYW1lIG90IHRoZSBnZW5lcmF0ZWQgcmVzb3VyY2UgaWYgYXZhaWxhYmxlCisgKiBAU0FYOiAgYSBTQVggaGFuZGxlciBmb3IgcHJvZ3Jlc3NpdmUgY2FsbGJhY2sgb3V0cHV0IChub3QgaW1wbGVtZW50ZWQgeWV0KQorICogQElPYnVmOiAgYW4gb3V0cHV0IGJ1ZmZlciBmb3IgcHJvZ3Jlc3NpdmUgb3V0cHV0IChub3QgaW1wbGVtZW50ZWQgeWV0KQorICogQHByb2ZpbGU6ICBwcm9maWxlIEZJTEUgKiBvdXRwdXQgb3IgTlVMTAorICogQHVzZXJDdHh0OiAgdXNlciBwcm92aWRlZCB0cmFuc2Zvcm0gY29udGV4dAorICoKKyAqIEFwcGx5IHRoZSBzdHlsZXNoZWV0IHRvIHRoZSBkb2N1bWVudCBhbmQgZ2VuZXJhdGUgdGhlIG91dHB1dCBhY2NvcmRpbmcKKyAqIHRvIEBvdXRwdXQgQFNBWCBhbmQgQElPYnVmLiBJdCdzIGFuIGVycm9yIHRvIHNwZWNpZnkgYm90aCBAU0FYIGFuZCBASU9idWYuCisgKgorICogTk9URTogVGhpcyBtYXkgbGVhZCB0byBhIG5vbi13ZWxsZm9ybWVkIG91dHB1dCBYTUwgd2lzZSAhCisgKiBOT1RFOiBUaGlzIG1heSBhbHNvIHJlc3VsdCBpbiBtdWx0aXBsZSBmaWxlcyBiZWluZyBnZW5lcmF0ZWQKKyAqIE5PVEU6IHVzaW5nIElPYnVmLCB0aGUgcmVzdWx0IGVuY29kaW5nIHVzZWQgd2lsbCBiZSB0aGUgb25lIHVzZWQgZm9yCisgKiAgICAgICBjcmVhdGluZyB0aGUgb3V0cHV0IGJ1ZmZlciwgdXNlIHRoZSBmb2xsb3dpbmcgbWFjcm8gdG8gcmVhZCBpdAorICogICAgICAgZnJvbSB0aGUgc3R5bGVzaGVldAorICogICAgICAgWFNMVF9HRVRfSU1QT1JUX1BUUihlbmNvZGluZywgc3R5bGUsIGVuY29kaW5nKQorICogTk9URTogdXNpbmcgU0FYLCBhbnkgZW5jb2Rpbmcgc3BlY2lmaWVkIGluIHRoZSBzdHlsZXNoZWV0IHdpbGwgYmUgbG9zdAorICogICAgICAgc2luY2UgdGhlIGludGVyZmFjZSB1c2VzIG9ubHkgVVRGOAorICoKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiBieSB3cml0dGVuIHRvIHRoZSBtYWluIHJlc291cmNlIG9yIC0xIGluIGNhc2Ugb2YKKyAqICAgICAgICAgZXJyb3IuCisgKi8KK2ludAoreHNsdFJ1blN0eWxlc2hlZXRVc2VyKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxEb2NQdHIgZG9jLAorICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqKnBhcmFtcywgY29uc3QgY2hhciAqb3V0cHV0LAorICAgICAgICAgICAgICAgICAgeG1sU0FYSGFuZGxlclB0ciBTQVgsIHhtbE91dHB1dEJ1ZmZlclB0ciBJT2J1ZiwKKwkJICBGSUxFICogcHJvZmlsZSwgeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgdXNlckN0eHQpCit7CisgICAgeG1sRG9jUHRyIHRtcDsKKyAgICBpbnQgcmV0OworCisgICAgaWYgKChvdXRwdXQgPT0gTlVMTCkgJiYgKFNBWCA9PSBOVUxMKSAmJiAoSU9idWYgPT0gTlVMTCkpCisgICAgICAgIHJldHVybiAoLTEpOworICAgIGlmICgoU0FYICE9IE5VTEwpICYmIChJT2J1ZiAhPSBOVUxMKSkKKyAgICAgICAgcmV0dXJuICgtMSk7CisKKyAgICAvKiB1bnN1cHBvcnRlZCB5ZXQgKi8KKyAgICBpZiAoU0FYICE9IE5VTEwpIHsKKyAgICAgICAgWFNMVF9UT0RPICAgLyogeHNsdFJ1blN0eWxlc2hlZXQgeG1sU0FYSGFuZGxlclB0ciBTQVggKi8KKwlyZXR1cm4gKC0xKTsKKyAgICB9CisKKyAgICB0bXAgPSB4c2x0QXBwbHlTdHlsZXNoZWV0SW50ZXJuYWwoc3R5bGUsIGRvYywgcGFyYW1zLCBvdXRwdXQsIHByb2ZpbGUsCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlckN0eHQpOworICAgIGlmICh0bXAgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgZG9jLAorICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0UnVuU3R5bGVzaGVldCA6IHJ1biBmYWlsZWRcbiIpOworICAgICAgICByZXR1cm4gKC0xKTsKKyAgICB9CisgICAgaWYgKElPYnVmICE9IE5VTEwpIHsKKyAgICAgICAgLyogVE9ETzogaW5jb21wbGV0ZSwgSU9idWYgb3V0cHV0IG5vdCBwcm9ncmVzc2l2ZSAqLworICAgICAgICByZXQgPSB4c2x0U2F2ZVJlc3VsdFRvKElPYnVmLCB0bXAsIHN0eWxlKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXQgPSB4c2x0U2F2ZVJlc3VsdFRvRmlsZW5hbWUob3V0cHV0LCB0bXAsIHN0eWxlLCAwKTsKKyAgICB9CisgICAgeG1sRnJlZURvYyh0bXApOworICAgIHJldHVybiAocmV0KTsKK30KKworLyoqCisgKiB4c2x0UnVuU3R5bGVzaGVldDoKKyAqIEBzdHlsZTogIGEgcGFyc2VkIFhTTFQgc3R5bGVzaGVldAorICogQGRvYzogIGEgcGFyc2VkIFhNTCBkb2N1bWVudAorICogQHBhcmFtczogIGEgTlVMTCB0ZXJtaW5hdGVkIGFycmF5IG9mIHBhcmFtZXRlcnMgbmFtZXMvdmFsdWVzIHR1cGxlcworICogQG91dHB1dDogIHRoZSBVUkwvZmlsZW5hbWUgb3QgdGhlIGdlbmVyYXRlZCByZXNvdXJjZSBpZiBhdmFpbGFibGUKKyAqIEBTQVg6ICBhIFNBWCBoYW5kbGVyIGZvciBwcm9ncmVzc2l2ZSBjYWxsYmFjayBvdXRwdXQgKG5vdCBpbXBsZW1lbnRlZCB5ZXQpCisgKiBASU9idWY6ICBhbiBvdXRwdXQgYnVmZmVyIGZvciBwcm9ncmVzc2l2ZSBvdXRwdXQgKG5vdCBpbXBsZW1lbnRlZCB5ZXQpCisgKgorICogQXBwbHkgdGhlIHN0eWxlc2hlZXQgdG8gdGhlIGRvY3VtZW50IGFuZCBnZW5lcmF0ZSB0aGUgb3V0cHV0IGFjY29yZGluZworICogdG8gQG91dHB1dCBAU0FYIGFuZCBASU9idWYuIEl0J3MgYW4gZXJyb3IgdG8gc3BlY2lmeSBib3RoIEBTQVggYW5kIEBJT2J1Zi4KKyAqCisgKiBOT1RFOiBUaGlzIG1heSBsZWFkIHRvIGEgbm9uLXdlbGxmb3JtZWQgb3V0cHV0IFhNTCB3aXNlICEKKyAqIE5PVEU6IFRoaXMgbWF5IGFsc28gcmVzdWx0IGluIG11bHRpcGxlIGZpbGVzIGJlaW5nIGdlbmVyYXRlZAorICogTk9URTogdXNpbmcgSU9idWYsIHRoZSByZXN1bHQgZW5jb2RpbmcgdXNlZCB3aWxsIGJlIHRoZSBvbmUgdXNlZCBmb3IKKyAqICAgICAgIGNyZWF0aW5nIHRoZSBvdXRwdXQgYnVmZmVyLCB1c2UgdGhlIGZvbGxvd2luZyBtYWNybyB0byByZWFkIGl0CisgKiAgICAgICBmcm9tIHRoZSBzdHlsZXNoZWV0CisgKiAgICAgICBYU0xUX0dFVF9JTVBPUlRfUFRSKGVuY29kaW5nLCBzdHlsZSwgZW5jb2RpbmcpCisgKiBOT1RFOiB1c2luZyBTQVgsIGFueSBlbmNvZGluZyBzcGVjaWZpZWQgaW4gdGhlIHN0eWxlc2hlZXQgd2lsbCBiZSBsb3N0CisgKiAgICAgICBzaW5jZSB0aGUgaW50ZXJmYWNlIHVzZXMgb25seSBVVEY4CisgKgorICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gdG8gdGhlIG1haW4gcmVzb3VyY2Ugb3IgLTEgaW4gY2FzZSBvZgorICogICAgICAgICBlcnJvci4KKyAqLworaW50Cit4c2x0UnVuU3R5bGVzaGVldCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sRG9jUHRyIGRvYywKKyAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKipwYXJhbXMsIGNvbnN0IGNoYXIgKm91dHB1dCwKKyAgICAgICAgICAgICAgICAgIHhtbFNBWEhhbmRsZXJQdHIgU0FYLCB4bWxPdXRwdXRCdWZmZXJQdHIgSU9idWYpCit7CisgICAgcmV0dXJuKHhzbHRSdW5TdHlsZXNoZWV0VXNlcihzdHlsZSwgZG9jLCBwYXJhbXMsIG91dHB1dCwgU0FYLCBJT2J1ZiwKKwkJICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKSk7Cit9CisKKy8qKgorICogeHNsdFJlZ2lzdGVyQWxsRWxlbWVudDoKKyAqIEBjdHh0OiAgdGhlIFhQYXRoIGNvbnRleHQKKyAqCisgKiBSZWdpc3RlcnMgYWxsIGRlZmF1bHQgWFNMVCBlbGVtZW50cyBpbiB0aGlzIGNvbnRleHQKKyAqLwordm9pZAoreHNsdFJlZ2lzdGVyQWxsRWxlbWVudCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KQoreworICAgIHhzbHRSZWdpc3RlckV4dEVsZW1lbnQoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgImFwcGx5LXRlbXBsYXRlcyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRBcHBseVRlbXBsYXRlcyk7CisgICAgeHNsdFJlZ2lzdGVyRXh0RWxlbWVudChjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAiYXBwbHktaW1wb3J0cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRBcHBseUltcG9ydHMpOworICAgIHhzbHRSZWdpc3RlckV4dEVsZW1lbnQoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgImNhbGwtdGVtcGxhdGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UsCisJCQkgICAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0Q2FsbFRlbXBsYXRlKTsKKyAgICB4c2x0UmVnaXN0ZXJFeHRFbGVtZW50KGN0eHQsIChjb25zdCB4bWxDaGFyICopICJlbGVtZW50IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRfTkFNRVNQQUNFLAorCQkJICAgKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdEVsZW1lbnQpOworICAgIHhzbHRSZWdpc3RlckV4dEVsZW1lbnQoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgImF0dHJpYnV0ZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRBdHRyaWJ1dGUpOworICAgIHhzbHRSZWdpc3RlckV4dEVsZW1lbnQoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgInRleHQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UsCisJCQkgICAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0VGV4dCk7CisgICAgeHNsdFJlZ2lzdGVyRXh0RWxlbWVudChjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24pOworICAgIHhzbHRSZWdpc3RlckV4dEVsZW1lbnQoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgImNvbW1lbnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UsCisJCQkgICAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0Q29tbWVudCk7CisgICAgeHNsdFJlZ2lzdGVyRXh0RWxlbWVudChjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAiY29weSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRDb3B5KTsKKyAgICB4c2x0UmVnaXN0ZXJFeHRFbGVtZW50KGN0eHQsIChjb25zdCB4bWxDaGFyICopICJ2YWx1ZS1vZiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRWYWx1ZU9mKTsKKyAgICB4c2x0UmVnaXN0ZXJFeHRFbGVtZW50KGN0eHQsIChjb25zdCB4bWxDaGFyICopICJudW1iZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UsCisJCQkgICAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0TnVtYmVyKTsKKyAgICB4c2x0UmVnaXN0ZXJFeHRFbGVtZW50KGN0eHQsIChjb25zdCB4bWxDaGFyICopICJmb3ItZWFjaCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRGb3JFYWNoKTsKKyAgICB4c2x0UmVnaXN0ZXJFeHRFbGVtZW50KGN0eHQsIChjb25zdCB4bWxDaGFyICopICJpZiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRJZik7CisgICAgeHNsdFJlZ2lzdGVyRXh0RWxlbWVudChjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAiY2hvb3NlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRfTkFNRVNQQUNFLAorCQkJICAgKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdENob29zZSk7CisgICAgeHNsdFJlZ2lzdGVyRXh0RWxlbWVudChjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAic29ydCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRTb3J0KTsKKyAgICB4c2x0UmVnaXN0ZXJFeHRFbGVtZW50KGN0eHQsIChjb25zdCB4bWxDaGFyICopICJjb3B5LW9mIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRfTkFNRVNQQUNFLAorCQkJICAgKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdENvcHlPZik7CisgICAgeHNsdFJlZ2lzdGVyRXh0RWxlbWVudChjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAibWVzc2FnZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHRNZXNzYWdlKTsKKworICAgIC8qCisgICAgICogVGhvc2UgZG9uJ3QgaGF2ZSBjYWxsYWJsZSBlbnRyeSBwb2ludHMgYnV0IGFyZSByZWdpc3RlcmVkIGFueXdheQorICAgICAqLworICAgIHhzbHRSZWdpc3RlckV4dEVsZW1lbnQoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgInZhcmlhYmxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFhTTFRfTkFNRVNQQUNFLAorCQkJICAgKHhzbHRUcmFuc2Zvcm1GdW5jdGlvbikgeHNsdERlYnVnKTsKKyAgICB4c2x0UmVnaXN0ZXJFeHRFbGVtZW50KGN0eHQsIChjb25zdCB4bWxDaGFyICopICJwYXJhbSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHREZWJ1Zyk7CisgICAgeHNsdFJlZ2lzdGVyRXh0RWxlbWVudChjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAid2l0aC1wYXJhbSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHREZWJ1Zyk7CisgICAgeHNsdFJlZ2lzdGVyRXh0RWxlbWVudChjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAiZGVjaW1hbC1mb3JtYXQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UsCisJCQkgICAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0RGVidWcpOworICAgIHhzbHRSZWdpc3RlckV4dEVsZW1lbnQoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgIndoZW4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UsCisJCQkgICAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0RGVidWcpOworICAgIHhzbHRSZWdpc3RlckV4dEVsZW1lbnQoY3R4dCwgKGNvbnN0IHhtbENoYXIgKikgIm90aGVyd2lzZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBYU0xUX05BTUVTUEFDRSwKKwkJCSAgICh4c2x0VHJhbnNmb3JtRnVuY3Rpb24pIHhzbHREZWJ1Zyk7CisgICAgeHNsdFJlZ2lzdGVyRXh0RWxlbWVudChjdHh0LCAoY29uc3QgeG1sQ2hhciAqKSAiZmFsbGJhY2siLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgWFNMVF9OQU1FU1BBQ0UsCisJCQkgICAoeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSB4c2x0RGVidWcpOworCit9CmRpZmYgLS1naXQgYS9saWJ4c2x0L3RyYW5zZm9ybS5oIGIvbGlieHNsdC90cmFuc2Zvcm0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yY2ZiZWMyCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC90cmFuc2Zvcm0uaApAQCAtMCwwICsxLDIwNyBAQAorLyoKKyAqIFN1bW1hcnk6IHRoZSBYU0xUIGVuZ2luZSB0cmFuc2Zvcm1hdGlvbiBwYXJ0LgorICogRGVzY3JpcHRpb246IFRoaXMgbW9kdWxlIGltcGxlbWVudHMgdGhlIGJ1bGsgb2YgdGhlIGFjdHVhbAorICogICAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uIHByb2Nlc3NpbmcuIE1vc3Qgb2YgdGhlIHhzbDogZWxlbWVudAorICogICAgICAgICAgICAgIGNvbnN0cnVjdHMgYXJlIGltcGxlbWVudGVkIGluIHRoaXMgbW9kdWxlLgorICoKKyAqIENvcHk6IFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBBdXRob3I6IERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVF9UUkFOU0ZPUk1fSF9fCisjZGVmaW5lIF9fWE1MX1hTTFRfVFJBTlNGT1JNX0hfXworCisjaW5jbHVkZSA8bGlieG1sL3BhcnNlci5oPgorI2luY2x1ZGUgPGxpYnhtbC94bWxJTy5oPgorI2luY2x1ZGUgInhzbHRleHBvcnRzLmgiCisjaW5jbHVkZSA8bGlieHNsdC94c2x0SW50ZXJuYWxzLmg+CisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyoqCisgKiBYSW5jbHVkZSBkZWZhdWx0IHByb2Nlc3NpbmcuCisgKi8KK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0U2V0WEluY2x1ZGVEZWZhdWx0CShpbnQgeGluY2x1ZGUpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwKKwkJeHNsdEdldFhJbmNsdWRlRGVmYXVsdAkodm9pZCk7CisKKy8qKgorICogRXhwb3J0IGNvbnRleHQgdG8gdXNlcnMuCisgKi8KK1hTTFRQVUJGVU4geHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgWFNMVENBTEwKKwkJeHNsdE5ld1RyYW5zZm9ybUNvbnRleHQJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgeG1sRG9jUHRyIGRvYyk7CisKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0RnJlZVRyYW5zZm9ybUNvbnRleHQoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCk7CisKK1hTTFRQVUJGVU4geG1sRG9jUHRyIFhTTFRDQUxMCisJCXhzbHRBcHBseVN0eWxlc2hlZXRVc2VyCSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKwkJCQkJIHhtbERvY1B0ciBkb2MsCisJCQkJCSBjb25zdCBjaGFyICoqcGFyYW1zLAorCQkJCQkgY29uc3QgY2hhciAqb3V0cHV0LAorCQkJCQkgRklMRSAqIHByb2ZpbGUsCisJCQkJCSB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciB1c2VyQ3R4dCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKyAgICAgICAgICAgICAgICB4c2x0UHJvY2Vzc09uZU5vZGUgICAgICAoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4c2x0U3RhY2tFbGVtUHRyIHBhcmFtcyk7CisvKioKKyAqIFByaXZhdGUgSW50ZXJmYWNlcy4KKyAqLworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRBcHBseVN0cmlwU3BhY2VzCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgeG1sTm9kZVB0ciBub2RlKTsKK1hTTFRQVUJGVU4geG1sRG9jUHRyIFhTTFRDQUxMCisJCXhzbHRBcHBseVN0eWxlc2hlZXQJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkgeG1sRG9jUHRyIGRvYywKKwkJCQkJIGNvbnN0IGNoYXIgKipwYXJhbXMpOworWFNMVFBVQkZVTiB4bWxEb2NQdHIgWFNMVENBTEwKKwkJeHNsdFByb2ZpbGVTdHlsZXNoZWV0CSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKwkJCQkJIHhtbERvY1B0ciBkb2MsCisJCQkJCSBjb25zdCBjaGFyICoqcGFyYW1zLAorCQkJCQkgRklMRSAqIG91dHB1dCk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQl4c2x0UnVuU3R5bGVzaGVldAkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSB4bWxEb2NQdHIgZG9jLAorCQkJCQkgY29uc3QgY2hhciAqKnBhcmFtcywKKwkJCQkJIGNvbnN0IGNoYXIgKm91dHB1dCwKKwkJCQkJIHhtbFNBWEhhbmRsZXJQdHIgU0FYLAorCQkJCQkgeG1sT3V0cHV0QnVmZmVyUHRyIElPYnVmKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCXhzbHRSdW5TdHlsZXNoZWV0VXNlcgkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCSB4bWxEb2NQdHIgZG9jLAorCQkJCQkgY29uc3QgY2hhciAqKnBhcmFtcywKKwkJCQkJIGNvbnN0IGNoYXIgKm91dHB1dCwKKwkJCQkJIHhtbFNBWEhhbmRsZXJQdHIgU0FYLAorCQkJCQkgeG1sT3V0cHV0QnVmZmVyUHRyIElPYnVmLAorCQkJCQkgRklMRSAqIHByb2ZpbGUsCisJCQkJCSB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciB1c2VyQ3R4dCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdEFwcGx5T25lVGVtcGxhdGUJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCSB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGxpc3QsCisJCQkJCSB4c2x0VGVtcGxhdGVQdHIgdGVtcGwsCisJCQkJCSB4c2x0U3RhY2tFbGVtUHRyIHBhcmFtcyk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdERvY3VtZW50RWxlbQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXApOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRTb3J0CQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXApOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRDb3B5CQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXApOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRUZXh0CQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXApOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRFbGVtZW50CQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXApOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRDb21tZW50CQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXApOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRBdHRyaWJ1dGUJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIHhtbE5vZGVQdHIgaW5zdCwKKwkJCQkJIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdFByb2Nlc3NpbmdJbnN0cnVjdGlvbih4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIHhtbE5vZGVQdHIgaW5zdCwKKwkJCQkJIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdENvcHlPZgkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAorCQkJCQkgeG1sTm9kZVB0ciBpbnN0LAorCQkJCQkgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0VmFsdWVPZgkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAorCQkJCQkgeG1sTm9kZVB0ciBpbnN0LAorCQkJCQkgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0TnVtYmVyCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXApOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRBcHBseUltcG9ydHMJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAorCQkJCQkgeG1sTm9kZVB0ciBpbnN0LAorCQkJCQkgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0Q2FsbFRlbXBsYXRlCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIHhtbE5vZGVQdHIgaW5zdCwKKwkJCQkJIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdEFwcGx5VGVtcGxhdGVzCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIHhtbE5vZGVQdHIgaW5zdCwKKwkJCQkJIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdENob29zZQkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAorCQkJCQkgeG1sTm9kZVB0ciBpbnN0LAorCQkJCQkgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0SWYJCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXApOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRGb3JFYWNoCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCSB4bWxOb2RlUHRyIGluc3QsCisJCQkJCSB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXApOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRSZWdpc3RlckFsbEVsZW1lbnQJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpOworCitYU0xUUFVCRlVOIHhtbE5vZGVQdHIgWFNMVENBTEwKKwkJeHNsdENvcHlUZXh0U3RyaW5nCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgeG1sTm9kZVB0ciB0YXJnZXQsCisJCQkJCSBjb25zdCB4bWxDaGFyICpzdHJpbmcsCisJCQkJCSBpbnQgbm9lc2NhcGUpOworCisvKiBGb2xsb3dpbmcgMiBmdW5jdGlvbnMgbmVlZGVkIGZvciBsaWJleHNsdC9mdW5jdGlvbnMuYyAqLworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRMb2NhbFZhcmlhYmxlUG9wCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgaW50IGxpbWl0TnIsCisJCQkJCSBpbnQgbGV2ZWwpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwKKwkJeHNsdExvY2FsVmFyaWFibGVQdXNoCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkgeHNsdFN0YWNrRWxlbVB0ciB2YXJpYWJsZSwKKwkJCQkJIGludCBsZXZlbCk7CisvKgorICogSG9vayBmb3IgdGhlIGRlYnVnZ2VyIGlmIGFjdGl2YXRlZC4KKyAqLworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbEhhbmRsZURlYnVnZ2VyCSh4bWxOb2RlUHRyIGN1ciwKKwkJCQkJIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJIHhzbHRUZW1wbGF0ZVB0ciB0ZW1wbCwKKwkJCQkJIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpOworCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19YTUxfWFNMVF9UUkFOU0ZPUk1fSF9fICovCisKZGlmZiAtLWdpdCBhL2xpYnhzbHQvdHJpby5oIGIvbGlieHNsdC90cmlvLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTQxYmRkMAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQvdHJpby5oCkBAIC0wLDAgKzEsMjE2IEBACisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoKKyAqICRJZCQKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDE5OTggQmpvcm4gUmVlc2UgYW5kIERhbmllbCBTdGVuYmVyZy4KKyAqCisgKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkKKyAqIHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUKKyAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMuCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIFdJVEhPVVQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRAorICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKKyAqIE1FUkNIQU5USUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFRIRSBBVVRIT1JTIEFORAorICogQ09OVFJJQlVUT1JTIEFDQ0VQVCBOTyBSRVNQT05TSUJJTElUWSBJTiBBTlkgQ09OQ0VJVkFCTEUgTUFOTkVSLgorICoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgorICogaHR0cDovL2N0cmlvLnNvdXJjZWZvcmdlLm5ldC8KKyAqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisjaWZuZGVmIFRSSU9fVFJJT19ICisjZGVmaW5lIFRSSU9fVFJJT19ICisKKyNpZiAhZGVmaW5lZChXSVRIT1VUX1RSSU8pCisKKy8qCisgKiBVc2UgYXV0b2NvbmYgZGVmaW5lcyBpZiBwcmVzZW50LiBQYWNrYWdlcyB1c2luZyB0cmlvIG11c3QgZGVmaW5lCisgKiBIQVZFX0NPTkZJR19IIGFzIGEgY29tcGlsZXIgb3B0aW9uIHRoZW1zZWx2ZXMuCisgKi8KKyNpZiBkZWZpbmVkKEhBVkVfQ09ORklHX0gpCisjIGluY2x1ZGUgPGNvbmZpZy5oPgorI2VuZGlmCisKKyNpbmNsdWRlICJ0cmlvZGVmLmgiCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2lmIGRlZmluZWQoVFJJT19DT01QSUxFUl9BTkNJRU5UKQorIyBpbmNsdWRlIDx2YXJhcmdzLmg+CisjZWxzZQorIyBpbmNsdWRlIDxzdGRhcmcuaD4KKyNlbmRpZgorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qCisgKiBFcnJvciBjb2Rlcy4KKyAqCisgKiBSZW1lbWJlciB0byBhZGQgYSB0ZXh0dWFsIGRlc2NyaXB0aW9uIHRvIHRyaW9fc3RyZXJyb3IuCisgKi8KK2VudW0geworICBUUklPX0VPRiAgICAgID0gMSwKKyAgVFJJT19FSU5WQUwgICA9IDIsCisgIFRSSU9fRVRPT01BTlkgPSAzLAorICBUUklPX0VEQkxSRUYgID0gNCwKKyAgVFJJT19FR0FQICAgICA9IDUsCisgIFRSSU9fRU5PTUVNICAgPSA2LAorICBUUklPX0VSQU5HRSAgID0gNywKKyAgVFJJT19FUlJOTyAgICA9IDgsCisgIFRSSU9fRUNVU1RPTSAgPSA5Cit9OworCisvKiBFcnJvciBtYWNyb3MgKi8KKyNkZWZpbmUgVFJJT19FUlJPUl9DT0RFKHgpICgoLSh4KSkgJiAweDAwRkYpCisjZGVmaW5lIFRSSU9fRVJST1JfUE9TSVRJT04oeCkgKCgtKHgpKSA+PiA4KQorI2RlZmluZSBUUklPX0VSUk9SX05BTUUoeCkgdHJpb19zdHJlcnJvcih4KQorCit0eXBlZGVmIGludCAoKnRyaW9fb3V0c3RyZWFtX3QpIFRSSU9fUFJPVE8oKHRyaW9fcG9pbnRlcl90LCBpbnQpKTsKK3R5cGVkZWYgaW50ICgqdHJpb19pbnN0cmVhbV90KSBUUklPX1BST1RPKCh0cmlvX3BvaW50ZXJfdCkpOworCitUUklPX0NPTlNUIGNoYXIgKnRyaW9fc3RyZXJyb3IgVFJJT19QUk9UTygoaW50KSk7CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiBQcmludCBGdW5jdGlvbnMKKyAqLworCitpbnQgdHJpb19wcmludGYgVFJJT19QUk9UTygoVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIC4uLikpOworaW50IHRyaW9fdnByaW50ZiBUUklPX1BST1RPKChUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgdmFfbGlzdCBhcmdzKSk7CitpbnQgdHJpb19wcmludGZ2IFRSSU9fUFJPVE8oKFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCB2b2lkICoqYXJncykpOworCitpbnQgdHJpb19mcHJpbnRmIFRSSU9fUFJPVE8oKEZJTEUgKmZpbGUsIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCAuLi4pKTsKK2ludCB0cmlvX3ZmcHJpbnRmIFRSSU9fUFJPVE8oKEZJTEUgKmZpbGUsIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCB2YV9saXN0IGFyZ3MpKTsKK2ludCB0cmlvX2ZwcmludGZ2IFRSSU9fUFJPVE8oKEZJTEUgKmZpbGUsIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCB2b2lkICoqYXJncykpOworCitpbnQgdHJpb19kcHJpbnRmIFRSSU9fUFJPVE8oKGludCBmZCwgVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIC4uLikpOworaW50IHRyaW9fdmRwcmludGYgVFJJT19QUk9UTygoaW50IGZkLCBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgdmFfbGlzdCBhcmdzKSk7CitpbnQgdHJpb19kcHJpbnRmdiBUUklPX1BST1RPKChpbnQgZmQsIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCB2b2lkICoqYXJncykpOworCitpbnQgdHJpb19jcHJpbnRmIFRSSU9fUFJPVE8oKHRyaW9fb3V0c3RyZWFtX3Qgc3RyZWFtLCB0cmlvX3BvaW50ZXJfdCBjbG9zdXJlLAorCQkJICAgICBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgLi4uKSk7CitpbnQgdHJpb192Y3ByaW50ZiBUUklPX1BST1RPKCh0cmlvX291dHN0cmVhbV90IHN0cmVhbSwgdHJpb19wb2ludGVyX3QgY2xvc3VyZSwKKwkJCSAgICAgIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCB2YV9saXN0IGFyZ3MpKTsKK2ludCB0cmlvX2NwcmludGZ2IFRSSU9fUFJPVE8oKHRyaW9fb3V0c3RyZWFtX3Qgc3RyZWFtLCB0cmlvX3BvaW50ZXJfdCBjbG9zdXJlLAorCQkJICAgICAgVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIHZvaWQgKiphcmdzKSk7CisKK2ludCB0cmlvX3NwcmludGYgVFJJT19QUk9UTygoY2hhciAqYnVmZmVyLCBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgLi4uKSk7CitpbnQgdHJpb192c3ByaW50ZiBUUklPX1BST1RPKChjaGFyICpidWZmZXIsIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCB2YV9saXN0IGFyZ3MpKTsKK2ludCB0cmlvX3NwcmludGZ2IFRSSU9fUFJPVE8oKGNoYXIgKmJ1ZmZlciwgVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIHZvaWQgKiphcmdzKSk7CisKK2ludCB0cmlvX3NucHJpbnRmIFRSSU9fUFJPVE8oKGNoYXIgKmJ1ZmZlciwgc2l6ZV90IG1heCwgVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIC4uLikpOworaW50IHRyaW9fdnNucHJpbnRmIFRSSU9fUFJPVE8oKGNoYXIgKmJ1ZmZlciwgc2l6ZV90IGJ1ZmZlclNpemUsIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LAorCQkgICB2YV9saXN0IGFyZ3MpKTsKK2ludCB0cmlvX3NucHJpbnRmdiBUUklPX1BST1RPKChjaGFyICpidWZmZXIsIHNpemVfdCBidWZmZXJTaXplLCBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwKKwkJICAgdm9pZCAqKmFyZ3MpKTsKKworaW50IHRyaW9fc25wcmludGZjYXQgVFJJT19QUk9UTygoY2hhciAqYnVmZmVyLCBzaXplX3QgbWF4LCBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgLi4uKSk7CitpbnQgdHJpb192c25wcmludGZjYXQgVFJJT19QUk9UTygoY2hhciAqYnVmZmVyLCBzaXplX3QgYnVmZmVyU2l6ZSwgVFJJT19DT05TVCBjaGFyICpmb3JtYXQsCisgICAgICAgICAgICAgICAgICAgICAgdmFfbGlzdCBhcmdzKSk7CisKK2NoYXIgKnRyaW9fYXByaW50ZiBUUklPX1BST1RPKChUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgLi4uKSk7CitjaGFyICp0cmlvX3ZhcHJpbnRmIFRSSU9fUFJPVE8oKFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCB2YV9saXN0IGFyZ3MpKTsKKworaW50IHRyaW9fYXNwcmludGYgVFJJT19QUk9UTygoY2hhciAqKnJldCwgVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIC4uLikpOworaW50IHRyaW9fdmFzcHJpbnRmIFRSSU9fUFJPVE8oKGNoYXIgKipyZXQsIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCB2YV9saXN0IGFyZ3MpKTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIFNjYW4gRnVuY3Rpb25zCisgKi8KK2ludCB0cmlvX3NjYW5mIFRSSU9fUFJPVE8oKFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCAuLi4pKTsKK2ludCB0cmlvX3ZzY2FuZiBUUklPX1BST1RPKChUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgdmFfbGlzdCBhcmdzKSk7CitpbnQgdHJpb19zY2FuZnYgVFJJT19QUk9UTygoVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIHZvaWQgKiphcmdzKSk7CisKK2ludCB0cmlvX2ZzY2FuZiBUUklPX1BST1RPKChGSUxFICpmaWxlLCBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgLi4uKSk7CitpbnQgdHJpb192ZnNjYW5mIFRSSU9fUFJPVE8oKEZJTEUgKmZpbGUsIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCB2YV9saXN0IGFyZ3MpKTsKK2ludCB0cmlvX2ZzY2FuZnYgVFJJT19QUk9UTygoRklMRSAqZmlsZSwgVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIHZvaWQgKiphcmdzKSk7CisKK2ludCB0cmlvX2RzY2FuZiBUUklPX1BST1RPKChpbnQgZmQsIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCAuLi4pKTsKK2ludCB0cmlvX3Zkc2NhbmYgVFJJT19QUk9UTygoaW50IGZkLCBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgdmFfbGlzdCBhcmdzKSk7CitpbnQgdHJpb19kc2NhbmZ2IFRSSU9fUFJPVE8oKGludCBmZCwgVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIHZvaWQgKiphcmdzKSk7CisKK2ludCB0cmlvX2NzY2FuZiBUUklPX1BST1RPKCh0cmlvX2luc3RyZWFtX3Qgc3RyZWFtLCB0cmlvX3BvaW50ZXJfdCBjbG9zdXJlLAorCQkJICAgIFRSSU9fQ09OU1QgY2hhciAqZm9ybWF0LCAuLi4pKTsKK2ludCB0cmlvX3Zjc2NhbmYgVFJJT19QUk9UTygodHJpb19pbnN0cmVhbV90IHN0cmVhbSwgdHJpb19wb2ludGVyX3QgY2xvc3VyZSwKKwkJCSAgICAgVFJJT19DT05TVCBjaGFyICpmb3JtYXQsIHZhX2xpc3QgYXJncykpOworaW50IHRyaW9fY3NjYW5mdiBUUklPX1BST1RPKCh0cmlvX2luc3RyZWFtX3Qgc3RyZWFtLCB0cmlvX3BvaW50ZXJfdCBjbG9zdXJlLAorCQkJICAgICBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgdm9pZCAqKmFyZ3MpKTsKKworaW50IHRyaW9fc3NjYW5mIFRSSU9fUFJPVE8oKFRSSU9fQ09OU1QgY2hhciAqYnVmZmVyLCBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgLi4uKSk7CitpbnQgdHJpb192c3NjYW5mIFRSSU9fUFJPVE8oKFRSSU9fQ09OU1QgY2hhciAqYnVmZmVyLCBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgdmFfbGlzdCBhcmdzKSk7CitpbnQgdHJpb19zc2NhbmZ2IFRSSU9fUFJPVE8oKFRSSU9fQ09OU1QgY2hhciAqYnVmZmVyLCBUUklPX0NPTlNUIGNoYXIgKmZvcm1hdCwgdm9pZCAqKmFyZ3MpKTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIExvY2FsZSBGdW5jdGlvbnMKKyAqLwordm9pZCB0cmlvX2xvY2FsZV9zZXRfZGVjaW1hbF9wb2ludCBUUklPX1BST1RPKChjaGFyICpkZWNpbWFsUG9pbnQpKTsKK3ZvaWQgdHJpb19sb2NhbGVfc2V0X3Rob3VzYW5kX3NlcGFyYXRvciBUUklPX1BST1RPKChjaGFyICp0aG91c2FuZFNlcGFyYXRvcikpOwordm9pZCB0cmlvX2xvY2FsZV9zZXRfZ3JvdXBpbmcgVFJJT19QUk9UTygoY2hhciAqZ3JvdXBpbmcpKTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIFJlbmFtaW5nCisgKi8KKyNpZmRlZiBUUklPX1JFUExBQ0VfU1RESU8KKy8qIFJlcGxhY2UgdGhlIDxzdGRpby5oPiBmdW5jdGlvbnMgKi8KKyNpZm5kZWYgSEFWRV9QUklOVEYKKyMgZGVmaW5lIHByaW50ZiB0cmlvX3ByaW50ZgorI2VuZGlmCisjaWZuZGVmIEhBVkVfVlBSSU5URgorIyBkZWZpbmUgdnByaW50ZiB0cmlvX3ZwcmludGYKKyNlbmRpZgorI2lmbmRlZiBIQVZFX0ZQUklOVEYKKyMgZGVmaW5lIGZwcmludGYgdHJpb19mcHJpbnRmCisjZW5kaWYKKyNpZm5kZWYgSEFWRV9WRlBSSU5URgorIyBkZWZpbmUgdmZwcmludGYgdHJpb192ZnByaW50ZgorI2VuZGlmCisjaWZuZGVmIEhBVkVfU1BSSU5URgorIyBkZWZpbmUgc3ByaW50ZiB0cmlvX3NwcmludGYKKyNlbmRpZgorI2lmbmRlZiBIQVZFX1ZTUFJJTlRGCisjIGRlZmluZSB2c3ByaW50ZiB0cmlvX3ZzcHJpbnRmCisjZW5kaWYKKyNpZm5kZWYgSEFWRV9TTlBSSU5URgorIyBkZWZpbmUgc25wcmludGYgdHJpb19zbnByaW50ZgorI2VuZGlmCisjaWZuZGVmIEhBVkVfVlNOUFJJTlRGCisjIGRlZmluZSB2c25wcmludGYgdHJpb192c25wcmludGYKKyNlbmRpZgorI2lmbmRlZiBIQVZFX1NDQU5GCisjIGRlZmluZSBzY2FuZiB0cmlvX3NjYW5mCisjZW5kaWYKKyNpZm5kZWYgSEFWRV9WU0NBTkYKKyMgZGVmaW5lIHZzY2FuZiB0cmlvX3ZzY2FuZgorI2VuZGlmCisjaWZuZGVmIEhBVkVfRlNDQU5GCisjIGRlZmluZSBmc2NhbmYgdHJpb19mc2NhbmYKKyNlbmRpZgorI2lmbmRlZiBIQVZFX1ZGU0NBTkYKKyMgZGVmaW5lIHZmc2NhbmYgdHJpb192ZnNjYW5mCisjZW5kaWYKKyNpZm5kZWYgSEFWRV9TU0NBTkYKKyMgZGVmaW5lIHNzY2FuZiB0cmlvX3NzY2FuZgorI2VuZGlmCisjaWZuZGVmIEhBVkVfVlNTQ0FORgorIyBkZWZpbmUgdnNzY2FuZiB0cmlvX3Zzc2NhbmYKKyNlbmRpZgorLyogVGhlc2UgYXJlbid0IHN0ZGlvIGZ1bmN0aW9ucywgYnV0IHdlIG1ha2UgdGhlbSBsb29rIHNpbWlsYXIgKi8KKyNkZWZpbmUgZHByaW50ZiB0cmlvX2RwcmludGYKKyNkZWZpbmUgdmRwcmludGYgdHJpb192ZHByaW50ZgorI2RlZmluZSBhcHJpbnRmIHRyaW9fYXByaW50ZgorI2RlZmluZSB2YXByaW50ZiB0cmlvX3ZhcHJpbnRmCisjZGVmaW5lIGFzcHJpbnRmIHRyaW9fYXNwcmludGYKKyNkZWZpbmUgdmFzcHJpbnRmIHRyaW9fdmFzcHJpbnRmCisjZGVmaW5lIGRzY2FuZiB0cmlvX2RzY2FuZgorI2RlZmluZSB2ZHNjYW5mIHRyaW9fdmRzY2FuZgorI2VuZGlmCisKKyNpZmRlZiBfX2NwbHVzcGx1cworfSAvKiBleHRlcm4gIkMiICovCisjZW5kaWYKKworI2VuZGlmIC8qIFdJVEhPVVRfVFJJTyAqLworCisjZW5kaWYgLyogVFJJT19UUklPX0ggKi8KZGlmZiAtLWdpdCBhL2xpYnhzbHQvdHJpb2RlZi5oIGIvbGlieHNsdC90cmlvZGVmLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZkMzJmYgotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQvdHJpb2RlZi5oCkBAIC0wLDAgKzEsMjIwIEBACisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoKKyAqICRJZCQKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIwMDEgQmpvcm4gUmVlc2UgPGJyZWVzZUB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQ+CisgKgorICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55CisgKiBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlCisgKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzLgorICoKKyAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBXSVRIT1VUIEFOWSBFWFBSRVNTIE9SIElNUExJRUQKKyAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GCisgKiBNRVJDSEFOVElCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBUSEUgQVVUSE9SUyBBTkQKKyAqIENPTlRSSUJVVE9SUyBBQ0NFUFQgTk8gUkVTUE9OU0lCSUxJVFkgSU4gQU5ZIENPTkNFSVZBQkxFIE1BTk5FUi4KKyAqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisjaWZuZGVmIFRSSU9fVFJJT0RFRl9ICisjZGVmaW5lIFRSSU9fVFJJT0RFRl9ICisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiBQbGF0Zm9ybSBhbmQgY29tcGlsZXIgc3VwcG9ydCBkZXRlY3Rpb24KKyAqLworI2lmIGRlZmluZWQoX19HTlVDX18pCisjIGRlZmluZSBUUklPX0NPTVBJTEVSX0dDQworI2VsaWYgZGVmaW5lZChfX1NVTlBST19DKQorIyBkZWZpbmUgVFJJT19DT01QSUxFUl9TVU5QUk8KKyNlbGlmIGRlZmluZWQoX19TVU5QUk9fQ0MpCisjIGRlZmluZSBUUklPX0NPTVBJTEVSX1NVTlBSTworIyBkZWZpbmUgX19TVU5QUk9fQyBfX1NVTlBST19DQworI2VsaWYgZGVmaW5lZChfX3hsQ19fKSB8fCBkZWZpbmVkKF9fSUJNQ19fKSB8fCBkZWZpbmVkKF9fSUJNQ1BQX18pCisjIGRlZmluZSBUUklPX0NPTVBJTEVSX1hMQworI2VsaWYgZGVmaW5lZChfQUlYKSAmJiAhZGVmaW5lZChfX0dOVUNfXykKKyMgZGVmaW5lIFRSSU9fQ09NUElMRVJfWExDIC8qIFdvcmthcm91bmQgZm9yIG9sZCB4bGMgKi8KKyNlbGlmIGRlZmluZWQoX19ERUNDKSB8fCBkZWZpbmVkKF9fREVDQ1hYKQorIyBkZWZpbmUgVFJJT19DT01QSUxFUl9ERUNDCisjZWxpZiBkZWZpbmVkKF9fb3NmX18pICYmIGRlZmluZWQoX19MQU5HVUFHRV9DX18pCisjIGRlZmluZSBUUklPX0NPTVBJTEVSX0RFQ0MgLyogV29ya2Fyb3VuZCBmb3Igb2xkIERFQyBDIGNvbXBpbGVycyAqLworI2VsaWYgZGVmaW5lZChfTVNDX1ZFUikKKyMgZGVmaW5lIFRSSU9fQ09NUElMRVJfTVNWQworI2VsaWYgZGVmaW5lZChfX0JPUkxBTkRDX18pCisjIGRlZmluZSBUUklPX0NPTVBJTEVSX0JDQgorI2VuZGlmCisKKyNpZiBkZWZpbmVkKFZNUykgfHwgZGVmaW5lZChfX1ZNUykKKy8qCisgKiBWTVMgaXMgcGxhY2VkIGZpcnN0IHRvIGF2b2lkIGlkZW50aWZ5aW5nIHRoZSBwbGF0Zm9ybSBhcyBVbml4CisgKiBiYXNlZCBvbiB0aGUgREVDQyBjb21waWxlciBsYXRlciBvbi4KKyAqLworIyBkZWZpbmUgVFJJT19QTEFURk9STV9WTVMKKyNlbGlmIGRlZmluZWQodW5peCkgfHwgZGVmaW5lZChfX3VuaXgpIHx8IGRlZmluZWQoX191bml4X18pCisjIGRlZmluZSBUUklPX1BMQVRGT1JNX1VOSVgKKyNlbGlmIGRlZmluZWQoVFJJT19DT01QSUxFUl9YTEMpIHx8IGRlZmluZWQoX0FJWCkKKyMgZGVmaW5lIFRSSU9fUExBVEZPUk1fVU5JWAorI2VsaWYgZGVmaW5lZChUUklPX0NPTVBJTEVSX0RFQ0MpIHx8IGRlZmluZWQoX19vc2ZfX18pCisjIGRlZmluZSBUUklPX1BMQVRGT1JNX1VOSVgKKyNlbGlmIGRlZmluZWQoX19OZXRCU0RfXykKKyMgZGVmaW5lIFRSSU9fUExBVEZPUk1fVU5JWAorI2VsaWYgZGVmaW5lZChfX1FOWF9fKQorIyBkZWZpbmUgVFJJT19QTEFURk9STV9VTklYCisjIGRlZmluZSBUUklPX1BMQVRGT1JNX1FOWAorI2VsaWYgZGVmaW5lZChfX0NZR1dJTl9fKQorIyBkZWZpbmUgVFJJT19QTEFURk9STV9VTklYCisjZWxpZiBkZWZpbmVkKEFNSUdBKSAmJiBkZWZpbmVkKFRSSU9fQ09NUElMRVJfR0NDKQorIyBkZWZpbmUgVFJJT19QTEFURk9STV9VTklYCisjZWxpZiBkZWZpbmVkKFRSSU9fQ09NUElMRVJfTVNWQykgfHwgZGVmaW5lZChXSU4zMikgfHwgZGVmaW5lZChfV0lOMzIpCisjIGRlZmluZSBUUklPX1BMQVRGT1JNX1dJTjMyCisjZWxpZiBkZWZpbmVkKG1wZWl4KSB8fCBkZWZpbmVkKF9fbXBleGwpCisjIGRlZmluZSBUUklPX1BMQVRGT1JNX01QRUlYCisjZW5kaWYKKworI2lmIGRlZmluZWQoX0FJWCkKKyMgZGVmaW5lIFRSSU9fUExBVEZPUk1fQUlYCisjZWxpZiBkZWZpbmVkKF9faHB1eCkKKyMgZGVmaW5lIFRSSU9fUExBVEZPUk1fSFBVWAorI2VsaWYgZGVmaW5lZChzdW4pIHx8IGRlZmluZWQoX19zdW5fXykKKyMgaWYgZGVmaW5lZChfX1NWUjQpIHx8IGRlZmluZWQoX19zdnI0X18pCisjICBkZWZpbmUgVFJJT19QTEFURk9STV9TT0xBUklTCisjIGVsc2UKKyMgIGRlZmluZSBUUklPX1BMQVRGT1JNX1NVTk9TCisjIGVuZGlmCisjZW5kaWYKKworI2lmIGRlZmluZWQoX19TVERDX18pIHx8IGRlZmluZWQoVFJJT19DT01QSUxFUl9NU1ZDKSB8fCBkZWZpbmVkKFRSSU9fQ09NUElMRVJfQkNCKQorIyBkZWZpbmUgVFJJT19DT01QSUxFUl9TVVBQT1JUU19DODkKKyMgaWYgZGVmaW5lZChfX1NURENfVkVSU0lPTl9fKQorIyAgZGVmaW5lIFRSSU9fQ09NUElMRVJfU1VQUE9SVFNfQzkwCisjICBpZiAoX19TVERDX1ZFUlNJT05fXyA+PSAxOTk0MDlMKQorIyAgIGRlZmluZSBUUklPX0NPTVBJTEVSX1NVUFBPUlRTX0M5NAorIyAgZW5kaWYKKyMgIGlmIChfX1NURENfVkVSU0lPTl9fID49IDE5OTkwMUwpCisjICAgZGVmaW5lIFRSSU9fQ09NUElMRVJfU1VQUE9SVFNfQzk5CisjICBlbmRpZgorIyBlbGlmIGRlZmluZWQoVFJJT19DT01QSUxFUl9TVU5QUk8pCisjICBpZiAoX19TVU5QUk9fQyA+PSAweDQyMCkKKyMgICBkZWZpbmUgVFJJT19DT01QSUxFUl9TVVBQT1JUU19DOTQKKyMgIGVuZGlmCisjIGVuZGlmCisjZW5kaWYKKworI2lmIGRlZmluZWQoX1hPUEVOX1NPVVJDRSkKKyMgaWYgZGVmaW5lZChfWE9QRU5fU09VUkNFX0VYVEVOREVEKQorIyAgZGVmaW5lIFRSSU9fQ09NUElMRVJfU1VQUE9SVFNfVU5JWDk1CisjIGVuZGlmCisjIGlmIChfWE9QRU5fVkVSU0lPTiA+PSA1MDApCisjICBkZWZpbmUgVFJJT19DT01QSUxFUl9TVVBQT1JUU19VTklYOTgKKyMgZW5kaWYKKyMgaWYgKF9YT1BFTl9WRVJTSU9OID49IDYwMCkKKyMgIGRlZmluZSBUUklPX0NPTVBJTEVSX1NVUFBPUlRTX1VOSVgwMQorIyBlbmRpZgorI2VuZGlmCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiBHZW5lcmljIGRlZmluZXMKKyAqLworCisjaWYgIWRlZmluZWQoVFJJT19QVUJMSUMpCisjIGRlZmluZSBUUklPX1BVQkxJQworI2VuZGlmCisjaWYgIWRlZmluZWQoVFJJT19QUklWQVRFKQorIyBkZWZpbmUgVFJJT19QUklWQVRFIHN0YXRpYworI2VuZGlmCisKKyNpZiAhKGRlZmluZWQoVFJJT19DT01QSUxFUl9TVVBQT1JUU19DODkpIHx8IGRlZmluZWQoX19jcGx1c3BsdXMpKQorIyBkZWZpbmUgVFJJT19DT01QSUxFUl9BTkNJRU5UCisjZW5kaWYKKworI2lmIGRlZmluZWQoVFJJT19DT01QSUxFUl9BTkNJRU5UKQorIyBkZWZpbmUgVFJJT19DT05TVAorIyBkZWZpbmUgVFJJT19WT0xBVElMRQorIyBkZWZpbmUgVFJJT19TSUdORUQKK3R5cGVkZWYgZG91YmxlIHRyaW9fbG9uZ19kb3VibGVfdDsKK3R5cGVkZWYgY2hhciAqIHRyaW9fcG9pbnRlcl90OworIyBkZWZpbmUgVFJJT19TVUZGSVhfTE9ORyh4KSB4CisjIGRlZmluZSBUUklPX1BST1RPKHgpICgpCisjIGRlZmluZSBUUklPX05PQVJHUworIyBkZWZpbmUgVFJJT19BUkdTMShsaXN0LGExKSBsaXN0IGExOworIyBkZWZpbmUgVFJJT19BUkdTMihsaXN0LGExLGEyKSBsaXN0IGExOyBhMjsKKyMgZGVmaW5lIFRSSU9fQVJHUzMobGlzdCxhMSxhMixhMykgbGlzdCBhMTsgYTI7IGEzOworIyBkZWZpbmUgVFJJT19BUkdTNChsaXN0LGExLGEyLGEzLGE0KSBsaXN0IGExOyBhMjsgYTM7IGE0OworIyBkZWZpbmUgVFJJT19BUkdTNShsaXN0LGExLGEyLGEzLGE0LGE1KSBsaXN0IGExOyBhMjsgYTM7IGE0OyBhNTsKKyMgZGVmaW5lIFRSSU9fQVJHUzYobGlzdCxhMSxhMixhMyxhNCxhNSxhNikgbGlzdCBhMTsgYTI7IGEzOyBhNDsgYTU7IGE2OworIyBkZWZpbmUgVFJJT19WQVJHUzIobGlzdCxhMSxhMikgbGlzdCBhMTsgYTIKKyMgZGVmaW5lIFRSSU9fVkFSR1MzKGxpc3QsYTEsYTIsYTMpIGxpc3QgYTE7IGEyOyBhMworIyBkZWZpbmUgVFJJT19WQVJHUzQobGlzdCxhMSxhMixhMyxhNCkgbGlzdCBhMTsgYTI7IGEzOyBhNAorIyBkZWZpbmUgVFJJT19WQVJHUzUobGlzdCxhMSxhMixhMyxhNCxhNSkgbGlzdCBhMTsgYTI7IGEzOyBhNDsgYTUKKyMgZGVmaW5lIFRSSU9fVkFfREVDTCB2YV9kY2wKKyMgZGVmaW5lIFRSSU9fVkFfU1RBUlQoeCx5KSB2YV9zdGFydCh4KQorIyBkZWZpbmUgVFJJT19WQV9FTkQoeCkgdmFfZW5kKHgpCisjZWxzZSAvKiBBTlNJIEMgKi8KKyMgZGVmaW5lIFRSSU9fQ09OU1QgY29uc3QKKyMgZGVmaW5lIFRSSU9fVk9MQVRJTEUgdm9sYXRpbGUKKyMgZGVmaW5lIFRSSU9fU0lHTkVEIHNpZ25lZAordHlwZWRlZiBsb25nIGRvdWJsZSB0cmlvX2xvbmdfZG91YmxlX3Q7Cit0eXBlZGVmIHZvaWQgKiB0cmlvX3BvaW50ZXJfdDsKKyMgZGVmaW5lIFRSSU9fU1VGRklYX0xPTkcoeCkgeCAjIyBMCisjIGRlZmluZSBUUklPX1BST1RPKHgpIHgKKyMgZGVmaW5lIFRSSU9fTk9BUkdTIHZvaWQKKyMgZGVmaW5lIFRSSU9fQVJHUzEobGlzdCxhMSkgKGExKQorIyBkZWZpbmUgVFJJT19BUkdTMihsaXN0LGExLGEyKSAoYTEsYTIpCisjIGRlZmluZSBUUklPX0FSR1MzKGxpc3QsYTEsYTIsYTMpIChhMSxhMixhMykKKyMgZGVmaW5lIFRSSU9fQVJHUzQobGlzdCxhMSxhMixhMyxhNCkgKGExLGEyLGEzLGE0KQorIyBkZWZpbmUgVFJJT19BUkdTNShsaXN0LGExLGEyLGEzLGE0LGE1KSAoYTEsYTIsYTMsYTQsYTUpCisjIGRlZmluZSBUUklPX0FSR1M2KGxpc3QsYTEsYTIsYTMsYTQsYTUsYTYpIChhMSxhMixhMyxhNCxhNSxhNikKKyMgZGVmaW5lIFRSSU9fVkFSR1MyIFRSSU9fQVJHUzIKKyMgZGVmaW5lIFRSSU9fVkFSR1MzIFRSSU9fQVJHUzMKKyMgZGVmaW5lIFRSSU9fVkFSR1M0IFRSSU9fQVJHUzQKKyMgZGVmaW5lIFRSSU9fVkFSR1M1IFRSSU9fQVJHUzUKKyMgZGVmaW5lIFRSSU9fVkFfREVDTCAuLi4KKyMgZGVmaW5lIFRSSU9fVkFfU1RBUlQoeCx5KSB2YV9zdGFydCh4LHkpCisjIGRlZmluZSBUUklPX1ZBX0VORCh4KSB2YV9lbmQoeCkKKyNlbmRpZgorCisjaWYgZGVmaW5lZChUUklPX0NPTVBJTEVSX1NVUFBPUlRTX0M5OSkgfHwgZGVmaW5lZChfX2NwbHVzcGx1cykKKyMgZGVmaW5lIFRSSU9fSU5MSU5FIGlubGluZQorI2VsaWYgZGVmaW5lZChUUklPX0NPTVBJTEVSX0dDQykKKyMgZGVmaW5lIFRSSU9fSU5MSU5FIF9faW5saW5lX18KKyNlbGlmIGRlZmluZWQoVFJJT19DT01QSUxFUl9NU1ZDKQorIyBkZWZpbmUgVFJJT19JTkxJTkUgX2lubGluZQorI2VsaWYgZGVmaW5lZChUUklPX0NPTVBJTEVSX0JDQikKKyMgZGVmaW5lIFRSSU9fSU5MSU5FIF9faW5saW5lCisjZWxzZQorIyBkZWZpbmUgVFJJT19JTkxJTkUKKyNlbmRpZgorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogV29ya2Fyb3VuZHMKKyAqLworCisjaWYgZGVmaW5lZChUUklPX1BMQVRGT1JNX1ZNUykKKy8qCisgKiBDb21wdXRhdGlvbnMgZG9uZSB3aXRoIGNvbnN0YW50cyBhdCBjb21waWxlIHRpbWUgY2FuIHRyaWdnZXIgdGhlc2UKKyAqIGV2ZW4gd2hlbiBjb21waWxpbmcgd2l0aCBJRUVFIGVuYWJsZWQuCisgKi8KKyMgcHJhZ21hIG1lc3NhZ2UgZGlzYWJsZSAoVU5ERVJGTE9XLCBGTE9BVE9WRVJGTCkKKworIyBpZiAoX19DUlRMX1ZFUiA8IDgwMDAwMDAwKQorLyoKKyAqIEFsdGhvdWdoIHRoZSBjb21waWxlciBzdXBwb3J0cyBDOTkgbGFuZ3VhZ2UgY29uc3RydWN0cywgdGhlIEMKKyAqIHJ1bi10aW1lIGxpYnJhcnkgZG9lcyBub3QgY29udGFpbiBhbGwgQzk5IGZ1bmN0aW9ucy4KKyAqCisgKiBUaGlzIHdhcyB0aGUgY2FzZSBmb3IgNzAzMDAwMjIuIFVwZGF0ZSB0aGUgODAwMDAwMDAgdmFsdWUgd2hlbgorICogaXQgaGFzIGJlZW4gYWNjdXJhdGVseSBkZXRlcm1pbmVkIHdoYXQgdmVyc2lvbiBvZiB0aGUgbGlicmFyeQorICogc3VwcG9ydHMgQzk5LgorICovCisjICBpZiBkZWZpbmVkKFRSSU9fQ09NUElMRVJfU1VQUE9SVFNfQzk5KQorIyAgIHVuZGVmIFRSSU9fQ09NUElMRVJfU1VQUE9SVFNfQzk5CisjICBlbmRpZgorIyBlbmRpZgorI2VuZGlmCisKKy8qCisgKiBOb3QgYWxsIHByZXByb2Nlc3NvcnMgc3VwcG9ydHMgdGhlIExMIHRva2VuLgorICovCisjaWYgZGVmaW5lZChUUklPX0NPTVBJTEVSX0JDQikKKyNlbHNlCisjIGRlZmluZSBUUklPX0NPTVBJTEVSX1NVUFBPUlRTX0xMCisjZW5kaWYKKworI2VuZGlmIC8qIFRSSU9fVFJJT0RFRl9IICovCmRpZmYgLS1naXQgYS9saWJ4c2x0L3ZhcmlhYmxlcy5jIGIvbGlieHNsdC92YXJpYWJsZXMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40M2E2MTU2Ci0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC92YXJpYWJsZXMuYwpAQCAtMCwwICsxLDIzMTIgQEAKKy8qCisgKiB2YXJpYWJsZXMuYzogSW1wbGVtZW50YXRpb24gb2YgdGhlIHZhcmlhYmxlIHN0b3JhZ2UgYW5kIGxvb2t1cAorICoKKyAqIFJlZmVyZW5jZToKKyAqICAgaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteHNsdC0xOTk5MTExNgorICoKKyAqIFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBkYW5pZWxAdmVpbGxhcmQuY29tCisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CisjaW5jbHVkZSA8bGlieG1sL3RyZWUuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdmFsaWQuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvaGFzaC5oPgorI2luY2x1ZGUgPGxpYnhtbC94bWxlcnJvci5oPgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aC5oPgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aEludGVybmFscy5oPgorI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvZGljdC5oPgorI2luY2x1ZGUgInhzbHQuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisjaW5jbHVkZSAieHNsdHV0aWxzLmgiCisjaW5jbHVkZSAidmFyaWFibGVzLmgiCisjaW5jbHVkZSAidHJhbnNmb3JtLmgiCisjaW5jbHVkZSAiaW1wb3J0cy5oIgorI2luY2x1ZGUgInByZXByb2MuaCIKKyNpbmNsdWRlICJrZXlzLmgiCisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKyAjZGVmaW5lIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorI2VuZGlmCisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKK2NvbnN0IHhtbENoYXIgKnhzbHREb2NGcmFnRmFrZSA9IChjb25zdCB4bWxDaGFyICopICIgZmFrZSBub2RlIGxpYnhzbHQiOworI2VuZGlmCisKK2NvbnN0IHhtbENoYXIgKnhzbHRDb21wdXRpbmdHbG9iYWxWYXJNYXJrZXIgPQorIChjb25zdCB4bWxDaGFyICopICIgdmFyL3BhcmFtIGJlaW5nIGNvbXB1dGVkIjsKKworI2RlZmluZSBYU0xUX1ZBUl9HTE9CQUwgMTw8MAorI2RlZmluZSBYU0xUX1ZBUl9JTl9TRUxFQ1QgMTw8MQorI2RlZmluZSBYU0xUX1RDVFhUX1ZBUklBQkxFKGMpICgoeHNsdFN0YWNrRWxlbVB0cikgKGMpLT5jb250ZXh0VmFyaWFibGUpCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICogIFJlc3VsdCBWYWx1ZSBUcmVlIChSZXN1bHQgVHJlZSBGcmFnbWVudCkgaW50ZXJmYWNlcwkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKy8qKgorICogeHNsdENyZWF0ZVJWVDoKKyAqIEBjdHh0OiAgYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogQ3JlYXRlcyBhIFJlc3VsdCBWYWx1ZSBUcmVlCisgKiAodGhlIFhTTFQgMS4wIHRlcm0gZm9yIHRoaXMgaXMgIlJlc3VsdCBUcmVlIEZyYWdtZW50IikgCisgKgorICogUmV0dXJucyB0aGUgcmVzdWx0IHZhbHVlIHRyZWUgb3IgTlVMTCBpbiBjYXNlIG9mIEFQSSBvciBpbnRlcm5hbCBlcnJvcnMuCisgKi8KK3htbERvY1B0cgoreHNsdENyZWF0ZVJWVCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KQoreworICAgIHhtbERvY1B0ciBjb250YWluZXI7CisKKyAgICAvKgorICAgICogUXVlc3Rpb246IFdoeSBpcyB0aGlzIGZ1bmN0aW9uIHB1YmxpYz8KKyAgICAqIEFuc3dlcjogSXQgaXMgY2FsbGVkIGJ5IHRoZSBFWFNMVCBtb2R1bGUuCisgICAgKi8gICAgCisgICAgaWYgKGN0eHQgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICAvKgorICAgICogUmV1c2UgYSBSVEYgZnJvbSB0aGUgY2FjaGUgaWYgYXZhaWxhYmxlLgorICAgICovCisgICAgaWYgKGN0eHQtPmNhY2hlLT5SVlQpIHsKKwljb250YWluZXIgPSBjdHh0LT5jYWNoZS0+UlZUOworCWN0eHQtPmNhY2hlLT5SVlQgPSAoeG1sRG9jUHRyKSBjb250YWluZXItPm5leHQ7CisJLyogY2xlYXIgdGhlIGludGVybmFsIHBvaW50ZXJzICovCisJY29udGFpbmVyLT5uZXh0ID0gTlVMTDsKKwljb250YWluZXItPnByZXYgPSBOVUxMOworCWlmIChjdHh0LT5jYWNoZS0+bmJSVlQgPiAwKQorCSAgICBjdHh0LT5jYWNoZS0+bmJSVlQtLTsKKyNpZmRlZiBYU0xUX0RFQlVHX1BST0ZJTEVfQ0FDSEUKKwljdHh0LT5jYWNoZS0+ZGJnUmV1c2VkUlZUcysrOworI2VuZGlmCisJcmV0dXJuKGNvbnRhaW5lcik7CisgICAgfQorCisgICAgY29udGFpbmVyID0geG1sTmV3RG9jKE5VTEwpOworICAgIGlmIChjb250YWluZXIgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisgICAgY29udGFpbmVyLT5kaWN0ID0gY3R4dC0+ZGljdDsKKyAgICB4bWxEaWN0UmVmZXJlbmNlKGNvbnRhaW5lci0+ZGljdCk7CisgICAgWFNMVF9NQVJLX1JFU19UUkVFX0ZSQUcoY29udGFpbmVyKTsKKyAgICBjb250YWluZXItPmRvYyA9IGNvbnRhaW5lcjsKKyAgICBjb250YWluZXItPnBhcmVudCA9IE5VTEw7CisgICAgcmV0dXJuKGNvbnRhaW5lcik7Cit9CisKKy8qKgorICogeHNsdFJlZ2lzdGVyVG1wUlZUOgorICogQGN0eHQ6ICBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBSVlQ6ICBhIHJlc3VsdCB2YWx1ZSB0cmVlIChSZXN1bHQgVHJlZSBGcmFnbWVudCkKKyAqCisgKiBSZWdpc3RlcnMgdGhlIHJlc3VsdCB2YWx1ZSB0cmVlIChYU0xUIDEuMCB0ZXJtOiBSZXN1bHQgVHJlZSBGcmFnbWVudCkKKyAqIGluIHRoZSBnYXJiYWdlIGNvbGxlY3Rvci4KKyAqIFRoZSBmcmFnbWVudCB3aWxsIGJlIGZyZWVkIGF0IHRoZSBleGl0IG9mIHRoZSBjdXJyZW50bHkKKyAqIGluc3RhbnRpYXRlZCB4c2w6dGVtcGxhdGUuCisgKiBPYnNvbGV0ZTsgdGhpcyBmdW5jdGlvbiBtaWdodCBwcm9kdWNlIG1hc3NpdmUgbWVtb3J5IG92ZXJoZWFkLAorICogc2luY2UgdGhlIGZyYWdtZW50IGlzIG9ubHkgZnJlZWQgd2hlbiB0aGUgY3VycmVudCB4c2w6dGVtcGxhdGUKKyAqIGV4aXRzLiBVc2UgeHNsdFJlZ2lzdGVyTG9jYWxSVlQoKSBpbnN0ZWFkLgorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MgYW5kIC0xIGluIGNhc2Ugb2YgQVBJIG9yIGludGVybmFsIGVycm9ycy4KKyAqLworaW50Cit4c2x0UmVnaXN0ZXJUbXBSVlQoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sRG9jUHRyIFJWVCkKK3sKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKFJWVCA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworCisgICAgLyoKKyAgICAqIFdlJ2xsIHJlc3RyaWN0IHRoZSBsaWZldGltZSBvZiB1c2VyLWNyZWF0ZWQgZnJhZ21lbnRzCisgICAgKiBpbnNpbmRlIGFuIHhzbDp2YXJpYWJsZSBhbmQgeHNsOnBhcmFtIHRvIHRoZSBsaWZldGltZSBvZiB0aGUKKyAgICAqIHZhci9wYXJhbSBpdHNlbGYuCisgICAgKi8KKyAgICBpZiAoY3R4dC0+Y29udGV4dFZhcmlhYmxlICE9IE5VTEwpIHsKKwlSVlQtPm5leHQgPSAoeG1sTm9kZVB0cikgWFNMVF9UQ1RYVF9WQVJJQUJMRShjdHh0KS0+ZnJhZ21lbnQ7CisJWFNMVF9UQ1RYVF9WQVJJQUJMRShjdHh0KS0+ZnJhZ21lbnQgPSBSVlQ7CisJcmV0dXJuKDApOworICAgIH0KKworICAgIFJWVC0+bmV4dCA9ICh4bWxOb2RlUHRyKSBjdHh0LT50bXBSVlQ7CisgICAgaWYgKGN0eHQtPnRtcFJWVCAhPSBOVUxMKQorCWN0eHQtPnRtcFJWVC0+cHJldiA9ICh4bWxOb2RlUHRyKSBSVlQ7CisgICAgY3R4dC0+dG1wUlZUID0gUlZUOworICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0UmVnaXN0ZXJMb2NhbFJWVDoKKyAqIEBjdHh0OiAgYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAUlZUOiAgYSByZXN1bHQgdmFsdWUgdHJlZSAoUmVzdWx0IFRyZWUgRnJhZ21lbnQ7IHhtbERvY1B0cikKKyAqCisgKiBSZWdpc3RlcnMgYSByZXN1bHQgdmFsdWUgdHJlZSAoWFNMVCAxLjAgdGVybTogUmVzdWx0IFRyZWUgRnJhZ21lbnQpCisgKiBpbiB0aGUgUlZUIGdhcmJhZ2UgY29sbGVjdG9yLgorICogVGhlIGZyYWdtZW50IHdpbGwgYmUgZnJlZWQgd2hlbiB0aGUgaW5zdHJ1Y3Rpb24gd2hpY2ggY3JlYXRlZCB0aGUKKyAqIGZyYWdtZW50IGV4aXRzLgorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MgYW5kIC0xIGluIGNhc2Ugb2YgQVBJIG9yIGludGVybmFsIGVycm9ycy4KKyAqLworaW50Cit4c2x0UmVnaXN0ZXJMb2NhbFJWVCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkgICAgIHhtbERvY1B0ciBSVlQpCit7CisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChSVlQgPT0gTlVMTCkpCisJcmV0dXJuKC0xKTsKKyAgICAKKyAgICAvKgorICAgICogV2hlbiBldmFsdWF0aW5nICJzZWxlY3QiIGV4cHJlc3Npb25zIG9mIHhzbDp2YXJpYWJsZQorICAgICogYW5kIHhzbDpwYXJhbSwgd2UgbmVlZCB0byBiaW5kIG5ld2x5IGNyZWF0ZWQgdHJlZSBmcmFnbWVudHMKKyAgICAqIHRvIHRoZSB2YXJpYWJsZSBpdHNlbGY7IG90aGVyd2lzZSB0aGUgdHJhZ21lbnQgd2lsbCBiZQorICAgICogZnJlZWQgYmVmb3JlIHdlIGxlYXZlIHRoZSBzY29wZSBvZiBhIHZhci4KKyAgICAqLworICAgIGlmICgoY3R4dC0+Y29udGV4dFZhcmlhYmxlICE9IE5VTEwpICYmCisJKFhTTFRfVENUWFRfVkFSSUFCTEUoY3R4dCktPmZsYWdzICYgWFNMVF9WQVJfSU5fU0VMRUNUKSkKKyAgICB7CisJUlZULT5uZXh0ID0gKHhtbE5vZGVQdHIpIFhTTFRfVENUWFRfVkFSSUFCTEUoY3R4dCktPmZyYWdtZW50OworCVhTTFRfVENUWFRfVkFSSUFCTEUoY3R4dCktPmZyYWdtZW50ID0gUlZUOworCXJldHVybigwKTsKKyAgICB9CisgICAgLyoKKyAgICAqIFN0b3JlIHRoZSBmcmFnbWVudCBpbiB0aGUgc2NvcGUgb2YgdGhlIGN1cnJlbnQgaW5zdHJ1Y3Rpb24uCisgICAgKiBJZiBub3QgcmVmZXJlbmNlIGJ5IGEgcmV0dXJuaW5nIGluc3RydWN0aW9uIChsaWtlIEVYU0xUJ3MgZnVuY3Rpb24pLAorICAgICogdGhlbiB0aGlzIGZyYWdtZW50IHdpbGwgYmUgZnJlZWQsIHdoZW4gdGhlIGluc3RydWN0aW9uIGV4aXRzLgorICAgICovCisgICAgUlZULT5uZXh0ID0gKHhtbE5vZGVQdHIpIGN0eHQtPmxvY2FsUlZUOworICAgIGlmIChjdHh0LT5sb2NhbFJWVCAhPSBOVUxMKQorCWN0eHQtPmxvY2FsUlZULT5wcmV2ID0gKHhtbE5vZGVQdHIpIFJWVDsKKyAgICBjdHh0LT5sb2NhbFJWVCA9IFJWVDsKKyAgICAvKgorICAgICogV2UgbmVlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBmaXJzdCByZWdpc3RlcmVkIGZyYWdtZW50CisgICAgKiBmb3IgZXh0ZW5zaW9uIGluc3RydWN0aW9ucyB3aGljaCByZXR1cm4gZnJhZ21lbnRzCisgICAgKiAoZS5nLiBFWFNMVCdTIGZ1bmN0aW9uKSwgaW4gb3JkZXIgdG8gbGV0CisgICAgKiB4c2x0RXh0ZW5zaW9uSW5zdHJ1Y3Rpb25SZXN1bHRGaW5hbGl6ZSgpIGNsZWFyIHRoZQorICAgICogcHJlc2VydmluZyBmbGFnIG9uIHRoZSBmcmFnbWVudHMuCisgICAgKi8KKyAgICBpZiAoY3R4dC0+bG9jYWxSVlRCYXNlID09IE5VTEwpCisJY3R4dC0+bG9jYWxSVlRCYXNlID0gUlZUOworICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0RXh0ZW5zaW9uSW5zdHJ1Y3Rpb25SZXN1bHRGaW5hbGl6ZToKKyAqIEBjdHh0OiAgYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogRmluYWxpemVzIHRoZSBkYXRhIChlLmcuIHJlc3VsdCB0cmVlIGZyYWdtZW50cykgY3JlYXRlZAorICogd2l0aGluIGEgdmFsdWUtcmV0dXJuaW5nIHByb2Nlc3MgKGUuZy4gRVhTTFQncyBmdW5jdGlvbikuCisgKiBUcmVlIGZyYWdtZW50cyBtYXJrZWQgYXMgYmVpbmcgcmV0dXJuZWQgYnkgYSBmdW5jdGlvbiBhcmUKKyAqIHNldCB0byBub3JtYWwgc3RhdGUsIHdoaWNoIG1lYW5zIHRoYXQgdGhlIGZyYWdtZW50IGdhcmJhZ2UKKyAqIGNvbGxlY3RvciB3aWxsIGZyZWUgdGhlbSBhZnRlciB0aGUgZnVuY3Rpb24tY2FsbGluZyBwcm9jZXNzIGV4aXRzLgorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MgYW5kIC0xIGluIGNhc2Ugb2YgQVBJIG9yIGludGVybmFsIGVycm9ycy4KKyAqLworaW50Cit4c2x0RXh0ZW5zaW9uSW5zdHJ1Y3Rpb25SZXN1bHRGaW5hbGl6ZSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KQoreworICAgIHhtbERvY1B0ciBjdXI7CisKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorCXJldHVybigtMSk7CisgICAgaWYgKGN0eHQtPmxvY2FsUlZUQmFzZSA9PSBOVUxMKQorCXJldHVybigwKTsKKyAgICAvKgorICAgICogRW5hYmxlIHJlbWFpbmluZyBsb2NhbCB0cmVlIGZyYWdtZW50cyB0byBiZSBmcmVlZAorICAgICogYnkgdGhlIGZyYWdtZW50IGdhcmJhZ2UgY29sbGVjdG9yLgorICAgICovCisgICAgY3VyID0gY3R4dC0+bG9jYWxSVlRCYXNlOworICAgIGRvIHsKKwljdXItPnBzdmkgPSBOVUxMOworCWN1ciA9ICh4bWxEb2NQdHIpIGN1ci0+bmV4dDsKKyAgICB9IHdoaWxlIChjdXIgIT0gTlVMTCk7CisgICAgcmV0dXJuKDApOworfQorCisvKioKKyAqIHhzbHRFeHRlbnNpb25JbnN0cnVjdGlvblJlc3VsdFJlZ2lzdGVyOgorICogQGN0eHQ6IGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQG9iajogYW4gWFBhdGggb2JqZWN0IHRvIGJlIGluc3BlY3RlZCBmb3IgcmVzdWx0IHRyZWUgZnJhZ21lbnRzCisgKgorICogTWFya3MgdGhlIHJlc3VsdCBvZiBhIHZhbHVlLXJldHVybmluZyBleHRlbnNpb24gaW5zdHJ1Y3Rpb24KKyAqIGluIG9yZGVyIHRvIGF2b2lkIGl0IGJlaW5nIGdhcmJhZ2UgY29sbGVjdGVkIGJlZm9yZSB0aGUKKyAqIGV4dGVuc2lvbiBpbnN0cnVjdGlvbiBleGl0cy4KKyAqIE5vdGUgdGhhdCBvbmUgc3RpbGwgaGFzIHRvIGFkZGl0aW9uYWxseSByZWdpc3RlciBhbnkgbmV3bHkgY3JlYXRlZAorICogdHJlZSBmcmFnbWVudHMgKHZpYSB4c2x0Q3JlYXRlUlZUKCkpIHdpdGggeHNsdFJlZ2lzdGVyTG9jYWxSVlQoKS4KKyAqCisgKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzIGFuZCAtMSBpbiBjYXNlIG9mIGVycm9yLgorICovCitpbnQKK3hzbHRFeHRlbnNpb25JbnN0cnVjdGlvblJlc3VsdFJlZ2lzdGVyKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJICAgICAgIHhtbFhQYXRoT2JqZWN0UHRyIG9iaikKK3sKKyAgICBpbnQgaTsKKyAgICB4bWxOb2RlUHRyIGN1cjsKKyAgICB4bWxEb2NQdHIgZG9jOworCisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChvYmogPT0gTlVMTCkpCisJcmV0dXJuKC0xKTsKKworICAgIC8qCisgICAgKiBPUFRJTUlaRSBUT0RPOiBJZiBubyBsb2NhbCB2YXJpYWJsZXMvcGFyYW1zIGFuZCBubyBsb2NhbCB0cmVlCisgICAgKiBmcmFnbWVudHMgd2VyZSBjcmVhdGVkLCB0aGVuIHdlIGRvbid0IG5lZWQgdG8gYW5hbHlzZSB0aGUgWFBhdGgKKyAgICAqIG9iamVjdHMgZm9yIHRyZWUgZnJhZ21lbnRzLgorICAgICovCisKKyAgICBpZiAoKG9iai0+dHlwZSAhPSBYUEFUSF9OT0RFU0VUKSAmJiAob2JqLT50eXBlICE9IFhQQVRIX1hTTFRfVFJFRSkpCisJcmV0dXJuKDApOworICAgIGlmICgob2JqLT5ub2Rlc2V0dmFsID09IE5VTEwpIHx8IChvYmotPm5vZGVzZXR2YWwtPm5vZGVOciA9PSAwKSkKKwlyZXR1cm4oMCk7CisKKyAgICBmb3IgKGkgPSAwOyBpIDwgb2JqLT5ub2Rlc2V0dmFsLT5ub2RlTnI7IGkrKykgeworCWN1ciA9IG9iai0+bm9kZXNldHZhbC0+bm9kZVRhYltpXTsKKwlpZiAoY3VyLT50eXBlID09IFhNTF9OQU1FU1BBQ0VfREVDTCkgeworCSAgICAvKgorCSAgICAqIFRoZSBYUGF0aCBtb2R1bGUgc2V0cyB0aGUgb3duZXIgZWxlbWVudCBvZiBhIG5zLW5vZGUgb24KKwkgICAgKiB0aGUgbnMtPm5leHQgZmllbGQuCisJICAgICovCisJICAgIGlmICgoKCh4bWxOc1B0cikgY3VyKS0+bmV4dCAhPSBOVUxMKSAmJgorCQkoKCh4bWxOc1B0cikgY3VyKS0+bmV4dC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSkKKwkgICAgeworCQljdXIgPSAoeG1sTm9kZVB0cikgKCh4bWxOc1B0cikgY3VyKS0+bmV4dDsKKwkJZG9jID0gY3VyLT5kb2M7CQorCSAgICB9IGVsc2UgeworCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgY3R4dC0+aW5zdCwKKwkJICAgICJJbnRlcm5hbCBlcnJvciBpbiAiCisJCSAgICAieHNsdEV4dGVuc2lvbkluc3RydWN0aW9uUmVzdWx0UmVnaXN0ZXIoKTogIgorCQkgICAgIkNhbm5vdCByZXRyaWV2ZSB0aGUgZG9jIG9mIGEgbmFtZXNwYWNlIG5vZGUuXG4iKTsKKwkJZ290byBlcnJvcjsKKwkgICAgfQorCX0gZWxzZSB7CisJICAgIGRvYyA9IGN1ci0+ZG9jOworCX0KKwlpZiAoZG9jID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIGN0eHQtPmluc3QsCisJCSJJbnRlcm5hbCBlcnJvciBpbiAiCisJCSJ4c2x0RXh0ZW5zaW9uSW5zdHJ1Y3Rpb25SZXN1bHRSZWdpc3RlcigpOiAiCisJCSJDYW5ub3QgcmV0cmlldmUgdGhlIGRvYyBvZiBhIG5vZGUuXG4iKTsKKwkgICAgZ290byBlcnJvcjsKKwl9CisJaWYgKGRvYy0+bmFtZSAmJiAoZG9jLT5uYW1lWzBdID09ICcgJykpIHsKKwkgICAgLyoKKwkgICAgKiBUaGlzIGlzIGEgcmVzdWx0IHRyZWUgZnJhZ21lbnQuCisJICAgICogV2UnbGwgdXNlIHRoZSBAcHN2aSBmaWVsZCBmb3IgcmVmZXJlbmNlIGNvdW50aW5nLgorCSAgICAqIFRPRE86IEhvdyBkbyB3ZSBrbm93IGlmIHRoaXMgaXMgYSB2YWx1ZSBvZiBhCisJICAgICogIGdsb2JhbCB2YXJpYWJsZSBvciBhIGRvYyBhY3F1aXJlZCB2aWEgdGhlCisJICAgICogIGRvY3VtZW50KCkgZnVuY3Rpb24/CisJICAgICovCisJICAgIGRvYy0+cHN2aSA9ICh2b2lkICopICgobG9uZykgMSk7CisJfQorICAgIH0KKworICAgIHJldHVybigwKTsKK2Vycm9yOgorICAgIHJldHVybigtMSk7Cit9CisKKy8qKgorICogeHNsdFJlbGVhc2VSVlQ6CisgKiBAY3R4dDogIGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQFJWVDogIGEgcmVzdWx0IHZhbHVlIHRyZWUgKFJlc3VsdCBUcmVlIEZyYWdtZW50KQorICoKKyAqIEVpdGhlciBmcmVlcyB0aGUgUlZUICh3aGljaCBpcyBhbiB4bWxEb2MpIG9yIHN0b3JlcworICogaXQgaW4gdGhlIGNvbnRleHQncyBjYWNoZSBmb3IgbGF0ZXIgcmV1c2UuCisgKi8KK3ZvaWQKK3hzbHRSZWxlYXNlUlZUKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbERvY1B0ciBSVlQpCit7CisgICAgaWYgKFJWVCA9PSBOVUxMKQorCXJldHVybjsKKworICAgIGlmIChjdHh0ICYmIChjdHh0LT5jYWNoZS0+bmJSVlQgPCA0MCkpIHsKKwkvKgorCSogU3RvcmUgdGhlIFJlc3VsdCBUcmVlIEZyYWdtZW50LgorCSogRnJlZSB0aGUgZG9jdW1lbnQgaW5mby4KKwkqLworCWlmIChSVlQtPl9wcml2YXRlICE9IE5VTEwpIHsKKwkgICAgeHNsdEZyZWVEb2N1bWVudEtleXMoKHhzbHREb2N1bWVudFB0cikgUlZULT5fcHJpdmF0ZSk7CisJICAgIHhtbEZyZWUoUlZULT5fcHJpdmF0ZSk7CisJICAgIFJWVC0+X3ByaXZhdGUgPSBOVUxMOworCX0KKwkvKgorCSogQ2xlYXIgdGhlIGRvY3VtZW50IHRyZWUuCisJKiBSRVZJU0lUIFRPRE86IERvIHdlIGV4cGVjdCBJRC9JRFJFRiB0YWJsZXMgdG8gYmUgZXhpc3RlbnQ/CQorCSovCisJaWYgKFJWVC0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCSAgICB4bWxGcmVlTm9kZUxpc3QoUlZULT5jaGlsZHJlbik7CisJICAgIFJWVC0+Y2hpbGRyZW4gPSBOVUxMOworCSAgICBSVlQtPmxhc3QgPSBOVUxMOworCX0KKwlpZiAoUlZULT5pZHMgIT0gTlVMTCkgeworCSAgICB4bWxGcmVlSURUYWJsZSgoeG1sSURUYWJsZVB0cikgUlZULT5pZHMpOworCSAgICBSVlQtPmlkcyA9IE5VTEw7CisJfQorCWlmIChSVlQtPnJlZnMgIT0gTlVMTCkgeworCSAgICB4bWxGcmVlUmVmVGFibGUoKHhtbFJlZlRhYmxlUHRyKSBSVlQtPnJlZnMpOworCSAgICBSVlQtPnJlZnMgPSBOVUxMOworCX0KKworCS8qCisJKiBSZXNldCB0aGUgcmVmZXJlbmNlIGNvdW50ZXIuCisJKi8KKwlSVlQtPnBzdmkgPSAwOworCisJUlZULT5uZXh0ID0gKHhtbE5vZGVQdHIpIGN0eHQtPmNhY2hlLT5SVlQ7CisJY3R4dC0+Y2FjaGUtPlJWVCA9IFJWVDsKKworCWN0eHQtPmNhY2hlLT5uYlJWVCsrOworCisjaWZkZWYgWFNMVF9ERUJVR19QUk9GSUxFX0NBQ0hFCisJY3R4dC0+Y2FjaGUtPmRiZ0NhY2hlZFJWVHMrKzsKKyNlbmRpZgorCXJldHVybjsKKyAgICB9CisgICAgLyoKKyAgICAqIEZyZWUgaXQuCisgICAgKi8KKyAgICBpZiAoUlZULT5fcHJpdmF0ZSAhPSBOVUxMKSB7CisJeHNsdEZyZWVEb2N1bWVudEtleXMoKHhzbHREb2N1bWVudFB0cikgUlZULT5fcHJpdmF0ZSk7CisJeG1sRnJlZShSVlQtPl9wcml2YXRlKTsKKyAgICB9CisgICAgeG1sRnJlZURvYyhSVlQpOworfQorCisvKioKKyAqIHhzbHRSZWdpc3RlclBlcnNpc3RSVlQ6CisgKiBAY3R4dDogIGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQFJWVDogIGEgcmVzdWx0IHZhbHVlIHRyZWUgKFJlc3VsdCBUcmVlIEZyYWdtZW50KQorICoKKyAqIFJlZ2lzdGVyIHRoZSByZXN1bHQgdmFsdWUgdHJlZSAoWFNMVCAxLjAgdGVybTogUmVzdWx0IFRyZWUgRnJhZ21lbnQpCisgKiBpbiB0aGUgZnJhZ21lbnQgZ2FyYmFnZSBjb2xsZWN0b3IuCisgKiBUaGUgZnJhZ21lbnQgd2lsbCBiZSBmcmVlZCB3aGVuIHRoZSB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0IGlzCisgKiBmcmVlZC4KKyAqCisgKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzIGFuZCAtMSBpbiBjYXNlIG9mIGVycm9yLgorICovCitpbnQKK3hzbHRSZWdpc3RlclBlcnNpc3RSVlQoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sRG9jUHRyIFJWVCkKK3sKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKFJWVCA9PSBOVUxMKSkgcmV0dXJuKC0xKTsKKworICAgIFJWVC0+bmV4dCA9ICh4bWxOb2RlUHRyKSBjdHh0LT5wZXJzaXN0UlZUOworICAgIGlmIChjdHh0LT5wZXJzaXN0UlZUICE9IE5VTEwpCisJY3R4dC0+cGVyc2lzdFJWVC0+cHJldiA9ICh4bWxOb2RlUHRyKSBSVlQ7CisgICAgY3R4dC0+cGVyc2lzdFJWVCA9IFJWVDsKKyAgICByZXR1cm4oMCk7Cit9CisKKy8qKgorICogeHNsdEZyZWVSVlRzOgorICogQGN0eHQ6ICBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqCisgKiBGcmVlcyBhbGwgcmVnaXN0ZXJlZCByZXN1bHQgdmFsdWUgdHJlZXMgKFJlc3VsdCBUcmVlIEZyYWdtZW50cykKKyAqIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbi4gSW50ZXJuYWwgZnVuY3Rpb247IHNob3VsZCBub3QgYmUgY2FsbGVkCisgKiBieSB1c2VyLWNvZGUuCisgKi8KK3ZvaWQKK3hzbHRGcmVlUlZUcyh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KQoreworICAgIHhtbERvY1B0ciBjdXIsIG5leHQ7CisKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorCXJldHVybjsKKyAgICAvKgorICAgICogTG9jYWwgZnJhZ21lbnRzLgorICAgICovCisgICAgY3VyID0gY3R4dC0+bG9jYWxSVlQ7CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisgICAgICAgIG5leHQgPSAoeG1sRG9jUHRyKSBjdXItPm5leHQ7CisJaWYgKGN1ci0+X3ByaXZhdGUgIT0gTlVMTCkgeworCSAgICB4c2x0RnJlZURvY3VtZW50S2V5cyhjdXItPl9wcml2YXRlKTsKKwkgICAgeG1sRnJlZShjdXItPl9wcml2YXRlKTsKKwl9CisJeG1sRnJlZURvYyhjdXIpOworCWN1ciA9IG5leHQ7CisgICAgfQorICAgIGN0eHQtPmxvY2FsUlZUID0gTlVMTDsKKyAgICAvKgorICAgICogVXNlci1jcmVhdGVkIHBlci10ZW1wbGF0ZSBmcmFnbWVudHMuCisgICAgKi8KKyAgICBjdXIgPSBjdHh0LT50bXBSVlQ7CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisgICAgICAgIG5leHQgPSAoeG1sRG9jUHRyKSBjdXItPm5leHQ7CisJaWYgKGN1ci0+X3ByaXZhdGUgIT0gTlVMTCkgeworCSAgICB4c2x0RnJlZURvY3VtZW50S2V5cyhjdXItPl9wcml2YXRlKTsKKwkgICAgeG1sRnJlZShjdXItPl9wcml2YXRlKTsKKwl9CisJeG1sRnJlZURvYyhjdXIpOworCWN1ciA9IG5leHQ7CisgICAgfQorICAgIGN0eHQtPnRtcFJWVCA9IE5VTEw7CisgICAgLyoKKyAgICAqIEdsb2JhbCBmcmFnbWVudHMuCisgICAgKi8KKyAgICBjdXIgPSBjdHh0LT5wZXJzaXN0UlZUOworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworICAgICAgICBuZXh0ID0gKHhtbERvY1B0cikgY3VyLT5uZXh0OworCWlmIChjdXItPl9wcml2YXRlICE9IE5VTEwpIHsKKwkgICAgeHNsdEZyZWVEb2N1bWVudEtleXMoY3VyLT5fcHJpdmF0ZSk7CisJICAgIHhtbEZyZWUoY3VyLT5fcHJpdmF0ZSk7CisJfQorCXhtbEZyZWVEb2MoY3VyKTsKKwljdXIgPSBuZXh0OworICAgIH0KKyAgICBjdHh0LT5wZXJzaXN0UlZUID0gTlVMTDsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJCU1vZHVsZSBpbnRlcmZhY2VzCQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0TmV3U3RhY2tFbGVtOgorICoKKyAqIENyZWF0ZSBhIG5ldyBYU0xUIFBhcnNlckNvbnRleHQKKyAqCisgKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgeHNsdFBhcnNlclN0YWNrRWxlbSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworc3RhdGljIHhzbHRTdGFja0VsZW1QdHIKK3hzbHROZXdTdGFja0VsZW0oeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCkKK3sKKyAgICB4c2x0U3RhY2tFbGVtUHRyIHJldDsKKyAgICAvKgorICAgICogUmV1c2UgYSBzdGFjayBpdGVtIGZyb20gdGhlIGNhY2hlIGlmIGF2YWlsYWJsZS4KKyAgICAqLworICAgIGlmIChjdHh0ICYmIGN0eHQtPmNhY2hlLT5zdGFja0l0ZW1zKSB7CisJcmV0ID0gY3R4dC0+Y2FjaGUtPnN0YWNrSXRlbXM7CisJY3R4dC0+Y2FjaGUtPnN0YWNrSXRlbXMgPSByZXQtPm5leHQ7CisJcmV0LT5uZXh0ID0gTlVMTDsKKwljdHh0LT5jYWNoZS0+bmJTdGFja0l0ZW1zLS07CisjaWZkZWYgWFNMVF9ERUJVR19QUk9GSUxFX0NBQ0hFCisJY3R4dC0+Y2FjaGUtPmRiZ1JldXNlZFZhcnMrKzsKKyNlbmRpZgorCXJldHVybihyZXQpOworICAgIH0KKyAgICByZXQgPSAoeHNsdFN0YWNrRWxlbVB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0U3RhY2tFbGVtKSk7CisgICAgaWYgKHJldCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSJ4c2x0TmV3U3RhY2tFbGVtIDogbWFsbG9jIGZhaWxlZFxuIik7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeHNsdFN0YWNrRWxlbSkpOworICAgIHJldC0+Y29udGV4dCA9IGN0eHQ7CisgICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdENvcHlTdGFja0VsZW06CisgKiBAZWxlbTogIGFuIFhTTFQgc3RhY2sgZWxlbWVudAorICoKKyAqIE1ha2VzIGEgY29weSBvZiB0aGUgc3RhY2sgZWxlbWVudAorICoKKyAqIFJldHVybnMgdGhlIGNvcHkgb2YgTlVMTAorICovCitzdGF0aWMgeHNsdFN0YWNrRWxlbVB0cgoreHNsdENvcHlTdGFja0VsZW0oeHNsdFN0YWNrRWxlbVB0ciBlbGVtKSB7CisgICAgeHNsdFN0YWNrRWxlbVB0ciBjdXI7CisKKyAgICBjdXIgPSAoeHNsdFN0YWNrRWxlbVB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0U3RhY2tFbGVtKSk7CisgICAgaWYgKGN1ciA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSJ4c2x0Q29weVN0YWNrRWxlbSA6IG1hbGxvYyBmYWlsZWRcbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KGN1ciwgMCwgc2l6ZW9mKHhzbHRTdGFja0VsZW0pKTsKKyAgICBjdXItPmNvbnRleHQgPSBlbGVtLT5jb250ZXh0OworICAgIGN1ci0+bmFtZSA9IGVsZW0tPm5hbWU7CisgICAgY3VyLT5uYW1lVVJJID0gZWxlbS0+bmFtZVVSSTsKKyAgICBjdXItPnNlbGVjdCA9IGVsZW0tPnNlbGVjdDsKKyAgICBjdXItPnRyZWUgPSBlbGVtLT50cmVlOworICAgIGN1ci0+Y29tcCA9IGVsZW0tPmNvbXA7ICAgIAorICAgIHJldHVybihjdXIpOworfQorCisvKioKKyAqIHhzbHRGcmVlU3RhY2tFbGVtOgorICogQGVsZW06ICBhbiBYU0xUIHN0YWNrIGVsZW1lbnQKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGJ5IEBlbGVtCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0RnJlZVN0YWNrRWxlbSh4c2x0U3RhY2tFbGVtUHRyIGVsZW0pIHsKKyAgICBpZiAoZWxlbSA9PSBOVUxMKQorCXJldHVybjsKKyAgICBpZiAoZWxlbS0+dmFsdWUgIT0gTlVMTCkKKwl4bWxYUGF0aEZyZWVPYmplY3QoZWxlbS0+dmFsdWUpOworICAgIC8qCisgICAgKiBSZWxlYXNlIHRoZSBsaXN0IG9mIHRlbXBvcmFyeSBSZXN1bHQgVHJlZSBGcmFnbWVudHMuCisgICAgKi8KKyAgICBpZiAoZWxlbS0+ZnJhZ21lbnQpIHsKKwl4bWxEb2NQdHIgY3VyOworCisJd2hpbGUgKGVsZW0tPmZyYWdtZW50ICE9IE5VTEwpIHsKKwkgICAgY3VyID0gZWxlbS0+ZnJhZ21lbnQ7CisJICAgIGVsZW0tPmZyYWdtZW50ID0gKHhtbERvY1B0cikgY3VyLT5uZXh0OworCisJICAgIGlmIChlbGVtLT5jb250ZXh0ICYmCisJCShjdXItPnBzdmkgPT0gKHZvaWQgKikgKChsb25nKSAxKSkpCisJICAgIHsKKwkJLyoKKwkJKiBUaGlzIGZyYWdtZW50IGlzIGEgcmVzdWx0IG9mIGFuIGV4dGVuc2lvbiBpbnN0cnVjdGlvbgorCQkqIChlLmcuIFhTTFQncyBmdW5jdGlvbikgYW5kIG5lZWRzIHRvIGJlIHByZXNlcnZlZCB1bnRpbAorCQkqIHRoZSBpbnN0cnVjdGlvbiBleGl0cy4KKwkJKiBFeGFtcGxlOiBUaGUgZnJhZ21lbnQgb2YgdGhlIHZhcmlhYmxlIG11c3Qgbm90IGJlIGZyZWVkCisJCSogIHNpbmNlIGl0IGlzIHJldHVybmVkIGJ5IHRoZSBFWFNMVCBmdW5jdGlvbjoKKwkJKiAgPGY6ZnVuY3Rpb24gbmFtZT0iZm9vIj4KKwkJKiAgIDx4c2w6dmFyaWFibGUgbmFtZT0iYmFyIj4KKwkJKiAgICAgPGJhci8+CisJCSogICA8L3hzbDp2YXJpYWJsZT4KKwkJKiAgIDxmOnJlc3VsdCBzZWxlY3Q9IiRiYXIiLz4KKwkJKiAgPC9mOmZ1bmN0aW9uPgorCQkqIAorCQkqLworCQl4c2x0UmVnaXN0ZXJMb2NhbFJWVChlbGVtLT5jb250ZXh0LCBjdXIpOworCSAgICB9IGVsc2UgeworCQl4c2x0UmVsZWFzZVJWVCgoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIpIGVsZW0tPmNvbnRleHQsCisJCSAgICBjdXIpOworCSAgICB9CSAgICAKKwl9CisgICAgfQorICAgIC8qCisgICAgKiBDYWNoZSBvciBmcmVlIHRoZSB2YXJpYWJsZSBzdHJ1Y3R1cmUuCisgICAgKi8KKyAgICBpZiAoZWxlbS0+Y29udGV4dCAmJiAoZWxlbS0+Y29udGV4dC0+Y2FjaGUtPm5iU3RhY2tJdGVtcyA8IDUwKSkgeworCS8qCisJKiBTdG9yZSB0aGUgaXRlbSBpbiB0aGUgY2FjaGUuCisJKi8KKwl4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0ID0gZWxlbS0+Y29udGV4dDsKKwltZW1zZXQoZWxlbSwgMCwgc2l6ZW9mKHhzbHRTdGFja0VsZW0pKTsKKwllbGVtLT5jb250ZXh0ID0gY3R4dDsKKwllbGVtLT5uZXh0ID0gY3R4dC0+Y2FjaGUtPnN0YWNrSXRlbXM7CisJY3R4dC0+Y2FjaGUtPnN0YWNrSXRlbXMgPSBlbGVtOwkKKwljdHh0LT5jYWNoZS0+bmJTdGFja0l0ZW1zKys7CisjaWZkZWYgWFNMVF9ERUJVR19QUk9GSUxFX0NBQ0hFCisJY3R4dC0+Y2FjaGUtPmRiZ0NhY2hlZFZhcnMrKzsKKyNlbmRpZgorCXJldHVybjsKKyAgICB9CisgICAgeG1sRnJlZShlbGVtKTsKK30KKworLyoqCisgKiB4c2x0RnJlZVN0YWNrRWxlbUxpc3Q6CisgKiBAZWxlbTogIGFuIFhTTFQgc3RhY2sgZWxlbWVudAorICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgYnkgQGVsZW0KKyAqLwordm9pZAoreHNsdEZyZWVTdGFja0VsZW1MaXN0KHhzbHRTdGFja0VsZW1QdHIgZWxlbSkgeworICAgIHhzbHRTdGFja0VsZW1QdHIgbmV4dDsKKyAgICAKKyAgICB3aGlsZSAoZWxlbSAhPSBOVUxMKSB7CisJbmV4dCA9IGVsZW0tPm5leHQ7CisJeHNsdEZyZWVTdGFja0VsZW0oZWxlbSk7CisJZWxlbSA9IG5leHQ7CisgICAgfQorfQorCisvKioKKyAqIHhzbHRTdGFja0xvb2t1cDoKKyAqIEBjdHh0OiAgYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAbmFtZTogIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBuYW1lCisgKiBAbmFtZVVSSTogIHRoZSBVUkkgcGFydCBvZiB0aGUgbmFtZQorICoKKyAqIExvY2F0ZSBhbiBlbGVtZW50IGluIHRoZSBzdGFjayBiYXNlZCBvbiBpdHMgbmFtZS4KKyAqLworI2lmIDAgLyogVE9ETzogVGhvc2Ugc2VlbSB0byBoYXZlIGJlZW4gdXNlZCBmb3IgZGVidWdnaW5nLiAqLworc3RhdGljIGludCBzdGFja19hZGRyID0gMDsKK3N0YXRpYyBpbnQgc3RhY2tfY21wID0gMDsKKyNlbmRpZgorCitzdGF0aWMgeHNsdFN0YWNrRWxlbVB0cgoreHNsdFN0YWNrTG9va3VwKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKm5hbWUsCisJICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lVVJJKSB7CisgICAgaW50IGk7CisgICAgeHNsdFN0YWNrRWxlbVB0ciBjdXI7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkgfHwgKGN0eHQtPnZhcnNOciA9PSAwKSkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICAvKgorICAgICAqIERvIHRoZSBsb29rdXAgZnJvbSB0aGUgdG9wIG9mIHRoZSBzdGFjaywgYnV0CisgICAgICogZG9uJ3QgdXNlIHBhcmFtcyBiZWluZyBjb21wdXRlZCBpbiBhIGNhbGwtcGFyYW0KKyAgICAgKiBGaXJzdCBsb29rdXAgZXhwZWN0cyB0aGUgdmFyaWFibGUgbmFtZSBhbmQgVVJJIHRvCisgICAgICogY29tZSBmcm9tIHRoZSBkaXNjdGlvbm5hcnkgYW5kIGhlbmNlIHBvaW50ZXIgY29tcGFyaXNvbi4KKyAgICAgKi8KKyAgICBmb3IgKGkgPSBjdHh0LT52YXJzTnI7IGkgPiBjdHh0LT52YXJzQmFzZTsgaS0tKSB7CisJY3VyID0gY3R4dC0+dmFyc1RhYltpLTFdOworCXdoaWxlIChjdXIgIT0gTlVMTCkgeworCSAgICBpZiAoKGN1ci0+bmFtZSA9PSBuYW1lKSAmJiAoY3VyLT5uYW1lVVJJID09IG5hbWVVUkkpKSB7CisjaWYgMAorCQlzdGFja19hZGRyKys7CisjZW5kaWYKKwkJcmV0dXJuKGN1cik7CisJICAgIH0KKwkgICAgY3VyID0gY3VyLT5uZXh0OworCX0KKyAgICB9CisKKyAgICAvKgorICAgICAqIFJlZG8gdGhlIGxvb2t1cCB3aXRoIGludGVybmVkIHN0cmluZyBjb21wYXJlcworICAgICAqIHRvIGF2b2lkIHN0cmluZyBjb21wYXJlcy4KKyAgICAgKi8KKyAgICBuYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CisgICAgaWYgKG5hbWVVUkkgIT0gTlVMTCkKKyAgICAgICAgbmFtZVVSSSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZVVSSSwgLTEpOworCisgICAgZm9yIChpID0gY3R4dC0+dmFyc05yOyBpID4gY3R4dC0+dmFyc0Jhc2U7IGktLSkgeworCWN1ciA9IGN0eHQtPnZhcnNUYWJbaS0xXTsKKwl3aGlsZSAoY3VyICE9IE5VTEwpIHsKKwkgICAgaWYgKChjdXItPm5hbWUgPT0gbmFtZSkgJiYgKGN1ci0+bmFtZVVSSSA9PSBuYW1lVVJJKSkgeworI2lmIDAKKwkJc3RhY2tfY21wKys7CisjZW5kaWYKKwkJcmV0dXJuKGN1cik7CisJICAgIH0KKwkgICAgY3VyID0gY3VyLT5uZXh0OworCX0KKyAgICB9CisKKyAgICByZXR1cm4oTlVMTCk7Cit9CisKKy8qKgorICogeHNsdENoZWNrU3RhY2tFbGVtOgorICogQGN0eHQ6ICB4biBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBuYW1lOiAgdGhlIHZhcmlhYmxlIG5hbWUKKyAqIEBuYW1lVVJJOiAgdGhlIHZhcmlhYmxlIG5hbWVzcGFjZSBVUkkKKyAqCisgKiBDaGVja3Mgd2hldGhlciBhIHZhcmlhYmxlIG9yIHBhcmFtIGlzIGFscmVhZHkgZGVmaW5lZC4KKyAqCisgKiBVUkdFTlQgVE9ETzogQ2hlY2tzIGZvciByZWRlZmluaXRpb24gb2YgdmFycy9wYXJhbXMgc2hvdWxkIGJlCisgKiAgZG9uZSBvbmx5IGF0IGNvbXBpbGF0aW9uIHRpbWUuCisgKgorICogUmV0dXJucyAxIGlmIHZhcmlhYmxlIGlzIHByZXNlbnQsIDIgaWYgcGFyYW0gaXMgcHJlc2VudCwgMyBpZiB0aGlzCisgKiAgICAgICAgIGlzIGFuIGluaGVyaXRlZCBwYXJhbSwgMCBpZiBub3QgZm91bmQsIC0xIGluIGNhc2Ugb2YgZmFpbHVyZS4KKyAqLworc3RhdGljIGludAoreHNsdENoZWNrU3RhY2tFbGVtKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKm5hbWUsCisJICAgICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lVVJJKSB7CisgICAgeHNsdFN0YWNrRWxlbVB0ciBjdXI7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCisJcmV0dXJuKC0xKTsKKworICAgIGN1ciA9IHhzbHRTdGFja0xvb2t1cChjdHh0LCBuYW1lLCBuYW1lVVJJKTsKKyAgICBpZiAoY3VyID09IE5VTEwpCisgICAgICAgIHJldHVybigwKTsKKyAgICBpZiAoY3VyLT5jb21wICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKGN1ci0+Y29tcC0+dHlwZSA9PSBYU0xUX0ZVTkNfV0lUSFBBUkFNKQorCSAgICByZXR1cm4oMyk7CisJZWxzZSBpZiAoY3VyLT5jb21wLT50eXBlID09IFhTTFRfRlVOQ19QQVJBTSkKKwkgICAgcmV0dXJuKDIpOworICAgIH0KKyAgICAKKyAgICByZXR1cm4oMSk7Cit9CisKKy8qKgorICogeHNsdEFkZFN0YWNrRWxlbToKKyAqIEBjdHh0OiAgeG4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAZWxlbTogIGEgc3RhY2sgZWxlbWVudAorICoKKyAqIFB1c2ggYW4gZWxlbWVudCAob3IgbGlzdCkgb250byB0aGUgc3RhY2suCisgKiBJbiBjYXNlIG9mIGEgbGlzdCwgZWFjaCBtZW1iZXIgd2lsbCBiZSBwdXNoZWQgaW50bworICogYSBzZXBlcmF0ZSBzbG90OyBpLmUuIHRoZXJlJ3MgYWx3YXlzIDEgc3RhY2sgZW50cnkgZm9yCisgKiAxIHN0YWNrIGVsZW1lbnQuCisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgLTEgaW4gY2FzZSBvZiBmYWlsdXJlLgorICovCitzdGF0aWMgaW50Cit4c2x0QWRkU3RhY2tFbGVtKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhzbHRTdGFja0VsZW1QdHIgZWxlbSkKK3sKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGVsZW0gPT0gTlVMTCkpCisJcmV0dXJuKC0xKTsKKworICAgIGRvIHsKKwlpZiAoY3R4dC0+dmFyc01heCA9PSAwKSB7CisJICAgIGN0eHQtPnZhcnNNYXggPSAxMDsKKwkgICAgY3R4dC0+dmFyc1RhYiA9CisJCSh4c2x0U3RhY2tFbGVtUHRyICopIHhtbE1hbGxvYyhjdHh0LT52YXJzTWF4ICoKKwkJc2l6ZW9mKGN0eHQtPnZhcnNUYWJbMF0pKTsKKwkgICAgaWYgKGN0eHQtPnZhcnNUYWIgPT0gTlVMTCkgeworCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIm1hbGxvYyBmYWlsZWQgIVxuIik7CisJCXJldHVybiAoLTEpOworCSAgICB9CisJfQorCWlmIChjdHh0LT52YXJzTnIgPj0gY3R4dC0+dmFyc01heCkgeworCSAgICBjdHh0LT52YXJzTWF4ICo9IDI7CisJICAgIGN0eHQtPnZhcnNUYWIgPQorCQkoeHNsdFN0YWNrRWxlbVB0ciAqKSB4bWxSZWFsbG9jKGN0eHQtPnZhcnNUYWIsCisJCWN0eHQtPnZhcnNNYXggKgorCQlzaXplb2YoY3R4dC0+dmFyc1RhYlswXSkpOworCSAgICBpZiAoY3R4dC0+dmFyc1RhYiA9PSBOVUxMKSB7CisJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAicmVhbGxvYyBmYWlsZWQgIVxuIik7CisJCXJldHVybiAoLTEpOworCSAgICB9CisJfQorCWN0eHQtPnZhcnNUYWJbY3R4dC0+dmFyc05yKytdID0gZWxlbTsKKwljdHh0LT52YXJzID0gZWxlbTsKKwkKKwllbGVtID0gZWxlbS0+bmV4dDsKKyAgICB9IHdoaWxlIChlbGVtICE9IE5VTEwpOworICAgIAorICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0QWRkU3RhY2tFbGVtTGlzdDoKKyAqIEBjdHh0OiAgeG4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAZWxlbXM6ICBhIHN0YWNrIGVsZW1lbnQgbGlzdAorICoKKyAqIFB1c2ggYW4gZWxlbWVudCBsaXN0IG9udG8gdGhlIHN0YWNrLgorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgZmFpbHVyZS4KKyAqLworaW50Cit4c2x0QWRkU3RhY2tFbGVtTGlzdCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4c2x0U3RhY2tFbGVtUHRyIGVsZW1zKQoreworICAgIHJldHVybih4c2x0QWRkU3RhY2tFbGVtKGN0eHQsIGVsZW1zKSk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICoJCQlNb2R1bGUgaW50ZXJmYWNlcwkJCQkqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdEV2YWxWYXJpYWJsZToKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQHZhcmlhYmxlOiAgdGhlIHZhcmlhYmxlIG9yIHBhcmFtZXRlciBpdGVtCisgKiBAY29tcDogdGhlIGNvbXBpbGVkIFhTTFQgaW5zdHJ1Y3Rpb24KKyAqCisgKiBFdmFsdWF0ZSBhIHZhcmlhYmxlIHZhbHVlLgorICoKKyAqIFJldHVybnMgdGhlIFhQYXRoIE9iamVjdCB2YWx1ZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworc3RhdGljIHhtbFhQYXRoT2JqZWN0UHRyCit4c2x0RXZhbFZhcmlhYmxlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhzbHRTdGFja0VsZW1QdHIgdmFyaWFibGUsCisJICAgICAgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjYXN0ZWRDb21wKQoreworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1WYXJpYWJsZVB0ciBjb21wID0KKwkoeHNsdFN0eWxlSXRlbVZhcmlhYmxlUHRyKSBjYXN0ZWRDb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXAgPSBjYXN0ZWRDb21wOworI2VuZGlmICAgCisgICAgeG1sWFBhdGhPYmplY3RQdHIgcmVzdWx0ID0gTlVMTDsKKyAgICB4bWxOb2RlUHRyIG9sZEluc3Q7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHZhcmlhYmxlID09IE5VTEwpKQorCXJldHVybihOVUxMKTsKKworICAgIC8qCisgICAgKiBBIHZhcmlhYmxlIG9yIHBhcmFtZXRlciBhcmUgZXZhbHVhdGVkIG9uIGRlbWFuZDsgdGh1cyB0aGUKKyAgICAqIGNvbnRleHQgKG9mIFhTTFQgYW5kIFhQYXRoKSBuZWVkIHRvIGJlIHRlbXBvcmFyaWx5IGFkanVzdGVkIGFuZAorICAgICogcmVzdG9yZWQgb24gZXhpdC4KKyAgICAqLworICAgIG9sZEluc3QgPSBjdHh0LT5pbnN0OworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1ZBUklBQkxFCisgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfVkFSSUFCTEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJIkV2YWx1YXRpbmcgdmFyaWFibGUgJyVzJ1xuIiwgdmFyaWFibGUtPm5hbWUpKTsKKyNlbmRpZgorICAgIGlmICh2YXJpYWJsZS0+c2VsZWN0ICE9IE5VTEwpIHsKKwl4bWxYUGF0aENvbXBFeHByUHRyIHhwRXhwciA9IE5VTEw7CisJeG1sRG9jUHRyIG9sZFhQRG9jOworCXhtbE5vZGVQdHIgb2xkWFBDb250ZXh0Tm9kZTsKKwlpbnQgb2xkWFBQcm94aW1pdHlQb3NpdGlvbiwgb2xkWFBDb250ZXh0U2l6ZSwgb2xkWFBOc05yOworCXhtbE5zUHRyICpvbGRYUE5hbWVzcGFjZXM7CisJeG1sWFBhdGhDb250ZXh0UHRyIHhwY3R4dCA9IGN0eHQtPnhwYXRoQ3R4dDsKKwl4c2x0U3RhY2tFbGVtUHRyIG9sZFZhciA9IGN0eHQtPmNvbnRleHRWYXJpYWJsZTsKKworCWlmICgoY29tcCAhPSBOVUxMKSAmJiAoY29tcC0+Y29tcCAhPSBOVUxMKSkgeworCSAgICB4cEV4cHIgPSBjb21wLT5jb21wOworCX0gZWxzZSB7CisJICAgIHhwRXhwciA9IHhtbFhQYXRoQ29tcGlsZSh2YXJpYWJsZS0+c2VsZWN0KTsKKwl9CisJaWYgKHhwRXhwciA9PSBOVUxMKQorCSAgICByZXR1cm4oTlVMTCk7CisJLyoKKwkqIFNhdmUgY29udGV4dCBzdGF0ZXMuCisJKi8KKwlvbGRYUERvYyA9IHhwY3R4dC0+ZG9jOworCW9sZFhQQ29udGV4dE5vZGUgPSB4cGN0eHQtPm5vZGU7CisJb2xkWFBQcm94aW1pdHlQb3NpdGlvbiA9IHhwY3R4dC0+cHJveGltaXR5UG9zaXRpb247CisJb2xkWFBDb250ZXh0U2l6ZSA9IHhwY3R4dC0+Y29udGV4dFNpemU7CisJb2xkWFBOYW1lc3BhY2VzID0geHBjdHh0LT5uYW1lc3BhY2VzOworCW9sZFhQTnNOciA9IHhwY3R4dC0+bnNOcjsKKwkJCisJeHBjdHh0LT5ub2RlID0gY3R4dC0+bm9kZTsKKwkvKgorCSogT1BUSU1JWkUgVE9ETzogTGFtZSB0cnkgdG8gc2V0IHRoZSBjb250ZXh0IGRvYy4KKwkqICAgR2V0IHJpZCBvZiB0aGlzIHNvbWVob3cgaW4geHBhdGguYy4KKwkqLworCWlmICgoY3R4dC0+bm9kZS0+dHlwZSAhPSBYTUxfTkFNRVNQQUNFX0RFQ0wpICYmCisJICAgIGN0eHQtPm5vZGUtPmRvYykKKwkgICAgeHBjdHh0LT5kb2MgPSBjdHh0LT5ub2RlLT5kb2M7CisJLyoKKwkqIEJVRyBUT0RPOiBUaGUgcHJveGltaXR5IHBvc2l0aW9uIGFuZCB0aGUgY29udGV4dCBzaXplIHdpbGwKKwkqICBwb3RlbnRpYWxseSBiZSB3cm9uZy4KKwkqICBFeGFtcGxlOiAKKwkqICA8eHNsOnRlbXBsYXRlIHNlbGVjdD0iZm9vIj4KKwkqICAgIDx4c2w6dmFyaWFibGUgbmFtZT0icG9zIiBzZWxlY3Q9InBvc2l0aW9uKCkiLz4KKwkqICAgIDx4c2w6Zm9yLWVhY2ggc2VsZWN0PSJiYXIiPgorCSogICAgICA8eHNsOnZhbHVlLW9mIHNlbGVjdD0iJHBvcyIvPgorCSogICAgPC94c2w6Zm9yLWVhY2g+CisJKiAgPC94c2w6dGVtcGxhdGU+CisJKiAgSGVyZSB0aGUgcHJveGltaXR5IHBvc2l0aW9uIGFuZCBjb250ZXh0IHNpemUgYXJlIGNoYW5nZWQKKwkqICB0byB0aGUgY29udGV4dCBvZiA8eHNsOmZvci1lYWNoIHNlbGVjdD0iYmFyIj4sIGJ1dAorCSogIHRoZSB2YXJpYWJsZSBuZWVkcyB0byBiZSBldmFsdWF0ZWQgaW4gdGhlIGNvbnRleHQgb2YKKwkqICA8eHNsOnRlbXBsYXRlIHNlbGVjdD0iZm9vIj4uCisJKi8JCisJaWYgKGNvbXAgIT0gTlVMTCkgeworCSAgICAKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwkgICAgaWYgKGNvbXAtPmluU2NvcGVOcyAhPSBOVUxMKSB7CisJCXhwY3R4dC0+bmFtZXNwYWNlcyA9IGNvbXAtPmluU2NvcGVOcy0+bGlzdDsKKwkJeHBjdHh0LT5uc05yID0gY29tcC0+aW5TY29wZU5zLT54cGF0aE51bWJlcjsKKwkgICAgfSBlbHNlIHsKKwkJeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwkJeHBjdHh0LT5uc05yID0gMDsKKwkgICAgfQorI2Vsc2UKKwkgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gY29tcC0+bnNMaXN0OworCSAgICB4cGN0eHQtPm5zTnIgPSBjb21wLT5uc05yOworI2VuZGlmCisJfSBlbHNlIHsKKwkgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwkgICAgeHBjdHh0LT5uc05yID0gMDsKKwl9CisKKwkvKgorCSogV2UgbmVlZCB0byBtYXJrIHRoYXQgd2UgYXJlICJzZWxlY3RpbmciIGEgdmFyJ3MgdmFsdWU7CisJKiBpZiBhbnkgdHJlZSBmcmFnbWVudHMgYXJlIGNyZWF0ZWQgaW5zaWRlIHRoZSBleHByZXNzaW9uLAorCSogdGhlbiB0aG9zZSBuZWVkIHRvIGJlIHN0b3JlZCBpbnNpZGUgdGhlIHZhcmlhYmxlOyBvdGhlcndpc2UKKwkqIHdlJ2xsIGV2ZW50dWFsbHkgZnJlZSBzdGlsbCByZWZlcmVuY2VkIGZyYWdtZW50cywgYmVmb3JlCisJKiB3ZSBsZWF2ZSB0aGUgc2NvcGUgb2YgdGhlIHZhcmlhYmxlLgorCSovCisJY3R4dC0+Y29udGV4dFZhcmlhYmxlID0gdmFyaWFibGU7CQorCXZhcmlhYmxlLT5mbGFncyB8PSBYU0xUX1ZBUl9JTl9TRUxFQ1Q7CQorCQorCXJlc3VsdCA9IHhtbFhQYXRoQ29tcGlsZWRFdmFsKHhwRXhwciwgeHBjdHh0KTsKKworCXZhcmlhYmxlLT5mbGFncyBePSBYU0xUX1ZBUl9JTl9TRUxFQ1Q7CisJLyoKKwkqIFJlc3RvcmUgQ29udGV4dCBzdGF0ZXMuCisJKi8KKwljdHh0LT5jb250ZXh0VmFyaWFibGUgPSBvbGRWYXI7CisKKwl4cGN0eHQtPmRvYyA9IG9sZFhQRG9jOworCXhwY3R4dC0+bm9kZSA9IG9sZFhQQ29udGV4dE5vZGU7CisJeHBjdHh0LT5jb250ZXh0U2l6ZSA9IG9sZFhQQ29udGV4dFNpemU7CisJeHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IG9sZFhQUHJveGltaXR5UG9zaXRpb247CisJeHBjdHh0LT5uYW1lc3BhY2VzID0gb2xkWFBOYW1lc3BhY2VzOworCXhwY3R4dC0+bnNOciA9IG9sZFhQTnNOcjsKKworCWlmICgoY29tcCA9PSBOVUxMKSB8fCAoY29tcC0+Y29tcCA9PSBOVUxMKSkKKwkgICAgeG1sWFBhdGhGcmVlQ29tcEV4cHIoeHBFeHByKTsKKwlpZiAocmVzdWx0ID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsCisJCShjb21wICE9IE5VTEwpID8gY29tcC0+aW5zdCA6IE5VTEwsCisJCSJGYWlsZWQgdG8gZXZhbHVhdGUgdGhlIGV4cHJlc3Npb24gb2YgdmFyaWFibGUgJyVzJy5cbiIsCisJCXZhcmlhYmxlLT5uYW1lKTsKKwkgICAgY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfVkFSSUFCTEUKKyNpZmRlZiBMSUJYTUxfREVCVUdfRU5BQkxFRAorCX0gZWxzZSB7CisJICAgIGlmICgoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQgPT0gc3Rkb3V0KSB8fAorCQkoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQgPT0gc3RkZXJyKSkKKwkJeG1sWFBhdGhEZWJ1Z0R1bXBPYmplY3QoKEZJTEUgKil4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCQkJcmVzdWx0LCAwKTsKKyNlbmRpZgorI2VuZGlmCisJfQorICAgIH0gZWxzZSB7CisJaWYgKHZhcmlhYmxlLT50cmVlID09IE5VTEwpIHsKKwkgICAgcmVzdWx0ID0geG1sWFBhdGhOZXdDU3RyaW5nKCIiKTsKKwl9IGVsc2UgewkgICAgCisJICAgIGlmICh2YXJpYWJsZS0+dHJlZSkgeworCQl4bWxEb2NQdHIgY29udGFpbmVyOworCQl4bWxOb2RlUHRyIG9sZEluc2VydDsKKwkJeG1sRG9jUHRyICBvbGRPdXRwdXQ7CisJCXhzbHRTdGFja0VsZW1QdHIgb2xkVmFyID0gY3R4dC0+Y29udGV4dFZhcmlhYmxlOworCisJCS8qCisJCSogR2VuZXJhdGUgYSByZXN1bHQgdHJlZSBmcmFnbWVudC4KKwkJKi8KKwkJY29udGFpbmVyID0geHNsdENyZWF0ZVJWVChjdHh0KTsKKwkJaWYgKGNvbnRhaW5lciA9PSBOVUxMKQorCQkgICAgZ290byBlcnJvcjsKKwkJLyoKKwkJKiBOT1RFOiBMb2NhbCBSZXN1bHQgVHJlZSBGcmFnbWVudHMgb2YgcGFyYW1zL3ZhcmlhYmxlcworCQkqIGFyZSBub3QgcmVnaXN0ZXJlZCBnbG9iYWxseSBhbnltb3JlOyB0aGUgbGlmZS10aW1lCisJCSogaXMgbm90IGRpcmVjdGx5IGRlcGVuZGFudCBvZiB0aGUgcGFyYW0vdmFyaWFibGUgaXRzZWxmLgorCQkqCisJCSogT0xEOiB4c2x0UmVnaXN0ZXJUbXBSVlQoY3R4dCwgY29udGFpbmVyKTsKKwkJKi8KKwkJLyoKKwkJKiBBdHRhY2ggdGhlIFJlc3VsdCBUcmVlIEZyYWdtZW50IHRvIHRoZSB2YXJpYWJsZTsKKwkJKiB3aGVuIHRoZSB2YXJpYWJsZSBpcyBmcmVlZCwgaXQgd2lsbCBhbHNvIGZyZWUgCisJCSogdGhlIFJlc3VsdCBUcmVlIEZyYWdtZW50LgorCQkqLworCQl2YXJpYWJsZS0+ZnJhZ21lbnQgPSBjb250YWluZXI7CisJCQorCQlvbGRPdXRwdXQgPSBjdHh0LT5vdXRwdXQ7CisJCW9sZEluc2VydCA9IGN0eHQtPmluc2VydDsJCQorCQkKKwkJY3R4dC0+b3V0cHV0ID0gY29udGFpbmVyOworCQljdHh0LT5pbnNlcnQgPSAoeG1sTm9kZVB0cikgY29udGFpbmVyOworCQljdHh0LT5jb250ZXh0VmFyaWFibGUgPSB2YXJpYWJsZTsKKwkJLyoKKwkJKiBQcm9jZXNzIHRoZSBzZXF1ZW5jZSBjb25zdHJ1Y3RvciAodmFyaWFibGUtPnRyZWUpLgorCQkqIFRoZSByZXN1bHRpbmcgdHJlZSB3aWxsIGJlIGhlbGQgYnkgQGNvbnRhaW5lci4KKwkJKi8KKwkJeHNsdEFwcGx5T25lVGVtcGxhdGUoY3R4dCwgY3R4dC0+bm9kZSwgdmFyaWFibGUtPnRyZWUsCisJCSAgICBOVUxMLCBOVUxMKTsKKworCQljdHh0LT5jb250ZXh0VmFyaWFibGUgPSBvbGRWYXI7CQkKKwkJY3R4dC0+aW5zZXJ0ID0gb2xkSW5zZXJ0OworCQljdHh0LT5vdXRwdXQgPSBvbGRPdXRwdXQ7CisJCQorCQlyZXN1bHQgPSB4bWxYUGF0aE5ld1ZhbHVlVHJlZSgoeG1sTm9kZVB0cikgY29udGFpbmVyKTsKKwkgICAgfQorCSAgICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKwkJcmVzdWx0ID0geG1sWFBhdGhOZXdDU3RyaW5nKCIiKTsKKwkgICAgfSBlbHNlIHsKKwkJLyoKKwkJKiBGcmVlaW5nIGlzIG5vdCBoYW5kbGVkIHRoZXJlIGFueW1vcmUuCisJCSogUVVFU1RJT04gVE9ETzogV2hhdCBkb2VzIHRoZSBhYm92ZSBjb21tZW50IG1lYW4/CisJCSovCisJICAgICAgICByZXN1bHQtPmJvb2x2YWwgPSAwOyAKKwkgICAgfQorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorI2lmZGVmIExJQlhNTF9ERUJVR19FTkFCTEVECisKKwkgICAgaWYgKCh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCA9PSBzdGRvdXQpIHx8CisJCSh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCA9PSBzdGRlcnIpKQorCQl4bWxYUGF0aERlYnVnRHVtcE9iamVjdCgoRklMRSAqKXhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJCQlyZXN1bHQsIDApOworI2VuZGlmCisjZW5kaWYKKwl9CisgICAgfQorCitlcnJvcjoKKyAgICBjdHh0LT5pbnN0ID0gb2xkSW5zdDsKKyAgICByZXR1cm4ocmVzdWx0KTsKK30KKworLyoqCisgKiB4c2x0RXZhbEdsb2JhbFZhcmlhYmxlOgorICogQGVsZW06ICB0aGUgdmFyaWFibGUgb3IgcGFyYW1ldGVyCisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqCisgKiBFdmFsdWF0ZXMgYSB0aGUgdmFsdWUgb2YgYSBnbG9iYWwgeHNsOnZhcmlhYmxlIG9yCisgKiB4c2w6cGFyYW0gZGVjbGFyYXRpb24uCisgKgorICogUmV0dXJucyB0aGUgWFBhdGggT2JqZWN0IHZhbHVlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgorICovCitzdGF0aWMgeG1sWFBhdGhPYmplY3RQdHIKK3hzbHRFdmFsR2xvYmFsVmFyaWFibGUoeHNsdFN0YWNrRWxlbVB0ciBlbGVtLCB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KQoreworICAgIHhtbFhQYXRoT2JqZWN0UHRyIHJlc3VsdCA9IE5VTEw7CisgICAgeG1sTm9kZVB0ciBvbGRJbnN0OworICAgIGNvbnN0IHhtbENoYXIqIG9sZFZhck5hbWU7CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVCYXNpY0l0ZW1WYXJpYWJsZVB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZWxlbSA9PSBOVUxMKSkKKwlyZXR1cm4oTlVMTCk7CisgICAgaWYgKGVsZW0tPmNvbXB1dGVkKQorCXJldHVybihlbGVtLT52YWx1ZSk7CisKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJFdmFsdWF0aW5nIGdsb2JhbCB2YXJpYWJsZSAlc1xuIiwgZWxlbS0+bmFtZSkpOworI2VuZGlmCisKKyNpZmRlZiBXSVRIX0RFQlVHR0VSCisgICAgaWYgKChjdHh0LT5kZWJ1Z1N0YXR1cyAhPSBYU0xUX0RFQlVHX05PTkUpICYmCisgICAgICAgIGVsZW0tPmNvbXAgJiYgZWxlbS0+Y29tcC0+aW5zdCkKKyAgICAgICAgeHNsSGFuZGxlRGVidWdnZXIoZWxlbS0+Y29tcC0+aW5zdCwgTlVMTCwgTlVMTCwgY3R4dCk7CisjZW5kaWYKKworICAgIG9sZEluc3QgPSBjdHh0LT5pbnN0OworICAgIGNvbXAgPSBlbGVtLT5jb21wOworICAgIG9sZFZhck5hbWUgPSBlbGVtLT5uYW1lOworICAgIGVsZW0tPm5hbWUgPSB4c2x0Q29tcHV0aW5nR2xvYmFsVmFyTWFya2VyOworICAgIC8qCisgICAgKiBPUFRJTUlaRSBUT0RPOiBXZSBzaG91bGQgY29uc2lkZXIgaW5zdGFudGlhdGluZyBnbG9iYWwgdmFycy9wYXJhbXMKKyAgICAqICBvbi1kZW1hbmQuIFRoZSB2YXJzL3BhcmFtcyBkb24ndCBuZWVkIHRvIGJlIGV2YWx1YXRlZCBpZiBuZXZlcgorICAgICogIGNhbGxlZDsgYW5kIGluIHRoZSBjYXNlIG9mIGdsb2JhbCBwYXJhbXMsIGlmIHZhbHVlcyBmb3Igc3VjaCBwYXJhbXMKKyAgICAqICBhcmUgcHJvdmlkZWQgYnkgdGhlIHVzZXIuCisgICAgKi8KKyAgICBpZiAoZWxlbS0+c2VsZWN0ICE9IE5VTEwpIHsJCQorCXhtbFhQYXRoQ29tcEV4cHJQdHIgeHBFeHByID0gTlVMTDsKKwl4bWxEb2NQdHIgb2xkWFBEb2M7CisJeG1sTm9kZVB0ciBvbGRYUENvbnRleHROb2RlOworCWludCBvbGRYUFByb3hpbWl0eVBvc2l0aW9uLCBvbGRYUENvbnRleHRTaXplLCBvbGRYUE5zTnI7CisJeG1sTnNQdHIgKm9sZFhQTmFtZXNwYWNlczsKKwl4bWxYUGF0aENvbnRleHRQdHIgeHBjdHh0ID0gY3R4dC0+eHBhdGhDdHh0OworCisJaWYgKChjb21wICE9IE5VTEwpICYmIChjb21wLT5jb21wICE9IE5VTEwpKSB7CisJICAgIHhwRXhwciA9IGNvbXAtPmNvbXA7CisJfSBlbHNlIHsKKwkgICAgeHBFeHByID0geG1sWFBhdGhDb21waWxlKGVsZW0tPnNlbGVjdCk7CisJfQorCWlmICh4cEV4cHIgPT0gTlVMTCkKKwkgICAgZ290byBlcnJvcjsKKwkKKwkKKwlpZiAoY29tcCAhPSBOVUxMKQorCSAgICBjdHh0LT5pbnN0ID0gY29tcC0+aW5zdDsKKwllbHNlCisJICAgIGN0eHQtPmluc3QgPSBOVUxMOworCS8qCisJKiBTUEVDIFhTTFQgMS4wOgorCSogIkF0IHRvcC1sZXZlbCwgdGhlIGV4cHJlc3Npb24gb3IgdGVtcGxhdGUgc3BlY2lmeWluZyB0aGUKKwkqICB2YXJpYWJsZSB2YWx1ZSBpcyBldmFsdWF0ZWQgd2l0aCB0aGUgc2FtZSBjb250ZXh0IGFzIHRoYXQgdXNlZAorCSogIHRvIHByb2Nlc3MgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgc291cmNlIGRvY3VtZW50OiB0aGUgY3VycmVudAorCSogIG5vZGUgaXMgdGhlIHJvb3Qgbm9kZSBvZiB0aGUgc291cmNlIGRvY3VtZW50IGFuZCB0aGUgY3VycmVudAorCSogIG5vZGUgbGlzdCBpcyBhIGxpc3QgY29udGFpbmluZyBqdXN0IHRoZSByb290IG5vZGUgb2YgdGhlIHNvdXJjZQorCSogIGRvY3VtZW50LiIJCisJKi8KKwkvKgorCSogU2F2ZSBjb250ZXh0IHN0YXRlcy4KKwkqLworCW9sZFhQRG9jID0geHBjdHh0LT5kb2M7CisJb2xkWFBDb250ZXh0Tm9kZSA9IHhwY3R4dC0+bm9kZTsKKwlvbGRYUFByb3hpbWl0eVBvc2l0aW9uID0geHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbjsKKwlvbGRYUENvbnRleHRTaXplID0geHBjdHh0LT5jb250ZXh0U2l6ZTsKKwlvbGRYUE5hbWVzcGFjZXMgPSB4cGN0eHQtPm5hbWVzcGFjZXM7CisJb2xkWFBOc05yID0geHBjdHh0LT5uc05yOworCQkKKwl4cGN0eHQtPm5vZGUgPSBjdHh0LT5pbml0aWFsQ29udGV4dE5vZGU7CisJeHBjdHh0LT5kb2MgPSBjdHh0LT5pbml0aWFsQ29udGV4dERvYzsKKwl4cGN0eHQtPmNvbnRleHRTaXplID0gMTsKKwl4cGN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gMTsKKwkJCisJaWYgKGNvbXAgIT0gTlVMTCkgeworCSAgICAKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwkgICAgaWYgKGNvbXAtPmluU2NvcGVOcyAhPSBOVUxMKSB7CisJCXhwY3R4dC0+bmFtZXNwYWNlcyA9IGNvbXAtPmluU2NvcGVOcy0+bGlzdDsKKwkJeHBjdHh0LT5uc05yID0gY29tcC0+aW5TY29wZU5zLT54cGF0aE51bWJlcjsKKwkgICAgfSBlbHNlIHsKKwkJeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwkJeHBjdHh0LT5uc05yID0gMDsKKwkgICAgfQorI2Vsc2UKKwkgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gY29tcC0+bnNMaXN0OworCSAgICB4cGN0eHQtPm5zTnIgPSBjb21wLT5uc05yOworI2VuZGlmCisJfSBlbHNlIHsKKwkgICAgeHBjdHh0LT5uYW1lc3BhY2VzID0gTlVMTDsKKwkgICAgeHBjdHh0LT5uc05yID0gMDsKKwl9CisJCisJcmVzdWx0ID0geG1sWFBhdGhDb21waWxlZEV2YWwoeHBFeHByLCB4cGN0eHQpOworCisJLyoKKwkqIFJlc3RvcmUgQ29udGV4dCBzdGF0ZXMuCisJKi8KKwl4cGN0eHQtPmRvYyA9IG9sZFhQRG9jOworCXhwY3R4dC0+bm9kZSA9IG9sZFhQQ29udGV4dE5vZGU7CisJeHBjdHh0LT5jb250ZXh0U2l6ZSA9IG9sZFhQQ29udGV4dFNpemU7CisJeHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IG9sZFhQUHJveGltaXR5UG9zaXRpb247CisJeHBjdHh0LT5uYW1lc3BhY2VzID0gb2xkWFBOYW1lc3BhY2VzOworCXhwY3R4dC0+bnNOciA9IG9sZFhQTnNOcjsKKworCWlmICgoY29tcCA9PSBOVUxMKSB8fCAoY29tcC0+Y29tcCA9PSBOVUxMKSkKKwkgICAgeG1sWFBhdGhGcmVlQ29tcEV4cHIoeHBFeHByKTsKKwlpZiAocmVzdWx0ID09IE5VTEwpIHsKKwkgICAgaWYgKGNvbXAgPT0gTlVMTCkKKwkJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIE5VTEwsIE5VTEwsCisJCSAgICAiRXZhbHVhdGluZyBnbG9iYWwgdmFyaWFibGUgJXMgZmFpbGVkXG4iLCBlbGVtLT5uYW1lKTsKKwkgICAgZWxzZQorCQl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgY29tcC0+aW5zdCwKKwkJICAgICJFdmFsdWF0aW5nIGdsb2JhbCB2YXJpYWJsZSAlcyBmYWlsZWRcbiIsIGVsZW0tPm5hbWUpOworCSAgICBjdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfVkFSSUFCTEUKKyNpZmRlZiBMSUJYTUxfREVCVUdfRU5BQkxFRAorCX0gZWxzZSB7CisJICAgIGlmICgoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQgPT0gc3Rkb3V0KSB8fAorCQkoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQgPT0gc3RkZXJyKSkKKwkJeG1sWFBhdGhEZWJ1Z0R1bXBPYmplY3QoKEZJTEUgKil4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCQkJcmVzdWx0LCAwKTsKKyNlbmRpZgorI2VuZGlmCisJfQorICAgIH0gZWxzZSB7CisJaWYgKGVsZW0tPnRyZWUgPT0gTlVMTCkgeworCSAgICByZXN1bHQgPSB4bWxYUGF0aE5ld0NTdHJpbmcoIiIpOworCX0gZWxzZSB7CisJICAgIHhtbERvY1B0ciBjb250YWluZXI7CisJICAgIHhtbE5vZGVQdHIgb2xkSW5zZXJ0OworCSAgICB4bWxEb2NQdHIgIG9sZE91dHB1dCwgb2xkWFBEb2M7CSAgICAKKwkgICAgLyoKKwkgICAgKiBHZW5lcmF0ZSBhIHJlc3VsdCB0cmVlIGZyYWdtZW50LgorCSAgICAqLworCSAgICBjb250YWluZXIgPSB4c2x0Q3JlYXRlUlZUKGN0eHQpOworCSAgICBpZiAoY29udGFpbmVyID09IE5VTEwpCisJCWdvdG8gZXJyb3I7CisJICAgIC8qCisJICAgICogTGV0IHRoZSBsaWZldGltZSBvZiB0aGUgdHJlZSBmcmFnbWVudCBiZSBoYW5kbGVkIGJ5CisJICAgICogdGhlIExpYnhzbHQncyBnYXJiYWdlIGNvbGxlY3Rvci4KKwkgICAgKi8KKwkgICAgeHNsdFJlZ2lzdGVyUGVyc2lzdFJWVChjdHh0LCBjb250YWluZXIpOwkgICAgCisKKwkgICAgb2xkT3V0cHV0ID0gY3R4dC0+b3V0cHV0OworCSAgICBvbGRJbnNlcnQgPSBjdHh0LT5pbnNlcnQ7CisKKwkgICAgb2xkWFBEb2MgPSBjdHh0LT54cGF0aEN0eHQtPmRvYzsKKwkgICAgCisJICAgIGN0eHQtPm91dHB1dCA9IGNvbnRhaW5lcjsJICAgIAorCSAgICBjdHh0LT5pbnNlcnQgPSAoeG1sTm9kZVB0cikgY29udGFpbmVyOworCisJICAgIGN0eHQtPnhwYXRoQ3R4dC0+ZG9jID0gY3R4dC0+aW5pdGlhbENvbnRleHREb2M7CisJICAgIC8qCisJICAgICogUHJvY2VzcyB0aGUgc2VxdWVuY2UgY29uc3RydWN0b3IuCisJICAgICovCisJICAgIHhzbHRBcHBseU9uZVRlbXBsYXRlKGN0eHQsIGN0eHQtPm5vZGUsIGVsZW0tPnRyZWUsIE5VTEwsIE5VTEwpOworCisJICAgIGN0eHQtPnhwYXRoQ3R4dC0+ZG9jID0gb2xkWFBEb2M7CisKKwkgICAgY3R4dC0+aW5zZXJ0ID0gb2xkSW5zZXJ0OworCSAgICBjdHh0LT5vdXRwdXQgPSBvbGRPdXRwdXQ7CisJICAgIAorCSAgICByZXN1bHQgPSB4bWxYUGF0aE5ld1ZhbHVlVHJlZSgoeG1sTm9kZVB0cikgY29udGFpbmVyKTsKKwkgICAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisJCXJlc3VsdCA9IHhtbFhQYXRoTmV3Q1N0cmluZygiIik7CisJICAgIH0gZWxzZSB7CisJICAgICAgICByZXN1bHQtPmJvb2x2YWwgPSAwOyAvKiBGcmVlaW5nIGlzIG5vdCBoYW5kbGVkIHRoZXJlIGFueW1vcmUgKi8KKwkgICAgfQorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorI2lmZGVmIExJQlhNTF9ERUJVR19FTkFCTEVECisJICAgIGlmICgoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQgPT0gc3Rkb3V0KSB8fAorCQkoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQgPT0gc3RkZXJyKSkKKwkJeG1sWFBhdGhEZWJ1Z0R1bXBPYmplY3QoKEZJTEUgKil4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCQkJcmVzdWx0LCAwKTsKKyNlbmRpZgorI2VuZGlmCisJfQorICAgIH0KKworZXJyb3I6CisgICAgZWxlbS0+bmFtZSA9IG9sZFZhck5hbWU7CisgICAgY3R4dC0+aW5zdCA9IG9sZEluc3Q7CisgICAgaWYgKHJlc3VsdCAhPSBOVUxMKSB7CisJZWxlbS0+dmFsdWUgPSByZXN1bHQ7CisJZWxlbS0+Y29tcHV0ZWQgPSAxOworICAgIH0KKyAgICByZXR1cm4ocmVzdWx0KTsKK30KKworLyoqCisgKiB4c2x0RXZhbEdsb2JhbFZhcmlhYmxlczoKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICoKKyAqIEV2YWx1YXRlcyBhbGwgZ2xvYmFsIHZhcmlhYmxlcyBhbmQgcGFyYW1ldGVycyBvZiBhIHN0eWxlc2hlZXQuCisgKiBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuIFRoaXMgaXMgY2FsbGVkIGF0IHN0YXJ0IG9mIGEgdHJhbnNmb3JtYXRpb24uCisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgLTEgaW4gY2FzZSBvZiBlcnJvcgorICovCitpbnQKK3hzbHRFdmFsR2xvYmFsVmFyaWFibGVzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpIHsKKyAgICB4c2x0U3RhY2tFbGVtUHRyIGVsZW07CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7ICAgIAorCisgICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChjdHh0LT5kb2N1bWVudCA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworIAorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJSZWdpc3RlcmluZyBnbG9iYWwgdmFyaWFibGVzXG4iKSk7CisjZW5kaWYKKyAgICAvKgorICAgICAqIFdhbGsgdGhlIGxpc3QgZnJvbSB0aGUgc3R5bGVzaGVldHMgYW5kIHBvcHVsYXRlIHRoZSBoYXNoIHRhYmxlCisgICAgICovCisgICAgc3R5bGUgPSBjdHh0LT5zdHlsZTsKKyAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworCWVsZW0gPSBzdHlsZS0+dmFyaWFibGVzOworCQorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorCWlmICgoc3R5bGUtPmRvYyAhPSBOVUxMKSAmJiAoc3R5bGUtPmRvYy0+VVJMICE9IE5VTEwpKSB7CisJICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJICAgICAiUmVnaXN0ZXJpbmcgZ2xvYmFsIHZhcmlhYmxlcyBmcm9tICVzXG4iLAorCQkgICAgICAgICAgICAgc3R5bGUtPmRvYy0+VVJMKSk7CisJfQorI2VuZGlmCisKKwl3aGlsZSAoZWxlbSAhPSBOVUxMKSB7CisJICAgIHhzbHRTdGFja0VsZW1QdHIgZGVmOworCisJICAgIC8qCisJICAgICAqIEdsb2JhbCB2YXJpYWJsZXMgYXJlIHN0b3JlZCBpbiB0aGUgdmFyaWFibGVzIHBvb2wuCisJICAgICAqLworCSAgICBkZWYgPSAoeHNsdFN0YWNrRWxlbVB0cikgCisJCSAgICB4bWxIYXNoTG9va3VwMihjdHh0LT5nbG9iYWxWYXJzLAorCQkgICAgICAgICAgICAgICAgIGVsZW0tPm5hbWUsIGVsZW0tPm5hbWVVUkkpOworCSAgICBpZiAoZGVmID09IE5VTEwpIHsKKworCQlkZWYgPSB4c2x0Q29weVN0YWNrRWxlbShlbGVtKTsKKwkJeG1sSGFzaEFkZEVudHJ5MihjdHh0LT5nbG9iYWxWYXJzLAorCQkJCSBlbGVtLT5uYW1lLCBlbGVtLT5uYW1lVVJJLCBkZWYpOworCSAgICB9IGVsc2UgaWYgKChlbGVtLT5jb21wICE9IE5VTEwpICYmCisJCSAgICAgICAoZWxlbS0+Y29tcC0+dHlwZSA9PSBYU0xUX0ZVTkNfVkFSSUFCTEUpKSB7CisJCS8qCisJCSAqIFJlZGVmaW5pdGlvbiBvZiB2YXJpYWJsZXMgZnJvbSBhIGRpZmZlcmVudCBzdHlsZXNoZWV0CisJCSAqIHNob3VsZCBub3QgZ2VuZXJhdGUgYSBtZXNzYWdlLgorCQkgKi8KKwkJaWYgKChlbGVtLT5jb21wLT5pbnN0ICE9IE5VTEwpICYmCisJCSAgICAoZGVmLT5jb21wICE9IE5VTEwpICYmIChkZWYtPmNvbXAtPmluc3QgIT0gTlVMTCkgJiYKKwkJICAgIChlbGVtLT5jb21wLT5pbnN0LT5kb2MgPT0gZGVmLT5jb21wLT5pbnN0LT5kb2MpKQorCQl7CisJCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgc3R5bGUsIGVsZW0tPmNvbXAtPmluc3QsCisJCQkiR2xvYmFsIHZhcmlhYmxlICVzIGFscmVhZHkgZGVmaW5lZFxuIiwgZWxlbS0+bmFtZSk7CisJCSAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPmVycm9ycysrOworCQl9CisJICAgIH0KKwkgICAgZWxlbSA9IGVsZW0tPm5leHQ7CisJfQorCisJc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBUaGlzIHBhcnQgZG9lcyB0aGUgYWN0dWFsIGV2YWx1YXRpb24KKyAgICAgKi8gICAgCisgICAgeG1sSGFzaFNjYW4oY3R4dC0+Z2xvYmFsVmFycywKKwkgICAgICAgICh4bWxIYXNoU2Nhbm5lcikgeHNsdEV2YWxHbG9iYWxWYXJpYWJsZSwgY3R4dCk7CisKKyAgICByZXR1cm4oMCk7Cit9CisKKy8qKgorICogeHNsdFJlZ2lzdGVyR2xvYmFsVmFyaWFibGU6CisgKiBAc3R5bGU6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAbmFtZTogIHRoZSB2YXJpYWJsZSBuYW1lCisgKiBAbnNfdXJpOiAgdGhlIHZhcmlhYmxlIG5hbWVzcGFjZSBVUkkKKyAqIEBzZWw6ICB0aGUgZXhwcmVzc2lvbiB3aGljaCBuZWVkIHRvIGJlIGV2YWx1YXRlZCB0byBnZW5lcmF0ZSBhIHZhbHVlCisgKiBAdHJlZTogIHRoZSBzdWJ0cmVlIGlmIHNlbCBpcyBOVUxMCisgKiBAY29tcDogIHRoZSBwcmVjb21waWxlZCB2YWx1ZQorICogQHZhbHVlOiAgdGhlIHN0cmluZyB2YWx1ZSBpZiBhdmFpbGFibGUKKyAqCisgKiBSZWdpc3RlciBhIG5ldyB2YXJpYWJsZSB2YWx1ZS4gSWYgQHZhbHVlIGlzIE5VTEwgaXQgdW5yZWdpc3RlcnMKKyAqIHRoZSB2YXJpYWJsZQorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworc3RhdGljIGludAoreHNsdFJlZ2lzdGVyR2xvYmFsVmFyaWFibGUoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCSAgICAgY29uc3QgeG1sQ2hhciAqbnNfdXJpLCBjb25zdCB4bWxDaGFyICpzZWwsCisJCSAgICAgeG1sTm9kZVB0ciB0cmVlLCB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXAsCisJCSAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUpIHsKKyAgICB4c2x0U3RhY2tFbGVtUHRyIGVsZW0sIHRtcDsKKyAgICBpZiAoc3R5bGUgPT0gTlVMTCkKKwlyZXR1cm4oLTEpOworICAgIGlmIChuYW1lID09IE5VTEwpCisJcmV0dXJuKC0xKTsKKyAgICBpZiAoY29tcCA9PSBOVUxMKQorCXJldHVybigtMSk7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfVkFSSUFCTEUKKyAgICBpZiAoY29tcC0+dHlwZSA9PSBYU0xUX0ZVTkNfUEFSQU0pCisJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSAiRGVmaW5pbmcgZ2xvYmFsIHBhcmFtICVzXG4iLCBuYW1lKTsKKyAgICBlbHNlCisJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSAiRGVmaW5pbmcgZ2xvYmFsIHZhcmlhYmxlICVzXG4iLCBuYW1lKTsKKyNlbmRpZgorCisgICAgZWxlbSA9IHhzbHROZXdTdGFja0VsZW0oTlVMTCk7CisgICAgaWYgKGVsZW0gPT0gTlVMTCkKKwlyZXR1cm4oLTEpOworICAgIGVsZW0tPmNvbXAgPSBjb21wOworICAgIGVsZW0tPm5hbWUgPSB4bWxEaWN0TG9va3VwKHN0eWxlLT5kaWN0LCBuYW1lLCAtMSk7CisgICAgZWxlbS0+c2VsZWN0ID0geG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgc2VsLCAtMSk7CisgICAgaWYgKG5zX3VyaSkKKwllbGVtLT5uYW1lVVJJID0geG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgbnNfdXJpLCAtMSk7CisgICAgZWxlbS0+dHJlZSA9IHRyZWU7CisgICAgdG1wID0gc3R5bGUtPnZhcmlhYmxlczsKKyAgICBpZiAodG1wID09IE5VTEwpIHsKKwllbGVtLT5uZXh0ID0gTlVMTDsKKwlzdHlsZS0+dmFyaWFibGVzID0gZWxlbTsKKyAgICB9IGVsc2UgeworCXdoaWxlICh0bXAgIT0gTlVMTCkgeworCSAgICBpZiAoKGVsZW0tPmNvbXAtPnR5cGUgPT0gWFNMVF9GVU5DX1ZBUklBQkxFKSAmJgorCQkodG1wLT5jb21wLT50eXBlID09IFhTTFRfRlVOQ19WQVJJQUJMRSkgJiYKKwkJKHhtbFN0ckVxdWFsKGVsZW0tPm5hbWUsIHRtcC0+bmFtZSkpICYmCisJCSgoZWxlbS0+bmFtZVVSSSA9PSB0bXAtPm5hbWVVUkkpIHx8CisJCSAoeG1sU3RyRXF1YWwoZWxlbS0+bmFtZVVSSSwgdG1wLT5uYW1lVVJJKSkpKQorCSAgICB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY29tcC0+aW5zdCwKKwkJInJlZGVmaW5pdGlvbiBvZiBnbG9iYWwgdmFyaWFibGUgJXNcbiIsIGVsZW0tPm5hbWUpOworCQlzdHlsZS0+ZXJyb3JzKys7CisJICAgIH0KKwkgICAgaWYgKHRtcC0+bmV4dCA9PSBOVUxMKQorCSAgICAgICAgYnJlYWs7CisJICAgIHRtcCA9IHRtcC0+bmV4dDsKKwl9CisJZWxlbS0+bmV4dCA9IE5VTEw7CisJdG1wLT5uZXh0ID0gZWxlbTsKKyAgICB9CisgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKwllbGVtLT5jb21wdXRlZCA9IDE7CisJZWxlbS0+dmFsdWUgPSB4bWxYUGF0aE5ld1N0cmluZyh2YWx1ZSk7CisgICAgfQorICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0UHJvY2Vzc1VzZXJQYXJhbUludGVybmFsCisgKgorICogQGN0eHQ6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAbmFtZTogIGEgbnVsbCB0ZXJtaW5hdGVkIHBhcmFtZXRlciBuYW1lCisgKiBAdmFsdWU6IGEgbnVsbCB0ZXJtaW5hdGVkIHZhbHVlIChtYXkgYmUgYW4gWFBhdGggZXhwcmVzc2lvbikKKyAqIEBldmFsOiAgMCB0byB0cmVhdCB0aGUgdmFsdWUgbGl0ZXJhbGx5LCBlbHNlIGV2YWx1YXRlIGFzIFhQYXRoIGV4cHJlc3Npb24KKyAqCisgKiBJZiBAZXZhbCBpcyAwIHRoZW4gQHZhbHVlIGlzIHRyZWF0ZWQgbGl0ZXJhbGx5IGFuZCBpcyBzdG9yZWQgaW4gdGhlIGdsb2JhbAorICogcGFyYW1ldGVyL3ZhcmlhYmxlIHRhYmxlIHdpdGhvdXQgYW55IGNoYW5nZS4KKyAqCisgKiBVZiBAZXZhbCBpcyAxIHRoZW4gQHZhbHVlIGlzIHRyZWF0ZWQgYXMgYW4gWFBhdGggZXhwcmVzc2lvbiBhbmQgaXMKKyAqIGV2YWx1YXRlZC4gIEluIHRoaXMgY2FzZSwgaWYgeW91IHdhbnQgdG8gcGFzcyBhIHN0cmluZyB3aGljaCB3aWxsIGJlCisgKiBpbnRlcnByZXRlZCBsaXRlcmFsbHkgdGhlbiBpdCBtdXN0IGJlIGVuY2xvc2VkIGluIHNpbmdsZSBvciBkb3VibGUgcXVvdGVzLgorICogSWYgdGhlIHN0cmluZyBjb250YWlucyBzaW5nbGUgcXVvdGVzIChkb3VibGUgcXVvdGVzKSB0aGVuIGl0IGNhbm5vdCBiZQorICogZW5jbG9zZWQgc2luZ2xlIHF1b3RlcyAoZG91YmxlIHF1b3RlcykuICBJZiB0aGUgc3RyaW5nIHdoaWNoIHlvdSB3YW50IHRvCisgKiBiZSB0cmVhdGVkIGxpdGVyYWxseSBjb250YWlucyBib3RoIHNpbmdsZSBhbmQgZG91YmxlIHF1b3RlcyAoZS5nLiBNZWV0CisgKiBhdCBKb2UncyBmb3IgIlR3ZWxmdGggTmlnaHQiIGF0IDcgbydjbG9jaykgdGhlbiB0aGVyZSBpcyBubyBzdWl0YWJsZQorICogcXVvdGluZyBjaGFyYWN0ZXIuICBZb3UgY2Fubm90IHVzZSAmYXBvczsgb3IgJnF1b3Q7IGluc2lkZSB0aGUgc3RyaW5nCisgKiBiZWNhdXNlIHRoZSByZXBsYWNlbWVudCBvZiBjaGFyYWN0ZXIgZW50aXRpZXMgd2l0aCB0aGVpciBlcXVpdmFsZW50cyBpcworICogZG9uZSBhdCBhIGRpZmZlcmVudCBzdGFnZSBvZiBwcm9jZXNzaW5nLiAgVGhlIHNvbHV0aW9uIGlzIHRvIGNhbGwKKyAqIHhzbHRRdW90ZVVzZXJQYXJhbXMgb3IgeHNsdFF1b3RlT25lVXNlclBhcmFtLgorICoKKyAqIFRoaXMgbmVlZHMgdG8gYmUgZG9uZSBvbiBwYXJzZWQgc3R5bGVzaGVldHMgYmVmb3JlIHN0YXJ0aW5nIHRvIGFwcGx5CisgKiB0cmFuc2Zvcm1hdGlvbnMuICBOb3JtYWxseSB0aGlzIHdpbGwgYmUgY2FsbGVkIChkaXJlY3RseSBvciBpbmRpcmVjdGx5KQorICogb25seSBmcm9tIHhzbHRFdmFsVXNlclBhcmFtcywgeHNsdEV2YWxPbmVVc2VyUGFyYW0sIHhzbHRRdW90ZVVzZXJQYXJhbXMsCisgKiBvciB4c2x0UXVvdGVPbmVVc2VyUGFyYW0uCisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgLTEgaW4gY2FzZSBvZiBlcnJvcgorICovCisKK3N0YXRpYworaW50Cit4c2x0UHJvY2Vzc1VzZXJQYXJhbUludGVybmFsKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCSAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwKKwkJCSAgICAgY29uc3QgeG1sQ2hhciAqIHZhbHVlLAorCQkJICAgICBpbnQgZXZhbCkgeworCisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CisgICAgY29uc3QgeG1sQ2hhciAqcHJlZml4OworICAgIGNvbnN0IHhtbENoYXIgKmhyZWY7CisgICAgeG1sWFBhdGhDb21wRXhwclB0ciB4cEV4cHI7CisgICAgeG1sWFBhdGhPYmplY3RQdHIgcmVzdWx0OworICAgIAorICAgIHhzbHRTdGFja0VsZW1QdHIgZWxlbTsKKyAgICBpbnQgcmVzOworICAgIHZvaWQgKnJlc19wdHI7CisKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorCXJldHVybigtMSk7CisgICAgaWYgKG5hbWUgPT0gTlVMTCkKKwlyZXR1cm4oMCk7CisgICAgaWYgKHZhbHVlID09IE5VTEwpCisJcmV0dXJuKDApOworCisgICAgc3R5bGUgPSBjdHh0LT5zdHlsZTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAiRXZhbHVhdGluZyB1c2VyIHBhcmFtZXRlciAlcz0lc1xuIiwgbmFtZSwgdmFsdWUpKTsKKyNlbmRpZgorCisgICAgLyoKKyAgICAgKiBOYW1lIGxvb2t1cAorICAgICAqLworCisgICAgbmFtZSA9IHhzbHRTcGxpdFFOYW1lKGN0eHQtPmRpY3QsIG5hbWUsICZwcmVmaXgpOworICAgIGhyZWYgPSBOVUxMOworICAgIGlmIChwcmVmaXggIT0gTlVMTCkgeworCXhtbE5zUHRyIG5zOworCisJbnMgPSB4bWxTZWFyY2hOcyhzdHlsZS0+ZG9jLCB4bWxEb2NHZXRSb290RWxlbWVudChzdHlsZS0+ZG9jKSwKKwkJCSBwcmVmaXgpOworCWlmIChucyA9PSBOVUxMKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBzdHlsZSwgTlVMTCwKKwkgICAgInVzZXIgcGFyYW0gOiBubyBuYW1lc3BhY2UgYm91bmQgdG8gcHJlZml4ICVzXG4iLCBwcmVmaXgpOworCSAgICBocmVmID0gTlVMTDsKKwl9IGVsc2UgeworCSAgICBocmVmID0gbnMtPmhyZWY7CisJfQorICAgIH0KKworICAgIGlmIChuYW1lID09IE5VTEwpCisJcmV0dXJuICgtMSk7CisKKyAgICByZXNfcHRyID0geG1sSGFzaExvb2t1cDIoY3R4dC0+Z2xvYmFsVmFycywgbmFtZSwgaHJlZik7CisgICAgaWYgKHJlc19wdHIgIT0gMCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBzdHlsZSwgTlVMTCwKKwkgICAgIkdsb2JhbCBwYXJhbWV0ZXIgJXMgYWxyZWFkeSBkZWZpbmVkXG4iLCBuYW1lKTsKKyAgICB9CisgICAgaWYgKGN0eHQtPmdsb2JhbFZhcnMgPT0gTlVMTCkKKwljdHh0LT5nbG9iYWxWYXJzID0geG1sSGFzaENyZWF0ZSgyMCk7CisKKyAgICAvKgorICAgICAqIGRvIG5vdCBvdmVyd3JpdGUgdmFyaWFibGVzIHdpdGggcGFyYW1ldGVycyBmcm9tIHRoZSBjb21tYW5kIGxpbmUKKyAgICAgKi8KKyAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworICAgICAgICBlbGVtID0gY3R4dC0+c3R5bGUtPnZhcmlhYmxlczsKKwl3aGlsZSAoZWxlbSAhPSBOVUxMKSB7CisJICAgIGlmICgoZWxlbS0+Y29tcCAhPSBOVUxMKSAmJgorCSAgICAgICAgKGVsZW0tPmNvbXAtPnR5cGUgPT0gWFNMVF9GVU5DX1ZBUklBQkxFKSAmJgorCQkoeG1sU3RyRXF1YWwoZWxlbS0+bmFtZSwgbmFtZSkpICYmCisJCSh4bWxTdHJFcXVhbChlbGVtLT5uYW1lVVJJLCBocmVmKSkpIHsKKwkJcmV0dXJuKDApOworCSAgICB9CisgICAgICAgICAgICBlbGVtID0gZWxlbS0+bmV4dDsKKwl9CisgICAgICAgIHN0eWxlID0geHNsdE5leHRJbXBvcnQoc3R5bGUpOworICAgIH0KKyAgICBzdHlsZSA9IGN0eHQtPnN0eWxlOworICAgIGVsZW0gPSBOVUxMOworCisgICAgLyoKKyAgICAgKiBEbyB0aGUgZXZhbHVhdGlvbiBpZiBAZXZhbCBpcyBub24temVyby4KKyAgICAgKi8KKworICAgIHJlc3VsdCA9IE5VTEw7CisgICAgaWYgKGV2YWwgIT0gMCkgeworICAgICAgICB4cEV4cHIgPSB4bWxYUGF0aENvbXBpbGUodmFsdWUpOworCWlmICh4cEV4cHIgIT0gTlVMTCkgeworCSAgICB4bWxEb2NQdHIgb2xkWFBEb2M7CisJICAgIHhtbE5vZGVQdHIgb2xkWFBDb250ZXh0Tm9kZTsKKwkgICAgaW50IG9sZFhQUHJveGltaXR5UG9zaXRpb24sIG9sZFhQQ29udGV4dFNpemUsIG9sZFhQTnNOcjsKKwkgICAgeG1sTnNQdHIgKm9sZFhQTmFtZXNwYWNlczsKKwkgICAgeG1sWFBhdGhDb250ZXh0UHRyIHhwY3R4dCA9IGN0eHQtPnhwYXRoQ3R4dDsKKwkgICAKKwkgICAgLyoKKwkgICAgKiBTYXZlIGNvbnRleHQgc3RhdGVzLgorCSAgICAqLworCSAgICBvbGRYUERvYyA9IHhwY3R4dC0+ZG9jOworCSAgICBvbGRYUENvbnRleHROb2RlID0geHBjdHh0LT5ub2RlOworCSAgICBvbGRYUFByb3hpbWl0eVBvc2l0aW9uID0geHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbjsKKwkgICAgb2xkWFBDb250ZXh0U2l6ZSA9IHhwY3R4dC0+Y29udGV4dFNpemU7CisJICAgIG9sZFhQTmFtZXNwYWNlcyA9IHhwY3R4dC0+bmFtZXNwYWNlczsKKwkgICAgb2xkWFBOc05yID0geHBjdHh0LT5uc05yOworCisJICAgIC8qCisJICAgICogU1BFQyBYU0xUIDEuMDoKKwkgICAgKiAiQXQgdG9wLWxldmVsLCB0aGUgZXhwcmVzc2lvbiBvciB0ZW1wbGF0ZSBzcGVjaWZ5aW5nIHRoZQorCSAgICAqICB2YXJpYWJsZSB2YWx1ZSBpcyBldmFsdWF0ZWQgd2l0aCB0aGUgc2FtZSBjb250ZXh0IGFzIHRoYXQgdXNlZAorCSAgICAqICB0byBwcm9jZXNzIHRoZSByb290IG5vZGUgb2YgdGhlIHNvdXJjZSBkb2N1bWVudDogdGhlIGN1cnJlbnQKKwkgICAgKiAgbm9kZSBpcyB0aGUgcm9vdCBub2RlIG9mIHRoZSBzb3VyY2UgZG9jdW1lbnQgYW5kIHRoZSBjdXJyZW50CisJICAgICogIG5vZGUgbGlzdCBpcyBhIGxpc3QgY29udGFpbmluZyBqdXN0IHRoZSByb290IG5vZGUgb2YgdGhlIHNvdXJjZQorCSAgICAqICBkb2N1bWVudC4iCisJICAgICovCisJICAgIHhwY3R4dC0+ZG9jID0gY3R4dC0+aW5pdGlhbENvbnRleHREb2M7CSAgICAKKwkgICAgeHBjdHh0LT5ub2RlID0gY3R4dC0+aW5pdGlhbENvbnRleHROb2RlOwkgICAgCisJICAgIHhwY3R4dC0+Y29udGV4dFNpemUgPSAxOworCSAgICB4cGN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gMTsKKwkgICAgLyogCisJICAgICogVGhlcmUgaXMgcmVhbGx5IG5vIGluIHNjb3BlIG5hbWVzcGFjZSBmb3IgcGFyYW1ldGVycyBvbiB0aGUKKwkgICAgKiBjb21tYW5kIGxpbmUuCisJICAgICovCisJICAgIHhwY3R4dC0+bmFtZXNwYWNlcyA9IE5VTEw7CisJICAgIHhwY3R4dC0+bnNOciA9IDA7CSAgIAorCSAgICAKKwkgICAgcmVzdWx0ID0geG1sWFBhdGhDb21waWxlZEV2YWwoeHBFeHByLCB4cGN0eHQpOworCSAgICAKKwkgICAgLyoKKwkgICAgKiBSZXN0b3JlIENvbnRleHQgc3RhdGVzLgorCSAgICAqLworCSAgICB4cGN0eHQtPmRvYyA9IG9sZFhQRG9jOworCSAgICB4cGN0eHQtPm5vZGUgPSBvbGRYUENvbnRleHROb2RlOworCSAgICB4cGN0eHQtPmNvbnRleHRTaXplID0gb2xkWFBDb250ZXh0U2l6ZTsKKwkgICAgeHBjdHh0LT5wcm94aW1pdHlQb3NpdGlvbiA9IG9sZFhQUHJveGltaXR5UG9zaXRpb247CisJICAgIHhwY3R4dC0+bmFtZXNwYWNlcyA9IG9sZFhQTmFtZXNwYWNlczsKKwkgICAgeHBjdHh0LT5uc05yID0gb2xkWFBOc05yOworCSAgICAKKwkgICAgeG1sWFBhdGhGcmVlQ29tcEV4cHIoeHBFeHByKTsKKwl9CisJaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBzdHlsZSwgTlVMTCwKKwkJIkV2YWx1YXRpbmcgdXNlciBwYXJhbWV0ZXIgJXMgZmFpbGVkXG4iLCBuYW1lKTsKKwkgICAgY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX1NUT1BQRUQ7CisJICAgIHJldHVybigtMSk7CisJfQorICAgIH0KKworICAgIC8qIAorICAgICAqIElmIEBldmFsIGlzIDAgdGhlbiBAdmFsdWUgaXMgdG8gYmUgdGFrZW4gbGl0ZXJhbGx5IGFuZCByZXN1bHQgaXMgTlVMTAorICAgICAqIAorICAgICAqIElmIEBldmFsIGlzIG5vdCAwLCB0aGVuIEB2YWx1ZSBpcyBhbiBYUGF0aCBleHByZXNzaW9uIGFuZCBoYXMgYmVlbgorICAgICAqIHN1Y2Nlc3NmdWxseSBldmFsdWF0ZWQgYW5kIHJlc3VsdCBjb250YWlucyB0aGUgcmVzdWx0aW5nIHZhbHVlIGFuZAorICAgICAqIGlzIG5vdCBOVUxMLgorICAgICAqCisgICAgICogTm93IGNyZWF0ZSBhbiB4c2x0U3RhY2tFbGVtUHRyIGZvciBpbnNlcnRpb24gaW50byB0aGUgY29udGV4dCdzCisgICAgICogZ2xvYmFsIHZhcmlhYmxlL3BhcmFtZXRlciBoYXNoIHRhYmxlLgorICAgICAqLworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1ZBUklBQkxFCisjaWZkZWYgTElCWE1MX0RFQlVHX0VOQUJMRUQKKyAgICBpZiAoKHhzbHRHZW5lcmljRGVidWdDb250ZXh0ID09IHN0ZG91dCkgfHwKKyAgICAgICAgKHhzbHRHZW5lcmljRGVidWdDb250ZXh0ID09IHN0ZGVycikpCisJICAgIHhtbFhQYXRoRGVidWdEdW1wT2JqZWN0KChGSUxFICopeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkJICAgIHJlc3VsdCwgMCk7CisjZW5kaWYKKyNlbmRpZgorCisgICAgZWxlbSA9IHhzbHROZXdTdGFja0VsZW0oTlVMTCk7CisgICAgaWYgKGVsZW0gIT0gTlVMTCkgeworCWVsZW0tPm5hbWUgPSBuYW1lOworCWVsZW0tPnNlbGVjdCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsdWUsIC0xKTsKKwlpZiAoaHJlZiAhPSBOVUxMKQorCSAgICBlbGVtLT5uYW1lVVJJID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBocmVmLCAtMSk7CisJZWxlbS0+dHJlZSA9IE5VTEw7CisJZWxlbS0+Y29tcHV0ZWQgPSAxOworCWlmIChldmFsID09IDApIHsKKwkgICAgZWxlbS0+dmFsdWUgPSB4bWxYUGF0aE5ld1N0cmluZyh2YWx1ZSk7CisJfSAKKwllbHNlIHsKKwkgICAgZWxlbS0+dmFsdWUgPSByZXN1bHQ7CisJfQorICAgIH0KKworICAgIC8qCisgICAgICogR2xvYmFsIHBhcmFtZXRlcnMgYXJlIHN0b3JlZCBpbiB0aGUgWFBhdGggY29udGV4dCB2YXJpYWJsZXMgcG9vbC4KKyAgICAgKi8KKworICAgIHJlcyA9IHhtbEhhc2hBZGRFbnRyeTIoY3R4dC0+Z2xvYmFsVmFycywgbmFtZSwgaHJlZiwgZWxlbSk7CisgICAgaWYgKHJlcyAhPSAwKSB7CisJeHNsdEZyZWVTdGFja0VsZW0oZWxlbSk7CisJeHNsdFRyYW5zZm9ybUVycm9yKGN0eHQsIHN0eWxlLCBOVUxMLAorCSAgICAiR2xvYmFsIHBhcmFtZXRlciAlcyBhbHJlYWR5IGRlZmluZWRcbiIsIG5hbWUpOworICAgIH0KKyAgICByZXR1cm4oMCk7Cit9CisKKy8qKgorICogeHNsdEV2YWxVc2VyUGFyYW1zOgorICoKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQHBhcmFtczogIGEgTlVMTCB0ZXJtaW5hdGVkIGFycmF5IG9mIHBhcmFtZXRlcnMgbmFtZS92YWx1ZSB0dXBsZXMKKyAqCisgKiBFdmFsdWF0ZSB0aGUgZ2xvYmFsIHZhcmlhYmxlcyBvZiBhIHN0eWxlc2hlZXQuIFRoaXMgbmVlZHMgdG8gYmUKKyAqIGRvbmUgb24gcGFyc2VkIHN0eWxlc2hlZXRzIGJlZm9yZSBzdGFydGluZyB0byBhcHBseSB0cmFuc2Zvcm1hdGlvbnMuCisgKiBFYWNoIG9mIHRoZSBwYXJhbWV0ZXJzIGlzIGV2YWx1YXRlZCBhcyBhbiBYUGF0aCBleHByZXNzaW9uIGFuZCBzdG9yZWQKKyAqIGluIHRoZSBnbG9iYWwgdmFyaWFibGVzL3BhcmFtZXRlciBoYXNoIHRhYmxlLiAgSWYgeW91IHdhbnQgeW91cgorICogcGFyYW1ldGVyIHVzZWQgbGl0ZXJhbGx5LCB1c2UgeHNsdFF1b3RlVXNlclBhcmFtcy4KKyAqCisgKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGVycm9yCisgKi8KKyAKK2ludAoreHNsdEV2YWxVc2VyUGFyYW1zKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIGNvbnN0IGNoYXIgKipwYXJhbXMpIHsKKyAgICBpbnQgaW5keCA9IDA7CisgICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKKyAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKKworICAgIGlmIChwYXJhbXMgPT0gTlVMTCkKKwlyZXR1cm4oMCk7CisgICAgd2hpbGUgKHBhcmFtc1tpbmR4XSAhPSBOVUxMKSB7CisJbmFtZSA9IChjb25zdCB4bWxDaGFyICopIHBhcmFtc1tpbmR4KytdOworCXZhbHVlID0gKGNvbnN0IHhtbENoYXIgKikgcGFyYW1zW2luZHgrK107CisgICAgCWlmICh4c2x0RXZhbE9uZVVzZXJQYXJhbShjdHh0LCBuYW1lLCB2YWx1ZSkgIT0gMCkgCisJICAgIHJldHVybigtMSk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisvKioKKyAqIHhzbHRRdW90ZVVzZXJQYXJhbXM6CisgKgorICogQGN0eHQ6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAcGFyYW1zOiAgYSBOVUxMIHRlcm1pbmF0ZWQgYXJyeSBvZiBwYXJhbWV0ZXJzIG5hbWVzL3ZhbHVlcyB0dXBsZXMKKyAqCisgKiBTaW1pbGFyIHRvIHhzbHRFdmFsVXNlclBhcmFtcywgYnV0IHRoZSB2YWx1ZXMgYXJlIHRyZWF0ZWQgbGl0ZXJhbGx5IGFuZAorICogYXJlICogKm5vdCogZXZhbHVhdGVkIGFzIFhQYXRoIGV4cHJlc3Npb25zLiBUaGlzIHNob3VsZCBiZSBkb25lIG9uIHBhcnNlZAorICogc3R5bGVzaGVldHMgYmVmb3JlIHN0YXJ0aW5nIHRvIGFwcGx5IHRyYW5zZm9ybWF0aW9ucy4KKyAqCisgKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGVycm9yLgorICovCisgCitpbnQKK3hzbHRRdW90ZVVzZXJQYXJhbXMoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgY29uc3QgY2hhciAqKnBhcmFtcykgeworICAgIGludCBpbmR4ID0gMDsKKyAgICBjb25zdCB4bWxDaGFyICpuYW1lOworICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOworCisgICAgaWYgKHBhcmFtcyA9PSBOVUxMKQorCXJldHVybigwKTsKKyAgICB3aGlsZSAocGFyYW1zW2luZHhdICE9IE5VTEwpIHsKKwluYW1lID0gKGNvbnN0IHhtbENoYXIgKikgcGFyYW1zW2luZHgrK107CisJdmFsdWUgPSAoY29uc3QgeG1sQ2hhciAqKSBwYXJhbXNbaW5keCsrXTsKKyAgICAJaWYgKHhzbHRRdW90ZU9uZVVzZXJQYXJhbShjdHh0LCBuYW1lLCB2YWx1ZSkgIT0gMCkgCisJICAgIHJldHVybigtMSk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisvKioKKyAqIHhzbHRFdmFsT25lVXNlclBhcmFtOgorICogQGN0eHQ6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAbmFtZTogIGEgbnVsbCB0ZXJtaW5hdGVkIHN0cmluZyBnaXZpbmcgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlcgorICogQHZhbHVlOiAgYSBudWxsIHRlcm1pbmF0ZWQgc3RyaW5nIGdpdmluZyB0aGUgWFBhdGggZXhwcmVzc2lvbiB0byBiZSBldmFsdWF0ZWQKKyAqCisgKiBUaGlzIGlzIG5vcm1hbGx5IGNhbGxlZCBmcm9tIHhzbHRFdmFsVXNlclBhcmFtcyB0byBwcm9jZXNzIGEgc2luZ2xlCisgKiBwYXJhbWV0ZXIgZnJvbSBhIGxpc3Qgb2YgcGFyYW1ldGVycy4gIFRoZSBAdmFsdWUgaXMgZXZhbHVhdGVkIGFzIGFuCisgKiBYUGF0aCBleHByZXNzaW9uIGFuZCB0aGUgcmVzdWx0IGlzIHN0b3JlZCBpbiB0aGUgY29udGV4dCdzIGdsb2JhbAorICogdmFyaWFibGUvcGFyYW1ldGVyIGhhc2ggdGFibGUuCisgKgorICogVG8gaGF2ZSBhIHBhcmFtZXRlciB0cmVhdGVkIGxpdGVyYWxseSAobm90IGFzIGFuIFhQYXRoIGV4cHJlc3Npb24pCisgKiB1c2UgeHNsdFF1b3RlVXNlclBhcmFtcyAob3IgeHNsdFF1b3RlT25lVXNlclBhcmFtKS4gIEZvciBtb3JlCisgKiBkZXRhaWxzIHNlZSBkZXNjcmlwdGlvbiBvZiB4c2x0UHJvY2Vzc09uZVVzZXJQYXJhbUludGVybmFsLgorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgZXJyb3IuCisgKi8KKworaW50Cit4c2x0RXZhbE9uZVVzZXJQYXJhbSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorICAgIAkJICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwKKwkJICAgICBjb25zdCB4bWxDaGFyICogdmFsdWUpIHsKKyAgICByZXR1cm4geHNsdFByb2Nlc3NVc2VyUGFyYW1JbnRlcm5hbChjdHh0LCBuYW1lLCB2YWx1ZSwKKwkJICAgICAgICAgICAgICAgICAgICAgICAgMSAvKiB4cGF0aCBldmFsID8gKi8pOworfQorCisvKioKKyAqIHhzbHRRdW90ZU9uZVVzZXJQYXJhbToKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQG5hbWU6ICBhIG51bGwgdGVybWluYXRlZCBzdHJpbmcgZ2l2aW5nIHRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIKKyAqIEB2YWx1ZTogIGEgbnVsbCB0ZXJtaW5hdGVkIHN0cmluZyBnaXZpbmcgdGhlIHBhcmFtZXRlciB2YWx1ZQorICoKKyAqIFRoaXMgaXMgbm9ybWFsbHkgY2FsbGVkIGZyb20geHNsdFF1b3RlVXNlclBhcmFtcyB0byBwcm9jZXNzIGEgc2luZ2xlCisgKiBwYXJhbWV0ZXIgZnJvbSBhIGxpc3Qgb2YgcGFyYW1ldGVycy4gIFRoZSBAdmFsdWUgaXMgc3RvcmVkIGluIHRoZQorICogY29udGV4dCdzIGdsb2JhbCB2YXJpYWJsZS9wYXJhbWV0ZXIgaGFzaCB0YWJsZS4KKyAqCisgKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGVycm9yLgorICovCisKK2ludAoreHNsdFF1b3RlT25lVXNlclBhcmFtKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkgY29uc3QgeG1sQ2hhciAqIG5hbWUsCisJCQkgY29uc3QgeG1sQ2hhciAqIHZhbHVlKSB7CisgICAgcmV0dXJuIHhzbHRQcm9jZXNzVXNlclBhcmFtSW50ZXJuYWwoY3R4dCwgbmFtZSwgdmFsdWUsCisJCQkJCTAgLyogeHBhdGggZXZhbCA/ICovKTsKK30KKworLyoqCisgKiB4c2x0QnVpbGRWYXJpYWJsZToKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQGNvbXA6ICB0aGUgcHJlY29tcGlsZWQgZm9ybQorICogQHRyZWU6ICB0aGUgdHJlZSBpZiBzZWxlY3QgaXMgTlVMTAorICoKKyAqIENvbXB1dGVzIGEgbmV3IHZhcmlhYmxlIHZhbHVlLgorICoKKyAqIFJldHVybnMgdGhlIHhzbHRTdGFja0VsZW1QdHIgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3N0YXRpYyB4c2x0U3RhY2tFbGVtUHRyCit4c2x0QnVpbGRWYXJpYWJsZSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkgIHhzbHRTdHlsZVByZUNvbXBQdHIgY2FzdGVkQ29tcCwKKwkJICB4bWxOb2RlUHRyIHRyZWUpCit7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlQmFzaWNJdGVtVmFyaWFibGVQdHIgY29tcCA9CisJKHhzbHRTdHlsZUJhc2ljSXRlbVZhcmlhYmxlUHRyKSBjYXN0ZWRDb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXAgPSBjYXN0ZWRDb21wOworI2VuZGlmIAorICAgIHhzbHRTdGFja0VsZW1QdHIgZWxlbTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgICJCdWlsZGluZyB2YXJpYWJsZSAlcyIsIGNvbXAtPm5hbWUpKTsKKyAgICBpZiAoY29tcC0+c2VsZWN0ICE9IE5VTEwpCisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfVkFSSUFCTEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkgIiBzZWxlY3QgJXMiLCBjb21wLT5zZWxlY3QpKTsKKyAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9WQVJJQUJMRVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwgIlxuIikpOworI2VuZGlmCisKKyAgICBlbGVtID0geHNsdE5ld1N0YWNrRWxlbShjdHh0KTsKKyAgICBpZiAoZWxlbSA9PSBOVUxMKQorCXJldHVybihOVUxMKTsKKyAgICBlbGVtLT5jb21wID0gKHhzbHRTdHlsZVByZUNvbXBQdHIpIGNvbXA7CisgICAgZWxlbS0+bmFtZSA9IGNvbXAtPm5hbWU7CisgICAgZWxlbS0+c2VsZWN0ID0gY29tcC0+c2VsZWN0OworICAgIGVsZW0tPm5hbWVVUkkgPSBjb21wLT5uczsKKyAgICBlbGVtLT50cmVlID0gdHJlZTsKKyAgICBlbGVtLT52YWx1ZSA9IHhzbHRFdmFsVmFyaWFibGUoY3R4dCwgZWxlbSwKKwkoeHNsdFN0eWxlUHJlQ29tcFB0cikgY29tcCk7CisgICAgaWYgKGVsZW0tPnZhbHVlICE9IE5VTEwpCisJZWxlbS0+Y29tcHV0ZWQgPSAxOworICAgIHJldHVybihlbGVtKTsKK30KKworLyoqCisgKiB4c2x0UmVnaXN0ZXJWYXJpYWJsZToKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQGNvbXA6IHRoZSBjb21waWxlZCBYU0xULXZhcmlhYmxlIChvciBwYXJhbSkgaW5zdHJ1Y3Rpb24KKyAqIEB0cmVlOiAgdGhlIHRyZWUgaWYgc2VsZWN0IGlzIE5VTEwKKyAqIEBpc1BhcmFtOiAgaW5kaWNhdGVzIGlmIHRoaXMgaXMgYSBwYXJhbWV0ZXIKKyAqCisgKiBDb21wdXRlcyBhbmQgcmVnaXN0ZXJzIGEgbmV3IHZhcmlhYmxlLgorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworc3RhdGljIGludAoreHNsdFJlZ2lzdGVyVmFyaWFibGUoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJICAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNhc3RlZENvbXAsCisJCSAgICAgeG1sTm9kZVB0ciB0cmVlLCBpbnQgaXNQYXJhbSkKK3sKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVCYXNpY0l0ZW1WYXJpYWJsZVB0ciBjb21wID0KKwkoeHNsdFN0eWxlQmFzaWNJdGVtVmFyaWFibGVQdHIpIGNhc3RlZENvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcCA9IGNhc3RlZENvbXA7CisgICAgaW50IHByZXNlbnQ7CisjZW5kaWYKKyAgICB4c2x0U3RhY2tFbGVtUHRyIHZhcmlhYmxlOyAgICAKKyAgICAKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICAvKgorICAgICogUkVGQUNUT1JFRCBOT1RFOiBSZWRlZmluaXRpb25zIG9mIHZhcnMvcGFyYW1zIGFyZSBjaGVja2VkCisgICAgKiAgYXQgY29tcGlsYXRpb24gdGltZSBpbiB0aGUgcmVmYWN0b3JlZCBjb2RlLgorICAgICogeHNsOndpdGgtcGFyYW0gcGFyYW1ldGVycyBhcmUgY2hlY2tlZCBpbiB4c2x0QXBwbHlYU0xUVGVtcGxhdGUoKS4KKyAgICAqLworI2Vsc2UKKyAgICBwcmVzZW50ID0geHNsdENoZWNrU3RhY2tFbGVtKGN0eHQsIGNvbXAtPm5hbWUsIGNvbXAtPm5zKTsKKyAgICBpZiAoaXNQYXJhbSA9PSAwKSB7CQorCWlmICgocHJlc2VudCAhPSAwKSAmJiAocHJlc2VudCAhPSAzKSkgeworCSAgICAvKiBUT0RPOiByZXBvcnQgUU5hbWUuICovCisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjb21wLT5pbnN0LAorCQkiWFNMVC12YXJpYWJsZTogUmVkZWZpbml0aW9uIG9mIHZhcmlhYmxlICclcycuXG4iLCBjb21wLT5uYW1lKTsKKwkgICAgcmV0dXJuKDApOworCX0KKyAgICB9IGVsc2UgaWYgKHByZXNlbnQgIT0gMCkgeworCWlmICgocHJlc2VudCA9PSAxKSB8fCAocHJlc2VudCA9PSAyKSkgeworCSAgICAvKiBUT0RPOiByZXBvcnQgUU5hbWUuICovCisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBjb21wLT5pbnN0LAorCQkiWFNMVC1wYXJhbTogUmVkZWZpbml0aW9uIG9mIHBhcmFtZXRlciAnJXMnLlxuIiwgY29tcC0+bmFtZSk7CisJICAgIHJldHVybigwKTsKKwl9CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1ZBUklBQkxFCisJWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfVkFSSUFCTEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAicGFyYW0gJXMgZGVmaW5lZCBieSBjYWxsZXJcbiIsIGNvbXAtPm5hbWUpKTsKKyNlbmRpZgorCXJldHVybigwKTsKKyAgICB9CisjZW5kaWYgLyogZWxzZSBvZiBYU0xUX1JFRkFDVE9SRUQgKi8KKworICAgIHZhcmlhYmxlID0geHNsdEJ1aWxkVmFyaWFibGUoY3R4dCwgKHhzbHRTdHlsZVByZUNvbXBQdHIpIGNvbXAsIHRyZWUpOworICAgIHhzbHRBZGRTdGFja0VsZW0oY3R4dCwgdmFyaWFibGUpOworICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0R2xvYmFsVmFyaWFibGVMb29rdXA6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBuYW1lOiAgdGhlIHZhcmlhYmxlIG5hbWUKKyAqIEBuc191cmk6ICB0aGUgdmFyaWFibGUgbmFtZXNwYWNlIFVSSQorICoKKyAqIFNlYXJjaCBpbiB0aGUgVmFyaWFibGUgYXJyYXkgb2YgdGhlIGNvbnRleHQgZm9yIHRoZSBnaXZlbgorICogdmFyaWFibGUgdmFsdWUuCisgKgorICogUmV0dXJucyB0aGUgdmFsdWUgb3IgTlVMTCBpZiBub3QgZm91bmQKKyAqLworc3RhdGljIHhtbFhQYXRoT2JqZWN0UHRyCit4c2x0R2xvYmFsVmFyaWFibGVMb29rdXAoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkJICAgICAgICAgY29uc3QgeG1sQ2hhciAqbnNfdXJpKSB7CisgICAgeHNsdFN0YWNrRWxlbVB0ciBlbGVtOworICAgIHhtbFhQYXRoT2JqZWN0UHRyIHJldCA9IE5VTEw7CisKKyAgICAvKgorICAgICAqIExvb2t1cCB0aGUgZ2xvYmFsIHZhcmlhYmxlcyBpbiBYUGF0aCBnbG9iYWwgdmFyaWFibGUgaGFzaCB0YWJsZQorICAgICAqLworICAgIGlmICgoY3R4dC0+eHBhdGhDdHh0ID09IE5VTEwpIHx8IChjdHh0LT5nbG9iYWxWYXJzID09IE5VTEwpKQorCXJldHVybihOVUxMKTsKKyAgICBlbGVtID0gKHhzbHRTdGFja0VsZW1QdHIpCisJICAgIHhtbEhhc2hMb29rdXAyKGN0eHQtPmdsb2JhbFZhcnMsIG5hbWUsIG5zX3VyaSk7CisgICAgaWYgKGVsZW0gPT0gTlVMTCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJICJnbG9iYWwgdmFyaWFibGUgbm90IGZvdW5kICVzXG4iLCBuYW1lKSk7CisjZW5kaWYKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIC8qCisgICAgKiBVUkdFTlQgVE9ETzogTW92ZSB0aGUgZGV0ZWN0aW9uIG9mIHJlY3Vyc2l2ZSBkZWZpbml0aW9ucworICAgICogdG8gY29tcGlsZS10aW1lLgorICAgICovCisgICAgaWYgKGVsZW0tPmNvbXB1dGVkID09IDApIHsKKwlpZiAoZWxlbS0+bmFtZSA9PSB4c2x0Q29tcHV0aW5nR2xvYmFsVmFyTWFya2VyKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBlbGVtLT5jb21wLT5pbnN0LAorCQkiUmVjdXJzaXZlIGRlZmluaXRpb24gb2YgJXNcbiIsIG5hbWUpOworCSAgICByZXR1cm4oTlVMTCk7CisJfQorCXJldCA9IHhzbHRFdmFsR2xvYmFsVmFyaWFibGUoZWxlbSwgY3R4dCk7CisgICAgfSBlbHNlCisJcmV0ID0gZWxlbS0+dmFsdWU7CisgICAgcmV0dXJuKHhtbFhQYXRoT2JqZWN0Q29weShyZXQpKTsKK30KKworLyoqCisgKiB4c2x0VmFyaWFibGVMb29rdXA6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBuYW1lOiAgdGhlIHZhcmlhYmxlIG5hbWUKKyAqIEBuc191cmk6ICB0aGUgdmFyaWFibGUgbmFtZXNwYWNlIFVSSQorICoKKyAqIFNlYXJjaCBpbiB0aGUgVmFyaWFibGUgYXJyYXkgb2YgdGhlIGNvbnRleHQgZm9yIHRoZSBnaXZlbgorICogdmFyaWFibGUgdmFsdWUuCisgKgorICogUmV0dXJucyB0aGUgdmFsdWUgb3IgTlVMTCBpZiBub3QgZm91bmQKKyAqLworeG1sWFBhdGhPYmplY3RQdHIKK3hzbHRWYXJpYWJsZUxvb2t1cCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICpuYW1lLAorCQkgICBjb25zdCB4bWxDaGFyICpuc191cmkpIHsKKyAgICB4c2x0U3RhY2tFbGVtUHRyIGVsZW07CisKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorCXJldHVybihOVUxMKTsKKworICAgIGVsZW0gPSB4c2x0U3RhY2tMb29rdXAoY3R4dCwgbmFtZSwgbnNfdXJpKTsKKyAgICBpZiAoZWxlbSA9PSBOVUxMKSB7CisJcmV0dXJuKHhzbHRHbG9iYWxWYXJpYWJsZUxvb2t1cChjdHh0LCBuYW1lLCBuc191cmkpKTsKKyAgICB9CisgICAgaWYgKGVsZW0tPmNvbXB1dGVkID09IDApIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfVkFSSUFCTEUKKwlYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9WQVJJQUJMRVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICAgICAgICAgInVuY29tcHV0ZWQgdmFyaWFibGUgJXNcbiIsIG5hbWUpKTsKKyNlbmRpZgorICAgICAgICBlbGVtLT52YWx1ZSA9IHhzbHRFdmFsVmFyaWFibGUoY3R4dCwgZWxlbSwgTlVMTCk7CisJZWxlbS0+Y29tcHV0ZWQgPSAxOworICAgIH0KKyAgICBpZiAoZWxlbS0+dmFsdWUgIT0gTlVMTCkKKwlyZXR1cm4oeG1sWFBhdGhPYmplY3RDb3B5KGVsZW0tPnZhbHVlKSk7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1ZBUklBQkxFCisgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfVkFSSUFCTEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAgInZhcmlhYmxlIG5vdCBmb3VuZCAlc1xuIiwgbmFtZSkpOworI2VuZGlmCisgICAgcmV0dXJuKE5VTEwpOworfQorCisvKioKKyAqIHhzbHRQYXJzZVN0eWxlc2hlZXRDYWxsZXJQYXJhbToKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dCAKKyAqIEBpbnN0OiAgdGhlIHhzbDp3aXRoLXBhcmFtIGluc3RydWN0aW9uIGVsZW1lbnQKKyAqCisgKiBQcm9jZXNzZXMgYW4geHNsOndpdGgtcGFyYW0gaW5zdHJ1Y3Rpb24gYXQgdHJhbnNmb3JtYXRpb24gdGltZS4KKyAqIFRoZSB2YWx1ZSBpcyBjb21wdXRlLCBidXQgbm90IHJlY29yZGVkLgorICogTk9URSB0aGF0IHRoaXMgaXMgYWxzbyBjYWxsZWQgd2l0aCBhbiAqeHNsOnBhcmFtKiBlbGVtZW50CisgKiBmcm9tIGV4c2x0RnVuY0Z1bmN0aW9uRnVuY3Rpb24oKS4gCisgKgorICogUmV0dXJucyB0aGUgbmV3IHhzbHRTdGFja0VsZW1QdHIgb3IgTlVMTAorICovCisKK3hzbHRTdGFja0VsZW1QdHIKK3hzbHRQYXJzZVN0eWxlc2hlZXRDYWxsZXJQYXJhbSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGluc3QpCit7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlQmFzaWNJdGVtVmFyaWFibGVQdHIgY29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wOworI2VuZGlmCisgICAgeG1sTm9kZVB0ciB0cmVlID0gTlVMTDsgLyogVGhlIGZpcnN0IGNoaWxkIG5vZGUgb2YgdGhlIGluc3RydWN0aW9uIG9yCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGluc3RydWN0aW9uIGl0c2VsZi4gKi8KKyAgICB4c2x0U3RhY2tFbGVtUHRyIHBhcmFtID0gTlVMTDsKKyAgICAKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkpCisJcmV0dXJuKE5VTEwpOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgY29tcCA9ICh4c2x0U3R5bGVCYXNpY0l0ZW1WYXJpYWJsZVB0cikgaW5zdC0+cHN2aTsKKyNlbHNlCisgICAgY29tcCA9ICh4c2x0U3R5bGVQcmVDb21wUHRyKSBpbnN0LT5wc3ZpOworI2VuZGlmCisgICAgCisgICAgaWYgKGNvbXAgPT0gTlVMTCkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkgICAgIkludGVybmFsIGVycm9yIGluIHhzbHRQYXJzZVN0eWxlc2hlZXRDYWxsZXJQYXJhbSgpOiAiCisJICAgICJUaGUgWFNMVCAnd2l0aC1wYXJhbScgaW5zdHJ1Y3Rpb24gd2FzIG5vdCBjb21waWxlZC5cbiIpOworICAgICAgICByZXR1cm4oTlVMTCk7CisgICAgfQorICAgIGlmIChjb21wLT5uYW1lID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkgICAgIkludGVybmFsIGVycm9yIGluIHhzbHRQYXJzZVN0eWxlc2hlZXRDYWxsZXJQYXJhbSgpOiAiCisJICAgICJYU0xUICd3aXRoLXBhcmFtJzogVGhlIGF0dHJpYnV0ZSAnbmFtZScgd2FzIG5vdCBjb21waWxlZC5cbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfVkFSSUFCTEUKKyAgICBYU0xUX1RSQUNFKGN0eHQsWFNMVF9UUkFDRV9WQVJJQUJMRVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgIkhhbmRsaW5nIHhzbDp3aXRoLXBhcmFtICVzXG4iLCBjb21wLT5uYW1lKSk7CisjZW5kaWYKKworICAgIGlmIChjb21wLT5zZWxlY3QgPT0gTlVMTCkgeworCXRyZWUgPSBpbnN0LT5jaGlsZHJlbjsKKyAgICB9IGVsc2UgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorCVhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAiICAgICAgICBzZWxlY3QgJXNcbiIsIGNvbXAtPnNlbGVjdCkpOworI2VuZGlmCisJdHJlZSA9IGluc3Q7CisgICAgfQorCisgICAgcGFyYW0gPSB4c2x0QnVpbGRWYXJpYWJsZShjdHh0LCAoeHNsdFN0eWxlUHJlQ29tcFB0cikgY29tcCwgdHJlZSk7CisKKyAgICByZXR1cm4ocGFyYW0pOworfQorCisvKioKKyAqIHhzbHRQYXJzZUdsb2JhbFZhcmlhYmxlOgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICogQGN1cjogIHRoZSAidmFyaWFibGUiIGVsZW1lbnQKKyAqCisgKiBQYXJzZXMgYSBnbG9iYWwgWFNMVCAndmFyaWFibGUnIGRlY2xhcmF0aW9uIGF0IGNvbXBpbGF0aW9uIHRpbWUKKyAqIGFuZCByZWdpc3RlcnMgaXQKKyAqLwordm9pZAoreHNsdFBhcnNlR2xvYmFsVmFyaWFibGUoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgY3VyKQoreworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1WYXJpYWJsZVB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIGlmICgoY3VyID09IE5VTEwpIHx8IChzdHlsZSA9PSBOVUxMKSkKKwlyZXR1cm47CisgICAgCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgLyoKKyAgICAqIE5vdGUgdGhhdCB4c2x0U3R5bGVQcmVDb21wdXRlKCkgd2lsbCBiZSBjYWxsZWQgZnJvbQorICAgICogeHNsdC5jIG9ubHkuCisgICAgKi8KKyAgICBjb21wID0gKHhzbHRTdHlsZUl0ZW1WYXJpYWJsZVB0cikgY3VyLT5wc3ZpOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wdXRlKHN0eWxlLCBjdXIpOworICAgIGNvbXAgPSAoeHNsdFN0eWxlUHJlQ29tcFB0cikgY3VyLT5wc3ZpOworI2VuZGlmCisgICAgaWYgKGNvbXAgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCSAgICAgInhzbDp2YXJpYWJsZSA6IGNvbXBpbGF0aW9uIGZhaWxlZFxuIik7CisJcmV0dXJuOworICAgIH0KKworICAgIGlmIChjb21wLT5uYW1lID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkgICAgInhzbDp2YXJpYWJsZSA6IG1pc3NpbmcgbmFtZSBhdHRyaWJ1dGVcbiIpOworCXJldHVybjsKKyAgICB9CisKKyAgICAvKgorICAgICogUGFyc2UgdGhlIGNvbnRlbnQgKGEgc2VxdWVuY2UgY29uc3RydWN0b3IpIG9mIHhzbDp2YXJpYWJsZS4KKyAgICAqLworICAgIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQJCisgICAgICAgIHhzbHRQYXJzZVNlcXVlbmNlQ29uc3RydWN0b3IoWFNMVF9DQ1RYVChzdHlsZSksIGN1ci0+Y2hpbGRyZW4pOworI2Vsc2UKKyAgICAgICAgeHNsdFBhcnNlVGVtcGxhdGVDb250ZW50KHN0eWxlLCBjdXIpOworI2VuZGlmCisgICAgfQorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJIlJlZ2lzdGVyaW5nIGdsb2JhbCB2YXJpYWJsZSAlc1xuIiwgY29tcC0+bmFtZSk7CisjZW5kaWYKKworICAgIHhzbHRSZWdpc3Rlckdsb2JhbFZhcmlhYmxlKHN0eWxlLCBjb21wLT5uYW1lLCBjb21wLT5ucywKKwljb21wLT5zZWxlY3QsIGN1ci0+Y2hpbGRyZW4sICh4c2x0U3R5bGVQcmVDb21wUHRyKSBjb21wLAorCU5VTEwpOworfQorCisvKioKKyAqIHhzbHRQYXJzZUdsb2JhbFBhcmFtOgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICogQGN1cjogIHRoZSAicGFyYW0iIGVsZW1lbnQKKyAqCisgKiBwYXJzZSBhbiBYU0xUIHRyYW5zZm9ybWF0aW9uIHBhcmFtIGRlY2xhcmF0aW9uIGFuZCByZWNvcmQKKyAqIGl0cyB2YWx1ZS4KKyAqLworCit2b2lkCit4c2x0UGFyc2VHbG9iYWxQYXJhbSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBjdXIpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyAgICB4c2x0U3R5bGVJdGVtUGFyYW1QdHIgY29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wOworI2VuZGlmCisKKyAgICBpZiAoKGN1ciA9PSBOVUxMKSB8fCAoc3R5bGUgPT0gTlVMTCkpCisJcmV0dXJuOworICAgIAorI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIC8qCisgICAgKiBOb3RlIHRoYXQgeHNsdFN0eWxlUHJlQ29tcHV0ZSgpIHdpbGwgYmUgY2FsbGVkIGZyb20KKyAgICAqIHhzbHQuYyBvbmx5LgorICAgICovCisgICAgY29tcCA9ICh4c2x0U3R5bGVJdGVtUGFyYW1QdHIpIGN1ci0+cHN2aTsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcHV0ZShzdHlsZSwgY3VyKTsKKyAgICBjb21wID0gKHhzbHRTdHlsZVByZUNvbXBQdHIpIGN1ci0+cHN2aTsKKyNlbmRpZiAgICAKKyAgICBpZiAoY29tcCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICAieHNsOnBhcmFtIDogY29tcGlsYXRpb24gZmFpbGVkXG4iKTsKKwlyZXR1cm47CisgICAgfQorCisgICAgaWYgKGNvbXAtPm5hbWUgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCSAgICAieHNsOnBhcmFtIDogbWlzc2luZyBuYW1lIGF0dHJpYnV0ZVxuIik7CisJcmV0dXJuOworICAgIH0KKworICAgIC8qCisgICAgKiBQYXJzZSB0aGUgY29udGVudCAoYSBzZXF1ZW5jZSBjb25zdHJ1Y3Rvcikgb2YgeHNsOnBhcmFtLgorICAgICovCisgICAgaWYgKGN1ci0+Y2hpbGRyZW4gIT0gTlVMTCkgeworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAkKKyAgICAgICAgeHNsdFBhcnNlU2VxdWVuY2VDb25zdHJ1Y3RvcihYU0xUX0NDVFhUKHN0eWxlKSwgY3VyLT5jaGlsZHJlbik7CisjZWxzZQorICAgICAgICB4c2x0UGFyc2VUZW1wbGF0ZUNvbnRlbnQoc3R5bGUsIGN1cik7CisjZW5kaWYKKyAgICB9CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfVkFSSUFCTEUKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJSZWdpc3RlcmluZyBnbG9iYWwgcGFyYW0gJXNcbiIsIGNvbXAtPm5hbWUpOworI2VuZGlmCisKKyAgICB4c2x0UmVnaXN0ZXJHbG9iYWxWYXJpYWJsZShzdHlsZSwgY29tcC0+bmFtZSwgY29tcC0+bnMsCisJY29tcC0+c2VsZWN0LCBjdXItPmNoaWxkcmVuLCAoeHNsdFN0eWxlUHJlQ29tcFB0cikgY29tcCwKKwlOVUxMKTsKK30KKworLyoqCisgKiB4c2x0UGFyc2VTdHlsZXNoZWV0VmFyaWFibGU6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBpbnN0OiAgdGhlIHhzbDp2YXJpYWJsZSBpbnN0cnVjdGlvbiBlbGVtZW50CisgKgorICogUmVnaXN0ZXJzIGEgbG9jYWwgWFNMVCAndmFyaWFibGUnIGluc3RydWN0aW9uIGF0IHRyYW5zZm9ybWF0aW9uIHRpbWUKKyAqIGFuZCBldmFsdWF0ZXMgaXRzIHZhbHVlLgorICovCit2b2lkCit4c2x0UGFyc2VTdHlsZXNoZWV0VmFyaWFibGUoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBpbnN0KQoreworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1WYXJpYWJsZVB0ciBjb21wOworI2Vsc2UKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNvbXA7CisjZW5kaWYKKworICAgIGlmICgoaW5zdCA9PSBOVUxMKSB8fCAoY3R4dCA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICBjb21wID0gaW5zdC0+cHN2aTsKKyAgICBpZiAoY29tcCA9PSBOVUxMKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBpbnN0LAorCSAgICAiSW50ZXJuYWwgZXJyb3IgaW4geHNsdFBhcnNlU3R5bGVzaGVldFZhcmlhYmxlKCk6ICIKKwkgICAgIlRoZSBYU0xUICd2YXJpYWJsZScgaW5zdHJ1Y3Rpb24gd2FzIG5vdCBjb21waWxlZC5cbiIpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGlmIChjb21wLT5uYW1lID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgaW5zdCwKKwkgICAgIkludGVybmFsIGVycm9yIGluIHhzbHRQYXJzZVN0eWxlc2hlZXRWYXJpYWJsZSgpOiAiCisJICAgICJUaGUgYXR0cmlidXRlICduYW1lJyB3YXMgbm90IGNvbXBpbGVkLlxuIik7CisJcmV0dXJuOworICAgIH0KKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19WQVJJQUJMRQorICAgIFhTTFRfVFJBQ0UoY3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJSZWdpc3RlcmluZyB2YXJpYWJsZSAnJXMnXG4iLCBjb21wLT5uYW1lKSk7CisjZW5kaWYKKworICAgIHhzbHRSZWdpc3RlclZhcmlhYmxlKGN0eHQsICh4c2x0U3R5bGVQcmVDb21wUHRyKSBjb21wLCBpbnN0LT5jaGlsZHJlbiwgMCk7Cit9CisKKy8qKgorICogeHNsdFBhcnNlU3R5bGVzaGVldFBhcmFtOgorICogQGN0eHQ6ICB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAY3VyOiAgdGhlIFhTTFQgJ3BhcmFtJyBlbGVtZW50CisgKgorICogUmVnaXN0ZXJzIGEgbG9jYWwgWFNMVCAncGFyYW0nIGRlY2xhcmF0aW9uIGF0IHRyYW5zZm9ybWF0aW9uIHRpbWUgYW5kCisgKiBldmFsdWF0ZXMgaXRzIHZhbHVlLgorICovCit2b2lkCit4c2x0UGFyc2VTdHlsZXNoZWV0UGFyYW0oeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBjdXIpCit7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbVBhcmFtUHRyIGNvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcDsKKyNlbmRpZgorCisgICAgaWYgKChjdXIgPT0gTlVMTCkgfHwgKGN0eHQgPT0gTlVMTCkpCisJcmV0dXJuOworCisgICAgY29tcCA9IGN1ci0+cHN2aTsKKyAgICBpZiAoKGNvbXAgPT0gTlVMTCkgfHwgKGNvbXAtPm5hbWUgPT0gTlVMTCkpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgY3VyLAorCSAgICAiSW50ZXJuYWwgZXJyb3IgaW4geHNsdFBhcnNlU3R5bGVzaGVldFBhcmFtKCk6ICIKKwkgICAgIlRoZSBYU0xUICdwYXJhbScgZGVjbGFyYXRpb24gd2FzIG5vdCBjb21waWxlZCBjb3JyZWN0bHkuXG4iKTsKKwlyZXR1cm47CisgICAgfQorCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1ZBUklBQkxFCisgICAgWFNMVF9UUkFDRShjdHh0LFhTTFRfVFJBQ0VfVkFSSUFCTEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJIlJlZ2lzdGVyaW5nIHBhcmFtICVzXG4iLCBjb21wLT5uYW1lKSk7CisjZW5kaWYKKworICAgIHhzbHRSZWdpc3RlclZhcmlhYmxlKGN0eHQsICh4c2x0U3R5bGVQcmVDb21wUHRyKSBjb21wLCBjdXItPmNoaWxkcmVuLCAxKTsKK30KKworLyoqCisgKiB4c2x0RnJlZUdsb2JhbFZhcmlhYmxlczoKKyAqIEBjdHh0OiAgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICoKKyAqIEZyZWUgdXAgdGhlIGRhdGEgYXNzb2NpYXRlZCB0byB0aGUgZ2xvYmFsIHZhcmlhYmxlcworICogaXRzIHZhbHVlLgorICovCisKK3ZvaWQKK3hzbHRGcmVlR2xvYmFsVmFyaWFibGVzKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpIHsKKyAgICB4bWxIYXNoRnJlZShjdHh0LT5nbG9iYWxWYXJzLCAoeG1sSGFzaERlYWxsb2NhdG9yKSB4c2x0RnJlZVN0YWNrRWxlbSk7Cit9CisKKy8qKgorICogeHNsdFhQYXRoVmFyaWFibGVMb29rdXA6CisgKiBAY3R4dDogIGEgdm9pZCAqIGJ1dCB0aGUgdGhlIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dCBhY3R1YWxseQorICogQG5hbWU6ICB0aGUgdmFyaWFibGUgbmFtZQorICogQG5zX3VyaTogIHRoZSB2YXJpYWJsZSBuYW1lc3BhY2UgVVJJCisgKgorICogVGhpcyBpcyB0aGUgZW50cnkgcG9pbnQgd2hlbiBhIHZhcmliYWxlIGlzIG5lZWRlZCBieSB0aGUgWFBhdGgKKyAqIGludGVycHJldG9yLgorICoKKyAqIFJldHVybnMgdGhlIHZhbHVlIG9yIE5VTEwgaWYgbm90IGZvdW5kCisgKi8KK3htbFhQYXRoT2JqZWN0UHRyCit4c2x0WFBhdGhWYXJpYWJsZUxvb2t1cCh2b2lkICpjdHh0LCBjb25zdCB4bWxDaGFyICpuYW1lLAorCSAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICpuc191cmkpIHsKKyAgICB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciB0Y3R4dDsKKyAgICB4bWxYUGF0aE9iamVjdFB0ciB2YWx1ZU9iaiA9IE5VTEw7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCisJcmV0dXJuKE5VTEwpOworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1ZBUklBQkxFCisgICAgWFNMVF9UUkFDRSgoKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyKWN0eHQpLFhTTFRfVFJBQ0VfVkFSSUFCTEVTLHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICJMb29rdXAgdmFyaWFibGUgJyVzJ1xuIiwgbmFtZSkpOworI2VuZGlmCisgICAgCisgICAgdGN0eHQgPSAoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIpIGN0eHQ7CisgICAgLyoKKyAgICAqIExvY2FsIHZhcmlhYmxlcy9wYXJhbXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgKgorICAgICogRG8gdGhlIGxvb2t1cCBmcm9tIHRoZSB0b3Agb2YgdGhlIHN0YWNrLCBidXQKKyAgICAqIGRvbid0IHVzZSBwYXJhbXMgYmVpbmcgY29tcHV0ZWQgaW4gYSBjYWxsLXBhcmFtCisgICAgKiBGaXJzdCBsb29rdXAgZXhwZWN0cyB0aGUgdmFyaWFibGUgbmFtZSBhbmQgVVJJIHRvCisgICAgKiBjb21lIGZyb20gdGhlIGRpc2N0aW9ubmFyeSBhbmQgaGVuY2UgcG9pbnRlciBjb21wYXJpc29uLgorICAgICovCisgICAgaWYgKHRjdHh0LT52YXJzTnIgIT0gMCkgeworCWludCBpOworCXhzbHRTdGFja0VsZW1QdHIgdmFyaWFibGUgPSBOVUxMLCBjdXI7CisKKwlmb3IgKGkgPSB0Y3R4dC0+dmFyc05yOyBpID4gdGN0eHQtPnZhcnNCYXNlOyBpLS0pIHsKKwkgICAgY3VyID0gdGN0eHQtPnZhcnNUYWJbaS0xXTsKKwkgICAgaWYgKChjdXItPm5hbWUgPT0gbmFtZSkgJiYgKGN1ci0+bmFtZVVSSSA9PSBuc191cmkpKSB7CisjaWYgMAorCQlzdGFja19hZGRyKys7CisjZW5kaWYKKwkJdmFyaWFibGUgPSBjdXI7CisJCWdvdG8gbG9jYWxfdmFyaWFibGVfZm91bmQ7CisJICAgIH0KKwkgICAgY3VyID0gY3VyLT5uZXh0OworCX0JCisJLyoKKwkqIFJlZG8gdGhlIGxvb2t1cCB3aXRoIGludGVybmVkIHN0cmluZ3MgdG8gYXZvaWQgc3RyaW5nIGNvbXBhcmlzb24uCisJKgorCSogT1BUSU1JWkUgVE9ETzogVGhlIHByb2JsZW0gaGVyZSBpcywgdGhhdCBpZiB3ZSByZXF1ZXN0IGEKKwkqICBnbG9iYWwgdmFyaWFibGUsIHRoZW4gdGhpcyB3aWxsIGJlIGFsc28gZXhlY3V0ZWQuCisJKi8KKwl7CisJICAgIGNvbnN0IHhtbENoYXIgKnRtcE5hbWUgPSBuYW1lLCAqdG1wTnNOYW1lID0gbnNfdXJpOworCisJICAgIG5hbWUgPSB4bWxEaWN0TG9va3VwKHRjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CisJICAgIGlmIChuc191cmkpCisJCW5zX3VyaSA9IHhtbERpY3RMb29rdXAodGN0eHQtPmRpY3QsIG5zX3VyaSwgLTEpOworCSAgICBpZiAoKHRtcE5hbWUgIT0gbmFtZSkgfHwgKHRtcE5zTmFtZSAhPSBuc191cmkpKSB7CQkKKwkJZm9yIChpID0gdGN0eHQtPnZhcnNOcjsgaSA+IHRjdHh0LT52YXJzQmFzZTsgaS0tKSB7CisJCSAgICBjdXIgPSB0Y3R4dC0+dmFyc1RhYltpLTFdOworCQkgICAgaWYgKChjdXItPm5hbWUgPT0gbmFtZSkgJiYgKGN1ci0+bmFtZVVSSSA9PSBuc191cmkpKSB7CisjaWYgMAorCQkJc3RhY2tfY21wKys7CisjZW5kaWYKKwkJCXZhcmlhYmxlID0gY3VyOworCQkJZ290byBsb2NhbF92YXJpYWJsZV9mb3VuZDsKKwkJICAgIH0KKwkJfQorCSAgICB9CisJfQorCitsb2NhbF92YXJpYWJsZV9mb3VuZDoKKworCWlmICh2YXJpYWJsZSkgeworCSAgICBpZiAodmFyaWFibGUtPmNvbXB1dGVkID09IDApIHsKKwkJCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1ZBUklBQkxFCisJCVhTTFRfVFJBQ0UodGN0eHQsWFNMVF9UUkFDRV9WQVJJQUJMRVMseHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICAgICJ1bmNvbXB1dGVkIHZhcmlhYmxlICclcydcbiIsIG5hbWUpKTsKKyNlbmRpZgorCQl2YXJpYWJsZS0+dmFsdWUgPSB4c2x0RXZhbFZhcmlhYmxlKHRjdHh0LCB2YXJpYWJsZSwgTlVMTCk7CisJCXZhcmlhYmxlLT5jb21wdXRlZCA9IDE7CisJICAgIH0KKwkgICAgaWYgKHZhcmlhYmxlLT52YWx1ZSAhPSBOVUxMKSB7CisJCXZhbHVlT2JqID0geG1sWFBhdGhPYmplY3RDb3B5KHZhcmlhYmxlLT52YWx1ZSk7IAorCSAgICB9CisJICAgIHJldHVybih2YWx1ZU9iaik7CisJfQorICAgIH0KKyAgICAvKgorICAgICogR2xvYmFsIHZhcmlhYmxlcy9wYXJhbXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAqLyAgICAKKyAgICBpZiAodGN0eHQtPmdsb2JhbFZhcnMpIHsKKwl2YWx1ZU9iaiA9IHhzbHRHbG9iYWxWYXJpYWJsZUxvb2t1cCh0Y3R4dCwgbmFtZSwgbnNfdXJpKTsKKyAgICB9CisKKyAgICBpZiAodmFsdWVPYmogPT0gTlVMTCkgeworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1ZBUklBQkxFCisgICAgWFNMVF9UUkFDRSh0Y3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgICJ2YXJpYWJsZSBub3QgZm91bmQgJyVzJ1xuIiwgbmFtZSkpOworI2VuZGlmCisKKwlpZiAobnNfdXJpKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcih0Y3R4dCwgTlVMTCwgdGN0eHQtPmluc3QsCisJCSJWYXJpYWJsZSAneyVzfSVzJyBoYXMgbm90IGJlZW4gZGVjbGFyZWQuXG4iLCBuc191cmksIG5hbWUpOworCX0gZWxzZSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcih0Y3R4dCwgTlVMTCwgdGN0eHQtPmluc3QsCisJCSJWYXJpYWJsZSAnJXMnIGhhcyBub3QgYmVlbiBkZWNsYXJlZC5cbiIsIG5hbWUpOworCX0KKyAgICB9IGVsc2UgeworCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1ZBUklBQkxFCisJWFNMVF9UUkFDRSh0Y3R4dCxYU0xUX1RSQUNFX1ZBUklBQkxFUyx4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAiZm91bmQgdmFyaWFibGUgJyVzJ1xuIiwgbmFtZSkpOworI2VuZGlmCisgICAgfQorCisgICAgcmV0dXJuKHZhbHVlT2JqKTsKK30KKworCmRpZmYgLS1naXQgYS9saWJ4c2x0L3ZhcmlhYmxlcy5oIGIvbGlieHNsdC92YXJpYWJsZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTA1NWU0Ci0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC92YXJpYWJsZXMuaApAQCAtMCwwICsxLDkxIEBACisvKgorICogU3VtbWFyeTogaW50ZXJmYWNlIGZvciB0aGUgdmFyaWFibGUgbWF0Y2hpbmcgYW5kIGxvb2t1cC4KKyAqIERlc2NyaXB0aW9uOiBpbnRlcmZhY2UgZm9yIHRoZSB2YXJpYWJsZSBtYXRjaGluZyBhbmQgbG9va3VwLgorICoKKyAqIENvcHk6IFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBBdXRob3I6IERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVF9WQVJJQUJMRVNfSF9fCisjZGVmaW5lIF9fWE1MX1hTTFRfVkFSSUFCTEVTX0hfXworCisjaW5jbHVkZSA8bGlieG1sL3hwYXRoLmg+CisjaW5jbHVkZSA8bGlieG1sL3hwYXRoSW50ZXJuYWxzLmg+CisjaW5jbHVkZSAieHNsdGV4cG9ydHMuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisjaW5jbHVkZSAiZnVuY3Rpb25zLmgiCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworCisvKioKKyAqIFhTTFRfUkVHSVNURVJfVkFSSUFCTEVfTE9PS1VQOgorICoKKyAqIFJlZ2lzdGVyaW5nIG1hY3JvLCBub3QgZ2VuZXJhbCBwdXJwb3NlIGF0IGFsbCBidXQgdXNlZCBpbiBkaWZmZXJlbnQgbW9kdWxlcy4KKyAqLworCisjZGVmaW5lIFhTTFRfUkVHSVNURVJfVkFSSUFCTEVfTE9PS1VQKGN0eHQpCQkJXAorICAgIHhtbFhQYXRoUmVnaXN0ZXJWYXJpYWJsZUxvb2t1cCgoY3R4dCktPnhwYXRoQ3R4dCwJCVwKKwkgICAgICAgeHNsdFhQYXRoVmFyaWFibGVMb29rdXAsCSh2b2lkICopKGN0eHQpKTsJXAorICAgIHhzbHRSZWdpc3RlckFsbEZ1bmN0aW9ucygoY3R4dCktPnhwYXRoQ3R4dCk7CQlcCisgICAgeHNsdFJlZ2lzdGVyQWxsRWxlbWVudChjdHh0KTsJCQkJXAorICAgIChjdHh0KS0+eHBhdGhDdHh0LT5leHRyYSA9IGN0eHQKKworLyoKKyAqIEludGVyZmFjZXMgZm9yIHRoZSB2YXJpYWJsZSBtb2R1bGUuCisgKi8KKworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwJCQorCQl4c2x0RXZhbEdsb2JhbFZhcmlhYmxlcwkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwJCQorCQl4c2x0RXZhbFVzZXJQYXJhbXMJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIGNvbnN0IGNoYXIgKipwYXJhbXMpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwJCQorICAgIAkJeHNsdFF1b3RlVXNlclBhcmFtcwkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgY29uc3QgY2hhciAqKnBhcmFtcyk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCisJCXhzbHRFdmFsT25lVXNlclBhcmFtCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKyAgICAJCQkJCQkgY29uc3QgeG1sQ2hhciAqIG5hbWUsCisJCQkJCQkgY29uc3QgeG1sQ2hhciAqIHZhbHVlKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkKKyAgICAJCXhzbHRRdW90ZU9uZVVzZXJQYXJhbQkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisgICAgCQkJCQkJIGNvbnN0IHhtbENoYXIgKiBuYW1lLAorCQkJCQkJIGNvbnN0IHhtbENoYXIgKiB2YWx1ZSk7CisKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0UGFyc2VHbG9iYWxWYXJpYWJsZQkJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkJIHhtbE5vZGVQdHIgY3VyKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0UGFyc2VHbG9iYWxQYXJhbQkJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkJIHhtbE5vZGVQdHIgY3VyKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0UGFyc2VTdHlsZXNoZWV0VmFyaWFibGUJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgeG1sTm9kZVB0ciBjdXIpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkKKyAgICAJCXhzbHRQYXJzZVN0eWxlc2hlZXRQYXJhbQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4bWxOb2RlUHRyIGN1cik7CitYU0xUUFVCRlVOIHhzbHRTdGFja0VsZW1QdHIgWFNMVENBTEwgCisJCXhzbHRQYXJzZVN0eWxlc2hlZXRDYWxsZXJQYXJhbQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4bWxOb2RlUHRyIGN1cik7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0QWRkU3RhY2tFbGVtTGlzdAkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgeHNsdFN0YWNrRWxlbVB0ciBlbGVtcyk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQorICAgIAkJeHNsdEZyZWVHbG9iYWxWYXJpYWJsZXMJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KTsKK1hTTFRQVUJGVU4geG1sWFBhdGhPYmplY3RQdHIgWFNMVENBTEwJCisJCXhzbHRWYXJpYWJsZUxvb2t1cAkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkJCQkJCSBjb25zdCB4bWxDaGFyICpuc191cmkpOworWFNMVFBVQkZVTiB4bWxYUGF0aE9iamVjdFB0ciBYU0xUQ0FMTAkKKwkJeHNsdFhQYXRoVmFyaWFibGVMb29rdXAJCSh2b2lkICpjdHh0LAorCQkJCQkJIGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCQkJCQkgY29uc3QgeG1sQ2hhciAqbnNfdXJpKTsKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX1ZBUklBQkxFU19IX18gKi8KKwpkaWZmIC0tZ2l0IGEvbGlieHNsdC94c2x0LmMgYi9saWJ4c2x0L3hzbHQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NWY1MDViCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC94c2x0LmMKQEAgLTAsMCArMSw2OTk3IEBACisvKgorICogeHNsdC5jOiBJbXBsZW1ldGF0aW9uIG9mIGFuIFhTTCBUcmFuc2Zvcm1hdGlvbiAxLjAgZW5naW5lCisgKgorICogUmVmZXJlbmNlOgorICogICBYU0xUIHNwZWNpZmljYXRpb24KKyAqICAgaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteHNsdC0xOTk5MTExNgorICoKKyAqICAgQXNzb2NpYXRpbmcgU3R5bGUgU2hlZXRzIHdpdGggWE1MIGRvY3VtZW50cworICogICBodHRwOi8vd3d3LnczLm9yZy8xOTk5LzA2L1JFQy14bWwtc3R5bGVzaGVldC0xOTk5MDYyOQorICoKKyAqIFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBkYW5pZWxAdmVpbGxhcmQuY29tCisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisKKyNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CisjaW5jbHVkZSA8bGlieG1sL3BhcnNlci5oPgorI2luY2x1ZGUgPGxpYnhtbC90cmVlLmg+CisjaW5jbHVkZSA8bGlieG1sL3ZhbGlkLmg+CisjaW5jbHVkZSA8bGlieG1sL2hhc2guaD4KKyNpbmNsdWRlIDxsaWJ4bWwvdXJpLmg+CisjaW5jbHVkZSA8bGlieG1sL3htbGVycm9yLmg+CisjaW5jbHVkZSA8bGlieG1sL3BhcnNlckludGVybmFscy5oPgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aEludGVybmFscy5oPgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aC5oPgorI2luY2x1ZGUgInhzbHQuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisjaW5jbHVkZSAicGF0dGVybi5oIgorI2luY2x1ZGUgInZhcmlhYmxlcy5oIgorI2luY2x1ZGUgIm5hbWVzcGFjZXMuaCIKKyNpbmNsdWRlICJhdHRyaWJ1dGVzLmgiCisjaW5jbHVkZSAieHNsdHV0aWxzLmgiCisjaW5jbHVkZSAiaW1wb3J0cy5oIgorI2luY2x1ZGUgImtleXMuaCIKKyNpbmNsdWRlICJkb2N1bWVudHMuaCIKKyNpbmNsdWRlICJleHRlbnNpb25zLmgiCisjaW5jbHVkZSAicHJlcHJvYy5oIgorI2luY2x1ZGUgImV4dHJhLmgiCisjaW5jbHVkZSAic2VjdXJpdHkuaCIKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworI2RlZmluZSBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworLyogI2RlZmluZSBXSVRIX1hTTFRfREVCVUdfQkxBTktTICovCisjZW5kaWYKKworY29uc3QgY2hhciAqeHNsdEVuZ2luZVZlcnNpb24gPSBMSUJYU0xUX1ZFUlNJT05fU1RSSU5HIExJQlhTTFRfVkVSU0lPTl9FWFRSQTsKK2NvbnN0IGludCB4c2x0TGlieHNsdFZlcnNpb24gPSBMSUJYU0xUX1ZFUlNJT047Citjb25zdCBpbnQgeHNsdExpYnhtbFZlcnNpb24gPSBMSUJYTUxfVkVSU0lPTjsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCitjb25zdCB4bWxDaGFyICp4c2x0Q29uc3ROYW1lc3BhY2VOYW1lWFNMVCA9IChjb25zdCB4bWxDaGFyICopIFhTTFRfTkFNRVNQQUNFOworCisjZGVmaW5lIFhTTFRfRUxFTUVOVF9DQVRFR09SWV9YU0xUIDAKKyNkZWZpbmUgWFNMVF9FTEVNRU5UX0NBVEVHT1JZX0VYVEVOU0lPTiAxCisjZGVmaW5lIFhTTFRfRUxFTUVOVF9DQVRFR09SWV9MUkUgMgorCisvKgorKiB4c2x0TGl0ZXJhbFJlc3VsdE1hcmtlcjoKKyogTWFya2VyIGZvciBMaXRlcmFsIHJlc3VsdCBlbGVtZW50cywgaW4gb3JkZXIgdG8gYXZvaWQgbXVsdGlwbGUgYXR0ZW1wdHMKKyogdG8gcmVjb2duaXplIHN1Y2ggZWxlbWVudHMgaW4gdGhlIHN0eWxlc2hlZXQncyB0cmVlLgorKiBUaGlzIG1hcmtlciBpcyBzZXQgb24gbm9kZS0+cHN2aSBkdXJpbmcgdGhlIGluaXRpYWwgdHJhdmVyc2FsCisqIG9mIGEgc3R5bGVzaGVldCdzIG5vZGUgdHJlZS4KKyoKK2NvbnN0IHhtbENoYXIgKnhzbHRMaXRlcmFsUmVzdWx0TWFya2VyID0KKyAgICAoY29uc3QgeG1sQ2hhciAqKSAiTGl0ZXJhbCBSZXN1bHQgRWxlbWVudCI7CisqLworCisvKgorKiB4c2x0WFNMVFRleHRNYXJrZXI6CisqIE1hcmtlciBmb3IgeHNsOnRleHQgZWxlbWVudHMuIFVzZWQgdG8gcmVjb2duaXplIHhzbDp0ZXh0IGVsZW1lbnRzCisqIGZvciBwb3N0LXByb2Nlc3Npbmcgb2YgdGhlIHN0eWxlc2hlZXQncyB0cmVlLCB3aGVyZSB0aG9zZQorKiBlbGVtZW50cyBhcmUgcmVtb3ZlZCBmcm9tIHRoZSB0cmVlLgorKi8KK2NvbnN0IHhtbENoYXIgKnhzbHRYU0xUVGV4dE1hcmtlciA9IChjb25zdCB4bWxDaGFyICopICJYU0xUIFRleHQgRWxlbWVudCI7CisKKy8qCisqIHhzbHRYU0xUQXR0ck1hcmtlcjoKKyogTWFya2VyIGZvciBYU0xUIGF0dHJpYnV0ZSBvbiBMaXRlcmFsIFJlc3VsdCBFbGVtZW50cy4KKyovCitjb25zdCB4bWxDaGFyICp4c2x0WFNMVEF0dHJNYXJrZXIgPSAoY29uc3QgeG1sQ2hhciAqKSAiTFJFIFhTTFQgQXR0ciI7CisKKyNlbmRpZgorCisjaWZkZWYgWFNMVF9MT0NBTEVfV0lOQVBJCitleHRlcm4geG1sUk11dGV4UHRyIHhzbHRMb2NhbGVNdXRleDsKKyNlbmRpZgorLyoKKyAqIEhhcm1sZXNzIGJ1dCBhdm9pZGluZyBhIHByb2JsZW0gd2hlbiBjb21waWxpbmcgYWdhaW5zdCBhCisgKiBsaWJ4bWwgPD0gMi4zLjExIHdpdGhvdXQgTElCWE1MX0RFQlVHX0VOQUJMRUQKKyAqLworI2lmbmRlZiBMSUJYTUxfREVCVUdfRU5BQkxFRAorZG91YmxlIHhtbFhQYXRoU3RyaW5nRXZhbE51bWJlcihjb25zdCB4bWxDaGFyICpzdHIpOworI2VuZGlmCisvKgorICogVXNlZnVsIG1hY3JvcworICovCisKKyNpZmRlZiAgSVNfQkxBTksKKyN1bmRlZglJU19CTEFOSworI2VuZGlmCisjZGVmaW5lIElTX0JMQU5LKGMpICgoKGMpID09IDB4MjApIHx8ICgoYykgPT0gMHgwOSkgfHwgKChjKSA9PSAweEEpIHx8CVwKKyAgICAgICAgICAgICAgICAgICAgICgoYykgPT0gMHgwRCkpCisKKyNpZmRlZglJU19CTEFOS19OT0RFCisjdW5kZWYJSVNfQkxBTktfTk9ERQorI2VuZGlmCisjZGVmaW5lIElTX0JMQU5LX05PREUobikJCQkJCQlcCisgICAgKCgobiktPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgJiYgKHhzbHRJc0JsYW5rKChuKS0+Y29udGVudCkpKQorCisvKioKKyAqIHhzbHRQYXJzZUNvbnRlbnRFcnJvcjoKKyAqCisgKiBAc3R5bGU6IHRoZSBzdHlsZXNoZWV0CisgKiBAbm9kZTogdGhlIG5vZGUgd2hlcmUgdGhlIGVycm9yIG9jY3VyZWQKKyAqCisgKiBDb21waWxlLXRpbWUgZXJyb3IgZnVuY3Rpb24uCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0UGFyc2VDb250ZW50RXJyb3IoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCSAgICAgICB4bWxOb2RlUHRyIG5vZGUpCit7CisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICBpZiAoSVNfWFNMVF9FTEVNKG5vZGUpKQorCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgbm9kZSwKKwkgICAgIlRoZSBYU0xULWVsZW1lbnQgJyVzJyBpcyBub3QgYWxsb3dlZCBhdCB0aGlzIHBvc2l0aW9uLlxuIiwKKwkgICAgbm9kZS0+bmFtZSk7CisgICAgZWxzZQorCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgbm9kZSwKKwkgICAgIlRoZSBlbGVtZW50ICclcycgaXMgbm90IGFsbG93ZWQgYXQgdGhpcyBwb3NpdGlvbi5cbiIsCisJICAgIG5vZGUtPm5hbWUpOworICAgIHN0eWxlLT5lcnJvcnMrKzsKK30KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorI2Vsc2UKKy8qKgorICogZXhjbFByZWZpeFB1c2g6CisgKiBAc3R5bGU6IHRoZSB0cmFuc2Zvcm1hdGlvbiBzdHlsZXNoZWV0CisgKiBAdmFsdWU6ICB0aGUgZXhjbHVkZWQgbmFtZXNwYWNlIG5hbWUgdG8gcHVzaCBvbiB0aGUgc3RhY2sKKyAqCisgKiBQdXNoIGFuIGV4Y2x1ZGVkIG5hbWVzcGFjZSBuYW1lIG9uIHRoZSBzdGFjaworICoKKyAqIFJldHVybnMgdGhlIG5ldyBpbmRleCBpbiB0aGUgc3RhY2sgb3IgLTEgaWYgYWxyZWFkeSBwcmVzZW50IG9yCisgKiBpbiBjYXNlIG9mIGVycm9yCisgKi8KK3N0YXRpYyBpbnQKK2V4Y2xQcmVmaXhQdXNoKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxDaGFyICogdmFsdWUpCit7CisgICAgaW50IGk7CisKKyAgICBpZiAoc3R5bGUtPmV4Y2xQcmVmaXhNYXggPT0gMCkgeworICAgICAgICBzdHlsZS0+ZXhjbFByZWZpeE1heCA9IDQ7CisgICAgICAgIHN0eWxlLT5leGNsUHJlZml4VGFiID0KKyAgICAgICAgICAgICh4bWxDaGFyICogKil4bWxNYWxsb2Moc3R5bGUtPmV4Y2xQcmVmaXhNYXggKgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3R5bGUtPmV4Y2xQcmVmaXhUYWJbMF0pKTsKKyAgICAgICAgaWYgKHN0eWxlLT5leGNsUHJlZml4VGFiID09IE5VTEwpIHsKKyAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWFsbG9jIGZhaWxlZCAhXG4iKTsKKyAgICAgICAgICAgIHJldHVybiAoLTEpOworICAgICAgICB9CisgICAgfQorICAgIC8qIGRvIG5vdCBwdXNoIGR1cGxpY2F0ZXMgKi8KKyAgICBmb3IgKGkgPSAwO2kgPCBzdHlsZS0+ZXhjbFByZWZpeE5yO2krKykgeworICAgICAgICBpZiAoeG1sU3RyRXF1YWwoc3R5bGUtPmV4Y2xQcmVmaXhUYWJbaV0sIHZhbHVlKSkKKwkgICAgcmV0dXJuKC0xKTsKKyAgICB9CisgICAgaWYgKHN0eWxlLT5leGNsUHJlZml4TnIgPj0gc3R5bGUtPmV4Y2xQcmVmaXhNYXgpIHsKKyAgICAgICAgc3R5bGUtPmV4Y2xQcmVmaXhNYXggKj0gMjsKKyAgICAgICAgc3R5bGUtPmV4Y2xQcmVmaXhUYWIgPQorICAgICAgICAgICAgKHhtbENoYXIgKiAqKXhtbFJlYWxsb2Moc3R5bGUtPmV4Y2xQcmVmaXhUYWIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZS0+ZXhjbFByZWZpeE1heCAqCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3R5bGUtPmV4Y2xQcmVmaXhUYWJbMF0pKTsKKyAgICAgICAgaWYgKHN0eWxlLT5leGNsUHJlZml4VGFiID09IE5VTEwpIHsKKyAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAicmVhbGxvYyBmYWlsZWQgIVxuIik7CisgICAgICAgICAgICByZXR1cm4gKC0xKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBzdHlsZS0+ZXhjbFByZWZpeFRhYltzdHlsZS0+ZXhjbFByZWZpeE5yXSA9IHZhbHVlOworICAgIHN0eWxlLT5leGNsUHJlZml4ID0gdmFsdWU7CisgICAgcmV0dXJuIChzdHlsZS0+ZXhjbFByZWZpeE5yKyspOworfQorLyoqCisgKiBleGNsUHJlZml4UG9wOgorICogQHN0eWxlOiB0aGUgdHJhbnNmb3JtYXRpb24gc3R5bGVzaGVldAorICoKKyAqIFBvcCBhbiBleGNsdWRlZCBwcmVmaXggdmFsdWUgZnJvbSB0aGUgc3RhY2sKKyAqCisgKiBSZXR1cm5zIHRoZSBzdG9yZWQgZXhjbHVkZWQgcHJlZml4IHZhbHVlCisgKi8KK3N0YXRpYyB4bWxDaGFyICoKK2V4Y2xQcmVmaXhQb3AoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUpCit7CisgICAgeG1sQ2hhciAqcmV0OworCisgICAgaWYgKHN0eWxlLT5leGNsUHJlZml4TnIgPD0gMCkKKyAgICAgICAgcmV0dXJuICgwKTsKKyAgICBzdHlsZS0+ZXhjbFByZWZpeE5yLS07CisgICAgaWYgKHN0eWxlLT5leGNsUHJlZml4TnIgPiAwKQorICAgICAgICBzdHlsZS0+ZXhjbFByZWZpeCA9IHN0eWxlLT5leGNsUHJlZml4VGFiW3N0eWxlLT5leGNsUHJlZml4TnIgLSAxXTsKKyAgICBlbHNlCisgICAgICAgIHN0eWxlLT5leGNsUHJlZml4ID0gTlVMTDsKKyAgICByZXQgPSBzdHlsZS0+ZXhjbFByZWZpeFRhYltzdHlsZS0+ZXhjbFByZWZpeE5yXTsKKyAgICBzdHlsZS0+ZXhjbFByZWZpeFRhYltzdHlsZS0+ZXhjbFByZWZpeE5yXSA9IDA7CisgICAgcmV0dXJuIChyZXQpOworfQorI2VuZGlmCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICoJCQlIZWxwZXIgZnVuY3Rpb25zCQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIGludCBpbml0aWFsaXplZCA9IDA7CisvKioKKyAqIHhzbHRJbml0OgorICoKKyAqIEluaXRpYWxpemVzIHRoZSBwcm9jZXNzb3IgKGUuZy4gcmVnaXN0ZXJzIGJ1aWx0LWluIGV4dGVuc2lvbnMsCisgKiBldGMuKQorICovCit2b2lkCit4c2x0SW5pdCAodm9pZCkgeworICAgIGlmIChpbml0aWFsaXplZCA9PSAwKSB7CisJaW5pdGlhbGl6ZWQgPSAxOworI2lmZGVmIFhTTFRfTE9DQUxFX1dJTkFQSQorCXhzbHRMb2NhbGVNdXRleCA9IHhtbE5ld1JNdXRleCgpOworI2VuZGlmCisgICAgICAgIHhzbHRSZWdpc3RlckFsbEV4dHJhcygpOworICAgIH0KK30KKworLyoqCisgKiB4c2x0VW5pbml0OgorICoKKyAqIFVuaW5pdGlhbGl6ZXMgdGhlIHByb2Nlc3Nvci4KKyAqLwordm9pZAoreHNsdFVuaW5pdCAodm9pZCkgeworICAgIGluaXRpYWxpemVkID0gMDsKK30KKworLyoqCisgKiB4c2x0SXNCbGFuazoKKyAqIEBzdHI6ICBhIHN0cmluZworICoKKyAqIENoZWNrIGlmIGEgc3RyaW5nIGlzIGlnbm9yYWJsZQorICoKKyAqIFJldHVybnMgMSBpZiB0aGUgc3RyaW5nIGlzIE5VTEwgb3IgbWFkZSBvZiBibGFua3MgY2hhcnMsIDAgb3RoZXJ3aXNlCisgKi8KK2ludAoreHNsdElzQmxhbmsoeG1sQ2hhciAqc3RyKSB7CisgICAgaWYgKHN0ciA9PSBOVUxMKQorCXJldHVybigxKTsKKyAgICB3aGlsZSAoKnN0ciAhPSAwKSB7CisJaWYgKCEoSVNfQkxBTksoKnN0cikpKSByZXR1cm4oMCk7CisJc3RyKys7CisgICAgfQorICAgIHJldHVybigxKTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKgkJUm91dGluZXMgdG8gaGFuZGxlIFhTTFQgZGF0YSBzdHJ1Y3R1cmVzCQkJKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworc3RhdGljIHhzbHREZWNpbWFsRm9ybWF0UHRyCit4c2x0TmV3RGVjaW1hbEZvcm1hdCh4bWxDaGFyICpuYW1lKQoreworICAgIHhzbHREZWNpbWFsRm9ybWF0UHRyIHNlbGY7CisgICAgLyogVVRGLTggZm9yIDB4MjAzMCAqLworICAgIHN0YXRpYyBjb25zdCB4bWxDaGFyIHBlcm1pbGxlWzRdID0gezB4ZTIsIDB4ODAsIDB4YjAsIDB9OworCisgICAgc2VsZiA9IHhtbE1hbGxvYyhzaXplb2YoeHNsdERlY2ltYWxGb3JtYXQpKTsKKyAgICBpZiAoc2VsZiAhPSBOVUxMKSB7CisJc2VsZi0+bmV4dCA9IE5VTEw7CisJc2VsZi0+bmFtZSA9IG5hbWU7CisJCisJLyogRGVmYXVsdCB2YWx1ZXMgKi8KKwlzZWxmLT5kaWdpdCA9IHhtbFN0cmR1cChCQURfQ0FTVCgiIyIpKTsKKwlzZWxmLT5wYXR0ZXJuU2VwYXJhdG9yID0geG1sU3RyZHVwKEJBRF9DQVNUKCI7IikpOworCXNlbGYtPmRlY2ltYWxQb2ludCA9IHhtbFN0cmR1cChCQURfQ0FTVCgiLiIpKTsKKwlzZWxmLT5ncm91cGluZyA9IHhtbFN0cmR1cChCQURfQ0FTVCgiLCIpKTsKKwlzZWxmLT5wZXJjZW50ID0geG1sU3RyZHVwKEJBRF9DQVNUKCIlIikpOworCXNlbGYtPnBlcm1pbGxlID0geG1sU3RyZHVwKEJBRF9DQVNUKHBlcm1pbGxlKSk7CisJc2VsZi0+emVyb0RpZ2l0ID0geG1sU3RyZHVwKEJBRF9DQVNUKCIwIikpOworCXNlbGYtPm1pbnVzU2lnbiA9IHhtbFN0cmR1cChCQURfQ0FTVCgiLSIpKTsKKwlzZWxmLT5pbmZpbml0eSA9IHhtbFN0cmR1cChCQURfQ0FTVCgiSW5maW5pdHkiKSk7CisJc2VsZi0+bm9OdW1iZXIgPSB4bWxTdHJkdXAoQkFEX0NBU1QoIk5hTiIpKTsKKyAgICB9CisgICAgcmV0dXJuIHNlbGY7Cit9CisKK3N0YXRpYyB2b2lkCit4c2x0RnJlZURlY2ltYWxGb3JtYXQoeHNsdERlY2ltYWxGb3JtYXRQdHIgc2VsZikKK3sKKyAgICBpZiAoc2VsZiAhPSBOVUxMKSB7CisJaWYgKHNlbGYtPmRpZ2l0KQorCSAgICB4bWxGcmVlKHNlbGYtPmRpZ2l0KTsKKwlpZiAoc2VsZi0+cGF0dGVyblNlcGFyYXRvcikKKwkgICAgeG1sRnJlZShzZWxmLT5wYXR0ZXJuU2VwYXJhdG9yKTsKKwlpZiAoc2VsZi0+ZGVjaW1hbFBvaW50KQorCSAgICB4bWxGcmVlKHNlbGYtPmRlY2ltYWxQb2ludCk7CisJaWYgKHNlbGYtPmdyb3VwaW5nKQorCSAgICB4bWxGcmVlKHNlbGYtPmdyb3VwaW5nKTsKKwlpZiAoc2VsZi0+cGVyY2VudCkKKwkgICAgeG1sRnJlZShzZWxmLT5wZXJjZW50KTsKKwlpZiAoc2VsZi0+cGVybWlsbGUpCisJICAgIHhtbEZyZWUoc2VsZi0+cGVybWlsbGUpOworCWlmIChzZWxmLT56ZXJvRGlnaXQpCisJICAgIHhtbEZyZWUoc2VsZi0+emVyb0RpZ2l0KTsKKwlpZiAoc2VsZi0+bWludXNTaWduKQorCSAgICB4bWxGcmVlKHNlbGYtPm1pbnVzU2lnbik7CisJaWYgKHNlbGYtPmluZmluaXR5KQorCSAgICB4bWxGcmVlKHNlbGYtPmluZmluaXR5KTsKKwlpZiAoc2VsZi0+bm9OdW1iZXIpCisJICAgIHhtbEZyZWUoc2VsZi0+bm9OdW1iZXIpOworCWlmIChzZWxmLT5uYW1lKQorCSAgICB4bWxGcmVlKHNlbGYtPm5hbWUpOworCXhtbEZyZWUoc2VsZik7CisgICAgfQorfQorCitzdGF0aWMgdm9pZAoreHNsdEZyZWVEZWNpbWFsRm9ybWF0TGlzdCh4c2x0U3R5bGVzaGVldFB0ciBzZWxmKQoreworICAgIHhzbHREZWNpbWFsRm9ybWF0UHRyIGl0ZXI7CisgICAgeHNsdERlY2ltYWxGb3JtYXRQdHIgdG1wOworCisgICAgaWYgKHNlbGYgPT0gTlVMTCkKKwlyZXR1cm47CisgICAgCisgICAgaXRlciA9IHNlbGYtPmRlY2ltYWxGb3JtYXQ7CisgICAgd2hpbGUgKGl0ZXIgIT0gTlVMTCkgeworCXRtcCA9IGl0ZXItPm5leHQ7CisJeHNsdEZyZWVEZWNpbWFsRm9ybWF0KGl0ZXIpOworCWl0ZXIgPSB0bXA7CisgICAgfQorfQorCisvKioKKyAqIHhzbHREZWNpbWFsRm9ybWF0R2V0QnlOYW1lOgorICogQHN0eWxlOiB0aGUgWFNMVCBzdHlsZXNoZWV0CisgKiBAbmFtZTogdGhlIGRlY2ltYWwtZm9ybWF0IG5hbWUgdG8gZmluZAorICoKKyAqIEZpbmQgZGVjaW1hbC1mb3JtYXQgYnkgbmFtZQorICoKKyAqIFJldHVybnMgdGhlIHhzbHREZWNpbWFsRm9ybWF0UHRyCisgKi8KK3hzbHREZWNpbWFsRm9ybWF0UHRyCit4c2x0RGVjaW1hbEZvcm1hdEdldEJ5TmFtZSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sQ2hhciAqbmFtZSkKK3sKKyAgICB4c2x0RGVjaW1hbEZvcm1hdFB0ciByZXN1bHQgPSBOVUxMOworCisgICAgaWYgKG5hbWUgPT0gTlVMTCkKKwlyZXR1cm4gc3R5bGUtPmRlY2ltYWxGb3JtYXQ7CisKKyAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworCWZvciAocmVzdWx0ID0gc3R5bGUtPmRlY2ltYWxGb3JtYXQtPm5leHQ7CisJICAgICByZXN1bHQgIT0gTlVMTDsKKwkgICAgIHJlc3VsdCA9IHJlc3VsdC0+bmV4dCkgeworCSAgICBpZiAoeG1sU3RyRXF1YWwobmFtZSwgcmVzdWx0LT5uYW1lKSkKKwkJcmV0dXJuIHJlc3VsdDsKKwl9CisJc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKKworLyoqCisgKiB4c2x0TmV3VGVtcGxhdGU6CisgKgorICogQ3JlYXRlIGEgbmV3IFhTTFQgVGVtcGxhdGUKKyAqCisgKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgeHNsdFRlbXBsYXRlUHRyIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgorICovCitzdGF0aWMgeHNsdFRlbXBsYXRlUHRyCit4c2x0TmV3VGVtcGxhdGUodm9pZCkgeworICAgIHhzbHRUZW1wbGF0ZVB0ciBjdXI7CisKKyAgICBjdXIgPSAoeHNsdFRlbXBsYXRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhzbHRUZW1wbGF0ZSkpOworICAgIGlmIChjdXIgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkieHNsdE5ld1RlbXBsYXRlIDogbWFsbG9jIGZhaWxlZFxuIik7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBtZW1zZXQoY3VyLCAwLCBzaXplb2YoeHNsdFRlbXBsYXRlKSk7CisgICAgY3VyLT5wcmlvcml0eSA9IFhTTFRfUEFUX05PX1BSSU9SSVRZOworICAgIHJldHVybihjdXIpOworfQorCisvKioKKyAqIHhzbHRGcmVlVGVtcGxhdGU6CisgKiBAdGVtcGxhdGU6ICBhbiBYU0xUIHRlbXBsYXRlCisgKgorICogRnJlZSB1cCB0aGUgbWVtb3J5IGFsbG9jYXRlZCBieSBAdGVtcGxhdGUKKyAqLworc3RhdGljIHZvaWQKK3hzbHRGcmVlVGVtcGxhdGUoeHNsdFRlbXBsYXRlUHRyIHRlbXBsYXRlKSB7CisgICAgaWYgKHRlbXBsYXRlID09IE5VTEwpCisJcmV0dXJuOworICAgIGlmICh0ZW1wbGF0ZS0+bWF0Y2gpIHhtbEZyZWUodGVtcGxhdGUtPm1hdGNoKTsKKy8qCisqICAgTk9URTogQG5hbWUgYW5kIEBuYW1lVVJJIGFyZSBwdXQgaW50byB0aGUgc3RyaW5nIGRpY3Qgbm93LgorKiAgIGlmICh0ZW1wbGF0ZS0+bmFtZSkgeG1sRnJlZSh0ZW1wbGF0ZS0+bmFtZSk7CisqICAgaWYgKHRlbXBsYXRlLT5uYW1lVVJJKSB4bWxGcmVlKHRlbXBsYXRlLT5uYW1lVVJJKTsKKyovCisvKgorICAgIGlmICh0ZW1wbGF0ZS0+bW9kZSkgeG1sRnJlZSh0ZW1wbGF0ZS0+bW9kZSk7CisgICAgaWYgKHRlbXBsYXRlLT5tb2RlVVJJKSB4bWxGcmVlKHRlbXBsYXRlLT5tb2RlVVJJKTsKKyAqLworICAgIGlmICh0ZW1wbGF0ZS0+aW5oZXJpdGVkTnMpIHhtbEZyZWUodGVtcGxhdGUtPmluaGVyaXRlZE5zKTsKKyAgICBtZW1zZXQodGVtcGxhdGUsIC0xLCBzaXplb2YoeHNsdFRlbXBsYXRlKSk7CisgICAgeG1sRnJlZSh0ZW1wbGF0ZSk7Cit9CisKKy8qKgorICogeHNsdEZyZWVUZW1wbGF0ZUxpc3Q6CisgKiBAdGVtcGxhdGU6ICBhbiBYU0xUIHRlbXBsYXRlIGxpc3QKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGJ5IGFsbCB0aGUgZWxlbWVudHMgb2YgQHRlbXBsYXRlCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0RnJlZVRlbXBsYXRlTGlzdCh4c2x0VGVtcGxhdGVQdHIgdGVtcGxhdGUpIHsKKyAgICB4c2x0VGVtcGxhdGVQdHIgY3VyOworCisgICAgd2hpbGUgKHRlbXBsYXRlICE9IE5VTEwpIHsKKwljdXIgPSB0ZW1wbGF0ZTsKKwl0ZW1wbGF0ZSA9IHRlbXBsYXRlLT5uZXh0OworCXhzbHRGcmVlVGVtcGxhdGUoY3VyKTsKKyAgICB9Cit9CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKworc3RhdGljIHZvaWQKK3hzbHRGcmVlTnNBbGlhc0xpc3QoeHNsdE5zQWxpYXNQdHIgaXRlbSkKK3sKKyAgICB4c2x0TnNBbGlhc1B0ciB0bXA7CisgICAgCisgICAgd2hpbGUgKGl0ZW0pIHsKKwl0bXAgPSBpdGVtOworCWl0ZW0gPSBpdGVtLT5uZXh0OworCXhtbEZyZWUodG1wKTsKKyAgICB9IAorICAgIHJldHVybjsKK30KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRF9YU0xUX05TQ09NUAorc3RhdGljIHZvaWQKK3hzbHRGcmVlTmFtZXNwYWNlTWFwKHhzbHROc01hcFB0ciBpdGVtKQoreworICAgIHhzbHROc01hcFB0ciB0bXA7CisgICAgCisgICAgd2hpbGUgKGl0ZW0pIHsKKwl0bXAgPSBpdGVtOworCWl0ZW0gPSBpdGVtLT5uZXh0OworCXhtbEZyZWUodG1wKTsKKyAgICB9IAorICAgIHJldHVybjsKK30KKworc3RhdGljIHhzbHROc01hcFB0cgoreHNsdE5ld05hbWVzcGFjZU1hcEl0ZW0oeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwKKwkJCXhtbERvY1B0ciBkb2MsCisJCQl4bWxOc1B0ciBucywKKwkJCXhtbE5vZGVQdHIgZWxlbSkKK3sKKyAgICB4c2x0TnNNYXBQdHIgcmV0OworCisgICAgaWYgKChjY3R4dCA9PSBOVUxMKSB8fCAoZG9jID09IE5VTEwpIHx8IChucyA9PSBOVUxMKSkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICByZXQgPSAoeHNsdE5zTWFwUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhzbHROc01hcCkpOworICAgIGlmIChyZXQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIGVsZW0sCisJICAgICJJbnRlcm5hbCBlcnJvcjogKHhzbHROZXdOYW1lc3BhY2VNYXBJdGVtKSAiCisJICAgICJtZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQuXG4iKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4c2x0TnNNYXApKTsKKyAgICByZXQtPmRvYyA9IGRvYzsKKyAgICByZXQtPm5zID0gbnM7CisgICAgcmV0LT5vcmlnTnNOYW1lID0gbnMtPmhyZWY7CisgICAgLyoKKyAgICAqIFN0b3JlIHRoZSBpdGVtIGF0IGN1cnJlbnQgc3R5bGVzaGVldC1sZXZlbC4KKyAgICAqLworICAgIGlmIChjY3R4dC0+cHNEYXRhLT5uc01hcCAhPSBOVUxMKQorCXJldC0+bmV4dCA9IGNjdHh0LT5wc0RhdGEtPm5zTWFwOworICAgIGNjdHh0LT5wc0RhdGEtPm5zTWFwID0gcmV0OworCisgICAgcmV0dXJuKHJldCk7Cit9CisjZW5kaWYgLyogWFNMVF9SRUZBQ1RPUkVEX1hTTFRfTlNDT01QICovCisKKy8qKgorICogeHNsdENvbXBpbGVyVmFySW5mb0ZyZWU6IAorICogQGNjdHh0OiB0aGUgY29tcGlsYXRpb24gY29udGV4dAorICogCisgKiBGcmVlcyB0aGUgbGlzdCBvZiBpbmZvcm1hdGlvbiBmb3IgdmFycy9wYXJhbXMuCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0Q29tcGlsZXJWYXJJbmZvRnJlZSh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0KQoreworICAgIHhzbHRWYXJJbmZvUHRyIGl2YXIgPSBjY3R4dC0+aXZhcnMsIGl2YXJ0bXA7ICAgIAorCisgICAgd2hpbGUgKGl2YXIpIHsKKwlpdmFydG1wID0gaXZhcjsKKwlpdmFyID0gaXZhci0+bmV4dDsKKwl4bWxGcmVlKGl2YXJ0bXApOworICAgIH0KK30KKworLyoqCisgKiB4c2x0Q29tcGlsZXJDdHh0RnJlZToKKyAqCisgKiBGcmVlIGFuIFhTTFQgY29tcGlsZXIgY29udGV4dC4gCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0Q29tcGlsYXRpb25DdHh0RnJlZSh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0KQoreyAgICAKKyAgICBpZiAoY2N0eHQgPT0gTlVMTCkKKwlyZXR1cm47CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJGcmVlaW5nIGNvbXBpbGF0aW9uIGNvbnRleHRcbiIpOworICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJIiMjIyBNYXggaW5vZGVzOiAlZFxuIiwgY2N0eHQtPm1heE5vZGVJbmZvcyk7CisgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkiIyMjIE1heCBMUkVzICA6ICVkXG4iLCBjY3R4dC0+bWF4TFJFcyk7CisjZW5kaWYKKyAgICAvKgorICAgICogRnJlZSBub2RlLWluZm9zLgorICAgICovCisgICAgaWYgKGNjdHh0LT5pbm9kZUxpc3QgIT0gTlVMTCkgeworCXhzbHRDb21waWxlck5vZGVJbmZvUHRyIHRtcCwgY3VyID0gY2N0eHQtPmlub2RlTGlzdDsKKwl3aGlsZSAoY3VyICE9IE5VTEwpIHsKKwkgICAgdG1wID0gY3VyOworCSAgICBjdXIgPSBjdXItPm5leHQ7CisJICAgIHhtbEZyZWUodG1wKTsKKwl9CisgICAgfQorICAgIGlmIChjY3R4dC0+dG1wTGlzdCAhPSBOVUxMKQorCXhzbHRQb2ludGVyTGlzdEZyZWUoY2N0eHQtPnRtcExpc3QpOworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRF9YUEFUSENPTVAKKyAgICBpZiAoY2N0eHQtPnhwYXRoQ3R4dCAhPSBOVUxMKQorCXhtbFhQYXRoRnJlZUNvbnRleHQoY2N0eHQtPnhwYXRoQ3R4dCk7CisjZW5kaWYKKyAgICBpZiAoY2N0eHQtPm5zQWxpYXNlcyAhPSBOVUxMKQorCXhzbHRGcmVlTnNBbGlhc0xpc3QoY2N0eHQtPm5zQWxpYXNlcyk7CisKKyAgICBpZiAoY2N0eHQtPml2YXJzKQorCXhzbHRDb21waWxlclZhckluZm9GcmVlKGNjdHh0KTsKKworICAgIHhtbEZyZWUoY2N0eHQpOworfQorCisvKioKKyAqIHhzbHRDb21waWxlckNyZWF0ZToKKyAqCisgKiBDcmVhdGVzIGFuIFhTTFQgY29tcGlsZXIgY29udGV4dC4KKyAqCisgKiBSZXR1cm5zIHRoZSBwb2ludGVyIHRvIHRoZSBjcmVhdGVkIHhzbHRDb21waWxlckN0eHQgb3IKKyAqICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLgorICovCitzdGF0aWMgeHNsdENvbXBpbGVyQ3R4dFB0cgoreHNsdENvbXBpbGF0aW9uQ3R4dENyZWF0ZSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkgeworICAgIHhzbHRDb21waWxlckN0eHRQdHIgcmV0OworCisgICAgcmV0ID0gKHhzbHRDb21waWxlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeHNsdENvbXBpbGVyQ3R4dCkpOworICAgIGlmIChyZXQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgTlVMTCwKKwkgICAgInhzbHRDb21waWxlckNyZWF0ZTogYWxsb2NhdGlvbiBvZiBjb21waWxlciAiCisJICAgICJjb250ZXh0IGZhaWxlZC5cbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhzbHRDb21waWxlckN0eHQpKTsKKworICAgIHJldC0+ZXJyU2V2ZXJpdHkgPSBYU0xUX0VSUk9SX1NFVkVSSVRZX0VSUk9SOworICAgIHJldC0+dG1wTGlzdCA9IHhzbHRQb2ludGVyTGlzdENyZWF0ZSgyMCk7CisgICAgaWYgKHJldC0+dG1wTGlzdCA9PSBOVUxMKSB7CisJZ290byBpbnRlcm5hbF9lcnI7CisgICAgfQorI2lmZGVmIFhTTFRfUkVGQUNUT1JFRF9YUEFUSENPTVAKKyAgICAvKgorICAgICogQ3JlYXRlIHRoZSBYUGF0aCBjb21waWxhdGlvbiBjb250ZXh0IGluIG9yZGVyCisgICAgKiB0byBzcGVlZCB1cCBwcmVjb21waWxhdGlvbiBvZiBYUGF0aCBleHByZXNzaW9ucy4KKyAgICAqLworICAgIHJldC0+eHBhdGhDdHh0ID0geG1sWFBhdGhOZXdDb250ZXh0KE5VTEwpOworICAgIGlmIChyZXQtPnhwYXRoQ3R4dCA9PSBOVUxMKQorCWdvdG8gaW50ZXJuYWxfZXJyOworI2VuZGlmCisgICAgCisgICAgcmV0dXJuKHJldCk7CisKK2ludGVybmFsX2VycjoKKyAgICB4c2x0Q29tcGlsYXRpb25DdHh0RnJlZShyZXQpOworICAgIHJldHVybihOVUxMKTsKK30KKworc3RhdGljIHZvaWQKK3hzbHRMUkVFZmZlY3RpdmVOc05vZGVzRnJlZSh4c2x0RWZmZWN0aXZlTnNQdHIgZmlyc3QpCit7CisgICAgeHNsdEVmZmVjdGl2ZU5zUHRyIHRtcDsKKworICAgIHdoaWxlIChmaXJzdCAhPSBOVUxMKSB7CisJdG1wID0gZmlyc3Q7CisJZmlyc3QgPSBmaXJzdC0+bmV4dEluU3RvcmU7CisJeG1sRnJlZSh0bXApOworICAgIH0KK30KKworc3RhdGljIHZvaWQKK3hzbHRGcmVlUHJpbmNpcGFsU3R5bGVzaGVldERhdGEoeHNsdFByaW5jaXBhbFN0eWxlc2hlZXREYXRhUHRyIGRhdGEpCit7CisgICAgaWYgKGRhdGEgPT0gTlVMTCkKKwlyZXR1cm47CisKKyAgICBpZiAoZGF0YS0+aW5TY29wZU5hbWVzcGFjZXMgIT0gTlVMTCkgeworCWludCBpOworCXhzbHROc0xpc3RDb250YWluZXJQdHIgbnNpOworCXhzbHRQb2ludGVyTGlzdFB0ciBsaXN0ID0KKwkgICAgKHhzbHRQb2ludGVyTGlzdFB0cikgZGF0YS0+aW5TY29wZU5hbWVzcGFjZXM7CisKKwlmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bnVtYmVyOyBpKyspIHsKKwkgICAgLyoKKwkgICAgKiBSRVZJU0lUIFRPRE86IEZyZWUgaW5mbyBvZiBpbi1zY29wZSBuYW1lc3BhY2VzLgorCSAgICAqLworCSAgICBuc2kgPSAoeHNsdE5zTGlzdENvbnRhaW5lclB0cikgbGlzdC0+aXRlbXNbaV07CisJICAgIGlmIChuc2ktPmxpc3QgIT0gTlVMTCkKKwkJeG1sRnJlZShuc2ktPmxpc3QpOworCSAgICB4bWxGcmVlKG5zaSk7CisJfQorCXhzbHRQb2ludGVyTGlzdEZyZWUobGlzdCk7CisJZGF0YS0+aW5TY29wZU5hbWVzcGFjZXMgPSBOVUxMOworICAgIH0KKworICAgIGlmIChkYXRhLT5leGNsUmVzdWx0TmFtZXNwYWNlcyAhPSBOVUxMKSB7CisJaW50IGk7CisJeHNsdFBvaW50ZXJMaXN0UHRyIGxpc3QgPSAoeHNsdFBvaW50ZXJMaXN0UHRyKQorCSAgICBkYXRhLT5leGNsUmVzdWx0TmFtZXNwYWNlczsJCisJCisJZm9yIChpID0gMDsgaSA8IGxpc3QtPm51bWJlcjsgaSsrKQorCSAgICB4c2x0UG9pbnRlckxpc3RGcmVlKCh4c2x0UG9pbnRlckxpc3RQdHIpIGxpc3QtPml0ZW1zW2ldKTsKKwkKKwl4c2x0UG9pbnRlckxpc3RGcmVlKGxpc3QpOworCWRhdGEtPmV4Y2xSZXN1bHROYW1lc3BhY2VzID0gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoZGF0YS0+ZXh0RWxlbU5hbWVzcGFjZXMgIT0gTlVMTCkgeworCXhzbHRQb2ludGVyTGlzdFB0ciBsaXN0ID0gKHhzbHRQb2ludGVyTGlzdFB0cikKKwkgICAgZGF0YS0+ZXh0RWxlbU5hbWVzcGFjZXM7CisJaW50IGk7CisKKwlmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bnVtYmVyOyBpKyspCisJICAgIHhzbHRQb2ludGVyTGlzdEZyZWUoKHhzbHRQb2ludGVyTGlzdFB0cikgbGlzdC0+aXRlbXNbaV0pOworCisJeHNsdFBvaW50ZXJMaXN0RnJlZShsaXN0KTsKKwlkYXRhLT5leHRFbGVtTmFtZXNwYWNlcyA9IE5VTEw7CisgICAgfQorICAgIGlmIChkYXRhLT5lZmZlY3RpdmVOcykgeworCXhzbHRMUkVFZmZlY3RpdmVOc05vZGVzRnJlZShkYXRhLT5lZmZlY3RpdmVOcyk7CisJZGF0YS0+ZWZmZWN0aXZlTnMgPSBOVUxMOworICAgIH0KKyNpZmRlZiBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAKKyAgICB4c2x0RnJlZU5hbWVzcGFjZU1hcChkYXRhLT5uc01hcCk7CisjZW5kaWYKKyAgICB4bWxGcmVlKGRhdGEpOworfQorCitzdGF0aWMgeHNsdFByaW5jaXBhbFN0eWxlc2hlZXREYXRhUHRyCit4c2x0TmV3UHJpbmNpcGFsU3R5bGVzaGVldERhdGEodm9pZCkKK3sKKyAgICB4c2x0UHJpbmNpcGFsU3R5bGVzaGVldERhdGFQdHIgcmV0OworCisgICAgcmV0ID0gKHhzbHRQcmluY2lwYWxTdHlsZXNoZWV0RGF0YVB0cikKKwl4bWxNYWxsb2Moc2l6ZW9mKHhzbHRQcmluY2lwYWxTdHlsZXNoZWV0RGF0YSkpOworICAgIGlmIChyZXQgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCSAgICAieHNsdE5ld1ByaW5jaXBhbFN0eWxlc2hlZXREYXRhOiBtZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQuXG4iKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4c2x0UHJpbmNpcGFsU3R5bGVzaGVldERhdGEpKTsKKyAgICAKKyAgICAvKgorICAgICogR2xvYmFsIGxpc3Qgb2YgaW4tc2NvcGUgbmFtZXNwYWNlcy4KKyAgICAqLyAgICAKKyAgICByZXQtPmluU2NvcGVOYW1lc3BhY2VzID0geHNsdFBvaW50ZXJMaXN0Q3JlYXRlKC0xKTsKKyAgICBpZiAocmV0LT5pblNjb3BlTmFtZXNwYWNlcyA9PSBOVUxMKQorCWdvdG8gaW50ZXJuYWxfZXJyOworICAgIC8qCisgICAgKiBHbG9iYWwgbGlzdCBvZiBleGNsdWRlZCByZXN1bHQgbnMtZGVjbHMuCisgICAgKi8KKyAgICByZXQtPmV4Y2xSZXN1bHROYW1lc3BhY2VzID0geHNsdFBvaW50ZXJMaXN0Q3JlYXRlKC0xKTsKKyAgICBpZiAocmV0LT5leGNsUmVzdWx0TmFtZXNwYWNlcyA9PSBOVUxMKQorCWdvdG8gaW50ZXJuYWxfZXJyOworICAgIC8qCisgICAgKiBHbG9iYWwgbGlzdCBvZiBleHRlbnNpb24gaW5zdHJ1Y3Rpb24gbmFtZXNwYWNlIG5hbWVzLgorICAgICovICAgIAorICAgIHJldC0+ZXh0RWxlbU5hbWVzcGFjZXMgPSB4c2x0UG9pbnRlckxpc3RDcmVhdGUoLTEpOworICAgIGlmIChyZXQtPmV4dEVsZW1OYW1lc3BhY2VzID09IE5VTEwpCisJZ290byBpbnRlcm5hbF9lcnI7CisKKyAgICByZXR1cm4ocmV0KTsKKworaW50ZXJuYWxfZXJyOgorCisgICAgcmV0dXJuKE5VTEwpOworfQorCisjZW5kaWYKKworLyoqCisgKiB4c2x0TmV3U3R5bGVzaGVldDoKKyAqCisgKiBDcmVhdGUgYSBuZXcgWFNMVCBTdHlsZXNoZWV0CisgKgorICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHhzbHRTdHlsZXNoZWV0UHRyIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgorICovCit4c2x0U3R5bGVzaGVldFB0cgoreHNsdE5ld1N0eWxlc2hlZXQodm9pZCkgeworICAgIHhzbHRTdHlsZXNoZWV0UHRyIHJldCA9IE5VTEw7ICAgIAorCisgICAgcmV0ID0gKHhzbHRTdHlsZXNoZWV0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhzbHRTdHlsZXNoZWV0KSk7CisgICAgaWYgKHJldCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJCSJ4c2x0TmV3U3R5bGVzaGVldCA6IG1hbGxvYyBmYWlsZWRcbiIpOworCWdvdG8gaW50ZXJuYWxfZXJyOworICAgIH0KKyAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeHNsdFN0eWxlc2hlZXQpKTsKKworICAgIHJldC0+b21pdFhtbERlY2xhcmF0aW9uID0gLTE7CisgICAgcmV0LT5zdGFuZGFsb25lID0gLTE7CisgICAgcmV0LT5kZWNpbWFsRm9ybWF0ID0geHNsdE5ld0RlY2ltYWxGb3JtYXQoTlVMTCk7CisgICAgcmV0LT5pbmRlbnQgPSAtMTsKKyAgICByZXQtPmVycm9ycyA9IDA7CisgICAgcmV0LT53YXJuaW5ncyA9IDA7CisgICAgcmV0LT5leGNsUHJlZml4TnIgPSAwOworICAgIHJldC0+ZXhjbFByZWZpeE1heCA9IDA7CisgICAgcmV0LT5leGNsUHJlZml4VGFiID0gTlVMTDsKKyAgICByZXQtPmV4dEluZm9zID0gTlVMTDsKKyAgICByZXQtPmV4dHJhc05yID0gMDsKKyAgICByZXQtPmludGVybmFsaXplZCA9IDE7CisgICAgcmV0LT5saXRlcmFsX3Jlc3VsdCA9IDA7CisgICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOworI2lmZGVmIFdJVEhfWFNMVF9ERUJVRworICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJImNyZWF0aW5nIGRpY3Rpb25hcnkgZm9yIHN0eWxlc2hlZXRcbiIpOworI2VuZGlmCisKKyAgICB4c2x0SW5pdCgpOworCisgICAgcmV0dXJuKHJldCk7CisKK2ludGVybmFsX2VycjoKKyAgICBpZiAocmV0ICE9IE5VTEwpCisJeHNsdEZyZWVTdHlsZXNoZWV0KHJldCk7CisgICAgcmV0dXJuKE5VTEwpOworfQorCisvKioKKyAqIHhzbHRBbGxvY2F0ZUV4dHJhOgorICogQHN0eWxlOiAgYW4gWFNMVCBzdHlsZXNoZWV0CisgKgorICogQWxsb2NhdGUgYW4gZXh0cmEgcnVudGltZSBpbmZvcm1hdGlvbiBzbG90IHN0YXRpY2FsbHkgd2hpbGUgY29tcGlsaW5nCisgKiB0aGUgc3R5bGVzaGVldCBhbmQgcmV0dXJuIGl0cyBudW1iZXIKKyAqCisgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdGhlIHNsb3QKKyAqLworaW50Cit4c2x0QWxsb2NhdGVFeHRyYSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkKK3sKKyAgICByZXR1cm4oc3R5bGUtPmV4dHJhc05yKyspOworfQorCisvKioKKyAqIHhzbHRBbGxvY2F0ZUV4dHJhQ3R4dDoKKyAqIEBjdHh0OiAgYW4gWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKgorICogQWxsb2NhdGUgYW4gZXh0cmEgcnVudGltZSBpbmZvcm1hdGlvbiBzbG90IGF0IHJ1bi10aW1lCisgKiBhbmQgcmV0dXJuIGl0cyBudW1iZXIKKyAqIFRoaXMgbWFrZSBzdXJlIHRoZXJlIGlzIGEgc2xvdCByZWFkeSBpbiB0aGUgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICoKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiB0aGUgc2xvdAorICovCitpbnQKK3hzbHRBbGxvY2F0ZUV4dHJhQ3R4dCh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KQoreworICAgIGlmIChjdHh0LT5leHRyYXNOciA+PSBjdHh0LT5leHRyYXNNYXgpIHsKKwlpbnQgaTsKKwlpZiAoY3R4dC0+ZXh0cmFzTnIgPT0gMCkgeworCSAgICBjdHh0LT5leHRyYXNNYXggPSAyMDsKKwkgICAgY3R4dC0+ZXh0cmFzID0gKHhzbHRSdW50aW1lRXh0cmFQdHIpCisJCXhtbE1hbGxvYyhjdHh0LT5leHRyYXNNYXggKiBzaXplb2YoeHNsdFJ1bnRpbWVFeHRyYSkpOworCSAgICBpZiAoY3R4dC0+ZXh0cmFzID09IE5VTEwpIHsKKwkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCisJCQkieHNsdEFsbG9jYXRlRXh0cmFDdHh0OiBvdXQgb2YgbWVtb3J5XG4iKTsKKwkJY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX0VSUk9SOworCQlyZXR1cm4oMCk7CisJICAgIH0KKwkgICAgZm9yIChpID0gMDtpIDwgY3R4dC0+ZXh0cmFzTWF4O2krKykgeworCQljdHh0LT5leHRyYXNbaV0uaW5mbyA9IE5VTEw7CisJCWN0eHQtPmV4dHJhc1tpXS5kZWFsbG9jYXRlID0gTlVMTDsKKwkJY3R4dC0+ZXh0cmFzW2ldLnZhbC5wdHIgPSBOVUxMOworCSAgICB9CisKKwl9IGVsc2UgeworCSAgICB4c2x0UnVudGltZUV4dHJhUHRyIHRtcDsKKworCSAgICBjdHh0LT5leHRyYXNNYXggKz0gMTAwOworCSAgICB0bXAgPSAoeHNsdFJ1bnRpbWVFeHRyYVB0cikgeG1sUmVhbGxvYyhjdHh0LT5leHRyYXMsCisJCSAgICAgICAgICAgIGN0eHQtPmV4dHJhc01heCAqIHNpemVvZih4c2x0UnVudGltZUV4dHJhKSk7CisJICAgIGlmICh0bXAgPT0gTlVMTCkgeworCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKKwkJCSJ4c2x0QWxsb2NhdGVFeHRyYUN0eHQ6IG91dCBvZiBtZW1vcnlcbiIpOworCQljdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfRVJST1I7CisJCXJldHVybigwKTsKKwkgICAgfQorCSAgICBjdHh0LT5leHRyYXMgPSB0bXA7CisJICAgIGZvciAoaSA9IGN0eHQtPmV4dHJhc05yO2kgPCBjdHh0LT5leHRyYXNNYXg7aSsrKSB7CisJCWN0eHQtPmV4dHJhc1tpXS5pbmZvID0gTlVMTDsKKwkJY3R4dC0+ZXh0cmFzW2ldLmRlYWxsb2NhdGUgPSBOVUxMOworCQljdHh0LT5leHRyYXNbaV0udmFsLnB0ciA9IE5VTEw7CisJICAgIH0KKwl9CisgICAgfQorICAgIHJldHVybihjdHh0LT5leHRyYXNOcisrKTsKK30KKworLyoqCisgKiB4c2x0RnJlZVN0eWxlc2hlZXRMaXN0OgorICogQHN0eWxlOiAgYW4gWFNMVCBzdHlsZXNoZWV0IGxpc3QKKyAqCisgKiBGcmVlIHVwIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGJ5IHRoZSBsaXN0IEBzdHlsZQorICovCitzdGF0aWMgdm9pZAoreHNsdEZyZWVTdHlsZXNoZWV0TGlzdCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkgeworICAgIHhzbHRTdHlsZXNoZWV0UHRyIG5leHQ7CisKKyAgICB3aGlsZSAoc3R5bGUgIT0gTlVMTCkgeworCW5leHQgPSBzdHlsZS0+bmV4dDsKKwl4c2x0RnJlZVN0eWxlc2hlZXQoc3R5bGUpOworCXN0eWxlID0gbmV4dDsKKyAgICB9Cit9CisKKy8qKgorICogeHNsdENsZWFudXBTdHlsZXNoZWV0VHJlZToKKyAqCisgKiBAZG9jOiB0aGUgZG9jdW1lbnQtbm9kZQorICogQG5vZGU6IHRoZSBlbGVtZW50IHdoZXJlIHRoZSBzdHlsZXNoZWV0IGlzIHJvb3RlZCBhdAorICoKKyAqIEFjdHVhbGx5IEBub2RlIG5lZWQgbm90IGJlIHRoZSBkb2N1bWVudC1lbGVtZW50LCBidXQKKyAqIGN1cnJlbnRseSBMaWJ4c2x0IGRvZXMgbm90IHN1cHBvcnQgZW1iZWRkZWQgc3R5bGVzaGVldHMuCisgKgorICogUmV0dXJucyAwIGlmIE9LLCAtMSBvbiBBUEkgb3IgaW50ZXJuYWwgZXJyb3JzLgorICovCitzdGF0aWMgaW50Cit4c2x0Q2xlYW51cFN0eWxlc2hlZXRUcmVlKHhtbERvY1B0ciBkb2MgQVRUUklCVVRFX1VOVVNFRCwKKwkJCSAgeG1sTm9kZVB0ciByb290RWxlbSBBVFRSSUJVVEVfVU5VU0VEKQoreyAgICAKKyNpZiAwIC8qIFRPRE86IEN1cnJlbnRseSBkaXNhYmxlZCwgc2luY2UgcHJvYmFibHkgbm90IG5lZWRlZC4gKi8KKyAgICB4bWxOb2RlUHRyIGN1cjsKKworICAgIGlmICgoZG9jID09IE5VTEwpIHx8IChyb290RWxlbSA9PSBOVUxMKSB8fAorCShyb290RWxlbS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSB8fAorCShkb2MgIT0gcm9vdEVsZW0tPmRvYykpCisJcmV0dXJuKC0xKTsKKworICAgIC8qCisgICAgKiBDbGVhbnVwIHdhcyBzdWdnZXN0ZWQgYnkgQWxla3NleSBTYW5pbjoKKyAgICAqIENsZWFyIHRoZSBQU1ZJIGZpZWxkIHRvIGF2b2lkIHByb2JsZW1zIGlmIHRoZQorICAgICogbm9kZS10cmVlIG9mIHRoZSBzdHlsZXNoZWV0IGlzIGludGVuZGVkIHRvIGJlIHVzZWQgZm9yCisgICAgKiBmdXJ0aGVyIHByb2Nlc3NpbmcgYnkgdGhlIHVzZXIgKGUuZy4gZm9yIGNvbXBpbGluZyBpdAorICAgICogb25jZSBhZ2FpbiAtIGFsdGhvdWdoIG5vdCByZWNvbW1lbmRlZCkuCisgICAgKi8KKworICAgIGN1ciA9IHJvb3RFbGVtOworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCWlmIChjdXItPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgeworCSAgICAvKgorCSAgICAqIENsZWFyIHRoZSBQU1ZJIGZpZWxkLgorCSAgICAqLworCSAgICBjdXItPnBzdmkgPSBOVUxMOworCSAgICBpZiAoY3VyLT5jaGlsZHJlbikgeworCQljdXIgPSBjdXItPmNoaWxkcmVuOworCQljb250aW51ZTsKKwkgICAgfQorCX0KKworbGVhdmVfbm9kZToKKwlpZiAoY3VyID09IHJvb3RFbGVtKQorCSAgICBicmVhazsKKwlpZiAoY3VyLT5uZXh0ICE9IE5VTEwpCisJICAgIGN1ciA9IGN1ci0+bmV4dDsKKwllbHNlIHsKKwkgICAgY3VyID0gY3VyLT5wYXJlbnQ7CisJICAgIGlmIChjdXIgPT0gTlVMTCkKKwkJYnJlYWs7CisJICAgIGdvdG8gbGVhdmVfbm9kZTsKKwl9CisgICAgfQorI2VuZGlmIC8qICNpZiAwICovCisgICAgcmV0dXJuKDApOworfQorCisvKioKKyAqIHhzbHRGcmVlU3R5bGVzaGVldDoKKyAqIEBzdHlsZTogIGFuIFhTTFQgc3R5bGVzaGVldAorICoKKyAqIEZyZWUgdXAgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgYnkgQHN0eWxlCisgKi8KK3ZvaWQKK3hzbHRGcmVlU3R5bGVzaGVldCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkKK3sKKyAgICBpZiAoc3R5bGUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworICAgIAorI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIC8qCisgICAgKiBTdGFydCB3aXRoIGEgY2xlYW51cCBvZiB0aGUgbWFpbiBzdHlsZXNoZWV0J3MgZG9jLgorICAgICovCisgICAgaWYgKChzdHlsZS0+cHJpbmNpcGFsID09IHN0eWxlKSAmJiAoc3R5bGUtPmRvYykpCisJeHNsdENsZWFudXBTdHlsZXNoZWV0VHJlZShzdHlsZS0+ZG9jLAorCSAgICB4bWxEb2NHZXRSb290RWxlbWVudChzdHlsZS0+ZG9jKSk7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVEX1hTTFRfTlNDT01QCisgICAgLyoKKyAgICAqIFJlc3RvcmUgY2hhbmdlZCBucy1kZWNscyBiZWZvcmUgZnJlZWluZyB0aGUgZG9jdW1lbnQuCisgICAgKi8KKyAgICBpZiAoKHN0eWxlLT5kb2MgIT0gTlVMTCkgJiYKKwlYU0xUX0hBU19JTlRFUk5BTF9OU01BUChzdHlsZSkpCisgICAgeworCXhzbHRSZXN0b3JlRG9jdW1lbnROYW1lc3BhY2VzKFhTTFRfR0VUX0lOVEVSTkFMX05TTUFQKHN0eWxlKSwKKwkgICAgc3R5bGUtPmRvYyk7CQorICAgIH0KKyNlbmRpZiAvKiBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAgKi8KKyNlbHNlCisgICAgLyoKKyAgICAqIFN0YXJ0IHdpdGggYSBjbGVhbnVwIG9mIHRoZSBtYWluIHN0eWxlc2hlZXQncyBkb2MuCisgICAgKi8KKyAgICBpZiAoKHN0eWxlLT5wYXJlbnQgPT0gTlVMTCkgJiYgKHN0eWxlLT5kb2MpKQorCXhzbHRDbGVhbnVwU3R5bGVzaGVldFRyZWUoc3R5bGUtPmRvYywKKwkgICAgeG1sRG9jR2V0Um9vdEVsZW1lbnQoc3R5bGUtPmRvYykpOworI2VuZGlmIC8qIFhTTFRfUkVGQUNUT1JFRCAqLworCisgICAgeHNsdEZyZWVLZXlzKHN0eWxlKTsKKyAgICB4c2x0RnJlZUV4dHMoc3R5bGUpOworICAgIHhzbHRGcmVlVGVtcGxhdGVIYXNoZXMoc3R5bGUpOworICAgIHhzbHRGcmVlRGVjaW1hbEZvcm1hdExpc3Qoc3R5bGUpOworICAgIHhzbHRGcmVlVGVtcGxhdGVMaXN0KHN0eWxlLT50ZW1wbGF0ZXMpOworICAgIHhzbHRGcmVlQXR0cmlidXRlU2V0c0hhc2hlcyhzdHlsZSk7CisgICAgeHNsdEZyZWVOYW1lc3BhY2VBbGlhc0hhc2hlcyhzdHlsZSk7CisgICAgeHNsdEZyZWVTdHlsZVByZUNvbXBzKHN0eWxlKTsKKyAgICAvKgorICAgICogRnJlZSBkb2N1bWVudHMgb2YgYWxsIGluY2x1ZGVkIHN0eWxzaGVldCBtb2R1bGVzIG9mIHRoaXMKKyAgICAqIHN0eWxlc2hlZXQgbGV2ZWwuCisgICAgKi8KKyAgICB4c2x0RnJlZVN0eWxlRG9jdW1lbnRzKHN0eWxlKTsKKyAgICAvKgorICAgICogVE9ETzogQmVzdCB0aW1lIHRvIHNodXRkb3duIGV4dGVuc2lvbiBzdHVmZj8KKyAgICAqLworICAgIHhzbHRTaHV0ZG93bkV4dHMoc3R5bGUpOworICAgICAgIAorICAgIGlmIChzdHlsZS0+dmFyaWFibGVzICE9IE5VTEwpCisgICAgICAgIHhzbHRGcmVlU3RhY2tFbGVtTGlzdChzdHlsZS0+dmFyaWFibGVzKTsKKyAgICBpZiAoc3R5bGUtPmNkYXRhU2VjdGlvbiAhPSBOVUxMKQorICAgICAgICB4bWxIYXNoRnJlZShzdHlsZS0+Y2RhdGFTZWN0aW9uLCBOVUxMKTsKKyAgICBpZiAoc3R5bGUtPnN0cmlwU3BhY2VzICE9IE5VTEwpCisgICAgICAgIHhtbEhhc2hGcmVlKHN0eWxlLT5zdHJpcFNwYWNlcywgTlVMTCk7CisgICAgaWYgKHN0eWxlLT5uc0hhc2ggIT0gTlVMTCkKKyAgICAgICAgeG1sSGFzaEZyZWUoc3R5bGUtPm5zSGFzaCwgTlVMTCk7CisgICAgaWYgKHN0eWxlLT5leGNsUHJlZml4VGFiICE9IE5VTEwpCisgICAgICAgIHhtbEZyZWUoc3R5bGUtPmV4Y2xQcmVmaXhUYWIpOworICAgIGlmIChzdHlsZS0+bWV0aG9kICE9IE5VTEwpCisgICAgICAgIHhtbEZyZWUoc3R5bGUtPm1ldGhvZCk7CisgICAgaWYgKHN0eWxlLT5tZXRob2RVUkkgIT0gTlVMTCkKKyAgICAgICAgeG1sRnJlZShzdHlsZS0+bWV0aG9kVVJJKTsKKyAgICBpZiAoc3R5bGUtPnZlcnNpb24gIT0gTlVMTCkKKyAgICAgICAgeG1sRnJlZShzdHlsZS0+dmVyc2lvbik7CisgICAgaWYgKHN0eWxlLT5lbmNvZGluZyAhPSBOVUxMKQorICAgICAgICB4bWxGcmVlKHN0eWxlLT5lbmNvZGluZyk7CisgICAgaWYgKHN0eWxlLT5kb2N0eXBlUHVibGljICE9IE5VTEwpCisgICAgICAgIHhtbEZyZWUoc3R5bGUtPmRvY3R5cGVQdWJsaWMpOworICAgIGlmIChzdHlsZS0+ZG9jdHlwZVN5c3RlbSAhPSBOVUxMKQorICAgICAgICB4bWxGcmVlKHN0eWxlLT5kb2N0eXBlU3lzdGVtKTsKKyAgICBpZiAoc3R5bGUtPm1lZGlhVHlwZSAhPSBOVUxMKQorICAgICAgICB4bWxGcmVlKHN0eWxlLT5tZWRpYVR5cGUpOworICAgIGlmIChzdHlsZS0+YXR0VlRzKQorICAgICAgICB4c2x0RnJlZUFWVExpc3Qoc3R5bGUtPmF0dFZUcyk7CisgICAgaWYgKHN0eWxlLT5pbXBvcnRzICE9IE5VTEwpCisgICAgICAgIHhzbHRGcmVlU3R5bGVzaGVldExpc3Qoc3R5bGUtPmltcG9ydHMpOworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgLyoKKyAgICAqIElmIHRoaXMgaXMgdGhlIHByaW5jaXBhbCBzdHlsZXNoZWV0LCB0aGVuCisgICAgKiBmcmVlIGl0cyBpbnRlcm5hbCBkYXRhLgorICAgICovCisgICAgaWYgKHN0eWxlLT5wcmluY2lwYWwgPT0gc3R5bGUpIHsKKwlpZiAoc3R5bGUtPnByaW5jaXBhbERhdGEpIHsKKwkgICAgeHNsdEZyZWVQcmluY2lwYWxTdHlsZXNoZWV0RGF0YShzdHlsZS0+cHJpbmNpcGFsRGF0YSk7CisJICAgIHN0eWxlLT5wcmluY2lwYWxEYXRhID0gTlVMTDsKKwl9CisgICAgfSAgICAKKyNlbmRpZgorICAgIC8qCisgICAgKiBCZXR0ZXIgdG8gZnJlZSB0aGUgbWFpbiBkb2N1bWVudCBvZiB0aGlzIHN0eWxlc2hlZXQgbGV2ZWwKKyAgICAqIGF0IHRoZSBlbmQgLSBzbyBoZXJlLgorICAgICovCisgICAgaWYgKHN0eWxlLT5kb2MgIT0gTlVMTCkgewkKKyAgICAgICAgeG1sRnJlZURvYyhzdHlsZS0+ZG9jKTsKKyAgICB9CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorICAgICAgICAgICAgICAgICAgICAgImZyZWVpbmcgZGljdGlvbmFyeSBmcm9tIHN0eWxlc2hlZXRcbiIpOworI2VuZGlmCisgICAgeG1sRGljdEZyZWUoc3R5bGUtPmRpY3QpOworCisgICAgbWVtc2V0KHN0eWxlLCAtMSwgc2l6ZW9mKHhzbHRTdHlsZXNoZWV0KSk7CisgICAgeG1sRnJlZShzdHlsZSk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICoJCVBhcnNpbmcgb2YgYW4gWFNMVCBTdHlsZXNoZWV0CQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIC8qCisgICAgKiBUaGlzIGlzIG5vdyBwZXJmb3JtZWQgaW4gYW4gb3B0aW1pemVkIHdheSBpbiB4c2x0UGFyc2VYU0xUVGVtcGxhdGUuCisgICAgKi8KKyNlbHNlCisvKioKKyAqIHhzbHRHZXRJbmhlcml0ZWROc0xpc3Q6CisgKiBAc3R5bGU6ICB0aGUgc3R5bGVzaGVldAorICogQHRlbXBsYXRlOiB0aGUgdGVtcGxhdGUKKyAqIEBub2RlOiAgdGhlIGN1cnJlbnQgbm9kZQorICoKKyAqIFNlYXJjaCBhbGwgdGhlIG5hbWVzcGFjZSBhcHBseWluZyB0byBhIGdpdmVuIGVsZW1lbnQgZXhjZXB0IHRoZSBvbmVzIAorICogZnJvbSBleGNsdWRlZCBvdXRwdXQgcHJlZml4ZXMgY3VycmVudGx5IGluIHNjb3BlLiBJbml0aWFsaXplIHRoZQorICogdGVtcGxhdGUgaW5oZXJpdGVkTnMgbGlzdCB3aXRoIGl0LgorICoKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbnRyaWVzIGZvdW5kCisgKi8KK3N0YXRpYyBpbnQKK3hzbHRHZXRJbmhlcml0ZWROc0xpc3QoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJICAgICAgICAgICAgICAgeHNsdFRlbXBsYXRlUHRyIHRlbXBsYXRlLAorCSAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKK3sKKyAgICB4bWxOc1B0ciBjdXI7CisgICAgeG1sTnNQdHIgKnJldCA9IE5VTEw7CisgICAgaW50IG5ibnMgPSAwOworICAgIGludCBtYXhucyA9IDEwOworICAgIGludCBpOyAgICAKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKHRlbXBsYXRlID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpIHx8CisJKHRlbXBsYXRlLT5pbmhlcml0ZWROc05yICE9IDApIHx8ICh0ZW1wbGF0ZS0+aW5oZXJpdGVkTnMgIT0gTlVMTCkpCisJcmV0dXJuKDApOworICAgIHdoaWxlIChub2RlICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgeworICAgICAgICAgICAgY3VyID0gbm9kZS0+bnNEZWY7CisgICAgICAgICAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKKwkJaWYgKHhtbFN0ckVxdWFsKGN1ci0+aHJlZiwgWFNMVF9OQU1FU1BBQ0UpKQorCQkgICAgZ290byBza2lwX25zOworCisJCWlmICgoY3VyLT5wcmVmaXggIT0gTlVMTCkgJiYKKwkJICAgICh4c2x0Q2hlY2tFeHRQcmVmaXgoc3R5bGUsIGN1ci0+cHJlZml4KSkpCisJCSAgICBnb3RvIHNraXBfbnM7CisJCS8qCisJCSogQ2hlY2sgaWYgdGhpcyBuYW1lc3BhY2Ugd2FzIGV4Y2x1ZGVkLgorCQkqIE5vdGUgdGhhdCBhdCB0aGlzIHBvaW50IG9ubHkgdGhlIGV4Y2x1c2lvbnMgZGVmaW5lZAorCQkqIG9uIHRoZSB0b3Btb3N0IHN0eWxlc2hlZXQgZWxlbWVudCBhcmUgaW4gdGhlIGV4Y2x1c2lvbi1saXN0LgorCQkqLworCQlmb3IgKGkgPSAwO2kgPCBzdHlsZS0+ZXhjbFByZWZpeE5yO2krKykgeworCQkgICAgaWYgKHhtbFN0ckVxdWFsKGN1ci0+aHJlZiwgc3R5bGUtPmV4Y2xQcmVmaXhUYWJbaV0pKQorCQkJZ290byBza2lwX25zOworCQl9CisgICAgICAgICAgICAgICAgaWYgKHJldCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIHJldCA9CisgICAgICAgICAgICAgICAgICAgICAgICAoeG1sTnNQdHIgKikgeG1sTWFsbG9jKChtYXhucyArIDEpICoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHhtbE5zUHRyKSk7CisgICAgICAgICAgICAgICAgICAgIGlmIChyZXQgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInhzbHRHZXRJbmhlcml0ZWROc0xpc3QgOiBvdXQgb2YgbWVtb3J5IVxuIik7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4oMCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0W25ibnNdID0gTlVMTDsKKyAgICAgICAgICAgICAgICB9CisJCS8qCisJCSogU2tpcCBzaGFkb3dlZCBuYW1lc3BhY2UgYmluZGluZ3MuCisJCSovCisgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG5ibnM7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBpZiAoKGN1ci0+cHJlZml4ID09IHJldFtpXS0+cHJlZml4KSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgKHhtbFN0ckVxdWFsKGN1ci0+cHJlZml4LCByZXRbaV0tPnByZWZpeCkpKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChpID49IG5ibnMpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5ibnMgPj0gbWF4bnMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1heG5zICo9IDI7CisgICAgICAgICAgICAgICAgICAgICAgICByZXQgPSAoeG1sTnNQdHIgKikgeG1sUmVhbGxvYyhyZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobWF4bnMgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEpICoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih4bWxOc1B0cikpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJldCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ4c2x0R2V0SW5oZXJpdGVkTnNMaXN0IDogcmVhbGxvYyBmYWlsZWQhXG4iKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4oMCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0W25ibnMrK10gPSBjdXI7CisgICAgICAgICAgICAgICAgICAgIHJldFtuYm5zXSA9IE5VTEw7CisgICAgICAgICAgICAgICAgfQorc2tpcF9uczoKKyAgICAgICAgICAgICAgICBjdXIgPSBjdXItPm5leHQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgbm9kZSA9IG5vZGUtPnBhcmVudDsKKyAgICB9CisgICAgaWYgKG5ibnMgIT0gMCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisgICAgICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgInRlbXBsYXRlIGhhcyAlZCBpbmhlcml0ZWQgbmFtZXNwYWNlc1xuIiwgbmJucyk7CisjZW5kaWYKKwl0ZW1wbGF0ZS0+aW5oZXJpdGVkTnNOciA9IG5ibnM7CisJdGVtcGxhdGUtPmluaGVyaXRlZE5zID0gcmV0OworICAgIH0KKyAgICByZXR1cm4gKG5ibnMpOworfQorI2VuZGlmIC8qIGVsc2Ugb2YgWFNMVF9SRUZBQ1RPUkVEICovCisKKy8qKgorICogeHNsdFBhcnNlU3R5bGVzaGVldE91dHB1dDoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBjdXI6ICB0aGUgIm91dHB1dCIgZWxlbWVudAorICoKKyAqIHBhcnNlIGFuIFhTTFQgc3R5bGVzaGVldCBvdXRwdXQgZWxlbWVudCBhbmQgcmVjb3JkCisgKiBpbmZvcm1hdGlvbiByZWxhdGVkIHRvIHRoZSBzdHlsZXNoZWV0IG91dHB1dAorICovCisKK3ZvaWQKK3hzbHRQYXJzZVN0eWxlc2hlZXRPdXRwdXQoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgY3VyKQoreworICAgIHhtbENoYXIgKmVsZW1lbnRzLAorICAgICAqcHJvcDsKKyAgICB4bWxDaGFyICplbGVtZW50LAorICAgICAqZW5kOworCisgICAgaWYgKChjdXIgPT0gTlVMTCkgfHwgKHN0eWxlID09IE5VTEwpKQorICAgICAgICByZXR1cm47CisgICAKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikgInZlcnNpb24iLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisgICAgICAgIGlmIChzdHlsZS0+dmVyc2lvbiAhPSBOVUxMKQorICAgICAgICAgICAgeG1sRnJlZShzdHlsZS0+dmVyc2lvbik7CisgICAgICAgIHN0eWxlLT52ZXJzaW9uID0gcHJvcDsKKyAgICB9CisKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikgImVuY29kaW5nIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworICAgICAgICBpZiAoc3R5bGUtPmVuY29kaW5nICE9IE5VTEwpCisgICAgICAgICAgICB4bWxGcmVlKHN0eWxlLT5lbmNvZGluZyk7CisgICAgICAgIHN0eWxlLT5lbmNvZGluZyA9IHByb3A7CisgICAgfQorCisgICAgLyogcmVsYXhlZCB0byBzdXBwb3J0IHh0OmRvY3VtZW50CisgICAgKiBUT0RPIEtCOiBXaGF0IGRvZXMgInJlbGF4ZWQgdG8gc3VwcG9ydCB4dDpkb2N1bWVudCIgbWVhbj8KKyAgICAqLworICAgIHByb3AgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSAibWV0aG9kIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworICAgICAgICBjb25zdCB4bWxDaGFyICpVUkk7CisKKyAgICAgICAgaWYgKHN0eWxlLT5tZXRob2QgIT0gTlVMTCkKKyAgICAgICAgICAgIHhtbEZyZWUoc3R5bGUtPm1ldGhvZCk7CisgICAgICAgIHN0eWxlLT5tZXRob2QgPSBOVUxMOworICAgICAgICBpZiAoc3R5bGUtPm1ldGhvZFVSSSAhPSBOVUxMKQorICAgICAgICAgICAgeG1sRnJlZShzdHlsZS0+bWV0aG9kVVJJKTsKKyAgICAgICAgc3R5bGUtPm1ldGhvZFVSSSA9IE5VTEw7CisKKwkvKgorCSogVE9ETzogRG9uJ3QgdXNlIHhzbHRHZXRRTmFtZVVSSSgpLgorCSovCisJVVJJID0geHNsdEdldFFOYW1lVVJJKGN1ciwgJnByb3ApOworCWlmIChwcm9wID09IE5VTEwpIHsKKwkgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKwl9IGVsc2UgaWYgKFVSSSA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJ4bWwiKSkgfHwKKyAgICAgICAgICAgICAgICAoeG1sU3RyRXF1YWwocHJvcCwgKGNvbnN0IHhtbENoYXIgKikgImh0bWwiKSkgfHwKKyAgICAgICAgICAgICAgICAoeG1sU3RyRXF1YWwocHJvcCwgKGNvbnN0IHhtbENoYXIgKikgInRleHQiKSkpIHsKKyAgICAgICAgICAgICAgICBzdHlsZS0+bWV0aG9kID0gcHJvcDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgdmFsdWUgZm9yIG1ldGhvZDogJXNcbiIsIHByb3ApOworICAgICAgICAgICAgICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKyAgICAgICAgICAgIH0KKwl9IGVsc2UgeworCSAgICBzdHlsZS0+bWV0aG9kID0gcHJvcDsKKwkgICAgc3R5bGUtPm1ldGhvZFVSSSA9IHhtbFN0cmR1cChVUkkpOworCX0KKyAgICB9CisKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikgImRvY3R5cGUtc3lzdGVtIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworICAgICAgICBpZiAoc3R5bGUtPmRvY3R5cGVTeXN0ZW0gIT0gTlVMTCkKKyAgICAgICAgICAgIHhtbEZyZWUoc3R5bGUtPmRvY3R5cGVTeXN0ZW0pOworICAgICAgICBzdHlsZS0+ZG9jdHlwZVN5c3RlbSA9IHByb3A7CisgICAgfQorCisgICAgcHJvcCA9IHhtbEdldE5zUHJvcChjdXIsIChjb25zdCB4bWxDaGFyICopICJkb2N0eXBlLXB1YmxpYyIsIE5VTEwpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKHN0eWxlLT5kb2N0eXBlUHVibGljICE9IE5VTEwpCisgICAgICAgICAgICB4bWxGcmVlKHN0eWxlLT5kb2N0eXBlUHVibGljKTsKKyAgICAgICAgc3R5bGUtPmRvY3R5cGVQdWJsaWMgPSBwcm9wOworICAgIH0KKworICAgIHByb3AgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSAic3RhbmRhbG9uZSIsIE5VTEwpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJ5ZXMiKSkgeworICAgICAgICAgICAgc3R5bGUtPnN0YW5kYWxvbmUgPSAxOworICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJubyIpKSB7CisgICAgICAgICAgICBzdHlsZS0+c3RhbmRhbG9uZSA9IDA7CisgICAgICAgIH0gZWxzZSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCB2YWx1ZSBmb3Igc3RhbmRhbG9uZTogJXNcbiIsIHByb3ApOworICAgICAgICAgICAgc3R5bGUtPmVycm9ycysrOworICAgICAgICB9CisgICAgICAgIHhtbEZyZWUocHJvcCk7CisgICAgfQorCisgICAgcHJvcCA9IHhtbEdldE5zUHJvcChjdXIsIChjb25zdCB4bWxDaGFyICopICJpbmRlbnQiLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisgICAgICAgIGlmICh4bWxTdHJFcXVhbChwcm9wLCAoY29uc3QgeG1sQ2hhciAqKSAieWVzIikpIHsKKyAgICAgICAgICAgIHN0eWxlLT5pbmRlbnQgPSAxOworICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJubyIpKSB7CisgICAgICAgICAgICBzdHlsZS0+aW5kZW50ID0gMDsKKyAgICAgICAgfSBlbHNlIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIHZhbHVlIGZvciBpbmRlbnQ6ICVzXG4iLCBwcm9wKTsKKyAgICAgICAgICAgIHN0eWxlLT5lcnJvcnMrKzsKKyAgICAgICAgfQorICAgICAgICB4bWxGcmVlKHByb3ApOworICAgIH0KKworICAgIHByb3AgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSAib21pdC14bWwtZGVjbGFyYXRpb24iLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisgICAgICAgIGlmICh4bWxTdHJFcXVhbChwcm9wLCAoY29uc3QgeG1sQ2hhciAqKSAieWVzIikpIHsKKyAgICAgICAgICAgIHN0eWxlLT5vbWl0WG1sRGVjbGFyYXRpb24gPSAxOworICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopICJubyIpKSB7CisgICAgICAgICAgICBzdHlsZS0+b21pdFhtbERlY2xhcmF0aW9uID0gMDsKKyAgICAgICAgfSBlbHNlIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIHZhbHVlIGZvciBvbWl0LXhtbC1kZWNsYXJhdGlvbjogJXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ApOworICAgICAgICAgICAgc3R5bGUtPmVycm9ycysrOworICAgICAgICB9CisgICAgICAgIHhtbEZyZWUocHJvcCk7CisgICAgfQorCisgICAgZWxlbWVudHMgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSAiY2RhdGEtc2VjdGlvbi1lbGVtZW50cyIsCisJTlVMTCk7CisgICAgaWYgKGVsZW1lbnRzICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKHN0eWxlLT5jZGF0YVNlY3Rpb24gPT0gTlVMTCkKKyAgICAgICAgICAgIHN0eWxlLT5jZGF0YVNlY3Rpb24gPSB4bWxIYXNoQ3JlYXRlKDEwKTsKKyAgICAgICAgaWYgKHN0eWxlLT5jZGF0YVNlY3Rpb24gPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICBlbGVtZW50ID0gZWxlbWVudHM7CisgICAgICAgIHdoaWxlICgqZWxlbWVudCAhPSAwKSB7CisgICAgICAgICAgICB3aGlsZSAoSVNfQkxBTksoKmVsZW1lbnQpKQorICAgICAgICAgICAgICAgIGVsZW1lbnQrKzsKKyAgICAgICAgICAgIGlmICgqZWxlbWVudCA9PSAwKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZW5kID0gZWxlbWVudDsKKyAgICAgICAgICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIUlTX0JMQU5LKCplbmQpKSkKKyAgICAgICAgICAgICAgICBlbmQrKzsKKyAgICAgICAgICAgIGVsZW1lbnQgPSB4bWxTdHJuZHVwKGVsZW1lbnQsIGVuZCAtIGVsZW1lbnQpOworICAgICAgICAgICAgaWYgKGVsZW1lbnQpIHsJCQorI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisgICAgICAgICAgICAgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhZGQgY2RhdGEgc2VjdGlvbiBvdXRwdXQgZWxlbWVudCAlc1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQpOworI2VuZGlmCisJCWlmICh4bWxWYWxpZGF0ZVFOYW1lKEJBRF9DQVNUIGVsZW1lbnQsIDApICE9IDApIHsKKwkJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCQkJIkF0dHJpYnV0ZSAnY2RhdGEtc2VjdGlvbi1lbGVtZW50cyc6IFRoZSB2YWx1ZSAiCisJCQkiJyVzJyBpcyBub3QgYSB2YWxpZCBRTmFtZS5cbiIsIGVsZW1lbnQpOworCQkgICAgeG1sRnJlZShlbGVtZW50KTsKKwkJICAgIHN0eWxlLT5lcnJvcnMrKzsKKwkJfSBlbHNlIHsKKwkJICAgIGNvbnN0IHhtbENoYXIgKlVSSTsKKworCQkgICAgLyoKKwkJICAgICogVE9ETzogRG9uJ3QgdXNlIHhzbHRHZXRRTmFtZVVSSSgpLgorCQkgICAgKi8KKwkJICAgIFVSSSA9IHhzbHRHZXRRTmFtZVVSSShjdXIsICZlbGVtZW50KTsKKwkJICAgIGlmIChlbGVtZW50ID09IE5VTEwpIHsKKwkJCS8qCisJCQkqIFRPRE86IFdlJ2xsIHJlcG9ydCBhZGRpdGlvbmFsbHkgYW4gZXJyb3IKKwkJCSogIHZpYSB0aGUgc3R5bGVzaGVldCdzIGVycm9yIGhhbmRsaW5nLgkJCQorCQkJKi8KKwkJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCQkJICAgICJBdHRyaWJ1dGUgJ2NkYXRhLXNlY3Rpb24tZWxlbWVudHMnOiBUaGUgdmFsdWUgIgorCQkJICAgICInJXMnIGlzIG5vdCBhIHZhbGlkIFFOYW1lLlxuIiwgZWxlbWVudCk7CisJCQlzdHlsZS0+ZXJyb3JzKys7CisJCSAgICB9IGVsc2UgeworCQkJeG1sTnNQdHIgbnM7CisJCQkKKwkJCS8qCisJCQkqIFhTTFQtMS4wICJFYWNoIFFOYW1lIGlzIGV4cGFuZGVkIGludG8gYW4KKwkJCSogIGV4cGFuZGVkLW5hbWUgdXNpbmcgdGhlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnMgaW4KKwkJCSogIGVmZmVjdCBvbiB0aGUgeHNsOm91dHB1dCBlbGVtZW50IGluIHdoaWNoIHRoZSBRTmFtZQorCQkJKiAgb2NjdXJzOyBpZiB0aGVyZSBpcyBhIGRlZmF1bHQgbmFtZXNwYWNlLCBpdCBpcyB1c2VkCisJCQkqICBmb3IgUU5hbWVzIHRoYXQgZG8gbm90IGhhdmUgYSBwcmVmaXgiCisJCQkqIE5PVEU6IEZpeCBvZiBidWcgIzMzOTU3MC4KKwkJCSovCisJCQlpZiAoVVJJID09IE5VTEwpIHsKKwkJCSAgICBucyA9IHhtbFNlYXJjaE5zKHN0eWxlLT5kb2MsIGN1ciwgTlVMTCk7CisJCQkgICAgaWYgKG5zICE9IE5VTEwpCisJCQkJVVJJID0gbnMtPmhyZWY7CisJCQl9CQkgICAKKwkJCXhtbEhhc2hBZGRFbnRyeTIoc3R5bGUtPmNkYXRhU2VjdGlvbiwgZWxlbWVudCwgVVJJLAorCQkJICAgICh2b2lkICopICJjZGF0YSIpOworCQkJeG1sRnJlZShlbGVtZW50KTsKKwkJICAgIH0KKwkJfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxlbWVudCA9IGVuZDsKKyAgICAgICAgfQorICAgICAgICB4bWxGcmVlKGVsZW1lbnRzKTsKKyAgICB9CisKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikgIm1lZGlhLXR5cGUiLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJaWYgKHN0eWxlLT5tZWRpYVR5cGUpCisJICAgIHhtbEZyZWUoc3R5bGUtPm1lZGlhVHlwZSk7CisJc3R5bGUtPm1lZGlhVHlwZSA9IHByb3A7CisgICAgfQorICAgIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKKwl4c2x0UGFyc2VDb250ZW50RXJyb3Ioc3R5bGUsIGN1ci0+Y2hpbGRyZW4pOworICAgIH0KK30KKworLyoqCisgKiB4c2x0UGFyc2VTdHlsZXNoZWV0RGVjaW1hbEZvcm1hdDoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBjdXI6ICB0aGUgImRlY2ltYWwtZm9ybWF0IiBlbGVtZW50CisgKgorICogPCEtLSBDYXRlZ29yeTogdG9wLWxldmVsLWVsZW1lbnQgLS0+CisgKiA8eHNsOmRlY2ltYWwtZm9ybWF0CisgKiAgIG5hbWUgPSBxbmFtZSwgZGVjaW1hbC1zZXBhcmF0b3IgPSBjaGFyLCBncm91cGluZy1zZXBhcmF0b3IgPSBjaGFyLAorICogICBpbmZpbml0eSA9IHN0cmluZywgbWludXMtc2lnbiA9IGNoYXIsIE5hTiA9IHN0cmluZywgcGVyY2VudCA9IGNoYXIKKyAqICAgcGVyLW1pbGxlID0gY2hhciwgemVyby1kaWdpdCA9IGNoYXIsIGRpZ2l0ID0gY2hhciwKKyAqIHBhdHRlcm4tc2VwYXJhdG9yID0gY2hhciAvPgorICoKKyAqIHBhcnNlIGFuIFhTTFQgc3R5bGVzaGVldCBkZWNpbWFsLWZvcm1hdCBlbGVtZW50IGFuZAorICogYW5kIHJlY29yZCB0aGUgZm9ybWF0dGluZyBjaGFyYWN0ZXJpc3RpY3MKKyAqLworc3RhdGljIHZvaWQKK3hzbHRQYXJzZVN0eWxlc2hlZXREZWNpbWFsRm9ybWF0KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGN1cikKK3sKKyAgICB4bWxDaGFyICpwcm9wOworICAgIHhzbHREZWNpbWFsRm9ybWF0UHRyIGZvcm1hdDsKKyAgICB4c2x0RGVjaW1hbEZvcm1hdFB0ciBpdGVyOworICAgIAorICAgIGlmICgoY3VyID09IE5VTEwpIHx8IChzdHlsZSA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICBmb3JtYXQgPSBzdHlsZS0+ZGVjaW1hbEZvcm1hdDsKKyAgICAKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgQkFEX0NBU1QoIm5hbWUiKSwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWZvcm1hdCA9IHhzbHREZWNpbWFsRm9ybWF0R2V0QnlOYW1lKHN0eWxlLCBwcm9wKTsKKwlpZiAoZm9ybWF0ICE9IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICJ4c2x0UGFyc2VTdHlsZXN0eWxlRGVjaW1hbEZvcm1hdDogJXMgYWxyZWFkeSBleGlzdHNcbiIsIHByb3ApOworCSAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPndhcm5pbmdzKys7CisJICAgIHJldHVybjsKKwl9CisJZm9ybWF0ID0geHNsdE5ld0RlY2ltYWxGb3JtYXQocHJvcCk7CisJaWYgKGZvcm1hdCA9PSBOVUxMKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorICAgICAieHNsdFBhcnNlU3R5bGVzdHlsZURlY2ltYWxGb3JtYXQ6IGZhaWxlZCBjcmVhdGluZyBuZXcgZGVjaW1hbC1mb3JtYXRcbiIpOworCSAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPmVycm9ycysrOworCSAgICByZXR1cm47CisJfQorCS8qIEFwcGVuZCBuZXcgZGVjaW1hbC1mb3JtYXQgc3RydWN0dXJlICovCisJZm9yIChpdGVyID0gc3R5bGUtPmRlY2ltYWxGb3JtYXQ7IGl0ZXItPm5leHQ7IGl0ZXIgPSBpdGVyLT5uZXh0KQorCSAgICA7CisJaWYgKGl0ZXIpCisJICAgIGl0ZXItPm5leHQgPSBmb3JtYXQ7CisgICAgfQorCisgICAgcHJvcCA9IHhtbEdldE5zUHJvcChjdXIsIChjb25zdCB4bWxDaGFyICopImRlY2ltYWwtc2VwYXJhdG9yIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWlmIChmb3JtYXQtPmRlY2ltYWxQb2ludCAhPSBOVUxMKSB4bWxGcmVlKGZvcm1hdC0+ZGVjaW1hbFBvaW50KTsKKwlmb3JtYXQtPmRlY2ltYWxQb2ludCAgPSBwcm9wOworICAgIH0KKyAgICAKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikiZ3JvdXBpbmctc2VwYXJhdG9yIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWlmIChmb3JtYXQtPmdyb3VwaW5nICE9IE5VTEwpIHhtbEZyZWUoZm9ybWF0LT5ncm91cGluZyk7CisJZm9ybWF0LT5ncm91cGluZyAgPSBwcm9wOworICAgIH0KKworICAgIHByb3AgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSJpbmZpbml0eSIsIE5VTEwpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKwlpZiAoZm9ybWF0LT5pbmZpbml0eSAhPSBOVUxMKSB4bWxGcmVlKGZvcm1hdC0+aW5maW5pdHkpOworCWZvcm1hdC0+aW5maW5pdHkgID0gcHJvcDsKKyAgICB9CisgICAgCisgICAgcHJvcCA9IHhtbEdldE5zUHJvcChjdXIsIChjb25zdCB4bWxDaGFyICopIm1pbnVzLXNpZ24iLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJaWYgKGZvcm1hdC0+bWludXNTaWduICE9IE5VTEwpIHhtbEZyZWUoZm9ybWF0LT5taW51c1NpZ24pOworCWZvcm1hdC0+bWludXNTaWduICA9IHByb3A7CisgICAgfQorICAgIAorICAgIHByb3AgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSJOYU4iLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJaWYgKGZvcm1hdC0+bm9OdW1iZXIgIT0gTlVMTCkgeG1sRnJlZShmb3JtYXQtPm5vTnVtYmVyKTsKKwlmb3JtYXQtPm5vTnVtYmVyICA9IHByb3A7CisgICAgfQorICAgIAorICAgIHByb3AgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSJwZXJjZW50IiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWlmIChmb3JtYXQtPnBlcmNlbnQgIT0gTlVMTCkgeG1sRnJlZShmb3JtYXQtPnBlcmNlbnQpOworCWZvcm1hdC0+cGVyY2VudCAgPSBwcm9wOworICAgIH0KKyAgICAKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikicGVyLW1pbGxlIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWlmIChmb3JtYXQtPnBlcm1pbGxlICE9IE5VTEwpIHhtbEZyZWUoZm9ybWF0LT5wZXJtaWxsZSk7CisJZm9ybWF0LT5wZXJtaWxsZSAgPSBwcm9wOworICAgIH0KKyAgICAKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikiemVyby1kaWdpdCIsIE5VTEwpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKwlpZiAoZm9ybWF0LT56ZXJvRGlnaXQgIT0gTlVMTCkgeG1sRnJlZShmb3JtYXQtPnplcm9EaWdpdCk7CisJZm9ybWF0LT56ZXJvRGlnaXQgID0gcHJvcDsKKyAgICB9CisgICAgCisgICAgcHJvcCA9IHhtbEdldE5zUHJvcChjdXIsIChjb25zdCB4bWxDaGFyICopImRpZ2l0IiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCWlmIChmb3JtYXQtPmRpZ2l0ICE9IE5VTEwpIHhtbEZyZWUoZm9ybWF0LT5kaWdpdCk7CisJZm9ybWF0LT5kaWdpdCAgPSBwcm9wOworICAgIH0KKyAgICAKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikicGF0dGVybi1zZXBhcmF0b3IiLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJaWYgKGZvcm1hdC0+cGF0dGVyblNlcGFyYXRvciAhPSBOVUxMKSB4bWxGcmVlKGZvcm1hdC0+cGF0dGVyblNlcGFyYXRvcik7CisJZm9ybWF0LT5wYXR0ZXJuU2VwYXJhdG9yICA9IHByb3A7CisgICAgfQorICAgIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKKwl4c2x0UGFyc2VDb250ZW50RXJyb3Ioc3R5bGUsIGN1ci0+Y2hpbGRyZW4pOworICAgIH0KK30KKworLyoqCisgKiB4c2x0UGFyc2VTdHlsZXNoZWV0UHJlc2VydmVTcGFjZToKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEBjdXI6ICB0aGUgInByZXNlcnZlLXNwYWNlIiBlbGVtZW50CisgKgorICogcGFyc2UgYW4gWFNMVCBzdHlsZXNoZWV0IHByZXNlcnZlLXNwYWNlIGVsZW1lbnQgYW5kIHJlY29yZAorICogZWxlbWVudHMgbmVlZGluZyBwcmVzZXJ2aW5nCisgKi8KKworc3RhdGljIHZvaWQKK3hzbHRQYXJzZVN0eWxlc2hlZXRQcmVzZXJ2ZVNwYWNlKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGN1cikgeworICAgIHhtbENoYXIgKmVsZW1lbnRzOworICAgIHhtbENoYXIgKmVsZW1lbnQsICplbmQ7CisKKyAgICBpZiAoKGN1ciA9PSBOVUxMKSB8fCAoc3R5bGUgPT0gTlVMTCkpCisJcmV0dXJuOworCisgICAgZWxlbWVudHMgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSJlbGVtZW50cyIsIE5VTEwpOworICAgIGlmIChlbGVtZW50cyA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICJ4c2x0UGFyc2VTdHlsZXNoZWV0UHJlc2VydmVTcGFjZTogbWlzc2luZyBlbGVtZW50cyBhdHRyaWJ1dGVcbiIpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKwlyZXR1cm47CisgICAgfQorCisgICAgaWYgKHN0eWxlLT5zdHJpcFNwYWNlcyA9PSBOVUxMKQorCXN0eWxlLT5zdHJpcFNwYWNlcyA9IHhtbEhhc2hDcmVhdGUoMTApOworICAgIGlmIChzdHlsZS0+c3RyaXBTcGFjZXMgPT0gTlVMTCkKKwlyZXR1cm47CisKKyAgICBlbGVtZW50ID0gZWxlbWVudHM7CisgICAgd2hpbGUgKCplbGVtZW50ICE9IDApIHsKKwl3aGlsZSAoSVNfQkxBTksoKmVsZW1lbnQpKSBlbGVtZW50Kys7CisJaWYgKCplbGVtZW50ID09IDApCisJICAgIGJyZWFrOworICAgICAgICBlbmQgPSBlbGVtZW50OworCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIUlTX0JMQU5LKCplbmQpKSkgZW5kKys7CisJZWxlbWVudCA9IHhtbFN0cm5kdXAoZWxlbWVudCwgZW5kIC0gZWxlbWVudCk7CisJaWYgKGVsZW1lbnQpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkiYWRkIHByZXNlcnZlZCBzcGFjZSBlbGVtZW50ICVzXG4iLCBlbGVtZW50KTsKKyNlbmRpZgorCSAgICBpZiAoeG1sU3RyRXF1YWwoZWxlbWVudCwgKGNvbnN0IHhtbENoYXIgKikiKiIpKSB7CisJCXN0eWxlLT5zdHJpcEFsbCA9IC0xOworCSAgICB9IGVsc2UgeworCQljb25zdCB4bWxDaGFyICpVUkk7CisKKwkJLyoKKwkJKiBUT0RPOiBEb24ndCB1c2UgeHNsdEdldFFOYW1lVVJJKCkuCisJCSovCisgICAgICAgICAgICAgICAgVVJJID0geHNsdEdldFFOYW1lVVJJKGN1ciwgJmVsZW1lbnQpOworCisJCXhtbEhhc2hBZGRFbnRyeTIoc3R5bGUtPnN0cmlwU3BhY2VzLCBlbGVtZW50LCBVUkksCisJCQkJKHhtbENoYXIgKikgInByZXNlcnZlIik7CisJICAgIH0KKwkgICAgeG1sRnJlZShlbGVtZW50KTsKKwl9CisJZWxlbWVudCA9IGVuZDsKKyAgICB9CisgICAgeG1sRnJlZShlbGVtZW50cyk7CisgICAgaWYgKGN1ci0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCXhzbHRQYXJzZUNvbnRlbnRFcnJvcihzdHlsZSwgY3VyLT5jaGlsZHJlbik7CisgICAgfQorfQorCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisjZWxzZQorLyoqCisgKiB4c2x0UGFyc2VTdHlsZXNoZWV0RXh0UHJlZml4OgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICogQHRlbXBsYXRlOiAgdGhlICJleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyIgcHJlZml4CisgKgorICogcGFyc2UgYW4gWFNMVCBzdHlsZXNoZWV0J3MgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeCIgYXR0cmlidXRlIHZhbHVlCisgKiBhbmQgcmVnaXN0ZXIgdGhlIG5hbWVzcGFjZXMgb2YgZXh0ZW5zaW9uIGluc3RydWN0aW9uLgorICogU1BFQyAiQSBuYW1lc3BhY2UgaXMgZGVzaWduYXRlZCBhcyBhbiBleHRlbnNpb24gbmFtZXNwYWNlIGJ5IHVzaW5nCisgKiAgIGFuIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIGF0dHJpYnV0ZSBvbjoKKyAqICAgMSkgYW4geHNsOnN0eWxlc2hlZXQgZWxlbWVudAorICogICAyKSBhbiB4c2w6ZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMgYXR0cmlidXRlIG9uIGEKKyAqICAgICAgbGl0ZXJhbCByZXN1bHQgZWxlbWVudCAKKyAqICAgMykgYW4gZXh0ZW5zaW9uIGluc3RydWN0aW9uLiIKKyAqLworc3RhdGljIHZvaWQKK3hzbHRQYXJzZVN0eWxlc2hlZXRFeHRQcmVmaXgoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgY3VyLAorCQkJICAgICBpbnQgaXNYc2x0RWxlbSkgeworICAgIHhtbENoYXIgKnByZWZpeGVzOworICAgIHhtbENoYXIgKnByZWZpeCwgKmVuZDsKKworICAgIGlmICgoY3VyID09IE5VTEwpIHx8IChzdHlsZSA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICBpZiAoaXNYc2x0RWxlbSkgeworCS8qIEZvciB4c2w6c3R5bGVzaGVldC94c2w6dHJhbnNmb3JtLiAqLworCXByZWZpeGVzID0geG1sR2V0TnNQcm9wKGN1ciwKKwkgICAgKGNvbnN0IHhtbENoYXIgKikiZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMiLCBOVUxMKTsKKyAgICB9IGVsc2UgeworCS8qIEZvciBsaXRlcmFsIHJlc3VsdCBlbGVtZW50cyBhbmQgZXh0ZW5zaW9uIGluc3RydWN0aW9ucy4gKi8KKwlwcmVmaXhlcyA9IHhtbEdldE5zUHJvcChjdXIsCisJICAgIChjb25zdCB4bWxDaGFyICopImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIiwgWFNMVF9OQU1FU1BBQ0UpOworICAgIH0KKyAgICBpZiAocHJlZml4ZXMgPT0gTlVMTCkgeworCXJldHVybjsKKyAgICB9CisKKyAgICBwcmVmaXggPSBwcmVmaXhlczsKKyAgICB3aGlsZSAoKnByZWZpeCAhPSAwKSB7CisJd2hpbGUgKElTX0JMQU5LKCpwcmVmaXgpKSBwcmVmaXgrKzsKKwlpZiAoKnByZWZpeCA9PSAwKQorCSAgICBicmVhazsKKyAgICAgICAgZW5kID0gcHJlZml4OworCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIUlTX0JMQU5LKCplbmQpKSkgZW5kKys7CisJcHJlZml4ID0geG1sU3RybmR1cChwcmVmaXgsIGVuZCAtIHByZWZpeCk7CisJaWYgKHByZWZpeCkgeworCSAgICB4bWxOc1B0ciBuczsKKworCSAgICBpZiAoeG1sU3RyRXF1YWwocHJlZml4LCAoY29uc3QgeG1sQ2hhciAqKSIjZGVmYXVsdCIpKQorCQlucyA9IHhtbFNlYXJjaE5zKHN0eWxlLT5kb2MsIGN1ciwgTlVMTCk7CisJICAgIGVsc2UKKwkJbnMgPSB4bWxTZWFyY2hOcyhzdHlsZS0+ZG9jLCBjdXIsIHByZWZpeCk7CisJICAgIGlmIChucyA9PSBOVUxMKSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCSAgICAieHNsOmV4dGVuc2lvbi1lbGVtZW50LXByZWZpeCA6IHVuZGVmaW5lZCBuYW1lc3BhY2UgJXNcbiIsCisJICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCk7CisJCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKwkgICAgfSBlbHNlIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworCQl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgImFkZCBleHRlbnNpb24gcHJlZml4ICVzXG4iLCBwcmVmaXgpOworI2VuZGlmCisJCXhzbHRSZWdpc3RlckV4dFByZWZpeChzdHlsZSwgcHJlZml4LCBucy0+aHJlZik7CisJICAgIH0KKwkgICAgeG1sRnJlZShwcmVmaXgpOworCX0KKwlwcmVmaXggPSBlbmQ7CisgICAgfQorICAgIHhtbEZyZWUocHJlZml4ZXMpOworfQorI2VuZGlmIC8qIGVsc2Ugb2YgWFNMVF9SRUZBQ1RPUkVEICovCisKKy8qKgorICogeHNsdFBhcnNlU3R5bGVzaGVldFN0cmlwU3BhY2U6CisgKiBAc3R5bGU6ICB0aGUgWFNMVCBzdHlsZXNoZWV0CisgKiBAY3VyOiAgdGhlICJzdHJpcC1zcGFjZSIgZWxlbWVudAorICoKKyAqIHBhcnNlIGFuIFhTTFQgc3R5bGVzaGVldCdzIHN0cmlwLXNwYWNlIGVsZW1lbnQgYW5kIHJlY29yZAorICogdGhlIGVsZW1lbnRzIG5lZWRpbmcgc3RyaXBwaW5nCisgKi8KKworc3RhdGljIHZvaWQKK3hzbHRQYXJzZVN0eWxlc2hlZXRTdHJpcFNwYWNlKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGN1cikgeworICAgIHhtbENoYXIgKmVsZW1lbnRzOworICAgIHhtbENoYXIgKmVsZW1lbnQsICplbmQ7CisKKyAgICBpZiAoKGN1ciA9PSBOVUxMKSB8fCAoc3R5bGUgPT0gTlVMTCkpCisJcmV0dXJuOworCisgICAgZWxlbWVudHMgPSB4bWxHZXROc1Byb3AoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSJlbGVtZW50cyIsIE5VTEwpOworICAgIGlmIChlbGVtZW50cyA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICJ4c2x0UGFyc2VTdHlsZXNoZWV0U3RyaXBTcGFjZTogbWlzc2luZyBlbGVtZW50cyBhdHRyaWJ1dGVcbiIpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKwlyZXR1cm47CisgICAgfQorCisgICAgaWYgKHN0eWxlLT5zdHJpcFNwYWNlcyA9PSBOVUxMKQorCXN0eWxlLT5zdHJpcFNwYWNlcyA9IHhtbEhhc2hDcmVhdGUoMTApOworICAgIGlmIChzdHlsZS0+c3RyaXBTcGFjZXMgPT0gTlVMTCkKKwlyZXR1cm47CisKKyAgICBlbGVtZW50ID0gZWxlbWVudHM7CisgICAgd2hpbGUgKCplbGVtZW50ICE9IDApIHsKKwl3aGlsZSAoSVNfQkxBTksoKmVsZW1lbnQpKSBlbGVtZW50Kys7CisJaWYgKCplbGVtZW50ID09IDApCisJICAgIGJyZWFrOworICAgICAgICBlbmQgPSBlbGVtZW50OworCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIUlTX0JMQU5LKCplbmQpKSkgZW5kKys7CisJZWxlbWVudCA9IHhtbFN0cm5kdXAoZWxlbWVudCwgZW5kIC0gZWxlbWVudCk7CisJaWYgKGVsZW1lbnQpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkiYWRkIHN0cmlwcGVkIHNwYWNlIGVsZW1lbnQgJXNcbiIsIGVsZW1lbnQpOworI2VuZGlmCisJICAgIGlmICh4bWxTdHJFcXVhbChlbGVtZW50LCAoY29uc3QgeG1sQ2hhciAqKSIqIikpIHsKKwkJc3R5bGUtPnN0cmlwQWxsID0gMTsKKwkgICAgfSBlbHNlIHsKKwkJY29uc3QgeG1sQ2hhciAqVVJJOworCisJCS8qCisJCSogVE9ETzogRG9uJ3QgdXNlIHhzbHRHZXRRTmFtZVVSSSgpLgorCQkqLworICAgICAgICAgICAgICAgIFVSSSA9IHhzbHRHZXRRTmFtZVVSSShjdXIsICZlbGVtZW50KTsKKworCQl4bWxIYXNoQWRkRW50cnkyKHN0eWxlLT5zdHJpcFNwYWNlcywgZWxlbWVudCwgVVJJLAorCQkJICAgICAgICAoeG1sQ2hhciAqKSAic3RyaXAiKTsKKwkgICAgfQorCSAgICB4bWxGcmVlKGVsZW1lbnQpOworCX0KKwllbGVtZW50ID0gZW5kOworICAgIH0KKyAgICB4bWxGcmVlKGVsZW1lbnRzKTsKKyAgICBpZiAoY3VyLT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJeHNsdFBhcnNlQ29udGVudEVycm9yKHN0eWxlLCBjdXItPmNoaWxkcmVuKTsKKyAgICB9Cit9CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKyNlbHNlCisvKioKKyAqIHhzbHRQYXJzZVN0eWxlc2hlZXRFeGNsdWRlUHJlZml4OgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICogQGN1cjogIHRoZSBjdXJyZW50IHBvaW50IGluIHRoZSBzdHlsZXNoZWV0CisgKgorICogcGFyc2UgYW4gWFNMVCBzdHlsZXNoZWV0IGV4Y2x1ZGUgcHJlZml4IGFuZCByZWNvcmQKKyAqIG5hbWVzcGFjZXMgbmVlZGluZyBzdHJpcHBpbmcKKyAqCisgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgRXhjbHVkZWQgcHJlZml4ZXMgYWRkZWQgYXQgdGhhdCBsZXZlbAorICovCisKK3N0YXRpYyBpbnQKK3hzbHRQYXJzZVN0eWxlc2hlZXRFeGNsdWRlUHJlZml4KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIGN1ciwKKwkJCQkgaW50IGlzWHNsdEVsZW0pCit7CisgICAgaW50IG5iID0gMDsKKyAgICB4bWxDaGFyICpwcmVmaXhlczsKKyAgICB4bWxDaGFyICpwcmVmaXgsICplbmQ7CisKKyAgICBpZiAoKGN1ciA9PSBOVUxMKSB8fCAoc3R5bGUgPT0gTlVMTCkpCisJcmV0dXJuKDApOworCisgICAgaWYgKGlzWHNsdEVsZW0pCisJcHJlZml4ZXMgPSB4bWxHZXROc1Byb3AoY3VyLAorCSAgICAoY29uc3QgeG1sQ2hhciAqKSJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIsIE5VTEwpOworICAgIGVsc2UKKwlwcmVmaXhlcyA9IHhtbEdldE5zUHJvcChjdXIsCisJICAgIChjb25zdCB4bWxDaGFyICopImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiwgWFNMVF9OQU1FU1BBQ0UpOworCisgICAgaWYgKHByZWZpeGVzID09IE5VTEwpIHsKKwlyZXR1cm4oMCk7CisgICAgfQorCisgICAgcHJlZml4ID0gcHJlZml4ZXM7CisgICAgd2hpbGUgKCpwcmVmaXggIT0gMCkgeworCXdoaWxlIChJU19CTEFOSygqcHJlZml4KSkgcHJlZml4Kys7CisJaWYgKCpwcmVmaXggPT0gMCkKKwkgICAgYnJlYWs7CisgICAgICAgIGVuZCA9IHByZWZpeDsKKwl3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCFJU19CTEFOSygqZW5kKSkpIGVuZCsrOworCXByZWZpeCA9IHhtbFN0cm5kdXAocHJlZml4LCBlbmQgLSBwcmVmaXgpOworCWlmIChwcmVmaXgpIHsKKwkgICAgeG1sTnNQdHIgbnM7CisKKwkgICAgaWYgKHhtbFN0ckVxdWFsKHByZWZpeCwgKGNvbnN0IHhtbENoYXIgKikiI2RlZmF1bHQiKSkKKwkJbnMgPSB4bWxTZWFyY2hOcyhzdHlsZS0+ZG9jLCBjdXIsIE5VTEwpOworCSAgICBlbHNlCisJCW5zID0geG1sU2VhcmNoTnMoc3R5bGUtPmRvYywgY3VyLCBwcmVmaXgpOworCSAgICBpZiAobnMgPT0gTlVMTCkgeworCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkgICAgInhzbDpleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyA6IHVuZGVmaW5lZCBuYW1lc3BhY2UgJXNcbiIsCisJICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCk7CisJCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKwkgICAgfSBlbHNlIHsKKwkJaWYgKGV4Y2xQcmVmaXhQdXNoKHN0eWxlLCAoeG1sQ2hhciAqKSBucy0+aHJlZikgPj0gMCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJImV4Y2x1ZGUgcmVzdWx0IHByZWZpeCAlc1xuIiwgcHJlZml4KTsKKyNlbmRpZgorCQkgICAgbmIrKzsKKwkJfQorCSAgICB9CisJICAgIHhtbEZyZWUocHJlZml4KTsKKwl9CisJcHJlZml4ID0gZW5kOworICAgIH0KKyAgICB4bWxGcmVlKHByZWZpeGVzKTsKKyAgICByZXR1cm4obmIpOworfQorI2VuZGlmIC8qIGVsc2Ugb2YgWFNMVF9SRUZBQ1RPUkVEICovCisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKworLyoKKyogeHNsdFRyZWVFbnN1cmVYTUxEZWNsOgorKiBAZG9jOiB0aGUgZG9jCisqIAorKiBCSUcgTk9URToKKyogIFRoaXMgd2FzIGNvcHkmcGFzdGVkIGZyb20gTGlieG1sMidzIHhtbFRyZWVFbnN1cmVYTUxEZWNsKCkgaW4gInRyZWUuYyIuCisqIEVuc3VyZXMgdGhhdCB0aGVyZSBpcyBhbiBYTUwgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIG9uIHRoZSBkb2MuCisqIAorKiBSZXR1cm5zIHRoZSBYTUwgbnMtc3RydWN0IG9yIE5VTEwgb24gQVBJIGFuZCBpbnRlcm5hbCBlcnJvcnMuCisqLworc3RhdGljIHhtbE5zUHRyCit4c2x0VHJlZUVuc3VyZVhNTERlY2woeG1sRG9jUHRyIGRvYykKK3sKKyAgICBpZiAoZG9jID09IE5VTEwpCisJcmV0dXJuIChOVUxMKTsKKyAgICBpZiAoZG9jLT5vbGROcyAhPSBOVUxMKQorCXJldHVybiAoZG9jLT5vbGROcyk7CisgICAgeworCXhtbE5zUHRyIG5zOworCW5zID0gKHhtbE5zUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbE5zKSk7CisJaWYgKG5zID09IE5VTEwpIHsKKwkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCisJCSJ4c2x0VHJlZUVuc3VyZVhNTERlY2w6IEZhaWxlZCB0byBhbGxvY2F0ZSAiCisJCSJ0aGUgWE1MIG5hbWVzcGFjZS5cbiIpOwkKKwkgICAgcmV0dXJuIChOVUxMKTsKKwl9CisJbWVtc2V0KG5zLCAwLCBzaXplb2YoeG1sTnMpKTsKKwlucy0+dHlwZSA9IFhNTF9MT0NBTF9OQU1FU1BBQ0U7CisJLyoKKwkqIFVSR0VOVCBUT0RPOiByZXZpc2l0IHRoaXMuCisJKi8KKyNpZmRlZiBMSUJYTUxfTkFNRVNQQUNFX0RJQ1QKKwlpZiAoZG9jLT5kaWN0KQorCSAgICBucy0+aHJlZiA9IHhtbERpY3RMb29rdXAoZG9jLT5kaWN0LCBYTUxfWE1MX05BTUVTUEFDRSwgLTEpOworCWVsc2UKKwkgICAgbnMtPmhyZWYgPSB4bWxTdHJkdXAoWE1MX1hNTF9OQU1FU1BBQ0UpOworI2Vsc2UKKwlucy0+aHJlZiA9IHhtbFN0cmR1cChYTUxfWE1MX05BTUVTUEFDRSk7IAorI2VuZGlmCisJbnMtPnByZWZpeCA9IHhtbFN0cmR1cCgoY29uc3QgeG1sQ2hhciAqKSJ4bWwiKTsKKwlkb2MtPm9sZE5zID0gbnM7CisJcmV0dXJuIChucyk7CisgICAgfQorfQorCisvKgorKiB4c2x0VHJlZUFjcXVpcmVTdG9yZWROczoKKyogQGRvYzogdGhlIGRvYworKiBAbnNOYW1lOiB0aGUgbmFtZXNwYWNlIG5hbWUKKyogQHByZWZpeDogdGhlIHByZWZpeAorKiAKKyogQklHIE5PVEU6CisqICBUaGlzIHdhcyBjb3B5JnBhc3RlZCBmcm9tIExpYnhtbDIncyB4bWxET01XcmFwU3RvcmVOcygpIGluICJ0cmVlLmMiLgorKiBDcmVhdGVzIG9yIHJldXNlcyBhbiB4bWxOcyBzdHJ1Y3Qgb24gZG9jLT5vbGROcyB3aXRoCisqIHRoZSBnaXZlbiBwcmVmaXggYW5kIG5hbWVzcGFjZSBuYW1lLgorKiAKKyogUmV0dXJucyB0aGUgYXF1aXJlZCBucyBzdHJ1Y3Qgb3IgTlVMTCBpbiBjYXNlIG9mIGFuIEFQSQorKiAgICAgICAgIG9yIGludGVybmFsIGVycm9yLgorKi8KK3N0YXRpYyB4bWxOc1B0cgoreHNsdFRyZWVBY3F1aXJlU3RvcmVkTnMoeG1sRG9jUHRyIGRvYywKKwkJCWNvbnN0IHhtbENoYXIgKm5zTmFtZSwKKwkJCWNvbnN0IHhtbENoYXIgKnByZWZpeCkKK3sKKyAgICB4bWxOc1B0ciBuczsKKworICAgIGlmIChkb2MgPT0gTlVMTCkKKwlyZXR1cm4gKE5VTEwpOworICAgIGlmIChkb2MtPm9sZE5zICE9IE5VTEwpCisJbnMgPSBkb2MtPm9sZE5zOworICAgIGVsc2UKKwlucyA9IHhzbHRUcmVlRW5zdXJlWE1MRGVjbChkb2MpOworICAgIGlmIChucyA9PSBOVUxMKQorCXJldHVybiAoTlVMTCk7CisgICAgaWYgKG5zLT5uZXh0ICE9IE5VTEwpIHsKKwkvKiBSZXVzZS4gKi8KKwlucyA9IG5zLT5uZXh0OworCXdoaWxlIChucyAhPSBOVUxMKSB7CisJICAgIGlmICgobnMtPnByZWZpeCA9PSBOVUxMKSAhPSAocHJlZml4ID09IE5VTEwpKSB7CisJCS8qIE5PUCAqLworCSAgICB9IGVsc2UgaWYgKHByZWZpeCA9PSBOVUxMKSB7CisJCWlmICh4bWxTdHJFcXVhbChucy0+aHJlZiwgbnNOYW1lKSkKKwkJICAgIHJldHVybiAobnMpOworCSAgICB9IGVsc2UgeworCQlpZiAoKG5zLT5wcmVmaXhbMF0gPT0gcHJlZml4WzBdKSAmJgorCQkgICAgIHhtbFN0ckVxdWFsKG5zLT5wcmVmaXgsIHByZWZpeCkgJiYKKwkJICAgICB4bWxTdHJFcXVhbChucy0+aHJlZiwgbnNOYW1lKSkKKwkJICAgIHJldHVybiAobnMpOworCQkKKwkgICAgfQorCSAgICBpZiAobnMtPm5leHQgPT0gTlVMTCkKKwkJYnJlYWs7CisJICAgIG5zID0gbnMtPm5leHQ7CisJfQorICAgIH0KKyAgICAvKiBDcmVhdGUuICovCisgICAgbnMtPm5leHQgPSB4bWxOZXdOcyhOVUxMLCBuc05hbWUsIHByZWZpeCk7CisgICAgcmV0dXJuIChucy0+bmV4dCk7Cit9CisKKy8qKgorICogeHNsdExSRUJ1aWxkRWZmZWN0aXZlTnM6CisgKgorICogQXBwbHkgbnMtYWxpYXNpbmcgb24gdGhlIG5hbWVzcGFjZSBvZiB0aGUgZ2l2ZW4gQGVsZW0gYW5kCisgKiBpdHMgYXR0cmlidXRlcy4KKyAqLworc3RhdGljIGludAoreHNsdExSRUJ1aWxkRWZmZWN0aXZlTnMoeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwKKwkJCXhtbE5vZGVQdHIgZWxlbSkKK3sKKyAgICB4bWxOc1B0ciBuczsKKyAgICB4c2x0TnNBbGlhc1B0ciBhbGlhczsKKworICAgIGlmICgoY2N0eHQgPT0gTlVMTCkgfHwgKGVsZW0gPT0gTlVMTCkpCisJcmV0dXJuKC0xKTsKKyAgICBpZiAoKGNjdHh0LT5uc0FsaWFzZXMgPT0gTlVMTCkgfHwgKCEgY2N0eHQtPmhhc05zQWxpYXNlcykpCisJcmV0dXJuKDApOworCisgICAgYWxpYXMgPSBjY3R4dC0+bnNBbGlhc2VzOyAgICAJCQorICAgIHdoaWxlIChhbGlhcyAhPSBOVUxMKSB7CisJaWYgKCAvKiBJZiBib3RoIG5hbWVzcGFjZXMgYXJlIE5VTEwuLi4gKi8KKwkgICAgKCAoZWxlbS0+bnMgPT0gTlVMTCkgJiYKKwkgICAgKChhbGlhcy0+bGl0ZXJhbE5zID09IE5VTEwpIHx8CisJICAgIChhbGlhcy0+bGl0ZXJhbE5zLT5ocmVmID09IE5VTEwpKSApIHx8CisJICAgIC8qIC4uLiBvciBib3RoIG5hbWVzcGFjZSBhcmUgZXF1YWwgKi8KKwkgICAgKCAoZWxlbS0+bnMgIT0gTlVMTCkgJiYKKwkgICAgKGFsaWFzLT5saXRlcmFsTnMgIT0gTlVMTCkgJiYKKwkgICAgeG1sU3RyRXF1YWwoZWxlbS0+bnMtPmhyZWYsIGFsaWFzLT5saXRlcmFsTnMtPmhyZWYpICkgKQorCXsKKwkgICAgaWYgKChhbGlhcy0+dGFyZ2V0TnMgIT0gTlVMTCkgJiYKKwkJKGFsaWFzLT50YXJnZXROcy0+aHJlZiAhPSBOVUxMKSkKKwkgICAgeworCQkvKgorCQkqIENvbnZlcnQgbmFtZXNwYWNlLgorCQkqLworCQlpZiAoZWxlbS0+ZG9jID09IGFsaWFzLT5kb2NPZlRhcmdldE5zKSB7CisJCSAgICAvKgorCQkgICAgKiBUaGlzIGlzIHRoZSBuaWNlIGNhc2U6IHNhbWUgZG9jcy4KKwkJICAgICogVGhpcyB3aWxsIGV2ZW50dWFsbHkgYXNzaWduIGEgbnMtZGVjbCB3aGljaAorCQkgICAgKiBpcyBzaGFkb3dlZCwgYnV0IHRoaXMgaGFzIG5vIG5lZ2F0aXZlIGVmZmVjdCBvbgorCQkgICAgKiB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgcmVzdWx0IHRyZWUuCisJCSAgICAqLworCQkgICAgZWxlbS0+bnMgPSBhbGlhcy0+dGFyZ2V0TnM7CisJCX0gZWxzZSB7CisJCSAgICAvKgorCQkgICAgKiBUaGlzIHRhcmdldCB4bWxOcyBvcmlnaW5hdGVzIGZyb20gYSBkaWZmZXJlbnQKKwkJICAgICogc3R5bGVzaGVldCB0cmVlLiBUcnkgdG8gbG9jYXRlIGl0IGluIHRoZQorCQkgICAgKiBpbi1zY29wZSBuYW1lc3BhY2VzLgorCQkgICAgKiBPUFRJTUlaRSBUT0RPOiBVc2UgdGhlIGNvbXBpbGVyLW5vZGUtaW5mbyBpblNjb3BlTnMuCisJCSAgICAqLworCQkgICAgbnMgPSB4bWxTZWFyY2hOcyhlbGVtLT5kb2MsIGVsZW0sCisJCQlhbGlhcy0+dGFyZ2V0TnMtPnByZWZpeCk7CQkgICAgCisJCSAgICAvKgorCQkgICAgKiBJZiBubyBtYXRjaGluZyBucy1kZWNsIGZvdW5kLCB0aGVuIGFzc2lnbiBhCisJCSAgICAqIG5zLWRlY2wgc3RvcmVkIGluIHhtbERvYy4KKwkJICAgICovCisJCSAgICBpZiAoKG5zID09IE5VTEwpIHx8CisJCQkoISB4bWxTdHJFcXVhbChucy0+aHJlZiwgYWxpYXMtPnRhcmdldE5zLT5ocmVmKSkpCisJCSAgICB7CisJCQkvKgorCQkJKiBCSUcgTk9URTogVGhlIHVzZSBvZiB4c2x0VHJlZUFjcXVpcmVTdG9yZWROcygpCisJCQkqICBpcyBub3QgdmVyeSBlZmZpY2llbnQsIGJ1dCBjdXJyZW50bHkgSSBkb24ndAorCQkJKiAgc2VlIGFuIG90aGVyIHdheSBvZiAqc2FmZWx5KiBjaGFuZ2luZyBhIG5vZGUncworCQkJKiAgbmFtZXNwYWNlLCBzaW5jZSB0aGUgeG1sTnMgc3RydWN0IGluCisJCQkqICBhbGlhcy0+dGFyZ2V0TnMgbWlnaHQgY29tZSBmcm9tIGFuIG90aGVyCisJCQkqICBzdHlsZXNoZWV0IHRyZWUuIFNvIHdlIG5lZWQgdG8gYW5jaG9yIGl0IGluIHRoZQorCQkJKiAgY3VycmVudCBkb2N1bWVudCwgd2l0aG91dCBhZGRpbmcgaXQgdG8gdGhlIHRyZWUsCisJCQkqICB3aGljaCB3b3VsZCBvdGhlcndpc2UgY2hhbmdlIHRoZSBpbi1zY29wZS1ucworCQkJKiAgc2VtYW50aWMgb2YgdGhlIHRyZWUuCisJCQkqLworCQkJbnMgPSB4c2x0VHJlZUFjcXVpcmVTdG9yZWROcyhlbGVtLT5kb2MsCisJCQkgICAgYWxpYXMtPnRhcmdldE5zLT5ocmVmLAorCQkJICAgIGFsaWFzLT50YXJnZXROcy0+cHJlZml4KTsKKwkJCQorCQkJaWYgKG5zID09IE5VTEwpIHsKKwkJCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBlbGVtLAorCQkJCSJJbnRlcm5hbCBlcnJvciBpbiAiCisJCQkJInhzbHRMUkVCdWlsZEVmZmVjdGl2ZU5zKCk6ICIKKwkJCQkiZmFpbGVkIHRvIGFjcXVpcmUgYSBzdG9yZWQgIgorCQkJCSJucy1kZWNsYXJhdGlvbi5cbiIpOworCQkJICAgIGNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJCQkgICAgcmV0dXJuKC0xKTsKKwkJCSAgICAKKwkJCX0KKwkJICAgIH0KKwkJICAgIGVsZW0tPm5zID0gbnM7CisJCX0JCSAgIAorCSAgICB9IGVsc2UgeworCQkvKgorCQkqIE1vdmUgaW50byBvciBsZWF2ZSBpbiB0aGUgTlVMTCBuYW1lc3BhY2UuCisJCSovCisJCWVsZW0tPm5zID0gTlVMTDsKKwkgICAgfQorCSAgICBicmVhazsKKwl9CisJYWxpYXMgPSBhbGlhcy0+bmV4dDsKKyAgICB9CisgICAgLyoKKyAgICAqIFNhbWUgd2l0aCBhdHRyaWJ1dGVzIG9mIGxpdGVyYWwgcmVzdWx0IGVsZW1lbnRzLgorICAgICovCisgICAgaWYgKGVsZW0tPnByb3BlcnRpZXMgIT0gTlVMTCkgeworCXhtbEF0dHJQdHIgYXR0ciA9IGVsZW0tPnByb3BlcnRpZXM7CisJCisJd2hpbGUgKGF0dHIgIT0gTlVMTCkgeworCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgeworCQlhdHRyID0gYXR0ci0+bmV4dDsKKwkJY29udGludWU7CisJICAgIH0KKwkgICAgYWxpYXMgPSBjY3R4dC0+bnNBbGlhc2VzOworCSAgICB3aGlsZSAoYWxpYXMgIT0gTlVMTCkgeworCQlpZiAoIC8qIElmIGJvdGggbmFtZXNwYWNlcyBhcmUgTlVMTC4uLiAqLworCQkgICAgKCAoZWxlbS0+bnMgPT0gTlVMTCkgJiYKKwkJICAgICgoYWxpYXMtPmxpdGVyYWxOcyA9PSBOVUxMKSB8fAorCQkgICAgKGFsaWFzLT5saXRlcmFsTnMtPmhyZWYgPT0gTlVMTCkpICkgfHwKKwkJICAgIC8qIC4uLiBvciBib3RoIG5hbWVzcGFjZSBhcmUgZXF1YWwgKi8KKwkJICAgICggKGVsZW0tPm5zICE9IE5VTEwpICYmCisJCSAgICAoYWxpYXMtPmxpdGVyYWxOcyAhPSBOVUxMKSAmJgorCQkgICAgeG1sU3RyRXF1YWwoZWxlbS0+bnMtPmhyZWYsIGFsaWFzLT5saXRlcmFsTnMtPmhyZWYpICkgKQorCQl7CisJCSAgICBpZiAoKGFsaWFzLT50YXJnZXROcyAhPSBOVUxMKSAmJgorCQkJKGFsaWFzLT50YXJnZXROcy0+aHJlZiAhPSBOVUxMKSkKKwkJICAgIHsJCSAgICAKKwkJCWlmIChlbGVtLT5kb2MgPT0gYWxpYXMtPmRvY09mVGFyZ2V0TnMpIHsKKwkJCSAgICBlbGVtLT5ucyA9IGFsaWFzLT50YXJnZXROczsKKwkJCX0gZWxzZSB7CisJCQkgICAgbnMgPSB4bWxTZWFyY2hOcyhlbGVtLT5kb2MsIGVsZW0sCisJCQkJYWxpYXMtPnRhcmdldE5zLT5wcmVmaXgpOworCQkJICAgIGlmICgobnMgPT0gTlVMTCkgfHwKKwkJCQkoISB4bWxTdHJFcXVhbChucy0+aHJlZiwgYWxpYXMtPnRhcmdldE5zLT5ocmVmKSkpCisJCQkgICAgeworCQkJCW5zID0geHNsdFRyZWVBY3F1aXJlU3RvcmVkTnMoZWxlbS0+ZG9jLAorCQkJCSAgICBhbGlhcy0+dGFyZ2V0TnMtPmhyZWYsCisJCQkJICAgIGFsaWFzLT50YXJnZXROcy0+cHJlZml4KTsKKwkJCQkKKwkJCQlpZiAobnMgPT0gTlVMTCkgeworCQkJCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBlbGVtLAorCQkJCQkiSW50ZXJuYWwgZXJyb3IgaW4gIgorCQkJCQkieHNsdExSRUJ1aWxkRWZmZWN0aXZlTnMoKTogIgorCQkJCQkiZmFpbGVkIHRvIGFjcXVpcmUgYSBzdG9yZWQgIgorCQkJCQkibnMtZGVjbGFyYXRpb24uXG4iKTsKKwkJCQkgICAgY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwkJCQkgICAgcmV0dXJuKC0xKTsKKwkJCQkgICAgCisJCQkJfQorCQkJICAgIH0KKwkJCSAgICBlbGVtLT5ucyA9IG5zOworCQkJfQorCQkgICAgfSBlbHNlIHsKKwkJICAgIC8qCisJCSAgICAqIE1vdmUgaW50byBvciBsZWF2ZSBpbiB0aGUgTlVMTCBuYW1lc3BhY2UuCisJCQkqLworCQkJZWxlbS0+bnMgPSBOVUxMOworCQkgICAgfQorCQkgICAgYnJlYWs7CisJCX0KKwkJYWxpYXMgPSBhbGlhcy0+bmV4dDsKKwkgICAgfQorCSAgICAKKwkgICAgYXR0ciA9IGF0dHItPm5leHQ7CisJfQorICAgIH0KKyAgICByZXR1cm4oMCk7Cit9CisKKy8qKgorICogeHNsdExSRUJ1aWxkRWZmZWN0aXZlTnNOb2RlczoKKyAqCisgKiBDb21wdXRlcyB0aGUgZWZmZWN0aXZlIG5hbWVzcGFjZXMgbm9kZXMgZm9yIGEgbGl0ZXJhbCByZXN1bHQKKyAqIGVsZW1lbnQuCisgKiBAZWZmZWN0aXZlTnMgaXMgdGhlIHNldCBvZiBlZmZlY3RpdmUgbnMtbm9kZXMKKyAqICBvbiB0aGUgbGl0ZXJhbCByZXN1bHQgZWxlbWVudCwgd2hpY2ggd2lsbCBiZSBhZGRlZCB0byB0aGUgcmVzdWx0CisgKiAgZWxlbWVudCBpZiBub3QgYWxyZWFkeSBleGlzdGluZyBpbiB0aGUgcmVzdWx0IHRyZWUuCisgKiAgVGhpcyBtZWFucyB0aGF0IGV4Y2x1ZGVkIG5hbWVzcGFjZXMgKHZpYSBleGNsdWRlLXJlc3VsdC1wcmVmaXhlcywKKyAqICBleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyBhbmQgdGhlIFhTTFQgbmFtZXNwYWNlKSBub3QgYWRkZWQKKyAqICB0byB0aGUgc2V0LgorICogIE5hbWVzcGFjZS1hbGlhc2luZyB3YXMgYXBwbGllZCBvbiB0aGUgQGVmZmVjdGl2ZU5zLgorICovCitzdGF0aWMgaW50Cit4c2x0TFJFQnVpbGRFZmZlY3RpdmVOc05vZGVzKHhzbHRDb21waWxlckN0eHRQdHIgY2N0eHQsCisJCQkgICAgIHhzbHRTdHlsZUl0ZW1MUkVsZW1lbnRJbmZvUHRyIGl0ZW0sCisJCQkgICAgIHhtbE5vZGVQdHIgZWxlbSwKKwkJCSAgICAgaW50IGlzTFJFKQoreworICAgIHhtbE5zUHRyIG5zLCB0bXBuczsKKyAgICB4c2x0RWZmZWN0aXZlTnNQdHIgZWZmTnMsIGxhc3RFZmZOcyA9IE5VTEw7CisgICAgaW50IGksIGosIGhvbGRCeUVsZW07CisgICAgeHNsdFBvaW50ZXJMaXN0UHRyIGV4dEVsZW1OcyA9IGNjdHh0LT5pbm9kZS0+ZXh0RWxlbU5zOworICAgIHhzbHRQb2ludGVyTGlzdFB0ciBleGNsUmVzdWx0TnMgPSBjY3R4dC0+aW5vZGUtPmV4Y2xSZXN1bHROczsKKworICAgIGlmICgoY2N0eHQgPT0gTlVMTCkgfHwgKGNjdHh0LT5pbm9kZSA9PSBOVUxMKSB8fCAoZWxlbSA9PSBOVUxMKSB8fAorCShpdGVtID09IE5VTEwpIHx8IChpdGVtLT5lZmZlY3RpdmVOcyAhPSBOVUxMKSkKKwlyZXR1cm4oLTEpOworCisgICAgaWYgKGl0ZW0tPmluU2NvcGVOcyA9PSBOVUxMKSAgICAKKwlyZXR1cm4oMCk7CisKKyAgICBleHRFbGVtTnMgPSBjY3R4dC0+aW5vZGUtPmV4dEVsZW1OczsKKyAgICBleGNsUmVzdWx0TnMgPSBjY3R4dC0+aW5vZGUtPmV4Y2xSZXN1bHROczsKKworICAgIGZvciAoaSA9IDA7IGkgPCBpdGVtLT5pblNjb3BlTnMtPnRvdGFsTnVtYmVyOyBpKyspIHsKKwlucyA9IGl0ZW0tPmluU2NvcGVOcy0+bGlzdFtpXTsKKwkvKgorCSogU2tpcCBuYW1lc3BhY2VzIGRlc2lnbmF0ZWQgYXMgZXhjbHVkZWQgbmFtZXNwYWNlcworCSogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCSoKKwkqIFhTTFQtMjAgVE9ETzogSW4gWFNMVCAyLjAgd2UgbmVlZCB0byBrZWVwIG5hbWVzcGFjZXMKKwkqICB3aGljaCBhcmUgdGFyZ2V0IG5hbWVzcGFjZXMgb2YgbmFtZXNwYWNlLWFsaWFzZXMKKwkqICByZWdhcmRsZXNzIGlmIGRlc2lnbmF0ZWQgYXMgZXhjbHVkZWQuCisJKgorCSogRXhjbHVkZSB0aGUgWFNMVCBuYW1lc3BhY2UuCisJKi8KKwlpZiAoeG1sU3RyRXF1YWwobnMtPmhyZWYsIFhTTFRfTkFNRVNQQUNFKSkKKwkgICAgZ290byBza2lwX25zOworCisJLyoKKwkqIEFwcGx5IG5hbWVzcGFjZSBhbGlhc2luZworCSogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisJKgorCSogU1BFQyBYU0xUIDIuMAorCSogICItIEEgbmFtZXNwYWNlIG5vZGUgd2hvc2Ugc3RyaW5nIHZhbHVlIGlzIGEgbGl0ZXJhbCBuYW1lc3BhY2UKKwkqICAgICBVUkkgaXMgbm90IGNvcGllZCB0byB0aGUgcmVzdWx0IHRyZWUuCisJKiAgIC0gQSBuYW1lc3BhY2Ugbm9kZSB3aG9zZSBzdHJpbmcgdmFsdWUgaXMgYSB0YXJnZXQgbmFtZXNwYWNlIFVSSQorCSogICAgIGlzIGNvcGllZCB0byB0aGUgcmVzdWx0IHRyZWUsIHdoZXRoZXIgb3Igbm90IHRoZSBVUkkKKwkqICAgICBpZGVudGlmaWVzIGFuIGV4Y2x1ZGVkIG5hbWVzcGFjZS4iCisJKiAKKwkqIE5PVEU6IFRoZSBucy1hbGlhc2luZyBtYWNoYW5pc20gaXMgbm9uLWNhc2NhZGluZy4KKwkqICAoY2hlY2tlZCB3aXRoIFNheG9uLCBYYWxhbiBhbmQgTVNYTUwgLk5FVCkuCisJKiBVUkdFTlQgVE9ETzogaXMgc3R5bGUtPm5zQWxpYXNlcyB0aGUgZWZmZWN0aXZlIGxpc3Qgb2YKKwkqICBucy1hbGlhc2VzLCBvciBkbyB3ZSBuZWVkIHRvIGxvb2t1cCB0aGUgd2hvbGUKKwkqICBpbXBvcnQtdHJlZT8KKwkqIFRPRE86IEdldCByaWQgb2YgaW1wb3J0LXRyZWUgbG9va3VwLgorCSovCisJaWYgKGNjdHh0LT5oYXNOc0FsaWFzZXMpIHsKKwkgICAgeHNsdE5zQWxpYXNQdHIgYWxpYXM7CisJICAgIC8qCisJICAgICogRmlyc3QgY2hlY2sgZm9yIGJlaW5nIGEgdGFyZ2V0IG5hbWVzcGFjZS4KKwkgICAgKi8KKwkgICAgYWxpYXMgPSBjY3R4dC0+bnNBbGlhc2VzOworCSAgICBkbyB7CisJCS8qCisJCSogVE9ETzogSXMgeG1sbnM9IiIgaGFuZGxlZCBhbHJlYWR5PworCQkqLworCQlpZiAoKGFsaWFzLT50YXJnZXROcyAhPSBOVUxMKSAmJgorCQkgICAgKHhtbFN0ckVxdWFsKGFsaWFzLT50YXJnZXROcy0+aHJlZiwgbnMtPmhyZWYpKSkKKwkJeworCQkgICAgLyoKKwkJICAgICogUmVjb2duaXplZCBhcyBhIHRhcmdldCBuYW1lc3BhY2U7IHVzZSBpdCByZWdhcmRsZXNzCisJCSAgICAqIGlmIGV4Y2x1ZGVkIG90aGVyd2lzZS4KKwkJICAgICovCisJCSAgICBnb3RvIGFkZF9lZmZlY3RpdmVfbnM7CisJCX0KKwkJYWxpYXMgPSBhbGlhcy0+bmV4dDsKKwkgICAgfSB3aGlsZSAoYWxpYXMgIT0gTlVMTCk7CisKKwkgICAgYWxpYXMgPSBjY3R4dC0+bnNBbGlhc2VzOworCSAgICBkbyB7CisJCS8qCisJCSogVE9ETzogSXMgeG1sbnM9IiIgaGFuZGxlZCBhbHJlYWR5PworCQkqLworCQlpZiAoKGFsaWFzLT5saXRlcmFsTnMgIT0gTlVMTCkgJiYKKwkJICAgICh4bWxTdHJFcXVhbChhbGlhcy0+bGl0ZXJhbE5zLT5ocmVmLCBucy0+aHJlZikpKQorCQl7CisJCSAgICAvKgorCQkgICAgKiBSZWNvZ25pemVkIGFzIGFuIG5hbWVzcGFjZSBhbGlhczsgZG8gbm90IHVzZSBpdC4KKwkJICAgICovCisJCSAgICBnb3RvIHNraXBfbnM7CisJCX0KKwkJYWxpYXMgPSBhbGlhcy0+bmV4dDsKKwkgICAgfSB3aGlsZSAoYWxpYXMgIT0gTlVMTCk7CisJfQorCQorCS8qCisJKiBFeGNsdWRlIGV4Y2x1ZGVkIHJlc3VsdCBuYW1lc3BhY2VzLgorCSovCisJaWYgKGV4Y2xSZXN1bHROcykgeworCSAgICBmb3IgKGogPSAwOyBqIDwgZXhjbFJlc3VsdE5zLT5udW1iZXI7IGorKykKKwkJaWYgKHhtbFN0ckVxdWFsKG5zLT5ocmVmLCBCQURfQ0FTVCBleGNsUmVzdWx0TnMtPml0ZW1zW2pdKSkKKwkJICAgIGdvdG8gc2tpcF9uczsKKwl9CisJLyoKKwkqIEV4Y2x1ZGUgZXh0ZW5zaW9uLWVsZW1lbnQgbmFtZXNwYWNlcy4KKwkqLworCWlmIChleHRFbGVtTnMpIHsKKwkgICAgZm9yIChqID0gMDsgaiA8IGV4dEVsZW1Ocy0+bnVtYmVyOyBqKyspCisJCWlmICh4bWxTdHJFcXVhbChucy0+aHJlZiwgQkFEX0NBU1QgZXh0RWxlbU5zLT5pdGVtc1tqXSkpCisJCSAgICBnb3RvIHNraXBfbnM7CisJfQorCithZGRfZWZmZWN0aXZlX25zOgorCS8qCisJKiBPUFRJTUlaRSBUT0RPOiBUaGlzIGluZm9ybWF0aW9uIG1heSBub3QgYmUgbmVlZGVkLgorCSovCisJaWYgKGlzTFJFICYmIChlbGVtLT5uc0RlZiAhPSBOVUxMKSkgeworCSAgICBob2xkQnlFbGVtID0gMDsKKwkgICAgdG1wbnMgPSBlbGVtLT5uc0RlZjsKKwkgICAgZG8geworCQlpZiAodG1wbnMgPT0gbnMpIHsKKwkJICAgIGhvbGRCeUVsZW0gPSAxOworCQkgICAgYnJlYWs7CisJCX0KKwkJdG1wbnMgPSB0bXBucy0+bmV4dDsKKwkgICAgfSB3aGlsZSAodG1wbnMgIT0gTlVMTCk7CSAgICAKKwl9IGVsc2UKKwkgICAgaG9sZEJ5RWxlbSA9IDA7CisJCisJCisJLyoKKwkqIEFkZCB0aGUgZWZmZWN0aXZlIG5hbWVzcGFjZSBkZWNsYXJhdGlvbi4KKwkqLworCWVmZk5zID0gKHhzbHRFZmZlY3RpdmVOc1B0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0RWZmZWN0aXZlTnMpKTsKKwlpZiAoZWZmTnMgPT0gTlVMTCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBlbGVtLAorCQkiSW50ZXJuYWwgZXJyb3IgaW4geHNsdExSRUJ1aWxkRWZmZWN0aXZlTnMoKTogIgorCQkiZmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeS5cbiIpOworCSAgICBjY3R4dC0+c3R5bGUtPmVycm9ycysrOworCSAgICByZXR1cm4oLTEpOworCX0KKwlpZiAoY2N0eHQtPnBzRGF0YS0+ZWZmZWN0aXZlTnMgPT0gTlVMTCkgeworCSAgICBjY3R4dC0+cHNEYXRhLT5lZmZlY3RpdmVOcyA9IGVmZk5zOworCSAgICBlZmZOcy0+bmV4dEluU3RvcmUgPSBOVUxMOwkgCisJfSBlbHNlIHsKKwkgICAgZWZmTnMtPm5leHRJblN0b3JlID0gY2N0eHQtPnBzRGF0YS0+ZWZmZWN0aXZlTnM7CisJICAgIGNjdHh0LT5wc0RhdGEtPmVmZmVjdGl2ZU5zID0gZWZmTnM7CisJfQorCisJZWZmTnMtPm5leHQgPSBOVUxMOworCWVmZk5zLT5wcmVmaXggPSBucy0+cHJlZml4OworCWVmZk5zLT5uc05hbWUgPSBucy0+aHJlZjsKKwllZmZOcy0+aG9sZEJ5RWxlbSA9IGhvbGRCeUVsZW07CisJCisJaWYgKGxhc3RFZmZOcyA9PSBOVUxMKQorCSAgICBpdGVtLT5lZmZlY3RpdmVOcyA9IGVmZk5zOworCWVsc2UKKwkgICAgbGFzdEVmZk5zLT5uZXh0ID0gZWZmTnM7CisJbGFzdEVmZk5zID0gZWZmTnM7CisJCitza2lwX25zOgorCXt9CisgICAgfQorICAgIHJldHVybigwKTsKK30KKworCisvKioKKyAqIHhzbHRMUkVJbmZvQ3JlYXRlOgorICoKKyAqIEBpc0xSRTogaW5kaWNhdGVzIGlmIHRoZSBnaXZlbiBAZWxlbSBpcyBhIGxpdGVyYWwgcmVzdWx0IGVsZW1lbnQKKyAqCisgKiBDcmVhdGVzIGEgbmV3IGluZm8gZm9yIGEgbGl0ZXJhbCByZXN1bHQgZWxlbWVudC4KKyAqLworc3RhdGljIGludAoreHNsdExSRUluZm9DcmVhdGUoeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwKKwkJICB4bWxOb2RlUHRyIGVsZW0sCisJCSAgaW50IGlzTFJFKQoreworICAgIHhzbHRTdHlsZUl0ZW1MUkVsZW1lbnRJbmZvUHRyIGl0ZW07CisKKyAgICBpZiAoKGNjdHh0ID09IE5VTEwpIHx8IChjY3R4dC0+aW5vZGUgPT0gTlVMTCkpCisJcmV0dXJuKC0xKTsKKworICAgIGl0ZW0gPSAoeHNsdFN0eWxlSXRlbUxSRWxlbWVudEluZm9QdHIpCisJeG1sTWFsbG9jKHNpemVvZih4c2x0U3R5bGVJdGVtTFJFbGVtZW50SW5mbykpOworICAgIGlmIChpdGVtID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBOVUxMLAorCSAgICAiSW50ZXJuYWwgZXJyb3IgaW4geHNsdExSRUluZm9DcmVhdGUoKTogIgorCSAgICAibWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkLlxuIik7CisJY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwlyZXR1cm4oLTEpOworICAgIH0KKyAgICBtZW1zZXQoaXRlbSwgMCwgc2l6ZW9mKHhzbHRTdHlsZUl0ZW1MUkVsZW1lbnRJbmZvKSk7CisgICAgaXRlbS0+dHlwZSA9IFhTTFRfRlVOQ19MSVRFUkFMX1JFU1VMVF9FTEVNRU5UOworICAgIC8qCisgICAgKiBTdG9yZSBpdCBpbiB0aGUgc3R5bGVzaGVldC4KKyAgICAqLworICAgIGl0ZW0tPm5leHQgPSBjY3R4dC0+c3R5bGUtPnByZUNvbXBzOworICAgIGNjdHh0LT5zdHlsZS0+cHJlQ29tcHMgPSAoeHNsdEVsZW1QcmVDb21wUHRyKSBpdGVtOworICAgIC8qCisgICAgKiBAaW5TY29wZU5zIGFyZSB1c2VkIGZvciBleGVjdXRpb24gb2YgWFBhdGggZXhwcmVzc2lvbnMKKyAgICAqICBpbiBBVlRzLgorICAgICovCisgICAgaXRlbS0+aW5TY29wZU5zID0gY2N0eHQtPmlub2RlLT5pblNjb3BlTnM7CisgICAgCisgICAgaWYgKGVsZW0pCisJeHNsdExSRUJ1aWxkRWZmZWN0aXZlTnNOb2RlcyhjY3R4dCwgaXRlbSwgZWxlbSwgaXNMUkUpOworCisgICAgY2N0eHQtPmlub2RlLT5saXRSZXNFbGVtSW5mbyA9IGl0ZW07CisgICAgY2N0eHQtPmlub2RlLT5uc0NoYW5nZWQgPSAwOworICAgIGNjdHh0LT5tYXhMUkVzKys7CisgICAgcmV0dXJuKDApOworfQorCisvKioKKyAqIHhzbHRDb21waWxlclZhckluZm9QdXNoOiAKKyAqIEBjY3R4dDogdGhlIGNvbXBpbGF0aW9uIGNvbnRleHQKKyAqIAorICogUHVzaGVzIGEgbmV3IHZhci9wYXJhbSBpbmZvIG9udG8gdGhlIHN0YWNrLgorICoKKyAqIFJldHVybnMgdGhlIGFjcXVpcmVkIHZhcmlhYmxlIGluZm8uCisgKi8gCitzdGF0aWMgeHNsdFZhckluZm9QdHIKK3hzbHRDb21waWxlclZhckluZm9QdXNoKHhzbHRDb21waWxlckN0eHRQdHIgY2N0eHQsCisJCQkJICB4bWxOb2RlUHRyIGluc3QsCisJCQkJICBjb25zdCB4bWxDaGFyICpuYW1lLAorCQkJCSAgY29uc3QgeG1sQ2hhciAqbnNOYW1lKQoreworICAgIHhzbHRWYXJJbmZvUHRyIGl2YXI7CisKKyAgICBpZiAoKGNjdHh0LT5pdmFyICE9IE5VTEwpICYmIChjY3R4dC0+aXZhci0+bmV4dCAhPSBOVUxMKSkgeworCWl2YXIgPSBjY3R4dC0+aXZhci0+bmV4dDsKKyAgICB9IGVsc2UgaWYgKChjY3R4dC0+aXZhciA9PSBOVUxMKSAmJiAoY2N0eHQtPml2YXJzICE9IE5VTEwpKSB7CisJaXZhciA9IGNjdHh0LT5pdmFyczsKKyAgICB9IGVsc2UgeworCWl2YXIgPSAoeHNsdFZhckluZm9QdHIpIHhtbE1hbGxvYyhzaXplb2YoeHNsdFZhckluZm8pKTsKKwlpZiAoaXZhciA9PSBOVUxMKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIGluc3QsCisJCSJ4c2x0UGFyc2VJblNjb3BlVmFyUHVzaDogeG1sTWFsbG9jKCkgZmFpbGVkIVxuIik7CisJICAgIGNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJICAgIHJldHVybihOVUxMKTsKKwl9CisJLyogbWVtc2V0KHJldFZhciwgMCwgc2l6ZW9mKHhzbHRJblNjb3BlVmFyKSk7ICovCisJaWYgKGNjdHh0LT5pdmFycyA9PSBOVUxMKSB7CisJICAgIGNjdHh0LT5pdmFycyA9IGl2YXI7CisJICAgIGl2YXItPnByZXYgPSBOVUxMOworCX0gZWxzZSB7CisJICAgIGNjdHh0LT5pdmFyLT5uZXh0ID0gaXZhcjsKKwkgICAgaXZhci0+cHJldiA9IGNjdHh0LT5pdmFyOworCX0KKwljY3R4dC0+aXZhciA9IGl2YXI7CisJaXZhci0+bmV4dCA9IE5VTEw7CisgICAgfQorICAgIGl2YXItPmRlcHRoID0gY2N0eHQtPmRlcHRoOworICAgIGl2YXItPm5hbWUgPSBuYW1lOworICAgIGl2YXItPm5zTmFtZSA9IG5zTmFtZTsKKyAgICByZXR1cm4oaXZhcik7Cit9CisKKy8qKgorICogeHNsdENvbXBpbGVyVmFySW5mb1BvcDogCisgKiBAY2N0eHQ6IHRoZSBjb21waWxhdGlvbiBjb250ZXh0CisgKiAKKyAqIFBvcHMgYWxsIHZhci9wYXJhbSBpbmZvcyBmcm9tIHRoZSBzdGFjaywgd2hpY2gKKyAqIGhhdmUgdGhlIGN1cnJlbnQgZGVwdGguCisgKi8gCitzdGF0aWMgdm9pZAoreHNsdENvbXBpbGVyVmFySW5mb1BvcCh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0KQoreworCisgICAgd2hpbGUgKChjY3R4dC0+aXZhciAhPSBOVUxMKSAmJgorCShjY3R4dC0+aXZhci0+ZGVwdGggPiBjY3R4dC0+ZGVwdGgpKQorICAgIHsKKwljY3R4dC0+aXZhciA9IGNjdHh0LT5pdmFyLT5wcmV2OworICAgIH0KK30KKworLyoKKyogeHNsdENvbXBpbGVyTm9kZVB1c2g6CisqCisqIEBjY3R4dDogdGhlIGNvbXBpbGF0aW9uIGNvbnRleHQKKyogQG5vZGU6IHRoZSBub2RlIHRvIGJlIHB1c2hlZCAodGhpcyBjYW4gYWxzbyBiZSB0aGUgZG9jLW5vZGUpCisqCisqIAorKgorKiBSZXR1cm5zIHRoZSBjdXJyZW50IG5vZGUgaW5mbyBzdHJ1Y3R1cmUgb3IKKyogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IuCisqLworc3RhdGljIHhzbHRDb21waWxlck5vZGVJbmZvUHRyCit4c2x0Q29tcGlsZXJOb2RlUHVzaCh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCit7ICAgIAorICAgIHhzbHRDb21waWxlck5vZGVJbmZvUHRyIGlub2RlLCBpcHJldjsKKworICAgIGlmICgoY2N0eHQtPmlub2RlICE9IE5VTEwpICYmIChjY3R4dC0+aW5vZGUtPm5leHQgIT0gTlVMTCkpIHsJCisJaW5vZGUgPSBjY3R4dC0+aW5vZGUtPm5leHQ7CisgICAgfSBlbHNlIGlmICgoY2N0eHQtPmlub2RlID09IE5VTEwpICYmIChjY3R4dC0+aW5vZGVMaXN0ICE9IE5VTEwpKSB7CisJaW5vZGUgPSBjY3R4dC0+aW5vZGVMaXN0OwkKKyAgICB9IGVsc2UgeworCS8qCisJKiBDcmVhdGUgYSBuZXcgbm9kZS1pbmZvLgorCSovCisJaW5vZGUgPSAoeHNsdENvbXBpbGVyTm9kZUluZm9QdHIpCisJICAgIHhtbE1hbGxvYyhzaXplb2YoeHNsdENvbXBpbGVyTm9kZUluZm8pKTsKKwlpZiAoaW5vZGUgPT0gTlVMTCkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBOVUxMLAorCQkieHNsdENvbXBpbGVyTm9kZVB1c2g6IG1hbGxvYyBmYWlsZWQuXG4iKTsKKwkgICAgcmV0dXJuKE5VTEwpOworCX0KKwltZW1zZXQoaW5vZGUsIDAsIHNpemVvZih4c2x0Q29tcGlsZXJOb2RlSW5mbykpOworCWlmIChjY3R4dC0+aW5vZGVMaXN0ID09IE5VTEwpCisJICAgIGNjdHh0LT5pbm9kZUxpc3QgPSBpbm9kZTsKKwllbHNlIHsKKwkgICAgY2N0eHQtPmlub2RlTGFzdC0+bmV4dCA9IGlub2RlOworCSAgICBpbm9kZS0+cHJldiA9IGNjdHh0LT5pbm9kZUxhc3Q7CisJfQorCWNjdHh0LT5pbm9kZUxhc3QgPSBpbm9kZTsKKwljY3R4dC0+bWF4Tm9kZUluZm9zKys7CQorCWlmIChjY3R4dC0+aW5vZGUgPT0gTlVMTCkgeworCSAgICBjY3R4dC0+aW5vZGUgPSBpbm9kZTsKKwkgICAgLyoKKwkgICAgKiBDcmVhdGUgYW4gaW5pdGlhbCBsaXRlcmFsIHJlc3VsdCBlbGVtZW50IGluZm8gZm9yCisJICAgICogdGhlIHJvb3Qgb2YgdGhlIHN0eWxlc2hlZXQuCisJICAgICovCisJICAgIHhzbHRMUkVJbmZvQ3JlYXRlKGNjdHh0LCBOVUxMLCAwKTsKKwl9IAorICAgIH0gICAgICAgCisgICAgY2N0eHQtPmRlcHRoKys7CisgICAgY2N0eHQtPmlub2RlID0gaW5vZGU7CisgICAgLyoKKyAgICAqIFJFVklTSVQgVE9ETzogS2VlcCB0aGUgcmVzZXQgYWx3YXlzIGNvbXBsZXRlLiAgICAKKyAgICAqIE5PVEU6IEJlIGNhcmVmdWxsIHdpdGggdGhlIEBub2RlLCBzaW5jZSBpdCBtaWdodCBiZQorICAgICogIGEgZG9jLW5vZGUuCisgICAgKi8KKyAgICBpbm9kZS0+bm9kZSA9IG5vZGU7CisgICAgaW5vZGUtPmRlcHRoID0gY2N0eHQtPmRlcHRoOworICAgIGlub2RlLT50ZW1wbCA9IE5VTEw7CisgICAgaW5vZGUtPmNhdGVnb3J5ID0gWFNMVF9FTEVNRU5UX0NBVEVHT1JZX1hTTFQ7CisgICAgaW5vZGUtPnR5cGUgPSAwOworICAgIGlub2RlLT5pdGVtID0gTlVMTDsKKyAgICBpbm9kZS0+Y3VyQ2hpbGRUeXBlID0gMDsKKyAgICBpbm9kZS0+ZXh0Q29udGVudEhhbmRsZWQgPSAwOworICAgIGlub2RlLT5pc1Jvb3QgPSAwOworICAgIAorICAgIGlmIChpbm9kZS0+cHJldiAhPSBOVUxMKSB7CisJaXByZXYgPSBpbm9kZS0+cHJldjsKKwkvKgorCSogSW5oZXJpdCB0aGUgZm9sbG93aW5nIGluZm9ybWF0aW9uOgorCSogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisJKgorCSogSW4tc2NvcGUgbmFtZXNwYWNlcworCSovCisJaW5vZGUtPmluU2NvcGVOcyA9IGlwcmV2LT5pblNjb3BlTnM7CisJLyoKKwkqIEluZm8gZm9yIGxpdGVyYWwgcmVzdWx0IGVsZW1lbnRzCisJKi8KKwlpbm9kZS0+bGl0UmVzRWxlbUluZm8gPSBpcHJldi0+bGl0UmVzRWxlbUluZm87CisJaW5vZGUtPm5zQ2hhbmdlZCA9IGlwcmV2LT5uc0NoYW5nZWQ7CisJLyoKKwkqIEV4Y2x1ZGVkIHJlc3VsdCBuYW1lc3BhY2VzCisJKi8KKwlpbm9kZS0+ZXhjbFJlc3VsdE5zID0gaXByZXYtPmV4Y2xSZXN1bHROczsKKwkvKgorCSogRXh0ZW5zaW9uIGluc3RydWN0aW9uIG5hbWVzcGFjZXMKKwkqLworCWlub2RlLT5leHRFbGVtTnMgPSBpcHJldi0+ZXh0RWxlbU5zOworCS8qCisJKiBXaGl0ZXNwYWNlIHByZXNlcnZhdGlvbgorCSovCisJaW5vZGUtPnByZXNlcnZlV2hpdGVzcGFjZSA9IGlwcmV2LT5wcmVzZXJ2ZVdoaXRlc3BhY2U7CisJLyoKKwkqIEZvcndhcmRzLWNvbXBhdGlibGUgbW9kZQorCSovCisJaW5vZGUtPmZvcndhcmRzQ29tcGF0ID0gaXByZXYtPmZvcndhcmRzQ29tcGF0OwkKKyAgICB9IGVsc2UgeworCWlub2RlLT5pblNjb3BlTnMgPSBOVUxMOworCWlub2RlLT5leGNsUmVzdWx0TnMgPSBOVUxMOworCWlub2RlLT5leHRFbGVtTnMgPSBOVUxMOworCWlub2RlLT5wcmVzZXJ2ZVdoaXRlc3BhY2UgPSAwOworCWlub2RlLT5mb3J3YXJkc0NvbXBhdCA9IDA7CisgICAgfQorICAgIAorICAgIHJldHVybihpbm9kZSk7Cit9CisKKy8qCisqIHhzbHRDb21waWxlck5vZGVQb3A6CisqCisqIEBjY3R4dDogdGhlIGNvbXBpbGF0aW9uIGNvbnRleHQKKyogQG5vZGU6IHRoZSBub2RlIHRvIGJlIHB1c2hlZCAodGhpcyBjYW4gYWxzbyBiZSB0aGUgZG9jLW5vZGUpCisqCisqIFBvcHMgdGhlIGN1cnJlbnQgbm9kZSBpbmZvLgorKi8KK3N0YXRpYyB2b2lkCit4c2x0Q29tcGlsZXJOb2RlUG9wKHhzbHRDb21waWxlckN0eHRQdHIgY2N0eHQsIHhtbE5vZGVQdHIgbm9kZSkKK3sgICAgCisgICAgaWYgKGNjdHh0LT5pbm9kZSA9PSBOVUxMKSB7CisJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCisJICAgICJ4c2x0Q29tcGlsZXJOb2RlUG9wOiBUb3Atbm9kZSBtaXNtYXRjaC5cbiIpOworCXJldHVybjsKKyAgICB9CisgICAgLyoKKyAgICAqIE5PVEU6IEJlIGNhcmVmdWxsIHdpdGggdGhlIEBub2RlLCBzaW5jZSBpdCBtaWdodCBiZQorICAgICogIGEgZG9jLW5vZGUuCisgICAgKi8KKyAgICBpZiAoY2N0eHQtPmlub2RlLT5ub2RlICE9IG5vZGUpIHsKKwl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKKwkieHNsdENvbXBpbGVyTm9kZVBvcDogTm9kZSBtaXNtYXRjaC5cbiIpOworCWdvdG8gbWlzbWF0Y2g7CisgICAgfQorICAgIGlmIChjY3R4dC0+aW5vZGUtPmRlcHRoICE9IGNjdHh0LT5kZXB0aCkgeworCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAorCSJ4c2x0Q29tcGlsZXJOb2RlUG9wOiBEZXB0aCBtaXNtYXRjaC5cbiIpOworCWdvdG8gbWlzbWF0Y2g7CisgICAgfQorICAgIC8qCisgICAgKiBQb3AgaW5mb3JtYXRpb24gb2YgdmFyaWFibGVzLgorICAgICovCisgICAgaWYgKChjY3R4dC0+aXZhcikgJiYgKGNjdHh0LT5pdmFyLT5kZXB0aCA+IGNjdHh0LT5kZXB0aCkpCisJeHNsdENvbXBpbGVyVmFySW5mb1BvcChjY3R4dCk7CisKKyAgICBjY3R4dC0+ZGVwdGgtLTsKKyAgICBjY3R4dC0+aW5vZGUgPSBjY3R4dC0+aW5vZGUtPnByZXY7CisgICAgaWYgKGNjdHh0LT5pbm9kZSAhPSBOVUxMKQorCWNjdHh0LT5pbm9kZS0+Y3VyQ2hpbGRUeXBlID0gMDsKKyAgICByZXR1cm47CisKK21pc21hdGNoOgorICAgIHsKKwljb25zdCB4bWxDaGFyICpuc05hbWUgPSBOVUxMLCAqbmFtZSA9IE5VTEw7CisJY29uc3QgeG1sQ2hhciAqaW5mbnNOYW1lID0gTlVMTCwgKmluZm5hbWUgPSBOVUxMOworCQorCWlmIChub2RlKSB7CisJICAgIGlmIChub2RlLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKKwkJbmFtZSA9IG5vZGUtPm5hbWU7CisJCWlmIChub2RlLT5ucyAhPSBOVUxMKQorCQkgICAgbnNOYW1lID0gbm9kZS0+bnMtPmhyZWY7CisJCWVsc2UKKwkJICAgIG5zTmFtZSA9IEJBRF9DQVNUICIiOworCSAgICB9IGVsc2UgeworCQluYW1lID0gQkFEX0NBU1QgIiNkb2N1bWVudCI7CisJCW5zTmFtZSA9IEJBRF9DQVNUICIiOworCSAgICB9CisJfSBlbHNlCisJICAgIG5hbWUgPSBCQURfQ0FTVCAiTm90IGdpdmVuIjsKKworCWlmIChjY3R4dC0+aW5vZGUtPm5vZGUpIHsKKwkgICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgeworCQlpbmZuYW1lID0gY2N0eHQtPmlub2RlLT5ub2RlLT5uYW1lOworCQlpZiAoY2N0eHQtPmlub2RlLT5ub2RlLT5ucyAhPSBOVUxMKQorCQkgICAgaW5mbnNOYW1lID0gY2N0eHQtPmlub2RlLT5ub2RlLT5ucy0+aHJlZjsKKwkJZWxzZQorCQkgICAgaW5mbnNOYW1lID0gQkFEX0NBU1QgIiI7CisJICAgIH0gZWxzZSB7CisJCWluZm5hbWUgPSBCQURfQ0FTVCAiI2RvY3VtZW50IjsKKwkJaW5mbnNOYW1lID0gQkFEX0NBU1QgIiI7CisJICAgIH0KKwl9IGVsc2UKKwkgICAgaW5mbmFtZSA9IEJBRF9DQVNUICJOb3QgZ2l2ZW4iOworCisJCisJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCisJICAgICJ4c2x0Q29tcGlsZXJOb2RlUG9wOiBHaXZlbiAgIDogJyVzJyBVUkkgJyVzJ1xuIiwKKwkgICAgbmFtZSwgbnNOYW1lKTsKKwl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKKwkgICAgInhzbHRDb21waWxlck5vZGVQb3A6IEV4cGVjdGVkOiAnJXMnIFVSSSAnJXMnXG4iLAorCSAgICBpbmZuYW1lLCBpbmZuc05hbWUpOworICAgIH0KK30KKworLyoKKyogeHNsdENvbXBpbGVyQnVpbGRJblNjb3BlTnNMaXN0OgorKgorKiBDcmVhdGUgYW5kIHN0b3JlIHRoZSBsaXN0IG9mIGluLXNjb3BlIG5hbWVzcGFjZXMgZm9yIHRoZSBnaXZlbgorKiBub2RlIGluIHRoZSBzdHlsZXNoZWV0LiBJZiB0aGVyZSBhcmUgbm8gY2hhbmdlcyBpbiB0aGUgaW4tc2NvcGUKKyogbmFtZXNwYWNlcyB0aGVuIHRoZSBsYXN0IG5zLWluZm8gb2YgdGhlIGFuY2VzdG9yIGF4aXMgd2lsbCBiZSByZXR1cm5lZC4KKyogQ29tcGlsYXRpb24tdGltZSBvbmx5LgorKgorKiBSZXR1cm5zIHRoZSBucy1pbmZvIG9yIE5VTEwgaWYgdGhlcmUgYXJlIG5vIG5hbWVzcGFjZXMgaW4gc2NvcGUuCisqLworc3RhdGljIHhzbHROc0xpc3RDb250YWluZXJQdHIKK3hzbHRDb21waWxlckJ1aWxkSW5TY29wZU5zTGlzdCh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCit7CisgICAgeHNsdE5zTGlzdENvbnRhaW5lclB0ciBuc2kgPSBOVUxMOworICAgIHhtbE5zUHRyICpsaXN0ID0gTlVMTCwgbnM7CisgICAgaW50IGksIG1heG5zID0gNTsKKyAgICAvKgorICAgICogQ3JlYXRlIGEgbmV3IG5zLWxpc3QgZm9yIHRoaXMgcG9zaXRpb24gaW4gdGhlIG5vZGUtdHJlZS4KKyAgICAqIHhtbEdldE5zTGlzdCgpIHdpbGwgcmV0dXJuIE5VTEwsIGlmIHRoZXJlIGFyZSBubyBucy1kZWNscyBpbiB0aGUKKyAgICAqIHRyZWUuIE5vdGUgdGhhdCB0aGUgbnMtZGVjbCBmb3IgdGhlIFhNTCBuYW1lc3BhY2UgaXMgbm90IGFkZGVkCisgICAgKiB0byB0aGUgcmVzdWx0aW5nIGxpc3Q7IHRoZSBYUGF0aCBtb2R1bGUgaGFuZGxlcyB0aGUgWE1MIG5hbWVzcGFjZQorICAgICogaW50ZXJuYWxseS4KKyAgICAqLworICAgIHdoaWxlIChub2RlICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgeworICAgICAgICAgICAgbnMgPSBub2RlLT5uc0RlZjsKKyAgICAgICAgICAgIHdoaWxlIChucyAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgaWYgKG5zaSA9PSBOVUxMKSB7CisJCSAgICBuc2kgPSAoeHNsdE5zTGlzdENvbnRhaW5lclB0cikKKwkJCXhtbE1hbGxvYyhzaXplb2YoeHNsdE5zTGlzdENvbnRhaW5lcikpOworCQkgICAgaWYgKG5zaSA9PSBOVUxMKSB7CisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBOVUxMLAorCQkJICAgICJ4c2x0Q29tcGlsZXJCdWlsZEluU2NvcGVOc0xpc3Q6ICIKKwkJCSAgICAibWFsbG9jIGZhaWxlZCFcbiIpOworCQkJZ290byBpbnRlcm5hbF9lcnI7CisJCSAgICB9CisJCSAgICBtZW1zZXQobnNpLCAwLCBzaXplb2YoeHNsdE5zTGlzdENvbnRhaW5lcikpOworICAgICAgICAgICAgICAgICAgICBuc2ktPmxpc3QgPQorICAgICAgICAgICAgICAgICAgICAgICAgKHhtbE5zUHRyICopIHhtbE1hbGxvYyhtYXhucyAqIHNpemVvZih4bWxOc1B0cikpOworICAgICAgICAgICAgICAgICAgICBpZiAobnNpLT5saXN0ID09IE5VTEwpIHsKKwkJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIE5VTEwsCisJCQkgICAgInhzbHRDb21waWxlckJ1aWxkSW5TY29wZU5zTGlzdDogIgorCQkJICAgICJtYWxsb2MgZmFpbGVkIVxuIik7CisJCQlnb3RvIGludGVybmFsX2VycjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBuc2ktPmxpc3RbMF0gPSBOVUxMOworICAgICAgICAgICAgICAgIH0KKwkJLyoKKwkJKiBTa2lwIHNoYWRvd2VkIG5hbWVzcGFjZSBiaW5kaW5ncy4KKwkJKi8KKyAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnNpLT50b3RhbE51bWJlcjsgaSsrKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICgobnMtPnByZWZpeCA9PSBuc2ktPmxpc3RbaV0tPnByZWZpeCkgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICh4bWxTdHJFcXVhbChucy0+cHJlZml4LCBuc2ktPmxpc3RbaV0tPnByZWZpeCkpKQorCQkgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChpID49IG5zaS0+dG90YWxOdW1iZXIpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG5zaS0+dG90YWxOdW1iZXIgKzEgPj0gbWF4bnMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG1heG5zICo9IDI7CisJCQluc2ktPmxpc3QgPQorCQkJICAgICh4bWxOc1B0ciAqKSB4bWxSZWFsbG9jKG5zaS0+bGlzdCwKKwkJCQltYXhucyAqIHNpemVvZih4bWxOc1B0cikpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5zaS0+bGlzdCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgTlVMTCwKKwkJCQkieHNsdENvbXBpbGVyQnVpbGRJblNjb3BlTnNMaXN0OiAiCisJCQkJInJlYWxsb2MgZmFpbGVkIVxuIik7CisJCQkJZ290byBpbnRlcm5hbF9lcnI7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbnNpLT5saXN0W25zaS0+dG90YWxOdW1iZXIrK10gPSBuczsKKyAgICAgICAgICAgICAgICAgICAgbnNpLT5saXN0W25zaS0+dG90YWxOdW1iZXJdID0gTlVMTDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBucyA9IG5zLT5uZXh0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG5vZGUgPSBub2RlLT5wYXJlbnQ7CisgICAgfQorICAgIGlmIChuc2kgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisgICAgLyoKKyAgICAqIE1vdmUgdGhlIGRlZmF1bHQgbmFtZXNwYWNlIHRvIGxhc3QgcG9zaXRpb24uCisgICAgKi8KKyAgICBuc2ktPnhwYXRoTnVtYmVyID0gbnNpLT50b3RhbE51bWJlcjsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbnNpLT50b3RhbE51bWJlcjsgaSsrKSB7CisJaWYgKG5zaS0+bGlzdFtpXS0+cHJlZml4ID09IE5VTEwpIHsKKwkgICAgbnMgPSBuc2ktPmxpc3RbaV07CisJICAgIG5zaS0+bGlzdFtpXSA9IG5zaS0+bGlzdFtuc2ktPnRvdGFsTnVtYmVyLTFdOworCSAgICBuc2ktPmxpc3RbbnNpLT50b3RhbE51bWJlci0xXSA9IG5zOworCSAgICBuc2ktPnhwYXRoTnVtYmVyLS07CisJICAgIGJyZWFrOworCX0KKyAgICB9CisgICAgLyoKKyAgICAqIFN0b3JlIHRoZSBucy1saXN0IGluIHRoZSBzdHlsZXNoZWV0LgorICAgICovCisgICAgaWYgKHhzbHRQb2ludGVyTGlzdEFkZFNpemUoCisJKHhzbHRQb2ludGVyTGlzdFB0ciljY3R4dC0+cHNEYXRhLT5pblNjb3BlTmFtZXNwYWNlcywKKwkodm9pZCAqKSBuc2ksIDUpID09IC0xKQorICAgIHsJCisJeG1sRnJlZShuc2kpOworCW5zaSA9IE5VTEw7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgTlVMTCwKKwkgICAgInhzbHRDb21waWxlckJ1aWxkSW5TY29wZU5zTGlzdDogZmFpbGVkIHRvIGFkZCBucy1pbmZvLlxuIik7CisJZ290byBpbnRlcm5hbF9lcnI7CisgICAgfQorICAgIC8qCisgICAgKiBOb3RpZnkgb2YgY2hhbmdlIGluIHN0YXR1cyB3cnQgbmFtZXNwYWNlcy4KKyAgICAqLworICAgIGlmIChjY3R4dC0+aW5vZGUgIT0gTlVMTCkKKwljY3R4dC0+aW5vZGUtPm5zQ2hhbmdlZCA9IDE7CisKKyAgICByZXR1cm4obnNpKTsKKworaW50ZXJuYWxfZXJyOgorICAgIGlmIChsaXN0ICE9IE5VTEwpCisJeG1sRnJlZShsaXN0KTsgICAgCisgICAgY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKyAgICByZXR1cm4oTlVMTCk7Cit9CisKK3N0YXRpYyBpbnQKK3hzbHRQYXJzZU5zUHJlZml4TGlzdCh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0LAorCQkgICAgICB4c2x0UG9pbnRlckxpc3RQdHIgbGlzdCwKKwkJICAgICAgeG1sTm9kZVB0ciBub2RlLAorCQkgICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSkKK3sKKyAgICB4bWxDaGFyICpjdXIsICplbmQ7CisgICAgeG1sTnNQdHIgbnM7CisgICAgCisgICAgaWYgKChjY3R4dCA9PSBOVUxMKSB8fCAodmFsdWUgPT0gTlVMTCkgfHwgKGxpc3QgPT0gTlVMTCkpCisJcmV0dXJuKC0xKTsKKworICAgIGxpc3QtPm51bWJlciA9IDA7CisKKyAgICBjdXIgPSAoeG1sQ2hhciAqKSB2YWx1ZTsKKyAgICB3aGlsZSAoKmN1ciAhPSAwKSB7CisJd2hpbGUgKElTX0JMQU5LKCpjdXIpKSBjdXIrKzsKKwlpZiAoKmN1ciA9PSAwKQorCSAgICBicmVhazsKKwllbmQgPSBjdXI7CisJd2hpbGUgKCgqZW5kICE9IDApICYmICghSVNfQkxBTksoKmVuZCkpKSBlbmQrKzsKKwljdXIgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKKwlpZiAoY3VyID09IE5VTEwpIHsKKwkgICAgY3VyID0gZW5kOworCSAgICBjb250aW51ZTsKKwl9CQkKKwkvKgorCSogVE9ETzogRXhwb3J0IGFuZCB1c2UgeG1sU2VhcmNoTnNCeVByZWZpeFN0cmljdCgpCisJKiAgIGluIExpYnhtbDIsIHRyZWUuYywgc2luY2UgeG1sU2VhcmNoTnMoKSBpcyBpbiBtb3N0CisJKiAgIGNhc2VzIG5vdCBlZmZpY2llbnQgYW5kIGluIHNvbWUgY2FzZXMgbm90IGNvcnJlY3QuCisJKgorCSogWFNMVC0yIFRPRE86IFhTTFQgMi4wIGFsbG93cyBhbiBhZGRpdGlvbmFsICIjYWxsIiB2YWx1ZS4KKwkqLworCWlmICgoY3VyWzBdID09ICcjJykgJiYKKwkgICAgeG1sU3RyRXF1YWwoY3VyLCAoY29uc3QgeG1sQ2hhciAqKSIjZGVmYXVsdCIpKQorCSAgICBucyA9IHhtbFNlYXJjaE5zKGNjdHh0LT5zdHlsZS0+ZG9jLCBub2RlLCBOVUxMKTsKKwllbHNlCisJICAgIG5zID0geG1sU2VhcmNoTnMoY2N0eHQtPnN0eWxlLT5kb2MsIG5vZGUsIGN1cik7CSAgICAKKworCWlmIChucyA9PSBOVUxMKSB7CisJICAgIC8qCisJICAgICogVE9ETzogQmV0dGVyIHRvIHJlcG9ydCB0aGUgYXR0ci1ub2RlLCBvdGhlcndpc2UKKwkgICAgKiAgdGhlIHVzZXIgd29uJ3Qga25vdyB3aGljaCBhdHRyaWJ1dGUgd2FzIGludmFsaWQuCisJICAgICovCisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIG5vZGUsCisJCSJObyBuYW1lc3BhY2UgYmluZGluZyBpbiBzY29wZSBmb3IgcHJlZml4ICclcycuXG4iLCBjdXIpOworCSAgICAvKgorCSAgICAqIFhTTFQtMS4wOiAiSXQgaXMgYW4gZXJyb3IgaWYgdGhlcmUgaXMgbm8gbmFtZXNwYWNlCisJICAgICogIGJvdW5kIHRvIHRoZSBwcmVmaXggb24gdGhlIGVsZW1lbnQgYmVhcmluZyB0aGUKKwkgICAgKiAgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgb3IgeHNsOmV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzCisJICAgICogIGF0dHJpYnV0ZS4iCisJICAgICovCisJICAgIGNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJfSBlbHNlIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkicmVzb2x2ZWQgcHJlZml4ICclcydcbiIsIGN1cik7CisjZW5kaWYKKwkgICAgLyoKKwkgICAgKiBOb3RlIHRoYXQgd2UgcHV0IHRoZSBuYW1lc3BhY2UgbmFtZSBpbnRvIHRoZSBkaWN0LgorCSAgICAqLworCSAgICBpZiAoeHNsdFBvaW50ZXJMaXN0QWRkU2l6ZShsaXN0LAorCQkodm9pZCAqKSB4bWxEaWN0TG9va3VwKGNjdHh0LT5zdHlsZS0+ZGljdCwKKwkJbnMtPmhyZWYsIC0xKSwgNSkgPT0gLTEpCisJICAgIHsKKwkJeG1sRnJlZShjdXIpOworCQlnb3RvIGludGVybmFsX2VycjsKKwkgICAgfQorCX0KKwl4bWxGcmVlKGN1cik7CisJCQorCWN1ciA9IGVuZDsKKyAgICB9CisgICAgcmV0dXJuKDApOworCitpbnRlcm5hbF9lcnI6CisgICAgY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKyAgICByZXR1cm4oLTEpOworfQorCisvKioKKyAqIHhzbHRDb21waWxlclV0aWxzQ3JlYXRlTWVyZ2VkTGlzdDoKKyAqIEBkZXN0OiB0aGUgZGVzdGluYXRpb24gbGlzdCAob3B0aW9uYWwpCisgKiBAZmlyc3Q6IHRoZSBmaXJzdCBsaXN0CisgKiBAc2Vjb25kOiB0aGUgc2Vjb25kIGxpc3QgKG9wdGlvbmFsKQorICoKKyAqIEFwcGVuZHMgdGhlIGNvbnRlbnQgb2YgQHNlY29uZCB0byBAZmlyc3QgaW50byBAZGVzdGluYXRpb24uCisgKiBJZiBAZGVzdGluYXRpb24gaXMgTlVMTCBhIG5ldyBsaXN0IHdpbGwgYmUgY3JlYXRlZC4KKyAqCisgKiBSZXR1cm5zIHRoZSBtZXJnZWQgbGlzdCBvZiBpdGVtcyBvciBOVUxMIGlmIHRoZXJlJ3Mgbm90aGluZyB0byBtZXJnZS4KKyAqLworc3RhdGljIHhzbHRQb2ludGVyTGlzdFB0cgoreHNsdENvbXBpbGVyVXRpbHNDcmVhdGVNZXJnZWRMaXN0KHhzbHRQb2ludGVyTGlzdFB0ciBmaXJzdCwKKwkJCSAgICB4c2x0UG9pbnRlckxpc3RQdHIgc2Vjb25kKQoreworICAgIHhzbHRQb2ludGVyTGlzdFB0ciByZXQ7CisgICAgc2l6ZV90IG51bTsKKworICAgIGlmIChmaXJzdCkKKwludW0gPSBmaXJzdC0+bnVtYmVyOworICAgIGVsc2UKKwludW0gPSAwOworICAgIGlmIChzZWNvbmQpCisJbnVtICs9IHNlY29uZC0+bnVtYmVyOyAgICAKKyAgICBpZiAobnVtID09IDApCisJcmV0dXJuKE5VTEwpOworICAgIHJldCA9IHhzbHRQb2ludGVyTGlzdENyZWF0ZShudW0pOworICAgIGlmIChyZXQgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisgICAgLyoKKyAgICAqIENvcHkgY29udGVudHMuCisgICAgKi8KKyAgICBpZiAoKGZpcnN0ICE9IE5VTEwpICYmICAoZmlyc3QtPm51bWJlciAhPSAwKSkgeworCW1lbWNweShyZXQtPml0ZW1zLCBmaXJzdC0+aXRlbXMsCisJICAgIGZpcnN0LT5udW1iZXIgKiBzaXplb2Yodm9pZCAqKSk7CisJaWYgKChzZWNvbmQgIT0gTlVMTCkgJiYgKHNlY29uZC0+bnVtYmVyICE9IDApKQorCSAgICBtZW1jcHkocmV0LT5pdGVtcyArIGZpcnN0LT5udW1iZXIsIHNlY29uZC0+aXRlbXMsCisJCXNlY29uZC0+bnVtYmVyICogc2l6ZW9mKHZvaWQgKikpOworICAgIH0gZWxzZSBpZiAoKHNlY29uZCAhPSBOVUxMKSAmJiAoc2Vjb25kLT5udW1iZXIgIT0gMCkpCisJbWVtY3B5KHJldC0+aXRlbXMsICh2b2lkICopIHNlY29uZC0+aXRlbXMsCisJICAgIHNlY29uZC0+bnVtYmVyICogc2l6ZW9mKHZvaWQgKikpOworICAgIHJldC0+bnVtYmVyID0gbnVtOworICAgIHJldHVybihyZXQpOworfQorCisvKgorKiB4c2x0UGFyc2VFeGNsUmVzdWx0UHJlZml4ZXM6CisqCisqIENyZWF0ZSBhbmQgc3RvcmUgdGhlIGxpc3Qgb2YgaW4tc2NvcGUgbmFtZXNwYWNlcyBmb3IgdGhlIGdpdmVuCisqIG5vZGUgaW4gdGhlIHN0eWxlc2hlZXQuIElmIHRoZXJlIGFyZSBubyBjaGFuZ2VzIGluIHRoZSBpbi1zY29wZQorKiBuYW1lc3BhY2VzIHRoZW4gdGhlIGxhc3QgbnMtaW5mbyBvZiB0aGUgYW5jZXN0b3IgYXhpcyB3aWxsIGJlIHJldHVybmVkLgorKiBDb21waWxhdGlvbi10aW1lIG9ubHkuCisqCisqIFJldHVybnMgdGhlIG5zLWluZm8gb3IgTlVMTCBpZiB0aGVyZSBhcmUgbm8gbmFtZXNwYWNlcyBpbiBzY29wZS4KKyovCitzdGF0aWMgeHNsdFBvaW50ZXJMaXN0UHRyCit4c2x0UGFyc2VFeGNsUmVzdWx0UHJlZml4ZXMoeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwgeG1sTm9kZVB0ciBub2RlLAorCQkJICAgIHhzbHRQb2ludGVyTGlzdFB0ciBkZWYsCisJCQkgICAgaW50IGluc3RyQ2F0ZWdvcnkpCit7ICAgIAorICAgIHhzbHRQb2ludGVyTGlzdFB0ciBsaXN0ID0gTlVMTDsKKyAgICB4bWxDaGFyICp2YWx1ZTsKKyAgICB4bWxBdHRyUHRyIGF0dHI7CisKKyAgICBpZiAoKGNjdHh0ID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQorCXJldHVybihOVUxMKTsKKworICAgIGlmIChpbnN0ckNhdGVnb3J5ID09IFhTTFRfRUxFTUVOVF9DQVRFR09SWV9YU0xUKQorCWF0dHIgPSB4bWxIYXNOc1Byb3Aobm9kZSwgQkFEX0NBU1QgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiwgTlVMTCk7CisgICAgZWxzZQorCWF0dHIgPSB4bWxIYXNOc1Byb3Aobm9kZSwgQkFEX0NBU1QgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiwKKwkgICAgWFNMVF9OQU1FU1BBQ0UpOworICAgIGlmIChhdHRyID09IE5VTEwpCQorCXJldHVybihkZWYpOworCisgICAgaWYgKGF0dHIgJiYgKGluc3RyQ2F0ZWdvcnkgPT0gWFNMVF9FTEVNRU5UX0NBVEVHT1JZX0xSRSkpIHsKKwkvKgorCSogTWFyayB0aGUgWFNMVCBhdHRyLgorCSovCisJYXR0ci0+cHN2aSA9ICh2b2lkICopIHhzbHRYU0xUQXR0ck1hcmtlcjsKKyAgICB9CisKKyAgICBpZiAoKGF0dHItPmNoaWxkcmVuICE9IE5VTEwpICYmCQorCShhdHRyLT5jaGlsZHJlbi0+Y29udGVudCAhPSBOVUxMKSkKKwl2YWx1ZSA9IGF0dHItPmNoaWxkcmVuLT5jb250ZW50OworICAgIGVsc2UgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIG5vZGUsCisJICAgICJBdHRyaWJ1dGUgJ2V4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzJzogSW52YWxpZCB2YWx1ZS5cbiIpOworCWNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuKGRlZik7CisgICAgfSAgICAgICAgCisKKyAgICBpZiAoeHNsdFBhcnNlTnNQcmVmaXhMaXN0KGNjdHh0LCBjY3R4dC0+dG1wTGlzdCwgbm9kZSwKKwlCQURfQ0FTVCB2YWx1ZSkgIT0gMCkKKwlnb3RvIGV4aXQ7CisgICAgaWYgKGNjdHh0LT50bXBMaXN0LT5udW1iZXIgPT0gMCkJCisJZ290byBleGl0OyAgICAKKyAgICAvKgorICAgICogTWVyZ2UgdGhlIGxpc3Qgd2l0aCB0aGUgaW5oZXJpdGVkIGxpc3QuCisgICAgKi8KKyAgICBsaXN0ID0geHNsdENvbXBpbGVyVXRpbHNDcmVhdGVNZXJnZWRMaXN0KGRlZiwgY2N0eHQtPnRtcExpc3QpOworICAgIGlmIChsaXN0ID09IE5VTEwpCisJZ290byBleGl0OyAgICAKKyAgICAvKgorICAgICogU3RvcmUgdGhlIGxpc3QgaW4gdGhlIHN0eWxlc2hlZXQvY29tcGlsZXIgY29udGV4dC4KKyAgICAqLworICAgIGlmICh4c2x0UG9pbnRlckxpc3RBZGRTaXplKAorCWNjdHh0LT5wc0RhdGEtPmV4Y2xSZXN1bHROYW1lc3BhY2VzLCBsaXN0LCA1KSA9PSAtMSkKKyAgICB7CisJeHNsdFBvaW50ZXJMaXN0RnJlZShsaXN0KTsKKwlsaXN0ID0gTlVMTDsKKwlnb3RvIGV4aXQ7CisgICAgfQorICAgIC8qCisgICAgKiBOb3RpZnkgb2YgY2hhbmdlIGluIHN0YXR1cyB3cnQgbmFtZXNwYWNlcy4KKyAgICAqLworICAgIGlmIChjY3R4dC0+aW5vZGUgIT0gTlVMTCkKKwljY3R4dC0+aW5vZGUtPm5zQ2hhbmdlZCA9IDE7CisKK2V4aXQ6ICAgIAorICAgIGlmIChsaXN0ICE9IE5VTEwpCisJcmV0dXJuKGxpc3QpOworICAgIGVsc2UKKwlyZXR1cm4oZGVmKTsKK30KKworLyoKKyogeHNsdFBhcnNlRXh0RWxlbVByZWZpeGVzOgorKgorKiBDcmVhdGUgYW5kIHN0b3JlIHRoZSBsaXN0IG9mIGluLXNjb3BlIG5hbWVzcGFjZXMgZm9yIHRoZSBnaXZlbgorKiBub2RlIGluIHRoZSBzdHlsZXNoZWV0LiBJZiB0aGVyZSBhcmUgbm8gY2hhbmdlcyBpbiB0aGUgaW4tc2NvcGUKKyogbmFtZXNwYWNlcyB0aGVuIHRoZSBsYXN0IG5zLWluZm8gb2YgdGhlIGFuY2VzdG9yIGF4aXMgd2lsbCBiZSByZXR1cm5lZC4KKyogQ29tcGlsYXRpb24tdGltZSBvbmx5LgorKgorKiBSZXR1cm5zIHRoZSBucy1pbmZvIG9yIE5VTEwgaWYgdGhlcmUgYXJlIG5vIG5hbWVzcGFjZXMgaW4gc2NvcGUuCisqLworc3RhdGljIHhzbHRQb2ludGVyTGlzdFB0cgoreHNsdFBhcnNlRXh0RWxlbVByZWZpeGVzKHhzbHRDb21waWxlckN0eHRQdHIgY2N0eHQsIHhtbE5vZGVQdHIgbm9kZSwKKwkJCSB4c2x0UG9pbnRlckxpc3RQdHIgZGVmLAorCQkJIGludCBpbnN0ckNhdGVnb3J5KQoreyAgICAKKyAgICB4c2x0UG9pbnRlckxpc3RQdHIgbGlzdCA9IE5VTEw7CisgICAgeG1sQXR0clB0ciBhdHRyOworICAgIHhtbENoYXIgKnZhbHVlOworICAgIGludCBpOworCisgICAgaWYgKChjY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICBpZiAoaW5zdHJDYXRlZ29yeSA9PSBYU0xUX0VMRU1FTlRfQ0FURUdPUllfWFNMVCkKKwlhdHRyID0geG1sSGFzTnNQcm9wKG5vZGUsIEJBRF9DQVNUICJleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyIsIE5VTEwpOworICAgIGVsc2UKKwlhdHRyID0geG1sSGFzTnNQcm9wKG5vZGUsIEJBRF9DQVNUICJleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyIsCisJICAgIFhTTFRfTkFNRVNQQUNFKTsKKyAgICBpZiAoYXR0ciA9PSBOVUxMKQkKKwlyZXR1cm4oZGVmKTsKKworICAgIGlmIChhdHRyICYmIChpbnN0ckNhdGVnb3J5ID09IFhTTFRfRUxFTUVOVF9DQVRFR09SWV9MUkUpKSB7CisJLyoKKwkqIE1hcmsgdGhlIFhTTFQgYXR0ci4KKwkqLworCWF0dHItPnBzdmkgPSAodm9pZCAqKSB4c2x0WFNMVEF0dHJNYXJrZXI7CisgICAgfQorCisgICAgaWYgKChhdHRyLT5jaGlsZHJlbiAhPSBOVUxMKSAmJgkKKwkoYXR0ci0+Y2hpbGRyZW4tPmNvbnRlbnQgIT0gTlVMTCkpCisJdmFsdWUgPSBhdHRyLT5jaGlsZHJlbi0+Y29udGVudDsKKyAgICBlbHNlIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBub2RlLAorCSAgICAiQXR0cmlidXRlICdleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyc6IEludmFsaWQgdmFsdWUuXG4iKTsKKwljY3R4dC0+c3R5bGUtPmVycm9ycysrOworCXJldHVybihkZWYpOworICAgIH0KKworCisgICAgaWYgKHhzbHRQYXJzZU5zUHJlZml4TGlzdChjY3R4dCwgY2N0eHQtPnRtcExpc3QsIG5vZGUsCisJQkFEX0NBU1QgdmFsdWUpICE9IDApCisJZ290byBleGl0OworCisgICAgaWYgKGNjdHh0LT50bXBMaXN0LT5udW1iZXIgPT0gMCkKKwlnb3RvIGV4aXQ7ICAgIAorICAgIC8qCisgICAgKiBSRVZJU0lUOiBSZWdpc3RlciB0aGUgZXh0ZW5zaW9uIG5hbWVzcGFjZXMuCisgICAgKi8KKyAgICBmb3IgKGkgPSAwOyBpIDwgY2N0eHQtPnRtcExpc3QtPm51bWJlcjsgaSsrKQorCXhzbHRSZWdpc3RlckV4dFByZWZpeChjY3R4dC0+c3R5bGUsIE5VTEwsCisJQkFEX0NBU1QgY2N0eHQtPnRtcExpc3QtPml0ZW1zW2ldKTsKKyAgICAvKgorICAgICogTWVyZ2UgdGhlIGxpc3Qgd2l0aCB0aGUgaW5oZXJpdGVkIGxpc3QuCisgICAgKi8KKyAgICBsaXN0ID0geHNsdENvbXBpbGVyVXRpbHNDcmVhdGVNZXJnZWRMaXN0KGRlZiwgY2N0eHQtPnRtcExpc3QpOworICAgIGlmIChsaXN0ID09IE5VTEwpCisJZ290byBleGl0OworICAgIC8qCisgICAgKiBTdG9yZSB0aGUgbGlzdCBpbiB0aGUgc3R5bGVzaGVldC4KKyAgICAqLworICAgIGlmICh4c2x0UG9pbnRlckxpc3RBZGRTaXplKAorCWNjdHh0LT5wc0RhdGEtPmV4dEVsZW1OYW1lc3BhY2VzLCBsaXN0LCA1KSA9PSAtMSkKKyAgICB7CisJeHNsdFBvaW50ZXJMaXN0RnJlZShsaXN0KTsKKwlsaXN0ID0gTlVMTDsKKwlnb3RvIGV4aXQ7CisgICAgfQorICAgIC8qCisgICAgKiBOb3RpZnkgb2YgY2hhbmdlIGluIHN0YXR1cyB3cnQgbmFtZXNwYWNlcy4KKyAgICAqLworICAgIGlmIChjY3R4dC0+aW5vZGUgIT0gTlVMTCkKKwljY3R4dC0+aW5vZGUtPm5zQ2hhbmdlZCA9IDE7CisKK2V4aXQ6ICAgIAorICAgIGlmIChsaXN0ICE9IE5VTEwpCisJcmV0dXJuKGxpc3QpOworICAgIGVsc2UKKwlyZXR1cm4oZGVmKTsKK30KKworLyoKKyogeHNsdFBhcnNlQXR0clhTTFRWZXJzaW9uOgorKgorKiBAY2N0eHQ6IHRoZSBjb21waWxhdGlvbiBjb250ZXh0CisqIEBub2RlOiB0aGUgZWxlbWVudC1ub2RlCisqIEBpc1hzbHRFbGVtOiB3aGV0aGVyIHRoaXMgaXMgYW4gWFNMVCBlbGVtZW50CisqCisqIFBhcnNlcyB0aGUgYXR0cmlidXRlIHhzbDp2ZXJzaW9uLgorKgorKiBSZXR1cm5zIDEgaWYgdGhlcmUgd2FzIHN1Y2ggYW4gYXR0cmlidXRlLCAwIGlmIG5vdCBhbmQKKyogICAgICAgICAtMSBpZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3Igb2NjdXJlZC4KKyovCitzdGF0aWMgaW50Cit4c2x0UGFyc2VBdHRyWFNMVFZlcnNpb24oeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwgeG1sTm9kZVB0ciBub2RlLAkJCSAKKwkJCSBpbnQgaW5zdHJDYXRlZ29yeSkKK3sKKyAgICB4bWxDaGFyICp2YWx1ZTsKKyAgICB4bWxBdHRyUHRyIGF0dHI7CisKKyAgICBpZiAoKGNjdHh0ID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQorCXJldHVybigtMSk7CisKKyAgICBpZiAoaW5zdHJDYXRlZ29yeSA9PSBYU0xUX0VMRU1FTlRfQ0FURUdPUllfWFNMVCkKKwlhdHRyID0geG1sSGFzTnNQcm9wKG5vZGUsIEJBRF9DQVNUICJ2ZXJzaW9uIiwgTlVMTCk7CisgICAgZWxzZQorCWF0dHIgPSB4bWxIYXNOc1Byb3Aobm9kZSwgQkFEX0NBU1QgInZlcnNpb24iLCBYU0xUX05BTUVTUEFDRSk7CisKKyAgICBpZiAoYXR0ciA9PSBOVUxMKQkKKwlyZXR1cm4oMCk7CisKKyAgICBhdHRyLT5wc3ZpID0gKHZvaWQgKikgeHNsdFhTTFRBdHRyTWFya2VyOworCisgICAgaWYgKChhdHRyLT5jaGlsZHJlbiAhPSBOVUxMKSAmJgkKKwkoYXR0ci0+Y2hpbGRyZW4tPmNvbnRlbnQgIT0gTlVMTCkpCisJdmFsdWUgPSBhdHRyLT5jaGlsZHJlbi0+Y29udGVudDsKKyAgICBlbHNlIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBub2RlLAorCSAgICAiQXR0cmlidXRlICd2ZXJzaW9uJzogSW52YWxpZCB2YWx1ZS5cbiIpOworCWNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuKDEpOworICAgIH0KKyAgICAKKyAgICBpZiAoISB4bWxTdHJFcXVhbCh2YWx1ZSwgKGNvbnN0IHhtbENoYXIgKikiMS4wIikpIHsKKwljY3R4dC0+aW5vZGUtPmZvcndhcmRzQ29tcGF0ID0gMTsKKwkvKgorCSogVE9ETzogVG8gd2hhdCBleHRlbnQgZG8gd2Ugc3VwcG9ydCB0aGUKKwkqICBmb3J3YXJkcy1jb21wYXRpYmxlIG1vZGU/CisJKi8KKwkvKgorCSogUmVwb3J0IHRoaXMgb25seSBvbmNlIHBlciBjb21waWxhdGlvbiBlcGlzb2RlLgorCSovCisJaWYgKCEgY2N0eHQtPmhhc0ZvcndhcmRzQ29tcGF0KSB7CisJICAgIGNjdHh0LT5oYXNGb3J3YXJkc0NvbXBhdCA9IDE7CisJICAgIGNjdHh0LT5lcnJTZXZlcml0eSA9IFhTTFRfRVJST1JfU0VWRVJJVFlfV0FSTklORzsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgbm9kZSwKKwkJIldhcm5pbmc6IHRoZSBhdHRyaWJ1dGUgeHNsOnZlcnNpb24gc3BlY2lmaWVzIGEgdmFsdWUgIgorCQkiZGlmZmVyZW50IGZyb20gJzEuMCcuIFN3aXRjaGluZyB0byBmb3J3YXJkcy1jb21wYXRpYmxlICIKKwkJIm1vZGUuIE9ubHkgZmVhdHVyZXMgb2YgWFNMVCAxLjAgYXJlIHN1cHBvcnRlZCBieSB0aGlzICIKKwkJInByb2Nlc3Nvci5cbiIpOworCSAgICBjY3R4dC0+c3R5bGUtPndhcm5pbmdzKys7CisJICAgIGNjdHh0LT5lcnJTZXZlcml0eSA9IFhTTFRfRVJST1JfU0VWRVJJVFlfRVJST1I7CisJfQkKKyAgICB9IGVsc2UgeworCWNjdHh0LT5pbm9kZS0+Zm9yd2FyZHNDb21wYXQgPSAwOworICAgIH0KKworICAgIGlmIChhdHRyICYmIChpbnN0ckNhdGVnb3J5ID09IFhTTFRfRUxFTUVOVF9DQVRFR09SWV9MUkUpKSB7CisJLyoKKwkqIFNldCBhIG1hcmtlciBvbiBYU0xUIGF0dHJpYnV0ZXMuCisJKi8KKwlhdHRyLT5wc3ZpID0gKHZvaWQgKikgeHNsdFhTTFRBdHRyTWFya2VyOworICAgIH0KKyAgICByZXR1cm4oMSk7Cit9CisKK3N0YXRpYyBpbnQKK3hzbHRQYXJzZVByZXByb2Nlc3NTdHlsZXNoZWV0VHJlZSh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCit7CisgICAgeG1sTm9kZVB0ciBkZWxldGVOb2RlLCBjdXIsIHR4dCwgdGV4dE5vZGUgPSBOVUxMOworICAgIHhtbERvY1B0ciBkb2M7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CisgICAgaW50IGludGVybmFsaXplID0gMCwgZmluZFNwYWNlQXR0cjsKKyAgICBpbnQgeHNsdFN0eWxlc2hlZXRFbGVtRGVwdGg7CisgICAgeG1sQXR0clB0ciBhdHRyOworICAgIHhtbENoYXIgKnZhbHVlOworICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsICpuc05hbWVYU0xUID0gTlVMTDsKKyAgICBpbnQgc3RyaWN0V2hpdGVzcGFjZSwgaW5YU0xUZXh0ID0gMDsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAKKyAgICB4c2x0TnNNYXBQdHIgbnNNYXBJdGVtOworI2VuZGlmCisKKyAgICBpZiAoKGNjdHh0ID09IE5VTEwpIHx8IChjY3R4dC0+c3R5bGUgPT0gTlVMTCkgfHwKKwkobm9kZSA9PSBOVUxMKSB8fCAobm9kZS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSkKKyAgICAgICAgcmV0dXJuKC0xKTsKKworICAgIGRvYyA9IG5vZGUtPmRvYzsKKyAgICBpZiAoZG9jID09IE5VTEwpCisJZ290byBpbnRlcm5hbF9lcnI7CisKKyAgICBzdHlsZSA9IGNjdHh0LT5zdHlsZTsKKyAgICBpZiAoKHN0eWxlLT5kaWN0ICE9IE5VTEwpICYmIChkb2MtPmRpY3QgPT0gc3R5bGUtPmRpY3QpKQorCWludGVybmFsaXplID0gMTsKKyAgICBlbHNlCisgICAgICAgIHN0eWxlLT5pbnRlcm5hbGl6ZWQgPSAwOworCisgICAgLyoKKyAgICAqIEluaXQgdmFsdWUgb2YgeG1sOnNwYWNlLiBTaW5jZSB0aGlzIG1pZ2h0IGJlIGFuIGVtYmVkZGVkCisgICAgKiBzdHlsZXNoZWV0LCB0aGlzIGlzIG5lZWRlZCB0byBiZSBwZXJmb3JtZWQgb24gdGhlIGVsZW1lbnQKKyAgICAqIHdoZXJlIHRoZSBzdHlsZXNoZWV0IGlzIHJvb3RlZCBhdCwgdGFraW5nIHhtbDpzcGFjZSBvZgorICAgICogYW5jZXN0b3JzIGludG8gYWNjb3VudC4KKyAgICAqLworICAgIGlmICghIGNjdHh0LT5zaW1wbGlmaWVkKQorCXhzbHRTdHlsZXNoZWV0RWxlbURlcHRoID0gY2N0eHQtPmRlcHRoICsxOworICAgIGVsc2UKKwl4c2x0U3R5bGVzaGVldEVsZW1EZXB0aCA9IDA7CisKKyAgICBpZiAoeG1sTm9kZUdldFNwYWNlUHJlc2VydmUobm9kZSkgIT0gMSkKKwljY3R4dC0+aW5vZGUtPnByZXNlcnZlV2hpdGVzcGFjZSA9IDA7CisgICAgZWxzZQorCWNjdHh0LT5pbm9kZS0+cHJlc2VydmVXaGl0ZXNwYWNlID0gMTsgCisgICAgCisgICAgLyoKKyAgICAqIEV2YWwgaWYgd2Ugc2hvdWxkIGtlZXAgdGhlIG9sZCBpbmNvcnJlY3QgYmVoYXZpb3VyLgorICAgICovCisgICAgc3RyaWN0V2hpdGVzcGFjZSA9IChjY3R4dC0+c3RyaWN0ICE9IDApID8gMSA6IDA7CisKKyAgICBuc05hbWVYU0xUID0geHNsdENvbnN0TmFtZXNwYWNlTmFtZVhTTFQ7CisKKyAgICBkZWxldGVOb2RlID0gTlVMTDsKKyAgICBjdXIgPSBub2RlOworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCWlmIChkZWxldGVOb2RlICE9IE5VTEwpCXsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19CTEFOS1MKKwkgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0UGFyc2VQcmVwcm9jZXNzU3R5bGVzaGVldFRyZWU6IHJlbW92aW5nIG5vZGVcbiIpOworI2VuZGlmCisJICAgIHhtbFVubGlua05vZGUoZGVsZXRlTm9kZSk7CisJICAgIHhtbEZyZWVOb2RlKGRlbGV0ZU5vZGUpOworCSAgICBkZWxldGVOb2RlID0gTlVMTDsKKwl9CisJaWYgKGN1ci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CisJICAgIAorCSAgICAvKgorCSAgICAqIENsZWFyIHRoZSBQU1ZJIGZpZWxkLgorCSAgICAqLworCSAgICBjdXItPnBzdmkgPSBOVUxMOworCisJICAgIHhzbHRDb21waWxlck5vZGVQdXNoKGNjdHh0LCBjdXIpOworCisJICAgIGluWFNMVGV4dCA9IDA7CisJICAgIHRleHROb2RlID0gTlVMTDsJICAgIAorCSAgICBmaW5kU3BhY2VBdHRyID0gMTsJICAgIAorCSAgICBjY3R4dC0+aW5vZGUtPnN0cmlwV2hpdGVzcGFjZSA9IDA7CisJICAgIC8qCisJICAgICogVE9ETzogSSdkIGxvdmUgdG8gdXNlIGEgc3RyaW5nIHBvaW50ZXIgY29tcGFyaXNvbiBoZXJlIDotLworCSAgICAqLworCSAgICBpZiAoSVNfWFNMVF9FTEVNKGN1cikpIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAKKwkJaWYgKGN1ci0+bnMtPmhyZWYgIT0gbnNOYW1lWFNMVCkgeworCQkgICAgbnNNYXBJdGVtID0geHNsdE5ld05hbWVzcGFjZU1hcEl0ZW0oY2N0eHQsCisJCQlkb2MsIGN1ci0+bnMsIGN1cik7CisJCSAgICBpZiAobnNNYXBJdGVtID09IE5VTEwpCisJCQlnb3RvIGludGVybmFsX2VycjsKKwkJICAgIGN1ci0+bnMtPmhyZWYgPSBuc05hbWVYU0xUOworCQl9CisjZW5kaWYKKworCQlpZiAoY3VyLT5uYW1lID09IE5VTEwpCisJCSAgICBnb3RvIHByb2Nlc3NfYXR0cmlidXRlczsKKwkJLyoKKwkJKiBNYXJrIHRoZSBYU0xUIGVsZW1lbnQgZm9yIGxhdGVyIHJlY29nbml0aW9uLgorCQkqIFRPRE86IFVzaW5nIHRoZSBtYXJrZXIgaXMgc3RpbGwgdG9vIGRhbmdlcm91cywgc2luY2UgaWYKKwkJKiAgIHRoZSBwYXJzaW5nIG1lY2hhbmlzbSBsZWF2ZXMgb3V0IGFuIFhTTFQgZWxlbWVudCwgdGhlbgorCQkqICAgdGhpcyBtaWdodCBoaXQgdGhlIHRyYW5zZm9ybWF0aW9uLW1lY2hhbmlzbSwgd2hpY2gKKwkJKiAgIHdpbGwgYnJlYWsgaWYgaXQgZG9lc24ndCBleHBlY3Qgc3VjaCBhIG1hcmtlci4KKwkJKi8KKwkJLyogY3VyLT5wc3ZpID0gKHZvaWQgKikgeHNsdFhTTFRFbGVtTWFya2VyOyAqLworCisJCS8qCisJCSogWFNMVCAyLjA6ICJBbnkgd2hpdGVzcGFjZSB0ZXh0IG5vZGUgd2hvc2UgcGFyZW50IGlzCisJCSogb25lIG9mIHRoZSBmb2xsb3dpbmcgZWxlbWVudHMgaXMgcmVtb3ZlZCBmcm9tIHRoZSAiCisJCSogdHJlZSwgcmVnYXJkbGVzcyBvZiBhbnkgeG1sOnNwYWNlIGF0dHJpYnV0ZXM6Li4uIgorCQkqIHhzbDphcHBseS1pbXBvcnRzLCAKKwkJKiB4c2w6YXBwbHktdGVtcGxhdGVzLAorCQkqIHhzbDphdHRyaWJ1dGUtc2V0LAorCQkqIHhzbDpjYWxsLXRlbXBsYXRlLCAKKwkJKiB4c2w6Y2hvb3NlLAorCQkqIHhzbDpzdHlsZXNoZWV0LCB4c2w6dHJhbnNmb3JtLgorCQkqIFhTTFQgMi4wOiB4c2w6YW5hbHl6ZS1zdHJpbmcsCisJCSogICAgICAgICAgIHhzbDpjaGFyYWN0ZXItbWFwLAorCQkqICAgICAgICAgICB4c2w6bmV4dC1tYXRjaAkJCisJCSoKKwkJKiBUT0RPOiBJJ2QgbG92ZSB0byB1c2UgYSBzdHJpbmcgcG9pbnRlciBjb21wYXJpc29uIGhlcmUgOi0vCisJCSovCQkKKwkJbmFtZSA9IGN1ci0+bmFtZTsKKwkJc3dpdGNoICgqbmFtZSkgeworCQkgICAgY2FzZSAndCc6CisJCQlpZiAoKG5hbWVbMF0gPT0gJ3QnKSAmJiAobmFtZVsxXSA9PSAnZScpICYmCisJCQkgICAgKG5hbWVbMl0gPT0gJ3gnKSAmJiAobmFtZVszXSA9PSAndCcpICYmCisJCQkgICAgKG5hbWVbNF0gPT0gMCkpCisJCQl7CisJCQkgICAgLyoKKwkJCSAgICAqIFByb2Nlc3MgdGhlIHhzbDp0ZXh0IGVsZW1lbnQuCisJCQkgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisJCQkgICAgKiBNYXJrIGl0IGZvciBsYXRlciByZWNvZ25pdGlvbi4KKwkJCSAgICAqLworCQkJICAgIGN1ci0+cHN2aSA9ICh2b2lkICopIHhzbHRYU0xUVGV4dE1hcmtlcjsKKwkJCSAgICAvKgorCQkJICAgICogRm9yIHN0eWxlc2hlZXRzLCB0aGUgc2V0IG9mCisJCQkgICAgKiB3aGl0ZXNwYWNlLXByZXNlcnZpbmcgZWxlbWVudCBuYW1lcworCQkJICAgICogY29uc2lzdHMgb2YganVzdCB4c2w6dGV4dC4KKwkJCSAgICAqLworCQkJICAgIGZpbmRTcGFjZUF0dHIgPSAwOworCQkJICAgIGNjdHh0LT5pbm9kZS0+cHJlc2VydmVXaGl0ZXNwYWNlID0gMTsKKwkJCSAgICBpblhTTFRleHQgPSAxOworCQkJfQkJCSAgICAKKwkJCWJyZWFrOworCQkgICAgY2FzZSAnYyc6CisJCQlpZiAoeG1sU3RyRXF1YWwobmFtZSwgQkFEX0NBU1QgImNob29zZSIpIHx8CisJCQkgICAgeG1sU3RyRXF1YWwobmFtZSwgQkFEX0NBU1QgImNhbGwtdGVtcGxhdGUiKSkKKwkJCSAgICBjY3R4dC0+aW5vZGUtPnN0cmlwV2hpdGVzcGFjZSA9IDE7CisJCQlicmVhazsKKwkJICAgIGNhc2UgJ2EnOgorCQkJaWYgKHhtbFN0ckVxdWFsKG5hbWUsIEJBRF9DQVNUICJhcHBseS10ZW1wbGF0ZXMiKSB8fAorCQkJICAgIHhtbFN0ckVxdWFsKG5hbWUsIEJBRF9DQVNUICJhcHBseS1pbXBvcnRzIikgfHwKKwkJCSAgICB4bWxTdHJFcXVhbChuYW1lLCBCQURfQ0FTVCAiYXR0cmlidXRlLXNldCIpKQorCisJCQkgICAgY2N0eHQtPmlub2RlLT5zdHJpcFdoaXRlc3BhY2UgPSAxOworCQkJYnJlYWs7CisJCSAgICBkZWZhdWx0OgorCQkJaWYgKHhzbHRTdHlsZXNoZWV0RWxlbURlcHRoID09IGNjdHh0LT5kZXB0aCkgeworCQkJICAgIC8qCisJCQkgICAgKiBUaGlzIGlzIGEgeHNsOnN0eWxlc2hlZXQveHNsOnRyYW5zZm9ybS4KKwkJCSAgICAqLworCQkJICAgIGNjdHh0LT5pbm9kZS0+c3RyaXBXaGl0ZXNwYWNlID0gMTsKKwkJCSAgICBicmVhazsKKwkJCX0KKworCQkJaWYgKChjdXItPnByZXYgIT0gTlVMTCkgJiYKKwkJCSAgICAoY3VyLT5wcmV2LT50eXBlID09IFhNTF9URVhUX05PREUpKQorCQkJeworCQkJICAgIC8qCisJCQkgICAgKiBYU0xUIDIuMCA6ICJBbnkgd2hpdGVzcGFjZSB0ZXh0IG5vZGUgd2hvc2UKKwkJCSAgICAqICBmb2xsb3dpbmctc2libGluZyBub2RlIGlzIGFuIHhzbDpwYXJhbSBvcgorCQkJICAgICogIHhzbDpzb3J0IGVsZW1lbnQgaXMgcmVtb3ZlZCBmcm9tIHRoZSB0cmVlLAorCQkJICAgICogIHJlZ2FyZGxlc3Mgb2YgYW55IHhtbDpzcGFjZSBhdHRyaWJ1dGVzLiIKKwkJCSAgICAqLworCQkJICAgIGlmICgoKCpuYW1lID09ICdwJykgfHwgKCpuYW1lID09ICdzJykpICYmCisJCQkJKHhtbFN0ckVxdWFsKG5hbWUsIEJBRF9DQVNUICJwYXJhbSIpIHx8CisJCQkJIHhtbFN0ckVxdWFsKG5hbWUsIEJBRF9DQVNUICJzb3J0IikpKQorCQkJICAgIHsKKwkJCQlkbyB7CisJCQkJICAgIGlmIChJU19CTEFOS19OT0RFKGN1ci0+cHJldikpIHsKKwkJCQkJdHh0ID0gY3VyLT5wcmV2OworCQkJCQl4bWxVbmxpbmtOb2RlKHR4dCk7CisJCQkJCXhtbEZyZWVOb2RlKHR4dCk7CisJCQkJICAgIH0gZWxzZSB7CisJCQkJCS8qCisJCQkJCSogVGhpcyB3aWxsIHJlc3VsdCBpbiBhIGNvbnRlbnQKKwkJCQkJKiBlcnJvciwgd2hlbiBoaXR0aW5nIHRoZSBwYXJzaW5nCisJCQkJCSogZnVuY3Rpb25zLgorCQkJCQkqLworCQkJCQlicmVhazsKKwkJCQkgICAgfQorCQkJCX0gd2hpbGUgKGN1ci0+cHJldik7CQkJCSAgICAKKwkJCSAgICB9CisJCQl9CisJCQlicmVhazsKKwkJfQorCSAgICB9CisKK3Byb2Nlc3NfYXR0cmlidXRlczoKKwkgICAgLyoKKwkgICAgKiBQcm9jZXNzIGF0dHJpYnV0ZXMuCisJICAgICogLS0tLS0tLS0tLS0tLS0tLS0tCisJICAgICovCisJICAgIGlmIChjdXItPnByb3BlcnRpZXMgIT0gTlVMTCkgeworCQlpZiAoY3VyLT5jaGlsZHJlbiA9PSBOVUxMKQorCQkgICAgZmluZFNwYWNlQXR0ciA9IDA7CisJCWF0dHIgPSBjdXItPnByb3BlcnRpZXM7CisJCWRvIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAKKwkJICAgIGlmICgoYXR0ci0+bnMpICYmIChhdHRyLT5ucy0+aHJlZiAhPSBuc05hbWVYU0xUKSAmJgorCQkJeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIG5zTmFtZVhTTFQpKQorCQkgICAgewkJCQorCQkJbnNNYXBJdGVtID0geHNsdE5ld05hbWVzcGFjZU1hcEl0ZW0oY2N0eHQsCisJCQkgICAgZG9jLCBhdHRyLT5ucywgY3VyKTsKKwkJCWlmIChuc01hcEl0ZW0gPT0gTlVMTCkKKwkJCSAgICBnb3RvIGludGVybmFsX2VycjsKKwkJCWF0dHItPm5zLT5ocmVmID0gbnNOYW1lWFNMVDsKKwkJICAgIH0JCSAgICAKKyNlbmRpZgorCQkgICAgaWYgKGludGVybmFsaXplKSB7CisJCQkvKgorCQkJKiBJbnRlcm5hbGl6ZSB0aGUgYXR0cmlidXRlJ3MgdmFsdWU7IHRoZSBnb2FsIGlzIHRvCisJCQkqIHNwZWVkIHVwIG9wZXJhdGlvbnMgYW5kIG1pbmltaXplIHVzZWQgc3BhY2UgYnkKKwkJCSogY29tcGlsZWQgc3R5bGVzaGVldHMuCisJCQkqLworCQkJdHh0ID0gYXR0ci0+Y2hpbGRyZW47CisJCQkvKgorCQkJKiBOT1RFIHRoYXQgdGhpcyBhc3N1bWVzIG9ubHkgb25lCisJCQkqICB0ZXh0LW5vZGUgaW4gdGhlIGF0dHJpYnV0ZSdzIGNvbnRlbnQuCisJCQkqLworCQkJaWYgKCh0eHQgIT0gTlVMTCkgJiYgKHR4dC0+Y29udGVudCAhPSBOVUxMKSAmJgorCQkJICAgICgheG1sRGljdE93bnMoc3R5bGUtPmRpY3QsIHR4dC0+Y29udGVudCkpKQorCQkJeworCQkJICAgIHZhbHVlID0gKHhtbENoYXIgKikgeG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwKKwkJCQl0eHQtPmNvbnRlbnQsIC0xKTsKKwkJCSAgICB4bWxOb2RlU2V0Q29udGVudCh0eHQsIE5VTEwpOworCQkJICAgIHR4dC0+Y29udGVudCA9IHZhbHVlOworCQkJfQorCQkgICAgfQorCQkgICAgLyoKKwkJICAgICogUHJvY2VzcyB4bWw6c3BhY2UgYXR0cmlidXRlcy4KKwkJICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCQkgICAgKi8KKwkJICAgIGlmICgoZmluZFNwYWNlQXR0ciAhPSAwKSAmJgorCQkJKGF0dHItPm5zICE9IE5VTEwpICYmCisJCQkoYXR0ci0+bmFtZSAhPSBOVUxMKSAmJgorCQkJKGF0dHItPm5hbWVbMF0gPT0gJ3MnKSAmJgkJCQorCQkJKGF0dHItPm5zLT5wcmVmaXggIT0gTlVMTCkgJiYKKwkJCShhdHRyLT5ucy0+cHJlZml4WzBdID09ICd4JykgJiYKKwkJCShhdHRyLT5ucy0+cHJlZml4WzFdID09ICdtJykgJiYKKwkJCShhdHRyLT5ucy0+cHJlZml4WzJdID09ICdsJykgJiYKKwkJCShhdHRyLT5ucy0+cHJlZml4WzNdID09IDApKQorCQkgICAgeworCQkJdmFsdWUgPSB4bWxHZXROc1Byb3AoY3VyLCBCQURfQ0FTVCAic3BhY2UiLAorCQkJICAgIFhNTF9YTUxfTkFNRVNQQUNFKTsKKwkJCWlmICh2YWx1ZSAhPSBOVUxMKSB7CisJCQkgICAgaWYgKHhtbFN0ckVxdWFsKHZhbHVlLCBCQURfQ0FTVCAicHJlc2VydmUiKSkgeworCQkJCWNjdHh0LT5pbm9kZS0+cHJlc2VydmVXaGl0ZXNwYWNlID0gMTsJCQkJCisJCQkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbCh2YWx1ZSwgQkFEX0NBU1QgImRlZmF1bHQiKSkgeworCQkJCWNjdHh0LT5pbm9kZS0+cHJlc2VydmVXaGl0ZXNwYWNlID0gMDsKKwkJCSAgICB9IGVsc2UgeworCQkJCS8qIEludmFsaWQgdmFsdWUgZm9yIHhtbDpzcGFjZS4gKi8KKwkJCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkJCQkgICAgIkF0dHJpYnV0ZSB4bWw6c3BhY2U6IEludmFsaWQgdmFsdWUuXG4iKTsKKwkJCQljY3R4dC0+c3R5bGUtPndhcm5pbmdzKys7CisJCQkgICAgfQorCQkJICAgIGZpbmRTcGFjZUF0dHIgPSAwOworCQkJICAgIHhtbEZyZWUodmFsdWUpOworCQkJfQorCQkJCisJCSAgICB9CisJCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKKwkJfSB3aGlsZSAoYXR0ciAhPSBOVUxMKTsKKwkgICAgfQorCSAgICAvKgorCSAgICAqIFdlJ2xsIGRlc2NlbmQgaW50byB0aGUgY2hpbGRyZW4gb2YgZWxlbWVudCBub2RlcyBvbmx5LgorCSAgICAqLworCSAgICBpZiAoY3VyLT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJCWN1ciA9IGN1ci0+Y2hpbGRyZW47CisJCWNvbnRpbnVlOworCSAgICB9CisJfSBlbHNlIGlmICgoY3VyLT50eXBlID09IFhNTF9URVhUX05PREUpIHx8CisJCShjdXItPnR5cGUgPT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpCisJeworCSAgICAvKgorCSAgICAqIE1lcmdlIGFkamFjZW50IHRleHQvQ0RBVEEtc2VjdGlvbi1ub2RlcworCSAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkgICAgCisJICAgICogSW4gb3JkZXIgdG8gYXZvaWQgYnJlYWtpbmcgb2YgZXhpc3Rpbmcgc3R5bGVzaGVldHMsCisJICAgICogaWYgdGhlIG9sZCBiZWhhdmlvdXIgaXMgd2FudGVkIChzdHJpY3RXaGl0ZXNwYWNlID09IDApLAorCSAgICAqIHRoZW4gd2UgKndvbid0KiBtZXJnZSBhZGphY2VudCB0ZXh0LW5vZGVzCisJICAgICogKGV4Y2VwdCBpbiB4c2w6dGV4dCk7IHRoaXMgd2lsbCBlbnN1cmUgdGhhdCB3aGl0ZXNwYWNlLW9ubHkKKwkgICAgKiB0ZXh0IG5vZGVzIGFyZSAoaW5jb3JyZWN0bHkpIG5vdCBzdHJpcHBlZCBpbiBzb21lIGNhc2VzLgorCSAgICAqIAorCSAgICAqIEV4YW1wbGU6ICAgICAgICAgICAgICAgOiA8Zm9vPiAgPCEtLSBiYXIgLS0+em9vPC9mb28+CisJICAgICogQ29ycmVudCAoc3RyaWN0KSByZXN1bHQ6IDxmb28+ICB6b288L2Zvbz4KKwkgICAgKiBJbmNvcnJlY3QgKG9sZCkgcmVzdWx0IDogPGZvbz56b288L2Zvbz4KKwkgICAgKiAgICAKKwkgICAgKiBOT1RFIHRoYXQgd2UgKndpbGwqIG1lcmdlIGFkamFjZW50IHRleHQtbm9kZXMgaWYKKwkgICAgKiB0aGV5IGFyZSBpbiB4c2w6dGV4dC4KKwkgICAgKiBFeGFtcGxlLCB0aGUgZm9sbG93aW5nOgorCSAgICAqIDx4c2w6dGV4dD4gIDwhLS0gYmFyIC0tPnpvbzx4c2w6dGV4dD4KKwkgICAgKiB3aWxsIHJlc3VsdCBpbiBib3RoIGNhc2VzIGluOgorCSAgICAqIDx4c2w6dGV4dD4gIHpvbzx4c2w6dGV4dD4KKwkgICAgKi8KKwkgICAgY3VyLT50eXBlID0gWE1MX1RFWFRfTk9ERTsKKwkgICAgaWYgKChzdHJpY3RXaGl0ZXNwYWNlICE9IDApIHx8IChpblhTTFRleHQgIT0gMCkpIHsKKwkJLyoKKwkJKiBOZXcgYmVoYXZpb3VyOyBtZXJnZSBub2Rlcy4KKwkJKi8KKwkJaWYgKHRleHROb2RlID09IE5VTEwpCisJCSAgICB0ZXh0Tm9kZSA9IGN1cjsKKwkJZWxzZSB7CisJCSAgICBpZiAoY3VyLT5jb250ZW50ICE9IE5VTEwpCisJCQl4bWxOb2RlQWRkQ29udGVudCh0ZXh0Tm9kZSwgY3VyLT5jb250ZW50KTsKKwkJICAgIGRlbGV0ZU5vZGUgPSBjdXI7CisJCX0KKwkJaWYgKChjdXItPm5leHQgPT0gTlVMTCkgfHwKKwkJICAgIChjdXItPm5leHQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkpCisJCSAgICBnb3RvIGVuZF9vZl90ZXh0OworCQllbHNlCisJCSAgICBnb3RvIG5leHRfc2libGluZzsKKwkgICAgfSBlbHNlIHsKKwkJLyoKKwkJKiBPbGQgYmVoYXZpb3VyLgorCQkqLworCQlpZiAodGV4dE5vZGUgPT0gTlVMTCkKKwkJICAgIHRleHROb2RlID0gY3VyOworCQlnb3RvIGVuZF9vZl90ZXh0OworCSAgICB9CSAgICAJICAgCisJfSBlbHNlIGlmICgoY3VyLT50eXBlID09IFhNTF9DT01NRU5UX05PREUpIHx8CisJICAgIChjdXItPnR5cGUgPT0gWE1MX1BJX05PREUpKQorCXsJICAgIAorCSAgICAvKgorCSAgICAqIFJlbW92ZSBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBhbmQgY29tbWVudHMuCisJICAgICovCisJICAgIGRlbGV0ZU5vZGUgPSBjdXI7CisJICAgIGlmICgoY3VyLT5uZXh0ID09IE5VTEwpIHx8CisJCShjdXItPm5leHQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkpCisJCWdvdG8gZW5kX29mX3RleHQ7CisJICAgIGVsc2UKKwkJZ290byBuZXh0X3NpYmxpbmc7CisJfSBlbHNlIHsKKwkgICAgdGV4dE5vZGUgPSBOVUxMOworCSAgICAvKgorCSAgICAqIEludmFsaWQgbm9kZS10eXBlIGZvciB0aGlzIGRhdGEtbW9kZWwuCisJICAgICovCisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCQkiSW52YWxpZCB0eXBlIG9mIG5vZGUgZm9yIHRoZSBYU0xUIGRhdGEgbW9kZWwuXG4iKTsKKwkgICAgY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwkgICAgZ290byBuZXh0X3NpYmxpbmc7CisJfQorCitlbmRfb2ZfdGV4dDoKKwlpZiAodGV4dE5vZGUpIHsKKwkgICAgdmFsdWUgPSB0ZXh0Tm9kZS0+Y29udGVudDsKKwkgICAgLyoKKwkgICAgKiBBdCB0aGlzIHBvaW50IGFsbCBhZGphY2VudCB0ZXh0L0NEQVRBLXNlY3Rpb24gbm9kZXMKKwkgICAgKiBoYXZlIGJlZW4gbWVyZ2VkLgorCSAgICAqCisJICAgICogU3RyaXAgd2hpdGVzcGFjZS1vbmx5IHRleHQtbm9kZXMuCisJICAgICogKGNjdHh0LT5pbm9kZS0+c3RyaXBXaGl0ZXNwYWNlKQorCSAgICAqLworCSAgICBpZiAoKHZhbHVlID09IE5VTEwpIHx8ICgqdmFsdWUgPT0gMCkgfHwKKwkJKCgoY2N0eHQtPmlub2RlLT5zdHJpcFdoaXRlc3BhY2UpIHx8CisJCSAgKCEgY2N0eHQtPmlub2RlLT5wcmVzZXJ2ZVdoaXRlc3BhY2UpKSAmJgorCQkgSVNfQkxBTksoKnZhbHVlKSAmJgorCQkgeHNsdElzQmxhbmsodmFsdWUpKSkKKwkgICAgewkJCisJCWlmICh0ZXh0Tm9kZSAhPSBjdXIpIHsKKwkJICAgIHhtbFVubGlua05vZGUodGV4dE5vZGUpOworCQkgICAgeG1sRnJlZU5vZGUodGV4dE5vZGUpOworCQl9IGVsc2UKKwkJICAgIGRlbGV0ZU5vZGUgPSB0ZXh0Tm9kZTsKKwkJdGV4dE5vZGUgPSBOVUxMOworCQlnb3RvIG5leHRfc2libGluZzsKKwkgICAgfQorCSAgICAvKgorCSAgICAqIENvbnZlcnQgQ0RBVEEtc2VjdGlvbiBub2RlcyB0byB0ZXh0LW5vZGVzLgorCSAgICAqIFRPRE86IENhbiB0aGlzIHByb2R1Y2UgcHJvYmxlbXM/CisJICAgICovCisJICAgIGlmICh0ZXh0Tm9kZS0+dHlwZSAhPSBYTUxfVEVYVF9OT0RFKSB7CisJCXRleHROb2RlLT50eXBlID0gWE1MX1RFWFRfTk9ERTsKKwkJdGV4dE5vZGUtPm5hbWUgPSB4bWxTdHJpbmdUZXh0OworCSAgICB9CisJICAgIGlmIChpbnRlcm5hbGl6ZSAmJgorCQkodGV4dE5vZGUtPmNvbnRlbnQgIT0gTlVMTCkgJiYKKwkJKCF4bWxEaWN0T3ducyhzdHlsZS0+ZGljdCwgdGV4dE5vZGUtPmNvbnRlbnQpKSkKKwkgICAgeworCQkvKgorCQkqIEludGVybmFsaXplIHRoZSBzdHJpbmcuCisJCSovCisJCXZhbHVlID0gKHhtbENoYXIgKikgeG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwKKwkJICAgIHRleHROb2RlLT5jb250ZW50LCAtMSk7CisJCXhtbE5vZGVTZXRDb250ZW50KHRleHROb2RlLCBOVUxMKTsKKwkJdGV4dE5vZGUtPmNvbnRlbnQgPSB2YWx1ZTsKKwkgICAgfQorCSAgICB0ZXh0Tm9kZSA9IE5VTEw7CisJICAgIC8qCisJICAgICogTm90ZSB0aGF0ICJkaXNhYmxlLW91dHB1dC1lc2NhcGluZyIgb2YgdGhlIHhzbDp0ZXh0CisJICAgICogZWxlbWVudCB3aWxsIGJlIGFwcGxpZWQgYXQgYSBsYXRlciBsZXZlbCwgd2hlbgorCSAgICAqIFhTTFQgZWxlbWVudHMgYXJlIHByb2Nlc3NlZC4KKwkgICAgKi8KKwl9CisKK25leHRfc2libGluZzoKKwlpZiAoY3VyLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKKwkgICAgeHNsdENvbXBpbGVyTm9kZVBvcChjY3R4dCwgY3VyKTsKKwl9CisJaWYgKGN1ciA9PSBub2RlKQorCSAgICBicmVhazsKKwlpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKKwkgICAgY3VyID0gY3VyLT5uZXh0OworCX0gZWxzZSB7CisJICAgIGN1ciA9IGN1ci0+cGFyZW50OworCSAgICBpblhTTFRleHQgPSAwOworCSAgICBnb3RvIG5leHRfc2libGluZzsKKwl9OworICAgIH0KKyAgICBpZiAoZGVsZXRlTm9kZSAhPSBOVUxMKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAieHNsdFBhcnNlUHJlcHJvY2Vzc1N0eWxlc2hlZXRUcmVlOiByZW1vdmluZyBub2RlXG4iKTsKKyNlbmRpZgorCXhtbFVubGlua05vZGUoZGVsZXRlTm9kZSk7CisJeG1sRnJlZU5vZGUoZGVsZXRlTm9kZSk7CisgICAgfQorICAgIHJldHVybigwKTsKKworaW50ZXJuYWxfZXJyOgorICAgIHJldHVybigtMSk7Cit9CisKKyNlbmRpZiAvKiBYU0xUX1JFRkFDVE9SRUQgKi8KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorI2Vsc2UKK3N0YXRpYyB2b2lkCit4c2x0UHJlY29tcHV0ZVN0eWxlc2hlZXQoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgY3VyKQoreworICAgIHhtbE5vZGVQdHIgZGVsZXRlTm9kZSwgc3R5bGVlbGVtOworICAgIGludCBpbnRlcm5hbGl6ZSA9IDA7CisKKyAgICBpZiAoKHN0eWxlID09IE5VTEwpIHx8IChjdXIgPT0gTlVMTCkpCisgICAgICAgIHJldHVybjsKKworICAgIGlmICgoY3VyLT5kb2MgIT0gTlVMTCkgJiYgKHN0eWxlLT5kaWN0ICE9IE5VTEwpICYmCisgICAgICAgIChjdXItPmRvYy0+ZGljdCA9PSBzdHlsZS0+ZGljdCkpCisJaW50ZXJuYWxpemUgPSAxOworICAgIGVsc2UKKyAgICAgICAgc3R5bGUtPmludGVybmFsaXplZCA9IDA7CisKKyAgICBpZiAoKGN1ciAhPSBOVUxMKSAmJiAoSVNfWFNMVF9FTEVNKGN1cikpICYmCisgICAgICAgIChJU19YU0xUX05BTUUoY3VyLCAic3R5bGVzaGVldCIpKSkgeworCXN0eWxlZWxlbSA9IGN1cjsKKyAgICB9IGVsc2UgeworICAgICAgICBzdHlsZWVsZW0gPSBOVUxMOworICAgIH0KKworICAgIC8qCisgICAgICogVGhpcyBjb250ZW50IGNvbWVzIGZyb20gdGhlIHN0eWxlc2hlZXQKKyAgICAgKiBGb3Igc3R5bGVzaGVldHMsIHRoZSBzZXQgb2Ygd2hpdGVzcGFjZS1wcmVzZXJ2aW5nCisgICAgICogZWxlbWVudCBuYW1lcyBjb25zaXN0cyBvZiBqdXN0IHhzbDp0ZXh0LgorICAgICAqLworICAgIGRlbGV0ZU5vZGUgPSBOVUxMOworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCWlmIChkZWxldGVOb2RlICE9IE5VTEwpIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfQkxBTktTCisJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdFByZWNvbXB1dGVTdHlsZXNoZWV0OiByZW1vdmluZyBpZ25vcmFibGUgYmxhbmsgbm9kZVxuIik7CisjZW5kaWYKKwkgICAgeG1sVW5saW5rTm9kZShkZWxldGVOb2RlKTsKKwkgICAgeG1sRnJlZU5vZGUoZGVsZXRlTm9kZSk7CisJICAgIGRlbGV0ZU5vZGUgPSBOVUxMOworCX0KKwlpZiAoY3VyLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKKwkgICAgaW50IGV4Y2xQcmVmaXhlczsKKwkgICAgLyoKKwkgICAgICogSW50ZXJuYWxpemUgYXR0cmlidXRlcyB2YWx1ZXMuCisJICAgICAqLworCSAgICBpZiAoKGludGVybmFsaXplKSAmJiAoY3VyLT5wcm9wZXJ0aWVzICE9IE5VTEwpKSB7CisJICAgICAgICB4bWxBdHRyUHRyIGF0dHIgPSBjdXItPnByb3BlcnRpZXM7CisJCXhtbE5vZGVQdHIgdHh0OworCisJCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKKwkJICAgIHR4dCA9IGF0dHItPmNoaWxkcmVuOworCQkgICAgaWYgKCh0eHQgIT0gTlVMTCkgJiYgKHR4dC0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSAmJgorCQkgICAgICAgICh0eHQtPmNvbnRlbnQgIT0gTlVMTCkgJiYKKwkJCSgheG1sRGljdE93bnMoc3R5bGUtPmRpY3QsIHR4dC0+Y29udGVudCkpKQorCQkgICAgeworCQkJeG1sQ2hhciAqdG1wOworCisJCQkvKgorCQkJICogaW50ZXJuYWxpemUgdGhlIHRleHQgc3RyaW5nLCBnb2FsIGlzIHRvIHNwZWVkCisJCQkgKiB1cCBvcGVyYXRpb25zIGFuZCBtaW5pbWl6ZSB1c2VkIHNwYWNlIGJ5IGNvbXBpbGVkCisJCQkgKiBzdHlsZXNoZWV0cy4KKwkJCSAqLworCQkJdG1wID0gKHhtbENoYXIgKikgeG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwKKwkJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHh0LT5jb250ZW50LCAtMSk7CisJCQlpZiAodG1wICE9IHR4dC0+Y29udGVudCkgeworCQkJICAgIHhtbE5vZGVTZXRDb250ZW50KHR4dCwgTlVMTCk7CisJCQkgICAgdHh0LT5jb250ZW50ID0gdG1wOworCQkJfQorCQkgICAgfQorCQkgICAgYXR0ciA9IGF0dHItPm5leHQ7CisJCX0KKwkgICAgfQorCSAgICBpZiAoSVNfWFNMVF9FTEVNKGN1cikpIHsKKwkJZXhjbFByZWZpeGVzID0gMDsKKwkJeHNsdFN0eWxlUHJlQ29tcHV0ZShzdHlsZSwgY3VyKTsKKwkJaWYgKElTX1hTTFRfTkFNRShjdXIsICJ0ZXh0IikpIHsKKwkJICAgIGZvciAoO2V4Y2xQcmVmaXhlcyA+IDA7ZXhjbFByZWZpeGVzLS0pCisJCQlleGNsUHJlZml4UG9wKHN0eWxlKTsKKwkJICAgIGdvdG8gc2tpcF9jaGlsZHJlbjsKKwkJfQorCSAgICB9IGVsc2UgeworCQlleGNsUHJlZml4ZXMgPSB4c2x0UGFyc2VTdHlsZXNoZWV0RXhjbHVkZVByZWZpeChzdHlsZSwgY3VyLCAwKTsKKwkgICAgfQorCSAgICAJICAgICAKKwkgICAgaWYgKChjdXItPm5zRGVmICE9IE5VTEwpICYmIChzdHlsZS0+ZXhjbFByZWZpeE5yID4gMCkpIHsKKwkJeG1sTnNQdHIgbnMgPSBjdXItPm5zRGVmLCBwcmV2ID0gTlVMTCwgbmV4dDsKKwkJeG1sTm9kZVB0ciByb290ID0gTlVMTDsKKwkJaW50IGksIG1vdmVkOworCisJCXJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChjdXItPmRvYyk7CisJCWlmICgocm9vdCAhPSBOVUxMKSAmJiAocm9vdCAhPSBjdXIpKSB7CisJCSAgICB3aGlsZSAobnMgIT0gTlVMTCkgeworCQkJbW92ZWQgPSAwOworCQkJbmV4dCA9IG5zLT5uZXh0OworCQkJZm9yIChpID0gMDtpIDwgc3R5bGUtPmV4Y2xQcmVmaXhOcjtpKyspIHsKKwkJCSAgICBpZiAoKG5zLT5wcmVmaXggIT0gTlVMTCkgJiYgCisJCQkgICAgICAgICh4bWxTdHJFcXVhbChucy0+aHJlZiwKKwkJCQkJICAgICBzdHlsZS0+ZXhjbFByZWZpeFRhYltpXSkpKSB7CisJCQkJLyoKKwkJCQkgKiBNb3ZlIHRoZSBuYW1lc3BhY2UgZGVmaW5pdGlvbiBvbiB0aGUgcm9vdAorCQkJCSAqIGVsZW1lbnQgdG8gYXZvaWQgZHVwbGljYXRpbmcgaXQgd2l0aG91dAorCQkJCSAqIGxvb3NpbmcgaXQuCisJCQkJICovCisJCQkJaWYgKHByZXYgPT0gTlVMTCkgeworCQkJCSAgICBjdXItPm5zRGVmID0gbnMtPm5leHQ7CisJCQkJfSBlbHNlIHsKKwkJCQkgICAgcHJldi0+bmV4dCA9IG5zLT5uZXh0OworCQkJCX0KKwkJCQlucy0+bmV4dCA9IHJvb3QtPm5zRGVmOworCQkJCXJvb3QtPm5zRGVmID0gbnM7CisJCQkJbW92ZWQgPSAxOworCQkJCWJyZWFrOworCQkJICAgIH0KKwkJCX0KKwkJCWlmIChtb3ZlZCA9PSAwKQorCQkJICAgIHByZXYgPSBuczsKKwkJCW5zID0gbmV4dDsKKwkJICAgIH0KKwkJfQorCSAgICB9CisJICAgIC8qCisJICAgICAqIElmIHdlIGhhdmUgcHJlZml4ZXMgbG9jYWxseSwgcmVjdXJzZSBhbmQgcG9wIHRoZW0gdXAgd2hlbgorCSAgICAgKiBnb2luZyBiYWNrCisJICAgICAqLworCSAgICBpZiAoZXhjbFByZWZpeGVzID4gMCkgeworCQl4c2x0UHJlY29tcHV0ZVN0eWxlc2hlZXQoc3R5bGUsIGN1ci0+Y2hpbGRyZW4pOworCQlmb3IgKDtleGNsUHJlZml4ZXMgPiAwO2V4Y2xQcmVmaXhlcy0tKQorCQkgICAgZXhjbFByZWZpeFBvcChzdHlsZSk7CisJCWdvdG8gc2tpcF9jaGlsZHJlbjsKKwkgICAgfQorCX0gZWxzZSBpZiAoY3VyLT50eXBlID09IFhNTF9URVhUX05PREUpIHsKKwkgICAgaWYgKElTX0JMQU5LX05PREUoY3VyKSkgeworCQlpZiAoeG1sTm9kZUdldFNwYWNlUHJlc2VydmUoY3VyKSAhPSAxKSB7CisJCSAgICBkZWxldGVOb2RlID0gY3VyOworCQl9CisJICAgIH0gZWxzZSBpZiAoKGN1ci0+Y29udGVudCAhPSBOVUxMKSAmJiAoaW50ZXJuYWxpemUpICYmCisJICAgICAgICAgICAgICAgKCF4bWxEaWN0T3ducyhzdHlsZS0+ZGljdCwgY3VyLT5jb250ZW50KSkpIHsKKwkJeG1sQ2hhciAqdG1wOworCisJCS8qCisJCSAqIGludGVybmFsaXplIHRoZSB0ZXh0IHN0cmluZywgZ29hbCBpcyB0byBzcGVlZAorCQkgKiB1cCBvcGVyYXRpb25zIGFuZCBtaW5pbWl6ZSB1c2VkIHNwYWNlIGJ5IGNvbXBpbGVkCisJCSAqIHN0eWxlc2hlZXRzLgorCQkgKi8KKwkJdG1wID0gKHhtbENoYXIgKikgeG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgY3VyLT5jb250ZW50LCAtMSk7CisJCXhtbE5vZGVTZXRDb250ZW50KGN1ciwgTlVMTCk7CisJCWN1ci0+Y29udGVudCA9IHRtcDsKKwkgICAgfQorCX0gZWxzZSBpZiAoKGN1ci0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSAmJgorCQkgICAoY3VyLT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CisJICAgIGRlbGV0ZU5vZGUgPSBjdXI7CisJICAgIGdvdG8gc2tpcF9jaGlsZHJlbjsKKwl9CisKKwkvKgorCSAqIFNraXAgdG8gbmV4dCBub2RlLiBJbiBjYXNlIG9mIGEgbmFtZXNwYWNlZCBlbGVtZW50IGNoaWxkcmVuIG9mCisJICogdGhlIHN0eWxlc2hlZXQgYW5kIG5vdCBpbiB0aGUgWFNMVCBuYW1lc3BhY2UgYW5kIG5vdCBhbiBleHRlbnNpb24KKwkgKiBlbGVtZW50LCBpZ25vcmUgaXRzIGNvbnRlbnQuCisJICovCisJaWYgKChjdXItPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYgKGN1ci0+bnMgIT0gTlVMTCkgJiYKKwkgICAgKHN0eWxlZWxlbSAhPSBOVUxMKSAmJiAoY3VyLT5wYXJlbnQgPT0gc3R5bGVlbGVtKSAmJgorCSAgICAoIXhtbFN0ckVxdWFsKGN1ci0+bnMtPmhyZWYsIFhTTFRfTkFNRVNQQUNFKSkgJiYKKwkgICAgKCF4c2x0Q2hlY2tFeHRVUkkoc3R5bGUsIGN1ci0+bnMtPmhyZWYpKSkgeworCSAgICBnb3RvIHNraXBfY2hpbGRyZW47CisJfSBlbHNlIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKKwkgICAgaWYgKChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfREVDTCkgJiYKKwkJKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgJiYKKwkJKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9OT0RFKSkgeworCQljdXIgPSBjdXItPmNoaWxkcmVuOworCQljb250aW51ZTsKKwkgICAgfQorCX0KKworc2tpcF9jaGlsZHJlbjoKKwlpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKKwkgICAgY3VyID0gY3VyLT5uZXh0OworCSAgICBjb250aW51ZTsKKwl9CisJZG8geworCisJICAgIGN1ciA9IGN1ci0+cGFyZW50OworCSAgICBpZiAoY3VyID09IE5VTEwpCisJCWJyZWFrOworCSAgICBpZiAoY3VyID09ICh4bWxOb2RlUHRyKSBzdHlsZS0+ZG9jKSB7CisJCWN1ciA9IE5VTEw7CisJCWJyZWFrOworCSAgICB9CisJICAgIGlmIChjdXItPm5leHQgIT0gTlVMTCkgeworCQljdXIgPSBjdXItPm5leHQ7CisJCWJyZWFrOworCSAgICB9CisJfSB3aGlsZSAoY3VyICE9IE5VTEwpOworICAgIH0KKyAgICBpZiAoZGVsZXRlTm9kZSAhPSBOVUxMKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAieHNsdFByZWNvbXB1dGVTdHlsZXNoZWV0OiByZW1vdmluZyBpZ25vcmFibGUgYmxhbmsgbm9kZVxuIik7CisjZW5kaWYKKwl4bWxVbmxpbmtOb2RlKGRlbGV0ZU5vZGUpOworCXhtbEZyZWVOb2RlKGRlbGV0ZU5vZGUpOworICAgIH0KK30KKyNlbmRpZiAvKiBlbmQgb2YgZWxzZSBYU0xUX1JFRkFDVE9SRUQgKi8KKworLyoqCisgKiB4c2x0R2F0aGVyTmFtZXNwYWNlczoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqCisgKiBCcm93c2UgdGhlIHN0eWxlc2hlZXQgYW5kIGJ1aWxkIHRoZSBuYW1zcGFjZSBoYXNoIHRhYmxlIHdoaWNoCisgKiB3aWxsIGJlIHVzZWQgZm9yIFhQYXRoIGludGVycHJldGF0aW9uLiBJZiBuZWVkZWQgZG8gYSBiaXQgb2Ygbm9ybWFsaXphdGlvbgorICovCisKK3N0YXRpYyB2b2lkCit4c2x0R2F0aGVyTmFtZXNwYWNlcyh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkgeworICAgIHhtbE5vZGVQdHIgY3VyOworICAgIGNvbnN0IHhtbENoYXIgKlVSSTsKKworICAgIGlmIChzdHlsZSA9PSBOVUxMKQorICAgICAgICByZXR1cm47CisgICAgLyogCisgICAgICogVE9ETzogYmFzaWNhbGx5IGlmIHRoZSBzdHlsZXNoZWV0IHVzZXMgdGhlIHNhbWUgcHJlZml4IGZvciBkaWZmZXJlbnQKKyAgICAgKiAgICAgICBwYXR0ZXJucywgd2VsbCB0aGV5IG1heSBiZSBpbiBwcm9ibGVtLCBob3BlZnVsbHkgdGhleSB3aWxsIGdldAorICAgICAqICAgICAgIGEgd2FybmluZyBmaXJzdC4KKyAgICAgKi8KKyAgICAvKgorICAgICogVE9ETzogRWxpbWluYXRlIHRoZSB1c2Ugb2YgdGhlIGhhc2ggZm9yIFhQYXRoIGV4cHJlc3Npb25zLgorICAgICogICBBbiBleHByZXNzaW9uIHNob3VsZCBiZSBldmFsdWF0ZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlIGluLXNjb3BlCisgICAgKiAgIG5hbWVzcGFjZXM7IGVsaW1pbmF0ZSB0aGUgcmVzdHJpY3Rpb24gb2YgYW4gWE1MIGRvY3VtZW50IHRvIGNvbnRhaW4KKyAgICAqICAgbm8gZHVwbGljYXRlIHByZWZpeGVzIGZvciBkaWZmZXJlbnQgbmFtZXNwYWNlIG5hbWVzLgorICAgICogCisgICAgKi8KKyAgICBjdXIgPSB4bWxEb2NHZXRSb290RWxlbWVudChzdHlsZS0+ZG9jKTsKKyAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKKwlpZiAoY3VyLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKKwkgICAgeG1sTnNQdHIgbnMgPSBjdXItPm5zRGVmOworCSAgICB3aGlsZSAobnMgIT0gTlVMTCkgeworCQlpZiAobnMtPnByZWZpeCAhPSBOVUxMKSB7CisJCSAgICBpZiAoc3R5bGUtPm5zSGFzaCA9PSBOVUxMKSB7CisJCQlzdHlsZS0+bnNIYXNoID0geG1sSGFzaENyZWF0ZSgxMCk7CisJCQlpZiAoc3R5bGUtPm5zSGFzaCA9PSBOVUxMKSB7CisJCQkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJCSAieHNsdEdhdGhlck5hbWVzcGFjZXM6IGZhaWxlZCB0byBjcmVhdGUgaGFzaCB0YWJsZVxuIik7CisJCQkgICAgc3R5bGUtPmVycm9ycysrOworCQkJICAgIHJldHVybjsKKwkJCX0KKwkJICAgIH0KKwkJICAgIFVSSSA9IHhtbEhhc2hMb29rdXAoc3R5bGUtPm5zSGFzaCwgbnMtPnByZWZpeCk7CisJCSAgICBpZiAoKFVSSSAhPSBOVUxMKSAmJiAoIXhtbFN0ckVxdWFsKFVSSSwgbnMtPmhyZWYpKSkgeworCQkJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICAiTmFtZXNwYWNlcyBwcmVmaXggJXMgdXNlZCBmb3IgbXVsdGlwbGUgbmFtZXNwYWNlc1xuIixucy0+cHJlZml4KTsKKwkJCXN0eWxlLT53YXJuaW5ncysrOworCQkgICAgfSBlbHNlIGlmIChVUkkgPT0gTlVMTCkgeworCQkJeG1sSGFzaFVwZGF0ZUVudHJ5KHN0eWxlLT5uc0hhc2gsIG5zLT5wcmVmaXgsCisJCQkgICAgKHZvaWQgKikgbnMtPmhyZWYsICh4bWxIYXNoRGVhbGxvY2F0b3IpeG1sRnJlZSk7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworCQkJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICJBZGRlZCBuYW1lc3BhY2U6ICVzIG1hcHBlZCB0byAlc1xuIiwgbnMtPnByZWZpeCwgbnMtPmhyZWYpOworI2VuZGlmCisJCSAgICB9CisJCX0KKwkJbnMgPSBucy0+bmV4dDsKKwkgICAgfQorCX0KKworCS8qCisJICogU2tpcCB0byBuZXh0IG5vZGUKKwkgKi8KKwlpZiAoY3VyLT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJICAgIGlmIChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfREVDTCkgeworCQljdXIgPSBjdXItPmNoaWxkcmVuOworCQljb250aW51ZTsKKwkgICAgfQorCX0KKwlpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKKwkgICAgY3VyID0gY3VyLT5uZXh0OworCSAgICBjb250aW51ZTsKKwl9CisJCisJZG8geworCSAgICBjdXIgPSBjdXItPnBhcmVudDsKKwkgICAgaWYgKGN1ciA9PSBOVUxMKQorCQlicmVhazsKKwkgICAgaWYgKGN1ciA9PSAoeG1sTm9kZVB0cikgc3R5bGUtPmRvYykgeworCQljdXIgPSBOVUxMOworCQlicmVhazsKKwkgICAgfQorCSAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKKwkJY3VyID0gY3VyLT5uZXh0OworCQlicmVhazsKKwkgICAgfQorCX0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKKyAgICB9Cit9CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKworc3RhdGljIHhzbHRTdHlsZVR5cGUKK3hzbHRHZXRYU0xURWxlbWVudFR5cGVCeU5vZGUoeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwKKwkJCSAgICAgeG1sTm9kZVB0ciBub2RlKQoreworICAgIGlmICgobm9kZSA9PSBOVUxMKSB8fCAobm9kZS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSB8fAorCShub2RlLT5uYW1lID09IE5VTEwpKQorCXJldHVybigwKTsKKworICAgIGlmIChub2RlLT5uYW1lWzBdID09ICdhJykgeworCWlmIChJU19YU0xUX05BTUUobm9kZSwgImFwcGx5LXRlbXBsYXRlcyIpKQorCSAgICByZXR1cm4oWFNMVF9GVU5DX0FQUExZVEVNUExBVEVTKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImF0dHJpYnV0ZSIpKQorCSAgICByZXR1cm4oWFNMVF9GVU5DX0FUVFJJQlVURSk7CisJZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJhcHBseS1pbXBvcnRzIikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfQVBQTFlJTVBPUlRTKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImF0dHJpYnV0ZS1zZXQiKSkKKwkgICAgcmV0dXJuKDApOworCisgICAgfSBlbHNlIGlmIChub2RlLT5uYW1lWzBdID09ICdjJykgeworCWlmIChJU19YU0xUX05BTUUobm9kZSwgImNob29zZSIpKQorCSAgICByZXR1cm4oWFNMVF9GVU5DX0NIT09TRSk7CisJZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJjb3B5IikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfQ09QWSk7CisJZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJjb3B5LW9mIikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfQ09QWU9GKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImNhbGwtdGVtcGxhdGUiKSkKKwkgICAgcmV0dXJuKFhTTFRfRlVOQ19DQUxMVEVNUExBVEUpOworCWVsc2UgaWYgKElTX1hTTFRfTkFNRShub2RlLCAiY29tbWVudCIpKQorCSAgICByZXR1cm4oWFNMVF9GVU5DX0NPTU1FTlQpOworCisgICAgfSBlbHNlIGlmIChub2RlLT5uYW1lWzBdID09ICdkJykgeworCWlmIChJU19YU0xUX05BTUUobm9kZSwgImRvY3VtZW50IikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfRE9DVU1FTlQpOworCWVsc2UgaWYgKElTX1hTTFRfTkFNRShub2RlLCAiZGVjaW1hbC1mb3JtYXQiKSkKKwkgICAgcmV0dXJuKDApOworCisgICAgfSBlbHNlIGlmIChub2RlLT5uYW1lWzBdID09ICdlJykgeworCWlmIChJU19YU0xUX05BTUUobm9kZSwgImVsZW1lbnQiKSkKKwkgICAgcmV0dXJuKFhTTFRfRlVOQ19FTEVNRU5UKTsKKworICAgIH0gZWxzZSBpZiAobm9kZS0+bmFtZVswXSA9PSAnZicpIHsKKwlpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJmb3ItZWFjaCIpKQorCSAgICByZXR1cm4oWFNMVF9GVU5DX0ZPUkVBQ0gpOworCWVsc2UgaWYgKElTX1hTTFRfTkFNRShub2RlLCAiZmFsbGJhY2siKSkKKwkgICAgcmV0dXJuKFhTTFRfRlVOQ19GQUxMQkFDSyk7CisKKyAgICB9IGVsc2UgaWYgKCoobm9kZS0+bmFtZSkgPT0gJ2knKSB7CisJaWYgKElTX1hTTFRfTkFNRShub2RlLCAiaWYiKSkKKwkgICAgcmV0dXJuKFhTTFRfRlVOQ19JRik7CisJZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJpbmNsdWRlIikpCisJICAgIHJldHVybigwKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgImltcG9ydCIpKQorCSAgICByZXR1cm4oMCk7CisKKyAgICB9IGVsc2UgaWYgKCoobm9kZS0+bmFtZSkgPT0gJ2snKSB7CisJaWYgKElTX1hTTFRfTkFNRShub2RlLCAia2V5IikpCisJICAgIHJldHVybigwKTsKKworICAgIH0gZWxzZSBpZiAoKihub2RlLT5uYW1lKSA9PSAnbScpIHsKKwlpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJtZXNzYWdlIikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfTUVTU0FHRSk7CisKKyAgICB9IGVsc2UgaWYgKCoobm9kZS0+bmFtZSkgPT0gJ24nKSB7CisJaWYgKElTX1hTTFRfTkFNRShub2RlLCAibnVtYmVyIikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfTlVNQkVSKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgIm5hbWVzcGFjZS1hbGlhcyIpKQorCSAgICByZXR1cm4oMCk7CisKKyAgICB9IGVsc2UgaWYgKCoobm9kZS0+bmFtZSkgPT0gJ28nKSB7CisJaWYgKElTX1hTTFRfTkFNRShub2RlLCAib3RoZXJ3aXNlIikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfT1RIRVJXSVNFKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgIm91dHB1dCIpKQorCSAgICByZXR1cm4oMCk7CisKKyAgICB9IGVsc2UgaWYgKCoobm9kZS0+bmFtZSkgPT0gJ3AnKSB7CisJaWYgKElTX1hTTFRfTkFNRShub2RlLCAicGFyYW0iKSkKKwkgICAgcmV0dXJuKFhTTFRfRlVOQ19QQVJBTSk7CisJZWxzZSBpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfUEkpOworCWVsc2UgaWYgKElTX1hTTFRfTkFNRShub2RlLCAicHJlc2VydmUtc3BhY2UiKSkKKwkgICAgcmV0dXJuKDApOworCisgICAgfSBlbHNlIGlmICgqKG5vZGUtPm5hbWUpID09ICdzJykgeworCWlmIChJU19YU0xUX05BTUUobm9kZSwgInNvcnQiKSkKKwkgICAgcmV0dXJuKFhTTFRfRlVOQ19TT1JUKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgInN0cmlwLXNwYWNlIikpCisJICAgIHJldHVybigwKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgInN0eWxlc2hlZXQiKSkKKwkgICAgcmV0dXJuKDApOworCisgICAgfSBlbHNlIGlmIChub2RlLT5uYW1lWzBdID09ICd0JykgeworCWlmIChJU19YU0xUX05BTUUobm9kZSwgInRleHQiKSkKKwkgICAgcmV0dXJuKFhTTFRfRlVOQ19URVhUKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgInRlbXBsYXRlIikpCisJICAgIHJldHVybigwKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgInRyYW5zZm9ybSIpKQorCSAgICByZXR1cm4oMCk7CisKKyAgICB9IGVsc2UgaWYgKCoobm9kZS0+bmFtZSkgPT0gJ3YnKSB7CisJaWYgKElTX1hTTFRfTkFNRShub2RlLCAidmFsdWUtb2YiKSkKKwkgICAgcmV0dXJuKFhTTFRfRlVOQ19WQUxVRU9GKTsKKwllbHNlIGlmIChJU19YU0xUX05BTUUobm9kZSwgInZhcmlhYmxlIikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfVkFSSUFCTEUpOworCisgICAgfSBlbHNlIGlmICgqKG5vZGUtPm5hbWUpID09ICd3JykgeworCWlmIChJU19YU0xUX05BTUUobm9kZSwgIndoZW4iKSkKKwkgICAgcmV0dXJuKFhTTFRfRlVOQ19XSEVOKTsKKwlpZiAoSVNfWFNMVF9OQU1FKG5vZGUsICJ3aXRoLXBhcmFtIikpCisJICAgIHJldHVybihYU0xUX0ZVTkNfV0lUSFBBUkFNKTsKKyAgICB9CisgICAgcmV0dXJuKDApOworfQorCisvKioKKyAqIHhzbHRQYXJzZUFueVhTTFRFbGVtOgorICoKKyAqIEBjY3R4dDogdGhlIGNvbXBpbGF0aW9uIGNvbnRleHQKKyAqIEBlbGVtOiB0aGUgZWxlbWVudCBub2RlIG9mIHRoZSBYU0xUIGluc3RydWN0aW9uCisgKgorICogUGFyc2VzLCB2YWxpZGF0ZXMgdGhlIGNvbnRlbnQgbW9kZWxzIGFuZCBjb21waWxlcyBYU0xUIGluc3RydWN0aW9ucy4KKyAqCisgKiBSZXR1cm5zIDAgaWYgZXZlcnl0aGluZydzIGZpbmU7CisgKiAgICAgICAgIC0xIG9uIEFQSSBvciBpbnRlcm5hbCBlcnJvcnMuCisgKi8gCitpbnQKK3hzbHRQYXJzZUFueVhTTFRFbGVtKHhzbHRDb21waWxlckN0eHRQdHIgY2N0eHQsIHhtbE5vZGVQdHIgZWxlbSkKK3sKKyAgICBpZiAoKGNjdHh0ID09IE5VTEwpIHx8IChlbGVtID09IE5VTEwpIHx8CisJKGVsZW0tPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkpCisJcmV0dXJuKC0xKTsKKworICAgIGVsZW0tPnBzdmkgPSBOVUxMOworCisgICAgaWYgKCEgKElTX1hTTFRfRUxFTV9GQVNUKGVsZW0pKSkKKwlyZXR1cm4oLTEpOworICAgIC8qCisgICAgKiBEZXRlY3Rpb24gb2YgaGFuZGxlZCBjb250ZW50IG9mIGV4dGVuc2lvbiBpbnN0cnVjdGlvbnMuCisgICAgKi8KKyAgICBpZiAoY2N0eHQtPmlub2RlLT5jYXRlZ29yeSA9PSBYU0xUX0VMRU1FTlRfQ0FURUdPUllfRVhURU5TSU9OKSB7CisJY2N0eHQtPmlub2RlLT5leHRDb250ZW50SGFuZGxlZCA9IDE7CisgICAgfQorICAgIAorICAgIHhzbHRDb21waWxlck5vZGVQdXNoKGNjdHh0LCBlbGVtKTsKKyAgICAvKgorICAgICogVVJHRU5UIFRPRE86IEZpbmQgYSB3YXkgdG8gc3BlZWQgdXAgdGhpcyBhbm5veWluZyByZWR1bmRhbnQKKyAgICAqICB0ZXh0dWFsIG5vZGUtbmFtZSBhbmQgbmFtZXNwYWNlIGNvbXBhcmlzb24uCisgICAgKi8KKyAgICBpZiAoY2N0eHQtPmlub2RlLT5wcmV2LT5jdXJDaGlsZFR5cGUgIT0gMCkKKwljY3R4dC0+aW5vZGUtPnR5cGUgPSBjY3R4dC0+aW5vZGUtPnByZXYtPmN1ckNoaWxkVHlwZTsKKyAgICBlbHNlCisJY2N0eHQtPmlub2RlLT50eXBlID0geHNsdEdldFhTTFRFbGVtZW50VHlwZUJ5Tm9kZShjY3R4dCwgZWxlbSk7ICAgIAorICAgIC8qCisgICAgKiBVcGRhdGUgdGhlIGluLXNjb3BlIG5hbWVzcGFjZXMgaWYgbmVlZGVkLgorICAgICovCisgICAgaWYgKGVsZW0tPm5zRGVmICE9IE5VTEwpCisJY2N0eHQtPmlub2RlLT5pblNjb3BlTnMgPQorCSAgICB4c2x0Q29tcGlsZXJCdWlsZEluU2NvcGVOc0xpc3QoY2N0eHQsIGVsZW0pOworICAgIC8qCisgICAgKiB4c2x0U3R5bGVQcmVDb21wdXRlKCk6CisgICAgKiAgVGhpcyB3aWxsIGNvbXBpbGUgdGhlIGluZm9ybWF0aW9uIGZvdW5kIG9uIHRoZSBjdXJyZW50CisgICAgKiAgZWxlbWVudCdzIGF0dHJpYnV0ZXMuIE5PVEUgdGhhdCB0aGlzIHdvbid0IHByb2Nlc3MgdGhlCisgICAgKiAgY2hpbGRyZW4gb2YgdGhlIGluc3RydWN0aW9uLgorICAgICovCisgICAgeHNsdFN0eWxlUHJlQ29tcHV0ZShjY3R4dC0+c3R5bGUsIGVsZW0pOworICAgIC8qCisgICAgKiBUT0RPOiBIb3cgdG8gcmVhY3Qgb24gZXJyb3JzIGluIHhzbHRTdHlsZVByZUNvbXB1dGUoKSA/CisgICAgKi8KKworICAgIC8qCisgICAgKiBWYWxpZGF0ZSB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgWFNMVC1lbGVtZW50LgorICAgICovCisgICAgc3dpdGNoIChjY3R4dC0+aW5vZGUtPnR5cGUpIHsJCisJY2FzZSBYU0xUX0ZVTkNfQVBQTFlJTVBPUlRTOgorCSAgICAvKiBFTVBUWSAqLworCSAgICBnb3RvIGVtcHR5X2NvbnRlbnQ7CisJY2FzZSBYU0xUX0ZVTkNfQVBQTFlURU1QTEFURVM6CisJICAgIC8qIDwhLS0gQ29udGVudDogKHhzbDpzb3J0IHwgeHNsOndpdGgtcGFyYW0pKiAtLT4gKi8KKwkgICAgZ290byBhcHBseV90ZW1wbGF0ZXM7CSAgICAKKwljYXNlIFhTTFRfRlVOQ19BVFRSSUJVVEU6CSAgICAKKwkgICAgLyogPCEtLSBDb250ZW50OiB0ZW1wbGF0ZSAtLT4gKi8KKwkgICAgZ290byBzZXF1ZW5jZV9jb25zdHJ1Y3RvcjsKKwljYXNlIFhTTFRfRlVOQ19DQUxMVEVNUExBVEU6CisJICAgIC8qIDwhLS0gQ29udGVudDogeHNsOndpdGgtcGFyYW0qIC0tPiAqLworCSAgICBnb3RvIGNhbGxfdGVtcGxhdGU7CisJY2FzZSBYU0xUX0ZVTkNfQ0hPT1NFOgkgICAgCisJICAgIC8qIDwhLS0gQ29udGVudDogKHhzbDp3aGVuKywgeHNsOm90aGVyd2lzZT8pIC0tPiAqLworCSAgICBnb3RvIGNob29zZTsKKwljYXNlIFhTTFRfRlVOQ19DT01NRU5UOgorCSAgICAvKiA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPiAqLworCSAgICBnb3RvIHNlcXVlbmNlX2NvbnN0cnVjdG9yOwkgICAgCisJY2FzZSBYU0xUX0ZVTkNfQ09QWToKKwkgICAgLyogPCEtLSBDb250ZW50OiB0ZW1wbGF0ZSAtLT4gKi8KKwkgICAgZ290byBzZXF1ZW5jZV9jb25zdHJ1Y3RvcjsJICAgIAorCWNhc2UgWFNMVF9GVU5DX0NPUFlPRjoKKwkgICAgLyogRU1QVFkgKi8KKwkgICAgZ290byBlbXB0eV9jb250ZW50OwkgICAKKwljYXNlIFhTTFRfRlVOQ19ET0NVTUVOVDogLyogRXh0cmEgb25lICovCisJICAgIC8qID8/IHRlbXBsYXRlID8/ICovCisJICAgIGdvdG8gc2VxdWVuY2VfY29uc3RydWN0b3I7CisJY2FzZSBYU0xUX0ZVTkNfRUxFTUVOVDoKKwkgICAgLyogPCEtLSBDb250ZW50OiB0ZW1wbGF0ZSAtLT4gKi8KKwkgICAgZ290byBzZXF1ZW5jZV9jb25zdHJ1Y3RvcjsKKwljYXNlIFhTTFRfRlVOQ19GQUxMQkFDSzoKKwkgICAgLyogPCEtLSBDb250ZW50OiB0ZW1wbGF0ZSAtLT4gKi8KKwkgICAgZ290byBzZXF1ZW5jZV9jb25zdHJ1Y3RvcjsKKwljYXNlIFhTTFRfRlVOQ19GT1JFQUNIOgorCSAgICAvKiA8IS0tIENvbnRlbnQ6ICh4c2w6c29ydCosIHRlbXBsYXRlKSAtLT4gKi8KKwkgICAgZ290byBmb3JfZWFjaDsKKwljYXNlIFhTTFRfRlVOQ19JRjoKKwkgICAgLyogPCEtLSBDb250ZW50OiB0ZW1wbGF0ZSAtLT4gKi8KKwkgICAgZ290byBzZXF1ZW5jZV9jb25zdHJ1Y3RvcjsKKwljYXNlIFhTTFRfRlVOQ19PVEhFUldJU0U6CisJICAgIC8qIDwhLS0gQ29udGVudDogdGVtcGxhdGUgLS0+ICovCisJICAgIGdvdG8gc2VxdWVuY2VfY29uc3RydWN0b3I7CisJY2FzZSBYU0xUX0ZVTkNfTUVTU0FHRToKKwkgICAgLyogPCEtLSBDb250ZW50OiB0ZW1wbGF0ZSAtLT4gKi8KKwkgICAgZ290byBzZXF1ZW5jZV9jb25zdHJ1Y3RvcjsKKwljYXNlIFhTTFRfRlVOQ19OVU1CRVI6CisJICAgIC8qIEVNUFRZICovCisJICAgIGdvdG8gZW1wdHlfY29udGVudDsKKwljYXNlIFhTTFRfRlVOQ19QQVJBTToKKwkgICAgLyoKKwkgICAgKiBDaGVjayBmb3IgcmVkZWZpbml0aW9uLgorCSAgICAqLworCSAgICBpZiAoKGVsZW0tPnBzdmkgIT0gTlVMTCkgJiYgKGNjdHh0LT5pdmFyICE9IE5VTEwpKSB7CisJCXhzbHRWYXJJbmZvUHRyIGl2YXIgPSBjY3R4dC0+aXZhcjsKKworCQlkbyB7CisJCSAgICBpZiAoKGl2YXItPm5hbWUgPT0KKwkJCSAoKHhzbHRTdHlsZUl0ZW1QYXJhbVB0cikgZWxlbS0+cHN2aSktPm5hbWUpICYmCisJCQkoaXZhci0+bnNOYW1lID09CisJCQkgKCh4c2x0U3R5bGVJdGVtUGFyYW1QdHIpIGVsZW0tPnBzdmkpLT5ucykpCisJCSAgICB7CisJCQllbGVtLT5wc3ZpID0gTlVMTDsKKwkJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIGVsZW0sCisJCQkgICAgIlJlZGVmaW5pdGlvbiBvZiB2YXJpYWJsZSBvciBwYXJhbWV0ZXIgJyVzJy5cbiIsCisJCQkgICAgaXZhci0+bmFtZSk7CisJCQljY3R4dC0+c3R5bGUtPmVycm9ycysrOworCQkJZ290byBlcnJvcjsKKwkJICAgIH0KKwkJICAgIGl2YXIgPSBpdmFyLT5wcmV2OworCQl9IHdoaWxlIChpdmFyICE9IE5VTEwpOworCSAgICB9CisJICAgIC8qICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPiAqLworCSAgICBnb3RvIHNlcXVlbmNlX2NvbnN0cnVjdG9yOworCWNhc2UgWFNMVF9GVU5DX1BJOgorCSAgICAvKiAgPCEtLSBDb250ZW50OiB0ZW1wbGF0ZSAtLT4gKi8KKwkgICAgZ290byBzZXF1ZW5jZV9jb25zdHJ1Y3RvcjsKKwljYXNlIFhTTFRfRlVOQ19TT1JUOgorCSAgICAvKiBFTVBUWSAqLworCSAgICBnb3RvIGVtcHR5X2NvbnRlbnQ7CisJY2FzZSBYU0xUX0ZVTkNfVEVYVDoKKwkgICAgLyogPCEtLSBDb250ZW50OiAjUENEQVRBIC0tPiAqLworCSAgICBnb3RvIHRleHQ7CisJY2FzZSBYU0xUX0ZVTkNfVkFMVUVPRjoKKwkgICAgLyogRU1QVFkgKi8KKwkgICAgZ290byBlbXB0eV9jb250ZW50OworCWNhc2UgWFNMVF9GVU5DX1ZBUklBQkxFOgorCSAgICAvKgorCSAgICAqIENoZWNrIGZvciByZWRlZmluaXRpb24uCisJICAgICovCisJICAgIGlmICgoZWxlbS0+cHN2aSAhPSBOVUxMKSAmJiAoY2N0eHQtPml2YXIgIT0gTlVMTCkpIHsKKwkJeHNsdFZhckluZm9QdHIgaXZhciA9IGNjdHh0LT5pdmFyOwkJCisKKwkJZG8geworCQkgICAgaWYgKChpdmFyLT5uYW1lID09CisJCQkgKCh4c2x0U3R5bGVJdGVtVmFyaWFibGVQdHIpIGVsZW0tPnBzdmkpLT5uYW1lKSAmJgorCQkJKGl2YXItPm5zTmFtZSA9PQorCQkJICgoeHNsdFN0eWxlSXRlbVZhcmlhYmxlUHRyKSBlbGVtLT5wc3ZpKS0+bnMpKQorCQkgICAgeworCQkJZWxlbS0+cHN2aSA9IE5VTEw7CisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBlbGVtLAorCQkJICAgICJSZWRlZmluaXRpb24gb2YgdmFyaWFibGUgb3IgcGFyYW1ldGVyICclcycuXG4iLAorCQkJICAgIGl2YXItPm5hbWUpOworCQkJY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwkJCWdvdG8gZXJyb3I7CisJCSAgICB9CisJCSAgICBpdmFyID0gaXZhci0+cHJldjsKKwkJfSB3aGlsZSAoaXZhciAhPSBOVUxMKTsKKwkgICAgfQorCSAgICAvKiA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPiAqLworCSAgICBnb3RvIHNlcXVlbmNlX2NvbnN0cnVjdG9yOworCWNhc2UgWFNMVF9GVU5DX1dIRU46CisJICAgIC8qIDwhLS0gQ29udGVudDogdGVtcGxhdGUgLS0+ICovCisJICAgIGdvdG8gc2VxdWVuY2VfY29uc3RydWN0b3I7CisJY2FzZSBYU0xUX0ZVTkNfV0lUSFBBUkFNOgorCSAgICAvKiA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPiAqLworCSAgICBnb3RvIHNlcXVlbmNlX2NvbnN0cnVjdG9yOworCWRlZmF1bHQ6CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKwkgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJInhzbHRQYXJzZVhTTFROb2RlOiBVbmhhbmRsZWQgWFNMVCBlbGVtZW50ICclcycuXG4iLAorCQllbGVtLT5uYW1lKTsJICAgIAorI2VuZGlmCisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIGVsZW0sCisJCSJ4c2x0UGFyc2VYU0xUTm9kZTogSW50ZXJuYWwgZXJyb3I7ICIKKwkJInVuaGFuZGxlZCBYU0xUIGVsZW1lbnQgJyVzJy5cbiIsIGVsZW0tPm5hbWUpOworCSAgICBjY3R4dC0+c3R5bGUtPmVycm9ycysrOworCSAgICBnb3RvIGludGVybmFsX2VycjsKKyAgICB9CisKK2FwcGx5X3RlbXBsYXRlczoKKyAgICAvKiA8IS0tIENvbnRlbnQ6ICh4c2w6c29ydCB8IHhzbDp3aXRoLXBhcmFtKSogLS0+ICovCisgICAgaWYgKGVsZW0tPmNoaWxkcmVuICE9IE5VTEwpIHsKKwl4bWxOb2RlUHRyIGNoaWxkID0gZWxlbS0+Y2hpbGRyZW47CisJZG8geworCSAgICBpZiAoY2hpbGQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgeworCQlpZiAoSVNfWFNMVF9FTEVNX0ZBU1QoY2hpbGQpKSB7CisJCSAgICBpZiAoeG1sU3RyRXF1YWwoY2hpbGQtPm5hbWUsIEJBRF9DQVNUICJ3aXRoLXBhcmFtIikpIHsKKwkJCWNjdHh0LT5pbm9kZS0+Y3VyQ2hpbGRUeXBlID0gWFNMVF9GVU5DX1dJVEhQQVJBTTsKKwkJCXhzbHRQYXJzZUFueVhTTFRFbGVtKGNjdHh0LCBjaGlsZCk7CisJCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGNoaWxkLT5uYW1lLCBCQURfQ0FTVCAic29ydCIpKSB7CisJCQljY3R4dC0+aW5vZGUtPmN1ckNoaWxkVHlwZSA9IFhTTFRfRlVOQ19TT1JUOworCQkJeHNsdFBhcnNlQW55WFNMVEVsZW0oY2N0eHQsIGNoaWxkKTsKKwkJICAgIH0gZWxzZQorCQkJeHNsdFBhcnNlQ29udGVudEVycm9yKGNjdHh0LT5zdHlsZSwgY2hpbGQpOworCQl9IGVsc2UKKwkJICAgIHhzbHRQYXJzZUNvbnRlbnRFcnJvcihjY3R4dC0+c3R5bGUsIGNoaWxkKTsKKwkgICAgfQorCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OworCX0gd2hpbGUgKGNoaWxkICE9IE5VTEwpOworICAgIH0gICAgCisgICAgZ290byBleGl0OworCitjYWxsX3RlbXBsYXRlOgorICAgIC8qIDwhLS0gQ29udGVudDogeHNsOndpdGgtcGFyYW0qIC0tPiAqLworICAgIGlmIChlbGVtLT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJeG1sTm9kZVB0ciBjaGlsZCA9IGVsZW0tPmNoaWxkcmVuOworCWRvIHsKKwkgICAgaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKKwkJaWYgKElTX1hTTFRfRUxFTV9GQVNUKGNoaWxkKSkgeworCQkgICAgeHNsdFN0eWxlVHlwZSB0eXBlOworCisJCSAgICB0eXBlID0geHNsdEdldFhTTFRFbGVtZW50VHlwZUJ5Tm9kZShjY3R4dCwgY2hpbGQpOworCQkgICAgaWYgKHR5cGUgPT0gWFNMVF9GVU5DX1dJVEhQQVJBTSkgeworCQkJY2N0eHQtPmlub2RlLT5jdXJDaGlsZFR5cGUgPSBYU0xUX0ZVTkNfV0lUSFBBUkFNOworCQkJeHNsdFBhcnNlQW55WFNMVEVsZW0oY2N0eHQsIGNoaWxkKTsKKwkJICAgIH0gZWxzZSB7CisJCQl4c2x0UGFyc2VDb250ZW50RXJyb3IoY2N0eHQtPnN0eWxlLCBjaGlsZCk7CisJCSAgICB9CisJCX0gZWxzZQorCQkgICAgeHNsdFBhcnNlQ29udGVudEVycm9yKGNjdHh0LT5zdHlsZSwgY2hpbGQpOworCSAgICB9CisJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CisJfSB3aGlsZSAoY2hpbGQgIT0gTlVMTCk7CisgICAgfSAgICAKKyAgICBnb3RvIGV4aXQ7CisKK3RleHQ6CisgICAgaWYgKGVsZW0tPmNoaWxkcmVuICE9IE5VTEwpIHsKKwl4bWxOb2RlUHRyIGNoaWxkID0gZWxlbS0+Y2hpbGRyZW47CisJZG8geworCSAgICBpZiAoKGNoaWxkLT50eXBlICE9IFhNTF9URVhUX05PREUpICYmCisJCShjaGlsZC0+dHlwZSAhPSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkKKwkgICAgeworCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBlbGVtLAorCQkgICAgIlRoZSBYU0xUICd0ZXh0JyBlbGVtZW50IG11c3QgaGF2ZSBvbmx5IGNoYXJhY3RlciAiCisJCSAgICAiZGF0YSBhcyBjb250ZW50LlxuIik7CisJICAgIH0KKwkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKKwl9IHdoaWxlIChjaGlsZCAhPSBOVUxMKTsKKyAgICB9CisgICAgZ290byBleGl0OworCitlbXB0eV9jb250ZW50OgorICAgIGlmIChlbGVtLT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJeG1sTm9kZVB0ciBjaGlsZCA9IGVsZW0tPmNoaWxkcmVuOworCS8qCisJKiBSZWxheGVkIGJlaGF2aW91cjogd2Ugd2lsbCBhbGxvdyB3aGl0ZXNwYWNlLW9ubHkgdGV4dC1ub2Rlcy4KKwkqLworCWRvIHsKKwkgICAgaWYgKCgoY2hpbGQtPnR5cGUgIT0gWE1MX1RFWFRfTk9ERSkgJiYKKwkJIChjaGlsZC0+dHlwZSAhPSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkgfHwKKwkJKCEgSVNfQkxBTktfTk9ERShjaGlsZCkpKQorCSAgICB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIGVsZW0sCisJCSAgICAiVGhpcyBYU0xUIGVsZW1lbnQgbXVzdCBoYXZlIG5vIGNvbnRlbnQuXG4iKTsKKwkJY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwkJYnJlYWs7CisJICAgIH0KKwkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKKwl9IHdoaWxlIChjaGlsZCAhPSBOVUxMKTsJCQorICAgIH0KKyAgICBnb3RvIGV4aXQ7CisKK2Nob29zZToKKyAgICAvKiA8IS0tIENvbnRlbnQ6ICh4c2w6d2hlbissIHhzbDpvdGhlcndpc2U/KSAtLT4gKi8KKyAgICAvKgorICAgICogVE9ETzogdGV4dC1ub2RlcyBpbiBiZXR3ZWVuIGFyZSAqbm90KiBhbGxvd2VkIGluIFhTTFQgMS4wLgorICAgICogICBUaGUgb2xkIGJlaGF2aW91ciBkaWQgbm90IGNoZWNrIHRoaXMuCisgICAgKiBOT1RFOiBJbiBYU0xUIDIuMCB0aGV5IGFyZSBzdHJpcHBlZCBiZWZvcmVoYW5kCisgICAgKiAgaWYgd2hpdGVzcGFjZS1vbmx5IChyZWdhcmRsZXNzIG9mIHhtbDpzcGFjZSkuCisgICAgKi8KKyAgICBpZiAoZWxlbS0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCXhtbE5vZGVQdHIgY2hpbGQgPSBlbGVtLT5jaGlsZHJlbjsKKwlpbnQgbmJXaGVuID0gMCwgbmJPdGhlcndpc2UgPSAwLCBlcnIgPSAwOworCWRvIHsKKwkgICAgaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKKwkJaWYgKElTX1hTTFRfRUxFTV9GQVNUKGNoaWxkKSkgeworCQkgICAgeHNsdFN0eWxlVHlwZSB0eXBlOworCQkKKwkJICAgIHR5cGUgPSB4c2x0R2V0WFNMVEVsZW1lbnRUeXBlQnlOb2RlKGNjdHh0LCBjaGlsZCk7CisJCSAgICBpZiAodHlwZSA9PSBYU0xUX0ZVTkNfV0hFTikgeworCQkJbmJXaGVuKys7CisJCQlpZiAobmJPdGhlcndpc2UpIHsKKwkJCSAgICB4c2x0UGFyc2VDb250ZW50RXJyb3IoY2N0eHQtPnN0eWxlLCBjaGlsZCk7CisJCQkgICAgZXJyID0gMTsKKwkJCSAgICBicmVhazsKKwkJCX0KKwkJCWNjdHh0LT5pbm9kZS0+Y3VyQ2hpbGRUeXBlID0gWFNMVF9GVU5DX1dIRU47CisJCQl4c2x0UGFyc2VBbnlYU0xURWxlbShjY3R4dCwgY2hpbGQpOworCQkgICAgfSBlbHNlIGlmICh0eXBlID09IFhTTFRfRlVOQ19PVEhFUldJU0UpIHsKKwkJCWlmICghIG5iV2hlbikgeworCQkJICAgIHhzbHRQYXJzZUNvbnRlbnRFcnJvcihjY3R4dC0+c3R5bGUsIGNoaWxkKTsKKwkJCSAgICBlcnIgPSAxOworCQkJICAgIGJyZWFrOworCQkJfQkJCQorCQkJaWYgKG5iT3RoZXJ3aXNlKSB7CisJCQkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgZWxlbSwKKwkJCQkiVGhlIFhTTFQgJ2Nob29zZScgZWxlbWVudCBtdXN0IG5vdCBjb250YWluICIKKwkJCQkibW9yZSB0aGFuIG9uZSBYU0xUICdvdGhlcndpc2UnIGVsZW1lbnQuXG4iKTsKKwkJCSAgICBjY3R4dC0+c3R5bGUtPmVycm9ycysrOworCQkJICAgIGVyciA9IDE7CisJCQkgICAgYnJlYWs7CisJCQl9CisJCQluYk90aGVyd2lzZSsrOworCQkJY2N0eHQtPmlub2RlLT5jdXJDaGlsZFR5cGUgPSBYU0xUX0ZVTkNfT1RIRVJXSVNFOworCQkJeHNsdFBhcnNlQW55WFNMVEVsZW0oY2N0eHQsIGNoaWxkKTsKKwkJICAgIH0gZWxzZQorCQkJeHNsdFBhcnNlQ29udGVudEVycm9yKGNjdHh0LT5zdHlsZSwgY2hpbGQpOworCQl9IGVsc2UKKwkJICAgIHhzbHRQYXJzZUNvbnRlbnRFcnJvcihjY3R4dC0+c3R5bGUsIGNoaWxkKTsKKwkgICAgfSAKKwkgICAgLyoKKwkJZWxzZQorCQkgICAgeHNsdFBhcnNlQ29udGVudEVycm9yKGNjdHh0LCBjaGlsZCk7CisJICAgICovCisJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CisJfSB3aGlsZSAoY2hpbGQgIT0gTlVMTCk7CisJaWYgKCghIGVycikgJiYgKCEgbmJXaGVuKSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBlbGVtLAorCQkiVGhlIFhTTFQgZWxlbWVudCAnY2hvb3NlJyBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lICIKKwkJIlhTTFQgZWxlbWVudCAnd2hlbicuXG4iKTsKKwkJY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwl9CQorICAgIH0gICAgCisgICAgZ290byBleGl0OworCitmb3JfZWFjaDoKKyAgICAvKiA8IS0tIENvbnRlbnQ6ICh4c2w6c29ydCosIHRlbXBsYXRlKSAtLT4gKi8KKyAgICAvKgorICAgICogTk9URTogVGV4dC1ub2RlcyBiZWZvcmUgeHNsOnNvcnQgYXJlICpub3QqIGFsbG93ZWQgaW4gWFNMVCAxLjAuCisgICAgKiAgIFRoZSBvbGQgYmVoYXZpb3VyIGRpZCBub3QgYWxsb3cgdGhpcywgYnV0IGl0IGNhdGNoZWQgdGhpcworICAgICogICBvbmx5IGF0IHRyYW5zZm9ybWF0aW9uLXRpbWUuCisgICAgKiAgIEluIFhTTFQgMi4wIHRoZXkgYXJlIHN0cmlwcGVkIGJlZm9yZWhhbmQgaWYgd2hpdGVzcGFjZS1vbmx5CisgICAgKiAgIChyZWdhcmRsZXNzIG9mIHhtbDpzcGFjZSkuCisgICAgKi8KKyAgICBpZiAoZWxlbS0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCXhtbE5vZGVQdHIgY2hpbGQgPSBlbGVtLT5jaGlsZHJlbjsKKwkvKgorCSogUGFyc2UgeHNsOnNvcnQgZmlyc3QuCisJKi8KKwlkbyB7CSAgICAKKwkgICAgaWYgKChjaGlsZC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSAmJgorCQlJU19YU0xUX0VMRU1fRkFTVChjaGlsZCkpCisJICAgIHsJCQorCQlpZiAoeHNsdEdldFhTTFRFbGVtZW50VHlwZUJ5Tm9kZShjY3R4dCwgY2hpbGQpID09CisJCSAgICBYU0xUX0ZVTkNfU09SVCkKKwkJewkJCisJCSAgICBjY3R4dC0+aW5vZGUtPmN1ckNoaWxkVHlwZSA9IFhTTFRfRlVOQ19TT1JUOworCQkgICAgeHNsdFBhcnNlQW55WFNMVEVsZW0oY2N0eHQsIGNoaWxkKTsKKwkJfSBlbHNlCisJCSAgICBicmVhazsKKwkgICAgfSBlbHNlCisJCWJyZWFrOworCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OworCX0gd2hpbGUgKGNoaWxkICE9IE5VTEwpOworCS8qCisJKiBQYXJzZSB0aGUgc2VxdWVjZSBjb25zdHJ1Y3Rvci4KKwkqLworCWlmIChjaGlsZCAhPSBOVUxMKQorCSAgICB4c2x0UGFyc2VTZXF1ZW5jZUNvbnN0cnVjdG9yKGNjdHh0LCBjaGlsZCk7CisgICAgfSAgICAKKyAgICBnb3RvIGV4aXQ7CisKK3NlcXVlbmNlX2NvbnN0cnVjdG9yOgorICAgIC8qCisgICAgKiBQYXJzZSB0aGUgc2VxdWVuY2UgY29uc3RydWN0b3IuCisgICAgKi8KKyAgICBpZiAoZWxlbS0+Y2hpbGRyZW4gIT0gTlVMTCkKKwl4c2x0UGFyc2VTZXF1ZW5jZUNvbnN0cnVjdG9yKGNjdHh0LCBlbGVtLT5jaGlsZHJlbik7CisKKyAgICAvKgorICAgICogUmVnaXN0ZXIgaW5mb3JtYXRpb24gZm9yIHZhcnMvcGFyYW1zLiBPbmx5IG5lZWRlZCBpZiB0aGVyZQorICAgICogYXJlIGFueSBmb2xsb3dpbmcgc2libGluZ3MuCisgICAgKi8KKyAgICBpZiAoKGVsZW0tPm5leHQgIT0gTlVMTCkgJiYKKwkoKGNjdHh0LT5pbm9kZS0+dHlwZSA9PSBYU0xUX0ZVTkNfVkFSSUFCTEUpIHx8CisJIChjY3R4dC0+aW5vZGUtPnR5cGUgPT0gWFNMVF9GVU5DX1BBUkFNKSkpCisgICAgewkKKwlpZiAoKGVsZW0tPnBzdmkgIT0gTlVMTCkgJiYKKwkgICAgKCgoeHNsdFN0eWxlQmFzaWNJdGVtVmFyaWFibGVQdHIpIGVsZW0tPnBzdmkpLT5uYW1lKSkKKwl7CQorCSAgICB4c2x0Q29tcGlsZXJWYXJJbmZvUHVzaChjY3R4dCwgZWxlbSwKKwkJKCh4c2x0U3R5bGVCYXNpY0l0ZW1WYXJpYWJsZVB0cikgZWxlbS0+cHN2aSktPm5hbWUsCisJCSgoeHNsdFN0eWxlQmFzaWNJdGVtVmFyaWFibGVQdHIpIGVsZW0tPnBzdmkpLT5ucyk7CisJfQorICAgIH0KKworZXJyb3I6CitleGl0OgorICAgIHhzbHRDb21waWxlck5vZGVQb3AoY2N0eHQsIGVsZW0pOworICAgIHJldHVybigwKTsKKworaW50ZXJuYWxfZXJyOgorICAgIHhzbHRDb21waWxlck5vZGVQb3AoY2N0eHQsIGVsZW0pOworICAgIHJldHVybigtMSk7Cit9CisKKy8qKgorICogeHNsdEZvcndhcmRzQ29tcGF0VW5rb3duSXRlbUNyZWF0ZToKKyAqCisgKiBAY2N0eHQ6IHRoZSBjb21waWxhdGlvbiBjb250ZXh0IAorICoKKyAqIENyZWF0ZXMgYSBjb21waWxlZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgdW5rbm93bgorICogWFNMVCBpbnN0cnVjdGlvbi4KKyAqCisgKiBSZXR1cm5zIHRoZSBjb21waWxlZCByZXByZXNlbnRhdGlvbi4KKyAqLyAKK3N0YXRpYyB4c2x0U3R5bGVJdGVtVWtub3duUHRyCit4c2x0Rm9yd2FyZHNDb21wYXRVbmtvd25JdGVtQ3JlYXRlKHhzbHRDb21waWxlckN0eHRQdHIgY2N0eHQpCit7CisgICAgeHNsdFN0eWxlSXRlbVVrbm93blB0ciBpdGVtOworCisgICAgaXRlbSA9ICh4c2x0U3R5bGVJdGVtVWtub3duUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhzbHRTdHlsZUl0ZW1Va25vd24pKTsKKyAgICBpZiAoaXRlbSA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgTlVMTCwKKwkgICAgIkludGVybmFsIGVycm9yIGluIHhzbHRGb3J3YXJkc0NvbXBhdFVua293bkl0ZW1DcmVhdGUoKTogIgorCSAgICAiRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeS5cbiIpOworCWNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBtZW1zZXQoaXRlbSwgMCwgc2l6ZW9mKHhzbHRTdHlsZUl0ZW1Va25vd24pKTsKKyAgICBpdGVtLT50eXBlID0gWFNMVF9GVU5DX1VOS09XTl9GT1JXQVJEU19DT01QQVQ7CisgICAgLyoKKyAgICAqIFN0b3JlIGl0IGluIHRoZSBzdHlsZXNoZWV0LgorICAgICovCisgICAgaXRlbS0+bmV4dCA9IGNjdHh0LT5zdHlsZS0+cHJlQ29tcHM7CisgICAgY2N0eHQtPnN0eWxlLT5wcmVDb21wcyA9ICh4c2x0RWxlbVByZUNvbXBQdHIpIGl0ZW07CisgICAgcmV0dXJuKGl0ZW0pOworfQorCisvKioKKyAqIHhzbHRQYXJzZVVua25vd25YU0xURWxlbToKKyAqCisgKiBAY2N0eHQ6IHRoZSBjb21waWxhdGlvbiBjb250ZXh0CisgKiBAbm9kZTogdGhlIGVsZW1lbnQgb2YgdGhlIHVua25vd24gWFNMVCBpbnN0cnVjdGlvbgorICoKKyAqIFBhcnNlcyBhbiB1bmtub3duIFhTTFQgZWxlbWVudC4KKyAqIElmIGZvcndhcmRzIGNvbXBhdGlibGUgbW9kZSBpcyBlbmFibGVkIHRoaXMgd2lsbCBhbGxvdworICogc3VjaCBhbiB1bmtub3duIFhTTFQgYW5kOyBvdGhlcndpc2UgaXQgaXMgcmVqZWN0ZWQuCisgKgorICogUmV0dXJucyAxIGluIHRoZSB1bmtub3duIFhTTFQgaW5zdHJ1Y3Rpb24gaXMgcmVqZWN0ZWQsCisgKiAgICAgICAgIDAgaWYgZXZlcnl0aGluZydzIGZpbmUgYW5kCisgKiAgICAgICAgIC0xIG9uIEFQSSBvciBpbnRlcm5hbCBlcnJvcnMuCisgKi8gCitzdGF0aWMgaW50Cit4c2x0UGFyc2VVbmtub3duWFNMVEVsZW0oeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwKKwkJCSAgICB4bWxOb2RlUHRyIG5vZGUpCit7CisgICAgaWYgKChjY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworCisgICAgLyoKKyAgICAqIERldGVjdGlvbiBvZiBoYW5kbGVkIGNvbnRlbnQgb2YgZXh0ZW5zaW9uIGluc3RydWN0aW9ucy4KKyAgICAqLworICAgIGlmIChjY3R4dC0+aW5vZGUtPmNhdGVnb3J5ID09IFhTTFRfRUxFTUVOVF9DQVRFR09SWV9FWFRFTlNJT04pIHsKKwljY3R4dC0+aW5vZGUtPmV4dENvbnRlbnRIYW5kbGVkID0gMTsKKyAgICB9ICAgIAorICAgIGlmIChjY3R4dC0+aW5vZGUtPmZvcndhcmRzQ29tcGF0ID09IDApIHsJCisJLyoKKwkqIFdlIGFyZSBub3QgaW4gZm9yd2FyZHMtY29tcGF0aWJsZSBtb2RlLCBzbyByYWlzZSBhbiBlcnJvci4KKwkqLworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIG5vZGUsCisJICAgICJVbmtub3duIFhTTFQgZWxlbWVudCAnJXMnLlxuIiwgbm9kZS0+bmFtZSk7CisJY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwlyZXR1cm4oMSk7CisgICAgfQorICAgIC8qCisgICAgKiBGb3J3YXJkcy1jb21wYXRpYmxlIG1vZGUuCisgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgICAqICAgIAorICAgICogUGFyc2UvY29tcGlsZSB4c2w6ZmFsbGJhY2sgZWxlbWVudHMuCisgICAgKgorICAgICogUVVFU1RJT046IERvIHdlIGhhdmUgdG8gcmFpc2UgYW4gZXJyb3IgaWYgdGhlcmUncyBubyB4c2w6ZmFsbGJhY2s/CisgICAgKiBBTlNXRVI6IE5vLCBzaW5jZSBpbiB0aGUgc3R5bGVzaGVldCB0aGUgZmFsbGJhY2sgYmVoYXZpb3VyIG1pZ2h0CisgICAgKiAgYWxzbyBiZSBwcm92aWRlZCBieSB1c2luZyB0aGUgWFNMVCBmdW5jdGlvbiAiZWxlbWVudC1hdmFpbGFibGUiLgorICAgICovCisgICAgaWYgKGNjdHh0LT51bmtub3duSXRlbSA9PSBOVUxMKSB7CisJLyoKKwkqIENyZWF0ZSBhIHNpbmdsZXRvbiBmb3IgYWxsIHVua25vd24gWFNMVCBpbnN0cnVjdGlvbnMuCisJKi8KKwljY3R4dC0+dW5rbm93bkl0ZW0gPSB4c2x0Rm9yd2FyZHNDb21wYXRVbmtvd25JdGVtQ3JlYXRlKGNjdHh0KTsKKwlpZiAoY2N0eHQtPnVua25vd25JdGVtID09IE5VTEwpIHsKKwkgICAgbm9kZS0+cHN2aSA9IE5VTEw7CisJICAgIHJldHVybigtMSk7CisJfQorICAgIH0KKyAgICBub2RlLT5wc3ZpID0gY2N0eHQtPnVua25vd25JdGVtOworICAgIGlmIChub2RlLT5jaGlsZHJlbiA9PSBOVUxMKQorCXJldHVybigwKTsKKyAgICBlbHNlIHsKKwl4bWxOb2RlUHRyIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CisKKwl4c2x0Q29tcGlsZXJOb2RlUHVzaChjY3R4dCwgbm9kZSk7CisJLyoKKwkqIFVwZGF0ZSB0aGUgaW4tc2NvcGUgbmFtZXNwYWNlcyBpZiBuZWVkZWQuCisJKi8KKwlpZiAobm9kZS0+bnNEZWYgIT0gTlVMTCkKKwkgICAgY2N0eHQtPmlub2RlLT5pblNjb3BlTnMgPQorCQl4c2x0Q29tcGlsZXJCdWlsZEluU2NvcGVOc0xpc3QoY2N0eHQsIG5vZGUpOworCS8qCisJKiBQYXJzZSBhbGwgeHNsOmZhbGxiYWNrIGNoaWxkcmVuLgorCSovCisJZG8geworCSAgICBpZiAoKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpICYmCisJCUlTX1hTTFRfRUxFTV9GQVNUKGNoaWxkKSAmJgorCQlJU19YU0xUX05BTUUoY2hpbGQsICJmYWxsYmFjayIpKQorCSAgICB7CisJCWNjdHh0LT5pbm9kZS0+Y3VyQ2hpbGRUeXBlID0gWFNMVF9GVU5DX0ZBTExCQUNLOworCQl4c2x0UGFyc2VBbnlYU0xURWxlbShjY3R4dCwgY2hpbGQpOworCSAgICB9CisJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CisJfSB3aGlsZSAoY2hpbGQgIT0gTlVMTCk7CisJCisJeHNsdENvbXBpbGVyTm9kZVBvcChjY3R4dCwgbm9kZSk7CisgICAgfQorICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0UGFyc2VTZXF1ZW5jZUNvbnN0cnVjdG9yOgorICoKKyAqIEBjY3R4dDogdGhlIGNvbXBpbGF0aW9uIGNvbnRleHQKKyAqIEBjdXI6IHRoZSBzdGFydC1ub2RlIG9mIHRoZSBjb250ZW50IHRvIGJlIHBhcnNlZAorICoKKyAqIFBhcnNlcyBhICJ0ZW1wbGF0ZSIgY29udGVudCAob3IgInNlcXVlbmNlIGNvbnN0cnVjdG9yIiBpbiBYU0xUIDIuMCB0ZXJtcykuCisgKiBUaGlzIHdpbGwgYWRkaXRpb25hbGx5IHJlbW92ZSB4c2w6dGV4dCBlbGVtZW50cyBmcm9tIHRoZSB0cmVlLgorICovIAordm9pZAoreHNsdFBhcnNlU2VxdWVuY2VDb25zdHJ1Y3Rvcih4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0LCB4bWxOb2RlUHRyIGN1cikKK3sKKyAgICB4c2x0U3R5bGVUeXBlIHR5cGU7CisgICAgeG1sTm9kZVB0ciBkZWxldGVOb2RlID0gTlVMTDsKKworICAgIGlmIChjY3R4dCA9PSBOVUxMKSB7CisJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCisJICAgICJ4c2x0UGFyc2VTZXF1ZW5jZUNvbnN0cnVjdG9yOiBCYWQgYXJndW1lbnRzXG4iKTsKKwljY3R4dC0+c3R5bGUtPmVycm9ycysrOworCXJldHVybjsKKyAgICB9CisgICAgLyoKKyAgICAqIERldGVjdGlvbiBvZiBoYW5kbGVkIGNvbnRlbnQgb2YgZXh0ZW5zaW9uIGluc3RydWN0aW9ucy4KKyAgICAqLworICAgIGlmIChjY3R4dC0+aW5vZGUtPmNhdGVnb3J5ID09IFhTTFRfRUxFTUVOVF9DQVRFR09SWV9FWFRFTlNJT04pIHsKKwljY3R4dC0+aW5vZGUtPmV4dENvbnRlbnRIYW5kbGVkID0gMTsKKyAgICB9CisgICAgaWYgKGN1ciA9PSBOVUxMKQorCXJldHVybjsKKyAgICAvKgorICAgICogVGhpcyBpcyB0aGUgY29udGVudCByZWZmZXJlZCB0byBhcyBhICJ0ZW1wbGF0ZSIuCisgICAgKiBFLmcuIGFuIHhzbDplbGVtZW50IGhhcyBzdWNoIGNvbnRlbnQgbW9kZWw6CisgICAgKiA8eHNsOmVsZW1lbnQKKyAgICAqICAgbmFtZSA9IHsgcW5hbWUgfQorICAgICogICBuYW1lc3BhY2UgPSB7IHVyaS1yZWZlcmVuY2UgfQorICAgICogICB1c2UtYXR0cmlidXRlLXNldHMgPSBxbmFtZXM+CisgICAgKiA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICAgICoKKyAgICAqIE5PVEUgdGhhdCBpbiBYU0xULTIgdGhlIHRlcm0gInRlbXBsYXRlIiB3YXMgYWJhbmRvbmVkIGR1ZSB0bworICAgICogIGNvbmZ1c2lvbiB3aXRoIHhzbDp0ZW1wbGF0ZSBhbmQgdGhlIHRlcm0gInNlcXVlbmNlIGNvbnN0cnVjdG9yIgorICAgICogIHdhcyBpbnRyb2R1Y2VkIGluc3RlYWQuCisgICAgKgorICAgICogVGhlIGZvbGxvd2luZyBYU0xULWluc3RydWN0aW9ucyBhcmUgYWxsb3dlZCB0byBhcHBlYXI6CisgICAgKiAgeHNsOmFwcGx5LXRlbXBsYXRlcywgeHNsOmNhbGwtdGVtcGxhdGUsIHhzbDphcHBseS1pbXBvcnRzLAorICAgICogIHhzbDpmb3ItZWFjaCwgeHNsOnZhbHVlLW9mLCB4c2w6Y29weS1vZiwgeHNsOm51bWJlciwKKyAgICAqICB4c2w6Y2hvb3NlLCB4c2w6aWYsIHhzbDp0ZXh0LCB4c2w6Y29weSwgeHNsOnZhcmlhYmxlLAorICAgICogIHhzbDptZXNzYWdlLCB4c2w6ZmFsbGJhY2ssCisgICAgKiAgeHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sIHhzbDpjb21tZW50LCB4c2w6ZWxlbWVudAorICAgICogIHhzbDphdHRyaWJ1dGUuIAorICAgICogQWRkaXRpb25hbCBhbGxvd2VkIGNvbnRlbnQ6CisgICAgKiAxKSBleHRlbnNpb24gaW5zdHJ1Y3Rpb25zCisgICAgKiAyKSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50cworICAgICogMykgUENEQVRBCisgICAgKgorICAgICogTk9URSB0aGF0IHRoaXMgY29udGVudCBtb2RlbCBkb2VzICpub3QqIGFsbG93IHhzbDpwYXJhbS4KKyAgICAqLyAgICAKKyAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKKwlpZiAoZGVsZXRlTm9kZSAhPSBOVUxMKQl7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0JMQU5LUworCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgInhzbHRQYXJzZVNlcXVlbmNlQ29uc3RydWN0b3I6IHJlbW92aW5nIHhzbDp0ZXh0IGVsZW1lbnRcbiIpOworI2VuZGlmCisJICAgIHhtbFVubGlua05vZGUoZGVsZXRlTm9kZSk7CisJICAgIHhtbEZyZWVOb2RlKGRlbGV0ZU5vZGUpOworCSAgICBkZWxldGVOb2RlID0gTlVMTDsKKwl9CisJaWYgKGN1ci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CSAgICAKKwkgICAgCisJICAgIGlmIChjdXItPnBzdmkgPT0geHNsdFhTTFRUZXh0TWFya2VyKSB7CisJCS8qCisJCSogeHNsOnRleHQgZWxlbWVudHMKKwkJKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCQkqLworCQl4bWxOb2RlUHRyIHRtcDsKKworCQljdXItPnBzdmkgPSBOVUxMOworCQkvKgorCQkqIE1hcmsgdGhlIHhzbDp0ZXh0IGVsZW1lbnQgZm9yIGxhdGVyIGRlbGV0aW9uLgorCQkqLworCQlkZWxldGVOb2RlID0gY3VyOworCQkvKgorCQkqIFZhbGlkYXRlIGNvbnRlbnQuCisJCSovCisJCXRtcCA9IGN1ci0+Y2hpbGRyZW47CisJCWlmICh0bXApIHsKKwkJICAgIC8qCisJCSAgICAqIFdlIGRvbid0IGV4cGVjdCBtb3JlIHRoYW4gb25lIHRleHQtbm9kZSBpbiB0aGUKKwkJICAgICogY29udGVudCwgc2luY2Ugd2UgYWxyZWFkeSBtZXJnZWQgYWRqYWNlbnQKKwkJICAgICogdGV4dC9DREFUQS1ub2RlcyBhbmQgZWxpbWluYXRlZCBQSS9jb21tZW50LW5vZGVzLgorCQkgICAgKi8KKwkJICAgIGlmICgodG1wLT50eXBlID09IFhNTF9URVhUX05PREUpIHx8CisJCQkodG1wLT5uZXh0ID09IE5VTEwpKQorCQkgICAgeworCQkJLyoKKwkJCSogTGVhdmUgdGhlIGNvbnRhaW5lZCB0ZXh0LW5vZGUgaW4gdGhlIHRyZWUuCisJCQkqLworCQkJeG1sVW5saW5rTm9kZSh0bXApOworCQkJeG1sQWRkUHJldlNpYmxpbmcoY3VyLCB0bXApOworCQkgICAgfSBlbHNlIHsKKwkJCXRtcCA9IE5VTEw7CisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBjdXIsCisJCQkgICAgIkVsZW1lbnQgJ3hzbDp0ZXh0JzogSW52YWxpZCB0eXBlICIKKwkJCSAgICAib2Ygbm9kZSBmb3VuZCBpbiBjb250ZW50LlxuIik7CisJCQljY3R4dC0+c3R5bGUtPmVycm9ycysrOworCQkgICAgfSAKKwkJfQorCQlpZiAoY3VyLT5wcm9wZXJ0aWVzKSB7CisJCSAgICB4bWxBdHRyUHRyIGF0dHI7CisJCSAgICAvKgorCQkgICAgKiBUT0RPOiBXZSBuZWVkIHRvIHJlcG9ydCBlcnJvcnMgZm9yCisJCSAgICAqICBpbnZhbGlkIGF0dHJzLgorCQkgICAgKi8KKwkJICAgIGF0dHIgPSBjdXItPnByb3BlcnRpZXM7CisJCSAgICBkbyB7CisJCQlpZiAoKGF0dHItPm5zID09IE5VTEwpICYmCisJCQkgICAgKGF0dHItPm5hbWUgIT0gTlVMTCkgJiYKKwkJCSAgICAoYXR0ci0+bmFtZVswXSA9PSAnZCcpICYmCisJCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwKKwkJCSAgICBCQURfQ0FTVCAiZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciKSkKKwkJCXsKKwkJCSAgICAvKgorCQkJICAgICogQXR0ciAiZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmciLgorCQkJICAgICogWFNMVC0yOiBUaGlzIGF0dHJpYnV0ZSBpcyBkZXByZWNhdGVkLgorCQkJICAgICovCisJCQkgICAgaWYgKChhdHRyLT5jaGlsZHJlbiAhPSBOVUxMKSAmJgorCQkJCXhtbFN0ckVxdWFsKGF0dHItPmNoaWxkcmVuLT5jb250ZW50LAorCQkJCUJBRF9DQVNUICJ5ZXMiKSkKKwkJCSAgICB7CisJCQkJLyoKKwkJCQkqIERpc2FibGUgb3V0cHV0IGVzY2FwaW5nIGZvciB0aGlzCisJCQkJKiB0ZXh0IG5vZGUuCisJCQkJKi8KKwkJCQlpZiAodG1wKQorCQkJCSAgICB0bXAtPm5hbWUgPSB4bWxTdHJpbmdUZXh0Tm9lbmM7CisJCQkgICAgfSBlbHNlIGlmICgoYXR0ci0+Y2hpbGRyZW4gPT0gTlVMTCkgfHwKKwkJCQkoYXR0ci0+Y2hpbGRyZW4tPmNvbnRlbnQgPT0gTlVMTCkgfHwKKwkJCQkoIXhtbFN0ckVxdWFsKGF0dHItPmNoaWxkcmVuLT5jb250ZW50LAorCQkJCUJBRF9DQVNUICJubyIpKSkKKwkJCSAgICB7CisJCQkJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwKKwkJCQkgICAgY3VyLAorCQkJCSAgICAiQXR0cmlidXRlICdkaXNhYmxlLW91dHB1dC1lc2NhcGluZyc6ICIKKwkJCQkgICAgIkludmFsaWQgdmFsdWUuIEV4cGVjdGVkIGlzICIKKwkJCQkgICAgIid5ZXMnIG9yICdubycuXG4iKTsKKwkJCQljY3R4dC0+c3R5bGUtPmVycm9ycysrOworCQkJICAgIH0KKwkJCSAgICBicmVhazsKKwkJCX0KKwkJCWF0dHIgPSBhdHRyLT5uZXh0OworCQkgICAgfSB3aGlsZSAoYXR0ciAhPSBOVUxMKTsKKwkJfQorCSAgICB9IGVsc2UgaWYgKElTX1hTTFRfRUxFTV9GQVNUKGN1cikpIHsKKwkJLyoKKwkJKiBUT0RPOiBVc2luZyB0aGUgWFNMVC1tYXJrZXIgaXMgc3RpbGwgbm90IHN0YWJsZSB5ZXQuCisJCSovCisJCS8qIGlmIChjdXItPnBzdmkgPT0geHNsdFhTTFRFbGVtTWFya2VyKSB7ICovCSAgICAKKwkJLyoKKwkJKiBYU0xUIGluc3RydWN0aW9ucworCQkqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisJCSovCisJCWN1ci0+cHN2aSA9IE5VTEw7CisJCXR5cGUgPSB4c2x0R2V0WFNMVEVsZW1lbnRUeXBlQnlOb2RlKGNjdHh0LCBjdXIpOworCQlzd2l0Y2ggKHR5cGUpIHsKKwkJICAgIGNhc2UgWFNMVF9GVU5DX0FQUExZSU1QT1JUUzoKKwkJICAgIGNhc2UgWFNMVF9GVU5DX0FQUExZVEVNUExBVEVTOgorCQkgICAgY2FzZSBYU0xUX0ZVTkNfQVRUUklCVVRFOgorCQkgICAgY2FzZSBYU0xUX0ZVTkNfQ0FMTFRFTVBMQVRFOgorCQkgICAgY2FzZSBYU0xUX0ZVTkNfQ0hPT1NFOgorCQkgICAgY2FzZSBYU0xUX0ZVTkNfQ09NTUVOVDoKKwkJICAgIGNhc2UgWFNMVF9GVU5DX0NPUFk6CisJCSAgICBjYXNlIFhTTFRfRlVOQ19DT1BZT0Y6CisJCSAgICBjYXNlIFhTTFRfRlVOQ19ET0NVTUVOVDogLyogRXh0cmEgb25lICovCisJCSAgICBjYXNlIFhTTFRfRlVOQ19FTEVNRU5UOgorCQkgICAgY2FzZSBYU0xUX0ZVTkNfRkFMTEJBQ0s6CisJCSAgICBjYXNlIFhTTFRfRlVOQ19GT1JFQUNIOgorCQkgICAgY2FzZSBYU0xUX0ZVTkNfSUY6CisJCSAgICBjYXNlIFhTTFRfRlVOQ19NRVNTQUdFOgorCQkgICAgY2FzZSBYU0xUX0ZVTkNfTlVNQkVSOgorCQkgICAgY2FzZSBYU0xUX0ZVTkNfUEk6CisJCSAgICBjYXNlIFhTTFRfRlVOQ19URVhUOgorCQkgICAgY2FzZSBYU0xUX0ZVTkNfVkFMVUVPRjoKKwkJICAgIGNhc2UgWFNMVF9GVU5DX1ZBUklBQkxFOgorCQkJLyoKKwkJCSogUGFyc2UgdGhlIFhTTFQgZWxlbWVudC4KKwkJCSovCisJCQljY3R4dC0+aW5vZGUtPmN1ckNoaWxkVHlwZSA9IHR5cGU7CisJCQl4c2x0UGFyc2VBbnlYU0xURWxlbShjY3R4dCwgY3VyKTsKKwkJCWJyZWFrOworCQkgICAgZGVmYXVsdDoKKwkJCXhzbHRQYXJzZVVua25vd25YU0xURWxlbShjY3R4dCwgY3VyKTsJCQkKKwkJCWN1ciA9IGN1ci0+bmV4dDsKKwkJCWNvbnRpbnVlOworCQl9CisJICAgIH0gZWxzZSB7CisJCS8qCisJCSogTm9uLVhTTFQgZWxlbWVudHMKKwkJKiAtLS0tLS0tLS0tLS0tLS0tLQorCQkqLworCQl4c2x0Q29tcGlsZXJOb2RlUHVzaChjY3R4dCwgY3VyKTsKKwkJLyoKKwkJKiBVcGRhdGUgdGhlIGluLXNjb3BlIG5hbWVzcGFjZXMgaWYgbmVlZGVkLgorCQkqLworCQlpZiAoY3VyLT5uc0RlZiAhPSBOVUxMKQorCQkgICAgY2N0eHQtPmlub2RlLT5pblNjb3BlTnMgPQorCQkJeHNsdENvbXBpbGVyQnVpbGRJblNjb3BlTnNMaXN0KGNjdHh0LCBjdXIpOworCQkvKgorCQkqIFRoZSBjdXJyZW50IGVsZW1lbnQgaXMgZWl0aGVyIGEgbGl0ZXJhbCByZXN1bHQgZWxlbWVudAorCQkqIG9yIGFuIGV4dGVuc2lvbiBpbnN0cnVjdGlvbi4KKwkJKgorCQkqIFByb2Nlc3MgYXR0ciAieHNsOmV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIi4KKwkJKiBGVVRVUkUgVE9ETzogSUlSQyBpbiBYU0xUIDIuMCB0aGlzIGF0dHJpYnV0ZSBtdXN0IGJlCisJCSogcHJvY2Vzc2VkIGJ5IHRoZSBpbXBsZW1lbnRvciBvZiB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9uOworCQkqIGkuZS4sIGl0IHdvbid0IGJlIGhhbmRsZWQgYnkgdGhlIFhTTFQgcHJvY2Vzc29yLgorCQkqLworCQkvKiBTUEVDIDEuMDoKKwkJKiAgICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIgaXMgb25seSBhbGxvd2VkIG9uIGxpdGVyYWwKKwkJKiAgIHJlc3VsdCBlbGVtZW50cyBhbmQgInhzbDpleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIKKwkJKiAgIG9uIHhzbDpzdHlsZXNoZWV0L3hzbDp0cmFuc2Zvcm0uCisJCSogU1BFQyAyLjA6CisJCSogICAiVGhlcmUgYXJlIGEgbnVtYmVyIG9mIHN0YW5kYXJkIGF0dHJpYnV0ZXMKKwkJKiAgIHRoYXQgbWF5IGFwcGVhciBvbiBhbnkgWFNMVCBlbGVtZW50OiBzcGVjaWZpY2FsbHkKKwkJKiAgIHZlcnNpb24sIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzLAorCQkqICAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMsIHhwYXRoLWRlZmF1bHQtbmFtZXNwYWNlLAorCQkqICAgZGVmYXVsdC1jb2xsYXRpb24sIGFuZCB1c2Utd2hlbi4iCisJCSoKKwkJKiBTUEVDIDIuMDoKKwkJKiAgIEZvciBsaXRlcmFsIHJlc3VsdCBlbGVtZW50czoKKwkJKiAgICJ4c2w6dmVyc2lvbiwgeHNsOmV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzLAorCQkqICAgIHhzbDpleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcywKKwkJKiAgICB4c2w6eHBhdGgtZGVmYXVsdC1uYW1lc3BhY2UsCisJCSogICAgeHNsOmRlZmF1bHQtY29sbGF0aW9uLCBvciB4c2w6dXNlLXdoZW4uIgorCQkqLworCQlpZiAoY3VyLT5wcm9wZXJ0aWVzKQorCQkgICAgY2N0eHQtPmlub2RlLT5leHRFbGVtTnMgPQorCQkJeHNsdFBhcnNlRXh0RWxlbVByZWZpeGVzKGNjdHh0LAorCQkJICAgIGN1ciwgY2N0eHQtPmlub2RlLT5leHRFbGVtTnMsCisJCQkgICAgWFNMVF9FTEVNRU5UX0NBVEVHT1JZX0xSRSk7CisJCS8qCisJCSogRXZhbCBpZiB3ZSBoYXZlIGFuIGV4dGVuc2lvbiBpbnN0cnVjdGlvbiBoZXJlLgorCQkqLworCQlpZiAoKGN1ci0+bnMgIT0gTlVMTCkgJiYKKwkJICAgIChjY3R4dC0+aW5vZGUtPmV4dEVsZW1OcyAhPSBOVUxMKSAmJgorCQkgICAgKHhzbHRDaGVja0V4dFByZWZpeChjY3R4dC0+c3R5bGUsIGN1ci0+bnMtPmhyZWYpID09IDEpKQorCQl7CisJCSAgICAvKgorCQkgICAgKiBFeHRlbnNpb24gaW5zdHJ1Y3Rpb25zCisJCSAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwkJICAgICogTWFyayB0aGUgbm9kZSBpbmZvcm1hdGlvbi4KKwkJICAgICovCisJCSAgICBjY3R4dC0+aW5vZGUtPmNhdGVnb3J5ID0gWFNMVF9FTEVNRU5UX0NBVEVHT1JZX0VYVEVOU0lPTjsKKwkJICAgIGNjdHh0LT5pbm9kZS0+ZXh0Q29udGVudEhhbmRsZWQgPSAwOworCQkgICAgaWYgKGN1ci0+cHN2aSAhPSBOVUxMKSB7CisJCQljdXItPnBzdmkgPSBOVUxMOworCQkJLyoKKwkJCSogVE9ETzogVGVtcG9yYXJ5IHNhbml0eSBjaGVjay4KKwkJCSovCisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBjdXIsCisJCQkgICAgIkludGVybmFsIGVycm9yIGluIHhzbHRQYXJzZVNlcXVlbmNlQ29uc3RydWN0b3IoKTogIgorCQkJICAgICJPY2N1cGllZCBQU1ZJIGZpZWxkLlxuIik7CisJCQljY3R4dC0+c3R5bGUtPmVycm9ycysrOworCQkJY3VyID0gY3VyLT5uZXh0OworCQkJY29udGludWU7CisJCSAgICB9CisJCSAgICBjdXItPnBzdmkgPSAodm9pZCAqKQorCQkJeHNsdFByZUNvbXB1dGVFeHRNb2R1bGVFbGVtZW50KGNjdHh0LT5zdHlsZSwgY3VyKTsKKwkJICAgIAorCQkgICAgaWYgKGN1ci0+cHN2aSA9PSBOVUxMKSB7CisJCQkvKgorCQkJKiBPTEQgQ09NTUVOVDogIlVua25vd24gZWxlbWVudCwgbWF5YmUgcmVnaXN0ZXJlZAorCQkJKiAgYXQgdGhlIGNvbnRleHQgbGV2ZWwuIE1hcmsgaXQgZm9yIGxhdGVyCisJCQkqICByZWNvZ25pdGlvbi4iCisJCQkqIFFVRVNUSU9OOiBXaGF0IGRvZXMgdGhlIHhzbHRFeHRNYXJrZXIgbWVhbj8KKwkJCSogIEFOU1dFUjogSXQgaXMgdXNlZCBpbgorCQkJKiAgIHhzbHRBcHBseVNlcXVlbmNlQ29uc3RydWN0b3IoKSBhdAorCQkJKiAgIHRyYW5zZm9ybWF0aW9uLXRpbWUgdG8gbG9vayBvdXQgZm9yIGV4dGVuc2lvbgorCQkJKiAgIHJlZ2lzdGVyZWQgaW4gdGhlIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQuCisJCQkqLworCQkJY3VyLT5wc3ZpID0gKHZvaWQgKikgeHNsdEV4dE1hcmtlcjsKKwkJICAgIH0KKwkJICAgIC8qCisJCSAgICAqIEJJRyBOT1RFOiBOb3cgdGhlIHVnbHkgcGFydC4gSW4gcHJldmlvdXMgdmVyc2lvbnMKKwkJICAgICogIG9mIExpYnhzbHQgKHVudGlsIDEuMS4xNiksIGFsbCB0aGUgY29udGVudCBvZiBhbgorCQkgICAgKiAgZXh0ZW5zaW9uIGluc3RydWN0aW9uIHdhcyBwcm9jZXNzZWQgYW5kIGNvbXBpbGVkIHdpdGhvdXQKKwkJICAgICogIHRoZSBuZWVkIG9mIHRoZSBleHRlbnNpb24tYXV0aG9yIHRvIGV4cGxpY2l0ZWx5IGNhbGwKKwkJICAgICogIHN1Y2ggYSBwcm9jZXNzaW5nOy5XZSBub3cgbmVlZCB0byBtaW1pYyB0aGlzIG9sZAorCQkgICAgKiAgYmVoYXZpb3VyIGluIG9yZGVyIHRvIGF2b2lkIGJyZWFraW5nIG9sZCBjb2RlCisJCSAgICAqICBvbiB0aGUgZXh0ZW5zaW9uLWF1dGhvcidzIHNpZGUuCisJCSAgICAqIFRoZSBtZWNoYW5pc206CisJCSAgICAqICAxKSBJZiB0aGUgYXV0aG9yIGRvZXMgKm5vdCogc2V0IHRoZQorCQkgICAgKiAgICBjb21waWxlLXRpbWUtZmxhZyBAZXh0Q29udGVudEhhbmRsZWQsIHRoZW4gd2UnbGwKKwkJICAgICogICAgcGFyc2UgdGhlIGNvbnRlbnQgYXNzdW1pbmcgdGhhdCBpdCdzIGEgInRlbXBsYXRlIgorCQkgICAgKiAgICAob3IgInNlcXVlbmNlIGNvbnN0cnVjdG9yIGluIFhTTFQgMi4wIHRlcm1zKS4KKwkJICAgICogICAgTk9URTogSWYgdGhlIGV4dGVuc2lvbiBpcyByZWdpc3RlcmVkIGF0CisJCSAgICAqICAgIHRyYW5zZm9ybWF0aW9uLXRpbWUgb25seSwgdGhlbiB0aGVyZSdzIG5vIHdheSBvZgorCQkgICAgKiAgICBrbm93aW5nIHRoYXQgY29udGVudCBzaGFsbCBiZSB2YWxpZCwgYW5kIHdlJ2xsCisJCSAgICAqICAgIHByb2Nlc3MgdGhlIGNvbnRlbnQgdGhlIHNhbWUgd2F5LgorCQkgICAgKiAgMikgSWYgdGhlIGF1dGhvciAqZG9lcyogc2V0IHRoZSBmbGFnLCB0aGVuIHdlJ2xsIGFzc3VtZQorCQkgICAgKiAgIHRoYXQgdGhlIGF1dGhvciBoYXMgaGFuZGxlZCB0aGUgcGFyc2luZyBoaW0vaGVyc2VsZgorCQkgICAgKiAgIChlLmcuIGNhbGxlZCB4c2x0UGFyc2VTZXF1ZW5jZUNvbnN0cnVjdG9yKCksIGV0Yy4KKwkJICAgICogICBleHBsaWNpdGVseSBpbiBoaXMvaGVyIGNvZGUpLgorCQkgICAgKi8KKwkJICAgIGlmICgoY3VyLT5jaGlsZHJlbiAhPSBOVUxMKSAmJgorCQkJKGNjdHh0LT5pbm9kZS0+ZXh0Q29udGVudEhhbmRsZWQgPT0gMCkpCisJCSAgICB7CisJCQkvKgorCQkJKiBEZWZhdWx0IHBhcnNpbmcgb2YgdGhlIGNvbnRlbnQgdXNpbmcgdGhlCisJCQkqIHNlcXVlbmNlLWNvbnN0cnVjdG9yIG1vZGVsLgorCQkJKi8KKwkJCXhzbHRQYXJzZVNlcXVlbmNlQ29uc3RydWN0b3IoY2N0eHQsIGN1ci0+Y2hpbGRyZW4pOworCQkgICAgfQorCQl9IGVsc2UgeworCQkgICAgLyoKKwkJICAgICogTGl0ZXJhbCByZXN1bHQgZWxlbWVudAorCQkgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisJCSAgICAqIEFsbG93ZWQgWFNMVCBhdHRyaWJ1dGVzOgorCQkgICAgKiAgeHNsOmV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIENEQVRBICNJTVBMSUVECisJCSAgICAqICB4c2w6ZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgQ0RBVEEgI0lNUExJRUQKKwkJICAgICogIFRPRE86IHhzbDp1c2UtYXR0cmlidXRlLXNldHMgJXFuYW1lczsgI0lNUExJRUQKKwkJICAgICogIHhzbDp2ZXJzaW9uIE5NVE9LRU4gI0lNUExJRUQKKwkJICAgICovCisJCSAgICBjdXItPnBzdmkgPSBOVUxMOworCQkgICAgY2N0eHQtPmlub2RlLT5jYXRlZ29yeSA9IFhTTFRfRUxFTUVOVF9DQVRFR09SWV9MUkU7CisJCSAgICBpZiAoY3VyLT5wcm9wZXJ0aWVzICE9IE5VTEwpIHsKKwkJCXhtbEF0dHJQdHIgYXR0ciA9IGN1ci0+cHJvcGVydGllczsKKwkJCS8qCisJCQkqIEF0dHJpYnV0ZSAieHNsOmV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIi4KKwkJCSovCisJCQljY3R4dC0+aW5vZGUtPmV4Y2xSZXN1bHROcyA9CisJCQkgICAgeHNsdFBhcnNlRXhjbFJlc3VsdFByZWZpeGVzKGNjdHh0LCBjdXIsCisJCQkJY2N0eHQtPmlub2RlLT5leGNsUmVzdWx0TnMsCisJCQkJWFNMVF9FTEVNRU5UX0NBVEVHT1JZX0xSRSk7CisJCQkvKgorCQkJKiBBdHRyaWJ1dGUgInhzbDp2ZXJzaW9uIi4KKwkJCSovCisJCQl4c2x0UGFyc2VBdHRyWFNMVFZlcnNpb24oY2N0eHQsIGN1ciwKKwkJCSAgICBYU0xUX0VMRU1FTlRfQ0FURUdPUllfTFJFKTsKKwkJCS8qCisJCQkqIFJlcG9ydCBpbnZhbGlkIFhTTFQgYXR0cmlidXRlcy4JCQkKKwkJCSogRm9yIFhTTFQgMS4wIG9ubHkgeHNsOnVzZS1hdHRyaWJ1dGUtc2V0cyBpcyBhbGxvd2VkCisJCQkqIG5leHQgdG8geHNsOnZlcnNpb24sIHhzbDpleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyBhbmQKKwkJCSogeHNsOmV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzLgorCQkJKgorCQkJKiBNYXJrIGFsbCBYU0xUIGF0dHJpYnV0ZXMsIGluIG9yZGVyIHRvIHNraXAgc3VjaAorCQkJKiBhdHRyaWJ1dGVzIHdoZW4gaW5zdGFudGlhdGluZyB0aGUgTFJFLgorCQkJKi8KKwkJCWRvIHsKKwkJCSAgICBpZiAoKGF0dHItPnBzdmkgIT0geHNsdFhTTFRBdHRyTWFya2VyKSAmJgorCQkJCUlTX1hTTFRfQVRUUl9GQVNUKGF0dHIpKQorCQkJICAgIHsJCQkJICAgIAorCQkJCWlmICghIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsCisJCQkJICAgIEJBRF9DQVNUICJ1c2UtYXR0cmlidXRlLXNldHMiKSkKKwkJCQl7CQkJCQorCQkJCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLAorCQkJCQljdXIsCisJCQkJCSJVbmtub3duIFhTTFQgYXR0cmlidXRlICclcycuXG4iLAorCQkJCQlhdHRyLT5uYW1lKTsKKwkJCQkgICAgY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwkJCQl9IGVsc2UgeworCQkJCSAgICAvKgorCQkJCSAgICAqIFhTTFQgYXR0ciBtYXJrZXIuCisJCQkJICAgICovCisJCQkJICAgIGF0dHItPnBzdmkgPSAodm9pZCAqKSB4c2x0WFNMVEF0dHJNYXJrZXI7CisJCQkJfQorCQkJICAgIH0KKwkJCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKKwkJCX0gd2hpbGUgKGF0dHIgIT0gTlVMTCk7CisJCSAgICB9CisJCSAgICAvKgorCQkgICAgKiBDcmVhdGUvcmV1c2UgaW5mbyBmb3IgdGhlIGxpdGVyYWwgcmVzdWx0IGVsZW1lbnQuCisJCSAgICAqLworCQkgICAgaWYgKGNjdHh0LT5pbm9kZS0+bnNDaGFuZ2VkKQorCQkJeHNsdExSRUluZm9DcmVhdGUoY2N0eHQsIGN1ciwgMSk7CisJCSAgICBjdXItPnBzdmkgPSBjY3R4dC0+aW5vZGUtPmxpdFJlc0VsZW1JbmZvOworCQkgICAgLyoKKwkJICAgICogQXBwbHkgbnMtYWxpYXNpbmcgb24gdGhlIGVsZW1lbnQgYW5kIG9uIGl0cyBhdHRyaWJ1dGVzLgorCQkgICAgKi8KKwkJICAgIGlmIChjY3R4dC0+aGFzTnNBbGlhc2VzKQorCQkJeHNsdExSRUJ1aWxkRWZmZWN0aXZlTnMoY2N0eHQsIGN1cik7CisJCSAgICAvKgorCQkgICAgKiBDb21waWxlIGF0dHJpYnV0ZSB2YWx1ZSB0ZW1wbGF0ZXMgKEFWVCkuCisJCSAgICAqLworCQkgICAgaWYgKGN1ci0+cHJvcGVydGllcykgeworCQkJeG1sQXR0clB0ciBhdHRyID0gY3VyLT5wcm9wZXJ0aWVzOworCQkJCisJCQl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CisJCQkgICAgeHNsdENvbXBpbGVBdHRyKGNjdHh0LT5zdHlsZSwgYXR0cik7CisJCQkgICAgYXR0ciA9IGF0dHItPm5leHQ7CisJCQl9CisJCSAgICB9CisJCSAgICAvKgorCQkgICAgKiBQYXJzZSB0aGUgY29udGVudCwgd2hpY2ggaXMgZGVmaW5lZCB0byBiZSBhICJ0ZW1wbGF0ZSIKKwkJICAgICogKG9yICJzZXF1ZW5jZSBjb25zdHJ1Y3RvciIgaW4gWFNMVCAyLjAgdGVybXMpLgorCQkgICAgKi8KKwkJICAgIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKKwkJCXhzbHRQYXJzZVNlcXVlbmNlQ29uc3RydWN0b3IoY2N0eHQsIGN1ci0+Y2hpbGRyZW4pOworCQkgICAgfQorCQl9CisJCS8qCisJCSogTGVhdmUgdGhlIG5vbi1YU0xUIGVsZW1lbnQuCisJCSovCisJCXhzbHRDb21waWxlck5vZGVQb3AoY2N0eHQsIGN1cik7CisJICAgIH0KKwl9CisJY3VyID0gY3VyLT5uZXh0OworICAgIH0KKyAgICBpZiAoZGVsZXRlTm9kZSAhPSBOVUxMKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0JMQU5LUworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICJ4c2x0UGFyc2VTZXF1ZW5jZUNvbnN0cnVjdG9yOiByZW1vdmluZyB4c2w6dGV4dCBlbGVtZW50XG4iKTsKKyNlbmRpZgorCXhtbFVubGlua05vZGUoZGVsZXRlTm9kZSk7CisJeG1sRnJlZU5vZGUoZGVsZXRlTm9kZSk7CisJZGVsZXRlTm9kZSA9IE5VTEw7CisgICAgfQorfQorCisvKioKKyAqIHhzbHRQYXJzZVRlbXBsYXRlQ29udGVudDoKKyAqIEBzdHlsZTogIHRoZSBYU0xUIHN0eWxlc2hlZXQKKyAqIEB0ZW1wbDogIHRoZSBub2RlIGNvbnRhaW5pbmcgdGhlIGNvbnRlbnQgdG8gYmUgcGFyc2VkCisgKgorICogUGFyc2VzIGFuZCBjb21waWxlcyB0aGUgY29udGVudC1tb2RlbCBvZiBhbiB4c2w6dGVtcGxhdGUgZWxlbWVudC4KKyAqIE5vdGUgdGhhdCB0aGlzIGlzICpub3QqIHRoZSAidGVtcGxhdGUiIGNvbnRlbnQgbW9kZWwgKG9yICJzZXF1ZW5jZQorICogIGNvbnN0cnVjdG9yIiBpbiBYU0xUIDIuMCk7IGl0IGl0IGFsbG93cyBhZGRpb25hbCB4c2w6cGFyYW0KKyAqICBlbGVtZW50cyBhcyBpbW1lZGlhdGUgY2hpbGRyZW4gb2YgQHRlbXBsLgorICoKKyAqIENhbGxlZCBieTogCisgKiAgIGV4c2x0RnVuY0Z1bmN0aW9uQ29tcCgpIChFWFNMVCwgZnVuY3Rpb25zLmMpCisgKiAgIFNvIHRoaXMgaXMgaW50ZW5kZWQgdG8gYmUgY2FsbGVkIGZyb20gZXh0ZW5zaW9uIGZ1bmN0aW9ucy4KKyAqLwordm9pZAoreHNsdFBhcnNlVGVtcGxhdGVDb250ZW50KHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIHRlbXBsKSB7CisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAodGVtcGwgPT0gTlVMTCkpCisJcmV0dXJuOworCisgICAgLyoKKyAgICAqIERldGVjdGlvbiBvZiBoYW5kbGVkIGNvbnRlbnQgb2YgZXh0ZW5zaW9uIGluc3RydWN0aW9ucy4KKyAgICAqLworICAgIGlmIChYU0xUX0NDVFhUKHN0eWxlKS0+aW5vZGUtPmNhdGVnb3J5ID09IFhTTFRfRUxFTUVOVF9DQVRFR09SWV9FWFRFTlNJT04pIHsKKwlYU0xUX0NDVFhUKHN0eWxlKS0+aW5vZGUtPmV4dENvbnRlbnRIYW5kbGVkID0gMTsKKyAgICB9CisKKyAgICBpZiAodGVtcGwtPmNoaWxkcmVuICE9IE5VTEwpIHsJCisJeG1sTm9kZVB0ciBjaGlsZCA9IHRlbXBsLT5jaGlsZHJlbjsKKwkvKgorCSogUHJvY2VzcyB4c2w6cGFyYW0gZWxlbWVudHMsIHdoaWNoIGNhbiBvbmx5IG9jY3VyIGFzIHRoZQorCSogaW1tZWRpYXRlIGNoaWxkcmVuIG9mIHhzbDp0ZW1wbGF0ZSAod2VsbCwgYW5kIG9mIGFueQorCSogdXNlci1kZWZpbmVkIGV4dGVuc2lvbiBpbnN0cnVjdGlvbiBpZiBuZWVkZWQpLgorCSovCQorCWRvIHsKKwkgICAgaWYgKChjaGlsZC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSAmJgorCQlJU19YU0xUX0VMRU1fRkFTVChjaGlsZCkgJiYKKwkJSVNfWFNMVF9OQU1FKGNoaWxkLCAicGFyYW0iKSkKKwkgICAgeworCQlYU0xUX0NDVFhUKHN0eWxlKS0+aW5vZGUtPmN1ckNoaWxkVHlwZSA9IFhTTFRfRlVOQ19QQVJBTTsKKwkJeHNsdFBhcnNlQW55WFNMVEVsZW0oWFNMVF9DQ1RYVChzdHlsZSksIGNoaWxkKTsKKwkgICAgfSBlbHNlCisJCWJyZWFrOworCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OworCX0gd2hpbGUgKGNoaWxkICE9IE5VTEwpOworCS8qCisJKiBQYXJzZSB0aGUgY29udGVudCBhbmQgcmVnaXN0ZXIgdGhlIHBhdHRlcm4uCisJKi8KKwl4c2x0UGFyc2VTZXF1ZW5jZUNvbnN0cnVjdG9yKFhTTFRfQ0NUWFQoc3R5bGUpLCBjaGlsZCk7CisgICAgfQorfQorCisjZWxzZSAvKiBYU0xUX1JFRkFDVE9SRUQgKi8KKworLyoqCisgKiB4c2x0UGFyc2VUZW1wbGF0ZUNvbnRlbnQ6CisgKiBAc3R5bGU6ICB0aGUgWFNMVCBzdHlsZXNoZWV0CisgKiBAdGVtcGw6ICB0aGUgY29udGFpbmVyIG5vZGUgKGNhbiBiZSBhIGRvY3VtZW50IGZvciBsaXRlcmFsIHJlc3VsdHMpCisgKgorICogcGFyc2UgYSB0ZW1wbGF0ZSBjb250ZW50LW1vZGVsCisgKiBDbGVhbi11cCB0aGUgdGVtcGxhdGUgY29udGVudCBmcm9tIHVud2FudGVkIGlnbm9yYWJsZSBibGFuayBub2RlcworICogYW5kIHByb2Nlc3MgeHNsdDp0ZXh0CisgKi8KK3ZvaWQKK3hzbHRQYXJzZVRlbXBsYXRlQ29udGVudCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciB0ZW1wbCkgeworICAgIHhtbE5vZGVQdHIgY3VyLCBkZWxldGU7CisgICAgLyoKKyAgICAgKiBUaGlzIGNvbnRlbnQgY29tZXMgZnJvbSB0aGUgc3R5bGVzaGVldAorICAgICAqIEZvciBzdHlsZXNoZWV0cywgdGhlIHNldCBvZiB3aGl0ZXNwYWNlLXByZXNlcnZpbmcKKyAgICAgKiBlbGVtZW50IG5hbWVzIGNvbnNpc3RzIG9mIGp1c3QgeHNsOnRleHQuCisgICAgICovCisgICAgY3VyID0gdGVtcGwtPmNoaWxkcmVuOworICAgIGRlbGV0ZSA9IE5VTEw7CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX0JMQU5LUworCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAgICAgInhzbHRQYXJzZVRlbXBsYXRlQ29udGVudDogcmVtb3ZpbmcgdGV4dFxuIik7CisjZW5kaWYKKwkgICAgeG1sVW5saW5rTm9kZShkZWxldGUpOworCSAgICB4bWxGcmVlTm9kZShkZWxldGUpOworCSAgICBkZWxldGUgPSBOVUxMOworCX0KKwlpZiAoSVNfWFNMVF9FTEVNKGN1cikpIHsKKwkgICAgaWYgKElTX1hTTFRfTkFNRShjdXIsICJ0ZXh0IikpIHsKKwkJLyoKKwkJKiBUT0RPOiBQcm9jZXNzaW5nIG9mIHhzbDp0ZXh0IHNob3VsZCBiZSBtb3ZlZCB0bworCQkqICAgeHNsdFByZWNvbXB1dGVTdHlsZXNoZWV0KCksIHNpbmNlIG90aGVyd2lzZSB0aGlzCisJCSogICB3aWxsIGJlIHBlcmZvcm1lZCBmb3IgZXZlcnkgbXVsdGlwbHkgaW5jbHVkZWQKKwkJKiAgIHN0eWxlc2hlZXQ7IGkuZS4gdGhpcyBoZXJlIGlzIG5vdCBza2lwcGVkIHdpdGgKKwkJKiAgIHRoZSB1c2Ugb2YgdGhlIHN0eWxlLT5ub3ByZXByb2MgZmxhZy4KKwkJKi8KKwkJaWYgKGN1ci0+Y2hpbGRyZW4gIT0gTlVMTCkgeworCQkgICAgeG1sQ2hhciAqcHJvcDsKKwkJICAgIHhtbE5vZGVQdHIgdGV4dCA9IGN1ci0+Y2hpbGRyZW4sIG5leHQ7CisJCSAgICBpbnQgbm9lc2MgPSAwOworCQkJCisJCSAgICBwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwKKwkJCShjb25zdCB4bWxDaGFyICopImRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIiwKKwkJCU5VTEwpOworCQkgICAgaWYgKHByb3AgIT0gTlVMTCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJCQl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJICAgICAiRGlzYWJsZSBlc2NhcGluZzogJXNcbiIsIHRleHQtPmNvbnRlbnQpOworI2VuZGlmCisJCQlpZiAoeG1sU3RyRXF1YWwocHJvcCwgKGNvbnN0IHhtbENoYXIgKikieWVzIikpIHsKKwkJCSAgICBub2VzYyA9IDE7CisJCQl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbChwcm9wLAorCQkJCQkJKGNvbnN0IHhtbENoYXIgKikibm8iKSl7CisJCQkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJICAgICAieHNsOnRleHQ6IGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nIGFsbG93cyBvbmx5IHllcyBvciBub1xuIik7CisJCQkgICAgc3R5bGUtPndhcm5pbmdzKys7CisKKwkJCX0KKwkJCXhtbEZyZWUocHJvcCk7CisJCSAgICB9CisKKwkJICAgIHdoaWxlICh0ZXh0ICE9IE5VTEwpIHsKKwkJCWlmICh0ZXh0LT50eXBlID09IFhNTF9DT01NRU5UX05PREUpIHsKKwkJCSAgICB0ZXh0ID0gdGV4dC0+bmV4dDsKKwkJCSAgICBjb250aW51ZTsKKwkJCX0KKwkJCWlmICgodGV4dC0+dHlwZSAhPSBYTUxfVEVYVF9OT0RFKSAmJgorCQkJICAgICAodGV4dC0+dHlwZSAhPSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkgeworCQkJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCQkgInhzbHRQYXJzZVRlbXBsYXRlQ29udGVudDogeHNsdDp0ZXh0IGNvbnRlbnQgcHJvYmxlbVxuIik7CisJCQkgICAgc3R5bGUtPmVycm9ycysrOworCQkJICAgIGJyZWFrOworCQkJfQorCQkJaWYgKChub2VzYykgJiYgKHRleHQtPnR5cGUgIT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpCisJCQkgICAgdGV4dC0+bmFtZSA9IHhtbFN0cmluZ1RleHROb2VuYzsKKwkJCXRleHQgPSB0ZXh0LT5uZXh0OworCQkgICAgfQorCisJCSAgICAvKgorCQkgICAgICogcmVwbGFjZSB4c2w6dGV4dCBieSB0aGUgbGlzdCBvZiBjaGlsZHMKKwkJICAgICAqLworCQkgICAgaWYgKHRleHQgPT0gTlVMTCkgeworCQkJdGV4dCA9IGN1ci0+Y2hpbGRyZW47CisJCQl3aGlsZSAodGV4dCAhPSBOVUxMKSB7CisJCQkgICAgaWYgKChzdHlsZS0+aW50ZXJuYWxpemVkKSAmJgorCQkJICAgICAgICAodGV4dC0+Y29udGVudCAhPSBOVUxMKSAmJgorCQkJICAgICAgICAoIXhtbERpY3RPd25zKHN0eWxlLT5kaWN0LCB0ZXh0LT5jb250ZW50KSkpIHsKKworCQkJCS8qCisJCQkJICogaW50ZXJuYWxpemUgdGhlIHRleHQgc3RyaW5nCisJCQkJICovCisJCQkJaWYgKHRleHQtPmRvYy0+ZGljdCAhPSBOVUxMKSB7CisJCQkJICAgIGNvbnN0IHhtbENoYXIgKnRtcDsKKwkJCQkgICAgCisJCQkJICAgIHRtcCA9IHhtbERpY3RMb29rdXAodGV4dC0+ZG9jLT5kaWN0LAorCQkJCSAgICAgICAgICAgICAgICAgICAgICAgIHRleHQtPmNvbnRlbnQsIC0xKTsKKwkJCQkgICAgaWYgKHRtcCAhPSB0ZXh0LT5jb250ZW50KSB7CisJCQkJICAgICAgICB4bWxOb2RlU2V0Q29udGVudCh0ZXh0LCBOVUxMKTsKKwkJCQkJdGV4dC0+Y29udGVudCA9ICh4bWxDaGFyICopIHRtcDsKKwkJCQkgICAgfQorCQkJCX0KKwkJCSAgICB9CisKKwkJCSAgICBuZXh0ID0gdGV4dC0+bmV4dDsKKwkJCSAgICB4bWxVbmxpbmtOb2RlKHRleHQpOworCQkJICAgIHhtbEFkZFByZXZTaWJsaW5nKGN1ciwgdGV4dCk7CisJCQkgICAgdGV4dCA9IG5leHQ7CisJCQl9CisJCSAgICB9CisJCX0KKwkJZGVsZXRlID0gY3VyOworCQlnb3RvIHNraXBfY2hpbGRyZW47CisJICAgIH0KKwl9CisJZWxzZSBpZiAoKGN1ci0+bnMgIT0gTlVMTCkgJiYgKHN0eWxlLT5uc0RlZnMgIT0gTlVMTCkgJiYKKwkgICAgKHhzbHRDaGVja0V4dFByZWZpeChzdHlsZSwgY3VyLT5ucy0+cHJlZml4KSkpCisJeworCSAgICAvKgorCSAgICAgKiBva2F5IHRoaXMgaXMgYW4gZXh0ZW5zaW9uIGVsZW1lbnQgY29tcGlsZSBpdCB0b28KKwkgICAgICovCisJICAgIHhzbHRTdHlsZVByZUNvbXB1dGUoc3R5bGUsIGN1cik7CisJfQorCWVsc2UgaWYgKGN1ci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKQorCXsKKwkgICAgLyoKKwkgICAgICogVGhpcyBpcyBhbiBlbGVtZW50IHdoaWNoIHdpbGwgYmUgb3V0cHV0IGFzIHBhcnQgb2YgdGhlCisJICAgICAqIHRlbXBsYXRlIGV4ZWN0dXRpb24sIHByZWNvbXBpbGUgQVZUIGlmIGZvdW5kLgorCSAgICAgKi8KKwkgICAgaWYgKChjdXItPm5zID09IE5VTEwpICYmIChzdHlsZS0+ZGVmYXVsdEFsaWFzICE9IE5VTEwpKSB7CisJCWN1ci0+bnMgPSB4bWxTZWFyY2hOc0J5SHJlZihjdXItPmRvYywgY3VyLAorCQkJc3R5bGUtPmRlZmF1bHRBbGlhcyk7CisJICAgIH0KKwkgICAgaWYgKGN1ci0+cHJvcGVydGllcyAhPSBOVUxMKSB7CisJICAgICAgICB4bWxBdHRyUHRyIGF0dHIgPSBjdXItPnByb3BlcnRpZXM7CisKKwkJd2hpbGUgKGF0dHIgIT0gTlVMTCkgeworCQkgICAgeHNsdENvbXBpbGVBdHRyKHN0eWxlLCBhdHRyKTsKKwkJICAgIGF0dHIgPSBhdHRyLT5uZXh0OworCQl9CisJICAgIH0KKwl9CisJLyoKKwkgKiBTa2lwIHRvIG5leHQgbm9kZQorCSAqLworCWlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKKwkgICAgaWYgKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9ERUNMKSB7CisJCWN1ciA9IGN1ci0+Y2hpbGRyZW47CisJCWNvbnRpbnVlOworCSAgICB9CisJfQorc2tpcF9jaGlsZHJlbjoKKwlpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKKwkgICAgY3VyID0gY3VyLT5uZXh0OworCSAgICBjb250aW51ZTsKKwl9CisJCisJZG8geworCSAgICBjdXIgPSBjdXItPnBhcmVudDsKKwkgICAgaWYgKGN1ciA9PSBOVUxMKQorCQlicmVhazsKKwkgICAgaWYgKGN1ciA9PSB0ZW1wbCkgeworCQljdXIgPSBOVUxMOworCQlicmVhazsKKwkgICAgfQorCSAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKKwkJY3VyID0gY3VyLT5uZXh0OworCQlicmVhazsKKwkgICAgfQorCX0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKKyAgICB9CisgICAgaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSAieHNsdFBhcnNlVGVtcGxhdGVDb250ZW50OiByZW1vdmluZyB0ZXh0XG4iKTsKKyNlbmRpZgorCXhtbFVubGlua05vZGUoZGVsZXRlKTsKKwl4bWxGcmVlTm9kZShkZWxldGUpOworCWRlbGV0ZSA9IE5VTEw7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBTa2lwIHRoZSBmaXJzdCBwYXJhbXMKKyAgICAgKi8KKyAgICBjdXIgPSB0ZW1wbC0+Y2hpbGRyZW47CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJaWYgKChJU19YU0xUX0VMRU0oY3VyKSkgJiYgKCEoSVNfWFNMVF9OQU1FKGN1ciwgInBhcmFtIikpKSkKKwkgICAgYnJlYWs7CisJY3VyID0gY3VyLT5uZXh0OworICAgIH0KKworICAgIC8qCisgICAgICogQnJvd3NlIHRoZSByZW1haW5kZXIgb2YgdGhlIHRlbXBsYXRlCisgICAgICovCisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJaWYgKChJU19YU0xUX0VMRU0oY3VyKSkgJiYgKElTX1hTTFRfTkFNRShjdXIsICJwYXJhbSIpKSkgeworCSAgICB4bWxOb2RlUHRyIHBhcmFtID0gY3VyOworCisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCQkieHNsdFBhcnNlVGVtcGxhdGVDb250ZW50OiBpZ25vcmluZyBtaXNwbGFjZWQgcGFyYW0gZWxlbWVudFxuIik7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+d2FybmluZ3MrKzsKKyAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKKwkgICAgeG1sVW5saW5rTm9kZShwYXJhbSk7CisJICAgIHhtbEZyZWVOb2RlKHBhcmFtKTsKKwl9IGVsc2UKKwkgICAgYnJlYWs7CisgICAgfQorfQorCisjZW5kaWYgLyogZWxzZSBYU0xUX1JFRkFDVE9SRUQgKi8KKworLyoqCisgKiB4c2x0UGFyc2VTdHlsZXNoZWV0S2V5OgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICogQGtleTogIHRoZSAia2V5IiBlbGVtZW50CisgKgorICogPCEtLSBDYXRlZ29yeTogdG9wLWxldmVsLWVsZW1lbnQgLS0+CisgKiA8eHNsOmtleSBuYW1lID0gcW5hbWUsIG1hdGNoID0gcGF0dGVybiwgdXNlID0gZXhwcmVzc2lvbiAvPgorICoKKyAqIHBhcnNlIGFuIFhTTFQgc3R5bGVzaGVldCBrZXkgZGVmaW5pdGlvbiBhbmQgcmVnaXN0ZXIgaXQKKyAqLworCitzdGF0aWMgdm9pZAoreHNsdFBhcnNlU3R5bGVzaGVldEtleSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBrZXkpIHsKKyAgICB4bWxDaGFyICpwcm9wID0gTlVMTDsKKyAgICB4bWxDaGFyICp1c2UgPSBOVUxMOworICAgIHhtbENoYXIgKm1hdGNoID0gTlVMTDsKKyAgICB4bWxDaGFyICpuYW1lID0gTlVMTDsKKyAgICB4bWxDaGFyICpuYW1lVVJJID0gTlVMTDsKKworICAgIGlmICgoc3R5bGUgPT0gTlVMTCkgfHwgKGtleSA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICAvKgorICAgICAqIEdldCBhcmd1bWVudHMKKyAgICAgKi8KKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGtleSwgKGNvbnN0IHhtbENoYXIgKikibmFtZSIsIE5VTEwpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKyAgICAgICAgY29uc3QgeG1sQ2hhciAqVVJJOworCisJLyoKKwkqIFRPRE86IERvbid0IHVzZSB4c2x0R2V0UU5hbWVVUkkoKS4KKwkqLworCVVSSSA9IHhzbHRHZXRRTmFtZVVSSShrZXksICZwcm9wKTsKKwlpZiAocHJvcCA9PSBOVUxMKSB7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJICAgIGdvdG8gZXJyb3I7CisJfSBlbHNlIHsKKwkgICAgbmFtZSA9IHByb3A7CisJICAgIGlmIChVUkkgIT0gTlVMTCkKKwkJbmFtZVVSSSA9IHhtbFN0cmR1cChVUkkpOworCX0KKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdFBhcnNlU3R5bGVzaGVldEtleTogbmFtZSAlc1xuIiwgbmFtZSk7CisjZW5kaWYKKyAgICB9IGVsc2UgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwga2V5LAorCSAgICAieHNsOmtleSA6IGVycm9yIG1pc3NpbmcgbmFtZVxuIik7CisJaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKwlnb3RvIGVycm9yOworICAgIH0KKworICAgIG1hdGNoID0geG1sR2V0TnNQcm9wKGtleSwgKGNvbnN0IHhtbENoYXIgKikibWF0Y2giLCBOVUxMKTsKKyAgICBpZiAobWF0Y2ggPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwga2V5LAorCSAgICAieHNsOmtleSA6IGVycm9yIG1pc3NpbmcgbWF0Y2hcbiIpOworCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJZ290byBlcnJvcjsKKyAgICB9CisKKyAgICB1c2UgPSB4bWxHZXROc1Byb3Aoa2V5LCAoY29uc3QgeG1sQ2hhciAqKSJ1c2UiLCBOVUxMKTsKKyAgICBpZiAodXNlID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGtleSwKKwkgICAgInhzbDprZXkgOiBlcnJvciBtaXNzaW5nIHVzZVxuIik7CisJaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKwlnb3RvIGVycm9yOworICAgIH0KKworICAgIC8qCisgICAgICogcmVnaXN0ZXIgdGhlIGtleXMKKyAgICAgKi8KKyAgICB4c2x0QWRkS2V5KHN0eWxlLCBuYW1lLCBuYW1lVVJJLCBtYXRjaCwgdXNlLCBrZXkpOworCisKK2Vycm9yOgorICAgIGlmICh1c2UgIT0gTlVMTCkKKwl4bWxGcmVlKHVzZSk7CisgICAgaWYgKG1hdGNoICE9IE5VTEwpCisJeG1sRnJlZShtYXRjaCk7CisgICAgaWYgKG5hbWUgIT0gTlVMTCkKKwl4bWxGcmVlKG5hbWUpOworICAgIGlmIChuYW1lVVJJICE9IE5VTEwpCisJeG1sRnJlZShuYW1lVVJJKTsKKworICAgIGlmIChrZXktPmNoaWxkcmVuICE9IE5VTEwpIHsKKwl4c2x0UGFyc2VDb250ZW50RXJyb3Ioc3R5bGUsIGtleS0+Y2hpbGRyZW4pOworICAgIH0KK30KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorLyoqCisgKiB4c2x0UGFyc2VYU0xUVGVtcGxhdGU6CisgKiBAc3R5bGU6ICB0aGUgWFNMVCBzdHlsZXNoZWV0CisgKiBAdGVtcGxhdGU6ICB0aGUgInRlbXBsYXRlIiBlbGVtZW50CisgKgorICogcGFyc2UgYW4gWFNMVCBzdHlsZXNoZWV0IHRlbXBsYXRlIGJ1aWxkaW5nIHRoZSBhc3NvY2lhdGVkIHN0cnVjdHVyZXMKKyAqIFRPRE86IElzIEBzdHlsZSBldmVyIGV4cGVjdGVkIHRvIGJlIE5VTEw/CisgKgorICogQ2FsbGVkIGZyb206CisgKiAgIHhzbHRQYXJzZVhTTFRTdHlsZXNoZWV0KCkKKyAqICAgeHNsdFBhcnNlU3R5bGVzaGVldFRvcCgpCisgKi8KKworc3RhdGljIHZvaWQKK3hzbHRQYXJzZVhTTFRUZW1wbGF0ZSh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0LCB4bWxOb2RlUHRyIHRlbXBsTm9kZSkgeworICAgIHhzbHRUZW1wbGF0ZVB0ciB0ZW1wbDsKKyAgICB4bWxDaGFyICpwcm9wOyAgICAKKyAgICBkb3VibGUgIHByaW9yaXR5OyAgICAKKworICAgIGlmICgoY2N0eHQgPT0gTlVMTCkgfHwgKHRlbXBsTm9kZSA9PSBOVUxMKSkKKwlyZXR1cm47CisKKyAgICAvKgorICAgICAqIENyZWF0ZSBhbmQgbGluayB0aGUgc3RydWN0dXJlCisgICAgICovCisgICAgdGVtcGwgPSB4c2x0TmV3VGVtcGxhdGUoKTsKKyAgICBpZiAodGVtcGwgPT0gTlVMTCkKKwlyZXR1cm47CisKKyAgICB4c2x0Q29tcGlsZXJOb2RlUHVzaChjY3R4dCwgdGVtcGxOb2RlKTsKKyAgICBpZiAodGVtcGxOb2RlLT5uc0RlZiAhPSBOVUxMKQorCWNjdHh0LT5pbm9kZS0+aW5TY29wZU5zID0KKwkgICAgeHNsdENvbXBpbGVyQnVpbGRJblNjb3BlTnNMaXN0KGNjdHh0LCB0ZW1wbE5vZGUpOworCisgICAgdGVtcGwtPm5leHQgPSBjY3R4dC0+c3R5bGUtPnRlbXBsYXRlczsKKyAgICBjY3R4dC0+c3R5bGUtPnRlbXBsYXRlcyA9IHRlbXBsOworICAgIHRlbXBsLT5zdHlsZSA9IGNjdHh0LT5zdHlsZTsgIAorCisgICAgLyoKKyAgICAqIEF0dHJpYnV0ZSAibW9kZSIuCisgICAgKi8KKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKHRlbXBsTm9kZSwgKGNvbnN0IHhtbENoYXIgKikibW9kZSIsIE5VTEwpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsJCisgICAgICAgIGNvbnN0IHhtbENoYXIgKm1vZGVVUkk7CisKKwkvKgorCSogVE9ETzogV2UgbmVlZCBhIHN0YW5kYXJkaXplZCBmdW5jdGlvbiBmb3IgZXh0cmFjdGlvbgorCSogIG9mIG5hbWVzcGFjZSBuYW1lcyBhbmQgbG9jYWwgbmFtZXMgZnJvbSBRTmFtZXMuCisJKiAgRG9uJ3QgdXNlIHhzbHRHZXRRTmFtZVVSSSgpIGFzIGl0IGNhbm5vdCBjaGFubmX2CisJKiAgcmVwb3J0cyB0aHJvdWdoIHRoZSBjb250ZXh0LgorCSovCisJbW9kZVVSSSA9IHhzbHRHZXRRTmFtZVVSSSh0ZW1wbE5vZGUsICZwcm9wKTsKKwlpZiAocHJvcCA9PSBOVUxMKSB7CisJICAgIGNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJICAgIGdvdG8gZXJyb3I7CisJfQorCXRlbXBsLT5tb2RlID0geG1sRGljdExvb2t1cChjY3R4dC0+c3R5bGUtPmRpY3QsIHByb3AsIC0xKTsKKwl4bWxGcmVlKHByb3ApOworCXByb3AgPSBOVUxMOworCWlmICh4bWxWYWxpZGF0ZU5DTmFtZSh0ZW1wbC0+bW9kZSwgMCkpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgdGVtcGxOb2RlLAorCQkieHNsOnRlbXBsYXRlOiBBdHRyaWJ1dGUgJ21vZGUnOiBUaGUgbG9jYWwgcGFydCAnJXMnICIKKwkJIm9mIHRoZSB2YWx1ZSBpcyBub3QgYSB2YWxpZCBOQ05hbWUuXG4iLCB0ZW1wbC0+bmFtZSk7CisJICAgIGNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJICAgIGdvdG8gZXJyb3I7CisJfQorCWlmIChtb2RlVVJJICE9IE5VTEwpCisJICAgIHRlbXBsLT5tb2RlVVJJID0geG1sRGljdExvb2t1cChjY3R4dC0+c3R5bGUtPmRpY3QsIG1vZGVVUkksIC0xKTsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICAieHNsdFBhcnNlWFNMVFRlbXBsYXRlOiBtb2RlICVzXG4iLCB0ZW1wbC0+bW9kZSk7CisjZW5kaWYKKyAgICB9CisgICAgLyoKKyAgICAqIEF0dHJpYnV0ZSAibWF0Y2giLgorICAgICovCisgICAgcHJvcCA9IHhtbEdldE5zUHJvcCh0ZW1wbE5vZGUsIChjb25zdCB4bWxDaGFyICopIm1hdGNoIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworCXRlbXBsLT5tYXRjaCAgPSBwcm9wOworCXByb3AgPSBOVUxMOworICAgIH0KKyAgICAvKgorICAgICogQXR0cmlidXRlICJwcmlvcml0eSIuCisgICAgKi8KKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKHRlbXBsTm9kZSwgKGNvbnN0IHhtbENoYXIgKikicHJpb3JpdHkiLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJcHJpb3JpdHkgPSB4bWxYUGF0aFN0cmluZ0V2YWxOdW1iZXIocHJvcCk7CisJdGVtcGwtPnByaW9yaXR5ID0gKGZsb2F0KSBwcmlvcml0eTsKKwl4bWxGcmVlKHByb3ApOworCXByb3AgPSBOVUxMOworICAgIH0KKyAgICAvKgorICAgICogQXR0cmlidXRlICJuYW1lIi4KKyAgICAqLworICAgIHByb3AgPSB4bWxHZXROc1Byb3AodGVtcGxOb2RlLCAoY29uc3QgeG1sQ2hhciAqKSJuYW1lIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lVVJJOworCXhzbHRUZW1wbGF0ZVB0ciBjdXJUZW1wbDsKKwkKKwkvKgorCSogVE9ETzogRG9uJ3QgdXNlIHhzbHRHZXRRTmFtZVVSSSgpLgorCSovCisJbmFtZVVSSSA9IHhzbHRHZXRRTmFtZVVSSSh0ZW1wbE5vZGUsICZwcm9wKTsKKwlpZiAocHJvcCA9PSBOVUxMKSB7CisJICAgIGNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJICAgIGdvdG8gZXJyb3I7CisJfQorCXRlbXBsLT5uYW1lID0geG1sRGljdExvb2t1cChjY3R4dC0+c3R5bGUtPmRpY3QsIHByb3AsIC0xKTsKKwl4bWxGcmVlKHByb3ApOworCXByb3AgPSBOVUxMOworCWlmICh4bWxWYWxpZGF0ZU5DTmFtZSh0ZW1wbC0+bmFtZSwgMCkpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgdGVtcGxOb2RlLAorCQkieHNsOnRlbXBsYXRlOiBBdHRyaWJ1dGUgJ25hbWUnOiBUaGUgbG9jYWwgcGFydCAnJXMnIG9mICIKKwkJInRoZSB2YWx1ZSBpcyBub3QgYSB2YWxpZCBOQ05hbWUuXG4iLCB0ZW1wbC0+bmFtZSk7CisJICAgIGNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJICAgIGdvdG8gZXJyb3I7CisJfSAJCisJaWYgKG5hbWVVUkkgIT0gTlVMTCkKKwkgICAgdGVtcGwtPm5hbWVVUkkgPSB4bWxEaWN0TG9va3VwKGNjdHh0LT5zdHlsZS0+ZGljdCwgbmFtZVVSSSwgLTEpOworCWN1clRlbXBsID0gdGVtcGwtPm5leHQ7CisJd2hpbGUgKGN1clRlbXBsICE9IE5VTEwpIHsKKwkgICAgaWYgKChuYW1lVVJJICE9IE5VTEwgJiYgeG1sU3RyRXF1YWwoY3VyVGVtcGwtPm5hbWUsIHRlbXBsLT5uYW1lKSAmJgorCQl4bWxTdHJFcXVhbChjdXJUZW1wbC0+bmFtZVVSSSwgbmFtZVVSSSkgKSB8fAorCQkobmFtZVVSSSA9PSBOVUxMICYmIGN1clRlbXBsLT5uYW1lVVJJID09IE5VTEwgJiYKKwkJeG1sU3RyRXF1YWwoY3VyVGVtcGwtPm5hbWUsIHRlbXBsLT5uYW1lKSkpCisJICAgIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgdGVtcGxOb2RlLAorCQkgICAgInhzbDp0ZW1wbGF0ZTogZXJyb3IgZHVwbGljYXRlIG5hbWUgJyVzJ1xuIiwgdGVtcGwtPm5hbWUpOworCQljY3R4dC0+c3R5bGUtPmVycm9ycysrOworCQlnb3RvIGVycm9yOworCSAgICB9CisJICAgIGN1clRlbXBsID0gY3VyVGVtcGwtPm5leHQ7CisJfQorICAgIH0KKyAgICBpZiAodGVtcGxOb2RlLT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJeHNsdFBhcnNlVGVtcGxhdGVDb250ZW50KGNjdHh0LT5zdHlsZSwgdGVtcGxOb2RlKTsJCisJLyoKKwkqIE1BWUJFIFRPRE86IEN1c3RvbSBiZWhhdmlvdXI6IEluIG9yZGVyIHRvIHN0YXkgY29tcGF0aWJsZSB3aXRoCisJKiBYYWxhbiBhbmQgTVNYTUwoLk5FVCksIHdlIGNvdWxkIGFsbG93IHdoaXRlc3BhY2UKKwkqIHRvIGFwcGVhciBiZWZvcmUgYW4geG1sOnBhcmFtIGVsZW1lbnQ7IHRoaXMgd2hpdGVzcGFjZQorCSogd2lsbCBhZGRpdGlvbmFsbHkgYmVjb21lIHBhcnQgb2YgdGhlICJ0ZW1wbGF0ZSIuCisJKiBOT1RFIHRoYXQgdGhpcyBpcyB0b3RhbGx5IGRldmlhdGVzIGZyb20gdGhlIHNwZWMsIGJ1dAorCSogaXMgdGhlIGRlIGZhY3RvIGJlaGF2aW91ciBvZiBYYWxhbiBhbmQgTVNYTUwoLk5FVCkuCisJKiBQZXJzb25hbGx5IEkgd291bGRuJ3QgYWxsb3cgdGhpcywgc2luY2UgaWYgd2UgaGF2ZToKKwkqIDx4c2w6dGVtcGxhdGUgLi4ueG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CisJKiAgIDx4c2w6cGFyYW0gbmFtZT0iZm9vIi8+CisJKiAgIDx4c2w6cGFyYW0gbmFtZT0iYmFyIi8+CisJKiAgIDx4c2w6cGFyYW0gbmFtZT0iem9vIi8+CisJKiAuLi4gdGhlIHdoaXRlc3BhY2UgYmV0d2VlbiBldmVyeSB4c2w6cGFyYW0gd291bGQgYmUKKwkqIGFkZGVkIHRvIHRoZSByZXN1bHQgdHJlZS4KKwkqLwkJCisgICAgfSAgICAKKyAgICAKKyAgICB0ZW1wbC0+ZWxlbSA9IHRlbXBsTm9kZTsKKyAgICB0ZW1wbC0+Y29udGVudCA9IHRlbXBsTm9kZS0+Y2hpbGRyZW47CisgICAgeHNsdEFkZFRlbXBsYXRlKGNjdHh0LT5zdHlsZSwgdGVtcGwsIHRlbXBsLT5tb2RlLCB0ZW1wbC0+bW9kZVVSSSk7CisKK2Vycm9yOgorICAgIHhzbHRDb21waWxlck5vZGVQb3AoY2N0eHQsIHRlbXBsTm9kZSk7CisgICAgcmV0dXJuOworfQorCisjZWxzZSAvKiBYU0xUX1JFRkFDVE9SRUQgKi8KKworLyoqCisgKiB4c2x0UGFyc2VTdHlsZXNoZWV0VGVtcGxhdGU6CisgKiBAc3R5bGU6ICB0aGUgWFNMVCBzdHlsZXNoZWV0CisgKiBAdGVtcGxhdGU6ICB0aGUgInRlbXBsYXRlIiBlbGVtZW50CisgKgorICogcGFyc2UgYW4gWFNMVCBzdHlsZXNoZWV0IHRlbXBsYXRlIGJ1aWxkaW5nIHRoZSBhc3NvY2lhdGVkIHN0cnVjdHVyZXMKKyAqLworCitzdGF0aWMgdm9pZAoreHNsdFBhcnNlU3R5bGVzaGVldFRlbXBsYXRlKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIHRlbXBsYXRlKSB7CisgICAgeHNsdFRlbXBsYXRlUHRyIHJldDsKKyAgICB4bWxDaGFyICpwcm9wOworICAgIHhtbENoYXIgKm1vZGUgPSBOVUxMOworICAgIHhtbENoYXIgKm1vZGVVUkkgPSBOVUxMOworICAgIGRvdWJsZSAgcHJpb3JpdHk7CisKKyAgICBpZiAodGVtcGxhdGUgPT0gTlVMTCkKKwlyZXR1cm47CisKKyAgICAvKgorICAgICAqIENyZWF0ZSBhbmQgbGluayB0aGUgc3RydWN0dXJlCisgICAgICovCisgICAgcmV0ID0geHNsdE5ld1RlbXBsYXRlKCk7CisgICAgaWYgKHJldCA9PSBOVUxMKQorCXJldHVybjsKKyAgICByZXQtPm5leHQgPSBzdHlsZS0+dGVtcGxhdGVzOworICAgIHN0eWxlLT50ZW1wbGF0ZXMgPSByZXQ7CisgICAgcmV0LT5zdHlsZSA9IHN0eWxlOworICAgCisgICAgLyoKKyAgICAgKiBHZXQgaW5oZXJpdGVkIG5hbWVzcGFjZXMKKyAgICAgKi8KKyAgICAvKgorICAgICogVE9ETzogQXBwbHkgdGhlIG9wdGltaXplZCBpbi1zY29wZS1uYW1lc3BhY2UgbWVjaGFuaXNtCisgICAgKiAgIGFzIGZvciB0aGUgb3RoZXIgWFNMVCBpbnN0cnVjdGlvbnMuCisgICAgKi8KKyAgICB4c2x0R2V0SW5oZXJpdGVkTnNMaXN0KHN0eWxlLCByZXQsIHRlbXBsYXRlKTsKKworICAgIC8qCisgICAgICogR2V0IGFyZ3VtZW50cworICAgICAqLworICAgIHByb3AgPSB4bWxHZXROc1Byb3AodGVtcGxhdGUsIChjb25zdCB4bWxDaGFyICopIm1vZGUiLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisgICAgICAgIGNvbnN0IHhtbENoYXIgKlVSSTsKKworCS8qCisJKiBUT0RPOiBEb24ndCB1c2UgeHNsdEdldFFOYW1lVVJJKCkuCisJKi8KKwlVUkkgPSB4c2x0R2V0UU5hbWVVUkkodGVtcGxhdGUsICZwcm9wKTsKKwlpZiAocHJvcCA9PSBOVUxMKSB7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJICAgIGdvdG8gZXJyb3I7CisJfSBlbHNlIHsKKwkgICAgbW9kZSA9IHByb3A7CisJICAgIGlmIChVUkkgIT0gTlVMTCkKKwkJbW9kZVVSSSA9IHhtbFN0cmR1cChVUkkpOworCX0KKwlyZXQtPm1vZGUgPSB4bWxEaWN0TG9va3VwKHN0eWxlLT5kaWN0LCBtb2RlLCAtMSk7CisJcmV0LT5tb2RlVVJJID0geG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgbW9kZVVSSSwgLTEpOworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkgICAgICJ4c2x0UGFyc2VTdHlsZXNoZWV0VGVtcGxhdGU6IG1vZGUgJXNcbiIsIG1vZGUpOworI2VuZGlmCisgICAgICAgIGlmIChtb2RlICE9IE5VTEwpIHhtbEZyZWUobW9kZSk7CisJaWYgKG1vZGVVUkkgIT0gTlVMTCkgeG1sRnJlZShtb2RlVVJJKTsKKyAgICB9CisgICAgcHJvcCA9IHhtbEdldE5zUHJvcCh0ZW1wbGF0ZSwgKGNvbnN0IHhtbENoYXIgKikibWF0Y2giLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJaWYgKHJldC0+bWF0Y2ggIT0gTlVMTCkgeG1sRnJlZShyZXQtPm1hdGNoKTsKKwlyZXQtPm1hdGNoICA9IHByb3A7CisgICAgfQorCisgICAgcHJvcCA9IHhtbEdldE5zUHJvcCh0ZW1wbGF0ZSwgKGNvbnN0IHhtbENoYXIgKikicHJpb3JpdHkiLCBOVUxMKTsKKyAgICBpZiAocHJvcCAhPSBOVUxMKSB7CisJcHJpb3JpdHkgPSB4bWxYUGF0aFN0cmluZ0V2YWxOdW1iZXIocHJvcCk7CisJcmV0LT5wcmlvcml0eSA9IChmbG9hdCkgcHJpb3JpdHk7CisJeG1sRnJlZShwcm9wKTsKKyAgICB9CisKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKHRlbXBsYXRlLCAoY29uc3QgeG1sQ2hhciAqKSJuYW1lIiwgTlVMTCk7CisgICAgaWYgKHByb3AgIT0gTlVMTCkgeworICAgICAgICBjb25zdCB4bWxDaGFyICpVUkk7CisJeHNsdFRlbXBsYXRlUHRyIGN1cjsKKwkKKwkvKgorCSogVE9ETzogRG9uJ3QgdXNlIHhzbHRHZXRRTmFtZVVSSSgpLgorCSovCisJVVJJID0geHNsdEdldFFOYW1lVVJJKHRlbXBsYXRlLCAmcHJvcCk7CisJaWYgKHByb3AgPT0gTlVMTCkgeworCSAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPmVycm9ycysrOworCSAgICBnb3RvIGVycm9yOworCX0gZWxzZSB7CisJICAgIGlmICh4bWxWYWxpZGF0ZU5DTmFtZShwcm9wLDApKSB7CisJICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIHRlbXBsYXRlLAorCSAgICAgICAgICAgICJ4c2w6dGVtcGxhdGUgOiBlcnJvciBpbnZhbGlkIG5hbWUgJyVzJ1xuIiwgcHJvcCk7CisJCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJCWdvdG8gZXJyb3I7CisJICAgIH0KKwkgICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwgQkFEX0NBU1QgcHJvcCwgLTEpOworCSAgICB4bWxGcmVlKHByb3ApOworCSAgICBwcm9wID0gTlVMTDsKKwkgICAgaWYgKFVSSSAhPSBOVUxMKQorCQlyZXQtPm5hbWVVUkkgPSB4bWxEaWN0TG9va3VwKHN0eWxlLT5kaWN0LCBCQURfQ0FTVCBVUkksIC0xKTsKKwkgICAgZWxzZQorCQlyZXQtPm5hbWVVUkkgPSBOVUxMOworCSAgICBjdXIgPSByZXQtPm5leHQ7CisJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCSAgICAgICAgaWYgKChVUkkgIT0gTlVMTCAmJiB4bWxTdHJFcXVhbChjdXItPm5hbWUsIHJldC0+bmFtZSkgJiYKKwkJCQl4bWxTdHJFcXVhbChjdXItPm5hbWVVUkksIFVSSSkgKSB8fAorCQkgICAgKFVSSSA9PSBOVUxMICYmIGN1ci0+bmFtZVVSSSA9PSBOVUxMICYmCisJCQkJeG1sU3RyRXF1YWwoY3VyLT5uYW1lLCByZXQtPm5hbWUpKSkgeworCQkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCB0ZW1wbGF0ZSwKKwkJICAgICAgICAieHNsOnRlbXBsYXRlOiBlcnJvciBkdXBsaWNhdGUgbmFtZSAnJXMnXG4iLCByZXQtPm5hbWUpOworCQkgICAgc3R5bGUtPmVycm9ycysrOworCQkgICAgZ290byBlcnJvcjsKKwkJfQorCQljdXIgPSBjdXItPm5leHQ7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgLyoKKyAgICAgKiBwYXJzZSB0aGUgY29udGVudCBhbmQgcmVnaXN0ZXIgdGhlIHBhdHRlcm4KKyAgICAgKi8KKyAgICB4c2x0UGFyc2VUZW1wbGF0ZUNvbnRlbnQoc3R5bGUsIHRlbXBsYXRlKTsKKyAgICByZXQtPmVsZW0gPSB0ZW1wbGF0ZTsKKyAgICByZXQtPmNvbnRlbnQgPSB0ZW1wbGF0ZS0+Y2hpbGRyZW47CisgICAgeHNsdEFkZFRlbXBsYXRlKHN0eWxlLCByZXQsIHJldC0+bW9kZSwgcmV0LT5tb2RlVVJJKTsKKworZXJyb3I6CisgICAgcmV0dXJuOworfQorCisjZW5kaWYgLyogZWxzZSBYU0xUX1JFRkFDVE9SRUQgKi8KKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCisvKioKKyAqIHhzbHRJbmNsdWRlQ29tcDoKKyAqIEBjY3R4dDogdGhlIGNvbXBpbGF0aW9uIGNvbnRlbnh0CisgKiBAbm9kZTogIHRoZSB4c2w6aW5jbHVkZSBub2RlCisgKgorICogUHJvY2VzcyB0aGUgeHNsdCBpbmNsdWRlIG5vZGUgb24gdGhlIHNvdXJjZSBub2RlCisgKi8KK3N0YXRpYyB4c2x0U3R5bGVJdGVtSW5jbHVkZVB0cgoreHNsdENvbXBpbGVYU0xUSW5jbHVkZUVsZW0oeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwgeG1sTm9kZVB0ciBub2RlKSB7CisgICAgeHNsdFN0eWxlSXRlbUluY2x1ZGVQdHIgaXRlbTsKKworICAgIGlmICgoY2N0eHQgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCisJcmV0dXJuKE5VTEwpOworCisgICAgbm9kZS0+cHN2aSA9IE5VTEw7CisgICAgaXRlbSA9ICh4c2x0U3R5bGVJdGVtSW5jbHVkZVB0cikgeG1sTWFsbG9jKHNpemVvZih4c2x0U3R5bGVJdGVtSW5jbHVkZSkpOworICAgIGlmIChpdGVtID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgY2N0eHQtPnN0eWxlLCBub2RlLAorCQkieHNsdEluY2x1ZGVDb21wIDogbWFsbG9jIGZhaWxlZFxuIik7CisJY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIG1lbXNldChpdGVtLCAwLCBzaXplb2YoeHNsdFN0eWxlSXRlbUluY2x1ZGUpKTsKKworICAgIG5vZGUtPnBzdmkgPSBpdGVtOworICAgIGl0ZW0tPmluc3QgPSBub2RlOworICAgIGl0ZW0tPnR5cGUgPSBYU0xUX0ZVTkNfSU5DTFVERTsKKworICAgIGl0ZW0tPm5leHQgPSBjY3R4dC0+c3R5bGUtPnByZUNvbXBzOworICAgIGNjdHh0LT5zdHlsZS0+cHJlQ29tcHMgPSAoeHNsdEVsZW1QcmVDb21wUHRyKSBpdGVtOworCisgICAgcmV0dXJuKGl0ZW0pOworfQorCisvKioKKyAqIHhzbHRQYXJzZUZpbmRUb3BMZXZlbEVsZW06CisgKi8KK3N0YXRpYyBpbnQKK3hzbHRQYXJzZUZpbmRUb3BMZXZlbEVsZW0oeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwKKwkJCSAgICAgIHhtbE5vZGVQdHIgY3VyLAorCQkJICAgICAgY29uc3QgeG1sQ2hhciAqbmFtZSwKKwkJCSAgICAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZVVSSSwKKwkJCSAgICAgIGludCBicmVha09uT3RoZXJFbGVtLAkJCSAgICAgIAorCQkJICAgICAgeG1sTm9kZVB0ciAqcmVzdWx0Tm9kZSkKK3sKKyAgICBpZiAobmFtZSA9PSBOVUxMKQorCXJldHVybigtMSk7CisKKyAgICAqcmVzdWx0Tm9kZSA9IE5VTEw7CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJaWYgKGN1ci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CisJICAgIGlmICgoY3VyLT5ucyAhPSBOVUxMKSAmJiAoY3VyLT5uYW1lICE9IE5VTEwpKSB7CisJCWlmICgoKihjdXItPm5hbWUpID09ICpuYW1lKSAmJgorCQkgICAgeG1sU3RyRXF1YWwoY3VyLT5uYW1lLCBuYW1lKSAmJgorCQkgICAgeG1sU3RyRXF1YWwoY3VyLT5ucy0+aHJlZiwgbmFtZXNwYWNlVVJJKSkJCSAgICAKKwkJeworCQkgICAgKnJlc3VsdE5vZGUgPSBjdXI7CisJCSAgICByZXR1cm4oMSk7CisJCX0KKwkgICAgfQorCSAgICBpZiAoYnJlYWtPbk90aGVyRWxlbSkKKwkJYnJlYWs7CisJfQorCWN1ciA9IGN1ci0+bmV4dDsKKyAgICB9CisgICAgKnJlc3VsdE5vZGUgPSBjdXI7CisgICAgcmV0dXJuKDApOworfQorCitzdGF0aWMgaW50Cit4c2x0UGFyc2VUb3BMZXZlbFhTTFRFbGVtKHhzbHRDb21waWxlckN0eHRQdHIgY2N0eHQsCisJCQkgIHhtbE5vZGVQdHIgbm9kZSwKKwkJCSAgeHNsdFN0eWxlVHlwZSB0eXBlKQoreworICAgIGludCByZXQgPSAwOworCisgICAgLyoKKyAgICAqIFRPRE86IFRoZSByZWFzb24gd2h5IHRoaXMgZnVuY3Rpb24gZXhpc3RzOgorICAgICogIGR1ZSB0byBoaXN0b3JpY2FsIHJlYXNvbnMgc29tZSBvZiB0aGUKKyAgICAqICB0b3AtbGV2ZWwgZGVjbGFyYXRpb25zIGFyZSBwcm9jZXNzZWQgYnkgZnVuY3Rpb25zCisgICAgKiAgaW4gb3RoZXIgZmlsZXMuIFNpbmNlIHdlIG5lZWQgc3RpbGwgdG8gc2V0CisgICAgKiAgdXAgdGhlIG5vZGUtaW5mbyBhbmQgZ2VuZXJhdGUgaW5mb3JtYXRpb24gbGlrZQorICAgICogIGluLXNjb3BlIG5hbWVzcGFjZXMsIHRoaXMgaXMgYSB3cmFwcGVyIGFyb3VuZAorICAgICogIHRob3NlIG9sZCBwYXJzaW5nIGZ1bmN0aW9ucy4KKyAgICAqLworICAgIHhzbHRDb21waWxlck5vZGVQdXNoKGNjdHh0LCBub2RlKTsKKyAgICBpZiAobm9kZS0+bnNEZWYgIT0gTlVMTCkKKwljY3R4dC0+aW5vZGUtPmluU2NvcGVOcyA9CisJICAgIHhzbHRDb21waWxlckJ1aWxkSW5TY29wZU5zTGlzdChjY3R4dCwgbm9kZSk7CisgICAgY2N0eHQtPmlub2RlLT50eXBlID0gdHlwZTsKKworICAgIHN3aXRjaCAodHlwZSkgeworCWNhc2UgWFNMVF9GVU5DX0lOQ0xVREU6CisJICAgIHsKKwkJaW50IG9sZElzSW5jbHVkZTsKKworCQlpZiAoeHNsdENvbXBpbGVYU0xUSW5jbHVkZUVsZW0oY2N0eHQsIG5vZGUpID09IE5VTEwpCisJCSAgICBnb3RvIGV4aXQ7CQkKKwkJLyoKKwkJKiBNYXJrIHRoaXMgc3R5bGVzaGVldCB0cmVlIGFzIGJlaW5nIGN1cnJlbnRseSBpbmNsdWRlZC4KKwkJKi8KKwkJb2xkSXNJbmNsdWRlID0gY2N0eHQtPmlzSW5jbHVkZTsKKwkJY2N0eHQtPmlzSW5jbHVkZSA9IDE7CisJCQkJCQkKKwkJaWYgKHhzbHRQYXJzZVN0eWxlc2hlZXRJbmNsdWRlKGNjdHh0LT5zdHlsZSwgbm9kZSkgIT0gMCkgeworCQkgICAgY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsKKwkJfQorCQljY3R4dC0+aXNJbmNsdWRlID0gb2xkSXNJbmNsdWRlOworCSAgICB9CisJICAgIGJyZWFrOworCWNhc2UgWFNMVF9GVU5DX1BBUkFNOgorCSAgICB4c2x0U3R5bGVQcmVDb21wdXRlKGNjdHh0LT5zdHlsZSwgbm9kZSk7CisJICAgIHhzbHRQYXJzZUdsb2JhbFBhcmFtKGNjdHh0LT5zdHlsZSwgbm9kZSk7CisJICAgIGJyZWFrOworCWNhc2UgWFNMVF9GVU5DX1ZBUklBQkxFOgorCSAgICB4c2x0U3R5bGVQcmVDb21wdXRlKGNjdHh0LT5zdHlsZSwgbm9kZSk7CisJICAgIHhzbHRQYXJzZUdsb2JhbFZhcmlhYmxlKGNjdHh0LT5zdHlsZSwgbm9kZSk7CisJICAgIGJyZWFrOworCWNhc2UgWFNMVF9GVU5DX0FUVFJTRVQ6CisJICAgIHhzbHRQYXJzZVN0eWxlc2hlZXRBdHRyaWJ1dGVTZXQoY2N0eHQtPnN0eWxlLCBub2RlKTsKKwkgICAgYnJlYWs7CisJZGVmYXVsdDoKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgbm9kZSwKKwkJIkludGVybmFsIGVycm9yOiAoeHNsdFBhcnNlVG9wTGV2ZWxYU0xURWxlbSkgIgorCQkiQ2Fubm90IGhhbmRsZSB0aGlzIHRvcC1sZXZlbCBkZWNsYXJhdGlvbi5cbiIpOworCSAgICBjY3R4dC0+c3R5bGUtPmVycm9ycysrOworCSAgICByZXQgPSAtMTsKKyAgICB9CisKK2V4aXQ6CisgICAgeHNsdENvbXBpbGVyTm9kZVBvcChjY3R4dCwgbm9kZSk7CisKKyAgICByZXR1cm4ocmV0KTsKK30KKworI2lmIDAKK3N0YXRpYyBpbnQKK3hzbHRQYXJzZVJlbW92ZVdoaXRlc3BhY2UoeG1sTm9kZVB0ciBub2RlKQoreworICAgIGlmICgobm9kZSA9PSBOVUxMKSB8fCAobm9kZS0+Y2hpbGRyZW4gPT0gTlVMTCkpCisJcmV0dXJuKDApOworICAgIGVsc2UgeworCXhtbE5vZGVQdHIgZGVsTm9kZSA9IE5VTEwsIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CisKKwlkbyB7CisJICAgIGlmIChkZWxOb2RlKSB7CisJCXhtbFVubGlua05vZGUoZGVsTm9kZSk7CisJCXhtbEZyZWVOb2RlKGRlbE5vZGUpOworCQlkZWxOb2RlID0gTlVMTDsKKwkgICAgfQorCSAgICBpZiAoKChjaGlsZC0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB8fAorCQkgKGNoaWxkLT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSAmJgorCQkoSVNfQkxBTktfTk9ERShjaGlsZCkpKQorCQlkZWxOb2RlID0gY2hpbGQ7CSAgICAKKwkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKKwl9IHdoaWxlIChjaGlsZCAhPSBOVUxMKTsKKwlpZiAoZGVsTm9kZSkgeworCSAgICB4bWxVbmxpbmtOb2RlKGRlbE5vZGUpOworCSAgICB4bWxGcmVlTm9kZShkZWxOb2RlKTsKKwkgICAgZGVsTm9kZSA9IE5VTEw7CisJfQorICAgIH0KKyAgICByZXR1cm4oMCk7Cit9CisjZW5kaWYKKworc3RhdGljIGludAoreHNsdFBhcnNlWFNMVFN0eWxlc2hlZXRFbGVtQ29yZSh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCit7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKyAgICBpbnQgdGVtcGxhdGVzID0gMDsKKyNlbmRpZgorICAgIHhtbE5vZGVQdHIgY3VyLCBzdGFydCA9IE5VTEw7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CisKKyAgICBpZiAoKGNjdHh0ID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpIHx8CisJKG5vZGUtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkpCisJcmV0dXJuKC0xKTsgICAgCisKKyAgICBzdHlsZSA9IGNjdHh0LT5zdHlsZTsgICAgCisgICAgLyoKKyAgICAqIEF0IHRoaXMgc3RhZ2UgYWxsIGltcG9ydCBkZWNsYXJhdGlvbnMgb2YgYWxsIHN0eWxlc2hlZXQgbW9kdWxlcworICAgICogd2l0aCB0aGUgc2FtZSBzdHlsZXNoZWV0IGxldmVsIGhhdmUgYmVlbiBwcm9jZXNzZWQuCisgICAgKiBOb3cgd2UgY2FuIHNhZmVseSBwYXJzZSB0aGUgcmVzdCBvZiB0aGUgZGVjbGFyYXRpb25zLgorICAgICovCisgICAgaWYgKElTX1hTTFRfRUxFTV9GQVNUKG5vZGUpICYmIElTX1hTTFRfTkFNRShub2RlLCAiaW5jbHVkZSIpKQorICAgIHsKKwl4c2x0RG9jdW1lbnRQdHIgaW5jbHVkZTsKKwkvKgorCSogVVJHRU5UIFRPRE86IE1ha2UgdGhpcyB3b3JrIHdpdGggc2ltcGxpZmllZCBzdHlsZXNoZWV0cyEKKwkqICAgSS5lLiwgd2hlbiB3ZSB3b24ndCBmaW5kIGFuIHhzbDpzdHlsZXNoZWV0IGVsZW1lbnQuCisJKi8KKwkvKgorCSogVGhpcyBpcyBhcyBpbmNsdWRlIGRlY2xhcmF0aW9uLgorCSovCisJaW5jbHVkZSA9ICgoeHNsdFN0eWxlSXRlbUluY2x1ZGVQdHIpIG5vZGUtPnBzdmkpLT5pbmNsdWRlOworCWlmIChpbmNsdWRlID09IE5VTEwpIHsKKwkgICAgLyogVE9ETzogcmFpc2UgZXJyb3I/ICovCisJICAgIHJldHVybigtMSk7CisJfQorCS8qCisJKiBUT0RPOiBBY3R1YWxseSBhbiB4c2w6aW5jbHVkZSBzaG91bGQgbG9jYXRlIGFuIGVtYmVkZGVkCisJKiAgc3R5bGVzaGVldCBhcyB3ZWxsOyBzbyB0aGUgZG9jdW1lbnQtZWxlbWVudCB3b24ndCBhbHdheXMKKwkqICBiZSB0aGUgZWxlbWVudCB3aGVyZSB0aGUgYWN0dWFsIHN0eWxlc2hlZXQgaXMgcm9vdGVkIGF0LgorCSogIEJ1dCBzdWNoIGVtYmVkZGVkIHN0eWxlc2hlZXRzIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IExpYnhzbHQgeWV0LgorCSovCisJbm9kZSA9IHhtbERvY0dldFJvb3RFbGVtZW50KGluY2x1ZGUtPmRvYyk7CisJaWYgKG5vZGUgPT0gTlVMTCkgeworCSAgICByZXR1cm4oLTEpOworCX0KKyAgICB9ICAgIAorICAgIAorICAgIGlmIChub2RlLT5jaGlsZHJlbiA9PSBOVUxMKQorCXJldHVybigwKTsKKyAgICAvKgorICAgICogUHVzaCB0aGUgeHNsOnN0eWxlc2hlZXQveHNsOnRyYW5zZm9ybSBlbGVtZW50LgorICAgICovICAKKyAgICB4c2x0Q29tcGlsZXJOb2RlUHVzaChjY3R4dCwgbm9kZSk7CisgICAgY2N0eHQtPmlub2RlLT5pc1Jvb3QgPSAxOworICAgIGNjdHh0LT5pbm9kZS0+bnNDaGFuZ2VkID0gMDsKKyAgICAvKgorICAgICogU3RhcnQgd2l0aCB0aGUgbmFrZWQgZHVtbXkgaW5mbyBmb3IgbGl0ZXJhbCByZXN1bHQgZWxlbWVudHMuCisgICAgKi8KKyAgICBjY3R4dC0+aW5vZGUtPmxpdFJlc0VsZW1JbmZvID0gY2N0eHQtPmlub2RlTGlzdC0+bGl0UmVzRWxlbUluZm87CisKKyAgICAvKgorICAgICogSW4gZXZlcnkgY2FzZSwgd2UgbmVlZCB0byBoYXZlCisgICAgKiB0aGUgaW4tc2NvcGUgbmFtZXNwYWNlcyBvZiB0aGUgZWxlbWVudCwgd2hlcmUgdGhlCisgICAgKiBzdHlsZXNoZWV0IGlzIHJvb3RlZCBhdCwgcmVnYXJkbGVzcyBpZiBpdCdzIGFuIFhTTFQKKyAgICAqIGluc3RydWN0aW9uIG9yIGEgbGl0ZXJhbCByZXN1bHQgaW5zdHJ1Y3Rpb24gKG9yIGlmCisgICAgKiB0aGlzIGlzIGFuIGVtYmVkZGVkIHN0eWxlc2hlZXQpLgorICAgICovCQkKKyAgICBjY3R4dC0+aW5vZGUtPmluU2NvcGVOcyA9CisJeHNsdENvbXBpbGVyQnVpbGRJblNjb3BlTnNMaXN0KGNjdHh0LCBub2RlKTsKKworICAgIC8qCisgICAgKiBQcm9jZXNzIGF0dHJpYnV0ZXMgb2YgeHNsOnN0eWxlc2hlZXQveHNsOnRyYW5zZm9ybS4KKyAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgKiBBbGxvd2VkIGFyZToKKyAgICAqICBpZCA9IGlkCisgICAgKiAgZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMgPSB0b2tlbnMKKyAgICAqICBleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyA9IHRva2VucworICAgICogIHZlcnNpb24gPSBudW1iZXIgKG1hbmRhdG9yeSkgICAgCisgICAgKi8KKyAgICBpZiAoeHNsdFBhcnNlQXR0clhTTFRWZXJzaW9uKGNjdHh0LCBub2RlLAorCVhTTFRfRUxFTUVOVF9DQVRFR09SWV9YU0xUKSA9PSAwKQorICAgIHsgICAgCisJLyoKKwkqIEF0dHJpYnV0ZSAidmVyc2lvbiIuCisJKiBYU0xUIDEuMDogIkFuIHhzbDpzdHlsZXNoZWV0IGVsZW1lbnQgKm11c3QqIGhhdmUgYSB2ZXJzaW9uCisJKiAgYXR0cmlidXRlLCBpbmRpY2F0aW5nIHRoZSB2ZXJzaW9uIG9mIFhTTFQgdGhhdCB0aGUKKwkqICBzdHlsZXNoZWV0IHJlcXVpcmVzIi4KKwkqIFRoZSByb290IGVsZW1lbnQgb2YgYSBzaW1wbGlmaWVkIHN0eWxlc2hlZXQgbXVzdCBhbHNvIGhhdmUKKwkqIHRoaXMgYXR0cmlidXRlLgorCSovCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVEX01BTkRBVE9SWV9WRVJTSU9OCisJaWYgKGlzWHNsdEVsZW0pCisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBjY3R4dC0+c3R5bGUsIG5vZGUsCisJCSJUaGUgYXR0cmlidXRlICd2ZXJzaW9uJyBpcyBtaXNzaW5nLlxuIik7CisJY2N0eHQtPnN0eWxlLT5lcnJvcnMrKzsJCisjZWxzZQorCS8qIE9MRCBiZWhhdmlvdXIuICovCisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgbm9kZSwKKwkgICAgInhzbDp2ZXJzaW9uIGlzIG1pc3Npbmc6IGRvY3VtZW50IG1heSBub3QgYmUgYSBzdHlsZXNoZWV0XG4iKTsKKwljY3R4dC0+c3R5bGUtPndhcm5pbmdzKys7CisjZW5kaWYKKyAgICB9ICAgIAorICAgIC8qCisgICAgKiBUaGUgbmFtZXNwYWNlcyBkZWNsYXJlZCBieSB0aGUgYXR0cmlidXRlcworICAgICogICJleHRlbnNpb24tZWxlbWVudC1wcmVmaXhlcyIgYW5kCisgICAgKiAgImV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzIiBhcmUgbG9jYWwgdG8gKnRoaXMqCisgICAgKiAgc3R5bGVzaGVldCB0cmVlOyBpLmUuLCB0aGV5IGFyZSAqbm90KiB2aXNpYmxlIHRvCisgICAgKiAgb3RoZXIgc3R5bGVzaGVldC1tb2R1bGVzLCB3aGV0aGVyIGltcG9ydGVkIG9yIGluY2x1ZGVkLgorICAgICogCisgICAgKiBBdHRyaWJ1dGUgImV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIi4KKyAgICAqLworICAgIGNjdHh0LT5pbm9kZS0+ZXh0RWxlbU5zID0KKwl4c2x0UGFyc2VFeHRFbGVtUHJlZml4ZXMoY2N0eHQsIG5vZGUsIE5VTEwsCisJICAgIFhTTFRfRUxFTUVOVF9DQVRFR09SWV9YU0xUKTsKKyAgICAvKgorICAgICogQXR0cmlidXRlICJleGNsdWRlLXJlc3VsdC1wcmVmaXhlcyIuCisgICAgKi8KKyAgICBjY3R4dC0+aW5vZGUtPmV4Y2xSZXN1bHROcyA9CisJeHNsdFBhcnNlRXhjbFJlc3VsdFByZWZpeGVzKGNjdHh0LCBub2RlLCBOVUxMLAorCSAgICBYU0xUX0VMRU1FTlRfQ0FURUdPUllfWFNMVCk7CisgICAgLyoKKyAgICAqIENyZWF0ZS9yZXVzZSBpbmZvIGZvciB0aGUgbGl0ZXJhbCByZXN1bHQgZWxlbWVudC4KKyAgICAqLworICAgIGlmIChjY3R4dC0+aW5vZGUtPm5zQ2hhbmdlZCkKKwl4c2x0TFJFSW5mb0NyZWF0ZShjY3R4dCwgbm9kZSwgMCk7CisgICAgLyoKKyAgICAqIFByb2Nlc3NlZCB0b3AtbGV2ZWwgZWxlbWVudHM6CisgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgICAgKiAgeHNsOnZhcmlhYmxlLCB4c2w6cGFyYW0gKFFOYW1lLCBpbi1zY29wZSBucywKKyAgICAqICAgIGV4cHJlc3Npb24gKHZhcnMgYWxsb3dlZCkpCisgICAgKiAgeHNsOmF0dHJpYnV0ZS1zZXQgKFFOYW1lLCBpbi1zY29wZSBucykKKyAgICAqICB4c2w6c3RyaXAtc3BhY2UsIHhzbDpwcmVzZXJ2ZS1zcGFjZSAoWFBhdGggTmFtZVRlc3RzLAorICAgICogICAgaW4tc2NvcGUgbnMpCisgICAgKiAgICBJICp0aGluayogZ2xvYmFsIHNjb3BlLCBtZXJnZSB3aXRoIGluY2x1ZGVzCisgICAgKiAgeHNsOm91dHB1dCAoUU5hbWUsIGluLXNjb3BlIG5zKQorICAgICogIHhzbDprZXkgKFFOYW1lLCBpbi1zY29wZSBucywgcGF0dGVybiwKKyAgICAqICAgIGV4cHJlc3Npb24gKHZhcnMgKm5vdCogYWxsb3dlZCkpCisgICAgKiAgeHNsOmRlY2ltYWwtZm9ybWF0IChRTmFtZSwgbmVlZHMgaW4tc2NvcGUgbnMpCisgICAgKiAgeHNsOm5hbWVzcGFjZS1hbGlhcyAoaW4tc2NvcGUgbnMpCisgICAgKiAgICBnbG9iYWwgc2NvcGUsIG1lcmdlIHdpdGggaW5jbHVkZXMKKyAgICAqICB4c2w6dGVtcGxhdGUgKGxhc3QsIFFOYW1lLCBwYXR0ZXJuKQorICAgICoKKyAgICAqICh3aGl0ZXNwYWNlLW9ubHkgdGV4dC1ub2RlcyBoYXZlICpub3QqIGJlZW4gcmVtb3ZlZAorICAgICogIHlldDsgdGhpcyB3aWxsIGJlIGRvbmUgaW4geHNsdFBhcnNlU2VxdWVuY2VDb25zdHJ1Y3RvcikKKyAgICAqCisgICAgKiBSZXBvcnQgbWlzcGxhY2VkIGNoaWxkLW5vZGVzIGZpcnN0LgorICAgICovCisgICAgY3VyID0gbm9kZS0+Y2hpbGRyZW47CisgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJaWYgKGN1ci0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCQkiTWlzcGxhY2VkIHRleHQgbm9kZSAoY29udGVudDogJyVzJykuXG4iLAorCQkoY3VyLT5jb250ZW50ICE9IE5VTEwpID8gY3VyLT5jb250ZW50IDogQkFEX0NBU1QgIiIpOworCSAgICBzdHlsZS0+ZXJyb3JzKys7CisJfSBlbHNlIGlmIChjdXItPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwgIk1pc3BsYWNlZCBub2RlLlxuIik7CisJICAgIHN0eWxlLT5lcnJvcnMrKzsKKwl9CisJY3VyID0gY3VyLT5uZXh0OworICAgIH0KKyAgICAvKgorICAgICogU2tpcCB4c2w6aW1wb3J0IGVsZW1lbnRzOyB0aGV5IGhhdmUgYmVlbiBwcm9jZXNzZWQKKyAgICAqIGFscmVhZHkuCisgICAgKi8KKyAgICBjdXIgPSBub2RlLT5jaGlsZHJlbjsKKyAgICB3aGlsZSAoKGN1ciAhPSBOVUxMKSAmJiB4c2x0UGFyc2VGaW5kVG9wTGV2ZWxFbGVtKGNjdHh0LCBjdXIsCisJICAgIEJBRF9DQVNUICJpbXBvcnQiLCBYU0xUX05BTUVTUEFDRSwgMSwgJmN1cikgPT0gMSkKKwljdXIgPSBjdXItPm5leHQ7CisgICAgaWYgKGN1ciA9PSBOVUxMKQorCWdvdG8gZXhpdDsKKworICAgIHN0YXJ0ID0gY3VyOworICAgIC8qCisgICAgKiBQcm9jZXNzIGFsbCB0b3AtbGV2ZWwgeHNsOnBhcmFtIGVsZW1lbnRzLgorICAgICovCisgICAgd2hpbGUgKChjdXIgIT0gTlVMTCkgJiYKKwl4c2x0UGFyc2VGaW5kVG9wTGV2ZWxFbGVtKGNjdHh0LCBjdXIsCisJQkFEX0NBU1QgInBhcmFtIiwgWFNMVF9OQU1FU1BBQ0UsIDAsICZjdXIpID09IDEpCisgICAgeworCXhzbHRQYXJzZVRvcExldmVsWFNMVEVsZW0oY2N0eHQsIGN1ciwgWFNMVF9GVU5DX1BBUkFNKTsJCisJY3VyID0gY3VyLT5uZXh0OworICAgIH0gIAorICAgIC8qCisgICAgKiBQcm9jZXNzIGFsbCB0b3AtbGV2ZWwgeHNsOnZhcmlhYmxlIGVsZW1lbnRzLgorICAgICovCisgICAgY3VyID0gc3RhcnQ7CisgICAgd2hpbGUgKChjdXIgIT0gTlVMTCkgJiYKKwl4c2x0UGFyc2VGaW5kVG9wTGV2ZWxFbGVtKGNjdHh0LCBjdXIsCisJQkFEX0NBU1QgInZhcmlhYmxlIiwgWFNMVF9OQU1FU1BBQ0UsIDAsICZjdXIpID09IDEpCisgICAgeworCXhzbHRQYXJzZVRvcExldmVsWFNMVEVsZW0oY2N0eHQsIGN1ciwgWFNMVF9GVU5DX1ZBUklBQkxFKTsKKwljdXIgPSBjdXItPm5leHQ7CisgICAgfSAgIAorICAgIC8qCisgICAgKiBQcm9jZXNzIGFsbCB0aGUgcmVzdCBvZiB0b3AtbGV2ZWwgZWxlbWVudHMuCisgICAgKi8KKyAgICBjdXIgPSBzdGFydDsKKyAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsJCisJLyoKKwkqIFByb2Nlc3MgZWxlbWVudCBub2Rlcy4KKwkqLworCWlmIChjdXItPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewkgICAgCisJICAgIGlmIChjdXItPm5zID09IE5VTEwpIHsKKwkJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJCSAgICAiVW5leHBlY3RlZCB0b3AtbGV2ZWwgZWxlbWVudCBpbiBubyBuYW1lc3BhY2UuXG4iKTsKKwkJc3R5bGUtPmVycm9ycysrOworCQljdXIgPSBjdXItPm5leHQ7CisJCWNvbnRpbnVlOworCSAgICB9CisJICAgIC8qCisJICAgICogUHJvY2VzcyBhbGwgWFNMVCBlbGVtZW50cy4KKwkgICAgKi8KKwkgICAgaWYgKElTX1hTTFRfRUxFTV9GQVNUKGN1cikpIHsKKwkJLyoKKwkJKiB4c2w6aW1wb3J0IGlzIG9ubHkgYWxsb3dlZCBhdCB0aGUgYmVnaW5uaW5nLgorCQkqLworCQlpZiAoSVNfWFNMVF9OQU1FKGN1ciwgImltcG9ydCIpKSB7CisJCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkJCSJNaXNwbGFjZWQgeHNsOmltcG9ydCBlbGVtZW50LlxuIik7CisJCSAgICBzdHlsZS0+ZXJyb3JzKys7CisJCSAgICBjdXIgPSBjdXItPm5leHQ7CisJCSAgICBjb250aW51ZTsKKwkJfQorCQkvKiAKKwkJKiBUT0RPOiBDaGFuZ2UgdGhlIHJldHVybiB0eXBlIG9mIHRoZSBwYXJzaW5nIGZ1bmN0aW9ucworCQkqICB0byBpbnQuCisJCSovCisJCWlmIChJU19YU0xUX05BTUUoY3VyLCAidGVtcGxhdGUiKSkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJCSAgICB0ZW1wbGF0ZXMrKzsKKyNlbmRpZgorCQkgICAgLyoKKwkJICAgICogVE9ETzogSXMgdGhlIHBvc2l0aW9uIG9mIHhzbDp0ZW1wbGF0ZSBpbiB0aGUKKwkJICAgICogIHRyZWUgc2lnbmlmaWNhbnQ/IElmIG5vdCBpdCB3b3VsZCBiZSBlYXNpZXIgdG8KKwkJICAgICogIHBhcnNlIHRoZW0gYXQgYSBsYXRlciBzdGFnZS4KKwkJICAgICovCisJCSAgICB4c2x0UGFyc2VYU0xUVGVtcGxhdGUoY2N0eHQsIGN1cik7CisJCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgInZhcmlhYmxlIikpIHsKKwkJICAgIC8qIE5PUDsgZG9uZSBhbHJlYWR5ICovCisJCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgInBhcmFtIikpIHsKKwkJICAgIC8qIE5PUDsgZG9uZSBhbHJlYWR5ICovCisJCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgImluY2x1ZGUiKSkgewkJICAgIAorCQkgICAgaWYgKGN1ci0+cHN2aSAhPSBOVUxMKQkJICAgIAorCQkJeHNsdFBhcnNlWFNMVFN0eWxlc2hlZXRFbGVtQ29yZShjY3R4dCwgY3VyKTsKKwkJICAgIGVsc2UgeworCQkJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJCQkgICAgIkludGVybmFsIGVycm9yOiAiCisJCQkgICAgIih4c2x0UGFyc2VYU0xUU3R5bGVzaGVldEVsZW1Db3JlKSAiCisJCQkgICAgIlRoZSB4c2w6aW5jbHVkZSBlbGVtZW50IHdhcyBub3QgY29tcGlsZWQuXG4iKTsKKwkJCXN0eWxlLT5lcnJvcnMrKzsKKwkJICAgIH0KKwkJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoY3VyLCAic3RyaXAtc3BhY2UiKSkgeworCQkgICAgLyogTm8gbm9kZSBpbmZvIG5lZWRlZC4gKi8KKwkJICAgIHhzbHRQYXJzZVN0eWxlc2hlZXRTdHJpcFNwYWNlKHN0eWxlLCBjdXIpOworCQl9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShjdXIsICJwcmVzZXJ2ZS1zcGFjZSIpKSB7CisJCSAgICAvKiBObyBub2RlIGluZm8gbmVlZGVkLiAqLworCQkgICAgeHNsdFBhcnNlU3R5bGVzaGVldFByZXNlcnZlU3BhY2Uoc3R5bGUsIGN1cik7CisJCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgIm91dHB1dCIpKSB7CisJCSAgICAvKiBObyBub2RlLWluZm8gbmVlZGVkLiAqLworCQkgICAgeHNsdFBhcnNlU3R5bGVzaGVldE91dHB1dChzdHlsZSwgY3VyKTsKKwkJfSBlbHNlIGlmIChJU19YU0xUX05BTUUoY3VyLCAia2V5IikpIHsKKwkJICAgIC8qIFRPRE86IG5vZGUtaW5mbyBuZWVkZWQgZm9yIGV4cHJlc3Npb25zID8gKi8KKwkJICAgIHhzbHRQYXJzZVN0eWxlc2hlZXRLZXkoc3R5bGUsIGN1cik7CisJCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgImRlY2ltYWwtZm9ybWF0IikpIHsKKwkJICAgIC8qIE5vIG5vZGUtaW5mbyBuZWVkZWQuICovCQkgICAgIAorCQkgICAgeHNsdFBhcnNlU3R5bGVzaGVldERlY2ltYWxGb3JtYXQoc3R5bGUsIGN1cik7CisJCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgImF0dHJpYnV0ZS1zZXQiKSkgewkJICAgIAorCQkgICAgeHNsdFBhcnNlVG9wTGV2ZWxYU0xURWxlbShjY3R4dCwgY3VyLAorCQkJWFNMVF9GVU5DX0FUVFJTRVQpOwkJCisJCX0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgIm5hbWVzcGFjZS1hbGlhcyIpKSB7CisJCSAgICAvKiBOT1A7IGRvbmUgYWxyZWFkeSAqLwkJICAgIAorCQl9IGVsc2UgeworCQkgICAgaWYgKGNjdHh0LT5pbm9kZS0+Zm9yd2FyZHNDb21wYXQpIHsKKwkJCS8qCisJCQkqIEZvcndhcmRzLWNvbXBhdGlibGUgbW9kZToKKwkJCSoKKwkJCSogWFNMVC0xOiAiaWYgaXQgaXMgYSB0b3AtbGV2ZWwgZWxlbWVudCBhbmQKKwkJCSogIFhTTFQgMS4wIGRvZXMgbm90IGFsbG93IHN1Y2ggZWxlbWVudHMgYXMgdG9wLWxldmVsCisJCQkqICBlbGVtZW50cywgdGhlbiB0aGUgZWxlbWVudCBtdXN0IGJlIGlnbm9yZWQgYWxvbmcKKwkJCSogIHdpdGggaXRzIGNvbnRlbnQ7IgorCQkJKi8KKwkJCS8qCisJCQkqIFRPRE86IEkgZG9uJ3QgdGhpbmsgd2Ugc2hvdWxkIGdlbmVyYXRlIGEgd2FybmluZy4KKwkJCSovCisJCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkJCSAgICAiRm9yd2FyZHMtY29tcGF0aWJsZSBtb2RlOiBJZ25vcmluZyB1bmtub3duIFhTTFQgIgorCQkJICAgICJlbGVtZW50ICclcycuXG4iLCBjdXItPm5hbWUpOworCQkJc3R5bGUtPndhcm5pbmdzKys7CisJCSAgICB9IGVsc2UgeworCQkJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJCQkgICAgIlVua25vd24gWFNMVCBlbGVtZW50ICclcycuXG4iLCBjdXItPm5hbWUpOworCQkJc3R5bGUtPmVycm9ycysrOworCQkgICAgfQorCQl9CisJICAgIH0gZWxzZSB7CisJCXhzbHRUb3BMZXZlbEZ1bmN0aW9uIGZ1bmN0aW9uOworCisJCS8qCisJCSogUHJvY2VzcyBub24tWFNMVCBlbGVtZW50cywgd2hpY2ggYXJlIGluIGEKKwkJKiAgbm9uLU5VTEwgbmFtZXNwYWNlLgorCQkqLworCQkvKgorCQkqIFFVRVNUSU9OOiBXaGF0IGRvZXMgeHNsdEV4dE1vZHVsZVRvcExldmVsTG9va3VwKCkKKwkJKiAgZG8gZXhhY3RseT8KKwkJKi8KKwkJZnVuY3Rpb24gPSB4c2x0RXh0TW9kdWxlVG9wTGV2ZWxMb29rdXAoY3VyLT5uYW1lLAorCQkgICAgY3VyLT5ucy0+aHJlZik7CisJCWlmIChmdW5jdGlvbiAhPSBOVUxMKQorCQkgICAgZnVuY3Rpb24oc3R5bGUsIGN1cik7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKwkJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICAgICJ4c2x0UGFyc2VYU0xUU3R5bGVzaGVldEVsZW1Db3JlIDogVXNlci1kZWZpbmVkICIKKwkJICAgICJkYXRhIGVsZW1lbnQgJyVzJy5cbiIsIGN1ci0+bmFtZSk7CisjZW5kaWYKKwkgICAgfQorCX0KKwljdXIgPSBjdXItPm5leHQ7CisgICAgfQorCitleGl0OgorCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSIjIyMgRU5EIG9mIHBhcnNpbmcgdG9wLWxldmVsIGVsZW1lbnRzIG9mIGRvYyAnJXMnLlxuIiwKKwlub2RlLT5kb2MtPlVSTCk7CisgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkiIyMjIFRlbXBsYXRlczogJWRcbiIsIHRlbXBsYXRlcyk7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkiIyMjIE1heCBpbm9kZXM6ICVkXG4iLCBjY3R4dC0+bWF4Tm9kZUluZm9zKTsKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSIjIyMgTWF4IExSRXMgIDogJWRcbiIsIGNjdHh0LT5tYXhMUkVzKTsKKyNlbmRpZiAvKiBYU0xUX1JFRkFDVE9SRUQgKi8KKyNlbmRpZiAvKiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORyAqLworCisgICAgeHNsdENvbXBpbGVyTm9kZVBvcChjY3R4dCwgbm9kZSk7CisgICAgcmV0dXJuKDApOworfQorCisvKioKKyAqIHhzbHRQYXJzZVhTTFRTdHlsZXNoZWV0OgorICogQGNjdHh0OiB0aGUgY29tcGlsZXIgY29udGV4dAorICogQG5vZGU6IHRoZSB4c2w6c3R5bGVzaGVldC94c2w6dHJhbnNmb3JtIGVsZW1lbnQtbm9kZQorICoKKyAqIFBhcnNlcyB0aGUgeHNsOnN0eWxlc2hlZXQgYW5kIHhzbDp0cmFuc2Zvcm0gZWxlbWVudC4gCisgKgorICogPHhzbDpzdHlsZXNoZWV0CisgKiAgaWQgPSBpZAorICogIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzID0gdG9rZW5zCisgKiAgZXhjbHVkZS1yZXN1bHQtcHJlZml4ZXMgPSB0b2tlbnMKKyAqICB2ZXJzaW9uID0gbnVtYmVyPgorICogIDwhLS0gQ29udGVudDogKHhzbDppbXBvcnQqLCB0b3AtbGV2ZWwtZWxlbWVudHMpIC0tPgorICogPC94c2w6c3R5bGVzaGVldD4KKyAqCisgKiBCSUcgVE9ETzogVGhlIHhzbDppbmNsdWRlIHN0dWZmLgorICogCisgKiBDYWxsZWQgYnkgeHNsdFBhcnNlU3R5bGVzaGVldFRyZWUoKQorICoKKyAqIFJldHVybnMgMCBvbiBzdWNjZXNzLCBhIHBvc2l0aXZlIHJlc3VsdCBvbiBlcnJvcnMgYW5kCisgKiAgICAgICAgIC0xIG9uIEFQSSBvciBpbnRlcm5hbCBlcnJvcnMuCisgKi8KK3N0YXRpYyBpbnQKK3hzbHRQYXJzZVhTTFRTdHlsZXNoZWV0RWxlbSh4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCit7CisgICAgeG1sTm9kZVB0ciBjdXIsIHN0YXJ0OworCisgICAgaWYgKChjY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworICAgIAorICAgIGlmIChub2RlLT5jaGlsZHJlbiA9PSBOVUxMKQorCWdvdG8gZXhpdDsKKworICAgIC8qCisgICAgKiBQcm9jZXNzIHRvcC1sZXZlbCBlbGVtZW50czoKKyAgICAqICB4c2w6aW1wb3J0IChtdXN0IGJlIGZpcnN0KQorICAgICogIHhzbDppbmNsdWRlICh0aGlzIGlzIGp1c3QgYSBwcmUtcHJvY2Vzc2luZykKKyAgICAqLworICAgIGN1ciA9IG5vZGUtPmNoaWxkcmVuOworICAgIC8qCisgICAgKiBQcm9jZXNzIHhzbDppbXBvcnQgZWxlbWVudHMuCisgICAgKiBYU0xUIDEuMDogIlRoZSB4c2w6aW1wb3J0IGVsZW1lbnQgY2hpbGRyZW4gbXVzdCBwcmVjZWRlIGFsbAorICAgICogIG90aGVyIGVsZW1lbnQgY2hpbGRyZW4gb2YgYW4geHNsOnN0eWxlc2hlZXQgZWxlbWVudCwKKyAgICAqICBpbmNsdWRpbmcgYW55IHhzbDppbmNsdWRlIGVsZW1lbnQgY2hpbGRyZW4uIgorICAgICovICAgIAorICAgIHdoaWxlICgoY3VyICE9IE5VTEwpICYmCisJeHNsdFBhcnNlRmluZFRvcExldmVsRWxlbShjY3R4dCwgY3VyLAorCSAgICBCQURfQ0FTVCAiaW1wb3J0IiwgWFNMVF9OQU1FU1BBQ0UsIDEsICZjdXIpID09IDEpCisgICAgeworCWlmICh4c2x0UGFyc2VTdHlsZXNoZWV0SW1wb3J0KGNjdHh0LT5zdHlsZSwgY3VyKSAhPSAwKSB7CisJICAgIGNjdHh0LT5zdHlsZS0+ZXJyb3JzKys7CisJfQorCWN1ciA9IGN1ci0+bmV4dDsKKyAgICB9CisgICAgaWYgKGN1ciA9PSBOVUxMKQorCWdvdG8gZXhpdDsKKyAgICBzdGFydCA9IGN1cjsKKyAgICAvKgorICAgICogUHJlLXByb2Nlc3MgYWxsIHhzbDppbmNsdWRlIGVsZW1lbnRzLgorICAgICovCisgICAgY3VyID0gc3RhcnQ7CisgICAgd2hpbGUgKChjdXIgIT0gTlVMTCkgJiYKKwl4c2x0UGFyc2VGaW5kVG9wTGV2ZWxFbGVtKGNjdHh0LCBjdXIsCisJICAgIEJBRF9DQVNUICJpbmNsdWRlIiwgWFNMVF9OQU1FU1BBQ0UsIDAsICZjdXIpID09IDEpCisgICAgeworCXhzbHRQYXJzZVRvcExldmVsWFNMVEVsZW0oY2N0eHQsIGN1ciwgWFNMVF9GVU5DX0lOQ0xVREUpOworCWN1ciA9IGN1ci0+bmV4dDsKKyAgICB9CisgICAgLyoKKyAgICAqIFByZS1wcm9jZXNzIGFsbCB4c2w6bmFtZXNwYWNlLWFsaWFzIGVsZW1lbnRzLgorICAgICogVVJHRU5UIFRPRE86IFRoaXMgd29uJ3Qgd29yayBjb3JyZWN0bHk6IHRoZSBvcmRlciBvZiBpbmNsdWRlZAorICAgICogIGFsaWFzZXMgYW5kIGFsaWFzZXMgZGVmaW5lZCBoZXJlIGlzIHNpZ25pZmljYW50LgorICAgICovCisgICAgY3VyID0gc3RhcnQ7CisgICAgd2hpbGUgKChjdXIgIT0gTlVMTCkgJiYKKwl4c2x0UGFyc2VGaW5kVG9wTGV2ZWxFbGVtKGNjdHh0LCBjdXIsCisJICAgIEJBRF9DQVNUICJuYW1lc3BhY2UtYWxpYXMiLCBYU0xUX05BTUVTUEFDRSwgMCwgJmN1cikgPT0gMSkKKyAgICB7CisJeHNsdE5hbWVzcGFjZUFsaWFzKGNjdHh0LT5zdHlsZSwgY3VyKTsKKwljdXIgPSBjdXItPm5leHQ7CisgICAgfQorCisgICAgaWYgKGNjdHh0LT5pc0luY2x1ZGUpIHsKKwkvKgorCSogSWYgdGhpcyBzdHlsZXNoZWV0IGlzIGludGVuZGVkIGZvciBpbmNsdXNpb24sIHRoZW4KKwkqIHdlIHdpbGwgcHJvY2VzcyBvbmx5IGltcG9ydHMgYW5kIGluY2x1ZGVzLiAKKwkqLworCWdvdG8gZXhpdDsKKyAgICB9IAorICAgIC8qCisgICAgKiBOb3cgcGFyc2UgdGhlIHJlc3Qgb2YgdGhlIHRvcC1sZXZlbCBlbGVtZW50cy4KKyAgICAqLworICAgIHhzbHRQYXJzZVhTTFRTdHlsZXNoZWV0RWxlbUNvcmUoY2N0eHQsIG5vZGUpOyAJCitleGl0OgorCisgICAgcmV0dXJuKDApOworfQorCisjZWxzZSAvKiBYU0xUX1JFRkFDVE9SRUQgKi8KKworLyoqCisgKiB4c2x0UGFyc2VTdHlsZXNoZWV0VG9wOgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldAorICogQHRvcDogIHRoZSB0b3AgbGV2ZWwgInN0eWxlc2hlZXQiIG9yICJ0cmFuc2Zvcm0iIGVsZW1lbnQKKyAqCisgKiBzY2FuIHRoZSB0b3AgbGV2ZWwgZWxlbWVudHMgb2YgYW4gWFNMIHN0eWxlc2hlZXQKKyAqLworc3RhdGljIHZvaWQKK3hzbHRQYXJzZVN0eWxlc2hlZXRUb3AoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgdG9wKSB7CisgICAgeG1sTm9kZVB0ciBjdXI7CisgICAgeG1sQ2hhciAqcHJvcDsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworICAgIGludCB0ZW1wbGF0ZXMgPSAwOworI2VuZGlmCisKKyAgICBpZiAodG9wID09IE5VTEwpCisJcmV0dXJuOworCisgICAgcHJvcCA9IHhtbEdldE5zUHJvcCh0b3AsIChjb25zdCB4bWxDaGFyICopInZlcnNpb24iLCBOVUxMKTsKKyAgICBpZiAocHJvcCA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCB0b3AsCisJICAgICJ4c2w6dmVyc2lvbiBpcyBtaXNzaW5nOiBkb2N1bWVudCBtYXkgbm90IGJlIGEgc3R5bGVzaGVldFxuIik7CisJaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT53YXJuaW5ncysrOworICAgIH0gZWxzZSB7CisJaWYgKCgheG1sU3RyRXF1YWwocHJvcCwgKGNvbnN0IHhtbENoYXIgKikiMS4wIikpICYmCisgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopIjEuMSIpKSkgeworCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIHRvcCwKKwkJInhzbDp2ZXJzaW9uOiBvbmx5IDEuMCBmZWF0dXJlcyBhcmUgc3VwcG9ydGVkXG4iKTsKKwkgICAgIC8qIFRPRE8gc2V0IHVwIGNvbXBhdGliaWxpdHkgd2hlbiBub3QgWFNMVCAxLjAgKi8KKwkgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT53YXJuaW5ncysrOworCX0KKwl4bWxGcmVlKHByb3ApOworICAgIH0KKworICAgIC8qCisgICAgICogcHJvY2VzcyB4c2w6aW1wb3J0IGVsZW1lbnRzCisgICAgICovCisgICAgY3VyID0gdG9wLT5jaGlsZHJlbjsKKyAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKKwkgICAgaWYgKElTX0JMQU5LX05PREUoY3VyKSkgeworCQkgICAgY3VyID0gY3VyLT5uZXh0OworCQkgICAgY29udGludWU7CisJICAgIH0KKwkgICAgaWYgKElTX1hTTFRfRUxFTShjdXIpICYmIElTX1hTTFRfTkFNRShjdXIsICJpbXBvcnQiKSkgeworCQkgICAgaWYgKHhzbHRQYXJzZVN0eWxlc2hlZXRJbXBvcnQoc3R5bGUsIGN1cikgIT0gMCkKKwkJCSAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPmVycm9ycysrOworCSAgICB9IGVsc2UKKwkJICAgIGJyZWFrOworCSAgICBjdXIgPSBjdXItPm5leHQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBwcm9jZXNzIG90aGVyIHRvcC1sZXZlbCBlbGVtZW50cworICAgICAqLworICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgeworCWlmIChJU19CTEFOS19OT0RFKGN1cikpIHsKKwkgICAgY3VyID0gY3VyLT5uZXh0OworCSAgICBjb250aW51ZTsKKwl9CisJaWYgKGN1ci0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB7CisJICAgIGlmIChjdXItPmNvbnRlbnQgIT0gTlVMTCkgeworCQl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkJICAgICJtaXNwbGFjZWQgdGV4dCBub2RlOiAnJXMnXG4iLCBjdXItPmNvbnRlbnQpOworCSAgICB9CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisgICAgICAgICAgICBjdXIgPSBjdXItPm5leHQ7CisJICAgIGNvbnRpbnVlOworCX0KKwlpZiAoKGN1ci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSAmJiAoY3VyLT5ucyA9PSBOVUxMKSkgeworCSAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LAorCQkgICAgICJGb3VuZCBhIHRvcC1sZXZlbCBlbGVtZW50ICVzIHdpdGggbnVsbCBuYW1lc3BhY2UgVVJJXG4iLAorCQkgICAgIGN1ci0+bmFtZSk7CisJICAgIGlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisJICAgIGN1ciA9IGN1ci0+bmV4dDsKKwkgICAgY29udGludWU7CisJfQorCWlmICgoY3VyLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpICYmICghKElTX1hTTFRfRUxFTShjdXIpKSkpIHsKKwkgICAgeHNsdFRvcExldmVsRnVuY3Rpb24gZnVuY3Rpb247CisKKwkgICAgZnVuY3Rpb24gPSB4c2x0RXh0TW9kdWxlVG9wTGV2ZWxMb29rdXAoY3VyLT5uYW1lLAorCQkJCQkJICAgY3VyLT5ucy0+aHJlZik7CisJICAgIGlmIChmdW5jdGlvbiAhPSBOVUxMKQorCQlmdW5jdGlvbihzdHlsZSwgY3VyKTsKKworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSAgICAieHNsdFBhcnNlU3R5bGVzaGVldFRvcCA6IGZvdW5kIGZvcmVpZ24gZWxlbWVudCAlc1xuIiwKKwkJICAgIGN1ci0+bmFtZSk7CisjZW5kaWYKKyAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKKwkgICAgY29udGludWU7CisJfQorCWlmIChJU19YU0xUX05BTUUoY3VyLCAiaW1wb3J0IikpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHN0eWxlLCBjdXIsCisJCQkieHNsdFBhcnNlU3R5bGVzaGVldFRvcDogaWdub3JpbmcgbWlzcGxhY2VkIGltcG9ydCBlbGVtZW50XG4iKTsKKwkgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKyAgICB9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShjdXIsICJpbmNsdWRlIikpIHsKKwkgICAgaWYgKHhzbHRQYXJzZVN0eWxlc2hlZXRJbmNsdWRlKHN0eWxlLCBjdXIpICE9IDApCisJCWlmIChzdHlsZSAhPSBOVUxMKSBzdHlsZS0+ZXJyb3JzKys7CisgICAgfSBlbHNlIGlmIChJU19YU0xUX05BTUUoY3VyLCAic3RyaXAtc3BhY2UiKSkgeworCSAgICB4c2x0UGFyc2VTdHlsZXNoZWV0U3RyaXBTcGFjZShzdHlsZSwgY3VyKTsKKyAgICB9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShjdXIsICJwcmVzZXJ2ZS1zcGFjZSIpKSB7CisJICAgIHhzbHRQYXJzZVN0eWxlc2hlZXRQcmVzZXJ2ZVNwYWNlKHN0eWxlLCBjdXIpOworICAgIH0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgIm91dHB1dCIpKSB7CisJICAgIHhzbHRQYXJzZVN0eWxlc2hlZXRPdXRwdXQoc3R5bGUsIGN1cik7CisgICAgfSBlbHNlIGlmIChJU19YU0xUX05BTUUoY3VyLCAia2V5IikpIHsKKwkgICAgeHNsdFBhcnNlU3R5bGVzaGVldEtleShzdHlsZSwgY3VyKTsKKyAgICB9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShjdXIsICJkZWNpbWFsLWZvcm1hdCIpKSB7CisJICAgIHhzbHRQYXJzZVN0eWxlc2hlZXREZWNpbWFsRm9ybWF0KHN0eWxlLCBjdXIpOworICAgIH0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgImF0dHJpYnV0ZS1zZXQiKSkgeworCSAgICB4c2x0UGFyc2VTdHlsZXNoZWV0QXR0cmlidXRlU2V0KHN0eWxlLCBjdXIpOworICAgIH0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgInZhcmlhYmxlIikpIHsKKwkgICAgeHNsdFBhcnNlR2xvYmFsVmFyaWFibGUoc3R5bGUsIGN1cik7CisgICAgfSBlbHNlIGlmIChJU19YU0xUX05BTUUoY3VyLCAicGFyYW0iKSkgeworCSAgICB4c2x0UGFyc2VHbG9iYWxQYXJhbShzdHlsZSwgY3VyKTsKKyAgICB9IGVsc2UgaWYgKElTX1hTTFRfTkFNRShjdXIsICJ0ZW1wbGF0ZSIpKSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKwkgICAgdGVtcGxhdGVzKys7CisjZW5kaWYKKwkgICAgeHNsdFBhcnNlU3R5bGVzaGVldFRlbXBsYXRlKHN0eWxlLCBjdXIpOworICAgIH0gZWxzZSBpZiAoSVNfWFNMVF9OQU1FKGN1ciwgIm5hbWVzcGFjZS1hbGlhcyIpKSB7CisJICAgIHhzbHROYW1lc3BhY2VBbGlhcyhzdHlsZSwgY3VyKTsKKwl9IGVsc2UgeworCSAgICAvKgorCSAgICAqIEJVRyBUT0RPOiBUaGUgdmVyc2lvbiBvZiB0aGUgKmRvYyogaXMgaXJyZWxldmFudCBmb3IKKwkgICAgKiAgdGhlIGZvcndhcmRzLWNvbXBhdGlibGUgbW9kZS4KKwkgICAgKi8KKyAgICAgICAgICAgIGlmICgoc3R5bGUgIT0gTlVMTCkgJiYgKHN0eWxlLT5kb2MtPnZlcnNpb24gIT0gTlVMTCkgJiYKKwkgICAgICAgICghc3RybmNtcCgoY29uc3QgY2hhciAqKSBzdHlsZS0+ZG9jLT52ZXJzaW9uLCAiMS4wIiwgMykpKSB7CisJICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgc3R5bGUsIGN1ciwKKwkJCSJ4c2x0UGFyc2VTdHlsZXNoZWV0VG9wOiB1bmtub3duICVzIGVsZW1lbnRcbiIsCisJCQljdXItPm5hbWUpOworCSAgICAgICAgaWYgKHN0eWxlICE9IE5VTEwpIHN0eWxlLT5lcnJvcnMrKzsKKwkgICAgfQorCSAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAvKiBkbyBGb3J3YXJkcy1Db21wYXRpYmxlIFByb2Nlc3NpbmcgKi8KKwkgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgY3VyLAorCQkJInhzbHRQYXJzZVN0eWxlc2hlZXRUb3A6IGlnbm9yaW5nIHVua25vd24gJXMgZWxlbWVudFxuIiwKKwkJCWN1ci0+bmFtZSk7CisJICAgICAgICBpZiAoc3R5bGUgIT0gTlVMTCkgc3R5bGUtPndhcm5pbmdzKys7CisgICAgICAgICAgICB9CisJfQorCWN1ciA9IGN1ci0+bmV4dDsKKyAgICB9CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgInBhcnNlZCAlZCB0ZW1wbGF0ZXNcbiIsIHRlbXBsYXRlcyk7CisjZW5kaWYKK30KKworI2VuZGlmIC8qIGVsc2Ugb2YgWFNMVF9SRUZBQ1RPUkVEICovCisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKy8qKgorICogeHNsdFBhcnNlU2ltcGxpZmllZFN0eWxlc2hlZXRUcmVlOgorICoKKyAqIEBzdHlsZTogdGhlIHN0eWxlc2hlZXQgKFRPRE86IENoYW5nZSB0aGlzIHRvIHRoZSBjb21waWxlciBjb250ZXh0KQorICogQGRvYzogdGhlIGRvY3VtZW50IGNvbnRhaW5pbmcgdGhlIHN0eWxlc2hlZXQuCisgKiBAbm9kZTogdGhlIG5vZGUgd2hlcmUgdGhlIHN0eWxlc2hlZXQgaXMgcm9vdGVkIGF0CisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgYSBwb3NpdGl2ZSByZXN1bHQgaWYgYW4gZXJyb3Igb2NjdXJyZWQKKyAqICAgICAgICAgYW5kIC0xIG9uIEFQSSBhbmQgaW50ZXJuYWwgZXJyb3JzLgorICovCitzdGF0aWMgaW50Cit4c2x0UGFyc2VTaW1wbGlmaWVkU3R5bGVzaGVldFRyZWUoeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dCwKKwkJCQkgIHhtbERvY1B0ciBkb2MsCisJCQkJICB4bWxOb2RlUHRyIG5vZGUpCit7CisgICAgeHNsdFRlbXBsYXRlUHRyIHRlbXBsOworICAgIAorICAgIGlmICgoY2N0eHQgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCisJcmV0dXJuKC0xKTsKKworICAgIGlmICh4c2x0UGFyc2VBdHRyWFNMVFZlcnNpb24oY2N0eHQsIG5vZGUsIDApID09IFhTTFRfRUxFTUVOVF9DQVRFR09SWV9MUkUpCisgICAgeworCS8qCisJKiBUT0RPOiBBZGp1c3QgcmVwb3J0LCBzaW5jZSB0aGlzIG1pZ2h0IGJlIGFuCisJKiBlbWJlZGRlZCBzdHlsZXNoZWV0LgorCSovCisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIGNjdHh0LT5zdHlsZSwgbm9kZSwKKwkgICAgIlRoZSBhdHRyaWJ1dGUgJ3hzbDp2ZXJzaW9uJyBpcyBtaXNzaW5nOyBjYW5ub3QgaWRlbnRpZnkgIgorCSAgICAidGhpcyBkb2N1bWVudCBhcyBhbiBYU0xUIHN0eWxlc2hlZXQgZG9jdW1lbnQuXG4iKTsKKwljY3R4dC0+c3R5bGUtPmVycm9ycysrOworCXJldHVybigxKTsKKyAgICB9CisgICAgCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKyAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCSJ4c2x0UGFyc2VTaW1wbGlmaWVkU3R5bGVzaGVldFRyZWU6IGRvY3VtZW50IGlzIHN0eWxlc2hlZXRcbiIpOworI2VuZGlmICAgICAgICAKKyAgICAKKyAgICAvKgorICAgICogQ3JlYXRlIGFuZCBsaW5rIHRoZSB0ZW1wbGF0ZQorICAgICovCisgICAgdGVtcGwgPSB4c2x0TmV3VGVtcGxhdGUoKTsKKyAgICBpZiAodGVtcGwgPT0gTlVMTCkgeworCXJldHVybigtMSk7CisgICAgfQorICAgIHRlbXBsLT5uZXh0ID0gY2N0eHQtPnN0eWxlLT50ZW1wbGF0ZXM7CisgICAgY2N0eHQtPnN0eWxlLT50ZW1wbGF0ZXMgPSB0ZW1wbDsKKyAgICB0ZW1wbC0+bWF0Y2ggPSB4bWxTdHJkdXAoQkFEX0NBU1QgIi8iKTsKKworICAgIC8qCisgICAgKiBOb3RlIHRoYXQgd2UgcHVzaCB0aGUgZG9jdW1lbnQtbm9kZSBpbiB0aGlzIHNwZWNpYWwgY2FzZS4KKyAgICAqLworICAgIHhzbHRDb21waWxlck5vZGVQdXNoKGNjdHh0LCAoeG1sTm9kZVB0cikgZG9jKTsKKyAgICAvKgorICAgICogSW4gZXZlcnkgY2FzZSwgd2UgbmVlZCB0byBoYXZlCisgICAgKiB0aGUgaW4tc2NvcGUgbmFtZXNwYWNlcyBvZiB0aGUgZWxlbWVudCwgd2hlcmUgdGhlCisgICAgKiBzdHlsZXNoZWV0IGlzIHJvb3RlZCBhdCwgcmVnYXJkbGVzcyBpZiBpdCdzIGFuIFhTTFQKKyAgICAqIGluc3RydWN0aW9uIG9yIGEgbGl0ZXJhbCByZXN1bHQgaW5zdHJ1Y3Rpb24gKG9yIGlmCisgICAgKiB0aGlzIGlzIGFuIGVtYmVkZGVkIHN0eWxlc2hlZXQpLgorICAgICovCisgICAgY2N0eHQtPmlub2RlLT5pblNjb3BlTnMgPQorCXhzbHRDb21waWxlckJ1aWxkSW5TY29wZU5zTGlzdChjY3R4dCwgbm9kZSk7CisgICAgLyoKKyAgICAqIFBhcnNlIHRoZSBjb250ZW50IGFuZCByZWdpc3RlciB0aGUgbWF0Y2gtcGF0dGVybi4KKyAgICAqLworICAgIHhzbHRQYXJzZVNlcXVlbmNlQ29uc3RydWN0b3IoY2N0eHQsIG5vZGUpOworICAgIHhzbHRDb21waWxlck5vZGVQb3AoY2N0eHQsICh4bWxOb2RlUHRyKSBkb2MpOworCisgICAgdGVtcGwtPmVsZW0gPSAoeG1sTm9kZVB0cikgZG9jOworICAgIHRlbXBsLT5jb250ZW50ID0gbm9kZTsKKyAgICB4c2x0QWRkVGVtcGxhdGUoY2N0eHQtPnN0eWxlLCB0ZW1wbCwgTlVMTCwgTlVMTCk7CisgICAgY2N0eHQtPnN0eWxlLT5saXRlcmFsX3Jlc3VsdCA9IDE7CisgICAgcmV0dXJuKDApOworfQorCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVEX1hTTFRfTlNDT01QCisvKioKKyAqIHhzbHRSZXN0b3JlRG9jdW1lbnROYW1lc3BhY2VzOgorICogQG5zOiBtYXAgb2YgbmFtZXNwYWNlcworICogQGRvYzogdGhlIGRvY3VtZW50CisgKgorICogUmVzdG9yZSB0aGUgbmFtZXNwYWNlcyBmb3IgdGhlIGRvY3VtZW50CisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgLTEgaW4gY2FzZSBvZiBmYWlsdXJlCisgKi8KK2ludAoreHNsdFJlc3RvcmVEb2N1bWVudE5hbWVzcGFjZXMoeHNsdE5zTWFwUHRyIG5zLCB4bWxEb2NQdHIgZG9jKQoreworICAgIGlmIChkb2MgPT0gTlVMTCkKKwlyZXR1cm4oLTEpOworICAgIC8qCisgICAgKiBSZXZlcnQgdGhlIGNoYW5nZXMgd2UgaGF2ZSBhcHBsaWVkIHRvIHRoZSBuYW1lc3BhY2UtVVJJcyBvZgorICAgICogbnMtZGVjbHMuCisgICAgKi8gICAgCisgICAgd2hpbGUgKG5zICE9IE5VTEwpIHsKKwlpZiAoKG5zLT5kb2MgPT0gZG9jKSAmJiAobnMtPm5zICE9IE5VTEwpKSB7CisJICAgIG5zLT5ucy0+aHJlZiA9IG5zLT5vcmlnTnNOYW1lOworCSAgICBucy0+b3JpZ05zTmFtZSA9IE5VTEw7CisJICAgIG5zLT5ucyA9IE5VTEw7CSAgICAKKwl9CisJbnMgPSBucy0+bmV4dDsKKyAgICB9CisgICAgcmV0dXJuKDApOworfQorI2VuZGlmIC8qIFhTTFRfUkVGQUNUT1JFRF9YU0xUX05TQ09NUCAqLworCisvKioKKyAqIHhzbHRQYXJzZVN0eWxlc2hlZXRQcm9jZXNzOgorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldCAodGhlIGN1cnJlbnQgc3R5bGVzaGVldC1sZXZlbCkKKyAqIEBkb2M6ICBhbmQgeG1sRG9jIHBhcnNlZCBYTUwKKyAqCisgKiBQYXJzZXMgYW4gWFNMVCBzdHlsZXNoZWV0LCBhZGRpbmcgdGhlIGFzc29jaWF0ZWQgc3RydWN0dXJlcy4KKyAqIENhbGxlZCBieToKKyAqICB4c2x0UGFyc2VTdHlsZXNoZWV0SW1wb3J0ZWREb2MoKSAoeHNsdC5jKQorICogIHhzbHRQYXJzZVN0eWxlc2hlZXRJbmNsdWRlKCkgKGltcG9ydHMuYykKKyAqCisgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgQHN0eWxlIHBhcmFtZXRlciBpZiBldmVyeXRoaW5nCisgKiB3ZW50IHJpZ2h0LCBOVUxMIGlmIHNvbWV0aGluZyB3ZW50IGFtaXNzLgorICovCit4c2x0U3R5bGVzaGVldFB0cgoreHNsdFBhcnNlU3R5bGVzaGVldFByb2Nlc3MoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbERvY1B0ciBkb2MpCit7CisgICAgeHNsdENvbXBpbGVyQ3R4dFB0ciBjY3R4dDsKKyAgICB4bWxOb2RlUHRyIGN1cjsKKyAgICBpbnQgb2xkSXNTaW1wbGlmaWVkU3R5bGVzaGVldDsKKworICAgIHhzbHRJbml0R2xvYmFscygpOworCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoZG9jID09IE5VTEwpKQorCXJldHVybihOVUxMKTsKKworICAgIGNjdHh0ID0gWFNMVF9DQ1RYVChzdHlsZSk7CisKKyAgICBjdXIgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOworICAgIGlmIChjdXIgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgKHhtbE5vZGVQdHIpIGRvYywKKwkJInhzbHRQYXJzZVN0eWxlc2hlZXRQcm9jZXNzIDogZW1wdHkgc3R5bGVzaGVldFxuIik7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICBvbGRJc1NpbXBsaWZpZWRTdHlsZXNoZWV0ID0gY2N0eHQtPnNpbXBsaWZpZWQ7CisKKyAgICBpZiAoKElTX1hTTFRfRUxFTShjdXIpKSAmJiAKKwkoKElTX1hTTFRfTkFNRShjdXIsICJzdHlsZXNoZWV0IikpIHx8CisJIChJU19YU0xUX05BTUUoY3VyLCAidHJhbnNmb3JtIikpKSkgewkKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCSJ4c2x0UGFyc2VTdHlsZXNoZWV0UHJvY2VzcyA6IGZvdW5kIHN0eWxlc2hlZXRcbiIpOworI2VuZGlmCisJY2N0eHQtPnNpbXBsaWZpZWQgPSAwOworCXN0eWxlLT5saXRlcmFsX3Jlc3VsdCA9IDA7CisgICAgfSBlbHNlIHsKKwljY3R4dC0+c2ltcGxpZmllZCA9IDE7CisJc3R5bGUtPmxpdGVyYWxfcmVzdWx0ID0gMTsKKyAgICB9CisgICAgLyoKKyAgICAqIFByZS1wcm9jZXNzIHRoZSBzdHlsZXNoZWV0IGlmIG5vdCBhbHJlYWR5IGRvbmUgYmVmb3JlLgorICAgICogIFRoaXMgd2lsbCByZW1vdmUgUElzIGFuZCBjb21tZW50cywgbWVyZ2UgYWRqYWNlbnQKKyAgICAqICB0ZXh0IG5vZGVzLCBpbnRlcm5hbGl6ZSBzdHJpbmdzLCBldGMuCisgICAgKi8KKyAgICBpZiAoISBzdHlsZS0+bm9wcmVwcm9jKQorCXhzbHRQYXJzZVByZXByb2Nlc3NTdHlsZXNoZWV0VHJlZShjY3R4dCwgY3VyKTsKKyAgICAvKgorICAgICogUGFyc2UgYW5kIGNvbXBpbGUgdGhlIHN0eWxlc2hlZXQuCisgICAgKi8KKyAgICBpZiAoc3R5bGUtPmxpdGVyYWxfcmVzdWx0ID09IDApIHsKKwlpZiAoeHNsdFBhcnNlWFNMVFN0eWxlc2hlZXRFbGVtKGNjdHh0LCBjdXIpICE9IDApCisJICAgIHJldHVybihOVUxMKTsKKyAgICB9IGVsc2UgeworCWlmICh4c2x0UGFyc2VTaW1wbGlmaWVkU3R5bGVzaGVldFRyZWUoY2N0eHQsIGRvYywgY3VyKSAhPSAwKQorCSAgICByZXR1cm4oTlVMTCk7CisgICAgfSAgICAKKworICAgIGNjdHh0LT5zaW1wbGlmaWVkID0gb2xkSXNTaW1wbGlmaWVkU3R5bGVzaGVldDsKKworICAgIHJldHVybihzdHlsZSk7Cit9CisKKyNlbHNlIC8qIFhTTFRfUkVGQUNUT1JFRCAqLworCisvKioKKyAqIHhzbHRQYXJzZVN0eWxlc2hlZXRQcm9jZXNzOgorICogQHJldDogIHRoZSBYU0xUIHN0eWxlc2hlZXQgKHRoZSBjdXJyZW50IHN0eWxlc2hlZXQtbGV2ZWwpCisgKiBAZG9jOiAgYW5kIHhtbERvYyBwYXJzZWQgWE1MCisgKgorICogUGFyc2VzIGFuIFhTTFQgc3R5bGVzaGVldCwgYWRkaW5nIHRoZSBhc3NvY2lhdGVkIHN0cnVjdHVyZXMuCisgKiBDYWxsZWQgYnk6CisgKiAgeHNsdFBhcnNlU3R5bGVzaGVldEltcG9ydGVkRG9jKCkgKHhzbHQuYykKKyAqICB4c2x0UGFyc2VTdHlsZXNoZWV0SW5jbHVkZSgpIChpbXBvcnRzLmMpCisgKgorICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIEBzdHlsZSBwYXJhbWV0ZXIgaWYgZXZlcnl0aGluZworICogd2VudCByaWdodCwgTlVMTCBpZiBzb21ldGhpbmcgd2VudCBhbWlzcy4KKyAqLworeHNsdFN0eWxlc2hlZXRQdHIKK3hzbHRQYXJzZVN0eWxlc2hlZXRQcm9jZXNzKHhzbHRTdHlsZXNoZWV0UHRyIHJldCwgeG1sRG9jUHRyIGRvYykgeworICAgIHhtbE5vZGVQdHIgY3VyOworCisgICAgeHNsdEluaXRHbG9iYWxzKCk7CisKKyAgICBpZiAoZG9jID09IE5VTEwpCisJcmV0dXJuKE5VTEwpOworICAgIGlmIChyZXQgPT0gTlVMTCkKKwlyZXR1cm4ocmV0KTsKKyAgICAKKyAgICAvKgorICAgICAqIEZpcnN0IHN0ZXBzLCByZW1vdmUgYmxhbmsgbm9kZXMsCisgICAgICogbG9jYXRlIHRoZSB4c2w6c3R5bGVzaGVldCBlbGVtZW50IGFuZCB0aGUKKyAgICAgKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24uCisgICAgICovCisgICAgY3VyID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKKyAgICBpZiAoY3VyID09IE5VTEwpIHsKKwl4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgcmV0LCAoeG1sTm9kZVB0cikgZG9jLAorCQkieHNsdFBhcnNlU3R5bGVzaGVldFByb2Nlc3MgOiBlbXB0eSBzdHlsZXNoZWV0XG4iKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorCisgICAgaWYgKChJU19YU0xUX0VMRU0oY3VyKSkgJiYgCisJKChJU19YU0xUX05BTUUoY3VyLCAic3R5bGVzaGVldCIpKSB8fAorCSAoSVNfWFNMVF9OQU1FKGN1ciwgInRyYW5zZm9ybSIpKSkpIHsJCisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKwl4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkieHNsdFBhcnNlU3R5bGVzaGVldFByb2Nlc3MgOiBmb3VuZCBzdHlsZXNoZWV0XG4iKTsKKyNlbmRpZgorCXJldC0+bGl0ZXJhbF9yZXN1bHQgPSAwOworCXhzbHRQYXJzZVN0eWxlc2hlZXRFeGNsdWRlUHJlZml4KHJldCwgY3VyLCAxKTsKKwl4c2x0UGFyc2VTdHlsZXNoZWV0RXh0UHJlZml4KHJldCwgY3VyLCAxKTsKKyAgICB9IGVsc2UgeworCXhzbHRQYXJzZVN0eWxlc2hlZXRFeGNsdWRlUHJlZml4KHJldCwgY3VyLCAwKTsKKwl4c2x0UGFyc2VTdHlsZXNoZWV0RXh0UHJlZml4KHJldCwgY3VyLCAwKTsKKwlyZXQtPmxpdGVyYWxfcmVzdWx0ID0gMTsKKyAgICB9CisgICAgaWYgKCFyZXQtPm5vcHJlcHJvYykgeworCXhzbHRQcmVjb21wdXRlU3R5bGVzaGVldChyZXQsIGN1cik7CisgICAgfQorICAgIGlmIChyZXQtPmxpdGVyYWxfcmVzdWx0ID09IDApIHsKKwl4c2x0UGFyc2VTdHlsZXNoZWV0VG9wKHJldCwgY3VyKTsKKyAgICB9IGVsc2UgeworCXhtbENoYXIgKnByb3A7CisJeHNsdFRlbXBsYXRlUHRyIHRlbXBsYXRlOworCisJLyoKKwkgKiB0aGUgZG9jdW1lbnQgaXRzZWxmIG1pZ2h0IGJlIHRoZSB0ZW1wbGF0ZSwgY2hlY2sgeHNsOnZlcnNpb24KKwkgKi8KKwlwcm9wID0geG1sR2V0TnNQcm9wKGN1ciwgKGNvbnN0IHhtbENoYXIgKikidmVyc2lvbiIsIFhTTFRfTkFNRVNQQUNFKTsKKwlpZiAocHJvcCA9PSBOVUxMKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCByZXQsIGN1ciwKKwkJInhzbHRQYXJzZVN0eWxlc2hlZXRQcm9jZXNzIDogZG9jdW1lbnQgaXMgbm90IGEgc3R5bGVzaGVldFxuIik7CisJICAgIHJldHVybihOVUxMKTsKKwl9CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworICAgICAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkieHNsdFBhcnNlU3R5bGVzaGVldFByb2Nlc3MgOiBkb2N1bWVudCBpcyBzdHlsZXNoZWV0XG4iKTsKKyNlbmRpZgorCQorCWlmICgheG1sU3RyRXF1YWwocHJvcCwgKGNvbnN0IHhtbENoYXIgKikiMS4wIikpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIHJldCwgY3VyLAorCQkieHNsOnZlcnNpb246IG9ubHkgMS4wIGZlYXR1cmVzIGFyZSBzdXBwb3J0ZWRcbiIpOworCSAgICAgLyogVE9ETyBzZXQgdXAgY29tcGF0aWJpbGl0eSB3aGVuIG5vdCBYU0xUIDEuMCAqLworCSAgICByZXQtPndhcm5pbmdzKys7CisJfQorCXhtbEZyZWUocHJvcCk7CisKKwkvKgorCSAqIENyZWF0ZSBhbmQgbGluayB0aGUgdGVtcGxhdGUKKwkgKi8KKwl0ZW1wbGF0ZSA9IHhzbHROZXdUZW1wbGF0ZSgpOworCWlmICh0ZW1wbGF0ZSA9PSBOVUxMKSB7CisJICAgIHJldHVybihOVUxMKTsKKwl9CisJdGVtcGxhdGUtPm5leHQgPSByZXQtPnRlbXBsYXRlczsKKwlyZXQtPnRlbXBsYXRlcyA9IHRlbXBsYXRlOworCXRlbXBsYXRlLT5tYXRjaCA9IHhtbFN0cmR1cCgoY29uc3QgeG1sQ2hhciAqKSIvIik7CisKKwkvKgorCSAqIHBhcnNlIHRoZSBjb250ZW50IGFuZCByZWdpc3RlciB0aGUgcGF0dGVybgorCSAqLworCXhzbHRQYXJzZVRlbXBsYXRlQ29udGVudChyZXQsICh4bWxOb2RlUHRyKSBkb2MpOworCXRlbXBsYXRlLT5lbGVtID0gKHhtbE5vZGVQdHIpIGRvYzsKKwl0ZW1wbGF0ZS0+Y29udGVudCA9IGRvYy0+Y2hpbGRyZW47CisJeHNsdEFkZFRlbXBsYXRlKHJldCwgdGVtcGxhdGUsIE5VTEwsIE5VTEwpOworCXJldC0+bGl0ZXJhbF9yZXN1bHQgPSAxOwkKKyAgICB9CisKKyAgICByZXR1cm4ocmV0KTsKK30KKworI2VuZGlmIC8qIGVsc2Ugb2YgWFNMVF9SRUZBQ1RPUkVEICovCisKKy8qKgorICogeHNsdFBhcnNlU3R5bGVzaGVldEltcG9ydGVkRG9jOgorICogQGRvYzogIGFuIHhtbERvYyBwYXJzZWQgWE1MCisgKiBAcGFyZW50U3R5bGU6IHBvaW50ZXIgdG8gdGhlIHBhcmVudCBzdHlsZXNoZWV0IChpZiBpdCBleGlzdHMpCisgKgorICogcGFyc2UgYW4gWFNMVCBzdHlsZXNoZWV0IGJ1aWxkaW5nIHRoZSBhc3NvY2lhdGVkIHN0cnVjdHVyZXMKKyAqIGV4Y2VwdCB0aGUgcHJvY2Vzc2luZyBub3QgbmVlZGVkIGZvciBpbXBvcnRlZCBkb2N1bWVudHMuCisgKgorICogUmV0dXJucyBhIG5ldyBYU0xUIHN0eWxlc2hlZXQgc3RydWN0dXJlLgorICovCisKK3hzbHRTdHlsZXNoZWV0UHRyCit4c2x0UGFyc2VTdHlsZXNoZWV0SW1wb3J0ZWREb2MoeG1sRG9jUHRyIGRvYywKKwkJCSAgICAgICB4c2x0U3R5bGVzaGVldFB0ciBwYXJlbnRTdHlsZSkgeworICAgIHhzbHRTdHlsZXNoZWV0UHRyIHJldFN0eWxlOworCisgICAgaWYgKGRvYyA9PSBOVUxMKQorCXJldHVybihOVUxMKTsKKworICAgIHJldFN0eWxlID0geHNsdE5ld1N0eWxlc2hlZXQoKTsKKyAgICBpZiAocmV0U3R5bGUgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisgICAgLyoKKyAgICAqIFNldCB0aGUgaW1wb3J0aW5nIHN0eWxlc2hlZXQgbW9kdWxlOyBhbHNvIHVzZWQgdG8gZGV0ZWN0IHJlY3Vyc2lvbi4KKyAgICAqLworICAgIHJldFN0eWxlLT5wYXJlbnQgPSBwYXJlbnRTdHlsZTsKKyAgICAvKgorICAgICogQWRqdXN0IHRoZSBzdHJpbmcgZGljdC4KKyAgICAqLworICAgIGlmIChkb2MtPmRpY3QgIT0gTlVMTCkgeworICAgICAgICB4bWxEaWN0RnJlZShyZXRTdHlsZS0+ZGljdCk7CisJcmV0U3R5bGUtPmRpY3QgPSBkb2MtPmRpY3Q7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHCisgICAgICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICJyZXVzaW5nIGRpY3Rpb25hcnkgZnJvbSAlcyBmb3Igc3R5bGVzaGVldFxuIiwKKwkgICAgZG9jLT5VUkwpOworI2VuZGlmCisJeG1sRGljdFJlZmVyZW5jZShyZXRTdHlsZS0+ZGljdCk7CisgICAgfSAgICAJCisgICAgCisgICAgLyoKKyAgICAqIFRPRE86IEVsaW1pbmF0ZSB4c2x0R2F0aGVyTmFtZXNwYWNlcygpOyB3ZSBtdXN0IG5vdCByZXN0cmljdAorICAgICogIHRoZSBzdHlsZXNoZWV0IHRvIGNvbnRhaW50IGRpc3RpbmN0IG5hbWVzcGFjZSBwcmVmaXhlcy4KKyAgICAqLworICAgIHhzbHRHYXRoZXJOYW1lc3BhY2VzKHJldFN0eWxlKTsKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHsKKwl4c2x0Q29tcGlsZXJDdHh0UHRyIGNjdHh0OworCXhzbHRTdHlsZXNoZWV0UHRyIG9sZEN1clNoZWV0OworCSAgICAKKwlpZiAocGFyZW50U3R5bGUgPT0gTlVMTCkgeworCSAgICB4c2x0UHJpbmNpcGFsU3R5bGVzaGVldERhdGFQdHIgcHJpbmNpcGFsRGF0YTsKKwkgICAgLyoKKwkgICAgKiBQcmluY2lwYWwgc3R5bGVzaGVldAorCSAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tCisJICAgICovCisJICAgIHJldFN0eWxlLT5wcmluY2lwYWwgPSByZXRTdHlsZTsKKwkgICAgLyoKKwkgICAgKiBDcmVhdGUgZXh0cmEgZGF0YSBmb3IgdGhlIHByaW5jaXBhbCBzdHlsZXNoZWV0LgorCSAgICAqLworCSAgICBwcmluY2lwYWxEYXRhID0geHNsdE5ld1ByaW5jaXBhbFN0eWxlc2hlZXREYXRhKCk7CisJICAgIGlmIChwcmluY2lwYWxEYXRhID09IE5VTEwpIHsKKwkJeHNsdEZyZWVTdHlsZXNoZWV0KHJldFN0eWxlKTsKKwkJcmV0dXJuKE5VTEwpOworCSAgICB9CisJICAgIHJldFN0eWxlLT5wcmluY2lwYWxEYXRhID0gcHJpbmNpcGFsRGF0YTsKKwkgICAgLyoKKwkgICAgKiBDcmVhdGUgdGhlIGNvbXBpbGF0aW9uIGNvbnRleHQKKwkgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwkgICAgKiAob25seSBvbmNlOyBmb3IgdGhlIHByaW5jaXBhbCBzdHlsZXNoZWV0KS4KKwkgICAgKiBUaGlzIGlzIGN1cnJlbnRseSB0aGUgb25seSBmdW5jdGlvbiB3aGVyZSB0aGUKKwkgICAgKiBjb21waWxhdGlvbiBjb250ZXh0IGlzIGNyZWF0ZWQuCisJICAgICovCisJICAgIGNjdHh0ID0geHNsdENvbXBpbGF0aW9uQ3R4dENyZWF0ZShyZXRTdHlsZSk7CisJICAgIGlmIChjY3R4dCA9PSBOVUxMKSB7CisJCXhzbHRGcmVlU3R5bGVzaGVldChyZXRTdHlsZSk7CisJCXJldHVybihOVUxMKTsKKwkgICAgfQkgICAgCSAgICAKKwkgICAgcmV0U3R5bGUtPmNvbXBDdHh0ID0gKHZvaWQgKikgY2N0eHQ7CisJICAgIGNjdHh0LT5zdHlsZSA9IHJldFN0eWxlOworCSAgICBjY3R4dC0+ZGljdCA9IHJldFN0eWxlLT5kaWN0OworCSAgICBjY3R4dC0+cHNEYXRhID0gcHJpbmNpcGFsRGF0YTsKKwkgICAgLyoKKwkgICAgKiBQdXNoIGluaXRpYWwgZHVtbXkgbm9kZSBpbmZvLgorCSAgICAqLworCSAgICBjY3R4dC0+ZGVwdGggPSAtMTsKKwkgICAgeHNsdENvbXBpbGVyTm9kZVB1c2goY2N0eHQsICh4bWxOb2RlUHRyKSBkb2MpOworCX0gZWxzZSB7CisJICAgIC8qCisJICAgICogSW1wb3J0ZWQgc3R5bGVzaGVldC4KKwkgICAgKi8KKwkgICAgcmV0U3R5bGUtPnByaW5jaXBhbCA9IHBhcmVudFN0eWxlLT5wcmluY2lwYWw7CisJICAgIGNjdHh0ID0gcGFyZW50U3R5bGUtPmNvbXBDdHh0OworCSAgICByZXRTdHlsZS0+Y29tcEN0eHQgPSBjY3R4dDsKKwl9CisJLyoKKwkqIFNhdmUgdGhlIG9sZCBhbmQgc2V0IHRoZSBjdXJyZW50IHN0eWxlc2hlZXQgc3RydWN0dXJlIGluIHRoZQorCSogY29tcGlsYXRpb24gY29udGV4dC4KKwkqLworCW9sZEN1clNoZWV0ID0gY2N0eHQtPnN0eWxlOworCWNjdHh0LT5zdHlsZSA9IHJldFN0eWxlOworCQorCXJldFN0eWxlLT5kb2MgPSBkb2M7CisJeHNsdFBhcnNlU3R5bGVzaGVldFByb2Nlc3MocmV0U3R5bGUsIGRvYyk7CisJCisJY2N0eHQtPnN0eWxlID0gb2xkQ3VyU2hlZXQ7CisJaWYgKHBhcmVudFN0eWxlID09IE5VTEwpIHsKKwkgICAgLyoKKwkgICAgKiBQb3AgdGhlIGluaXRpYWwgZHVtbXkgbm9kZSBpbmZvLgorCSAgICAqLworCSAgICB4c2x0Q29tcGlsZXJOb2RlUG9wKGNjdHh0LCAoeG1sTm9kZVB0cikgZG9jKTsKKwl9IGVsc2UgeworCSAgICAvKgorCSAgICAqIENsZWFyIHRoZSBjb21waWxhdGlvbiBjb250ZXh0IG9mIGltcG9ydGVkCisJICAgICogc3R5bGVzaGVldHMuCisJICAgICogVE9ETzogcmVhbGx5PworCSAgICAqLworCSAgICAvKiByZXRTdHlsZS0+Y29tcEN0eHQgPSBOVUxMOyAqLworCX0KKwkvKgorCSogRnJlZSB0aGUgc3R5bGVzaGVldCBpZiB0aGVyZSB3ZXJlIGVycm9ycy4KKwkqLworCWlmIChyZXRTdHlsZSAhPSBOVUxMKSB7CisJICAgIGlmIChyZXRTdHlsZS0+ZXJyb3JzICE9IDApIHsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAKKwkJLyoKKwkJKiBSZXN0b3JlIGFsbCBjaGFuZ2VzIG1hZGUgdG8gbmFtZXNwYWNlIFVSSXMgb2YgbnMtZGVjbHMuCisJCSovCisJCWlmIChjY3R4dC0+cHNEYXRhLT5uc01hcCkJCQorCQkgICAgeHNsdFJlc3RvcmVEb2N1bWVudE5hbWVzcGFjZXMoY2N0eHQtPnBzRGF0YS0+bnNNYXAsIGRvYyk7CisjZW5kaWYKKwkJLyoKKwkJKiBEZXRhY2ggdGhlIGRvYyBmcm9tIHRoZSBzdHlsZXNoZWV0OyBvdGhlcndpc2UgdGhlIGRvYworCQkqIHdpbGwgYmUgZnJlZWQgaW4geHNsdEZyZWVTdHlsZXNoZWV0KCkuCisJCSovCisJCXJldFN0eWxlLT5kb2MgPSBOVUxMOworCQkvKgorCQkqIENsZWFudXAgdGhlIGRvYyBpZiBpdHMgdGhlIG1haW4gc3R5bGVzaGVldC4KKwkJKi8KKwkJaWYgKHBhcmVudFN0eWxlID09IE5VTEwpIHsKKwkJICAgIHhzbHRDbGVhbnVwU3R5bGVzaGVldFRyZWUoZG9jLCB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpKTsKKwkJICAgIGlmIChyZXRTdHlsZS0+Y29tcEN0eHQgIT0gTlVMTCkgewkJCQorCQkJeHNsdENvbXBpbGF0aW9uQ3R4dEZyZWUocmV0U3R5bGUtPmNvbXBDdHh0KTsKKwkJCXJldFN0eWxlLT5jb21wQ3R4dCA9IE5VTEw7CisJCSAgICB9CisJCX0KKworCQl4c2x0RnJlZVN0eWxlc2hlZXQocmV0U3R5bGUpOworCQlyZXRTdHlsZSA9IE5VTEw7CisJICAgIH0KKwl9CisgICAgfQorICAgICAgICAKKyNlbHNlIC8qIFhTTFRfUkVGQUNUT1JFRCAqLworICAgIC8qCisgICAgKiBPbGQgYmVoYXZpb3VyLgorICAgICovCisgICAgcmV0U3R5bGUtPmRvYyA9IGRvYzsKKyAgICBpZiAoeHNsdFBhcnNlU3R5bGVzaGVldFByb2Nlc3MocmV0U3R5bGUsIGRvYykgPT0gTlVMTCkgeworCQlyZXRTdHlsZS0+ZG9jID0gTlVMTDsKKwkJeHNsdEZyZWVTdHlsZXNoZWV0KHJldFN0eWxlKTsKKwkJcmV0U3R5bGUgPSBOVUxMOworICAgIH0KKyAgICBpZiAocmV0U3R5bGUgIT0gTlVMTCkgeworCWlmIChyZXRTdHlsZS0+ZXJyb3JzICE9IDApIHsKKwkgICAgcmV0U3R5bGUtPmRvYyA9IE5VTEw7CisJICAgIGlmIChwYXJlbnRTdHlsZSA9PSBOVUxMKQorCQl4c2x0Q2xlYW51cFN0eWxlc2hlZXRUcmVlKGRvYywKKwkJICAgIHhtbERvY0dldFJvb3RFbGVtZW50KGRvYykpOworCSAgICB4c2x0RnJlZVN0eWxlc2hlZXQocmV0U3R5bGUpOworCSAgICByZXRTdHlsZSA9IE5VTEw7CisJfQorICAgIH0KKyNlbmRpZiAvKiBlbHNlIG9mIFhTTFRfUkVGQUNUT1JFRCAqLworICAgICAgICAKKyAgICByZXR1cm4ocmV0U3R5bGUpOworfQorCisvKioKKyAqIHhzbHRQYXJzZVN0eWxlc2hlZXREb2M6CisgKiBAZG9jOiAgYW5kIHhtbERvYyBwYXJzZWQgWE1MCisgKgorICogcGFyc2UgYW4gWFNMVCBzdHlsZXNoZWV0LCBidWlsZGluZyB0aGUgYXNzb2NpYXRlZCBzdHJ1Y3R1cmVzLiAgZG9jCisgKiBpcyBrZXB0IGFzIGEgcmVmZXJlbmNlIHdpdGhpbiB0aGUgcmV0dXJuZWQgc3R5bGVzaGVldCwgc28gY2hhbmdlcworICogdG8gZG9jIGFmdGVyIHRoZSBwYXJzaW5nIHdpbGwgYmUgcmVmbGVjdGVkIHdoZW4gdGhlIHN0eWxlc2hlZXQKKyAqIGlzIGFwcGxpZWQsIGFuZCB0aGUgZG9jIGlzIGF1dG9tYXRpY2FsbHkgZnJlZWQgd2hlbiB0aGUKKyAqIHN0eWxlc2hlZXQgaXMgY2xvc2VkLgorICoKKyAqIFJldHVybnMgYSBuZXcgWFNMVCBzdHlsZXNoZWV0IHN0cnVjdHVyZS4KKyAqLworCit4c2x0U3R5bGVzaGVldFB0cgoreHNsdFBhcnNlU3R5bGVzaGVldERvYyh4bWxEb2NQdHIgZG9jKSB7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgcmV0OworCisgICAgeHNsdEluaXRHbG9iYWxzKCk7CisKKyAgICByZXQgPSB4c2x0UGFyc2VTdHlsZXNoZWV0SW1wb3J0ZWREb2MoZG9jLCBOVUxMKTsKKyAgICBpZiAocmV0ID09IE5VTEwpCisJcmV0dXJuKE5VTEwpOworCisgICAgeHNsdFJlc29sdmVTdHlsZXNoZWV0QXR0cmlidXRlU2V0KHJldCk7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgLyoKKyAgICAqIEZyZWUgdGhlIGNvbXBpbGF0aW9uIGNvbnRleHQuCisgICAgKiBUT0RPOiBDaGVjayBpZiBpdCdzIGJldHRlciB0byBtb3ZlIHRoaXMgY2xlYW51cCB0bworICAgICogICB4c2x0UGFyc2VTdHlsZXNoZWV0SW1wb3J0ZWREb2MoKS4KKyAgICAqLworICAgIGlmIChyZXQtPmNvbXBDdHh0ICE9IE5VTEwpIHsKKwl4c2x0Q29tcGlsYXRpb25DdHh0RnJlZShYU0xUX0NDVFhUKHJldCkpOworCXJldC0+Y29tcEN0eHQgPSBOVUxMOworICAgIH0KKyNlbmRpZgorICAgIHJldHVybihyZXQpOworfQorCisvKioKKyAqIHhzbHRQYXJzZVN0eWxlc2hlZXRGaWxlOgorICogQGZpbGVuYW1lOiAgdGhlIGZpbGVuYW1lL1VSTCB0byB0aGUgc3R5bGVzaGVldAorICoKKyAqIExvYWQgYW5kIHBhcnNlIGFuIFhTTFQgc3R5bGVzaGVldAorICoKKyAqIFJldHVybnMgYSBuZXcgWFNMVCBzdHlsZXNoZWV0IHN0cnVjdHVyZS4KKyAqLworCit4c2x0U3R5bGVzaGVldFB0cgoreHNsdFBhcnNlU3R5bGVzaGVldEZpbGUoY29uc3QgeG1sQ2hhciogZmlsZW5hbWUpIHsKKyAgICB4c2x0U2VjdXJpdHlQcmVmc1B0ciBzZWM7CisgICAgeHNsdFN0eWxlc2hlZXRQdHIgcmV0OworICAgIHhtbERvY1B0ciBkb2M7CisgICAgCisgICAgeHNsdEluaXRHbG9iYWxzKCk7CisKKyAgICBpZiAoZmlsZW5hbWUgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJICAgICJ4c2x0UGFyc2VTdHlsZXNoZWV0RmlsZSA6IHBhcnNlICVzXG4iLCBmaWxlbmFtZSk7CisjZW5kaWYKKworICAgIC8qCisgICAgICogU2VjdXJpdHkgZnJhbWV3b3JrIGNoZWNrCisgICAgICovCisgICAgc2VjID0geHNsdEdldERlZmF1bHRTZWN1cml0eVByZWZzKCk7CisgICAgaWYgKHNlYyAhPSBOVUxMKSB7CisJaW50IHJlczsKKworCXJlcyA9IHhzbHRDaGVja1JlYWQoc2VjLCBOVUxMLCBmaWxlbmFtZSk7CisJaWYgKHJlcyA9PSAwKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkgInhzbHRQYXJzZVN0eWxlc2hlZXRGaWxlOiByZWFkIHJpZ2h0cyBmb3IgJXMgZGVuaWVkXG4iLAorCQkJICAgICBmaWxlbmFtZSk7CisJICAgIHJldHVybihOVUxMKTsKKwl9CisgICAgfQorCisgICAgZG9jID0geHNsdERvY0RlZmF1bHRMb2FkZXIoZmlsZW5hbWUsIE5VTEwsIFhTTFRfUEFSU0VfT1BUSU9OUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBYU0xUX0xPQURfU1RBUlQpOworICAgIGlmIChkb2MgPT0gTlVMTCkgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLAorCQkieHNsdFBhcnNlU3R5bGVzaGVldEZpbGUgOiBjYW5ub3QgcGFyc2UgJXNcbiIsIGZpbGVuYW1lKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorICAgIHJldCA9IHhzbHRQYXJzZVN0eWxlc2hlZXREb2MoZG9jKTsKKyAgICBpZiAocmV0ID09IE5VTEwpIHsKKwl4bWxGcmVlRG9jKGRvYyk7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKworICAgIHJldHVybihyZXQpOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqCQkJSGFuZGxpbmcgb2YgU3R5bGVzaGVldCBQSQkJCSoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworI2RlZmluZSBDVVIgKCpjdXIpCisjZGVmaW5lIFNLSVAodmFsKSBjdXIgKz0gKHZhbCkKKyNkZWZpbmUgTlhUKHZhbCkgY3VyWyh2YWwpXQorI2RlZmluZSBTS0lQX0JMQU5LUwkJCQkJCVwKKyAgICB3aGlsZSAoSVNfQkxBTksoQ1VSKSkgTkVYVAorI2RlZmluZSBORVhUICgoKmN1cikgPyAgY3VyKysgOiBjdXIpCisKKy8qKgorICogeHNsdFBhcnNlU3R5bGVzaGVldFBJOgorICogQHZhbHVlOiB0aGUgdmFsdWUgb2YgdGhlIFBJCisgKgorICogVGhpcyBmdW5jdGlvbiBjaGVja3MgdGhhdCB0aGUgdHlwZSBpcyB0ZXh0L3htbCBhbmQgZXh0cmFjdHMKKyAqIHRoZSBVUkktUmVmZXJlbmNlIGZvciB0aGUgc3R5bGVzaGVldAorICoKKyAqIFJldHVybnMgdGhlIFVSSS1SZWZlcmVuY2UgZm9yIHRoZSBzdHlsZXNoZWV0IG9yIE5VTEwgKGl0IG5lZWQgdG8KKyAqICAgICAgICAgYmUgZnJlZWQgYnkgdGhlIGNhbGxlcikKKyAqLworc3RhdGljIHhtbENoYXIgKgoreHNsdFBhcnNlU3R5bGVzaGVldFBJKGNvbnN0IHhtbENoYXIgKnZhbHVlKSB7CisgICAgY29uc3QgeG1sQ2hhciAqY3VyOworICAgIGNvbnN0IHhtbENoYXIgKnN0YXJ0OworICAgIHhtbENoYXIgKnZhbDsKKyAgICB4bWxDaGFyIHRtcDsKKyAgICB4bWxDaGFyICpocmVmID0gTlVMTDsKKyAgICBpbnQgaXNYbWwgPSAwOworCisgICAgaWYgKHZhbHVlID09IE5VTEwpCisJcmV0dXJuKE5VTEwpOworCisgICAgY3VyID0gdmFsdWU7CisgICAgd2hpbGUgKENVUiAhPSAwKSB7CisJU0tJUF9CTEFOS1M7CisJaWYgKChDVVIgPT0gJ3QnKSAmJiAoTlhUKDEpID09ICd5JykgJiYgKE5YVCgyKSA9PSAncCcpICYmCisJICAgIChOWFQoMykgPT0gJ2UnKSkgeworCSAgICBTS0lQKDQpOworCSAgICBTS0lQX0JMQU5LUzsKKwkgICAgaWYgKENVUiAhPSAnPScpCisJCWNvbnRpbnVlOworCSAgICBORVhUOworCSAgICBpZiAoKENVUiAhPSAnXCcnKSAmJiAoQ1VSICE9ICciJykpCisJCWNvbnRpbnVlOworCSAgICB0bXAgPSBDVVI7CisJICAgIE5FWFQ7CisJICAgIHN0YXJ0ID0gY3VyOworCSAgICB3aGlsZSAoKENVUiAhPSAwKSAmJiAoQ1VSICE9IHRtcCkpCisJCU5FWFQ7CisJICAgIGlmIChDVVIgIT0gdG1wKQorCQljb250aW51ZTsKKwkgICAgdmFsID0geG1sU3RybmR1cChzdGFydCwgY3VyIC0gc3RhcnQpOworCSAgICBORVhUOworCSAgICBpZiAodmFsID09IE5VTEwpIAorCQlyZXR1cm4oTlVMTCk7CisJICAgIGlmICgoeG1sU3RyY2FzZWNtcCh2YWwsIEJBRF9DQVNUICJ0ZXh0L3htbCIpKSAmJgorCQkoeG1sU3RyY2FzZWNtcCh2YWwsIEJBRF9DQVNUICJ0ZXh0L3hzbCIpKSkgeworICAgICAgICAgICAgICAgIHhtbEZyZWUodmFsKTsKKwkJYnJlYWs7CisJICAgIH0KKwkgICAgaXNYbWwgPSAxOworCSAgICB4bWxGcmVlKHZhbCk7CisJfSBlbHNlIGlmICgoQ1VSID09ICdoJykgJiYgKE5YVCgxKSA9PSAncicpICYmIChOWFQoMikgPT0gJ2UnKSAmJgorCSAgICAoTlhUKDMpID09ICdmJykpIHsKKwkgICAgU0tJUCg0KTsKKwkgICAgU0tJUF9CTEFOS1M7CisJICAgIGlmIChDVVIgIT0gJz0nKQorCQljb250aW51ZTsKKwkgICAgTkVYVDsKKwkgICAgaWYgKChDVVIgIT0gJ1wnJykgJiYgKENVUiAhPSAnIicpKQorCQljb250aW51ZTsKKwkgICAgdG1wID0gQ1VSOworCSAgICBORVhUOworCSAgICBzdGFydCA9IGN1cjsKKwkgICAgd2hpbGUgKChDVVIgIT0gMCkgJiYgKENVUiAhPSB0bXApKQorCQlORVhUOworCSAgICBpZiAoQ1VSICE9IHRtcCkKKwkJY29udGludWU7CisJICAgIGlmIChocmVmID09IE5VTEwpCisJCWhyZWYgPSB4bWxTdHJuZHVwKHN0YXJ0LCBjdXIgLSBzdGFydCk7CisJICAgIE5FWFQ7CisJfSBlbHNlIHsKKwkgICAgd2hpbGUgKChDVVIgIT0gMCkgJiYgKCFJU19CTEFOSyhDVVIpKSkKKwkJTkVYVDsKKwl9CisgICAgICAgICAgICAKKyAgICB9CisKKyAgICBpZiAoIWlzWG1sKSB7CisJaWYgKGhyZWYgIT0gTlVMTCkKKwkgICAgeG1sRnJlZShocmVmKTsKKwlocmVmID0gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuKGhyZWYpOworfQorCisvKioKKyAqIHhzbHRMb2FkU3R5bGVzaGVldFBJOgorICogQGRvYzogIGEgZG9jdW1lbnQgdG8gcHJvY2VzcworICoKKyAqIFRoaXMgZnVuY3Rpb24gdHJpZXMgdG8gbG9jYXRlIHRoZSBzdHlsZXNoZWV0IFBJIGluIHRoZSBnaXZlbiBkb2N1bWVudAorICogSWYgZm91bmQsIGFuZCBpZiBjb250YWluZWQgd2l0aGluIHRoZSBkb2N1bWVudCwgaXQgd2lsbCBleHRyYWN0IAorICogdGhhdCBzdWJ0cmVlIHRvIGJ1aWxkIHRoZSBzdHlsZXNoZWV0IHRvIHByb2Nlc3MgQGRvYyAoZG9jIGl0c2VsZiB3aWxsCisgKiBiZSBtb2RpZmllZCkuIElmIGZvdW5kIGJ1dCByZWZlcmVuY2luZyBhbiBleHRlcm5hbCBkb2N1bWVudCBpdCB3aWxsCisgKiBhdHRlbXB0IHRvIGxvYWQgaXQgYW5kIGdlbmVyYXRlIGEgc3R5bGVzaGVldCBmcm9tIGl0LiBJbiBib3RoIGNhc2VzLAorICogdGhlIHJlc3VsdGluZyBzdHlsZXNoZWV0IGFuZCB0aGUgZG9jdW1lbnQgbmVlZCB0byBiZSBmcmVlZCBvbmNlIHRoZQorICogdHJhbnNmb3JtYXRpb24gaXMgZG9uZS4KKyAqCisgKiBSZXR1cm5zIGEgbmV3IFhTTFQgc3R5bGVzaGVldCBzdHJ1Y3R1cmUgb3IgTlVMTCBpZiBub3QgZm91bmQuCisgKi8KK3hzbHRTdHlsZXNoZWV0UHRyCit4c2x0TG9hZFN0eWxlc2hlZXRQSSh4bWxEb2NQdHIgZG9jKSB7CisgICAgeG1sTm9kZVB0ciBjaGlsZDsKKyAgICB4c2x0U3R5bGVzaGVldFB0ciByZXQgPSBOVUxMOworICAgIHhtbENoYXIgKmhyZWYgPSBOVUxMOworICAgIHhtbFVSSVB0ciBVUkk7CisKKyAgICB4c2x0SW5pdEdsb2JhbHMoKTsKKworICAgIGlmIChkb2MgPT0gTlVMTCkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICAvKgorICAgICAqIEZpbmQgdGhlIHRleHQveG1sIHN0eWxlc2hlZXQgUEkgaWQgYW55IGJlZm9yZSB0aGUgcm9vdAorICAgICAqLworICAgIGNoaWxkID0gZG9jLT5jaGlsZHJlbjsKKyAgICB3aGlsZSAoKGNoaWxkICE9IE5VTEwpICYmIChjaGlsZC0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSkgeworCWlmICgoY2hpbGQtPnR5cGUgPT0gWE1MX1BJX05PREUpICYmCisJICAgICh4bWxTdHJFcXVhbChjaGlsZC0+bmFtZSwgQkFEX0NBU1QgInhtbC1zdHlsZXNoZWV0IikpKSB7CisJICAgIGhyZWYgPSB4c2x0UGFyc2VTdHlsZXNoZWV0UEkoY2hpbGQtPmNvbnRlbnQpOworCSAgICBpZiAoaHJlZiAhPSBOVUxMKQorCQlicmVhazsKKwl9CisJY2hpbGQgPSBjaGlsZC0+bmV4dDsKKyAgICB9CisKKyAgICAvKgorICAgICAqIElmIGZvdW5kIGNoZWNrIHRoZSBocmVmIHRvIHNlbGVjdCBwcm9jZXNzaW5nCisgICAgICovCisgICAgaWYgKGhyZWYgIT0gTlVMTCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJInhzbHRMb2FkU3R5bGVzaGVldFBJIDogZm91bmQgUEkgaHJlZj0lc1xuIiwgaHJlZik7CisjZW5kaWYKKwlVUkkgPSB4bWxQYXJzZVVSSSgoY29uc3QgY2hhciAqKSBocmVmKTsKKwlpZiAoVVJJID09IE5VTEwpIHsKKwkgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIGNoaWxkLAorCQkgICAgInhtbC1zdHlsZXNoZWV0IDogaHJlZiAlcyBpcyBub3QgdmFsaWRcbiIsIGhyZWYpOworCSAgICB4bWxGcmVlKGhyZWYpOworCSAgICByZXR1cm4oTlVMTCk7CisJfQorCWlmICgoVVJJLT5mcmFnbWVudCAhPSBOVUxMKSAmJiAoVVJJLT5zY2hlbWUgPT0gTlVMTCkgJiYKKyAgICAgICAgICAgIChVUkktPm9wYXF1ZSA9PSBOVUxMKSAmJiAoVVJJLT5hdXRob3JpdHkgPT0gTlVMTCkgJiYKKyAgICAgICAgICAgIChVUkktPnNlcnZlciA9PSBOVUxMKSAmJiAoVVJJLT51c2VyID09IE5VTEwpICYmCisgICAgICAgICAgICAoVVJJLT5wYXRoID09IE5VTEwpICYmIChVUkktPnF1ZXJ5ID09IE5VTEwpKSB7CisJICAgIHhtbEF0dHJQdHIgSUQ7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUEFSU0lORworCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkgICAgInhzbHRMb2FkU3R5bGVzaGVldFBJIDogUmVmZXJlbmNlIHRvIElEICVzXG4iLCBocmVmKTsKKyNlbmRpZgorCSAgICBpZiAoVVJJLT5mcmFnbWVudFswXSA9PSAnIycpCisJCUlEID0geG1sR2V0SUQoZG9jLCAoY29uc3QgeG1sQ2hhciAqKSAmKFVSSS0+ZnJhZ21lbnRbMV0pKTsKKwkgICAgZWxzZQorCQlJRCA9IHhtbEdldElEKGRvYywgKGNvbnN0IHhtbENoYXIgKikgVVJJLT5mcmFnbWVudCk7CisJICAgIGlmIChJRCA9PSBOVUxMKSB7CisJCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBjaGlsZCwKKwkJICAgICJ4bWwtc3R5bGVzaGVldCA6IG5vIElEICVzIGZvdW5kXG4iLCBVUkktPmZyYWdtZW50KTsKKwkgICAgfSBlbHNlIHsKKwkJeG1sRG9jUHRyIGZha2U7CisJCXhtbE5vZGVQdHIgc3VidHJlZSwgbmV3dHJlZTsKKwkJeG1sTnNQdHIgbnM7CisKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKwkJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJICAgICJjcmVhdGluZyBuZXcgZG9jdW1lbnQgZnJvbSAlcyBmb3IgZW1iZWRkZWQgc3R5bGVzaGVldFxuIiwKKwkJICAgIGRvYy0+VVJMKTsKKyNlbmRpZgorCQkvKgorCQkgKiBtb3ZlIHRoZSBzdWJ0cmVlIGluIGEgbmV3IGRvY3VtZW50IHBhc3NlZCB0bworCQkgKiB0aGUgc3R5bGVzaGVldCBhbmFseXplcgorCQkgKi8KKwkJc3VidHJlZSA9IElELT5wYXJlbnQ7CisJCWZha2UgPSB4bWxOZXdEb2MoTlVMTCk7CisJCWlmIChmYWtlICE9IE5VTEwpIHsKKwkJICAgIC8qCisJCSAgICAqIFNob3VsZCB0aGUgZGljdGlvbmFyeSBzdGlsbCBiZSBzaGFyZWQgZXZlbiB0aG91Z2gKKwkJICAgICogdGhlIG5vZGVzIGFyZSBiZWluZyBjb3BpZWQgcmF0aGVyIHRoYW4gbW92ZWQ/CisJCSAgICAqLworCQkgICAgZmFrZS0+ZGljdCA9IGRvYy0+ZGljdDsKKwkJICAgIHhtbERpY3RSZWZlcmVuY2UoZG9jLT5kaWN0KTsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUcKKwkJICAgIHhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkicmV1c2luZyBkaWN0aW9uYXJ5IGZyb20gJXMgZm9yIGVtYmVkZGVkIHN0eWxlc2hlZXRcbiIsCisJCQlkb2MtPlVSTCk7CisjZW5kaWYKKworCQkgICAgbmV3dHJlZSA9IHhtbERvY0NvcHlOb2RlKHN1YnRyZWUsIGZha2UsIDEpOworCisJCSAgICBmYWtlLT5VUkwgPSB4bWxOb2RlR2V0QmFzZShkb2MsIHN1YnRyZWUtPnBhcmVudCk7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHCisJCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJInNldCBiYXNlIFVSSSBmb3IgZW1iZWRkZWQgc3R5bGVzaGVldCBhcyAlc1xuIiwKKwkJCWZha2UtPlVSTCk7CisjZW5kaWYKKworCQkgICAgLyoKKwkJICAgICogQWRkIGFsbCBuYW1lc3BhY2VzIGluIHNjb3BlIG9mIGVtYmVkZGVkIHN0eWxlc2hlZXQgdG8KKwkJICAgICogcm9vdCBlbGVtZW50IG9mIG5ld2x5IGNyZWF0ZWQgc3R5bGVzaGVldCBkb2N1bWVudAorCQkgICAgKi8KKwkJICAgIHdoaWxlICgoc3VidHJlZSA9IHN1YnRyZWUtPnBhcmVudCkgIT0gKHhtbE5vZGVQdHIpZG9jKSB7CisJCQlmb3IgKG5zID0gc3VidHJlZS0+bnM7IG5zOyBucyA9IG5zLT5uZXh0KSB7CisJCQkgICAgeG1sTmV3TnMobmV3dHJlZSwgIG5zLT5ocmVmLCBucy0+cHJlZml4KTsKKwkJCX0KKwkJICAgIH0KKworCQkgICAgeG1sQWRkQ2hpbGQoKHhtbE5vZGVQdHIpZmFrZSwgbmV3dHJlZSk7CisJCSAgICByZXQgPSB4c2x0UGFyc2VTdHlsZXNoZWV0RG9jKGZha2UpOworCQkgICAgaWYgKHJldCA9PSBOVUxMKQorCQkJeG1sRnJlZURvYyhmYWtlKTsKKwkJfQorCSAgICB9CisJfSBlbHNlIHsKKwkgICAgeG1sQ2hhciAqVVJMLCAqYmFzZTsKKworCSAgICAvKgorCSAgICAgKiBSZWZlcmVuY2UgdG8gYW4gZXh0ZXJuYWwgc3R5bGVzaGVldAorCSAgICAgKi8KKworCSAgICBiYXNlID0geG1sTm9kZUdldEJhc2UoZG9jLCAoeG1sTm9kZVB0cikgZG9jKTsKKwkgICAgVVJMID0geG1sQnVpbGRVUkkoaHJlZiwgYmFzZSk7CisJICAgIGlmIChVUkwgIT0gTlVMTCkgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QQVJTSU5HCisJCXhzbHRHZW5lcmljRGVidWcoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsCisJCQkieHNsdExvYWRTdHlsZXNoZWV0UEkgOiBmZXRjaGluZyAlc1xuIiwgVVJMKTsKKyNlbmRpZgorCQlyZXQgPSB4c2x0UGFyc2VTdHlsZXNoZWV0RmlsZShVUkwpOworCQl4bWxGcmVlKFVSTCk7CisJICAgIH0gZWxzZSB7CisjaWZkZWYgV0lUSF9YU0xUX0RFQlVHX1BBUlNJTkcKKwkJeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSJ4c2x0TG9hZFN0eWxlc2hlZXRQSSA6IGZldGNoaW5nICVzXG4iLCBocmVmKTsKKyNlbmRpZgorCQlyZXQgPSB4c2x0UGFyc2VTdHlsZXNoZWV0RmlsZShocmVmKTsKKwkgICAgfQorCSAgICBpZiAoYmFzZSAhPSBOVUxMKQorCQl4bWxGcmVlKGJhc2UpOworCX0KKwl4bWxGcmVlVVJJKFVSSSk7CisJeG1sRnJlZShocmVmKTsKKyAgICB9CisgICAgcmV0dXJuKHJldCk7Cit9CmRpZmYgLS1naXQgYS9saWJ4c2x0L3hzbHQuaCBiL2xpYnhzbHQveHNsdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg0OWIwM2MKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L3hzbHQuaApAQCAtMCwwICsxLDEwMyBAQAorLyoKKyAqIFN1bW1hcnk6IEludGVyZmFjZXMsIGNvbnN0YW50cyBhbmQgdHlwZXMgcmVsYXRlZCB0byB0aGUgWFNMVCBlbmdpbmUKKyAqIERlc2NyaXB0aW9uOiBJbnRlcmZhY2VzLCBjb25zdGFudHMgYW5kIHR5cGVzIHJlbGF0ZWQgdG8gdGhlIFhTTFQgZW5naW5lCisgKgorICogQ29weTogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIEF1dGhvcjogRGFuaWVsIFZlaWxsYXJkCisgKi8KKworI2lmbmRlZiBfX1hNTF9YU0xUX0hfXworI2RlZmluZSBfX1hNTF9YU0xUX0hfXworCisjaW5jbHVkZSA8bGlieG1sL3RyZWUuaD4KKyNpbmNsdWRlICJ4c2x0ZXhwb3J0cy5oIgorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qKgorICogWFNMVF9ERUZBVUxUX1ZFUlNJT046CisgKgorICogVGhlIGRlZmF1bHQgdmVyc2lvbiBvZiBYU0xUIHN1cHBvcnRlZC4KKyAqLworI2RlZmluZSBYU0xUX0RFRkFVTFRfVkVSU0lPTiAgICAgIjEuMCIKKworLyoqCisgKiBYU0xUX0RFRkFVTFRfVkVORE9SOgorICoKKyAqIFRoZSBYU0xUICJ2ZW5kb3IiIHN0cmluZyBmb3IgdGhpcyBwcm9jZXNzb3IuCisgKi8KKyNkZWZpbmUgWFNMVF9ERUZBVUxUX1ZFTkRPUiAgICAgICJsaWJ4c2x0IgorCisvKioKKyAqIFhTTFRfREVGQVVMVF9VUkw6CisgKgorICogVGhlIFhTTFQgInZlbmRvciIgVVJMIGZvciB0aGlzIHByb2Nlc3Nvci4KKyAqLworI2RlZmluZSBYU0xUX0RFRkFVTFRfVVJMICAgICAgICAgImh0dHA6Ly94bWxzb2Z0Lm9yZy9YU0xULyIKKworLyoqCisgKiBYU0xUX05BTUVTUEFDRToKKyAqCisgKiBUaGUgWFNMVCBzcGVjaWZpY2F0aW9uIG5hbWVzcGFjZS4KKyAqLworI2RlZmluZSBYU0xUX05BTUVTUEFDRSAoKHhtbENoYXIgKikgImh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFNML1RyYW5zZm9ybSIpCisKKy8qKgorICogWFNMVF9QQVJTRV9PUFRJT05TOgorICoKKyAqIFRoZSBzZXQgb2Ygb3B0aW9ucyB0byBwYXNzIHRvIGFuIHhtbFJlYWR4eHggd2hlbiBsb2FkaW5nIGZpbGVzIGZvcgorICogWFNMVCBjb25zdW1wdGlvbi4KKyAqLworI2RlZmluZSBYU0xUX1BBUlNFX09QVElPTlMgXAorIFhNTF9QQVJTRV9OT0VOVCB8IFhNTF9QQVJTRV9EVERMT0FEIHwgWE1MX1BBUlNFX0RUREFUVFIgfCBYTUxfUEFSU0VfTk9DREFUQQorCisvKioKKyAqIHhzbHRNYXhEZXB0aDoKKyAqCisgKiBUaGlzIHZhbHVlIGlzIHVzZWQgdG8gZGV0ZWN0IHRlbXBsYXRlcyBsb29wcy4KKyAqLworWFNMVFBVQlZBUiBpbnQgeHNsdE1heERlcHRoOworCisvKioKKyAqIHhzbHRFbmdpbmVWZXJzaW9uOgorICoKKyAqIFRoZSB2ZXJzaW9uIHN0cmluZyBmb3IgbGlieHNsdC4KKyAqLworWFNMVFBVQlZBUiBjb25zdCBjaGFyICp4c2x0RW5naW5lVmVyc2lvbjsKKworLyoqCisgKiB4c2x0TGlieHNsdFZlcnNpb246CisgKgorICogVGhlIHZlcnNpb24gb2YgbGlieHNsdCBjb21waWxlZC4KKyAqLworWFNMVFBVQlZBUiBjb25zdCBpbnQgeHNsdExpYnhzbHRWZXJzaW9uOworCisvKioKKyAqIHhzbHRMaWJ4bWxWZXJzaW9uOgorICoKKyAqIFRoZSB2ZXJzaW9uIG9mIGxpYnhtbCBsaWJ4c2x0IHdhcyBjb21waWxlZCBhZ2FpbnN0LgorICovCitYU0xUUFVCVkFSIGNvbnN0IGludCB4c2x0TGlieG1sVmVyc2lvbjsKKworLyoKKyAqIEdsb2JhbCBpbml0aWFsaXphdGlvbiBmdW5jdGlvbi4KKyAqLworCitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJeHNsdEluaXQJCSh2b2lkKTsKKworLyoKKyAqIEdsb2JhbCBjbGVhbnVwIGZ1bmN0aW9uLgorICovCitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCisJCXhzbHRDbGVhbnVwR2xvYmFscwkodm9pZCk7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX0hfXyAqLworCmRpZmYgLS1naXQgYS9saWJ4c2x0L3hzbHRJbnRlcm5hbHMuaCBiL2xpYnhzbHQveHNsdEludGVybmFscy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5OTFhOTMKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L3hzbHRJbnRlcm5hbHMuaApAQCAtMCwwICsxLDE5NjcgQEAKKy8qCisgKiBTdW1tYXJ5OiBpbnRlcm5hbCBkYXRhIHN0cnVjdHVyZXMsIGNvbnN0YW50cyBhbmQgZnVuY3Rpb25zCisgKiBEZXNjcmlwdGlvbjogSW50ZXJuYWwgZGF0YSBzdHJ1Y3R1cmVzLCBjb25zdGFudHMgYW5kIGZ1bmN0aW9ucyB1c2VkCisgKiAgICAgICAgICAgICAgYnkgdGhlIFhTTFQgZW5naW5lLiAKKyAqICAgICAgICAgICAgICBUaGV5IGFyZSBub3QgcGFydCBvZiB0aGUgQVBJIG9yIEFCSSwgaS5lLiB0aGV5IGNhbiBjaGFuZ2UKKyAqICAgICAgICAgICAgICB3aXRob3V0IHByaW9yIG5vdGljZSwgdXNlIGNhcmVmdWxseS4KKyAqCisgKiBDb3B5OiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCisgKgorICogQXV0aG9yOiBEYW5pZWwgVmVpbGxhcmQKKyAqLworCisjaWZuZGVmIF9fWE1MX1hTTFRfSU5URVJOQUxTX0hfXworI2RlZmluZSBfX1hNTF9YU0xUX0lOVEVSTkFMU19IX18KKworI2luY2x1ZGUgPGxpYnhtbC90cmVlLmg+CisjaW5jbHVkZSA8bGlieG1sL2hhc2guaD4KKyNpbmNsdWRlIDxsaWJ4bWwveHBhdGguaD4KKyNpbmNsdWRlIDxsaWJ4bWwveG1sZXJyb3IuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvZGljdC5oPgorI2luY2x1ZGUgPGxpYnhtbC94bWxzdHJpbmcuaD4KKyNpbmNsdWRlIDxsaWJ4c2x0L3hzbHQuaD4KKyNpbmNsdWRlICJ4c2x0ZXhwb3J0cy5oIgorI2luY2x1ZGUgInhzbHRsb2NhbGUuaCIKKyNpbmNsdWRlICJudW1iZXJzSW50ZXJuYWxzLmgiCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyogI2RlZmluZSBYU0xUX0RFQlVHX1BST0ZJTEVfQ0FDSEUgKi8KKworLyoqCisgKiBYU0xUX0lTX1RFWFRfTk9ERToKKyAqCisgKiBjaGVjayBpZiB0aGUgYXJndW1lbnQgaXMgYSB0ZXh0IG5vZGUKKyAqLworI2RlZmluZSBYU0xUX0lTX1RFWFRfTk9ERShuKSAoKG4gIT0gTlVMTCkgJiYgXAorICAgICgoKG4pLT50eXBlID09IFhNTF9URVhUX05PREUpIHx8IFwKKyAgICAgKChuKS0+dHlwZSA9PSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkpCisKKworLyoqCisgKiBYU0xUX01BUktfUkVTX1RSRUVfRlJBRzoKKyAqCisgKiBpbnRlcm5hbCBtYWNybyB0byBzZXQgdXAgdHJlZSBmcmFnbWVudHMKKyAqLworI2RlZmluZSBYU0xUX01BUktfUkVTX1RSRUVfRlJBRyhuKSBcCisgICAgKG4pLT5uYW1lID0gKGNoYXIgKikgeG1sU3RyZHVwKEJBRF9DQVNUICIgZmFrZSBub2RlIGxpYnhzbHQiKTsKKworLyoqCisgKiBYU0xUX0lTX1JFU19UUkVFX0ZSQUc6CisgKgorICogaW50ZXJuYWwgbWFjcm8gdG8gdGVzdCB0cmVlIGZyYWdtZW50cworICovCisjZGVmaW5lIFhTTFRfSVNfUkVTX1RSRUVfRlJBRyhuKSBcCisgICAgKChuICE9IE5VTEwpICYmICgobiktPnR5cGUgPT0gWE1MX0RPQ1VNRU5UX05PREUpICYmIFwKKyAgICAgKChuKS0+bmFtZSAhPSBOVUxMKSAmJiAoKG4pLT5uYW1lWzBdID09ICcgJykpCisKKy8qKgorICogWFNMVF9SRUZBQ1RPUkVEX0tFWUNPTVA6CisgKgorICogSW50ZXJuYWwgZGVmaW5lIHRvIGVuYWJsZSBvbi1kZW1hbmQgeHNsOmtleSBjb21wdXRhdGlvbi4KKyAqIFRoYXQncyB0aGUgb25seSBtb2RlIG5vdyBidXQgdGhlIGRlZmluZSBpcyBrZXB0IGZvciBjb21wYXRpYmlsaXR5CisgKi8KKyNkZWZpbmUgWFNMVF9SRUZBQ1RPUkVEX0tFWUNPTVAKKworLyoqCisgKiBYU0xUX0ZBU1RfSUY6CisgKgorICogSW50ZXJuYWwgZGVmaW5lIHRvIGVuYWJsZSB1c2FnZSBvZiB4bWxYUGF0aENvbXBpbGVkRXZhbFRvQm9vbGVhbigpCisgKiBmb3IgWFNMVCAidGVzdHMiOyBlLmcuIGluIDx4c2w6aWYgdGVzdD0iL2Zvby9iYXIiPgorICovCisjZGVmaW5lIFhTTFRfRkFTVF9JRgorCisvKioKKyAqIFhTTFRfUkVGQUNUT1JFRDoKKyAqCisgKiBJbnRlcm5hbCBkZWZpbmUgdG8gZW5hYmxlIHRoZSByZWZhY3RvcmVkIHBhcnRzIG9mIExpYnhzbHQuCisgKi8KKy8qICNkZWZpbmUgWFNMVF9SRUZBQ1RPUkVEICovCisvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLworCisvKioKKyAqIFhTTFRfUkVGQUNUT1JFRF9WQVJTOgorICoKKyAqIEludGVybmFsIGRlZmluZSB0byBlbmFibGUgdGhlIHJlZmFjdG9yZWQgdmFyaWFibGUgcGFydCBvZiBsaWJ4c2x0CisgKi8KKyNkZWZpbmUgWFNMVF9SRUZBQ1RPUkVEX1ZBUlMKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorCitleHRlcm4gY29uc3QgeG1sQ2hhciAqeHNsdFhTTFRBdHRyTWFya2VyOworCisKKy8qIFRPRE86IFJFTU9WRTogI2RlZmluZSBYU0xUX1JFRkFDVE9SRURfRVhDTFJFU05TICovCisKKy8qIFRPRE86IFJFTU9WRTogI2RlZmluZSBYU0xUX1JFRkFDVE9SRURfTlNBTElBUyAqLworCisvKioKKyAqIFhTTFRfUkVGQUNUT1JFRF9YU0xUX05TQ09NUAorICoKKyAqIEludGVybmFsIGRlZmluZSB0byBlbmFibGUgdGhlIHBvaW50ZXItY29tcGFyaXNvbiBvZgorICogbmFtZXNwYWNlcyBvZiBYU0xUIGVsZW1lbnRzLiAKKyAqLworLyogI2RlZmluZSBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAgKi8KKworLyoqCisgKiBYU0xUX1JFRkFDVE9SRURfWFBBVEhDT01QOgorICoKKyAqIEludGVybmFsIGRlZmluZSB0byBlbmFibGUgdGhlIG9wdGltaXphdGlvbiBvZiB0aGUKKyAqIGNvbXBpbGF0aW9uIG9mIFhQYXRoIGV4cHJlc3Npb25zLgorICovCisjZGVmaW5lIFhTTFRfUkVGQUNUT1JFRF9YUEFUSENPTVAKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRF9YU0xUX05TQ09NUAorCitleHRlcm4gY29uc3QgeG1sQ2hhciAqeHNsdENvbnN0TmFtZXNwYWNlTmFtZVhTTFQ7CisKKy8qKgorICogSVNfWFNMVF9FTEVNX0ZBU1Q6CisgKgorICogcXVpY2sgdGVzdCB0byBkZXRlY3QgWFNMVCBlbGVtZW50cworICovCisjZGVmaW5lIElTX1hTTFRfRUxFTV9GQVNUKG4pIFwKKyAgICAoKChuKSAhPSBOVUxMKSAmJiAoKG4pLT5ucyAhPSBOVUxMKSAmJiBcCisgICAgKChuKS0+bnMtPmhyZWYgPT0geHNsdENvbnN0TmFtZXNwYWNlTmFtZVhTTFQpKQorCisvKioKKyAqIElTX1hTTFRfQVRUUl9GQVNUOgorICoKKyAqIHF1aWNrIHRlc3QgdG8gZGV0ZWN0IFhTTFQgYXR0cmlidXRlcworICovCisjZGVmaW5lIElTX1hTTFRfQVRUUl9GQVNUKGEpIFwKKyAgICAoKChhKSAhPSBOVUxMKSAmJiAoKGEpLT5ucyAhPSBOVUxMKSAmJiBcCisgICAgKChhKS0+bnMtPmhyZWYgPT0geHNsdENvbnN0TmFtZXNwYWNlTmFtZVhTTFQpKQorCisvKioKKyAqIFhTTFRfSEFTX0lOVEVSTkFMX05TTUFQOgorICoKKyAqIGNoZWNrIGZvciBuYW1lc3BhY2UgbWFwcGluZworICovCisjZGVmaW5lIFhTTFRfSEFTX0lOVEVSTkFMX05TTUFQKHMpIFwKKyAgICAoKChzKSAhPSBOVUxMKSAmJiAoKHMpLT5wcmluY2lwYWwpICYmIFwKKyAgICAgKChzKS0+cHJpbmNpcGFsLT5wcmluY2lwYWxEYXRhKSAmJiBcCisgICAgICgocyktPnByaW5jaXBhbC0+cHJpbmNpcGFsRGF0YS0+bnNNYXApKQorCisvKioKKyAqIFhTTFRfR0VUX0lOVEVSTkFMX05TTUFQOgorICoKKyAqIGdldCBwb2ludGVyIHRvIG5hbWVzcGFjZSBtYXAKKyAqLworI2RlZmluZSBYU0xUX0dFVF9JTlRFUk5BTF9OU01BUChzKSAoKHMpLT5wcmluY2lwYWwtPnByaW5jaXBhbERhdGEtPm5zTWFwKQorCisjZWxzZSAvKiBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAgKi8KKworLyoqCisgKiBJU19YU0xUX0VMRU1fRkFTVDoKKyAqCisgKiBxdWljayBjaGVjayB3aGV0aGVyIHRoaXMgaXMgYW4geHNsdCBlbGVtZW50CisgKi8KKyNkZWZpbmUgSVNfWFNMVF9FTEVNX0ZBU1QobikgXAorICAgICgoKG4pICE9IE5VTEwpICYmICgobiktPm5zICE9IE5VTEwpICYmIFwKKyAgICAgKHhtbFN0ckVxdWFsKChuKS0+bnMtPmhyZWYsIFhTTFRfTkFNRVNQQUNFKSkpCisKKy8qKgorICogSVNfWFNMVF9BVFRSX0ZBU1Q6CisgKgorICogcXVpY2sgY2hlY2sgZm9yIHhzbHQgbmFtZXNwYWNlIGF0dHJpYnV0ZQorICovCisjZGVmaW5lIElTX1hTTFRfQVRUUl9GQVNUKGEpIFwKKyAgICAoKChhKSAhPSBOVUxMKSAmJiAoKGEpLT5ucyAhPSBOVUxMKSAmJiBcCisgICAgICh4bWxTdHJFcXVhbCgoYSktPm5zLT5ocmVmLCBYU0xUX05BTUVTUEFDRSkpKQorCisKKyNlbmRpZiAvKiBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAgKi8KKworCisvKioKKyAqIFhTTFRfUkVGQUNUT1JFRF9NQU5EQVRPUllfVkVSU0lPTjoKKyAqCisgKiBUT0RPOiBDdXJyZW50bHkgZGlzYWJsZWQgdG8gc3VycHJlc3MgcmVncmVzc2lvbiB0ZXN0IGZhaWx1cmVzLCBzaW5jZQorICogIHRoZSBvbGQgYmVoYXZpb3VyIHdhcyB0aGF0IGEgbWlzc2luZyB2ZXJzaW9uIGF0dHJpYnV0ZQorICogIHByb2R1Y2VkIGEgb25seSBhIHdhcm5pbmcgYW5kIG5vdCBhbiBlcnJvciwgd2hpY2ggd2FzIGluY2VycmVjdC4KKyAqICBTbyB0aGUgcmVncmVzc2lvbiB0ZXN0cyBuZWVkIHRvIGJlIGZpeGVkIGlmIHRoaXMgaXMgZW5hYmxlZC4KKyAqLworLyogI2RlZmluZSBYU0xUX1JFRkFDVE9SRURfTUFOREFUT1JZX1ZFUlNJT04gKi8KKworLyoqCisgKiB4c2x0UG9pbnRlckxpc3Q6CisgKgorICogUG9pbnRlci1saXN0IGZvciB2YXJpb3VzIHB1cnBvc2VzLgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFBvaW50ZXJMaXN0IHhzbHRQb2ludGVyTGlzdDsKK3R5cGVkZWYgeHNsdFBvaW50ZXJMaXN0ICp4c2x0UG9pbnRlckxpc3RQdHI7CitzdHJ1Y3QgX3hzbHRQb2ludGVyTGlzdCB7CisgICAgdm9pZCAqKml0ZW1zOworICAgIGludCBudW1iZXI7CisgICAgaW50IHNpemU7Cit9OworCisjZW5kaWYKKworLyoqCisgKiBYU0xUX1JFRkFDVE9SRURfUEFSU0lORzoKKyAqCisgKiBJbnRlcm5hbCBkZWZpbmUgdG8gZW5hYmxlIHRoZSByZWZhY3RvcmVkIHBhcnRzIG9mIExpYnhzbHQKKyAqIHJlbGF0ZWQgdG8gcGFyc2luZy4KKyAqLworLyogI2RlZmluZSBYU0xUX1JFRkFDVE9SRURfUEFSU0lORyAqLworCisvKioKKyAqIFhTTFRfTUFYX1NPUlQ6CisgKgorICogTWF4IG51bWJlciBvZiBzcGVjaWZpZWQgeHNsOnNvcnQgb24gYW4gZWxlbWVudC4KKyAqLworI2RlZmluZSBYU0xUX01BWF9TT1JUIDE1CisKKy8qKgorICogWFNMVF9QQVRfTk9fUFJJT1JJVFk6CisgKgorICogU3BlY2lmaWMgdmFsdWUgZm9yIHBhdHRlcm4gd2l0aG91dCBwcmlvcml0eSBleHByZXNzZWQuCisgKi8KKyNkZWZpbmUgWFNMVF9QQVRfTk9fUFJJT1JJVFkgLTEyMzQ1Nzg5CisKKy8qKgorICogeHNsdFJ1bnRpbWVFeHRyYToKKyAqCisgKiBFeHRyYSBpbmZvcm1hdGlvbiBhZGRlZCB0byB0aGUgdHJhbnNmb3JtYXRpb24gY29udGV4dC4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRSdW50aW1lRXh0cmEgeHNsdFJ1bnRpbWVFeHRyYTsKK3R5cGVkZWYgeHNsdFJ1bnRpbWVFeHRyYSAqeHNsdFJ1bnRpbWVFeHRyYVB0cjsKK3N0cnVjdCBfeHNsdFJ1bnRpbWVFeHRyYSB7CisgICAgdm9pZCAgICAgICAqaW5mbzsJCS8qIHBvaW50ZXIgdG8gdGhlIGV4dHJhIGRhdGEgKi8KKyAgICB4bWxGcmVlRnVuYyBkZWFsbG9jYXRlOwkvKiBwb2ludGVyIHRvIHRoZSBkZWFsbG9jYXRpb24gcm91dGluZSAqLworICAgIHVuaW9uIHsJCQkvKiBkdWFsLXB1cnBvc2UgZmllbGQgKi8KKyAgICAgICAgdm9pZCAgICpwdHI7CQkvKiBkYXRhIG5vdCBuZWVkaW5nIGRlYWxsb2NhdGlvbiAqLworCWludCAgICBpdmFsOwkJLyogaW50ZWdlciB2YWx1ZSBzdG9yYWdlICovCisgICAgfSB2YWw7Cit9OworCisvKioKKyAqIFhTTFRfUlVOVElNRV9FWFRSQV9MU1Q6CisgKiBAY3R4dDogdGhlIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBucjogdGhlIGluZGV4CisgKgorICogTWFjcm8gdXNlZCB0byBhY2Nlc3MgZXh0cmEgaW5mb3JtYXRpb24gc3RvcmVkIGluIHRoZSBjb250ZXh0CisgKi8KKyNkZWZpbmUgWFNMVF9SVU5USU1FX0VYVFJBX0xTVChjdHh0LCBucikgKGN0eHQpLT5leHRyYXNbKG5yKV0uaW5mbworLyoqCisgKiBYU0xUX1JVTlRJTUVfRVhUUkFfRlJFRToKKyAqIEBjdHh0OiB0aGUgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQG5yOiB0aGUgaW5kZXgKKyAqCisgKiBNYWNybyB1c2VkIHRvIGZyZWUgZXh0cmEgaW5mb3JtYXRpb24gc3RvcmVkIGluIHRoZSBjb250ZXh0CisgKi8KKyNkZWZpbmUgWFNMVF9SVU5USU1FX0VYVFJBX0ZSRUUoY3R4dCwgbnIpIChjdHh0KS0+ZXh0cmFzWyhucildLmRlYWxsb2NhdGUKKy8qKgorICogWFNMVF9SVU5USU1FX0VYVFJBOgorICogQGN0eHQ6IHRoZSB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAbnI6IHRoZSBpbmRleAorICoKKyAqIE1hY3JvIHVzZWQgdG8gZGVmaW5lIGV4dHJhIGluZm9ybWF0aW9uIHN0b3JlZCBpbiB0aGUgY29udGV4dAorICovCisjZGVmaW5lCVhTTFRfUlVOVElNRV9FWFRSQShjdHh0LCBuciwgdHlwKSAoY3R4dCktPmV4dHJhc1sobnIpXS52YWwudHlwCisKKy8qKgorICogeHNsdFRlbXBsYXRlOgorICoKKyAqIFRoZSBpbi1tZW1vcnkgc3RydWN0dXJlIGNvcnJlc3BvbmRpbmcgdG8gYW4gWFNMVCBUZW1wbGF0ZS4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRUZW1wbGF0ZSB4c2x0VGVtcGxhdGU7Cit0eXBlZGVmIHhzbHRUZW1wbGF0ZSAqeHNsdFRlbXBsYXRlUHRyOworc3RydWN0IF94c2x0VGVtcGxhdGUgeworICAgIHN0cnVjdCBfeHNsdFRlbXBsYXRlICpuZXh0Oy8qIGNoYWluZWQgbGlzdCBzb3J0ZWQgYnkgcHJpb3JpdHkgKi8KKyAgICBzdHJ1Y3QgX3hzbHRTdHlsZXNoZWV0ICpzdHlsZTsvKiB0aGUgY29udGFpbmluZyBzdHlsZXNoZWV0ICovCisgICAgeG1sQ2hhciAqbWF0Y2g7CS8qIHRoZSBtYXRjaGluZyBzdHJpbmcgKi8KKyAgICBmbG9hdCBwcmlvcml0eTsJLyogYXMgZ2l2ZW4gZnJvbSB0aGUgc3R5bGVzaGVldCwgbm90IGNvbXB1dGVkICovCisgICAgY29uc3QgeG1sQ2hhciAqbmFtZTsgLyogdGhlIGxvY2FsIHBhcnQgb2YgdGhlIG5hbWUgUU5hbWUgKi8KKyAgICBjb25zdCB4bWxDaGFyICpuYW1lVVJJOyAvKiB0aGUgVVJJIHBhcnQgb2YgdGhlIG5hbWUgUU5hbWUgKi8KKyAgICBjb25zdCB4bWxDaGFyICptb2RlOy8qIHRoZSBsb2NhbCBwYXJ0IG9mIHRoZSBtb2RlIFFOYW1lICovCisgICAgY29uc3QgeG1sQ2hhciAqbW9kZVVSSTsvKiB0aGUgVVJJIHBhcnQgb2YgdGhlIG1vZGUgUU5hbWUgKi8KKyAgICB4bWxOb2RlUHRyIGNvbnRlbnQ7CS8qIHRoZSB0ZW1wbGF0ZSByZXBsYWNlbWVudCB2YWx1ZSAqLworICAgIHhtbE5vZGVQdHIgZWxlbTsJLyogdGhlIHNvdXJjZSBlbGVtZW50ICovCisKKyAgICAvKgorICAgICogVE9ETzogQGluaGVyaXRlZE5zTnIgYW5kIEBpbmhlcml0ZWROcyB3b24ndCBiZSB1c2VkIGluIHRoZQorICAgICogIHJlZmFjdG9yZWQgY29kZS4KKyAgICAqLworICAgIGludCBpbmhlcml0ZWROc05yOyAgLyogbnVtYmVyIG9mIGluaGVyaXRlZCBuYW1lc3BhY2VzICovCisgICAgeG1sTnNQdHIgKmluaGVyaXRlZE5zOy8qIGluaGVyaXRlZCBub24tZXhjbHVkZWQgbmFtZXNwYWNlcyAqLworCisgICAgLyogUHJvZmlsaW5nIGluZm9ybWF0aW9ucyAqLworICAgIGludCBuYkNhbGxzOyAgICAgICAgLyogdGhlIG51bWJlciBvZiB0aW1lIHRoZSB0ZW1wbGF0ZSB3YXMgY2FsbGVkICovCisgICAgdW5zaWduZWQgbG9uZyB0aW1lOyAvKiB0aGUgdGltZSBzcGVudCBpbiB0aGlzIHRlbXBsYXRlICovCisgICAgdm9pZCAqcGFyYW1zOyAgICAgICAvKiB4c2w6cGFyYW0gaW5zdHJ1Y3Rpb25zICovCit9OworCisvKioKKyAqIHhzbHREZWNpbWFsRm9ybWF0OgorICoKKyAqIERhdGEgc3RydWN0dXJlIG9mIGRlY2ltYWwtZm9ybWF0LgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdERlY2ltYWxGb3JtYXQgeHNsdERlY2ltYWxGb3JtYXQ7Cit0eXBlZGVmIHhzbHREZWNpbWFsRm9ybWF0ICp4c2x0RGVjaW1hbEZvcm1hdFB0cjsKK3N0cnVjdCBfeHNsdERlY2ltYWxGb3JtYXQgeworICAgIHN0cnVjdCBfeHNsdERlY2ltYWxGb3JtYXQgKm5leHQ7IC8qIGNoYWluZWQgbGlzdCAqLworICAgIHhtbENoYXIgKm5hbWU7CisgICAgLyogVXNlZCBmb3IgaW50ZXJwcmV0YXRpb24gb2YgcGF0dGVybiAqLworICAgIHhtbENoYXIgKmRpZ2l0OworICAgIHhtbENoYXIgKnBhdHRlcm5TZXBhcmF0b3I7CisgICAgLyogTWF5IGFwcGVhciBpbiByZXN1bHQgKi8KKyAgICB4bWxDaGFyICptaW51c1NpZ247CisgICAgeG1sQ2hhciAqaW5maW5pdHk7CisgICAgeG1sQ2hhciAqbm9OdW1iZXI7IC8qIE5vdC1hLW51bWJlciAqLworICAgIC8qIFVzZWQgZm9yIGludGVycHJldGF0aW9uIG9mIHBhdHRlcm4gYW5kIG1heSBhcHBlYXIgaW4gcmVzdWx0ICovCisgICAgeG1sQ2hhciAqZGVjaW1hbFBvaW50OworICAgIHhtbENoYXIgKmdyb3VwaW5nOworICAgIHhtbENoYXIgKnBlcmNlbnQ7CisgICAgeG1sQ2hhciAqcGVybWlsbGU7CisgICAgeG1sQ2hhciAqemVyb0RpZ2l0OworfTsKKworLyoqCisgKiB4c2x0RG9jdW1lbnQ6CisgKgorICogRGF0YSBzdHJ1Y3R1cmUgYXNzb2NpYXRlZCB0byBhIHBhcnNlZCBkb2N1bWVudC4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHREb2N1bWVudCB4c2x0RG9jdW1lbnQ7Cit0eXBlZGVmIHhzbHREb2N1bWVudCAqeHNsdERvY3VtZW50UHRyOworc3RydWN0IF94c2x0RG9jdW1lbnQgeworICAgIHN0cnVjdCBfeHNsdERvY3VtZW50ICpuZXh0OwkvKiBkb2N1bWVudHMgYXJlIGtlcHQgaW4gYSBjaGFpbmVkIGxpc3QgKi8KKyAgICBpbnQgbWFpbjsJCQkvKiBpcyB0aGlzIHRoZSBtYWluIGRvY3VtZW50ICovCisgICAgeG1sRG9jUHRyIGRvYzsJCS8qIHRoZSBwYXJzZWQgZG9jdW1lbnQgKi8KKyAgICB2b2lkICprZXlzOwkJCS8qIGtleSB0YWJsZXMgc3RvcmFnZSAqLworICAgIHN0cnVjdCBfeHNsdERvY3VtZW50ICppbmNsdWRlczsgLyogc3Vic2lkaWFyeSBpbmNsdWRlcyAqLworICAgIGludCBwcmVwcm9jOwkJLyogcHJlLXByb2Nlc3NpbmcgYWxyZWFkeSBkb25lICovCisgICAgaW50IG5iS2V5c0NvbXB1dGVkOworfTsKKworLyoqCisgKiB4c2x0S2V5RGVmOgorICoKKyAqIFJlcHJlc2VudGF0aW9uIG9mIGFuIHhzbDprZXkuCisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0S2V5RGVmIHhzbHRLZXlEZWY7Cit0eXBlZGVmIHhzbHRLZXlEZWYgKnhzbHRLZXlEZWZQdHI7CitzdHJ1Y3QgX3hzbHRLZXlEZWYgeworICAgIHN0cnVjdCBfeHNsdEtleURlZiAqbmV4dDsKKyAgICB4bWxOb2RlUHRyIGluc3Q7CisgICAgeG1sQ2hhciAqbmFtZTsKKyAgICB4bWxDaGFyICpuYW1lVVJJOworICAgIHhtbENoYXIgKm1hdGNoOworICAgIHhtbENoYXIgKnVzZTsKKyAgICB4bWxYUGF0aENvbXBFeHByUHRyIGNvbXA7CisgICAgeG1sWFBhdGhDb21wRXhwclB0ciB1c2Vjb21wOworICAgIHhtbE5zUHRyICpuc0xpc3Q7ICAgICAgICAgICAvKiB0aGUgbmFtZXNwYWNlcyBpbiBzY29wZSAqLworICAgIGludCBuc05yOyAgICAgICAgICAgICAgICAgICAvKiB0aGUgbnVtYmVyIG9mIG5hbWVzcGFjZXMgaW4gc2NvcGUgKi8KK307CisKKy8qKgorICogeHNsdEtleVRhYmxlOgorICoKKyAqIEhvbGRzIHRoZSBjb21wdXRlZCBrZXlzIGZvciBrZXkgZGVmaW5pdGlvbnMgb2YgdGhlIHNhbWUgUU5hbWUuCisgKiBJcyBvd25lZCBieSBhbiB4c2x0RG9jdW1lbnQuCisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0S2V5VGFibGUgeHNsdEtleVRhYmxlOwordHlwZWRlZiB4c2x0S2V5VGFibGUgKnhzbHRLZXlUYWJsZVB0cjsKK3N0cnVjdCBfeHNsdEtleVRhYmxlIHsKKyAgICBzdHJ1Y3QgX3hzbHRLZXlUYWJsZSAqbmV4dDsKKyAgICB4bWxDaGFyICpuYW1lOworICAgIHhtbENoYXIgKm5hbWVVUkk7CisgICAgeG1sSGFzaFRhYmxlUHRyIGtleXM7Cit9OworCisvKgorICogVGhlIGluLW1lbW9yeSBzdHJ1Y3R1cmUgY29ycmVzcG9uZGluZyB0byBhbiBYU0xUIFN0eWxlc2hlZXQuCisgKiBOT1RFOiBtb3N0IG9mIHRoZSBjb250ZW50IGlzIHNpbXBseSBsaW5rZWQgZnJvbSB0aGUgZG9jIHRyZWUKKyAqICAgICAgIHN0cnVjdHVyZSwgbm8gc3BlY2lmaWMgYWxsb2NhdGlvbiBpcyBtYWRlLgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlc2hlZXQgeHNsdFN0eWxlc2hlZXQ7Cit0eXBlZGVmIHhzbHRTdHlsZXNoZWV0ICp4c2x0U3R5bGVzaGVldFB0cjsKKwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRUcmFuc2Zvcm1Db250ZXh0IHhzbHRUcmFuc2Zvcm1Db250ZXh0OwordHlwZWRlZiB4c2x0VHJhbnNmb3JtQ29udGV4dCAqeHNsdFRyYW5zZm9ybUNvbnRleHRQdHI7CisKKy8qKgorICogeHNsdEVsZW1QcmVDb21wOgorICoKKyAqIFRoZSBpbi1tZW1vcnkgc3RydWN0dXJlIGNvcnJlc3BvbmRpbmcgdG8gZWxlbWVudCBwcmVjb21wdXRlZCBkYXRhLAorICogZGVzaWduZWQgdG8gYmUgZXh0ZW5kZWQgYnkgZXh0ZW5zaW9uIGltcGxlbWVudG9ycy4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRFbGVtUHJlQ29tcCB4c2x0RWxlbVByZUNvbXA7Cit0eXBlZGVmIHhzbHRFbGVtUHJlQ29tcCAqeHNsdEVsZW1QcmVDb21wUHRyOworCisvKioKKyAqIHhzbHRUcmFuc2Zvcm1GdW5jdGlvbjoKKyAqIEBjdHh0OiB0aGUgWFNMVCB0cmFuc2Zvcm1hdGlvbiBjb250ZXh0CisgKiBAbm9kZTogdGhlIGlucHV0IG5vZGUKKyAqIEBpbnN0OiB0aGUgc3R5bGVzaGVldCBub2RlCisgKiBAY29tcDogdGhlIGNvbXBpbGVkIGluZm9ybWF0aW9uIGZyb20gdGhlIHN0eWxlc2hlZXQKKyAqCisgKiBTaWduYXR1cmUgb2YgdGhlIGZ1bmN0aW9uIGFzc29jaWF0ZWQgdG8gZWxlbWVudHMgcGFydCBvZiB0aGUKKyAqIHN0eWxlc2hlZXQgbGFuZ3VhZ2UgbGlrZSB4c2w6aWYgb3IgeHNsOmFwcGx5LXRlbXBsYXRlcy4KKyAqLwordHlwZWRlZiB2b2lkICgqeHNsdFRyYW5zZm9ybUZ1bmN0aW9uKSAoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAorCQkJCSAgICAgICB4bWxOb2RlUHRyIGluc3QsCisJCQkgICAgICAgICAgICAgICB4c2x0RWxlbVByZUNvbXBQdHIgY29tcCk7CisKKy8qKgorICogeHNsdFNvcnRGdW5jOgorICogQGN0eHQ6ICAgIGEgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQHNvcnRzOiAgIHRoZSBub2RlLXNldCB0byBzb3J0CisgKiBAbmJzb3J0czogdGhlIG51bWJlciBvZiBzb3J0cworICoKKyAqIFNpZ25hdHVyZSBvZiB0aGUgZnVuY3Rpb24gdG8gdXNlIGR1cmluZyBzb3J0aW5nCisgKi8KK3R5cGVkZWYgdm9pZCAoKnhzbHRTb3J0RnVuYykgKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgKnNvcnRzLAorCQkJICAgICAgaW50IG5ic29ydHMpOworCit0eXBlZGVmIGVudW0geworICAgIFhTTFRfRlVOQ19DT1BZPTEsCisgICAgWFNMVF9GVU5DX1NPUlQsCisgICAgWFNMVF9GVU5DX1RFWFQsCisgICAgWFNMVF9GVU5DX0VMRU1FTlQsCisgICAgWFNMVF9GVU5DX0FUVFJJQlVURSwKKyAgICBYU0xUX0ZVTkNfQ09NTUVOVCwKKyAgICBYU0xUX0ZVTkNfUEksCisgICAgWFNMVF9GVU5DX0NPUFlPRiwKKyAgICBYU0xUX0ZVTkNfVkFMVUVPRiwKKyAgICBYU0xUX0ZVTkNfTlVNQkVSLAorICAgIFhTTFRfRlVOQ19BUFBMWUlNUE9SVFMsCisgICAgWFNMVF9GVU5DX0NBTExURU1QTEFURSwKKyAgICBYU0xUX0ZVTkNfQVBQTFlURU1QTEFURVMsCisgICAgWFNMVF9GVU5DX0NIT09TRSwKKyAgICBYU0xUX0ZVTkNfSUYsCisgICAgWFNMVF9GVU5DX0ZPUkVBQ0gsCisgICAgWFNMVF9GVU5DX0RPQ1VNRU5ULAorICAgIFhTTFRfRlVOQ19XSVRIUEFSQU0sCisgICAgWFNMVF9GVU5DX1BBUkFNLAorICAgIFhTTFRfRlVOQ19WQVJJQUJMRSwKKyAgICBYU0xUX0ZVTkNfV0hFTiwKKyAgICBYU0xUX0ZVTkNfRVhURU5TSU9OCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgLAorICAgIFhTTFRfRlVOQ19PVEhFUldJU0UsCisgICAgWFNMVF9GVU5DX0ZBTExCQUNLLAorICAgIFhTTFRfRlVOQ19NRVNTQUdFLAorICAgIFhTTFRfRlVOQ19JTkNMVURFLAorICAgIFhTTFRfRlVOQ19BVFRSU0VULAorICAgIFhTTFRfRlVOQ19MSVRFUkFMX1JFU1VMVF9FTEVNRU5ULAorICAgIFhTTFRfRlVOQ19VTktPV05fRk9SV0FSRFNfQ09NUEFUCisjZW5kaWYKK30geHNsdFN0eWxlVHlwZTsKKworLyoqCisgKiB4c2x0RWxlbVByZUNvbXBEZWFsbG9jYXRvcjoKKyAqIEBjb21wOiAgdGhlICN4c2x0RWxlbVByZUNvbXAgdG8gZnJlZSB1cAorICoKKyAqIERlYWxsb2NhdGVzIGFuICN4c2x0RWxlbVByZUNvbXAgc3RydWN0dXJlLgorICovCit0eXBlZGVmIHZvaWQgKCp4c2x0RWxlbVByZUNvbXBEZWFsbG9jYXRvcikgKHhzbHRFbGVtUHJlQ29tcFB0ciBjb21wKTsKKworLyoqCisgKiB4c2x0RWxlbVByZUNvbXA6CisgKgorICogVGhlIGJhc2ljIHN0cnVjdHVyZSBmb3IgY29tcGlsZWQgaXRlbXMgb2YgdGhlIEFTVCBvZiB0aGUgWFNMVCBwcm9jZXNzb3IuCisgKiBUaGlzIHN0cnVjdHVyZSBpcyBhbHNvIGludGVuZGVkIHRvIGJlIGV4dGVuZGVkIGJ5IGV4dGVuc2lvbiBpbXBsZW1lbnRvcnMuCisgKiBUT0RPOiBUaGlzIGlzIHNvbWVob3cgbm90IG5pY2UsIHNpbmNlIGl0IGhhcyBhICJmcmVlIiBmaWVsZCwgd2hpY2gKKyAqICAgZGVyaXZlZCBzdHlsZXNoZWV0LXN0cnVjdHMgZG8gbm90IGhhdmUuCisgKi8KK3N0cnVjdCBfeHNsdEVsZW1QcmVDb21wIHsKKyAgICB4c2x0RWxlbVByZUNvbXBQdHIgbmV4dDsJCS8qIG5leHQgaXRlbSBpbiB0aGUgZ2xvYmFsIGNoYWluZWQKKwkJCQkJICAgbGlzdCBob2xkIGJ5IHhzbHRTdHlsZXNoZWV0LiAqLworICAgIHhzbHRTdHlsZVR5cGUgdHlwZTsJCS8qIHR5cGUgb2YgdGhlIGVsZW1lbnQgKi8KKyAgICB4c2x0VHJhbnNmb3JtRnVuY3Rpb24gZnVuYzsgCS8qIGhhbmRsaW5nIGZ1bmN0aW9uICovCisgICAgeG1sTm9kZVB0ciBpbnN0OwkJCS8qIHRoZSBub2RlIGluIHRoZSBzdHlsZXNoZWV0J3MgdHJlZQorCQkJCQkgICBjb3JyZXNwb25kaW5nIHRvIHRoaXMgaXRlbSAqLworCisgICAgLyogZW5kIG9mIGNvbW1vbiBwYXJ0ICovCisgICAgeHNsdEVsZW1QcmVDb21wRGVhbGxvY2F0b3IgZnJlZTsJLyogdGhlIGRlYWxsb2NhdG9yICovCit9OworCisvKioKKyAqIHhzbHRTdHlsZVByZUNvbXA6CisgKgorICogVGhlIGFic3RyYWN0IGJhc2ljIHN0cnVjdHVyZSBmb3IgaXRlbXMgb2YgdGhlIFhTTFQgcHJvY2Vzc29yLgorICogVGhpcyBpbmNsdWRlczoKKyAqIDEpIGNvbXBpbGVkIGZvcm1zIG9mIFhTTFQgaW5zdHJ1Y3Rpb25zICh4c2w6aWYsIHhzbDphdHRyaWJ1dGUsIGV0Yy4pCisgKiAyKSBjb21waWxlZCBmb3JtcyBvZiBsaXRlcmFsIHJlc3VsdCBlbGVtZW50cworICogMykgY29tcGlsZWQgZm9ybXMgb2YgZXh0ZW5zaW9uIGVsZW1lbnRzCisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0U3R5bGVQcmVDb21wIHhzbHRTdHlsZVByZUNvbXA7Cit0eXBlZGVmIHhzbHRTdHlsZVByZUNvbXAgKnhzbHRTdHlsZVByZUNvbXBQdHI7CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKworLyoKKyogU29tZSBwb2ludGVyLWxpc3QgdXRpbGl0eSBmdW5jdGlvbnMuCisqLworWFNMVFBVQkZVTiB4c2x0UG9pbnRlckxpc3RQdHIgWFNMVENBTEwKKwkJeHNsdFBvaW50ZXJMaXN0Q3JlYXRlCQkoaW50IGluaXRpYWxTaXplKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0UG9pbnRlckxpc3RGcmVlCQkoeHNsdFBvaW50ZXJMaXN0UHRyIGxpc3QpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCXhzbHRQb2ludGVyTGlzdENsZWFyCQkoeHNsdFBvaW50ZXJMaXN0UHRyIGxpc3QpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwKKwkJeHNsdFBvaW50ZXJMaXN0QWRkU2l6ZQkJKHhzbHRQb2ludGVyTGlzdFB0ciBsaXN0LAkJCQkJCSAKKwkJCQkJCSB2b2lkICppdGVtLAorCQkJCQkJIGludCBpbml0aWFsU2l6ZSk7CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICogUmVmYWN0b3JlZCBzdHJ1Y3R1cmVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit0eXBlZGVmIHN0cnVjdCBfeHNsdE5zTGlzdENvbnRhaW5lciB4c2x0TnNMaXN0Q29udGFpbmVyOwordHlwZWRlZiB4c2x0TnNMaXN0Q29udGFpbmVyICp4c2x0TnNMaXN0Q29udGFpbmVyUHRyOworc3RydWN0IF94c2x0TnNMaXN0Q29udGFpbmVyIHsKKyAgICB4bWxOc1B0ciAqbGlzdDsKKyAgICBpbnQgdG90YWxOdW1iZXI7CisgICAgaW50IHhwYXRoTnVtYmVyOyAgICAKK307CisKKy8qKgorICogWFNMVF9JVEVNX0NPTVBBVElCSUxJVFlfRklFTERTOgorICogCisgKiBGaWVsZHMgZm9yIEFQSSBjb21wYXRpYmlsaXR5IHRvIHRoZSBzdHJ1Y3R1cmUKKyAqIF94c2x0RWxlbVByZUNvbXAgd2hpY2ggaXMgdXNlZCBmb3IgZXh0ZW5zaW9uIGZ1bmN0aW9ucy4KKyAqIE5vdGUgdGhhdCBAbmV4dCBpcyB1c2VkIGZvciBzdG9yYWdlOyBpdCBkb2VzIG5vdCByZWZsZWN0IGEgbmV4dAorICogc2libGluZyBpbiB0aGUgdHJlZS4KKyAqIFRPRE86IEV2YWx1YXRlIGlmIHdlIHJlYWxseSBuZWVkIHN1Y2ggYSBjb21wYXRpYmlsaXR5LgorICovCisjZGVmaW5lIFhTTFRfSVRFTV9DT01QQVRJQklMSVRZX0ZJRUxEUyBcCisgICAgeHNsdEVsZW1QcmVDb21wUHRyIG5leHQ7XAorICAgIHhzbHRTdHlsZVR5cGUgdHlwZTtcCisgICAgeHNsdFRyYW5zZm9ybUZ1bmN0aW9uIGZ1bmM7XAorICAgIHhtbE5vZGVQdHIgaW5zdDsKKworLyoqCisgKiBYU0xUX0lURU1fTkFWSUdBVElPTl9GSUVMRFM6CisgKgorICogQ3VycmVudGx5IGVtcHR5LgorICogVE9ETzogSXQgaXMgaW50ZW5kZWQgdG8gaG9sZCBuYXZpZ2F0aW9uYWwgZmllbGRzIGluIHRoZSBmdXR1cmUuCisgKi8KKyNkZWZpbmUgWFNMVF9JVEVNX05BVklHQVRJT05fRklFTERTCisvKgorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgcGFyZW50O1wKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIGNoaWxkcmVuO1wKKyAgICB4c2x0U3R5bGVQcmVDb21wUHRyIG5leHRJdGVtOyAKKyovCisKKy8qKgorICogWFNMVF9JVEVNX05TSU5TQ09QRV9GSUVMRFM6CisgKgorICogVGhlIGluLXNjb3BlIG5hbWVzcGFjZXMuCisgKi8KKyNkZWZpbmUgWFNMVF9JVEVNX05TSU5TQ09QRV9GSUVMRFMgeHNsdE5zTGlzdENvbnRhaW5lclB0ciBpblNjb3BlTnM7CisKKy8qKgorICogWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFM6CisgKgorICogQ29tbW9uIGZpZWxkcyB1c2VkIGZvciBhbGwgaXRlbXMuCisgKi8KKyNkZWZpbmUgWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFMgXAorICAgIFhTTFRfSVRFTV9DT01QQVRJQklMSVRZX0ZJRUxEUyBcCisgICAgWFNMVF9JVEVNX05BVklHQVRJT05fRklFTERTIFwKKyAgICBYU0xUX0lURU1fTlNJTlNDT1BFX0ZJRUxEUworCisvKioKKyAqIF94c2x0U3R5bGVQcmVDb21wOiAKKyAqCisgKiBUaGUgYWJzdHJhY3QgYmFzaWMgc3RydWN0dXJlIGZvciBpdGVtcyBvZiB0aGUgWFNMVCBwcm9jZXNzb3IuCisgKiBUaGlzIGluY2x1ZGVzOgorICogMSkgY29tcGlsZWQgZm9ybXMgb2YgWFNMVCBpbnN0cnVjdGlvbnMgKGUuZy4geHNsOmlmLCB4c2w6YXR0cmlidXRlLCBldGMuKQorICogMikgY29tcGlsZWQgZm9ybXMgb2YgbGl0ZXJhbCByZXN1bHQgZWxlbWVudHMKKyAqIDMpIHZhcmlvdXMgcHJvcGVydGllcyBmb3IgWFNMVCBpbnN0cnVjdGlvbnMgKGUuZy4geHNsOndoZW4sCisgKiAgICB4c2w6d2l0aC1wYXJhbSkKKyAqCisgKiBSRVZJU0lUIFRPRE86IEtlZXAgdGhpcyBzdHJ1Y3R1cmUgZXF1YWwgdG8gdGhlIGZpZWxkcworICogICBkZWZpbmVkIGJ5IFhTTFRfSVRFTV9DT01NT05fRklFTERTCisgKi8KK3N0cnVjdCBfeHNsdFN0eWxlUHJlQ29tcCB7CisgICAgeHNsdEVsZW1QcmVDb21wUHRyIG5leHQ7ICAgIC8qIG5leHQgaXRlbSBpbiB0aGUgZ2xvYmFsIGNoYWluZWQKKwkJCQkgICBsaXN0IGhvbGQgYnkgeHNsdFN0eWxlc2hlZXQgKi8KKyAgICB4c2x0U3R5bGVUeXBlIHR5cGU7ICAgICAgICAgLyogdHlwZSBvZiB0aGUgaXRlbSAqLyAKKyAgICB4c2x0VHJhbnNmb3JtRnVuY3Rpb24gZnVuYzsgLyogaGFuZGxpbmcgZnVuY3Rpb24gKi8KKyAgICB4bWxOb2RlUHRyIGluc3Q7CQkvKiB0aGUgbm9kZSBpbiB0aGUgc3R5bGVzaGVldCdzIHRyZWUKKwkJCQkgICBjb3JyZXNwb25kaW5nIHRvIHRoaXMgaXRlbS4gKi8KKyAgICAvKiBDdXJyZW50bHkgbm8gbmF2aWdhdGlvbmFsIGZpZWxkcy4gKi8KKyAgICB4c2x0TnNMaXN0Q29udGFpbmVyUHRyIGluU2NvcGVOczsKK307CisKKy8qKgorICogeHNsdFN0eWxlQmFzaWNFbXB0eUl0ZW06CisgKiAKKyAqIEFic3RyYWN0IHN0cnVjdHVyZSBvbmx5IHVzZWQgYXMgYSBzaG9ydC1jdXQgZm9yCisgKiBYU0xUIGl0ZW1zIHdpdGggbm8gZXh0cmEgZmllbGRzLgorICogTk9URSB0aGF0IGl0IGlzIGludGVuZGVkIHRoYXQgdGhpcyBzdHJ1Y3R1cmUgbG9va3MgdGhlIHNhbWUgYXMKKyAqICBfeHNsdFN0eWxlUHJlQ29tcC4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRTdHlsZUJhc2ljRW1wdHlJdGVtIHhzbHRTdHlsZUJhc2ljRW1wdHlJdGVtOwordHlwZWRlZiB4c2x0U3R5bGVCYXNpY0VtcHR5SXRlbSAqeHNsdFN0eWxlQmFzaWNFbXB0eUl0ZW1QdHI7CisKK3N0cnVjdCBfeHNsdFN0eWxlQmFzaWNFbXB0eUl0ZW0geworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTCit9OworCisvKioKKyAqIHhzbHRTdHlsZUJhc2ljRXhwcmVzc2lvbkl0ZW06CisgKiAKKyAqIEFic3RyYWN0IHN0cnVjdHVyZSBvbmx5IHVzZWQgYXMgYSBzaG9ydC1jdXQgZm9yCisgKiBYU0xUIGl0ZW1zIHdpdGgganVzdCBhbiBleHByZXNzaW9uLgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlQmFzaWNFeHByZXNzaW9uSXRlbSB4c2x0U3R5bGVCYXNpY0V4cHJlc3Npb25JdGVtOwordHlwZWRlZiB4c2x0U3R5bGVCYXNpY0V4cHJlc3Npb25JdGVtICp4c2x0U3R5bGVCYXNpY0V4cHJlc3Npb25JdGVtUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUJhc2ljRXhwcmVzc2lvbkl0ZW0geworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTCisKKyAgICBjb25zdCB4bWxDaGFyICpzZWxlY3Q7IC8qIFRPRE86IENoYW5nZSB0aGlzIHRvICJleHByZXNzaW9uIi4gKi8KKyAgICB4bWxYUGF0aENvbXBFeHByUHRyIGNvbXA7IC8qIFRPRE86IENoYW5nZSB0aGlzIHRvIGNvbXBFeHByLiAqLworfTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKiBYU0xULWluc3RydWN0aW9ucy9kZWNsYXJhdGlvbnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdFN0eWxlSXRlbUVsZW1lbnQ6CisgKiAKKyAqIDwhLS0gQ2F0ZWdvcnk6IGluc3RydWN0aW9uIC0tPgorICogPHhzbDplbGVtZW50CisgKiAgbmFtZSA9IHsgcW5hbWUgfQorICogIG5hbWVzcGFjZSA9IHsgdXJpLXJlZmVyZW5jZSB9CisgKiAgdXNlLWF0dHJpYnV0ZS1zZXRzID0gcW5hbWVzPgorICogIDwhLS0gQ29udGVudDogdGVtcGxhdGUgLS0+CisgKiA8L3hzbDplbGVtZW50PgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbUVsZW1lbnQgeHNsdFN0eWxlSXRlbUVsZW1lbnQ7Cit0eXBlZGVmIHhzbHRTdHlsZUl0ZW1FbGVtZW50ICp4c2x0U3R5bGVJdGVtRWxlbWVudFB0cjsKKworc3RydWN0IF94c2x0U3R5bGVJdGVtRWxlbWVudCB7CisgICAgWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFMgCisKKyAgICBjb25zdCB4bWxDaGFyICp1c2U7CisgICAgaW50ICAgICAgaGFzX3VzZTsKKyAgICBjb25zdCB4bWxDaGFyICpuYW1lOyAgICAKKyAgICBpbnQgICAgICBoYXNfbmFtZTsKKyAgICBjb25zdCB4bWxDaGFyICpuczsKKyAgICBjb25zdCB4bWxDaGFyICpuc1ByZWZpeDsKKyAgICBpbnQgICAgICBoYXNfbnM7Cit9OworCisvKioKKyAqIHhzbHRTdHlsZUl0ZW1BdHRyaWJ1dGU6CisgKgorICogPCEtLSBDYXRlZ29yeTogaW5zdHJ1Y3Rpb24gLS0+CisgKiA8eHNsOmF0dHJpYnV0ZQorICogIG5hbWUgPSB7IHFuYW1lIH0KKyAqICBuYW1lc3BhY2UgPSB7IHVyaS1yZWZlcmVuY2UgfT4KKyAqICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICogPC94c2w6YXR0cmlidXRlPgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbUF0dHJpYnV0ZSB4c2x0U3R5bGVJdGVtQXR0cmlidXRlOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtQXR0cmlidXRlICp4c2x0U3R5bGVJdGVtQXR0cmlidXRlUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1BdHRyaWJ1dGUgeworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTCisgICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKKyAgICBpbnQgICAgICBoYXNfbmFtZTsKKyAgICBjb25zdCB4bWxDaGFyICpuczsKKyAgICBjb25zdCB4bWxDaGFyICpuc1ByZWZpeDsKKyAgICBpbnQgICAgICBoYXNfbnM7Cit9OworCisvKioKKyAqIHhzbHRTdHlsZUl0ZW1UZXh0OgorICoKKyAqIDwhLS0gQ2F0ZWdvcnk6IGluc3RydWN0aW9uIC0tPgorICogPHhzbDp0ZXh0CisgKiAgZGlzYWJsZS1vdXRwdXQtZXNjYXBpbmcgPSAieWVzIiB8ICJubyI+CisgKiAgPCEtLSBDb250ZW50OiAjUENEQVRBIC0tPgorICogPC94c2w6dGV4dD4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1UZXh0IHhzbHRTdHlsZUl0ZW1UZXh0OwordHlwZWRlZiB4c2x0U3R5bGVJdGVtVGV4dCAqeHNsdFN0eWxlSXRlbVRleHRQdHI7CisKK3N0cnVjdCBfeHNsdFN0eWxlSXRlbVRleHQgeworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTCisgICAgaW50ICAgICAgbm9lc2NhcGU7CQkvKiB0ZXh0ICovCit9OworCisvKioKKyAqIHhzbHRTdHlsZUl0ZW1Db21tZW50OgorICoKKyAqIDwhLS0gQ2F0ZWdvcnk6IGluc3RydWN0aW9uIC0tPgorICogIDx4c2w6Y29tbWVudD4KKyAqICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICogPC94c2w6Y29tbWVudD4KKyAqLwordHlwZWRlZiB4c2x0U3R5bGVCYXNpY0VtcHR5SXRlbSB4c2x0U3R5bGVJdGVtQ29tbWVudDsKK3R5cGVkZWYgeHNsdFN0eWxlSXRlbUNvbW1lbnQgKnhzbHRTdHlsZUl0ZW1Db21tZW50UHRyOworCisvKioKKyAqIHhzbHRTdHlsZUl0ZW1QSToKKyAqCisgKiA8IS0tIENhdGVnb3J5OiBpbnN0cnVjdGlvbiAtLT4KKyAqICA8eHNsOnByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24KKyAqICBuYW1lID0geyBuY25hbWUgfT4KKyAqICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICogPC94c2w6cHJvY2Vzc2luZy1pbnN0cnVjdGlvbj4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1QSSB4c2x0U3R5bGVJdGVtUEk7Cit0eXBlZGVmIHhzbHRTdHlsZUl0ZW1QSSAqeHNsdFN0eWxlSXRlbVBJUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1QSSB7CisgICAgWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFMKKyAgICBjb25zdCB4bWxDaGFyICpuYW1lOworICAgIGludCAgICAgIGhhc19uYW1lOworfTsKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtQXBwbHlJbXBvcnRzOgorICoKKyAqIDwhLS0gQ2F0ZWdvcnk6IGluc3RydWN0aW9uIC0tPgorICogPHhzbDphcHBseS1pbXBvcnRzIC8+CisgKi8KK3R5cGVkZWYgeHNsdFN0eWxlQmFzaWNFbXB0eUl0ZW0geHNsdFN0eWxlSXRlbUFwcGx5SW1wb3J0czsKK3R5cGVkZWYgeHNsdFN0eWxlSXRlbUFwcGx5SW1wb3J0cyAqeHNsdFN0eWxlSXRlbUFwcGx5SW1wb3J0c1B0cjsKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtQXBwbHlUZW1wbGF0ZXM6CisgKgorICogPCEtLSBDYXRlZ29yeTogaW5zdHJ1Y3Rpb24gLS0+CisgKiAgPHhzbDphcHBseS10ZW1wbGF0ZXMKKyAqICBzZWxlY3QgPSBub2RlLXNldC1leHByZXNzaW9uCisgKiAgbW9kZSA9IHFuYW1lPgorICogIDwhLS0gQ29udGVudDogKHhzbDpzb3J0IHwgeHNsOndpdGgtcGFyYW0pKiAtLT4KKyAqIDwveHNsOmFwcGx5LXRlbXBsYXRlcz4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1BcHBseVRlbXBsYXRlcyB4c2x0U3R5bGVJdGVtQXBwbHlUZW1wbGF0ZXM7Cit0eXBlZGVmIHhzbHRTdHlsZUl0ZW1BcHBseVRlbXBsYXRlcyAqeHNsdFN0eWxlSXRlbUFwcGx5VGVtcGxhdGVzUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1BcHBseVRlbXBsYXRlcyB7CisgICAgWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFMKKworICAgIGNvbnN0IHhtbENoYXIgKm1vZGU7CS8qIGFwcGx5LXRlbXBsYXRlcyAqLworICAgIGNvbnN0IHhtbENoYXIgKm1vZGVVUkk7CS8qIGFwcGx5LXRlbXBsYXRlcyAqLworICAgIGNvbnN0IHhtbENoYXIgKnNlbGVjdDsJLyogc29ydCwgY29weS1vZiwgdmFsdWUtb2YsIGFwcGx5LXRlbXBsYXRlcyAqLworICAgIHhtbFhQYXRoQ29tcEV4cHJQdHIgY29tcDsJLyogYSBwcmVjb21waWxlZCBYUGF0aCBleHByZXNzaW9uICovCisgICAgLyogVE9ETzogd2l0aC1wYXJhbXMgKi8KK307CisKKy8qKgorICogeHNsdFN0eWxlSXRlbUNhbGxUZW1wbGF0ZToKKyAqCisgKiA8IS0tIENhdGVnb3J5OiBpbnN0cnVjdGlvbiAtLT4KKyAqICA8eHNsOmNhbGwtdGVtcGxhdGUKKyAqICBuYW1lID0gcW5hbWU+CisgKiAgPCEtLSBDb250ZW50OiB4c2w6d2l0aC1wYXJhbSogLS0+CisgKiA8L3hzbDpjYWxsLXRlbXBsYXRlPgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbUNhbGxUZW1wbGF0ZSB4c2x0U3R5bGVJdGVtQ2FsbFRlbXBsYXRlOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtQ2FsbFRlbXBsYXRlICp4c2x0U3R5bGVJdGVtQ2FsbFRlbXBsYXRlUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1DYWxsVGVtcGxhdGUgeworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTCisKKyAgICB4c2x0VGVtcGxhdGVQdHIgdGVtcGw7CS8qIGNhbGwtdGVtcGxhdGUgKi8KKyAgICBjb25zdCB4bWxDaGFyICpuYW1lOwkvKiBlbGVtZW50LCBhdHRyaWJ1dGUsIHBpICovCisgICAgaW50ICAgICAgaGFzX25hbWU7CQkvKiBlbGVtZW50LCBhdHRyaWJ1dGUsIHBpICovCisgICAgY29uc3QgeG1sQ2hhciAqbnM7CQkvKiBlbGVtZW50ICovCisgICAgaW50ICAgICAgaGFzX25zOwkJLyogZWxlbWVudCAqLworICAgIC8qIFRPRE86IHdpdGgtcGFyYW1zICovCit9OworCisvKioKKyAqIHhzbHRTdHlsZUl0ZW1Db3B5OgorICoKKyAqIDwhLS0gQ2F0ZWdvcnk6IGluc3RydWN0aW9uIC0tPgorICogPHhzbDpjb3B5CisgKiAgdXNlLWF0dHJpYnV0ZS1zZXRzID0gcW5hbWVzPgorICogIDwhLS0gQ29udGVudDogdGVtcGxhdGUgLS0+CisgKiA8L3hzbDpjb3B5PgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbUNvcHkgeHNsdFN0eWxlSXRlbUNvcHk7Cit0eXBlZGVmIHhzbHRTdHlsZUl0ZW1Db3B5ICp4c2x0U3R5bGVJdGVtQ29weVB0cjsKKworc3RydWN0IF94c2x0U3R5bGVJdGVtQ29weSB7CisgICBYU0xUX0lURU1fQ09NTU9OX0ZJRUxEUworICAgIGNvbnN0IHhtbENoYXIgKnVzZTsJCS8qIGNvcHksIGVsZW1lbnQgKi8KKyAgICBpbnQgICAgICBoYXNfdXNlOwkJLyogY29weSwgZWxlbWVudCAqLyAgICAKK307CisKKy8qKgorICogeHNsdFN0eWxlSXRlbUlmOgorICoKKyAqIDwhLS0gQ2F0ZWdvcnk6IGluc3RydWN0aW9uIC0tPgorICogIDx4c2w6aWYKKyAqICB0ZXN0ID0gYm9vbGVhbi1leHByZXNzaW9uPgorICogIDwhLS0gQ29udGVudDogdGVtcGxhdGUgLS0+CisgKiA8L3hzbDppZj4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1JZiB4c2x0U3R5bGVJdGVtSWY7Cit0eXBlZGVmIHhzbHRTdHlsZUl0ZW1JZiAqeHNsdFN0eWxlSXRlbUlmUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1JZiB7CisgICAgWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFMKKworICAgIGNvbnN0IHhtbENoYXIgKnRlc3Q7CS8qIGlmICovCisgICAgeG1sWFBhdGhDb21wRXhwclB0ciBjb21wOwkvKiBhIHByZWNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24gKi8KK307CisKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtQ29weU9mOgorICoKKyAqIDwhLS0gQ2F0ZWdvcnk6IGluc3RydWN0aW9uIC0tPgorICogPHhzbDpjb3B5LW9mCisgKiAgc2VsZWN0ID0gZXhwcmVzc2lvbiAvPgorICovCit0eXBlZGVmIHhzbHRTdHlsZUJhc2ljRXhwcmVzc2lvbkl0ZW0geHNsdFN0eWxlSXRlbUNvcHlPZjsKK3R5cGVkZWYgeHNsdFN0eWxlSXRlbUNvcHlPZiAqeHNsdFN0eWxlSXRlbUNvcHlPZlB0cjsKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtVmFsdWVPZjoKKyAqCisgKiA8IS0tIENhdGVnb3J5OiBpbnN0cnVjdGlvbiAtLT4KKyAqIDx4c2w6dmFsdWUtb2YKKyAqICBzZWxlY3QgPSBzdHJpbmctZXhwcmVzc2lvbgorICogIGRpc2FibGUtb3V0cHV0LWVzY2FwaW5nID0gInllcyIgfCAibm8iIC8+CisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0U3R5bGVJdGVtVmFsdWVPZiB4c2x0U3R5bGVJdGVtVmFsdWVPZjsKK3R5cGVkZWYgeHNsdFN0eWxlSXRlbVZhbHVlT2YgKnhzbHRTdHlsZUl0ZW1WYWx1ZU9mUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1WYWx1ZU9mIHsKKyAgICBYU0xUX0lURU1fQ09NTU9OX0ZJRUxEUworCisgICAgY29uc3QgeG1sQ2hhciAqc2VsZWN0OworICAgIHhtbFhQYXRoQ29tcEV4cHJQdHIgY29tcDsJLyogYSBwcmVjb21waWxlZCBYUGF0aCBleHByZXNzaW9uICovCisgICAgaW50ICAgICAgbm9lc2NhcGU7Cit9OworCisvKioKKyAqIHhzbHRTdHlsZUl0ZW1OdW1iZXI6CisgKgorICogPCEtLSBDYXRlZ29yeTogaW5zdHJ1Y3Rpb24gLS0+CisgKiAgPHhzbDpudW1iZXIKKyAqICBsZXZlbCA9ICJzaW5nbGUiIHwgIm11bHRpcGxlIiB8ICJhbnkiCisgKiAgY291bnQgPSBwYXR0ZXJuCisgKiAgZnJvbSA9IHBhdHRlcm4KKyAqICB2YWx1ZSA9IG51bWJlci1leHByZXNzaW9uCisgKiAgZm9ybWF0ID0geyBzdHJpbmcgfQorICogIGxhbmcgPSB7IG5tdG9rZW4gfQorICogIGxldHRlci12YWx1ZSA9IHsgImFscGhhYmV0aWMiIHwgInRyYWRpdGlvbmFsIiB9CisgKiAgZ3JvdXBpbmctc2VwYXJhdG9yID0geyBjaGFyIH0KKyAqICBncm91cGluZy1zaXplID0geyBudW1iZXIgfSAvPgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbU51bWJlciB4c2x0U3R5bGVJdGVtTnVtYmVyOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtTnVtYmVyICp4c2x0U3R5bGVJdGVtTnVtYmVyUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1OdW1iZXIgeworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTCisgICAgeHNsdE51bWJlckRhdGEgbnVtZGF0YTsJLyogbnVtYmVyICovCit9OworCisvKioKKyAqIHhzbHRTdHlsZUl0ZW1DaG9vc2U6CisgKgorICogPCEtLSBDYXRlZ29yeTogaW5zdHJ1Y3Rpb24gLS0+CisgKiAgPHhzbDpjaG9vc2U+CisgKiAgPCEtLSBDb250ZW50OiAoeHNsOndoZW4rLCB4c2w6b3RoZXJ3aXNlPykgLS0+CisgKiA8L3hzbDpjaG9vc2U+CisgKi8KK3R5cGVkZWYgeHNsdFN0eWxlQmFzaWNFbXB0eUl0ZW0geHNsdFN0eWxlSXRlbUNob29zZTsKK3R5cGVkZWYgeHNsdFN0eWxlSXRlbUNob29zZSAqeHNsdFN0eWxlSXRlbUNob29zZVB0cjsKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtRmFsbGJhY2s6CisgKgorICogPCEtLSBDYXRlZ29yeTogaW5zdHJ1Y3Rpb24gLS0+CisgKiAgPHhzbDpmYWxsYmFjaz4KKyAqICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICogPC94c2w6ZmFsbGJhY2s+CisgKi8KK3R5cGVkZWYgeHNsdFN0eWxlQmFzaWNFbXB0eUl0ZW0geHNsdFN0eWxlSXRlbUZhbGxiYWNrOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtRmFsbGJhY2sgKnhzbHRTdHlsZUl0ZW1GYWxsYmFja1B0cjsKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtRm9yRWFjaDoKKyAqCisgKiA8IS0tIENhdGVnb3J5OiBpbnN0cnVjdGlvbiAtLT4KKyAqIDx4c2w6Zm9yLWVhY2gKKyAqICAgc2VsZWN0ID0gbm9kZS1zZXQtZXhwcmVzc2lvbj4KKyAqICAgPCEtLSBDb250ZW50OiAoeHNsOnNvcnQqLCB0ZW1wbGF0ZSkgLS0+CisgKiA8L3hzbDpmb3ItZWFjaD4KKyAqLwordHlwZWRlZiB4c2x0U3R5bGVCYXNpY0V4cHJlc3Npb25JdGVtIHhzbHRTdHlsZUl0ZW1Gb3JFYWNoOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtRm9yRWFjaCAqeHNsdFN0eWxlSXRlbUZvckVhY2hQdHI7CisKKy8qKgorICogeHNsdFN0eWxlSXRlbU1lc3NhZ2U6CisgKgorICogPCEtLSBDYXRlZ29yeTogaW5zdHJ1Y3Rpb24gLS0+CisgKiA8eHNsOm1lc3NhZ2UKKyAqICAgdGVybWluYXRlID0gInllcyIgfCAibm8iPgorICogICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICogPC94c2w6bWVzc2FnZT4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1NZXNzYWdlIHhzbHRTdHlsZUl0ZW1NZXNzYWdlOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtTWVzc2FnZSAqeHNsdFN0eWxlSXRlbU1lc3NhZ2VQdHI7CisKK3N0cnVjdCBfeHNsdFN0eWxlSXRlbU1lc3NhZ2UgeworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTICAgIAorICAgIGludCB0ZXJtaW5hdGU7Cit9OworCisvKioKKyAqIHhzbHRTdHlsZUl0ZW1Eb2N1bWVudDoKKyAqCisgKiBOT1RFOiBUaGlzIGlzIG5vdCBhbiBpbnN0cnVjdGlvbiBvZiBYU0xUIDEuMC4KKyAqLwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1Eb2N1bWVudCB4c2x0U3R5bGVJdGVtRG9jdW1lbnQ7Cit0eXBlZGVmIHhzbHRTdHlsZUl0ZW1Eb2N1bWVudCAqeHNsdFN0eWxlSXRlbURvY3VtZW50UHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1Eb2N1bWVudCB7CisgICAgWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFMKKyAgICBpbnQgICAgICB2ZXIxMTsJCS8qIGFzc2lnbmVkOiBpbiB4c2x0RG9jdW1lbnRDb21wOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWQ6IG5vd2hlcmU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVE9ETzogQ2hlY2sgaWYgd2UgbmVlZC4gKi8KKyAgICBjb25zdCB4bWxDaGFyICpmaWxlbmFtZTsJLyogZG9jdW1lbnQgVVJMICovCisgICAgaW50IGhhc19maWxlbmFtZTsKK307ICAgCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICogTm9uLWluc3RydWN0aW9ucyAoYWN0dWFsbHkgcHJvcGVydGllcyBvZiBpbnN0cnVjdGlvbnMvZGVjbGFyYXRpb25zKSAgKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHRTdHlsZUJhc2ljSXRlbVZhcmlhYmxlOgorICoKKyAqIEJhc2ljIHN0cnVjdCBmb3IgeHNsOnZhcmlhYmxlLCB4c2w6cGFyYW0gYW5kIHhzbDp3aXRoLXBhcmFtLgorICogSXQncyBjdXJyZW50bHkgaW1wb3J0YW50IHRvIGhhdmUgZXF1YWwgZmllbGRzLCBzaW5jZQorICogeHNsdFBhcnNlU3R5bGVzaGVldENhbGxlclBhcmFtKCkgaXMgdXNlZCB3aXRoIHhzbDp3aXRoLXBhcmFtIGZyb20KKyAqIHRoZSB4c2x0IHNpZGUgYW5kIHdpdGggeHNsOnBhcmFtIGZyb20gdGhlIGV4c2x0IHNpZGUgKGluCisgKiBleHNsdEZ1bmNGdW5jdGlvbkZ1bmN0aW9uKCkpLgorICoKKyAqIEZVVFVSRSBOT1RFOiBJbiBYU0xUIDIuMCB4c2w6cGFyYW0sIHhzbDp2YXJpYWJsZSBhbmQgeHNsOndpdGgtcGFyYW0KKyAqICAgaGF2ZSBhZGRpdGlvbmFsIGRpZmZlcmVudCBmaWVsZHMuCisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0U3R5bGVCYXNpY0l0ZW1WYXJpYWJsZSB4c2x0U3R5bGVCYXNpY0l0ZW1WYXJpYWJsZTsKK3R5cGVkZWYgeHNsdFN0eWxlQmFzaWNJdGVtVmFyaWFibGUgKnhzbHRTdHlsZUJhc2ljSXRlbVZhcmlhYmxlUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUJhc2ljSXRlbVZhcmlhYmxlIHsKKyAgICBYU0xUX0lURU1fQ09NTU9OX0ZJRUxEUworCisgICAgY29uc3QgeG1sQ2hhciAqc2VsZWN0OworICAgIHhtbFhQYXRoQ29tcEV4cHJQdHIgY29tcDsKKworICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CisgICAgaW50ICAgICAgaGFzX25hbWU7CisgICAgY29uc3QgeG1sQ2hhciAqbnM7CisgICAgaW50ICAgICAgaGFzX25zOworfTsKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtVmFyaWFibGU6CisgKgorICogPCEtLSBDYXRlZ29yeTogdG9wLWxldmVsLWVsZW1lbnQgLS0+CisgKiA8eHNsOnBhcmFtCisgKiAgIG5hbWUgPSBxbmFtZQorICogICBzZWxlY3QgPSBleHByZXNzaW9uPgorICogICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICogPC94c2w6cGFyYW0+CisgKi8KK3R5cGVkZWYgeHNsdFN0eWxlQmFzaWNJdGVtVmFyaWFibGUgeHNsdFN0eWxlSXRlbVZhcmlhYmxlOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtVmFyaWFibGUgKnhzbHRTdHlsZUl0ZW1WYXJpYWJsZVB0cjsKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtUGFyYW06CisgKgorICogPCEtLSBDYXRlZ29yeTogdG9wLWxldmVsLWVsZW1lbnQgLS0+CisgKiA8eHNsOnBhcmFtCisgKiAgIG5hbWUgPSBxbmFtZQorICogICBzZWxlY3QgPSBleHByZXNzaW9uPgorICogICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICogPC94c2w6cGFyYW0+CisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0U3R5bGVJdGVtUGFyYW0geHNsdFN0eWxlSXRlbVBhcmFtOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtUGFyYW0gKnhzbHRTdHlsZUl0ZW1QYXJhbVB0cjsKKworc3RydWN0IF94c2x0U3R5bGVJdGVtUGFyYW0geworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTCisKKyAgICBjb25zdCB4bWxDaGFyICpzZWxlY3Q7CisgICAgeG1sWFBhdGhDb21wRXhwclB0ciBjb21wOworCisgICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKKyAgICBpbnQgICAgICBoYXNfbmFtZTsKKyAgICBjb25zdCB4bWxDaGFyICpuczsKKyAgICBpbnQgICAgICBoYXNfbnM7ICAgIAorfTsKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtV2l0aFBhcmFtOgorICoKKyAqIDx4c2w6d2l0aC1wYXJhbQorICogIG5hbWUgPSBxbmFtZQorICogIHNlbGVjdCA9IGV4cHJlc3Npb24+CisgKiAgPCEtLSBDb250ZW50OiB0ZW1wbGF0ZSAtLT4KKyAqIDwveHNsOndpdGgtcGFyYW0+CisgKi8KK3R5cGVkZWYgeHNsdFN0eWxlQmFzaWNJdGVtVmFyaWFibGUgeHNsdFN0eWxlSXRlbVdpdGhQYXJhbTsKK3R5cGVkZWYgeHNsdFN0eWxlSXRlbVdpdGhQYXJhbSAqeHNsdFN0eWxlSXRlbVdpdGhQYXJhbVB0cjsKKworLyoqCisgKiB4c2x0U3R5bGVJdGVtU29ydDoKKyAqCisgKiBSZWZsZWN0cyB0aGUgWFNMVCB4c2w6c29ydCBpdGVtLgorICogQWxsb3dlZCBwYXJlbnRzOiB4c2w6YXBwbHktdGVtcGxhdGVzLCB4c2w6Zm9yLWVhY2gKKyAqIDx4c2w6c29ydAorICogICBzZWxlY3QgPSBzdHJpbmctZXhwcmVzc2lvbgorICogICBsYW5nID0geyBubXRva2VuIH0KKyAqICAgZGF0YS10eXBlID0geyAidGV4dCIgfCAibnVtYmVyIiB8IHFuYW1lLWJ1dC1ub3QtbmNuYW1lIH0KKyAqICAgb3JkZXIgPSB7ICJhc2NlbmRpbmciIHwgImRlc2NlbmRpbmciIH0KKyAqICAgY2FzZS1vcmRlciA9IHsgInVwcGVyLWZpcnN0IiB8ICJsb3dlci1maXJzdCIgfSAvPgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbVNvcnQgeHNsdFN0eWxlSXRlbVNvcnQ7Cit0eXBlZGVmIHhzbHRTdHlsZUl0ZW1Tb3J0ICp4c2x0U3R5bGVJdGVtU29ydFB0cjsKKworc3RydWN0IF94c2x0U3R5bGVJdGVtU29ydCB7CisgICAgWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFMKKworICAgIGNvbnN0IHhtbENoYXIgKnN0eXBlOyAgICAgICAvKiBzb3J0ICovCisgICAgaW50ICAgICAgaGFzX3N0eXBlOwkJLyogc29ydCAqLworICAgIGludCAgICAgIG51bWJlcjsJCS8qIHNvcnQgKi8KKyAgICBjb25zdCB4bWxDaGFyICpvcmRlcjsJLyogc29ydCAqLworICAgIGludCAgICAgIGhhc19vcmRlcjsJCS8qIHNvcnQgKi8KKyAgICBpbnQgICAgICBkZXNjZW5kaW5nOwkvKiBzb3J0ICovCisgICAgY29uc3QgeG1sQ2hhciAqbGFuZzsJLyogc29ydCAqLworICAgIGludCAgICAgIGhhc19sYW5nOwkJLyogc29ydCAqLworICAgIHhzbHRMb2NhbGUgbG9jYWxlOwkJLyogc29ydCAqLworICAgIGNvbnN0IHhtbENoYXIgKmNhc2Vfb3JkZXI7CS8qIHNvcnQgKi8KKyAgICBpbnQgICAgICBsb3dlcl9maXJzdDsJLyogc29ydCAqLworCisgICAgY29uc3QgeG1sQ2hhciAqdXNlOworICAgIGludCAgICAgIGhhc191c2U7CisKKyAgICBjb25zdCB4bWxDaGFyICpzZWxlY3Q7CS8qIHNvcnQsIGNvcHktb2YsIHZhbHVlLW9mLCBhcHBseS10ZW1wbGF0ZXMgKi8KKworICAgIHhtbFhQYXRoQ29tcEV4cHJQdHIgY29tcDsJLyogYSBwcmVjb21waWxlZCBYUGF0aCBleHByZXNzaW9uICovCit9OworCisKKy8qKgorICogeHNsdFN0eWxlSXRlbVdoZW46CisgKiAKKyAqIDx4c2w6d2hlbgorICogICB0ZXN0ID0gYm9vbGVhbi1leHByZXNzaW9uPgorICogICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICogPC94c2w6d2hlbj4KKyAqIEFsbG93ZWQgcGFyZW50OiB4c2w6Y2hvb3NlCisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0U3R5bGVJdGVtV2hlbiB4c2x0U3R5bGVJdGVtV2hlbjsKK3R5cGVkZWYgeHNsdFN0eWxlSXRlbVdoZW4gKnhzbHRTdHlsZUl0ZW1XaGVuUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1XaGVuIHsKKyAgICBYU0xUX0lURU1fQ09NTU9OX0ZJRUxEUworCisgICAgY29uc3QgeG1sQ2hhciAqdGVzdDsKKyAgICB4bWxYUGF0aENvbXBFeHByUHRyIGNvbXA7Cit9OworCisvKioKKyAqIHhzbHRTdHlsZUl0ZW1PdGhlcndpc2U6CisgKgorICogQWxsb3dlZCBwYXJlbnQ6IHhzbDpjaG9vc2UKKyAqIDx4c2w6b3RoZXJ3aXNlPgorICogICA8IS0tIENvbnRlbnQ6IHRlbXBsYXRlIC0tPgorICogPC94c2w6b3RoZXJ3aXNlPgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbU90aGVyd2lzZSB4c2x0U3R5bGVJdGVtT3RoZXJ3aXNlOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtT3RoZXJ3aXNlICp4c2x0U3R5bGVJdGVtT3RoZXJ3aXNlUHRyOworCitzdHJ1Y3QgX3hzbHRTdHlsZUl0ZW1PdGhlcndpc2UgeworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTCit9OworCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbUluY2x1ZGUgeHNsdFN0eWxlSXRlbUluY2x1ZGU7Cit0eXBlZGVmIHhzbHRTdHlsZUl0ZW1JbmNsdWRlICp4c2x0U3R5bGVJdGVtSW5jbHVkZVB0cjsKKworc3RydWN0IF94c2x0U3R5bGVJdGVtSW5jbHVkZSB7CisgICAgWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFMKKyAgICB4c2x0RG9jdW1lbnRQdHIgaW5jbHVkZTsKK307CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICogIFhTTFQgZWxlbWVudHMgaW4gZm9yd2FyZHMtY29tcGF0aWJsZSBtb2RlICAgICAgICAgICAgICAgICAgICAgICAgICAgKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbVVrbm93biB4c2x0U3R5bGVJdGVtVWtub3duOwordHlwZWRlZiB4c2x0U3R5bGVJdGVtVWtub3duICp4c2x0U3R5bGVJdGVtVWtub3duUHRyOworc3RydWN0IF94c2x0U3R5bGVJdGVtVWtub3duIHsKKyAgICBYU0xUX0lURU1fQ09NTU9OX0ZJRUxEUworfTsKKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqICBFeHRlbnNpb24gZWxlbWVudHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoKKyAqIHhzbHRTdHlsZUl0ZW1FeHRFbGVtZW50OgorICoKKyAqIFJlZmxlY3RzIGV4dGVuc2lvbiBlbGVtZW50cy4KKyAqCisgKiBOT1RFOiBEdWUgdG8gdGhlIGZhY3QgdGhhdCB0aGUgc3RydWN0dXJlIHhzbHRFbGVtUHJlQ29tcCBpcyBtb3N0CisgKiBwcm9iYWJseSBhbHJlYWR5IGhlYXZpbHkgaW4gdXNlIG91dCB0aGVyZSBieSB1c2Vycywgc28gd2UgY2Fubm90CisgKiBlYXNpbHkgY2hhbmdlIGl0LCB3ZSdsbCBjcmVhdGUgYW4gaW50ZXJtZWRpYXRlIHN0cnVjdHVyZSB3aGljaCB3aWxsCisgKiBob2xkIGFuIHhzbHRFbGVtUHJlQ29tcFB0ci4KKyAqIEJJRyBOT1RFOiBUaGUgb25seSBwcm9ibGVtIEkgc2VlIGhlcmUgaXMgdGhhdCB0aGUgdXNlciBwcm9jZXNzZXMgdGhlCisgKiAgY29udGVudCBvZiB0aGUgc3R5bGVzaGVldCB0cmVlLCBwb3NzaWJseSBoZSdsbCBsb29rdXAgdGhlIG5vZGUtPnBzdmkKKyAqICBmaWVsZHMgaW4gb3JkZXIgdG8gZmluZCBzdWJzZXF1ZW50IGV4dGVuc2lvbiBmdW5jdGlvbnMuCisgKiAgSW4gdGhpcyBjYXNlLCB0aGUgdXNlcidzIGNvZGUgd2lsbCBicmVhaywgc2luY2UgdGhlIG5vZGUtPnBzdmkKKyAqICBmaWVsZCB3aWxsIGhvbGQgbm93IHRoZSB4c2x0U3R5bGVJdGVtRXh0RWxlbWVudFB0ciBhbmQgbm90CisgKiAgdGhlIHhzbHRFbGVtUHJlQ29tcFB0ci4KKyAqICBIb3dldmVyIHRoZSBwbGFjZSB3aGVyZSB0aGUgc3RydWN0dXJlIGlzIGFuY2hvcmVkIGluIHRoZSBub2RlLXRyZWUsCisgKiAgbmFtZWx5IG5vZGUtPnBzdmksIGhhcyBiZWVkIGFscmVhZHkgb25jZSBiZWVuIG1vdmVkIGZyb20gbm9kZS0+X3ByaXZhdGUKKyAqICB0byBub2RlLT5wc3ZpLCBzbyB3ZSBoYXZlIGEgcHJlY2VkZW50IGhlcmUsIHdoaWNoLCBJIHRoaW5rLCBzaG91bGQgYWxsb3cKKyAqICB1cyB0byBjaGFuZ2Ugc3VjaCBzZW1hbnRpY3Mgd2l0aG91dCBoZWFkYWNoZXMuCisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0U3R5bGVJdGVtRXh0RWxlbWVudCB4c2x0U3R5bGVJdGVtRXh0RWxlbWVudDsKK3R5cGVkZWYgeHNsdFN0eWxlSXRlbUV4dEVsZW1lbnQgKnhzbHRTdHlsZUl0ZW1FeHRFbGVtZW50UHRyOworc3RydWN0IF94c2x0U3R5bGVJdGVtRXh0RWxlbWVudCB7CisgICAgWFNMVF9JVEVNX0NPTU1PTl9GSUVMRFMKKyAgICB4c2x0RWxlbVByZUNvbXBQdHIgaXRlbTsgICAKK307CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqCQkJCQkJCQkJKgorICogIExpdGVyYWwgcmVzdWx0IGVsZW1lbnRzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgorICoJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit0eXBlZGVmIHN0cnVjdCBfeHNsdEVmZmVjdGl2ZU5zIHhzbHRFZmZlY3RpdmVOczsKK3R5cGVkZWYgeHNsdEVmZmVjdGl2ZU5zICp4c2x0RWZmZWN0aXZlTnNQdHI7CitzdHJ1Y3QgX3hzbHRFZmZlY3RpdmVOcyB7CisgICAgeHNsdEVmZmVjdGl2ZU5zUHRyIG5leHRJblN0b3JlOyAvKiBzdG9yYWdlIG5leHQgKi8KKyAgICB4c2x0RWZmZWN0aXZlTnNQdHIgbmV4dDsgLyogbmV4dCBpdGVtIGluIHRoZSBsaXN0ICovCisgICAgY29uc3QgeG1sQ2hhciAqcHJlZml4OworICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZTsKKyAgICAvKiAKKyAgICAqIEluZGljYXRlcyBpZiBlY2xhcmVkIG9uIHRoZSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50OyBkdW5ubyBpZiByZWFsbHkKKyAgICAqIG5lZWRlZC4KKyAgICAqLworICAgIGludCBob2xkQnlFbGVtOworfTsKKworLyoKKyAqIEluZm8gZm9yIGxpdGVyYWwgcmVzdWx0IGVsZW1lbnRzLgorICogVGhpcyB3aWxsIGJlIHNldCBvbiB0aGUgZWxlbS0+cHN2aSBmaWVsZCBhbmQgd2lsbCBiZQorICogc2hhcmVkIGJ5IGxpdGVyYWwgcmVzdWx0IGVsZW1lbnRzLCB3aGljaCBoYXZlIHRoZSBzYW1lCisgKiBleGNsdWRlZCByZXN1bHQgbmFtZXNwYWNlczsgaS5lLiwgdGhpcyAqd29uJ3QqIGJlIGNyZWF0ZWQgdW5pcXVlbHkKKyAqIGZvciBldmVyeSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50LgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0eWxlSXRlbUxSRWxlbWVudEluZm8geHNsdFN0eWxlSXRlbUxSRWxlbWVudEluZm87Cit0eXBlZGVmIHhzbHRTdHlsZUl0ZW1MUkVsZW1lbnRJbmZvICp4c2x0U3R5bGVJdGVtTFJFbGVtZW50SW5mb1B0cjsKK3N0cnVjdCBfeHNsdFN0eWxlSXRlbUxSRWxlbWVudEluZm8geworICAgIFhTTFRfSVRFTV9DT01NT05fRklFTERTCisgICAgLyoKKyAgICAqIEBlZmZlY3RpdmVOcyBpcyB0aGUgc2V0IG9mIGVmZmVjdGl2ZSBucy1ub2RlcworICAgICogIG9uIHRoZSBsaXRlcmFsIHJlc3VsdCBlbGVtZW50LCB3aGljaCB3aWxsIGJlIGFkZGVkIHRvIHRoZSByZXN1bHQKKyAgICAqICBlbGVtZW50IGlmIG5vdCBhbHJlYWR5IGV4aXN0aW5nIGluIHRoZSByZXN1bHQgdHJlZS4KKyAgICAqICBUaGlzIG1lYW5zIHRoYXQgZXhjbHVkZWQgbmFtZXNwYWNlcyAodmlhIGV4Y2x1ZGUtcmVzdWx0LXByZWZpeGVzLAorICAgICogIGV4dGVuc2lvbi1lbGVtZW50LXByZWZpeGVzIGFuZCB0aGUgWFNMVCBuYW1lc3BhY2UpIG5vdCBhZGRlZAorICAgICogIHRvIHRoZSBzZXQuCisgICAgKiAgTmFtZXNwYWNlLWFsaWFzaW5nIHdhcyBhcHBsaWVkIG9uIHRoZSBAZWZmZWN0aXZlTnMuCisgICAgKi8KKyAgICB4c2x0RWZmZWN0aXZlTnNQdHIgZWZmZWN0aXZlTnM7CisKK307CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwordHlwZWRlZiBzdHJ1Y3QgX3hzbHROc0FsaWFzIHhzbHROc0FsaWFzOwordHlwZWRlZiB4c2x0TnNBbGlhcyAqeHNsdE5zQWxpYXNQdHI7CitzdHJ1Y3QgX3hzbHROc0FsaWFzIHsKKyAgICB4c2x0TnNBbGlhc1B0ciBuZXh0OyAvKiBuZXh0IGluIHRoZSBsaXN0ICovICAgIAorICAgIHhtbE5zUHRyIGxpdGVyYWxOczsKKyAgICB4bWxOc1B0ciB0YXJnZXROczsKKyAgICB4bWxEb2NQdHIgZG9jT2ZUYXJnZXROczsKK307CisjZW5kaWYKKworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRF9YU0xUX05TQ09NUAorCit0eXBlZGVmIHN0cnVjdCBfeHNsdE5zTWFwIHhzbHROc01hcDsKK3R5cGVkZWYgeHNsdE5zTWFwICp4c2x0TnNNYXBQdHI7CitzdHJ1Y3QgX3hzbHROc01hcCB7CisgICAgeHNsdE5zTWFwUHRyIG5leHQ7IC8qIG5leHQgaW4gdGhlIGxpc3QgKi8KKyAgICB4bWxEb2NQdHIgZG9jOworICAgIHhtbE5vZGVQdHIgZWxlbTsgLyogdGhlIGVsZW1lbnQgaG9sZGluZyB0aGUgbnMtZGVjbCAqLworICAgIHhtbE5zUHRyIG5zOyAvKiB0aGUgeG1sTnMgc3RydWN0dXJlIGhvbGRpbmcgdGhlIFhNTCBuYW1lc3BhY2UgbmFtZSAqLworICAgIGNvbnN0IHhtbENoYXIgKm9yaWdOc05hbWU7IC8qIHRoZSBvcmlnaW5hbCBYTUwgbmFtZXNwYWNlIG5hbWUgKi8KKyAgICBjb25zdCB4bWxDaGFyICpuZXdOc05hbWU7IC8qIHRoZSBtYXBwZWQgWE1MIG5hbWVzcGFjZSBuYW1lICovICAgIAorfTsKKyNlbmRpZgorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKgkJCQkJCQkJCSoKKyAqICBDb21waWxlLXRpbWUgc3RydWN0dXJlcyBmb3IgKmludGVybmFsKiB1c2Ugb25seSAgICAgICAgICAgICAgICAgICAgICoKKyAqCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKwordHlwZWRlZiBzdHJ1Y3QgX3hzbHRQcmluY2lwYWxTdHlsZXNoZWV0RGF0YSB4c2x0UHJpbmNpcGFsU3R5bGVzaGVldERhdGE7Cit0eXBlZGVmIHhzbHRQcmluY2lwYWxTdHlsZXNoZWV0RGF0YSAqeHNsdFByaW5jaXBhbFN0eWxlc2hlZXREYXRhUHRyOworCit0eXBlZGVmIHN0cnVjdCBfeHNsdE5zTGlzdCB4c2x0TnNMaXN0OwordHlwZWRlZiB4c2x0TnNMaXN0ICp4c2x0TnNMaXN0UHRyOworc3RydWN0IF94c2x0TnNMaXN0IHsKKyAgICB4c2x0TnNMaXN0UHRyIG5leHQ7IC8qIG5leHQgaW4gdGhlIGxpc3QgKi8KKyAgICB4bWxOc1B0ciBuczsKK307CisKKy8qCisqIHhzbHRWYXJJbmZvOgorKgorKiBVc2VkIGF0IGNvbXBpbGF0aW9uIHRpbWUgZm9yIHBhcmFtZXRlcnMgYW5kIHZhcmlhYmxlcy4KKyovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFZhckluZm8geHNsdFZhckluZm87Cit0eXBlZGVmIHhzbHRWYXJJbmZvICp4c2x0VmFySW5mb1B0cjsKK3N0cnVjdCBfeHNsdFZhckluZm8geworICAgIHhzbHRWYXJJbmZvUHRyIG5leHQ7IC8qIG5leHQgaW4gdGhlIGxpc3QgKi8KKyAgICB4c2x0VmFySW5mb1B0ciBwcmV2OworICAgIGludCBkZXB0aDsgLyogdGhlIGRlcHRoIGluIHRoZSB0cmVlICovCisgICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKKyAgICBjb25zdCB4bWxDaGFyICpuc05hbWU7Cit9OworCisvKioKKyAqIHhzbHRDb21waWxlck5vZGVJbmZvOgorICoKKyAqIFBlci1ub2RlIGluZm9ybWF0aW9uIGR1cmluZyBjb21waWxlLXRpbWUuCisgKi8KK3R5cGVkZWYgc3RydWN0IF94c2x0Q29tcGlsZXJOb2RlSW5mbyB4c2x0Q29tcGlsZXJOb2RlSW5mbzsKK3R5cGVkZWYgeHNsdENvbXBpbGVyTm9kZUluZm8gKnhzbHRDb21waWxlck5vZGVJbmZvUHRyOworc3RydWN0IF94c2x0Q29tcGlsZXJOb2RlSW5mbyB7CisgICAgeHNsdENvbXBpbGVyTm9kZUluZm9QdHIgbmV4dDsKKyAgICB4c2x0Q29tcGlsZXJOb2RlSW5mb1B0ciBwcmV2OworICAgIHhtbE5vZGVQdHIgbm9kZTsKKyAgICBpbnQgZGVwdGg7CisgICAgeHNsdFRlbXBsYXRlUHRyIHRlbXBsOyAgIC8qIFRoZSBvd25pbmcgdGVtcGxhdGUgKi8KKyAgICBpbnQgY2F0ZWdvcnk7CSAgICAgLyogWFNMVCBlbGVtZW50LCBMUi1lbGVtZW50IG9yCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbiBlbGVtZW50ICovCisgICAgeHNsdFN0eWxlVHlwZSB0eXBlOworICAgIHhzbHRFbGVtUHJlQ29tcFB0ciBpdGVtOyAvKiBUaGUgY29tcGlsZWQgaW5mb3JtYXRpb24gKi8KKyAgICAvKiBUaGUgY3VycmVudCBpbi1zY29wZSBuYW1lc3BhY2VzICovCisgICAgeHNsdE5zTGlzdENvbnRhaW5lclB0ciBpblNjb3BlTnM7CisgICAgLyogVGhlIGN1cnJlbnQgZXhjbHVkZWQgcmVzdWx0IG5hbWVzcGFjZXMgKi8KKyAgICB4c2x0UG9pbnRlckxpc3RQdHIgZXhjbFJlc3VsdE5zOyAKKyAgICAvKiBUaGUgY3VycmVudCBleHRlbnNpb24gaW5zdHJ1Y3Rpb24gbmFtZXNwYWNlcyAqLworICAgIHhzbHRQb2ludGVyTGlzdFB0ciBleHRFbGVtTnM7CisKKyAgICAvKiBUaGUgY3VycmVudCBpbmZvIGZvciBsaXRlcmFsIHJlc3VsdCBlbGVtZW50cy4gKi8KKyAgICB4c2x0U3R5bGVJdGVtTFJFbGVtZW50SW5mb1B0ciBsaXRSZXNFbGVtSW5mbzsKKyAgICAvKiAKKyAgICAqIFNldCB0byAxIGlmIGluLXNjb3BlIG5hbWVzcGFjZXMgY2hhbmdlZCwKKyAgICAqICBvciBleGNsdWRlZCByZXN1bHQgbmFtZXNwYWNlcyBjaGFuZ2VkLAorICAgICogIG9yIGV4dGVuc2lvbiBlbGVtZW50IG5hbWVzcGFjZXMgY2hhbmdlZC4KKyAgICAqIFRoaXMgd2lsbCB0cmlnZ2VyIGNyZWF0aW9uIG9mIG5ldyBpbmZvcworICAgICogIGZvciBsaXRlcmFsIHJlc3VsdCBlbGVtZW50cy4KKyAgICAqLworICAgIGludCBuc0NoYW5nZWQ7CisgICAgaW50IHByZXNlcnZlV2hpdGVzcGFjZTsKKyAgICBpbnQgc3RyaXBXaGl0ZXNwYWNlOworICAgIGludCBpc1Jvb3Q7IC8qIHdoZXRoZXIgdGhpcyBpcyB0aGUgc3R5bGVzaGVldCdzIHJvb3Qgbm9kZSAqLworICAgIGludCBmb3J3YXJkc0NvbXBhdDsgLyogd2hldGhlciBmb3J3YXJkcy1jb21wYXRpYmxlIG1vZGUgaXMgZW5hYmxlZCAqLworICAgIC8qIHdoZXRoZXIgdGhlIGNvbnRlbnQgb2YgYW4gZXh0ZW5zaW9uIGVsZW1lbnQgd2FzIHByb2Nlc3NlZCAqLworICAgIGludCBleHRDb250ZW50SGFuZGxlZDsKKyAgICAvKiB0aGUgdHlwZSBvZiB0aGUgY3VycmVudCBjaGlsZCAqLworICAgIHhzbHRTdHlsZVR5cGUgY3VyQ2hpbGRUeXBlOyAgICAKK307CisKKy8qKgorICogWFNMVF9DQ1RYVDoKKyAqCisgKiBnZXQgcG9pbnRlciB0byBjb21waWxlciBjb250ZXh0CisgKi8KKyNkZWZpbmUgWFNMVF9DQ1RYVChzdHlsZSkgKCh4c2x0Q29tcGlsZXJDdHh0UHRyKSBzdHlsZS0+Y29tcEN0eHQpIAorCit0eXBlZGVmIGVudW0geworICAgIFhTTFRfRVJST1JfU0VWRVJJVFlfRVJST1IgPSAwLAorICAgIFhTTFRfRVJST1JfU0VWRVJJVFlfV0FSTklORworfSB4c2x0RXJyb3JTZXZlcml0eVR5cGU7CisKK3R5cGVkZWYgc3RydWN0IF94c2x0Q29tcGlsZXJDdHh0IHhzbHRDb21waWxlckN0eHQ7Cit0eXBlZGVmIHhzbHRDb21waWxlckN0eHQgKnhzbHRDb21waWxlckN0eHRQdHI7CitzdHJ1Y3QgX3hzbHRDb21waWxlckN0eHQgeworICAgIHZvaWQgKmVycm9yQ3R4dDsgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIGVycm9yIGNvbnRleHQgKi8KKyAgICAvKgorICAgICogdXNlZCBmb3IgZXJyb3Ivd2FybmluZyByZXBvcnRzOyBlLmcuIFhTTFRfRVJST1JfU0VWRVJJVFlfV0FSTklORyAqLworICAgIHhzbHRFcnJvclNldmVyaXR5VHlwZSBlcnJTZXZlcml0eTsJCQorICAgIGludCB3YXJuaW5nczsJCS8qIFRPRE86IG51bWJlciBvZiB3YXJuaW5ncyBmb3VuZCBhdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxhdGlvbiAqLworICAgIGludCBlcnJvcnM7CQkJLyogVE9ETzogbnVtYmVyIG9mIGVycm9ycyBmb3VuZCBhdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxhdGlvbiAqLworICAgIHhtbERpY3RQdHIgZGljdDsKKyAgICB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZTsKKyAgICBpbnQgc2ltcGxpZmllZDsgLyogd2hldGhlciB0aGlzIGlzIGEgc2ltcGxpZmllZCBzdHlsZXNoZWV0ICovCisgICAgLyogVE9ETzogc3RydWN0dXJlZC91bnN0cnVjdHVyZWQgZXJyb3IgY29udGV4dHMuICovCisgICAgaW50IGRlcHRoOyAvKiBDdXJyZW50IGRlcHRoIG9mIHByb2Nlc3NpbmcgKi8KKyAgICAKKyAgICB4c2x0Q29tcGlsZXJOb2RlSW5mb1B0ciBpbm9kZTsKKyAgICB4c2x0Q29tcGlsZXJOb2RlSW5mb1B0ciBpbm9kZUxpc3Q7CisgICAgeHNsdENvbXBpbGVyTm9kZUluZm9QdHIgaW5vZGVMYXN0OworICAgIHhzbHRQb2ludGVyTGlzdFB0ciB0bXBMaXN0OyAvKiBVc2VkIGZvciB2YXJpb3VzIHB1cnBvc2VzICovCisgICAgLyoKKyAgICAqIFRoZSBYU0xUIHZlcnNpb24gYXMgc3BlY2lmaWVkIGJ5IHRoZSBzdHlsZXNoZWV0J3Mgcm9vdCBlbGVtZW50LgorICAgICovCisgICAgaW50IGlzSW5jbHVkZTsKKyAgICBpbnQgaGFzRm9yd2FyZHNDb21wYXQ7IC8qIHdoZXRoZXIgZm9yd2FyZHMtY29tcGF0aWJsZSBtb2RlIHdhcyB1c2VkCisJCQkgICAgIGluIGEgcGFyc2luZyBlcGlzb2RlICovCisgICAgaW50IG1heE5vZGVJbmZvczsgLyogVEVNUCBUT0RPOiBqdXN0IGZvciB0aGUgaW50ZXJlc3QgKi8KKyAgICBpbnQgbWF4TFJFczsgIC8qIFRFTVAgVE9ETzoganVzdCBmb3IgdGhlIGludGVyZXN0ICovCisgICAgLyogCisgICAgKiBJbiBvcmRlciB0byBrZWVwIHRoZSBvbGQgYmVoYXZpb3VyLCBhcHBseWluZyBzdHJpY3QgcnVsZXMgb2YKKyAgICAqIHRoZSBzcGVjIGNhbiBiZSB0dXJuZWQgb2ZmLiBUaGlzIGhhcyBlZmZlY3Qgb25seSBvbiBzcGVjaWFsCisgICAgKiBtZWNoYW5pc21zIGxpa2Ugd2hpdGVzcGFjZS1zdHJpcHBpbmcgaW4gdGhlIHN0eWxlc2hlZXQuCisgICAgKi8KKyAgICBpbnQgc3RyaWN0OworICAgIHhzbHRQcmluY2lwYWxTdHlsZXNoZWV0RGF0YVB0ciBwc0RhdGE7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVEX1hQQVRIQ09NUAorICAgIHhtbFhQYXRoQ29udGV4dFB0ciB4cGF0aEN0eHQ7CisjZW5kaWYKKyAgICB4c2x0U3R5bGVJdGVtVWtub3duUHRyIHVua25vd25JdGVtOworICAgIGludCBoYXNOc0FsaWFzZXM7IC8qIEluZGljYXRvciBpZiB0aGVyZSB3YXMgYW4geHNsOm5hbWVzcGFjZS1hbGlhcy4gKi8KKyAgICB4c2x0TnNBbGlhc1B0ciBuc0FsaWFzZXM7CisgICAgeHNsdFZhckluZm9QdHIgaXZhcnM7IC8qIFN0b3JhZ2Ugb2YgbG9jYWwgaW4tc2NvcGUgdmFyaWFibGVzL3BhcmFtcy4gKi8KKyAgICB4c2x0VmFySW5mb1B0ciBpdmFyOyAvKiB0b3Btb3N0IGxvY2FsIHZhcmlhYmxlL3BhcmFtLiAqLworfTsgICAKKworI2Vsc2UgLyogWFNMVF9SRUZBQ1RPUkVEICovCisvKgorKiBUaGUgb2xkIHN0cnVjdHVyZXMgYmVmb3JlIHJlZmFjdG9yaW5nLgorKi8KKworLyoqCisgKiBfeHNsdFN0eWxlUHJlQ29tcDoKKyAqCisgKiBUaGUgaW4tbWVtb3J5IHN0cnVjdHVyZSBjb3JyZXNwb25kaW5nIHRvIFhTTFQgc3R5bGVzaGVldCBjb25zdHJ1Y3RzCisgKiBwcmVjb21wdXRlZCBkYXRhLgorICovCitzdHJ1Y3QgX3hzbHRTdHlsZVByZUNvbXAgeworICAgIHhzbHRFbGVtUHJlQ29tcFB0ciBuZXh0OwkvKiBjaGFpbmVkIGxpc3QgKi8KKyAgICB4c2x0U3R5bGVUeXBlIHR5cGU7CQkvKiB0eXBlIG9mIHRoZSBlbGVtZW50ICovCisgICAgeHNsdFRyYW5zZm9ybUZ1bmN0aW9uIGZ1bmM7IC8qIGhhbmRsaW5nIGZ1bmN0aW9uICovCisgICAgeG1sTm9kZVB0ciBpbnN0OwkJLyogdGhlIGluc3RydWN0aW9uICovCisKKyAgICAvKgorICAgICAqIFByZSBjb21wdXRlZCB2YWx1ZXMuCisgICAgICovCisKKyAgICBjb25zdCB4bWxDaGFyICpzdHlwZTsgICAgICAgLyogc29ydCAqLworICAgIGludCAgICAgIGhhc19zdHlwZTsJCS8qIHNvcnQgKi8KKyAgICBpbnQgICAgICBudW1iZXI7CQkvKiBzb3J0ICovCisgICAgY29uc3QgeG1sQ2hhciAqb3JkZXI7CS8qIHNvcnQgKi8KKyAgICBpbnQgICAgICBoYXNfb3JkZXI7CQkvKiBzb3J0ICovCisgICAgaW50ICAgICAgZGVzY2VuZGluZzsJLyogc29ydCAqLworICAgIGNvbnN0IHhtbENoYXIgKmxhbmc7CS8qIHNvcnQgKi8KKyAgICBpbnQgICAgICBoYXNfbGFuZzsJCS8qIHNvcnQgKi8KKyAgICB4c2x0TG9jYWxlIGxvY2FsZTsJCS8qIHNvcnQgKi8KKyAgICBjb25zdCB4bWxDaGFyICpjYXNlX29yZGVyOwkvKiBzb3J0ICovCisgICAgaW50ICAgICAgbG93ZXJfZmlyc3Q7CS8qIHNvcnQgKi8KKworICAgIGNvbnN0IHhtbENoYXIgKnVzZTsJCS8qIGNvcHksIGVsZW1lbnQgKi8KKyAgICBpbnQgICAgICBoYXNfdXNlOwkJLyogY29weSwgZWxlbWVudCAqLworCisgICAgaW50ICAgICAgbm9lc2NhcGU7CQkvKiB0ZXh0ICovCisKKyAgICBjb25zdCB4bWxDaGFyICpuYW1lOwkvKiBlbGVtZW50LCBhdHRyaWJ1dGUsIHBpICovCisgICAgaW50ICAgICAgaGFzX25hbWU7CQkvKiBlbGVtZW50LCBhdHRyaWJ1dGUsIHBpICovCisgICAgY29uc3QgeG1sQ2hhciAqbnM7CQkvKiBlbGVtZW50ICovCisgICAgaW50ICAgICAgaGFzX25zOwkJLyogZWxlbWVudCAqLworCisgICAgY29uc3QgeG1sQ2hhciAqbW9kZTsJLyogYXBwbHktdGVtcGxhdGVzICovCisgICAgY29uc3QgeG1sQ2hhciAqbW9kZVVSSTsJLyogYXBwbHktdGVtcGxhdGVzICovCisKKyAgICBjb25zdCB4bWxDaGFyICp0ZXN0OwkvKiBpZiAqLworCisgICAgeHNsdFRlbXBsYXRlUHRyIHRlbXBsOwkvKiBjYWxsLXRlbXBsYXRlICovCisKKyAgICBjb25zdCB4bWxDaGFyICpzZWxlY3Q7CS8qIHNvcnQsIGNvcHktb2YsIHZhbHVlLW9mLCBhcHBseS10ZW1wbGF0ZXMgKi8KKworICAgIGludCAgICAgIHZlcjExOwkJLyogZG9jdW1lbnQgKi8KKyAgICBjb25zdCB4bWxDaGFyICpmaWxlbmFtZTsJLyogZG9jdW1lbnQgVVJMICovCisgICAgaW50ICAgICAgaGFzX2ZpbGVuYW1lOwkvKiBkb2N1bWVudCAqLworCisgICAgeHNsdE51bWJlckRhdGEgbnVtZGF0YTsJLyogbnVtYmVyICovCisKKyAgICB4bWxYUGF0aENvbXBFeHByUHRyIGNvbXA7CS8qIGEgcHJlY29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbiAqLworICAgIHhtbE5zUHRyICpuc0xpc3Q7CQkvKiB0aGUgbmFtZXNwYWNlcyBpbiBzY29wZSAqLworICAgIGludCBuc05yOwkJCS8qIHRoZSBudW1iZXIgb2YgbmFtZXNwYWNlcyBpbiBzY29wZSAqLworfTsKKworI2VuZGlmIC8qIFhTTFRfUkVGQUNUT1JFRCAqLworCisKKy8qCisgKiBUaGUgaW4tbWVtb3J5IHN0cnVjdHVyZSBjb3JyZXNwb25kaW5nIHRvIGFuIFhTTFQgVmFyaWFibGUKKyAqIG9yIFBhcmFtLgorICovCit0eXBlZGVmIHN0cnVjdCBfeHNsdFN0YWNrRWxlbSB4c2x0U3RhY2tFbGVtOwordHlwZWRlZiB4c2x0U3RhY2tFbGVtICp4c2x0U3RhY2tFbGVtUHRyOworc3RydWN0IF94c2x0U3RhY2tFbGVtIHsKKyAgICBzdHJ1Y3QgX3hzbHRTdGFja0VsZW0gKm5leHQ7LyogY2hhaW5lZCBsaXN0ICovCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wOyAgIC8qIHRoZSBjb21waWxlZCBmb3JtICovCisgICAgaW50IGNvbXB1dGVkOwkJLyogd2FzIHRoZSBldmFsdWF0aW9uIGRvbmUgKi8KKyAgICBjb25zdCB4bWxDaGFyICpuYW1lOwkvKiB0aGUgbG9jYWwgcGFydCBvZiB0aGUgbmFtZSBRTmFtZSAqLworICAgIGNvbnN0IHhtbENoYXIgKm5hbWVVUkk7CS8qIHRoZSBVUkkgcGFydCBvZiB0aGUgbmFtZSBRTmFtZSAqLworICAgIGNvbnN0IHhtbENoYXIgKnNlbGVjdDsJLyogdGhlIGV2YWwgc3RyaW5nICovCisgICAgeG1sTm9kZVB0ciB0cmVlOwkJLyogdGhlIHNlcXVlbmNlIGNvbnN0cnVjdG9yIGlmIG5vIGV2YWwKKwkJCQkgICAgc3RyaW5nIG9yIHRoZSBsb2NhdGlvbiAqLworICAgIHhtbFhQYXRoT2JqZWN0UHRyIHZhbHVlOwkvKiBUaGUgdmFsdWUgaWYgY29tcHV0ZWQgKi8KKyAgICB4bWxEb2NQdHIgZnJhZ21lbnQ7CQkvKiBUaGUgUmVzdWx0IFRyZWUgRnJhZ21lbnRzIChuZWVkZWQgZm9yIFhTTFQgMS4wKQorCQkJCSAgIHdoaWNoIGFyZSBib3VuZCB0byB0aGUgdmFyaWFibGUncyBsaWZldGltZS4gKi8KKyAgICBpbnQgbGV2ZWw7ICAgICAgICAgICAgICAgICAgLyogdGhlIGRlcHRoIGluIHRoZSB0cmVlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtMSBpZiBwZXJzaXN0ZW50IChlLmcuIGEgZ2l2ZW4geHNsOndpdGgtcGFyYW0pICovCisgICAgeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY29udGV4dDsgLyogVGhlIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQ7IG5lZWRlZCB0byBjYWNoZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSB2YXJpYWJsZXMgKi8KKyAgICBpbnQgZmxhZ3M7Cit9OworCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisKK3N0cnVjdCBfeHNsdFByaW5jaXBhbFN0eWxlc2hlZXREYXRhIHsKKyAgICAvKgorICAgICogTmFtZXNwYWNlIGRpY3Rpb25hcnkgZm9yIG5zLXByZWZpeGVzIGFuZCBucy1uYW1lczoKKyAgICAqIFRPRE86IFNoYXJlZCBiZXR3ZWVuIHN0eWxlc2hlZXRzLCBhbmQgWFBhdGggbWVjaGFuaXNtcy4KKyAgICAqICAgTm90IHVzZWQgeWV0LgorICAgICovCisgICAgeG1sRGljdFB0ciBuYW1lc3BhY2VEaWN0OworICAgIC8qCisgICAgKiBHbG9iYWwgbGlzdCBvZiBpbi1zY29wZSBuYW1lc3BhY2VzLgorICAgICovCisgICAgeHNsdFBvaW50ZXJMaXN0UHRyIGluU2NvcGVOYW1lc3BhY2VzOworICAgIC8qCisgICAgKiBHbG9iYWwgbGlzdCBvZiBpbmZvcm1hdGlvbiBmb3IgW3hzbDpdZXhjbHVkZWQtcmVzdWx0LXByZWZpeGVzLgorICAgICovCisgICAgeHNsdFBvaW50ZXJMaXN0UHRyIGV4Y2xSZXN1bHROYW1lc3BhY2VzOworICAgIC8qCisgICAgKiBHbG9iYWwgbGlzdCBvZiBpbmZvcm1hdGlvbiBmb3IgW3hzbDpdZXh0ZW5zaW9uLWVsZW1lbnQtcHJlZml4ZXMuCisgICAgKi8KKyAgICB4c2x0UG9pbnRlckxpc3RQdHIgZXh0RWxlbU5hbWVzcGFjZXM7CisgICAgeHNsdEVmZmVjdGl2ZU5zUHRyIGVmZmVjdGl2ZU5zOworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRF9YU0xUX05TQ09NUAorICAgIC8qCisgICAgKiBOYW1lc3BhY2UgbmFtZSBtYXAgdG8gZ2V0IHJpZCBvZiBzdHJpbmcgY29tcGFyaXNvbiBvZiBuYW1lc3BhY2UgbmFtZXMuCisgICAgKi8KKyAgICB4c2x0TnNNYXBQdHIgbnNNYXA7CisjZW5kaWYKK307CisKKyAgICAKKyNlbmRpZgorLyoKKyAqIE5vdGUgdGhhdCB3ZSBhZGRlZCBhIEBjb21wQ3R4dCBmaWVsZCB0byBhbmNob3IgYW4gc3R5bGVzaGVldCBjb21waWxhdGlvbgorICogY29udGV4dCwgc2luY2UsIGR1ZSB0byBoaXN0b3JpY2FsIHJlYXNvbnMsIHZhcmlvdXMgY29tcGlsZS10aW1lIGZ1bmN0aW9uCisgKiB0YWtlIG9ubHkgdGhlIHN0eWxlc2hlZXQgYXMgYXJndW1lbnQgYW5kIG5vdCBhIGNvbXBpbGF0aW9uIGNvbnRleHQuCisgKi8KK3N0cnVjdCBfeHNsdFN0eWxlc2hlZXQgeworICAgIC8qCisgICAgICogVGhlIHN0eWxlc2hlZXQgaW1wb3J0IHJlbGF0aW9uIGlzIGtlcHQgYXMgYSB0cmVlLgorICAgICAqLworICAgIHN0cnVjdCBfeHNsdFN0eWxlc2hlZXQgKnBhcmVudDsKKyAgICBzdHJ1Y3QgX3hzbHRTdHlsZXNoZWV0ICpuZXh0OworICAgIHN0cnVjdCBfeHNsdFN0eWxlc2hlZXQgKmltcG9ydHM7CisKKyAgICB4c2x0RG9jdW1lbnRQdHIgZG9jTGlzdDsJCS8qIHRoZSBpbmNsdWRlIGRvY3VtZW50IGxpc3QgKi8KKworICAgIC8qCisgICAgICogR2VuZXJhbCBkYXRhIG9uIHRoZSBzdHlsZSBzaGVldCBkb2N1bWVudC4KKyAgICAgKi8KKyAgICB4bWxEb2NQdHIgZG9jOwkJLyogdGhlIHBhcnNlZCBYTUwgc3R5bGVzaGVldCAqLworICAgIHhtbEhhc2hUYWJsZVB0ciBzdHJpcFNwYWNlczsvKiB0aGUgaGFzaCB0YWJsZSBvZiB0aGUgc3RyaXAtc3BhY2UgYW5kCisJCQkJICAgcHJlc2VydmUgc3BhY2UgZWxlbWVudHMgKi8KKyAgICBpbnQgICAgICAgICAgICAgc3RyaXBBbGw7CS8qIHN0cmlwLXNwYWNlICogKDEpIHByZXNlcnZlLXNwYWNlICogKC0xKSAqLworICAgIHhtbEhhc2hUYWJsZVB0ciBjZGF0YVNlY3Rpb247LyogdGhlIGhhc2ggdGFibGUgb2YgdGhlIGNkYXRhLXNlY3Rpb24gKi8KKworICAgIC8qCisgICAgICogR2xvYmFsIHZhcmlhYmxlIG9yIHBhcmFtZXRlcnMuCisgICAgICovCisgICAgeHNsdFN0YWNrRWxlbVB0ciB2YXJpYWJsZXM7IC8qIGxpbmtlZCBsaXN0IG9mIHBhcmFtIGFuZCB2YXJpYWJsZXMgKi8KKworICAgIC8qCisgICAgICogVGVtcGxhdGUgZGVzY3JpcHRpb25zLgorICAgICAqLworICAgIHhzbHRUZW1wbGF0ZVB0ciB0ZW1wbGF0ZXM7CS8qIHRoZSBvcmRlcmVkIGxpc3Qgb2YgdGVtcGxhdGVzICovCisgICAgdm9pZCAqdGVtcGxhdGVzSGFzaDsJLyogaGFzaCB0YWJsZSBvciB3aGVyZXZlciBjb21waWxlZCB0ZW1wbGF0ZXMKKwkJCQkgICBpbmZvcm1hdGlvbnMgYXJlIHN0b3JlZCAqLworICAgIHZvaWQgKnJvb3RNYXRjaDsJCS8qIHRlbXBsYXRlIGJhc2VkIG9uIC8gKi8KKyAgICB2b2lkICprZXlNYXRjaDsJCS8qIHRlbXBsYXRlIGJhc2VkIG9uIGtleSgpICovCisgICAgdm9pZCAqZWxlbU1hdGNoOwkJLyogdGVtcGxhdGUgYmFzZWQgb24gKiAqLworICAgIHZvaWQgKmF0dHJNYXRjaDsJCS8qIHRlbXBsYXRlIGJhc2VkIG9uIEAqICovCisgICAgdm9pZCAqcGFyZW50TWF0Y2g7CQkvKiB0ZW1wbGF0ZSBiYXNlZCBvbiAuLiAqLworICAgIHZvaWQgKnRleHRNYXRjaDsJCS8qIHRlbXBsYXRlIGJhc2VkIG9uIHRleHQoKSAqLworICAgIHZvaWQgKnBpTWF0Y2g7CQkvKiB0ZW1wbGF0ZSBiYXNlZCBvbiBwcm9jZXNzaW5nLWluc3RydWN0aW9uKCkgKi8KKyAgICB2b2lkICpjb21tZW50TWF0Y2g7CQkvKiB0ZW1wbGF0ZSBiYXNlZCBvbiBjb21tZW50KCkgKi8KKyAgICAKKyAgICAvKgorICAgICAqIE5hbWVzcGFjZSBhbGlhc2VzLgorICAgICAqIE5PVEU6IE5vdCB1c2VkIGluIHRoZSByZWZhY3RvcmVkIGNvZGUuCisgICAgICovCisgICAgeG1sSGFzaFRhYmxlUHRyIG5zQWxpYXNlczsJLyogdGhlIG5hbWVzcGFjZSBhbGlhcyBoYXNoIHRhYmxlcyAqLworCisgICAgLyoKKyAgICAgKiBBdHRyaWJ1dGUgc2V0cy4KKyAgICAgKi8KKyAgICB4bWxIYXNoVGFibGVQdHIgYXR0cmlidXRlU2V0czsvKiB0aGUgYXR0cmlidXRlIHNldHMgaGFzaCB0YWJsZXMgKi8KKworICAgIC8qCisgICAgICogTmFtZXNwYWNlcy4KKyAgICAgKiBUT0RPOiBFbGltaW5hdGUgdGhpcy4KKyAgICAgKi8KKyAgICB4bWxIYXNoVGFibGVQdHIgbnNIYXNoOyAgICAgLyogdGhlIHNldCBvZiBuYW1lc3BhY2VzIGluIHVzZToKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVRURU5USU9OOiBUaGlzIGlzIHVzZWQgZm9yCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGlvbiBvZiBYUGF0aCBleHByZXNzaW9uczsgdW5mb3J0dW5hdGVseQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCByZXN0cmljdHMgdGhlIHN0eWxlc2hlZXQgdG8gaGF2ZSBkaXN0aW5jdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhlcy4KKwkJCQkgICBUT0RPOiBXZSBuZWVkIHRvIGdldCByaWQgb2YgdGhpcy4gICAgCisJCQkJICovCisgICAgdm9pZCAgICAgICAgICAgKm5zRGVmczsgICAgIC8qIEFUVEVOVElPTiBUT0RPOiBUaGlzIGlzIGN1cnJlbnRseSB1c2VkIHRvIHN0b3JlCisJCQkJICAgeHNsdEV4dERlZlB0ciAoaW4gZXh0ZW5zaW9ucy5jKSBhbmQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5vdCogeG1sTnNQdHIuCisJCQkJICovCisKKyAgICAvKgorICAgICAqIEtleSBkZWZpbml0aW9ucy4KKyAgICAgKi8KKyAgICB2b2lkICprZXlzOwkJCS8qIGtleSBkZWZpbml0aW9ucyAqLworCisgICAgLyoKKyAgICAgKiBPdXRwdXQgcmVsYXRlZCBzdHVmZi4KKyAgICAgKi8KKyAgICB4bWxDaGFyICptZXRob2Q7CQkvKiB0aGUgb3V0cHV0IG1ldGhvZCAqLworICAgIHhtbENoYXIgKm1ldGhvZFVSSTsJCS8qIGFzc29jaWF0ZWQgbmFtZXNwYWNlIGlmIGFueSAqLworICAgIHhtbENoYXIgKnZlcnNpb247CQkvKiB2ZXJzaW9uIHN0cmluZyAqLworICAgIHhtbENoYXIgKmVuY29kaW5nOwkJLyogZW5jb2Rpbmcgc3RyaW5nICovCisgICAgaW50IG9taXRYbWxEZWNsYXJhdGlvbjsgICAgIC8qIG9taXQteG1sLWRlY2xhcmF0aW9uID0gInllcyIgfCAibm8iICovCisKKyAgICAvKiAKKyAgICAgKiBOdW1iZXIgZm9ybWF0dGluZy4KKyAgICAgKi8KKyAgICB4c2x0RGVjaW1hbEZvcm1hdFB0ciBkZWNpbWFsRm9ybWF0OworICAgIGludCBzdGFuZGFsb25lOyAgICAgICAgICAgICAvKiBzdGFuZGFsb25lID0gInllcyIgfCAibm8iICovCisgICAgeG1sQ2hhciAqZG9jdHlwZVB1YmxpYzsgICAgIC8qIGRvY3R5cGUtcHVibGljIHN0cmluZyAqLworICAgIHhtbENoYXIgKmRvY3R5cGVTeXN0ZW07ICAgICAvKiBkb2N0eXBlLXN5c3RlbSBzdHJpbmcgKi8KKyAgICBpbnQgaW5kZW50OwkJCS8qIHNob3VsZCBvdXRwdXQgYmVpbmcgaW5kZW50ZWQgKi8KKyAgICB4bWxDaGFyICptZWRpYVR5cGU7CQkvKiBtZWRpYS10eXBlIHN0cmluZyAqLworCisgICAgLyoKKyAgICAgKiBQcmVjb21wdXRlZCBibG9ja3MuCisgICAgICovCisgICAgeHNsdEVsZW1QcmVDb21wUHRyIHByZUNvbXBzOy8qIGxpc3Qgb2YgcHJlY29tcHV0ZWQgYmxvY2tzICovCisgICAgaW50IHdhcm5pbmdzOwkJLyogbnVtYmVyIG9mIHdhcm5pbmdzIGZvdW5kIGF0IGNvbXBpbGF0aW9uICovCisgICAgaW50IGVycm9yczsJCQkvKiBudW1iZXIgb2YgZXJyb3JzIGZvdW5kIGF0IGNvbXBpbGF0aW9uICovCisKKyAgICB4bWxDaGFyICAqZXhjbFByZWZpeDsJLyogbGFzdCBleGNsdWRlZCBwcmVmaXhlcyAqLworICAgIHhtbENoYXIgKipleGNsUHJlZml4VGFiOwkvKiBhcnJheSBvZiBleGNsdWRlZCBwcmVmaXhlcyAqLworICAgIGludCAgICAgICBleGNsUHJlZml4TnI7CS8qIG51bWJlciBvZiBleGNsdWRlZCBwcmVmaXhlcyBpbiBzY29wZSAqLworICAgIGludCAgICAgICBleGNsUHJlZml4TWF4OwkvKiBzaXplIG9mIHRoZSBhcnJheSAqLworCisgICAgdm9pZCAgICAgKl9wcml2YXRlOwkJLyogdXNlciBkZWZpbmVkIGRhdGEgKi8KKworICAgIC8qCisgICAgICogRXh0ZW5zaW9ucy4KKyAgICAgKi8KKyAgICB4bWxIYXNoVGFibGVQdHIgZXh0SW5mb3M7CS8qIHRoZSBleHRlbnNpb24gZGF0YSAqLworICAgIGludAkJICAgIGV4dHJhc05yOwkvKiB0aGUgbnVtYmVyIG9mIGV4dHJhcyByZXF1aXJlZCAqLworCisgICAgLyoKKyAgICAgKiBGb3Iga2VlcGluZyB0cmFjayBvZiBuZXN0ZWQgaW5jbHVkZXMKKyAgICAgKi8KKyAgICB4c2x0RG9jdW1lbnRQdHIgaW5jbHVkZXM7CS8qIHBvaW50cyB0byBsYXN0IG5lc3RlZCBpbmNsdWRlICovCisKKyAgICAvKgorICAgICAqIGRpY3Rpb25hcnk6IHNoYXJlZCBiZXR3ZWVuIHN0eWxlc2hlZXQsIGNvbnRleHQgYW5kIGRvY3VtZW50cy4KKyAgICAgKi8KKyAgICB4bWxEaWN0UHRyIGRpY3Q7CisgICAgLyoKKyAgICAgKiBwcmVjb21waWxlZCBhdHRyaWJ1dGUgdmFsdWUgdGVtcGxhdGVzLgorICAgICAqLworICAgIHZvaWQgKmF0dFZUczsKKyAgICAvKgorICAgICAqIGlmIG5hbWVzcGFjZS1hbGlhcyBoYXMgYW4gYWxpYXMgZm9yIHRoZSBkZWZhdWx0IHN0eWxlc2hlZXQgcHJlZml4CisgICAgICogTk9URTogTm90IHVzZWQgaW4gdGhlIHJlZmFjdG9yZWQgY29kZS4KKyAgICAgKi8KKyAgICBjb25zdCB4bWxDaGFyICpkZWZhdWx0QWxpYXM7CisgICAgLyoKKyAgICAgKiBieXBhc3MgcHJlLXByb2Nlc3NpbmcgKGFscmVhZHkgZG9uZSkgKHVzZWQgaW4gaW1wb3J0cykKKyAgICAgKi8KKyAgICBpbnQgbm9wcmVwcm9jOworICAgIC8qCisgICAgICogYWxsIGRvY3VtZW50IHRleHQgc3RyaW5ncyB3ZXJlIGludGVybmFsaXplZAorICAgICAqLworICAgIGludCBpbnRlcm5hbGl6ZWQ7CisgICAgLyoKKyAgICAgKiBMaXRlcmFsIFJlc3VsdCBFbGVtZW50IGFzIFN0eWxlc2hlZXQgYy5mLiBzZWN0aW9uIDIuMworICAgICAqLworICAgIGludCBsaXRlcmFsX3Jlc3VsdDsKKyAgICAvKgorICAgICogVGhlIHByaW5jaXBhbCBzdHlsZXNoZWV0CisgICAgKi8KKyAgICB4c2x0U3R5bGVzaGVldFB0ciBwcmluY2lwYWw7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgLyoKKyAgICAqIENvbXBpbGF0aW9uIGNvbnRleHQgdXNlZCBkdXJpbmcgY29tcGlsZS10aW1lLgorICAgICovCisgICAgeHNsdENvbXBpbGVyQ3R4dFB0ciBjb21wQ3R4dDsgLyogVE9ETzogQ2hhbmdlIHRoaXMgdG8gKHZvaWQgKikuICovCisKKyAgICB4c2x0UHJpbmNpcGFsU3R5bGVzaGVldERhdGFQdHIgcHJpbmNpcGFsRGF0YTsgICAgCisjZW5kaWYKK307CisKK3R5cGVkZWYgc3RydWN0IF94c2x0VHJhbnNmb3JtQ2FjaGUgeHNsdFRyYW5zZm9ybUNhY2hlOwordHlwZWRlZiB4c2x0VHJhbnNmb3JtQ2FjaGUgKnhzbHRUcmFuc2Zvcm1DYWNoZVB0cjsKK3N0cnVjdCBfeHNsdFRyYW5zZm9ybUNhY2hlIHsKKyAgICB4bWxEb2NQdHIgUlZUOworICAgIGludCBuYlJWVDsKKyAgICB4c2x0U3RhY2tFbGVtUHRyIHN0YWNrSXRlbXM7CisgICAgaW50IG5iU3RhY2tJdGVtczsKKyNpZmRlZiBYU0xUX0RFQlVHX1BST0ZJTEVfQ0FDSEUKKyAgICBpbnQgZGJnQ2FjaGVkUlZUczsKKyAgICBpbnQgZGJnUmV1c2VkUlZUczsKKyAgICBpbnQgZGJnQ2FjaGVkVmFyczsKKyAgICBpbnQgZGJnUmV1c2VkVmFyczsKKyNlbmRpZgorfTsKKworLyoKKyAqIFRoZSBpbi1tZW1vcnkgc3RydWN0dXJlIGNvcnJlc3BvbmRpbmcgdG8gYW4gWFNMVCBUcmFuc2Zvcm1hdGlvbi4KKyAqLwordHlwZWRlZiBlbnVtIHsKKyAgICBYU0xUX09VVFBVVF9YTUwgPSAwLAorICAgIFhTTFRfT1VUUFVUX0hUTUwsCisgICAgWFNMVF9PVVRQVVRfVEVYVAorfSB4c2x0T3V0cHV0VHlwZTsKKwordHlwZWRlZiBlbnVtIHsKKyAgICBYU0xUX1NUQVRFX09LID0gMCwKKyAgICBYU0xUX1NUQVRFX0VSUk9SLAorICAgIFhTTFRfU1RBVEVfU1RPUFBFRAorfSB4c2x0VHJhbnNmb3JtU3RhdGU7CisKK3N0cnVjdCBfeHNsdFRyYW5zZm9ybUNvbnRleHQgeworICAgIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlOwkJLyogdGhlIHN0eWxlc2hlZXQgdXNlZCAqLworICAgIHhzbHRPdXRwdXRUeXBlIHR5cGU7CQkvKiB0aGUgdHlwZSBvZiBvdXRwdXQgKi8KKworICAgIHhzbHRUZW1wbGF0ZVB0ciAgdGVtcGw7CQkvKiB0aGUgY3VycmVudCB0ZW1wbGF0ZSAqLworICAgIGludCAgICAgICAgICAgICAgdGVtcGxOcjsJCS8qIE5iIG9mIHRlbXBsYXRlcyBpbiB0aGUgc3RhY2sgKi8KKyAgICBpbnQgICAgICAgICAgICAgIHRlbXBsTWF4OwkJLyogU2l6ZSBvZiB0aGUgdGVtcGx0ZXMgc3RhY2sgKi8KKyAgICB4c2x0VGVtcGxhdGVQdHIgKnRlbXBsVGFiOwkJLyogdGhlIHRlbXBsYXRlIHN0YWNrICovCisKKyAgICB4c2x0U3RhY2tFbGVtUHRyICB2YXJzOwkJLyogdGhlIGN1cnJlbnQgdmFyaWFibGUgbGlzdCAqLworICAgIGludCAgICAgICAgICAgICAgIHZhcnNOcjsJCS8qIE5iIG9mIHZhcmlhYmxlIGxpc3QgaW4gdGhlIHN0YWNrICovCisgICAgaW50ICAgICAgICAgICAgICAgdmFyc01heDsJCS8qIFNpemUgb2YgdGhlIHZhcmlhYmxlIGxpc3Qgc3RhY2sgKi8KKyAgICB4c2x0U3RhY2tFbGVtUHRyICp2YXJzVGFiOwkJLyogdGhlIHZhcmlhYmxlIGxpc3Qgc3RhY2sgKi8KKyAgICBpbnQgICAgICAgICAgICAgICB2YXJzQmFzZTsJCS8qIHRoZSB2YXIgYmFzZSBmb3IgY3VycmVudCB0ZW1wbCAqLworCisgICAgLyoKKyAgICAgKiBFeHRlbnNpb25zCisgICAgICovCisgICAgeG1sSGFzaFRhYmxlUHRyICAgZXh0RnVuY3Rpb25zOwkvKiB0aGUgZXh0ZW5zaW9uIGZ1bmN0aW9ucyAqLworICAgIHhtbEhhc2hUYWJsZVB0ciAgIGV4dEVsZW1lbnRzOwkvKiB0aGUgZXh0ZW5zaW9uIGVsZW1lbnRzICovCisgICAgeG1sSGFzaFRhYmxlUHRyICAgZXh0SW5mb3M7CQkvKiB0aGUgZXh0ZW5zaW9uIGRhdGEgKi8KKworICAgIGNvbnN0IHhtbENoYXIgKm1vZGU7CQkvKiB0aGUgY3VycmVudCBtb2RlICovCisgICAgY29uc3QgeG1sQ2hhciAqbW9kZVVSSTsJCS8qIHRoZSBjdXJyZW50IG1vZGUgVVJJICovCisKKyAgICB4c2x0RG9jdW1lbnRQdHIgZG9jTGlzdDsJCS8qIHRoZSBkb2N1bWVudCBsaXN0ICovCisKKyAgICB4c2x0RG9jdW1lbnRQdHIgZG9jdW1lbnQ7CQkvKiB0aGUgY3VycmVudCBzb3VyY2UgZG9jdW1lbnQ7IGNhbiBiZSBOVUxMIGlmIGFuIFJURiAqLworICAgIHhtbE5vZGVQdHIgbm9kZTsJCQkvKiB0aGUgY3VycmVudCBub2RlIGJlaW5nIHByb2Nlc3NlZCAqLworICAgIHhtbE5vZGVTZXRQdHIgbm9kZUxpc3Q7CQkvKiB0aGUgY3VycmVudCBub2RlIGxpc3QgKi8KKyAgICAvKiB4bWxOb2RlUHRyIGN1cnJlbnQ7CQkJdGhlIG5vZGUgKi8KKworICAgIHhtbERvY1B0ciBvdXRwdXQ7CQkJLyogdGhlIHJlc3VsdGluZyBkb2N1bWVudCAqLworICAgIHhtbE5vZGVQdHIgaW5zZXJ0OwkJCS8qIHRoZSBpbnNlcnRpb24gbm9kZSAqLworCisgICAgeG1sWFBhdGhDb250ZXh0UHRyIHhwYXRoQ3R4dDsJLyogdGhlIFhQYXRoIGNvbnRleHQgKi8KKyAgICB4c2x0VHJhbnNmb3JtU3RhdGUgc3RhdGU7CQkvKiB0aGUgY3VycmVudCBzdGF0ZSAqLworCisgICAgLyoKKyAgICAgKiBHbG9iYWwgdmFyaWFibGVzCisgICAgICovCisgICAgeG1sSGFzaFRhYmxlUHRyICAgZ2xvYmFsVmFyczsJLyogdGhlIGdsb2JhbCB2YXJpYWJsZXMgYW5kIHBhcmFtcyAqLworCisgICAgeG1sTm9kZVB0ciBpbnN0OwkJCS8qIHRoZSBpbnN0cnVjdGlvbiBpbiB0aGUgc3R5bGVzaGVldCAqLworCisgICAgaW50IHhpbmNsdWRlOwkJCS8qIHNob3VsZCBYSW5jbHVkZSBiZSBwcm9jZXNzZWQgKi8KKworICAgIGNvbnN0IGNoYXIgKiAgICAgIG91dHB1dEZpbGU7CS8qIHRoZSBvdXRwdXQgVVJJIGlmIGtub3duICovCisKKyAgICBpbnQgcHJvZmlsZTsgICAgICAgICAgICAgICAgICAgICAgICAvKiBpcyB0aGlzIHJ1biBwcm9maWxlZCAqLworICAgIGxvbmcgICAgICAgICAgICAgcHJvZjsJCS8qIHRoZSBjdXJyZW50IHByb2ZpbGVkIHZhbHVlICovCisgICAgaW50ICAgICAgICAgICAgICBwcm9mTnI7CQkvKiBOYiBvZiB0ZW1wbGF0ZXMgaW4gdGhlIHN0YWNrICovCisgICAgaW50ICAgICAgICAgICAgICBwcm9mTWF4OwkJLyogU2l6ZSBvZiB0aGUgdGVtcGx0YWVzIHN0YWNrICovCisgICAgbG9uZyAgICAgICAgICAgICpwcm9mVGFiOwkJLyogdGhlIHByb2ZpbGUgdGVtcGxhdGUgc3RhY2sgKi8KKworICAgIHZvaWQgICAgICAgICAgICAqX3ByaXZhdGU7CQkvKiB1c2VyIGRlZmluZWQgZGF0YSAqLworCisgICAgaW50ICAgICAgICAgICAgICBleHRyYXNOcjsJCS8qIHRoZSBudW1iZXIgb2YgZXh0cmFzIHVzZWQgKi8KKyAgICBpbnQgICAgICAgICAgICAgIGV4dHJhc01heDsJCS8qIHRoZSBudW1iZXIgb2YgZXh0cmFzIGFsbG9jYXRlZCAqLworICAgIHhzbHRSdW50aW1lRXh0cmFQdHIgZXh0cmFzOwkJLyogZXh0cmEgcGVyIHJ1bnRpbWUgaW5mb3JtYXRpb25zICovCisKKyAgICB4c2x0RG9jdW1lbnRQdHIgIHN0eWxlTGlzdDsJCS8qIHRoZSBzdHlsZXNoZWV0IGRvY3MgbGlzdCAqLworICAgIHZvaWQgICAgICAgICAgICAgICAgICogc2VjOwkJLyogdGhlIHNlY3VyaXR5IHByZWZlcmVuY2VzIGlmIGFueSAqLworCisgICAgeG1sR2VuZXJpY0Vycm9yRnVuYyAgZXJyb3I7CQkvKiBhIHNwZWNpZmljIGVycm9yIGhhbmRsZXIgKi8KKyAgICB2b2lkICAgICAgICAgICAgICAqIGVycmN0eDsJCS8qIGNvbnRleHQgZm9yIHRoZSBlcnJvciBoYW5kbGVyICovCisKKyAgICB4c2x0U29ydEZ1bmMgICAgICBzb3J0ZnVuYzsJCS8qIGEgY3R4dCBzcGVjaWZpYyBzb3J0IHJvdXRpbmUgKi8KKworICAgIC8qCisgICAgICogaGFuZGxpbmcgb2YgdGVtcG9yYXJ5IFJlc3VsdCBWYWx1ZSBUcmVlCisgICAgICogKFhTTFQgMS4wIHRlcm06ICJSZXN1bHQgVHJlZSBGcmFnbWVudCIpCisgICAgICovCisgICAgeG1sRG9jUHRyICAgICAgIHRtcFJWVDsJCS8qIGxpc3Qgb2YgUlZUIHdpdGhvdXQgcGVyc2lzdGFuY2UgKi8KKyAgICB4bWxEb2NQdHIgICAgICAgcGVyc2lzdFJWVDsJCS8qIGxpc3Qgb2YgcGVyc2lzdGFudCBSVlRzICovCisgICAgaW50ICAgICAgICAgICAgIGN0eHRmbGFnczsgICAgICAgICAgLyogY29udGV4dCBwcm9jZXNzaW5nIGZsYWdzICovCisKKyAgICAvKgorICAgICAqIFNwZWVkIG9wdGltaXphdGlvbiB3aGVuIGNvYWxlc2NpbmcgdGV4dCBub2RlcworICAgICAqLworICAgIGNvbnN0IHhtbENoYXIgICpsYXN0dGV4dDsJCS8qIGxhc3QgdGV4dCBub2RlIGNvbnRlbnQgKi8KKyAgICB1bnNpZ25lZCBpbnQgICAgbGFzdHRzaXplOwkJLyogbGFzdCB0ZXh0IG5vZGUgc2l6ZSAqLworICAgIHVuc2lnbmVkIGludCAgICBsYXN0dHVzZTsJCS8qIGxhc3QgdGV4dCBub2RlIHVzZSAqLworICAgIC8qCisgICAgICogUGVyIENvbnRleHQgRGVidWdnaW5nCisgICAgICovCisgICAgaW50IGRlYnVnU3RhdHVzOwkJCS8qIHRoZSBjb250ZXh0IGxldmVsIGRlYnVnIHN0YXR1cyAqLworICAgIHVuc2lnbmVkIGxvbmcqIHRyYWNlQ29kZTsJCS8qIHBvaW50ZXIgdG8gdGhlIHZhcmlhYmxlIGhvbGRpbmcgdGhlIG1hc2sgKi8KKworICAgIGludCBwYXJzZXJPcHRpb25zOwkJCS8qIHBhcnNlciBvcHRpb25zIHhtbFBhcnNlck9wdGlvbiAqLworCisgICAgLyoKKyAgICAgKiBkaWN0aW9uYXJ5OiBzaGFyZWQgYmV0d2VlbiBzdHlsZXNoZWV0LCBjb250ZXh0IGFuZCBkb2N1bWVudHMuCisgICAgICovCisgICAgeG1sRGljdFB0ciBkaWN0OworICAgIHhtbERvY1B0cgkJdG1wRG9jOyAvKiBPYnNvbGV0ZTsgbm90IHVzZWQgaW4gdGhlIGxpYnJhcnkuICovCisgICAgLyoKKyAgICAgKiBhbGwgZG9jdW1lbnQgdGV4dCBzdHJpbmdzIGFyZSBpbnRlcm5hbGl6ZWQKKyAgICAgKi8KKyAgICBpbnQgaW50ZXJuYWxpemVkOworICAgIGludCBuYktleXM7CisgICAgaW50IGhhc1RlbXBsS2V5UGF0dGVybnM7CisgICAgeHNsdFRlbXBsYXRlUHRyIGN1cnJlbnRUZW1wbGF0ZVJ1bGU7IC8qIHRoZSBDdXJyZW50IFRlbXBsYXRlIFJ1bGUgKi8KKyAgICB4bWxOb2RlUHRyIGluaXRpYWxDb250ZXh0Tm9kZTsKKyAgICB4bWxEb2NQdHIgaW5pdGlhbENvbnRleHREb2M7CisgICAgeHNsdFRyYW5zZm9ybUNhY2hlUHRyIGNhY2hlOworICAgIHZvaWQgKmNvbnRleHRWYXJpYWJsZTsgLyogdGhlIGN1cnJlbnQgdmFyaWFibGUgaXRlbSAqLworICAgIHhtbERvY1B0ciBsb2NhbFJWVDsgLyogbGlzdCBvZiBsb2NhbCB0cmVlIGZyYWdtZW50czsgd2lsbCBiZSBmcmVlZCB3aGVuCisJCQkgICB0aGUgaW5zdHJ1Y3Rpb24gd2hpY2ggY3JlYXRlZCB0aGUgZnJhZ21lbnQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXRzICovCisgICAgeG1sRG9jUHRyIGxvY2FsUlZUQmFzZTsKKyAgICBpbnQga2V5SW5pdExldmVsOyAgIC8qIE5lZWRlZCB0byBjYXRjaCByZWN1cnNpdmUga2V5cyBpc3N1ZXMgKi8KKyAgICBpbnQgZnVuY0xldmVsOyAgICAgIC8qIE5lZWRlZCB0byBjYXRjaCByZWN1cnNpdmUgZnVuY3Rpb25zIGlzc3VlcyAqLworfTsKKworLyoqCisgKiBDSEVDS19TVE9QUEVEOgorICoKKyAqIE1hY3JvIHRvIGNoZWNrIGlmIHRoZSBYU0xUIHByb2Nlc3Npbmcgc2hvdWxkIGJlIHN0b3BwZWQuCisgKiBXaWxsIHJldHVybiBmcm9tIHRoZSBmdW5jdGlvbi4KKyAqLworI2RlZmluZSBDSEVDS19TVE9QUEVEIGlmIChjdHh0LT5zdGF0ZSA9PSBYU0xUX1NUQVRFX1NUT1BQRUQpIHJldHVybjsKKworLyoqCisgKiBDSEVDS19TVE9QUEVERToKKyAqCisgKiBNYWNybyB0byBjaGVjayBpZiB0aGUgWFNMVCBwcm9jZXNzaW5nIHNob3VsZCBiZSBzdG9wcGVkLgorICogV2lsbCBnb3RvIHRoZSBlcnJvcjogbGFiZWwuCisgKi8KKyNkZWZpbmUgQ0hFQ0tfU1RPUFBFREUgaWYgKGN0eHQtPnN0YXRlID09IFhTTFRfU1RBVEVfU1RPUFBFRCkgZ290byBlcnJvcjsKKworLyoqCisgKiBDSEVDS19TVE9QUEVEMDoKKyAqCisgKiBNYWNybyB0byBjaGVjayBpZiB0aGUgWFNMVCBwcm9jZXNzaW5nIHNob3VsZCBiZSBzdG9wcGVkLgorICogV2lsbCByZXR1cm4gZnJvbSB0aGUgZnVuY3Rpb24gd2l0aCBhIDAgdmFsdWUuCisgKi8KKyNkZWZpbmUgQ0hFQ0tfU1RPUFBFRDAgaWYgKGN0eHQtPnN0YXRlID09IFhTTFRfU1RBVEVfU1RPUFBFRCkgcmV0dXJuKDApOworCisvKgorICogVGhlIG1hY3JvIFhNTF9DQVNUX0ZQVFIgaXMgYSBoYWNrIHRvIGF2b2lkIGEgZ2NjIHdhcm5pbmcgYWJvdXQKKyAqIHBvc3NpYmxlIGluY29tcGF0aWJpbGl0aWVzIGJldHdlZW4gZnVuY3Rpb24gcG9pbnRlcnMgYW5kIG9iamVjdAorICogcG9pbnRlcnMuICBJdCBpcyBkZWZpbmVkIGluIGxpYnhtbC9oYXNoLmggd2l0aGluIHJlY2VudCB2ZXJzaW9ucworICogb2YgbGlieG1sMiwgYnV0IGlzIHB1dCBoZXJlIGZvciBjb21wYXRpYmlsaXR5LgorICovCisjaWZuZGVmIFhNTF9DQVNUX0ZQVFIKKy8qKgorICogWE1MX0NBU1RfRlBUUjoKKyAqIEBmcHRyOiAgcG9pbnRlciB0byBhIGZ1bmN0aW9uCisgKgorICogTWFjcm8gdG8gZG8gYSBjYXN0aW5nIGZyb20gYW4gb2JqZWN0IHBvaW50ZXIgdG8gYQorICogZnVuY3Rpb24gcG9pbnRlciB3aXRob3V0IGVuY291bnRlcmluZyBhIHdhcm5pbmcgZnJvbQorICogZ2NjCisgKgorICogI2RlZmluZSBYTUxfQ0FTVF9GUFRSKGZwdHIpICgqKHZvaWQgKiopKCZmcHRyKSkKKyAqIFRoaXMgbWFjcm8gdmlvbGF0ZWQgSVNPIEMgYWxpYXNpbmcgcnVsZXMgKGdjYzQgb24gczM5MCBicm9rZSkKKyAqIHNvIGl0IGlzIGRpc2FibGVkIG5vdworICovCisKKyNkZWZpbmUgWE1MX0NBU1RfRlBUUihmcHRyKSBmcHRyCisjZW5kaWYKKy8qCisgKiBGdW5jdGlvbnMgYXNzb2NpYXRlZCB0byB0aGUgaW50ZXJuYWwgdHlwZXMKK3hzbHREZWNpbWFsRm9ybWF0UHRyCXhzbHREZWNpbWFsRm9ybWF0R2V0QnlOYW1lKHhzbHRTdHlsZXNoZWV0UHRyIHNoZWV0LAorCQkJCQkJICAgeG1sQ2hhciAqbmFtZSk7CisgKi8KK1hTTFRQVUJGVU4geHNsdFN0eWxlc2hlZXRQdHIgWFNMVENBTEwJCisJCQl4c2x0TmV3U3R5bGVzaGVldAkodm9pZCk7CitYU0xUUFVCRlVOIHhzbHRTdHlsZXNoZWV0UHRyIFhTTFRDQUxMCQorCQkJeHNsdFBhcnNlU3R5bGVzaGVldEZpbGUJKGNvbnN0IHhtbENoYXIqIGZpbGVuYW1lKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCQorCQkJeHNsdEZyZWVTdHlsZXNoZWV0CSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCQorCQkJeHNsdElzQmxhbmsJCSh4bWxDaGFyICpzdHIpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkJCisJCQl4c2x0RnJlZVN0YWNrRWxlbUxpc3QJKHhzbHRTdGFja0VsZW1QdHIgZWxlbSk7CitYU0xUUFVCRlVOIHhzbHREZWNpbWFsRm9ybWF0UHRyIFhTTFRDQUxMCQorCQkJeHNsdERlY2ltYWxGb3JtYXRHZXRCeU5hbWUoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCQkgeG1sQ2hhciAqbmFtZSk7CisKK1hTTFRQVUJGVU4geHNsdFN0eWxlc2hlZXRQdHIgWFNMVENBTEwJCisJCQl4c2x0UGFyc2VTdHlsZXNoZWV0UHJvY2Vzcyh4c2x0U3R5bGVzaGVldFB0ciByZXQsCisJCQkJCQkgeG1sRG9jUHRyIGRvYyk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQkKKwkJCXhzbHRQYXJzZVN0eWxlc2hlZXRPdXRwdXQoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCQkgeG1sTm9kZVB0ciBjdXIpOworWFNMVFBVQkZVTiB4c2x0U3R5bGVzaGVldFB0ciBYU0xUQ0FMTAkKKwkJCXhzbHRQYXJzZVN0eWxlc2hlZXREb2MJKHhtbERvY1B0ciBkb2MpOworWFNMVFBVQkZVTiB4c2x0U3R5bGVzaGVldFB0ciBYU0xUQ0FMTAkKKwkJCXhzbHRQYXJzZVN0eWxlc2hlZXRJbXBvcnRlZERvYyh4bWxEb2NQdHIgZG9jLAorCQkJCQkJeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUpOworWFNMVFBVQkZVTiB4c2x0U3R5bGVzaGVldFB0ciBYU0xUQ0FMTAkKKwkJCXhzbHRMb2FkU3R5bGVzaGVldFBJCSh4bWxEb2NQdHIgZG9jKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTCAJCQkKKwkJCXhzbHROdW1iZXJGb3JtYXQJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgeHNsdE51bWJlckRhdGFQdHIgZGF0YSwKKwkJCQkJCSB4bWxOb2RlUHRyIG5vZGUpOworWFNMVFBVQkZVTiB4bWxYUGF0aEVycm9yIFhTTFRDQUxMCQkgCisJCQl4c2x0Rm9ybWF0TnVtYmVyQ29udmVyc2lvbih4c2x0RGVjaW1hbEZvcm1hdFB0ciBzZWxmLAorCQkJCQkJIHhtbENoYXIgKmZvcm1hdCwKKwkJCQkJCSBkb3VibGUgbnVtYmVyLAorCQkJCQkJIHhtbENoYXIgKipyZXN1bHQpOworCitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQkKKwkJCXhzbHRQYXJzZVRlbXBsYXRlQ29udGVudCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwKKwkJCQkJCSB4bWxOb2RlUHRyIHRlbXBsKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkJCisJCQl4c2x0QWxsb2NhdGVFeHRyYQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwJCQkKKwkJCXhzbHRBbGxvY2F0ZUV4dHJhQ3R4dAkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCk7CisvKgorICogRXh0cmEgZnVuY3Rpb25zIGZvciBSZXN1bHQgVmFsdWUgVHJlZXMKKyAqLworWFNMVFBVQkZVTiB4bWxEb2NQdHIgWFNMVENBTEwJCQorCQkJeHNsdENyZWF0ZVJWVAkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwJCQkKKwkJCXhzbHRSZWdpc3RlclRtcFJWVAkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4bWxEb2NQdHIgUlZUKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkJCisJCQl4c2x0UmVnaXN0ZXJMb2NhbFJWVAkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4bWxEb2NQdHIgUlZUKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkJCisJCQl4c2x0UmVnaXN0ZXJQZXJzaXN0UlZUCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHhtbERvY1B0ciBSVlQpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwKKwkJCXhzbHRFeHRlbnNpb25JbnN0cnVjdGlvblJlc3VsdFJlZ2lzdGVyKAorCQkJCQkJIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgeG1sWFBhdGhPYmplY3RQdHIgb2JqKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCQl4c2x0RXh0ZW5zaW9uSW5zdHJ1Y3Rpb25SZXN1bHRGaW5hbGl6ZSgKKwkJCQkJCSB4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQkJeHNsdEZyZWVSVlRzCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJCXhzbHRSZWxlYXNlUlZUCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4bWxEb2NQdHIgUlZUKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCQl4c2x0VHJhbnNTdG9yYWdlQWRkCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHZvaWQgKmlkLAorCQkJCQkJIHZvaWQgKmRhdGEpOworWFNMVFBVQkZVTiB2b2lkICogWFNMVENBTEwKKwkJCXhzbHRUcmFuc1N0b3JhZ2VSZW1vdmUJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgdm9pZCAqaWQpOworCisvKgorICogRXh0cmEgZnVuY3Rpb25zIGZvciBBdHRyaWJ1dGUgVmFsdWUgVGVtcGxhdGVzCisgKi8KK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQkJeHNsdENvbXBpbGVBdHRyCQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCQkgeG1sQXR0clB0ciBhdHRyKTsKK1hTTFRQVUJGVU4geG1sQ2hhciAqIFhTTFRDQUxMCisJCQl4c2x0RXZhbEFWVAkJKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCQkJCQkgdm9pZCAqYXZ0LAorCQkJCQkJIHhtbE5vZGVQdHIgbm9kZSk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJCXhzbHRGcmVlQVZUTGlzdAkJKHZvaWQgKmF2dCk7CisKKy8qCisgKiBFeHRyYSBmdW5jdGlvbiBmb3Igc3VjY2Vzc2Z1bCB4c2x0Q2xlYW51cEdsb2JhbHMgLyB4c2x0SW5pdCBzZXF1ZW5jZS4KKyAqLworCitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwKKwkJCXhzbHRVbmluaXQJCSh2b2lkKTsKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKiAgQ29tcGlsZS10aW1lIGZ1bmN0aW9ucyBmb3IgKmludGVybmFsKiB1c2Ugb25seSAgICAgICAgICAgICAgICAgICAgICAqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQgIAorWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCisJCQl4c2x0UGFyc2VTZXF1ZW5jZUNvbnN0cnVjdG9yKAorCQkJCQkJIHhzbHRDb21waWxlckN0eHRQdHIgY2N0eHQsCisJCQkJCQkgeG1sTm9kZVB0ciBzdGFydCk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQkJeHNsdFBhcnNlQW55WFNMVEVsZW0JKHhzbHRDb21waWxlckN0eHRQdHIgY2N0eHQsCisJCQkJCQkgeG1sTm9kZVB0ciBlbGVtKTsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRURfWFNMVF9OU0NPTVAKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCisJCQl4c2x0UmVzdG9yZURvY3VtZW50TmFtZXNwYWNlcygKKwkJCQkJCSB4c2x0TnNNYXBQdHIgbnMsCisJCQkJCQkgeG1sRG9jUHRyIGRvYyk7CisjZW5kaWYKKyNlbmRpZiAvKiBYU0xUX1JFRkFDVE9SRUQgKi8KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICoJCQkJCQkJCQkqCisgKiAgVHJhbnNmb3JtYXRpb24tdGltZSBmdW5jdGlvbnMgZm9yICppbnRlcm5hbCogdXNlIG9ubHkgICAgICAgICAgICAgICAqCisgKgkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQkJeHNsdEluaXRDdHh0S2V5CQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4c2x0RG9jdW1lbnRQdHIgZG9jLAorCQkJCQkJIHhzbHRLZXlEZWZQdHIga2V5ZCk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQkJeHNsdEluaXRBbGxEb2NLZXlzCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KTsKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hNTF9YU0xUX0hfXyAqLworCmRpZmYgLS1naXQgYS9saWJ4c2x0L3hzbHRjb25maWcuaCBiL2xpYnhzbHQveHNsdGNvbmZpZy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiMjBlYmQKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L3hzbHRjb25maWcuaApAQCAtMCwwICsxLDE3MiBAQAorLyoKKyAqIFN1bW1hcnk6IGNvbXBpbGUtdGltZSB2ZXJzaW9uIGluZm9ybWF0aW9ucyBmb3IgdGhlIFhTTFQgZW5naW5lCisgKiBEZXNjcmlwdGlvbjogY29tcGlsZS10aW1lIHZlcnNpb24gaW5mb3JtYXRpb25zIGZvciB0aGUgWFNMVCBlbmdpbmUKKyAqICAgICAgICAgICAgICB0aGlzIG1vZHVsZSBpcyBhdXRvZ2VuZXJhdGVkLgorICoKKyAqIENvcHk6IFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBBdXRob3I6IERhbmllbCBWZWlsbGFyZAorICovCisKKyNpZm5kZWYgX19YTUxfWFNMVENPTkZJR19IX18KKyNkZWZpbmUgX19YTUxfWFNMVENPTkZJR19IX18KKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvKioKKyAqIExJQlhTTFRfRE9UVEVEX1ZFUlNJT046CisgKgorICogdGhlIHZlcnNpb24gc3RyaW5nIGxpa2UgIjEuMi4zIgorICovCisjZGVmaW5lIExJQlhTTFRfRE9UVEVEX1ZFUlNJT04gIjEuMS4yNiIKKworLyoqCisgKiBMSUJYU0xUX1ZFUlNJT046CisgKgorICogdGhlIHZlcnNpb24gbnVtYmVyOiAxLjIuMyB2YWx1ZSBpcyAxMDIwMworICovCisjZGVmaW5lIExJQlhTTFRfVkVSU0lPTiAxMDEyNgorCisvKioKKyAqIExJQlhTTFRfVkVSU0lPTl9TVFJJTkc6CisgKgorICogdGhlIHZlcnNpb24gbnVtYmVyIHN0cmluZywgMS4yLjMgdmFsdWUgaXMgIjEwMjAzIgorICovCisjZGVmaW5lIExJQlhTTFRfVkVSU0lPTl9TVFJJTkcgIjEwMTI2IgorCisvKioKKyAqIExJQlhTTFRfVkVSU0lPTl9FWFRSQToKKyAqCisgKiBleHRyYSB2ZXJzaW9uIGluZm9ybWF0aW9uLCB1c2VkIHRvIHNob3cgYSBDVlMgY29tcGlsYXRpb24KKyAqLworI2RlZmluZQlMSUJYU0xUX1ZFUlNJT05fRVhUUkEgIi1HSVR2MS4xLjI2IgorCisvKioKKyAqIFdJVEhfWFNMVF9ERUJVRzoKKyAqCisgKiBBY3RpdmF0ZSB0aGUgY29tcGlsYXRpb24gb2YgdGhlIGRlYnVnIHJlcG9ydGluZy4gU3BlZWQgcGVuYWx0eQorICogaXMgaW5zaWduaWZpYW50IGFuZCBiZWluZyBhYmxlIHRvIHJ1biB4c2x0cG9jIC12IGlzIHVzZWZ1bC4gT24KKyAqIGJ5IGRlZmF1bHQgdW5sZXNzIC0td2l0aG91dC1kZWJ1ZyBpcyBwYXNzZWQgdG8gY29uZmlndXJlCisgKi8KKyNpZiAxCisjZGVmaW5lIFdJVEhfWFNMVF9ERUJVRworI2VuZGlmCisKKyNpZiAxCisvKioKKyAqIERFQlVHX01FTU9SWToKKyAqCisgKiBzaG91bGQgYmUgYWN0aXZhdGVkIG9ubHkgd2hlbiBkZWJ1Z2dpbmcgbGlieHNsdC4gSXQgcmVwbGFjZXMgdGhlCisgKiBhbGxvY2F0b3Igd2l0aCBhIGNvbGxlY3QgYW5kIGRlYnVnIHNoZWxsIHRvIHRoZSBsaWJjIGFsbG9jYXRvci4KKyAqIFVzZSBjb25maWd1cmUgLS13aXRoLW1lbS1kZWJ1ZyB0byBhY3RpdmF0ZSBpdCBvbiBib3RoIGxpYnJhcnkKKyAqLworI2RlZmluZSBERUJVR19NRU1PUlkKKworLyoqCisgKiBERUJVR19NRU1PUllfTE9DQVRJT046CisgKgorICogc2hvdWxkIGJlIGFjdGl2YXRlZCBvbmx5IHdoZW4gZGVidWdnaW5nIGxpYnhzbHQuCisgKiBERUJVR19NRU1PUllfTE9DQVRJT04gc2hvdWxkIGJlIGFjdGl2YXRlZCBvbmx5IHdoZW4gbGlieG1sIGhhcworICogYmVlbiBjb25maWd1cmVkIHdpdGggLS13aXRoLWRlYnVnLW1lbSB0b28KKyAqLworI2RlZmluZSBERUJVR19NRU1PUllfTE9DQVRJT04KKyNlbmRpZgorCisvKioKKyAqIFhTTFRfTkVFRF9UUklPOgorICoKKyAqIHNob3VsZCBiZSBhY3RpdmF0ZWQgaWYgdGhlIGV4aXN0aW5nIGxpYmMgbGlicmFyeSBsYWNrcyBzb21lIG9mIHRoZQorICogc3RyaW5nIGZvcm1hdHRpbmcgZnVuY3Rpb24sIGluIHRoYXQgY2FzZSByZXVzZSB0aGUgVHJpbyBvbmVzIGFscmVhZHkKKyAqIGNvbXBpbGVkIGluIHRoZSBsaWJ4bWwyIGxpYnJhcnkuCisgKi8KKworI2lmIDAKKyNkZWZpbmUgWFNMVF9ORUVEX1RSSU8KKyNlbmRpZgorI2lmZGVmIF9fVk1TCisjZGVmaW5lIEhBVkVfTUFUSF9IIDEKKyNkZWZpbmUgSEFWRV9TWVNfU1RBVF9IIDEKKyNpZm5kZWYgWFNMVF9ORUVEX1RSSU8KKyNkZWZpbmUgWFNMVF9ORUVEX1RSSU8KKyNlbmRpZgorI2VuZGlmCisKKyNpZmRlZglYU0xUX05FRURfVFJJTworI2RlZmluZQlUUklPX1JFUExBQ0VfU1RESU8KKyNlbmRpZgorCisvKioKKyAqIFdJVEhfWFNMVF9ERUJVR0dFUjoKKyAqCisgKiBBY3RpdmF0ZSB0aGUgY29tcGlsYXRpb24gb2YgdGhlIGRlYnVnZ2VyIHN1cHBvcnQuIFNwZWVkIHBlbmFsdHkKKyAqIGlzIGluc2lnbmlmaWFudC4KKyAqIE9uIGJ5IGRlZmF1bHQgdW5sZXNzIC0td2l0aG91dC1kZWJ1Z2dlciBpcyBwYXNzZWQgdG8gY29uZmlndXJlCisgKi8KKyNpZiAxCisjaWZuZGVmIFdJVEhfREVCVUdHRVIKKyNkZWZpbmUgV0lUSF9ERUJVR0dFUgorI2VuZGlmCisjZW5kaWYKKworLyoqCisgKiBXSVRIX01PRFVMRVM6CisgKgorICogV2hldGhlciBtb2R1bGUgc3VwcG9ydCBpcyBjb25maWd1cmVkIGludG8gbGlieHNsdAorICogTm90ZTogbm8gZGVmYXVsdCBtb2R1bGUgcGF0aCBmb3Igd2luMzIgcGxhdGZvcm1zCisgKi8KKyNpZiAxCisjaWZuZGVmIFdJVEhfTU9EVUxFUworI2RlZmluZSBXSVRIX01PRFVMRVMKKyNlbmRpZgorI2RlZmluZSBMSUJYU0xUX0RFRkFVTFRfUExVR0lOU19QQVRIKCkgIi91c3IvbGliL2xpYnhzbHQtcGx1Z2lucyIKKyNlbmRpZgorCisvKioKKyAqIExvY2FsZSBzdXBwb3J0CisgKi8KKyNpZiAxCisjaWZuZGVmIFhTTFRfTE9DQUxFX1hMT0NBTEUKKyNkZWZpbmUgWFNMVF9MT0NBTEVfWExPQ0FMRQorI2VuZGlmCisjZWxpZiAwCisjaWZuZGVmIFhTTFRfTE9DQUxFX1dJTkFQSQorI2RlZmluZSBYU0xUX0xPQ0FMRV9XSU5BUEkKKyNlbmRpZgorI2VuZGlmCisKKy8qKgorICogQVRUUklCVVRFX1VOVVNFRDoKKyAqCisgKiBUaGlzIG1hY3JvIGlzIHVzZWQgdG8gZmxhZyB1bnVzZWQgZnVuY3Rpb24gcGFyYW1ldGVycyB0byBHQ0MKKyAqLworI2lmZGVmIF9fR05VQ19fCisjaWZkZWYgSEFWRV9BTlNJREVDTF9ICisjaW5jbHVkZSA8YW5zaWRlY2wuaD4KKyNlbmRpZgorI2lmbmRlZiBBVFRSSUJVVEVfVU5VU0VECisjZGVmaW5lIEFUVFJJQlVURV9VTlVTRUQgX19hdHRyaWJ1dGVfXygodW51c2VkKSkKKyNlbmRpZgorI2Vsc2UKKyNkZWZpbmUgQVRUUklCVVRFX1VOVVNFRAorI2VuZGlmCisKKy8qKgorICogTElCWFNMVF9QVUJMSUM6CisgKgorICogVGhpcyBtYWNybyBpcyB1c2VkIHRvIGRlY2xhcmUgUFVCTElDIHZhcmlhYmxlcyBmb3IgQ3lnd2luIGFuZCBmb3IgTVNDIG9uIFdpbmRvd3MKKyAqLworI2lmICFkZWZpbmVkIExJQlhTTFRfUFVCTElDCisjaWYgKGRlZmluZWQoX19DWUdXSU5fXykgfHwgZGVmaW5lZCBfTVNDX1ZFUikgJiYgIWRlZmluZWQgSU5fTElCWFNMVCAmJiAhZGVmaW5lZCBMSUJYU0xUX1NUQVRJQworI2RlZmluZSBMSUJYU0xUX1BVQkxJQyBfX2RlY2xzcGVjKGRsbGltcG9ydCkKKyNlbHNlCisjZGVmaW5lIExJQlhTTFRfUFVCTElDCisjZW5kaWYKKyNlbmRpZgorCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19YTUxfWFNMVENPTkZJR19IX18gKi8KZGlmZiAtLWdpdCBhL2xpYnhzbHQveHNsdGNvbmZpZy5oLmluIGIvbGlieHNsdC94c2x0Y29uZmlnLmguaW4KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjRjYWM2ZAotLS0gL2Rldi9udWxsCisrKyBiL2xpYnhzbHQveHNsdGNvbmZpZy5oLmluCkBAIC0wLDAgKzEsMTcyIEBACisvKgorICogU3VtbWFyeTogY29tcGlsZS10aW1lIHZlcnNpb24gaW5mb3JtYXRpb25zIGZvciB0aGUgWFNMVCBlbmdpbmUKKyAqIERlc2NyaXB0aW9uOiBjb21waWxlLXRpbWUgdmVyc2lvbiBpbmZvcm1hdGlvbnMgZm9yIHRoZSBYU0xUIGVuZ2luZQorICogICAgICAgICAgICAgIHRoaXMgbW9kdWxlIGlzIGF1dG9nZW5lcmF0ZWQuCisgKgorICogQ29weTogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIEF1dGhvcjogRGFuaWVsIFZlaWxsYXJkCisgKi8KKworI2lmbmRlZiBfX1hNTF9YU0xUQ09ORklHX0hfXworI2RlZmluZSBfX1hNTF9YU0xUQ09ORklHX0hfXworCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qKgorICogTElCWFNMVF9ET1RURURfVkVSU0lPTjoKKyAqCisgKiB0aGUgdmVyc2lvbiBzdHJpbmcgbGlrZSAiMS4yLjMiCisgKi8KKyNkZWZpbmUgTElCWFNMVF9ET1RURURfVkVSU0lPTiAiQFZFUlNJT05AIgorCisvKioKKyAqIExJQlhTTFRfVkVSU0lPTjoKKyAqCisgKiB0aGUgdmVyc2lvbiBudW1iZXI6IDEuMi4zIHZhbHVlIGlzIDEwMjAzCisgKi8KKyNkZWZpbmUgTElCWFNMVF9WRVJTSU9OIEBMSUJYU0xUX1ZFUlNJT05fTlVNQkVSQAorCisvKioKKyAqIExJQlhTTFRfVkVSU0lPTl9TVFJJTkc6CisgKgorICogdGhlIHZlcnNpb24gbnVtYmVyIHN0cmluZywgMS4yLjMgdmFsdWUgaXMgIjEwMjAzIgorICovCisjZGVmaW5lIExJQlhTTFRfVkVSU0lPTl9TVFJJTkcgIkBMSUJYU0xUX1ZFUlNJT05fTlVNQkVSQCIKKworLyoqCisgKiBMSUJYU0xUX1ZFUlNJT05fRVhUUkE6CisgKgorICogZXh0cmEgdmVyc2lvbiBpbmZvcm1hdGlvbiwgdXNlZCB0byBzaG93IGEgQ1ZTIGNvbXBpbGF0aW9uCisgKi8KKyNkZWZpbmUJTElCWFNMVF9WRVJTSU9OX0VYVFJBICJATElCWFNMVF9WRVJTSU9OX0VYVFJBQCIKKworLyoqCisgKiBXSVRIX1hTTFRfREVCVUc6CisgKgorICogQWN0aXZhdGUgdGhlIGNvbXBpbGF0aW9uIG9mIHRoZSBkZWJ1ZyByZXBvcnRpbmcuIFNwZWVkIHBlbmFsdHkKKyAqIGlzIGluc2lnbmlmaWFudCBhbmQgYmVpbmcgYWJsZSB0byBydW4geHNsdHBvYyAtdiBpcyB1c2VmdWwuIE9uCisgKiBieSBkZWZhdWx0IHVubGVzcyAtLXdpdGhvdXQtZGVidWcgaXMgcGFzc2VkIHRvIGNvbmZpZ3VyZQorICovCisjaWYgQFdJVEhfWFNMVF9ERUJVR0AKKyNkZWZpbmUgV0lUSF9YU0xUX0RFQlVHCisjZW5kaWYKKworI2lmIEBXSVRIX01FTV9ERUJVR0AKKy8qKgorICogREVCVUdfTUVNT1JZOgorICoKKyAqIHNob3VsZCBiZSBhY3RpdmF0ZWQgb25seSB3aGVuIGRlYnVnZ2luZyBsaWJ4c2x0LiBJdCByZXBsYWNlcyB0aGUKKyAqIGFsbG9jYXRvciB3aXRoIGEgY29sbGVjdCBhbmQgZGVidWcgc2hlbGwgdG8gdGhlIGxpYmMgYWxsb2NhdG9yLgorICogVXNlIGNvbmZpZ3VyZSAtLXdpdGgtbWVtLWRlYnVnIHRvIGFjdGl2YXRlIGl0IG9uIGJvdGggbGlicmFyeQorICovCisjZGVmaW5lIERFQlVHX01FTU9SWQorCisvKioKKyAqIERFQlVHX01FTU9SWV9MT0NBVElPTjoKKyAqCisgKiBzaG91bGQgYmUgYWN0aXZhdGVkIG9ubHkgd2hlbiBkZWJ1Z2dpbmcgbGlieHNsdC4KKyAqIERFQlVHX01FTU9SWV9MT0NBVElPTiBzaG91bGQgYmUgYWN0aXZhdGVkIG9ubHkgd2hlbiBsaWJ4bWwgaGFzCisgKiBiZWVuIGNvbmZpZ3VyZWQgd2l0aCAtLXdpdGgtZGVidWctbWVtIHRvbworICovCisjZGVmaW5lIERFQlVHX01FTU9SWV9MT0NBVElPTgorI2VuZGlmCisKKy8qKgorICogWFNMVF9ORUVEX1RSSU86CisgKgorICogc2hvdWxkIGJlIGFjdGl2YXRlZCBpZiB0aGUgZXhpc3RpbmcgbGliYyBsaWJyYXJ5IGxhY2tzIHNvbWUgb2YgdGhlCisgKiBzdHJpbmcgZm9ybWF0dGluZyBmdW5jdGlvbiwgaW4gdGhhdCBjYXNlIHJldXNlIHRoZSBUcmlvIG9uZXMgYWxyZWFkeQorICogY29tcGlsZWQgaW4gdGhlIGxpYnhtbDIgbGlicmFyeS4KKyAqLworCisjaWYgQFdJVEhfVFJJT0AKKyNkZWZpbmUgWFNMVF9ORUVEX1RSSU8KKyNlbmRpZgorI2lmZGVmIF9fVk1TCisjZGVmaW5lIEhBVkVfTUFUSF9IIDEKKyNkZWZpbmUgSEFWRV9TWVNfU1RBVF9IIDEKKyNpZm5kZWYgWFNMVF9ORUVEX1RSSU8KKyNkZWZpbmUgWFNMVF9ORUVEX1RSSU8KKyNlbmRpZgorI2VuZGlmCisKKyNpZmRlZglYU0xUX05FRURfVFJJTworI2RlZmluZQlUUklPX1JFUExBQ0VfU1RESU8KKyNlbmRpZgorCisvKioKKyAqIFdJVEhfWFNMVF9ERUJVR0dFUjoKKyAqCisgKiBBY3RpdmF0ZSB0aGUgY29tcGlsYXRpb24gb2YgdGhlIGRlYnVnZ2VyIHN1cHBvcnQuIFNwZWVkIHBlbmFsdHkKKyAqIGlzIGluc2lnbmlmaWFudC4KKyAqIE9uIGJ5IGRlZmF1bHQgdW5sZXNzIC0td2l0aG91dC1kZWJ1Z2dlciBpcyBwYXNzZWQgdG8gY29uZmlndXJlCisgKi8KKyNpZiBAV0lUSF9ERUJVR0dFUkAKKyNpZm5kZWYgV0lUSF9ERUJVR0dFUgorI2RlZmluZSBXSVRIX0RFQlVHR0VSCisjZW5kaWYKKyNlbmRpZgorCisvKioKKyAqIFdJVEhfTU9EVUxFUzoKKyAqCisgKiBXaGV0aGVyIG1vZHVsZSBzdXBwb3J0IGlzIGNvbmZpZ3VyZWQgaW50byBsaWJ4c2x0CisgKiBOb3RlOiBubyBkZWZhdWx0IG1vZHVsZSBwYXRoIGZvciB3aW4zMiBwbGF0Zm9ybXMKKyAqLworI2lmIEBXSVRIX01PRFVMRVNACisjaWZuZGVmIFdJVEhfTU9EVUxFUworI2RlZmluZSBXSVRIX01PRFVMRVMKKyNlbmRpZgorI2RlZmluZSBMSUJYU0xUX0RFRkFVTFRfUExVR0lOU19QQVRIKCkgIkBMSUJYU0xUX0RFRkFVTFRfUExVR0lOU19QQVRIQCIKKyNlbmRpZgorCisvKioKKyAqIExvY2FsZSBzdXBwb3J0CisgKi8KKyNpZiBAWFNMVF9MT0NBTEVfWExPQ0FMRUAKKyNpZm5kZWYgWFNMVF9MT0NBTEVfWExPQ0FMRQorI2RlZmluZSBYU0xUX0xPQ0FMRV9YTE9DQUxFCisjZW5kaWYKKyNlbGlmIEBYU0xUX0xPQ0FMRV9XSU5BUElACisjaWZuZGVmIFhTTFRfTE9DQUxFX1dJTkFQSQorI2RlZmluZSBYU0xUX0xPQ0FMRV9XSU5BUEkKKyNlbmRpZgorI2VuZGlmCisKKy8qKgorICogQVRUUklCVVRFX1VOVVNFRDoKKyAqCisgKiBUaGlzIG1hY3JvIGlzIHVzZWQgdG8gZmxhZyB1bnVzZWQgZnVuY3Rpb24gcGFyYW1ldGVycyB0byBHQ0MKKyAqLworI2lmZGVmIF9fR05VQ19fCisjaWZkZWYgSEFWRV9BTlNJREVDTF9ICisjaW5jbHVkZSA8YW5zaWRlY2wuaD4KKyNlbmRpZgorI2lmbmRlZiBBVFRSSUJVVEVfVU5VU0VECisjZGVmaW5lIEFUVFJJQlVURV9VTlVTRUQgX19hdHRyaWJ1dGVfXygodW51c2VkKSkKKyNlbmRpZgorI2Vsc2UKKyNkZWZpbmUgQVRUUklCVVRFX1VOVVNFRAorI2VuZGlmCisKKy8qKgorICogTElCWFNMVF9QVUJMSUM6CisgKgorICogVGhpcyBtYWNybyBpcyB1c2VkIHRvIGRlY2xhcmUgUFVCTElDIHZhcmlhYmxlcyBmb3IgQ3lnd2luIGFuZCBmb3IgTVNDIG9uIFdpbmRvd3MKKyAqLworI2lmICFkZWZpbmVkIExJQlhTTFRfUFVCTElDCisjaWYgKGRlZmluZWQoX19DWUdXSU5fXykgfHwgZGVmaW5lZCBfTVNDX1ZFUikgJiYgIWRlZmluZWQgSU5fTElCWFNMVCAmJiAhZGVmaW5lZCBMSUJYU0xUX1NUQVRJQworI2RlZmluZSBMSUJYU0xUX1BVQkxJQyBfX2RlY2xzcGVjKGRsbGltcG9ydCkKKyNlbHNlCisjZGVmaW5lIExJQlhTTFRfUFVCTElDCisjZW5kaWYKKyNlbmRpZgorCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19YTUxfWFNMVENPTkZJR19IX18gKi8KZGlmZiAtLWdpdCBhL2xpYnhzbHQveHNsdGV4cG9ydHMuaCBiL2xpYnhzbHQveHNsdGV4cG9ydHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MjVjMTIyCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC94c2x0ZXhwb3J0cy5oCkBAIC0wLDAgKzEsMTQyIEBACisvKgorICogU3VtbWFyeTogbWFjcm9zIGZvciBtYXJraW5nIHN5bWJvbHMgYXMgZXhwb3J0YWJsZS9pbXBvcnRhYmxlLgorICogRGVzY3JpcHRpb246IG1hY3JvcyBmb3IgbWFya2luZyBzeW1ib2xzIGFzIGV4cG9ydGFibGUvaW1wb3J0YWJsZS4KKyAqCisgKiBDb3B5OiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCisgKgorICogQXV0aG9yOiBJZ29yIFpsYXRrb3ZpYyA8aWdvckB6bGF0a292aWMuY29tPgorICovCisKKyNpZm5kZWYgX19YU0xUX0VYUE9SVFNfSF9fCisjZGVmaW5lIF9fWFNMVF9FWFBPUlRTX0hfXworCisvKioKKyAqIFhTTFRQVUJGVU46CisgKiBYU0xUUFVCRlVOLCBYU0xUUFVCVkFSLCBYU0xUQ0FMTAorICoKKyAqIE1hY3JvcyB3aGljaCBkZWNsYXJlIGFuIGV4cG9ydGFibGUgZnVuY3Rpb24sIGFuIGV4cG9ydGFibGUgdmFyaWFibGUgYW5kCisgKiB0aGUgY2FsbGluZyBjb252ZW50aW9uIHVzZWQgZm9yIGZ1bmN0aW9ucy4KKyAqCisgKiBQbGVhc2UgdXNlIGFuIGV4dHJhIGJsb2NrIGZvciBldmVyeSBwbGF0Zm9ybS9jb21waWxlciBjb21iaW5hdGlvbiB3aGVuCisgKiBtb2RpZnlpbmcgdGhpcywgcmF0aGVyIHRoYW4gb3ZlcmxvbmcgI2lmZGVmIGxpbmVzLiBUaGlzIGhlbHBzCisgKiByZWFkYWJpbGl0eSBhcyB3ZWxsIGFzIHRoZSBmYWN0IHRoYXQgZGlmZmVyZW50IGNvbXBpbGVycyBvbiB0aGUgc2FtZQorICogcGxhdGZvcm0gbWlnaHQgbmVlZCBkaWZmZXJlbnQgZGVmaW5pdGlvbnMuCisgKi8KKworLyoqCisgKiBYU0xUUFVCRlVOOgorICoKKyAqIE1hY3JvcyB3aGljaCBkZWNsYXJlIGFuIGV4cG9ydGFibGUgZnVuY3Rpb24KKyAqLworI2RlZmluZSBYU0xUUFVCRlVOCisvKioKKyAqIFhTTFRQVUJWQVI6CisgKgorICogTWFjcm9zIHdoaWNoIGRlY2xhcmUgYW4gZXhwb3J0YWJsZSB2YXJpYWJsZQorICovCisjZGVmaW5lIFhTTFRQVUJWQVIgZXh0ZXJuCisvKioKKyAqIFhTTFRDQUxMOgorICoKKyAqIE1hY3JvcyB3aGljaCBkZWNsYXJlIHRoZSBjYWxsZWQgY29udmVudGlvbiBmb3IgZXhwb3J0ZWQgZnVuY3Rpb25zCisgKi8KKyNkZWZpbmUgWFNMVENBTEwKKworLyoqIERPQ19ESVNBQkxFICovCisKKy8qIFdpbmRvd3MgcGxhdGZvcm0gd2l0aCBNUyBjb21waWxlciAqLworI2lmIGRlZmluZWQoX1dJTjMyKSAmJiBkZWZpbmVkKF9NU0NfVkVSKQorICAjdW5kZWYgWFNMVFBVQkZVTgorICAjdW5kZWYgWFNMVFBVQlZBUgorICAjdW5kZWYgWFNMVENBTEwKKyAgI2lmIGRlZmluZWQoSU5fTElCWFNMVCkgJiYgIWRlZmluZWQoTElCWFNMVF9TVEFUSUMpCisgICAgI2RlZmluZSBYU0xUUFVCRlVOIF9fZGVjbHNwZWMoZGxsZXhwb3J0KQorICAgICNkZWZpbmUgWFNMVFBVQlZBUiBfX2RlY2xzcGVjKGRsbGV4cG9ydCkKKyAgI2Vsc2UKKyAgICAjZGVmaW5lIFhTTFRQVUJGVU4KKyAgICAjaWYgIWRlZmluZWQoTElCWFNMVF9TVEFUSUMpCisgICAgICAjZGVmaW5lIFhTTFRQVUJWQVIgX19kZWNsc3BlYyhkbGxpbXBvcnQpIGV4dGVybgorICAgICNlbHNlCisgICAgICAjZGVmaW5lIFhTTFRQVUJWQVIgZXh0ZXJuCisgICAgI2VuZGlmCisgICNlbmRpZgorICAjZGVmaW5lIFhTTFRDQUxMIF9fY2RlY2wKKyAgI2lmICFkZWZpbmVkIF9SRUVOVFJBTlQKKyAgICAjZGVmaW5lIF9SRUVOVFJBTlQKKyAgI2VuZGlmCisjZW5kaWYKKworLyogV2luZG93cyBwbGF0Zm9ybSB3aXRoIEJvcmxhbmQgY29tcGlsZXIgKi8KKyNpZiBkZWZpbmVkKF9XSU4zMikgJiYgZGVmaW5lZChfX0JPUkxBTkRDX18pCisgICN1bmRlZiBYU0xUUFVCRlVOCisgICN1bmRlZiBYU0xUUFVCVkFSCisgICN1bmRlZiBYU0xUQ0FMTAorICAjaWYgZGVmaW5lZChJTl9MSUJYU0xUKSAmJiAhZGVmaW5lZChMSUJYU0xUX1NUQVRJQykKKyAgICAjZGVmaW5lIFhTTFRQVUJGVU4gX19kZWNsc3BlYyhkbGxleHBvcnQpCisgICAgI2RlZmluZSBYU0xUUFVCVkFSIF9fZGVjbHNwZWMoZGxsZXhwb3J0KSBleHRlcm4KKyAgI2Vsc2UKKyAgICAjZGVmaW5lIFhTTFRQVUJGVU4KKyAgICAjaWYgIWRlZmluZWQoTElCWFNMVF9TVEFUSUMpCisgICAgICAjZGVmaW5lIFhTTFRQVUJWQVIgX19kZWNsc3BlYyhkbGxpbXBvcnQpIGV4dGVybgorICAgICNlbHNlCisgICAgICAjZGVmaW5lIFhTTFRQVUJWQVIgZXh0ZXJuCisgICAgI2VuZGlmCisgICNlbmRpZgorICAjZGVmaW5lIFhTTFRDQUxMIF9fY2RlY2wKKyAgI2lmICFkZWZpbmVkIF9SRUVOVFJBTlQKKyAgICAjZGVmaW5lIF9SRUVOVFJBTlQKKyAgI2VuZGlmCisjZW5kaWYKKworLyogV2luZG93cyBwbGF0Zm9ybSB3aXRoIEdOVSBjb21waWxlciAoTWluZ3cpICovCisjaWYgZGVmaW5lZChfV0lOMzIpICYmIGRlZmluZWQoX19NSU5HVzMyX18pCisgICN1bmRlZiBYU0xUUFVCRlVOCisgICN1bmRlZiBYU0xUUFVCVkFSCisgICN1bmRlZiBYU0xUQ0FMTAorLyoKKyAgI2lmIGRlZmluZWQoSU5fTElCWFNMVCkgJiYgIWRlZmluZWQoTElCWFNMVF9TVEFUSUMpCisqLworICAjaWYgIWRlZmluZWQoTElCWFNMVF9TVEFUSUMpCisgICAgI2RlZmluZSBYU0xUUFVCRlVOIF9fZGVjbHNwZWMoZGxsZXhwb3J0KQorICAgICNkZWZpbmUgWFNMVFBVQlZBUiBfX2RlY2xzcGVjKGRsbGV4cG9ydCkgZXh0ZXJuCisgICNlbHNlCisgICAgI2RlZmluZSBYU0xUUFVCRlVOCisgICAgI2lmICFkZWZpbmVkKExJQlhTTFRfU1RBVElDKQorICAgICAgI2RlZmluZSBYU0xUUFVCVkFSIF9fZGVjbHNwZWMoZGxsaW1wb3J0KSBleHRlcm4KKyAgICAjZWxzZQorICAgICAgI2RlZmluZSBYU0xUUFVCVkFSIGV4dGVybgorICAgICNlbmRpZgorICAjZW5kaWYKKyAgI2RlZmluZSBYU0xUQ0FMTCBfX2NkZWNsCisgICNpZiAhZGVmaW5lZCBfUkVFTlRSQU5UCisgICAgI2RlZmluZSBfUkVFTlRSQU5UCisgICNlbmRpZgorI2VuZGlmCisKKy8qIEN5Z3dpbiBwbGF0Zm9ybSwgR05VIGNvbXBpbGVyICovCisjaWYgZGVmaW5lZChfV0lOMzIpICYmIGRlZmluZWQoX19DWUdXSU5fXykKKyAgI3VuZGVmIFhTTFRQVUJGVU4KKyAgI3VuZGVmIFhTTFRQVUJWQVIKKyAgI3VuZGVmIFhTTFRDQUxMCisgICNpZiBkZWZpbmVkKElOX0xJQlhTTFQpICYmICFkZWZpbmVkKExJQlhTTFRfU1RBVElDKQorICAgICNkZWZpbmUgWFNMVFBVQkZVTiBfX2RlY2xzcGVjKGRsbGV4cG9ydCkKKyAgICAjZGVmaW5lIFhTTFRQVUJWQVIgX19kZWNsc3BlYyhkbGxleHBvcnQpCisgICNlbHNlCisgICAgI2RlZmluZSBYU0xUUFVCRlVOCisgICAgI2lmICFkZWZpbmVkKExJQlhTTFRfU1RBVElDKQorICAgICAgI2RlZmluZSBYU0xUUFVCVkFSIF9fZGVjbHNwZWMoZGxsaW1wb3J0KSBleHRlcm4KKyAgICAjZWxzZQorICAgICAgI2RlZmluZSBYU0xUUFVCVkFSCisgICAgI2VuZGlmCisgICNlbmRpZgorICAjZGVmaW5lIFhTTFRDQUxMIF9fY2RlY2wKKyNlbmRpZgorCisvKiBDb21wYXRpYmlsaXR5ICovCisjaWYgIWRlZmluZWQoTElCWFNMVF9QVUJMSUMpCisjZGVmaW5lIExJQlhTTFRfUFVCTElDIFhTTFRQVUJWQVIKKyNlbmRpZgorCisjZW5kaWYgLyogX19YU0xUX0VYUE9SVFNfSF9fICovCisKKwpkaWZmIC0tZ2l0IGEvbGlieHNsdC94c2x0bG9jYWxlLmMgYi9saWJ4c2x0L3hzbHRsb2NhbGUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzAzY2RlCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC94c2x0bG9jYWxlLmMKQEAgLTAsMCArMSw1MDkgQEAKKy8qCisgKiB4c2x0bG9jYWxlLmM6IGxvY2FsZSBoYW5kbGluZworICoKKyAqIFJlZmVyZW5jZToKKyAqIFJGQyAzMDY2OiBUYWdzIGZvciB0aGUgSWRlbnRpZmljYXRpb24gb2YgTGFuZ3VhZ2VzCisgKiBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMDY2LnR4dAorICogSVNPIDYzOS0xLCBJU08gMzE2Ni0xCisgKgorICogQXV0aG9yOiBOaWNrIFdlbGxuaG9mZXIKKyAqIHdpbmFwaSBwb3J0OiBSb3VtZW4gUGV0cm92CisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaW5jbHVkZSA8c3RyaW5nLmg+CisjaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgorCisjaW5jbHVkZSAieHNsdGxvY2FsZS5oIgorI2luY2x1ZGUgInhzbHR1dGlscy5oIgorCisjaWYgZGVmaW5lZChfX0dMSUJDX18pICYmIF9fR0xJQkNfXyA9PSAyICYmIF9fR0xJQkNfTUlOT1JfXyA8PSAyCisjZGVmaW5lIG5ld2xvY2FsZSBfX25ld2xvY2FsZQorI2RlZmluZSBmcmVlbG9jYWxlIF9fZnJlZWxvY2FsZQorI2RlZmluZSBzdHJ4ZnJtX2wgX19zdHJ4ZnJtX2wKKyNkZWZpbmUgTENfQ09MTEFURV9NQVNLICgxIDw8IExDX0NPTExBVEUpCisjZW5kaWYKKworI2RlZmluZSBJU0FMUEhBKGMpICgoYyAmIDB4YzApID09IDB4NDAgJiYgKHVuc2lnbmVkKSgoYyAmIDB4MWYpIC0gMSkgPCAyNikKKyNkZWZpbmUgVE9VUFBFUihjKSAoYyAmIH4weDIwKQorI2RlZmluZSBUT0xPV0VSKGMpIChjIHwgMHgyMCkKKworLyp3aXRob3V0IHRlcm1pbmF0aW5nIG51bGwgY2hhcmFjdGVyKi8KKyNkZWZpbmUgWFNMVE1BWF9JU082MzlMQU5HTEVOCQk4CisjZGVmaW5lIFhTTFRNQVhfSVNPMzE2NkNOVFJZTEVOCQk4CisJCQkJCS8qIDxsYW5nPi08Y250cnk+ICovCisjZGVmaW5lIFhTTFRNQVhfTEFOR1RBR0xFTgkJKFhTTFRNQVhfSVNPNjM5TEFOR0xFTisxK1hTTFRNQVhfSVNPMzE2NkNOVFJZTEVOKQorCitzdGF0aWMgY29uc3QgeG1sQ2hhciogeHNsdERlZmF1bHRSZWdpb24oY29uc3QgeG1sQ2hhciAqbG9jYWxlTmFtZSk7CisKKyNpZmRlZiBYU0xUX0xPQ0FMRV9XSU5BUEkKK3htbFJNdXRleFB0ciB4c2x0TG9jYWxlTXV0ZXggPSBOVUxMOworCitzdHJ1Y3QgeHNsdFJGQzE3NjZJbmZvX3MgeworICAgICAgLypub3RlIHR5cGVkZWYgdW5zaWduZWQgY2hhciB4bWxDaGFyICEqLworICAgIHhtbENoYXIgICAgdGFnW1hTTFRNQVhfTEFOR1RBR0xFTisxXTsKKyAgICAgIC8qbm90ZSB0eXBlZGVmIExDSUQgeHNsdExvY2FsZSAhKi8KKyAgICB4c2x0TG9jYWxlIGxjaWQ7Cit9OwordHlwZWRlZiBzdHJ1Y3QgeHNsdFJGQzE3NjZJbmZvX3MgeHNsdFJGQzE3NjZJbmZvOworCitzdGF0aWMgaW50IHhzbHRMb2NhbGVMaXN0U2l6ZSA9IDA7CitzdGF0aWMgeHNsdFJGQzE3NjZJbmZvICp4c2x0TG9jYWxlTGlzdCA9IE5VTEw7CisKKworc3RhdGljIHhzbHRMb2NhbGUKK3hzbHRfbG9jYWxlX1dJTkFQSShjb25zdCB4bWxDaGFyICpsYW5ndWFnZVRhZykgeworICAgIGludCBrOworICAgIHhzbHRSRkMxNzY2SW5mbyAqcCA9IHhzbHRMb2NhbGVMaXN0OworCisgICAgZm9yIChrPTA7IGs8eHNsdExvY2FsZUxpc3RTaXplOyBrKyssIHArKykKKwlpZiAoeG1sU3RyY21wKHAtPnRhZywgbGFuZ3VhZ2VUYWcpID09IDApIHJldHVybiBwLT5sY2lkOworICAgIHJldHVybigoeHNsdExvY2FsZSkwKTsKK30KKworc3RhdGljIHZvaWQgeHNsdEVudW1TdXBwb3J0ZWRMb2NhbGVzKHZvaWQpOworI2VuZGlmCisKKy8qKgorICogeHNsdE5ld0xvY2FsZToKKyAqIEBsYW5ndWFnZVRhZzogUkZDIDMwNjYgbGFuZ3VhZ2UgdGFnCisgKgorICogQ3JlYXRlcyBhIG5ldyBsb2NhbGUgb2YgYW4gb3BhcXVlIHN5c3RlbSBkZXBlbmRlbnQgdHlwZSBiYXNlZCBvbiB0aGUKKyAqIGxhbmd1YWdlIHRhZy4KKyAqCisgKiBSZXR1cm5zIHRoZSBsb2NhbGUgb3IgTlVMTCBvbiBlcnJvciBvciBpZiBubyBtYXRjaGluZyBsb2NhbGUgd2FzIGZvdW5kCisgKi8KK3hzbHRMb2NhbGUKK3hzbHROZXdMb2NhbGUoY29uc3QgeG1sQ2hhciAqbGFuZ3VhZ2VUYWcpIHsKKyNpZmRlZiBYU0xUX0xPQ0FMRV9YTE9DQUxFCisgICAgeHNsdExvY2FsZSBsb2NhbGU7CisgICAgY2hhciBsb2NhbGVOYW1lW1hTTFRNQVhfTEFOR1RBR0xFTis2XTsgLyogNiBjaGFycyBmb3IgIi51dGY4XDAiICovCisgICAgY29uc3QgeG1sQ2hhciAqcCA9IGxhbmd1YWdlVGFnOworICAgIGNvbnN0IGNoYXIgKnJlZ2lvbiA9IE5VTEw7CisgICAgY2hhciAqcSA9IGxvY2FsZU5hbWU7CisgICAgaW50IGksIGxsZW47CisgICAgCisgICAgLyogQ29udmVydCBzb21ldGhpbmcgbGlrZSAicHQtYnIiIHRvICJwdF9CUi51dGY4IiAqLworICAgIAorICAgIGlmIChsYW5ndWFnZVRhZyA9PSBOVUxMKQorICAgIAlyZXR1cm4oTlVMTCk7CisgICAgCisgICAgZm9yIChpPTA7IGk8WFNMVE1BWF9JU082MzlMQU5HTEVOICYmIElTQUxQSEEoKnApOyArK2kpCisJKnErKyA9IFRPTE9XRVIoKnArKyk7CisgICAgCisgICAgaWYgKGkgPT0gMCkKKyAgICAJcmV0dXJuKE5VTEwpOworICAgIAorICAgIGxsZW4gPSBpOworICAgICpxKysgPSAnXyc7CisgICAgCisgICAgaWYgKCpwKSB7CisgICAgCWlmICgqcCsrICE9ICctJykKKyAgICAJICAgIHJldHVybihOVUxMKTsKKwkKKwlmb3IgKGk9MDsgaTxYU0xUTUFYX0lTTzMxNjZDTlRSWUxFTiAmJiBJU0FMUEhBKCpwKTsgKytpKQorCSAgICAqcSsrID0gVE9VUFBFUigqcCsrKTsKKyAgICAKKyAgICAJaWYgKGkgPT0gMCB8fCAqcCkKKyAgICAJICAgIHJldHVybihOVUxMKTsKKyAgICAJCisgICAgICAgIG1lbWNweShxLCAiLnV0ZjgiLCA2KTsKKyAgICAgICAgbG9jYWxlID0gbmV3bG9jYWxlKExDX0NPTExBVEVfTUFTSywgbG9jYWxlTmFtZSwgTlVMTCk7CisgICAgICAgIGlmIChsb2NhbGUgIT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybihsb2NhbGUpOworICAgICAgICAKKyAgICAgICAgLyogQ29udGludWUgd2l0aG91dCB1c2luZyBjb3VudHJ5IGNvZGUgKi8KKyAgICAgICAgCisgICAgICAgIHEgPSBsb2NhbGVOYW1lICsgbGxlbiArIDE7CisgICAgfQorICAgIAorICAgIC8qIFRyeSBsb2NhbGUgd2l0aG91dCB0ZXJyaXRvcnksIGUuZy4gZm9yIEVzcGVyYW50byAoZW8pICovCisKKyAgICBtZW1jcHkocSwgIi51dGY4IiwgNik7CisgICAgbG9jYWxlID0gbmV3bG9jYWxlKExDX0NPTExBVEVfTUFTSywgbG9jYWxlTmFtZSwgTlVMTCk7CisgICAgaWYgKGxvY2FsZSAhPSBOVUxMKQorICAgICAgICByZXR1cm4obG9jYWxlKTsKKworICAgIC8qIFRyeSB0byBmaW5kIG1vc3QgY29tbW9uIGNvdW50cnkgZm9yIGxhbmd1YWdlICovCisgICAgCisgICAgaWYgKGxsZW4gIT0gMikKKyAgICAgICAgcmV0dXJuKE5VTEwpOworCisgICAgcmVnaW9uID0gKGNoYXIgKil4c2x0RGVmYXVsdFJlZ2lvbigoeG1sQ2hhciAqKWxvY2FsZU5hbWUpOworICAgIGlmIChyZWdpb24gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuKE5VTEwpOworICAgICAKKyAgICBxID0gbG9jYWxlTmFtZSArIGxsZW4gKyAxOworICAgICpxKysgPSByZWdpb25bMF07CisgICAgKnErKyA9IHJlZ2lvblsxXTsKKyAgICBtZW1jcHkocSwgIi51dGY4IiwgNik7CisgICAgbG9jYWxlID0gbmV3bG9jYWxlKExDX0NPTExBVEVfTUFTSywgbG9jYWxlTmFtZSwgTlVMTCk7CisgICAgCisgICAgcmV0dXJuKGxvY2FsZSk7CisjZW5kaWYKKworI2lmZGVmIFhTTFRfTE9DQUxFX1dJTkFQSQoreworICAgIHhzbHRMb2NhbGUgICAgbG9jYWxlID0gKHhzbHRMb2NhbGUpMDsKKyAgICB4bWxDaGFyICAgICAgIGxvY2FsZU5hbWVbWFNMVE1BWF9MQU5HVEFHTEVOKzFdOworICAgIHhtbENoYXIgICAgICAgKnEgPSBsb2NhbGVOYW1lOworICAgIGNvbnN0IHhtbENoYXIgKnAgPSBsYW5ndWFnZVRhZzsKKyAgICBpbnQgICAgICAgICAgIGksIGxsZW47CisgICAgY29uc3QgeG1sQ2hhciAqcmVnaW9uID0gTlVMTDsKKworICAgIGlmIChsYW5ndWFnZVRhZyA9PSBOVUxMKSBnb3RvIGVuZDsKKworICAgIHhzbHRFbnVtU3VwcG9ydGVkTG9jYWxlcygpOworCisgICAgZm9yIChpPTA7IGk8WFNMVE1BWF9JU082MzlMQU5HTEVOICYmIElTQUxQSEEoKnApOyArK2kpCisJKnErKyA9IFRPTE9XRVIoKnArKyk7CisgICAgaWYgKGkgPT0gMCkgZ290byBlbmQ7CisKKyAgICBsbGVuID0gaTsKKyAgICAqcSsrID0gJy0nOworICAgIGlmICgqcCkgeyAvKmlmIGNvdW50cnkgdGFnIGlzIGdpdmVuKi8KKwlpZiAoKnArKyAhPSAnLScpIGdvdG8gZW5kOworCQorCWZvciAoaT0wOyBpPFhTTFRNQVhfSVNPMzE2NkNOVFJZTEVOICYmIElTQUxQSEEoKnApOyArK2kpCisJICAgICpxKysgPSBUT1VQUEVSKCpwKyspOworCWlmIChpID09IDAgfHwgKnApIGdvdG8gZW5kOworCisJKnEgPSAnXDAnOworCWxvY2FsZSA9IHhzbHRfbG9jYWxlX1dJTkFQSShsb2NhbGVOYW1lKTsKKwlpZiAobG9jYWxlICE9ICh4c2x0TG9jYWxlKTApIGdvdG8gZW5kOworICAgIH0KKyAgICAvKiBUcnkgdG8gZmluZCBtb3N0IGNvbW1vbiBjb3VudHJ5IGZvciBsYW5ndWFnZSAqLworICAgIHJlZ2lvbiA9IHhzbHREZWZhdWx0UmVnaW9uKGxvY2FsZU5hbWUpOworICAgIGlmIChyZWdpb24gPT0gTlVMTCkgZ290byBlbmQ7CisKKyAgICBzdHJjcHkobG9jYWxlTmFtZSArIGxsZW4gKyAxLCByZWdpb24pOworICAgIGxvY2FsZSA9IHhzbHRfbG9jYWxlX1dJTkFQSShsb2NhbGVOYW1lKTsKK2VuZDoKKyAgICByZXR1cm4obG9jYWxlKTsKK30KKyNlbmRpZgorCisjaWZkZWYgWFNMVF9MT0NBTEVfTk9ORQorICAgIHJldHVybihOVUxMKTsKKyNlbmRpZgorfQorCitzdGF0aWMgY29uc3QgeG1sQ2hhcioKK3hzbHREZWZhdWx0UmVnaW9uKGNvbnN0IHhtbENoYXIgKmxvY2FsZU5hbWUpIHsKKyAgICB4bWxDaGFyIGM7CisgICAgLyogcmVnaW9uIHNob3VsZCBiZSB4bWxDaGFyLCBidXQgZ2NjIHdhcm5zIG9uIGFsbCBzdHJpbmcgYXNzaWdubWVudHMgKi8KKyAgICBjb25zdCBjaGFyICpyZWdpb24gPSBOVUxMOworICAgIAorICAgIGMgPSBsb2NhbGVOYW1lWzFdOworICAgIC8qIFRoaXMgaXMgYmFzZWQgb24gdGhlIGxvY2FsZXMgZnJvbSBnbGliYyAyLjMuMyAqLworICAgIAorICAgIHN3aXRjaCAobG9jYWxlTmFtZVswXSkgeworICAgICAgICBjYXNlICdhJzoKKyAgICAgICAgICAgIGlmIChjID09ICdhJyB8fCBjID09ICdtJykgcmVnaW9uID0gIkVUIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ2YnKSByZWdpb24gPSAiWkEiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnbicpIHJlZ2lvbiA9ICJFUyI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdyJykgcmVnaW9uID0gIkFFIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3onKSByZWdpb24gPSAiQVoiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2InOgorICAgICAgICAgICAgaWYgKGMgPT0gJ2UnKSByZWdpb24gPSAiQlkiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnZycpIHJlZ2lvbiA9ICJCRyI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICduJykgcmVnaW9uID0gIkJEIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3InKSByZWdpb24gPSAiRlIiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAncycpIHJlZ2lvbiA9ICJCQSI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnYyc6CisgICAgICAgICAgICBpZiAoYyA9PSAnYScpIHJlZ2lvbiA9ICJFUyI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdzJykgcmVnaW9uID0gIkNaIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3knKSByZWdpb24gPSAiR0IiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2QnOgorICAgICAgICAgICAgaWYgKGMgPT0gJ2EnKSByZWdpb24gPSAiREsiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnZScpIHJlZ2lvbiA9ICJERSI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnZSc6CisgICAgICAgICAgICBpZiAoYyA9PSAnbCcpIHJlZ2lvbiA9ICJHUiI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICduJyB8fCBjID09ICdvJykgcmVnaW9uID0gIlVTIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3MnIHx8IGMgPT0gJ3UnKSByZWdpb24gPSAiRVMiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAndCcpIHJlZ2lvbiA9ICJFRSI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnZic6CisgICAgICAgICAgICBpZiAoYyA9PSAnYScpIHJlZ2lvbiA9ICJJUiI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdpJykgcmVnaW9uID0gIkZJIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ28nKSByZWdpb24gPSAiRk8iOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAncicpIHJlZ2lvbiA9ICJGUiI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnZyc6CisgICAgICAgICAgICBpZiAoYyA9PSAnYScpIHJlZ2lvbiA9ICJJRSI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdsJykgcmVnaW9uID0gIkVTIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3YnKSByZWdpb24gPSAiR0IiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2gnOgorICAgICAgICAgICAgaWYgKGMgPT0gJ2UnKSByZWdpb24gPSAiSUwiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnaScpIHJlZ2lvbiA9ICJJTiI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdyJykgcmVnaW9uID0gIkhUIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3UnKSByZWdpb24gPSAiSFUiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2knOgorICAgICAgICAgICAgaWYgKGMgPT0gJ2QnKSByZWdpb24gPSAiSUQiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAncycpIHJlZ2lvbiA9ICJJUyI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICd0JykgcmVnaW9uID0gIklUIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3cnKSByZWdpb24gPSAiSUwiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2onOgorICAgICAgICAgICAgaWYgKGMgPT0gJ2EnKSByZWdpb24gPSAiSlAiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2snOgorICAgICAgICAgICAgaWYgKGMgPT0gJ2wnKSByZWdpb24gPSAiR0wiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnbycpIHJlZ2lvbiA9ICJLUiI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICd3JykgcmVnaW9uID0gIkdCIjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICdsJzoKKyAgICAgICAgICAgIGlmIChjID09ICd0JykgcmVnaW9uID0gIkxUIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3YnKSByZWdpb24gPSAiTFYiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ20nOgorICAgICAgICAgICAgaWYgKGMgPT0gJ2snKSByZWdpb24gPSAiTUsiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnbCcgfHwgYyA9PSAncicpIHJlZ2lvbiA9ICJJTiI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICduJykgcmVnaW9uID0gIk1OIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3MnKSByZWdpb24gPSAiTVkiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAndCcpIHJlZ2lvbiA9ICJNVCI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnbic6CisgICAgICAgICAgICBpZiAoYyA9PSAnYicgfHwgYyA9PSAnbicgfHwgYyA9PSAnbycpIHJlZ2lvbiA9ICJOTyI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdlJykgcmVnaW9uID0gIk5QIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ2wnKSByZWdpb24gPSAiTkwiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ28nOgorICAgICAgICAgICAgaWYgKGMgPT0gJ20nKSByZWdpb24gPSAiRVQiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ3AnOgorICAgICAgICAgICAgaWYgKGMgPT0gJ2EnKSByZWdpb24gPSAiSU4iOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnbCcpIHJlZ2lvbiA9ICJQTCI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICd0JykgcmVnaW9uID0gIlBUIjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICdyJzoKKyAgICAgICAgICAgIGlmIChjID09ICdvJykgcmVnaW9uID0gIlJPIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3UnKSByZWdpb24gPSAiUlUiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ3MnOgorICAgICAgICAgICAgc3dpdGNoIChjKSB7CisgICAgICAgICAgICAgICAgY2FzZSAnZSc6IHJlZ2lvbiA9ICJOTyI7IGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ2gnOiByZWdpb24gPSAiWVUiOyBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdrJzogcmVnaW9uID0gIlNLIjsgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAnbCc6IHJlZ2lvbiA9ICJTSSI7IGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ28nOiByZWdpb24gPSAiRVQiOyBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdxJzogcmVnaW9uID0gIkFMIjsgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAndCc6IHJlZ2lvbiA9ICJaQSI7IGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ3YnOiByZWdpb24gPSAiU0UiOyBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICd0JzoKKyAgICAgICAgICAgIGlmIChjID09ICdhJyB8fCBjID09ICdlJykgcmVnaW9uID0gIklOIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ2gnKSByZWdpb24gPSAiVEgiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnaScpIHJlZ2lvbiA9ICJFUiI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdyJykgcmVnaW9uID0gIlRSIjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ3QnKSByZWdpb24gPSAiUlUiOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ3UnOgorICAgICAgICAgICAgaWYgKGMgPT0gJ2snKSByZWdpb24gPSAiVUEiOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAncicpIHJlZ2lvbiA9ICJQSyI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAndic6CisgICAgICAgICAgICBpZiAoYyA9PSAnaScpIHJlZ2lvbiA9ICJWTiI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAndyc6CisgICAgICAgICAgICBpZiAoYyA9PSAnYScpIHJlZ2lvbiA9ICJCRSI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAneCc6CisgICAgICAgICAgICBpZiAoYyA9PSAnaCcpIHJlZ2lvbiA9ICJaQSI7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAneic6CisgICAgICAgICAgICBpZiAoYyA9PSAnaCcpIHJlZ2lvbiA9ICJDTiI7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICd1JykgcmVnaW9uID0gIlpBIjsKKyAgICAgICAgICAgIGJyZWFrOworICAgIH0KKyAgICByZXR1cm4oKHhtbENoYXIgKilyZWdpb24pOworfQorCisvKioKKyAqIHhzbHRGcmVlTG9jYWxlOgorICogQGxvY2FsZTogdGhlIGxvY2FsZSB0byBmcmVlCisgKgorICogRnJlZXMgYSBsb2NhbGUgY3JlYXRlZCB3aXRoIHhzbHROZXdMb2NhbGUKKyAqLwordm9pZAoreHNsdEZyZWVMb2NhbGUoeHNsdExvY2FsZSBsb2NhbGUpIHsKKyNpZmRlZiBYU0xUX0xPQ0FMRV9YTE9DQUxFCisgICAgZnJlZWxvY2FsZShsb2NhbGUpOworI2VuZGlmCit9CisKKy8qKgorICogeHNsdFN0cnhmcm06CisgKiBAbG9jYWxlOiBsb2NhbGUgY3JlYXRlZCB3aXRoIHhzbHROZXdMb2NhbGUKKyAqIEBzdHJpbmc6IFVURi04IHN0cmluZyB0byB0cmFuc2Zvcm0KKyAqCisgKiBUcmFuc2Zvcm1zIGEgc3RyaW5nIGFjY29yZGluZyB0byBsb2NhbGUuIFRoZSB0cmFuc2Zvcm1lZCBzdHJpbmcgbXVzdCB0aGVuIGJlCisgKiBjb21wYXJlZCB3aXRoIHhzbHRMb2NhbGVTdHJjbXAgYW5kIGZyZWVkIHdpdGggeG1sRnJlZS4KKyAqCisgKiBSZXR1cm5zIHRoZSB0cmFuc2Zvcm1lZCBzdHJpbmcgb3IgTlVMTCBvbiBlcnJvcgorICovCit4c2x0TG9jYWxlQ2hhciAqCit4c2x0U3RyeGZybSh4c2x0TG9jYWxlIGxvY2FsZSwgY29uc3QgeG1sQ2hhciAqc3RyaW5nKQoreworI2lmZGVmIFhTTFRfTE9DQUxFX05PTkUKKyAgICByZXR1cm4oTlVMTCk7CisjZWxzZQorICAgIHNpemVfdCB4c3RybGVuLCByOworICAgIHhzbHRMb2NhbGVDaGFyICp4c3RyOworICAgIAorI2lmZGVmIFhTTFRfTE9DQUxFX1hMT0NBTEUKKyAgICB4c3RybGVuID0gc3RyeGZybV9sKE5VTEwsIChjb25zdCBjaGFyICopc3RyaW5nLCAwLCBsb2NhbGUpICsgMTsKKyAgICB4c3RyID0gKHhzbHRMb2NhbGVDaGFyICopIHhtbE1hbGxvYyh4c3RybGVuKTsKKyAgICBpZiAoeHN0ciA9PSBOVUxMKSB7CisJeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsCisJICAgICJ4c2x0U3RyeGZybSA6IG91dCBvZiBtZW1vcnkgZXJyb3JcbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisKKyAgICByID0gc3RyeGZybV9sKChjaGFyICopeHN0ciwgKGNvbnN0IGNoYXIgKilzdHJpbmcsIHhzdHJsZW4sIGxvY2FsZSk7CisjZW5kaWYKKworI2lmZGVmIFhTTFRfTE9DQUxFX1dJTkFQSQorICAgIHhzdHJsZW4gPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX1VURjgsIDAsIHN0cmluZywgLTEsIE5VTEwsIDApOworICAgIGlmICh4c3RybGVuID09IDApIHsKKyAgICAgICAgeHNsdFRyYW5zZm9ybUVycm9yKE5VTEwsIE5VTEwsIE5VTEwsICJ4c2x0U3RyeGZybSA6IE11bHRpQnl0ZVRvV2lkZUNoYXIgY2hlY2sgZmFpbGVkXG4iKTsKKyAgICAgICAgcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICB4c3RyID0gKHhzbHRMb2NhbGVDaGFyKikgeG1sTWFsbG9jKHhzdHJsZW4gKiBzaXplb2YoeHNsdExvY2FsZUNoYXIpKTsKKyAgICBpZiAoeHN0ciA9PSBOVUxMKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLCAieHNsdFN0cnhmcm0gOiBvdXQgb2YgbWVtb3J5XG4iKTsKKyAgICAgICAgcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICByID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9VVEY4LCAwLCBzdHJpbmcsIC0xLCB4c3RyLCB4c3RybGVuKTsKKyAgICBpZiAociA9PSAwKSB7CisgICAgICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLCAieHNsdFN0cnhmcm0gOiBNdWx0aUJ5dGVUb1dpZGVDaGFyIGZhaWxlZFxuIik7CisgICAgICAgIHhtbEZyZWUoeHN0cik7CisgICAgICAgIHJldHVybihOVUxMKTsKKyAgICB9CisgICAgcmV0dXJuKHhzdHIpOworI2VuZGlmIC8qIFhTTFRfTE9DQUxFX1dJTkFQSSAqLworCisgICAgaWYgKHIgPj0geHN0cmxlbikgeworCXhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBOVUxMLCBOVUxMLCAieHNsdFN0cnhmcm0gOiBzdHJ4ZnJtIGZhaWxlZFxuIik7CisgICAgICAgIHhtbEZyZWUoeHN0cik7CisgICAgICAgIHJldHVybihOVUxMKTsKKyAgICB9CisKKyAgICByZXR1cm4oeHN0cik7CisjZW5kaWYgLyogWFNMVF9MT0NBTEVfTk9ORSAqLworfQorCisvKioKKyAqIHhzbHRMb2NhbGVTdHJjbXA6CisgKiBAbG9jYWxlOiBhIGxvY2FsZSBpZGVudGlmaWVyCisgKiBAc3RyMTogYSBzdHJpbmcgdHJhbnNmb3JtZWQgd2l0aCB4c2x0U3RyeGZybQorICogQHN0cjI6IGEgc3RyaW5nIHRyYW5zZm9ybWVkIHdpdGggeHNsdFN0cnhmcm0KKyAqCisgKiBDb21wYXJlcyB0d28gc3RyaW5ncyB0cmFuc2Zvcm1lZCB3aXRoIHhzbHRTdHJ4ZnJtCisgKgorICogUmV0dXJucyBhIHZhbHVlIDwgMCBpZiBzdHIxIHNvcnRzIGJlZm9yZSBzdHIyLAorICogICAgICAgICBhIHZhbHVlID4gMCBpZiBzdHIxIHNvcnRzIGFmdGVyIHN0cjIsCisgKiAgICAgICAgIDAgaWYgc3RyMSBhbmQgc3RyMiBhcmUgZXF1YWwgd3J0IHNvcnRpbmcKKyAqLworaW50Cit4c2x0TG9jYWxlU3RyY21wKHhzbHRMb2NhbGUgbG9jYWxlLCBjb25zdCB4c2x0TG9jYWxlQ2hhciAqc3RyMSwgY29uc3QgeHNsdExvY2FsZUNoYXIgKnN0cjIpIHsKKyAgICAodm9pZClsb2NhbGU7CisjaWZkZWYgWFNMVF9MT0NBTEVfV0lOQVBJCit7CisgICAgaW50IHJldDsKKyAgICBpZiAoc3RyMSA9PSBzdHIyKSByZXR1cm4oMCk7CisgICAgaWYgKHN0cjEgPT0gTlVMTCkgcmV0dXJuKC0xKTsKKyAgICBpZiAoc3RyMiA9PSBOVUxMKSByZXR1cm4oMSk7CisgICAgcmV0ID0gQ29tcGFyZVN0cmluZ1cobG9jYWxlLCAwLCBzdHIxLCAtMSwgc3RyMiwgLTEpOworICAgIGlmIChyZXQgPT0gMCkgeworICAgICAgICB4c2x0VHJhbnNmb3JtRXJyb3IoTlVMTCwgTlVMTCwgTlVMTCwgInhzbHRMb2NhbGVTdHJjbXAgOiBDb21wYXJlU3RyaW5nVyBmYWlsXG4iKTsKKyAgICAgICAgcmV0dXJuKDApOworICAgIH0KKyAgICByZXR1cm4ocmV0IC0gMik7Cit9CisjZWxzZQorICAgIHJldHVybih4bWxTdHJjbXAoc3RyMSwgc3RyMikpOworI2VuZGlmCit9CisKKyNpZmRlZiBYU0xUX0xPQ0FMRV9XSU5BUEkKKy8qKgorICogeHNsdENvdW50U3VwcG9ydGVkTG9jYWxlczoKKyAqIEBsY2lkOiBub3QgdXNlZAorICoKKyAqIGNhbGxiYWNrIHVzZWQgdG8gY291bnQgbG9jYWxlcworICoKKyAqIFJldHVybnMgVFJVRQorICovCitCT09MIENBTExCQUNLCit4c2x0Q291bnRTdXBwb3J0ZWRMb2NhbGVzKExQU1RSIGxjaWQpIHsKKyAgICAodm9pZCkgbGNpZDsKKyAgICArK3hzbHRMb2NhbGVMaXN0U2l6ZTsKKyAgICByZXR1cm4oVFJVRSk7Cit9CisKKy8qKgorICogeHNsdEl0ZXJhdGVTdXBwb3J0ZWRMb2NhbGVzOgorICogQGxjaWQ6IG5vdCB1c2VkCisgKgorICogY2FsbGJhY2sgdXNlZCB0byB0cmFjayBsb2NhbGVzCisgKgorICogUmV0dXJucyBUUlVFIGlmIG5vdCBhdCB0aGUgZW5kIG9mIHRoZSBhcnJheQorICovCitCT09MIENBTExCQUNLCit4c2x0SXRlcmF0ZVN1cHBvcnRlZExvY2FsZXMoTFBTVFIgbGNpZCkgeworICAgIHN0YXRpYyBpbnQgY291bnQgPSAwOworICAgIHhtbENoYXIgICAgaXNvNjM5bGFuZyBbWFNMVE1BWF9JU082MzlMQU5HTEVOICArMV07CisgICAgeG1sQ2hhciAgICBpc28zMTM2Y3RyeVtYU0xUTUFYX0lTTzMxNjZDTlRSWUxFTisxXTsKKyAgICBpbnQgICAgICAgIGssIGw7CisgICAgeHNsdFJGQzE3NjZJbmZvICpwID0geHNsdExvY2FsZUxpc3QgKyBjb3VudDsKKworICAgIGsgPSBzc2NhbmYobGNpZCwgIiVseCIsIChsb25nKikmcC0+bGNpZCk7CisgICAgaWYgKGsgPCAxKSBnb3RvIGVuZDsKKyAgICAvKmRvbid0IGNvdW50IHRlcm1pbmF0aW5nIG51bGwgY2hhcmFjdGVyKi8KKyAgICBrID0gR2V0TG9jYWxlSW5mb0EocC0+bGNpZCwgTE9DQUxFX1NJU082MzlMQU5HTkFNRSAsIGlzbzYzOWxhbmcgLCBzaXplb2YoaXNvNjM5bGFuZyApKTsKKyAgICBpZiAoLS1rIDwgMSkgZ290byBlbmQ7CisgICAgbCA9IEdldExvY2FsZUluZm9BKHAtPmxjaWQsIExPQ0FMRV9TSVNPMzE2NkNUUllOQU1FLCBpc28zMTM2Y3RyeSwgc2l6ZW9mKGlzbzMxMzZjdHJ5KSk7CisgICAgaWYgKC0tbCA8IDEpIGdvdG8gZW5kOworCisgICAgeyAgLypmaWxsIHJlc3VsdHMqLworCXhtbENoYXIgICAgKnEgPSBwLT50YWc7CisJbWVtY3B5KHEsIGlzbzYzOWxhbmcsIGspOworCXEgKz0gazsKKwkqcSsrID0gJy0nOworCW1lbWNweShxLCBpc28zMTM2Y3RyeSwgbCk7CisJcSArPSBsOworCSpxID0gJ1wwJzsKKyAgICB9CisgICAgKytjb3VudDsKK2VuZDoKKyAgICByZXR1cm4oKGNvdW50IDwgeHNsdExvY2FsZUxpc3RTaXplKSA/IFRSVUUgOiBGQUxTRSk7Cit9CisKKworc3RhdGljIHZvaWQKK3hzbHRFbnVtU3VwcG9ydGVkTG9jYWxlcyh2b2lkKSB7CisgICAgeG1sUk11dGV4TG9jayh4c2x0TG9jYWxlTXV0ZXgpOworICAgIGlmICh4c2x0TG9jYWxlTGlzdFNpemUgPD0gMCkgeworCXNpemVfdCBsZW47CisKKwlFbnVtU3lzdGVtTG9jYWxlc0EoeHNsdENvdW50U3VwcG9ydGVkTG9jYWxlcywgTENJRF9TVVBQT1JURUQpOworCisJbGVuID0geHNsdExvY2FsZUxpc3RTaXplICogc2l6ZW9mKHhzbHRSRkMxNzY2SW5mbyk7CisJeHNsdExvY2FsZUxpc3QgPSB4bWxNYWxsb2MobGVuKTsKKwltZW1zZXQoeHNsdExvY2FsZUxpc3QsIDAsIGxlbik7CisJRW51bVN5c3RlbUxvY2FsZXNBKHhzbHRJdGVyYXRlU3VwcG9ydGVkTG9jYWxlcywgTENJRF9TVVBQT1JURUQpOworICAgIH0KKyAgICB4bWxSTXV0ZXhVbmxvY2soeHNsdExvY2FsZU11dGV4KTsKK30KKworI2VuZGlmIC8qZGVmIFhTTFRfTE9DQUxFX1dJTkFQSSovCmRpZmYgLS1naXQgYS9saWJ4c2x0L3hzbHRsb2NhbGUuaCBiL2xpYnhzbHQveHNsdGxvY2FsZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5MzQzYjAKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L3hzbHRsb2NhbGUuaApAQCAtMCwwICsxLDU3IEBACisvKgorICogU3VtbWFyeTogTG9jYWxlIGhhbmRsaW5nCisgKiBEZXNjcmlwdGlvbjogSW50ZXJmYWNlcyBmb3IgbG9jYWxlIGhhbmRsaW5nLiBOZWVkZWQgZm9yIGxhbmd1YWdlIGRlcGVuZGVudAorICogICAgICAgICAgICAgIHNvcnRpbmcuCisgKgorICogQ29weTogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIEF1dGhvcjogTmljayBXZWxsbmhvZmVyCisgKi8KKworI2lmbmRlZiBfX1hNTF9YU0xUTE9DQUxFX0hfXworI2RlZmluZSBfX1hNTF9YU0xUTE9DQUxFX0hfXworCisjaW5jbHVkZSA8bGlieG1sL3htbHN0cmluZy5oPgorCisjaWZkZWYgWFNMVF9MT0NBTEVfWExPQ0FMRQorCisjaW5jbHVkZSA8bG9jYWxlLmg+CisjaW5jbHVkZSA8eGxvY2FsZS5oPgorCisjaWZkZWYgX19HTElCQ19fCisvKmxvY2FsZV90IGlzIGRlZmluZWQgb25seSBpZiBfR05VX1NPVVJDRSBpcyBkZWZpbmVkKi8KK3R5cGVkZWYgX19sb2NhbGVfdCB4c2x0TG9jYWxlOworI2Vsc2UKK3R5cGVkZWYgbG9jYWxlX3QgeHNsdExvY2FsZTsKKyNlbmRpZgordHlwZWRlZiB4bWxDaGFyIHhzbHRMb2NhbGVDaGFyOworCisjZWxpZiBkZWZpbmVkKFhTTFRfTE9DQUxFX1dJTkFQSSkKKworI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNpbmNsdWRlIDx3aW5ubHMuaD4KKwordHlwZWRlZiBMQ0lEIHhzbHRMb2NhbGU7Cit0eXBlZGVmIHdjaGFyX3QgeHNsdExvY2FsZUNoYXI7CisKKyNlbHNlCisKKy8qCisgKiBYU0xUX0xPQ0FMRV9OT05FOgorICogTWFjcm8gaW5kaWNhdGluZyB0aGF0IGxvY2FsZSBhcmUgbm90IHN1cHBvcnRlZAorICovCisjaWZuZGVmIFhTTFRfTE9DQUxFX05PTkUKKyNkZWZpbmUgWFNMVF9MT0NBTEVfTk9ORQorI2VuZGlmCisKK3R5cGVkZWYgdm9pZCAqeHNsdExvY2FsZTsKK3R5cGVkZWYgeG1sQ2hhciB4c2x0TG9jYWxlQ2hhcjsKKworI2VuZGlmCisKK3hzbHRMb2NhbGUgeHNsdE5ld0xvY2FsZShjb25zdCB4bWxDaGFyICpsYW5nTmFtZSk7Cit2b2lkIHhzbHRGcmVlTG9jYWxlKHhzbHRMb2NhbGUgbG9jYWxlKTsKK3hzbHRMb2NhbGVDaGFyICp4c2x0U3RyeGZybSh4c2x0TG9jYWxlIGxvY2FsZSwgY29uc3QgeG1sQ2hhciAqc3RyaW5nKTsKK2ludCB4c2x0TG9jYWxlU3RyY21wKHhzbHRMb2NhbGUgbG9jYWxlLCBjb25zdCB4c2x0TG9jYWxlQ2hhciAqc3RyMSwgY29uc3QgeHNsdExvY2FsZUNoYXIgKnN0cjIpOworCisjZW5kaWYgLyogX19YTUxfWFNMVExPQ0FMRV9IX18gKi8KZGlmZiAtLWdpdCBhL2xpYnhzbHQveHNsdHV0aWxzLmMgYi9saWJ4c2x0L3hzbHR1dGlscy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk1NjVlMTUKLS0tIC9kZXYvbnVsbAorKysgYi9saWJ4c2x0L3hzbHR1dGlscy5jCkBAIC0wLDAgKzEsMjI4MSBAQAorLyoKKyAqIHhzbHR1dGlscy5jOiBVdGlsaXRpZXMgZm9yIHRoZSBYU0wgVHJhbnNmb3JtYXRpb24gMS4wIGVuZ2luZQorICoKKyAqIFJlZmVyZW5jZToKKyAqICAgaHR0cDovL3d3dy53My5vcmcvVFIvMTk5OS9SRUMteHNsdC0xOTk5MTExNgorICoKKyAqIFNlZSBDb3B5cmlnaHQgZm9yIHRoZSBzdGF0dXMgb2YgdGhpcyBzb2Z0d2FyZS4KKyAqCisgKiBkYW5pZWxAdmVpbGxhcmQuY29tCisgKi8KKworI2RlZmluZSBJTl9MSUJYU0xUCisjaW5jbHVkZSAibGlieHNsdC5oIgorCisjaWZuZGVmCVhTTFRfTkVFRF9UUklPCisjaW5jbHVkZSA8c3RkaW8uaD4KKyNlbHNlCisjaW5jbHVkZSA8dHJpby5oPgorI2VuZGlmCisKKyNpbmNsdWRlIDxzdHJpbmcuaD4KKyNpZmRlZiBIQVZFX1NZU19USU1FX0gKKyNpbmNsdWRlIDxzeXMvdGltZS5oPgorI2VuZGlmCisjaWZkZWYgSEFWRV9VTklTVERfSAorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2VuZGlmCisjaWZkZWYgSEFWRV9TVERMSUJfSAorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2VuZGlmCisjaW5jbHVkZSA8c3RkYXJnLmg+CisKKyNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CisjaW5jbHVkZSA8bGlieG1sL3RyZWUuaD4KKyNpbmNsdWRlIDxsaWJ4bWwvSFRNTHRyZWUuaD4KKyNpbmNsdWRlIDxsaWJ4bWwveG1sZXJyb3IuaD4KKyNpbmNsdWRlIDxsaWJ4bWwveG1sSU8uaD4KKyNpbmNsdWRlICJ4c2x0dXRpbHMuaCIKKyNpbmNsdWRlICJ0ZW1wbGF0ZXMuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisjaW5jbHVkZSAiaW1wb3J0cy5oIgorI2luY2x1ZGUgInRyYW5zZm9ybS5oIgorCisvKiBnZXR0aW1lb2ZkYXkgb24gV2luZG93cyA/Pz8gKi8KKyNpZiBkZWZpbmVkKFdJTjMyKSAmJiAhZGVmaW5lZChfX0NZR1dJTl9fKQorI2lmZGVmIF9NU0NfVkVSCisjaW5jbHVkZSA8d2luc29jazIuaD4KKyNwcmFnbWEgY29tbWVudChsaWIsICJ3czJfMzIubGliIikKKyNkZWZpbmUgZ2V0dGltZW9mZGF5KHAxLHAyKQorI2RlZmluZSBIQVZFX0dFVFRJTUVPRkRBWQorI2RlZmluZSBYU0xUX1dJTjMyX1BFUkZPUk1BTkNFX0NPVU5URVIKKyNlbmRpZiAvKiBfTVNfVkVSICovCisjZW5kaWYgLyogV0lOMzIgKi8KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogCQkJCQkJCQkJKgorICogCQkJQ29udmVuaWVuY2UgZnVuY3Rpb24JCQkJKgorICogCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0R2V0Q05zUHJvcDoKKyAqIEBzdHlsZTogdGhlIHN0eWxlc2hlZXQKKyAqIEBub2RlOiAgdGhlIG5vZGUKKyAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBuYW1lCisgKiBAbmFtZVNwYWNlOiAgdGhlIFVSSSBvZiB0aGUgbmFtZXNwYWNlCisgKgorICogU2ltaWxhciB0byB4bWxHZXROc1Byb3AoKSBidXQgd2l0aCBhIHNsaWdodGx5IGRpZmZlcmVudCBzZW1hbnRpYworICoKKyAqIFNlYXJjaCBhbmQgZ2V0IHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgYXNzb2NpYXRlZCB0byBhIG5vZGUKKyAqIFRoaXMgYXR0cmlidXRlIGhhcyB0byBiZSBhbmNob3JlZCBpbiB0aGUgbmFtZXNwYWNlIHNwZWNpZmllZCwKKyAqIG9yIGhhcyBubyBuYW1lc3BhY2UgYW5kIHRoZSBlbGVtZW50IGlzIGluIHRoYXQgbmFtZXNwYWNlLgorICoKKyAqIFRoaXMgZG9lcyB0aGUgZW50aXR5IHN1YnN0aXR1dGlvbi4KKyAqIFRoaXMgZnVuY3Rpb24gbG9va3MgaW4gRFREIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBmb3IgI0ZJWEVEIG9yCisgKiBkZWZhdWx0IGRlY2xhcmF0aW9uIHZhbHVlcyB1bmxlc3MgRFREIHVzZSBoYXMgYmVlbiB0dXJuZWQgb2ZmLgorICoKKyAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvciBOVUxMIGlmIG5vdCBmb3VuZC4gVGhlIHN0cmluZyBpcyBhbGxvY2F0ZWQKKyAqICAgICAgICAgaW4gdGhlIHN0eWxlc2hlZXQgZGljdGlvbmFyeS4KKyAqLworY29uc3QgeG1sQ2hhciAqCit4c2x0R2V0Q05zUHJvcCh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgeG1sTm9kZVB0ciBub2RlLAorICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lLCBjb25zdCB4bWxDaGFyICpuYW1lU3BhY2UpIHsKKyAgICB4bWxBdHRyUHRyIHByb3A7CisgICAgeG1sRG9jUHRyIGRvYzsKKyAgICB4bWxOc1B0ciBuczsKKyAgICB4bWxDaGFyICp0bXA7CisgICAgY29uc3QgeG1sQ2hhciAqcmV0OworCisgICAgaWYgKChub2RlID09IE5VTEwpIHx8IChzdHlsZSA9PSBOVUxMKSB8fCAoc3R5bGUtPmRpY3QgPT0gTlVMTCkpCisJcmV0dXJuKE5VTEwpOworCisgICAgcHJvcCA9IG5vZGUtPnByb3BlcnRpZXM7CisgICAgaWYgKG5hbWVTcGFjZSA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiB4bWxHZXRQcm9wKG5vZGUsIG5hbWUpOworICAgIH0KKyAgICB3aGlsZSAocHJvcCAhPSBOVUxMKSB7CisJLyoKKwkgKiBPbmUgbmVlZCB0byBoYXZlCisJICogICAtIHNhbWUgYXR0cmlidXRlIG5hbWVzCisJICogICAtIGFuZCB0aGUgYXR0cmlidXRlIGNhcnJ5aW5nIHRoYXQgbmFtZXNwYWNlCisJICovCisgICAgICAgIGlmICgoeG1sU3RyRXF1YWwocHJvcC0+bmFtZSwgbmFtZSkpICYmCisJICAgICgoKHByb3AtPm5zID09IE5VTEwpICYmIChub2RlLT5ucyAhPSBOVUxMKSAmJgorCSAgICAgICh4bWxTdHJFcXVhbChub2RlLT5ucy0+aHJlZiwgbmFtZVNwYWNlKSkpIHx8CisJICAgICAoKHByb3AtPm5zICE9IE5VTEwpICYmCisJICAgICAgKHhtbFN0ckVxdWFsKHByb3AtPm5zLT5ocmVmLCBuYW1lU3BhY2UpKSkpKSB7CisKKwkgICAgdG1wID0geG1sTm9kZUxpc3RHZXRTdHJpbmcobm9kZS0+ZG9jLCBwcm9wLT5jaGlsZHJlbiwgMSk7CisJICAgIGlmICh0bXAgPT0gTlVMTCkKKwkgICAgICAgIHJldCA9IHhtbERpY3RMb29rdXAoc3R5bGUtPmRpY3QsIEJBRF9DQVNUICIiLCAwKTsKKwkgICAgZWxzZSB7CisJICAgICAgICByZXQgPSB4bWxEaWN0TG9va3VwKHN0eWxlLT5kaWN0LCB0bXAsIC0xKTsKKwkJeG1sRnJlZSh0bXApOworCSAgICB9CisJICAgIHJldHVybiByZXQ7CisgICAgICAgIH0KKwlwcm9wID0gcHJvcC0+bmV4dDsKKyAgICB9CisgICAgdG1wID0gTlVMTDsKKyAgICAvKgorICAgICAqIENoZWNrIGlmIHRoZXJlIGlzIGEgZGVmYXVsdCBkZWNsYXJhdGlvbiBpbiB0aGUgaW50ZXJuYWwKKyAgICAgKiBvciBleHRlcm5hbCBzdWJzZXRzCisgICAgICovCisgICAgZG9jID0gIG5vZGUtPmRvYzsKKyAgICBpZiAoZG9jICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKGRvYy0+aW50U3Vic2V0ICE9IE5VTEwpIHsKKwkgICAgeG1sQXR0cmlidXRlUHRyIGF0dHJEZWNsOworCisJICAgIGF0dHJEZWNsID0geG1sR2V0RHRkQXR0ckRlc2MoZG9jLT5pbnRTdWJzZXQsIG5vZGUtPm5hbWUsIG5hbWUpOworCSAgICBpZiAoKGF0dHJEZWNsID09IE5VTEwpICYmIChkb2MtPmV4dFN1YnNldCAhPSBOVUxMKSkKKwkJYXR0ckRlY2wgPSB4bWxHZXREdGRBdHRyRGVzYyhkb2MtPmV4dFN1YnNldCwgbm9kZS0+bmFtZSwgbmFtZSk7CisJCQorCSAgICBpZiAoKGF0dHJEZWNsICE9IE5VTEwpICYmIChhdHRyRGVjbC0+cHJlZml4ICE9IE5VTEwpKSB7CisJICAgICAgICAvKgorCQkgKiBUaGUgRFREIGRlY2xhcmF0aW9uIG9ubHkgYWxsb3dzIGEgcHJlZml4IHNlYXJjaAorCQkgKi8KKwkJbnMgPSB4bWxTZWFyY2hOcyhkb2MsIG5vZGUsIGF0dHJEZWNsLT5wcmVmaXgpOworCQlpZiAoKG5zICE9IE5VTEwpICYmICh4bWxTdHJFcXVhbChucy0+aHJlZiwgbmFtZVNwYWNlKSkpCisJCSAgICByZXR1cm4oeG1sRGljdExvb2t1cChzdHlsZS0+ZGljdCwKKwkJICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJEZWNsLT5kZWZhdWx0VmFsdWUsIC0xKSk7CisJICAgIH0KKwl9CisgICAgfQorICAgIHJldHVybihOVUxMKTsKK30KKy8qKgorICogeHNsdEdldE5zUHJvcDoKKyAqIEBub2RlOiAgdGhlIG5vZGUKKyAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBuYW1lCisgKiBAbmFtZVNwYWNlOiAgdGhlIFVSSSBvZiB0aGUgbmFtZXNwYWNlCisgKgorICogU2ltaWxhciB0byB4bWxHZXROc1Byb3AoKSBidXQgd2l0aCBhIHNsaWdodGx5IGRpZmZlcmVudCBzZW1hbnRpYworICoKKyAqIFNlYXJjaCBhbmQgZ2V0IHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUgYXNzb2NpYXRlZCB0byBhIG5vZGUKKyAqIFRoaXMgYXR0cmlidXRlIGhhcyB0byBiZSBhbmNob3JlZCBpbiB0aGUgbmFtZXNwYWNlIHNwZWNpZmllZCwKKyAqIG9yIGhhcyBubyBuYW1lc3BhY2UgYW5kIHRoZSBlbGVtZW50IGlzIGluIHRoYXQgbmFtZXNwYWNlLgorICoKKyAqIFRoaXMgZG9lcyB0aGUgZW50aXR5IHN1YnN0aXR1dGlvbi4KKyAqIFRoaXMgZnVuY3Rpb24gbG9va3MgaW4gRFREIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBmb3IgI0ZJWEVEIG9yCisgKiBkZWZhdWx0IGRlY2xhcmF0aW9uIHZhbHVlcyB1bmxlc3MgRFREIHVzZSBoYXMgYmVlbiB0dXJuZWQgb2ZmLgorICoKKyAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvciBOVUxMIGlmIG5vdCBmb3VuZC4KKyAqICAgICBJdCdzIHVwIHRvIHRoZSBjYWxsZXIgdG8gZnJlZSB0aGUgbWVtb3J5LgorICovCit4bWxDaGFyICoKK3hzbHRHZXROc1Byb3AoeG1sTm9kZVB0ciBub2RlLCBjb25zdCB4bWxDaGFyICpuYW1lLCBjb25zdCB4bWxDaGFyICpuYW1lU3BhY2UpIHsKKyAgICB4bWxBdHRyUHRyIHByb3A7CisgICAgeG1sRG9jUHRyIGRvYzsKKyAgICB4bWxOc1B0ciBuczsKKworICAgIGlmIChub2RlID09IE5VTEwpCisJcmV0dXJuKE5VTEwpOworCisgICAgcHJvcCA9IG5vZGUtPnByb3BlcnRpZXM7CisgICAgLyoKKyAgICAqIFRPRE86IFN1YnN0aXR1dGUgeG1sR2V0UHJvcCgpIGZvciB4bWxHZXROc1Byb3AoKSwgc2luY2UgdGhlIGZvcm1lcgorICAgICogaXMgbm90IG5hbWVzcGFjZS1hd2FyZSBhbmQgd2lsbCByZXR1cm4gYW4gYXR0cmlidXRlIHdpdGggZXF1YWwKKyAgICAqIG5hbWUgcmVnYXJkbGVzcyBvZiBpdHMgbmFtZXNwYWNlLgorICAgICogRXhhbXBsZToKKyAgICAqICAgPHhzbDplbGVtZW50IGZvbzpuYW1lPSJteU5hbWUiLz4KKyAgICAqICAgU28gdGhpcyB3b3VsZCByZXR1cm4gIm15TmFtZSIgZXZlbiBpZiBhbiBhdHRyaWJ1dGUgQG5hbWUKKyAgICAqICAgaW4gdGhlIFhTTFQgd2FzIHJlcXVlc3RlZC4KKyAgICAqLworICAgIGlmIChuYW1lU3BhY2UgPT0gTlVMTCkKKwlyZXR1cm4oeG1sR2V0UHJvcChub2RlLCBuYW1lKSk7CisgICAgd2hpbGUgKHByb3AgIT0gTlVMTCkgeworCS8qCisJICogT25lIG5lZWQgdG8gaGF2ZQorCSAqICAgLSBzYW1lIGF0dHJpYnV0ZSBuYW1lcworCSAqICAgLSBhbmQgdGhlIGF0dHJpYnV0ZSBjYXJyeWluZyB0aGF0IG5hbWVzcGFjZQorCSAqLworICAgICAgICBpZiAoKHhtbFN0ckVxdWFsKHByb3AtPm5hbWUsIG5hbWUpKSAmJgorCSAgICAoKChwcm9wLT5ucyA9PSBOVUxMKSAmJiAobm9kZS0+bnMgIT0gTlVMTCkgJiYKKwkgICAgICAoeG1sU3RyRXF1YWwobm9kZS0+bnMtPmhyZWYsIG5hbWVTcGFjZSkpKSB8fAorCSAgICAgKChwcm9wLT5ucyAhPSBOVUxMKSAmJgorCSAgICAgICh4bWxTdHJFcXVhbChwcm9wLT5ucy0+aHJlZiwgbmFtZVNwYWNlKSkpKSkgeworCSAgICB4bWxDaGFyICpyZXQ7CisKKwkgICAgcmV0ID0geG1sTm9kZUxpc3RHZXRTdHJpbmcobm9kZS0+ZG9jLCBwcm9wLT5jaGlsZHJlbiwgMSk7CisJICAgIGlmIChyZXQgPT0gTlVMTCkgcmV0dXJuKHhtbFN0cmR1cCgoeG1sQ2hhciAqKSIiKSk7CisJICAgIHJldHVybihyZXQpOworICAgICAgICB9CisJcHJvcCA9IHByb3AtPm5leHQ7CisgICAgfQorCisgICAgLyoKKyAgICAgKiBDaGVjayBpZiB0aGVyZSBpcyBhIGRlZmF1bHQgZGVjbGFyYXRpb24gaW4gdGhlIGludGVybmFsCisgICAgICogb3IgZXh0ZXJuYWwgc3Vic2V0cworICAgICAqLworICAgIGRvYyA9ICBub2RlLT5kb2M7CisgICAgaWYgKGRvYyAhPSBOVUxMKSB7CisgICAgICAgIGlmIChkb2MtPmludFN1YnNldCAhPSBOVUxMKSB7CisJICAgIHhtbEF0dHJpYnV0ZVB0ciBhdHRyRGVjbDsKKworCSAgICBhdHRyRGVjbCA9IHhtbEdldER0ZEF0dHJEZXNjKGRvYy0+aW50U3Vic2V0LCBub2RlLT5uYW1lLCBuYW1lKTsKKwkgICAgaWYgKChhdHRyRGVjbCA9PSBOVUxMKSAmJiAoZG9jLT5leHRTdWJzZXQgIT0gTlVMTCkpCisJCWF0dHJEZWNsID0geG1sR2V0RHRkQXR0ckRlc2MoZG9jLT5leHRTdWJzZXQsIG5vZGUtPm5hbWUsIG5hbWUpOworCQkKKwkgICAgaWYgKChhdHRyRGVjbCAhPSBOVUxMKSAmJiAoYXR0ckRlY2wtPnByZWZpeCAhPSBOVUxMKSkgeworCSAgICAgICAgLyoKKwkJICogVGhlIERURCBkZWNsYXJhdGlvbiBvbmx5IGFsbG93cyBhIHByZWZpeCBzZWFyY2gKKwkJICovCisJCW5zID0geG1sU2VhcmNoTnMoZG9jLCBub2RlLCBhdHRyRGVjbC0+cHJlZml4KTsKKwkJaWYgKChucyAhPSBOVUxMKSAmJiAoeG1sU3RyRXF1YWwobnMtPmhyZWYsIG5hbWVTcGFjZSkpKQorCQkgICAgcmV0dXJuKHhtbFN0cmR1cChhdHRyRGVjbC0+ZGVmYXVsdFZhbHVlKSk7CisJICAgIH0KKwl9CisgICAgfQorICAgIHJldHVybihOVUxMKTsKK30KKworLyoqCisgKiB4c2x0R2V0VVRGOENoYXI6CisgKiBAdXRmOiAgYSBzZXF1ZW5jZSBvZiBVVEYtOCBlbmNvZGVkIGJ5dGVzCisgKiBAbGVuOiAgYSBwb2ludGVyIHRvIEBieXRlcyBsZW4KKyAqCisgKiBSZWFkIG9uZSBVVEY4IENoYXIgZnJvbSBAdXRmCisgKiBGdW5jdGlvbiBjb3BpZWQgZnJvbSBsaWJ4bWwyIHhtbEdldFVURjhDaGFyKCkgLi4uIHRvIGRpc2NhcmQgdWx0aW1hdGVseQorICogYW5kIHVzZSB0aGUgb3JpZ2luYWwgQVBJCisgKgorICogUmV0dXJucyB0aGUgY2hhciB2YWx1ZSBvciAtMSBpbiBjYXNlIG9mIGVycm9yIGFuZCB1cGRhdGUgQGxlbiB3aXRoIHRoZQorICogICAgICAgIG51bWJlciBvZiBieXRlcyB1c2VkCisgKi8KK2ludAoreHNsdEdldFVURjhDaGFyKGNvbnN0IHVuc2lnbmVkIGNoYXIgKnV0ZiwgaW50ICpsZW4pIHsKKyAgICB1bnNpZ25lZCBpbnQgYzsKKworICAgIGlmICh1dGYgPT0gTlVMTCkKKwlnb3RvIGVycm9yOworICAgIGlmIChsZW4gPT0gTlVMTCkKKwlnb3RvIGVycm9yOworICAgIGlmICgqbGVuIDwgMSkKKwlnb3RvIGVycm9yOworCisgICAgYyA9IHV0ZlswXTsKKyAgICBpZiAoYyAmIDB4ODApIHsKKwlpZiAoKmxlbiA8IDIpCisJICAgIGdvdG8gZXJyb3I7CisJaWYgKCh1dGZbMV0gJiAweGMwKSAhPSAweDgwKQorCSAgICBnb3RvIGVycm9yOworCWlmICgoYyAmIDB4ZTApID09IDB4ZTApIHsKKwkgICAgaWYgKCpsZW4gPCAzKQorCQlnb3RvIGVycm9yOworCSAgICBpZiAoKHV0ZlsyXSAmIDB4YzApICE9IDB4ODApCisJCWdvdG8gZXJyb3I7CisJICAgIGlmICgoYyAmIDB4ZjApID09IDB4ZjApIHsKKwkJaWYgKCpsZW4gPCA0KQorCQkgICAgZ290byBlcnJvcjsKKwkJaWYgKChjICYgMHhmOCkgIT0gMHhmMCB8fCAodXRmWzNdICYgMHhjMCkgIT0gMHg4MCkKKwkJICAgIGdvdG8gZXJyb3I7CisJCSpsZW4gPSA0OworCQkvKiA0LWJ5dGUgY29kZSAqLworCQljID0gKHV0ZlswXSAmIDB4NykgPDwgMTg7CisJCWMgfD0gKHV0ZlsxXSAmIDB4M2YpIDw8IDEyOworCQljIHw9ICh1dGZbMl0gJiAweDNmKSA8PCA2OworCQljIHw9IHV0ZlszXSAmIDB4M2Y7CisJICAgIH0gZWxzZSB7CisJICAgICAgLyogMy1ieXRlIGNvZGUgKi8KKwkJKmxlbiA9IDM7CisJCWMgPSAodXRmWzBdICYgMHhmKSA8PCAxMjsKKwkJYyB8PSAodXRmWzFdICYgMHgzZikgPDwgNjsKKwkJYyB8PSB1dGZbMl0gJiAweDNmOworCSAgICB9CisJfSBlbHNlIHsKKwkgIC8qIDItYnl0ZSBjb2RlICovCisJICAgICpsZW4gPSAyOworCSAgICBjID0gKHV0ZlswXSAmIDB4MWYpIDw8IDY7CisJICAgIGMgfD0gdXRmWzFdICYgMHgzZjsKKwl9CisgICAgfSBlbHNlIHsKKwkvKiAxLWJ5dGUgY29kZSAqLworCSpsZW4gPSAxOworICAgIH0KKyAgICByZXR1cm4oYyk7CisKK2Vycm9yOgorICAgIGlmIChsZW4gIT0gTlVMTCkKKwkqbGVuID0gMDsKKyAgICByZXR1cm4oLTEpOworfQorCisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisKKy8qKgorICogeHNsdFBvaW50ZXJMaXN0QWRkU2l6ZToKKyAqIEBsaXN0OiB0aGUgcG9pbnRlciBsaXN0IHN0cnVjdHVyZQorICogQGl0ZW06IHRoZSBpdGVtIHRvIGJlIHN0b3JlZAorICogQGluaXRpYWxTaXplOiB0aGUgaW5pdGlhbCBzaXplIG9mIHRoZSBsaXN0CisgKgorICogQWRkcyBhbiBpdGVtIHRvIHRoZSBsaXN0LgorICoKKyAqIFJldHVybnMgdGhlIHBvc2l0aW9uIG9mIHRoZSBhZGRlZCBpdGVtIGluIHRoZSBsaXN0IG9yCisgKiAgICAgICAgIC0xIGluIGNhc2Ugb2YgYW4gZXJyb3IuCisgKi8KK2ludAoreHNsdFBvaW50ZXJMaXN0QWRkU2l6ZSh4c2x0UG9pbnRlckxpc3RQdHIgbGlzdCwJCSAgICAgICAKKwkJICAgICAgIHZvaWQgKml0ZW0sCisJCSAgICAgICBpbnQgaW5pdGlhbFNpemUpCit7CisgICAgaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKKwlpZiAoaW5pdGlhbFNpemUgPD0gMCkKKwkgICAgaW5pdGlhbFNpemUgPSAxOworCWxpc3QtPml0ZW1zID0gKHZvaWQgKiopIHhtbE1hbGxvYygKKwkgICAgaW5pdGlhbFNpemUgKiBzaXplb2Yodm9pZCAqKSk7CisJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKKwkgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkgICAgICJ4c2x0UG9pbnRlckxpc3RBZGRTaXplOiBtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlLlxuIik7CisJICAgIHJldHVybigtMSk7CisJfQorCWxpc3QtPm51bWJlciA9IDA7CisJbGlzdC0+c2l6ZSA9IGluaXRpYWxTaXplOworICAgIH0gZWxzZSBpZiAobGlzdC0+c2l6ZSA8PSBsaXN0LT5udW1iZXIpIHsKKwlsaXN0LT5zaXplICo9IDI7CisJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sUmVhbGxvYyhsaXN0LT5pdGVtcywKKwkgICAgbGlzdC0+c2l6ZSAqIHNpemVvZih2b2lkICopKTsKKwlpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgeworCSAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LAorCSAgICAgInhzbHRQb2ludGVyTGlzdEFkZFNpemU6IG1lbW9yeSByZS1hbGxvY2F0aW9uIGZhaWx1cmUuXG4iKTsKKwkgICAgbGlzdC0+c2l6ZSA9IDA7CisJICAgIHJldHVybigtMSk7CisJfQorICAgIH0KKyAgICBsaXN0LT5pdGVtc1tsaXN0LT5udW1iZXIrK10gPSBpdGVtOworICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2x0UG9pbnRlckxpc3RDcmVhdGU6CisgKiBAaW5pdGlhbFNpemU6IHRoZSBpbml0aWFsIHNpemUgZm9yIHRoZSBsaXN0CisgKgorICogQ3JlYXRlcyBhbiB4c2x0UG9pbnRlckxpc3Qgc3RydWN0dXJlLgorICoKKyAqIFJldHVybnMgYSB4c2x0UG9pbnRlckxpc3Qgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBhbiBlcnJvci4KKyAqLworeHNsdFBvaW50ZXJMaXN0UHRyCit4c2x0UG9pbnRlckxpc3RDcmVhdGUoaW50IGluaXRpYWxTaXplKQoreworICAgIHhzbHRQb2ludGVyTGlzdFB0ciByZXQ7CisKKyAgICByZXQgPSB4bWxNYWxsb2Moc2l6ZW9mKHhzbHRQb2ludGVyTGlzdCkpOworICAgIGlmIChyZXQgPT0gTlVMTCkgeworCXhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsCisJICAgICAieHNsdFBvaW50ZXJMaXN0Q3JlYXRlOiBtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlLlxuIik7CisJcmV0dXJuIChOVUxMKTsKKyAgICB9CisgICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhzbHRQb2ludGVyTGlzdCkpOworICAgIGlmIChpbml0aWFsU2l6ZSA+IDApIHsKKwl4c2x0UG9pbnRlckxpc3RBZGRTaXplKHJldCwgTlVMTCwgaW5pdGlhbFNpemUpOworCXJldC0+bnVtYmVyID0gMDsKKyAgICB9CisgICAgcmV0dXJuIChyZXQpOworfQorCisvKioKKyAqIHhzbHRQb2ludGVyTGlzdEZyZWU6CisgKiBAbGlzdDogcG9pbnRlciB0byB0aGUgbGlzdCB0byBiZSBmcmVlZAorICoKKyAqIEZyZWVzIHRoZSB4c2x0UG9pbnRlckxpc3Qgc3RydWN0dXJlLiBUaGlzIGRvZXMgbm90IGZyZWUKKyAqIHRoZSBjb250ZW50IG9mIHRoZSBsaXN0LgorICovCit2b2lkCit4c2x0UG9pbnRlckxpc3RGcmVlKHhzbHRQb2ludGVyTGlzdFB0ciBsaXN0KQoreworICAgIGlmIChsaXN0ID09IE5VTEwpCisJcmV0dXJuOworICAgIGlmIChsaXN0LT5pdGVtcyAhPSBOVUxMKQorCXhtbEZyZWUobGlzdC0+aXRlbXMpOworICAgIHhtbEZyZWUobGlzdCk7Cit9CisKKy8qKgorICogeHNsdFBvaW50ZXJMaXN0Q2xlYXI6CisgKiBAbGlzdDogcG9pbnRlciB0byB0aGUgbGlzdCB0byBiZSBjbGVhcmVkCisgKgorICogUmVzZXRzIHRoZSBsaXN0LCBidXQgZG9lcyBub3QgZnJlZSB0aGUgYWxsb2NhdGVkIGFycmF5CisgKiBhbmQgZG9lcyBub3QgZnJlZSB0aGUgY29udGVudCBvZiB0aGUgbGlzdC4KKyAqLwordm9pZAoreHNsdFBvaW50ZXJMaXN0Q2xlYXIoeHNsdFBvaW50ZXJMaXN0UHRyIGxpc3QpCit7CisgICAgaWYgKGxpc3QtPml0ZW1zICE9IE5VTEwpIHsKKwl4bWxGcmVlKGxpc3QtPml0ZW1zKTsKKwlsaXN0LT5pdGVtcyA9IE5VTEw7CisgICAgfQorICAgIGxpc3QtPm51bWJlciA9IDA7CisgICAgbGlzdC0+c2l6ZSA9IDA7Cit9CisKKyNlbmRpZiAvKiBYU0xUX1JFRkFDVE9SRUQgKi8KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogCQkJCQkJCQkJKgorICogCQlIYW5kbGluZyBvZiBYU0xUIHN0eWxlc2hlZXRzIG1lc3NhZ2VzCQkJKgorICogCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyoqCisgKiB4c2x0TWVzc2FnZToKKyAqIEBjdHh0OiAgYW4gWFNMVCBwcm9jZXNzaW5nIGNvbnRleHQKKyAqIEBub2RlOiAgVGhlIGN1cnJlbnQgbm9kZQorICogQGluc3Q6ICBUaGUgbm9kZSBjb250YWluaW5nIHRoZSBtZXNzYWdlIGluc3RydWN0aW9uCisgKgorICogUHJvY2VzcyBhbmQgeHNsOm1lc3NhZ2UgY29uc3RydWN0CisgKi8KK3ZvaWQKK3hzbHRNZXNzYWdlKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgeG1sTm9kZVB0ciBpbnN0KSB7CisgICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBlcnJvciA9IHhzbHRHZW5lcmljRXJyb3I7CisgICAgdm9pZCAqZXJyY3R4ID0geHNsdEdlbmVyaWNFcnJvckNvbnRleHQ7CisgICAgeG1sQ2hhciAqcHJvcCwgKm1lc3NhZ2U7CisgICAgaW50IHRlcm1pbmF0ZSA9IDA7CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGluc3QgPT0gTlVMTCkpCisJcmV0dXJuOworCisgICAgaWYgKGN0eHQtPmVycm9yICE9IE5VTEwpIHsKKwllcnJvciA9IGN0eHQtPmVycm9yOworCWVycmN0eCA9IGN0eHQtPmVycmN0eDsKKyAgICB9CisKKyAgICBwcm9wID0geG1sR2V0TnNQcm9wKGluc3QsIChjb25zdCB4bWxDaGFyICopInRlcm1pbmF0ZSIsIE5VTEwpOworICAgIGlmIChwcm9wICE9IE5VTEwpIHsKKwlpZiAoeG1sU3RyRXF1YWwocHJvcCwgKGNvbnN0IHhtbENoYXIgKikieWVzIikpIHsKKwkgICAgdGVybWluYXRlID0gMTsKKwl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKHByb3AsIChjb25zdCB4bWxDaGFyICopIm5vIikpIHsKKwkgICAgdGVybWluYXRlID0gMDsKKwl9IGVsc2UgeworCSAgICBlcnJvcihlcnJjdHgsCisJCSJ4c2w6bWVzc2FnZSA6IHRlcm1pbmF0ZSBleHBlY3RpbmcgJ3llcycgb3IgJ25vJ1xuIik7CisJICAgIGN0eHQtPnN0YXRlID0gWFNMVF9TVEFURV9FUlJPUjsKKwl9CisJeG1sRnJlZShwcm9wKTsKKyAgICB9CisgICAgbWVzc2FnZSA9IHhzbHRFdmFsVGVtcGxhdGVTdHJpbmcoY3R4dCwgbm9kZSwgaW5zdCk7CisgICAgaWYgKG1lc3NhZ2UgIT0gTlVMTCkgeworCWludCBsZW4gPSB4bWxTdHJsZW4obWVzc2FnZSk7CisKKwllcnJvcihlcnJjdHgsICIlcyIsIChjb25zdCBjaGFyICopbWVzc2FnZSk7CisJaWYgKChsZW4gPiAwKSAmJiAobWVzc2FnZVtsZW4gLSAxXSAhPSAnXG4nKSkKKwkgICAgZXJyb3IoZXJyY3R4LCAiXG4iKTsKKwl4bWxGcmVlKG1lc3NhZ2UpOworICAgIH0KKyAgICBpZiAodGVybWluYXRlKQorCWN0eHQtPnN0YXRlID0gWFNMVF9TVEFURV9TVE9QUEVEOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAJCQkJCQkJCQkqCisgKiAJCUhhbmRsaW5nIG9mIG91dCBvZiBjb250ZXh0IGVycm9ycwkJCSoKKyAqIAkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKyNkZWZpbmUgWFNMVF9HRVRfVkFSX1NUUihtc2csIHN0cikgewkJCQlcCisgICAgaW50ICAgICAgIHNpemU7CQkJCQkJXAorICAgIGludCAgICAgICBjaGFyczsJCQkJCQlcCisgICAgY2hhciAgICAgICpsYXJnZXI7CQkJCQkJXAorICAgIHZhX2xpc3QgICBhcDsJCQkJCQlcCisJCQkJCQkJCVwKKyAgICBzdHIgPSAoY2hhciAqKSB4bWxNYWxsb2MoMTUwKTsJCQkJXAorICAgIGlmIChzdHIgPT0gTlVMTCkgCQkJCQkJXAorCXJldHVybjsJCQkJCQkJXAorCQkJCQkJCQlcCisgICAgc2l6ZSA9IDE1MDsJCQkJCQkJXAorCQkJCQkJCQlcCisgICAgd2hpbGUgKHNpemUgPCA2NDAwMCkgewkJCQkJXAorCXZhX3N0YXJ0KGFwLCBtc2cpOwkJCQkJXAorICAJY2hhcnMgPSB2c25wcmludGYoc3RyLCBzaXplLCBtc2csIGFwKTsJCQlcCisJdmFfZW5kKGFwKTsJCQkJCQlcCisJaWYgKChjaGFycyA+IC0xKSAmJiAoY2hhcnMgPCBzaXplKSkJCQlcCisJICAgIGJyZWFrOwkJCQkJCVwKKwlpZiAoY2hhcnMgPiAtMSkJCQkJCQlcCisJICAgIHNpemUgKz0gY2hhcnMgKyAxOwkJCQkJXAorCWVsc2UJCQkJCQkJXAorCSAgICBzaXplICs9IDEwMDsJCQkJCVwKKwlpZiAoKGxhcmdlciA9IChjaGFyICopIHhtbFJlYWxsb2Moc3RyLCBzaXplKSkgPT0gTlVMTCkge1wKKwkgICAgeG1sRnJlZShzdHIpOwkJCQkJXAorCSAgICByZXR1cm47CQkJCQkJXAorCX0JCQkJCQkJXAorCXN0ciA9IGxhcmdlcjsJCQkJCQlcCisgICAgfQkJCQkJCQkJXAorfQorLyoqCisgKiB4c2x0R2VuZXJpY0Vycm9yRGVmYXVsdEZ1bmM6CisgKiBAY3R4OiAgYW4gZXJyb3IgY29udGV4dAorICogQG1zZzogIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkvdHJhbnNtaXQKKyAqIEAuLi46ICBleHRyYSBwYXJhbWV0ZXJzIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CisgKiAKKyAqIERlZmF1bHQgaGFuZGxlciBmb3Igb3V0IG9mIGNvbnRleHQgZXJyb3IgbWVzc2FnZXMuCisgKi8KK3N0YXRpYyB2b2lkCit4c2x0R2VuZXJpY0Vycm9yRGVmYXVsdEZ1bmModm9pZCAqY3R4IEFUVFJJQlVURV9VTlVTRUQsIGNvbnN0IGNoYXIgKm1zZywgLi4uKSB7CisgICAgdmFfbGlzdCBhcmdzOworCisgICAgaWYgKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0ID09IE5VTEwpCisJeHNsdEdlbmVyaWNFcnJvckNvbnRleHQgPSAodm9pZCAqKSBzdGRlcnI7CisKKyAgICB2YV9zdGFydChhcmdzLCBtc2cpOworICAgIHZmcHJpbnRmKChGSUxFICopeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsIG1zZywgYXJncyk7CisgICAgdmFfZW5kKGFyZ3MpOworfQorCit4bWxHZW5lcmljRXJyb3JGdW5jIHhzbHRHZW5lcmljRXJyb3IgPSB4c2x0R2VuZXJpY0Vycm9yRGVmYXVsdEZ1bmM7Cit2b2lkICp4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCA9IE5VTEw7CisKKworLyoqCisgKiB4c2x0U2V0R2VuZXJpY0Vycm9yRnVuYzoKKyAqIEBjdHg6ICB0aGUgbmV3IGVycm9yIGhhbmRsaW5nIGNvbnRleHQKKyAqIEBoYW5kbGVyOiAgdGhlIG5ldyBoYW5kbGVyIGZ1bmN0aW9uCisgKgorICogRnVuY3Rpb24gdG8gcmVzZXQgdGhlIGhhbmRsZXIgYW5kIHRoZSBlcnJvciBjb250ZXh0IGZvciBvdXQgb2YKKyAqIGNvbnRleHQgZXJyb3IgbWVzc2FnZXMuCisgKiBUaGlzIHNpbXBseSBtZWFucyB0aGF0IEBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIGZvciBzdWJzZXF1ZW50CisgKiBlcnJvciBtZXNzYWdlcyB3aGlsZSBub3QgcGFyc2luZyBub3IgdmFsaWRhdGluZy4gQW5kIEBjdHggd2lsbAorICogYmUgcGFzc2VkIGFzIGZpcnN0IGFyZ3VtZW50IHRvIEBoYW5kbGVyCisgKiBPbmUgY2FuIHNpbXBseSBmb3JjZSBtZXNzYWdlcyB0byBiZSBlbWl0dGVkIHRvIGFub3RoZXIgRklMRSAqIHRoYW4KKyAqIHN0ZGVyciBieSBzZXR0aW5nIEBjdHggdG8gdGhpcyBmaWxlIGhhbmRsZSBhbmQgQGhhbmRsZXIgdG8gTlVMTC4KKyAqLwordm9pZAoreHNsdFNldEdlbmVyaWNFcnJvckZ1bmModm9pZCAqY3R4LCB4bWxHZW5lcmljRXJyb3JGdW5jIGhhbmRsZXIpIHsKKyAgICB4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCA9IGN0eDsKKyAgICBpZiAoaGFuZGxlciAhPSBOVUxMKQorCXhzbHRHZW5lcmljRXJyb3IgPSBoYW5kbGVyOworICAgIGVsc2UKKwl4c2x0R2VuZXJpY0Vycm9yID0geHNsdEdlbmVyaWNFcnJvckRlZmF1bHRGdW5jOworfQorCisvKioKKyAqIHhzbHRHZW5lcmljRGVidWdEZWZhdWx0RnVuYzoKKyAqIEBjdHg6ICBhbiBlcnJvciBjb250ZXh0CisgKiBAbXNnOiAgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheS90cmFuc21pdAorICogQC4uLjogIGV4dHJhIHBhcmFtZXRlcnMgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKKyAqIAorICogRGVmYXVsdCBoYW5kbGVyIGZvciBvdXQgb2YgY29udGV4dCBlcnJvciBtZXNzYWdlcy4KKyAqLworc3RhdGljIHZvaWQKK3hzbHRHZW5lcmljRGVidWdEZWZhdWx0RnVuYyh2b2lkICpjdHggQVRUUklCVVRFX1VOVVNFRCwgY29uc3QgY2hhciAqbXNnLCAuLi4pIHsKKyAgICB2YV9saXN0IGFyZ3M7CisKKyAgICBpZiAoeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQgPT0gTlVMTCkKKwlyZXR1cm47CisKKyAgICB2YV9zdGFydChhcmdzLCBtc2cpOworICAgIHZmcHJpbnRmKChGSUxFICopeHNsdEdlbmVyaWNEZWJ1Z0NvbnRleHQsIG1zZywgYXJncyk7CisgICAgdmFfZW5kKGFyZ3MpOworfQorCit4bWxHZW5lcmljRXJyb3JGdW5jIHhzbHRHZW5lcmljRGVidWcgPSB4c2x0R2VuZXJpY0RlYnVnRGVmYXVsdEZ1bmM7Cit2b2lkICp4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCA9IE5VTEw7CisKKworLyoqCisgKiB4c2x0U2V0R2VuZXJpY0RlYnVnRnVuYzoKKyAqIEBjdHg6ICB0aGUgbmV3IGVycm9yIGhhbmRsaW5nIGNvbnRleHQKKyAqIEBoYW5kbGVyOiAgdGhlIG5ldyBoYW5kbGVyIGZ1bmN0aW9uCisgKgorICogRnVuY3Rpb24gdG8gcmVzZXQgdGhlIGhhbmRsZXIgYW5kIHRoZSBlcnJvciBjb250ZXh0IGZvciBvdXQgb2YKKyAqIGNvbnRleHQgZXJyb3IgbWVzc2FnZXMuCisgKiBUaGlzIHNpbXBseSBtZWFucyB0aGF0IEBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIGZvciBzdWJzZXF1ZW50CisgKiBlcnJvciBtZXNzYWdlcyB3aGlsZSBub3QgcGFyc2luZyBvciB2YWxpZGF0aW5nLiBBbmQgQGN0eCB3aWxsCisgKiBiZSBwYXNzZWQgYXMgZmlyc3QgYXJndW1lbnQgdG8gQGhhbmRsZXIKKyAqIE9uZSBjYW4gc2ltcGx5IGZvcmNlIG1lc3NhZ2VzIHRvIGJlIGVtaXR0ZWQgdG8gYW5vdGhlciBGSUxFICogdGhhbgorICogc3RkZXJyIGJ5IHNldHRpbmcgQGN0eCB0byB0aGlzIGZpbGUgaGFuZGxlIGFuZCBAaGFuZGxlciB0byBOVUxMLgorICovCit2b2lkCit4c2x0U2V0R2VuZXJpY0RlYnVnRnVuYyh2b2lkICpjdHgsIHhtbEdlbmVyaWNFcnJvckZ1bmMgaGFuZGxlcikgeworICAgIHhzbHRHZW5lcmljRGVidWdDb250ZXh0ID0gY3R4OworICAgIGlmIChoYW5kbGVyICE9IE5VTEwpCisJeHNsdEdlbmVyaWNEZWJ1ZyA9IGhhbmRsZXI7CisgICAgZWxzZQorCXhzbHRHZW5lcmljRGVidWcgPSB4c2x0R2VuZXJpY0RlYnVnRGVmYXVsdEZ1bmM7Cit9CisKKy8qKgorICogeHNsdFByaW50RXJyb3JDb250ZXh0OgorICogQGN0eHQ6ICB0aGUgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQHN0eWxlOiAgdGhlIHN0eWxlc2hlZXQKKyAqIEBub2RlOiAgdGhlIGN1cnJlbnQgbm9kZSBiZWluZyBwcm9jZXNzZWQKKyAqCisgKiBEaXNwbGF5IHRoZSBjb250ZXh0IG9mIGFuIGVycm9yLgorICovCit2b2lkCit4c2x0UHJpbnRFcnJvckNvbnRleHQoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCB4bWxOb2RlUHRyIG5vZGUpIHsKKyAgICBpbnQgbGluZSA9IDA7CisgICAgY29uc3QgeG1sQ2hhciAqZmlsZSA9IE5VTEw7CisgICAgY29uc3QgeG1sQ2hhciAqbmFtZSA9IE5VTEw7CisgICAgY29uc3QgY2hhciAqdHlwZSA9ICJlcnJvciI7CisgICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBlcnJvciA9IHhzbHRHZW5lcmljRXJyb3I7CisgICAgdm9pZCAqZXJyY3R4ID0geHNsdEdlbmVyaWNFcnJvckNvbnRleHQ7CisKKyAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CisJY3R4dC0+c3RhdGUgPSBYU0xUX1NUQVRFX0VSUk9SOworCWlmIChjdHh0LT5lcnJvciAhPSBOVUxMKSB7CisJICAgIGVycm9yID0gY3R4dC0+ZXJyb3I7CisJICAgIGVycmN0eCA9IGN0eHQtPmVycmN0eDsKKwl9CisgICAgfQorICAgIGlmICgobm9kZSA9PSBOVUxMKSAmJiAoY3R4dCAhPSBOVUxMKSkKKwlub2RlID0gY3R4dC0+aW5zdDsKKworICAgIGlmIChub2RlICE9IE5VTEwpICB7CisJaWYgKChub2RlLT50eXBlID09IFhNTF9ET0NVTUVOVF9OT0RFKSB8fAorCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFKSkgeworCSAgICB4bWxEb2NQdHIgZG9jID0gKHhtbERvY1B0cikgbm9kZTsKKworCSAgICBmaWxlID0gZG9jLT5VUkw7CisJfSBlbHNlIHsKKwkgICAgbGluZSA9IHhtbEdldExpbmVObyhub2RlKTsKKwkgICAgaWYgKChub2RlLT5kb2MgIT0gTlVMTCkgJiYgKG5vZGUtPmRvYy0+VVJMICE9IE5VTEwpKQorCQlmaWxlID0gbm9kZS0+ZG9jLT5VUkw7CisJICAgIGlmIChub2RlLT5uYW1lICE9IE5VTEwpCisJCW5hbWUgPSBub2RlLT5uYW1lOworCX0KKyAgICB9IAorICAgIAorICAgIGlmIChjdHh0ICE9IE5VTEwpCisJdHlwZSA9ICJydW50aW1lIGVycm9yIjsKKyAgICBlbHNlIGlmIChzdHlsZSAhPSBOVUxMKSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisJaWYgKFhTTFRfQ0NUWFQoc3R5bGUpLT5lcnJTZXZlcml0eSA9PSBYU0xUX0VSUk9SX1NFVkVSSVRZX1dBUk5JTkcpCisJICAgIHR5cGUgPSAiY29tcGlsYXRpb24gd2FybmluZyI7CisJZWxzZQorCSAgICB0eXBlID0gImNvbXBpbGF0aW9uIGVycm9yIjsKKyNlbHNlCisJdHlwZSA9ICJjb21waWxhdGlvbiBlcnJvciI7CisjZW5kaWYKKyAgICB9CisKKyAgICBpZiAoKGZpbGUgIT0gTlVMTCkgJiYgKGxpbmUgIT0gMCkgJiYgKG5hbWUgIT0gTlVMTCkpCisJZXJyb3IoZXJyY3R4LCAiJXM6IGZpbGUgJXMgbGluZSAlZCBlbGVtZW50ICVzXG4iLAorCSAgICAgIHR5cGUsIGZpbGUsIGxpbmUsIG5hbWUpOworICAgIGVsc2UgaWYgKChmaWxlICE9IE5VTEwpICYmIChuYW1lICE9IE5VTEwpKQorCWVycm9yKGVycmN0eCwgIiVzOiBmaWxlICVzIGVsZW1lbnQgJXNcbiIsIHR5cGUsIGZpbGUsIG5hbWUpOworICAgIGVsc2UgaWYgKChmaWxlICE9IE5VTEwpICYmIChsaW5lICE9IDApKQorCWVycm9yKGVycmN0eCwgIiVzOiBmaWxlICVzIGxpbmUgJWRcbiIsIHR5cGUsIGZpbGUsIGxpbmUpOworICAgIGVsc2UgaWYgKGZpbGUgIT0gTlVMTCkKKwllcnJvcihlcnJjdHgsICIlczogZmlsZSAlc1xuIiwgdHlwZSwgZmlsZSk7CisgICAgZWxzZSBpZiAobmFtZSAhPSBOVUxMKQorCWVycm9yKGVycmN0eCwgIiVzOiBlbGVtZW50ICVzXG4iLCB0eXBlLCBuYW1lKTsKKyAgICBlbHNlCisJZXJyb3IoZXJyY3R4LCAiJXNcbiIsIHR5cGUpOworfQorCisvKioKKyAqIHhzbHRTZXRUcmFuc2Zvcm1FcnJvckZ1bmM6CisgKiBAY3R4dDogIHRoZSBYU0xUIHRyYW5zZm9ybWF0aW9uIGNvbnRleHQKKyAqIEBjdHg6ICB0aGUgbmV3IGVycm9yIGhhbmRsaW5nIGNvbnRleHQKKyAqIEBoYW5kbGVyOiAgdGhlIG5ldyBoYW5kbGVyIGZ1bmN0aW9uCisgKgorICogRnVuY3Rpb24gdG8gcmVzZXQgdGhlIGhhbmRsZXIgYW5kIHRoZSBlcnJvciBjb250ZXh0IGZvciBvdXQgb2YKKyAqIGNvbnRleHQgZXJyb3IgbWVzc2FnZXMgc3BlY2lmaWMgdG8gYSBnaXZlbiBYU0xUIHRyYW5zcm9tYXRpb24uCisgKgorICogVGhpcyBzaW1wbHkgbWVhbnMgdGhhdCBAaGFuZGxlciB3aWxsIGJlIGNhbGxlZCBmb3Igc3Vic2VxdWVudAorICogZXJyb3IgbWVzc2FnZXMgd2hpbGUgcnVubmluZyB0aGUgdHJhbnNmb3JtYXRpb24uCisgKi8KK3ZvaWQKK3hzbHRTZXRUcmFuc2Zvcm1FcnJvckZ1bmMoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY3R4LCB4bWxHZW5lcmljRXJyb3JGdW5jIGhhbmRsZXIpCit7CisgICAgY3R4dC0+ZXJyb3IgPSBoYW5kbGVyOworICAgIGN0eHQtPmVycmN0eCA9IGN0eDsKK30KKworLyoqCisgKiB4c2x0VHJhbnNmb3JtRXJyb3I6CisgKiBAY3R4dDogIGFuIFhTTFQgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICogQHN0eWxlOiAgdGhlIFhTTFQgc3R5bGVzaGVldCB1c2VkCisgKiBAbm9kZTogIHRoZSBjdXJyZW50IG5vZGUgaW4gdGhlIHN0eWxlc2hlZXQKKyAqIEBtc2c6ICB0aGUgbWVzc2FnZSB0byBkaXNwbGF5L3RyYW5zbWl0CisgKiBALi4uOiAgZXh0cmEgcGFyYW1ldGVycyBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQorICoKKyAqIERpc3BsYXkgYW5kIGZvcm1hdCBhbiBlcnJvciBtZXNzYWdlcywgZ2l2ZXMgZmlsZSwgbGluZSwgcG9zaXRpb24gYW5kCisgKiBleHRyYSBwYXJhbWV0ZXJzLCB3aWxsIHVzZSB0aGUgc3BlY2lmaWMgdHJhbnNmb3JtYXRpb24gY29udGV4dCBpZiBhdmFpbGFibGUKKyAqLwordm9pZAoreHNsdFRyYW5zZm9ybUVycm9yKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsCisJCSAgIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkgICB4bWxOb2RlUHRyIG5vZGUsCisJCSAgIGNvbnN0IGNoYXIgKm1zZywgLi4uKSB7CisgICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBlcnJvciA9IHhzbHRHZW5lcmljRXJyb3I7CisgICAgdm9pZCAqZXJyY3R4ID0geHNsdEdlbmVyaWNFcnJvckNvbnRleHQ7CisgICAgY2hhciAqIHN0cjsKKworICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKKwljdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfRVJST1I7CisJaWYgKGN0eHQtPmVycm9yICE9IE5VTEwpIHsKKwkgICAgZXJyb3IgPSBjdHh0LT5lcnJvcjsKKwkgICAgZXJyY3R4ID0gY3R4dC0+ZXJyY3R4OworCX0KKyAgICB9CisgICAgaWYgKChub2RlID09IE5VTEwpICYmIChjdHh0ICE9IE5VTEwpKQorCW5vZGUgPSBjdHh0LT5pbnN0OworICAgIHhzbHRQcmludEVycm9yQ29udGV4dChjdHh0LCBzdHlsZSwgbm9kZSk7CisgICAgWFNMVF9HRVRfVkFSX1NUUihtc2csIHN0cik7CisgICAgZXJyb3IoZXJyY3R4LCAiJXMiLCBzdHIpOworICAgIGlmIChzdHIgIT0gTlVMTCkKKwl4bWxGcmVlKHN0cik7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJCQlRTmFtZXMJCQkJCSoKKyAqIAkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdFNwbGl0UU5hbWU6CisgKiBAZGljdDogYSBkaWN0aW9uYXJ5CisgKiBAbmFtZTogIHRoZSBmdWxsIFFOYW1lCisgKiBAcHJlZml4OiB0aGUgcmV0dXJuIHZhbHVlCisgKgorICogU3BsaXQgUU5hbWVzIGludG8gcHJlZml4IGFuZCBsb2NhbCBuYW1lcywgYm90aCBhbGxvY2F0ZWQgZnJvbSBhIGRpY3Rpb25hcnkuCisgKgorICogUmV0dXJuczogdGhlIGxvY2FsbmFtZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCisgKi8KK2NvbnN0IHhtbENoYXIgKgoreHNsdFNwbGl0UU5hbWUoeG1sRGljdFB0ciBkaWN0LCBjb25zdCB4bWxDaGFyICpuYW1lLCBjb25zdCB4bWxDaGFyICoqcHJlZml4KSB7CisgICAgaW50IGxlbiA9IDA7CisgICAgY29uc3QgeG1sQ2hhciAqcmV0ID0gTlVMTDsKKworICAgICpwcmVmaXggPSBOVUxMOworICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoZGljdCA9PSBOVUxMKSkgcmV0dXJuKE5VTEwpOworICAgIGlmIChuYW1lWzBdID09ICc6JykKKyAgICAgICAgcmV0dXJuKHhtbERpY3RMb29rdXAoZGljdCwgbmFtZSwgLTEpKTsKKyAgICB3aGlsZSAoKG5hbWVbbGVuXSAhPSAwKSAmJiAobmFtZVtsZW5dICE9ICc6JykpIGxlbisrOworICAgIGlmIChuYW1lW2xlbl0gPT0gMCkgcmV0dXJuKHhtbERpY3RMb29rdXAoZGljdCwgbmFtZSwgLTEpKTsKKyAgICAqcHJlZml4ID0geG1sRGljdExvb2t1cChkaWN0LCBuYW1lLCBsZW4pOworICAgIHJldCA9IHhtbERpY3RMb29rdXAoZGljdCwgJm5hbWVbbGVuICsgMV0sIC0xKTsKKyAgICByZXR1cm4ocmV0KTsKK30KKworLyoqCisgKiB4c2x0R2V0UU5hbWVVUkk6CisgKiBAbm9kZTogIHRoZSBub2RlIGhvbGRpbmcgdGhlIFFOYW1lCisgKiBAbmFtZTogIHBvaW50ZXIgdG8gdGhlIGluaXRpYWwgUU5hbWUgdmFsdWUKKyAqCisgKiBUaGlzIGZ1bmN0aW9uIGFuYWx5emVzIEBuYW1lLCBpZiB0aGUgbmFtZSBjb250YWlucyBhIHByZWZpeCwKKyAqIHRoZSBmdW5jdGlvbiBzZWFjaGVzIHRoZSBhc3NvY2lhdGVkIG5hbWVzcGFjZSBpbiBzY29wZSBmb3IgaXQuCisgKiBJdCB3aWxsIGFsc28gcmVwbGFjZSBAbmFtZSB2YWx1ZSB3aXRoIHRoZSBOQ05hbWUsIHRoZSBvbGQgdmFsdWUgYmVpbmcKKyAqIGZyZWVkLgorICogRXJyb3JzIGluIHRoZSBwcmVmaXggbG9va3VwIGFyZSBzaWduYWxsZWQgYnkgc2V0dGluZyBAbmFtZSB0byBOVUxMLgorICoKKyAqIE5PVEU6IHRoZSBuYW1lc3BhY2UgcmV0dXJuZWQgaXMgYSBwb2ludGVyIHRvIHRoZSBwbGFjZSB3aGVyZSBpdCBpcworICogICAgICAgZGVmaW5lZCBhbmQgaGVuY2UgaGFzIHRoZSBzYW1lIGxpZmVzcGFuIGFzIHRoZSBkb2N1bWVudCBob2xkaW5nIGl0LgorICoKKyAqIFJldHVybnMgdGhlIG5hbWVzcGFjZSBVUkkgaWYgdGhlcmUgaXMgYSBwcmVmaXgsIG9yIE5VTEwgaWYgQG5hbWUgaXMKKyAqICAgICAgICAgbm90IHByZWZpeGVkLgorICovCitjb25zdCB4bWxDaGFyICoKK3hzbHRHZXRRTmFtZVVSSSh4bWxOb2RlUHRyIG5vZGUsIHhtbENoYXIgKiogbmFtZSkKK3sKKyAgICBpbnQgbGVuID0gMDsKKyAgICB4bWxDaGFyICpxbmFtZTsKKyAgICB4bWxOc1B0ciBuczsKKworICAgIGlmIChuYW1lID09IE5VTEwpCisJcmV0dXJuKE5VTEwpOworICAgIHFuYW1lID0gKm5hbWU7CisgICAgaWYgKChxbmFtZSA9PSBOVUxMKSB8fCAoKnFuYW1lID09IDApKQorCXJldHVybihOVUxMKTsKKyAgICBpZiAobm9kZSA9PSBOVUxMKSB7CisJeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkJICAgICAgICAgIlFOYW1lOiBubyBlbGVtZW50IGZvciBuYW1lc3BhY2UgbG9va3VwICVzXG4iLAorCQkJIHFuYW1lKTsKKwl4bWxGcmVlKHFuYW1lKTsKKwkqbmFtZSA9IE5VTEw7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKworICAgIC8qIG5hc3R5IGJ1dCB2YWxpZCAqLworICAgIGlmIChxbmFtZVswXSA9PSAnOicpCisJcmV0dXJuKE5VTEwpOworCisgICAgLyoKKyAgICAgKiB3ZSBhcmUgbm90IHRyeWluZyB0byB2YWxpZGF0ZSBidXQganVzdCB0byBjdXQsIGFuZCB5ZXMgaXQgd2lsbAorICAgICAqIHdvcmsgZXZlbiBpZiB0aGlzIGlzIGEgc2V0IG9mIFVURi04IGVuY29kZWQgY2hhcnMKKyAgICAgKi8KKyAgICB3aGlsZSAoKHFuYW1lW2xlbl0gIT0gMCkgJiYgKHFuYW1lW2xlbl0gIT0gJzonKSkgCisJbGVuKys7CisgICAgCisgICAgaWYgKHFuYW1lW2xlbl0gPT0gMCkKKwlyZXR1cm4oTlVMTCk7CisKKyAgICAvKgorICAgICAqIGhhbmRsZSB4bWw6IHNlcGFyYXRlbHksIHRoaXMgb25lIGlzIG1hZ2ljYWwKKyAgICAgKi8KKyAgICBpZiAoKHFuYW1lWzBdID09ICd4JykgJiYgKHFuYW1lWzFdID09ICdtJykgJiYKKyAgICAgICAgKHFuYW1lWzJdID09ICdsJykgJiYgKHFuYW1lWzNdID09ICc6JykpIHsKKwlpZiAocW5hbWVbNF0gPT0gMCkKKwkgICAgcmV0dXJuKE5VTEwpOworICAgICAgICAqbmFtZSA9IHhtbFN0cmR1cCgmcW5hbWVbNF0pOworCXhtbEZyZWUocW5hbWUpOworCXJldHVybihYTUxfWE1MX05BTUVTUEFDRSk7CisgICAgfQorCisgICAgcW5hbWVbbGVuXSA9IDA7CisgICAgbnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIHFuYW1lKTsKKyAgICBpZiAobnMgPT0gTlVMTCkgeworCXhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsCisJCSIlczolcyA6IG5vIG5hbWVzcGFjZSBib3VuZCB0byBwcmVmaXggJXNcbiIsCisJCSAgICAgICAgIHFuYW1lLCAmcW5hbWVbbGVuICsgMV0sIHFuYW1lKTsKKwkqbmFtZSA9IE5VTEw7CisJeG1sRnJlZShxbmFtZSk7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKyAgICAqbmFtZSA9IHhtbFN0cmR1cCgmcW5hbWVbbGVuICsgMV0pOworICAgIHhtbEZyZWUocW5hbWUpOworICAgIHJldHVybihucy0+aHJlZik7Cit9CisKKy8qKgorICogeHNsdEdldFFOYW1lVVJJMjoKKyAqIEBzdHlsZTogIHN0eWxlc2hlZXQgcG9pbnRlcgorICogQG5vZGU6ICAgdGhlIG5vZGUgaG9sZGluZyB0aGUgUU5hbWUKKyAqIEBuYW1lOiAgIHBvaW50ZXIgdG8gdGhlIGluaXRpYWwgUU5hbWUgdmFsdWUKKyAqCisgKiBUaGlzIGZ1bmN0aW9uIGlzIHNpbWlsYXIgdG8geHNsdEdldFFOYW1lVVJJLCBidXQgaXMgdXNlZCB3aGVuCisgKiBAbmFtZSBpcyBhIGRpY3Rpb25hcnkgZW50cnkuCisgKgorICogUmV0dXJucyB0aGUgbmFtZXNwYWNlIFVSSSBpZiB0aGVyZSBpcyBhIHByZWZpeCwgb3IgTlVMTCBpZiBAbmFtZSBpcworICogbm90IHByZWZpeGVkLgorICovCitjb25zdCB4bWxDaGFyICoKK3hzbHRHZXRRTmFtZVVSSTIoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsIHhtbE5vZGVQdHIgbm9kZSwKKwkJIGNvbnN0IHhtbENoYXIgKipuYW1lKSB7CisgICAgaW50IGxlbiA9IDA7CisgICAgeG1sQ2hhciAqcW5hbWU7CisgICAgeG1sTnNQdHIgbnM7CisKKyAgICBpZiAobmFtZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4oTlVMTCk7CisgICAgcW5hbWUgPSAoeG1sQ2hhciAqKSpuYW1lOworICAgIGlmICgocW5hbWUgPT0gTlVMTCkgfHwgKCpxbmFtZSA9PSAwKSkKKyAgICAgICAgcmV0dXJuKE5VTEwpOworICAgIGlmIChub2RlID09IE5VTEwpIHsKKyAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiUU5hbWU6IG5vIGVsZW1lbnQgZm9yIG5hbWVzcGFjZSBsb29rdXAgJXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHFuYW1lKTsKKwkqbmFtZSA9IE5VTEw7CisJcmV0dXJuKE5VTEwpOworICAgIH0KKworICAgIC8qCisgICAgICogd2UgYXJlIG5vdCB0cnlpbmcgdG8gdmFsaWRhdGUgYnV0IGp1c3QgdG8gY3V0LCBhbmQgeWVzIGl0IHdpbGwKKyAgICAgKiB3b3JrIGV2ZW4gaWYgdGhpcyBpcyBhIHNldCBvZiBVVEYtOCBlbmNvZGVkIGNoYXJzCisgICAgICovCisgICAgd2hpbGUgKChxbmFtZVtsZW5dICE9IDApICYmIChxbmFtZVtsZW5dICE9ICc6JykpCisgICAgICAgIGxlbisrOworCisgICAgaWYgKHFuYW1lW2xlbl0gPT0gMCkKKyAgICAgICAgcmV0dXJuKE5VTEwpOworCisgICAgLyoKKyAgICAgKiBoYW5kbGUgeG1sOiBzZXBhcmF0ZWx5LCB0aGlzIG9uZSBpcyBtYWdpY2FsCisgICAgICovCisgICAgaWYgKChxbmFtZVswXSA9PSAneCcpICYmIChxbmFtZVsxXSA9PSAnbScpICYmCisgICAgICAgIChxbmFtZVsyXSA9PSAnbCcpICYmIChxbmFtZVszXSA9PSAnOicpKSB7CisgICAgICAgIGlmIChxbmFtZVs0XSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuKE5VTEwpOworICAgICAgICAqbmFtZSA9IHhtbERpY3RMb29rdXAoc3R5bGUtPmRpY3QsICZxbmFtZVs0XSwgLTEpOworICAgICAgICByZXR1cm4oWE1MX1hNTF9OQU1FU1BBQ0UpOworICAgIH0KKworICAgIHFuYW1lID0geG1sU3RybmR1cCgqbmFtZSwgbGVuKTsKKyAgICBucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcW5hbWUpOworICAgIGlmIChucyA9PSBOVUxMKSB7CisJaWYgKHN0eWxlKSB7CisJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihOVUxMLCBzdHlsZSwgbm9kZSwKKwkJIk5vIG5hbWVzcGFjZSBib3VuZCB0byBwcmVmaXggJyVzJy5cbiIsCisJCXFuYW1lKTsKKwkgICAgc3R5bGUtPmVycm9ycysrOworCX0gZWxzZSB7CisJICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsCisgICAgICAgICAgICAgICAgIiVzIDogbm8gbmFtZXNwYWNlIGJvdW5kIHRvIHByZWZpeCAlc1xuIiwKKwkJKm5hbWUsIHFuYW1lKTsKKwl9CisgICAgICAgICpuYW1lID0gTlVMTDsKKyAgICAgICAgeG1sRnJlZShxbmFtZSk7CisgICAgICAgIHJldHVybihOVUxMKTsKKyAgICB9CisgICAgKm5hbWUgPSB4bWxEaWN0TG9va3VwKHN0eWxlLT5kaWN0LCAoKm5hbWUpK2xlbisxLCAtMSk7CisgICAgeG1sRnJlZShxbmFtZSk7CisgICAgcmV0dXJuKG5zLT5ocmVmKTsKK30KKwkJCQkJCQkJCQkgICAgICAKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJCQlTb3J0aW5nCQkJCQkqCisgKiAJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHREb2N1bWVudFNvcnRGdW5jdGlvbjoKKyAqIEBsaXN0OiAgdGhlIG5vZGUgc2V0CisgKgorICogcmVvcmRlciB0aGUgY3VycmVudCBub2RlIGxpc3QgQGxpc3QgYWNjb3JkaW5nbHkgdG8gdGhlIGRvY3VtZW50IG9yZGVyCisgKiBUaGlzIGZ1bmN0aW9uIGlzIHNsb3csIG9ic29sZXRlIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgYW55bW9yZS4KKyAqLwordm9pZAoreHNsdERvY3VtZW50U29ydEZ1bmN0aW9uKHhtbE5vZGVTZXRQdHIgbGlzdCkgeworICAgIGludCBpLCBqOworICAgIGludCBsZW4sIHRzdDsKKyAgICB4bWxOb2RlUHRyIG5vZGU7CisKKyAgICBpZiAobGlzdCA9PSBOVUxMKQorCXJldHVybjsKKyAgICBsZW4gPSBsaXN0LT5ub2RlTnI7CisgICAgaWYgKGxlbiA8PSAxKQorCXJldHVybjsKKyAgICAvKiBUT0RPOiBzb3J0IGlzIHJlYWxseSBub3Qgb3B0aW1pemVkLCBkb2VzIGl0IG5lZWRzIHRvID8gKi8KKyAgICBmb3IgKGkgPSAwO2kgPCBsZW4gLTE7aSsrKSB7CisJZm9yIChqID0gaSArIDE7IGogPCBsZW47IGorKykgeworCSAgICB0c3QgPSB4bWxYUGF0aENtcE5vZGVzKGxpc3QtPm5vZGVUYWJbaV0sIGxpc3QtPm5vZGVUYWJbal0pOworCSAgICBpZiAodHN0ID09IC0xKSB7CisJCW5vZGUgPSBsaXN0LT5ub2RlVGFiW2ldOworCQlsaXN0LT5ub2RlVGFiW2ldID0gbGlzdC0+bm9kZVRhYltqXTsKKwkJbGlzdC0+bm9kZVRhYltqXSA9IG5vZGU7CisJICAgIH0KKwl9CisgICAgfQorfQorCisvKioKKyAqIHhzbHRDb21wdXRlU29ydFJlc3VsdDoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQHNvcnQ6ICBub2RlIGxpc3QKKyAqCisgKiByZW9yZGVyIHRoZSBjdXJyZW50IG5vZGUgbGlzdCBhY2NvcmRpbmdseSB0byB0aGUgc2V0IG9mIHNvcnRpbmcKKyAqIHJlcXVpcmVtZW50IHByb3ZpZGVkIGJ5IHRoZSBhcnJheSBvZiBub2Rlcy4KKyAqCisgKiBSZXR1cm5zIGEgb3JkZXJlZCBYUGF0aCBub2Rlc2V0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KKyAqLworeG1sWFBhdGhPYmplY3RQdHIgKgoreHNsdENvbXB1dGVTb3J0UmVzdWx0KHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgc29ydCkgeworI2lmZGVmIFhTTFRfUkVGQUNUT1JFRAorICAgIHhzbHRTdHlsZUl0ZW1Tb3J0UHRyIGNvbXA7CisjZWxzZQorICAgIHhzbHRTdHlsZVByZUNvbXBQdHIgY29tcDsKKyNlbmRpZgorICAgIHhtbFhQYXRoT2JqZWN0UHRyICpyZXN1bHRzID0gTlVMTDsKKyAgICB4bWxOb2RlU2V0UHRyIGxpc3QgPSBOVUxMOworICAgIHhtbFhQYXRoT2JqZWN0UHRyIHJlczsKKyAgICBpbnQgbGVuID0gMDsKKyAgICBpbnQgaTsgICAgCisgICAgeG1sTm9kZVB0ciBvbGROb2RlOworICAgIHhtbE5vZGVQdHIgb2xkSW5zdDsKKyAgICBpbnQJb2xkUG9zLCBvbGRTaXplIDsKKyAgICBpbnQgb2xkTnNOcjsKKyAgICB4bWxOc1B0ciAqb2xkTmFtZXNwYWNlczsKKworICAgIGNvbXAgPSBzb3J0LT5wc3ZpOworICAgIGlmIChjb21wID09IE5VTEwpIHsKKwl4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LAorCSAgICAgInhzbDpzb3J0IDogY29tcGlsYXRpb24gZmFpbGVkXG4iKTsKKwlyZXR1cm4oTlVMTCk7CisgICAgfQorCisgICAgaWYgKChjb21wLT5zZWxlY3QgPT0gTlVMTCkgfHwgKGNvbXAtPmNvbXAgPT0gTlVMTCkpCisJcmV0dXJuKE5VTEwpOworCisgICAgbGlzdCA9IGN0eHQtPm5vZGVMaXN0OworICAgIGlmICgobGlzdCA9PSBOVUxMKSB8fCAobGlzdC0+bm9kZU5yIDw9IDEpKQorCXJldHVybihOVUxMKTsKKworICAgIGxlbiA9IGxpc3QtPm5vZGVOcjsKKworICAgIC8qIFRPRE86IHhzbDpzb3J0IGxhbmcgYXR0cmlidXRlICovCisgICAgLyogVE9ETzogeHNsOnNvcnQgY2FzZS1vcmRlciBhdHRyaWJ1dGUgKi8KKworCisgICAgcmVzdWx0cyA9IHhtbE1hbGxvYyhsZW4gKiBzaXplb2YoeG1sWFBhdGhPYmplY3RQdHIpKTsKKyAgICBpZiAocmVzdWx0cyA9PSBOVUxMKSB7CisJeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkgICAgICJ4c2x0Q29tcHV0ZVNvcnRSZXN1bHQ6IG1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmVcbiIpOworCXJldHVybihOVUxMKTsKKyAgICB9CisKKyAgICBvbGROb2RlID0gY3R4dC0+bm9kZTsKKyAgICBvbGRJbnN0ID0gY3R4dC0+aW5zdDsKKyAgICBvbGRQb3MgPSBjdHh0LT54cGF0aEN0eHQtPnByb3hpbWl0eVBvc2l0aW9uOworICAgIG9sZFNpemUgPSBjdHh0LT54cGF0aEN0eHQtPmNvbnRleHRTaXplOworICAgIG9sZE5zTnIgPSBjdHh0LT54cGF0aEN0eHQtPm5zTnI7CisgICAgb2xkTmFtZXNwYWNlcyA9IGN0eHQtPnhwYXRoQ3R4dC0+bmFtZXNwYWNlczsKKyAgICBmb3IgKGkgPSAwO2kgPCBsZW47aSsrKSB7CisJY3R4dC0+aW5zdCA9IHNvcnQ7CisJY3R4dC0+eHBhdGhDdHh0LT5jb250ZXh0U2l6ZSA9IGxlbjsKKwljdHh0LT54cGF0aEN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gaSArIDE7CisJY3R4dC0+bm9kZSA9IGxpc3QtPm5vZGVUYWJbaV07CisJY3R4dC0+eHBhdGhDdHh0LT5ub2RlID0gY3R4dC0+bm9kZTsKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRUQKKwlpZiAoY29tcC0+aW5TY29wZU5zICE9IE5VTEwpIHsKKwkgICAgY3R4dC0+eHBhdGhDdHh0LT5uYW1lc3BhY2VzID0gY29tcC0+aW5TY29wZU5zLT5saXN0OworCSAgICBjdHh0LT54cGF0aEN0eHQtPm5zTnIgPSBjb21wLT5pblNjb3BlTnMtPnhwYXRoTnVtYmVyOworCX0gZWxzZSB7CisJICAgIGN0eHQtPnhwYXRoQ3R4dC0+bmFtZXNwYWNlcyA9IE5VTEw7CisJICAgIGN0eHQtPnhwYXRoQ3R4dC0+bnNOciA9IDA7CisJfQorI2Vsc2UKKwljdHh0LT54cGF0aEN0eHQtPm5hbWVzcGFjZXMgPSBjb21wLT5uc0xpc3Q7CisJY3R4dC0+eHBhdGhDdHh0LT5uc05yID0gY29tcC0+bnNOcjsKKyNlbmRpZgorCXJlcyA9IHhtbFhQYXRoQ29tcGlsZWRFdmFsKGNvbXAtPmNvbXAsIGN0eHQtPnhwYXRoQ3R4dCk7CisJaWYgKHJlcyAhPSBOVUxMKSB7CisJICAgIGlmIChyZXMtPnR5cGUgIT0gWFBBVEhfU1RSSU5HKQorCQlyZXMgPSB4bWxYUGF0aENvbnZlcnRTdHJpbmcocmVzKTsKKwkgICAgaWYgKGNvbXAtPm51bWJlcikKKwkJcmVzID0geG1sWFBhdGhDb252ZXJ0TnVtYmVyKHJlcyk7CisJICAgIHJlcy0+aW5kZXggPSBpOwkvKiBTYXZlIG9yaWdpbmFsIHBvcyBmb3IgZHVwbCByZXNvbHYgKi8KKwkgICAgaWYgKGNvbXAtPm51bWJlcikgeworCQlpZiAocmVzLT50eXBlID09IFhQQVRIX05VTUJFUikgeworCQkgICAgcmVzdWx0c1tpXSA9IHJlczsKKwkJfSBlbHNlIHsKKyNpZmRlZiBXSVRIX1hTTFRfREVCVUdfUFJPQ0VTUworCQkgICAgeHNsdEdlbmVyaWNEZWJ1Zyh4c2x0R2VuZXJpY0RlYnVnQ29udGV4dCwKKwkJCSJ4c2x0Q29tcHV0ZVNvcnRSZXN1bHQ6IHNlbGVjdCBkaWRuJ3QgZXZhbHVhdGUgdG8gYSBudW1iZXJcbiIpOworI2VuZGlmCisJCSAgICByZXN1bHRzW2ldID0gTlVMTDsKKwkJfQorCSAgICB9IGVsc2UgeworCQlpZiAocmVzLT50eXBlID09IFhQQVRIX1NUUklORykgeworCQkgICAgaWYgKGNvbXAtPmxvY2FsZSAhPSAoeHNsdExvY2FsZSkwKSB7CisJCQl4bWxDaGFyICpzdHIgPSByZXMtPnN0cmluZ3ZhbDsKKwkJCXJlcy0+c3RyaW5ndmFsID0gKHhtbENoYXIgKikgeHNsdFN0cnhmcm0oY29tcC0+bG9jYWxlLCBzdHIpOworCQkJeG1sRnJlZShzdHIpOworCQkgICAgfQorCisJCSAgICByZXN1bHRzW2ldID0gcmVzOworCQl9IGVsc2UgeworI2lmZGVmIFdJVEhfWFNMVF9ERUJVR19QUk9DRVNTCisJCSAgICB4c2x0R2VuZXJpY0RlYnVnKHhzbHRHZW5lcmljRGVidWdDb250ZXh0LAorCQkJInhzbHRDb21wdXRlU29ydFJlc3VsdDogc2VsZWN0IGRpZG4ndCBldmFsdWF0ZSB0byBhIHN0cmluZ1xuIik7CisjZW5kaWYKKwkJICAgIHJlc3VsdHNbaV0gPSBOVUxMOworCQl9CisJICAgIH0KKwl9IGVsc2UgeworCSAgICBjdHh0LT5zdGF0ZSA9IFhTTFRfU1RBVEVfU1RPUFBFRDsKKwkgICAgcmVzdWx0c1tpXSA9IE5VTEw7CisJfQorICAgIH0KKyAgICBjdHh0LT5ub2RlID0gb2xkTm9kZTsKKyAgICBjdHh0LT5pbnN0ID0gb2xkSW5zdDsKKyAgICBjdHh0LT54cGF0aEN0eHQtPmNvbnRleHRTaXplID0gb2xkU2l6ZTsKKyAgICBjdHh0LT54cGF0aEN0eHQtPnByb3hpbWl0eVBvc2l0aW9uID0gb2xkUG9zOworICAgIGN0eHQtPnhwYXRoQ3R4dC0+bnNOciA9IG9sZE5zTnI7CisgICAgY3R4dC0+eHBhdGhDdHh0LT5uYW1lc3BhY2VzID0gb2xkTmFtZXNwYWNlczsKKworICAgIHJldHVybihyZXN1bHRzKTsKK30KKworLyoqCisgKiB4c2x0RGVmYXVsdFNvcnRGdW5jdGlvbjoKKyAqIEBjdHh0OiAgYSBYU0xUIHByb2Nlc3MgY29udGV4dAorICogQHNvcnRzOiAgYXJyYXkgb2Ygc29ydCBub2RlcworICogQG5ic29ydHM6ICB0aGUgbnVtYmVyIG9mIHNvcnRzIGluIHRoZSBhcnJheQorICoKKyAqIHJlb3JkZXIgdGhlIGN1cnJlbnQgbm9kZSBsaXN0IGFjY29yZGluZ2x5IHRvIHRoZSBzZXQgb2Ygc29ydGluZworICogcmVxdWlyZW1lbnQgcHJvdmlkZWQgYnkgdGhlIGFycnkgb2Ygbm9kZXMuCisgKi8KK3ZvaWQJCit4c2x0RGVmYXVsdFNvcnRGdW5jdGlvbih4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LCB4bWxOb2RlUHRyICpzb3J0cywKKwkgICAgICAgICAgIGludCBuYnNvcnRzKSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVECisgICAgeHNsdFN0eWxlSXRlbVNvcnRQdHIgY29tcDsKKyNlbHNlCisgICAgeHNsdFN0eWxlUHJlQ29tcFB0ciBjb21wOworI2VuZGlmCisgICAgeG1sWFBhdGhPYmplY3RQdHIgKnJlc3VsdHNUYWJbWFNMVF9NQVhfU09SVF07CisgICAgeG1sWFBhdGhPYmplY3RQdHIgKnJlc3VsdHMgPSBOVUxMLCAqcmVzOworICAgIHhtbE5vZGVTZXRQdHIgbGlzdCA9IE5VTEw7CisgICAgaW50IGRlc2NlbmRpbmcsIG51bWJlciwgZGVzYywgbnVtYjsKKyAgICBpbnQgbGVuID0gMDsKKyAgICBpbnQgaSwgaiwgaW5jcjsKKyAgICBpbnQgdHN0OworICAgIGludCBkZXB0aDsKKyAgICB4bWxOb2RlUHRyIG5vZGU7CisgICAgeG1sWFBhdGhPYmplY3RQdHIgdG1wOyAgICAKKyAgICBpbnQgdGVtcHN0eXBlW1hTTFRfTUFYX1NPUlRdLCB0ZW1wb3JkZXJbWFNMVF9NQVhfU09SVF07CisKKyAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNvcnRzID09IE5VTEwpIHx8IChuYnNvcnRzIDw9IDApIHx8CisJKG5ic29ydHMgPj0gWFNMVF9NQVhfU09SVCkpCisJcmV0dXJuOworICAgIGlmIChzb3J0c1swXSA9PSBOVUxMKQorCXJldHVybjsKKyAgICBjb21wID0gc29ydHNbMF0tPnBzdmk7CisgICAgaWYgKGNvbXAgPT0gTlVMTCkKKwlyZXR1cm47CisKKyAgICBsaXN0ID0gY3R4dC0+bm9kZUxpc3Q7CisgICAgaWYgKChsaXN0ID09IE5VTEwpIHx8IChsaXN0LT5ub2RlTnIgPD0gMSkpCisJcmV0dXJuOyAvKiBub3RoaW5nIHRvIGRvICovCisKKyAgICBmb3IgKGogPSAwOyBqIDwgbmJzb3J0czsgaisrKSB7CisJY29tcCA9IHNvcnRzW2pdLT5wc3ZpOworCXRlbXBzdHlwZVtqXSA9IDA7CisJaWYgKChjb21wLT5zdHlwZSA9PSBOVUxMKSAmJiAoY29tcC0+aGFzX3N0eXBlICE9IDApKSB7CisJICAgIGNvbXAtPnN0eXBlID0KKwkJeHNsdEV2YWxBdHRyVmFsdWVUZW1wbGF0ZShjdHh0LCBzb3J0c1tqXSwKKwkJCQkJICAoY29uc3QgeG1sQ2hhciAqKSAiZGF0YS10eXBlIiwKKwkJCQkJICBYU0xUX05BTUVTUEFDRSk7CisJICAgIGlmIChjb21wLT5zdHlwZSAhPSBOVUxMKSB7CisJCXRlbXBzdHlwZVtqXSA9IDE7CisJCWlmICh4bWxTdHJFcXVhbChjb21wLT5zdHlwZSwgKGNvbnN0IHhtbENoYXIgKikgInRleHQiKSkKKwkJICAgIGNvbXAtPm51bWJlciA9IDA7CisJCWVsc2UgaWYgKHhtbFN0ckVxdWFsKGNvbXAtPnN0eXBlLCAoY29uc3QgeG1sQ2hhciAqKSAibnVtYmVyIikpCisJCSAgICBjb21wLT5udW1iZXIgPSAxOworCQllbHNlIHsKKwkJICAgIHhzbHRUcmFuc2Zvcm1FcnJvcihjdHh0LCBOVUxMLCBzb3J0c1tqXSwKKwkJCSAgInhzbHREb1NvcnRGdW5jdGlvbjogbm8gc3VwcG9ydCBmb3IgZGF0YS10eXBlID0gJXNcbiIsCisJCQkJICAgICBjb21wLT5zdHlwZSk7CisJCSAgICBjb21wLT5udW1iZXIgPSAwOyAvKiB1c2UgZGVmYXVsdCAqLworCQl9CisJICAgIH0KKwl9CisJdGVtcG9yZGVyW2pdID0gMDsKKwlpZiAoKGNvbXAtPm9yZGVyID09IE5VTEwpICYmIChjb21wLT5oYXNfb3JkZXIgIT0gMCkpIHsKKwkgICAgY29tcC0+b3JkZXIgPSB4c2x0RXZhbEF0dHJWYWx1ZVRlbXBsYXRlKGN0eHQsIHNvcnRzW2pdLAorCQkJCQkJICAgIChjb25zdCB4bWxDaGFyICopICJvcmRlciIsCisJCQkJCQkgICAgWFNMVF9OQU1FU1BBQ0UpOworCSAgICBpZiAoY29tcC0+b3JkZXIgIT0gTlVMTCkgeworCQl0ZW1wb3JkZXJbal0gPSAxOworCQlpZiAoeG1sU3RyRXF1YWwoY29tcC0+b3JkZXIsIChjb25zdCB4bWxDaGFyICopICJhc2NlbmRpbmciKSkKKwkJICAgIGNvbXAtPmRlc2NlbmRpbmcgPSAwOworCQllbHNlIGlmICh4bWxTdHJFcXVhbChjb21wLT5vcmRlciwKKwkJCQkgICAgIChjb25zdCB4bWxDaGFyICopICJkZXNjZW5kaW5nIikpCisJCSAgICBjb21wLT5kZXNjZW5kaW5nID0gMTsKKwkJZWxzZSB7CisJCSAgICB4c2x0VHJhbnNmb3JtRXJyb3IoY3R4dCwgTlVMTCwgc29ydHNbal0sCisJCQkgICAgICJ4c2x0RG9Tb3J0RnVuY3Rpb246IGludmFsaWQgdmFsdWUgJXMgZm9yIG9yZGVyXG4iLAorCQkJCSAgICAgY29tcC0+b3JkZXIpOworCQkgICAgY29tcC0+ZGVzY2VuZGluZyA9IDA7IC8qIHVzZSBkZWZhdWx0ICovCisJCX0KKwkgICAgfQorCX0KKyAgICB9CisKKyAgICBsZW4gPSBsaXN0LT5ub2RlTnI7CisKKyAgICByZXN1bHRzVGFiWzBdID0geHNsdENvbXB1dGVTb3J0UmVzdWx0KGN0eHQsIHNvcnRzWzBdKTsKKyAgICBmb3IgKGkgPSAxO2kgPCBYU0xUX01BWF9TT1JUO2krKykKKwlyZXN1bHRzVGFiW2ldID0gTlVMTDsKKworICAgIHJlc3VsdHMgPSByZXN1bHRzVGFiWzBdOworCisgICAgY29tcCA9IHNvcnRzWzBdLT5wc3ZpOworICAgIGRlc2NlbmRpbmcgPSBjb21wLT5kZXNjZW5kaW5nOworICAgIG51bWJlciA9IGNvbXAtPm51bWJlcjsKKyAgICBpZiAocmVzdWx0cyA9PSBOVUxMKQorCXJldHVybjsKKworICAgIC8qIFNoZWxsJ3Mgc29ydCBvZiBub2RlLXNldCAqLworICAgIGZvciAoaW5jciA9IGxlbiAvIDI7IGluY3IgPiAwOyBpbmNyIC89IDIpIHsKKwlmb3IgKGkgPSBpbmNyOyBpIDwgbGVuOyBpKyspIHsKKwkgICAgaiA9IGkgLSBpbmNyOworCSAgICBpZiAocmVzdWx0c1tpXSA9PSBOVUxMKQorCQljb250aW51ZTsKKwkgICAgCisJICAgIHdoaWxlIChqID49IDApIHsKKwkJaWYgKHJlc3VsdHNbal0gPT0gTlVMTCkKKwkJICAgIHRzdCA9IDE7CisJCWVsc2UgeworCQkgICAgaWYgKG51bWJlcikgeworCQkJLyogV2UgbWFrZSBOYU4gc21hbGxlciB0aGFuIG51bWJlciBpbiBhY2NvcmRhbmNlCisJCQkgICB3aXRoIFhTTFQgc3BlYyAqLworCQkJaWYgKHhtbFhQYXRoSXNOYU4ocmVzdWx0c1tqXS0+ZmxvYXR2YWwpKSB7CisJCQkgICAgaWYgKHhtbFhQYXRoSXNOYU4ocmVzdWx0c1tqICsgaW5jcl0tPmZsb2F0dmFsKSkKKwkJCQl0c3QgPSAwOworCQkJICAgIGVsc2UKKwkJCQl0c3QgPSAtMTsKKwkJCX0gZWxzZSBpZiAoeG1sWFBhdGhJc05hTihyZXN1bHRzW2ogKyBpbmNyXS0+ZmxvYXR2YWwpKQorCQkJICAgIHRzdCA9IDE7CisJCQllbHNlIGlmIChyZXN1bHRzW2pdLT5mbG9hdHZhbCA9PQorCQkJCXJlc3VsdHNbaiArIGluY3JdLT5mbG9hdHZhbCkKKwkJCSAgICB0c3QgPSAwOworCQkJZWxzZSBpZiAocmVzdWx0c1tqXS0+ZmxvYXR2YWwgPiAKKwkJCQlyZXN1bHRzW2ogKyBpbmNyXS0+ZmxvYXR2YWwpCisJCQkgICAgdHN0ID0gMTsKKwkJCWVsc2UgdHN0ID0gLTE7CisJCSAgICB9IGVsc2UgaWYoY29tcC0+bG9jYWxlICE9ICh4c2x0TG9jYWxlKTApIHsKKwkJCXRzdCA9IHhzbHRMb2NhbGVTdHJjbXAoCisJCQkgICAgY29tcC0+bG9jYWxlLAorCQkJICAgICh4c2x0TG9jYWxlQ2hhciAqKSByZXN1bHRzW2pdLT5zdHJpbmd2YWwsCisJCQkgICAgKHhzbHRMb2NhbGVDaGFyICopIHJlc3VsdHNbaiArIGluY3JdLT5zdHJpbmd2YWwpOyAKKwkJICAgIH0gZWxzZSB7CisJCQl0c3QgPSB4bWxTdHJjbXAocmVzdWx0c1tqXS0+c3RyaW5ndmFsLAorCQkJCSAgICAgcmVzdWx0c1tqICsgaW5jcl0tPnN0cmluZ3ZhbCk7IAorCQkgICAgfQorCQkgICAgaWYgKGRlc2NlbmRpbmcpCisJCQl0c3QgPSAtdHN0OworCQl9CisJCWlmICh0c3QgPT0gMCkgeworCQkgICAgLyoKKwkJICAgICAqIE9rYXkgd2UgbmVlZCB0byB1c2UgbXVsdGkgbGV2ZWwgc29ydHMKKwkJICAgICAqLworCQkgICAgZGVwdGggPSAxOworCQkgICAgd2hpbGUgKGRlcHRoIDwgbmJzb3J0cykgeworCQkJaWYgKHNvcnRzW2RlcHRoXSA9PSBOVUxMKQorCQkJICAgIGJyZWFrOworCQkJY29tcCA9IHNvcnRzW2RlcHRoXS0+cHN2aTsKKwkJCWlmIChjb21wID09IE5VTEwpCisJCQkgICAgYnJlYWs7CisJCQlkZXNjID0gY29tcC0+ZGVzY2VuZGluZzsKKwkJCW51bWIgPSBjb21wLT5udW1iZXI7CisKKwkJCS8qCisJCQkgKiBDb21wdXRlIHRoZSByZXN1bHQgb2YgdGhlIG5leHQgbGV2ZWwgZm9yIHRoZQorCQkJICogZnVsbCBzZXQsIHRoaXMgbWlnaHQgYmUgb3B0aW1pemVkIC4uLiBvciBub3QKKwkJCSAqLworCQkJaWYgKHJlc3VsdHNUYWJbZGVwdGhdID09IE5VTEwpIAorCQkJICAgIHJlc3VsdHNUYWJbZGVwdGhdID0geHNsdENvbXB1dGVTb3J0UmVzdWx0KGN0eHQsCisJCQkJICAgICAgICAgICAgICAgICAgICAgICAgc29ydHNbZGVwdGhdKTsKKwkJCXJlcyA9IHJlc3VsdHNUYWJbZGVwdGhdOworCQkJaWYgKHJlcyA9PSBOVUxMKSAKKwkJCSAgICBicmVhazsKKwkJCWlmIChyZXNbal0gPT0gTlVMTCkgeworCQkJICAgIGlmIChyZXNbaitpbmNyXSAhPSBOVUxMKQorCQkJCXRzdCA9IDE7CisJCQl9IGVsc2UgeworCQkJICAgIGlmIChudW1iKSB7CisJCQkJLyogV2UgbWFrZSBOYU4gc21hbGxlciB0aGFuIG51bWJlciBpbgorCQkJCSAgIGFjY29yZGFuY2Ugd2l0aCBYU0xUIHNwZWMgKi8KKwkJCQlpZiAoeG1sWFBhdGhJc05hTihyZXNbal0tPmZsb2F0dmFsKSkgeworCQkJCSAgICBpZiAoeG1sWFBhdGhJc05hTihyZXNbaiArCisJCQkJICAgIAkJaW5jcl0tPmZsb2F0dmFsKSkKKwkJCQkJdHN0ID0gMDsKKwkJCQkgICAgZWxzZQorCQkJCSAgICAgICAgdHN0ID0gLTE7CisJCQkJfSBlbHNlIGlmICh4bWxYUGF0aElzTmFOKHJlc1tqICsgaW5jcl0tPgorCQkJCQkJZmxvYXR2YWwpKQorCQkJCSAgICB0c3QgPSAxOworCQkJCWVsc2UgaWYgKHJlc1tqXS0+ZmxvYXR2YWwgPT0gcmVzW2ogKyBpbmNyXS0+CisJCQkJCQlmbG9hdHZhbCkKKwkJCQkgICAgdHN0ID0gMDsKKwkJCQllbHNlIGlmIChyZXNbal0tPmZsb2F0dmFsID4gCisJCQkJCXJlc1tqICsgaW5jcl0tPmZsb2F0dmFsKQorCQkJCSAgICB0c3QgPSAxOworCQkJCWVsc2UgdHN0ID0gLTE7CisJCQkgICAgfSBlbHNlIGlmKGNvbXAtPmxvY2FsZSAhPSAoeHNsdExvY2FsZSkwKSB7CisJCQkJdHN0ID0geHNsdExvY2FsZVN0cmNtcCgKKwkJCQkgICAgY29tcC0+bG9jYWxlLAorCQkJCSAgICAoeHNsdExvY2FsZUNoYXIgKikgcmVzW2pdLT5zdHJpbmd2YWwsCisJCQkJICAgICh4c2x0TG9jYWxlQ2hhciAqKSByZXNbaiArIGluY3JdLT5zdHJpbmd2YWwpOyAKKwkJCSAgICB9IGVsc2UgeworCQkJCXRzdCA9IHhtbFN0cmNtcChyZXNbal0tPnN0cmluZ3ZhbCwKKwkJCQkJICAgICByZXNbaiArIGluY3JdLT5zdHJpbmd2YWwpOyAKKwkJCSAgICB9CisJCQkgICAgaWYgKGRlc2MpCisJCQkJdHN0ID0gLXRzdDsKKwkJCX0KKworCQkJLyoKKwkJCSAqIGlmIHdlIHN0aWxsIGNhbid0IGRpZmZlcmVuY2lhdGUgYXQgdGhpcyBsZXZlbAorCQkJICogdHJ5IG9uZSBsZXZlbCBkZWVwZXIuCisJCQkgKi8KKwkJCWlmICh0c3QgIT0gMCkKKwkJCSAgICBicmVhazsKKwkJCWRlcHRoKys7CisJCSAgICB9CisJCX0KKwkJaWYgKHRzdCA9PSAwKSB7CisJCSAgICB0c3QgPSByZXN1bHRzW2pdLT5pbmRleCA+IHJlc3VsdHNbaiArIGluY3JdLT5pbmRleDsKKwkJfQorCQlpZiAodHN0ID4gMCkgeworCQkgICAgdG1wID0gcmVzdWx0c1tqXTsKKwkJICAgIHJlc3VsdHNbal0gPSByZXN1bHRzW2ogKyBpbmNyXTsKKwkJICAgIHJlc3VsdHNbaiArIGluY3JdID0gdG1wOworCQkgICAgbm9kZSA9IGxpc3QtPm5vZGVUYWJbal07CisJCSAgICBsaXN0LT5ub2RlVGFiW2pdID0gbGlzdC0+bm9kZVRhYltqICsgaW5jcl07CisJCSAgICBsaXN0LT5ub2RlVGFiW2ogKyBpbmNyXSA9IG5vZGU7CisJCSAgICBkZXB0aCA9IDE7CisJCSAgICB3aGlsZSAoZGVwdGggPCBuYnNvcnRzKSB7CisJCQlpZiAoc29ydHNbZGVwdGhdID09IE5VTEwpCisJCQkgICAgYnJlYWs7CisJCQlpZiAocmVzdWx0c1RhYltkZXB0aF0gPT0gTlVMTCkKKwkJCSAgICBicmVhazsKKwkJCXJlcyA9IHJlc3VsdHNUYWJbZGVwdGhdOworCQkJdG1wID0gcmVzW2pdOworCQkJcmVzW2pdID0gcmVzW2ogKyBpbmNyXTsKKwkJCXJlc1tqICsgaW5jcl0gPSB0bXA7CisJCQlkZXB0aCsrOworCQkgICAgfQorCQkgICAgaiAtPSBpbmNyOworCQl9IGVsc2UKKwkJICAgIGJyZWFrOworCSAgICB9CisJfQorICAgIH0KKworICAgIGZvciAoaiA9IDA7IGogPCBuYnNvcnRzOyBqKyspIHsKKwljb21wID0gc29ydHNbal0tPnBzdmk7CisJaWYgKHRlbXBzdHlwZVtqXSA9PSAxKSB7CisJICAgIC8qIFRoZSBkYXRhLXR5cGUgbmVlZHMgdG8gYmUgcmVjb21wdXRlZCBlYWNoIHRpbWUgKi8KKwkgICAgeG1sRnJlZSgodm9pZCAqKShjb21wLT5zdHlwZSkpOworCSAgICBjb21wLT5zdHlwZSA9IE5VTEw7CisJfQorCWlmICh0ZW1wb3JkZXJbal0gPT0gMSkgeworCSAgICAvKiBUaGUgb3JkZXIgbmVlZHMgdG8gYmUgcmVjb21wdXRlZCBlYWNoIHRpbWUgKi8KKwkgICAgeG1sRnJlZSgodm9pZCAqKShjb21wLT5vcmRlcikpOworCSAgICBjb21wLT5vcmRlciA9IE5VTEw7CisJfQorCWlmIChyZXN1bHRzVGFiW2pdICE9IE5VTEwpIHsKKwkgICAgZm9yIChpID0gMDtpIDwgbGVuO2krKykKKwkJeG1sWFBhdGhGcmVlT2JqZWN0KHJlc3VsdHNUYWJbal1baV0pOworCSAgICB4bWxGcmVlKHJlc3VsdHNUYWJbal0pOworCX0KKyAgICB9Cit9CisKKworc3RhdGljIHhzbHRTb3J0RnVuYyB4c2x0U29ydEZ1bmN0aW9uID0geHNsdERlZmF1bHRTb3J0RnVuY3Rpb247CisKKy8qKgorICogeHNsdERvU29ydEZ1bmN0aW9uOgorICogQGN0eHQ6ICBhIFhTTFQgcHJvY2VzcyBjb250ZXh0CisgKiBAc29ydHM6ICBhcnJheSBvZiBzb3J0IG5vZGVzCisgKiBAbmJzb3J0czogIHRoZSBudW1iZXIgb2Ygc29ydHMgaW4gdGhlIGFycmF5CisgKgorICogcmVvcmRlciB0aGUgY3VycmVudCBub2RlIGxpc3QgYWNjb3JkaW5nbHkgdG8gdGhlIHNldCBvZiBzb3J0aW5nCisgKiByZXF1aXJlbWVudCBwcm92aWRlZCBieSB0aGUgYXJyeSBvZiBub2Rlcy4KKyAqIFRoaXMgaXMgYSB3cmFwcGVyIGZ1bmN0aW9uLCB0aGUgYWN0dWFsIGZ1bmN0aW9uIHVzZWQgaXMgc3BlY2lmaWVkCisgKiB1c2luZyB4c2x0U2V0Q3R4dFNvcnRGdW5jKCkgdG8gc2V0IHRoZSBjb250ZXh0IHNwZWNpZmljIHNvcnQgZnVuY3Rpb24sCisgKiBvciB4c2x0U2V0U29ydEZ1bmMoKSB0byBzZXQgdGhlIGdsb2JhbCBzb3J0IGZ1bmN0aW9uLgorICogSWYgYSBzb3J0IGZ1bmN0aW9uIGlzIHNldCBvbiB0aGUgY29udGV4dCwgdGhpcyB3aWxsIGdldCBjYWxsZWQuCisgKiBPdGhlcndpc2UgdGhlIGdsb2JhbCBzb3J0IGZ1bmN0aW9uIGlzIGNhbGxlZC4KKyAqLwordm9pZAoreHNsdERvU29ydEZ1bmN0aW9uKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgKiBzb3J0cywKKyAgICAgICAgICAgICAgICAgICBpbnQgbmJzb3J0cykKK3sKKyAgICBpZiAoY3R4dC0+c29ydGZ1bmMgIT0gTlVMTCkKKwkoY3R4dC0+c29ydGZ1bmMpKGN0eHQsIHNvcnRzLCBuYnNvcnRzKTsKKyAgICBlbHNlIGlmICh4c2x0U29ydEZ1bmN0aW9uICE9IE5VTEwpCisgICAgICAgIHhzbHRTb3J0RnVuY3Rpb24oY3R4dCwgc29ydHMsIG5ic29ydHMpOworfQorCisvKioKKyAqIHhzbHRTZXRTb3J0RnVuYzoKKyAqIEBoYW5kbGVyOiAgdGhlIG5ldyBoYW5kbGVyIGZ1bmN0aW9uCisgKgorICogRnVuY3Rpb24gdG8gcmVzZXQgdGhlIGdsb2JhbCBoYW5kbGVyIGZvciBYU0xUIHNvcnRpbmcuCisgKiBJZiB0aGUgaGFuZGxlciBpcyBOVUxMLCB0aGUgZGVmYXVsdCBzb3J0IGZ1bmN0aW9uIHdpbGwgYmUgdXNlZC4KKyAqLwordm9pZAoreHNsdFNldFNvcnRGdW5jKHhzbHRTb3J0RnVuYyBoYW5kbGVyKSB7CisgICAgaWYgKGhhbmRsZXIgIT0gTlVMTCkKKwl4c2x0U29ydEZ1bmN0aW9uID0gaGFuZGxlcjsKKyAgICBlbHNlCisJeHNsdFNvcnRGdW5jdGlvbiA9IHhzbHREZWZhdWx0U29ydEZ1bmN0aW9uOworfQorCisvKioKKyAqIHhzbHRTZXRDdHh0U29ydEZ1bmM6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBoYW5kbGVyOiAgdGhlIG5ldyBoYW5kbGVyIGZ1bmN0aW9uCisgKgorICogRnVuY3Rpb24gdG8gc2V0IHRoZSBoYW5kbGVyIGZvciBYU0xUIHNvcnRpbmcKKyAqIGZvciB0aGUgc3BlY2lmaWVkIGNvbnRleHQuIAorICogSWYgdGhlIGhhbmRsZXIgaXMgTlVMTCwgdGhlbiB0aGUgZ2xvYmFsCisgKiBzb3J0IGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkCisgKi8KK3ZvaWQgCit4c2x0U2V0Q3R4dFNvcnRGdW5jKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIHhzbHRTb3J0RnVuYyBoYW5kbGVyKSB7CisgICAgY3R4dC0+c29ydGZ1bmMgPSBoYW5kbGVyOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAJCQkJCQkJCQkqCisgKiAJCQkJUGFyc2luZyBvcHRpb25zCQkJCSoKKyAqIAkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdFNldEN0eHRQYXJzZU9wdGlvbnM6CisgKiBAY3R4dDogIGEgWFNMVCBwcm9jZXNzIGNvbnRleHQKKyAqIEBvcHRpb25zOiAgYSBjb21iaW5hdGlvbiBvZiBsaWJ4bWwyIHhtbFBhcnNlck9wdGlvbgorICogCisgKiBDaGFuZ2UgdGhlIGRlZmF1bHQgcGFyc2VyIG9wdGlvbiBwYXNzZWQgYnkgdGhlIFhTTFQgZW5naW5lIHRvIHRoZSAKKyAqIHBhcnNlciB3aGVuIHVzaW5nIGRvY3VtZW50KCkgbG9hZGluZy4KKyAqCisgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyBvcHRpb25zIG9yIC0xIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworaW50IAoreHNsdFNldEN0eHRQYXJzZU9wdGlvbnMoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwgaW50IG9wdGlvbnMpCit7CisgICAgaW50IG9sZG9wdHM7CisKKyAgICBpZiAoY3R4dCA9PSBOVUxMKQorICAgICAgICByZXR1cm4oLTEpOworICAgIG9sZG9wdHMgPSBjdHh0LT5wYXJzZXJPcHRpb25zOworICAgIGlmIChjdHh0LT54aW5jbHVkZSkKKyAgICAgICAgb2xkb3B0cyB8PSBYTUxfUEFSU0VfWElOQ0xVREU7CisgICAgY3R4dC0+cGFyc2VyT3B0aW9ucyA9IG9wdGlvbnM7CisgICAgaWYgKG9wdGlvbnMgJiBYTUxfUEFSU0VfWElOQ0xVREUpCisgICAgICAgIGN0eHQtPnhpbmNsdWRlID0gMTsKKyAgICBlbHNlCisgICAgICAgIGN0eHQtPnhpbmNsdWRlID0gMDsKKyAgICByZXR1cm4ob2xkb3B0cyk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJCQlPdXRwdXQJCQkJCSoKKyAqIAkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdFNhdmVSZXN1bHRUbzoKKyAqIEBidWY6ICBhbiBvdXRwdXQgYnVmZmVyCisgKiBAcmVzdWx0OiAgdGhlIHJlc3VsdCB4bWxEb2NQdHIKKyAqIEBzdHlsZTogIHRoZSBzdHlsZXNoZWV0CisgKgorICogU2F2ZSB0aGUgcmVzdWx0IEByZXN1bHQgb2J0YWluZWQgYnkgYXBwbHlpbmcgdGhlIEBzdHlsZSBzdHlsZXNoZWV0CisgKiB0byBhbiBJL08gb3V0cHV0IGNoYW5uZWwgQGJ1ZgorICoKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlIHdyaXR0ZW4gb3IgLTEgaW4gY2FzZSBvZiBmYWlsdXJlLgorICovCitpbnQKK3hzbHRTYXZlUmVzdWx0VG8oeG1sT3V0cHV0QnVmZmVyUHRyIGJ1ZiwgeG1sRG9jUHRyIHJlc3VsdCwKKwkgICAgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUpIHsKKyAgICBjb25zdCB4bWxDaGFyICplbmNvZGluZzsKKyAgICBpbnQgYmFzZTsKKyAgICBjb25zdCB4bWxDaGFyICptZXRob2Q7CisgICAgaW50IGluZGVudDsKKworICAgIGlmICgoYnVmID09IE5VTEwpIHx8IChyZXN1bHQgPT0gTlVMTCkgfHwgKHN0eWxlID09IE5VTEwpKQorCXJldHVybigtMSk7CisgICAgaWYgKChyZXN1bHQtPmNoaWxkcmVuID09IE5VTEwpIHx8CisJKChyZXN1bHQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9EVERfTk9ERSkgJiYKKwkgKHJlc3VsdC0+Y2hpbGRyZW4tPm5leHQgPT0gTlVMTCkpKQorCXJldHVybigwKTsKKworICAgIGlmICgoc3R5bGUtPm1ldGhvZFVSSSAhPSBOVUxMKSAmJgorCSgoc3R5bGUtPm1ldGhvZCA9PSBOVUxMKSB8fAorCSAoIXhtbFN0ckVxdWFsKHN0eWxlLT5tZXRob2QsIChjb25zdCB4bWxDaGFyICopICJ4aHRtbCIpKSkpIHsKKyAgICAgICAgeHNsdEdlbmVyaWNFcnJvcih4c2x0R2VuZXJpY0Vycm9yQ29udGV4dCwKKwkJInhzbHRTYXZlUmVzdWx0VG8gOiB1bmtub3duIG91cHV0IG1ldGhvZFxuIik7CisgICAgICAgIHJldHVybigtMSk7CisgICAgfQorCisgICAgYmFzZSA9IGJ1Zi0+d3JpdHRlbjsKKworICAgIFhTTFRfR0VUX0lNUE9SVF9QVFIobWV0aG9kLCBzdHlsZSwgbWV0aG9kKQorICAgIFhTTFRfR0VUX0lNUE9SVF9QVFIoZW5jb2RpbmcsIHN0eWxlLCBlbmNvZGluZykKKyAgICBYU0xUX0dFVF9JTVBPUlRfSU5UKGluZGVudCwgc3R5bGUsIGluZGVudCk7CisKKyAgICBpZiAoKG1ldGhvZCA9PSBOVUxMKSAmJiAocmVzdWx0LT50eXBlID09IFhNTF9IVE1MX0RPQ1VNRU5UX05PREUpKQorCW1ldGhvZCA9IChjb25zdCB4bWxDaGFyICopICJodG1sIjsKKworICAgIGlmICgobWV0aG9kICE9IE5VTEwpICYmCisJKHhtbFN0ckVxdWFsKG1ldGhvZCwgKGNvbnN0IHhtbENoYXIgKikgImh0bWwiKSkpIHsKKwlpZiAoZW5jb2RpbmcgIT0gTlVMTCkgeworCSAgICBodG1sU2V0TWV0YUVuY29kaW5nKHJlc3VsdCwgKGNvbnN0IHhtbENoYXIgKikgZW5jb2RpbmcpOworCX0gZWxzZSB7CisJICAgIGh0bWxTZXRNZXRhRW5jb2RpbmcocmVzdWx0LCAoY29uc3QgeG1sQ2hhciAqKSAiVVRGLTgiKTsKKwl9CisJaWYgKGluZGVudCA9PSAtMSkKKwkgICAgaW5kZW50ID0gMTsKKwlodG1sRG9jQ29udGVudER1bXBGb3JtYXRPdXRwdXQoYnVmLCByZXN1bHQsIChjb25zdCBjaGFyICopIGVuY29kaW5nLAorCQkgICAgICAgICAgICAgICAgICAgICAgIGluZGVudCk7CisJeG1sT3V0cHV0QnVmZmVyRmx1c2goYnVmKTsKKyAgICB9IGVsc2UgaWYgKChtZXRob2QgIT0gTlVMTCkgJiYKKwkoeG1sU3RyRXF1YWwobWV0aG9kLCAoY29uc3QgeG1sQ2hhciAqKSAieGh0bWwiKSkpIHsKKwlpZiAoZW5jb2RpbmcgIT0gTlVMTCkgeworCSAgICBodG1sU2V0TWV0YUVuY29kaW5nKHJlc3VsdCwgKGNvbnN0IHhtbENoYXIgKikgZW5jb2RpbmcpOworCX0gZWxzZSB7CisJICAgIGh0bWxTZXRNZXRhRW5jb2RpbmcocmVzdWx0LCAoY29uc3QgeG1sQ2hhciAqKSAiVVRGLTgiKTsKKwl9CisJaHRtbERvY0NvbnRlbnREdW1wT3V0cHV0KGJ1ZiwgcmVzdWx0LCAoY29uc3QgY2hhciAqKSBlbmNvZGluZyk7CisJeG1sT3V0cHV0QnVmZmVyRmx1c2goYnVmKTsKKyAgICB9IGVsc2UgaWYgKChtZXRob2QgIT0gTlVMTCkgJiYKKwkgICAgICAgKHhtbFN0ckVxdWFsKG1ldGhvZCwgKGNvbnN0IHhtbENoYXIgKikgInRleHQiKSkpIHsKKwl4bWxOb2RlUHRyIGN1cjsKKworCWN1ciA9IHJlc3VsdC0+Y2hpbGRyZW47CisJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CisJICAgIGlmIChjdXItPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkKKwkJeG1sT3V0cHV0QnVmZmVyV3JpdGVTdHJpbmcoYnVmLCAoY29uc3QgY2hhciAqKSBjdXItPmNvbnRlbnQpOworCisJICAgIC8qCisJICAgICAqIFNraXAgdG8gbmV4dCBub2RlCisJICAgICAqLworCSAgICBpZiAoY3VyLT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJCWlmICgoY3VyLT5jaGlsZHJlbi0+dHlwZSAhPSBYTUxfRU5USVRZX0RFQ0wpICYmCisJCSAgICAoY3VyLT5jaGlsZHJlbi0+dHlwZSAhPSBYTUxfRU5USVRZX1JFRl9OT0RFKSAmJgorCQkgICAgKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9OT0RFKSkgeworCQkgICAgY3VyID0gY3VyLT5jaGlsZHJlbjsKKwkJICAgIGNvbnRpbnVlOworCQl9CisJICAgIH0KKwkgICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CisJCWN1ciA9IGN1ci0+bmV4dDsKKwkJY29udGludWU7CisJICAgIH0KKwkgICAgCisJICAgIGRvIHsKKwkJY3VyID0gY3VyLT5wYXJlbnQ7CisJCWlmIChjdXIgPT0gTlVMTCkKKwkJICAgIGJyZWFrOworCQlpZiAoY3VyID09ICh4bWxOb2RlUHRyKSBzdHlsZS0+ZG9jKSB7CisJCSAgICBjdXIgPSBOVUxMOworCQkgICAgYnJlYWs7CisJCX0KKwkJaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CisJCSAgICBjdXIgPSBjdXItPm5leHQ7CisJCSAgICBicmVhazsKKwkJfQorCSAgICB9IHdoaWxlIChjdXIgIT0gTlVMTCk7CisJfQorCXhtbE91dHB1dEJ1ZmZlckZsdXNoKGJ1Zik7CisgICAgfSBlbHNlIHsKKwlpbnQgb21pdFhtbERlY2w7CisJaW50IHN0YW5kYWxvbmU7CisKKwlYU0xUX0dFVF9JTVBPUlRfSU5UKG9taXRYbWxEZWNsLCBzdHlsZSwgb21pdFhtbERlY2xhcmF0aW9uKTsKKwlYU0xUX0dFVF9JTVBPUlRfSU5UKHN0YW5kYWxvbmUsIHN0eWxlLCBzdGFuZGFsb25lKTsKKworCWlmIChvbWl0WG1sRGVjbCAhPSAxKSB7CisJICAgIHhtbE91dHB1dEJ1ZmZlcldyaXRlU3RyaW5nKGJ1ZiwgIjw/eG1sIHZlcnNpb249Iik7CisJICAgIGlmIChyZXN1bHQtPnZlcnNpb24gIT0gTlVMTCkgCisJCXhtbEJ1ZmZlcldyaXRlUXVvdGVkU3RyaW5nKGJ1Zi0+YnVmZmVyLCByZXN1bHQtPnZlcnNpb24pOworCSAgICBlbHNlCisJCXhtbE91dHB1dEJ1ZmZlcldyaXRlU3RyaW5nKGJ1ZiwgIlwiMS4wXCIiKTsKKwkgICAgaWYgKGVuY29kaW5nID09IE5VTEwpIHsKKwkJaWYgKHJlc3VsdC0+ZW5jb2RpbmcgIT0gTlVMTCkKKwkJICAgIGVuY29kaW5nID0gcmVzdWx0LT5lbmNvZGluZzsKKwkJZWxzZSBpZiAocmVzdWx0LT5jaGFyc2V0ICE9IFhNTF9DSEFSX0VOQ09ESU5HX1VURjgpCisJCSAgICBlbmNvZGluZyA9IChjb25zdCB4bWxDaGFyICopCisJCQkgICAgICAgeG1sR2V0Q2hhckVuY29kaW5nTmFtZSgoeG1sQ2hhckVuY29kaW5nKQorCQkJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LT5jaGFyc2V0KTsKKwkgICAgfQorCSAgICBpZiAoZW5jb2RpbmcgIT0gTlVMTCkgeworCQl4bWxPdXRwdXRCdWZmZXJXcml0ZVN0cmluZyhidWYsICIgZW5jb2Rpbmc9Iik7CisJCXhtbEJ1ZmZlcldyaXRlUXVvdGVkU3RyaW5nKGJ1Zi0+YnVmZmVyLCAoeG1sQ2hhciAqKSBlbmNvZGluZyk7CisJICAgIH0KKwkgICAgc3dpdGNoIChzdGFuZGFsb25lKSB7CisJCWNhc2UgMDoKKwkJICAgIHhtbE91dHB1dEJ1ZmZlcldyaXRlU3RyaW5nKGJ1ZiwgIiBzdGFuZGFsb25lPVwibm9cIiIpOworCQkgICAgYnJlYWs7CisJCWNhc2UgMToKKwkJICAgIHhtbE91dHB1dEJ1ZmZlcldyaXRlU3RyaW5nKGJ1ZiwgIiBzdGFuZGFsb25lPVwieWVzXCIiKTsKKwkJICAgIGJyZWFrOworCQlkZWZhdWx0OgorCQkgICAgYnJlYWs7CisJICAgIH0KKwkgICAgeG1sT3V0cHV0QnVmZmVyV3JpdGVTdHJpbmcoYnVmLCAiPz5cbiIpOworCX0KKwlpZiAocmVzdWx0LT5jaGlsZHJlbiAhPSBOVUxMKSB7CisJICAgIHhtbE5vZGVQdHIgY2hpbGQgPSByZXN1bHQtPmNoaWxkcmVuOworCisJICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CisJCXhtbE5vZGVEdW1wT3V0cHV0KGJ1ZiwgcmVzdWx0LCBjaGlsZCwgMCwgKGluZGVudCA9PSAxKSwKKwkJCSAgICAgICAgICAoY29uc3QgY2hhciAqKSBlbmNvZGluZyk7CisJCWlmICgoY2hpbGQtPnR5cGUgPT0gWE1MX0RURF9OT0RFKSB8fAorCQkgICAgKChjaGlsZC0+dHlwZSA9PSBYTUxfQ09NTUVOVF9OT0RFKSAmJgorCQkgICAgIChjaGlsZC0+bmV4dCAhPSBOVUxMKSkpCisJCSAgICB4bWxPdXRwdXRCdWZmZXJXcml0ZVN0cmluZyhidWYsICJcbiIpOworCQljaGlsZCA9IGNoaWxkLT5uZXh0OworCSAgICB9CisJICAgIHhtbE91dHB1dEJ1ZmZlcldyaXRlU3RyaW5nKGJ1ZiwgIlxuIik7CisJfQorCXhtbE91dHB1dEJ1ZmZlckZsdXNoKGJ1Zik7CisgICAgfQorICAgIHJldHVybihidWYtPndyaXR0ZW4gLSBiYXNlKTsKK30KKworLyoqCisgKiB4c2x0U2F2ZVJlc3VsdFRvRmlsZW5hbWU6CisgKiBAVVJMOiAgYSBmaWxlbmFtZSBvciBVUkwKKyAqIEByZXN1bHQ6ICB0aGUgcmVzdWx0IHhtbERvY1B0cgorICogQHN0eWxlOiAgdGhlIHN0eWxlc2hlZXQKKyAqIEBjb21wcmVzc2lvbjogIHRoZSBjb21wcmVzc2lvbiBmYWN0b3IgKDAgLSA5IGluY2x1ZGVkKQorICoKKyAqIFNhdmUgdGhlIHJlc3VsdCBAcmVzdWx0IG9idGFpbmVkIGJ5IGFwcGx5aW5nIHRoZSBAc3R5bGUgc3R5bGVzaGVldAorICogdG8gYSBmaWxlIG9yIEBVUkwKKyAqCisgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZSB3cml0dGVuIG9yIC0xIGluIGNhc2Ugb2YgZmFpbHVyZS4KKyAqLworaW50Cit4c2x0U2F2ZVJlc3VsdFRvRmlsZW5hbWUoY29uc3QgY2hhciAqVVJMLCB4bWxEb2NQdHIgcmVzdWx0LAorCQkJIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLCBpbnQgY29tcHJlc3Npb24pIHsKKyAgICB4bWxPdXRwdXRCdWZmZXJQdHIgYnVmOworICAgIGNvbnN0IHhtbENoYXIgKmVuY29kaW5nOworICAgIGludCByZXQ7CisKKyAgICBpZiAoKFVSTCA9PSBOVUxMKSB8fCAocmVzdWx0ID09IE5VTEwpIHx8IChzdHlsZSA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworICAgIGlmIChyZXN1bHQtPmNoaWxkcmVuID09IE5VTEwpCisJcmV0dXJuKDApOworCisgICAgWFNMVF9HRVRfSU1QT1JUX1BUUihlbmNvZGluZywgc3R5bGUsIGVuY29kaW5nKQorICAgIGlmIChlbmNvZGluZyAhPSBOVUxMKSB7CisJeG1sQ2hhckVuY29kaW5nSGFuZGxlclB0ciBlbmNvZGVyOworCisJZW5jb2RlciA9IHhtbEZpbmRDaGFyRW5jb2RpbmdIYW5kbGVyKChjaGFyICopZW5jb2RpbmcpOworCWlmICgoZW5jb2RlciAhPSBOVUxMKSAmJgorCSAgICAoeG1sU3RyRXF1YWwoKGNvbnN0IHhtbENoYXIgKillbmNvZGVyLT5uYW1lLAorCQkJIChjb25zdCB4bWxDaGFyICopICJVVEYtOCIpKSkKKwkgICAgZW5jb2RlciA9IE5VTEw7CisJYnVmID0geG1sT3V0cHV0QnVmZmVyQ3JlYXRlRmlsZW5hbWUoVVJMLCBlbmNvZGVyLCBjb21wcmVzc2lvbik7CisgICAgfSBlbHNlIHsKKwlidWYgPSB4bWxPdXRwdXRCdWZmZXJDcmVhdGVGaWxlbmFtZShVUkwsIE5VTEwsIGNvbXByZXNzaW9uKTsKKyAgICB9CisgICAgaWYgKGJ1ZiA9PSBOVUxMKQorCXJldHVybigtMSk7CisgICAgeHNsdFNhdmVSZXN1bHRUbyhidWYsIHJlc3VsdCwgc3R5bGUpOworICAgIHJldCA9IHhtbE91dHB1dEJ1ZmZlckNsb3NlKGJ1Zik7CisgICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdFNhdmVSZXN1bHRUb0ZpbGU6CisgKiBAZmlsZTogIGEgRklMRSAqIEkvTworICogQHJlc3VsdDogIHRoZSByZXN1bHQgeG1sRG9jUHRyCisgKiBAc3R5bGU6ICB0aGUgc3R5bGVzaGVldAorICoKKyAqIFNhdmUgdGhlIHJlc3VsdCBAcmVzdWx0IG9idGFpbmVkIGJ5IGFwcGx5aW5nIHRoZSBAc3R5bGUgc3R5bGVzaGVldAorICogdG8gYW4gb3BlbiBGSUxFICogSS9PLgorICogVGhpcyBkb2VzIG5vdCBjbG9zZSB0aGUgRklMRSBAZmlsZQorICoKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIG9yIC0xIGluIGNhc2Ugb2YgZmFpbHVyZS4KKyAqLworaW50Cit4c2x0U2F2ZVJlc3VsdFRvRmlsZShGSUxFICpmaWxlLCB4bWxEb2NQdHIgcmVzdWx0LCB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkgeworICAgIHhtbE91dHB1dEJ1ZmZlclB0ciBidWY7CisgICAgY29uc3QgeG1sQ2hhciAqZW5jb2Rpbmc7CisgICAgaW50IHJldDsKKworICAgIGlmICgoZmlsZSA9PSBOVUxMKSB8fCAocmVzdWx0ID09IE5VTEwpIHx8IChzdHlsZSA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworICAgIGlmIChyZXN1bHQtPmNoaWxkcmVuID09IE5VTEwpCisJcmV0dXJuKDApOworCisgICAgWFNMVF9HRVRfSU1QT1JUX1BUUihlbmNvZGluZywgc3R5bGUsIGVuY29kaW5nKQorICAgIGlmIChlbmNvZGluZyAhPSBOVUxMKSB7CisJeG1sQ2hhckVuY29kaW5nSGFuZGxlclB0ciBlbmNvZGVyOworCisJZW5jb2RlciA9IHhtbEZpbmRDaGFyRW5jb2RpbmdIYW5kbGVyKChjaGFyICopZW5jb2RpbmcpOworCWlmICgoZW5jb2RlciAhPSBOVUxMKSAmJgorCSAgICAoeG1sU3RyRXF1YWwoKGNvbnN0IHhtbENoYXIgKillbmNvZGVyLT5uYW1lLAorCQkJIChjb25zdCB4bWxDaGFyICopICJVVEYtOCIpKSkKKwkgICAgZW5jb2RlciA9IE5VTEw7CisJYnVmID0geG1sT3V0cHV0QnVmZmVyQ3JlYXRlRmlsZShmaWxlLCBlbmNvZGVyKTsKKyAgICB9IGVsc2UgeworCWJ1ZiA9IHhtbE91dHB1dEJ1ZmZlckNyZWF0ZUZpbGUoZmlsZSwgTlVMTCk7CisgICAgfQorCisgICAgaWYgKGJ1ZiA9PSBOVUxMKQorCXJldHVybigtMSk7CisgICAgeHNsdFNhdmVSZXN1bHRUbyhidWYsIHJlc3VsdCwgc3R5bGUpOworICAgIHJldCA9IHhtbE91dHB1dEJ1ZmZlckNsb3NlKGJ1Zik7CisgICAgcmV0dXJuKHJldCk7Cit9CisKKy8qKgorICogeHNsdFNhdmVSZXN1bHRUb0ZkOgorICogQGZkOiAgYSBmaWxlIGRlc2NyaXB0b3IKKyAqIEByZXN1bHQ6ICB0aGUgcmVzdWx0IHhtbERvY1B0cgorICogQHN0eWxlOiAgdGhlIHN0eWxlc2hlZXQKKyAqCisgKiBTYXZlIHRoZSByZXN1bHQgQHJlc3VsdCBvYnRhaW5lZCBieSBhcHBseWluZyB0aGUgQHN0eWxlIHN0eWxlc2hlZXQKKyAqIHRvIGFuIG9wZW4gZmlsZSBkZXNjcmlwdG9yCisgKiBUaGlzIGRvZXMgbm90IGNsb3NlIHRoZSBkZXNjcmlwdG9yLgorICoKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIG9yIC0xIGluIGNhc2Ugb2YgZmFpbHVyZS4KKyAqLworaW50Cit4c2x0U2F2ZVJlc3VsdFRvRmQoaW50IGZkLCB4bWxEb2NQdHIgcmVzdWx0LCB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkgeworICAgIHhtbE91dHB1dEJ1ZmZlclB0ciBidWY7CisgICAgY29uc3QgeG1sQ2hhciAqZW5jb2Rpbmc7CisgICAgaW50IHJldDsKKworICAgIGlmICgoZmQgPCAwKSB8fCAocmVzdWx0ID09IE5VTEwpIHx8IChzdHlsZSA9PSBOVUxMKSkKKwlyZXR1cm4oLTEpOworICAgIGlmIChyZXN1bHQtPmNoaWxkcmVuID09IE5VTEwpCisJcmV0dXJuKDApOworCisgICAgWFNMVF9HRVRfSU1QT1JUX1BUUihlbmNvZGluZywgc3R5bGUsIGVuY29kaW5nKQorICAgIGlmIChlbmNvZGluZyAhPSBOVUxMKSB7CisJeG1sQ2hhckVuY29kaW5nSGFuZGxlclB0ciBlbmNvZGVyOworCisJZW5jb2RlciA9IHhtbEZpbmRDaGFyRW5jb2RpbmdIYW5kbGVyKChjaGFyICopZW5jb2RpbmcpOworCWlmICgoZW5jb2RlciAhPSBOVUxMKSAmJgorCSAgICAoeG1sU3RyRXF1YWwoKGNvbnN0IHhtbENoYXIgKillbmNvZGVyLT5uYW1lLAorCQkJIChjb25zdCB4bWxDaGFyICopICJVVEYtOCIpKSkKKwkgICAgZW5jb2RlciA9IE5VTEw7CisJYnVmID0geG1sT3V0cHV0QnVmZmVyQ3JlYXRlRmQoZmQsIGVuY29kZXIpOworICAgIH0gZWxzZSB7CisJYnVmID0geG1sT3V0cHV0QnVmZmVyQ3JlYXRlRmQoZmQsIE5VTEwpOworICAgIH0KKyAgICBpZiAoYnVmID09IE5VTEwpCisJcmV0dXJuKC0xKTsKKyAgICB4c2x0U2F2ZVJlc3VsdFRvKGJ1ZiwgcmVzdWx0LCBzdHlsZSk7CisgICAgcmV0ID0geG1sT3V0cHV0QnVmZmVyQ2xvc2UoYnVmKTsKKyAgICByZXR1cm4ocmV0KTsKK30KKworLyoqCisgKiB4c2x0U2F2ZVJlc3VsdFRvU3RyaW5nOgorICogQGRvY190eHRfcHRyOiAgTWVtb3J5IHBvaW50ZXIgZm9yIGFsbG9jYXRlZCBYTUwgdGV4dAorICogQGRvY190eHRfbGVuOiAgTGVuZ3RoIG9mIHRoZSBnZW5lcmF0ZWQgWE1MIHRleHQKKyAqIEByZXN1bHQ6ICB0aGUgcmVzdWx0IHhtbERvY1B0cgorICogQHN0eWxlOiAgdGhlIHN0eWxlc2hlZXQKKyAqCisgKiBTYXZlIHRoZSByZXN1bHQgQHJlc3VsdCBvYnRhaW5lZCBieSBhcHBseWluZyB0aGUgQHN0eWxlIHN0eWxlc2hlZXQKKyAqIHRvIGEgbmV3IGFsbG9jYXRlZCBzdHJpbmcuCisgKgorICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcyBhbmQgLTEgaW4gY2FzZSBvZiBlcnJvcgorICovCitpbnQKK3hzbHRTYXZlUmVzdWx0VG9TdHJpbmcoeG1sQ2hhciAqKmRvY190eHRfcHRyLCBpbnQgKiBkb2NfdHh0X2xlbiwgCisJCSAgICAgICB4bWxEb2NQdHIgcmVzdWx0LCB4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSkgeworICAgIHhtbE91dHB1dEJ1ZmZlclB0ciBidWY7CisgICAgY29uc3QgeG1sQ2hhciAqZW5jb2Rpbmc7CisKKyAgICAqZG9jX3R4dF9wdHIgPSBOVUxMOworICAgICpkb2NfdHh0X2xlbiA9IDA7CisgICAgaWYgKHJlc3VsdC0+Y2hpbGRyZW4gPT0gTlVMTCkKKwlyZXR1cm4oMCk7CisKKyAgICBYU0xUX0dFVF9JTVBPUlRfUFRSKGVuY29kaW5nLCBzdHlsZSwgZW5jb2RpbmcpCisgICAgaWYgKGVuY29kaW5nICE9IE5VTEwpIHsKKwl4bWxDaGFyRW5jb2RpbmdIYW5kbGVyUHRyIGVuY29kZXI7CisKKwllbmNvZGVyID0geG1sRmluZENoYXJFbmNvZGluZ0hhbmRsZXIoKGNoYXIgKillbmNvZGluZyk7CisJaWYgKChlbmNvZGVyICE9IE5VTEwpICYmCisJICAgICh4bWxTdHJFcXVhbCgoY29uc3QgeG1sQ2hhciAqKWVuY29kZXItPm5hbWUsCisJCQkgKGNvbnN0IHhtbENoYXIgKikgIlVURi04IikpKQorCSAgICBlbmNvZGVyID0gTlVMTDsKKwlidWYgPSB4bWxBbGxvY091dHB1dEJ1ZmZlcihlbmNvZGVyKTsKKyAgICB9IGVsc2UgeworCWJ1ZiA9IHhtbEFsbG9jT3V0cHV0QnVmZmVyKE5VTEwpOworICAgIH0KKyAgICBpZiAoYnVmID09IE5VTEwpCisJcmV0dXJuKC0xKTsKKyAgICB4c2x0U2F2ZVJlc3VsdFRvKGJ1ZiwgcmVzdWx0LCBzdHlsZSk7CisgICAgaWYgKGJ1Zi0+Y29udiAhPSBOVUxMKSB7CisJKmRvY190eHRfbGVuID0gYnVmLT5jb252LT51c2U7CisJKmRvY190eHRfcHRyID0geG1sU3RybmR1cChidWYtPmNvbnYtPmNvbnRlbnQsICpkb2NfdHh0X2xlbik7CisgICAgfSBlbHNlIHsKKwkqZG9jX3R4dF9sZW4gPSBidWYtPmJ1ZmZlci0+dXNlOworCSpkb2NfdHh0X3B0ciA9IHhtbFN0cm5kdXAoYnVmLT5idWZmZXItPmNvbnRlbnQsICpkb2NfdHh0X2xlbik7CisgICAgfQorICAgICh2b2lkKXhtbE91dHB1dEJ1ZmZlckNsb3NlKGJ1Zik7CisgICAgcmV0dXJuIDA7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJR2VuZXJhdGluZyBwcm9maWxpbmcgaW5mb3JtYXRpb25zCQkJKgorICogCQkJCQkJCQkJKgorICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIGxvbmcgY2FsaWJyYXRpb24gPSAtMTsKKworLyoqCisgKiB4c2x0Q2FsaWJyYXRlVGltZXN0YW1wczoKKyAqCisgKiBVc2VkIGZvciB0byBjYWxpYnJhdGUgdGhlIHhzbHRUaW1lc3RhbXAoKSBmdW5jdGlvbgorICogU2hvdWxkIHdvcmsgaWYgbGF1bmNoZWQgYXQgc3RhcnR1cCBhbmQgd2UgZG9uJ3QgbG9vc2Ugb3VyIHF1YW50dW0gOi0pCisgKgorICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB1c2VkIGJ5IHhzbHRUaW1lc3RhbXAoKQorICovCitzdGF0aWMgbG9uZworeHNsdENhbGlicmF0ZVRpbWVzdGFtcHModm9pZCkgeworICAgIHJlZ2lzdGVyIGludCBpOworCisgICAgZm9yIChpID0gMDtpIDwgOTk5O2krKykKKwl4c2x0VGltZXN0YW1wKCk7CisgICAgcmV0dXJuKHhzbHRUaW1lc3RhbXAoKSAvIDEwMDApOworfQorCisvKioKKyAqIHhzbHRDYWxpYnJhdGVBZGp1c3Q6CisgKiBAZGVsdGE6ICBhIG5lZ2F0aXZlIGRlYWx5IHZhbHVlIGZvdW5kCisgKgorICogVXNlZCBmb3IgdG8gY29ycmVjdCB0aGUgY2FsaWJyYXRpb24gZm9yIHhzbHRUaW1lc3RhbXAoKQorICovCit2b2lkCit4c2x0Q2FsaWJyYXRlQWRqdXN0KGxvbmcgZGVsdGEpIHsKKyAgICBjYWxpYnJhdGlvbiArPSBkZWx0YTsKK30KKworLyoqCisgKiB4c2x0VGltZXN0YW1wOgorICoKKyAqIFVzZWQgZm9yIGdhdGhlcmluZyBwcm9maWxpbmcgZGF0YQorICoKKyAqIFJldHVybnMgdGhlIG51bWJlciBvZiB0ZW50aCBvZiBtaWxsaXNlY29uZHMgc2luY2UgdGhlIGJlZ2lubmluZyBvZiB0aGUKKyAqIHByb2ZpbGluZworICovCitsb25nCit4c2x0VGltZXN0YW1wKHZvaWQpCit7CisjaWZkZWYgWFNMVF9XSU4zMl9QRVJGT1JNQU5DRV9DT1VOVEVSCisgICAgQk9PTCBvazsKKyAgICBMQVJHRV9JTlRFR0VSIHBlcmZvcm1hbmNlQ291bnQ7CisgICAgTEFSR0VfSU5URUdFUiBwZXJmb3JtYW5jZUZyZXF1ZW5jeTsKKyAgICBMT05HTE9ORyBxdWFkQ291bnQ7CisgICAgZG91YmxlIHNlY29uZHM7CisgICAgc3RhdGljIExPTkdMT05HIHN0YXJ0dXBRdWFkQ291bnQgPSAwOworICAgIHN0YXRpYyBMT05HTE9ORyBzdGFydHVwUXVhZEZyZXEgPSAwOworCisgICAgb2sgPSBRdWVyeVBlcmZvcm1hbmNlQ291bnRlcigmcGVyZm9ybWFuY2VDb3VudCk7CisgICAgaWYgKCFvaykKKyAgICAgICAgcmV0dXJuIDA7CisgICAgcXVhZENvdW50ID0gcGVyZm9ybWFuY2VDb3VudC5RdWFkUGFydDsKKyAgICBpZiAoY2FsaWJyYXRpb24gPCAwKSB7CisgICAgICAgIGNhbGlicmF0aW9uID0gMDsKKyAgICAgICAgb2sgPSBRdWVyeVBlcmZvcm1hbmNlRnJlcXVlbmN5KCZwZXJmb3JtYW5jZUZyZXF1ZW5jeSk7CisgICAgICAgIGlmICghb2spCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgc3RhcnR1cFF1YWRGcmVxID0gcGVyZm9ybWFuY2VGcmVxdWVuY3kuUXVhZFBhcnQ7CisgICAgICAgIHN0YXJ0dXBRdWFkQ291bnQgPSBxdWFkQ291bnQ7CisgICAgICAgIHJldHVybiAoMCk7CisgICAgfQorICAgIGlmIChzdGFydHVwUXVhZEZyZXEgPT0gMCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgc2Vjb25kcyA9IChxdWFkQ291bnQgLSBzdGFydHVwUXVhZENvdW50KSAvIChkb3VibGUpIHN0YXJ0dXBRdWFkRnJlcTsKKyAgICByZXR1cm4gKGxvbmcpIChzZWNvbmRzICogWFNMVF9USU1FU1RBTVBfVElDU19QRVJfU0VDKTsKKworI2Vsc2UgLyogWFNMVF9XSU4zMl9QRVJGT1JNQU5DRV9DT1VOVEVSICovCisjaWZkZWYgSEFWRV9HRVRUSU1FT0ZEQVkKKyAgICBzdGF0aWMgc3RydWN0IHRpbWV2YWwgc3RhcnR1cDsKKyAgICBzdHJ1Y3QgdGltZXZhbCBjdXI7CisgICAgbG9uZyB0aWNzOworCisgICAgaWYgKGNhbGlicmF0aW9uIDwgMCkgeworICAgICAgICBnZXR0aW1lb2ZkYXkoJnN0YXJ0dXAsIE5VTEwpOworICAgICAgICBjYWxpYnJhdGlvbiA9IDA7CisgICAgICAgIGNhbGlicmF0aW9uID0geHNsdENhbGlicmF0ZVRpbWVzdGFtcHMoKTsKKyAgICAgICAgZ2V0dGltZW9mZGF5KCZzdGFydHVwLCBOVUxMKTsKKyAgICAgICAgcmV0dXJuICgwKTsKKyAgICB9CisKKyAgICBnZXR0aW1lb2ZkYXkoJmN1ciwgTlVMTCk7CisgICAgdGljcyA9IChjdXIudHZfc2VjIC0gc3RhcnR1cC50dl9zZWMpICogWFNMVF9USU1FU1RBTVBfVElDU19QRVJfU0VDOworICAgIHRpY3MgKz0gKGN1ci50dl91c2VjIC0gc3RhcnR1cC50dl91c2VjKSAvCisgICAgICAgICAgICAgICAgICAgICAgICAgICgxMDAwMDAwbCAvIFhTTFRfVElNRVNUQU1QX1RJQ1NfUEVSX1NFQyk7CisgICAgCisgICAgdGljcyAtPSBjYWxpYnJhdGlvbjsKKyAgICByZXR1cm4odGljcyk7CisjZWxzZQorCisgICAgLyogTmVpdGhlciBnZXR0aW1lb2ZkYXkoKSBub3IgV2luMzIgcGVyZm9ybWFuY2UgY291bnRlciBhdmFpbGFibGUgKi8KKworICAgIHJldHVybiAoMCk7CisKKyNlbmRpZiAvKiBIQVZFX0dFVFRJTUVPRkRBWSAqLworI2VuZGlmIC8qIFhTTFRfV0lOMzJfUEVSRk9STUFOQ0VfQ09VTlRFUiAqLworfQorCisjZGVmaW5lIE1BWF9URU1QTEFURVMgMTAwMDAKKworLyoqCisgKiB4c2x0U2F2ZVByb2ZpbGluZzoKKyAqIEBjdHh0OiAgYW4gWFNMVCBjb250ZXh0CisgKiBAb3V0cHV0OiAgYSBGSUxFICogZm9yIHNhdmluZyB0aGUgaW5mb3JtYXRpb25zCisgKgorICogU2F2ZSB0aGUgcHJvZmlsaW5nIGluZm9ybWF0aW9ucyBvbiBAb3V0cHV0CisgKi8KK3ZvaWQKK3hzbHRTYXZlUHJvZmlsaW5nKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQsIEZJTEUgKm91dHB1dCkgeworICAgIGludCBuYiwgaSxqOworICAgIGludCBtYXg7CisgICAgaW50IHRvdGFsOworICAgIGxvbmcgdG90YWx0OworICAgIHhzbHRUZW1wbGF0ZVB0ciAqdGVtcGxhdGVzOworICAgIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlOworICAgIHhzbHRUZW1wbGF0ZVB0ciB0ZW1wbGF0ZTsKKworICAgIGlmICgob3V0cHV0ID09IE5VTEwpIHx8IChjdHh0ID09IE5VTEwpKQorCXJldHVybjsKKyAgICBpZiAoY3R4dC0+cHJvZmlsZSA9PSAwKQorCXJldHVybjsKKworICAgIG5iID0gMDsKKyAgICBtYXggPSBNQVhfVEVNUExBVEVTOworICAgIHRlbXBsYXRlcyA9IHhtbE1hbGxvYyhtYXggKiBzaXplb2YoeHNsdFRlbXBsYXRlUHRyKSk7CisgICAgaWYgKHRlbXBsYXRlcyA9PSBOVUxMKQorCXJldHVybjsKKworICAgIHN0eWxlID0gY3R4dC0+c3R5bGU7CisgICAgd2hpbGUgKHN0eWxlICE9IE5VTEwpIHsKKwl0ZW1wbGF0ZSA9IHN0eWxlLT50ZW1wbGF0ZXM7CisJd2hpbGUgKHRlbXBsYXRlICE9IE5VTEwpIHsKKwkgICAgaWYgKG5iID49IG1heCkKKwkJYnJlYWs7CisKKwkgICAgaWYgKHRlbXBsYXRlLT5uYkNhbGxzID4gMCkKKwkJdGVtcGxhdGVzW25iKytdID0gdGVtcGxhdGU7CisJICAgIHRlbXBsYXRlID0gdGVtcGxhdGUtPm5leHQ7CisJfQorCisJc3R5bGUgPSB4c2x0TmV4dEltcG9ydChzdHlsZSk7CisgICAgfQorCisgICAgZm9yIChpID0gMDtpIDwgbmIgLTE7aSsrKSB7CisJZm9yIChqID0gaSArIDE7IGogPCBuYjsgaisrKSB7CisJICAgIGlmICgodGVtcGxhdGVzW2ldLT50aW1lIDw9IHRlbXBsYXRlc1tqXS0+dGltZSkgfHwKKwkJKCh0ZW1wbGF0ZXNbaV0tPnRpbWUgPT0gdGVtcGxhdGVzW2pdLT50aW1lKSAmJgorCSAgICAgICAgICh0ZW1wbGF0ZXNbaV0tPm5iQ2FsbHMgPD0gdGVtcGxhdGVzW2pdLT5uYkNhbGxzKSkpIHsKKwkJdGVtcGxhdGUgPSB0ZW1wbGF0ZXNbal07CisJCXRlbXBsYXRlc1tqXSA9IHRlbXBsYXRlc1tpXTsKKwkJdGVtcGxhdGVzW2ldID0gdGVtcGxhdGU7CisJICAgIH0KKwl9CisgICAgfQorCisgICAgZnByaW50ZihvdXRwdXQsICIlNnMlMjBzJTIwcyUxMHMgIENhbGxzIFRvdCAxMDB1cyBBdmdcblxuIiwKKwkgICAgIm51bWJlciIsICJtYXRjaCIsICJuYW1lIiwgIm1vZGUiKTsKKyAgICB0b3RhbCA9IDA7CisgICAgdG90YWx0ID0gMDsKKyAgICBmb3IgKGkgPSAwO2kgPCBuYjtpKyspIHsKKwlmcHJpbnRmKG91dHB1dCwgIiU1ZCAiLCBpKTsKKwlpZiAodGVtcGxhdGVzW2ldLT5tYXRjaCAhPSBOVUxMKSB7CisJICAgIGlmICh4bWxTdHJsZW4odGVtcGxhdGVzW2ldLT5tYXRjaCkgPiAyMCkKKwkJZnByaW50ZihvdXRwdXQsICIlc1xuJTI2cyIsIHRlbXBsYXRlc1tpXS0+bWF0Y2gsICIiKTsKKwkgICAgZWxzZQorCQlmcHJpbnRmKG91dHB1dCwgIiUyMHMiLCB0ZW1wbGF0ZXNbaV0tPm1hdGNoKTsKKwl9IGVsc2UgeworCSAgICBmcHJpbnRmKG91dHB1dCwgIiUyMHMiLCAiIik7CisJfQorCWlmICh0ZW1wbGF0ZXNbaV0tPm5hbWUgIT0gTlVMTCkgeworCSAgICBpZiAoeG1sU3RybGVuKHRlbXBsYXRlc1tpXS0+bmFtZSkgPiAyMCkKKwkJZnByaW50ZihvdXRwdXQsICIlc1xuJTQ2cyIsIHRlbXBsYXRlc1tpXS0+bmFtZSwgIiIpOworCSAgICBlbHNlCisJCWZwcmludGYob3V0cHV0LCAiJTIwcyIsIHRlbXBsYXRlc1tpXS0+bmFtZSk7CisJfSBlbHNlIHsKKwkgICAgZnByaW50ZihvdXRwdXQsICIlMjBzIiwgIiIpOworCX0KKwlpZiAodGVtcGxhdGVzW2ldLT5tb2RlICE9IE5VTEwpIHsKKwkgICAgaWYgKHhtbFN0cmxlbih0ZW1wbGF0ZXNbaV0tPm1vZGUpID4gMTApCisJCWZwcmludGYob3V0cHV0LCAiJXNcbiU1NnMiLCB0ZW1wbGF0ZXNbaV0tPm1vZGUsICIiKTsKKwkgICAgZWxzZQorCQlmcHJpbnRmKG91dHB1dCwgIiUxMHMiLCB0ZW1wbGF0ZXNbaV0tPm1vZGUpOworCX0gZWxzZSB7CisJICAgIGZwcmludGYob3V0cHV0LCAiJTEwcyIsICIiKTsKKwl9CisJZnByaW50ZihvdXRwdXQsICIgJTZkIiwgdGVtcGxhdGVzW2ldLT5uYkNhbGxzKTsKKwlmcHJpbnRmKG91dHB1dCwgIiAlNmxkICU2bGRcbiIsIHRlbXBsYXRlc1tpXS0+dGltZSwKKwkJdGVtcGxhdGVzW2ldLT50aW1lIC8gdGVtcGxhdGVzW2ldLT5uYkNhbGxzKTsKKwl0b3RhbCArPSB0ZW1wbGF0ZXNbaV0tPm5iQ2FsbHM7CisJdG90YWx0ICs9IHRlbXBsYXRlc1tpXS0+dGltZTsKKyAgICB9CisgICAgZnByaW50ZihvdXRwdXQsICJcbiUzMHMlMjZzICU2ZCAlNmxkXG4iLCAiVG90YWwiLCAiIiwgdG90YWwsIHRvdGFsdCk7CisKKyAgICB4bWxGcmVlKHRlbXBsYXRlcyk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJRmV0Y2hpbmcgcHJvZmlsaW5nIGluZm9ybWF0aW9ucwkJCQkqCisgKiAJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKioKKyAqIHhzbHRHZXRQcm9maWxlSW5mb3JtYXRpb246CisgKiBAY3R4dDogIGEgdHJhbnNmb3JtYXRpb24gY29udGV4dAorICoKKyAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCBhZnRlciB0aGUgdHJhbnNmb3JtYXRpb24gY29tcGxldGVkCisgKiB0byBleHRyYWN0IHRlbXBsYXRlIHByb2Nlc3NpbmcgcHJvZmlsaW5nIGluZm9ybWF0aW9ucyBpZiBhdmFpbGJsZS4KKyAqIFRoZSBpbmZvcm1hdGlvbnMgYXJlIHJldHVybmVkIGFzIGFuIFhNTCBkb2N1bWVudCB0cmVlIGxpa2UKKyAqIDw/eG1sIHZlcnNpb249IjEuMCI/PgorICogPHByb2ZpbGU+CisgKiA8dGVtcGxhdGUgcmFuaz0iMSIgbWF0Y2g9IioiIG5hbWU9IiIKKyAqICAgICAgICAgbW9kZT0iIiBjYWxscz0iNiIgdGltZT0iNDgiIGF2ZXJhZ2U9IjgiLz4KKyAqIDx0ZW1wbGF0ZSByYW5rPSIyIiBtYXRjaD0iaXRlbTJ8aXRlbTMiIG5hbWU9IiIKKyAqICAgICAgICAgbW9kZT0iIiBjYWxscz0iMTAiIHRpbWU9IjMwIiBhdmVyYWdlPSIzIi8+CisgKiA8dGVtcGxhdGUgcmFuaz0iMyIgbWF0Y2g9Iml0ZW0xIiBuYW1lPSIiCisgKiAgICAgICAgIG1vZGU9IiIgY2FsbHM9IjUiIHRpbWU9IjE3IiBhdmVyYWdlPSIzIi8+CisgKiA8L3Byb2ZpbGU+CisgKiBUaGUgY2FsbGVyIHdpbGwgbmVlZCB0byBmcmVlIHVwIHRoZSByZXR1cm5lZCB0cmVlIHdpdGggeG1sRnJlZURvYygpCisgKgorICogUmV0dXJucyB0aGUgeG1sRG9jUHRyIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHJlc3VsdCBvciBOVUxMIGlmIG5vdCBhdmFpbGFibGUuCisgKi8KKworeG1sRG9jUHRyCit4c2x0R2V0UHJvZmlsZUluZm9ybWF0aW9uKHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpCit7CisgICAgeG1sRG9jUHRyIHJldCA9IE5VTEw7CisgICAgeG1sTm9kZVB0ciByb290LCBjaGlsZDsKKyAgICBjaGFyIGJ1ZlsxMDBdOworCisgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGU7CisgICAgeHNsdFRlbXBsYXRlUHRyICp0ZW1wbGF0ZXM7CisgICAgeHNsdFRlbXBsYXRlUHRyIHRlbXBsOworICAgIGludCBuYiA9IDAsIG1heCA9IDAsIGksIGo7CisKKyAgICBpZiAoIWN0eHQpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKCFjdHh0LT5wcm9maWxlKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIG5iID0gMDsKKyAgICBtYXggPSAxMDAwMDsKKyAgICB0ZW1wbGF0ZXMgPQorICAgICAgICAoeHNsdFRlbXBsYXRlUHRyICopIHhtbE1hbGxvYyhtYXggKiBzaXplb2YoeHNsdFRlbXBsYXRlUHRyKSk7CisgICAgaWYgKHRlbXBsYXRlcyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qCisgICAgICogY29sbGVjdCBhbGwgdGhlIHRlbXBsYXRlcyBpbiBhbiBhcnJheQorICAgICAqLworICAgIHN0eWxlID0gY3R4dC0+c3R5bGU7CisgICAgd2hpbGUgKHN0eWxlICE9IE5VTEwpIHsKKyAgICAgICAgdGVtcGwgPSBzdHlsZS0+dGVtcGxhdGVzOworICAgICAgICB3aGlsZSAodGVtcGwgIT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKG5iID49IG1heCkKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgaWYgKHRlbXBsLT5uYkNhbGxzID4gMCkKKyAgICAgICAgICAgICAgICB0ZW1wbGF0ZXNbbmIrK10gPSB0ZW1wbDsKKyAgICAgICAgICAgIHRlbXBsID0gdGVtcGwtPm5leHQ7CisgICAgICAgIH0KKworICAgICAgICBzdHlsZSA9ICh4c2x0U3R5bGVzaGVldFB0cikgeHNsdE5leHRJbXBvcnQoc3R5bGUpOworICAgIH0KKworICAgIC8qCisgICAgICogU29ydCB0aGUgYXJyYXkgYnkgdGltZSBzcGVudAorICAgICAqLworICAgIGZvciAoaSA9IDA7IGkgPCBuYiAtIDE7IGkrKykgeworICAgICAgICBmb3IgKGogPSBpICsgMTsgaiA8IG5iOyBqKyspIHsKKyAgICAgICAgICAgIGlmICgodGVtcGxhdGVzW2ldLT50aW1lIDw9IHRlbXBsYXRlc1tqXS0+dGltZSkgfHwKKyAgICAgICAgICAgICAgICAoKHRlbXBsYXRlc1tpXS0+dGltZSA9PSB0ZW1wbGF0ZXNbal0tPnRpbWUpICYmCisgICAgICAgICAgICAgICAgICh0ZW1wbGF0ZXNbaV0tPm5iQ2FsbHMgPD0gdGVtcGxhdGVzW2pdLT5uYkNhbGxzKSkpIHsKKyAgICAgICAgICAgICAgICB0ZW1wbCA9IHRlbXBsYXRlc1tqXTsKKyAgICAgICAgICAgICAgICB0ZW1wbGF0ZXNbal0gPSB0ZW1wbGF0ZXNbaV07CisgICAgICAgICAgICAgICAgdGVtcGxhdGVzW2ldID0gdGVtcGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKgorICAgICAqIEdlbmVyYXRlIGEgZG9jdW1lbnQgY29ycmVzcG9uZGluZyB0byB0aGUgcmVzdWx0cy4KKyAgICAgKi8KKyAgICByZXQgPSB4bWxOZXdEb2MoQkFEX0NBU1QgIjEuMCIpOworICAgIHJvb3QgPSB4bWxOZXdEb2NOb2RlKHJldCwgTlVMTCwgQkFEX0NBU1QgInByb2ZpbGUiLCBOVUxMKTsKKyAgICB4bWxEb2NTZXRSb290RWxlbWVudChyZXQsIHJvb3QpOworCisgICAgZm9yIChpID0gMDsgaSA8IG5iOyBpKyspIHsKKyAgICAgICAgY2hpbGQgPSB4bWxOZXdDaGlsZChyb290LCBOVUxMLCBCQURfQ0FTVCAidGVtcGxhdGUiLCBOVUxMKTsKKyAgICAgICAgc3ByaW50ZihidWYsICIlZCIsIGkgKyAxKTsKKyAgICAgICAgeG1sU2V0UHJvcChjaGlsZCwgQkFEX0NBU1QgInJhbmsiLCBCQURfQ0FTVCBidWYpOworICAgICAgICB4bWxTZXRQcm9wKGNoaWxkLCBCQURfQ0FTVCAibWF0Y2giLCBCQURfQ0FTVCB0ZW1wbGF0ZXNbaV0tPm1hdGNoKTsKKyAgICAgICAgeG1sU2V0UHJvcChjaGlsZCwgQkFEX0NBU1QgIm5hbWUiLCBCQURfQ0FTVCB0ZW1wbGF0ZXNbaV0tPm5hbWUpOworICAgICAgICB4bWxTZXRQcm9wKGNoaWxkLCBCQURfQ0FTVCAibW9kZSIsIEJBRF9DQVNUIHRlbXBsYXRlc1tpXS0+bW9kZSk7CisKKyAgICAgICAgc3ByaW50ZihidWYsICIlZCIsIHRlbXBsYXRlc1tpXS0+bmJDYWxscyk7CisgICAgICAgIHhtbFNldFByb3AoY2hpbGQsIEJBRF9DQVNUICJjYWxscyIsIEJBRF9DQVNUIGJ1Zik7CisKKyAgICAgICAgc3ByaW50ZihidWYsICIlbGQiLCB0ZW1wbGF0ZXNbaV0tPnRpbWUpOworICAgICAgICB4bWxTZXRQcm9wKGNoaWxkLCBCQURfQ0FTVCAidGltZSIsIEJBRF9DQVNUIGJ1Zik7CisKKyAgICAgICAgc3ByaW50ZihidWYsICIlbGQiLCB0ZW1wbGF0ZXNbaV0tPnRpbWUgLyB0ZW1wbGF0ZXNbaV0tPm5iQ2FsbHMpOworICAgICAgICB4bWxTZXRQcm9wKGNoaWxkLCBCQURfQ0FTVCAiYXZlcmFnZSIsIEJBRF9DQVNUIGJ1Zik7CisgICAgfTsKKworICAgIHhtbEZyZWUodGVtcGxhdGVzKTsKKworICAgIHJldHVybiByZXQ7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIAkJCQkJCQkJCSoKKyAqIAkJSG9va3MgZm9yIGxpYnhtbDIgWFBhdGgJCQkJCSoKKyAqIAkJCQkJCQkJCSoKKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qKgorICogeHNsdFhQYXRoQ29tcGlsZToKKyAqIEBzdHlsZTogdGhlIHN0eWxlc2hlZXQKKyAqIEBzdHI6ICB0aGUgWFBhdGggZXhwcmVzc2lvbgorICoKKyAqIENvbXBpbGUgYW4gWFBhdGggZXhwcmVzc2lvbgorICoKKyAqIFJldHVybnMgdGhlIHhtbFhQYXRoQ29tcEV4cHJQdHIgcmVzdWx0aW5nIGZyb20gdGhlIGNvbXBpbGF0aW9uIG9yIE5VTEwuCisgKiAgICAgICAgIHRoZSBjYWxsZXIgaGFzIHRvIGZyZWUgdGhlIG9iamVjdC4KKyAqLworeG1sWFBhdGhDb21wRXhwclB0cgoreHNsdFhQYXRoQ29tcGlsZSh4c2x0U3R5bGVzaGVldFB0ciBzdHlsZSwgY29uc3QgeG1sQ2hhciAqc3RyKSB7CisgICAgeG1sWFBhdGhDb250ZXh0UHRyIHhwYXRoQ3R4dDsKKyAgICB4bWxYUGF0aENvbXBFeHByUHRyIHJldDsKKworICAgIGlmIChzdHlsZSAhPSBOVUxMKSB7CisjaWZkZWYgWFNMVF9SRUZBQ1RPUkVEX1hQQVRIQ09NUAorCWlmIChYU0xUX0NDVFhUKHN0eWxlKSkgeworCSAgICAvKgorCSAgICAqIFByb3Bvc2VkIGJ5IEplcm9tZSBQZXNlbnRpCisJICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwkgICAgKiBGb3IgYmV0dGVyIGVmZmljaWVuY3kgd2UnbGwgcmV1c2UgdGhlIGNvbXBpbGF0aW9uCisJICAgICogY29udGV4dCdzIFhQYXRoIGNvbnRleHQuIEZvciB0aGUgY29tbW9uIHN0eWxlc2hlZXQgdXNpbmcKKwkgICAgKiBYUGF0aCBleHByZXNzaW9ucyB0aGlzIHdpbGwgcmVkdWNlIGNvbXBpbGF0aW9uIHRpbWUgdG8KKwkgICAgKiBhYm91dCA1MCUuCisJICAgICoKKwkgICAgKiBTZWUgaHR0cDovL21haWwuZ25vbWUub3JnL2FyY2hpdmVzL3hzbHQvMjAwNi1BcHJpbC9tc2cwMDAzNy5odG1sCisJICAgICovCisJICAgIHhwYXRoQ3R4dCA9IFhTTFRfQ0NUWFQoc3R5bGUpLT54cGF0aEN0eHQ7CisJICAgIHhwYXRoQ3R4dC0+ZG9jID0gc3R5bGUtPmRvYzsKKwl9IGVsc2UKKwkgICAgeHBhdGhDdHh0ID0geG1sWFBhdGhOZXdDb250ZXh0KHN0eWxlLT5kb2MpOworI2Vsc2UKKwl4cGF0aEN0eHQgPSB4bWxYUGF0aE5ld0NvbnRleHQoc3R5bGUtPmRvYyk7CisjZW5kaWYKKwlpZiAoeHBhdGhDdHh0ID09IE5VTEwpCisJICAgIHJldHVybiBOVUxMOworCXhwYXRoQ3R4dC0+ZGljdCA9IHN0eWxlLT5kaWN0OworICAgIH0gZWxzZSB7CisJeHBhdGhDdHh0ID0geG1sWFBhdGhOZXdDb250ZXh0KE5VTEwpOworCWlmICh4cGF0aEN0eHQgPT0gTlVMTCkKKwkgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIC8qCisgICAgKiBDb21waWxlIHRoZSBleHByZXNzaW9uLgorICAgICovCisgICAgcmV0ID0geG1sWFBhdGhDdHh0Q29tcGlsZSh4cGF0aEN0eHQsIHN0cik7CisKKyNpZmRlZiBYU0xUX1JFRkFDVE9SRURfWFBBVEhDT01QCisgICAgaWYgKChzdHlsZSA9PSBOVUxMKSB8fCAoISBYU0xUX0NDVFhUKHN0eWxlKSkpIHsKKwl4bWxYUGF0aEZyZWVDb250ZXh0KHhwYXRoQ3R4dCk7CisgICAgfQorI2Vsc2UKKyAgICB4bWxYUGF0aEZyZWVDb250ZXh0KHhwYXRoQ3R4dCk7CisjZW5kaWYKKyAgICAvKgorICAgICAqIFRPRE86IHRoZXJlIGlzIGEgbG90IG9mIG9wdGltaXphdGlvbnMgd2hpY2ggc2hvdWxkIGJlIHBvc3NpYmxlCisgICAgICogICAgICAgbGlrZSB2YXJpYWJsZSBzbG90IHByZWNvbXB1dGF0aW9ucywgZnVuY3Rpb24gcHJlY29tcHV0YXRpb25zLCBldGMuCisgICAgICovCisKKyAgICByZXR1cm4ocmV0KTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogCQkJCQkJCQkJKgorICogCQlIb29rcyBmb3IgdGhlIGRlYnVnZ2VyCQkJCQkqCisgKiAJCQkJCQkJCQkqCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKgorICogVGhlcmUgaXMgY3VycmVudGx5IG9ubHkgMyBkZWJ1Z2dpbmcgY2FsbGJhY2sgZGVmaW5lZAorICogRGVidWdnZXIgY2FsbGJhY2tzIGFyZSBkaXNhYmxlZCBieSBkZWZhdWx0CisgKi8KKyNkZWZpbmUgWFNMVF9DQUxMQkFDS19OVU1CRVIgMworCit0eXBlZGVmIHN0cnVjdCBfeHNsdERlYnVnZ2VyQ2FsbGJhY2tzIHhzbHREZWJ1Z2dlckNhbGxiYWNrczsKK3R5cGVkZWYgeHNsdERlYnVnZ2VyQ2FsbGJhY2tzICp4c2x0RGVidWdnZXJDYWxsYmFja3NQdHI7CitzdHJ1Y3QgX3hzbHREZWJ1Z2dlckNhbGxiYWNrcyB7CisgICAgeHNsdEhhbmRsZURlYnVnZ2VyQ2FsbGJhY2sgaGFuZGxlcjsKKyAgICB4c2x0QWRkQ2FsbENhbGxiYWNrIGFkZDsKKyAgICB4c2x0RHJvcENhbGxDYWxsYmFjayBkcm9wOworfTsKKworc3RhdGljIHhzbHREZWJ1Z2dlckNhbGxiYWNrcyB4c2x0RGVidWdnZXJDdXJyZW50Q2FsbGJhY2tzID0geworICAgIE5VTEwsIC8qIGhhbmRsZXIgKi8KKyAgICBOVUxMLCAvKiBhZGQgKi8KKyAgICBOVUxMICAvKiBkcm9wICovCit9OworCitpbnQgeHNsRGVidWdTdGF0dXM7CisKKy8qKgorICogeHNsdFNldERlYnVnZ2VyU3RhdHVzOgorICogQHZhbHVlIDogdGhlIHZhbHVlIHRvIGJlIHNldAorICogCisgKiBUaGlzIGZ1bmN0aW9uIHNldHMgdGhlIHZhbHVlIG9mIHhzbERlYnVnU3RhdHVzLgorICovCit2b2lkCit4c2x0U2V0RGVidWdnZXJTdGF0dXMoaW50IHZhbHVlKQoreworICAgIHhzbERlYnVnU3RhdHVzID0gdmFsdWU7CQorfQorCisvKioKKyAqIHhzbHRHZXREZWJ1Z2dlclN0YXR1czogCisgKiAKKyAqIEdldCB4c2xEZWJ1Z1N0YXR1cy4KKyAqCisgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB4c2xEZWJ1Z1N0YXR1cy4KKyAqLworaW50Cit4c2x0R2V0RGVidWdnZXJTdGF0dXModm9pZCkKK3sKKyAgICByZXR1cm4oeHNsRGVidWdTdGF0dXMpOwkKK30KKworLyoqCisgKiB4c2x0U2V0RGVidWdnZXJDYWxsYmFja3M6CisgKiBAbm8gOiBudW1iZXIgb2YgY2FsbGJhY2tzCisgKiBAYmxvY2sgOiB0aGUgYmxvY2sgb2YgY2FsbGJhY2tzCisgKiAKKyAqIFRoaXMgZnVuY3Rpb24gYWxsb3cgdG8gcGx1ZyBhIGRlYnVnZ2VyIGludG8gdGhlIFhTTFQgbGlicmFyeQorICogQGJsb2NrIHBvaW50cyB0byBhIGJsb2NrIG9mIG1lbW9yeSBjb250YWluaW5nIHRoZSBhZGRyZXNzIG9mIEBubyAKKyAqIGNhbGxiYWNrIHJvdXRpbmVzLgorICoKKyAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MgYW5kIC0xIGluIGNhc2Ugb2YgZXJyb3IKKyAqLworaW50Cit4c2x0U2V0RGVidWdnZXJDYWxsYmFja3MoaW50IG5vLCB2b2lkICpibG9jaykKK3sKKyAgICB4c2x0RGVidWdnZXJDYWxsYmFja3NQdHIgY2FsbGJhY2tzOworCisgICAgaWYgKChibG9jayA9PSBOVUxMKSB8fCAobm8gIT0gWFNMVF9DQUxMQkFDS19OVU1CRVIpKQorCXJldHVybigtMSk7CisKKyAgICBjYWxsYmFja3MgPSAoeHNsdERlYnVnZ2VyQ2FsbGJhY2tzUHRyKSBibG9jazsKKyAgICB4c2x0RGVidWdnZXJDdXJyZW50Q2FsbGJhY2tzLmhhbmRsZXIgPSBjYWxsYmFja3MtPmhhbmRsZXI7CisgICAgeHNsdERlYnVnZ2VyQ3VycmVudENhbGxiYWNrcy5hZGQgID0gY2FsbGJhY2tzLT5hZGQ7CisgICAgeHNsdERlYnVnZ2VyQ3VycmVudENhbGxiYWNrcy5kcm9wICA9IGNhbGxiYWNrcy0+ZHJvcDsKKyAgICByZXR1cm4oMCk7Cit9CisKKy8qKgorICogeHNsSGFuZGxlRGVidWdnZXI6CisgKiBAY3VyIDogc291cmNlIG5vZGUgYmVpbmcgZXhlY3V0ZWQKKyAqIEBub2RlIDogZGF0YSBub2RlIGJlaW5nIHByb2Nlc3NlZAorICogQHRlbXBsIDogdGVtbGF0ZSB0aGF0IGFwcGxpZXMgdG8gbm9kZQorICogQGN0eHQgOiB0aGUgeHNsdCB0cmFuc2Zvcm0gY29udGV4dCAKKyAqIAorICogSWYgZWl0aGVyIGN1ciBvciBub2RlIGFyZSBhIGJyZWFrcG9pbnQsIG9yIHhzbERlYnVnU3RhdHVzIGluIHN0YXRlIAorICogICB3aGVyZSBkZWJ1Z2dpbmcgbXVzdCBvY2NjdXIgYXQgdGhpcyB0aW1lIHRoZW4gdHJhbnNmZXIgY29udHJvbAorICogICB0byB0aGUgeHNsRGVidWdCcmVhayBmdW5jdGlvbgorICovCit2b2lkCit4c2xIYW5kbGVEZWJ1Z2dlcih4bWxOb2RlUHRyIGN1ciwgeG1sTm9kZVB0ciBub2RlLCB4c2x0VGVtcGxhdGVQdHIgdGVtcGwsCisJICAgICAgICAgIHhzbHRUcmFuc2Zvcm1Db250ZXh0UHRyIGN0eHQpCit7CisgICAgaWYgKHhzbHREZWJ1Z2dlckN1cnJlbnRDYWxsYmFja3MuaGFuZGxlciAhPSBOVUxMKQorCXhzbHREZWJ1Z2dlckN1cnJlbnRDYWxsYmFja3MuaGFuZGxlcihjdXIsIG5vZGUsIHRlbXBsLCBjdHh0KTsKK30KKworLyoqCisgKiB4c2xBZGRDYWxsOgorICogQHRlbXBsIDogY3VycmVudCB0ZW1wbGF0ZSBiZWluZyBhcHBsaWVkCisgKiBAc291cmNlIDogdGhlIHNvdXJjZSBub2RlIGJlaW5nIHByb2Nlc3NlZAorICoKKyAqIEFkZCB0ZW1wbGF0ZSAiY2FsbCIgdG8gY2FsbCBzdGFjaworICogUmV0dXJucyA6IDEgb24gc3VjZXNzIDAgb3RoZXJ3aXNlIGFuIGVycm9yIG1heSBiZSBwcmludGVkIGlmIAorICogICAgICAgICAgICBXSVRIX1hTTFRfREVCVUdfQlJFQUtQT0lOVFMgaXMgZGVmaW5lZAorICovCitpbnQKK3hzbEFkZENhbGwoeHNsdFRlbXBsYXRlUHRyIHRlbXBsLCB4bWxOb2RlUHRyIHNvdXJjZSkKK3sKKyAgICBpZiAoeHNsdERlYnVnZ2VyQ3VycmVudENhbGxiYWNrcy5hZGQgIT0gTlVMTCkKKwlyZXR1cm4oeHNsdERlYnVnZ2VyQ3VycmVudENhbGxiYWNrcy5hZGQodGVtcGwsIHNvdXJjZSkpOworICAgIHJldHVybigwKTsKK30KKworLyoqCisgKiB4c2xEcm9wQ2FsbDoKKyAqCisgKiBEcm9wIHRoZSB0b3Btb3N0IGl0ZW0gb2ZmIHRoZSBjYWxsIHN0YWNrCisgKi8KK3ZvaWQKK3hzbERyb3BDYWxsKHZvaWQpCit7CisgICAgaWYgKHhzbHREZWJ1Z2dlckN1cnJlbnRDYWxsYmFja3MuZHJvcCAhPSBOVUxMKQorCXhzbHREZWJ1Z2dlckN1cnJlbnRDYWxsYmFja3MuZHJvcCgpOworfQorCmRpZmYgLS1naXQgYS9saWJ4c2x0L3hzbHR1dGlscy5oIGIvbGlieHNsdC94c2x0dXRpbHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zODg2YmUzCi0tLSAvZGV2L251bGwKKysrIGIvbGlieHNsdC94c2x0dXRpbHMuaApAQCAtMCwwICsxLDMwOSBAQAorLyoKKyAqIFN1bW1hcnk6IHNldCBvZiB1dGlsaXRpZXMgZm9yIHRoZSBYU0xUIGVuZ2luZQorICogRGVzY3JpcHRpb246IGludGVyZmFjZXMgZm9yIHRoZSB1dGlsaXRpZXMgbW9kdWxlIG9mIHRoZSBYU0xUIGVuZ2luZS4KKyAqICAgICAgICAgICAgICB0aGluZ3MgbGlrZSBtZXNzYWdlIGhhbmRsaW5nLCBwcm9maWxpbmcsIGFuZCBvdGhlcgorICogICAgICAgICAgICAgIGdlbmVyYWxseSB1c2VmdWwgcm91dGluZXMuCisgKgorICogQ29weTogU2VlIENvcHlyaWdodCBmb3IgdGhlIHN0YXR1cyBvZiB0aGlzIHNvZnR3YXJlLgorICoKKyAqIEF1dGhvcjogRGFuaWVsIFZlaWxsYXJkCisgKi8KKworI2lmbmRlZiBfX1hNTF9YU0xUVVRJTFNfSF9fCisjZGVmaW5lIF9fWE1MX1hTTFRVVElMU19IX18KKworI2luY2x1ZGUgPGxpYnhzbHQveHNsdGNvbmZpZy5oPgorI2lmZGVmIEhBVkVfU1REQVJHX0gKKyNpbmNsdWRlIDxzdGRhcmcuaD4KKyNlbmRpZgorI2luY2x1ZGUgPGxpYnhtbC94cGF0aC5oPgorI2luY2x1ZGUgPGxpYnhtbC9kaWN0Lmg+CisjaW5jbHVkZSA8bGlieG1sL3htbGVycm9yLmg+CisjaW5jbHVkZSAieHNsdGV4cG9ydHMuaCIKKyNpbmNsdWRlICJ4c2x0SW50ZXJuYWxzLmgiCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLyoqCisgKiBYU0xUX1RPRE86CisgKgorICogTWFjcm8gdG8gZmxhZyB1bmltcGxlbWVudGVkIGJsb2Nrcy4KKyAqLworI2RlZmluZSBYU0xUX1RPRE8gCQkJCQkJCVwKKyAgICB4c2x0R2VuZXJpY0Vycm9yKHhzbHRHZW5lcmljRXJyb3JDb250ZXh0LAkJCQlcCisJICAgICJVbmltcGxlbWVudGVkIGJsb2NrIGF0ICVzOiVkXG4iLAkJCQlcCisgICAgICAgICAgICBfX0ZJTEVfXywgX19MSU5FX18pOworCisvKioKKyAqIFhTTFRfU1RSQU5HRToKKyAqCisgKiBNYWNybyB0byBmbGFnIHRoYXQgYSBwcm9ibGVtIHdhcyBkZXRlY3RlZCBpbnRlcm5hbGx5LgorICovCisjZGVmaW5lIFhTTFRfU1RSQU5HRSAJCQkJCQkJXAorICAgIHhzbHRHZW5lcmljRXJyb3IoeHNsdEdlbmVyaWNFcnJvckNvbnRleHQsCQkJCVwKKwkgICAgIkludGVybmFsIGVycm9yIGF0ICVzOiVkXG4iLAkJCQlcCisgICAgICAgICAgICBfX0ZJTEVfXywgX19MSU5FX18pOworCisvKioKKyAqIElTX1hTTFRfRUxFTToKKyAqCisgKiBDaGVja3MgdGhhdCB0aGUgZWxlbWVudCBwZXJ0YWlucyB0byBYU0xUIG5hbWVzcGFjZS4KKyAqLworI2RlZmluZSBJU19YU0xUX0VMRU0obikJCQkJCQkJXAorICAgICgoKG4pICE9IE5VTEwpICYmICgobiktPm5zICE9IE5VTEwpICYmCQkJCVwKKyAgICAgKHhtbFN0ckVxdWFsKChuKS0+bnMtPmhyZWYsIFhTTFRfTkFNRVNQQUNFKSkpCisKKy8qKgorICogSVNfWFNMVF9OQU1FOgorICoKKyAqIENoZWNrcyB0aGUgdmFsdWUgb2YgYW4gZWxlbWVudCBpbiBYU0xUIG5hbWVzcGFjZS4KKyAqLworI2RlZmluZSBJU19YU0xUX05BTUUobiwgdmFsKQkJCQkJCVwKKyAgICAoeG1sU3RyRXF1YWwoKG4pLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSAodmFsKSkpCisKKy8qKgorICogSVNfWFNMVF9SRUFMX05PREU6CisgKgorICogQ2hlY2sgdGhhdCBhIG5vZGUgaXMgYSAncmVhbCcgb25lOiBkb2N1bWVudCwgZWxlbWVudCwgdGV4dCBvciBhdHRyaWJ1dGUuCisgKi8KKyNkZWZpbmUgSVNfWFNMVF9SRUFMX05PREUobikJCQkJCQlcCisgICAgKCgobikgIT0gTlVMTCkgJiYJCQkJCQkJXAorICAgICAoKChuKS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB8fAkJCQlcCisgICAgICAoKG4pLT50eXBlID09IFhNTF9URVhUX05PREUpIHx8CQkJCQlcCisgICAgICAoKG4pLT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpIHx8CQkJCVwKKyAgICAgICgobiktPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB8fAkJCQlcCisgICAgICAoKG4pLT50eXBlID09IFhNTF9ET0NVTUVOVF9OT0RFKSB8fAkJCQlcCisgICAgICAoKG4pLT50eXBlID09IFhNTF9IVE1MX0RPQ1VNRU5UX05PREUpIHx8CQkJCVwKKyAgICAgICgobiktPnR5cGUgPT0gWE1MX0NPTU1FTlRfTk9ERSkgfHwJCQkJXAorICAgICAgKChuKS0+dHlwZSA9PSBYTUxfUElfTk9ERSkpKSAgICAgIAorCisvKgorICogT3VyIG93biB2ZXJzaW9uIG9mIG5hbWVzcGFjZWQgYXRyaWJ1dGVzIGxvb2t1cC4KKyAqLworWFNMVFBVQkZVTiB4bWxDaGFyICogWFNMVENBTEwKKwkJeHNsdEdldE5zUHJvcAkoeG1sTm9kZVB0ciBub2RlLAorCQkJCSBjb25zdCB4bWxDaGFyICpuYW1lLAorCQkJCSBjb25zdCB4bWxDaGFyICpuYW1lU3BhY2UpOworWFNMVFBVQkZVTiBjb25zdCB4bWxDaGFyICogWFNMVENBTEwKKwkJeHNsdEdldENOc1Byb3AJKHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCSB4bWxOb2RlUHRyIG5vZGUsCisJCQkJIGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCQkJIGNvbnN0IHhtbENoYXIgKm5hbWVTcGFjZSk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAorCQl4c2x0R2V0VVRGOENoYXIJKGNvbnN0IHVuc2lnbmVkIGNoYXIgKnV0ZiwKKwkJCQkgaW50ICpsZW4pOworCisvKgorICogWFNMVCBEZWJ1ZyBUcmFjaW5nIFRyYWNpbmcgVHlwZXMKKyAqLwordHlwZWRlZiBlbnVtIHsKKwlYU0xUX1RSQUNFX0FMTCA9CQktMSwKKwlYU0xUX1RSQUNFX05PTkUgPSAJCTAsCisJWFNMVF9UUkFDRV9DT1BZX1RFWFQgPSAJCTE8PDAsCisJWFNMVF9UUkFDRV9QUk9DRVNTX05PREUgPSAJMTw8MSwKKwlYU0xUX1RSQUNFX0FQUExZX1RFTVBMQVRFID0gCTE8PDIsCisJWFNMVF9UUkFDRV9DT1BZID0gCQkxPDwzLAorCVhTTFRfVFJBQ0VfQ09NTUVOVCA9IAkJMTw8NCwKKwlYU0xUX1RSQUNFX1BJID0gCQkxPDw1LAorCVhTTFRfVFJBQ0VfQ09QWV9PRiA9IAkJMTw8NiwKKwlYU0xUX1RSQUNFX1ZBTFVFX09GID0gCQkxPDw3LAorCVhTTFRfVFJBQ0VfQ0FMTF9URU1QTEFURSA9IAkxPDw4LAorCVhTTFRfVFJBQ0VfQVBQTFlfVEVNUExBVEVTID0gCTE8PDksCisJWFNMVF9UUkFDRV9DSE9PU0UgPSAJCTE8PDEwLAorCVhTTFRfVFJBQ0VfSUYgPSAJCTE8PDExLAorCVhTTFRfVFJBQ0VfRk9SX0VBQ0ggPSAJCTE8PDEyLAorCVhTTFRfVFJBQ0VfU1RSSVBfU1BBQ0VTID0gCTE8PDEzLAorCVhTTFRfVFJBQ0VfVEVNUExBVEVTID0gCQkxPDwxNCwKKwlYU0xUX1RSQUNFX0tFWVMgPSAJCTE8PDE1LAorCVhTTFRfVFJBQ0VfVkFSSUFCTEVTID0gCQkxPDwxNgorfSB4c2x0RGVidWdUcmFjZUNvZGVzOworCisvKioKKyAqIFhTTFRfVFJBQ0U6CisgKgorICogQ29udHJvbCB0aGUgdHlwZSBvZiB4c2wgZGVidWd0cmFjZSBtZXNzYWdlcyBlbWl0dGVkLgorICovCisjZGVmaW5lIFhTTFRfVFJBQ0UoY3R4dCxjb2RlLGNhbGwpCVwKKwlpZiAoY3R4dC0+dHJhY2VDb2RlICYmICgqKGN0eHQtPnRyYWNlQ29kZSkgJiBjb2RlKSkgXAorCSAgICBjYWxsCisKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0RGVidWdTZXREZWZhdWx0VHJhY2UoeHNsdERlYnVnVHJhY2VDb2RlcyB2YWwpOworWFNMVFBVQkZVTiB4c2x0RGVidWdUcmFjZUNvZGVzIFhTTFRDQUxMCisJCXhzbHREZWJ1Z0dldERlZmF1bHRUcmFjZSh2b2lkKTsKKworLyoKKyAqIFhTTFQgc3BlY2lmaWMgZXJyb3IgYW5kIGRlYnVnIHJlcG9ydGluZyBmdW5jdGlvbnMuCisgKi8KK1hTTFRQVUJWQVIgeG1sR2VuZXJpY0Vycm9yRnVuYyB4c2x0R2VuZXJpY0Vycm9yOworWFNMVFBVQlZBUiB2b2lkICp4c2x0R2VuZXJpY0Vycm9yQ29udGV4dDsKK1hTTFRQVUJWQVIgeG1sR2VuZXJpY0Vycm9yRnVuYyB4c2x0R2VuZXJpY0RlYnVnOworWFNMVFBVQlZBUiB2b2lkICp4c2x0R2VuZXJpY0RlYnVnQ29udGV4dDsKKworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkKKwkJeHNsdFByaW50RXJyb3JDb250ZXh0CQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkJIHhtbE5vZGVQdHIgbm9kZSk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQorICAgIAkJeHNsdE1lc3NhZ2UJCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4bWxOb2RlUHRyIG5vZGUsCisJCQkJCQkgeG1sTm9kZVB0ciBpbnN0KTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0U2V0R2VuZXJpY0Vycm9yRnVuYwkJKHZvaWQgKmN0eCwKKwkJCQkJCSB4bWxHZW5lcmljRXJyb3JGdW5jIGhhbmRsZXIpOworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkKKyAgICAJCXhzbHRTZXRHZW5lcmljRGVidWdGdW5jCQkodm9pZCAqY3R4LAorCQkJCQkJIHhtbEdlbmVyaWNFcnJvckZ1bmMgaGFuZGxlcik7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQorICAgIAkJeHNsdFNldFRyYW5zZm9ybUVycm9yRnVuYwkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB2b2lkICpjdHgsCisJCQkJCQkgeG1sR2VuZXJpY0Vycm9yRnVuYyBoYW5kbGVyKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0VHJhbnNmb3JtRXJyb3IJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlLAorCQkJCQkJIHhtbE5vZGVQdHIgbm9kZSwKKwkJCQkJCSBjb25zdCBjaGFyICptc2csCisJCQkJCQkgLi4uKTsKKworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwKKwkJeHNsdFNldEN0eHRQYXJzZU9wdGlvbnMJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIGludCBvcHRpb25zKTsKKy8qCisgKiBTb3J0aW5nLgorICovCisKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0RG9jdW1lbnRTb3J0RnVuY3Rpb24JKHhtbE5vZGVTZXRQdHIgbGlzdCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQorICAgIAkJeHNsdFNldFNvcnRGdW5jCQkJKHhzbHRTb3J0RnVuYyBoYW5kbGVyKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0U2V0Q3R4dFNvcnRGdW5jCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSB4c2x0U29ydEZ1bmMgaGFuZGxlcik7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQorICAgIAkJeHNsdERlZmF1bHRTb3J0RnVuY3Rpb24JCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHhtbE5vZGVQdHIgKnNvcnRzLAorCQkJCQkJIGludCBuYnNvcnRzKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0RG9Tb3J0RnVuY3Rpb24JCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHhtbE5vZGVQdHIgKiBzb3J0cywKKwkJCQkJCSBpbnQgbmJzb3J0cyk7CitYU0xUUFVCRlVOIHhtbFhQYXRoT2JqZWN0UHRyICogWFNMVENBTEwgCisgICAgCQl4c2x0Q29tcHV0ZVNvcnRSZXN1bHQJCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0LAorCQkJCQkJIHhtbE5vZGVQdHIgc29ydCk7CisKKy8qCisgKiBRTmFtZXMgaGFuZGxpbmcuCisgKi8KKworWFNMVFBVQkZVTiBjb25zdCB4bWxDaGFyICogWFNMVENBTEwKKwkJeHNsdFNwbGl0UU5hbWUJCQkoeG1sRGljdFB0ciBkaWN0LAorCQkJCQkJIGNvbnN0IHhtbENoYXIgKm5hbWUsCisJCQkJCQkgY29uc3QgeG1sQ2hhciAqKnByZWZpeCk7CitYU0xUUFVCRlVOIGNvbnN0IHhtbENoYXIgKiBYU0xUQ0FMTCAKKyAgICAJCXhzbHRHZXRRTmFtZVVSSQkJCSh4bWxOb2RlUHRyIG5vZGUsCisJCQkJCQkgeG1sQ2hhciAqKm5hbWUpOworCitYU0xUUFVCRlVOIGNvbnN0IHhtbENoYXIgKiBYU0xUQ0FMTAorCQl4c2x0R2V0UU5hbWVVUkkyCQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCQkgeG1sTm9kZVB0ciBub2RlLAorCQkJCQkJIGNvbnN0IHhtbENoYXIgKipuYW1lKTsKKworLyoKKyAqIE91dHB1dCwgcmV1c2UgbGlieG1sIEkvTyBidWZmZXJzLgorICovCitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCisgICAgCQl4c2x0U2F2ZVJlc3VsdFRvCQkoeG1sT3V0cHV0QnVmZmVyUHRyIGJ1ZiwKKwkJCQkJCSB4bWxEb2NQdHIgcmVzdWx0LAorCQkJCQkJIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkKKyAgICAJCXhzbHRTYXZlUmVzdWx0VG9GaWxlbmFtZQkoY29uc3QgY2hhciAqVVJJLAorCQkJCQkJIHhtbERvY1B0ciByZXN1bHQsCisJCQkJCQkgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCQkgaW50IGNvbXByZXNzaW9uKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkKKyAgICAJCXhzbHRTYXZlUmVzdWx0VG9GaWxlCQkoRklMRSAqZmlsZSwKKwkJCQkJCSB4bWxEb2NQdHIgcmVzdWx0LAorCQkJCQkJIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMCQkKKyAgICAJCXhzbHRTYXZlUmVzdWx0VG9GZAkJKGludCBmZCwKKwkJCQkJCSB4bWxEb2NQdHIgcmVzdWx0LAorCQkJCQkJIHhzbHRTdHlsZXNoZWV0UHRyIHN0eWxlKTsKK1hTTFRQVUJGVU4gaW50IFhTTFRDQUxMICAgICAgICAgICAgIAorICAgIAkJeHNsdFNhdmVSZXN1bHRUb1N0cmluZyAgICAgICAgICAoeG1sQ2hhciAqKmRvY190eHRfcHRyLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKiBkb2NfdHh0X2xlbiwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sRG9jUHRyIHJlc3VsdCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUpOworCisvKgorICogWFBhdGggaW50ZXJmYWNlCisgKi8KK1hTTFRQVUJGVU4geG1sWFBhdGhDb21wRXhwclB0ciBYU0xUQ0FMTAorCQl4c2x0WFBhdGhDb21waWxlCQkoeHNsdFN0eWxlc2hlZXRQdHIgc3R5bGUsCisJCQkJCQkgY29uc3QgeG1sQ2hhciAqc3RyKTsKKworLyoKKyAqIFByb2ZpbGluZy4KKyAqLworWFNMVFBVQkZVTiB2b2lkIFhTTFRDQUxMCQkKKyAgICAJCXhzbHRTYXZlUHJvZmlsaW5nCQkoeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCwKKwkJCQkJCSBGSUxFICpvdXRwdXQpOworWFNMVFBVQkZVTiB4bWxEb2NQdHIgWFNMVENBTEwJCisgICAgCQl4c2x0R2V0UHJvZmlsZUluZm9ybWF0aW9uCSh4c2x0VHJhbnNmb3JtQ29udGV4dFB0ciBjdHh0KTsKKworWFNMVFBVQkZVTiBsb25nIFhTTFRDQUxMCQkKKyAgICAJCXhzbHRUaW1lc3RhbXAJCQkodm9pZCk7CitYU0xUUFVCRlVOIHZvaWQgWFNMVENBTEwJCQorICAgIAkJeHNsdENhbGlicmF0ZUFkanVzdAkJKGxvbmcgZGVsdGEpOworCisvKioKKyAqIFhTTFRfVElNRVNUQU1QX1RJQ1NfUEVSX1NFQzoKKyAqCisgKiBTYW1wbGluZyBwcmVjaXNpb24gZm9yIHByb2ZpbGluZworICovCisjZGVmaW5lIFhTTFRfVElNRVNUQU1QX1RJQ1NfUEVSX1NFQyAxMDAwMDBsCisKKy8qCisgKiBIb29rcyBmb3IgdGhlIGRlYnVnZ2VyLgorICovCisKK3R5cGVkZWYgZW51bSB7CisgICAgWFNMVF9ERUJVR19OT05FID0gMCwgLyogbm8gZGVidWdnaW5nIGFsbG93ZWQgKi8KKyAgICBYU0xUX0RFQlVHX0lOSVQsCisgICAgWFNMVF9ERUJVR19TVEVQLAorICAgIFhTTFRfREVCVUdfU1RFUE9VVCwKKyAgICBYU0xUX0RFQlVHX05FWFQsCisgICAgWFNMVF9ERUJVR19TVE9QLAorICAgIFhTTFRfREVCVUdfQ09OVCwKKyAgICBYU0xUX0RFQlVHX1JVTiwKKyAgICBYU0xUX0RFQlVHX1JVTl9SRVNUQVJULAorICAgIFhTTFRfREVCVUdfUVVJVAorfSB4c2x0RGVidWdTdGF0dXNDb2RlczsKKworWFNMVFBVQlZBUiBpbnQgeHNsRGVidWdTdGF0dXM7CisKK3R5cGVkZWYgdm9pZCAoKnhzbHRIYW5kbGVEZWJ1Z2dlckNhbGxiYWNrKSAoeG1sTm9kZVB0ciBjdXIsIHhtbE5vZGVQdHIgbm9kZSwKKwkJCXhzbHRUZW1wbGF0ZVB0ciB0ZW1wbCwgeHNsdFRyYW5zZm9ybUNvbnRleHRQdHIgY3R4dCk7Cit0eXBlZGVmIGludCAoKnhzbHRBZGRDYWxsQ2FsbGJhY2spICh4c2x0VGVtcGxhdGVQdHIgdGVtcGwsIHhtbE5vZGVQdHIgc291cmNlKTsKK3R5cGVkZWYgdm9pZCAoKnhzbHREcm9wQ2FsbENhbGxiYWNrKSAodm9pZCk7CisKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAorCQl4c2x0U2V0RGVidWdnZXJTdGF0dXMJCShpbnQgdmFsdWUpOworWFNMVFBVQkZVTiBpbnQgWFNMVENBTEwKKwkJeHNsdEdldERlYnVnZ2VyU3RhdHVzCQkodm9pZCk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCisJCXhzbHRTZXREZWJ1Z2dlckNhbGxiYWNrcwkoaW50IG5vLCB2b2lkICpibG9jayk7CitYU0xUUFVCRlVOIGludCBYU0xUQ0FMTAkJCisJCXhzbEFkZENhbGwJCQkoeHNsdFRlbXBsYXRlUHRyIHRlbXBsLAorCQkJCQkJIHhtbE5vZGVQdHIgc291cmNlKTsKK1hTTFRQVUJGVU4gdm9pZCBYU0xUQ0FMTAkJCisJCXhzbERyb3BDYWxsCQkJKHZvaWQpOworCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYgLyogX19YTUxfWFNMVFVUSUxTX0hfXyAqLworCisK