LyoKICogc25tcF9hZ2VudC5jCiAqCiAqIFNpbXBsZSBOZXR3b3JrIE1hbmFnZW1lbnQgUHJvdG9jb2wgKFJGQyAxMDY3KS4KICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodHMuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCUNvcHlyaWdodCAxOTg4LCAxOTg5IGJ5IENhcm5lZ2llIE1lbGxvbiBVbml2ZXJzaXR5CgogICAgICAgICAgICAgICAgICAgICAgQWxsIFJpZ2h0cyBSZXNlcnZlZAoKUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzIApkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBhbmQgd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIApwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0CmJvdGggdGhhdCBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiAKc3VwcG9ydGluZyBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBDTVUgbm90IGJlCnVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZQpzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICAKCkNNVSBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwgSU5DTFVESU5HCkFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTyBFVkVOVCBTSEFMTApDTVUgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SCkFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywKV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIgVE9SVElPVVMgQUNUSU9OLApBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTClNPRlRXQVJFLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIAogKiByZXNlcnZlZC4gIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSAKICogQ09QWUlORyBmaWxlIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwovKiogQGRlZmdyb3VwIHNubXBfYWdlbnQgbmV0LXNubXAgYWdlbnQgcmVsYXRlZCBwcm9jZXNzaW5nIAogKiAgQGluZ3JvdXAgYWdlbnQKICoKICogQHsKICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmZGVmIEhBVkVfTElNSVRTX0gKI2luY2x1ZGUgPGxpbWl0cy5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZW5kaWYKI2lmIFRJTUVfV0lUSF9TWVNfVElNRQojIGlmZGVmIFdJTjMyCiMgIGluY2x1ZGUgPHN5cy90aW1lYi5oPgojIGVsc2UKIyAgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBlbmRpZgojIGluY2x1ZGUgPHRpbWUuaD4KI2Vsc2UKIyBpZiBIQVZFX1NZU19USU1FX0gKIyAgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBlbHNlCiMgIGluY2x1ZGUgPHRpbWUuaD4KIyBlbmRpZgojZW5kaWYKI2lmIEhBVkVfU1lTX1NFTEVDVF9ICiNpbmNsdWRlIDxzeXMvc2VsZWN0Lmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpbmNsdWRlIDxlcnJuby5oPgojaWYgSEFWRV9XSU5TT0NLX0gKI2luY2x1ZGUgPHdpbnNvY2suaD4KI2VuZGlmCgojZGVmaW5lIFNOTVBfTkVFRF9SRVFVRVNUX0xJU1QKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2Fzc2VydC5oPgoKI2lmIEhBVkVfU1lTTE9HX0gKI2luY2x1ZGUgPHN5c2xvZy5oPgojZW5kaWYKCiNpZmRlZiBORVRTTk1QX1VTRV9MSUJXUkFQCiNpbmNsdWRlIDx0Y3BkLmg+CmludCAgICAgICAgICAgICBhbGxvd19zZXZlcml0eSA9IExPR19JTkZPOwppbnQgICAgICAgICAgICAgZGVueV9zZXZlcml0eSA9IExPR19XQVJOSU5HOwojZW5kaWYKCiNpbmNsdWRlICJzbm1wZC5oIgojaW5jbHVkZSAibWliZ3JvdXAvc3RydWN0LmgiCiNpbmNsdWRlICJtaWJncm91cC91dGlsX2Z1bmNzLmgiCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9taWJfbW9kdWxlX2NvbmZpZy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbWliX21vZHVsZXMuaD4KCiNpZmRlZiBVU0lOR19BR0VOVFhfUFJPVE9DT0xfTU9EVUxFCiNpbmNsdWRlICJhZ2VudHgvcHJvdG9jb2wuaCIKI2VuZGlmCgojaWZkZWYgVVNJTkdfQUdFTlRYX01BU1RFUl9NT0RVTEUKI2luY2x1ZGUgImFnZW50eC9tYXN0ZXIuaCIKI2VuZGlmCgojaWZkZWYgVVNJTkdfU01VWF9NT0RVTEUKI2luY2x1ZGUgInNtdXgvc211eC5oIgojZW5kaWYKCm9pZCAgICAgIHZlcnNpb25fc3lzb2lkW10gPSB7IE5FVFNOTVBfU1lTVEVNX01JQiB9OwppbnQgICAgICB2ZXJzaW9uX3N5c29pZF9sZW4gPSBPSURfTEVOR1RIKHZlcnNpb25fc3lzb2lkKTsKCiNkZWZpbmUgU05NUF9BRERSQ0FDSEVfU0laRSAxMAojZGVmaW5lIFNOTVBfQUREUkNBQ0hFX01BWEFHRSAzMDAgLyogaW4gc2Vjb25kcyAqLwoKZW51bSB7CiAgICBTTk1QX0FERFJDQUNIRV9VTlVTRUQgPSAwLAogICAgU05NUF9BRERSQ0FDSEVfVVNFRCA9IDEKfTsKCnN0cnVjdCBhZGRyQ2FjaGUgewogICAgY2hhciAgICAgICAgICAgKmFkZHI7CiAgICBpbnQgICAgICAgICAgICBzdGF0dXM7CiAgICBzdHJ1Y3QgdGltZXZhbCBsYXN0SGl0Owp9OwoKc3RhdGljIHN0cnVjdCBhZGRyQ2FjaGUgYWRkckNhY2hlW1NOTVBfQUREUkNBQ0hFX1NJWkVdOwppbnQgICAgICAgICAgICAgbG9nX2FkZHJlc3NlcyA9IDA7CgoKCnR5cGVkZWYgc3RydWN0IF9hZ2VudF9uc2FwIHsKICAgIGludCAgICAgICAgICAgICBoYW5kbGU7CiAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdDsKICAgIHZvaWQgICAgICAgICAgICpzOyAgICAgICAgICAvKiAgT3BhcXVlIGludGVybmFsIHNlc3Npb24gcG9pbnRlci4gICovCiAgICBzdHJ1Y3QgX2FnZW50X25zYXAgKm5leHQ7Cn0gYWdlbnRfbnNhcDsKCnN0YXRpYyBhZ2VudF9uc2FwICphZ2VudF9uc2FwX2xpc3QgPSBOVUxMOwpzdGF0aWMgbmV0c25tcF9hZ2VudF9zZXNzaW9uICphZ2VudF9zZXNzaW9uX2xpc3QgPSBOVUxMOwpuZXRzbm1wX2FnZW50X3Nlc3Npb24gKm5ldHNubXBfcHJvY2Vzc2luZ19zZXQgPSBOVUxMOwpuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFnZW50X2RlbGVnYXRlZF9saXN0ID0gTlVMTDsKbmV0c25tcF9hZ2VudF9zZXNzaW9uICpuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0ID0gTlVMTDsKCgppbnQgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9jaGVja19wYWNrZXQobmV0c25tcF9zZXNzaW9uICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgbmV0c25tcF90cmFuc3BvcnRfcyAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqLCBpbnQpOwppbnQgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9jaGVja19wYXJzZShuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50KTsKdm9pZCAgICAgICAgICAgIGRlbGV0ZV9zdWJuZXRzbm1wX3RyZWVfY2FjaGUobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApOwppbnQgICAgICAgICAgICAgaGFuZGxlX3BkdShuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CmludCAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZV9yZXF1ZXN0KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RhdHVzKTsKaW50ICAgICAgICAgICAgIG5ldHNubXBfd3JhcF91cF9yZXF1ZXN0KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHN0YXR1cyk7CmludCAgICAgICAgICAgICBjaGVja19kZWxheWVkX3JlcXVlc3QobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApOwppbnQgICAgICAgICAgICAgaGFuZGxlX2dldG5leHRfbG9vcChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CmludCAgICAgICAgICAgICBoYW5kbGVfc2V0X2xvb3AobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApOwoKaW50ICAgICAgICAgICAgIG5ldHNubXBfY2hlY2tfcXVldWVkX2NoYWluX2ZvcihuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CmludCAgICAgICAgICAgICBuZXRzbm1wX2FkZF9xdWV1ZWQobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApOwppbnQgICAgICAgICAgICAgbmV0c25tcF9yZW1vdmVfZnJvbV9kZWxlZ2F0ZWQobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApOwoKCnN0YXRpYyBpbnQgICAgICBjdXJyZW50X2dsb2JhbGlkID0gMDsKCmludCAgICAgIG5ldHNubXBfcnVubmluZyA9IDE7CgppbnQKbmV0c25tcF9hbGxvY2F0ZV9nbG9iYWxjYWNoZWlkKHZvaWQpCnsKICAgIHJldHVybiArK2N1cnJlbnRfZ2xvYmFsaWQ7Cn0KCmludApuZXRzbm1wX2dldF9sb2NhbF9jYWNoaWQobmV0c25tcF9jYWNoZW1hcCAqY2FjaGVfc3RvcmUsIGludCBnbG9iYWxpZCkKewogICAgd2hpbGUgKGNhY2hlX3N0b3JlICE9IE5VTEwpIHsKICAgICAgICBpZiAoY2FjaGVfc3RvcmUtPmdsb2JhbGlkID09IGdsb2JhbGlkKQogICAgICAgICAgICByZXR1cm4gY2FjaGVfc3RvcmUtPmNhY2hlaWQ7CiAgICAgICAgY2FjaGVfc3RvcmUgPSBjYWNoZV9zdG9yZS0+bmV4dDsKICAgIH0KICAgIHJldHVybiAtMTsKfQoKbmV0c25tcF9jYWNoZW1hcCAqCm5ldHNubXBfZ2V0X29yX2FkZF9sb2NhbF9jYWNoaWQobmV0c25tcF9jYWNoZW1hcCAqKmNhY2hlX3N0b3JlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBnbG9iYWxpZCwgaW50IGxvY2FsaWQpCnsKICAgIG5ldHNubXBfY2FjaGVtYXAgKnRtcHA7CgogICAgdG1wcCA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9jYWNoZW1hcCk7CiAgICBpZiAoKmNhY2hlX3N0b3JlKSB7CiAgICAgICAgdG1wcC0+bmV4dCA9ICpjYWNoZV9zdG9yZTsKICAgICAgICAqY2FjaGVfc3RvcmUgPSB0bXBwOwogICAgfSBlbHNlIHsKICAgICAgICAqY2FjaGVfc3RvcmUgPSB0bXBwOwogICAgfQoKICAgIHRtcHAtPmdsb2JhbGlkID0gZ2xvYmFsaWQ7CiAgICB0bXBwLT5jYWNoZWlkID0gbG9jYWxpZDsKICAgIHJldHVybiB0bXBwOwp9Cgp2b2lkCm5ldHNubXBfZnJlZV9jYWNoZW1hcChuZXRzbm1wX2NhY2hlbWFwICpjYWNoZV9zdG9yZSkKewogICAgbmV0c25tcF9jYWNoZW1hcCAqdG1wcDsKICAgIHdoaWxlIChjYWNoZV9zdG9yZSkgewogICAgICAgIHRtcHAgPSBjYWNoZV9zdG9yZTsKICAgICAgICBjYWNoZV9zdG9yZSA9IGNhY2hlX3N0b3JlLT5uZXh0OwogICAgICAgIFNOTVBfRlJFRSh0bXBwKTsKICAgIH0KfQoKCnR5cGVkZWYgc3RydWN0IGFnZW50X3NldF9jYWNoZV9zIHsKICAgIC8qCiAgICAgKiBtYXRjaCBvbiB0aGVzZSAyIAogICAgICovCiAgICBpbnQgICAgICAgICAgICAgdHJhbnNJRDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc2VzczsKCiAgICAvKgogICAgICogc3RvcmUgdGhpcyBpbmZvIAogICAgICovCiAgICBuZXRzbm1wX3RyZWVfY2FjaGUgKnRyZWVjYWNoZTsKICAgIGludCAgICAgICAgICAgICB0cmVlY2FjaGVfbGVuOwogICAgaW50ICAgICAgICAgICAgIHRyZWVjYWNoZV9udW07CgogICAgaW50ICAgICAgICAgICAgIHZiY291bnQ7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHM7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnNhdmVkX3ZhcnM7CiAgICBuZXRzbm1wX2RhdGFfbGlzdCAqYWdlbnRfZGF0YTsKCiAgICAvKgogICAgICogbGlzdCAKICAgICAqLwogICAgc3RydWN0IGFnZW50X3NldF9jYWNoZV9zICpuZXh0Owp9IGFnZW50X3NldF9jYWNoZTsKCnN0YXRpYyBhZ2VudF9zZXRfY2FjaGUgKlNldHMgPSBOVUxMOwoKYWdlbnRfc2V0X2NhY2hlICoKc2F2ZV9zZXRfY2FjaGUobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGFnZW50X3NldF9jYWNoZSAqcHRyOwoKICAgIGlmICghYXNwIHx8ICFhc3AtPnJlcWluZm8gfHwgIWFzcC0+cGR1KQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHB0ciA9IFNOTVBfTUFMTE9DX1RZUEVERUYoYWdlbnRfc2V0X2NhY2hlKTsKICAgIGlmIChwdHIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAvKgogICAgICogU2F2ZSB0aGUgaW1wb3J0YW50IGluZm9ybWF0aW9uIAogICAgICovCiAgICBERUJVR01TR1RMKCgidmVyYm9zZTphc3AiLCAiYXNwICVwIHJlcWluZm8gJXAgc2F2ZWQgaW4gY2FjaGUgKG1vZGUgJWQpXG4iLAogICAgICAgICAgICAgICAgYXNwLCBhc3AtPnJlcWluZm8sIGFzcC0+cGR1LT5jb21tYW5kKSk7CiAgICBwdHItPnRyYW5zSUQgPSBhc3AtPnBkdS0+dHJhbnNpZDsKICAgIHB0ci0+c2VzcyA9IGFzcC0+c2Vzc2lvbjsKICAgIHB0ci0+dHJlZWNhY2hlID0gYXNwLT50cmVlY2FjaGU7CiAgICBwdHItPnRyZWVjYWNoZV9sZW4gPSBhc3AtPnRyZWVjYWNoZV9sZW47CiAgICBwdHItPnRyZWVjYWNoZV9udW0gPSBhc3AtPnRyZWVjYWNoZV9udW07CiAgICBwdHItPmFnZW50X2RhdGEgPSBhc3AtPnJlcWluZm8tPmFnZW50X2RhdGE7CiAgICBwdHItPnJlcXVlc3RzID0gYXNwLT5yZXF1ZXN0czsKICAgIHB0ci0+c2F2ZWRfdmFycyA9IGFzcC0+cGR1LT52YXJpYWJsZXM7IC8qIHJlcXVlc3RzIGNvbnRhaW5zIHBvaW50ZXJzIHRvIHZhcmlhYmxlcyAqLwogICAgcHRyLT52YmNvdW50ID0gYXNwLT52YmNvdW50OwoKICAgIC8qCiAgICAgKiBtYWtlIHRoZSBhZ2VudCBmb3JnZXQgYWJvdXQgd2hhdCB3ZSd2ZSBzYXZlZCAKICAgICAqLwogICAgYXNwLT50cmVlY2FjaGUgPSBOVUxMOwogICAgYXNwLT5yZXFpbmZvLT5hZ2VudF9kYXRhID0gTlVMTDsKICAgIGFzcC0+cGR1LT52YXJpYWJsZXMgPSBOVUxMOwogICAgYXNwLT5yZXF1ZXN0cyA9IE5VTEw7CgogICAgcHRyLT5uZXh0ID0gU2V0czsKICAgIFNldHMgPSBwdHI7CgogICAgcmV0dXJuIHB0cjsKfQoKaW50CmdldF9zZXRfY2FjaGUobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGFnZW50X3NldF9jYWNoZSAqcHRyLCAqcHJldiA9IE5VTEw7CgogICAgZm9yIChwdHIgPSBTZXRzOyBwdHIgIT0gTlVMTDsgcHRyID0gcHRyLT5uZXh0KSB7CiAgICAgICAgaWYgKHB0ci0+c2VzcyA9PSBhc3AtPnNlc3Npb24gJiYgcHRyLT50cmFuc0lEID09IGFzcC0+cGR1LT50cmFuc2lkKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHJlbW92ZSB0aGlzIGl0ZW0gZnJvbSBsaXN0CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocHJldikKICAgICAgICAgICAgICAgIHByZXYtPm5leHQgPSBwdHItPm5leHQ7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIFNldHMgPSBwdHItPm5leHQ7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBmb3VuZCBpdC4gIEdldCB0aGUgbmVlZGVkIGRhdGEgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBhc3AtPnRyZWVjYWNoZSA9IHB0ci0+dHJlZWNhY2hlOwogICAgICAgICAgICBhc3AtPnRyZWVjYWNoZV9sZW4gPSBwdHItPnRyZWVjYWNoZV9sZW47CiAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlX251bSA9IHB0ci0+dHJlZWNhY2hlX251bTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEZyZWUgcHJldmlvdXNseSBhbGxvY2F0ZWQgcmVxdWVzdHMgYmVmb3JlIG92ZXJ3cml0aW5nIGJ5CiAgICAgICAgICAgICAqIGNhY2hlZCBvbmVzLCBvdGhlcndpc2UgbWVtb3J5IGxlYWtzIQogICAgICAgICAgICAgKi8KCSAgICBpZiAoYXNwLT5yZXF1ZXN0cykgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIEkgZG9uJ3QgdGhpbmsgdGhpcyBjYXNlIHNob3VsZCBldmVyIGhhcHBlbi4gUGxlYXNlIGVtYWlsCiAgICAgICAgICAgICAgICAgKiB0aGUgbmV0LXNubXAtY29kZXJzQGxpc3RzLnNvdXJjZWZvcmdlLm5ldCBpZiB5b3UgaGF2ZQogICAgICAgICAgICAgICAgICogYSB0ZXN0IGNhc2UgdGhhdCBoaXRzIHRoaXMgYXNzZXJ0LiAtLSByc3RvcnkKICAgICAgICAgICAgICAgICAqLwoJCWludCBpOwogICAgICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQoTlVMTCA9PSBhc3AtPnJlcXVlc3RzKTsgLyogc2VlIG5vdGUgYWJvdmUgKi8KCQlmb3IgKGkgPSAwOyBpIDwgYXNwLT52YmNvdW50OyBpKyspIHsKCQkgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKCZhc3AtPnJlcXVlc3RzW2ldKTsKCQl9CgkJZnJlZShhc3AtPnJlcXVlc3RzKTsKCSAgICB9CgkgICAgLyoKCSAgICAgKiBJZiB3ZSByZXBsYWNlIGFzcC0+cmVxdWVzdHMgd2l0aCB0aGUgaW5mbyBmcm9tIHRoZSBzZXQgY2FjaGUsCgkgICAgICogd2Ugc2hvdWxkIHJlcGxhY2UgYXNwLT5wZHUtPnZhcmlhYmxlcyBhbHNvIHdpdGggdGhlIGNhY2hlZAoJICAgICAqIGluZm8sIGFzIGFzcC0+cmVxdWVzdHMgY29udGFpbnMgcG9pbnRlcnMgdG8gdGhlbS4gIEFuZCB3ZQoJICAgICAqIHNob3VsZCBhbHNvIGZyZWUgdGhlIGN1cnJlbnQgYXNwLT5wZHUtPnZhcmlhYmxlcyBsaXN0Li4uCgkgICAgICovCgkgICAgaWYgKHB0ci0+c2F2ZWRfdmFycykgewoJCWlmIChhc3AtPnBkdS0+dmFyaWFibGVzKQoJCSAgICBzbm1wX2ZyZWVfdmFyYmluZChhc3AtPnBkdS0+dmFyaWFibGVzKTsKCQlhc3AtPnBkdS0+dmFyaWFibGVzID0gcHRyLT5zYXZlZF92YXJzOwogICAgICAgICAgICAgICAgYXNwLT52YmNvdW50ID0gcHRyLT52YmNvdW50OwoJICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogd2hlbiB3b3VsZCB3ZSBub3QgaGF2ZSBzYXZlZCB2YXJpYWJsZXM/IHNvbWVvbmUKICAgICAgICAgICAgICAgICAqIGxldCBtZSBrbm93IGlmIHRoZXkgaGl0IHRoaXMgYXNzZXJ0LiAtLSByc3RvcnkKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQoTlVMTCAhPSBwdHItPnNhdmVkX3ZhcnMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFzcC0+cmVxdWVzdHMgPSBwdHItPnJlcXVlc3RzOwoKICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQoTlVMTCAhPSBhc3AtPnJlcWluZm8pOwogICAgICAgICAgICBhc3AtPnJlcWluZm8tPmFzcCA9IGFzcDsKICAgICAgICAgICAgYXNwLT5yZXFpbmZvLT5hZ2VudF9kYXRhID0gcHRyLT5hZ2VudF9kYXRhOwogICAgICAgICAgICAKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdXBkYXRlIHJlcXVlc3QgcmVxaW5mbywgaWYgaXQncyBvdXQgb2YgZGF0ZS4KICAgICAgICAgICAgICogeXl5LXJrczogaW52ZXN0aWdhdGUgd2hlbi93aHkgc29tZXRpbWVzIHRoZXkgbWF0Y2gsCiAgICAgICAgICAgICAqIHNvbWV0aW1lcyB0aGV5IGRvbid0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYoYXNwLT5yZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8gIT0gYXNwLT5yZXFpbmZvKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogLSBvbmUgZG9uJ3QgbWF0Y2ggY2FzZTogYWdlbnR4IHN1YmFnZW50cy4gcHJldiBhc3AgJiByZXFpbmZvCiAgICAgICAgICAgICAgICAgKiAgIGZyZWVkLCByZXF1ZXN0IHJlcWluZm8gcHRycyBub3QgY2xlYXJlZC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnRtcCA9IGFzcC0+cmVxdWVzdHM7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgidmVyYm9zZTphc3AiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgcmVxaW5mbyAlcCBkb2Vzbid0IG1hdGNoIGNhY2hlZCByZXFpbmZvICVwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5yZXFpbmZvLCBhc3AtPnJlcXVlc3RzLT5hZ2VudF9yZXFfaW5mbykpOwogICAgICAgICAgICAgICAgZm9yKDsgdG1wOyB0bXAgPSB0bXAtPm5leHQpCiAgICAgICAgICAgICAgICAgICAgdG1wLT5hZ2VudF9yZXFfaW5mbyA9IGFzcC0+cmVxaW5mbzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiAtIG1hdGNoIGNhc2U6ID8KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIHJlcWluZm8gJXAgbWF0Y2hlcyBjYWNoZWQgcmVxaW5mbyAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cmVxaW5mbywgYXNwLT5yZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgU05NUF9GUkVFKHB0cik7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICBwcmV2ID0gcHRyOwogICAgfQogICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKfQoKLyogQnVsa2NhY2hlIGhvbGRzIHRoZSB2YWx1ZXMgZm9yIHRoZSAqcmVwZWF0aW5nKiB2YXJiaW5kcyAob25seSksCiAqICAgYnV0IG9yZGVyZWQgImJ5IGNvbHVtbiIgLSBpLmUuIHRoZSByZXBldGl0aW9ucyBmb3IgZWFjaAogKiAgIHJlcGVhdGluZyB2YXJiaW5kIGZvbGxvdyBvbiBpbW1lZGlhdGVseSBmcm9tIG9uZSBhbm90aGVyLAogKiAgIHJhdGhlciB0aGFuIGJlaW5nIGludGVybGVhdmVkLCBhcyByZXF1aXJlZCBieSB0aGUgcHJvdG9jb2wuCiAqCiAqIFNvIHdlIG5lZWQgdG8gcmVhcnJhbmdlIHRoZSB2YXJiaW5kIGxpc3Qgc28gaXQncyBvcmRlcmVkICJieSByb3ciLgogKgogKiBJbiB0aGUgZm9sbG93aW5nIGNvZGUgY2h1bms6CiAqICAgICBuICAgICAgICAgICAgPSAjIG5vbi1yZXBlYXRpbmcgdmFyYmluZHMKICogICAgIHIgICAgICAgICAgICA9ICMgcmVwZWF0aW5nIHZhcmJpbmRzCiAqICAgICBhc3AtPnZiY291bnQgPSAjIHZhcmJpbmRzIGluIHRoZSBpbmNvbWluZyBQRFUKICogICAgICAgICAoU28gYXNwLT52YmNvdW50ID0gbityKQogKgogKiAgICAgcmVwZWF0cyA9IERlc2lyZWQgIyBvZiByZXBldGl0aW9ucyAob2YgJ3InIHZhcmJpbmRzKQogKi8KTkVUU05NUF9TVEFUSUNfSU5MSU5FIHZvaWQKX3Jlb3JkZXJfZ2V0YnVsayhuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgaW50ICAgICAgICAgICAgIGksIG4gPSAwLCByID0gMDsKICAgIGludCAgICAgICAgICAgICByZXBlYXRzID0gYXNwLT5wZHUtPmVycmluZGV4OwogICAgaW50ICAgICAgICAgICAgIGosIGs7CiAgICBpbnQgICAgICAgICAgICAgYWxsX2VvTWliOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpwcmV2ID0gTlVMTCwgKmN1cnI7CiAgICAgICAgICAgIAogICAgaWYgKGFzcC0+dmJjb3VudCA9PSAwKSAgLyogTm90aGluZyB0byBkbyEgKi8KICAgICAgICByZXR1cm47CgogICAgaWYgKGFzcC0+cGR1LT5lcnJzdGF0IDwgYXNwLT52YmNvdW50KSB7CiAgICAgICAgbiA9IGFzcC0+cGR1LT5lcnJzdGF0OwogICAgfSBlbHNlIHsKICAgICAgICBuID0gYXNwLT52YmNvdW50OwogICAgfQogICAgaWYgKChyID0gYXNwLT52YmNvdW50IC0gbikgPCAwKSB7CiAgICAgICAgciA9IDA7CiAgICB9CgogICAgLyogd2UgZG8gbm90aGluZyBpZiB0aGVyZSBpcyBub3RoaW5nIHJlcGVhdGVkICovCiAgICBpZiAociA9PSAwKQogICAgICAgIHJldHVybjsKICAgICAgICAgICAgCiAgICAvKiBGaXggZW5kT2ZNaWJWaWV3IGVudHJpZXMuICovCiAgICBmb3IgKGkgPSAwOyBpIDwgcjsgaSsrKSB7CiAgICAgICAgcHJldiA9IE5VTEw7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IHJlcGVhdHM7IGorKykgewoJICAgIGN1cnIgPSBhc3AtPmJ1bGtjYWNoZVtpICogcmVwZWF0cyArIGpdOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiAgSWYgd2UgZG9uJ3QgaGF2ZSBhIHZhbGlkIG5hbWUgZm9yIGEgZ2l2ZW4gcmVwZXRpdGlvbgogICAgICAgICAgICAgKiAgIChhbmQgcHJvYmFibHkgZm9yIGFsbCB0aGUgb25lcyB0aGF0IGZvbGxvdyBhcyB3ZWxsKSwKICAgICAgICAgICAgICogICBleHRlbmQgdGhlIHByZXZpb3VzIHJlc3VsdCB0byBpbmRpY2F0ZSAnZW5kT2ZNaWJWaWV3Jy4KICAgICAgICAgICAgICogIE9yIGlmIHRoZSByZXBldGl0aW9uIGFscmVhZHkgaGFzIHR5cGUgZW5kT2ZNaWJWaWV3IG1ha2UKICAgICAgICAgICAgICogICBzdXJlIGl0IGhhcyB0aGUgY29ycmVjdCBvYmppZCAoaS5lLiB0aGF0IG9mIHRoZSBwcmV2aW91cwogICAgICAgICAgICAgKiAgIGVudHJ5IG9yIHRoYXQgb2YgdGhlIG9yaWdpbmFsIHJlcXVlc3QpLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGN1cnItPm5hbWVfbGVuZ3RoID09IDAgfHwgY3Vyci0+dHlwZSA9PSBTTk1QX0VORE9GTUlCVklFVykgewoJCWlmIChwcmV2ID09IE5VTEwpIHsKCQkgICAgLyogVXNlIG9iamlkIGZyb20gb3JpZ2luYWwgcGR1LiAqLwoJCSAgICBwcmV2ID0gYXNwLT5vcmlnX3BkdS0+dmFyaWFibGVzOwoJCSAgICBmb3IgKGsgPSBpOyBwcmV2ICYmIGsgPiAwOyBrLS0pCgkJCXByZXYgPSBwcmV2LT5uZXh0X3ZhcmlhYmxlOwoJCX0KCQlpZiAocHJldikgewoJCSAgICBzbm1wX3NldF92YXJfb2JqaWQoY3VyciwgcHJldi0+bmFtZSwgcHJldi0+bmFtZV9sZW5ndGgpOwoJCSAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUoY3VyciwgU05NUF9FTkRPRk1JQlZJRVcsIE5VTEwsIDApOwoJCX0KICAgICAgICAgICAgfQogICAgICAgICAgICBwcmV2ID0gY3VycjsKICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIEZvciBlYWNoIG9mIHRoZSBvcmlnaW5hbCByZXBlYXRpbmcgdmFyYmluZHMgKGV4Y2VwdCB0aGUgbGFzdCksCiAgICAgKiAgZ28gdGhyb3VnaCB0aGUgYmxvY2sgb2YgcmVzdWx0cyBmb3IgdGhhdCB2YXJiaW5kLAogICAgICogIGFuZCBsaW5rIGVhY2ggaW5zdGFuY2UgdG8gdGhlIGNvcnJlc3BvbmRpbmcgaW5zdGFuY2UKICAgICAqICBpbiB0aGUgbmV4dCBibG9jay4KICAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IHIgLSAxOyBpKyspIHsKICAgICAgICBmb3IgKGogPSAwOyBqIDwgcmVwZWF0czsgaisrKSB7CiAgICAgICAgICAgIGFzcC0+YnVsa2NhY2hlW2kgKiByZXBlYXRzICsgal0tPm5leHRfdmFyaWFibGUgPQogICAgICAgICAgICAgICAgYXNwLT5idWxrY2FjaGVbKGkgKyAxKSAqIHJlcGVhdHMgKyBqXTsKICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIEZvciB0aGUgbGFzdCBvZiB0aGUgb3JpZ2luYWwgcmVwZWF0aW5nIHZhcmJpbmRzLAogICAgICogIGdvIHRocm91Z2ggdGhhdCBibG9jayBvZiByZXN1bHRzLCBhbmQgbGluayBlYWNoCiAgICAgKiAgaW5zdGFuY2UgdG8gdGhlICpuZXh0KiBpbnN0YW5jZSBpbiB0aGUgKmZpcnN0KiBibG9jay4KICAgICAqCiAgICAgKiBUaGUgdmVyeSBsYXN0IGluc3RhbmNlIG9mIHRoaXMgYmxvY2sgaXMgbGVmdCB1bnRvdWNoZWQKICAgICAqICBzaW5jZSBpdCAoY29ycmVjdGx5KSBwb2ludHMgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdC4KICAgICAqLwogICAgZm9yIChqID0gMDsgaiA8IHJlcGVhdHMgLSAxOyBqKyspIHsKCWFzcC0+YnVsa2NhY2hlWyhyIC0gMSkgKiByZXBlYXRzICsgal0tPm5leHRfdmFyaWFibGUgPSAKCSAgICBhc3AtPmJ1bGtjYWNoZVtqICsgMV07CiAgICB9CgogICAgLyoKICAgICAqIElmIHdlJ3ZlIGdvdCBhIGZ1bGwgcm93IG9mIGVuZE9mTWliVmlld3MsIHRoZW4gd2UKICAgICAqICBjYW4gdHJ1bmNhdGUgdGhlIHJlc3VsdCB2YXJiaW5kIGxpc3QgYWZ0ZXIgdGhhdC4KICAgICAqCiAgICAgKiBMb29rIGZvciBlbmRPZk1pYlZpZXcgZXhjZXB0aW9uIHZhbHVlcyBpbiB0aGUgbGlzdCBvZgogICAgICogIHJlcGV0aXRpb25zIGZvciB0aGUgZmlyc3QgdmFyYmluZCwgYW5kIGNoZWNrIHRoZSAKICAgICAqICBjb3JyZXNwb25kaW5nIGluc3RhbmNlcyBmb3IgdGhlIG90aGVyIHZhcmJpbmRzCiAgICAgKiAgKGZvbGxvd2luZyB0aGUgbmV4dF92YXJpYWJsZSBsaW5rcykuCiAgICAgKgogICAgICogSWYgdGhleSdyZSBhbGwgZW5kT2ZNaWJWaWV3IHRvbywgdGhlbiB3ZSBjYW4gdGVybWluYXRlCiAgICAgKiAgdGhlIGxpbmtlZCBsaXN0IHRoZXJlLCBhbmQgZnJlZSBhbnkgcmVkdW5kYW50IHZhcmJpbmRzLgogICAgICovCiAgICBhbGxfZW9NaWIgPSAwOwogICAgZm9yIChpID0gMDsgaSA8IHJlcGVhdHM7IGkrKykgewogICAgICAgIGlmIChhc3AtPmJ1bGtjYWNoZVtpXS0+dHlwZSA9PSBTTk1QX0VORE9GTUlCVklFVykgewogICAgICAgICAgICBhbGxfZW9NaWIgPSAxOwogICAgICAgICAgICBmb3IgKGogPSAxLCBwcmV2PWFzcC0+YnVsa2NhY2hlW2ldOwogICAgICAgICAgICAgICAgIGogPCByOwogICAgICAgICAgICAgICAgIGorKywgcHJldj1wcmV2LT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICBpZiAocHJldi0+dHlwZSAhPSBTTk1QX0VORE9GTUlCVklFVykgewogICAgICAgICAgICAgICAgICAgIGFsbF9lb01pYiA9IDA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CS8qIEZvdW5kIGEgcmVhbCB2YWx1ZSAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChhbGxfZW9NaWIpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIGluZGVlZCBhIGZ1bGwgZW5kT2ZNaWJWaWV3IHJvdy4KICAgICAgICAgICAgICAgICAqIFRlcm1pbmF0ZSB0aGUgbGlzdCBoZXJlICYgZnJlZSB0aGUgcmVzdC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQoIHByZXYtPm5leHRfdmFyaWFibGUgKTsKICAgICAgICAgICAgICAgIHByZXYtPm5leHRfdmFyaWFibGUgPSBOVUxMOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCgovKiBFbmRPZk1pYlZpZXcgcmVwbGllcyB0byBhIEdFVE5FWFQgcmVxdWVzdCBzaG91bGQgYWNjb3JkaW5nIHRvIFJGQzM0MTYKICogIGhhdmUgdGhlIG9iamVjdCBJRCBzZXQgdG8gdGhhdCBvZiB0aGUgcmVxdWVzdC4gT3VyIHRyZWUgc2VhcmNoIAogKiAgYWxnb3JpdGhtIHdpbGwgc29tZXRpbWVzIGJyZWFrIHRoYXQgcmVxdWlyZW1lbnQuIFRoaXMgZnVuY3Rpb24gd2lsbAogKiAgZml4IHRoYXQuCiAqLwpORVRTTk1QX1NUQVRJQ19JTkxJTkUgdm9pZApfZml4X2VuZG9mbWlidmlldyhuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YiwgKm92YjsKCiAgICBpZiAoYXNwLT52YmNvdW50ID09IDApICAvKiBOb3RoaW5nIHRvIGRvISAqLwogICAgICAgIHJldHVybjsKCiAgICBmb3IgKHZiID0gYXNwLT5wZHUtPnZhcmlhYmxlcywgb3ZiID0gYXNwLT5vcmlnX3BkdS0+dmFyaWFibGVzOwoJIHZiICYmIG92YjsgdmIgPSB2Yi0+bmV4dF92YXJpYWJsZSwgb3ZiID0gb3ZiLT5uZXh0X3ZhcmlhYmxlKSB7CglpZiAodmItPnR5cGUgPT0gU05NUF9FTkRPRk1JQlZJRVcpCgkgICAgc25tcF9zZXRfdmFyX29iamlkKHZiLCBvdmItPm5hbWUsIG92Yi0+bmFtZV9sZW5ndGgpOwogICAgfQp9CgoKaW50CmdldE5leHRTZXNzSUQoKQp7CiAgICBzdGF0aWMgaW50ICAgICAgU2Vzc2lvbklEID0gMDsKCiAgICByZXR1cm4gKytTZXNzaW9uSUQ7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIGNoZWNrcyBmb3IgcGFja2V0cyBhcnJpdmluZyBvbiB0aGUgU05NUCBwb3J0IGFuZAogKiBwcm9jZXNzZXMgdGhlbShzbm1wX3JlYWQpIGlmIHNvbWUgYXJlIGZvdW5kLCB1c2luZyB0aGUgc2VsZWN0KCkuIElmIGJsb2NrCiAqIGlzIG5vbiB6ZXJvLCB0aGUgZnVuY3Rpb24gY2FsbCBibG9ja3MgdW50aWwgYSBwYWNrZXQgYXJyaXZlcwogKgogKiBAcGFyYW0gYmxvY2sgdXNlZCB0byBjb250cm9sIGJsb2NraW5nIGluIHRoZSBzZWxlY3QoKSBmdW5jdGlvbiwgMSA9IGJsb2NrCiAqICAgICAgICBmb3JldmVyLCBhbmQgMCA9IGRvbid0IGJsb2NrCiAqCiAqIEByZXR1cm4gIFJldHVybnMgYSBwb3NpdGl2ZSBpbnRlZ2VyIGlmIHBhY2tldHMgd2VyZSBwcm9jZXNzZWQsIGFuZCAtMSBpZiBhbgogKiBlcnJvciB3YXMgZm91bmQuCiAqCiAqLwppbnQKYWdlbnRfY2hlY2tfYW5kX3Byb2Nlc3MoaW50IGJsb2NrKQp7CiAgICBpbnQgICAgICAgICAgICAgbnVtZmRzOwogICAgZmRfc2V0ICAgICAgICAgIGZkc2V0OwogICAgc3RydWN0IHRpbWV2YWwgIHRpbWVvdXQgPSB7IExPTkdfTUFYLCAwIH0sICp0dnAgPSAmdGltZW91dDsKICAgIGludCAgICAgICAgICAgICBjb3VudDsKICAgIGludCAgICAgICAgICAgICBmYWtlYmxvY2sgPSAwOwoKICAgIG51bWZkcyA9IDA7CiAgICBGRF9aRVJPKCZmZHNldCk7CiAgICBzbm1wX3NlbGVjdF9pbmZvKCZudW1mZHMsICZmZHNldCwgdHZwLCAmZmFrZWJsb2NrKTsKICAgIGlmIChibG9jayAhPSAwICYmIGZha2VibG9jayAhPSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBUaGVyZSBhcmUgbm8gYWxhcm1zIHJlZ2lzdGVyZWQsIGFuZCB0aGUgY2FsbGVyIGFza2VkIGZvciBibG9ja2luZywgc28KICAgICAgICAgKiBsZXQgc2VsZWN0KCkgYmxvY2sgZm9yZXZlci4gIAogICAgICAgICAqLwoKICAgICAgICB0dnAgPSBOVUxMOwogICAgfSBlbHNlIGlmIChibG9jayAhPSAwICYmIGZha2VibG9jayA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBUaGUgY2FsbGVyIGFza2VkIGZvciBibG9ja2luZywgYnV0IHRoZXJlIGlzIGFuIGFsYXJtIGR1ZSBzb29uZXIgdGhhbgogICAgICAgICAqIExPTkdfTUFYIHNlY29uZHMgZnJvbSBub3csIHNvIHVzZSB0aGUgbW9kaWZpZWQgdGltZW91dCByZXR1cm5lZCBieQogICAgICAgICAqIHNubXBfc2VsZWN0X2luZm8gYXMgdGhlIHRpbWVvdXQgZm9yIHNlbGVjdCgpLiAgCiAgICAgICAgICovCgogICAgfSBlbHNlIGlmIChibG9jayA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBUaGUgY2FsbGVyIGRvZXMgbm90IHdhbnQgdXMgdG8gYmxvY2sgYXQgYWxsLiAgCiAgICAgICAgICovCgogICAgICAgIHRpbWVyY2xlYXIodHZwKTsKICAgIH0KCiAgICBjb3VudCA9IHNlbGVjdChudW1mZHMsICZmZHNldCwgMCwgMCwgdHZwKTsKCiAgICBpZiAoY291bnQgPiAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBwYWNrZXRzIGZvdW5kLCBwcm9jZXNzIHRoZW0gCiAgICAgICAgICovCiAgICAgICAgc25tcF9yZWFkKCZmZHNldCk7CiAgICB9IGVsc2UKICAgICAgICBzd2l0Y2ggKGNvdW50KSB7CiAgICAgICAgY2FzZSAwOgogICAgICAgICAgICBzbm1wX3RpbWVvdXQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAtMToKICAgICAgICAgICAgaWYgKGVycm5vICE9IEVJTlRSKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZ19wZXJyb3IoInNlbGVjdCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAic2VsZWN0IHJldHVybmVkICVkXG4iLCBjb3VudCk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmRpZiAtLSBjb3VudD4wICovCgogICAgLyoKICAgICAqIFJ1biByZXF1ZXN0ZWQgYWxhcm1zLiAgCiAgICAgKi8KICAgIHJ1bl9hbGFybXMoKTsKCiAgICBuZXRzbm1wX2NoZWNrX291dHN0YW5kaW5nX2FnZW50X3JlcXVlc3RzKCk7CgogICAgcmV0dXJuIGNvdW50Owp9CgoKLyoKICogU2V0IHVwIHRoZSBhZGRyZXNzIGNhY2hlLiAgCiAqLwp2b2lkCm5ldHNubXBfYWRkcmNhY2hlX2luaXRpYWxpc2Uodm9pZCkKewogICAgaW50ICAgICAgICAgICAgIGkgPSAwOwoKICAgIGZvciAoaSA9IDA7IGkgPCBTTk1QX0FERFJDQUNIRV9TSVpFOyBpKyspIHsKICAgICAgICBhZGRyQ2FjaGVbaV0uYWRkciA9IE5VTEw7CiAgICAgICAgYWRkckNhY2hlW2ldLnN0YXR1cyA9IFNOTVBfQUREUkNBQ0hFX1VOVVNFRDsKICAgIH0KfQoKdm9pZCBuZXRzbm1wX2FkZHJjYWNoZV9kZXN0cm95KHZvaWQpCnsKICAgIGludCAgICAgICAgICAgICBpID0gMDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgU05NUF9BRERSQ0FDSEVfU0laRTsgaSsrKSB7CiAgICAgICAgaWYgKGFkZHJDYWNoZVtpXS5zdGF0dXMgPT0gU05NUF9BRERSQ0FDSEVfVVNFRCkgewogICAgICAgICAgICBmcmVlKGFkZHJDYWNoZVtpXS5hZGRyKTsKICAgICAgICAgICAgYWRkckNhY2hlW2ldLnN0YXR1cyA9IFNOTVBfQUREUkNBQ0hFX1VOVVNFRDsKICAgICAgICB9CiAgICB9Cn0KCi8qCiAqIEFkZHMgYSBuZXcgZW50cnkgdG8gdGhlIGNhY2hlIG9mIGFkZHJlc3NlcyB0aGF0CiAqIGhhdmUgcmVjZW50bHkgbWFkZSBjb25uZWN0aW9ucyB0byB0aGUgYWdlbnQuCiAqIFJldHVybnMgMCBpZiB0aGUgZW50cnkgYWxyZWFkeSBleGlzdHMgKGJ1dCB1cGRhdGVzCiAqIHRoZSBlbnRyeSB3aXRoIGEgbmV3IHRpbWVzdGFtcCkgYW5kIDEgaWYgdGhlCiAqIGVudHJ5IGRpZCBub3QgcHJldmlvdXNseSBleGlzdC4KICoKICogSW1wbGVtZW50cyBhIHNpbXBsZSBMUlUgY2FjaGUgcmVwbGFjZW1lbnQKICogcG9saWN5LiBVc2VzIGEgbGluZWFyIHNlYXJjaCwgd2hpY2ggc2hvdWxkIGJlCiAqIG9rYXksIGFzIGxvbmcgYXMgU05NUF9BRERSQ0FDSEVfU0laRSByZW1haW5zCiAqIHJlbGF0aXZlbHkgc21hbGwuCiAqCiAqIEByZXR2YWwgMCA6IHVwZGF0ZWQgZXhpc3RpbmcgZW50cnkKICogQHJldHZhbCAxIDogYWRkZWQgbmV3IGVudHJ5CiAqLwppbnQKbmV0c25tcF9hZGRyY2FjaGVfYWRkKGNvbnN0IGNoYXIgKmFkZHIpCnsKICAgIGludCBvbGRlc3QgPSAtMTsgLyogSW5kZXggb2YgdGhlIG9sZGVzdCBjYWNoZSBlbnRyeSAqLwogICAgaW50IHVudXNlZCA9IC0xOyAvKiBJbmRleCBvZiB0aGUgZmlyc3QgZnJlZSBjYWNoZSBlbnRyeSAqLwogICAgaW50IGk7IC8qIExvb3BpbmcgdmFyaWFibGUgKi8KICAgIGludCByYyA9IC0xOwogICAgc3RydWN0IHRpbWV2YWwgbm93OyAvKiBXaGF0IHRpbWUgaXMgaXQgbm93PyAqLwogICAgc3RydWN0IHRpbWV2YWwgYWdlZDsgLyogT2xkZXN0IGFsbG93YWJsZSBjYWNoZSBlbnRyeSAqLwoKICAgIC8qCiAgICAgKiBGaXJzdCBnZXQgdGhlIGN1cnJlbnQgYW5kIG9sZGVzdCBhbGxvd2FibGUgdGltZXN0YW1wcwogICAgICovCiAgICBnZXR0aW1lb2ZkYXkoJm5vdywgKHN0cnVjdCB0aW1lem9uZSopIE5VTEwpOwogICAgYWdlZC50dl9zZWMgPSBub3cudHZfc2VjIC0gU05NUF9BRERSQ0FDSEVfTUFYQUdFOwogICAgYWdlZC50dl91c2VjID0gbm93LnR2X3VzZWM7CgogICAgLyoKICAgICAqIE5vdyBsb29rIGZvciBhIHBsYWNlIHRvIHB1dCB0aGlzIHRoaW5nCiAgICAgKi8KICAgIGZvcihpID0gMDsgaSA8IFNOTVBfQUREUkNBQ0hFX1NJWkU7IGkrKykgewogICAgICAgIGlmIChhZGRyQ2FjaGVbaV0uc3RhdHVzID09IFNOTVBfQUREUkNBQ0hFX1VOVVNFRCkgeyAvKiBJZiB1bnVzZWQgKi8KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcmVtZW1iZXIgdGhpcyBsb2NhdGlvbiwgaW4gY2FzZSBhZGRyIGlzbid0IGluIHRoZSBjYWNoZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHVudXNlZCA8IDApCiAgICAgICAgICAgICAgICB1bnVzZWQgPSBpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsgLyogSWYgdXNlZCAqLwogICAgICAgICAgICBpZiAoKE5VTEwgIT0gYWRkcikgJiYgKHN0cmNtcChhZGRyQ2FjaGVbaV0uYWRkciwgYWRkcikgPT0gMCkpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBmb3VuZCBhIG1hdGNoCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGFkZHJDYWNoZVtpXS5sYXN0SGl0ID0gbm93OwogICAgICAgICAgICAgICAgaWYgKHRpbWVyY21wKCZhZGRyQ2FjaGVbaV0ubGFzdEhpdCwgJmFnZWQsIDwpKQoJCSAgICByYyA9IDE7IC8qIHNob3VsZCBoYXZlIGV4cGlyZWQsIHNvIGlzIG5ldyAqLwoJCWVsc2UKCQkgICAgcmMgPSAwOyAvKiBub3QgZXhwaXJlZCwgc28gaXMgZXhpc3RpbmcgZW50cnkgKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFVzZWQsIGJ1dCBub3QgdGhpcyBhZGRyZXNzLiBjaGVjayBpZiBpdCdzIHN0YWxlLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAodGltZXJjbXAoJmFkZHJDYWNoZVtpXS5sYXN0SGl0LCAmYWdlZCwgPCkpIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIFN0YWxlLCByZXVzZQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShhZGRyQ2FjaGVbaV0uYWRkcik7CiAgICAgICAgICAgICAgICAgICAgYWRkckNhY2hlW2ldLnN0YXR1cyA9IFNOTVBfQUREUkNBQ0hFX1VOVVNFRDsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIHJlbWVtYmVyIHRoaXMgbG9jYXRpb24sIGluIGNhc2UgYWRkciBpc24ndCBpbiB0aGUgY2FjaGUKICAgICAgICAgICAgICAgICAgICAgKi8KCQkgICAgaWYgKHVudXNlZCA8IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHVudXNlZCA9IGk7CiAgICAgICAgICAgICAgICB9CgkgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogU3RpbGwgZnJlc2gsIGJ1dCBhIGNhbmRpZGF0ZSBmb3IgTFJVIHJlcGxhY2VtZW50CiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgaWYgKG9sZGVzdCA8IDApCiAgICAgICAgICAgICAgICAgICAgICAgIG9sZGVzdCA9IGk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodGltZXJjbXAoJmFkZHJDYWNoZVtpXS5sYXN0SGl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZhZGRyQ2FjaGVbb2xkZXN0XS5sYXN0SGl0LCA8KSkKICAgICAgICAgICAgICAgICAgICAgICAgb2xkZXN0ID0gaTsKICAgICAgICAgICAgICAgIH0gLyogZnJlc2ggKi8KICAgICAgICAgICAgfSAvKiB1c2VkLCBubyBtYXRjaCAqLwogICAgICAgIH0gLyogdXNlZCAqLwogICAgfSAvKiBmb3IgbG9vcCAqLwoKICAgIGlmICgoLTEgPT0gcmMpICYmIChOVUxMICE9IGFkZHIpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBXZSBkaWRuJ3QgZmluZCB0aGUgZW50cnkgaW4gdGhlIGNhY2hlCiAgICAgICAgICovCiAgICAgICAgaWYgKHVudXNlZCA+PSAwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIElmIHdlIGhhdmUgYSBzbG90IGZyZWUgYW55d2F5LCB1c2UgaXQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGFkZHJDYWNoZVt1bnVzZWRdLmFkZHIgPSBzdHJkdXAoYWRkcik7CiAgICAgICAgICAgIGFkZHJDYWNoZVt1bnVzZWRdLnN0YXR1cyA9IFNOTVBfQUREUkNBQ0hFX1VTRUQ7CiAgICAgICAgICAgIGFkZHJDYWNoZVt1bnVzZWRdLmxhc3RIaXQgPSBub3c7CiAgICAgICAgfQogICAgICAgIGVsc2UgeyAvKiBPdGhlcndpc2UsIHJlcGxhY2Ugb2xkZXN0IGVudHJ5ICovCiAgICAgICAgICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfVkVSQk9TRSkpCiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfSU5GTywgIlB1cmdpbmcgYWRkcmVzcyBmcm9tIGFkZHJlc3MgY2FjaGU6ICVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJDYWNoZVtvbGRlc3RdLmFkZHIpOwogICAgICAgICAgICAKICAgICAgICAgICAgZnJlZShhZGRyQ2FjaGVbb2xkZXN0XS5hZGRyKTsKICAgICAgICAgICAgYWRkckNhY2hlW29sZGVzdF0uYWRkciA9IHN0cmR1cChhZGRyKTsKICAgICAgICAgICAgYWRkckNhY2hlW29sZGVzdF0ubGFzdEhpdCA9IG5vdzsKICAgICAgICB9CiAgICAgICAgcmMgPSAxOwogICAgfQogICAgaWYgKChsb2dfYWRkcmVzc2VzICYmICgxID09IHJjKSkgfHwKICAgICAgICBuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX1ZFUkJPU0UpKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0lORk8sICJSZWNlaXZlZCBTTk1QIHBhY2tldChzKSBmcm9tICVzXG4iLCBhZGRyKTsKICAgICB9CgogICAgcmV0dXJuIHJjOwp9CgovKgogKiBBZ2UgdGhlIGVudHJpZXMgaW4gdGhlIGFkZHJlc3MgY2FjaGUuICAKICoKICogYmFja3dhcmRzIGNvbXBhdGFiaWxpdHk7IG5vdCB1c2VkIGFueXdoZXJlCiAqLwp2b2lkCm5ldHNubXBfYWRkcmNhY2hlX2FnZSh2b2lkKQp7CiAgICAodm9pZCluZXRzbm1wX2FkZHJjYWNoZV9hZGQoTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIG5ldHNubXBfYWdlbnRfY2hlY2tfcGFja2V0CiAqCiAqIFBhcmFtZXRlcnM6CiAqCXNlc3Npb24sIHRyYW5zcG9ydCwgdHJhbnNwb3J0X2RhdGEsIHRyYW5zcG9ydF9kYXRhX2xlbmd0aAogKiAgICAgIAogKiBSZXR1cm5zOgogKgkxCU9uIHN1Y2Nlc3MuCiAqCTAJT24gZXJyb3IuCiAqCiAqIEhhbmRsZXIgZm9yIGFsbCBpbmNvbWluZyBtZXNzYWdlcyAoYS5rLmEuIHBhY2tldHMpIGZvciB0aGUgYWdlbnQuICBJZiB1c2luZwogKiB0aGUgbGlid3JhcCB1dGlsaXR5LCBsb2cgdGhlIGNvbm5lY3Rpb24gYW5kIGRlbnkvYWxsb3cgdGhlIGFjY2Vzcy4gUHJpbnQKICogb3V0cHV0IHdoZW4gYXBwcm9wcmlhdGUsIGFuZCBpbmNyZW1lbnQgdGhlIGluY29taW5nIGNvdW50ZXIuCiAqCiAqLwoKaW50Cm5ldHNubXBfYWdlbnRfY2hlY2tfcGFja2V0KG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKnRyYW5zcG9ydF9kYXRhLCBpbnQgdHJhbnNwb3J0X2RhdGFfbGVuZ3RoKQp7CiAgICBjaGFyICAgICAgICAgICAqYWRkcl9zdHJpbmcgPSBOVUxMOwojaWZkZWYgIE5FVFNOTVBfVVNFX0xJQldSQVAKICAgIGNoYXIgKnRjcHVkcGFkZHIgPSBOVUxMLCAqbmFtZTsKICAgIHNob3J0IG5vdF9sb2dfY29ubmVjdGlvbjsKCiAgICBuYW1lID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfQVBQVFlQRSk7CgogICAgLyogbm90X2xvZ19jb25uZWN0aW9uIHdpbGwgYmUgMSBpZiB3ZSBzaG91bGQgc2tpcCB0aGUgbWVzc2FnZXMgKi8KICAgIG5vdF9sb2dfY29ubmVjdGlvbiA9IG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9ET05UX0xPR19UQ1BXUkFQUEVSU19DT05ORUNUUyk7CgogICAgLyoKICAgICAqIGhhbmRsZSB0aGUgZXJyb3IgY2FzZQogICAgICogZGVmYXVsdCB0byBsb2dnaW5nIHRoZSBtZXNzYWdlcwogICAgICovCiAgICBpZiAobm90X2xvZ19jb25uZWN0aW9uID09IFNOTVBFUlJfR0VORVJSKSBub3RfbG9nX2Nvbm5lY3Rpb24gPSAwOwojZW5kaWYKCiAgICAvKgogICAgICogTG9nIHRoZSBtZXNzYWdlIGFuZC9vciBkdW1wIHRoZSBtZXNzYWdlLgogICAgICogT3B0aW9uYWxseSBjYWNoZSB0aGUgbmV0d29yayBhZGRyZXNzIG9mIHRoZSBzZW5kZXIuCiAgICAgKi8KCiAgICBpZiAodHJhbnNwb3J0ICE9IE5VTEwgJiYgdHJhbnNwb3J0LT5mX2ZtdGFkZHIgIT0gTlVMTCkgewogICAgICAgIC8qCiAgICAgICAgICogT2theSBJIGRvIGtub3cgaG93IHRvIGZvcm1hdCB0aGlzIGFkZHJlc3MgZm9yIGxvZ2dpbmcuICAKICAgICAgICAgKi8KICAgICAgICBhZGRyX3N0cmluZyA9IHRyYW5zcG9ydC0+Zl9mbXRhZGRyKHRyYW5zcG9ydCwgdHJhbnNwb3J0X2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnRfZGF0YV9sZW5ndGgpOwogICAgICAgIC8qCiAgICAgICAgICogRG9uJ3QgZm9yZ2V0IHRvIGZyZWUoKSBpdC4gIAogICAgICAgICAqLwogICAgfQojaWZkZWYgIE5FVFNOTVBfVVNFX0xJQldSQVAKICAgIC8qIENhdGNoIHVkcCx1ZHA2LHRjcCx0Y3A2IHRyYW5zcG9ydHMgdXNpbmcgIlsiICovCiAgICBpZiAoYWRkcl9zdHJpbmcpCiAgICAgICAgdGNwdWRwYWRkciA9IHN0cnN0cihhZGRyX3N0cmluZywgIlsiKTsKICAgIGlmICggdGNwdWRwYWRkciAhPSAwICkgewogICAgICAgIGNoYXIgc2J1Zls2NF07CiAgICAgICAgY2hhciAqeHA7CgogICAgICAgIHN0cmxjcHkoc2J1ZiwgdGNwdWRwYWRkciArIDEsIHNpemVvZihzYnVmKSk7CiAgICAgICAgeHAgPSBzdHJzdHIoc2J1ZiwgIl0iKTsKICAgICAgICBpZiAoeHApCiAgICAgICAgICAgICp4cCA9ICdcMCc7CiAKICAgICAgICBpZiAoaG9zdHNfY3RsKG5hbWUsIFNUUklOR19VTktOT1dOLCBzYnVmLCBTVFJJTkdfVU5LTk9XTikpIHsKICAgICAgICAgICAgaWYgKCFub3RfbG9nX2Nvbm5lY3Rpb24pIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKGFsbG93X3NldmVyaXR5LCAiQ29ubmVjdGlvbiBmcm9tICVzXG4iLCBhZGRyX3N0cmluZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzbm1wX2xvZyhkZW55X3NldmVyaXR5LCAiQ29ubmVjdGlvbiBmcm9tICVzIFJFRlVTRURcbiIsCiAgICAgICAgICAgICAgICAgICAgIGFkZHJfc3RyaW5nKTsKICAgICAgICAgICAgU05NUF9GUkVFKGFkZHJfc3RyaW5nKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIGRvbid0IGxvZyBjYWxsYmFjayBjb25uZWN0aW9ucy4KICAgICAgICAgKiBXaGF0IGFib3V0ICdMb2NhbCBJUEMnLCAnSVBYJyBhbmQgJ0FBTDUgUFZDJz8KICAgICAgICAgKi8KICAgICAgICBpZiAoMCA9PSBzdHJuY21wKGFkZHJfc3RyaW5nLCAiY2FsbGJhY2siLCA4KSkKICAgICAgICAgICAgOwogICAgICAgIGVsc2UgaWYgKGhvc3RzX2N0bChuYW1lLCBTVFJJTkdfVU5LTk9XTiwgU1RSSU5HX1VOS05PV04sIFNUUklOR19VTktOT1dOKSl7CiAgICAgICAgICAgIGlmICghbm90X2xvZ19jb25uZWN0aW9uKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhhbGxvd19zZXZlcml0eSwgIkNvbm5lY3Rpb24gZnJvbSA8VU5LTk9XTj4gKCVzKVxuIiwgYWRkcl9zdHJpbmcpOwogICAgICAgICAgICB9OwogICAgICAgICAgICBTTk1QX0ZSRUUoYWRkcl9zdHJpbmcpOwogICAgICAgICAgICBhZGRyX3N0cmluZyA9IHN0cmR1cCgiPFVOS05PV04+Iik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc25tcF9sb2coZGVueV9zZXZlcml0eSwgIkNvbm5lY3Rpb24gZnJvbSA8VU5LTk9XTj4gKCVzKSBSRUZVU0VEXG4iLCBhZGRyX3N0cmluZyk7CiAgICAgICAgICAgIFNOTVBfRlJFRShhZGRyX3N0cmluZyk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgIH0KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKk5FVFNOTVBfVVNFX0xJQldSQVAgKi8KCiAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5QS1RTKTsKCiAgICBpZiAoYWRkcl9zdHJpbmcgIT0gTlVMTCkgewogICAgICAgIG5ldHNubXBfYWRkcmNhY2hlX2FkZChhZGRyX3N0cmluZyk7CiAgICAgICAgU05NUF9GUkVFKGFkZHJfc3RyaW5nKTsKICAgIH0KICAgIHJldHVybiAxOwp9CgoKaW50Cm5ldHNubXBfYWdlbnRfY2hlY2tfcGFyc2UobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwgbmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcmVzdWx0KQp7CiAgICBpZiAocmVzdWx0ID09IDApIHsKICAgICAgICBpZiAoc25tcF9nZXRfZG9fbG9nZ2luZygpICYmCgkgICAgbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELCAKCQkJCSAgIE5FVFNOTVBfRFNfQUdFTlRfVkVSQk9TRSkpIHsKICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJfcHRyOwoKICAgICAgICAgICAgc3dpdGNoIChwZHUtPmNvbW1hbmQpIHsKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19HRVQ6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIEdFVCBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIEdFVE5FWFQgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19SRVNQT05TRToKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgUkVTUE9OU0UgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19TRVQ6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIFNFVCBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX1RSQVA6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIFRSQVAgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBHRVRCVUxLIG1lc3NhZ2UsIG5vbi1yZXA9JWxkLCBtYXhfcmVwPSVsZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+ZXJyc3RhdCwgcGR1LT5lcnJpbmRleCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTkZPUk06CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIElORk9STSBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX1RSQVAyOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBUUkFQMiBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX1JFUE9SVDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgUkVQT1JUIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9SRVNFUlZFMToKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgSU5URVJOQUwgUkVTRVJWRTEgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUyOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBJTlRFUk5BTCBSRVNFUlZFMiBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQUNUSU9OOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBJTlRFUk5BTCBBQ1RJT04gbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX0NPTU1JVDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgSU5URVJOQUwgQ09NTUlUIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9GUkVFOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBJTlRFUk5BTCBGUkVFIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9VTkRPOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBJTlRFUk5BTCBVTkRPIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBVTktOT1dOIG1lc3NhZ2UsIHR5cGU9JTAyWFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+Y29tbWFuZCk7CiAgICAgICAgICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyX3B0ciA9IHBkdS0+dmFyaWFibGVzOyB2YXJfcHRyICE9IE5VTEw7CiAgICAgICAgICAgICAgICAgdmFyX3B0ciA9IHZhcl9wdHItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICAgICAgICAgIHNpemVfdCAgICAgICAgICBjX29pZGxlbiA9IDI1NiwgY19vdXRsZW4gPSAwOwogICAgICAgICAgICAgICAgdV9jaGFyICAgICAgICAgKmNfb2lkID0gKHVfY2hhciAqKSBtYWxsb2MoY19vaWRsZW4pOwoKICAgICAgICAgICAgICAgIGlmIChjX29pZCkgewogICAgICAgICAgICAgICAgICAgIGlmICghc3ByaW50X3JlYWxsb2Nfb2JqaWQKICAgICAgICAgICAgICAgICAgICAgICAgKCZjX29pZCwgJmNfb2lkbGVuLCAmY19vdXRsZW4sIDEsIHZhcl9wdHItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICB2YXJfcHRyLT5uYW1lX2xlbmd0aCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICAgIC0tICVzIFtUUlVOQ0FURURdXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjX29pZCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICAgIC0tICVzXG4iLCBjX29pZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShjX29pZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMDsgICAgICAgICAgICAgICAgICAgLyogWFhYOiBkb2VzIGl0IG1hdHRlciB3aGF0IHRoZSByZXR1cm4gdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBpcz8gIFllczogaWYgd2UgcmV0dXJuIDAsIHRoZW4gdGhlIFBEVSBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGR1bXBlZC4gICovCn0KCgovKgogKiBHbG9iYWwgYWNjZXNzIHRvIHRoZSBwcmltYXJ5IHNlc3Npb24gc3RydWN0dXJlIGZvciB0aGlzIGFnZW50LgogKiBmb3IgSW5kZXggQWxsb2NhdGlvbiB1c2UgaW5pdGlhbGx5LiAKICovCgovKgogKiBJIGRvbid0IHVuZGVyc3RhbmQgd2hhdCB0aGlzIGlzIGZvciBhdCB0aGUgbW9tZW50LiAgQUZBSUNTIGFzIGxvbmcgYXMgaXQKICogZ2V0cyBzZXQgYW5kIHBvaW50cyBhdCBhIHNlc3Npb24sIHRoYXQncyBmaW5lLiAgPz8/ICAKICovCgpuZXRzbm1wX3Nlc3Npb24gKm1haW5fc2Vzc2lvbiA9IE5VTEw7CgoKCi8qCiAqIFNldCB1cCBhbiBhZ2VudCBzZXNzaW9uIG9uIHRoZSBnaXZlbiB0cmFuc3BvcnQuICBSZXR1cm4gYSBoYW5kbGUKICogd2hpY2ggbWF5IGxhdGVyIGJlIHVzZWQgdG8gZGUtcmVnaXN0ZXIgdGhpcyB0cmFuc3BvcnQuICBBIHJldHVybgogKiB2YWx1ZSBvZiAtMSBpbmRpY2F0ZXMgYW4gZXJyb3IuICAKICovCgppbnQKbmV0c25tcF9yZWdpc3Rlcl9hZ2VudF9uc2FwKG5ldHNubXBfdHJhbnNwb3J0ICp0KQp7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnMsICpzcCA9IE5VTEw7CiAgICBhZ2VudF9uc2FwICAgICAqYSA9IE5VTEwsICpuID0gTlVMTCwgKipwcmV2TmV4dCA9ICZhZ2VudF9uc2FwX2xpc3Q7CiAgICBpbnQgICAgICAgICAgICAgaGFuZGxlID0gMDsKICAgIHZvaWQgICAgICAgICAgICppc3AgPSBOVUxMOwoKICAgIGlmICh0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgREVCVUdNU0dUTCgoIm5ldHNubXBfcmVnaXN0ZXJfYWdlbnRfbnNhcCIsICJmZCAlZFxuIiwgdC0+c29jaykpOwoKICAgIG4gPSAoYWdlbnRfbnNhcCAqKSBtYWxsb2Moc2l6ZW9mKGFnZW50X25zYXApKTsKICAgIGlmIChuID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBzID0gKG5ldHNubXBfc2Vzc2lvbiAqKSBtYWxsb2Moc2l6ZW9mKG5ldHNubXBfc2Vzc2lvbikpOwogICAgaWYgKHMgPT0gTlVMTCkgewogICAgICAgIFNOTVBfRlJFRShuKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBtZW1zZXQocywgMCwgc2l6ZW9mKG5ldHNubXBfc2Vzc2lvbikpOwogICAgc25tcF9zZXNzX2luaXQocyk7CgogICAgLyoKICAgICAqIFNldCB1cCB0aGUgc2Vzc2lvbiBhcHByb3ByaWF0ZWx5IGZvciBhbiBhZ2VudC4gIAogICAgICovCgogICAgcy0+dmVyc2lvbiA9IFNOTVBfREVGQVVMVF9WRVJTSU9OOwogICAgcy0+Y2FsbGJhY2sgPSBoYW5kbGVfc25tcF9wYWNrZXQ7CiAgICBzLT5hdXRoZW50aWNhdG9yID0gTlVMTDsKICAgIHMtPmZsYWdzID0gbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIAoJCQkJICBORVRTTk1QX0RTX0FHRU5UX0ZMQUdTKTsKICAgIHMtPmlzQXV0aG9yaXRhdGl2ZSA9IFNOTVBfU0VTU19BVVRIT1JJVEFUSVZFOwoKICAgIHNwID0gc25tcF9hZGQocywgdCwgbmV0c25tcF9hZ2VudF9jaGVja19wYWNrZXQsCiAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfY2hlY2tfcGFyc2UpOwogICAgaWYgKHNwID09IE5VTEwpIHsKICAgICAgICBTTk1QX0ZSRUUocyk7CiAgICAgICAgU05NUF9GUkVFKG4pOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBpc3AgPSBzbm1wX3Nlc3NfcG9pbnRlcihzcCk7CiAgICBpZiAoaXNwID09IE5VTEwpIHsgICAgICAgICAgLyogIG92ZXItY2F1dGlvdXMgICovCiAgICAgICAgU05NUF9GUkVFKHMpOwogICAgICAgIFNOTVBfRlJFRShuKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgbi0+cyA9IGlzcDsKICAgIG4tPnQgPSB0OwoKICAgIGlmIChtYWluX3Nlc3Npb24gPT0gTlVMTCkgewogICAgICAgIG1haW5fc2Vzc2lvbiA9IHNubXBfc2Vzc19zZXNzaW9uKGlzcCk7CiAgICB9CgogICAgZm9yIChhID0gYWdlbnRfbnNhcF9saXN0OyBhICE9IE5VTEwgJiYgaGFuZGxlICsgMSA+PSBhLT5oYW5kbGU7CiAgICAgICAgIGEgPSBhLT5uZXh0KSB7CiAgICAgICAgaGFuZGxlID0gYS0+aGFuZGxlOwogICAgICAgIHByZXZOZXh0ID0gJihhLT5uZXh0KTsKICAgIH0KCiAgICBpZiAoaGFuZGxlIDwgSU5UX01BWCkgewogICAgICAgIG4tPmhhbmRsZSA9IGhhbmRsZSArIDE7CiAgICAgICAgbi0+bmV4dCA9IGE7CiAgICAgICAgKnByZXZOZXh0ID0gbjsKICAgICAgICBTTk1QX0ZSRUUocyk7CiAgICAgICAgcmV0dXJuIG4tPmhhbmRsZTsKICAgIH0gZWxzZSB7CiAgICAgICAgU05NUF9GUkVFKHMpOwogICAgICAgIFNOTVBfRlJFRShuKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9Cn0KCnZvaWQKbmV0c25tcF9kZXJlZ2lzdGVyX2FnZW50X25zYXAoaW50IGhhbmRsZSkKewogICAgYWdlbnRfbnNhcCAgICAgKmEgPSBOVUxMLCAqKnByZXZOZXh0ID0gJmFnZW50X25zYXBfbGlzdDsKICAgIGludCAgICAgICAgICAgICBtYWluX3Nlc3Npb25fZGVyZWdpc3RlcmVkID0gMDsKCiAgICBERUJVR01TR1RMKCgibmV0c25tcF9kZXJlZ2lzdGVyX2FnZW50X25zYXAiLCAiaGFuZGxlICVkXG4iLCBoYW5kbGUpKTsKCiAgICBmb3IgKGEgPSBhZ2VudF9uc2FwX2xpc3Q7IGEgIT0gTlVMTCAmJiBhLT5oYW5kbGUgPCBoYW5kbGU7IGEgPSBhLT5uZXh0KSB7CiAgICAgICAgcHJldk5leHQgPSAmKGEtPm5leHQpOwogICAgfQoKICAgIGlmIChhICE9IE5VTEwgJiYgYS0+aGFuZGxlID09IGhhbmRsZSkgewogICAgICAgICpwcmV2TmV4dCA9IGEtPm5leHQ7CglpZiAoc25tcF9zZXNzX3Nlc3Npb25fbG9va3VwKGEtPnMpKSB7CiAgICAgICAgICAgIGlmIChtYWluX3Nlc3Npb24gPT0gc25tcF9zZXNzX3Nlc3Npb24oYS0+cykpIHsKICAgICAgICAgICAgICAgIG1haW5fc2Vzc2lvbl9kZXJlZ2lzdGVyZWQgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNubXBfY2xvc2Uoc25tcF9zZXNzX3Nlc3Npb24oYS0+cykpOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGUgYWJvdmUgZnJlZSgpcyB0aGUgdHJhbnNwb3J0IGFuZCBzZXNzaW9uIHBvaW50ZXJzLiAgCiAgICAgICAgICAgICAqLwogICAgICAgIH0KICAgICAgICBTTk1QX0ZSRUUoYSk7CiAgICB9CgogICAgLyoKICAgICAqIElmIHdlJ3ZlIGRlcmVnaXN0ZXJlZCB0aGUgc2Vzc2lvbiB0aGF0IG1haW5fc2Vzc2lvbiB1c2VkIHRvIHBvaW50IHRvLAogICAgICogdGhlbiBtYWtlIGl0IHBvaW50IHRvIGFub3RoZXIgb25lLCBvciBpbiB0aGUgbGFzdCByZXNvcnQsIG1ha2UgaXQgZXF1YWwKICAgICAqIHRvIE5VTEwuICBCYXNpY2FsbHkgdGhpcyBzaG91bGRuJ3QgZXZlciBoYXBwZW4gaW4gbm9ybWFsIG9wZXJhdGlvbgogICAgICogYmVjYXVzZSBtYWluX3Nlc3Npb24gc3RhcnRzIG9mZiBwb2ludGluZyBhdCB0aGUgZmlyc3Qgc2Vzc2lvbiBhZGRlZCBieQogICAgICogaW5pdF9tYXN0ZXJfYWdlbnQoKSwgd2hpY2ggdGhlbiBkaXNjYXJkcyB0aGUgaGFuZGxlLiAgCiAgICAgKi8KCiAgICBpZiAobWFpbl9zZXNzaW9uX2RlcmVnaXN0ZXJlZCkgewogICAgICAgIGlmIChhZ2VudF9uc2FwX2xpc3QgIT0gTlVMTCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsCgkJCSJXQVJOSU5HOiBtYWluX3Nlc3Npb24gcHRyIGNoYW5nZWQgZnJvbSAlcCB0byAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgbWFpbl9zZXNzaW9uLCBzbm1wX3Nlc3Nfc2Vzc2lvbihhZ2VudF9uc2FwX2xpc3QtPnMpKSk7CiAgICAgICAgICAgIG1haW5fc2Vzc2lvbiA9IHNubXBfc2Vzc19zZXNzaW9uKGFnZW50X25zYXBfbGlzdC0+cyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLAoJCQkiV0FSTklORzogbWFpbl9zZXNzaW9uIHB0ciBjaGFuZ2VkIGZyb20gJXAgdG8gTlVMTFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgbWFpbl9zZXNzaW9uKSk7CiAgICAgICAgICAgIG1haW5fc2Vzc2lvbiA9IE5VTEw7CiAgICAgICAgfQogICAgfQp9CgoKCi8qCiAqIAogKiBUaGlzIGZ1bmN0aW9uIGhhcyBiZWVuIG1vZGlmaWVkIHRvIHVzZSB0aGUgZXhwZXJpbWVudGFsCiAqIG5ldHNubXBfcmVnaXN0ZXJfYWdlbnRfbnNhcCBpbnRlcmZhY2UuICBUaGUgbWFqb3IgcmVzcG9uc2liaWxpdHkgb2YgdGhpcwogKiBmdW5jdGlvbiBub3cgaXMgdG8gaW50ZXJwcmV0IGEgc3RyaW5nIHNwZWNpZmllZCB0byB0aGUgYWdlbnQgKHZpYSAtcCBvbiB0aGUKICogY29tbWFuZCBsaW5lLCBvciBmcm9tIGEgY29uZmlndXJhdGlvbiBmaWxlKSBhcyBhIGxpc3Qgb2YgYWdlbnQgTlNBUHMgb24KICogd2hpY2ggdG8gbGlzdGVuIGZvciBTTk1QIHBhY2tldHMuICBUeXBpY2FsbHksIHdoZW4geW91IGFkZCBhIG5ldyB0cmFuc3BvcnQKICogZG9tYWluICJmb28iLCB5b3UgYWRkIGNvZGUgaGVyZSBzdWNoIHRoYXQgaWYgdGhlICJmb28iIGNvZGUgaXMgY29tcGlsZWQKICogaW50byB0aGUgYWdlbnQgKFNOTVBfVFJBTlNQT1JUX0ZPT19ET01BSU4gaXMgZGVmaW5lZCksIHRoZW4gYSB0b2tlbiBvZiB0aGUKICogZm9ybSAiZm9vOmJsZXRjaC0zYTAwNTRlZiV3b2Imd29iIiBnZXRzIHR1cm5lZCBpbnRvIHRoZSBhcHByb3ByaWF0ZQogKiB0cmFuc3BvcnQgZGVzY3JpcHRvci4gIG5ldHNubXBfcmVnaXN0ZXJfYWdlbnRfbnNhcCBpcyB0aGVuIGNhbGxlZCB3aXRoIHRoYXQKICogdHJhbnNwb3J0IGRlc2NyaXB0b3IgYW5kIHNldHMgdXAgYSBsaXN0ZW5pbmcgYWdlbnQgc2Vzc2lvbiBvbiBpdC4KICogCiAqIEV2ZXJ5dGhpbmcgdGhlbiB3b3JrcyBtdWNoIGFzIG5vcm1hbDogdGhlIGFnZW50IHJ1bnMgaW4gYW4gaW5maW5pdGUgbG9vcAogKiAoaW4gdGhlIHNubXBkLmMvcmVjZWl2ZSgpcm91dGluZSksIHdoaWNoIGNhbGxzIHNubXBfcmVhZCgpIHdoZW4gYSByZXF1ZXN0CiAqIGlzIHJlYWRhYmxlIG9uIGFueSBvZiB0aGUgZ2l2ZW4gdHJhbnNwb3J0cy4gIFRoaXMgcm91dGluZSB0aGVuIHRyYXZlcnNlcwogKiB0aGUgbGlicmFyeSAnU2Vzc2lvbnMnIGxpc3QgdG8gaWRlbnRpZnkgdGhlIHJlbGV2YW50IHNlc3Npb24gYW5kIGV2ZW50dWFsbHkKICogaW52b2tlcyAnX3Nlc3NfcmVhZCcuICBUaGlzIHRoZW4gcHJvY2Vzc2VzIHRoZSBpbmNvbWluZyBwYWNrZXQsIGNhbGxpbmcgdGhlCiAqIHByZV9wYXJzZSwgcGFyc2UsIHBvc3RfcGFyc2UgYW5kIGNhbGxiYWNrIHJvdXRpbmVzIGluIHR1cm4uCiAqIAogKiBKQlBOIDIwMDAxMTE3CiAqLwoKaW50CmluaXRfbWFzdGVyX2FnZW50KHZvaWQpCnsKICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQ7CiAgICBjaGFyICAgICAgICAgICAqY3B0cjsKICAgIGNoYXIgICAgICAgICAgICpidWYgPSBOVUxMOwogICAgY2hhciAgICAgICAgICAgKnN0OwoKICAgIC8qIGRlZmF1bHQgdG8gYSBkZWZhdWx0IGNhY2hlIHNpemUgKi8KICAgIG5ldHNubXBfc2V0X2xvb2t1cF9jYWNoZV9zaXplKC0xKTsKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELCAKCQkJICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfUk9MRSkgIT0gTUFTVEVSX0FHRU5UKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLAogICAgICAgICAgICAgICAgICAgICJpbml0X21hc3Rlcl9hZ2VudDsgbm90IG1hc3RlciBhZ2VudFxuIikpOwoKICAgICAgICBuZXRzbm1wX2Fzc2VydCgiYWdlbnQgcm9sZSAhbWFzdGVyICYmICFzdWJfYWdlbnQiKTsKICAgICAgICAKICAgICAgICByZXR1cm4gMDsgICAgICAgICAgICAgICAvKiAgTm8gZXJyb3IgaWYgISBNQVNURVJfQUdFTlQgICovCiAgICB9CgogICAgLyoKICAgICAqIEhhdmUgc3BlY2lmaWMgYWdlbnQgcG9ydHMgYmVlbiBzcGVjaWZpZWQ/ICAKICAgICAqLwogICAgY3B0ciA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELCAKCQkJCSBORVRTTk1QX0RTX0FHRU5UX1BPUlRTKTsKCiAgICBpZiAoY3B0cikgewogICAgICAgIGJ1ZiA9IHN0cmR1cChjcHRyKTsKICAgICAgICBpZiAoIWJ1ZikgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAiRXJyb3IgcHJvY2Vzc2luZyB0cmFuc3BvcnQgXCIlc1wiXG4iLCBjcHRyKTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIE5vLCBzbyBqdXN0IHNwZWNpZnkgdGhlIGRlZmF1bHQgcG9ydC4gIAogICAgICAgICAqLwogICAgICAgIGJ1ZiA9IHN0cmR1cCgiIik7CiAgICB9CgogICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiZmluYWwgcG9ydCBzcGVjOiBcIiVzXCJcbiIsIGJ1ZikpOwogICAgc3QgPSBidWY7CiAgICBkbyB7CiAgICAgICAgLyoKICAgICAgICAgKiBTcGVjaWZpY2F0aW9uIGZvcm1hdDogCiAgICAgICAgICogCiAgICAgICAgICogTk9ORTogICAgICAgICAgICAgICAgICAgICAgKGEgcHNldWRvLXRyYW5zcG9ydCkKICAgICAgICAgKiBVRFA6W2FkZHJlc3M6XXBvcnQgICAgICAgIChhbHNvIGRlZmF1bHQgaWYgbm8gdHJhbnNwb3J0IGlzIHNwZWNpZmllZCkKICAgICAgICAgKiBUQ1A6W2FkZHJlc3M6XXBvcnQgICAgICAgICAoaWYgc3VwcG9ydGVkKQogICAgICAgICAqIFVuaXg6cGF0aG5hbWUgICAgICAgICAgICAgIChpZiBzdXBwb3J0ZWQpCiAgICAgICAgICogQUFMNVBWQzppdGYudnBpLnZjaSAgICAgICAgKGlmIHN1cHBvcnRlZCkKICAgICAgICAgKiBJUFg6W25ldHdvcmtdOm5vZGVbL3BvcnRdIChpZiBzdXBwb3J0ZWQpCiAgICAgICAgICogCiAgICAgICAgICovCgoJY3B0ciA9IHN0OwoJc3QgPSBzdHJjaHIoc3QsICcsJyk7CglpZiAoc3QpCgkgICAgKnN0KysgPSAnXDAnOwoKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJpbnN0YWxsaW5nIG1hc3RlciBhZ2VudCBvbiBwb3J0ICVzXG4iLAogICAgICAgICAgICAgICAgICAgIGNwdHIpKTsKCiAgICAgICAgaWYgKHN0cm5jYXNlY21wKGNwdHIsICJub25lIiwgNCkgPT0gMCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJpbml0X21hc3Rlcl9hZ2VudDsgcHNldWRvLXRyYW5zcG9ydCBcIm5vbmVcIiAiCgkJCSJyZXF1ZXN0ZWRcbiIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHRyYW5zcG9ydCA9IG5ldHNubXBfdHJhbnNwb3J0X29wZW5fc2VydmVyKCJzbm1wIiwgY3B0cik7CgogICAgICAgIGlmICh0cmFuc3BvcnQgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiRXJyb3Igb3BlbmluZyBzcGVjaWZpZWQgZW5kcG9pbnQgXCIlc1wiXG4iLAogICAgICAgICAgICAgICAgICAgICBjcHRyKTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICBpZiAobmV0c25tcF9yZWdpc3Rlcl9hZ2VudF9uc2FwKHRyYW5zcG9ydCkgPT0gMCkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAiRXJyb3IgcmVnaXN0ZXJpbmcgc3BlY2lmaWVkIHRyYW5zcG9ydCBcIiVzXCIgYXMgYW4gIgoJCSAgICAgImFnZW50IE5TQVBcbiIsIGNwdHIpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJpbml0X21hc3Rlcl9hZ2VudDsgXCIlc1wiIHJlZ2lzdGVyZWQgYXMgYW4gYWdlbnQgIgoJCQkiTlNBUFxuIiwgY3B0cikpOwogICAgICAgIH0KICAgIH0gd2hpbGUoc3QgJiYgKnN0ICE9ICdcMCcpOwoKI2lmZGVmIFVTSU5HX0FHRU5UWF9NQVNURVJfTU9EVUxFCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELCAKCQkJICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfQUdFTlRYX01BU1RFUikgPT0gMSkKICAgICAgICByZWFsX2luaXRfbWFzdGVyKCk7CiNlbmRpZgojaWZkZWYgVVNJTkdfU01VWF9NT0RVTEUKICAgIGlmKHNob3VsZF9pbml0KCJzbXV4IikpCiAgICByZWFsX2luaXRfc211eCgpOwojZW5kaWYKCiAgICByZXR1cm4gMDsKfQoKdm9pZApjbGVhcl9uc2FwX2xpc3Qodm9pZCkKewogICAgREVCVUdNU0dUTCgoImNsZWFyX25zYXBfbGlzdCIsICJjbGVhciB0aGUgbnNhcCBsaXN0XG4iKSk7CgogICAgd2hpbGUgKGFnZW50X25zYXBfbGlzdCAhPSBOVUxMKQoJbmV0c25tcF9kZXJlZ2lzdGVyX2FnZW50X25zYXAoYWdlbnRfbnNhcF9saXN0LT5oYW5kbGUpOwp9Cgp2b2lkCnNodXRkb3duX21hc3Rlcl9hZ2VudCh2b2lkKQp7CiAgICBjbGVhcl9uc2FwX2xpc3QoKTsKfQoKCm5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqCmluaXRfYWdlbnRfc25tcF9zZXNzaW9uKG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sIG5ldHNubXBfcGR1ICpwZHUpCnsKICAgIG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwID0gKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqKQogICAgICAgIGNhbGxvYygxLCBzaXplb2YobmV0c25tcF9hZ2VudF9zZXNzaW9uKSk7CgogICAgaWYgKGFzcCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCJhZ2VudF9zZXNpb24gJTA4cCBjcmVhdGVkXG4iLCBhc3ApKTsKICAgIGFzcC0+c2Vzc2lvbiA9IHNlc3Npb247CiAgICBhc3AtPnBkdSA9IHNubXBfY2xvbmVfcGR1KHBkdSk7CiAgICBhc3AtPm9yaWdfcGR1ID0gc25tcF9jbG9uZV9wZHUocGR1KTsKICAgIGFzcC0+cncgPSBSRUFEOwogICAgYXNwLT5leGFjdCA9IFRSVUU7CiAgICBhc3AtPm5leHQgPSBOVUxMOwogICAgYXNwLT5tb2RlID0gUkVTRVJWRTE7CiAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICBhc3AtPmluZGV4ID0gMDsKICAgIGFzcC0+b2xkbW9kZSA9IDA7CiAgICBhc3AtPnRyZWVjYWNoZV9udW0gPSAtMTsKICAgIGFzcC0+dHJlZWNhY2hlX2xlbiA9IDA7CiAgICBhc3AtPnJlcWluZm8gPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvKTsKICAgIERFQlVHTVNHVEwoKCJ2ZXJib3NlOmFzcCIsICJhc3AgJXAgcmVxaW5mbyAlcCBjcmVhdGVkXG4iLAogICAgICAgICAgICAgICAgYXNwLCBhc3AtPnJlcWluZm8pKTsKCiAgICByZXR1cm4gYXNwOwp9Cgp2b2lkCmZyZWVfYWdlbnRfc25tcF9zZXNzaW9uKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBpZiAoIWFzcCkKICAgICAgICByZXR1cm47CgogICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCJhZ2VudF9zZXNzaW9uICUwOHAgcmVsZWFzZWRcbiIsIGFzcCkpOwoKICAgIG5ldHNubXBfcmVtb3ZlX2Zyb21fZGVsZWdhdGVkKGFzcCk7CiAgICAKICAgIERFQlVHTVNHVEwoKCJ2ZXJib3NlOmFzcCIsICJhc3AgJXAgcmVxaW5mbyAlcCBmcmVlZFxuIiwKICAgICAgICAgICAgICAgIGFzcCwgYXNwLT5yZXFpbmZvKSk7CiAgICBpZiAoYXNwLT5vcmlnX3BkdSkKICAgICAgICBzbm1wX2ZyZWVfcGR1KGFzcC0+b3JpZ19wZHUpOwogICAgaWYgKGFzcC0+cGR1KQogICAgICAgIHNubXBfZnJlZV9wZHUoYXNwLT5wZHUpOwogICAgaWYgKGFzcC0+cmVxaW5mbykKICAgICAgICBuZXRzbm1wX2ZyZWVfYWdlbnRfcmVxdWVzdF9pbmZvKGFzcC0+cmVxaW5mbyk7CiAgICBpZiAoYXNwLT50cmVlY2FjaGUpIHsKICAgICAgICBTTk1QX0ZSRUUoYXNwLT50cmVlY2FjaGUpOwogICAgfQogICAgaWYgKGFzcC0+YnVsa2NhY2hlKSB7CiAgICAgICAgU05NUF9GUkVFKGFzcC0+YnVsa2NhY2hlKTsKICAgIH0KICAgIGlmIChhc3AtPnJlcXVlc3RzKSB7CiAgICAgICAgaW50ICAgICAgICAgICAgIGk7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGFzcC0+dmJjb3VudDsgaSsrKSB7CiAgICAgICAgICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cygmYXNwLT5yZXF1ZXN0c1tpXSk7CiAgICAgICAgfQogICAgICAgIFNOTVBfRlJFRShhc3AtPnJlcXVlc3RzKTsKICAgIH0KICAgIGlmIChhc3AtPmNhY2hlX3N0b3JlKSB7CiAgICAgICAgbmV0c25tcF9mcmVlX2NhY2hlbWFwKGFzcC0+Y2FjaGVfc3RvcmUpOwogICAgICAgIGFzcC0+Y2FjaGVfc3RvcmUgPSBOVUxMOwogICAgfQogICAgU05NUF9GUkVFKGFzcCk7Cn0KCmludApuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWQobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGludCAgICAgICAgICAgICBpOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CgogICAgaWYgKE5VTEwgPT0gYXNwLT50cmVlY2FjaGUpCiAgICAgICAgcmV0dXJuIDA7CiAgICAKICAgIGZvciAoaSA9IDA7IGkgPD0gYXNwLT50cmVlY2FjaGVfbnVtOyBpKyspIHsKICAgICAgICBmb3IgKHJlcXVlc3QgPSBhc3AtPnRyZWVjYWNoZVtpXS5yZXF1ZXN0c19iZWdpbjsgcmVxdWVzdDsKICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5kZWxlZ2F0ZWQpCiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKaW50Cm5ldHNubXBfY2hlY2tfZGVsZWdhdGVkX2NoYWluX2ZvcihuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgbmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3B0bXA7CiAgICBmb3IgKGFzcHRtcCA9IGFnZW50X2RlbGVnYXRlZF9saXN0OyBhc3B0bXA7IGFzcHRtcCA9IGFzcHRtcC0+bmV4dCkgewogICAgICAgIGlmIChhc3B0bXAgPT0gYXNwKQogICAgICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAwOwp9CgppbnQKbmV0c25tcF9jaGVja19mb3JfZGVsZWdhdGVkX2FuZF9hZGQobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGlmIChuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWQoYXNwKSkgewogICAgICAgIGlmICghbmV0c25tcF9jaGVja19kZWxlZ2F0ZWRfY2hhaW5fZm9yKGFzcCkpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogYWRkIHRvIGRlbGVnYXRlZCByZXF1ZXN0IGNoYWluIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYXNwLT5uZXh0ID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7CiAgICAgICAgICAgIGFnZW50X2RlbGVnYXRlZF9saXN0ID0gYXNwOwogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJkZWxlZ2F0ZSBzZXNzaW9uID09ICUwOHBcbiIsIGFzcCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAwOwp9CgppbnQKbmV0c25tcF9yZW1vdmVfZnJvbV9kZWxlZ2F0ZWQobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqY3VyciwgKnByZXYgPSBOVUxMOwogICAgCiAgICBmb3IgKGN1cnIgPSBhZ2VudF9kZWxlZ2F0ZWRfbGlzdDsgY3VycjsgcHJldiA9IGN1cnIsIGN1cnIgPSBjdXJyLT5uZXh0KSB7CiAgICAgICAgLyoKICAgICAgICAgKiBpcyB0aGlzIHVzPwogICAgICAgICAqLwogICAgICAgIGlmIChjdXJyICE9IGFzcCkKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgCiAgICAgICAgLyoKICAgICAgICAgKiByZW1vdmUgZnJvbSBxdWV1ZSAKICAgICAgICAgKi8KICAgICAgICBpZiAocHJldiAhPSBOVUxMKQogICAgICAgICAgICBwcmV2LT5uZXh0ID0gYXNwLT5uZXh0OwogICAgICAgIGVsc2UKICAgICAgICAgICAgYWdlbnRfZGVsZWdhdGVkX2xpc3QgPSBhc3AtPm5leHQ7CgogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgInJlbW92ZSBkZWxlZ2F0ZWQgc2Vzc2lvbiA9PSAlMDhwXG4iLCBhc3ApKTsKCiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCi8qCiAqIG5ldHNubXBfcmVtb3ZlX2RlbGVnYXRlZF9yZXF1ZXN0c19mb3Jfc2Vzc2lvbgogKgogKiBjYWxsZWQgd2hlbiBhIHNlc3Npb24gaXMgYmVpbmcgY2xvc2VkLiBDaGVjayBhbGwgZGVsZWdhdGVkIHJlcXVlc3RzIHRvCiAqIHNlZSBpZiB0aGUgYXJlIHdhaXRpbmcgb24gdGhpcyBzZXNzaW9uLCBhbmQgaWYgc2V0LCBzZXQgdGhlIHN0YXR1cyBmb3IKICogdGhhdCByZXF1ZXN0IHRvIEdFTkVSUi4KICovCmludApuZXRzbm1wX3JlbW92ZV9kZWxlZ2F0ZWRfcmVxdWVzdHNfZm9yX3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICpzZXNzKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcDsKICAgIGludCBjb3VudCA9IDA7CiAgICAKICAgIGZvciAoYXNwID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7IGFzcDsgYXNwID0gYXNwLT5uZXh0KSB7CiAgICAgICAgLyoKICAgICAgICAgKiBjaGVjayBlYWNoIHJlcXVlc3QKICAgICAgICAgKi8KICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKICAgICAgICBmb3IocmVxdWVzdCA9IGFzcC0+cmVxdWVzdHM7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNoZWNrIHNlc3Npb24KICAgICAgICAgICAgICovCiAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwhPXJlcXVlc3QtPnN1YnRyZWUpOwogICAgICAgICAgICBpZihyZXF1ZXN0LT5zdWJ0cmVlLT5zZXNzaW9uICE9IHNlc3MpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG1hdGNoZWQhIG1hcmsgcmVxdWVzdCBhcyBkb25lCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3QsIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgICAgICsrY291bnQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBpZiB3ZSBmb3VuZCBhbnksIHRoYXQgcmVxdWVzdCBtYXkgYmUgZmluaXNoZWQgbm93CiAgICAgKi8KICAgIGlmKGNvdW50KSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAicmVtb3ZlZCAlZCBkZWxlZ2F0ZWQgcmVxdWVzdChzKSBmb3Igc2Vzc2lvbiAiCiAgICAgICAgICAgICAgICAgICAgIiUwOHBcbiIsIGNvdW50LCBzZXNzKSk7CiAgICAgICAgbmV0c25tcF9jaGVja19vdXRzdGFuZGluZ19hZ2VudF9yZXF1ZXN0cygpOwogICAgfQogICAgCiAgICByZXR1cm4gY291bnQ7Cn0KCmludApuZXRzbm1wX2NoZWNrX3F1ZXVlZF9jaGFpbl9mb3IobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwdG1wOwogICAgZm9yIChhc3B0bXAgPSBuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0OyBhc3B0bXA7IGFzcHRtcCA9IGFzcHRtcC0+bmV4dCkgewogICAgICAgIGlmIChhc3B0bXAgPT0gYXNwKQogICAgICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAwOwp9CgppbnQKbmV0c25tcF9hZGRfcXVldWVkKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcF90bXA7CgogICAgLyoKICAgICAqIGZpcnN0IGl0ZW0/CiAgICAgKi8KICAgIGlmIChOVUxMID09IG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3QpIHsKICAgICAgICBuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0ID0gYXNwOwogICAgICAgIHJldHVybiAxOwogICAgfQoKCiAgICAvKgogICAgICogYWRkIHRvIGVuZCBvZiBxdWV1ZWQgcmVxdWVzdCBjaGFpbiAKICAgICAqLwogICAgYXNwX3RtcCA9IG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3Q7CiAgICBmb3IgKDsgYXNwX3RtcDsgYXNwX3RtcCA9IGFzcF90bXAtPm5leHQpIHsKICAgICAgICAvKgogICAgICAgICAqIGFscmVhZHkgaW4gcXVldWU/CiAgICAgICAgICovCiAgICAgICAgaWYgKGFzcF90bXAgPT0gYXNwKQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgLyoKICAgICAgICAgKiBlbmQgb2YgcXVldWU/CiAgICAgICAgICovCiAgICAgICAgaWYgKE5VTEwgPT0gYXNwX3RtcC0+bmV4dCkKICAgICAgICAgICAgYXNwX3RtcC0+bmV4dCA9IGFzcDsKICAgIH0KICAgIHJldHVybiAxOwp9CgoKaW50Cm5ldHNubXBfd3JhcF91cF9yZXF1ZXN0KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLCBpbnQgc3RhdHVzKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcl9wdHI7CiAgICBpbnQgICAgICAgICAgICAgaTsKCiAgICAvKgogICAgICogaWYgdGhpcyByZXF1ZXN0IHdhcyBhIHNldCwgY2xlYXIgdGhlIGdsb2JhbCBub3cgdGhhdCB3ZSBhcmUKICAgICAqIGRvbmUuCiAgICAgKi8KICAgIGlmIChhc3AgPT0gbmV0c25tcF9wcm9jZXNzaW5nX3NldCkgewogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgIlNFVCByZXF1ZXN0IGNvbXBsZXRlLCBhc3AgPSAlMDhwXG4iLAogICAgICAgICAgICAgICAgICAgIGFzcCkpOwogICAgICAgIG5ldHNubXBfcHJvY2Vzc2luZ19zZXQgPSBOVUxMOwogICAgfQoKICAgIGlmIChhc3AtPnBkdSkgewogICAgICAgIC8qCiAgICAgICAgICogSWYgd2UndmUgZ290IGFuIGVycm9yIHN0YXR1cywgdGhlbiB0aGlzIG5lZWRzIHRvIGJlCiAgICAgICAgICogIHBhc3NlZCBiYWNrIHVwIHRvIHRoZSBoaWdoZXIgbGV2ZWxzLi4uLgogICAgICAgICAqLwogICAgICAgIGlmICggc3RhdHVzICE9IDAgICYmIGFzcC0+c3RhdHVzID09IDAgKQogICAgICAgICAgICBhc3AtPnN0YXR1cyA9IHN0YXR1czsKCiAgICAgICAgc3dpdGNoIChhc3AtPnBkdS0+Y29tbWFuZCkgewogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9CRUdJTjoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfUkVTRVJWRTE6CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUyOgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9BQ1RJT046CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogc29tZSBzdHVmZiBuZWVkcyB0byBiZSBzYXZlZCBpbiBzcGVjaWFsIHN1YmFnZW50IGNhc2VzIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzYXZlX3NldF9jYWNoZShhc3ApOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICAgICAgICAgICAgICBfZml4X2VuZG9mbWlidmlldyhhc3ApOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogZm9yIGEgR0VUQlVMSyByZXNwb25zZSB3ZSBuZWVkIHRvIHJlYXJyYW5nZSB0aGUgdmFyYmluZHMgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIF9yZW9yZGVyX2dldGJ1bGsoYXNwKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBNYXkgbmVlZCB0byAiZHVtYiBkb3duIiBhIFNFVCBlcnJvciBzdGF0dXMgZm9yIGEKICAgICAgICAgKiB2MSBxdWVyeS4gIFNlZSBSRkMyNTc2IC0gc2VjdGlvbiA0LjMKICAgICAgICAgKi8KI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgaWYgKChhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19TRVQpICYmCiAgICAgICAgICAgIChhc3AtPnBkdS0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMSkpIHsKICAgICAgICAgICAgc3dpdGNoIChhc3AtPnN0YXR1cykgewogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9XUk9OR1ZBTFVFOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9XUk9OR0VOQ09ESU5HOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9XUk9OR1RZUEU6CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX1dST05HTEVOR1RIOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9JTkNPTlNJU1RFTlRWQUxVRToKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9CQURWQUxVRTsKICAgICAgICAgICAgICAgICAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX0JBRFZBTFVFOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9OT0FDQ0VTUzoKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfTk9UV1JJVEFCTEU6CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX05PQ1JFQVRJT046CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX0lOQ09OU0lTVEVOVE5BTUU6CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX0FVVEhPUklaQVRJT05FUlJPUjoKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9OT1NVQ0hOQU1FOwogICAgICAgICAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gU05NUF9FUlJfTk9TVUNITkFNRTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRToKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfQ09NTUlURkFJTEVEOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9VTkRPRkFJTEVEOgogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgICAgICAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKgogICAgICAgICAqIFNpbWlsYXJseSB3ZSBtYXkgbmVlZCB0byAiZHVtYiBkb3duIiB2MiBleGNlcHRpb24KICAgICAgICAgKiAgdHlwZXMgdG8gdGhyb3cgYW4gZXJyb3IgZm9yIGEgdjEgcXVlcnkuCiAgICAgICAgICogIFNlZSBSRkMyNTc2IC0gc2VjdGlvbiA0LjEuMi4zCiAgICAgICAgICovCiAgICAgICAgaWYgKChhc3AtPnBkdS0+Y29tbWFuZCAhPSBTTk1QX01TR19TRVQpICYmCiAgICAgICAgICAgIChhc3AtPnBkdS0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMSkpIHsKICAgICAgICAgICAgZm9yICh2YXJfcHRyID0gYXNwLT5wZHUtPnZhcmlhYmxlcywgaSA9IDE7CiAgICAgICAgICAgICAgICAgdmFyX3B0ciAhPSBOVUxMOyB2YXJfcHRyID0gdmFyX3B0ci0+bmV4dF92YXJpYWJsZSwgaSsrKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHZhcl9wdHItPnR5cGUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIFNOTVBfTk9TVUNIT0JKRUNUOgogICAgICAgICAgICAgICAgICAgIGNhc2UgU05NUF9OT1NVQ0hJTlNUQU5DRToKICAgICAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRU5ET0ZNSUJWSUVXOgogICAgICAgICAgICAgICAgICAgIGNhc2UgQVNOX0NPVU5URVI2NDoKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gU05NUF9FUlJfTk9TVUNITkFNRTsKICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBTTk1QX0VSUl9OT1NVQ0hOQU1FOwogICAgICAgICAgICAgICAgICAgICAgICBhc3AtPmluZGV4ID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZiAvKiBzbm1wdjEgc3VwcG9ydCAqLwogICAgfSAvKiogaWYgYXNwLT5wZHUgKi8KCiAgICAvKgogICAgICogVXBkYXRlIHRoZSBzbm1wIGVycm9yLWNvdW50IHN0YXRpc3RpY3MKICAgICAqICAgWFhYIC0gc2hvdWxkIHdlIGluY2x1ZGUgdGhlIFYyIGVycm9ycyBpbiB0aGlzIG9yIG5vdD8KICAgICAqLwojZGVmaW5lIElOQ0xVREVfVjJFUlJPUlNfSU5fVjFTVEFUUwoKICAgIHN3aXRjaCAoc3RhdHVzKSB7CiNpZmRlZiBJTkNMVURFX1YyRVJST1JTX0lOX1YxU1RBVFMKICAgIGNhc2UgU05NUF9FUlJfV1JPTkdWQUxVRToKICAgIGNhc2UgU05NUF9FUlJfV1JPTkdFTkNPRElORzoKICAgIGNhc2UgU05NUF9FUlJfV1JPTkdUWVBFOgogICAgY2FzZSBTTk1QX0VSUl9XUk9OR0xFTkdUSDoKICAgIGNhc2UgU05NUF9FUlJfSU5DT05TSVNURU5UVkFMVUU6CiNlbmRpZgogICAgY2FzZSBTTk1QX0VSUl9CQURWQUxVRToKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QT1VUQkFEVkFMVUVTKTsKICAgICAgICBicmVhazsKI2lmZGVmIElOQ0xVREVfVjJFUlJPUlNfSU5fVjFTVEFUUwogICAgY2FzZSBTTk1QX0VSUl9OT0FDQ0VTUzoKICAgIGNhc2UgU05NUF9FUlJfTk9UV1JJVEFCTEU6CiAgICBjYXNlIFNOTVBfRVJSX05PQ1JFQVRJT046CiAgICBjYXNlIFNOTVBfRVJSX0lOQ09OU0lTVEVOVE5BTUU6CiAgICBjYXNlIFNOTVBfRVJSX0FVVEhPUklaQVRJT05FUlJPUjoKI2VuZGlmCiAgICBjYXNlIFNOTVBfRVJSX05PU1VDSE5BTUU6CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVE5PU1VDSE5BTUVTKTsKICAgICAgICBicmVhazsKI2lmZGVmIElOQ0xVREVfVjJFUlJPUlNfSU5fVjFTVEFUUwogICAgY2FzZSBTTk1QX0VSUl9SRVNPVVJDRVVOQVZBSUxBQkxFOgogICAgY2FzZSBTTk1QX0VSUl9DT01NSVRGQUlMRUQ6CiAgICBjYXNlIFNOTVBfRVJSX1VORE9GQUlMRUQ6CiNlbmRpZgogICAgY2FzZSBTTk1QX0VSUl9HRU5FUlI6CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVEdFTkVSUlMpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgU05NUF9FUlJfVE9PQklHOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBPVVRUT09CSUdTKTsKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoKHN0YXR1cyA9PSBTTk1QX0VSUl9OT0VSUk9SKSAmJiAoYXNwLT5wZHUpKSB7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljX2J5KChhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19TRVQgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBVF9TTk1QSU5UT1RBTFNFVFZBUlMgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RBVF9TTk1QSU5UT1RBTFJFUVZBUlMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudF92YXJiaW5kcyhhc3AtPnBkdS0+dmFyaWFibGVzKSk7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogVXNlIGEgY29weSBvZiB0aGUgb3JpZ2luYWwgcmVxdWVzdAogICAgICAgICAqICAgdG8gcmVwb3J0IGZhaWx1cmVzLgogICAgICAgICAqLwogICAgICAgIHNubXBfZnJlZV9wZHUoYXNwLT5wZHUpOwogICAgICAgIGFzcC0+cGR1ID0gYXNwLT5vcmlnX3BkdTsKICAgICAgICBhc3AtPm9yaWdfcGR1ID0gTlVMTDsKICAgIH0KICAgIGlmIChhc3AtPnBkdSkgewogICAgICAgIGFzcC0+cGR1LT5jb21tYW5kID0gU05NUF9NU0dfUkVTUE9OU0U7CiAgICAgICAgYXNwLT5wZHUtPmVycnN0YXQgPSBhc3AtPnN0YXR1czsKICAgICAgICBhc3AtPnBkdS0+ZXJyaW5kZXggPSBhc3AtPmluZGV4OwogICAgICAgIGlmICghc25tcF9zZW5kKGFzcC0+c2Vzc2lvbiwgYXNwLT5wZHUpICYmCiAgICAgICAgICAgICBhc3AtPnNlc3Npb24tPnNfc25tcF9lcnJubyAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJfcHRyOwogICAgICAgICAgICBzbm1wX3BlcnJvcigic2VuZCByZXNwb25zZSIpOwogICAgICAgICAgICBmb3IgKHZhcl9wdHIgPSBhc3AtPnBkdS0+dmFyaWFibGVzOyB2YXJfcHRyICE9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgIHZhcl9wdHIgPSB2YXJfcHRyLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICBzaXplX3QgIGNfb2lkbGVuID0gMjU2LCBjX291dGxlbiA9IDA7CiAgICAgICAgICAgICAgICB1X2NoYXIgKmNfb2lkID0gKHVfY2hhciAqKSBtYWxsb2MoY19vaWRsZW4pOwoKICAgICAgICAgICAgICAgIGlmIChjX29pZCkgewogICAgICAgICAgICAgICAgICAgIGlmICghc3ByaW50X3JlYWxsb2Nfb2JqaWQgKCZjX29pZCwgJmNfb2lkbGVuLCAmY19vdXRsZW4sIDEsCiAJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJfcHRyLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcl9wdHItPm5hbWVfbGVuZ3RoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiICAgIC0tICVzIFtUUlVOQ0FURURdXG4iLCBjX29pZCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIiAgICAtLSAlc1xuIiwgY19vaWQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUoY19vaWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNubXBfZnJlZV9wZHUoYXNwLT5wZHUpOwogICAgICAgICAgICBhc3AtPnBkdSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBPVVRQS1RTKTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QT1VUR0VUUkVTUE9OU0VTKTsKICAgICAgICBhc3AtPnBkdSA9IE5VTEw7IC8qIHl5eS1ya3M6IHJlZHVuZGFudCwgbm8/ICovCiAgICAgICAgbmV0c25tcF9yZW1vdmVfYW5kX2ZyZWVfYWdlbnRfc25tcF9zZXNzaW9uKGFzcCk7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKdm9pZApkdW1wX3Nlc3NfbGlzdCh2b2lkKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmE7CgogICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiRFVNUCBhZ2VudF9zZXNzX2xpc3QgLT4gIikpOwogICAgZm9yIChhID0gYWdlbnRfc2Vzc2lvbl9saXN0OyBhICE9IE5VTEw7IGEgPSBhLT5uZXh0KSB7CiAgICAgICAgREVCVUdNU0coKCJzbm1wX2FnZW50IiwgIiUwOHBbc2Vzc2lvbiAlMDhwXSAtPiAiLCBhLCBhLT5zZXNzaW9uKSk7CiAgICB9CiAgICBERUJVR01TRygoInNubXBfYWdlbnQiLCAiW05JTF1cbiIpKTsKfQoKdm9pZApuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24obmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYSwgKipwcmV2TmV4dCA9ICZhZ2VudF9zZXNzaW9uX2xpc3Q7CgogICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiUkVNT1ZFIHNlc3Npb24gPT0gJTA4cFxuIiwgYXNwKSk7CgogICAgZm9yIChhID0gYWdlbnRfc2Vzc2lvbl9saXN0OyBhICE9IE5VTEw7IGEgPSAqcHJldk5leHQpIHsKICAgICAgICBpZiAoYSA9PSBhc3ApIHsKICAgICAgICAgICAgKnByZXZOZXh0ID0gYS0+bmV4dDsKICAgICAgICAgICAgYS0+bmV4dCA9IE5VTEw7CiAgICAgICAgICAgIGZyZWVfYWdlbnRfc25tcF9zZXNzaW9uKGEpOwogICAgICAgICAgICBhc3AgPSBOVUxMOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcmV2TmV4dCA9ICYoYS0+bmV4dCk7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChhID09IE5VTEwgJiYgYXNwICE9IE5VTEwpIHsKICAgICAgICAvKgogICAgICAgICAqIFdlIGNvdWxuZCd0IGZpbmQgaXQgb24gdGhlIGxpc3QsIHNvIGZyZWUgaXQgYW55d2F5LiAgCiAgICAgICAgICovCiAgICAgICAgZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgIH0KfQoKdm9pZApuZXRzbm1wX2ZyZWVfYWdlbnRfc25tcF9zZXNzaW9uX2J5X3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICogc2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKCpmcmVlX3JlcXVlc3QpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmV0c25tcF9yZXF1ZXN0X2xpc3QgKikpCnsKICAgIG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYSwgKm5leHQsICoqcHJldk5leHQgPSAmYWdlbnRfc2Vzc2lvbl9saXN0OwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgIlJFTU9WRSBzZXNzaW9uID09ICUwOHBcbiIsIHNlc3MpKTsKCiAgICBmb3IgKGEgPSBhZ2VudF9zZXNzaW9uX2xpc3Q7IGEgIT0gTlVMTDsgYSA9IG5leHQpIHsKICAgICAgICBpZiAoYS0+c2Vzc2lvbiA9PSBzZXNzKSB7CiAgICAgICAgICAgICpwcmV2TmV4dCA9IGEtPm5leHQ7CiAgICAgICAgICAgIG5leHQgPSBhLT5uZXh0OwogICAgICAgICAgICBmcmVlX2FnZW50X3NubXBfc2Vzc2lvbihhKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcmV2TmV4dCA9ICYoYS0+bmV4dCk7CiAgICAgICAgICAgIG5leHQgPSBhLT5uZXh0OwogICAgICAgIH0KICAgIH0KfQoKLyoqIGhhbmRsZXMgYW4gaW5jb21pbmcgU05NUCBwYWNrZXQgaW50byB0aGUgYWdlbnQgKi8KaW50CmhhbmRsZV9zbm1wX3BhY2tldChpbnQgb3AsIG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sIGludCByZXFpZCwKICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcGR1ICpwZHUsIHZvaWQgKm1hZ2ljKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcDsKICAgIGludCAgICAgICAgICAgICBzdGF0dXMsIGFjY2Vzc19yZXQsIHJjOwoKICAgIC8qCiAgICAgKiBXZSBvbmx5IHN1cHBvcnQgcmVjZWl2aW5nIGhlcmUuICAKICAgICAqLwogICAgaWYgKG9wICE9IE5FVFNOTVBfQ0FMTEJBQ0tfT1BfUkVDRUlWRURfTUVTU0FHRSkgewogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIC8qCiAgICAgKiBSRVNQT05TRSBtZXNzYWdlcyB3b24ndCBnZXQgdGhpcyBmYXIsIGJ1dCBUUkFQLWxpa2UgbWVzc2FnZXMKICAgICAqIG1pZ2h0LiAgCiAgICAgKi8KICAgIGlmIChwZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfVFJBUCB8fCBwZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfSU5GT1JNIHx8CiAgICAgICAgcGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1RSQVAyKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAicmVjZWl2ZWQgdHJhcC1saWtlIFBEVSAoJTAyeClcbiIsCiAgICAgICAgICAgICAgICAgICAgcGR1LT5jb21tYW5kKSk7CiAgICAgICAgcGR1LT5jb21tYW5kID0gU05NUF9NU0dfVFJBUDI7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUFVOS05PV05QRFVIQU5ETEVSUyk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgLyoKICAgICAqIHNlbmQgc25tcHYzIGF1dGhmYWlsIHRyYXAuCiAgICAgKi8KICAgIGlmIChwZHUtPnZlcnNpb24gID09IFNOTVBfVkVSU0lPTl8zICYmIAogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9PSBTTk1QRVJSX1VTTV9BVVRIRU5USUNBVElPTkZBSUxVUkUpIHsKICAgICAgICAgICBzZW5kX2Vhc3lfdHJhcChTTk1QX1RSQVBfQVVUSEZBSUwsIDApOwogICAgICAgICAgIHJldHVybiAxOwogICAgfSAKCQogICAgaWYgKG1hZ2ljID09IE5VTEwpIHsKICAgICAgICBhc3AgPSBpbml0X2FnZW50X3NubXBfc2Vzc2lvbihzZXNzaW9uLCBwZHUpOwogICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICB9IGVsc2UgewogICAgICAgIGFzcCA9IChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKikgbWFnaWM7CiAgICAgICAgc3RhdHVzID0gYXNwLT5zdGF0dXM7CiAgICB9CgogICAgaWYgKChhY2Nlc3NfcmV0ID0gY2hlY2tfYWNjZXNzKGFzcC0+cGR1KSkgIT0gMCkgewogICAgICAgIGlmIChhY2Nlc3NfcmV0ID09IFZBQ01fTk9TVUNIQ09OVEVYVCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByZmMzNDEzIHNlY3Rpb24gMy4yLCBzdGVwIDUgc2F5cyB0aGF0IHdlIGluY3JlbWVudCB0aGUKICAgICAgICAgICAgICogY291bnRlciBidXQgZG9uJ3QgcmV0dXJuIGEgcmVzcG9uc2Ugb2YgYW55IGtpbmQgCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogd2UgY3VycmVudGx5IGRvbid0IHN1cHBvcnQgdW5hdmFpbGFibGUgY29udGV4dHMsIGFzCiAgICAgICAgICAgICAqIHRoZXJlIGlzIG5vIHJlYXNvbiB0byB0aGF0IEkgY3VycmVudGx5IGtub3cgb2YgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QVU5LTk9XTkNPTlRFWFRTKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGRyb3AgdGhlIHJlcXVlc3QgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogYWNjZXNzIGNvbnRyb2wgc2V0dXAgaXMgaW5jb3JyZWN0IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2VuZF9lYXN5X3RyYXAoU05NUF9UUkFQX0FVVEhGQUlMLCAwKTsKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQojaWYgZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKQogICAgICAgICAgICBpZiAoYXNwLT5wZHUtPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzJjKSB7CiNlbHNlCiNpZiBkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQogICAgICAgICAgICBpZiAoYXNwLT5wZHUtPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzEpIHsKI2Vsc2UKICAgICAgICAgICAgaWYgKGFzcC0+cGR1LT52ZXJzaW9uICE9IFNOTVBfVkVSU0lPTl8xCiAgICAgICAgICAgICAgICAmJiBhc3AtPnBkdS0+dmVyc2lvbiAhPSBTTk1QX1ZFUlNJT05fMmMpIHsKI2VuZGlmCiNlbmRpZgogICAgICAgICAgICAgICAgYXNwLT5wZHUtPmVycnN0YXQgPSBTTk1QX0VSUl9BVVRIT1JJWkFUSU9ORVJST1I7CiAgICAgICAgICAgICAgICBhc3AtPnBkdS0+Y29tbWFuZCA9IFNOTVBfTVNHX1JFU1BPTlNFOwogICAgICAgICAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVFBLVFMpOwogICAgICAgICAgICAgICAgaWYgKCFzbm1wX3NlbmQoYXNwLT5zZXNzaW9uLCBhc3AtPnBkdSkpCiAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3BkdShhc3AtPnBkdSk7CiAgICAgICAgICAgICAgICBhc3AtPnBkdSA9IE5VTEw7CiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9IGVsc2UgewojZW5kaWYgLyogc3VwcG9ydCBmb3IgY29tbXVuaXR5IGJhc2VkIFNOTVAgKi8KICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBkcm9wIHRoZSByZXF1ZXN0IAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCiAgICAgICAgICAgIH0KI2VuZGlmIC8qIHN1cHBvcnQgZm9yIGNvbW11bml0eSBiYXNlZCBTTk1QICovCiAgICAgICAgfQogICAgfQoKICAgIHJjID0gbmV0c25tcF9oYW5kbGVfcmVxdWVzdChhc3AsIHN0YXR1cyk7CgogICAgLyoKICAgICAqIGRvbmUgCiAgICAgKi8KICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImVuZCBvZiBoYW5kbGVfc25tcF9wYWNrZXQsIGFzcCA9ICUwOHBcbiIsCiAgICAgICAgICAgICAgICBhc3ApKTsKICAgIHJldHVybiByYzsKfQoKbmV0c25tcF9yZXF1ZXN0X2luZm8gKgpuZXRzbm1wX2FkZF92YXJiaW5kX3RvX2NhY2hlKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLCBpbnQgdmJjb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiB2YXJiaW5kX3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3N1YnRyZWUgKnRwKQp7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCA9IE5VTEw7CiAgICBpbnQgICAgICAgICAgICAgY2FjaGVpZDsKCiAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJhZGRfdmJfdG9fY2FjaGUoJThwLCAlZCwgIiwgYXNwLCB2YmNvdW50KSk7CiAgICBERUJVR01TR09JRCgoInNubXBfYWdlbnQiLCB2YXJiaW5kX3B0ci0+bmFtZSwKICAgICAgICAgICAgICAgICB2YXJiaW5kX3B0ci0+bmFtZV9sZW5ndGgpKTsKICAgIERFQlVHTVNHKCgic25tcF9hZ2VudCIsICIsICU4cClcbiIsIHRwKSk7CgogICAgaWYgKHRwICYmCiAgICAgICAgKGFzcC0+cGR1LT5jb21tYW5kID09IFNOTVBfTVNHX0dFVE5FWFQgfHwKICAgICAgICAgYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfR0VUQlVMSykpIHsKICAgICAgICBpbnQgcmVzdWx0OwogICAgICAgIGludCBwcmVmaXhfbGVuOwoKICAgICAgICBwcmVmaXhfbGVuID0gbmV0c25tcF9vaWRfZmluZF9wcmVmaXgodHAtPnN0YXJ0X2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT5zdGFydF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT5lbmRfYSwgdHAtPmVuZF9sZW4pOwogICAgICAgIGlmIChwcmVmaXhfbGVuIDwgMSkgewogICAgICAgICAgICByZXN1bHQgPSBWQUNNX05PVElOVklFVzsgLyogYWNrLi4uICBiYWQgYmFkIHRoaW5nIGhhcHBlbmVkICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVzdWx0ID0KICAgICAgICAgICAgICAgIG5ldHNubXBfYWNtX2NoZWNrX3N1YnRyZWUoYXNwLT5wZHUsIHRwLT5zdGFydF9hLCBwcmVmaXhfbGVuKTsKICAgICAgICB9CgogICAgICAgIHdoaWxlIChyZXN1bHQgPT0gVkFDTV9OT1RJTlZJRVcpIHsKICAgICAgICAgICAgLyogdGhlIGVudGlyZSBzdWJ0cmVlIGlzIG5vdCBpbiB2aWV3LiBTa2lwIGl0LiAqLwogICAgICAgICAgICAvKiogQHRvZG8gbWFrZSB0aGlzIGJlIG1vcmUgaW50ZWxsaWdlbnQgYWJvdXQgcmFuZ2VzLgogICAgICAgICAgICAgICAgUmlnaHQgbm93IHdlIG1lcmVseSB0YWtlIHRoZSBoaWdoZXN0IGxldmVsCiAgICAgICAgICAgICAgICBjb21tb25hbGl0eSBvZiBhIHJlZ2lzdHJhdGlvbiByYW5nZSBhbmQgdXNlIHRoYXQuCiAgICAgICAgICAgICAgICBBdCB0aW1lcyB3ZSBtaWdodCBiZSBhYmxlIHRvIGJlIHNtYXJ0ZXIgYWJvdXQKICAgICAgICAgICAgICAgIGNoZWNraW5nIHRoZSByYW5nZSBpdHNlbGYgYXMgb3Bwb3NlZCB0byB0aGUgbm9kZQogICAgICAgICAgICAgICAgYWJvdmUgd2hlcmUgdGhlIHJhbmdlIGV4aXN0cywgYnV0IEkgZG91YnQgdGhpcyB3aWxsCiAgICAgICAgICAgICAgICBjb21lIHVwIGFsbCB0aGF0IGZyZXF1ZW50bHkuICovCiAgICAgICAgICAgIHRwID0gdHAtPm5leHQ7CiAgICAgICAgICAgIGlmICh0cCkgewogICAgICAgICAgICAgICAgcHJlZml4X2xlbiA9IG5ldHNubXBfb2lkX2ZpbmRfcHJlZml4KHRwLT5zdGFydF9hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT5zdGFydF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPmVuZF9hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT5lbmRfbGVuKTsKICAgICAgICAgICAgICAgIGlmIChwcmVmaXhfbGVuIDwgMSkgewogICAgICAgICAgICAgICAgICAgIC8qIGFjay4uLiAgYmFkIGJhZCB0aGluZyBoYXBwZW5lZCAqLwogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFZBQ01fTk9USU5WSUVXOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPQogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FjbV9jaGVja19zdWJ0cmVlKGFzcC0+cGR1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT5zdGFydF9hLCBwcmVmaXhfbGVuKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBpZiAodHAgPT0gTlVMTCkgewogICAgICAgIC8qCiAgICAgICAgICogbm8gYXBwcm9wcmlhdGUgcmVnaXN0cmF0aW9uIGZvdW5kIAogICAgICAgICAqLwogICAgICAgIC8qCiAgICAgICAgICogbWFrZSB1cCB0aGUgcmVzcG9uc2Ugb3Vyc2VsdmVzIAogICAgICAgICAqLwogICAgICAgIHN3aXRjaCAoYXNwLT5wZHUtPmNvbW1hbmQpIHsKICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICAgICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOgogICAgICAgICAgICB2YXJiaW5kX3B0ci0+dHlwZSA9IFNOTVBfRU5ET0ZNSUJWSUVXOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTTk1QX01TR19TRVQ6CiAgICAgICAgY2FzZSBTTk1QX01TR19HRVQ6CiAgICAgICAgICAgIHZhcmJpbmRfcHRyLT50eXBlID0gU05NUF9OT1NVQ0hPQkpFQ1Q7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gTlVMTDsgICAgICAgIC8qIHNob3VsZG4ndCBnZXQgaGVyZSAqLwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAidHAtPnN0YXJ0ICIpKTsKICAgICAgICBERUJVR01TR09JRCgoInNubXBfYWdlbnQiLCB0cC0+c3RhcnRfYSwgdHAtPnN0YXJ0X2xlbikpOwogICAgICAgIERFQlVHTVNHKCgic25tcF9hZ2VudCIsICIsIHRwLT5lbmQgIikpOwogICAgICAgIERFQlVHTVNHT0lEKCgic25tcF9hZ2VudCIsIHRwLT5lbmRfYSwgdHAtPmVuZF9sZW4pKTsKICAgICAgICBERUJVR01TRygoInNubXBfYWdlbnQiLCAiLCBcbiIpKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBtYWxsb2MgdGhlIHJlcXVlc3Qgc3RydWN0dXJlIAogICAgICAgICAqLwogICAgICAgIHJlcXVlc3QgPSAmKGFzcC0+cmVxdWVzdHNbdmJjb3VudCAtIDFdKTsKICAgICAgICByZXF1ZXN0LT5pbmRleCA9IHZiY291bnQ7CiAgICAgICAgcmVxdWVzdC0+ZGVsZWdhdGVkID0gMDsKICAgICAgICByZXF1ZXN0LT5wcm9jZXNzZWQgPSAwOwogICAgICAgIHJlcXVlc3QtPnN0YXR1cyA9IDA7CiAgICAgICAgcmVxdWVzdC0+c3VidHJlZSA9IHRwOwogICAgICAgIHJlcXVlc3QtPmFnZW50X3JlcV9pbmZvID0gYXNwLT5yZXFpbmZvOwogICAgICAgIGlmIChyZXF1ZXN0LT5wYXJlbnRfZGF0YSkgewogICAgICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdWVzdCk7CiAgICAgICAgfQogICAgICAgIERFQlVHTVNHVEwoKCJ2ZXJib3NlOmFzcCIsICJhc3AgJXAgcmVxaW5mbyAlcCBhc3NpZ25lZCB0byByZXF1ZXN0XG4iLAogICAgICAgICAgICAgICAgICAgIGFzcCwgYXNwLT5yZXFpbmZvKSk7CgogICAgICAgIC8qCiAgICAgICAgICogZm9yIG5vbi1TRVQgbW9kZXMsIHNldCB0aGUgdHlwZSB0byBOVUxMIAogICAgICAgICAqLwogICAgICAgIGlmICghTU9ERV9JU19TRVQoYXNwLT5wZHUtPmNvbW1hbmQpKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwgImFzcCAlcCByZXFpbmZvICVwIGFzc2lnbmVkIHRvIHJlcXVlc3RcbiIsCiAgICAgICAgICAgICAgICAgICAgYXNwLCBhc3AtPnJlcWluZm8pKTsKICAgICAgICAgICAgaWYgKHZhcmJpbmRfcHRyLT50eXBlID09IEFTTl9QUklWX0lOQ0xfUkFOR0UpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgInZhcmJpbmQgJWQgaXMgaW5jbHVzaXZlXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+aW5kZXgpKTsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluY2x1c2l2ZSA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyYmluZF9wdHItPnR5cGUgPSBBU05fTlVMTDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogcGxhY2UgdGhlbSBpbiBhIGNhY2hlIAogICAgICAgICAqLwogICAgICAgIGlmICh0cC0+Z2xvYmFsX2NhY2hlaWQpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogd2UgbmVlZCB0byBtZXJnZSBhbGwgbWFya2VkIHN1YnRyZWVzIHRvZ2V0aGVyIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGFzcC0+Y2FjaGVfc3RvcmUgJiYgLTEgIT0KICAgICAgICAgICAgICAgIChjYWNoZWlkID0gbmV0c25tcF9nZXRfbG9jYWxfY2FjaGlkKGFzcC0+Y2FjaGVfc3RvcmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cC0+Z2xvYmFsX2NhY2hlaWQpKSkgewogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY2FjaGVpZCA9ICsrKGFzcC0+dHJlZWNhY2hlX251bSk7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2dldF9vcl9hZGRfbG9jYWxfY2FjaGlkKCZhc3AtPmNhY2hlX3N0b3JlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cC0+Z2xvYmFsX2NhY2hlaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlaWQpOwogICAgICAgICAgICAgICAgZ290byBtYWxsb2NzbG90OyAgICAgICAgLyogWFhYOiBpY2sgKi8KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAodHAtPmNhY2hlaWQgPiAtMSAmJiB0cC0+Y2FjaGVpZCA8PSBhc3AtPnRyZWVjYWNoZV9udW0gJiYKICAgICAgICAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlW3RwLT5jYWNoZWlkXS5zdWJ0cmVlID09IHRwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHdlIGhhdmUgYWxyZWFkeSBhZGRlZCBhIHJlcXVlc3QgdG8gdGhpcyB0cmVlCiAgICAgICAgICAgICAqIHBvaW50ZXIgYmVmb3JlIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2FjaGVpZCA9IHRwLT5jYWNoZWlkOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNhY2hlaWQgPSArKyhhc3AtPnRyZWVjYWNoZV9udW0pOwogICAgICAgICAgbWFsbG9jc2xvdDoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogbmV3IHNsb3QgbmVlZGVkIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGFzcC0+dHJlZWNhY2hlX251bSA+PSBhc3AtPnRyZWVjYWNoZV9sZW4pIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBleGFwYW5kIGNhY2hlIGFycmF5IAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogV1dXOiBub24tbGluZWFyIGV4cGFuc2lvbiBuZWVkZWQgKHdpdGggY2FwKSAKICAgICAgICAgICAgICAgICAqLwojZGVmaW5lIENBQ0hFX0dST1dfU0laRSAxNgogICAgICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVfbGVuID0KICAgICAgICAgICAgICAgICAgICAoYXNwLT50cmVlY2FjaGVfbGVuICsgQ0FDSEVfR1JPV19TSVpFKTsKICAgICAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlID0KICAgICAgICAgICAgICAgICAgICByZWFsbG9jKGFzcC0+dHJlZWNhY2hlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG5ldHNubXBfdHJlZV9jYWNoZSkgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVfbGVuKTsKICAgICAgICAgICAgICAgIGlmIChhc3AtPnRyZWVjYWNoZSA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgbWVtc2V0KCYoYXNwLT50cmVlY2FjaGVbY2FjaGVpZF0pLCAweDAwLAogICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihuZXRzbm1wX3RyZWVfY2FjaGUpICogKENBQ0hFX0dST1dfU0laRSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlW2NhY2hlaWRdLnN1YnRyZWUgPSB0cDsKICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVbY2FjaGVpZF0ucmVxdWVzdHNfYmVnaW4gPSByZXF1ZXN0OwogICAgICAgICAgICB0cC0+Y2FjaGVpZCA9IGNhY2hlaWQ7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGlmIHRoaXMgaXMgYSBzZWFyY2ggdHlwZSwgZ2V0IHRoZSBlbmRpbmcgcmFuZ2Ugb2lkIGFzIHdlbGwgCiAgICAgICAgICovCiAgICAgICAgaWYgKGFzcC0+cGR1LT5jb21tYW5kID09IFNOTVBfTVNHX0dFVE5FWFQgfHwKICAgICAgICAgICAgYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfR0VUQlVMSykgewogICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmQgPSB0cC0+ZW5kX2E7CiAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZF9sZW4gPSB0cC0+ZW5kX2xlbjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmQgPSBOVUxMOwogICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuID0gMDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogbGluayBpbnRvIGNoYWluIAogICAgICAgICAqLwogICAgICAgIGlmIChhc3AtPnRyZWVjYWNoZVtjYWNoZWlkXS5yZXF1ZXN0c19lbmQpCiAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlW2NhY2hlaWRdLnJlcXVlc3RzX2VuZC0+bmV4dCA9IHJlcXVlc3Q7CiAgICAgICAgcmVxdWVzdC0+bmV4dCA9IE5VTEw7CiAgICAgICAgcmVxdWVzdC0+cHJldiA9IGFzcC0+dHJlZWNhY2hlW2NhY2hlaWRdLnJlcXVlc3RzX2VuZDsKICAgICAgICBhc3AtPnRyZWVjYWNoZVtjYWNoZWlkXS5yZXF1ZXN0c19lbmQgPSByZXF1ZXN0OwoKICAgICAgICAvKgogICAgICAgICAqIGFkZCB0aGUgZ2l2ZW4gcmVxdWVzdCB0byB0aGUgbGlzdCBvZiByZXF1ZXN0cyB0aGV5IG5lZWQKICAgICAgICAgKiB0byBoYW5kbGUgcmVzdWx0cyBmb3IgCiAgICAgICAgICovCiAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiID0gcmVxdWVzdC0+cmVxdWVzdHZiX3N0YXJ0ID0gdmFyYmluZF9wdHI7CiAgICB9CiAgICByZXR1cm4gcmVxdWVzdDsKfQoKLyoKICogY2hlY2sgdGhlIEFDTShzKSBmb3IgdGhlIHJlc3VsdHMgb24gZWFjaCBvZiB0aGUgdmFyYmluZHMuCiAqIElmIEFDTSBkaXNhbGxvd3MgaXQsIHJlcGxhY2UgdGhlIHZhbHVlIHdpdGggdHlwZQogKiAKICogUmV0dXJucyBudW1iZXIgb2YgdmFyYmluZHMgd2l0aCBBQ00gZXJyb3JzCiAqLwppbnQKY2hlY2tfYWNtKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLCB1X2NoYXIgdHlwZSkKewogICAgaW50ICAgICAgICAgICAgIHZpZXc7CiAgICBpbnQgICAgICAgICAgICAgaSwgaiwgazsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0OwogICAgaW50ICAgICAgICAgICAgIHJldCA9IDA7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZiLCAqdmIyLCAqdmJjOwogICAgaW50ICAgICAgICAgICAgIGVhcmxpZXN0ID0gMDsKCiAgICBmb3IgKGkgPSAwOyBpIDw9IGFzcC0+dHJlZWNhY2hlX251bTsgaSsrKSB7CiAgICAgICAgZm9yIChyZXF1ZXN0ID0gYXNwLT50cmVlY2FjaGVbaV0ucmVxdWVzdHNfYmVnaW47CiAgICAgICAgICAgICByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBmb3IgZWFjaCByZXF1ZXN0LCBydW4gaXQgdGhyb3VnaCBpbl9hX3ZpZXcoKSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGVhcmxpZXN0ID0gMDsKICAgICAgICAgICAgZm9yKGogPSByZXF1ZXN0LT5yZXBlYXQsIHZiID0gcmVxdWVzdC0+cmVxdWVzdHZiX3N0YXJ0OwogICAgICAgICAgICAgICAgdmIgJiYgaiA+IC0xOwogICAgICAgICAgICAgICAgai0tLCB2YiA9IHZiLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICBpZiAodmItPnR5cGUgIT0gQVNOX05VTEwgJiYKICAgICAgICAgICAgICAgICAgICB2Yi0+dHlwZSAhPSBBU05fUFJJVl9SRVRSWSkgeyAvKiBub3QgeWV0IHByb2Nlc3NlZCAqLwogICAgICAgICAgICAgICAgICAgIHZpZXcgPQogICAgICAgICAgICAgICAgICAgICAgICBpbl9hX3ZpZXcodmItPm5hbWUsICZ2Yi0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnBkdSwgdmItPnR5cGUpOwoKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIGlmIGEgQUNNIGVycm9yIG9jY3VycywgbWFyayBpdCBhcyB0eXBlIHBhc3NlZCBpbiAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAodmlldyAhPSBWQUNNX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0Kys7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5yZXBlYXQgPCByZXF1ZXN0LT5vcmlnX3JlcGVhdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYmFzaWNhbGx5IHRoaXMgbWVhbnMgYSBHRVRCVUxLICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXBlYXQrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZWFybGllc3QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmIgPSB2YjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYXJsaWVzdCA9IDE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdWdoLiAgaWYgYSB3aG9sZSBub3cgZXhpc3RzLCB3ZSBuZWVkIHRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3ZlIHRoZSBjb250ZW50cyB1cCB0aGUgY2hhaW4gYW5kIGZpbGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIGF0IHRoZSBlbmQgZWxzZSB3ZSB3b24ndCBlbmQgdXAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxleG9ncmFwaGljYWxseSBzb3J0ZWQgcHJvcGVybHkgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqID4gLTEgJiYgdmItPm5leHRfdmFyaWFibGUgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Yi0+bmV4dF92YXJpYWJsZS0+dHlwZSAhPSBBU05fTlVMTCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT5uZXh0X3ZhcmlhYmxlLT50eXBlICE9IEFTTl9QUklWX1JFVFJZKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGsgPSBqLCB2YmMgPSB2YiwgdmIyID0gdmItPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGsgPiAtMiAmJiB2YmMgJiYgdmIyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrLS0sIHZiYyA9IHZiMiwgdmIyID0gdmIyLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNsb25lIG5leHQgaW50byB0aGUgY3VycmVudCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2Nsb25lX3Zhcih2YjIsIHZiYyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiYy0+bmV4dF92YXJpYWJsZSA9IHZiMjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHZiLCB0eXBlLCBOVUxMLCAwKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKaW50Cm5ldHNubXBfY3JlYXRlX3N1YnRyZWVfY2FjaGUobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIG5ldHNubXBfc3VidHJlZSAqdHA7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcmJpbmRfcHRyLCAqdmJzYXZlLCAqdmJwdHIsICoqcHJldk5leHQ7CiAgICBpbnQgICAgICAgICAgICAgdmlldzsKICAgIGludCAgICAgICAgICAgICB2YmNvdW50ID0gMDsKICAgIGludCAgICAgICAgICAgICBidWxrY291bnQgPSAwLCBidWxrcmVwID0gMDsKICAgIGludCAgICAgICAgICAgICBpID0gMCwgbiA9IDAsIHIgPSAwOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CgogICAgaWYgKGFzcC0+dHJlZWNhY2hlID09IE5VTEwgJiYgYXNwLT50cmVlY2FjaGVfbGVuID09IDApIHsKICAgICAgICBhc3AtPnRyZWVjYWNoZV9sZW4gPSBTTk1QX01BWCgxICsgYXNwLT52YmNvdW50IC8gNCwgMTYpOwogICAgICAgIGFzcC0+dHJlZWNhY2hlID0KICAgICAgICAgICAgY2FsbG9jKGFzcC0+dHJlZWNhY2hlX2xlbiwgc2l6ZW9mKG5ldHNubXBfdHJlZV9jYWNoZSkpOwogICAgICAgIGlmIChhc3AtPnRyZWVjYWNoZSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQogICAgYXNwLT50cmVlY2FjaGVfbnVtID0gLTE7CgogICAgaWYgKGFzcC0+cGR1LT5jb21tYW5kID09IFNOTVBfTVNHX0dFVEJVTEspIHsKICAgICAgICAvKgogICAgICAgICAqIGdldGJ1bGsgcHJlcCAKICAgICAgICAgKi8KICAgICAgICBpbnQgICAgICAgICAgICAgY291bnQgPSBjb3VudF92YXJiaW5kcyhhc3AtPnBkdS0+dmFyaWFibGVzKTsKICAgICAgICBpZiAoYXNwLT5wZHUtPmVycnN0YXQgPCAwKSB7CiAgICAgICAgICAgIGFzcC0+cGR1LT5lcnJzdGF0ID0gMDsKICAgICAgICB9CiAgICAgICAgaWYgKGFzcC0+cGR1LT5lcnJpbmRleCA8IDApIHsKICAgICAgICAgICAgYXNwLT5wZHUtPmVycmluZGV4ID0gMDsKICAgICAgICB9CgogICAgICAgIGlmIChhc3AtPnBkdS0+ZXJyc3RhdCA8IGNvdW50KSB7CiAgICAgICAgICAgIG4gPSBhc3AtPnBkdS0+ZXJyc3RhdDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuID0gY291bnQ7CiAgICAgICAgfQogICAgICAgIGlmICgociA9IGNvdW50IC0gbikgPD0gMCkgewogICAgICAgICAgICByID0gMDsKICAgICAgICAgICAgYXNwLT5idWxrY2FjaGUgPSBOVUxMOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGludCAgICAgICAgICAgbWF4YnVsayA9CiAgICAgICAgICAgICAgICBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX01BWF9HRVRCVUxLUkVQRUFUUyk7CiAgICAgICAgICAgIGludCBtYXhyZXNwb25zZXMgPQogICAgICAgICAgICAgICAgbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9NQVhfR0VUQlVMS1JFU1BPTlNFUyk7CgogICAgICAgICAgICBpZiAobWF4cmVzcG9uc2VzID09IDApCiAgICAgICAgICAgICAgICBtYXhyZXNwb25zZXMgPSAxMDA7ICAgLyogbW9yZSB0aGFuIHJlYXNvbmFibGUgZGVmYXVsdCAqLwoKICAgICAgICAgICAgLyogZW5zdXJlIHRoYXQgdGhlIHRvdGFsIG51bWJlciBvZiByZXNwb25zZXMgZml0cyBpbiBhIG1hbGxvY2FibGUKICAgICAgICAgICAgICogcmVzdWx0IHZlY3RvcgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKG1heHJlc3BvbnNlcyA8IDAgfHwKICAgICAgICAgICAgICAgIG1heHJlc3BvbnNlcyA+IElOVF9NQVggLyBzaXplb2Yoc3RydWN0IHZhcmJpbmRfbGlzdCAqKSkKICAgICAgICAgICAgICAgIG1heHJlc3BvbnNlcyA9IElOVF9NQVggLyBzaXplb2Yoc3RydWN0IHZhcmJpbmRfbGlzdCAqKTsKCiAgICAgICAgICAgIC8qIGVuc3VyZSB0aGF0IHRoZSBtYXhpbXVtIG51bWJlciBvZiByZXBldGl0aW9ucyB3aWxsIGZpdCBpbiB0aGUKICAgICAgICAgICAgICogcmVzdWx0IHZlY3RvcgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKG1heGJ1bGsgPD0gMCB8fCBtYXhidWxrID4gbWF4cmVzcG9uc2VzIC8gcikKICAgICAgICAgICAgICAgIG1heGJ1bGsgPSBtYXhyZXNwb25zZXMgLyByOwoKICAgICAgICAgICAgLyogbGltaXQgZ2V0YnVsayBudW1iZXIgb2YgcmVwZWF0cyB0byBhIGNvbmZpZ3VyZWQgc2l6ZSAqLwogICAgICAgICAgICBpZiAoYXNwLT5wZHUtPmVycmluZGV4ID4gbWF4YnVsaykgewogICAgICAgICAgICAgICAgYXNwLT5wZHUtPmVycmluZGV4ID0gbWF4YnVsazsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cnVuY2F0aW5nIG51bWJlciBvZiBnZXRidWxrIHJlcGVhdHMgdG8gJWxkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5wZHUtPmVycmluZGV4KSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGFzcC0+YnVsa2NhY2hlID0KICAgICAgICAgICAgICAgIChuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiopIG1hbGxvYygKICAgICAgICAgICAgICAgICAgICAobiArIGFzcC0+cGR1LT5lcnJpbmRleCAqIHIpICogc2l6ZW9mKHN0cnVjdCB2YXJiaW5kX2xpc3QgKikpOwoKICAgICAgICAgICAgaWYgKCFhc3AtPmJ1bGtjYWNoZSkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiQnVsa2NhY2hlIG1hbGxvYyBmYWlsZWRcbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiR0VUQlVMSyBOID0gJWQsIE0gPSAlbGQsIFIgPSAlZFxuIiwKICAgICAgICAgICAgICAgICAgICBuLCBhc3AtPnBkdS0+ZXJyaW5kZXgsIHIpKTsKICAgIH0KCiAgICAvKgogICAgICogY29sbGVjdCB2YXJiaW5kcyBpbnRvIHRoZWlyIHJlZ2lzdGVyZWQgdHJlZXMgCiAgICAgKi8KICAgIHByZXZOZXh0ID0gJihhc3AtPnBkdS0+dmFyaWFibGVzKTsKICAgIGZvciAodmFyYmluZF9wdHIgPSBhc3AtPnBkdS0+dmFyaWFibGVzOyB2YXJiaW5kX3B0cjsKICAgICAgICAgdmFyYmluZF9wdHIgPSB2YnNhdmUpIHsKCiAgICAgICAgLyoKICAgICAgICAgKiBnZXRidWxrIG1lc3Mgd2l0aCB0aGlzIHBvaW50ZXIsIHNvIHNhdmUgaXQgCiAgICAgICAgICovCiAgICAgICAgdmJzYXZlID0gdmFyYmluZF9wdHItPm5leHRfdmFyaWFibGU7CgogICAgICAgIGlmIChhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19HRVRCVUxLKSB7CiAgICAgICAgICAgIGlmIChuID4gMCkgewogICAgICAgICAgICAgICAgbi0tOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHJlcGVhdGUgcmVxdWVzdCB2YXJiaW5kcyBvbiBHRVRCVUxLLiAgVGhlc2Ugd2lsbAogICAgICAgICAgICAgICAgICogaGF2ZSB0byBiZSBwcm9wZXJseSByZWFycmFuZ2VkIGxhdGVyIHRob3VnaCBhcwogICAgICAgICAgICAgICAgICogcmVzcG9uc2VzIGFyZSBzdXBwb3NlZCB0byBhY3R1YWxseSBiZSBpbnRlcmxhY2VkCiAgICAgICAgICAgICAgICAgKiB3aXRoIGVhY2ggb3RoZXIuICBUaGlzIGlzIGRvbmUgd2l0aCB0aGUgYXNwLT5idWxrY2FjaGUuIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBidWxrcmVwID0gYXNwLT5wZHUtPmVycmluZGV4IC0gMTsKICAgICAgICAgICAgICAgIGlmIChhc3AtPnBkdS0+ZXJyaW5kZXggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgdmJwdHIgPSB2YXJiaW5kX3B0cjsKICAgICAgICAgICAgICAgICAgICBhc3AtPmJ1bGtjYWNoZVtidWxrY291bnQrK10gPSB2YnB0cjsKCiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IGFzcC0+cGR1LT5lcnJpbmRleDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZicHRyLT5uZXh0X3ZhcmlhYmxlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfTUFMTE9DX1NUUlVDVCh2YXJpYWJsZV9saXN0KTsKICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICogZG9uJ3QgY2xvbmUgdGhlIG9pZCBhcyBpdCdzIGdvdCB0byBiZQogICAgICAgICAgICAgICAgICAgICAgICAgKiBvdmVyd3JpdHRlbiBhbnl3YXkgCiAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZicHRyLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogWFhYV1dXOiBhY2shISEgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgIk5leHRWYXIgbWFsbG9jIGZhaWxlZFxuIikpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmJwdHIgPSB2YnB0ci0+bmV4dF92YXJpYWJsZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZicHRyLT5uYW1lX2xlbmd0aCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YnB0ci0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5idWxrY2FjaGVbYnVsa2NvdW50KytdID0gdmJwdHI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdmJwdHItPm5leHRfdmFyaWFibGUgPSB2YnNhdmU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogMCByZXBlYXRzIHJlcXVlc3RlZCBmb3IgdGhpcyB2YXJiaW5kLCBzbyB0YWtlIGl0IG9mZgogICAgICAgICAgICAgICAgICAgICAqIHRoZSBsaXN0LiAgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgdmJwdHIgPSB2YXJiaW5kX3B0cjsKICAgICAgICAgICAgICAgICAgICAqcHJldk5leHQgPSB2YnB0ci0+bmV4dF92YXJpYWJsZTsKICAgICAgICAgICAgICAgICAgICB2YnB0ci0+bmV4dF92YXJpYWJsZSA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmJwdHIpOwogICAgICAgICAgICAgICAgICAgIGFzcC0+dmJjb3VudC0tOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGNvdW50IHRoZSB2YXJiaW5kcyAKICAgICAgICAgKi8KICAgICAgICArK3ZiY291bnQ7CgogICAgICAgIC8qCiAgICAgICAgICogZmluZCB0aGUgb3duaW5nIHRyZWUgCiAgICAgICAgICovCiAgICAgICAgdHAgPSBuZXRzbm1wX3N1YnRyZWVfZmluZCh2YXJiaW5kX3B0ci0+bmFtZSwgdmFyYmluZF9wdHItPm5hbWVfbGVuZ3RoLAoJCQkJICBOVUxMLCBhc3AtPnBkdS0+Y29udGV4dE5hbWUpOwoKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIGFjY2VzcyBjb250cm9sIAogICAgICAgICAqLwogICAgICAgIHN3aXRjaCAoYXNwLT5wZHUtPmNvbW1hbmQpIHsKICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgICAgICAgICAgdmlldyA9IGluX2Ffdmlldyh2YXJiaW5kX3B0ci0+bmFtZSwgJnZhcmJpbmRfcHRyLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnBkdSwgdmFyYmluZF9wdHItPnR5cGUpOwogICAgICAgICAgICBpZiAodmlldyAhPSBWQUNNX1NVQ0NFU1MpCiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUodmFyYmluZF9wdHIsIFNOTVBfTk9TVUNIT0JKRUNULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDApOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTTk1QX01TR19TRVQ6CiAgICAgICAgICAgIHZpZXcgPSBpbl9hX3ZpZXcodmFyYmluZF9wdHItPm5hbWUsICZ2YXJiaW5kX3B0ci0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5wZHUsIHZhcmJpbmRfcHRyLT50eXBlKTsKICAgICAgICAgICAgaWYgKHZpZXcgIT0gVkFDTV9TVUNDRVNTKSB7CiAgICAgICAgICAgICAgICBhc3AtPmluZGV4ID0gdmJjb3VudDsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0FDQ0VTUzsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgIGNhc2UgU05NUF9NU0dfR0VUQlVMSzoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB2aWV3ID0gVkFDTV9TVUNDRVNTOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBYWFhXV1c6IGNoZWNrIFZBQ00gaGVyZSB0byBzZWUgaWYgInRwIiBpcyBldmVuIHdvcnRod2hpbGUgCiAgICAgICAgICAgICAqLwogICAgICAgIH0KICAgICAgICBpZiAodmlldyA9PSBWQUNNX1NVQ0NFU1MpIHsKICAgICAgICAgICAgcmVxdWVzdCA9IG5ldHNubXBfYWRkX3ZhcmJpbmRfdG9fY2FjaGUoYXNwLCB2YmNvdW50LCB2YXJiaW5kX3B0ciwKCQkJCQkJICAgdHApOwogICAgICAgICAgICBpZiAocmVxdWVzdCAmJiBhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19HRVRCVUxLKSB7CiAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXBlYXQgPSByZXF1ZXN0LT5vcmlnX3JlcGVhdCA9IGJ1bGtyZXA7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByZXZOZXh0ID0gJih2YXJiaW5kX3B0ci0+bmV4dF92YXJpYWJsZSk7CiAgICB9CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKLyoKICogdGhpcyBmdW5jdGlvbiBpcyBvbmx5IGFwcGxpY2FibGUgaW4gZ2V0bmV4dCBsaWtlIGNvbnRleHRzIAogKi8KaW50Cm5ldHNubXBfcmVhc3NpZ25fcmVxdWVzdHMobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIC8qCiAgICAgKiBhc3N1bWUgYWxsIHRoZSByZXF1ZXN0cyBoYXZlIGJlZW4gZmlsbGVkIG9yIHJlamVjdGVkIGJ5IHRoZQogICAgICogc3VidHJlZXMsIHNvIHJlYXNzaWduIHRoZSByZWplY3RlZCBvbmVzIHRvIHRoZSBuZXh0IHN1YnRyZWUgaW4KICAgICAqIHRoZSBjaGFpbiAKICAgICAqLwoKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIC8qCiAgICAgKiBnZXQgb2xkIGluZm8gCiAgICAgKi8KICAgIG5ldHNubXBfdHJlZV9jYWNoZSAqb2xkX3RyZWVjYWNoZSA9IGFzcC0+dHJlZWNhY2hlOwoKICAgIC8qCiAgICAgKiBtYWxsb2MgbmV3IHNwYWNlIAogICAgICovCiAgICBhc3AtPnRyZWVjYWNoZSA9CiAgICAgICAgKG5ldHNubXBfdHJlZV9jYWNoZSAqKSBjYWxsb2MoYXNwLT50cmVlY2FjaGVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihuZXRzbm1wX3RyZWVfY2FjaGUpKTsKICAgIGFzcC0+dHJlZWNhY2hlX251bSA9IC0xOwogICAgaWYgKGFzcC0+Y2FjaGVfc3RvcmUpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfY2FjaGVtYXAoYXNwLT5jYWNoZV9zdG9yZSk7CiAgICAgICAgYXNwLT5jYWNoZV9zdG9yZSA9IE5VTEw7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IGFzcC0+dmJjb3VudDsgaSsrKSB7CiAgICAgICAgaWYgKGFzcC0+cmVxdWVzdHNbaV0ucmVxdWVzdHZiID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogT2NjdXJzIHdoZW4gdGhlcmUncyBhIG1peHR1cmUgb2Ygc3RpbGwgYWN0aXZlCiAgICAgICAgICAgICAqICAgYW5kICJlbmRPZk1pYlZpZXciIHJlcGV0aXRpb25zCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKGFzcC0+cmVxdWVzdHNbaV0ucmVxdWVzdHZiLT50eXBlID09IEFTTl9OVUxMKSB7CiAgICAgICAgICAgIGlmICghbmV0c25tcF9hZGRfdmFyYmluZF90b19jYWNoZShhc3AsIGFzcC0+cmVxdWVzdHNbaV0uaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnJlcXVlc3RzW2ldLnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cmVxdWVzdHNbaV0uc3VidHJlZS0+bmV4dCkpIHsKICAgICAgICAgICAgICAgIGlmIChvbGRfdHJlZWNhY2hlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUob2xkX3RyZWVjYWNoZSk7CiAgICAgICAgICAgICAgICAgICAgb2xkX3RyZWVjYWNoZSA9IE5VTEw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGFzcC0+cmVxdWVzdHNbaV0ucmVxdWVzdHZiLT50eXBlID09IEFTTl9QUklWX1JFVFJZKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHJlLWFkZCB0aGUgc2FtZSBzdWJ0cmVlIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYXNwLT5yZXF1ZXN0c1tpXS5yZXF1ZXN0dmItPnR5cGUgPSBBU05fTlVMTDsKICAgICAgICAgICAgaWYgKCFuZXRzbm1wX2FkZF92YXJiaW5kX3RvX2NhY2hlKGFzcCwgYXNwLT5yZXF1ZXN0c1tpXS5pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cmVxdWVzdHNbaV0ucmVxdWVzdHZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5yZXF1ZXN0c1tpXS5zdWJ0cmVlKSkgewogICAgICAgICAgICAgICAgaWYgKG9sZF90cmVlY2FjaGUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShvbGRfdHJlZWNhY2hlKTsKICAgICAgICAgICAgICAgICAgICBvbGRfdHJlZWNhY2hlID0gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAob2xkX3RyZWVjYWNoZSAhPSBOVUxMKSB7CiAgICAgICAgU05NUF9GUkVFKG9sZF90cmVlY2FjaGUpOwogICAgfQogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCnZvaWQKbmV0c25tcF9kZWxldGVfcmVxdWVzdF9pbmZvcyhuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxbGlzdCkKewogICAgd2hpbGUgKHJlcWxpc3QpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxbGlzdCk7CiAgICAgICAgcmVxbGlzdCA9IHJlcWxpc3QtPm5leHQ7CiAgICB9Cn0KCnZvaWQKbmV0c25tcF9kZWxldGVfc3VidHJlZV9jYWNoZShuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgd2hpbGUgKGFzcC0+dHJlZWNhY2hlX251bSA+PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkb24ndCBkZWxldGUgc3VidHJlZXMgCiAgICAgICAgICovCiAgICAgICAgbmV0c25tcF9kZWxldGVfcmVxdWVzdF9pbmZvcyhhc3AtPnRyZWVjYWNoZVthc3AtPnRyZWVjYWNoZV9udW1dLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHNfYmVnaW4pOwogICAgICAgIGFzcC0+dHJlZWNhY2hlX251bS0tOwogICAgfQp9CgovKgogKiBjaGVjayBhbGwgcmVxdWVzdHMgZm9yIGVycm9ycwogKgogKiBATm90ZToKICogVGhpcyBmdW5jdGlvbiBpcyBhIGxpdHRsZSBkaWZmZXJlbnQgZnJvbSB0aGUgb3RoZXJzIGluIHRoYXQKICogaXQgZG9lcyBub3QgdXNlIGFueSBsaW5rZWQgbGlzdHMsIGluc3RlYWQgdXNpbmcgdGhlIG9yaWdpbmFsCiAqIGFzcCByZXF1ZXN0cyBhcnJheS4gVGhpcyBpcyBvZiBwYXJ0aWN1bGFyIGltcG9ydGFuY2UgZm9yCiAqIGNhc2VzIHdoZXJlIHRoZSBsaW5rZWQgbGlzdHMgYXJlIHVucmVsaWFibGUuIE9uZSBrbm93biBpbnN0YW5jZQogKiBvZiB0aGlzIHNjZW5hcmlvIG9jY3VycyB3aGVuIHRoZSByb3dfbWVyZ2UgaGVscGVyIGlzIHVzZWQsIHdoaWNoCiAqIG1heSB0ZW1wb3JhcmlseSBkaXNydXB0cyBsaW5rZWQgbGlzdHMgZHVyaW5nIGl0cyAoYW5kIGl0cyBjaGlsZHJlbnMpCiAqIGhhbmRsaW5nIG9mIHJlcXVlc3RzLgogKi8KaW50Cm5ldHNubXBfY2hlY2tfYWxsX3JlcXVlc3RzX2Vycm9yKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbG9va19mb3Jfc3BlY2lmaWMpCnsKICAgIGludCBpOwoKICAgIC8qCiAgICAgKiBmaW5kIGFueSBlcnJvcnMgbWFya2VkIGluIHRoZSByZXF1ZXN0cyAKICAgICAqLwogICAgZm9yKCBpID0gMDsgaSA8IGFzcC0+dmJjb3VudDsgKytpICkgewogICAgICAgIGlmICgoU05NUF9FUlJfTk9FUlJPUiAhPSBhc3AtPnJlcXVlc3RzW2ldLnN0YXR1cykgJiYKICAgICAgICAgICAgKCFsb29rX2Zvcl9zcGVjaWZpYyB8fAogICAgICAgICAgICAgYXNwLT5yZXF1ZXN0c1tpXS5zdGF0dXMgPT0gbG9va19mb3Jfc3BlY2lmaWMpKQogICAgICAgICAgICByZXR1cm4gYXNwLT5yZXF1ZXN0c1tpXS5zdGF0dXM7CiAgICB9CgogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCmludApuZXRzbm1wX2NoZWNrX3JlcXVlc3RzX2Vycm9yKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgLyoKICAgICAqIGZpbmQgYW55IGVycm9ycyBtYXJrZWQgaW4gdGhlIHJlcXVlc3RzIAogICAgICovCiAgICBmb3IgKDtyZXF1ZXN0cztyZXF1ZXN0cyA9IHJlcXVlc3RzLT5uZXh0KSB7CiAgICAgICAgaWYgKHJlcXVlc3RzLT5zdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikKICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RzLT5zdGF0dXM7CiAgICB9CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKaW50Cm5ldHNubXBfY2hlY2tfcmVxdWVzdHNfc3RhdHVzKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsb29rX2Zvcl9zcGVjaWZpYykKewogICAgLyoKICAgICAqIGZpbmQgYW55IGVycm9ycyBtYXJrZWQgaW4gdGhlIHJlcXVlc3RzIAogICAgICovCiAgICB3aGlsZSAocmVxdWVzdHMpIHsKICAgICAgICBpZihyZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8gIT0gYXNwLT5yZXFpbmZvKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJ2ZXJib3NlOmFzcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICIqKnJlcWluZm8gJXAgZG9lc24ndCBtYXRjaCBjYWNoZWQgcmVxaW5mbyAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5yZXFpbmZvLCByZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8pKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcXVlc3RzLT5zdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUiAmJgogICAgICAgICAgICAoIWxvb2tfZm9yX3NwZWNpZmljIHx8IHJlcXVlc3RzLT5zdGF0dXMgPT0gbG9va19mb3Jfc3BlY2lmaWMpCiAgICAgICAgICAgICYmIChsb29rX2Zvcl9zcGVjaWZpYyB8fCBhc3AtPmluZGV4ID09IDAKICAgICAgICAgICAgICAgIHx8IHJlcXVlc3RzLT5pbmRleCA8IGFzcC0+aW5kZXgpKSB7CiAgICAgICAgICAgIGFzcC0+aW5kZXggPSByZXF1ZXN0cy0+aW5kZXg7CiAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gcmVxdWVzdHMtPnN0YXR1czsKICAgICAgICB9CiAgICAgICAgcmVxdWVzdHMgPSByZXF1ZXN0cy0+bmV4dDsKICAgIH0KICAgIHJldHVybiBhc3AtPnN0YXR1czsKfQoKaW50Cm5ldHNubXBfY2hlY2tfYWxsX3JlcXVlc3RzX3N0YXR1cyhuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsb29rX2Zvcl9zcGVjaWZpYykKewogICAgaW50ICAgICAgICAgICAgIGk7CiAgICBmb3IgKGkgPSAwOyBpIDw9IGFzcC0+dHJlZWNhY2hlX251bTsgaSsrKSB7CiAgICAgICAgbmV0c25tcF9jaGVja19yZXF1ZXN0c19zdGF0dXMoYXNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlW2ldLnJlcXVlc3RzX2JlZ2luLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb2tfZm9yX3NwZWNpZmljKTsKICAgIH0KICAgIHJldHVybiBhc3AtPnN0YXR1czsKfQoKaW50CmhhbmRsZV92YXJfcmVxdWVzdHMobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGludCAgICAgICAgICAgICBpLCByZXRzdGF0dXMgPSBTTk1QX0VSUl9OT0VSUk9SLAogICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1IsIGZpbmFsX3N0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvOwoKICAgIGFzcC0+cmVxaW5mby0+YXNwID0gYXNwOwogICAgYXNwLT5yZXFpbmZvLT5tb2RlID0gYXNwLT5tb2RlOwoKICAgIC8qCiAgICAgKiBub3csIGhhdmUgdGhlIHN1YnRyZWVzIGluIHRoZSBjYWNoZSBnbyBzZWFyY2ggZm9yIHRoZWlyIHJlc3VsdHMgCiAgICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPD0gYXNwLT50cmVlY2FjaGVfbnVtOyBpKyspIHsKICAgICAgICAvKgogICAgICAgICAqIGRvbid0IGNhbGwgaGFuZGxlcnMgdy9udWxsIHJlZ2luZm8uCiAgICAgICAgICogLSB3aGVuIGlzIHRoaXM/IHN1YiBhZ2VudCBkaXNjb25uZWN0ZWQgd2hpbGUgcmVxdWVzdCBwcm9jZXNzaW5nPwogICAgICAgICAqIC0gc2hvdWxkIHRoaXMgY2FzZSBlbmNvbXBhc3MgbW9yZSBvZiB0aGlzIHN1YnJvdXRpbmU/CiAgICAgICAgICogICAtIGRvZXMgY2hlY2tfcmVxdWVzdF9zdGF0dXMgbWFrZSBzZW5kIGlmIGhhbmRsZXJzIHdlcmVuJ3QgY2FsbGVkPwogICAgICAgICAqLwogICAgICAgIGlmKE5VTEwgIT0gYXNwLT50cmVlY2FjaGVbaV0uc3VidHJlZS0+cmVnaW5mbykgewogICAgICAgICAgICByZWdpbmZvID0gYXNwLT50cmVlY2FjaGVbaV0uc3VidHJlZS0+cmVnaW5mbzsKICAgICAgICAgICAgc3RhdHVzID0gbmV0c25tcF9jYWxsX2hhbmRsZXJzKHJlZ2luZm8sIGFzcC0+cmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlW2ldLnJlcXVlc3RzX2JlZ2luKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9HRU5FUlI7CgogICAgICAgIC8qCiAgICAgICAgICogZmluZCBhbnkgZXJyb3JzIG1hcmtlZCBpbiB0aGUgcmVxdWVzdHMuICBGb3IgbGF0ZXIgcGFydHMgb2YKICAgICAgICAgKiBTRVQgcHJvY2Vzc2luZywgb25seSBjaGVjayBmb3IgbmV3IGVycm9ycyBzcGVjaWZpYyB0byB0aGF0CiAgICAgICAgICogc2V0IHByb2Nlc3NpbmcgZGlyZWN0aXZlICh3aGljaCBtdXN0IHN1cGVyY2VlZCB0aGUgcHJldmlvdXMKICAgICAgICAgKiBlcnJvcnMpLgogICAgICAgICAqLwogICAgICAgIHN3aXRjaCAoYXNwLT5tb2RlKSB7CiAgICAgICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgICAgIHJldHN0YXR1cyA9IG5ldHNubXBfY2hlY2tfcmVxdWVzdHNfc3RhdHVzKGFzcCwKCQkJCQkJICAgICAgYXNwLT50cmVlY2FjaGVbaV0uCgkJCQkJCSAgICAgIHJlcXVlc3RzX2JlZ2luLAoJCQkJCQkgICAgICBTTk1QX0VSUl9DT01NSVRGQUlMRUQpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgICAgICByZXRzdGF0dXMgPSBuZXRzbm1wX2NoZWNrX3JlcXVlc3RzX3N0YXR1cyhhc3AsCgkJCQkJCSAgICAgIGFzcC0+dHJlZWNhY2hlW2ldLgoJCQkJCQkgICAgICByZXF1ZXN0c19iZWdpbiwKCQkJCQkJICAgICAgU05NUF9FUlJfVU5ET0ZBSUxFRCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXRzdGF0dXMgPSBuZXRzbm1wX2NoZWNrX3JlcXVlc3RzX3N0YXR1cyhhc3AsCgkJCQkJCSAgICAgIGFzcC0+dHJlZWNhY2hlW2ldLgoJCQkJCQkgICAgICByZXF1ZXN0c19iZWdpbiwgMCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBhbHdheXMgdGFrZSBsb3dlc3QgdmFyYmluZCBpZiBwb3NzaWJsZSAKICAgICAgICAgKi8KICAgICAgICBpZiAocmV0c3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpIHsKICAgICAgICAgICAgc3RhdHVzID0gcmV0c3RhdHVzOwoJfQoKICAgICAgICAvKgogICAgICAgICAqIG90aGVyIHRoaW5ncyB3ZSBrbm93IGxlc3MgYWJvdXQgKG5vIGluZGV4KSAKICAgICAgICAgKi8KICAgICAgICAvKgogICAgICAgICAqIFdXVzogZHJvcCBzdXBwb3J0IGZvciB0aGlzPyAKICAgICAgICAgKi8KICAgICAgICBpZiAoZmluYWxfc3RhdHVzID09IFNOTVBfRVJSX05PRVJST1IgJiYgc3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogd2UgY2FuJ3QgYnJlYWsgaGVyZSwgc2luY2Ugc29tZSBwcm9jZXNzaW5nIG5lZWRzIHRvIGJlCiAgICAgICAgICAgICAqIGRvbmUgZm9yIGFsbCByZXF1ZXN0cyBhbnl3YXkgKElFLCBTRVQgaGFuZGxpbmcgZm9yIFVORE8KICAgICAgICAgICAgICogbmVlZHMgdG8gYmUgY2FsbGVkIHJlZ2FyZGxlc3Mgb2YgcHJldmlvdXMgc3RhdHVzCiAgICAgICAgICAgICAqIHJlc3VsdHMuCiAgICAgICAgICAgICAqIFdXVzogIFRoaXMgc2hvdWxkIGJlIHByZWRpY3RhYmxlIHRob3VnaCBhbmQKICAgICAgICAgICAgICogYnJlYWtpbmcgc2hvdWxkIGJlIHBvc3NpYmxlIGluIHNvbWUgY2FzZXMgKGVnIEdFVCwKICAgICAgICAgICAgICogR0VUTkVYVCwgLi4uKSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZpbmFsX3N0YXR1cyA9IHN0YXR1czsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGZpbmFsX3N0YXR1czsKfQoKLyoKICogbG9vcCB0aHJvdWdoIG91ciBzZXNzaW9ucyBrbm93biBkZWxlZ2F0ZWQgc2Vzc2lvbnMgYW5kIGNoZWNrIHRvIHNlZQogKiBpZiB0aGV5J3ZlIGNvbXBsZXRlZCB5ZXQuIElmIHRoZXJlIGFyZSBubyBtb3JlIGRlbGVnYXRlZCBzZXNzaW9ucywKICogY2hlY2sgZm9yIGFuZCBwcm9jZXNzIGFueSBxdWV1ZWQgcmVxdWVzdHMKICovCnZvaWQKbmV0c25tcF9jaGVja19vdXRzdGFuZGluZ19hZ2VudF9yZXF1ZXN0cyh2b2lkKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCwgKnByZXZfYXNwID0gTlVMTCwgKm5leHRfYXNwID0gTlVMTDsKCiAgICAvKgogICAgICogZGVhbCB3aXRoIGRlbGVnYXRlZCByZXF1ZXN0cwogICAgICovCiAgICBmb3IgKGFzcCA9IGFnZW50X2RlbGVnYXRlZF9saXN0OyBhc3A7IGFzcCA9IG5leHRfYXNwKSB7CiAgICAgICAgbmV4dF9hc3AgPSBhc3AtPm5leHQ7ICAgLyogc2F2ZSBpbiBjYXNlIHdlIGNsZWFuIHVwIGFzcCAqLwogICAgICAgIGlmICghbmV0c25tcF9jaGVja19mb3JfZGVsZWdhdGVkKGFzcCkpIHsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHdlJ3JlIGRvbmUgd2l0aCB0aGlzIG9uZSwgcmVtb3ZlIGZyb20gcXVldWUgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocHJldl9hc3AgIT0gTlVMTCkKICAgICAgICAgICAgICAgIHByZXZfYXNwLT5uZXh0ID0gYXNwLT5uZXh0OwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBhZ2VudF9kZWxlZ2F0ZWRfbGlzdCA9IGFzcC0+bmV4dDsKICAgICAgICAgICAgYXNwLT5uZXh0ID0gTlVMTDsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNoZWNrIHJlcXVlc3Qgc3RhdHVzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBuZXRzbm1wX2NoZWNrX2FsbF9yZXF1ZXN0c19zdGF0dXMoYXNwLCAwKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNvbnRpbnVlIHByb2Nlc3Npbmcgb3IgZmluaXNoIHVwIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2hlY2tfZGVsYXllZF9yZXF1ZXN0KGFzcCk7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpZiBoZWFkIHdhcyByZW1vdmVkLCBkb24ndCBkcm9wIGl0IGlmIGl0CiAgICAgICAgICAgICAqIHdhcyBpdCByZS1xdWV1ZWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgocHJldl9hc3AgPT0gTlVMTCkgJiYgKGFnZW50X2RlbGVnYXRlZF9saXN0ID09IGFzcCkpIHsKICAgICAgICAgICAgICAgIHByZXZfYXNwID0gYXNwOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFzcCBpcyBzdGlsbCBvbiB0aGUgcXVldWUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHByZXZfYXNwID0gYXNwOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogaWYgd2UgYXJlIHByb2Nlc3NpbmcgYSBzZXQgYW5kIHRoZXJlIGFyZSBtb3JlIGRlbGVnYXRlZAogICAgICogcmVxdWVzdHMsIGtlZXAgd2FpdGluZyBiZWZvcmUgZ2V0dGluZyB0byBxdWV1ZWQgcmVxdWVzdHMuCiAgICAgKi8KICAgIGlmIChuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0ICYmIChOVUxMICE9IGFnZW50X2RlbGVnYXRlZF9saXN0KSkKICAgICAgICByZXR1cm47CgogICAgd2hpbGUgKG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3QpIHsKCiAgICAgICAgLyoKICAgICAgICAgKiBpZiB3ZSBhcmUgcHJvY2Vzc2luZyBhIHNldCwgdGhlIGZpcnN0IGl0ZW0gYmV0dGVyIGJlCiAgICAgICAgICogdGhlIHNldCBiZWluZyAob3Igd2FpdGluZyB0byBiZSkgcHJvY2Vzc2VkLgogICAgICAgICAqLwogICAgICAgIG5ldHNubXBfYXNzZXJ0KCghbmV0c25tcF9wcm9jZXNzaW5nX3NldCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAobmV0c25tcF9wcm9jZXNzaW5nX3NldCA9PSBuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0KSk7CgogICAgICAgIC8qCiAgICAgICAgICogaWYgdGhlIHRvcCByZXF1ZXN0IGlzIGEgc2V0LCBkb24ndCBwb3AgaXQKICAgICAgICAgKiBvZmYgaWYgdGhlcmUgYXJlIGRlbGVnYXRlZCByZXF1ZXN0cwogICAgICAgICAqLwogICAgICAgIGlmICgobmV0c25tcF9hZ2VudF9xdWV1ZWRfbGlzdC0+cGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1NFVCkgJiYKICAgICAgICAgICAgKGFnZW50X2RlbGVnYXRlZF9saXN0KSkgewoKICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQobmV0c25tcF9wcm9jZXNzaW5nX3NldCA9PSBOVUxMKTsKCiAgICAgICAgICAgIG5ldHNubXBfcHJvY2Vzc2luZ19zZXQgPSBuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0OwogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJTRVQgcmVxdWVzdCByZW1haW5zIHF1ZXVlZCB3aGlsZSAiCiAgICAgICAgICAgICAgICAgICAgICAgICJkZWxlZ2F0ZWQgcmVxdWVzdHMgZmluaXNoLCBhc3AgPSAlMDhwXG4iLCBhc3ApKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIHBvcCB0aGUgZmlyc3QgcmVxdWVzdCBhbmQgcHJvY2VzcyBpdAogICAgICAgICAqLwogICAgICAgIGFzcCA9IG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3Q7CiAgICAgICAgbmV0c25tcF9hZ2VudF9xdWV1ZWRfbGlzdCA9IGFzcC0+bmV4dDsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsCiAgICAgICAgICAgICAgICAgICAgInByb2Nlc3NpbmcgcXVldWVkIHJlcXVlc3QsIGFzcCA9ICUwOHBcbiIsIGFzcCkpOwoKICAgICAgICBuZXRzbm1wX2hhbmRsZV9yZXF1ZXN0KGFzcCwgYXNwLT5zdGF0dXMpOwoKICAgICAgICAvKgogICAgICAgICAqIGlmIHdlIGhpdCBhIHNldCwgc3RvcAogICAgICAgICAqLwogICAgICAgIGlmIChOVUxMICE9IG5ldHNubXBfcHJvY2Vzc2luZ19zZXQpCiAgICAgICAgICAgIGJyZWFrOwogICAgfQp9CgovKiogRGVjaWRlIGlmIHRoZSByZXF1ZXN0ZWQgdHJhbnNhY3Rpb25faWQgaXMgc3RpbGwgYmVpbmcgcHJvY2Vzc2VkCiAgIHdpdGhpbiB0aGUgYWdlbnQuICBUaGlzIGlzIHVzZWQgdG8gdmFsaWRhdGUgd2hldGhlciBhIGRlbGF5ZWQgY2FjaGUKICAgKGNvbnRhaW5pbmcgcG9zc2libHkgZnJlZWQgcG9pbnRlcnMpIGlzIHN0aWxsIHVzYWJsZS4KCiAgIHJldHVybnMgU05NUEVSUl9TVUNDRVNTIGlmIGl0J3Mgc3RpbGwgdmFsaWQsIG9yIFNOTVBFUlJfR0VORVJSIGlmIG5vdC4gKi8KaW50Cm5ldHNubXBfY2hlY2tfdHJhbnNhY3Rpb25faWQoaW50IHRyYW5zYWN0aW9uX2lkKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcDsKCiAgICBmb3IgKGFzcCA9IGFnZW50X2RlbGVnYXRlZF9saXN0OyBhc3A7IGFzcCA9IGFzcC0+bmV4dCkgewogICAgICAgIGlmIChhc3AtPnBkdS0+dHJhbnNpZCA9PSB0cmFuc2FjdGlvbl9pZCkKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKICAgIH0KICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKfQoKCi8qCiAqIGNoZWNrX2RlbGF5ZWRfcmVxdWVzdChhc3ApCiAqCiAqIENhbGxlZCB0byByZXhhbWluZSBhIHNldCBvZiByZXF1ZXN0cyBhbmQgY29udGludWUgcHJvY2Vzc2luZyB0aGVtCiAqIG9uY2UgYWxsIHRoZSBwcmV2aW91cyAoZGVsYXllZCkgcmVxdWVzdHMgaGF2ZSBiZWVuIGhhbmRsZWQgb25lIHdheQogKiBvciBhbm90aGVyLgogKi8KCmludApjaGVja19kZWxheWVkX3JlcXVlc3QobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGludCAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9OT0VSUk9SOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgInByb2Nlc3NpbmcgZGVsZWdhdGVkIHJlcXVlc3QsIGFzcCA9ICUwOHBcbiIsCiAgICAgICAgICAgICAgICBhc3ApKTsKCiAgICBzd2l0Y2ggKGFzcC0+bW9kZSkgewogICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOgogICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgIG5ldHNubXBfY2hlY2tfYWxsX3JlcXVlc3RzX3N0YXR1cyhhc3AsIDApOwogICAgICAgIGhhbmRsZV9nZXRuZXh0X2xvb3AoYXNwKTsKICAgICAgICBpZiAobmV0c25tcF9jaGVja19mb3JfZGVsZWdhdGVkKGFzcCkgJiYKICAgICAgICAgICAgbmV0c25tcF9jaGVja190cmFuc2FjdGlvbl9pZChhc3AtPnBkdS0+dHJhbnNpZCkgIT0KICAgICAgICAgICAgU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFkZCB0byBkZWxlZ2F0ZWQgcmVxdWVzdCBjaGFpbiAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICghbmV0c25tcF9jaGVja19kZWxlZ2F0ZWRfY2hhaW5fZm9yKGFzcCkpIHsKICAgICAgICAgICAgICAgIGFzcC0+bmV4dCA9IGFnZW50X2RlbGVnYXRlZF9saXN0OwogICAgICAgICAgICAgICAgYWdlbnRfZGVsZWdhdGVkX2xpc3QgPSBhc3A7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgbmV0c25tcF9jaGVja19hbGxfcmVxdWVzdHNfc3RhdHVzKGFzcCwgU05NUF9FUlJfQ09NTUlURkFJTEVEKTsKICAgICAgICBnb3RvIHNldHRvcDsKCiAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgbmV0c25tcF9jaGVja19hbGxfcmVxdWVzdHNfc3RhdHVzKGFzcCwgU05NUF9FUlJfVU5ET0ZBSUxFRCk7CiAgICAgICAgZ290byBzZXR0b3A7CgogICAgY2FzZSBNT0RFX1NFVF9CRUdJTjoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgIHNldHRvcDoKICAgICAgICAvKiBJZiB3ZSBzaG91bGQgZG8gb25seSBvbmUgcGFzcywgdGhpcyBtZWFuIHdlICovCiAgICAgICAgLyogc2hvdWxkIG5vdCByZWVudGVyIHRoaXMgZnVuY3Rpb24gKi8KICAgICAgICBpZiAoKGFzcC0+cGR1LT5mbGFncyAmIFVDRF9NU0dfRkxBR19PTkVfUEFTU19PTkxZKSkgewogICAgICAgICAgICAvKiBXZSBzaG91bGQgaGF2ZSBmaW5pc2hlZCB0aGUgcHJvY2Vzc2luZyBhZnRlciB0aGUgZmlyc3QgKi8KICAgICAgICAgICAgLyogaGFuZGxlX3NldF9sb29wLCBzbyBqdXN0IHdyYXAgdXAgKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGhhbmRsZV9zZXRfbG9vcChhc3ApOwogICAgICAgIGlmIChhc3AtPm1vZGUgIT0gRklOSVNIRURfU1VDQ0VTUyAmJiBhc3AtPm1vZGUgIT0gRklOSVNIRURfRkFJTFVSRSkgewoKICAgICAgICAgICAgaWYgKG5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZF9hbmRfYWRkKGFzcCkpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBhZGQgdG8gZGVsZWdhdGVkIHJlcXVlc3QgY2hhaW4gCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICghYXNwLT5zdGF0dXMpCiAgICAgICAgICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBzdGF0dXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIGJyZWFrOwogICAgfQoKICAgIC8qCiAgICAgKiBpZiB3ZSBkb24ndCBoYXZlIGFueXRoaW5nIG91dHN0YW5kaW5nIChkZWxlZ2F0ZWQpLCB3cmFwIHVwIAogICAgICovCiAgICBpZiAoIW5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZChhc3ApKQogICAgICAgIHJldHVybiBuZXRzbm1wX3dyYXBfdXBfcmVxdWVzdChhc3AsIHN0YXR1cyk7CgogICAgcmV0dXJuIDE7Cn0KCi8qKiByZXR1cm5zIDEgaWYgdGhlcmUgYXJlIHZhbGlkIEdFVE5FWFQgcmVxdWVzdHMgbGVmdC4gIFJldHVybnMgMCBpZiBub3QuICovCmludApjaGVja19nZXRuZXh0X3Jlc3VsdHMobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIC8qCiAgICAgKiBnZXQgb2xkIGluZm8gCiAgICAgKi8KICAgIG5ldHNubXBfdHJlZV9jYWNoZSAqb2xkX3RyZWVjYWNoZSA9IGFzcC0+dHJlZWNhY2hlOwogICAgaW50ICAgICAgICAgICAgIG9sZF90cmVlY2FjaGVfbnVtID0gYXNwLT50cmVlY2FjaGVfbnVtOwogICAgaW50ICAgICAgICAgICAgIGNvdW50ID0gMDsKICAgIGludCAgICAgICAgICAgICBpLCBzcGVjaWFsID0gMDsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0OwoKICAgIGlmIChhc3AtPm1vZGUgPT0gU05NUF9NU0dfR0VUKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBTcGVjaWFsIGNhc2UgZm9yIGRvaW5nIElOQ0xVU0lWRSBnZXROZXh0IG9wZXJhdGlvbnMgaW4KICAgICAgICAgKiBBZ2VudFggc3ViYWdlbnRzLiAgCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLAogICAgICAgICAgICAgICAgICAgICJhc3AtPm1vZGUgPT0gU05NUF9NU0dfR0VUIGluIGNoX2dldG5leHRcbiIpKTsKICAgICAgICBhc3AtPm1vZGUgPSBhc3AtPm9sZG1vZGU7CiAgICAgICAgc3BlY2lhbCA9IDE7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8PSBvbGRfdHJlZWNhY2hlX251bTsgaSsrKSB7CiAgICAgICAgZm9yIChyZXF1ZXN0ID0gb2xkX3RyZWVjYWNoZVtpXS5yZXF1ZXN0c19iZWdpbjsgcmVxdWVzdDsKICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJZiB3ZSBoYXZlIGp1c3QgZG9uZSB0aGUgc3BlY2lhbCBjYXNlIEFnZW50WCBHRVQsIHRoZW4gYW55CiAgICAgICAgICAgICAqIHJlcXVlc3RzIHdoaWNoIHdlcmUgbm90IElOQ0xVU0lWRSB3aWxsIG5vdyBoYXZlIGEgd3JvbmcKICAgICAgICAgICAgICogcmVzcG9uc2UsIHNvIGp1bmsgdGhlbSBhbmQgcmV0cnkgZnJvbSB0aGUgc2FtZSBwbGFjZSAoZXhjZXB0CiAgICAgICAgICAgICAqIHRoYXQgdGhpcyB0aW1lIHRoZSBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIGluICJpbmV4YWN0IgogICAgICAgICAgICAgKiBtb2RlKS4gIAogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmIChzcGVjaWFsKSB7CiAgICAgICAgICAgICAgICBpZiAoIXJlcXVlc3QtPmluY2x1c2l2ZSkgewogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVxdWVzdCAlZCB3YXNuJ3QgaW5jbHVzaXZlXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluZGV4KSk7CiAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3QtPnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX1BSSVZfUkVUUlksIE5VTEwsIDApOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX05VTEwgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID09IFNOTVBfTk9TVUNISU5TVEFOQ0UgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID09IFNOTVBfTk9TVUNIT0JKRUNUKSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBpdCB3YXMgaW5jbHVzaXZlLCBidXQgbm8gcmVzdWx0cy4gIFN0aWxsIHJldHJ5IHRoaXMKICAgICAgICAgICAgICAgICAgICAgKiBzZWFyY2guIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0LT5yZXF1ZXN0dmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9QUklWX1JFVFJZLCBOVUxMLCAwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogb3V0IG9mIHJhbmdlPyAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChzbm1wX29pZF9jb21wYXJlKHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmFuZ2VfZW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuKSA+PSAwKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogYWNrLCBpdCdzIGJleW9uZCB0aGUgYWNjZXB0ZWQgZW5kIG9mIHJhbmdlLiAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGZpeCBpdCBieSBzZXR0aW5nIHRoZSBvaWQgdG8gdGhlIGVuZCBvZiByYW5nZSBvaWQgaW5zdGVhZCAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImNoZWNrX2dldG5leHRfcmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVxdWVzdCByZXNwb25zZSAlZCBvdXQgb2YgcmFuZ2VcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5pbmRleCkpOwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIEknbSBub3Qgc3VyZSB3aHkgaW5jbHVzaXZlIGlzIHNldCB1bmNvbmRpdGlvbmFsbHkgaGVyZSAoc2VlCiAgICAgICAgICAgICAgICAgKiBjb21tZW50cyBmb3IgcmV2aXNpb24gMS4xNjEpLCBidXQgaXQgY2F1c2VzIGEgcHJvYmxlbSBmb3IKICAgICAgICAgICAgICAgICAqIEdFVEJVTEsgb3ZlciBhbiBvdmVycmlkZGVuIHZhcmlhYmxlLiBUaGUgYnVsay10by1uZXh0CiAgICAgICAgICAgICAgICAgKiBoYW5kbGVyIHJlLXVzZXMgdGhlIHNhbWUgcmVxdWVzdCBmb3IgbXVsdGlwbGUgdmFyYmluZHMsCiAgICAgICAgICAgICAgICAgKiBhbmQgb25jZSBpbmNsdXNpdmUgd2FzIHNldCwgaXQgd2FzIG5ldmVyIGNsZWFyZWQuIFNvLCBhCiAgICAgICAgICAgICAgICAgKiBoYWNrLiBJbnN0ZWFkIG9mIHNldHRpbmcgaXQgdG8gMSwgc2V0IGl0IHRvIDIsIHNvIGJ1bGstdG8KICAgICAgICAgICAgICAgICAqIG5leHQgY2FuIGNsZWFyIGl0IGxhdGVyLiBBcyBvZiB0aGUgdGltZSBvZiB0aGlzIGhhY2ssIGFsbAogICAgICAgICAgICAgICAgICogY2hlY2tzIG9mIHRoaXMgdmFyIGFyZSBib29sZWFuIGNoZWNrcyAobm90ID09IDEpLCBzbyB0aGlzCiAgICAgICAgICAgICAgICAgKiBzaG91bGQgYmUgc2FmZS4gQ3Jvc3MgeW91ciBmaW5nZXJzLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICByZXF1ZXN0LT5pbmNsdXNpdmUgPSAyOwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFhYWDogc2hvdWxkIHNldCB0aGlzIHRvIHRoZSBvcmlnaW5hbCBPSUQ/IAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQocmVxdWVzdC0+cmVxdWVzdHZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuKTsKICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0LT5yZXF1ZXN0dmIsIEFTTl9OVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBtYXJrIGFueSBleGlzdGVudCByZXF1ZXN0cyB3aXRoIGlsbGVnYWwgcmVzdWx0cyBhcyBOVUxMIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBTTk1QX0VORE9GTUlCVklFVykgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGlsbGVnYWwgcmVzcG9uc2UgZnJvbSBhIHN1YmFnZW50LiAgQ2hhbmdlIGl0IGJhY2sgdG8gTlVMTCAKICAgICAgICAgICAgICAgICAqICB4eHgtcmtzOiBlcnIsIGhvdyBkbyB3ZSBrbm93IHRoaXMgaXMgYSBzdWJhZ2VudD8KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID0gQVNOX05VTEw7CiAgICAgICAgICAgICAgICByZXF1ZXN0LT5pbmNsdXNpdmUgPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID09IEFTTl9OVUxMIHx8CiAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX1BSSVZfUkVUUlkgfHwKICAgICAgICAgICAgICAgIChhc3AtPnJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRCVUxLCiAgICAgICAgICAgICAgICAgJiYgcmVxdWVzdC0+cmVwZWF0ID4gMCkpCiAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBjb3VudDsKfQoKLyoqIHJlcGVhdGVkbHkgY2FsbHMgZ2V0bmV4dCBoYW5kbGVycyBsb29raW5nIGZvciBhbiBhbnN3ZXIgdGlsbCBhbGwKICAgcmVxdWVzdHMgYXJlIHNhdGlzaWZpZWQuICBJdCdzIGV4cGVjdGVkIHRoYXQgb25lIHBhc3MgaGFzIGJlZW4gbWFkZQogICBiZWZvcmUgZW50ZXJpbmcgdGhpcyBmdW5jdGlvbiAqLwppbnQKaGFuZGxlX2dldG5leHRfbG9vcChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgaW50ICAgICAgICAgICAgIHN0YXR1czsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyX3B0cjsKCiAgICAvKgogICAgICogbG9vcCAKICAgICAqLwogICAgd2hpbGUgKG5ldHNubXBfcnVubmluZykgewoKICAgICAgICAvKgogICAgICAgICAqIGJhaWwgZm9yIG5vdyBpZiBhbnl0aGluZyBpcyBkZWxlZ2F0ZWQuIAogICAgICAgICAqLwogICAgICAgIGlmIChuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWQoYXNwKSkgewogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogY2hlY2sgdmFjbSBhZ2FpbnN0IHJlc3VsdHMgCiAgICAgICAgICovCiAgICAgICAgY2hlY2tfYWNtKGFzcCwgQVNOX1BSSVZfUkVUUlkpOwoKICAgICAgICAvKgogICAgICAgICAqIG5lZWQgdG8ga2VlcCBnb2luZyB3ZSdyZSBub3QgZG9uZSB5ZXQuIAogICAgICAgICAqLwogICAgICAgIGlmICghY2hlY2tfZ2V0bmV4dF9yZXN1bHRzKGFzcCkpCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG5vdGhpbmcgbGVmdCwgcXVpdCBub3cgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgLyoKICAgICAgICAgKiBuZXZlciBoYWQgYSByZXF1ZXN0IChlbXB0eSBwZHUpLCBxdWl0IG5vdyAKICAgICAgICAgKi8KICAgICAgICAvKgogICAgICAgICAqIFhYWFdXVzogaHVoPyAgdGhpcyB3b3VsZCBiZSB0b28gbGF0ZSwgbm8/ICBzaG91bGRuJ3Qgd2UKICAgICAgICAgKiBjYXRjaCB0aGlzIGVhcmxpZXI/IAogICAgICAgICAqLwogICAgICAgIC8qCiAgICAgICAgICogaWYgKGNvdW50ID09IDApCiAgICAgICAgICogYnJlYWs7IAogICAgICAgICAqLwoKICAgICAgICBERUJVR0lGKCJyZXN1bHRzIikgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJnZXRuZXh0IHJlc3VsdHMsIGJlZm9yZSBuZXh0IHBhc3M6XG4iKSk7CiAgICAgICAgICAgIGZvciAodmFyX3B0ciA9IGFzcC0+cGR1LT52YXJpYWJsZXM7IHZhcl9wdHI7CiAgICAgICAgICAgICAgICAgdmFyX3B0ciA9IHZhcl9wdHItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZXN1bHRzIiwgIlx0IikpOwogICAgICAgICAgICAgICAgREVCVUdNU0dWQVIoKCJyZXN1bHRzIiwgdmFyX3B0cikpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJyZXN1bHRzIiwgIlxuIikpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBuZXRzbm1wX3JlYXNzaWduX3JlcXVlc3RzKGFzcCk7CiAgICAgICAgc3RhdHVzID0gaGFuZGxlX3Zhcl9yZXF1ZXN0cyhhc3ApOwogICAgICAgIGlmIChzdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikgewogICAgICAgICAgICByZXR1cm4gc3RhdHVzOyAgICAgIC8qIHNob3VsZCBuZXZlciByZWFsbHkgaGFwcGVuICovCiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCmludApoYW5kbGVfc2V0KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzOwogICAgLyoKICAgICAqIFNFVFMgcmVxdWlyZSAzLTQgcGFzc2VzIHRocm91Z2ggdGhlIHZhcl9vcF9saXN0LgogICAgICogVGhlIGZpcnN0IHR3bwogICAgICogcGFzc2VzIHZlcmlmeSB0aGF0IGFsbCB0eXBlcywgbGVuZ3RocywgYW5kIHZhbHVlcyBhcmUgdmFsaWQKICAgICAqIGFuZCBtYXkgcmVzZXJ2ZSByZXNvdXJjZXMgYW5kIHRoZSB0aGlyZCBkb2VzIHRoZSBzZXQgYW5kIGEKICAgICAqIGZvdXJ0aCBleGVjdXRlcyBhbnkgYWN0aW9ucy4gIFRoZW4gdGhlIGlkZW50aWNhbCBHRVQgUkVTUE9OU0UKICAgICAqIHBhY2tldCBpcyByZXR1cm5lZC4KICAgICAqIElmIGVpdGhlciBvZiB0aGUgZmlyc3QgdHdvIHBhc3NlcyByZXR1cm5zIGFuIGVycm9yLCBhbm90aGVyCiAgICAgKiBwYXNzIGlzIG1hZGUgc28gdGhhdCBhbnkgcmVzZXJ2ZWQgcmVzb3VyY2VzIGNhbiBiZSBmcmVlZC4KICAgICAqIElmIHRoZSB0aGlyZCBwYXNzIHJldHVybnMgYW4gZXJyb3IsIGFub3RoZXIgcGFzcyBpcwogICAgICogbWFkZSBzbyB0aGF0CiAgICAgKiBhbnkgY2hhbmdlcyBjYW4gYmUgcmV2ZXJzZWQuCiAgICAgKiBJZiB0aGUgZm91cnRoIHBhc3MgKG9yIGFueSBvZiB0aGUgZXJyb3IgaGFuZGxpbmcgcGFzc2VzKQogICAgICogcmV0dXJuIGFuIGVycm9yLCB3ZSdkIHJhdGhlciBub3Qga25vdyBhYm91dCBpdCEKICAgICAqLwogICAgaWYgKCEoYXNwLT5wZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX09ORV9QQVNTX09OTFkpKSB7CiAgICAgICAgc3dpdGNoIChhc3AtPm1vZGUpIHsKICAgICAgICBjYXNlIE1PREVfU0VUX0JFR0lOOgogICAgICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5TRVRSRVFVRVNUUyk7CiAgICAgICAgICAgIGFzcC0+cncgPSBXUklURTsgICAgLyogV1dXOiBzdGlsbCBuZWVkZWQ/ICovCiAgICAgICAgICAgIGFzcC0+bW9kZSA9IE1PREVfU0VUX1JFU0VSVkUxOwogICAgICAgICAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgoKICAgICAgICAgICAgaWYgKGFzcC0+c3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpCiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBNT0RFX1NFVF9GUkVFOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBNT0RFX1NFVF9SRVNFUlZFMjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICAgICAgICAgIGlmIChhc3AtPnN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SKQogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gTU9ERV9TRVRfRlJFRTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gTU9ERV9TRVRfQUNUSU9OOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICAgICAgICAgIGlmIChhc3AtPnN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SKQogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gTU9ERV9TRVRfVU5ETzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gTU9ERV9TRVRfQ09NTUlUOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgICAgIGlmIChhc3AtPnN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SKSB7CiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBGSU5JU0hFRF9GQUlMVVJFOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gRklOSVNIRURfU1VDQ0VTUzsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgICAgICBhc3AtPm1vZGUgPSBGSU5JU0hFRF9GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgICAgICAgICBhc3AtPm1vZGUgPSBGSU5JU0hFRF9GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9TVUNDRVNTICYmIGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9GQUlMVVJFKSB7CiAgICAgICAgREVCVUdNU0dUTCgoImFnZW50X3NldCIsICJkb2luZyBzZXQgbW9kZSA9ICVkICglcylcbiIsIGFzcC0+bW9kZSwKICAgICAgICAgICAgICAgICAgICBzZV9maW5kX2xhYmVsX2luX3NsaXN0KCJhZ2VudF9tb2RlIiwgYXNwLT5tb2RlKSkpOwogICAgICAgIHN0YXR1cyA9IGhhbmRsZV92YXJfcmVxdWVzdHMoYXNwKTsKICAgICAgICBERUJVR01TR1RMKCgiYWdlbnRfc2V0IiwgImRpZCBzZXQgbW9kZSA9ICVkLCBzdGF0dXMgPSAlZFxuIiwKICAgICAgICAgICAgICAgICAgICBhc3AtPm1vZGUsIHN0YXR1cykpOwogICAgICAgIGlmICgoc3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IgJiYgYXNwLT5zdGF0dXMgPT0gU05NUF9FUlJfTk9FUlJPUikgfHwKCSAgICBzdGF0dXMgPT0gU05NUF9FUlJfQ09NTUlURkFJTEVEIHx8IAoJICAgIHN0YXR1cyA9PSBTTk1QX0VSUl9VTkRPRkFJTEVEKSB7CiAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gc3RhdHVzOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBhc3AtPnN0YXR1czsKfQoKaW50CmhhbmRsZV9zZXRfbG9vcChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgd2hpbGUgKGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9GQUlMVVJFICYmIGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9TVUNDRVNTKSB7CiAgICAgICAgaGFuZGxlX3NldChhc3ApOwogICAgICAgIGlmIChuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWQoYXNwKSkgewogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKCX0KICAgICAgICBpZiAoYXNwLT5wZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX09ORV9QQVNTX09OTFkpIHsKICAgICAgICAgICAgcmV0dXJuIGFzcC0+c3RhdHVzOwoJfQogICAgfQogICAgcmV0dXJuIGFzcC0+c3RhdHVzOwp9CgppbnQKbmV0c25tcF9oYW5kbGVfcmVxdWVzdChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCwgaW50IHN0YXR1cykKewogICAgLyoKICAgICAqIGlmIHRoaXMgaXNuJ3QgYSBkZWxlZ2F0ZWQgcmVxdWVzdCB0cnlpbmcgdG8gZmluaXNoLAogICAgICogcHJvY2Vzc2luZyBvZiBhIHNldCByZXF1ZXN0IHNob3VsZCBub3Qgc3RhcnQgdW50aWwgYWxsCiAgICAgKiBkZWxlZ2F0ZWQgcmVxdWVzdHMgaGF2ZSBjb21wbGV0ZWQsIGFuZCBubyBvdGhlciBuZXcgcmVxdWVzdHMKICAgICAqIHNob3VsZCBiZSBwcm9jZXNzZWQgdW50aWwgdGhlIHNldCByZXF1ZXN0IGNvbXBsZXRlcy4KICAgICAqLwogICAgaWYgKCgwID09IG5ldHNubXBfY2hlY2tfZGVsZWdhdGVkX2NoYWluX2Zvcihhc3ApKSAmJgogICAgICAgIChhc3AgIT0gbmV0c25tcF9wcm9jZXNzaW5nX3NldCkpIHsKICAgICAgICAvKgogICAgICAgICAqIGlmIHdlIGFyZSBwcm9jZXNzaW5nIGEgc2V0IGFuZCB0aGlzIGlzIG5vdCBhIGRlbGVnYXRlZAogICAgICAgICAqIHJlcXVlc3QsIHF1ZXVlIHRoZSByZXF1ZXN0CiAgICAgICAgICovCiAgICAgICAgaWYgKG5ldHNubXBfcHJvY2Vzc2luZ19zZXQpIHsKICAgICAgICAgICAgbmV0c25tcF9hZGRfcXVldWVkKGFzcCk7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgInJlcXVlc3QgcXVldWVkIHdoaWxlIHByb2Nlc3Npbmcgc2V0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICJhc3AgPSAlMDhwXG4iLCBhc3ApKTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIGZvciBzZXQgcmVxdWVzdAogICAgICAgICAqLwogICAgICAgIGlmIChhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19TRVQpIHsKICAgICAgICAgICAgbmV0c25tcF9wcm9jZXNzaW5nX3NldCA9IGFzcDsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGlmIHRoZXJlIGFyZSBkZWxlZ2F0ZWQgcmVxdWVzdHMsIHdlIG11c3Qgd2FpdCBmb3IgdGhlbQogICAgICAgICAgICAgKiB0byBmaW5pc2guCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoYWdlbnRfZGVsZWdhdGVkX2xpc3QpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgIlNFVCByZXF1ZXN0IHF1ZXVlZCB3aGlsZSAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVsZWdhdGVkIHJlcXVlc3RzIGZpbmlzaCwgYXNwID0gJTA4cFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcCkpOwogICAgICAgICAgICAgICAgbmV0c25tcF9hZGRfcXVldWVkKGFzcCk7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogcHJvY2VzcyB0aGUgcmVxdWVzdCAKICAgICAqLwogICAgc3RhdHVzID0gaGFuZGxlX3BkdShhc3ApOwoKICAgIC8qCiAgICAgKiBwcmludCB0aGUgcmVzdWx0cyBpbiBhcHByb3ByaWF0ZSBkZWJ1Z2dpbmcgbW9kZSAKICAgICAqLwogICAgREVCVUdJRigicmVzdWx0cyIpIHsKICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcl9wdHI7CiAgICAgICAgREVCVUdNU0dUTCgoInJlc3VsdHMiLCAicmVxdWVzdCByZXN1bHRzIChzdGF0dXMgPSAlZCk6XG4iLAogICAgICAgICAgICAgICAgICAgIHN0YXR1cykpOwogICAgICAgIGZvciAodmFyX3B0ciA9IGFzcC0+cGR1LT52YXJpYWJsZXM7IHZhcl9wdHI7CiAgICAgICAgICAgICB2YXJfcHRyID0gdmFyX3B0ci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVzdWx0cyIsICJcdCIpKTsKICAgICAgICAgICAgREVCVUdNU0dWQVIoKCJyZXN1bHRzIiwgdmFyX3B0cikpOwogICAgICAgICAgICBERUJVR01TRygoInJlc3VsdHMiLCAiXG4iKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBjaGVjayBmb3IgdW5jb21wbGV0ZWQgcmVxdWVzdHMgCiAgICAgKi8KICAgIGlmIChuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWRfYW5kX2FkZChhc3ApKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBhZGQgdG8gZGVsZWdhdGVkIHJlcXVlc3QgY2hhaW4gCiAgICAgICAgICovCiAgICAgICAgYXNwLT5zdGF0dXMgPSBzdGF0dXM7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogaWYgd2UgZG9uJ3QgaGF2ZSBhbnl0aGluZyBvdXRzdGFuZGluZyAoZGVsZWdhdGVkKSwgd3JhcCB1cAogICAgICAgICAqLwogICAgICAgIHJldHVybiBuZXRzbm1wX3dyYXBfdXBfcmVxdWVzdChhc3AsIHN0YXR1cyk7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCmludApoYW5kbGVfcGR1KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzLCBpbmNsdXNpdmVzID0gMDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdiA9IE5VTEw7CgogICAgLyoKICAgICAqIGZvciBpbGxlZ2FsIHJlcXVlc3RzLCBtYXJrIGFsbCBub2RlcyBhcyBBU05fTlVMTCAKICAgICAqLwogICAgc3dpdGNoIChhc3AtPnBkdS0+Y29tbWFuZCkgewoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUyOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQUNUSU9OOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQ09NTUlUOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfRlJFRToKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1VORE86CiAgICAgICAgc3RhdHVzID0gZ2V0X3NldF9jYWNoZShhc3ApOwogICAgICAgIGlmIChzdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikKICAgICAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgIGNhc2UgU05NUF9NU0dfR0VUQlVMSzoKICAgICAgICBmb3IgKHYgPSBhc3AtPnBkdS0+dmFyaWFibGVzOyB2ICE9IE5VTEw7IHYgPSB2LT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgIGlmICh2LT50eXBlID09IEFTTl9QUklWX0lOQ0xfUkFOR0UpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBMZWF2ZSB0aGUgdHlwZSBmb3Igbm93IChpdCBnZXRzIHNldCB0bwogICAgICAgICAgICAgICAgICogQVNOX05VTEwgaW4gbmV0c25tcF9hZGRfdmFyYmluZF90b19jYWNoZSwKICAgICAgICAgICAgICAgICAqIGNhbGxlZCBieSBjcmVhdGVfc3VibmV0c25tcF90cmVlX2NhY2hlIGJlbG93KS4KICAgICAgICAgICAgICAgICAqIElmIHdlIHNldCBpdCB0byBBU05fTlVMTCBub3csIHdlIHdvdWxkbid0IGJlCiAgICAgICAgICAgICAgICAgKiBhYmxlIHRvIGRpc3Rpbmd1aXNoIElOQ0xVU0lWRSBzZWFyY2gKICAgICAgICAgICAgICAgICAqIHJhbmdlcy4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpbmNsdXNpdmVzKys7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUodiwgQVNOX05VTEwsIE5VTEwsIDApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogZmFsbCB0aHJvdWdoIAogICAgICAgICAqLwoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX0JFR0lOOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfUkVTRVJWRTE6CiAgICBkZWZhdWx0OgogICAgICAgIGFzcC0+dmJjb3VudCA9IGNvdW50X3ZhcmJpbmRzKGFzcC0+cGR1LT52YXJpYWJsZXMpOwogICAgICAgIGlmIChhc3AtPnZiY291bnQpIC8qIGVmZW5jZSBkb2Vzbid0IGxpa2UgMCBzaXplIGFsbG9jcyAqLwogICAgICAgICAgICBhc3AtPnJlcXVlc3RzID0gKG5ldHNubXBfcmVxdWVzdF9pbmZvICopCiAgICAgICAgICAgICAgICBjYWxsb2MoYXNwLT52YmNvdW50LCBzaXplb2YobmV0c25tcF9yZXF1ZXN0X2luZm8pKTsKICAgICAgICAvKgogICAgICAgICAqIGNvbGxlY3QgdmFyYmluZHMgCiAgICAgICAgICovCiAgICAgICAgc3RhdHVzID0gbmV0c25tcF9jcmVhdGVfc3VidHJlZV9jYWNoZShhc3ApOwogICAgICAgIGlmIChzdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikKICAgICAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgIH0KCiAgICBhc3AtPm1vZGUgPSBhc3AtPnBkdS0+Y29tbWFuZDsKICAgIHN3aXRjaCAoYXNwLT5tb2RlKSB7CiAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgICAgICAvKgogICAgICAgICAqIGluY3JlbWVudCB0aGUgbWVzc2FnZSB0eXBlIGNvdW50ZXIgCiAgICAgICAgICovCiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOR0VUUkVRVUVTVFMpOwoKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIHZhY20gYWhlYWQgb2YgdGltZSAKICAgICAgICAgKi8KICAgICAgICBjaGVja19hY20oYXNwLCBTTk1QX05PU1VDSE9CSkVDVCk7CgogICAgICAgIC8qCiAgICAgICAgICogZ2V0IHRoZSByZXN1bHRzIAogICAgICAgICAqLwogICAgICAgIHN0YXR1cyA9IGhhbmRsZV92YXJfcmVxdWVzdHMoYXNwKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBEZWFsIHdpdGggdW5oYW5kbGVkIHJlc3VsdHMgLT4gbm9TdWNoSW5zdGFuY2UgKHJhdGhlcgogICAgICAgICAqIHRoYW4gbm9TdWNoT2JqZWN0IC0tIGluIHRoYXQgY2FzZSwgdGhlIHR5cGUgd2lsbAogICAgICAgICAqIGFscmVhZHkgaGF2ZSBiZWVuIHNldCB0byBub1N1Y2hPYmplY3Qgd2hlbiB3ZSByZWFsaXNlZAogICAgICAgICAqIHdlIGNvdWxkbid0IGZpbmQgYW4gYXBwcm9wcmlhdGUgdHJlZSkuICAKICAgICAgICAgKi8KICAgICAgICBpZiAoc3RhdHVzID09IFNOTVBfRVJSX05PRVJST1IpCiAgICAgICAgICAgIHNubXBfcmVwbGFjZV92YXJfdHlwZXMoYXNwLT5wZHUtPnZhcmlhYmxlcywgQVNOX05VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9OT1NVQ0hJTlNUQU5DRSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkdFVE5FWFRTKTsKICAgICAgICAvKgogICAgICAgICAqIGZhbGwgdGhyb3VnaCAKICAgICAgICAgKi8KCiAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6ICAgICAvKiBub3RlOiB0aGVyZSBpcyBubyBnZXRidWxrIHN0YXQgKi8KICAgICAgICAvKgogICAgICAgICAqIGxvb3AgdGhyb3VnaCBvdXIgbWliIHRyZWUgdGlsbCB3ZSBmaW5kIGFuCiAgICAgICAgICogYXBwcm9wcmlhdGUgcmVzcG9uc2UgdG8gcmV0dXJuIHRvIHRoZSBjYWxsZXIuIAogICAgICAgICAqLwoKICAgICAgICBpZiAoaW5jbHVzaXZlcykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlIGZvciBBZ2VudFggSU5DTFVTSVZFIGdldE5leHQKICAgICAgICAgICAgICogcmVxdWVzdHMgd2hlcmUgYSByZXN1bHQgbGV4aS1lcXVhbCB0byB0aGUgcmVxdWVzdCBpcyBva2F5CiAgICAgICAgICAgICAqIGJ1dCBpZiBzdWNoIGEgcmVzdWx0IGRvZXMgbm90IGV4aXN0LCB3ZSBzdGlsbCB3YW50IHRoZQogICAgICAgICAgICAgKiBsZXhpLW5leHQgb25lLiAgU28gYmFzaWNhbGx5IHdlIGRvIGEgR0VUIGZpcnN0LCBhbmQgaWYgYW55CiAgICAgICAgICAgICAqIG9mIHRoZSBJTkNMVVNJVkUgcmVxdWVzdHMgYXJlIHNhdGlzZmllZCwgd2UgdXNlIHRoYXQKICAgICAgICAgICAgICogdmFsdWUuICBUaGVuLCB1bnNhdGlzZmllZCBJTkNMVVNJVkUgcmVxdWVzdHMsIGFuZAogICAgICAgICAgICAgKiBub24tSU5DTFVTSVZFIHJlcXVlc3RzIGdldCBkb25lIGFzIG5vcm1hbC4gIAogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImluY2x1c2l2ZSByYW5nZShzKSBpbiBnZXROZXh0XG4iKSk7CiAgICAgICAgICAgIGFzcC0+b2xkbW9kZSA9IGFzcC0+bW9kZTsKICAgICAgICAgICAgYXNwLT5tb2RlID0gU05NUF9NU0dfR0VUOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBmaXJzdCBwYXNzIAogICAgICAgICAqLwogICAgICAgIHN0YXR1cyA9IGhhbmRsZV92YXJfcmVxdWVzdHMoYXNwKTsKICAgICAgICBpZiAoc3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpIHsKICAgICAgICAgICAgaWYgKCFpbmNsdXNpdmVzKQogICAgICAgICAgICAgICAgcmV0dXJuIHN0YXR1czsgIC8qIHNob3VsZCBuZXZlciByZWFsbHkgaGFwcGVuICovCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogbG9vcCB0aHJvdWdoIG91ciBtaWIgdHJlZSB0aWxsIHdlIGZpbmQgYW4KICAgICAgICAgKiBhcHByb3ByaWF0ZSByZXNwb25zZSB0byByZXR1cm4gdG8gdGhlIGNhbGxlci4gCiAgICAgICAgICovCgogICAgICAgIHN0YXR1cyA9IGhhbmRsZV9nZXRuZXh0X2xvb3AoYXNwKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX1NFVDoKI2lmZGVmIE5FVFNOTVBfRElTQUJMRV9TRVRfU1VQUE9SVAogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1RXUklUQUJMRTsKI2Vsc2UKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIGFjY2VzcyBwZXJtaXNzaW9ucyBmaXJzdCAKICAgICAgICAgKi8KICAgICAgICBpZiAoY2hlY2tfYWNtKGFzcCwgU05NUF9OT1NVQ0hPQkpFQ1QpKQogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9UV1JJVEFCTEU7CgogICAgICAgIGFzcC0+bW9kZSA9IE1PREVfU0VUX0JFR0lOOwogICAgICAgIHN0YXR1cyA9IGhhbmRsZV9zZXRfbG9vcChhc3ApOwojZW5kaWYKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9CRUdJTjoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUxOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfUkVTRVJWRTI6CiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9BQ1RJT046CiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9DT01NSVQ6CiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9GUkVFOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfVU5ETzoKICAgICAgICBhc3AtPnBkdS0+ZmxhZ3MgfD0gVUNEX01TR19GTEFHX09ORV9QQVNTX09OTFk7CiAgICAgICAgc3RhdHVzID0gaGFuZGxlX3NldF9sb29wKGFzcCk7CiAgICAgICAgLyoKICAgICAgICAgKiBhc3AgcmVsYXRlZCBjYWNoZSBpcyBzYXZlZCBpbiBjbGVhbnVwIAogICAgICAgICAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgU05NUF9NU0dfUkVTUE9OU0U6CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOR0VUUkVTUE9OU0VTKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKCiAgICBjYXNlIFNOTVBfTVNHX1RSQVA6CiAgICBjYXNlIFNOTVBfTVNHX1RSQVAyOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTlRSQVBTKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKCiAgICBkZWZhdWx0OgogICAgICAgIC8qCiAgICAgICAgICogV1dXOiBhcmUgcmVwb3J0cyBjb3VudGVkIHNvbWV3aGVyZSA/IAogICAgICAgICAqLwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOyAgLyogc2hvdWxkbid0IGdldCBoZXJlICovCiAgICAgICAgLyoKICAgICAgICAgKiBXV1cgCiAgICAgICAgICovCiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiogc2V0IGVycm9yIGZvciBhIHJlcXVlc3QKICogXGludGVybmFsIGV4dGVybmFsIGludGVyZmFjZTogbmV0c25tcF9yZXF1ZXN0X3NldF9lcnJvcgogKi8KTkVUU05NUF9TVEFUSUNfSU5MSU5FIGludApfcmVxdWVzdF9zZXRfZXJyb3IobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsIGludCBtb2RlLCBpbnQgZXJyb3JfdmFsdWUpCnsKICAgIGlmICghcmVxdWVzdCkKICAgICAgICByZXR1cm4gU05NUEVSUl9OT19WQVJTOwoKICAgIHJlcXVlc3QtPnByb2Nlc3NlZCA9IDE7CiAgICByZXF1ZXN0LT5kZWxlZ2F0ZWQgPSBSRVFVRVNUX0lTX05PVF9ERUxFR0FURUQ7CgogICAgc3dpdGNoIChlcnJvcl92YWx1ZSkgewogICAgY2FzZSBTTk1QX05PU1VDSE9CSkVDVDoKICAgIGNhc2UgU05NUF9OT1NVQ0hJTlNUQU5DRToKICAgIGNhc2UgU05NUF9FTkRPRk1JQlZJRVc6CiAgICAgICAgLyoKICAgICAgICAgKiB0aGVzZSBhcmUgZXhjZXB0aW9ucyB0aGF0IHNob3VsZCBiZSBwdXQgaW4gdGhlIHZhcmJpbmQKICAgICAgICAgKiBpbiB0aGUgY2FzZSBvZiBhIEdFVCBidXQgc2hvdWxkIGJlIHRyYW5zbGF0ZWQgZm9yIGEgU0VUCiAgICAgICAgICogaW50byBhIHJlYWwgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIHB1dCBpbiB0aGUgcmVxdWVzdCAKICAgICAgICAgKi8KICAgICAgICBzd2l0Y2ggKG1vZGUpIHsKICAgICAgICBjYXNlIE1PREVfR0VUOgogICAgICAgIGNhc2UgTU9ERV9HRVRORVhUOgogICAgICAgIGNhc2UgTU9ERV9HRVRCVUxLOgogICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPSBlcnJvcl92YWx1ZTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoZXNlIGFyZSB0ZWNobmljYWxseSBpbGxlZ2FsIHRvIHNldCBieSB0aGUKICAgICAgICAgICAgICogY2xpZW50IEFQSXMgZm9yIHRoZXNlIG1vZGVzLiAgQnV0IGFjY2VwdGluZwogICAgICAgICAgICAgKiB0aGVtIGhlcmUgYWxsb3dzIHRoZSAnc3BhcnNlX3RhYmxlJyBoZWxwZXIgdG8KICAgICAgICAgICAgICogcHJvdmlkZSBzb21lIGNvbW1vbiB0YWJsZSBoYW5kbGluZyBwcm9jZXNzaW5nCiAgICAgICAgICAgICAqCiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJJbGxlZ2FsIGVycm9yX3ZhbHVlICVkIGZvciBtb2RlICVkIGlnbm9yZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgIGVycm9yX3ZhbHVlLCBtb2RlKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgICAqLwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXF1ZXN0LT5zdGF0dXMgPSBTTk1QX0VSUl9OT1NVQ0hOQU1FOyAgICAgIC8qIFdXVzogY29ycmVjdD8gKi8KICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKICAgICAgICB9CiAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAgICAgLyogbmV2ZXIgZ2V0IGhlcmUgKi8KCiAgICBkZWZhdWx0OgogICAgICAgIGlmIChlcnJvcl92YWx1ZSA8IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaWxsZWdhbCBsb2NhbCBlcnJvciBjb2RlLiAgdHJhbnNsYXRlIHRvIGdlbmVyciAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFdXVzogZnVsbCB0cmFuc2xhdGlvbiBtYXA/IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIklsbGVnYWwgZXJyb3JfdmFsdWUgJWQgdHJhbnNsYXRlZCB0byAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgZXJyb3JfdmFsdWUsIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgICAgIHJlcXVlc3QtPnN0YXR1cyA9IFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBXV1c6IHRyYW5zbGF0aW9ucyBhbmQgbW9kZSBjaGVja2luZz8gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZXF1ZXN0LT5zdGF0dXMgPSBlcnJvcl92YWx1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKICAgIH0KICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCi8qKiBzZXQgZXJyb3IgZm9yIGEgcmVxdWVzdAogKiBAcGFyYW0gcmVxdWVzdCByZXF1ZXN0IHdoaWNoIGhhcyBlcnJvcgogKiBAcGFyYW0gZXJyb3JfdmFsdWUgZXJyb3IgdmFsdWUgZm9yIHJlcXVlc3QKICovCmludApuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCBpbnQgZXJyb3JfdmFsdWUpCnsKICAgIGlmICghcmVxdWVzdCB8fCAhcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKCiAgICByZXR1cm4gX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3QsIHJlcXVlc3QtPmFnZW50X3JlcV9pbmZvLT5tb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl92YWx1ZSk7Cn0KCi8qKiBzZXQgZXJyb3IgZm9yIGEgcmVxdWVzdCB3aXRoaW4gYSByZXF1ZXN0IGxpc3QKICogQHBhcmFtIHJlcXVlc3QgaGVhZCBvZiB0aGUgcmVxdWVzdCBsaXN0CiAqIEBwYXJhbSBlcnJvcl92YWx1ZSBlcnJvciB2YWx1ZSBmb3IgcmVxdWVzdAogKiBAcGFyYW0gaWR4IGluZGV4IG9mIHRoZSByZXF1ZXN0IHdoaWNoIGhhcyB0aGUgZXJyb3IKICovCmludApuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yX2lkeChuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGVycm9yX3ZhbHVlLCBpbnQgaWR4KQp7CiAgICBpbnQgaTsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXEgPSByZXF1ZXN0OwoKICAgIGlmICghcmVxdWVzdCB8fCAhcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKCiAgICAvKgogICAgICogU2tpcCB0byB0aGUgaW5kaWNhdGVkIHZhcmJpbmQKICAgICAqLwogICAgZm9yICggaT0yOyBpPGlkeDsgaSsrKSB7CiAgICAgICAgcmVxID0gcmVxLT5uZXh0OwogICAgICAgIGlmICghcmVxKQogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9OT19WQVJTOwogICAgfQogICAgCiAgICByZXR1cm4gX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcSwgcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8tPm1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3ZhbHVlKTsKfQoKLyoqIHNldCBlcnJvciBmb3IgYWxsIHJlcXVlc3RzCiAqIEBwYXJhbSByZXF1ZXN0cyByZXF1ZXN0IGxpc3QKICogQHBhcmFtIGVycm9yIGVycm9yIHZhbHVlIGZvciByZXF1ZXN0cwogKiBAcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUywgb3IgYW4gZXJyb3IgY29kZQogKi8KTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfcmVxdWVzdF9zZXRfZXJyb3JfYWxsKCBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsIGludCBlcnJvcikKewogICAgaW50IG1vZGUsIHJjLCByZXN1bHQgPSBTTk1QRVJSX1NVQ0NFU1M7CgogICAgaWYoKE5VTEwgPT0gcmVxdWVzdHMpIHx8IChOVUxMID09IHJlcXVlc3RzLT5hZ2VudF9yZXFfaW5mbykpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKICAgIAogICAgbW9kZSA9IHJlcXVlc3RzLT5hZ2VudF9yZXFfaW5mby0+bW9kZTsgLyogZXZlcnkgcmVxIGhhcyBzYW1lIG1vZGUgKi8KICAgIAogICAgZm9yKDsgcmVxdWVzdHMgOyByZXF1ZXN0cyA9IHJlcXVlc3RzLT5uZXh0KSB7CgogICAgICAgIC8qKiBwYXJhbm9pZCBzYW5pdHkgY2hlY2tzICovCiAgICAgICAgbmV0c25tcF9hc3NlcnQoTlVMTCAhPSByZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8pOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KG1vZGUgPT0gcmVxdWVzdHMtPmFnZW50X3JlcV9pbmZvLT5tb2RlKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBzZXQgZXJyb3IgZm9yIHRoaXMgcmVxdWVzdC4gTG9nIGFueSBlcnJvcnMsIHNhdmUgdGhlIGxhc3QKICAgICAgICAgKiB0byByZXR1cm4gdG8gdGhlIHVzZXIuCiAgICAgICAgICovCiAgICAgICAgaWYoKHJjID0gX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3RzLCBtb2RlLCBlcnJvcikpKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLCJnb3QgJWQgd2hpbGUgc2V0dGluZyByZXF1ZXN0IGVycm9yXG4iLCByYyk7CiAgICAgICAgICAgIHJlc3VsdCA9IHJjOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXN1bHQ7Cn0KCmV4dGVybiBzdHJ1Y3QgdGltZXZhbCBzdGFydHRpbWU7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgJ3N5c1VwVGltZScgYXQgdGhlIGdpdmVuIG1hcmtlciAKICAgICAgICAgICAgICAgICAqLwp1X2xvbmcKbmV0c25tcF9tYXJrZXJfdXB0aW1lKG1hcmtlcl90IHBtKQp7CiAgICB1X2xvbmcgICAgICAgICAgcmVzOwogICAgbWFya2VyX3QgICAgICAgIHN0YXJ0ID0gKG1hcmtlcl90KSAmIHN0YXJ0dGltZTsKCiAgICByZXMgPSB1YXRpbWVfaGRpZmYoc3RhcnQsIHBtKTsKICAgIHJldHVybiByZXM7ICAgICAgICAgICAgICAgICAvKiBhdGltZV9kaWZmIHdvcmtzIGluIG1zZWMsIG5vdCBjc2VjICovCn0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAqIHN0cnVjdCB0aW1ldmFsIGVxdWl2YWxlbnRzIG9mIHRoZXNlIAogICAgICAgICAgICAgICAgICAgICAgICAgKi8KdV9sb25nCm5ldHNubXBfdGltZXZhbF91cHRpbWUoc3RydWN0IHRpbWV2YWwgKiB0dikKewogICAgcmV0dXJuIG5ldHNubXBfbWFya2VyX3VwdGltZSgobWFya2VyX3QpIHR2KTsKfQoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgdmFsdWUgb2YgJ3N5c1VwVGltZScgCiAgICAgICAgICAgICAgICAgKi8KdV9sb25nCm5ldHNubXBfZ2V0X2FnZW50X3VwdGltZSh2b2lkKQp7CiAgICBzdHJ1Y3QgdGltZXZhbCAgbm93OwogICAgZ2V0dGltZW9mZGF5KCZub3csIE5VTEwpOwoKICAgIHJldHVybiBuZXRzbm1wX3RpbWV2YWxfdXB0aW1lKCZub3cpOwp9CgoKCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9hZ2VudF9hZGRfbGlzdF9kYXRhKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICphcmksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2RhdGFfbGlzdCAqbm9kZSkKewogICAgaWYgKGFyaSkgewoJaWYgKGFyaS0+YWdlbnRfZGF0YSkgewogICAgICAgICAgICBuZXRzbm1wX2FkZF9saXN0X2RhdGEoJmFyaS0+YWdlbnRfZGF0YSwgbm9kZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYXJpLT5hZ2VudF9kYXRhID0gbm9kZTsKCX0KICAgIH0KfQoKTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfYWdlbnRfcmVtb3ZlX2xpc3RfZGF0YShuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqYXJpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqIG5hbWUpCnsKICAgIGlmICgoTlVMTCA9PSBhcmkpIHx8IChOVUxMID09IGFyaS0+YWdlbnRfZGF0YSkpCiAgICAgICAgcmV0dXJuIDE7CgogICAgcmV0dXJuIG5ldHNubXBfcmVtb3ZlX2xpc3Rfbm9kZSgmYXJpLT5hZ2VudF9kYXRhLCBuYW1lKTsKfQoKTkVUU05NUF9JTkxJTkUgdm9pZCAgICAqCm5ldHNubXBfYWdlbnRfZ2V0X2xpc3RfZGF0YShuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqYXJpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgaWYgKGFyaSkgewogICAgICAgIHJldHVybiBuZXRzbm1wX2dldF9saXN0X2RhdGEoYXJpLT5hZ2VudF9kYXRhLCBuYW1lKTsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfZnJlZV9hZ2VudF9kYXRhX3NldChuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqYXJpKQp7CiAgICBpZiAoYXJpKSB7CiAgICAgICAgbmV0c25tcF9mcmVlX2xpc3RfZGF0YShhcmktPmFnZW50X2RhdGEpOwogICAgfQp9CgpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfZnJlZV9hZ2VudF9kYXRhX3NldHMobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKmFyaSkKewogICAgaWYgKGFyaSkgewogICAgICAgIG5ldHNubXBfZnJlZV9hbGxfbGlzdF9kYXRhKGFyaS0+YWdlbnRfZGF0YSk7CiAgICB9Cn0KCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9mcmVlX2FnZW50X3JlcXVlc3RfaW5mbyhuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqYXJpKQp7CiAgICBpZiAoYXJpKSB7CiAgICAgICAgaWYgKGFyaS0+YWdlbnRfZGF0YSkgewogICAgICAgICAgICBuZXRzbm1wX2ZyZWVfYWxsX2xpc3RfZGF0YShhcmktPmFnZW50X2RhdGEpOwoJfQogICAgICAgIFNOTVBfRlJFRShhcmkpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBkZXByZWNhdGVkIGZ1bmN0aW9ucwogKgogKi8KCi8qKiBzZXQgZXJyb3IgZm9yIGEgcmVxdWVzdAogKiBcZGVwcmVjYXRlZCwgdXNlIG5ldHNubXBfcmVxdWVzdF9zZXRfZXJyb3IgaW5zdGVhZAogKiBAcGFyYW0gcmVxaW5mbyBhZ2VudF9yZXF1ZXN0X2luZm8gcG9pbnRlciBmb3IgcmVxdWVzdAogKiBAcGFyYW0gcmVxdWVzdCByZXF1ZXN0X2luZm8gcG9pbnRlcgogKiBAcGFyYW0gZXJyb3JfdmFsdWUgZXJyb3IgdmFsdWUgZm9yIHJlcXVlc3RzCiAqIEByZXR1cm4gZXJyb3JfdmFsdWUKICovCmludApuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCBpbnQgZXJyb3JfdmFsdWUpCnsKICAgIGlmICghcmVxdWVzdCB8fCAhcmVxaW5mbykKICAgICAgICByZXR1cm4gZXJyb3JfdmFsdWU7CgogICAgX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3QsIHJlcWluZm8tPm1vZGUsIGVycm9yX3ZhbHVlKTsKICAgIAogICAgcmV0dXJuIGVycm9yX3ZhbHVlOwp9CgovKiogc2V0IGVycm9yIGZvciBhIHJlcXVlc3QKICogXGRlcHJlY2F0ZWQsIHVzZSBuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yIGluc3RlYWQKICogQHBhcmFtIG1vZGUgTmV0LVNOTVAgYWdlbnQgcHJvY2Vzc2luZyBtb2RlCiAqIEBwYXJhbSByZXF1ZXN0IHJlcXVlc3RfaW5mbyBwb2ludGVyCiAqIEBwYXJhbSBlcnJvcl92YWx1ZSBlcnJvciB2YWx1ZSBmb3IgcmVxdWVzdHMKICogQHJldHVybiBlcnJvcl92YWx1ZQogKi8KaW50Cm5ldHNubXBfc2V0X21vZGVfcmVxdWVzdF9lcnJvcihpbnQgbW9kZSwgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZXJyb3JfdmFsdWUpCnsKICAgIF9yZXF1ZXN0X3NldF9lcnJvcihyZXF1ZXN0LCBtb2RlLCBlcnJvcl92YWx1ZSk7CiAgICAKICAgIHJldHVybiBlcnJvcl92YWx1ZTsKfQoKLyoqIHNldCBlcnJvciBmb3IgYWxsIHJlcXVlc3QKICogXGRlcHJlY2F0ZWQgdXNlIG5ldHNubXBfcmVxdWVzdF9zZXRfZXJyb3JfYWxsCiAqIEBwYXJhbSByZXFpbmZvIGFnZW50X3JlcXVlc3RfaW5mbyBwb2ludGVyIGZvciByZXF1ZXN0cwogKiBAcGFyYW0gcmVxdWVzdHMgcmVxdWVzdCBsaXN0CiAqIEBwYXJhbSBlcnJvcl92YWx1ZSBlcnJvciB2YWx1ZSBmb3IgcmVxdWVzdHMKICogQHJldHVybiBlcnJvcl92YWx1ZQogKi8KaW50Cm5ldHNubXBfc2V0X2FsbF9yZXF1ZXN0c19lcnJvcihuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBlcnJvcl92YWx1ZSkKewogICAgbmV0c25tcF9yZXF1ZXN0X3NldF9lcnJvcl9hbGwocmVxdWVzdHMsIGVycm9yX3ZhbHVlKTsKICAgIHJldHVybiBlcnJvcl92YWx1ZTsKfQovKiogQH0gKi8K