LyoKICogc25tcF9hZ2VudC5jCiAqCiAqIFNpbXBsZSBOZXR3b3JrIE1hbmFnZW1lbnQgUHJvdG9jb2wgKFJGQyAxMDY3KS4KICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodHMuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCUNvcHlyaWdodCAxOTg4LCAxOTg5IGJ5IENhcm5lZ2llIE1lbGxvbiBVbml2ZXJzaXR5CgogICAgICAgICAgICAgICAgICAgICAgQWxsIFJpZ2h0cyBSZXNlcnZlZAoKUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzIApkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBhbmQgd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIApwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0CmJvdGggdGhhdCBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiAKc3VwcG9ydGluZyBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBDTVUgbm90IGJlCnVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZQpzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICAKCkNNVSBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwgSU5DTFVESU5HCkFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTyBFVkVOVCBTSEFMTApDTVUgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SCkFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywKV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIgVE9SVElPVVMgQUNUSU9OLApBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTClNPRlRXQVJFLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIAogKiByZXNlcnZlZC4gIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSAKICogQ09QWUlORyBmaWxlIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwovKiogQGRlZmdyb3VwIHNubXBfYWdlbnQgbmV0LXNubXAgYWdlbnQgcmVsYXRlZCBwcm9jZXNzaW5nIAogKiAgQGluZ3JvdXAgYWdlbnQKICoKICogQHsKICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmZGVmIEhBVkVfTElNSVRTX0gKI2luY2x1ZGUgPGxpbWl0cy5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZW5kaWYKI2lmIFRJTUVfV0lUSF9TWVNfVElNRQojIGlmZGVmIFdJTjMyCiMgIGluY2x1ZGUgPHN5cy90aW1lYi5oPgojIGVsc2UKIyAgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBlbmRpZgojIGluY2x1ZGUgPHRpbWUuaD4KI2Vsc2UKIyBpZiBIQVZFX1NZU19USU1FX0gKIyAgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBlbHNlCiMgIGluY2x1ZGUgPHRpbWUuaD4KIyBlbmRpZgojZW5kaWYKI2lmIEhBVkVfU1lTX1NFTEVDVF9ICiNpbmNsdWRlIDxzeXMvc2VsZWN0Lmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpbmNsdWRlIDxlcnJuby5oPgojaWYgSEFWRV9XSU5TT0NLX0gKI2luY2x1ZGUgPHdpbnNvY2suaD4KI2VuZGlmCgojZGVmaW5lIFNOTVBfTkVFRF9SRVFVRVNUX0xJU1QKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2Fzc2VydC5oPgoKI2lmIEhBVkVfU1lTTE9HX0gKI2luY2x1ZGUgPHN5c2xvZy5oPgojZW5kaWYKCiNpZmRlZiBORVRTTk1QX1VTRV9MSUJXUkFQCiNpbmNsdWRlIDx0Y3BkLmg+CmludCAgICAgICAgICAgICBhbGxvd19zZXZlcml0eSA9IExPR19JTkZPOwppbnQgICAgICAgICAgICAgZGVueV9zZXZlcml0eSA9IExPR19XQVJOSU5HOwojZW5kaWYKCiNpbmNsdWRlICJzbm1wZC5oIgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbWliX21vZHVsZV9jb25maWcuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L21pYl9tb2R1bGVzLmg+CgojaWZkZWYgVVNJTkdfQUdFTlRYX1BST1RPQ09MX01PRFVMRQojaW5jbHVkZSAiYWdlbnR4L3Byb3RvY29sLmgiCiNlbmRpZgoKI2lmZGVmIFVTSU5HX0FHRU5UWF9NQVNURVJfTU9EVUxFCiNpbmNsdWRlICJhZ2VudHgvbWFzdGVyLmgiCiNlbmRpZgoKI2lmZGVmIFVTSU5HX1NNVVhfTU9EVUxFCiNpbmNsdWRlICJzbXV4L3NtdXguaCIKI2VuZGlmCgpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfYWdlbnRfYWRkX2xpc3RfZGF0YShuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqYXJpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9kYXRhX2xpc3QgKm5vZGUpCnsKICAgIGlmIChhcmkpIHsKCWlmIChhcmktPmFnZW50X2RhdGEpIHsKICAgICAgICAgICAgbmV0c25tcF9hZGRfbGlzdF9kYXRhKCZhcmktPmFnZW50X2RhdGEsIG5vZGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGFyaS0+YWdlbnRfZGF0YSA9IG5vZGU7Cgl9CiAgICB9Cn0KCk5FVFNOTVBfSU5MSU5FIGludApuZXRzbm1wX2FnZW50X3JlbW92ZV9saXN0X2RhdGEobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKmFyaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKiBuYW1lKQp7CiAgICBpZiAoKE5VTEwgPT0gYXJpKSB8fCAoTlVMTCA9PSBhcmktPmFnZW50X2RhdGEpKQogICAgICAgIHJldHVybiAxOwoKICAgIHJldHVybiBuZXRzbm1wX3JlbW92ZV9saXN0X25vZGUoJmFyaS0+YWdlbnRfZGF0YSwgbmFtZSk7Cn0KCk5FVFNOTVBfSU5MSU5FIHZvaWQgICAgKgpuZXRzbm1wX2FnZW50X2dldF9saXN0X2RhdGEobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKmFyaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIGlmIChhcmkpIHsKICAgICAgICByZXR1cm4gbmV0c25tcF9nZXRfbGlzdF9kYXRhKGFyaS0+YWdlbnRfZGF0YSwgbmFtZSk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX2ZyZWVfYWdlbnRfZGF0YV9zZXQobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKmFyaSkKewogICAgaWYgKGFyaSkgewogICAgICAgIG5ldHNubXBfZnJlZV9saXN0X2RhdGEoYXJpLT5hZ2VudF9kYXRhKTsKICAgIH0KfQoKTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX2ZyZWVfYWdlbnRfZGF0YV9zZXRzKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICphcmkpCnsKICAgIGlmIChhcmkpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfYWxsX2xpc3RfZGF0YShhcmktPmFnZW50X2RhdGEpOwogICAgfQp9CgpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfZnJlZV9hZ2VudF9yZXF1ZXN0X2luZm8obmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKmFyaSkKewogICAgaWYgKGFyaSkgewogICAgICAgIGlmIChhcmktPmFnZW50X2RhdGEpIHsKICAgICAgICAgICAgbmV0c25tcF9mcmVlX2FsbF9saXN0X2RhdGEoYXJpLT5hZ2VudF9kYXRhKTsKCX0KICAgICAgICBTTk1QX0ZSRUUoYXJpKTsKICAgIH0KfQoKb2lkICAgICAgdmVyc2lvbl9zeXNvaWRbXSA9IHsgTkVUU05NUF9TWVNURU1fTUlCIH07CmludCAgICAgIHZlcnNpb25fc3lzb2lkX2xlbiA9IE9JRF9MRU5HVEgodmVyc2lvbl9zeXNvaWQpOwoKI2RlZmluZSBTTk1QX0FERFJDQUNIRV9TSVpFIDEwCiNkZWZpbmUgU05NUF9BRERSQ0FDSEVfTUFYQUdFIDMwMCAvKiBpbiBzZWNvbmRzICovCgplbnVtIHsKICAgIFNOTVBfQUREUkNBQ0hFX1VOVVNFRCA9IDAsCiAgICBTTk1QX0FERFJDQUNIRV9VU0VEID0gMQp9OwoKc3RydWN0IGFkZHJDYWNoZSB7CiAgICBjaGFyICAgICAgICAgICAqYWRkcjsKICAgIGludCAgICAgICAgICAgIHN0YXR1czsKICAgIHN0cnVjdCB0aW1ldmFsIGxhc3RIaXQ7Cn07CgpzdGF0aWMgc3RydWN0IGFkZHJDYWNoZSBhZGRyQ2FjaGVbU05NUF9BRERSQ0FDSEVfU0laRV07CmludCAgICAgICAgICAgICBsb2dfYWRkcmVzc2VzID0gMDsKCgoKdHlwZWRlZiBzdHJ1Y3QgX2FnZW50X25zYXAgewogICAgaW50ICAgICAgICAgICAgIGhhbmRsZTsKICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0OwogICAgdm9pZCAgICAgICAgICAgKnM7ICAgICAgICAgIC8qICBPcGFxdWUgaW50ZXJuYWwgc2Vzc2lvbiBwb2ludGVyLiAgKi8KICAgIHN0cnVjdCBfYWdlbnRfbnNhcCAqbmV4dDsKfSBhZ2VudF9uc2FwOwoKc3RhdGljIGFnZW50X25zYXAgKmFnZW50X25zYXBfbGlzdCA9IE5VTEw7CnN0YXRpYyBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFnZW50X3Nlc3Npb25fbGlzdCA9IE5VTEw7Cm5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqbmV0c25tcF9wcm9jZXNzaW5nX3NldCA9IE5VTEw7Cm5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYWdlbnRfZGVsZWdhdGVkX2xpc3QgPSBOVUxMOwpuZXRzbm1wX2FnZW50X3Nlc3Npb24gKm5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3QgPSBOVUxMOwoKCmludCAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X2NoZWNrX3BhY2tldChuZXRzbm1wX3Nlc3Npb24gKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBuZXRzbm1wX3RyYW5zcG9ydF9zICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICosIGludCk7CmludCAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X2NoZWNrX3BhcnNlKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQpOwp2b2lkICAgICAgICAgICAgZGVsZXRlX3N1Ym5ldHNubXBfdHJlZV9jYWNoZShuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CmludCAgICAgICAgICAgICBoYW5kbGVfcGR1KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKTsKaW50ICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlX3JlcXVlc3QobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdGF0dXMpOwppbnQgICAgICAgICAgICAgbmV0c25tcF93cmFwX3VwX3JlcXVlc3QobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RhdHVzKTsKaW50ICAgICAgICAgICAgIGNoZWNrX2RlbGF5ZWRfcmVxdWVzdChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CmludCAgICAgICAgICAgICBoYW5kbGVfZ2V0bmV4dF9sb29wKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKTsKaW50ICAgICAgICAgICAgIGhhbmRsZV9zZXRfbG9vcChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CgppbnQgICAgICAgICAgICAgbmV0c25tcF9jaGVja19xdWV1ZWRfY2hhaW5fZm9yKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKTsKaW50ICAgICAgICAgICAgIG5ldHNubXBfYWRkX3F1ZXVlZChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CmludCAgICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9mcm9tX2RlbGVnYXRlZChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CgoKc3RhdGljIGludCAgICAgIGN1cnJlbnRfZ2xvYmFsaWQgPSAwOwoKaW50ICAgICAgbmV0c25tcF9ydW5uaW5nID0gMTsKCmludApuZXRzbm1wX2FsbG9jYXRlX2dsb2JhbGNhY2hlaWQodm9pZCkKewogICAgcmV0dXJuICsrY3VycmVudF9nbG9iYWxpZDsKfQoKaW50Cm5ldHNubXBfZ2V0X2xvY2FsX2NhY2hpZChuZXRzbm1wX2NhY2hlbWFwICpjYWNoZV9zdG9yZSwgaW50IGdsb2JhbGlkKQp7CiAgICB3aGlsZSAoY2FjaGVfc3RvcmUgIT0gTlVMTCkgewogICAgICAgIGlmIChjYWNoZV9zdG9yZS0+Z2xvYmFsaWQgPT0gZ2xvYmFsaWQpCiAgICAgICAgICAgIHJldHVybiBjYWNoZV9zdG9yZS0+Y2FjaGVpZDsKICAgICAgICBjYWNoZV9zdG9yZSA9IGNhY2hlX3N0b3JlLT5uZXh0OwogICAgfQogICAgcmV0dXJuIC0xOwp9CgpuZXRzbm1wX2NhY2hlbWFwICoKbmV0c25tcF9nZXRfb3JfYWRkX2xvY2FsX2NhY2hpZChuZXRzbm1wX2NhY2hlbWFwICoqY2FjaGVfc3RvcmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGdsb2JhbGlkLCBpbnQgbG9jYWxpZCkKewogICAgbmV0c25tcF9jYWNoZW1hcCAqdG1wcDsKCiAgICB0bXBwID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2NhY2hlbWFwKTsKICAgIGlmICh0bXBwICE9IE5VTEwpIHsKICAgICAgICBpZiAoKmNhY2hlX3N0b3JlKSB7CiAgICAgICAgICAgIHRtcHAtPm5leHQgPSAqY2FjaGVfc3RvcmU7CiAgICAgICAgICAgICpjYWNoZV9zdG9yZSA9IHRtcHA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgKmNhY2hlX3N0b3JlID0gdG1wcDsKICAgICAgICB9CgogICAgICAgIHRtcHAtPmdsb2JhbGlkID0gZ2xvYmFsaWQ7CiAgICAgICAgdG1wcC0+Y2FjaGVpZCA9IGxvY2FsaWQ7CiAgICB9CiAgICByZXR1cm4gdG1wcDsKfQoKdm9pZApuZXRzbm1wX2ZyZWVfY2FjaGVtYXAobmV0c25tcF9jYWNoZW1hcCAqY2FjaGVfc3RvcmUpCnsKICAgIG5ldHNubXBfY2FjaGVtYXAgKnRtcHA7CiAgICB3aGlsZSAoY2FjaGVfc3RvcmUpIHsKICAgICAgICB0bXBwID0gY2FjaGVfc3RvcmU7CiAgICAgICAgY2FjaGVfc3RvcmUgPSBjYWNoZV9zdG9yZS0+bmV4dDsKICAgICAgICBTTk1QX0ZSRUUodG1wcCk7CiAgICB9Cn0KCgp0eXBlZGVmIHN0cnVjdCBhZ2VudF9zZXRfY2FjaGVfcyB7CiAgICAvKgogICAgICogbWF0Y2ggb24gdGhlc2UgMiAKICAgICAqLwogICAgaW50ICAgICAgICAgICAgIHRyYW5zSUQ7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnNlc3M7CgogICAgLyoKICAgICAqIHN0b3JlIHRoaXMgaW5mbyAKICAgICAqLwogICAgbmV0c25tcF90cmVlX2NhY2hlICp0cmVlY2FjaGU7CiAgICBpbnQgICAgICAgICAgICAgdHJlZWNhY2hlX2xlbjsKICAgIGludCAgICAgICAgICAgICB0cmVlY2FjaGVfbnVtOwoKICAgIGludCAgICAgICAgICAgICB2YmNvdW50OwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpzYXZlZF92YXJzOwogICAgbmV0c25tcF9kYXRhX2xpc3QgKmFnZW50X2RhdGE7CgogICAgLyoKICAgICAqIGxpc3QgCiAgICAgKi8KICAgIHN0cnVjdCBhZ2VudF9zZXRfY2FjaGVfcyAqbmV4dDsKfSBhZ2VudF9zZXRfY2FjaGU7CgpzdGF0aWMgYWdlbnRfc2V0X2NhY2hlICpTZXRzID0gTlVMTDsKCmFnZW50X3NldF9jYWNoZSAqCnNhdmVfc2V0X2NhY2hlKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBhZ2VudF9zZXRfY2FjaGUgKnB0cjsKCiAgICBpZiAoIWFzcCB8fCAhYXNwLT5yZXFpbmZvIHx8ICFhc3AtPnBkdSkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBwdHIgPSBTTk1QX01BTExPQ19UWVBFREVGKGFnZW50X3NldF9jYWNoZSk7CiAgICBpZiAocHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgLyoKICAgICAqIFNhdmUgdGhlIGltcG9ydGFudCBpbmZvcm1hdGlvbiAKICAgICAqLwogICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwgImFzcCAlcCByZXFpbmZvICVwIHNhdmVkIGluIGNhY2hlIChtb2RlICVkKVxuIiwKICAgICAgICAgICAgICAgIGFzcCwgYXNwLT5yZXFpbmZvLCBhc3AtPnBkdS0+Y29tbWFuZCkpOwogICAgcHRyLT50cmFuc0lEID0gYXNwLT5wZHUtPnRyYW5zaWQ7CiAgICBwdHItPnNlc3MgPSBhc3AtPnNlc3Npb247CiAgICBwdHItPnRyZWVjYWNoZSA9IGFzcC0+dHJlZWNhY2hlOwogICAgcHRyLT50cmVlY2FjaGVfbGVuID0gYXNwLT50cmVlY2FjaGVfbGVuOwogICAgcHRyLT50cmVlY2FjaGVfbnVtID0gYXNwLT50cmVlY2FjaGVfbnVtOwogICAgcHRyLT5hZ2VudF9kYXRhID0gYXNwLT5yZXFpbmZvLT5hZ2VudF9kYXRhOwogICAgcHRyLT5yZXF1ZXN0cyA9IGFzcC0+cmVxdWVzdHM7CiAgICBwdHItPnNhdmVkX3ZhcnMgPSBhc3AtPnBkdS0+dmFyaWFibGVzOyAvKiByZXF1ZXN0cyBjb250YWlucyBwb2ludGVycyB0byB2YXJpYWJsZXMgKi8KICAgIHB0ci0+dmJjb3VudCA9IGFzcC0+dmJjb3VudDsKCiAgICAvKgogICAgICogbWFrZSB0aGUgYWdlbnQgZm9yZ2V0IGFib3V0IHdoYXQgd2UndmUgc2F2ZWQgCiAgICAgKi8KICAgIGFzcC0+dHJlZWNhY2hlID0gTlVMTDsKICAgIGFzcC0+cmVxaW5mby0+YWdlbnRfZGF0YSA9IE5VTEw7CiAgICBhc3AtPnBkdS0+dmFyaWFibGVzID0gTlVMTDsKICAgIGFzcC0+cmVxdWVzdHMgPSBOVUxMOwoKICAgIHB0ci0+bmV4dCA9IFNldHM7CiAgICBTZXRzID0gcHRyOwoKICAgIHJldHVybiBwdHI7Cn0KCmludApnZXRfc2V0X2NhY2hlKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBhZ2VudF9zZXRfY2FjaGUgKnB0ciwgKnByZXYgPSBOVUxMOwoKICAgIGZvciAocHRyID0gU2V0czsgcHRyICE9IE5VTEw7IHB0ciA9IHB0ci0+bmV4dCkgewogICAgICAgIGlmIChwdHItPnNlc3MgPT0gYXNwLT5zZXNzaW9uICYmIHB0ci0+dHJhbnNJRCA9PSBhc3AtPnBkdS0+dHJhbnNpZCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByZW1vdmUgdGhpcyBpdGVtIGZyb20gbGlzdAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHByZXYpCiAgICAgICAgICAgICAgICBwcmV2LT5uZXh0ID0gcHRyLT5uZXh0OwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBTZXRzID0gcHRyLT5uZXh0OwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZm91bmQgaXQuICBHZXQgdGhlIG5lZWRlZCBkYXRhIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYXNwLT50cmVlY2FjaGUgPSBwdHItPnRyZWVjYWNoZTsKICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVfbGVuID0gcHRyLT50cmVlY2FjaGVfbGVuOwogICAgICAgICAgICBhc3AtPnRyZWVjYWNoZV9udW0gPSBwdHItPnRyZWVjYWNoZV9udW07CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGcmVlIHByZXZpb3VzbHkgYWxsb2NhdGVkIHJlcXVlc3RzIGJlZm9yZSBvdmVyd3JpdGluZyBieQogICAgICAgICAgICAgKiBjYWNoZWQgb25lcywgb3RoZXJ3aXNlIG1lbW9yeSBsZWFrcyEKICAgICAgICAgICAgICovCgkgICAgaWYgKGFzcC0+cmVxdWVzdHMpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBJIGRvbid0IHRoaW5rIHRoaXMgY2FzZSBzaG91bGQgZXZlciBoYXBwZW4uIFBsZWFzZSBlbWFpbAogICAgICAgICAgICAgICAgICogdGhlIG5ldC1zbm1wLWNvZGVyc0BsaXN0cy5zb3VyY2Vmb3JnZS5uZXQgaWYgeW91IGhhdmUKICAgICAgICAgICAgICAgICAqIGEgdGVzdCBjYXNlIHRoYXQgaGl0cyB0aGlzIGFzc2VydC4gLS0gcnN0b3J5CiAgICAgICAgICAgICAgICAgKi8KCQlpbnQgaTsKICAgICAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgPT0gYXNwLT5yZXF1ZXN0cyk7IC8qIHNlZSBub3RlIGFib3ZlICovCgkJZm9yIChpID0gMDsgaSA8IGFzcC0+dmJjb3VudDsgaSsrKSB7CgkJICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cygmYXNwLT5yZXF1ZXN0c1tpXSk7CgkJfQoJCWZyZWUoYXNwLT5yZXF1ZXN0cyk7CgkgICAgfQoJICAgIC8qCgkgICAgICogSWYgd2UgcmVwbGFjZSBhc3AtPnJlcXVlc3RzIHdpdGggdGhlIGluZm8gZnJvbSB0aGUgc2V0IGNhY2hlLAoJICAgICAqIHdlIHNob3VsZCByZXBsYWNlIGFzcC0+cGR1LT52YXJpYWJsZXMgYWxzbyB3aXRoIHRoZSBjYWNoZWQKCSAgICAgKiBpbmZvLCBhcyBhc3AtPnJlcXVlc3RzIGNvbnRhaW5zIHBvaW50ZXJzIHRvIHRoZW0uICBBbmQgd2UKCSAgICAgKiBzaG91bGQgYWxzbyBmcmVlIHRoZSBjdXJyZW50IGFzcC0+cGR1LT52YXJpYWJsZXMgbGlzdC4uLgoJICAgICAqLwoJICAgIGlmIChwdHItPnNhdmVkX3ZhcnMpIHsKCQlpZiAoYXNwLT5wZHUtPnZhcmlhYmxlcykKCQkgICAgc25tcF9mcmVlX3ZhcmJpbmQoYXNwLT5wZHUtPnZhcmlhYmxlcyk7CgkJYXNwLT5wZHUtPnZhcmlhYmxlcyA9IHB0ci0+c2F2ZWRfdmFyczsKICAgICAgICAgICAgICAgIGFzcC0+dmJjb3VudCA9IHB0ci0+dmJjb3VudDsKCSAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHdoZW4gd291bGQgd2Ugbm90IGhhdmUgc2F2ZWQgdmFyaWFibGVzPyBzb21lb25lCiAgICAgICAgICAgICAgICAgKiBsZXQgbWUga25vdyBpZiB0aGV5IGhpdCB0aGlzIGFzc2VydC4gLS0gcnN0b3J5CiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gcHRyLT5zYXZlZF92YXJzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhc3AtPnJlcXVlc3RzID0gcHRyLT5yZXF1ZXN0czsKCiAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gYXNwLT5yZXFpbmZvKTsKICAgICAgICAgICAgYXNwLT5yZXFpbmZvLT5hc3AgPSBhc3A7CiAgICAgICAgICAgIGFzcC0+cmVxaW5mby0+YWdlbnRfZGF0YSA9IHB0ci0+YWdlbnRfZGF0YTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHVwZGF0ZSByZXF1ZXN0IHJlcWluZm8sIGlmIGl0J3Mgb3V0IG9mIGRhdGUuCiAgICAgICAgICAgICAqIHl5eS1ya3M6IGludmVzdGlnYXRlIHdoZW4vd2h5IHNvbWV0aW1lcyB0aGV5IG1hdGNoLAogICAgICAgICAgICAgKiBzb21ldGltZXMgdGhleSBkb24ndC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKGFzcC0+cmVxdWVzdHMtPmFnZW50X3JlcV9pbmZvICE9IGFzcC0+cmVxaW5mbykgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIC0gb25lIGRvbid0IG1hdGNoIGNhc2U6IGFnZW50eCBzdWJhZ2VudHMuIHByZXYgYXNwICYgcmVxaW5mbwogICAgICAgICAgICAgICAgICogICBmcmVlZCwgcmVxdWVzdCByZXFpbmZvIHB0cnMgbm90IGNsZWFyZWQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICp0bXAgPSBhc3AtPnJlcXVlc3RzOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIHJlcWluZm8gJXAgZG9lc24ndCBtYXRjaCBjYWNoZWQgcmVxaW5mbyAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cmVxaW5mbywgYXNwLT5yZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8pKTsKICAgICAgICAgICAgICAgIGZvcig7IHRtcDsgdG1wID0gdG1wLT5uZXh0KQogICAgICAgICAgICAgICAgICAgIHRtcC0+YWdlbnRfcmVxX2luZm8gPSBhc3AtPnJlcWluZm87CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogLSBtYXRjaCBjYXNlOiA/CiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJ2ZXJib3NlOmFzcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICByZXFpbmZvICVwIG1hdGNoZXMgY2FjaGVkIHJlcWluZm8gJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnJlcWluZm8sIGFzcC0+cmVxdWVzdHMtPmFnZW50X3JlcV9pbmZvKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFNOTVBfRlJFRShwdHIpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgcHJldiA9IHB0cjsKICAgIH0KICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7Cn0KCi8qIEJ1bGtjYWNoZSBob2xkcyB0aGUgdmFsdWVzIGZvciB0aGUgKnJlcGVhdGluZyogdmFyYmluZHMgKG9ubHkpLAogKiAgIGJ1dCBvcmRlcmVkICJieSBjb2x1bW4iIC0gaS5lLiB0aGUgcmVwZXRpdGlvbnMgZm9yIGVhY2gKICogICByZXBlYXRpbmcgdmFyYmluZCBmb2xsb3cgb24gaW1tZWRpYXRlbHkgZnJvbSBvbmUgYW5vdGhlciwKICogICByYXRoZXIgdGhhbiBiZWluZyBpbnRlcmxlYXZlZCwgYXMgcmVxdWlyZWQgYnkgdGhlIHByb3RvY29sLgogKgogKiBTbyB3ZSBuZWVkIHRvIHJlYXJyYW5nZSB0aGUgdmFyYmluZCBsaXN0IHNvIGl0J3Mgb3JkZXJlZCAiYnkgcm93Ii4KICoKICogSW4gdGhlIGZvbGxvd2luZyBjb2RlIGNodW5rOgogKiAgICAgbiAgICAgICAgICAgID0gIyBub24tcmVwZWF0aW5nIHZhcmJpbmRzCiAqICAgICByICAgICAgICAgICAgPSAjIHJlcGVhdGluZyB2YXJiaW5kcwogKiAgICAgYXNwLT52YmNvdW50ID0gIyB2YXJiaW5kcyBpbiB0aGUgaW5jb21pbmcgUERVCiAqICAgICAgICAgKFNvIGFzcC0+dmJjb3VudCA9IG4rcikKICoKICogICAgIHJlcGVhdHMgPSBEZXNpcmVkICMgb2YgcmVwZXRpdGlvbnMgKG9mICdyJyB2YXJiaW5kcykKICovCk5FVFNOTVBfU1RBVElDX0lOTElORSB2b2lkCl9yZW9yZGVyX2dldGJ1bGsobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGludCAgICAgICAgICAgICBpLCBuID0gMCwgciA9IDA7CiAgICBpbnQgICAgICAgICAgICAgcmVwZWF0cyA9IGFzcC0+cGR1LT5lcnJpbmRleDsKICAgIGludCAgICAgICAgICAgICBqLCBrOwogICAgaW50ICAgICAgICAgICAgIGFsbF9lb01pYjsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqcHJldiA9IE5VTEwsICpjdXJyOwogICAgICAgICAgICAKICAgIGlmIChhc3AtPnZiY291bnQgPT0gMCkgIC8qIE5vdGhpbmcgdG8gZG8hICovCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChhc3AtPnBkdS0+ZXJyc3RhdCA8IGFzcC0+dmJjb3VudCkgewogICAgICAgIG4gPSBhc3AtPnBkdS0+ZXJyc3RhdDsKICAgIH0gZWxzZSB7CiAgICAgICAgbiA9IGFzcC0+dmJjb3VudDsKICAgIH0KICAgIGlmICgociA9IGFzcC0+dmJjb3VudCAtIG4pIDwgMCkgewogICAgICAgIHIgPSAwOwogICAgfQoKICAgIC8qIHdlIGRvIG5vdGhpbmcgaWYgdGhlcmUgaXMgbm90aGluZyByZXBlYXRlZCAqLwogICAgaWYgKHIgPT0gMCkKICAgICAgICByZXR1cm47CiAgICAgICAgICAgIAogICAgLyogRml4IGVuZE9mTWliVmlldyBlbnRyaWVzLiAqLwogICAgZm9yIChpID0gMDsgaSA8IHI7IGkrKykgewogICAgICAgIHByZXYgPSBOVUxMOwogICAgICAgIGZvciAoaiA9IDA7IGogPCByZXBlYXRzOyBqKyspIHsKCSAgICBjdXJyID0gYXNwLT5idWxrY2FjaGVbaSAqIHJlcGVhdHMgKyBqXTsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogIElmIHdlIGRvbid0IGhhdmUgYSB2YWxpZCBuYW1lIGZvciBhIGdpdmVuIHJlcGV0aXRpb24KICAgICAgICAgICAgICogICAoYW5kIHByb2JhYmx5IGZvciBhbGwgdGhlIG9uZXMgdGhhdCBmb2xsb3cgYXMgd2VsbCksCiAgICAgICAgICAgICAqICAgZXh0ZW5kIHRoZSBwcmV2aW91cyByZXN1bHQgdG8gaW5kaWNhdGUgJ2VuZE9mTWliVmlldycuCiAgICAgICAgICAgICAqICBPciBpZiB0aGUgcmVwZXRpdGlvbiBhbHJlYWR5IGhhcyB0eXBlIGVuZE9mTWliVmlldyBtYWtlCiAgICAgICAgICAgICAqICAgc3VyZSBpdCBoYXMgdGhlIGNvcnJlY3Qgb2JqaWQgKGkuZS4gdGhhdCBvZiB0aGUgcHJldmlvdXMKICAgICAgICAgICAgICogICBlbnRyeSBvciB0aGF0IG9mIHRoZSBvcmlnaW5hbCByZXF1ZXN0KS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChjdXJyLT5uYW1lX2xlbmd0aCA9PSAwIHx8IGN1cnItPnR5cGUgPT0gU05NUF9FTkRPRk1JQlZJRVcpIHsKCQlpZiAocHJldiA9PSBOVUxMKSB7CgkJICAgIC8qIFVzZSBvYmppZCBmcm9tIG9yaWdpbmFsIHBkdS4gKi8KCQkgICAgcHJldiA9IGFzcC0+b3JpZ19wZHUtPnZhcmlhYmxlczsKCQkgICAgZm9yIChrID0gaTsgcHJldiAmJiBrID4gMDsgay0tKQoJCQlwcmV2ID0gcHJldi0+bmV4dF92YXJpYWJsZTsKCQl9CgkJaWYgKHByZXYpIHsKCQkgICAgc25tcF9zZXRfdmFyX29iamlkKGN1cnIsIHByZXYtPm5hbWUsIHByZXYtPm5hbWVfbGVuZ3RoKTsKCQkgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKGN1cnIsIFNOTVBfRU5ET0ZNSUJWSUVXLCBOVUxMLCAwKTsKCQl9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJldiA9IGN1cnI7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBGb3IgZWFjaCBvZiB0aGUgb3JpZ2luYWwgcmVwZWF0aW5nIHZhcmJpbmRzIChleGNlcHQgdGhlIGxhc3QpLAogICAgICogIGdvIHRocm91Z2ggdGhlIGJsb2NrIG9mIHJlc3VsdHMgZm9yIHRoYXQgdmFyYmluZCwKICAgICAqICBhbmQgbGluayBlYWNoIGluc3RhbmNlIHRvIHRoZSBjb3JyZXNwb25kaW5nIGluc3RhbmNlCiAgICAgKiAgaW4gdGhlIG5leHQgYmxvY2suCiAgICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCByIC0gMTsgaSsrKSB7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IHJlcGVhdHM7IGorKykgewogICAgICAgICAgICBhc3AtPmJ1bGtjYWNoZVtpICogcmVwZWF0cyArIGpdLT5uZXh0X3ZhcmlhYmxlID0KICAgICAgICAgICAgICAgIGFzcC0+YnVsa2NhY2hlWyhpICsgMSkgKiByZXBlYXRzICsgal07CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBGb3IgdGhlIGxhc3Qgb2YgdGhlIG9yaWdpbmFsIHJlcGVhdGluZyB2YXJiaW5kcywKICAgICAqICBnbyB0aHJvdWdoIHRoYXQgYmxvY2sgb2YgcmVzdWx0cywgYW5kIGxpbmsgZWFjaAogICAgICogIGluc3RhbmNlIHRvIHRoZSAqbmV4dCogaW5zdGFuY2UgaW4gdGhlICpmaXJzdCogYmxvY2suCiAgICAgKgogICAgICogVGhlIHZlcnkgbGFzdCBpbnN0YW5jZSBvZiB0aGlzIGJsb2NrIGlzIGxlZnQgdW50b3VjaGVkCiAgICAgKiAgc2luY2UgaXQgKGNvcnJlY3RseSkgcG9pbnRzIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QuCiAgICAgKi8KICAgIGZvciAoaiA9IDA7IGogPCByZXBlYXRzIC0gMTsgaisrKSB7Cglhc3AtPmJ1bGtjYWNoZVsociAtIDEpICogcmVwZWF0cyArIGpdLT5uZXh0X3ZhcmlhYmxlID0gCgkgICAgYXNwLT5idWxrY2FjaGVbaiArIDFdOwogICAgfQoKICAgIC8qCiAgICAgKiBJZiB3ZSd2ZSBnb3QgYSBmdWxsIHJvdyBvZiBlbmRPZk1pYlZpZXdzLCB0aGVuIHdlCiAgICAgKiAgY2FuIHRydW5jYXRlIHRoZSByZXN1bHQgdmFyYmluZCBsaXN0IGFmdGVyIHRoYXQuCiAgICAgKgogICAgICogTG9vayBmb3IgZW5kT2ZNaWJWaWV3IGV4Y2VwdGlvbiB2YWx1ZXMgaW4gdGhlIGxpc3Qgb2YKICAgICAqICByZXBldGl0aW9ucyBmb3IgdGhlIGZpcnN0IHZhcmJpbmQsIGFuZCBjaGVjayB0aGUgCiAgICAgKiAgY29ycmVzcG9uZGluZyBpbnN0YW5jZXMgZm9yIHRoZSBvdGhlciB2YXJiaW5kcwogICAgICogIChmb2xsb3dpbmcgdGhlIG5leHRfdmFyaWFibGUgbGlua3MpLgogICAgICoKICAgICAqIElmIHRoZXkncmUgYWxsIGVuZE9mTWliVmlldyB0b28sIHRoZW4gd2UgY2FuIHRlcm1pbmF0ZQogICAgICogIHRoZSBsaW5rZWQgbGlzdCB0aGVyZSwgYW5kIGZyZWUgYW55IHJlZHVuZGFudCB2YXJiaW5kcy4KICAgICAqLwogICAgYWxsX2VvTWliID0gMDsKICAgIGZvciAoaSA9IDA7IGkgPCByZXBlYXRzOyBpKyspIHsKICAgICAgICBpZiAoYXNwLT5idWxrY2FjaGVbaV0tPnR5cGUgPT0gU05NUF9FTkRPRk1JQlZJRVcpIHsKICAgICAgICAgICAgYWxsX2VvTWliID0gMTsKICAgICAgICAgICAgZm9yIChqID0gMSwgcHJldj1hc3AtPmJ1bGtjYWNoZVtpXTsKICAgICAgICAgICAgICAgICBqIDwgcjsKICAgICAgICAgICAgICAgICBqKyssIHByZXY9cHJldi0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAgICAgaWYgKHByZXYtPnR5cGUgIT0gU05NUF9FTkRPRk1JQlZJRVcpIHsKICAgICAgICAgICAgICAgICAgICBhbGxfZW9NaWIgPSAwOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwkvKiBGb3VuZCBhIHJlYWwgdmFsdWUgKi8KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoYWxsX2VvTWliKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogVGhpcyBpcyBpbmRlZWQgYSBmdWxsIGVuZE9mTWliVmlldyByb3cuCiAgICAgICAgICAgICAgICAgKiBUZXJtaW5hdGUgdGhlIGxpc3QgaGVyZSAmIGZyZWUgdGhlIHJlc3QuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCBwcmV2LT5uZXh0X3ZhcmlhYmxlICk7CiAgICAgICAgICAgICAgICBwcmV2LT5uZXh0X3ZhcmlhYmxlID0gTlVMTDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgoKLyogRW5kT2ZNaWJWaWV3IHJlcGxpZXMgdG8gYSBHRVRORVhUIHJlcXVlc3Qgc2hvdWxkIGFjY29yZGluZyB0byBSRkMzNDE2CiAqICBoYXZlIHRoZSBvYmplY3QgSUQgc2V0IHRvIHRoYXQgb2YgdGhlIHJlcXVlc3QuIE91ciB0cmVlIHNlYXJjaCAKICogIGFsZ29yaXRobSB3aWxsIHNvbWV0aW1lcyBicmVhayB0aGF0IHJlcXVpcmVtZW50LiBUaGlzIGZ1bmN0aW9uIHdpbGwKICogIGZpeCB0aGF0LgogKi8KTkVUU05NUF9TVEFUSUNfSU5MSU5FIHZvaWQKX2ZpeF9lbmRvZm1pYnZpZXcobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmIsICpvdmI7CgogICAgaWYgKGFzcC0+dmJjb3VudCA9PSAwKSAgLyogTm90aGluZyB0byBkbyEgKi8KICAgICAgICByZXR1cm47CgogICAgZm9yICh2YiA9IGFzcC0+cGR1LT52YXJpYWJsZXMsIG92YiA9IGFzcC0+b3JpZ19wZHUtPnZhcmlhYmxlczsKCSB2YiAmJiBvdmI7IHZiID0gdmItPm5leHRfdmFyaWFibGUsIG92YiA9IG92Yi0+bmV4dF92YXJpYWJsZSkgewoJaWYgKHZiLT50eXBlID09IFNOTVBfRU5ET0ZNSUJWSUVXKQoJICAgIHNubXBfc2V0X3Zhcl9vYmppZCh2Yiwgb3ZiLT5uYW1lLCBvdmItPm5hbWVfbGVuZ3RoKTsKICAgIH0KfQoKCmludApnZXROZXh0U2Vzc0lEKHZvaWQpCnsKICAgIHN0YXRpYyBpbnQgICAgICBTZXNzaW9uSUQgPSAwOwoKICAgIHJldHVybiArK1Nlc3Npb25JRDsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gY2hlY2tzIGZvciBwYWNrZXRzIGFycml2aW5nIG9uIHRoZSBTTk1QIHBvcnQgYW5kCiAqIHByb2Nlc3NlcyB0aGVtKHNubXBfcmVhZCkgaWYgc29tZSBhcmUgZm91bmQsIHVzaW5nIHRoZSBzZWxlY3QoKS4gSWYgYmxvY2sKICogaXMgbm9uIHplcm8sIHRoZSBmdW5jdGlvbiBjYWxsIGJsb2NrcyB1bnRpbCBhIHBhY2tldCBhcnJpdmVzCiAqCiAqIEBwYXJhbSBibG9jayB1c2VkIHRvIGNvbnRyb2wgYmxvY2tpbmcgaW4gdGhlIHNlbGVjdCgpIGZ1bmN0aW9uLCAxID0gYmxvY2sKICogICAgICAgIGZvcmV2ZXIsIGFuZCAwID0gZG9uJ3QgYmxvY2sKICoKICogQHJldHVybiAgUmV0dXJucyBhIHBvc2l0aXZlIGludGVnZXIgaWYgcGFja2V0cyB3ZXJlIHByb2Nlc3NlZCwgYW5kIC0xIGlmIGFuCiAqIGVycm9yIHdhcyBmb3VuZC4KICoKICovCmludAphZ2VudF9jaGVja19hbmRfcHJvY2VzcyhpbnQgYmxvY2spCnsKICAgIGludCAgICAgICAgICAgICBudW1mZHM7CiAgICBmZF9zZXQgICAgICAgICAgZmRzZXQ7CiAgICBzdHJ1Y3QgdGltZXZhbCAgdGltZW91dCA9IHsgTE9OR19NQVgsIDAgfSwgKnR2cCA9ICZ0aW1lb3V0OwogICAgaW50ICAgICAgICAgICAgIGNvdW50OwogICAgaW50ICAgICAgICAgICAgIGZha2VibG9jayA9IDA7CgogICAgbnVtZmRzID0gMDsKICAgIEZEX1pFUk8oJmZkc2V0KTsKICAgIHNubXBfc2VsZWN0X2luZm8oJm51bWZkcywgJmZkc2V0LCB0dnAsICZmYWtlYmxvY2spOwogICAgaWYgKGJsb2NrICE9IDAgJiYgZmFrZWJsb2NrICE9IDApIHsKICAgICAgICAvKgogICAgICAgICAqIFRoZXJlIGFyZSBubyBhbGFybXMgcmVnaXN0ZXJlZCwgYW5kIHRoZSBjYWxsZXIgYXNrZWQgZm9yIGJsb2NraW5nLCBzbwogICAgICAgICAqIGxldCBzZWxlY3QoKSBibG9jayBmb3JldmVyLiAgCiAgICAgICAgICovCgogICAgICAgIHR2cCA9IE5VTEw7CiAgICB9IGVsc2UgaWYgKGJsb2NrICE9IDAgJiYgZmFrZWJsb2NrID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIFRoZSBjYWxsZXIgYXNrZWQgZm9yIGJsb2NraW5nLCBidXQgdGhlcmUgaXMgYW4gYWxhcm0gZHVlIHNvb25lciB0aGFuCiAgICAgICAgICogTE9OR19NQVggc2Vjb25kcyBmcm9tIG5vdywgc28gdXNlIHRoZSBtb2RpZmllZCB0aW1lb3V0IHJldHVybmVkIGJ5CiAgICAgICAgICogc25tcF9zZWxlY3RfaW5mbyBhcyB0aGUgdGltZW91dCBmb3Igc2VsZWN0KCkuICAKICAgICAgICAgKi8KCiAgICB9IGVsc2UgaWYgKGJsb2NrID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIFRoZSBjYWxsZXIgZG9lcyBub3Qgd2FudCB1cyB0byBibG9jayBhdCBhbGwuICAKICAgICAgICAgKi8KCiAgICAgICAgdGltZXJjbGVhcih0dnApOwogICAgfQoKICAgIGNvdW50ID0gc2VsZWN0KG51bWZkcywgJmZkc2V0LCBOVUxMLCBOVUxMLCB0dnApOwoKICAgIGlmIChjb3VudCA+IDApIHsKICAgICAgICAvKgogICAgICAgICAqIHBhY2tldHMgZm91bmQsIHByb2Nlc3MgdGhlbSAKICAgICAgICAgKi8KICAgICAgICBzbm1wX3JlYWQoJmZkc2V0KTsKICAgIH0gZWxzZQogICAgICAgIHN3aXRjaCAoY291bnQpIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgIHNubXBfdGltZW91dCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIC0xOgogICAgICAgICAgICBpZiAoZXJybm8gIT0gRUlOVFIpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nX3BlcnJvcigic2VsZWN0Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJzZWxlY3QgcmV0dXJuZWQgJWRcbiIsIGNvdW50KTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZGlmIC0tIGNvdW50PjAgKi8KCiAgICAvKgogICAgICogUnVuIHJlcXVlc3RlZCBhbGFybXMuICAKICAgICAqLwogICAgcnVuX2FsYXJtcygpOwoKICAgIG5ldHNubXBfY2hlY2tfb3V0c3RhbmRpbmdfYWdlbnRfcmVxdWVzdHMoKTsKCiAgICByZXR1cm4gY291bnQ7Cn0KCgovKgogKiBTZXQgdXAgdGhlIGFkZHJlc3MgY2FjaGUuICAKICovCnZvaWQKbmV0c25tcF9hZGRyY2FjaGVfaW5pdGlhbGlzZSh2b2lkKQp7CiAgICBpbnQgICAgICAgICAgICAgaSA9IDA7CgogICAgZm9yIChpID0gMDsgaSA8IFNOTVBfQUREUkNBQ0hFX1NJWkU7IGkrKykgewogICAgICAgIGFkZHJDYWNoZVtpXS5hZGRyID0gTlVMTDsKICAgICAgICBhZGRyQ2FjaGVbaV0uc3RhdHVzID0gU05NUF9BRERSQ0FDSEVfVU5VU0VEOwogICAgfQp9Cgp2b2lkIG5ldHNubXBfYWRkcmNhY2hlX2Rlc3Ryb3kodm9pZCkKewogICAgaW50ICAgICAgICAgICAgIGkgPSAwOwoKICAgIGZvciAoaSA9IDA7IGkgPCBTTk1QX0FERFJDQUNIRV9TSVpFOyBpKyspIHsKICAgICAgICBpZiAoYWRkckNhY2hlW2ldLnN0YXR1cyA9PSBTTk1QX0FERFJDQUNIRV9VU0VEKSB7CiAgICAgICAgICAgIGZyZWUoYWRkckNhY2hlW2ldLmFkZHIpOwogICAgICAgICAgICBhZGRyQ2FjaGVbaV0uc3RhdHVzID0gU05NUF9BRERSQ0FDSEVfVU5VU0VEOwogICAgICAgIH0KICAgIH0KfQoKLyoKICogQWRkcyBhIG5ldyBlbnRyeSB0byB0aGUgY2FjaGUgb2YgYWRkcmVzc2VzIHRoYXQKICogaGF2ZSByZWNlbnRseSBtYWRlIGNvbm5lY3Rpb25zIHRvIHRoZSBhZ2VudC4KICogUmV0dXJucyAwIGlmIHRoZSBlbnRyeSBhbHJlYWR5IGV4aXN0cyAoYnV0IHVwZGF0ZXMKICogdGhlIGVudHJ5IHdpdGggYSBuZXcgdGltZXN0YW1wKSBhbmQgMSBpZiB0aGUKICogZW50cnkgZGlkIG5vdCBwcmV2aW91c2x5IGV4aXN0LgogKgogKiBJbXBsZW1lbnRzIGEgc2ltcGxlIExSVSBjYWNoZSByZXBsYWNlbWVudAogKiBwb2xpY3kuIFVzZXMgYSBsaW5lYXIgc2VhcmNoLCB3aGljaCBzaG91bGQgYmUKICogb2theSwgYXMgbG9uZyBhcyBTTk1QX0FERFJDQUNIRV9TSVpFIHJlbWFpbnMKICogcmVsYXRpdmVseSBzbWFsbC4KICoKICogQHJldHZhbCAwIDogdXBkYXRlZCBleGlzdGluZyBlbnRyeQogKiBAcmV0dmFsIDEgOiBhZGRlZCBuZXcgZW50cnkKICovCmludApuZXRzbm1wX2FkZHJjYWNoZV9hZGQoY29uc3QgY2hhciAqYWRkcikKewogICAgaW50IG9sZGVzdCA9IC0xOyAvKiBJbmRleCBvZiB0aGUgb2xkZXN0IGNhY2hlIGVudHJ5ICovCiAgICBpbnQgdW51c2VkID0gLTE7IC8qIEluZGV4IG9mIHRoZSBmaXJzdCBmcmVlIGNhY2hlIGVudHJ5ICovCiAgICBpbnQgaTsgLyogTG9vcGluZyB2YXJpYWJsZSAqLwogICAgaW50IHJjID0gLTE7CiAgICBzdHJ1Y3QgdGltZXZhbCBub3c7IC8qIFdoYXQgdGltZSBpcyBpdCBub3c/ICovCiAgICBzdHJ1Y3QgdGltZXZhbCBhZ2VkOyAvKiBPbGRlc3QgYWxsb3dhYmxlIGNhY2hlIGVudHJ5ICovCgogICAgLyoKICAgICAqIEZpcnN0IGdldCB0aGUgY3VycmVudCBhbmQgb2xkZXN0IGFsbG93YWJsZSB0aW1lc3RhbXBzCiAgICAgKi8KICAgIGdldHRpbWVvZmRheSgmbm93LCAoc3RydWN0IHRpbWV6b25lKikgTlVMTCk7CiAgICBhZ2VkLnR2X3NlYyA9IG5vdy50dl9zZWMgLSBTTk1QX0FERFJDQUNIRV9NQVhBR0U7CiAgICBhZ2VkLnR2X3VzZWMgPSBub3cudHZfdXNlYzsKCiAgICAvKgogICAgICogTm93IGxvb2sgZm9yIGEgcGxhY2UgdG8gcHV0IHRoaXMgdGhpbmcKICAgICAqLwogICAgZm9yKGkgPSAwOyBpIDwgU05NUF9BRERSQ0FDSEVfU0laRTsgaSsrKSB7CiAgICAgICAgaWYgKGFkZHJDYWNoZVtpXS5zdGF0dXMgPT0gU05NUF9BRERSQ0FDSEVfVU5VU0VEKSB7IC8qIElmIHVudXNlZCAqLwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByZW1lbWJlciB0aGlzIGxvY2F0aW9uLCBpbiBjYXNlIGFkZHIgaXNuJ3QgaW4gdGhlIGNhY2hlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAodW51c2VkIDwgMCkKICAgICAgICAgICAgICAgIHVudXNlZCA9IGk7CiAgICAgICAgfQogICAgICAgIGVsc2UgeyAvKiBJZiB1c2VkICovCiAgICAgICAgICAgIGlmICgoTlVMTCAhPSBhZGRyKSAmJiAoc3RyY21wKGFkZHJDYWNoZVtpXS5hZGRyLCBhZGRyKSA9PSAwKSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGZvdW5kIGEgbWF0Y2gKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgYWRkckNhY2hlW2ldLmxhc3RIaXQgPSBub3c7CiAgICAgICAgICAgICAgICBpZiAodGltZXJjbXAoJmFkZHJDYWNoZVtpXS5sYXN0SGl0LCAmYWdlZCwgPCkpCgkJICAgIHJjID0gMTsgLyogc2hvdWxkIGhhdmUgZXhwaXJlZCwgc28gaXMgbmV3ICovCgkJZWxzZQoJCSAgICByYyA9IDA7IC8qIG5vdCBleHBpcmVkLCBzbyBpcyBleGlzdGluZyBlbnRyeSAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogVXNlZCwgYnV0IG5vdCB0aGlzIGFkZHJlc3MuIGNoZWNrIGlmIGl0J3Mgc3RhbGUuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICh0aW1lcmNtcCgmYWRkckNhY2hlW2ldLmxhc3RIaXQsICZhZ2VkLCA8KSkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogU3RhbGUsIHJldXNlCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKGFkZHJDYWNoZVtpXS5hZGRyKTsKICAgICAgICAgICAgICAgICAgICBhZGRyQ2FjaGVbaV0uc3RhdHVzID0gU05NUF9BRERSQ0FDSEVfVU5VU0VEOwogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogcmVtZW1iZXIgdGhpcyBsb2NhdGlvbiwgaW4gY2FzZSBhZGRyIGlzbid0IGluIHRoZSBjYWNoZQogICAgICAgICAgICAgICAgICAgICAqLwoJCSAgICBpZiAodW51c2VkIDwgMCkKICAgICAgICAgICAgICAgICAgICAgICAgdW51c2VkID0gaTsKICAgICAgICAgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBTdGlsbCBmcmVzaCwgYnV0IGEgY2FuZGlkYXRlIGZvciBMUlUgcmVwbGFjZW1lbnQKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAob2xkZXN0IDwgMCkKICAgICAgICAgICAgICAgICAgICAgICAgb2xkZXN0ID0gaTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0aW1lcmNtcCgmYWRkckNhY2hlW2ldLmxhc3RIaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFkZHJDYWNoZVtvbGRlc3RdLmxhc3RIaXQsIDwpKQogICAgICAgICAgICAgICAgICAgICAgICBvbGRlc3QgPSBpOwogICAgICAgICAgICAgICAgfSAvKiBmcmVzaCAqLwogICAgICAgICAgICB9IC8qIHVzZWQsIG5vIG1hdGNoICovCiAgICAgICAgfSAvKiB1c2VkICovCiAgICB9IC8qIGZvciBsb29wICovCgogICAgaWYgKCgtMSA9PSByYykgJiYgKE5VTEwgIT0gYWRkcikpIHsKICAgICAgICAvKgogICAgICAgICAqIFdlIGRpZG4ndCBmaW5kIHRoZSBlbnRyeSBpbiB0aGUgY2FjaGUKICAgICAgICAgKi8KICAgICAgICBpZiAodW51c2VkID49IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogSWYgd2UgaGF2ZSBhIHNsb3QgZnJlZSBhbnl3YXksIHVzZSBpdAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYWRkckNhY2hlW3VudXNlZF0uYWRkciA9IHN0cmR1cChhZGRyKTsKICAgICAgICAgICAgYWRkckNhY2hlW3VudXNlZF0uc3RhdHVzID0gU05NUF9BRERSQ0FDSEVfVVNFRDsKICAgICAgICAgICAgYWRkckNhY2hlW3VudXNlZF0ubGFzdEhpdCA9IG5vdzsKICAgICAgICB9CiAgICAgICAgZWxzZSB7IC8qIE90aGVyd2lzZSwgcmVwbGFjZSBvbGRlc3QgZW50cnkgKi8KICAgICAgICAgICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9WRVJCT1NFKSkKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19JTkZPLCAiUHVyZ2luZyBhZGRyZXNzIGZyb20gYWRkcmVzcyBjYWNoZTogJXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgYWRkckNhY2hlW29sZGVzdF0uYWRkcik7CiAgICAgICAgICAgIAogICAgICAgICAgICBmcmVlKGFkZHJDYWNoZVtvbGRlc3RdLmFkZHIpOwogICAgICAgICAgICBhZGRyQ2FjaGVbb2xkZXN0XS5hZGRyID0gc3RyZHVwKGFkZHIpOwogICAgICAgICAgICBhZGRyQ2FjaGVbb2xkZXN0XS5sYXN0SGl0ID0gbm93OwogICAgICAgIH0KICAgICAgICByYyA9IDE7CiAgICB9CiAgICBpZiAoKGxvZ19hZGRyZXNzZXMgJiYgKDEgPT0gcmMpKSB8fAogICAgICAgIG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfVkVSQk9TRSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfSU5GTywgIlJlY2VpdmVkIFNOTVAgcGFja2V0KHMpIGZyb20gJXNcbiIsIGFkZHIpOwogICAgIH0KCiAgICByZXR1cm4gcmM7Cn0KCi8qCiAqIEFnZSB0aGUgZW50cmllcyBpbiB0aGUgYWRkcmVzcyBjYWNoZS4gIAogKgogKiBiYWNrd2FyZHMgY29tcGF0YWJpbGl0eTsgbm90IHVzZWQgYW55d2hlcmUKICovCnZvaWQKbmV0c25tcF9hZGRyY2FjaGVfYWdlKHZvaWQpCnsKICAgICh2b2lkKW5ldHNubXBfYWRkcmNhY2hlX2FkZChOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogbmV0c25tcF9hZ2VudF9jaGVja19wYWNrZXQKICoKICogUGFyYW1ldGVyczoKICoJc2Vzc2lvbiwgdHJhbnNwb3J0LCB0cmFuc3BvcnRfZGF0YSwgdHJhbnNwb3J0X2RhdGFfbGVuZ3RoCiAqICAgICAgCiAqIFJldHVybnM6CiAqCTEJT24gc3VjY2Vzcy4KICoJMAlPbiBlcnJvci4KICoKICogSGFuZGxlciBmb3IgYWxsIGluY29taW5nIG1lc3NhZ2VzIChhLmsuYS4gcGFja2V0cykgZm9yIHRoZSBhZ2VudC4gIElmIHVzaW5nCiAqIHRoZSBsaWJ3cmFwIHV0aWxpdHksIGxvZyB0aGUgY29ubmVjdGlvbiBhbmQgZGVueS9hbGxvdyB0aGUgYWNjZXNzLiBQcmludAogKiBvdXRwdXQgd2hlbiBhcHByb3ByaWF0ZSwgYW5kIGluY3JlbWVudCB0aGUgaW5jb21pbmcgY291bnRlci4KICoKICovCgppbnQKbmV0c25tcF9hZ2VudF9jaGVja19wYWNrZXQobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqdHJhbnNwb3J0X2RhdGEsIGludCB0cmFuc3BvcnRfZGF0YV9sZW5ndGgpCnsKICAgIGNoYXIgICAgICAgICAgICphZGRyX3N0cmluZyA9IE5VTEw7CiNpZmRlZiAgTkVUU05NUF9VU0VfTElCV1JBUAogICAgY2hhciAqdGNwdWRwYWRkciA9IE5VTEwsICpuYW1lOwogICAgc2hvcnQgbm90X2xvZ19jb25uZWN0aW9uOwoKICAgIG5hbWUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFKTsKCiAgICAvKiBub3RfbG9nX2Nvbm5lY3Rpb24gd2lsbCBiZSAxIGlmIHdlIHNob3VsZCBza2lwIHRoZSBtZXNzYWdlcyAqLwogICAgbm90X2xvZ19jb25uZWN0aW9uID0gbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX0RPTlRfTE9HX1RDUFdSQVBQRVJTX0NPTk5FQ1RTKTsKCiAgICAvKgogICAgICogaGFuZGxlIHRoZSBlcnJvciBjYXNlCiAgICAgKiBkZWZhdWx0IHRvIGxvZ2dpbmcgdGhlIG1lc3NhZ2VzCiAgICAgKi8KICAgIGlmIChub3RfbG9nX2Nvbm5lY3Rpb24gPT0gU05NUEVSUl9HRU5FUlIpIG5vdF9sb2dfY29ubmVjdGlvbiA9IDA7CiNlbmRpZgoKICAgIC8qCiAgICAgKiBMb2cgdGhlIG1lc3NhZ2UgYW5kL29yIGR1bXAgdGhlIG1lc3NhZ2UuCiAgICAgKiBPcHRpb25hbGx5IGNhY2hlIHRoZSBuZXR3b3JrIGFkZHJlc3Mgb2YgdGhlIHNlbmRlci4KICAgICAqLwoKICAgIGlmICh0cmFuc3BvcnQgIT0gTlVMTCAmJiB0cmFuc3BvcnQtPmZfZm10YWRkciAhPSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBPa2F5IEkgZG8ga25vdyBob3cgdG8gZm9ybWF0IHRoaXMgYWRkcmVzcyBmb3IgbG9nZ2luZy4gIAogICAgICAgICAqLwogICAgICAgIGFkZHJfc3RyaW5nID0gdHJhbnNwb3J0LT5mX2ZtdGFkZHIodHJhbnNwb3J0LCB0cmFuc3BvcnRfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcG9ydF9kYXRhX2xlbmd0aCk7CiAgICAgICAgLyoKICAgICAgICAgKiBEb24ndCBmb3JnZXQgdG8gZnJlZSgpIGl0LiAgCiAgICAgICAgICovCiAgICB9CiNpZmRlZiAgTkVUU05NUF9VU0VfTElCV1JBUAogICAgLyogQ2F0Y2ggdWRwLHVkcDYsdGNwLHRjcDYgdHJhbnNwb3J0cyB1c2luZyAiWyIgKi8KICAgIGlmIChhZGRyX3N0cmluZykKICAgICAgICB0Y3B1ZHBhZGRyID0gc3Ryc3RyKGFkZHJfc3RyaW5nLCAiWyIpOwogICAgaWYgKCB0Y3B1ZHBhZGRyICE9IDAgKSB7CiAgICAgICAgY2hhciBzYnVmWzY0XTsKICAgICAgICBjaGFyICp4cDsKCiAgICAgICAgc3RybGNweShzYnVmLCB0Y3B1ZHBhZGRyICsgMSwgc2l6ZW9mKHNidWYpKTsKICAgICAgICB4cCA9IHN0cnN0cihzYnVmLCAiXSIpOwogICAgICAgIGlmICh4cCkKICAgICAgICAgICAgKnhwID0gJ1wwJzsKIAogICAgICAgIGlmIChob3N0c19jdGwobmFtZSwgU1RSSU5HX1VOS05PV04sIHNidWYsIFNUUklOR19VTktOT1dOKSkgewogICAgICAgICAgICBpZiAoIW5vdF9sb2dfY29ubmVjdGlvbikgewogICAgICAgICAgICAgICAgc25tcF9sb2coYWxsb3dfc2V2ZXJpdHksICJDb25uZWN0aW9uIGZyb20gJXNcbiIsIGFkZHJfc3RyaW5nKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNubXBfbG9nKGRlbnlfc2V2ZXJpdHksICJDb25uZWN0aW9uIGZyb20gJXMgUkVGVVNFRFxuIiwKICAgICAgICAgICAgICAgICAgICAgYWRkcl9zdHJpbmcpOwogICAgICAgICAgICBTTk1QX0ZSRUUoYWRkcl9zdHJpbmcpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogZG9uJ3QgbG9nIGNhbGxiYWNrIGNvbm5lY3Rpb25zLgogICAgICAgICAqIFdoYXQgYWJvdXQgJ0xvY2FsIElQQycsICdJUFgnIGFuZCAnQUFMNSBQVkMnPwogICAgICAgICAqLwogICAgICAgIGlmICgwID09IHN0cm5jbXAoYWRkcl9zdHJpbmcsICJjYWxsYmFjayIsIDgpKQogICAgICAgICAgICA7CiAgICAgICAgZWxzZSBpZiAoaG9zdHNfY3RsKG5hbWUsIFNUUklOR19VTktOT1dOLCBTVFJJTkdfVU5LTk9XTiwgU1RSSU5HX1VOS05PV04pKXsKICAgICAgICAgICAgaWYgKCFub3RfbG9nX2Nvbm5lY3Rpb24pIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKGFsbG93X3NldmVyaXR5LCAiQ29ubmVjdGlvbiBmcm9tIDxVTktOT1dOPiAoJXMpXG4iLCBhZGRyX3N0cmluZyk7CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIFNOTVBfRlJFRShhZGRyX3N0cmluZyk7CiAgICAgICAgICAgIGFkZHJfc3RyaW5nID0gc3RyZHVwKCI8VU5LTk9XTj4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzbm1wX2xvZyhkZW55X3NldmVyaXR5LCAiQ29ubmVjdGlvbiBmcm9tIDxVTktOT1dOPiAoJXMpIFJFRlVTRURcbiIsIGFkZHJfc3RyaW5nKTsKICAgICAgICAgICAgU05NUF9GUkVFKGFkZHJfc3RyaW5nKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qTkVUU05NUF9VU0VfTElCV1JBUCAqLwoKICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTlBLVFMpOwoKICAgIGlmIChhZGRyX3N0cmluZyAhPSBOVUxMKSB7CiAgICAgICAgbmV0c25tcF9hZGRyY2FjaGVfYWRkKGFkZHJfc3RyaW5nKTsKICAgICAgICBTTk1QX0ZSRUUoYWRkcl9zdHJpbmcpOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCgppbnQKbmV0c25tcF9hZ2VudF9jaGVja19wYXJzZShuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLCBuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgICAgICAgICAgICAgICAgICAgIGludCByZXN1bHQpCnsKICAgIGlmIChyZXN1bHQgPT0gMCkgewogICAgICAgIGlmIChzbm1wX2dldF9kb19sb2dnaW5nKCkgJiYKCSAgICBuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIAoJCQkJICAgTkVUU05NUF9EU19BR0VOVF9WRVJCT1NFKSkgewogICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcl9wdHI7CgogICAgICAgICAgICBzd2l0Y2ggKHBkdS0+Y29tbWFuZCkgewogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgR0VUIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgR0VUTkVYVCBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX1JFU1BPTlNFOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBSRVNQT05TRSBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX1NFVDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgU0VUIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfVFJBUDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgVFJBUCBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIEdFVEJVTEsgbWVzc2FnZSwgbm9uLXJlcD0lbGQsIG1heF9yZXA9JWxkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5lcnJzdGF0LCBwZHUtPmVycmluZGV4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lORk9STToKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgSU5GT1JNIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfVFJBUDI6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIFRSQVAyIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfUkVQT1JUOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBSRVBPUlQgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUxOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBJTlRFUk5BTCBSRVNFUlZFMSBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfUkVTRVJWRTI6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIElOVEVSTkFMIFJFU0VSVkUyIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9BQ1RJT046CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIElOVEVSTkFMIEFDVElPTiBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQ09NTUlUOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBJTlRFUk5BTCBDT01NSVQgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX0ZSRUU6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIElOVEVSTkFMIEZSRUUgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1VORE86CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIElOVEVSTkFMIFVORE8gbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIFVOS05PV04gbWVzc2FnZSwgdHlwZT0lMDJYXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5jb21tYW5kKTsKICAgICAgICAgICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXJfcHRyID0gcGR1LT52YXJpYWJsZXM7IHZhcl9wdHIgIT0gTlVMTDsKICAgICAgICAgICAgICAgICB2YXJfcHRyID0gdmFyX3B0ci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAgICAgc2l6ZV90ICAgICAgICAgIGNfb2lkbGVuID0gMjU2LCBjX291dGxlbiA9IDA7CiAgICAgICAgICAgICAgICB1X2NoYXIgICAgICAgICAqY19vaWQgPSAodV9jaGFyICopIG1hbGxvYyhjX29pZGxlbik7CgogICAgICAgICAgICAgICAgaWYgKGNfb2lkKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFzcHJpbnRfcmVhbGxvY19vYmppZAogICAgICAgICAgICAgICAgICAgICAgICAoJmNfb2lkLCAmY19vaWRsZW4sICZjX291dGxlbiwgMSwgdmFyX3B0ci0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIHZhcl9wdHItPm5hbWVfbGVuZ3RoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgICAgLS0gJXMgW1RSVU5DQVRFRF1cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNfb2lkKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgICAgLS0gJXNcbiIsIGNfb2lkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKGNfb2lkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAwOyAgICAgICAgICAgICAgICAgICAvKiBYWFg6IGRvZXMgaXQgbWF0dGVyIHdoYXQgdGhlIHJldHVybiB2YWx1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGlzPyAgWWVzOiBpZiB3ZSByZXR1cm4gMCwgdGhlbiB0aGUgUERVIGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogZHVtcGVkLiAgKi8KfQoKCi8qCiAqIEdsb2JhbCBhY2Nlc3MgdG8gdGhlIHByaW1hcnkgc2Vzc2lvbiBzdHJ1Y3R1cmUgZm9yIHRoaXMgYWdlbnQuCiAqIGZvciBJbmRleCBBbGxvY2F0aW9uIHVzZSBpbml0aWFsbHkuIAogKi8KCi8qCiAqIEkgZG9uJ3QgdW5kZXJzdGFuZCB3aGF0IHRoaXMgaXMgZm9yIGF0IHRoZSBtb21lbnQuICBBRkFJQ1MgYXMgbG9uZyBhcyBpdAogKiBnZXRzIHNldCBhbmQgcG9pbnRzIGF0IGEgc2Vzc2lvbiwgdGhhdCdzIGZpbmUuICA/Pz8gIAogKi8KCm5ldHNubXBfc2Vzc2lvbiAqbWFpbl9zZXNzaW9uID0gTlVMTDsKCgoKLyoKICogU2V0IHVwIGFuIGFnZW50IHNlc3Npb24gb24gdGhlIGdpdmVuIHRyYW5zcG9ydC4gIFJldHVybiBhIGhhbmRsZQogKiB3aGljaCBtYXkgbGF0ZXIgYmUgdXNlZCB0byBkZS1yZWdpc3RlciB0aGlzIHRyYW5zcG9ydC4gIEEgcmV0dXJuCiAqIHZhbHVlIG9mIC0xIGluZGljYXRlcyBhbiBlcnJvci4gIAogKi8KCmludApuZXRzbm1wX3JlZ2lzdGVyX2FnZW50X25zYXAobmV0c25tcF90cmFuc3BvcnQgKnQpCnsKICAgIG5ldHNubXBfc2Vzc2lvbiAqcywgKnNwID0gTlVMTDsKICAgIGFnZW50X25zYXAgICAgICphID0gTlVMTCwgKm4gPSBOVUxMLCAqKnByZXZOZXh0ID0gJmFnZW50X25zYXBfbGlzdDsKICAgIGludCAgICAgICAgICAgICBoYW5kbGUgPSAwOwogICAgdm9pZCAgICAgICAgICAgKmlzcCA9IE5VTEw7CgogICAgaWYgKHQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBERUJVR01TR1RMKCgibmV0c25tcF9yZWdpc3Rlcl9hZ2VudF9uc2FwIiwgImZkICVkXG4iLCB0LT5zb2NrKSk7CgogICAgbiA9IChhZ2VudF9uc2FwICopIG1hbGxvYyhzaXplb2YoYWdlbnRfbnNhcCkpOwogICAgaWYgKG4gPT0gTlVMTCkgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIHMgPSAobmV0c25tcF9zZXNzaW9uICopIG1hbGxvYyhzaXplb2YobmV0c25tcF9zZXNzaW9uKSk7CiAgICBpZiAocyA9PSBOVUxMKSB7CiAgICAgICAgU05NUF9GUkVFKG4pOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIG1lbXNldChzLCAwLCBzaXplb2YobmV0c25tcF9zZXNzaW9uKSk7CiAgICBzbm1wX3Nlc3NfaW5pdChzKTsKCiAgICAvKgogICAgICogU2V0IHVwIHRoZSBzZXNzaW9uIGFwcHJvcHJpYXRlbHkgZm9yIGFuIGFnZW50LiAgCiAgICAgKi8KCiAgICBzLT52ZXJzaW9uID0gU05NUF9ERUZBVUxUX1ZFUlNJT047CiAgICBzLT5jYWxsYmFjayA9IGhhbmRsZV9zbm1wX3BhY2tldDsKICAgIHMtPmF1dGhlbnRpY2F0b3IgPSBOVUxMOwogICAgcy0+ZmxhZ3MgPSBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwgCgkJCQkgIE5FVFNOTVBfRFNfQUdFTlRfRkxBR1MpOwogICAgcy0+aXNBdXRob3JpdGF0aXZlID0gU05NUF9TRVNTX0FVVEhPUklUQVRJVkU7CgogICAgc3AgPSBzbm1wX2FkZChzLCB0LCBuZXRzbm1wX2FnZW50X2NoZWNrX3BhY2tldCwKICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9jaGVja19wYXJzZSk7CiAgICBpZiAoc3AgPT0gTlVMTCkgewogICAgICAgIFNOTVBfRlJFRShzKTsKICAgICAgICBTTk1QX0ZSRUUobik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIGlzcCA9IHNubXBfc2Vzc19wb2ludGVyKHNwKTsKICAgIGlmIChpc3AgPT0gTlVMTCkgeyAgICAgICAgICAvKiAgb3Zlci1jYXV0aW91cyAgKi8KICAgICAgICBTTk1QX0ZSRUUocyk7CiAgICAgICAgU05NUF9GUkVFKG4pOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBuLT5zID0gaXNwOwogICAgbi0+dCA9IHQ7CgogICAgaWYgKG1haW5fc2Vzc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgbWFpbl9zZXNzaW9uID0gc25tcF9zZXNzX3Nlc3Npb24oaXNwKTsKICAgIH0KCiAgICBmb3IgKGEgPSBhZ2VudF9uc2FwX2xpc3Q7IGEgIT0gTlVMTCAmJiBoYW5kbGUgKyAxID49IGEtPmhhbmRsZTsKICAgICAgICAgYSA9IGEtPm5leHQpIHsKICAgICAgICBoYW5kbGUgPSBhLT5oYW5kbGU7CiAgICAgICAgcHJldk5leHQgPSAmKGEtPm5leHQpOwogICAgfQoKICAgIGlmIChoYW5kbGUgPCBJTlRfTUFYKSB7CiAgICAgICAgbi0+aGFuZGxlID0gaGFuZGxlICsgMTsKICAgICAgICBuLT5uZXh0ID0gYTsKICAgICAgICAqcHJldk5leHQgPSBuOwogICAgICAgIFNOTVBfRlJFRShzKTsKICAgICAgICByZXR1cm4gbi0+aGFuZGxlOwogICAgfSBlbHNlIHsKICAgICAgICBTTk1QX0ZSRUUocyk7CiAgICAgICAgU05NUF9GUkVFKG4pOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KfQoKdm9pZApuZXRzbm1wX2RlcmVnaXN0ZXJfYWdlbnRfbnNhcChpbnQgaGFuZGxlKQp7CiAgICBhZ2VudF9uc2FwICAgICAqYSA9IE5VTEwsICoqcHJldk5leHQgPSAmYWdlbnRfbnNhcF9saXN0OwogICAgaW50ICAgICAgICAgICAgIG1haW5fc2Vzc2lvbl9kZXJlZ2lzdGVyZWQgPSAwOwoKICAgIERFQlVHTVNHVEwoKCJuZXRzbm1wX2RlcmVnaXN0ZXJfYWdlbnRfbnNhcCIsICJoYW5kbGUgJWRcbiIsIGhhbmRsZSkpOwoKICAgIGZvciAoYSA9IGFnZW50X25zYXBfbGlzdDsgYSAhPSBOVUxMICYmIGEtPmhhbmRsZSA8IGhhbmRsZTsgYSA9IGEtPm5leHQpIHsKICAgICAgICBwcmV2TmV4dCA9ICYoYS0+bmV4dCk7CiAgICB9CgogICAgaWYgKGEgIT0gTlVMTCAmJiBhLT5oYW5kbGUgPT0gaGFuZGxlKSB7CiAgICAgICAgKnByZXZOZXh0ID0gYS0+bmV4dDsKCWlmIChzbm1wX3Nlc3Nfc2Vzc2lvbl9sb29rdXAoYS0+cykpIHsKICAgICAgICAgICAgaWYgKG1haW5fc2Vzc2lvbiA9PSBzbm1wX3Nlc3Nfc2Vzc2lvbihhLT5zKSkgewogICAgICAgICAgICAgICAgbWFpbl9zZXNzaW9uX2RlcmVnaXN0ZXJlZCA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc25tcF9jbG9zZShzbm1wX3Nlc3Nfc2Vzc2lvbihhLT5zKSk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoZSBhYm92ZSBmcmVlKClzIHRoZSB0cmFuc3BvcnQgYW5kIHNlc3Npb24gcG9pbnRlcnMuICAKICAgICAgICAgICAgICovCiAgICAgICAgfQogICAgICAgIFNOTVBfRlJFRShhKTsKICAgIH0KCiAgICAvKgogICAgICogSWYgd2UndmUgZGVyZWdpc3RlcmVkIHRoZSBzZXNzaW9uIHRoYXQgbWFpbl9zZXNzaW9uIHVzZWQgdG8gcG9pbnQgdG8sCiAgICAgKiB0aGVuIG1ha2UgaXQgcG9pbnQgdG8gYW5vdGhlciBvbmUsIG9yIGluIHRoZSBsYXN0IHJlc29ydCwgbWFrZSBpdCBlcXVhbAogICAgICogdG8gTlVMTC4gIEJhc2ljYWxseSB0aGlzIHNob3VsZG4ndCBldmVyIGhhcHBlbiBpbiBub3JtYWwgb3BlcmF0aW9uCiAgICAgKiBiZWNhdXNlIG1haW5fc2Vzc2lvbiBzdGFydHMgb2ZmIHBvaW50aW5nIGF0IHRoZSBmaXJzdCBzZXNzaW9uIGFkZGVkIGJ5CiAgICAgKiBpbml0X21hc3Rlcl9hZ2VudCgpLCB3aGljaCB0aGVuIGRpc2NhcmRzIHRoZSBoYW5kbGUuICAKICAgICAqLwoKICAgIGlmIChtYWluX3Nlc3Npb25fZGVyZWdpc3RlcmVkKSB7CiAgICAgICAgaWYgKGFnZW50X25zYXBfbGlzdCAhPSBOVUxMKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKCQkJIldBUk5JTkc6IG1haW5fc2Vzc2lvbiBwdHIgY2hhbmdlZCBmcm9tICVwIHRvICVwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBtYWluX3Nlc3Npb24sIHNubXBfc2Vzc19zZXNzaW9uKGFnZW50X25zYXBfbGlzdC0+cykpKTsKICAgICAgICAgICAgbWFpbl9zZXNzaW9uID0gc25tcF9zZXNzX3Nlc3Npb24oYWdlbnRfbnNhcF9saXN0LT5zKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsCgkJCSJXQVJOSU5HOiBtYWluX3Nlc3Npb24gcHRyIGNoYW5nZWQgZnJvbSAlcCB0byBOVUxMXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBtYWluX3Nlc3Npb24pKTsKICAgICAgICAgICAgbWFpbl9zZXNzaW9uID0gTlVMTDsKICAgICAgICB9CiAgICB9Cn0KCgoKLyoKICogCiAqIFRoaXMgZnVuY3Rpb24gaGFzIGJlZW4gbW9kaWZpZWQgdG8gdXNlIHRoZSBleHBlcmltZW50YWwKICogbmV0c25tcF9yZWdpc3Rlcl9hZ2VudF9uc2FwIGludGVyZmFjZS4gIFRoZSBtYWpvciByZXNwb25zaWJpbGl0eSBvZiB0aGlzCiAqIGZ1bmN0aW9uIG5vdyBpcyB0byBpbnRlcnByZXQgYSBzdHJpbmcgc3BlY2lmaWVkIHRvIHRoZSBhZ2VudCAodmlhIC1wIG9uIHRoZQogKiBjb21tYW5kIGxpbmUsIG9yIGZyb20gYSBjb25maWd1cmF0aW9uIGZpbGUpIGFzIGEgbGlzdCBvZiBhZ2VudCBOU0FQcyBvbgogKiB3aGljaCB0byBsaXN0ZW4gZm9yIFNOTVAgcGFja2V0cy4gIFR5cGljYWxseSwgd2hlbiB5b3UgYWRkIGEgbmV3IHRyYW5zcG9ydAogKiBkb21haW4gImZvbyIsIHlvdSBhZGQgY29kZSBoZXJlIHN1Y2ggdGhhdCBpZiB0aGUgImZvbyIgY29kZSBpcyBjb21waWxlZAogKiBpbnRvIHRoZSBhZ2VudCAoU05NUF9UUkFOU1BPUlRfRk9PX0RPTUFJTiBpcyBkZWZpbmVkKSwgdGhlbiBhIHRva2VuIG9mIHRoZQogKiBmb3JtICJmb286YmxldGNoLTNhMDA1NGVmJXdvYiZ3b2IiIGdldHMgdHVybmVkIGludG8gdGhlIGFwcHJvcHJpYXRlCiAqIHRyYW5zcG9ydCBkZXNjcmlwdG9yLiAgbmV0c25tcF9yZWdpc3Rlcl9hZ2VudF9uc2FwIGlzIHRoZW4gY2FsbGVkIHdpdGggdGhhdAogKiB0cmFuc3BvcnQgZGVzY3JpcHRvciBhbmQgc2V0cyB1cCBhIGxpc3RlbmluZyBhZ2VudCBzZXNzaW9uIG9uIGl0LgogKiAKICogRXZlcnl0aGluZyB0aGVuIHdvcmtzIG11Y2ggYXMgbm9ybWFsOiB0aGUgYWdlbnQgcnVucyBpbiBhbiBpbmZpbml0ZSBsb29wCiAqIChpbiB0aGUgc25tcGQuYy9yZWNlaXZlKClyb3V0aW5lKSwgd2hpY2ggY2FsbHMgc25tcF9yZWFkKCkgd2hlbiBhIHJlcXVlc3QKICogaXMgcmVhZGFibGUgb24gYW55IG9mIHRoZSBnaXZlbiB0cmFuc3BvcnRzLiAgVGhpcyByb3V0aW5lIHRoZW4gdHJhdmVyc2VzCiAqIHRoZSBsaWJyYXJ5ICdTZXNzaW9ucycgbGlzdCB0byBpZGVudGlmeSB0aGUgcmVsZXZhbnQgc2Vzc2lvbiBhbmQgZXZlbnR1YWxseQogKiBpbnZva2VzICdfc2Vzc19yZWFkJy4gIFRoaXMgdGhlbiBwcm9jZXNzZXMgdGhlIGluY29taW5nIHBhY2tldCwgY2FsbGluZyB0aGUKICogcHJlX3BhcnNlLCBwYXJzZSwgcG9zdF9wYXJzZSBhbmQgY2FsbGJhY2sgcm91dGluZXMgaW4gdHVybi4KICogCiAqIEpCUE4gMjAwMDExMTcKICovCgppbnQKaW5pdF9tYXN0ZXJfYWdlbnQodm9pZCkKewogICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydDsKICAgIGNoYXIgICAgICAgICAgICpjcHRyOwogICAgY2hhciAgICAgICAgICAgKmJ1ZiA9IE5VTEw7CiAgICBjaGFyICAgICAgICAgICAqc3Q7CgogICAgLyogZGVmYXVsdCB0byBhIGRlZmF1bHQgY2FjaGUgc2l6ZSAqLwogICAgbmV0c25tcF9zZXRfbG9va3VwX2NhY2hlX3NpemUoLTEpOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIAoJCQkgICAgICAgTkVUU05NUF9EU19BR0VOVF9ST0xFKSAhPSBNQVNURVJfQUdFTlQpIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsCiAgICAgICAgICAgICAgICAgICAgImluaXRfbWFzdGVyX2FnZW50OyBub3QgbWFzdGVyIGFnZW50XG4iKSk7CgogICAgICAgIG5ldHNubXBfYXNzZXJ0KCJhZ2VudCByb2xlICFtYXN0ZXIgJiYgIXN1Yl9hZ2VudCIpOwogICAgICAgIAogICAgICAgIHJldHVybiAwOyAgICAgICAgICAgICAgIC8qICBObyBlcnJvciBpZiAhIE1BU1RFUl9BR0VOVCAgKi8KICAgIH0KCiAgICAvKgogICAgICogSGF2ZSBzcGVjaWZpYyBhZ2VudCBwb3J0cyBiZWVuIHNwZWNpZmllZD8gIAogICAgICovCiAgICBjcHRyID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIAoJCQkJIE5FVFNOTVBfRFNfQUdFTlRfUE9SVFMpOwoKICAgIGlmIChjcHRyKSB7CiAgICAgICAgYnVmID0gc3RyZHVwKGNwdHIpOwogICAgICAgIGlmICghYnVmKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICJFcnJvciBwcm9jZXNzaW5nIHRyYW5zcG9ydCBcIiVzXCJcbiIsIGNwdHIpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogTm8sIHNvIGp1c3Qgc3BlY2lmeSB0aGUgZGVmYXVsdCBwb3J0LiAgCiAgICAgICAgICovCiAgICAgICAgYnVmID0gc3RyZHVwKCIiKTsKICAgIH0KCiAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJmaW5hbCBwb3J0IHNwZWM6IFwiJXNcIlxuIiwgYnVmKSk7CiAgICBzdCA9IGJ1ZjsKICAgIGRvIHsKICAgICAgICAvKgogICAgICAgICAqIFNwZWNpZmljYXRpb24gZm9ybWF0OiAKICAgICAgICAgKiAKICAgICAgICAgKiBOT05FOiAgICAgICAgICAgICAgICAgICAgICAoYSBwc2V1ZG8tdHJhbnNwb3J0KQogICAgICAgICAqIFVEUDpbYWRkcmVzczpdcG9ydCAgICAgICAgKGFsc28gZGVmYXVsdCBpZiBubyB0cmFuc3BvcnQgaXMgc3BlY2lmaWVkKQogICAgICAgICAqIFRDUDpbYWRkcmVzczpdcG9ydCAgICAgICAgIChpZiBzdXBwb3J0ZWQpCiAgICAgICAgICogVW5peDpwYXRobmFtZSAgICAgICAgICAgICAgKGlmIHN1cHBvcnRlZCkKICAgICAgICAgKiBBQUw1UFZDOml0Zi52cGkudmNpICAgICAgICAoaWYgc3VwcG9ydGVkKQogICAgICAgICAqIElQWDpbbmV0d29ya106bm9kZVsvcG9ydF0gKGlmIHN1cHBvcnRlZCkKICAgICAgICAgKiAKICAgICAgICAgKi8KCgljcHRyID0gc3Q7CglzdCA9IHN0cmNocihzdCwgJywnKTsKCWlmIChzdCkKCSAgICAqc3QrKyA9ICdcMCc7CgogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImluc3RhbGxpbmcgbWFzdGVyIGFnZW50IG9uIHBvcnQgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgY3B0cikpOwoKICAgICAgICBpZiAoc3RybmNhc2VjbXAoY3B0ciwgIm5vbmUiLCA0KSA9PSAwKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgImluaXRfbWFzdGVyX2FnZW50OyBwc2V1ZG8tdHJhbnNwb3J0IFwibm9uZVwiICIKCQkJInJlcXVlc3RlZFxuIikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdHJhbnNwb3J0ID0gbmV0c25tcF90cmFuc3BvcnRfb3Blbl9zZXJ2ZXIoInNubXAiLCBjcHRyKTsKCiAgICAgICAgaWYgKHRyYW5zcG9ydCA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJFcnJvciBvcGVuaW5nIHNwZWNpZmllZCBlbmRwb2ludCBcIiVzXCJcbiIsCiAgICAgICAgICAgICAgICAgICAgIGNwdHIpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIGlmIChuZXRzbm1wX3JlZ2lzdGVyX2FnZW50X25zYXAodHJhbnNwb3J0KSA9PSAwKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICJFcnJvciByZWdpc3RlcmluZyBzcGVjaWZpZWQgdHJhbnNwb3J0IFwiJXNcIiBhcyBhbiAiCgkJICAgICAiYWdlbnQgTlNBUFxuIiwgY3B0cik7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgImluaXRfbWFzdGVyX2FnZW50OyBcIiVzXCIgcmVnaXN0ZXJlZCBhcyBhbiBhZ2VudCAiCgkJCSJOU0FQXG4iLCBjcHRyKSk7CiAgICAgICAgfQogICAgfSB3aGlsZShzdCAmJiAqc3QgIT0gJ1wwJyk7CiAgICBTTk1QX0ZSRUUoYnVmKTsKCiNpZmRlZiBVU0lOR19BR0VOVFhfTUFTVEVSX01PRFVMRQogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwgCgkJCSAgICAgICBORVRTTk1QX0RTX0FHRU5UX0FHRU5UWF9NQVNURVIpID09IDEpCiAgICAgICAgcmVhbF9pbml0X21hc3RlcigpOwojZW5kaWYKI2lmZGVmIFVTSU5HX1NNVVhfTU9EVUxFCiAgICBpZihzaG91bGRfaW5pdCgic211eCIpKQogICAgcmVhbF9pbml0X3NtdXgoKTsKI2VuZGlmCgogICAgcmV0dXJuIDA7Cn0KCnZvaWQKY2xlYXJfbnNhcF9saXN0KHZvaWQpCnsKICAgIERFQlVHTVNHVEwoKCJjbGVhcl9uc2FwX2xpc3QiLCAiY2xlYXIgdGhlIG5zYXAgbGlzdFxuIikpOwoKICAgIHdoaWxlIChhZ2VudF9uc2FwX2xpc3QgIT0gTlVMTCkKCW5ldHNubXBfZGVyZWdpc3Rlcl9hZ2VudF9uc2FwKGFnZW50X25zYXBfbGlzdC0+aGFuZGxlKTsKfQoKdm9pZApzaHV0ZG93bl9tYXN0ZXJfYWdlbnQodm9pZCkKewogICAgY2xlYXJfbnNhcF9saXN0KCk7Cn0KCgpuZXRzbm1wX2FnZW50X3Nlc3Npb24gKgppbml0X2FnZW50X3NubXBfc2Vzc2lvbihuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLCBuZXRzbm1wX3BkdSAqcGR1KQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCA9IChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKikKICAgICAgICBjYWxsb2MoMSwgc2l6ZW9mKG5ldHNubXBfYWdlbnRfc2Vzc2lvbikpOwoKICAgIGlmIChhc3AgPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwiYWdlbnRfc2VzaW9uICU4cCBjcmVhdGVkXG4iLCBhc3ApKTsKICAgIGFzcC0+c2Vzc2lvbiA9IHNlc3Npb247CiAgICBhc3AtPnBkdSA9IHNubXBfY2xvbmVfcGR1KHBkdSk7CiAgICBhc3AtPm9yaWdfcGR1ID0gc25tcF9jbG9uZV9wZHUocGR1KTsKICAgIGFzcC0+cncgPSBSRUFEOwogICAgYXNwLT5leGFjdCA9IFRSVUU7CiAgICBhc3AtPm5leHQgPSBOVUxMOwogICAgYXNwLT5tb2RlID0gUkVTRVJWRTE7CiAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICBhc3AtPmluZGV4ID0gMDsKICAgIGFzcC0+b2xkbW9kZSA9IDA7CiAgICBhc3AtPnRyZWVjYWNoZV9udW0gPSAtMTsKICAgIGFzcC0+dHJlZWNhY2hlX2xlbiA9IDA7CiAgICBhc3AtPnJlcWluZm8gPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvKTsKICAgIERFQlVHTVNHVEwoKCJ2ZXJib3NlOmFzcCIsICJhc3AgJXAgcmVxaW5mbyAlcCBjcmVhdGVkXG4iLAogICAgICAgICAgICAgICAgYXNwLCBhc3AtPnJlcWluZm8pKTsKCiAgICByZXR1cm4gYXNwOwp9Cgp2b2lkCmZyZWVfYWdlbnRfc25tcF9zZXNzaW9uKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBpZiAoIWFzcCkKICAgICAgICByZXR1cm47CgogICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCJhZ2VudF9zZXNzaW9uICU4cCByZWxlYXNlZFxuIiwgYXNwKSk7CgogICAgbmV0c25tcF9yZW1vdmVfZnJvbV9kZWxlZ2F0ZWQoYXNwKTsKICAgIAogICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwgImFzcCAlcCByZXFpbmZvICVwIGZyZWVkXG4iLAogICAgICAgICAgICAgICAgYXNwLCBhc3AtPnJlcWluZm8pKTsKICAgIGlmIChhc3AtPm9yaWdfcGR1KQogICAgICAgIHNubXBfZnJlZV9wZHUoYXNwLT5vcmlnX3BkdSk7CiAgICBpZiAoYXNwLT5wZHUpCiAgICAgICAgc25tcF9mcmVlX3BkdShhc3AtPnBkdSk7CiAgICBpZiAoYXNwLT5yZXFpbmZvKQogICAgICAgIG5ldHNubXBfZnJlZV9hZ2VudF9yZXF1ZXN0X2luZm8oYXNwLT5yZXFpbmZvKTsKICAgIGlmIChhc3AtPnRyZWVjYWNoZSkgewogICAgICAgIFNOTVBfRlJFRShhc3AtPnRyZWVjYWNoZSk7CiAgICB9CiAgICBpZiAoYXNwLT5idWxrY2FjaGUpIHsKICAgICAgICBTTk1QX0ZSRUUoYXNwLT5idWxrY2FjaGUpOwogICAgfQogICAgaWYgKGFzcC0+cmVxdWVzdHMpIHsKICAgICAgICBpbnQgICAgICAgICAgICAgaTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXNwLT52YmNvdW50OyBpKyspIHsKICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKCZhc3AtPnJlcXVlc3RzW2ldKTsKICAgICAgICB9CiAgICAgICAgU05NUF9GUkVFKGFzcC0+cmVxdWVzdHMpOwogICAgfQogICAgaWYgKGFzcC0+Y2FjaGVfc3RvcmUpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfY2FjaGVtYXAoYXNwLT5jYWNoZV9zdG9yZSk7CiAgICAgICAgYXNwLT5jYWNoZV9zdG9yZSA9IE5VTEw7CiAgICB9CiAgICBTTk1QX0ZSRUUoYXNwKTsKfQoKaW50Cm5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgaW50ICAgICAgICAgICAgIGk7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKCiAgICBpZiAoTlVMTCA9PSBhc3AtPnRyZWVjYWNoZSkKICAgICAgICByZXR1cm4gMDsKICAgIAogICAgZm9yIChpID0gMDsgaSA8PSBhc3AtPnRyZWVjYWNoZV9udW07IGkrKykgewogICAgICAgIGZvciAocmVxdWVzdCA9IGFzcC0+dHJlZWNhY2hlW2ldLnJlcXVlc3RzX2JlZ2luOyByZXF1ZXN0OwogICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgaWYgKHJlcXVlc3QtPmRlbGVnYXRlZCkKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwp9CgppbnQKbmV0c25tcF9jaGVja19kZWxlZ2F0ZWRfY2hhaW5fZm9yKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcHRtcDsKICAgIGZvciAoYXNwdG1wID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7IGFzcHRtcDsgYXNwdG1wID0gYXNwdG1wLT5uZXh0KSB7CiAgICAgICAgaWYgKGFzcHRtcCA9PSBhc3ApCiAgICAgICAgICAgIHJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCmludApuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWRfYW5kX2FkZChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgaWYgKG5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZChhc3ApKSB7CiAgICAgICAgaWYgKCFuZXRzbm1wX2NoZWNrX2RlbGVnYXRlZF9jaGFpbl9mb3IoYXNwKSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhZGQgdG8gZGVsZWdhdGVkIHJlcXVlc3QgY2hhaW4gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBhc3AtPm5leHQgPSBhZ2VudF9kZWxlZ2F0ZWRfbGlzdDsKICAgICAgICAgICAgYWdlbnRfZGVsZWdhdGVkX2xpc3QgPSBhc3A7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImRlbGVnYXRlIHNlc3Npb24gPT0gJThwXG4iLCBhc3ApKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKaW50Cm5ldHNubXBfcmVtb3ZlX2Zyb21fZGVsZWdhdGVkKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmN1cnIsICpwcmV2ID0gTlVMTDsKICAgIAogICAgZm9yIChjdXJyID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7IGN1cnI7IHByZXYgPSBjdXJyLCBjdXJyID0gY3Vyci0+bmV4dCkgewogICAgICAgIC8qCiAgICAgICAgICogaXMgdGhpcyB1cz8KICAgICAgICAgKi8KICAgICAgICBpZiAoY3VyciAhPSBhc3ApCiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIAogICAgICAgIC8qCiAgICAgICAgICogcmVtb3ZlIGZyb20gcXVldWUgCiAgICAgICAgICovCiAgICAgICAgaWYgKHByZXYgIT0gTlVMTCkKICAgICAgICAgICAgcHJldi0+bmV4dCA9IGFzcC0+bmV4dDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGFnZW50X2RlbGVnYXRlZF9saXN0ID0gYXNwLT5uZXh0OwoKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJyZW1vdmUgZGVsZWdhdGVkIHNlc3Npb24gPT0gJThwXG4iLCBhc3ApKTsKCiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCi8qCiAqIG5ldHNubXBfcmVtb3ZlX2RlbGVnYXRlZF9yZXF1ZXN0c19mb3Jfc2Vzc2lvbgogKgogKiBjYWxsZWQgd2hlbiBhIHNlc3Npb24gaXMgYmVpbmcgY2xvc2VkLiBDaGVjayBhbGwgZGVsZWdhdGVkIHJlcXVlc3RzIHRvCiAqIHNlZSBpZiB0aGUgYXJlIHdhaXRpbmcgb24gdGhpcyBzZXNzaW9uLCBhbmQgaWYgc2V0LCBzZXQgdGhlIHN0YXR1cyBmb3IKICogdGhhdCByZXF1ZXN0IHRvIEdFTkVSUi4KICovCmludApuZXRzbm1wX3JlbW92ZV9kZWxlZ2F0ZWRfcmVxdWVzdHNfZm9yX3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICpzZXNzKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcDsKICAgIGludCBjb3VudCA9IDA7CiAgICAKICAgIGZvciAoYXNwID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7IGFzcDsgYXNwID0gYXNwLT5uZXh0KSB7CiAgICAgICAgLyoKICAgICAgICAgKiBjaGVjayBlYWNoIHJlcXVlc3QKICAgICAgICAgKi8KICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKICAgICAgICBmb3IocmVxdWVzdCA9IGFzcC0+cmVxdWVzdHM7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNoZWNrIHNlc3Npb24KICAgICAgICAgICAgICovCiAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwhPXJlcXVlc3QtPnN1YnRyZWUpOwogICAgICAgICAgICBpZihyZXF1ZXN0LT5zdWJ0cmVlLT5zZXNzaW9uICE9IHNlc3MpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG1hdGNoZWQhIG1hcmsgcmVxdWVzdCBhcyBkb25lCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3QsIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgICAgICsrY291bnQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBpZiB3ZSBmb3VuZCBhbnksIHRoYXQgcmVxdWVzdCBtYXkgYmUgZmluaXNoZWQgbm93CiAgICAgKi8KICAgIGlmKGNvdW50KSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAicmVtb3ZlZCAlZCBkZWxlZ2F0ZWQgcmVxdWVzdChzKSBmb3Igc2Vzc2lvbiAiCiAgICAgICAgICAgICAgICAgICAgIiU4cFxuIiwgY291bnQsIHNlc3MpKTsKICAgICAgICBuZXRzbm1wX2NoZWNrX291dHN0YW5kaW5nX2FnZW50X3JlcXVlc3RzKCk7CiAgICB9CiAgICAKICAgIHJldHVybiBjb3VudDsKfQoKaW50Cm5ldHNubXBfY2hlY2tfcXVldWVkX2NoYWluX2ZvcihuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgbmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3B0bXA7CiAgICBmb3IgKGFzcHRtcCA9IG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3Q7IGFzcHRtcDsgYXNwdG1wID0gYXNwdG1wLT5uZXh0KSB7CiAgICAgICAgaWYgKGFzcHRtcCA9PSBhc3ApCiAgICAgICAgICAgIHJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCmludApuZXRzbm1wX2FkZF9xdWV1ZWQobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwX3RtcDsKCiAgICAvKgogICAgICogZmlyc3QgaXRlbT8KICAgICAqLwogICAgaWYgKE5VTEwgPT0gbmV0c25tcF9hZ2VudF9xdWV1ZWRfbGlzdCkgewogICAgICAgIG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3QgPSBhc3A7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgoKICAgIC8qCiAgICAgKiBhZGQgdG8gZW5kIG9mIHF1ZXVlZCByZXF1ZXN0IGNoYWluIAogICAgICovCiAgICBhc3BfdG1wID0gbmV0c25tcF9hZ2VudF9xdWV1ZWRfbGlzdDsKICAgIGZvciAoOyBhc3BfdG1wOyBhc3BfdG1wID0gYXNwX3RtcC0+bmV4dCkgewogICAgICAgIC8qCiAgICAgICAgICogYWxyZWFkeSBpbiBxdWV1ZT8KICAgICAgICAgKi8KICAgICAgICBpZiAoYXNwX3RtcCA9PSBhc3ApCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvKgogICAgICAgICAqIGVuZCBvZiBxdWV1ZT8KICAgICAgICAgKi8KICAgICAgICBpZiAoTlVMTCA9PSBhc3BfdG1wLT5uZXh0KQogICAgICAgICAgICBhc3BfdG1wLT5uZXh0ID0gYXNwOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCgppbnQKbmV0c25tcF93cmFwX3VwX3JlcXVlc3QobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsIGludCBzdGF0dXMpCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyX3B0cjsKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIC8qCiAgICAgKiBpZiB0aGlzIHJlcXVlc3Qgd2FzIGEgc2V0LCBjbGVhciB0aGUgZ2xvYmFsIG5vdyB0aGF0IHdlIGFyZQogICAgICogZG9uZS4KICAgICAqLwogICAgaWYgKGFzcCA9PSBuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0KSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiU0VUIHJlcXVlc3QgY29tcGxldGUsIGFzcCA9ICU4cFxuIiwKICAgICAgICAgICAgICAgICAgICBhc3ApKTsKICAgICAgICBuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0ID0gTlVMTDsKICAgIH0KCiAgICBpZiAoYXNwLT5wZHUpIHsKICAgICAgICAvKgogICAgICAgICAqIElmIHdlJ3ZlIGdvdCBhbiBlcnJvciBzdGF0dXMsIHRoZW4gdGhpcyBuZWVkcyB0byBiZQogICAgICAgICAqICBwYXNzZWQgYmFjayB1cCB0byB0aGUgaGlnaGVyIGxldmVscy4uLi4KICAgICAgICAgKi8KICAgICAgICBpZiAoIHN0YXR1cyAhPSAwICAmJiBhc3AtPnN0YXR1cyA9PSAwICkKICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBzdGF0dXM7CgogICAgICAgIHN3aXRjaCAoYXNwLT5wZHUtPmNvbW1hbmQpIHsKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQkVHSU46CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUxOgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9SRVNFUlZFMjoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQUNUSU9OOgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHNvbWUgc3R1ZmYgbmVlZHMgdG8gYmUgc2F2ZWQgaW4gc3BlY2lhbCBzdWJhZ2VudCBjYXNlcyAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc2F2ZV9zZXRfY2FjaGUoYXNwKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgICAgICAgICAgX2ZpeF9lbmRvZm1pYnZpZXcoYXNwKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGZvciBhIEdFVEJVTEsgcmVzcG9uc2Ugd2UgbmVlZCB0byByZWFycmFuZ2UgdGhlIHZhcmJpbmRzIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBfcmVvcmRlcl9nZXRidWxrKGFzcCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogTWF5IG5lZWQgdG8gImR1bWIgZG93biIgYSBTRVQgZXJyb3Igc3RhdHVzIGZvciBhCiAgICAgICAgICogdjEgcXVlcnkuICBTZWUgUkZDMjU3NiAtIHNlY3Rpb24gNC4zCiAgICAgICAgICovCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgIGlmICgoYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfU0VUKSAmJgogICAgICAgICAgICAoYXNwLT5wZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpKSB7CiAgICAgICAgICAgIHN3aXRjaCAoYXNwLT5zdGF0dXMpIHsKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfV1JPTkdWQUxVRToKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfV1JPTkdFTkNPRElORzoKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfV1JPTkdUWVBFOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9XUk9OR0xFTkdUSDoKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfSU5DT05TSVNURU5UVkFMVUU6CiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gU05NUF9FUlJfQkFEVkFMVUU7CiAgICAgICAgICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBTTk1QX0VSUl9CQURWQUxVRTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfTk9BQ0NFU1M6CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX05PVFdSSVRBQkxFOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9OT0NSRUFUSU9OOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9JTkNPTlNJU1RFTlROQU1FOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9BVVRIT1JJWkFUSU9ORVJST1I6CiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gU05NUF9FUlJfTk9TVUNITkFNRTsKICAgICAgICAgICAgICAgICAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX05PU1VDSE5BTUU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX1JFU09VUkNFVU5BVkFJTEFCTEU6CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX0NPTU1JVEZBSUxFRDoKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfVU5ET0ZBSUxFRDoKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBTaW1pbGFybHkgd2UgbWF5IG5lZWQgdG8gImR1bWIgZG93biIgdjIgZXhjZXB0aW9uCiAgICAgICAgICogIHR5cGVzIHRvIHRocm93IGFuIGVycm9yIGZvciBhIHYxIHF1ZXJ5LgogICAgICAgICAqICBTZWUgUkZDMjU3NiAtIHNlY3Rpb24gNC4xLjIuMwogICAgICAgICAqLwogICAgICAgIGlmICgoYXNwLT5wZHUtPmNvbW1hbmQgIT0gU05NUF9NU0dfU0VUKSAmJgogICAgICAgICAgICAoYXNwLT5wZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpKSB7CiAgICAgICAgICAgIGZvciAodmFyX3B0ciA9IGFzcC0+cGR1LT52YXJpYWJsZXMsIGkgPSAxOwogICAgICAgICAgICAgICAgIHZhcl9wdHIgIT0gTlVMTDsgdmFyX3B0ciA9IHZhcl9wdHItPm5leHRfdmFyaWFibGUsIGkrKykgewogICAgICAgICAgICAgICAgc3dpdGNoICh2YXJfcHRyLT50eXBlKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBTTk1QX05PU1VDSE9CSkVDVDoKICAgICAgICAgICAgICAgICAgICBjYXNlIFNOTVBfTk9TVUNISU5TVEFOQ0U6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VORE9GTUlCVklFVzoKICAgICAgICAgICAgICAgICAgICBjYXNlIEFTTl9DT1VOVEVSNjQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PU1VDSE5BTUU7CiAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gU05NUF9FUlJfTk9TVUNITkFNRTsKICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5pbmRleCA9IGk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYgLyogc25tcHYxIHN1cHBvcnQgKi8KICAgIH0gLyoqIGlmIGFzcC0+cGR1ICovCgogICAgLyoKICAgICAqIFVwZGF0ZSB0aGUgc25tcCBlcnJvci1jb3VudCBzdGF0aXN0aWNzCiAgICAgKiAgIFhYWCAtIHNob3VsZCB3ZSBpbmNsdWRlIHRoZSBWMiBlcnJvcnMgaW4gdGhpcyBvciBub3Q/CiAgICAgKi8KI2RlZmluZSBJTkNMVURFX1YyRVJST1JTX0lOX1YxU1RBVFMKCiAgICBzd2l0Y2ggKHN0YXR1cykgewojaWZkZWYgSU5DTFVERV9WMkVSUk9SU19JTl9WMVNUQVRTCiAgICBjYXNlIFNOTVBfRVJSX1dST05HVkFMVUU6CiAgICBjYXNlIFNOTVBfRVJSX1dST05HRU5DT0RJTkc6CiAgICBjYXNlIFNOTVBfRVJSX1dST05HVFlQRToKICAgIGNhc2UgU05NUF9FUlJfV1JPTkdMRU5HVEg6CiAgICBjYXNlIFNOTVBfRVJSX0lOQ09OU0lTVEVOVFZBTFVFOgojZW5kaWYKICAgIGNhc2UgU05NUF9FUlJfQkFEVkFMVUU6CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVEJBRFZBTFVFUyk7CiAgICAgICAgYnJlYWs7CiNpZmRlZiBJTkNMVURFX1YyRVJST1JTX0lOX1YxU1RBVFMKICAgIGNhc2UgU05NUF9FUlJfTk9BQ0NFU1M6CiAgICBjYXNlIFNOTVBfRVJSX05PVFdSSVRBQkxFOgogICAgY2FzZSBTTk1QX0VSUl9OT0NSRUFUSU9OOgogICAgY2FzZSBTTk1QX0VSUl9JTkNPTlNJU1RFTlROQU1FOgogICAgY2FzZSBTTk1QX0VSUl9BVVRIT1JJWkFUSU9ORVJST1I6CiNlbmRpZgogICAgY2FzZSBTTk1QX0VSUl9OT1NVQ0hOQU1FOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBPVVROT1NVQ0hOQU1FUyk7CiAgICAgICAgYnJlYWs7CiNpZmRlZiBJTkNMVURFX1YyRVJST1JTX0lOX1YxU1RBVFMKICAgIGNhc2UgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRToKICAgIGNhc2UgU05NUF9FUlJfQ09NTUlURkFJTEVEOgogICAgY2FzZSBTTk1QX0VSUl9VTkRPRkFJTEVEOgojZW5kaWYKICAgIGNhc2UgU05NUF9FUlJfR0VORVJSOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBPVVRHRU5FUlJTKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfRVJSX1RPT0JJRzoKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QT1VUVE9PQklHUyk7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKChzdGF0dXMgPT0gU05NUF9FUlJfTk9FUlJPUikgJiYgKGFzcC0+cGR1KSkgewogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpY19ieSgoYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfU0VUID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRfU05NUElOVE9UQUxTRVRWQVJTIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRfU05NUElOVE9UQUxSRVFWQVJTKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRfdmFyYmluZHMoYXNwLT5wZHUtPnZhcmlhYmxlcykpOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIFVzZSBhIGNvcHkgb2YgdGhlIG9yaWdpbmFsIHJlcXVlc3QKICAgICAgICAgKiAgIHRvIHJlcG9ydCBmYWlsdXJlcy4KICAgICAgICAgKi8KICAgICAgICBzbm1wX2ZyZWVfcGR1KGFzcC0+cGR1KTsKICAgICAgICBhc3AtPnBkdSA9IGFzcC0+b3JpZ19wZHU7CiAgICAgICAgYXNwLT5vcmlnX3BkdSA9IE5VTEw7CiAgICB9CiAgICBpZiAoYXNwLT5wZHUpIHsKICAgICAgICBhc3AtPnBkdS0+Y29tbWFuZCA9IFNOTVBfTVNHX1JFU1BPTlNFOwogICAgICAgIGFzcC0+cGR1LT5lcnJzdGF0ID0gYXNwLT5zdGF0dXM7CiAgICAgICAgYXNwLT5wZHUtPmVycmluZGV4ID0gYXNwLT5pbmRleDsKICAgICAgICBpZiAoIXNubXBfc2VuZChhc3AtPnNlc3Npb24sIGFzcC0+cGR1KSAmJgogICAgICAgICAgICAgYXNwLT5zZXNzaW9uLT5zX3NubXBfZXJybm8gIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyX3B0cjsKICAgICAgICAgICAgc25tcF9wZXJyb3IoInNlbmQgcmVzcG9uc2UiKTsKICAgICAgICAgICAgZm9yICh2YXJfcHRyID0gYXNwLT5wZHUtPnZhcmlhYmxlczsgdmFyX3B0ciAhPSBOVUxMOwogICAgICAgICAgICAgICAgICAgICB2YXJfcHRyID0gdmFyX3B0ci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAgICAgc2l6ZV90ICBjX29pZGxlbiA9IDI1NiwgY19vdXRsZW4gPSAwOwogICAgICAgICAgICAgICAgdV9jaGFyICpjX29pZCA9ICh1X2NoYXIgKikgbWFsbG9jKGNfb2lkbGVuKTsKCiAgICAgICAgICAgICAgICBpZiAoY19vaWQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXNwcmludF9yZWFsbG9jX29iamlkICgmY19vaWQsICZjX29pZGxlbiwgJmNfb3V0bGVuLCAxLAogCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyX3B0ci0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJfcHRyLT5uYW1lX2xlbmd0aCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIiAgICAtLSAlcyBbVFJVTkNBVEVEXVxuIiwgY19vaWQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICIgICAgLS0gJXNcbiIsIGNfb2lkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKGNfb2lkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KGFzcC0+cGR1KTsKICAgICAgICAgICAgYXNwLT5wZHUgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QT1VUUEtUUyk7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVEdFVFJFU1BPTlNFUyk7CiAgICAgICAgYXNwLT5wZHUgPSBOVUxMOyAvKiB5eXktcmtzOiByZWR1bmRhbnQsIG5vPyAqLwogICAgICAgIG5ldHNubXBfcmVtb3ZlX2FuZF9mcmVlX2FnZW50X3NubXBfc2Vzc2lvbihhc3ApOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCnZvaWQKZHVtcF9zZXNzX2xpc3Qodm9pZCkKewogICAgbmV0c25tcF9hZ2VudF9zZXNzaW9uICphOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgIkRVTVAgYWdlbnRfc2Vzc19saXN0IC0+ICIpKTsKICAgIGZvciAoYSA9IGFnZW50X3Nlc3Npb25fbGlzdDsgYSAhPSBOVUxMOyBhID0gYS0+bmV4dCkgewogICAgICAgIERFQlVHTVNHKCgic25tcF9hZ2VudCIsICIlOHBbc2Vzc2lvbiAlOHBdIC0+ICIsIGEsIGEtPnNlc3Npb24pKTsKICAgIH0KICAgIERFQlVHTVNHKCgic25tcF9hZ2VudCIsICJbTklMXVxuIikpOwp9Cgp2b2lkCm5ldHNubXBfcmVtb3ZlX2FuZF9mcmVlX2FnZW50X3NubXBfc2Vzc2lvbihuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgbmV0c25tcF9hZ2VudF9zZXNzaW9uICphLCAqKnByZXZOZXh0ID0gJmFnZW50X3Nlc3Npb25fbGlzdDsKCiAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJSRU1PVkUgc2Vzc2lvbiA9PSAlOHBcbiIsIGFzcCkpOwoKICAgIGZvciAoYSA9IGFnZW50X3Nlc3Npb25fbGlzdDsgYSAhPSBOVUxMOyBhID0gKnByZXZOZXh0KSB7CiAgICAgICAgaWYgKGEgPT0gYXNwKSB7CiAgICAgICAgICAgICpwcmV2TmV4dCA9IGEtPm5leHQ7CiAgICAgICAgICAgIGEtPm5leHQgPSBOVUxMOwogICAgICAgICAgICBmcmVlX2FnZW50X3NubXBfc2Vzc2lvbihhKTsKICAgICAgICAgICAgYXNwID0gTlVMTDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcHJldk5leHQgPSAmKGEtPm5leHQpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoYSA9PSBOVUxMICYmIGFzcCAhPSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBXZSBjb3VsbmQndCBmaW5kIGl0IG9uIHRoZSBsaXN0LCBzbyBmcmVlIGl0IGFueXdheS4gIAogICAgICAgICAqLwogICAgICAgIGZyZWVfYWdlbnRfc25tcF9zZXNzaW9uKGFzcCk7CiAgICB9Cn0KCnZvaWQKbmV0c25tcF9mcmVlX2FnZW50X3NubXBfc2Vzc2lvbl9ieV9zZXNzaW9uKG5ldHNubXBfc2Vzc2lvbiAqIHNlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqZnJlZV9yZXF1ZXN0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ldHNubXBfcmVxdWVzdF9saXN0ICopKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmEsICpuZXh0LCAqKnByZXZOZXh0ID0gJmFnZW50X3Nlc3Npb25fbGlzdDsKCiAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJSRU1PVkUgc2Vzc2lvbiA9PSAlOHBcbiIsIHNlc3MpKTsKCiAgICBmb3IgKGEgPSBhZ2VudF9zZXNzaW9uX2xpc3Q7IGEgIT0gTlVMTDsgYSA9IG5leHQpIHsKICAgICAgICBpZiAoYS0+c2Vzc2lvbiA9PSBzZXNzKSB7CiAgICAgICAgICAgICpwcmV2TmV4dCA9IGEtPm5leHQ7CiAgICAgICAgICAgIG5leHQgPSBhLT5uZXh0OwogICAgICAgICAgICBmcmVlX2FnZW50X3NubXBfc2Vzc2lvbihhKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcmV2TmV4dCA9ICYoYS0+bmV4dCk7CiAgICAgICAgICAgIG5leHQgPSBhLT5uZXh0OwogICAgICAgIH0KICAgIH0KfQoKLyoqIGhhbmRsZXMgYW4gaW5jb21pbmcgU05NUCBwYWNrZXQgaW50byB0aGUgYWdlbnQgKi8KaW50CmhhbmRsZV9zbm1wX3BhY2tldChpbnQgb3AsIG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sIGludCByZXFpZCwKICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcGR1ICpwZHUsIHZvaWQgKm1hZ2ljKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcDsKICAgIGludCAgICAgICAgICAgICBzdGF0dXMsIGFjY2Vzc19yZXQsIHJjOwoKICAgIC8qCiAgICAgKiBXZSBvbmx5IHN1cHBvcnQgcmVjZWl2aW5nIGhlcmUuICAKICAgICAqLwogICAgaWYgKG9wICE9IE5FVFNOTVBfQ0FMTEJBQ0tfT1BfUkVDRUlWRURfTUVTU0FHRSkgewogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIC8qCiAgICAgKiBSRVNQT05TRSBtZXNzYWdlcyB3b24ndCBnZXQgdGhpcyBmYXIsIGJ1dCBUUkFQLWxpa2UgbWVzc2FnZXMKICAgICAqIG1pZ2h0LiAgCiAgICAgKi8KICAgIGlmIChwZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfVFJBUCB8fCBwZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfSU5GT1JNIHx8CiAgICAgICAgcGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1RSQVAyKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAicmVjZWl2ZWQgdHJhcC1saWtlIFBEVSAoJTAyeClcbiIsCiAgICAgICAgICAgICAgICAgICAgcGR1LT5jb21tYW5kKSk7CiAgICAgICAgcGR1LT5jb21tYW5kID0gU05NUF9NU0dfVFJBUDI7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUFVOS05PV05QRFVIQU5ETEVSUyk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgLyoKICAgICAqIHNlbmQgc25tcHYzIGF1dGhmYWlsIHRyYXAuCiAgICAgKi8KICAgIGlmIChwZHUtPnZlcnNpb24gID09IFNOTVBfVkVSU0lPTl8zICYmIAogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9PSBTTk1QRVJSX1VTTV9BVVRIRU5USUNBVElPTkZBSUxVUkUpIHsKICAgICAgICAgICBzZW5kX2Vhc3lfdHJhcChTTk1QX1RSQVBfQVVUSEZBSUwsIDApOwogICAgICAgICAgIHJldHVybiAxOwogICAgfSAKCQogICAgaWYgKG1hZ2ljID09IE5VTEwpIHsKICAgICAgICBhc3AgPSBpbml0X2FnZW50X3NubXBfc2Vzc2lvbihzZXNzaW9uLCBwZHUpOwogICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICB9IGVsc2UgewogICAgICAgIGFzcCA9IChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKikgbWFnaWM7CiAgICAgICAgc3RhdHVzID0gYXNwLT5zdGF0dXM7CiAgICB9CgogICAgaWYgKChhY2Nlc3NfcmV0ID0gY2hlY2tfYWNjZXNzKGFzcC0+cGR1KSkgIT0gMCkgewogICAgICAgIGlmIChhY2Nlc3NfcmV0ID09IFZBQ01fTk9TVUNIQ09OVEVYVCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByZmMzNDEzIHNlY3Rpb24gMy4yLCBzdGVwIDUgc2F5cyB0aGF0IHdlIGluY3JlbWVudCB0aGUKICAgICAgICAgICAgICogY291bnRlciBidXQgZG9uJ3QgcmV0dXJuIGEgcmVzcG9uc2Ugb2YgYW55IGtpbmQgCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogd2UgY3VycmVudGx5IGRvbid0IHN1cHBvcnQgdW5hdmFpbGFibGUgY29udGV4dHMsIGFzCiAgICAgICAgICAgICAqIHRoZXJlIGlzIG5vIHJlYXNvbiB0byB0aGF0IEkgY3VycmVudGx5IGtub3cgb2YgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QVU5LTk9XTkNPTlRFWFRTKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGRyb3AgdGhlIHJlcXVlc3QgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogYWNjZXNzIGNvbnRyb2wgc2V0dXAgaXMgaW5jb3JyZWN0IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2VuZF9lYXN5X3RyYXAoU05NUF9UUkFQX0FVVEhGQUlMLCAwKTsKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQojaWYgZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKQogICAgICAgICAgICBpZiAoYXNwLT5wZHUtPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzJjKSB7CiNlbHNlCiNpZiBkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQogICAgICAgICAgICBpZiAoYXNwLT5wZHUtPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzEpIHsKI2Vsc2UKICAgICAgICAgICAgaWYgKGFzcC0+cGR1LT52ZXJzaW9uICE9IFNOTVBfVkVSU0lPTl8xCiAgICAgICAgICAgICAgICAmJiBhc3AtPnBkdS0+dmVyc2lvbiAhPSBTTk1QX1ZFUlNJT05fMmMpIHsKI2VuZGlmCiNlbmRpZgogICAgICAgICAgICAgICAgYXNwLT5wZHUtPmVycnN0YXQgPSBTTk1QX0VSUl9BVVRIT1JJWkFUSU9ORVJST1I7CiAgICAgICAgICAgICAgICBhc3AtPnBkdS0+Y29tbWFuZCA9IFNOTVBfTVNHX1JFU1BPTlNFOwogICAgICAgICAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVFBLVFMpOwogICAgICAgICAgICAgICAgaWYgKCFzbm1wX3NlbmQoYXNwLT5zZXNzaW9uLCBhc3AtPnBkdSkpCiAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3BkdShhc3AtPnBkdSk7CiAgICAgICAgICAgICAgICBhc3AtPnBkdSA9IE5VTEw7CiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9IGVsc2UgewojZW5kaWYgLyogc3VwcG9ydCBmb3IgY29tbXVuaXR5IGJhc2VkIFNOTVAgKi8KICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBkcm9wIHRoZSByZXF1ZXN0IAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCiAgICAgICAgICAgIH0KI2VuZGlmIC8qIHN1cHBvcnQgZm9yIGNvbW11bml0eSBiYXNlZCBTTk1QICovCiAgICAgICAgfQogICAgfQoKICAgIHJjID0gbmV0c25tcF9oYW5kbGVfcmVxdWVzdChhc3AsIHN0YXR1cyk7CgogICAgLyoKICAgICAqIGRvbmUgCiAgICAgKi8KICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImVuZCBvZiBoYW5kbGVfc25tcF9wYWNrZXQsIGFzcCA9ICU4cFxuIiwKICAgICAgICAgICAgICAgIGFzcCkpOwogICAgcmV0dXJuIHJjOwp9CgpuZXRzbm1wX3JlcXVlc3RfaW5mbyAqCm5ldHNubXBfYWRkX3ZhcmJpbmRfdG9fY2FjaGUobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsIGludCB2YmNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIHZhcmJpbmRfcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfc3VidHJlZSAqdHApCnsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0ID0gTlVMTDsKICAgIGludCAgICAgICAgICAgICBjYWNoZWlkOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImFkZF92Yl90b19jYWNoZSglOHAsICVkLCAiLCBhc3AsIHZiY291bnQpKTsKICAgIERFQlVHTVNHT0lEKCgic25tcF9hZ2VudCIsIHZhcmJpbmRfcHRyLT5uYW1lLAogICAgICAgICAgICAgICAgIHZhcmJpbmRfcHRyLT5uYW1lX2xlbmd0aCkpOwogICAgREVCVUdNU0coKCJzbm1wX2FnZW50IiwgIiwgJThwKVxuIiwgdHApKTsKCiAgICBpZiAodHAgJiYKICAgICAgICAoYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfR0VUTkVYVCB8fAogICAgICAgICBhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19HRVRCVUxLKSkgewogICAgICAgIGludCByZXN1bHQ7CiAgICAgICAgaW50IHByZWZpeF9sZW47CgogICAgICAgIHByZWZpeF9sZW4gPSBuZXRzbm1wX29pZF9maW5kX3ByZWZpeCh0cC0+c3RhcnRfYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPnN0YXJ0X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPmVuZF9hLCB0cC0+ZW5kX2xlbik7CiAgICAgICAgaWYgKHByZWZpeF9sZW4gPCAxKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IFZBQ01fTk9USU5WSUVXOyAvKiBhY2suLi4gIGJhZCBiYWQgdGhpbmcgaGFwcGVuZWQgKi8KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQgPQogICAgICAgICAgICAgICAgbmV0c25tcF9hY21fY2hlY2tfc3VidHJlZShhc3AtPnBkdSwgdHAtPnN0YXJ0X2EsIHByZWZpeF9sZW4pOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKHJlc3VsdCA9PSBWQUNNX05PVElOVklFVykgewogICAgICAgICAgICAvKiB0aGUgZW50aXJlIHN1YnRyZWUgaXMgbm90IGluIHZpZXcuIFNraXAgaXQuICovCiAgICAgICAgICAgIC8qKiBAdG9kbyBtYWtlIHRoaXMgYmUgbW9yZSBpbnRlbGxpZ2VudCBhYm91dCByYW5nZXMuCiAgICAgICAgICAgICAgICBSaWdodCBub3cgd2UgbWVyZWx5IHRha2UgdGhlIGhpZ2hlc3QgbGV2ZWwKICAgICAgICAgICAgICAgIGNvbW1vbmFsaXR5IG9mIGEgcmVnaXN0cmF0aW9uIHJhbmdlIGFuZCB1c2UgdGhhdC4KICAgICAgICAgICAgICAgIEF0IHRpbWVzIHdlIG1pZ2h0IGJlIGFibGUgdG8gYmUgc21hcnRlciBhYm91dAogICAgICAgICAgICAgICAgY2hlY2tpbmcgdGhlIHJhbmdlIGl0c2VsZiBhcyBvcHBvc2VkIHRvIHRoZSBub2RlCiAgICAgICAgICAgICAgICBhYm92ZSB3aGVyZSB0aGUgcmFuZ2UgZXhpc3RzLCBidXQgSSBkb3VidCB0aGlzIHdpbGwKICAgICAgICAgICAgICAgIGNvbWUgdXAgYWxsIHRoYXQgZnJlcXVlbnRseS4gKi8KICAgICAgICAgICAgdHAgPSB0cC0+bmV4dDsKICAgICAgICAgICAgaWYgKHRwKSB7CiAgICAgICAgICAgICAgICBwcmVmaXhfbGVuID0gbmV0c25tcF9vaWRfZmluZF9wcmVmaXgodHAtPnN0YXJ0X2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPnN0YXJ0X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cC0+ZW5kX2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPmVuZF9sZW4pOwogICAgICAgICAgICAgICAgaWYgKHByZWZpeF9sZW4gPCAxKSB7CiAgICAgICAgICAgICAgICAgICAgLyogYWNrLi4uICBiYWQgYmFkIHRoaW5nIGhhcHBlbmVkICovCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVkFDTV9OT1RJTlZJRVc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWNtX2NoZWNrX3N1YnRyZWUoYXNwLT5wZHUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPnN0YXJ0X2EsIHByZWZpeF9sZW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGlmICh0cCA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBubyBhcHByb3ByaWF0ZSByZWdpc3RyYXRpb24gZm91bmQgCiAgICAgICAgICovCiAgICAgICAgLyoKICAgICAgICAgKiBtYWtlIHVwIHRoZSByZXNwb25zZSBvdXJzZWx2ZXMgCiAgICAgICAgICovCiAgICAgICAgc3dpdGNoIChhc3AtPnBkdS0+Y29tbWFuZCkgewogICAgICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgICAgIHZhcmJpbmRfcHRyLT50eXBlID0gU05NUF9FTkRPRk1JQlZJRVc7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFNOTVBfTVNHX1NFVDoKICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgICAgICAgICAgdmFyYmluZF9wdHItPnR5cGUgPSBTTk1QX05PU1VDSE9CSkVDVDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBOVUxMOyAgICAgICAgLyogc2hvdWxkbid0IGdldCBoZXJlICovCiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJ0cC0+c3RhcnQgIikpOwogICAgICAgIERFQlVHTVNHT0lEKCgic25tcF9hZ2VudCIsIHRwLT5zdGFydF9hLCB0cC0+c3RhcnRfbGVuKSk7CiAgICAgICAgREVCVUdNU0coKCJzbm1wX2FnZW50IiwgIiwgdHAtPmVuZCAiKSk7CiAgICAgICAgREVCVUdNU0dPSUQoKCJzbm1wX2FnZW50IiwgdHAtPmVuZF9hLCB0cC0+ZW5kX2xlbikpOwogICAgICAgIERFQlVHTVNHKCgic25tcF9hZ2VudCIsICIsIFxuIikpOwoKICAgICAgICAvKgogICAgICAgICAqIG1hbGxvYyB0aGUgcmVxdWVzdCBzdHJ1Y3R1cmUgCiAgICAgICAgICovCiAgICAgICAgcmVxdWVzdCA9ICYoYXNwLT5yZXF1ZXN0c1t2YmNvdW50IC0gMV0pOwogICAgICAgIHJlcXVlc3QtPmluZGV4ID0gdmJjb3VudDsKICAgICAgICByZXF1ZXN0LT5kZWxlZ2F0ZWQgPSAwOwogICAgICAgIHJlcXVlc3QtPnByb2Nlc3NlZCA9IDA7CiAgICAgICAgcmVxdWVzdC0+c3RhdHVzID0gMDsKICAgICAgICByZXF1ZXN0LT5zdWJ0cmVlID0gdHA7CiAgICAgICAgcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8gPSBhc3AtPnJlcWluZm87CiAgICAgICAgaWYgKHJlcXVlc3QtPnBhcmVudF9kYXRhKSB7CiAgICAgICAgICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cyhyZXF1ZXN0KTsKICAgICAgICB9CiAgICAgICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwgImFzcCAlcCByZXFpbmZvICVwIGFzc2lnbmVkIHRvIHJlcXVlc3RcbiIsCiAgICAgICAgICAgICAgICAgICAgYXNwLCBhc3AtPnJlcWluZm8pKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBmb3Igbm9uLVNFVCBtb2Rlcywgc2V0IHRoZSB0eXBlIHRvIE5VTEwgCiAgICAgICAgICovCiAgICAgICAgaWYgKCFNT0RFX0lTX1NFVChhc3AtPnBkdS0+Y29tbWFuZCkpIHsKICAgICAgICBERUJVR01TR1RMKCgidmVyYm9zZTphc3AiLCAiYXNwICVwIHJlcWluZm8gJXAgYXNzaWduZWQgdG8gcmVxdWVzdFxuIiwKICAgICAgICAgICAgICAgICAgICBhc3AsIGFzcC0+cmVxaW5mbykpOwogICAgICAgICAgICBpZiAodmFyYmluZF9wdHItPnR5cGUgPT0gQVNOX1BSSVZfSU5DTF9SQU5HRSkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAidmFyYmluZCAlZCBpcyBpbmNsdXNpdmVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5pbmRleCkpOwogICAgICAgICAgICAgICAgcmVxdWVzdC0+aW5jbHVzaXZlID0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXJiaW5kX3B0ci0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBwbGFjZSB0aGVtIGluIGEgY2FjaGUgCiAgICAgICAgICovCiAgICAgICAgaWYgKHRwLT5nbG9iYWxfY2FjaGVpZCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB3ZSBuZWVkIHRvIG1lcmdlIGFsbCBtYXJrZWQgc3VidHJlZXMgdG9nZXRoZXIgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoYXNwLT5jYWNoZV9zdG9yZSAmJiAtMSAhPQogICAgICAgICAgICAgICAgKGNhY2hlaWQgPSBuZXRzbm1wX2dldF9sb2NhbF9jYWNoaWQoYXNwLT5jYWNoZV9zdG9yZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT5nbG9iYWxfY2FjaGVpZCkpKSB7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjYWNoZWlkID0gKysoYXNwLT50cmVlY2FjaGVfbnVtKTsKICAgICAgICAgICAgICAgIG5ldHNubXBfZ2V0X29yX2FkZF9sb2NhbF9jYWNoaWQoJmFzcC0+Y2FjaGVfc3RvcmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT5nbG9iYWxfY2FjaGVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGVpZCk7CiAgICAgICAgICAgICAgICBnb3RvIG1hbGxvY3Nsb3Q7ICAgICAgICAvKiBYWFg6IGljayAqLwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICh0cC0+Y2FjaGVpZCA+IC0xICYmIHRwLT5jYWNoZWlkIDw9IGFzcC0+dHJlZWNhY2hlX251bSAmJgogICAgICAgICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVbdHAtPmNhY2hlaWRdLnN1YnRyZWUgPT0gdHApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogd2UgaGF2ZSBhbHJlYWR5IGFkZGVkIGEgcmVxdWVzdCB0byB0aGlzIHRyZWUKICAgICAgICAgICAgICogcG9pbnRlciBiZWZvcmUgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjYWNoZWlkID0gdHAtPmNhY2hlaWQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2FjaGVpZCA9ICsrKGFzcC0+dHJlZWNhY2hlX251bSk7CiAgICAgICAgICBtYWxsb2NzbG90OgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBuZXcgc2xvdCBuZWVkZWQgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoYXNwLT50cmVlY2FjaGVfbnVtID49IGFzcC0+dHJlZWNhY2hlX2xlbikgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGV4YXBhbmQgY2FjaGUgYXJyYXkgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBXV1c6IG5vbi1saW5lYXIgZXhwYW5zaW9uIG5lZWRlZCAod2l0aCBjYXApIAogICAgICAgICAgICAgICAgICovCiNkZWZpbmUgQ0FDSEVfR1JPV19TSVpFIDE2CiAgICAgICAgICAgICAgICBhc3AtPnRyZWVjYWNoZV9sZW4gPQogICAgICAgICAgICAgICAgICAgIChhc3AtPnRyZWVjYWNoZV9sZW4gKyBDQUNIRV9HUk9XX1NJWkUpOwogICAgICAgICAgICAgICAgYXNwLT50cmVlY2FjaGUgPQogICAgICAgICAgICAgICAgICAgIHJlYWxsb2MoYXNwLT50cmVlY2FjaGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobmV0c25tcF90cmVlX2NhY2hlKSAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnRyZWVjYWNoZV9sZW4pOwogICAgICAgICAgICAgICAgaWYgKGFzcC0+dHJlZWNhY2hlID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICBtZW1zZXQoJihhc3AtPnRyZWVjYWNoZVtjYWNoZWlkXSksIDB4MDAsCiAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG5ldHNubXBfdHJlZV9jYWNoZSkgKiAoQ0FDSEVfR1JPV19TSVpFKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVbY2FjaGVpZF0uc3VidHJlZSA9IHRwOwogICAgICAgICAgICBhc3AtPnRyZWVjYWNoZVtjYWNoZWlkXS5yZXF1ZXN0c19iZWdpbiA9IHJlcXVlc3Q7CiAgICAgICAgICAgIHRwLT5jYWNoZWlkID0gY2FjaGVpZDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogaWYgdGhpcyBpcyBhIHNlYXJjaCB0eXBlLCBnZXQgdGhlIGVuZGluZyByYW5nZSBvaWQgYXMgd2VsbCAKICAgICAgICAgKi8KICAgICAgICBpZiAoYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfR0VUTkVYVCB8fAogICAgICAgICAgICBhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19HRVRCVUxLKSB7CiAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZCA9IHRwLT5lbmRfYTsKICAgICAgICAgICAgcmVxdWVzdC0+cmFuZ2VfZW5kX2xlbiA9IHRwLT5lbmRfbGVuOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZCA9IE5VTEw7CiAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZF9sZW4gPSAwOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBsaW5rIGludG8gY2hhaW4gCiAgICAgICAgICovCiAgICAgICAgaWYgKGFzcC0+dHJlZWNhY2hlW2NhY2hlaWRdLnJlcXVlc3RzX2VuZCkKICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVbY2FjaGVpZF0ucmVxdWVzdHNfZW5kLT5uZXh0ID0gcmVxdWVzdDsKICAgICAgICByZXF1ZXN0LT5uZXh0ID0gTlVMTDsKICAgICAgICByZXF1ZXN0LT5wcmV2ID0gYXNwLT50cmVlY2FjaGVbY2FjaGVpZF0ucmVxdWVzdHNfZW5kOwogICAgICAgIGFzcC0+dHJlZWNhY2hlW2NhY2hlaWRdLnJlcXVlc3RzX2VuZCA9IHJlcXVlc3Q7CgogICAgICAgIC8qCiAgICAgICAgICogYWRkIHRoZSBnaXZlbiByZXF1ZXN0IHRvIHRoZSBsaXN0IG9mIHJlcXVlc3RzIHRoZXkgbmVlZAogICAgICAgICAqIHRvIGhhbmRsZSByZXN1bHRzIGZvciAKICAgICAgICAgKi8KICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmIgPSByZXF1ZXN0LT5yZXF1ZXN0dmJfc3RhcnQgPSB2YXJiaW5kX3B0cjsKICAgIH0KICAgIHJldHVybiByZXF1ZXN0Owp9CgovKgogKiBjaGVjayB0aGUgQUNNKHMpIGZvciB0aGUgcmVzdWx0cyBvbiBlYWNoIG9mIHRoZSB2YXJiaW5kcy4KICogSWYgQUNNIGRpc2FsbG93cyBpdCwgcmVwbGFjZSB0aGUgdmFsdWUgd2l0aCB0eXBlCiAqIAogKiBSZXR1cm5zIG51bWJlciBvZiB2YXJiaW5kcyB3aXRoIEFDTSBlcnJvcnMKICovCmludApjaGVja19hY20obmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsIHVfY2hhciB0eXBlKQp7CiAgICBpbnQgICAgICAgICAgICAgdmlldzsKICAgIGludCAgICAgICAgICAgICBpLCBqLCBrOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CiAgICBpbnQgICAgICAgICAgICAgcmV0ID0gMDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmIsICp2YjIsICp2YmM7CiAgICBpbnQgICAgICAgICAgICAgZWFybGllc3QgPSAwOwoKICAgIGZvciAoaSA9IDA7IGkgPD0gYXNwLT50cmVlY2FjaGVfbnVtOyBpKyspIHsKICAgICAgICBmb3IgKHJlcXVlc3QgPSBhc3AtPnRyZWVjYWNoZVtpXS5yZXF1ZXN0c19iZWdpbjsKICAgICAgICAgICAgIHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGZvciBlYWNoIHJlcXVlc3QsIHJ1biBpdCB0aHJvdWdoIGluX2FfdmlldygpIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZWFybGllc3QgPSAwOwogICAgICAgICAgICBmb3IoaiA9IHJlcXVlc3QtPnJlcGVhdCwgdmIgPSByZXF1ZXN0LT5yZXF1ZXN0dmJfc3RhcnQ7CiAgICAgICAgICAgICAgICB2YiAmJiBqID4gLTE7CiAgICAgICAgICAgICAgICBqLS0sIHZiID0gdmItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICAgICAgICAgIGlmICh2Yi0+dHlwZSAhPSBBU05fTlVMTCAmJgogICAgICAgICAgICAgICAgICAgIHZiLT50eXBlICE9IEFTTl9QUklWX1JFVFJZKSB7IC8qIG5vdCB5ZXQgcHJvY2Vzc2VkICovCiAgICAgICAgICAgICAgICAgICAgdmlldyA9CiAgICAgICAgICAgICAgICAgICAgICAgIGluX2Ffdmlldyh2Yi0+bmFtZSwgJnZiLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cGR1LCB2Yi0+dHlwZSk7CgogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogaWYgYSBBQ00gZXJyb3Igb2NjdXJzLCBtYXJrIGl0IGFzIHR5cGUgcGFzc2VkIGluIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGlmICh2aWV3ICE9IFZBQ01fU1VDQ0VTUykgewogICAgICAgICAgICAgICAgICAgICAgICByZXQrKzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnJlcGVhdCA8IHJlcXVlc3QtPm9yaWdfcmVwZWF0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBiYXNpY2FsbHkgdGhpcyBtZWFucyBhIEdFVEJVTEsgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcGVhdCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlYXJsaWVzdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2YiA9IHZiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhcmxpZXN0ID0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB1Z2guICBpZiBhIHdob2xlIG5vdyBleGlzdHMsIHdlIG5lZWQgdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdmUgdGhlIGNvbnRlbnRzIHVwIHRoZSBjaGFpbiBhbmQgZmlsbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gYXQgdGhlIGVuZCBlbHNlIHdlIHdvbid0IGVuZCB1cAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV4b2dyYXBoaWNhbGx5IHNvcnRlZCBwcm9wZXJseSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGogPiAtMSAmJiB2Yi0+bmV4dF92YXJpYWJsZSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT5uZXh0X3ZhcmlhYmxlLT50eXBlICE9IEFTTl9OVUxMICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPm5leHRfdmFyaWFibGUtPnR5cGUgIT0gQVNOX1BSSVZfUkVUUlkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IoayA9IGosIHZiYyA9IHZiLCB2YjIgPSB2Yi0+bmV4dF92YXJpYWJsZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgayA+IC0yICYmIHZiYyAmJiB2YjI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGstLSwgdmJjID0gdmIyLCB2YjIgPSB2YjItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY2xvbmUgbmV4dCBpbnRvIHRoZSBjdXJyZW50ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfY2xvbmVfdmFyKHZiMiwgdmJjKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmJjLT5uZXh0X3ZhcmlhYmxlID0gdmIyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUodmIsIHR5cGUsIE5VTEwsIDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCgppbnQKbmV0c25tcF9jcmVhdGVfc3VidHJlZV9jYWNoZShuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgbmV0c25tcF9zdWJ0cmVlICp0cDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyYmluZF9wdHIsICp2YnNhdmUsICp2YnB0ciwgKipwcmV2TmV4dDsKICAgIGludCAgICAgICAgICAgICB2aWV3OwogICAgaW50ICAgICAgICAgICAgIHZiY291bnQgPSAwOwogICAgaW50ICAgICAgICAgICAgIGJ1bGtjb3VudCA9IDAsIGJ1bGtyZXAgPSAwOwogICAgaW50ICAgICAgICAgICAgIGkgPSAwLCBuID0gMCwgciA9IDA7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKCiAgICBpZiAoYXNwLT50cmVlY2FjaGUgPT0gTlVMTCAmJiBhc3AtPnRyZWVjYWNoZV9sZW4gPT0gMCkgewogICAgICAgIGFzcC0+dHJlZWNhY2hlX2xlbiA9IFNOTVBfTUFYKDEgKyBhc3AtPnZiY291bnQgLyA0LCAxNik7CiAgICAgICAgYXNwLT50cmVlY2FjaGUgPQogICAgICAgICAgICBjYWxsb2MoYXNwLT50cmVlY2FjaGVfbGVuLCBzaXplb2YobmV0c25tcF90cmVlX2NhY2hlKSk7CiAgICAgICAgaWYgKGFzcC0+dHJlZWNhY2hlID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CiAgICBhc3AtPnRyZWVjYWNoZV9udW0gPSAtMTsKCiAgICBpZiAoYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfR0VUQlVMSykgewogICAgICAgIC8qCiAgICAgICAgICogZ2V0YnVsayBwcmVwIAogICAgICAgICAqLwogICAgICAgIGludCAgICAgICAgICAgICBjb3VudCA9IGNvdW50X3ZhcmJpbmRzKGFzcC0+cGR1LT52YXJpYWJsZXMpOwogICAgICAgIGlmIChhc3AtPnBkdS0+ZXJyc3RhdCA8IDApIHsKICAgICAgICAgICAgYXNwLT5wZHUtPmVycnN0YXQgPSAwOwogICAgICAgIH0KICAgICAgICBpZiAoYXNwLT5wZHUtPmVycmluZGV4IDwgMCkgewogICAgICAgICAgICBhc3AtPnBkdS0+ZXJyaW5kZXggPSAwOwogICAgICAgIH0KCiAgICAgICAgaWYgKGFzcC0+cGR1LT5lcnJzdGF0IDwgY291bnQpIHsKICAgICAgICAgICAgbiA9IGFzcC0+cGR1LT5lcnJzdGF0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG4gPSBjb3VudDsKICAgICAgICB9CiAgICAgICAgaWYgKChyID0gY291bnQgLSBuKSA8PSAwKSB7CiAgICAgICAgICAgIHIgPSAwOwogICAgICAgICAgICBhc3AtPmJ1bGtjYWNoZSA9IE5VTEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50ICAgICAgICAgICBtYXhidWxrID0KICAgICAgICAgICAgICAgIG5ldHNubXBfZHNfZ2V0X2ludChORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfTUFYX0dFVEJVTEtSRVBFQVRTKTsKICAgICAgICAgICAgaW50IG1heHJlc3BvbnNlcyA9CiAgICAgICAgICAgICAgICBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX01BWF9HRVRCVUxLUkVTUE9OU0VTKTsKCiAgICAgICAgICAgIGlmIChtYXhyZXNwb25zZXMgPT0gMCkKICAgICAgICAgICAgICAgIG1heHJlc3BvbnNlcyA9IDEwMDsgICAvKiBtb3JlIHRoYW4gcmVhc29uYWJsZSBkZWZhdWx0ICovCgogICAgICAgICAgICAvKiBlbnN1cmUgdGhhdCB0aGUgdG90YWwgbnVtYmVyIG9mIHJlc3BvbnNlcyBmaXRzIGluIGEgbWFsbG9jYWJsZQogICAgICAgICAgICAgKiByZXN1bHQgdmVjdG9yCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAobWF4cmVzcG9uc2VzIDwgMCB8fAogICAgICAgICAgICAgICAgbWF4cmVzcG9uc2VzID4gSU5UX01BWCAvIHNpemVvZihzdHJ1Y3QgdmFyYmluZF9saXN0ICopKQogICAgICAgICAgICAgICAgbWF4cmVzcG9uc2VzID0gSU5UX01BWCAvIHNpemVvZihzdHJ1Y3QgdmFyYmluZF9saXN0ICopOwoKICAgICAgICAgICAgLyogZW5zdXJlIHRoYXQgdGhlIG1heGltdW0gbnVtYmVyIG9mIHJlcGV0aXRpb25zIHdpbGwgZml0IGluIHRoZQogICAgICAgICAgICAgKiByZXN1bHQgdmVjdG9yCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAobWF4YnVsayA8PSAwIHx8IG1heGJ1bGsgPiBtYXhyZXNwb25zZXMgLyByKQogICAgICAgICAgICAgICAgbWF4YnVsayA9IG1heHJlc3BvbnNlcyAvIHI7CgogICAgICAgICAgICAvKiBsaW1pdCBnZXRidWxrIG51bWJlciBvZiByZXBlYXRzIHRvIGEgY29uZmlndXJlZCBzaXplICovCiAgICAgICAgICAgIGlmIChhc3AtPnBkdS0+ZXJyaW5kZXggPiBtYXhidWxrKSB7CiAgICAgICAgICAgICAgICBhc3AtPnBkdS0+ZXJyaW5kZXggPSBtYXhidWxrOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInRydW5jYXRpbmcgbnVtYmVyIG9mIGdldGJ1bGsgcmVwZWF0cyB0byAlbGRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnBkdS0+ZXJyaW5kZXgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYXNwLT5idWxrY2FjaGUgPQogICAgICAgICAgICAgICAgKG5ldHNubXBfdmFyaWFibGVfbGlzdCAqKikgbWFsbG9jKAogICAgICAgICAgICAgICAgICAgIChuICsgYXNwLT5wZHUtPmVycmluZGV4ICogcikgKiBzaXplb2Yoc3RydWN0IHZhcmJpbmRfbGlzdCAqKSk7CgogICAgICAgICAgICBpZiAoIWFzcC0+YnVsa2NhY2hlKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJCdWxrY2FjaGUgbWFsbG9jIGZhaWxlZFxuIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJHRVRCVUxLIE4gPSAlZCwgTSA9ICVsZCwgUiA9ICVkXG4iLAogICAgICAgICAgICAgICAgICAgIG4sIGFzcC0+cGR1LT5lcnJpbmRleCwgcikpOwogICAgfQoKICAgIC8qCiAgICAgKiBjb2xsZWN0IHZhcmJpbmRzIGludG8gdGhlaXIgcmVnaXN0ZXJlZCB0cmVlcyAKICAgICAqLwogICAgcHJldk5leHQgPSAmKGFzcC0+cGR1LT52YXJpYWJsZXMpOwogICAgZm9yICh2YXJiaW5kX3B0ciA9IGFzcC0+cGR1LT52YXJpYWJsZXM7IHZhcmJpbmRfcHRyOwogICAgICAgICB2YXJiaW5kX3B0ciA9IHZic2F2ZSkgewoKICAgICAgICAvKgogICAgICAgICAqIGdldGJ1bGsgbWVzcyB3aXRoIHRoaXMgcG9pbnRlciwgc28gc2F2ZSBpdCAKICAgICAgICAgKi8KICAgICAgICB2YnNhdmUgPSB2YXJiaW5kX3B0ci0+bmV4dF92YXJpYWJsZTsKCiAgICAgICAgaWYgKGFzcC0+cGR1LT5jb21tYW5kID09IFNOTVBfTVNHX0dFVEJVTEspIHsKICAgICAgICAgICAgaWYgKG4gPiAwKSB7CiAgICAgICAgICAgICAgICBuLS07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogcmVwZWF0ZSByZXF1ZXN0IHZhcmJpbmRzIG9uIEdFVEJVTEsuICBUaGVzZSB3aWxsCiAgICAgICAgICAgICAgICAgKiBoYXZlIHRvIGJlIHByb3Blcmx5IHJlYXJyYW5nZWQgbGF0ZXIgdGhvdWdoIGFzCiAgICAgICAgICAgICAgICAgKiByZXNwb25zZXMgYXJlIHN1cHBvc2VkIHRvIGFjdHVhbGx5IGJlIGludGVybGFjZWQKICAgICAgICAgICAgICAgICAqIHdpdGggZWFjaCBvdGhlci4gIFRoaXMgaXMgZG9uZSB3aXRoIHRoZSBhc3AtPmJ1bGtjYWNoZS4gCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGJ1bGtyZXAgPSBhc3AtPnBkdS0+ZXJyaW5kZXggLSAxOwogICAgICAgICAgICAgICAgaWYgKGFzcC0+cGR1LT5lcnJpbmRleCA+IDApIHsKICAgICAgICAgICAgICAgICAgICB2YnB0ciA9IHZhcmJpbmRfcHRyOwogICAgICAgICAgICAgICAgICAgIGFzcC0+YnVsa2NhY2hlW2J1bGtjb3VudCsrXSA9IHZicHRyOwoKICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgYXNwLT5wZHUtPmVycmluZGV4OyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmJwdHItPm5leHRfdmFyaWFibGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9NQUxMT0NfU1RSVUNUKHZhcmlhYmxlX2xpc3QpOwogICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgKiBkb24ndCBjbG9uZSB0aGUgb2lkIGFzIGl0J3MgZ290IHRvIGJlCiAgICAgICAgICAgICAgICAgICAgICAgICAqIG92ZXJ3cml0dGVuIGFueXdheSAKICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmJwdHItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBYWFhXV1c6IGFjayEhISAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiTmV4dFZhciBtYWxsb2MgZmFpbGVkXG4iKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YnB0ciA9IHZicHRyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmJwdHItPm5hbWVfbGVuZ3RoID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZicHRyLT50eXBlID0gQVNOX05VTEw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPmJ1bGtjYWNoZVtidWxrY291bnQrK10gPSB2YnB0cjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YnB0ci0+bmV4dF92YXJpYWJsZSA9IHZic2F2ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiAwIHJlcGVhdHMgcmVxdWVzdGVkIGZvciB0aGlzIHZhcmJpbmQsIHNvIHRha2UgaXQgb2ZmCiAgICAgICAgICAgICAgICAgICAgICogdGhlIGxpc3QuICAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICB2YnB0ciA9IHZhcmJpbmRfcHRyOwogICAgICAgICAgICAgICAgICAgICpwcmV2TmV4dCA9IHZicHRyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICAgICAgICAgIHZicHRyLT5uZXh0X3ZhcmlhYmxlID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2YnB0cik7CiAgICAgICAgICAgICAgICAgICAgYXNwLT52YmNvdW50LS07CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogY291bnQgdGhlIHZhcmJpbmRzIAogICAgICAgICAqLwogICAgICAgICsrdmJjb3VudDsKCiAgICAgICAgLyoKICAgICAgICAgKiBmaW5kIHRoZSBvd25pbmcgdHJlZSAKICAgICAgICAgKi8KICAgICAgICB0cCA9IG5ldHNubXBfc3VidHJlZV9maW5kKHZhcmJpbmRfcHRyLT5uYW1lLCB2YXJiaW5kX3B0ci0+bmFtZV9sZW5ndGgsCgkJCQkgIE5VTEwsIGFzcC0+cGR1LT5jb250ZXh0TmFtZSk7CgogICAgICAgIC8qCiAgICAgICAgICogY2hlY2sgYWNjZXNzIGNvbnRyb2wgCiAgICAgICAgICovCiAgICAgICAgc3dpdGNoIChhc3AtPnBkdS0+Y29tbWFuZCkgewogICAgICAgIGNhc2UgU05NUF9NU0dfR0VUOgogICAgICAgICAgICB2aWV3ID0gaW5fYV92aWV3KHZhcmJpbmRfcHRyLT5uYW1lLCAmdmFyYmluZF9wdHItPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cGR1LCB2YXJiaW5kX3B0ci0+dHlwZSk7CiAgICAgICAgICAgIGlmICh2aWV3ICE9IFZBQ01fU1VDQ0VTUykKICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZSh2YXJiaW5kX3B0ciwgU05NUF9OT1NVQ0hPQkpFQ1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFNOTVBfTVNHX1NFVDoKICAgICAgICAgICAgdmlldyA9IGluX2Ffdmlldyh2YXJiaW5kX3B0ci0+bmFtZSwgJnZhcmJpbmRfcHRyLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnBkdSwgdmFyYmluZF9wdHItPnR5cGUpOwogICAgICAgICAgICBpZiAodmlldyAhPSBWQUNNX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgIGFzcC0+aW5kZXggPSB2YmNvdW50OwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PQUNDRVNTOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICAgICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHZpZXcgPSBWQUNNX1NVQ0NFU1M7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFhYWFdXVzogY2hlY2sgVkFDTSBoZXJlIHRvIHNlZSBpZiAidHAiIGlzIGV2ZW4gd29ydGh3aGlsZSAKICAgICAgICAgICAgICovCiAgICAgICAgfQogICAgICAgIGlmICh2aWV3ID09IFZBQ01fU1VDQ0VTUykgewogICAgICAgICAgICByZXF1ZXN0ID0gbmV0c25tcF9hZGRfdmFyYmluZF90b19jYWNoZShhc3AsIHZiY291bnQsIHZhcmJpbmRfcHRyLAoJCQkJCQkgICB0cCk7CiAgICAgICAgICAgIGlmIChyZXF1ZXN0ICYmIGFzcC0+cGR1LT5jb21tYW5kID09IFNOTVBfTVNHX0dFVEJVTEspIHsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcGVhdCA9IHJlcXVlc3QtPm9yaWdfcmVwZWF0ID0gYnVsa3JlcDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJldk5leHQgPSAmKHZhcmJpbmRfcHRyLT5uZXh0X3ZhcmlhYmxlKTsKICAgIH0KCiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgovKgogKiB0aGlzIGZ1bmN0aW9uIGlzIG9ubHkgYXBwbGljYWJsZSBpbiBnZXRuZXh0IGxpa2UgY29udGV4dHMgCiAqLwppbnQKbmV0c25tcF9yZWFzc2lnbl9yZXF1ZXN0cyhuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgLyoKICAgICAqIGFzc3VtZSBhbGwgdGhlIHJlcXVlc3RzIGhhdmUgYmVlbiBmaWxsZWQgb3IgcmVqZWN0ZWQgYnkgdGhlCiAgICAgKiBzdWJ0cmVlcywgc28gcmVhc3NpZ24gdGhlIHJlamVjdGVkIG9uZXMgdG8gdGhlIG5leHQgc3VidHJlZSBpbgogICAgICogdGhlIGNoYWluIAogICAgICovCgogICAgaW50ICAgICAgICAgICAgIGk7CgogICAgLyoKICAgICAqIGdldCBvbGQgaW5mbyAKICAgICAqLwogICAgbmV0c25tcF90cmVlX2NhY2hlICpvbGRfdHJlZWNhY2hlID0gYXNwLT50cmVlY2FjaGU7CgogICAgLyoKICAgICAqIG1hbGxvYyBuZXcgc3BhY2UgCiAgICAgKi8KICAgIGFzcC0+dHJlZWNhY2hlID0KICAgICAgICAobmV0c25tcF90cmVlX2NhY2hlICopIGNhbGxvYyhhc3AtPnRyZWVjYWNoZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG5ldHNubXBfdHJlZV9jYWNoZSkpOwoKICAgIGlmIChhc3AtPnRyZWVjYWNoZSA9PSBOVUxMKQogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CgogICAgYXNwLT50cmVlY2FjaGVfbnVtID0gLTE7CiAgICBpZiAoYXNwLT5jYWNoZV9zdG9yZSkgewogICAgICAgIG5ldHNubXBfZnJlZV9jYWNoZW1hcChhc3AtPmNhY2hlX3N0b3JlKTsKICAgICAgICBhc3AtPmNhY2hlX3N0b3JlID0gTlVMTDsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgYXNwLT52YmNvdW50OyBpKyspIHsKICAgICAgICBpZiAoYXNwLT5yZXF1ZXN0c1tpXS5yZXF1ZXN0dmIgPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBPY2N1cnMgd2hlbiB0aGVyZSdzIGEgbWl4dHVyZSBvZiBzdGlsbCBhY3RpdmUKICAgICAgICAgICAgICogICBhbmQgImVuZE9mTWliVmlldyIgcmVwZXRpdGlvbnMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAoYXNwLT5yZXF1ZXN0c1tpXS5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX05VTEwpIHsKICAgICAgICAgICAgaWYgKCFuZXRzbm1wX2FkZF92YXJiaW5kX3RvX2NhY2hlKGFzcCwgYXNwLT5yZXF1ZXN0c1tpXS5pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cmVxdWVzdHNbaV0ucmVxdWVzdHZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5yZXF1ZXN0c1tpXS5zdWJ0cmVlLT5uZXh0KSkgewogICAgICAgICAgICAgICAgaWYgKG9sZF90cmVlY2FjaGUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShvbGRfdHJlZWNhY2hlKTsKICAgICAgICAgICAgICAgICAgICBvbGRfdHJlZWNhY2hlID0gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoYXNwLT5yZXF1ZXN0c1tpXS5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX1BSSVZfUkVUUlkpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcmUtYWRkIHRoZSBzYW1lIHN1YnRyZWUgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBhc3AtPnJlcXVlc3RzW2ldLnJlcXVlc3R2Yi0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgICAgICBpZiAoIW5ldHNubXBfYWRkX3ZhcmJpbmRfdG9fY2FjaGUoYXNwLCBhc3AtPnJlcXVlc3RzW2ldLmluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5yZXF1ZXN0c1tpXS5yZXF1ZXN0dmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnJlcXVlc3RzW2ldLnN1YnRyZWUpKSB7CiAgICAgICAgICAgICAgICBpZiAob2xkX3RyZWVjYWNoZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKG9sZF90cmVlY2FjaGUpOwogICAgICAgICAgICAgICAgICAgIG9sZF90cmVlY2FjaGUgPSBOVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChvbGRfdHJlZWNhY2hlICE9IE5VTEwpIHsKICAgICAgICBTTk1QX0ZSRUUob2xkX3RyZWVjYWNoZSk7CiAgICB9CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKdm9pZApuZXRzbm1wX2RlbGV0ZV9yZXF1ZXN0X2luZm9zKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXFsaXN0KQp7CiAgICB3aGlsZSAocmVxbGlzdCkgewogICAgICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cyhyZXFsaXN0KTsKICAgICAgICByZXFsaXN0ID0gcmVxbGlzdC0+bmV4dDsKICAgIH0KfQoKdm9pZApuZXRzbm1wX2RlbGV0ZV9zdWJ0cmVlX2NhY2hlKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICB3aGlsZSAoYXNwLT50cmVlY2FjaGVfbnVtID49IDApIHsKICAgICAgICAvKgogICAgICAgICAqIGRvbid0IGRlbGV0ZSBzdWJ0cmVlcyAKICAgICAgICAgKi8KICAgICAgICBuZXRzbm1wX2RlbGV0ZV9yZXF1ZXN0X2luZm9zKGFzcC0+dHJlZWNhY2hlW2FzcC0+dHJlZWNhY2hlX251bV0uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0c19iZWdpbik7CiAgICAgICAgYXNwLT50cmVlY2FjaGVfbnVtLS07CiAgICB9Cn0KCi8qCiAqIGNoZWNrIGFsbCByZXF1ZXN0cyBmb3IgZXJyb3JzCiAqCiAqIEBOb3RlOgogKiBUaGlzIGZ1bmN0aW9uIGlzIGEgbGl0dGxlIGRpZmZlcmVudCBmcm9tIHRoZSBvdGhlcnMgaW4gdGhhdAogKiBpdCBkb2VzIG5vdCB1c2UgYW55IGxpbmtlZCBsaXN0cywgaW5zdGVhZCB1c2luZyB0aGUgb3JpZ2luYWwKICogYXNwIHJlcXVlc3RzIGFycmF5LiBUaGlzIGlzIG9mIHBhcnRpY3VsYXIgaW1wb3J0YW5jZSBmb3IKICogY2FzZXMgd2hlcmUgdGhlIGxpbmtlZCBsaXN0cyBhcmUgdW5yZWxpYWJsZS4gT25lIGtub3duIGluc3RhbmNlCiAqIG9mIHRoaXMgc2NlbmFyaW8gb2NjdXJzIHdoZW4gdGhlIHJvd19tZXJnZSBoZWxwZXIgaXMgdXNlZCwgd2hpY2gKICogbWF5IHRlbXBvcmFyaWx5IGRpc3J1cHRzIGxpbmtlZCBsaXN0cyBkdXJpbmcgaXRzIChhbmQgaXRzIGNoaWxkcmVucykKICogaGFuZGxpbmcgb2YgcmVxdWVzdHMuCiAqLwppbnQKbmV0c25tcF9jaGVja19hbGxfcmVxdWVzdHNfZXJyb3IobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsb29rX2Zvcl9zcGVjaWZpYykKewogICAgaW50IGk7CgogICAgLyoKICAgICAqIGZpbmQgYW55IGVycm9ycyBtYXJrZWQgaW4gdGhlIHJlcXVlc3RzIAogICAgICovCiAgICBmb3IoIGkgPSAwOyBpIDwgYXNwLT52YmNvdW50OyArK2kgKSB7CiAgICAgICAgaWYgKChTTk1QX0VSUl9OT0VSUk9SICE9IGFzcC0+cmVxdWVzdHNbaV0uc3RhdHVzKSAmJgogICAgICAgICAgICAoIWxvb2tfZm9yX3NwZWNpZmljIHx8CiAgICAgICAgICAgICBhc3AtPnJlcXVlc3RzW2ldLnN0YXR1cyA9PSBsb29rX2Zvcl9zcGVjaWZpYykpCiAgICAgICAgICAgIHJldHVybiBhc3AtPnJlcXVlc3RzW2ldLnN0YXR1czsKICAgIH0KCiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKaW50Cm5ldHNubXBfY2hlY2tfcmVxdWVzdHNfZXJyb3IobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICAvKgogICAgICogZmluZCBhbnkgZXJyb3JzIG1hcmtlZCBpbiB0aGUgcmVxdWVzdHMgCiAgICAgKi8KICAgIGZvciAoO3JlcXVlc3RzO3JlcXVlc3RzID0gcmVxdWVzdHMtPm5leHQpIHsKICAgICAgICBpZiAocmVxdWVzdHMtPnN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SKQogICAgICAgICAgICByZXR1cm4gcmVxdWVzdHMtPnN0YXR1czsKICAgIH0KICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwp9CgppbnQKbmV0c25tcF9jaGVja19yZXF1ZXN0c19zdGF0dXMobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxvb2tfZm9yX3NwZWNpZmljKQp7CiAgICAvKgogICAgICogZmluZCBhbnkgZXJyb3JzIG1hcmtlZCBpbiB0aGUgcmVxdWVzdHMgCiAgICAgKi8KICAgIHdoaWxlIChyZXF1ZXN0cykgewogICAgICAgIGlmKHJlcXVlc3RzLT5hZ2VudF9yZXFfaW5mbyAhPSBhc3AtPnJlcWluZm8pIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwKICAgICAgICAgICAgICAgICAgICAgICAgIioqcmVxaW5mbyAlcCBkb2Vzbid0IG1hdGNoIGNhY2hlZCByZXFpbmZvICVwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnJlcWluZm8sIHJlcXVlc3RzLT5hZ2VudF9yZXFfaW5mbykpOwogICAgICAgIH0KICAgICAgICBpZiAocmVxdWVzdHMtPnN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SICYmCiAgICAgICAgICAgICghbG9va19mb3Jfc3BlY2lmaWMgfHwgcmVxdWVzdHMtPnN0YXR1cyA9PSBsb29rX2Zvcl9zcGVjaWZpYykKICAgICAgICAgICAgJiYgKGxvb2tfZm9yX3NwZWNpZmljIHx8IGFzcC0+aW5kZXggPT0gMAogICAgICAgICAgICAgICAgfHwgcmVxdWVzdHMtPmluZGV4IDwgYXNwLT5pbmRleCkpIHsKICAgICAgICAgICAgYXNwLT5pbmRleCA9IHJlcXVlc3RzLT5pbmRleDsKICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSByZXF1ZXN0cy0+c3RhdHVzOwogICAgICAgIH0KICAgICAgICByZXF1ZXN0cyA9IHJlcXVlc3RzLT5uZXh0OwogICAgfQogICAgcmV0dXJuIGFzcC0+c3RhdHVzOwp9CgppbnQKbmV0c25tcF9jaGVja19hbGxfcmVxdWVzdHNfc3RhdHVzKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxvb2tfZm9yX3NwZWNpZmljKQp7CiAgICBpbnQgICAgICAgICAgICAgaTsKICAgIGZvciAoaSA9IDA7IGkgPD0gYXNwLT50cmVlY2FjaGVfbnVtOyBpKyspIHsKICAgICAgICBuZXRzbm1wX2NoZWNrX3JlcXVlc3RzX3N0YXR1cyhhc3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVbaV0ucmVxdWVzdHNfYmVnaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9va19mb3Jfc3BlY2lmaWMpOwogICAgfQogICAgcmV0dXJuIGFzcC0+c3RhdHVzOwp9CgppbnQKaGFuZGxlX3Zhcl9yZXF1ZXN0cyhuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgaW50ICAgICAgICAgICAgIGksIHJldHN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1IsCiAgICAgICAgc3RhdHVzID0gU05NUF9FUlJfTk9FUlJPUiwgZmluYWxfc3RhdHVzID0gU05NUF9FUlJfTk9FUlJPUjsKICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm87CgogICAgYXNwLT5yZXFpbmZvLT5hc3AgPSBhc3A7CiAgICBhc3AtPnJlcWluZm8tPm1vZGUgPSBhc3AtPm1vZGU7CgogICAgLyoKICAgICAqIG5vdywgaGF2ZSB0aGUgc3VidHJlZXMgaW4gdGhlIGNhY2hlIGdvIHNlYXJjaCBmb3IgdGhlaXIgcmVzdWx0cyAKICAgICAqLwogICAgZm9yIChpID0gMDsgaSA8PSBhc3AtPnRyZWVjYWNoZV9udW07IGkrKykgewogICAgICAgIC8qCiAgICAgICAgICogZG9uJ3QgY2FsbCBoYW5kbGVycyB3L251bGwgcmVnaW5mby4KICAgICAgICAgKiAtIHdoZW4gaXMgdGhpcz8gc3ViIGFnZW50IGRpc2Nvbm5lY3RlZCB3aGlsZSByZXF1ZXN0IHByb2Nlc3Npbmc/CiAgICAgICAgICogLSBzaG91bGQgdGhpcyBjYXNlIGVuY29tcGFzcyBtb3JlIG9mIHRoaXMgc3Vicm91dGluZT8KICAgICAgICAgKiAgIC0gZG9lcyBjaGVja19yZXF1ZXN0X3N0YXR1cyBtYWtlIHNlbmQgaWYgaGFuZGxlcnMgd2VyZW4ndCBjYWxsZWQ/CiAgICAgICAgICovCiAgICAgICAgaWYoTlVMTCAhPSBhc3AtPnRyZWVjYWNoZVtpXS5zdWJ0cmVlLT5yZWdpbmZvKSB7CiAgICAgICAgICAgIHJlZ2luZm8gPSBhc3AtPnRyZWVjYWNoZVtpXS5zdWJ0cmVlLT5yZWdpbmZvOwogICAgICAgICAgICBzdGF0dXMgPSBuZXRzbm1wX2NhbGxfaGFuZGxlcnMocmVnaW5mbywgYXNwLT5yZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVbaV0ucmVxdWVzdHNfYmVnaW4pOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX0dFTkVSUjsKCiAgICAgICAgLyoKICAgICAgICAgKiBmaW5kIGFueSBlcnJvcnMgbWFya2VkIGluIHRoZSByZXF1ZXN0cy4gIEZvciBsYXRlciBwYXJ0cyBvZgogICAgICAgICAqIFNFVCBwcm9jZXNzaW5nLCBvbmx5IGNoZWNrIGZvciBuZXcgZXJyb3JzIHNwZWNpZmljIHRvIHRoYXQKICAgICAgICAgKiBzZXQgcHJvY2Vzc2luZyBkaXJlY3RpdmUgKHdoaWNoIG11c3Qgc3VwZXJjZWVkIHRoZSBwcmV2aW91cwogICAgICAgICAqIGVycm9ycykuCiAgICAgICAgICovCiAgICAgICAgc3dpdGNoIChhc3AtPm1vZGUpIHsKICAgICAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgICAgICAgICAgcmV0c3RhdHVzID0gbmV0c25tcF9jaGVja19yZXF1ZXN0c19zdGF0dXMoYXNwLAoJCQkJCQkgICAgICBhc3AtPnRyZWVjYWNoZVtpXS4KCQkJCQkJICAgICAgcmVxdWVzdHNfYmVnaW4sCgkJCQkJCSAgICAgIFNOTVBfRVJSX0NPTU1JVEZBSUxFRCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgICAgIHJldHN0YXR1cyA9IG5ldHNubXBfY2hlY2tfcmVxdWVzdHNfc3RhdHVzKGFzcCwKCQkJCQkJICAgICAgYXNwLT50cmVlY2FjaGVbaV0uCgkJCQkJCSAgICAgIHJlcXVlc3RzX2JlZ2luLAoJCQkJCQkgICAgICBTTk1QX0VSUl9VTkRPRkFJTEVEKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHN0YXR1cyA9IG5ldHNubXBfY2hlY2tfcmVxdWVzdHNfc3RhdHVzKGFzcCwKCQkJCQkJICAgICAgYXNwLT50cmVlY2FjaGVbaV0uCgkJCQkJCSAgICAgIHJlcXVlc3RzX2JlZ2luLCAwKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGFsd2F5cyB0YWtlIGxvd2VzdCB2YXJiaW5kIGlmIHBvc3NpYmxlIAogICAgICAgICAqLwogICAgICAgIGlmIChyZXRzdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikgewogICAgICAgICAgICBzdGF0dXMgPSByZXRzdGF0dXM7Cgl9CgogICAgICAgIC8qCiAgICAgICAgICogb3RoZXIgdGhpbmdzIHdlIGtub3cgbGVzcyBhYm91dCAobm8gaW5kZXgpIAogICAgICAgICAqLwogICAgICAgIC8qCiAgICAgICAgICogV1dXOiBkcm9wIHN1cHBvcnQgZm9yIHRoaXM/IAogICAgICAgICAqLwogICAgICAgIGlmIChmaW5hbF9zdGF0dXMgPT0gU05NUF9FUlJfTk9FUlJPUiAmJiBzdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB3ZSBjYW4ndCBicmVhayBoZXJlLCBzaW5jZSBzb21lIHByb2Nlc3NpbmcgbmVlZHMgdG8gYmUKICAgICAgICAgICAgICogZG9uZSBmb3IgYWxsIHJlcXVlc3RzIGFueXdheSAoSUUsIFNFVCBoYW5kbGluZyBmb3IgVU5ETwogICAgICAgICAgICAgKiBuZWVkcyB0byBiZSBjYWxsZWQgcmVnYXJkbGVzcyBvZiBwcmV2aW91cyBzdGF0dXMKICAgICAgICAgICAgICogcmVzdWx0cy4KICAgICAgICAgICAgICogV1dXOiAgVGhpcyBzaG91bGQgYmUgcHJlZGljdGFibGUgdGhvdWdoIGFuZAogICAgICAgICAgICAgKiBicmVha2luZyBzaG91bGQgYmUgcG9zc2libGUgaW4gc29tZSBjYXNlcyAoZWcgR0VULAogICAgICAgICAgICAgKiBHRVRORVhULCAuLi4pIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZmluYWxfc3RhdHVzID0gc3RhdHVzOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZmluYWxfc3RhdHVzOwp9CgovKgogKiBsb29wIHRocm91Z2ggb3VyIHNlc3Npb25zIGtub3duIGRlbGVnYXRlZCBzZXNzaW9ucyBhbmQgY2hlY2sgdG8gc2VlCiAqIGlmIHRoZXkndmUgY29tcGxldGVkIHlldC4gSWYgdGhlcmUgYXJlIG5vIG1vcmUgZGVsZWdhdGVkIHNlc3Npb25zLAogKiBjaGVjayBmb3IgYW5kIHByb2Nlc3MgYW55IHF1ZXVlZCByZXF1ZXN0cwogKi8Kdm9pZApuZXRzbm1wX2NoZWNrX291dHN0YW5kaW5nX2FnZW50X3JlcXVlc3RzKHZvaWQpCnsKICAgIG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLCAqcHJldl9hc3AgPSBOVUxMLCAqbmV4dF9hc3AgPSBOVUxMOwoKICAgIC8qCiAgICAgKiBkZWFsIHdpdGggZGVsZWdhdGVkIHJlcXVlc3RzCiAgICAgKi8KICAgIGZvciAoYXNwID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7IGFzcDsgYXNwID0gbmV4dF9hc3ApIHsKICAgICAgICBuZXh0X2FzcCA9IGFzcC0+bmV4dDsgICAvKiBzYXZlIGluIGNhc2Ugd2UgY2xlYW4gdXAgYXNwICovCiAgICAgICAgaWYgKCFuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWQoYXNwKSkgewoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogd2UncmUgZG9uZSB3aXRoIHRoaXMgb25lLCByZW1vdmUgZnJvbSBxdWV1ZSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChwcmV2X2FzcCAhPSBOVUxMKQogICAgICAgICAgICAgICAgcHJldl9hc3AtPm5leHQgPSBhc3AtPm5leHQ7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGFnZW50X2RlbGVnYXRlZF9saXN0ID0gYXNwLT5uZXh0OwogICAgICAgICAgICBhc3AtPm5leHQgPSBOVUxMOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogY2hlY2sgcmVxdWVzdCBzdGF0dXMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIG5ldHNubXBfY2hlY2tfYWxsX3JlcXVlc3RzX3N0YXR1cyhhc3AsIDApOwogICAgICAgICAgICAKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogY29udGludWUgcHJvY2Vzc2luZyBvciBmaW5pc2ggdXAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjaGVja19kZWxheWVkX3JlcXVlc3QoYXNwKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGlmIGhlYWQgd2FzIHJlbW92ZWQsIGRvbid0IGRyb3AgaXQgaWYgaXQKICAgICAgICAgICAgICogd2FzIGl0IHJlLXF1ZXVlZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKChwcmV2X2FzcCA9PSBOVUxMKSAmJiAoYWdlbnRfZGVsZWdhdGVkX2xpc3QgPT0gYXNwKSkgewogICAgICAgICAgICAgICAgcHJldl9hc3AgPSBhc3A7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogYXNwIGlzIHN0aWxsIG9uIHRoZSBxdWV1ZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcHJldl9hc3AgPSBhc3A7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBpZiB3ZSBhcmUgcHJvY2Vzc2luZyBhIHNldCBhbmQgdGhlcmUgYXJlIG1vcmUgZGVsZWdhdGVkCiAgICAgKiByZXF1ZXN0cywga2VlcCB3YWl0aW5nIGJlZm9yZSBnZXR0aW5nIHRvIHF1ZXVlZCByZXF1ZXN0cy4KICAgICAqLwogICAgaWYgKG5ldHNubXBfcHJvY2Vzc2luZ19zZXQgJiYgKE5VTEwgIT0gYWdlbnRfZGVsZWdhdGVkX2xpc3QpKQogICAgICAgIHJldHVybjsKCiAgICB3aGlsZSAobmV0c25tcF9hZ2VudF9xdWV1ZWRfbGlzdCkgewoKICAgICAgICAvKgogICAgICAgICAqIGlmIHdlIGFyZSBwcm9jZXNzaW5nIGEgc2V0LCB0aGUgZmlyc3QgaXRlbSBiZXR0ZXIgYmUKICAgICAgICAgKiB0aGUgc2V0IGJlaW5nIChvciB3YWl0aW5nIHRvIGJlKSBwcm9jZXNzZWQuCiAgICAgICAgICovCiAgICAgICAgbmV0c25tcF9hc3NlcnQoKCFuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0KSB8fAogICAgICAgICAgICAgICAgICAgICAgIChuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0ID09IG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3QpKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBpZiB0aGUgdG9wIHJlcXVlc3QgaXMgYSBzZXQsIGRvbid0IHBvcCBpdAogICAgICAgICAqIG9mZiBpZiB0aGVyZSBhcmUgZGVsZWdhdGVkIHJlcXVlc3RzCiAgICAgICAgICovCiAgICAgICAgaWYgKChuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0LT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfU0VUKSAmJgogICAgICAgICAgICAoYWdlbnRfZGVsZWdhdGVkX2xpc3QpKSB7CgogICAgICAgICAgICBuZXRzbm1wX2Fzc2VydChuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0ID09IE5VTEwpOwoKICAgICAgICAgICAgbmV0c25tcF9wcm9jZXNzaW5nX3NldCA9IG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3Q7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgIlNFVCByZXF1ZXN0IHJlbWFpbnMgcXVldWVkIHdoaWxlICIKICAgICAgICAgICAgICAgICAgICAgICAgImRlbGVnYXRlZCByZXF1ZXN0cyBmaW5pc2gsIGFzcCA9ICU4cFxuIiwgYXNwKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBwb3AgdGhlIGZpcnN0IHJlcXVlc3QgYW5kIHByb2Nlc3MgaXQKICAgICAgICAgKi8KICAgICAgICBhc3AgPSBuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0OwogICAgICAgIG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3QgPSBhc3AtPm5leHQ7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLAogICAgICAgICAgICAgICAgICAgICJwcm9jZXNzaW5nIHF1ZXVlZCByZXF1ZXN0LCBhc3AgPSAlOHBcbiIsIGFzcCkpOwoKICAgICAgICBuZXRzbm1wX2hhbmRsZV9yZXF1ZXN0KGFzcCwgYXNwLT5zdGF0dXMpOwoKICAgICAgICAvKgogICAgICAgICAqIGlmIHdlIGhpdCBhIHNldCwgc3RvcAogICAgICAgICAqLwogICAgICAgIGlmIChOVUxMICE9IG5ldHNubXBfcHJvY2Vzc2luZ19zZXQpCiAgICAgICAgICAgIGJyZWFrOwogICAgfQp9CgovKiogRGVjaWRlIGlmIHRoZSByZXF1ZXN0ZWQgdHJhbnNhY3Rpb25faWQgaXMgc3RpbGwgYmVpbmcgcHJvY2Vzc2VkCiAgIHdpdGhpbiB0aGUgYWdlbnQuICBUaGlzIGlzIHVzZWQgdG8gdmFsaWRhdGUgd2hldGhlciBhIGRlbGF5ZWQgY2FjaGUKICAgKGNvbnRhaW5pbmcgcG9zc2libHkgZnJlZWQgcG9pbnRlcnMpIGlzIHN0aWxsIHVzYWJsZS4KCiAgIHJldHVybnMgU05NUEVSUl9TVUNDRVNTIGlmIGl0J3Mgc3RpbGwgdmFsaWQsIG9yIFNOTVBFUlJfR0VORVJSIGlmIG5vdC4gKi8KaW50Cm5ldHNubXBfY2hlY2tfdHJhbnNhY3Rpb25faWQoaW50IHRyYW5zYWN0aW9uX2lkKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcDsKCiAgICBmb3IgKGFzcCA9IGFnZW50X2RlbGVnYXRlZF9saXN0OyBhc3A7IGFzcCA9IGFzcC0+bmV4dCkgewogICAgICAgIGlmIChhc3AtPnBkdS0+dHJhbnNpZCA9PSB0cmFuc2FjdGlvbl9pZCkKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKICAgIH0KICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKfQoKCi8qCiAqIGNoZWNrX2RlbGF5ZWRfcmVxdWVzdChhc3ApCiAqCiAqIENhbGxlZCB0byByZXhhbWluZSBhIHNldCBvZiByZXF1ZXN0cyBhbmQgY29udGludWUgcHJvY2Vzc2luZyB0aGVtCiAqIG9uY2UgYWxsIHRoZSBwcmV2aW91cyAoZGVsYXllZCkgcmVxdWVzdHMgaGF2ZSBiZWVuIGhhbmRsZWQgb25lIHdheQogKiBvciBhbm90aGVyLgogKi8KCmludApjaGVja19kZWxheWVkX3JlcXVlc3QobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGludCAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9OT0VSUk9SOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgInByb2Nlc3NpbmcgZGVsZWdhdGVkIHJlcXVlc3QsIGFzcCA9ICU4cFxuIiwKICAgICAgICAgICAgICAgIGFzcCkpOwoKICAgIHN3aXRjaCAoYXNwLT5tb2RlKSB7CiAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICAgICAgbmV0c25tcF9jaGVja19hbGxfcmVxdWVzdHNfc3RhdHVzKGFzcCwgMCk7CiAgICAgICAgaGFuZGxlX2dldG5leHRfbG9vcChhc3ApOwogICAgICAgIGlmIChuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWQoYXNwKSAmJgogICAgICAgICAgICBuZXRzbm1wX2NoZWNrX3RyYW5zYWN0aW9uX2lkKGFzcC0+cGR1LT50cmFuc2lkKSAhPQogICAgICAgICAgICBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogYWRkIHRvIGRlbGVnYXRlZCByZXF1ZXN0IGNoYWluIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFuZXRzbm1wX2NoZWNrX2RlbGVnYXRlZF9jaGFpbl9mb3IoYXNwKSkgewogICAgICAgICAgICAgICAgYXNwLT5uZXh0ID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7CiAgICAgICAgICAgICAgICBhZ2VudF9kZWxlZ2F0ZWRfbGlzdCA9IGFzcDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgICAgICBuZXRzbm1wX2NoZWNrX2FsbF9yZXF1ZXN0c19zdGF0dXMoYXNwLCBTTk1QX0VSUl9DT01NSVRGQUlMRUQpOwogICAgICAgIGdvdG8gc2V0dG9wOwoKICAgIGNhc2UgTU9ERV9TRVRfVU5ETzoKICAgICAgICBuZXRzbm1wX2NoZWNrX2FsbF9yZXF1ZXN0c19zdGF0dXMoYXNwLCBTTk1QX0VSUl9VTkRPRkFJTEVEKTsKICAgICAgICBnb3RvIHNldHRvcDsKCiAgICBjYXNlIE1PREVfU0VUX0JFR0lOOgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgc2V0dG9wOgogICAgICAgIC8qIElmIHdlIHNob3VsZCBkbyBvbmx5IG9uZSBwYXNzLCB0aGlzIG1lYW4gd2UgKi8KICAgICAgICAvKiBzaG91bGQgbm90IHJlZW50ZXIgdGhpcyBmdW5jdGlvbiAqLwogICAgICAgIGlmICgoYXNwLT5wZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX09ORV9QQVNTX09OTFkpKSB7CiAgICAgICAgICAgIC8qIFdlIHNob3VsZCBoYXZlIGZpbmlzaGVkIHRoZSBwcm9jZXNzaW5nIGFmdGVyIHRoZSBmaXJzdCAqLwogICAgICAgICAgICAvKiBoYW5kbGVfc2V0X2xvb3AsIHNvIGp1c3Qgd3JhcCB1cCAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaGFuZGxlX3NldF9sb29wKGFzcCk7CiAgICAgICAgaWYgKGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9TVUNDRVNTICYmIGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9GQUlMVVJFKSB7CgogICAgICAgICAgICBpZiAobmV0c25tcF9jaGVja19mb3JfZGVsZWdhdGVkX2FuZF9hZGQoYXNwKSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGFkZCB0byBkZWxlZ2F0ZWQgcmVxdWVzdCBjaGFpbiAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKCFhc3AtPnN0YXR1cykKICAgICAgICAgICAgICAgICAgICBhc3AtPnN0YXR1cyA9IHN0YXR1czsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgLyoKICAgICAqIGlmIHdlIGRvbid0IGhhdmUgYW55dGhpbmcgb3V0c3RhbmRpbmcgKGRlbGVnYXRlZCksIHdyYXAgdXAgCiAgICAgKi8KICAgIGlmICghbmV0c25tcF9jaGVja19mb3JfZGVsZWdhdGVkKGFzcCkpCiAgICAgICAgcmV0dXJuIG5ldHNubXBfd3JhcF91cF9yZXF1ZXN0KGFzcCwgc3RhdHVzKTsKCiAgICByZXR1cm4gMTsKfQoKLyoqIHJldHVybnMgMSBpZiB0aGVyZSBhcmUgdmFsaWQgR0VUTkVYVCByZXF1ZXN0cyBsZWZ0LiAgUmV0dXJucyAwIGlmIG5vdC4gKi8KaW50CmNoZWNrX2dldG5leHRfcmVzdWx0cyhuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgLyoKICAgICAqIGdldCBvbGQgaW5mbyAKICAgICAqLwogICAgbmV0c25tcF90cmVlX2NhY2hlICpvbGRfdHJlZWNhY2hlID0gYXNwLT50cmVlY2FjaGU7CiAgICBpbnQgICAgICAgICAgICAgb2xkX3RyZWVjYWNoZV9udW0gPSBhc3AtPnRyZWVjYWNoZV9udW07CiAgICBpbnQgICAgICAgICAgICAgY291bnQgPSAwOwogICAgaW50ICAgICAgICAgICAgIGksIHNwZWNpYWwgPSAwOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CgogICAgaWYgKGFzcC0+bW9kZSA9PSBTTk1QX01TR19HRVQpIHsKICAgICAgICAvKgogICAgICAgICAqIFNwZWNpYWwgY2FzZSBmb3IgZG9pbmcgSU5DTFVTSVZFIGdldE5leHQgb3BlcmF0aW9ucyBpbgogICAgICAgICAqIEFnZW50WCBzdWJhZ2VudHMuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsCiAgICAgICAgICAgICAgICAgICAgImFzcC0+bW9kZSA9PSBTTk1QX01TR19HRVQgaW4gY2hfZ2V0bmV4dFxuIikpOwogICAgICAgIGFzcC0+bW9kZSA9IGFzcC0+b2xkbW9kZTsKICAgICAgICBzcGVjaWFsID0gMTsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDw9IG9sZF90cmVlY2FjaGVfbnVtOyBpKyspIHsKICAgICAgICBmb3IgKHJlcXVlc3QgPSBvbGRfdHJlZWNhY2hlW2ldLnJlcXVlc3RzX2JlZ2luOyByZXF1ZXN0OwogICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIElmIHdlIGhhdmUganVzdCBkb25lIHRoZSBzcGVjaWFsIGNhc2UgQWdlbnRYIEdFVCwgdGhlbiBhbnkKICAgICAgICAgICAgICogcmVxdWVzdHMgd2hpY2ggd2VyZSBub3QgSU5DTFVTSVZFIHdpbGwgbm93IGhhdmUgYSB3cm9uZwogICAgICAgICAgICAgKiByZXNwb25zZSwgc28ganVuayB0aGVtIGFuZCByZXRyeSBmcm9tIHRoZSBzYW1lIHBsYWNlIChleGNlcHQKICAgICAgICAgICAgICogdGhhdCB0aGlzIHRpbWUgdGhlIGhhbmRsZXIgd2lsbCBiZSBjYWxsZWQgaW4gImluZXhhY3QiCiAgICAgICAgICAgICAqIG1vZGUpLiAgCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYgKHNwZWNpYWwpIHsKICAgICAgICAgICAgICAgIGlmICghcmVxdWVzdC0+aW5jbHVzaXZlKSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXF1ZXN0ICVkIHdhc24ndCBpbmNsdXNpdmVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+aW5kZXgpKTsKICAgICAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdC0+cmVxdWVzdHZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fUFJJVl9SRVRSWSwgTlVMTCwgMCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBBU05fTlVMTCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hJTlNUQU5DRSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hPQkpFQ1QpIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIGl0IHdhcyBpbmNsdXNpdmUsIGJ1dCBubyByZXN1bHRzLiAgU3RpbGwgcmV0cnkgdGhpcwogICAgICAgICAgICAgICAgICAgICAqIHNlYXJjaC4gCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3QtPnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX1BSSVZfUkVUUlksIE5VTEwsIDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBvdXQgb2YgcmFuZ2U/IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUocmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZF9sZW4pID49IDApIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBhY2ssIGl0J3MgYmV5b25kIHRoZSBhY2NlcHRlZCBlbmQgb2YgcmFuZ2UuIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogZml4IGl0IGJ5IHNldHRpbmcgdGhlIG9pZCB0byB0aGUgZW5kIG9mIHJhbmdlIG9pZCBpbnN0ZWFkIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiY2hlY2tfZ2V0bmV4dF9yZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXF1ZXN0IHJlc3BvbnNlICVkIG91dCBvZiByYW5nZVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluZGV4KSk7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogSSdtIG5vdCBzdXJlIHdoeSBpbmNsdXNpdmUgaXMgc2V0IHVuY29uZGl0aW9uYWxseSBoZXJlIChzZWUKICAgICAgICAgICAgICAgICAqIGNvbW1lbnRzIGZvciByZXZpc2lvbiAxLjE2MSksIGJ1dCBpdCBjYXVzZXMgYSBwcm9ibGVtIGZvcgogICAgICAgICAgICAgICAgICogR0VUQlVMSyBvdmVyIGFuIG92ZXJyaWRkZW4gdmFyaWFibGUuIFRoZSBidWxrLXRvLW5leHQKICAgICAgICAgICAgICAgICAqIGhhbmRsZXIgcmUtdXNlcyB0aGUgc2FtZSByZXF1ZXN0IGZvciBtdWx0aXBsZSB2YXJiaW5kcywKICAgICAgICAgICAgICAgICAqIGFuZCBvbmNlIGluY2x1c2l2ZSB3YXMgc2V0LCBpdCB3YXMgbmV2ZXIgY2xlYXJlZC4gU28sIGEKICAgICAgICAgICAgICAgICAqIGhhY2suIEluc3RlYWQgb2Ygc2V0dGluZyBpdCB0byAxLCBzZXQgaXQgdG8gMiwgc28gYnVsay10bwogICAgICAgICAgICAgICAgICogbmV4dCBjYW4gY2xlYXIgaXQgbGF0ZXIuIEFzIG9mIHRoZSB0aW1lIG9mIHRoaXMgaGFjaywgYWxsCiAgICAgICAgICAgICAgICAgKiBjaGVja3Mgb2YgdGhpcyB2YXIgYXJlIGJvb2xlYW4gY2hlY2tzIChub3QgPT0gMSksIHNvIHRoaXMKICAgICAgICAgICAgICAgICAqIHNob3VsZCBiZSBzYWZlLiBDcm9zcyB5b3VyIGZpbmdlcnMuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluY2x1c2l2ZSA9IDI7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogWFhYOiBzaG91bGQgc2V0IHRoaXMgdG8gdGhlIG9yaWdpbmFsIE9JRD8gCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZChyZXF1ZXN0LT5yZXF1ZXN0dmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmFuZ2VfZW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZF9sZW4pOwogICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3QtPnJlcXVlc3R2YiwgQVNOX05VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG1hcmsgYW55IGV4aXN0ZW50IHJlcXVlc3RzIHdpdGggaWxsZWdhbCByZXN1bHRzIGFzIE5VTEwgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID09IFNOTVBfRU5ET0ZNSUJWSUVXKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogaWxsZWdhbCByZXNwb25zZSBmcm9tIGEgc3ViYWdlbnQuICBDaGFuZ2UgaXQgYmFjayB0byBOVUxMIAogICAgICAgICAgICAgICAgICogIHh4eC1ya3M6IGVyciwgaG93IGRvIHdlIGtub3cgdGhpcyBpcyBhIHN1YmFnZW50PwogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPSBBU05fTlVMTDsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluY2x1c2l2ZSA9IDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX05VTEwgfHwKICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBBU05fUFJJVl9SRVRSWSB8fAogICAgICAgICAgICAgICAgKGFzcC0+cmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVEJVTEsKICAgICAgICAgICAgICAgICAmJiByZXF1ZXN0LT5yZXBlYXQgPiAwKSkKICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGNvdW50Owp9CgovKiogcmVwZWF0ZWRseSBjYWxscyBnZXRuZXh0IGhhbmRsZXJzIGxvb2tpbmcgZm9yIGFuIGFuc3dlciB0aWxsIGFsbAogICByZXF1ZXN0cyBhcmUgc2F0aXNpZmllZC4gIEl0J3MgZXhwZWN0ZWQgdGhhdCBvbmUgcGFzcyBoYXMgYmVlbiBtYWRlCiAgIGJlZm9yZSBlbnRlcmluZyB0aGlzIGZ1bmN0aW9uICovCmludApoYW5kbGVfZ2V0bmV4dF9sb29wKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJfcHRyOwoKICAgIC8qCiAgICAgKiBsb29wIAogICAgICovCiAgICB3aGlsZSAobmV0c25tcF9ydW5uaW5nKSB7CgogICAgICAgIC8qCiAgICAgICAgICogYmFpbCBmb3Igbm93IGlmIGFueXRoaW5nIGlzIGRlbGVnYXRlZC4gCiAgICAgICAgICovCiAgICAgICAgaWYgKG5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZChhc3ApKSB7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBjaGVjayB2YWNtIGFnYWluc3QgcmVzdWx0cyAKICAgICAgICAgKi8KICAgICAgICBjaGVja19hY20oYXNwLCBBU05fUFJJVl9SRVRSWSk7CgogICAgICAgIC8qCiAgICAgICAgICogbmVlZCB0byBrZWVwIGdvaW5nIHdlJ3JlIG5vdCBkb25lIHlldC4gCiAgICAgICAgICovCiAgICAgICAgaWYgKCFjaGVja19nZXRuZXh0X3Jlc3VsdHMoYXNwKSkKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogbm90aGluZyBsZWZ0LCBxdWl0IG5vdyAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvKgogICAgICAgICAqIG5ldmVyIGhhZCBhIHJlcXVlc3QgKGVtcHR5IHBkdSksIHF1aXQgbm93IAogICAgICAgICAqLwogICAgICAgIC8qCiAgICAgICAgICogWFhYV1dXOiBodWg/ICB0aGlzIHdvdWxkIGJlIHRvbyBsYXRlLCBubz8gIHNob3VsZG4ndCB3ZQogICAgICAgICAqIGNhdGNoIHRoaXMgZWFybGllcj8gCiAgICAgICAgICovCiAgICAgICAgLyoKICAgICAgICAgKiBpZiAoY291bnQgPT0gMCkKICAgICAgICAgKiBicmVhazsgCiAgICAgICAgICovCgogICAgICAgIERFQlVHSUYoInJlc3VsdHMiKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgImdldG5leHQgcmVzdWx0cywgYmVmb3JlIG5leHQgcGFzczpcbiIpKTsKICAgICAgICAgICAgZm9yICh2YXJfcHRyID0gYXNwLT5wZHUtPnZhcmlhYmxlczsgdmFyX3B0cjsKICAgICAgICAgICAgICAgICB2YXJfcHRyID0gdmFyX3B0ci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlc3VsdHMiLCAiXHQiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR1ZBUigoInJlc3VsdHMiLCB2YXJfcHRyKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoInJlc3VsdHMiLCAiXG4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIG5ldHNubXBfcmVhc3NpZ25fcmVxdWVzdHMoYXNwKTsKICAgICAgICBzdGF0dXMgPSBoYW5kbGVfdmFyX3JlcXVlc3RzKGFzcCk7CiAgICAgICAgaWYgKHN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SKSB7CiAgICAgICAgICAgIHJldHVybiBzdGF0dXM7ICAgICAgLyogc2hvdWxkIG5ldmVyIHJlYWxseSBoYXBwZW4gKi8KICAgICAgICB9CiAgICB9CiAgICBpZiAoIW5ldHNubXBfcnVubmluZykgewogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKaW50CmhhbmRsZV9zZXQobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGludCAgICAgICAgICAgICBzdGF0dXM7CiAgICAvKgogICAgICogU0VUUyByZXF1aXJlIDMtNCBwYXNzZXMgdGhyb3VnaCB0aGUgdmFyX29wX2xpc3QuCiAgICAgKiBUaGUgZmlyc3QgdHdvCiAgICAgKiBwYXNzZXMgdmVyaWZ5IHRoYXQgYWxsIHR5cGVzLCBsZW5ndGhzLCBhbmQgdmFsdWVzIGFyZSB2YWxpZAogICAgICogYW5kIG1heSByZXNlcnZlIHJlc291cmNlcyBhbmQgdGhlIHRoaXJkIGRvZXMgdGhlIHNldCBhbmQgYQogICAgICogZm91cnRoIGV4ZWN1dGVzIGFueSBhY3Rpb25zLiAgVGhlbiB0aGUgaWRlbnRpY2FsIEdFVCBSRVNQT05TRQogICAgICogcGFja2V0IGlzIHJldHVybmVkLgogICAgICogSWYgZWl0aGVyIG9mIHRoZSBmaXJzdCB0d28gcGFzc2VzIHJldHVybnMgYW4gZXJyb3IsIGFub3RoZXIKICAgICAqIHBhc3MgaXMgbWFkZSBzbyB0aGF0IGFueSByZXNlcnZlZCByZXNvdXJjZXMgY2FuIGJlIGZyZWVkLgogICAgICogSWYgdGhlIHRoaXJkIHBhc3MgcmV0dXJucyBhbiBlcnJvciwgYW5vdGhlciBwYXNzIGlzCiAgICAgKiBtYWRlIHNvIHRoYXQKICAgICAqIGFueSBjaGFuZ2VzIGNhbiBiZSByZXZlcnNlZC4KICAgICAqIElmIHRoZSBmb3VydGggcGFzcyAob3IgYW55IG9mIHRoZSBlcnJvciBoYW5kbGluZyBwYXNzZXMpCiAgICAgKiByZXR1cm4gYW4gZXJyb3IsIHdlJ2QgcmF0aGVyIG5vdCBrbm93IGFib3V0IGl0IQogICAgICovCiAgICBpZiAoIShhc3AtPnBkdS0+ZmxhZ3MgJiBVQ0RfTVNHX0ZMQUdfT05FX1BBU1NfT05MWSkpIHsKICAgICAgICBzd2l0Y2ggKGFzcC0+bW9kZSkgewogICAgICAgIGNhc2UgTU9ERV9TRVRfQkVHSU46CiAgICAgICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTlNFVFJFUVVFU1RTKTsKICAgICAgICAgICAgYXNwLT5ydyA9IFdSSVRFOyAgICAvKiBXV1c6IHN0aWxsIG5lZWRlZD8gKi8KICAgICAgICAgICAgYXNwLT5tb2RlID0gTU9ERV9TRVRfUkVTRVJWRTE7CiAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CgogICAgICAgICAgICBpZiAoYXNwLT5zdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikKICAgICAgICAgICAgICAgIGFzcC0+bW9kZSA9IE1PREVfU0VUX0ZSRUU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGFzcC0+bW9kZSA9IE1PREVfU0VUX1JFU0VSVkUyOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMjoKICAgICAgICAgICAgaWYgKGFzcC0+c3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpCiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBNT0RFX1NFVF9GUkVFOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBNT0RFX1NFVF9BQ1RJT047CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgICAgICAgICAgaWYgKGFzcC0+c3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpCiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBNT0RFX1NFVF9VTkRPOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBNT0RFX1NFVF9DT01NSVQ7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgICAgICAgICAgaWYgKGFzcC0+c3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpIHsKICAgICAgICAgICAgICAgIGFzcC0+bW9kZSA9IEZJTklTSEVEX0ZBSUxVUkU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBGSU5JU0hFRF9TVUNDRVNTOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgICAgIGFzcC0+bW9kZSA9IEZJTklTSEVEX0ZBSUxVUkU7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgICAgICAgIGFzcC0+bW9kZSA9IEZJTklTSEVEX0ZBSUxVUkU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoYXNwLT5tb2RlICE9IEZJTklTSEVEX1NVQ0NFU1MgJiYgYXNwLT5tb2RlICE9IEZJTklTSEVEX0ZBSUxVUkUpIHsKICAgICAgICBERUJVR01TR1RMKCgiYWdlbnRfc2V0IiwgImRvaW5nIHNldCBtb2RlID0gJWQgKCVzKVxuIiwgYXNwLT5tb2RlLAogICAgICAgICAgICAgICAgICAgIHNlX2ZpbmRfbGFiZWxfaW5fc2xpc3QoImFnZW50X21vZGUiLCBhc3AtPm1vZGUpKSk7CiAgICAgICAgc3RhdHVzID0gaGFuZGxlX3Zhcl9yZXF1ZXN0cyhhc3ApOwogICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudF9zZXQiLCAiZGlkIHNldCBtb2RlID0gJWQsIHN0YXR1cyA9ICVkXG4iLAogICAgICAgICAgICAgICAgICAgIGFzcC0+bW9kZSwgc3RhdHVzKSk7CiAgICAgICAgaWYgKChzdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUiAmJiBhc3AtPnN0YXR1cyA9PSBTTk1QX0VSUl9OT0VSUk9SKSB8fAoJICAgIHN0YXR1cyA9PSBTTk1QX0VSUl9DT01NSVRGQUlMRUQgfHwgCgkgICAgc3RhdHVzID09IFNOTVBfRVJSX1VORE9GQUlMRUQpIHsKICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBzdGF0dXM7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFzcC0+c3RhdHVzOwp9CgppbnQKaGFuZGxlX3NldF9sb29wKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICB3aGlsZSAoYXNwLT5tb2RlICE9IEZJTklTSEVEX0ZBSUxVUkUgJiYgYXNwLT5tb2RlICE9IEZJTklTSEVEX1NVQ0NFU1MpIHsKICAgICAgICBoYW5kbGVfc2V0KGFzcCk7CiAgICAgICAgaWYgKG5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZChhc3ApKSB7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwoJfQogICAgICAgIGlmIChhc3AtPnBkdS0+ZmxhZ3MgJiBVQ0RfTVNHX0ZMQUdfT05FX1BBU1NfT05MWSkgewogICAgICAgICAgICByZXR1cm4gYXNwLT5zdGF0dXM7Cgl9CiAgICB9CiAgICByZXR1cm4gYXNwLT5zdGF0dXM7Cn0KCmludApuZXRzbm1wX2hhbmRsZV9yZXF1ZXN0KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLCBpbnQgc3RhdHVzKQp7CiAgICAvKgogICAgICogaWYgdGhpcyBpc24ndCBhIGRlbGVnYXRlZCByZXF1ZXN0IHRyeWluZyB0byBmaW5pc2gsCiAgICAgKiBwcm9jZXNzaW5nIG9mIGEgc2V0IHJlcXVlc3Qgc2hvdWxkIG5vdCBzdGFydCB1bnRpbCBhbGwKICAgICAqIGRlbGVnYXRlZCByZXF1ZXN0cyBoYXZlIGNvbXBsZXRlZCwgYW5kIG5vIG90aGVyIG5ldyByZXF1ZXN0cwogICAgICogc2hvdWxkIGJlIHByb2Nlc3NlZCB1bnRpbCB0aGUgc2V0IHJlcXVlc3QgY29tcGxldGVzLgogICAgICovCiAgICBpZiAoKDAgPT0gbmV0c25tcF9jaGVja19kZWxlZ2F0ZWRfY2hhaW5fZm9yKGFzcCkpICYmCiAgICAgICAgKGFzcCAhPSBuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0KSkgewogICAgICAgIC8qCiAgICAgICAgICogaWYgd2UgYXJlIHByb2Nlc3NpbmcgYSBzZXQgYW5kIHRoaXMgaXMgbm90IGEgZGVsZWdhdGVkCiAgICAgICAgICogcmVxdWVzdCwgcXVldWUgdGhlIHJlcXVlc3QKICAgICAgICAgKi8KICAgICAgICBpZiAobmV0c25tcF9wcm9jZXNzaW5nX3NldCkgewogICAgICAgICAgICBuZXRzbm1wX2FkZF9xdWV1ZWQoYXNwKTsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAicmVxdWVzdCBxdWV1ZWQgd2hpbGUgcHJvY2Vzc2luZyBzZXQsICIKICAgICAgICAgICAgICAgICAgICAgICAgImFzcCA9ICU4cFxuIiwgYXNwKSk7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBjaGVjayBmb3Igc2V0IHJlcXVlc3QKICAgICAgICAgKi8KICAgICAgICBpZiAoYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfU0VUKSB7CiAgICAgICAgICAgIG5ldHNubXBfcHJvY2Vzc2luZ19zZXQgPSBhc3A7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpZiB0aGVyZSBhcmUgZGVsZWdhdGVkIHJlcXVlc3RzLCB3ZSBtdXN0IHdhaXQgZm9yIHRoZW0KICAgICAgICAgICAgICogdG8gZmluaXNoLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGFnZW50X2RlbGVnYXRlZF9saXN0KSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJTRVQgcmVxdWVzdCBxdWV1ZWQgd2hpbGUgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlbGVnYXRlZCByZXF1ZXN0cyBmaW5pc2gsIGFzcCA9ICU4cFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcCkpOwogICAgICAgICAgICAgICAgbmV0c25tcF9hZGRfcXVldWVkKGFzcCk7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogcHJvY2VzcyB0aGUgcmVxdWVzdCAKICAgICAqLwogICAgc3RhdHVzID0gaGFuZGxlX3BkdShhc3ApOwoKICAgIC8qCiAgICAgKiBwcmludCB0aGUgcmVzdWx0cyBpbiBhcHByb3ByaWF0ZSBkZWJ1Z2dpbmcgbW9kZSAKICAgICAqLwogICAgREVCVUdJRigicmVzdWx0cyIpIHsKICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcl9wdHI7CiAgICAgICAgREVCVUdNU0dUTCgoInJlc3VsdHMiLCAicmVxdWVzdCByZXN1bHRzIChzdGF0dXMgPSAlZCk6XG4iLAogICAgICAgICAgICAgICAgICAgIHN0YXR1cykpOwogICAgICAgIGZvciAodmFyX3B0ciA9IGFzcC0+cGR1LT52YXJpYWJsZXM7IHZhcl9wdHI7CiAgICAgICAgICAgICB2YXJfcHRyID0gdmFyX3B0ci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVzdWx0cyIsICJcdCIpKTsKICAgICAgICAgICAgREVCVUdNU0dWQVIoKCJyZXN1bHRzIiwgdmFyX3B0cikpOwogICAgICAgICAgICBERUJVR01TRygoInJlc3VsdHMiLCAiXG4iKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBjaGVjayBmb3IgdW5jb21wbGV0ZWQgcmVxdWVzdHMgCiAgICAgKi8KICAgIGlmIChuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWRfYW5kX2FkZChhc3ApKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBhZGQgdG8gZGVsZWdhdGVkIHJlcXVlc3QgY2hhaW4gCiAgICAgICAgICovCiAgICAgICAgYXNwLT5zdGF0dXMgPSBzdGF0dXM7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogaWYgd2UgZG9uJ3QgaGF2ZSBhbnl0aGluZyBvdXRzdGFuZGluZyAoZGVsZWdhdGVkKSwgd3JhcCB1cAogICAgICAgICAqLwogICAgICAgIHJldHVybiBuZXRzbm1wX3dyYXBfdXBfcmVxdWVzdChhc3AsIHN0YXR1cyk7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCmludApoYW5kbGVfcGR1KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzLCBpbmNsdXNpdmVzID0gMDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdiA9IE5VTEw7CgogICAgLyoKICAgICAqIGZvciBpbGxlZ2FsIHJlcXVlc3RzLCBtYXJrIGFsbCBub2RlcyBhcyBBU05fTlVMTCAKICAgICAqLwogICAgc3dpdGNoIChhc3AtPnBkdS0+Y29tbWFuZCkgewoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUyOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQUNUSU9OOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQ09NTUlUOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfRlJFRToKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1VORE86CiAgICAgICAgc3RhdHVzID0gZ2V0X3NldF9jYWNoZShhc3ApOwogICAgICAgIGlmIChzdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikKICAgICAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgIGNhc2UgU05NUF9NU0dfR0VUQlVMSzoKICAgICAgICBmb3IgKHYgPSBhc3AtPnBkdS0+dmFyaWFibGVzOyB2ICE9IE5VTEw7IHYgPSB2LT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgIGlmICh2LT50eXBlID09IEFTTl9QUklWX0lOQ0xfUkFOR0UpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBMZWF2ZSB0aGUgdHlwZSBmb3Igbm93IChpdCBnZXRzIHNldCB0bwogICAgICAgICAgICAgICAgICogQVNOX05VTEwgaW4gbmV0c25tcF9hZGRfdmFyYmluZF90b19jYWNoZSwKICAgICAgICAgICAgICAgICAqIGNhbGxlZCBieSBjcmVhdGVfc3VibmV0c25tcF90cmVlX2NhY2hlIGJlbG93KS4KICAgICAgICAgICAgICAgICAqIElmIHdlIHNldCBpdCB0byBBU05fTlVMTCBub3csIHdlIHdvdWxkbid0IGJlCiAgICAgICAgICAgICAgICAgKiBhYmxlIHRvIGRpc3Rpbmd1aXNoIElOQ0xVU0lWRSBzZWFyY2gKICAgICAgICAgICAgICAgICAqIHJhbmdlcy4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpbmNsdXNpdmVzKys7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUodiwgQVNOX05VTEwsIE5VTEwsIDApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogZmFsbCB0aHJvdWdoIAogICAgICAgICAqLwoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX0JFR0lOOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfUkVTRVJWRTE6CiAgICBkZWZhdWx0OgogICAgICAgIGFzcC0+dmJjb3VudCA9IGNvdW50X3ZhcmJpbmRzKGFzcC0+cGR1LT52YXJpYWJsZXMpOwogICAgICAgIGlmIChhc3AtPnZiY291bnQpIC8qIGVmZW5jZSBkb2Vzbid0IGxpa2UgMCBzaXplIGFsbG9jcyAqLwogICAgICAgICAgICBhc3AtPnJlcXVlc3RzID0gKG5ldHNubXBfcmVxdWVzdF9pbmZvICopCiAgICAgICAgICAgICAgICBjYWxsb2MoYXNwLT52YmNvdW50LCBzaXplb2YobmV0c25tcF9yZXF1ZXN0X2luZm8pKTsKICAgICAgICAvKgogICAgICAgICAqIGNvbGxlY3QgdmFyYmluZHMgCiAgICAgICAgICovCiAgICAgICAgc3RhdHVzID0gbmV0c25tcF9jcmVhdGVfc3VidHJlZV9jYWNoZShhc3ApOwogICAgICAgIGlmIChzdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikKICAgICAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgIH0KCiAgICBhc3AtPm1vZGUgPSBhc3AtPnBkdS0+Y29tbWFuZDsKICAgIHN3aXRjaCAoYXNwLT5tb2RlKSB7CiAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgICAgICAvKgogICAgICAgICAqIGluY3JlbWVudCB0aGUgbWVzc2FnZSB0eXBlIGNvdW50ZXIgCiAgICAgICAgICovCiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOR0VUUkVRVUVTVFMpOwoKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIHZhY20gYWhlYWQgb2YgdGltZSAKICAgICAgICAgKi8KICAgICAgICBjaGVja19hY20oYXNwLCBTTk1QX05PU1VDSE9CSkVDVCk7CgogICAgICAgIC8qCiAgICAgICAgICogZ2V0IHRoZSByZXN1bHRzIAogICAgICAgICAqLwogICAgICAgIHN0YXR1cyA9IGhhbmRsZV92YXJfcmVxdWVzdHMoYXNwKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBEZWFsIHdpdGggdW5oYW5kbGVkIHJlc3VsdHMgLT4gbm9TdWNoSW5zdGFuY2UgKHJhdGhlcgogICAgICAgICAqIHRoYW4gbm9TdWNoT2JqZWN0IC0tIGluIHRoYXQgY2FzZSwgdGhlIHR5cGUgd2lsbAogICAgICAgICAqIGFscmVhZHkgaGF2ZSBiZWVuIHNldCB0byBub1N1Y2hPYmplY3Qgd2hlbiB3ZSByZWFsaXNlZAogICAgICAgICAqIHdlIGNvdWxkbid0IGZpbmQgYW4gYXBwcm9wcmlhdGUgdHJlZSkuICAKICAgICAgICAgKi8KICAgICAgICBpZiAoc3RhdHVzID09IFNOTVBfRVJSX05PRVJST1IpCiAgICAgICAgICAgIHNubXBfcmVwbGFjZV92YXJfdHlwZXMoYXNwLT5wZHUtPnZhcmlhYmxlcywgQVNOX05VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9OT1NVQ0hJTlNUQU5DRSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkdFVE5FWFRTKTsKICAgICAgICAvKgogICAgICAgICAqIGZhbGwgdGhyb3VnaCAKICAgICAgICAgKi8KCiAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6ICAgICAvKiBub3RlOiB0aGVyZSBpcyBubyBnZXRidWxrIHN0YXQgKi8KICAgICAgICAvKgogICAgICAgICAqIGxvb3AgdGhyb3VnaCBvdXIgbWliIHRyZWUgdGlsbCB3ZSBmaW5kIGFuCiAgICAgICAgICogYXBwcm9wcmlhdGUgcmVzcG9uc2UgdG8gcmV0dXJuIHRvIHRoZSBjYWxsZXIuIAogICAgICAgICAqLwoKICAgICAgICBpZiAoaW5jbHVzaXZlcykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlIGZvciBBZ2VudFggSU5DTFVTSVZFIGdldE5leHQKICAgICAgICAgICAgICogcmVxdWVzdHMgd2hlcmUgYSByZXN1bHQgbGV4aS1lcXVhbCB0byB0aGUgcmVxdWVzdCBpcyBva2F5CiAgICAgICAgICAgICAqIGJ1dCBpZiBzdWNoIGEgcmVzdWx0IGRvZXMgbm90IGV4aXN0LCB3ZSBzdGlsbCB3YW50IHRoZQogICAgICAgICAgICAgKiBsZXhpLW5leHQgb25lLiAgU28gYmFzaWNhbGx5IHdlIGRvIGEgR0VUIGZpcnN0LCBhbmQgaWYgYW55CiAgICAgICAgICAgICAqIG9mIHRoZSBJTkNMVVNJVkUgcmVxdWVzdHMgYXJlIHNhdGlzZmllZCwgd2UgdXNlIHRoYXQKICAgICAgICAgICAgICogdmFsdWUuICBUaGVuLCB1bnNhdGlzZmllZCBJTkNMVVNJVkUgcmVxdWVzdHMsIGFuZAogICAgICAgICAgICAgKiBub24tSU5DTFVTSVZFIHJlcXVlc3RzIGdldCBkb25lIGFzIG5vcm1hbC4gIAogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImluY2x1c2l2ZSByYW5nZShzKSBpbiBnZXROZXh0XG4iKSk7CiAgICAgICAgICAgIGFzcC0+b2xkbW9kZSA9IGFzcC0+bW9kZTsKICAgICAgICAgICAgYXNwLT5tb2RlID0gU05NUF9NU0dfR0VUOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBmaXJzdCBwYXNzIAogICAgICAgICAqLwogICAgICAgIHN0YXR1cyA9IGhhbmRsZV92YXJfcmVxdWVzdHMoYXNwKTsKICAgICAgICBpZiAoc3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpIHsKICAgICAgICAgICAgaWYgKCFpbmNsdXNpdmVzKQogICAgICAgICAgICAgICAgcmV0dXJuIHN0YXR1czsgIC8qIHNob3VsZCBuZXZlciByZWFsbHkgaGFwcGVuICovCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogbG9vcCB0aHJvdWdoIG91ciBtaWIgdHJlZSB0aWxsIHdlIGZpbmQgYW4KICAgICAgICAgKiBhcHByb3ByaWF0ZSByZXNwb25zZSB0byByZXR1cm4gdG8gdGhlIGNhbGxlci4gCiAgICAgICAgICovCgogICAgICAgIHN0YXR1cyA9IGhhbmRsZV9nZXRuZXh0X2xvb3AoYXNwKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX1NFVDoKI2lmZGVmIE5FVFNOTVBfRElTQUJMRV9TRVRfU1VQUE9SVAogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1RXUklUQUJMRTsKI2Vsc2UKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIGFjY2VzcyBwZXJtaXNzaW9ucyBmaXJzdCAKICAgICAgICAgKi8KICAgICAgICBpZiAoY2hlY2tfYWNtKGFzcCwgU05NUF9OT1NVQ0hPQkpFQ1QpKQogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9UV1JJVEFCTEU7CgogICAgICAgIGFzcC0+bW9kZSA9IE1PREVfU0VUX0JFR0lOOwogICAgICAgIHN0YXR1cyA9IGhhbmRsZV9zZXRfbG9vcChhc3ApOwojZW5kaWYKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9CRUdJTjoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUxOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfUkVTRVJWRTI6CiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9BQ1RJT046CiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9DT01NSVQ6CiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9GUkVFOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfVU5ETzoKICAgICAgICBhc3AtPnBkdS0+ZmxhZ3MgfD0gVUNEX01TR19GTEFHX09ORV9QQVNTX09OTFk7CiAgICAgICAgc3RhdHVzID0gaGFuZGxlX3NldF9sb29wKGFzcCk7CiAgICAgICAgLyoKICAgICAgICAgKiBhc3AgcmVsYXRlZCBjYWNoZSBpcyBzYXZlZCBpbiBjbGVhbnVwIAogICAgICAgICAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgU05NUF9NU0dfUkVTUE9OU0U6CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOR0VUUkVTUE9OU0VTKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKCiAgICBjYXNlIFNOTVBfTVNHX1RSQVA6CiAgICBjYXNlIFNOTVBfTVNHX1RSQVAyOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTlRSQVBTKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKCiAgICBkZWZhdWx0OgogICAgICAgIC8qCiAgICAgICAgICogV1dXOiBhcmUgcmVwb3J0cyBjb3VudGVkIHNvbWV3aGVyZSA/IAogICAgICAgICAqLwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOyAgLyogc2hvdWxkbid0IGdldCBoZXJlICovCiAgICAgICAgLyoKICAgICAgICAgKiBXV1cgCiAgICAgICAgICovCiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiogc2V0IGVycm9yIGZvciBhIHJlcXVlc3QKICogXGludGVybmFsIGV4dGVybmFsIGludGVyZmFjZTogbmV0c25tcF9yZXF1ZXN0X3NldF9lcnJvcgogKi8KTkVUU05NUF9TVEFUSUNfSU5MSU5FIGludApfcmVxdWVzdF9zZXRfZXJyb3IobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsIGludCBtb2RlLCBpbnQgZXJyb3JfdmFsdWUpCnsKICAgIGlmICghcmVxdWVzdCkKICAgICAgICByZXR1cm4gU05NUEVSUl9OT19WQVJTOwoKICAgIHJlcXVlc3QtPnByb2Nlc3NlZCA9IDE7CiAgICByZXF1ZXN0LT5kZWxlZ2F0ZWQgPSBSRVFVRVNUX0lTX05PVF9ERUxFR0FURUQ7CgogICAgc3dpdGNoIChlcnJvcl92YWx1ZSkgewogICAgY2FzZSBTTk1QX05PU1VDSE9CSkVDVDoKICAgIGNhc2UgU05NUF9OT1NVQ0hJTlNUQU5DRToKICAgIGNhc2UgU05NUF9FTkRPRk1JQlZJRVc6CiAgICAgICAgLyoKICAgICAgICAgKiB0aGVzZSBhcmUgZXhjZXB0aW9ucyB0aGF0IHNob3VsZCBiZSBwdXQgaW4gdGhlIHZhcmJpbmQKICAgICAgICAgKiBpbiB0aGUgY2FzZSBvZiBhIEdFVCBidXQgc2hvdWxkIGJlIHRyYW5zbGF0ZWQgZm9yIGEgU0VUCiAgICAgICAgICogaW50byBhIHJlYWwgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIHB1dCBpbiB0aGUgcmVxdWVzdCAKICAgICAgICAgKi8KICAgICAgICBzd2l0Y2ggKG1vZGUpIHsKICAgICAgICBjYXNlIE1PREVfR0VUOgogICAgICAgIGNhc2UgTU9ERV9HRVRORVhUOgogICAgICAgIGNhc2UgTU9ERV9HRVRCVUxLOgogICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPSBlcnJvcl92YWx1ZTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGVzZSBhcmUgdGVjaG5pY2FsbHkgaWxsZWdhbCB0byBzZXQgYnkgdGhlCiAgICAgICAgICAgICAqIGNsaWVudCBBUElzIGZvciB0aGVzZSBtb2Rlcy4gIEJ1dCBhY2NlcHRpbmcKICAgICAgICAgICAgICogdGhlbSBoZXJlIGFsbG93cyB0aGUgJ3NwYXJzZV90YWJsZScgaGVscGVyIHRvCiAgICAgICAgICAgICAqIHByb3ZpZGUgc29tZSBjb21tb24gdGFibGUgaGFuZGxpbmcgcHJvY2Vzc2luZwogICAgICAgICAgICAgKgogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiSWxsZWdhbCBlcnJvcl92YWx1ZSAlZCBmb3IgbW9kZSAlZCBpZ25vcmVkXG4iLAogICAgICAgICAgICAgICAgICAgICBlcnJvcl92YWx1ZSwgbW9kZSk7CiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICAgKi8KCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmVxdWVzdC0+c3RhdHVzID0gU05NUF9FUlJfTk9TVUNITkFNRTsgICAgICAvKiBXV1c6IGNvcnJlY3Q/ICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAvKiBuZXZlciBnZXQgaGVyZSAqLwoKICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKGVycm9yX3ZhbHVlIDwgMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpbGxlZ2FsIGxvY2FsIGVycm9yIGNvZGUuICB0cmFuc2xhdGUgdG8gZ2VuZXJyIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogV1dXOiBmdWxsIHRyYW5zbGF0aW9uIG1hcD8gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiSWxsZWdhbCBlcnJvcl92YWx1ZSAlZCB0cmFuc2xhdGVkIHRvICVkXG4iLAogICAgICAgICAgICAgICAgICAgICBlcnJvcl92YWx1ZSwgU05NUF9FUlJfR0VORVJSKTsKICAgICAgICAgICAgcmVxdWVzdC0+c3RhdHVzID0gU05NUF9FUlJfR0VORVJSOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFdXVzogdHJhbnNsYXRpb25zIGFuZCBtb2RlIGNoZWNraW5nPyAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlcXVlc3QtPnN0YXR1cyA9IGVycm9yX3ZhbHVlOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCi8qKiBzZXQgZXJyb3IgZm9yIGEgcmVxdWVzdAogKiBAcGFyYW0gcmVxdWVzdCByZXF1ZXN0IHdoaWNoIGhhcyBlcnJvcgogKiBAcGFyYW0gZXJyb3JfdmFsdWUgZXJyb3IgdmFsdWUgZm9yIHJlcXVlc3QKICovCmludApuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCBpbnQgZXJyb3JfdmFsdWUpCnsKICAgIGlmICghcmVxdWVzdCB8fCAhcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKCiAgICByZXR1cm4gX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3QsIHJlcXVlc3QtPmFnZW50X3JlcV9pbmZvLT5tb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl92YWx1ZSk7Cn0KCi8qKiBzZXQgZXJyb3IgZm9yIGEgcmVxdWVzdCB3aXRoaW4gYSByZXF1ZXN0IGxpc3QKICogQHBhcmFtIHJlcXVlc3QgaGVhZCBvZiB0aGUgcmVxdWVzdCBsaXN0CiAqIEBwYXJhbSBlcnJvcl92YWx1ZSBlcnJvciB2YWx1ZSBmb3IgcmVxdWVzdAogKiBAcGFyYW0gaWR4IGluZGV4IG9mIHRoZSByZXF1ZXN0IHdoaWNoIGhhcyB0aGUgZXJyb3IKICovCmludApuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yX2lkeChuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGVycm9yX3ZhbHVlLCBpbnQgaWR4KQp7CiAgICBpbnQgaTsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXEgPSByZXF1ZXN0OwoKICAgIGlmICghcmVxdWVzdCB8fCAhcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKCiAgICAvKgogICAgICogU2tpcCB0byB0aGUgaW5kaWNhdGVkIHZhcmJpbmQKICAgICAqLwogICAgZm9yICggaT0yOyBpPGlkeDsgaSsrKSB7CiAgICAgICAgcmVxID0gcmVxLT5uZXh0OwogICAgICAgIGlmICghcmVxKQogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9OT19WQVJTOwogICAgfQogICAgCiAgICByZXR1cm4gX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcSwgcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8tPm1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3ZhbHVlKTsKfQoKLyoqIHNldCBlcnJvciBmb3IgYWxsIHJlcXVlc3RzCiAqIEBwYXJhbSByZXF1ZXN0cyByZXF1ZXN0IGxpc3QKICogQHBhcmFtIGVycm9yIGVycm9yIHZhbHVlIGZvciByZXF1ZXN0cwogKiBAcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUywgb3IgYW4gZXJyb3IgY29kZQogKi8KTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfcmVxdWVzdF9zZXRfZXJyb3JfYWxsKCBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsIGludCBlcnJvcikKewogICAgaW50IG1vZGUsIHJjLCByZXN1bHQgPSBTTk1QRVJSX1NVQ0NFU1M7CgogICAgaWYoKE5VTEwgPT0gcmVxdWVzdHMpIHx8IChOVUxMID09IHJlcXVlc3RzLT5hZ2VudF9yZXFfaW5mbykpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKICAgIAogICAgbW9kZSA9IHJlcXVlc3RzLT5hZ2VudF9yZXFfaW5mby0+bW9kZTsgLyogZXZlcnkgcmVxIGhhcyBzYW1lIG1vZGUgKi8KICAgIAogICAgZm9yKDsgcmVxdWVzdHMgOyByZXF1ZXN0cyA9IHJlcXVlc3RzLT5uZXh0KSB7CgogICAgICAgIC8qKiBwYXJhbm9pZCBzYW5pdHkgY2hlY2tzICovCiAgICAgICAgbmV0c25tcF9hc3NlcnQoTlVMTCAhPSByZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8pOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KG1vZGUgPT0gcmVxdWVzdHMtPmFnZW50X3JlcV9pbmZvLT5tb2RlKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBzZXQgZXJyb3IgZm9yIHRoaXMgcmVxdWVzdC4gTG9nIGFueSBlcnJvcnMsIHNhdmUgdGhlIGxhc3QKICAgICAgICAgKiB0byByZXR1cm4gdG8gdGhlIHVzZXIuCiAgICAgICAgICovCiAgICAgICAgaWYoKHJjID0gX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3RzLCBtb2RlLCBlcnJvcikpKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLCJnb3QgJWQgd2hpbGUgc2V0dGluZyByZXF1ZXN0IGVycm9yXG4iLCByYyk7CiAgICAgICAgICAgIHJlc3VsdCA9IHJjOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXN1bHQ7Cn0KCmV4dGVybiBzdHJ1Y3QgdGltZXZhbCBzdGFydHRpbWU7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgJ3N5c1VwVGltZScgYXQgdGhlIGdpdmVuIG1hcmtlciAKICAgICAgICAgICAgICAgICAqLwp1X2xvbmcKbmV0c25tcF9tYXJrZXJfdXB0aW1lKG1hcmtlcl90IHBtKQp7CiAgICB1X2xvbmcgICAgICAgICAgcmVzOwogICAgbWFya2VyX3QgICAgICAgIHN0YXJ0ID0gKG1hcmtlcl90KSAmIHN0YXJ0dGltZTsKCiAgICByZXMgPSB1YXRpbWVfaGRpZmYoc3RhcnQsIHBtKTsKICAgIHJldHVybiByZXM7ICAgICAgICAgICAgICAgICAvKiBhdGltZV9kaWZmIHdvcmtzIGluIG1zZWMsIG5vdCBjc2VjICovCn0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAqIHN0cnVjdCB0aW1ldmFsIGVxdWl2YWxlbnRzIG9mIHRoZXNlIAogICAgICAgICAgICAgICAgICAgICAgICAgKi8KdV9sb25nCm5ldHNubXBfdGltZXZhbF91cHRpbWUoc3RydWN0IHRpbWV2YWwgKiB0dikKewogICAgcmV0dXJuIG5ldHNubXBfbWFya2VyX3VwdGltZSgobWFya2VyX3QpIHR2KTsKfQoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgdmFsdWUgb2YgJ3N5c1VwVGltZScgCiAgICAgICAgICAgICAgICAgKi8KdV9sb25nCm5ldHNubXBfZ2V0X2FnZW50X3VwdGltZSh2b2lkKQp7CiAgICBzdHJ1Y3QgdGltZXZhbCAgbm93OwogICAgZ2V0dGltZW9mZGF5KCZub3csIE5VTEwpOwoKICAgIHJldHVybiBuZXRzbm1wX3RpbWV2YWxfdXB0aW1lKCZub3cpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogZGVwcmVjYXRlZCBmdW5jdGlvbnMKICoKICovCgovKiogc2V0IGVycm9yIGZvciBhIHJlcXVlc3QKICogXGRlcHJlY2F0ZWQsIHVzZSBuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yIGluc3RlYWQKICogQHBhcmFtIHJlcWluZm8gYWdlbnRfcmVxdWVzdF9pbmZvIHBvaW50ZXIgZm9yIHJlcXVlc3QKICogQHBhcmFtIHJlcXVlc3QgcmVxdWVzdF9pbmZvIHBvaW50ZXIKICogQHBhcmFtIGVycm9yX3ZhbHVlIGVycm9yIHZhbHVlIGZvciByZXF1ZXN0cwogKiBAcmV0dXJuIGVycm9yX3ZhbHVlCiAqLwppbnQKbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwgaW50IGVycm9yX3ZhbHVlKQp7CiAgICBpZiAoIXJlcXVlc3QgfHwgIXJlcWluZm8pCiAgICAgICAgcmV0dXJuIGVycm9yX3ZhbHVlOwoKICAgIF9yZXF1ZXN0X3NldF9lcnJvcihyZXF1ZXN0LCByZXFpbmZvLT5tb2RlLCBlcnJvcl92YWx1ZSk7CiAgICAKICAgIHJldHVybiBlcnJvcl92YWx1ZTsKfQoKLyoqIHNldCBlcnJvciBmb3IgYSByZXF1ZXN0CiAqIFxkZXByZWNhdGVkLCB1c2UgbmV0c25tcF9yZXF1ZXN0X3NldF9lcnJvciBpbnN0ZWFkCiAqIEBwYXJhbSBtb2RlIE5ldC1TTk1QIGFnZW50IHByb2Nlc3NpbmcgbW9kZQogKiBAcGFyYW0gcmVxdWVzdCByZXF1ZXN0X2luZm8gcG9pbnRlcgogKiBAcGFyYW0gZXJyb3JfdmFsdWUgZXJyb3IgdmFsdWUgZm9yIHJlcXVlc3RzCiAqIEByZXR1cm4gZXJyb3JfdmFsdWUKICovCmludApuZXRzbm1wX3NldF9tb2RlX3JlcXVlc3RfZXJyb3IoaW50IG1vZGUsIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGVycm9yX3ZhbHVlKQp7CiAgICBfcmVxdWVzdF9zZXRfZXJyb3IocmVxdWVzdCwgbW9kZSwgZXJyb3JfdmFsdWUpOwogICAgCiAgICByZXR1cm4gZXJyb3JfdmFsdWU7Cn0KCi8qKiBzZXQgZXJyb3IgZm9yIGFsbCByZXF1ZXN0CiAqIFxkZXByZWNhdGVkIHVzZSBuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yX2FsbAogKiBAcGFyYW0gcmVxaW5mbyBhZ2VudF9yZXF1ZXN0X2luZm8gcG9pbnRlciBmb3IgcmVxdWVzdHMKICogQHBhcmFtIHJlcXVlc3RzIHJlcXVlc3QgbGlzdAogKiBAcGFyYW0gZXJyb3JfdmFsdWUgZXJyb3IgdmFsdWUgZm9yIHJlcXVlc3RzCiAqIEByZXR1cm4gZXJyb3JfdmFsdWUKICovCmludApuZXRzbm1wX3NldF9hbGxfcmVxdWVzdHNfZXJyb3IobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZXJyb3JfdmFsdWUpCnsKICAgIG5ldHNubXBfcmVxdWVzdF9zZXRfZXJyb3JfYWxsKHJlcXVlc3RzLCBlcnJvcl92YWx1ZSk7CiAgICByZXR1cm4gZXJyb3JfdmFsdWU7Cn0KLyoqIEB9ICovCg==