LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYnVsa190b19uZXh0Lmg+CgoKc3RhdGljIG5ldHNubXBfbWliX2hhbmRsZXIgKl9jbG9uZV9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKml0KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogTmV3IEhhbmRsZXIgYmFzZWQgQVBJIAogKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiogQGRlZmdyb3VwIGhhbmRsZXIgTmV0LVNOTVAgQWdlbnQgaGFuZGxlciBhbmQgZXh0ZW5zaWJpbGl0eSBBUEkKICogIEBpbmdyb3VwIGFnZW50CiAqCiAqICBUaGUgYmFzaWMgdGhlb3J5IGdvZXMgc29tZXRoaW5nIGxpa2UgdGhpczogSW4gdGhlIHBhc3QsIHdpdGggdGhlCiAqICBvcmlnaW5hbCBtaWIgbW9kdWxlIGFwaSAod2hpY2ggZGVyaXZlZCBmcm9tIHRoZSBvcmlnaW5hbCBDTVUgU05NUAogKiAgY29kZSkgdGhlIHVuZGVybHlpbmcgbWliIG1vZHVsZXMgd2VyZSBwYXNzZWQgdmVyeSBsaXR0bGUKICogIGluZm9ybWF0aW9uIChvbmx5IHRoZSB0cnVseSBtb3N0IGJhc2ljIGluZm9ybWF0aW9uIGFib3V0IGEKICogIHJlcXVlc3QpLiAgVGhpcyB3b3JrZWQgd2VsbCBhdCB0aGUgdGltZSBidXQgaW4gdG9kYXlzIHdvcmxkIG9mCiAqICBzdWJhZ2VudHMsIGRldmljZSBpbnN0cnVtZW50YXRpb24sIGxvdyByZXNvdXJjZSBjb25zdW1wdGlvbiwgZXRjLAogKiAgaXQganVzdCBpc24ndCBmbGV4aWJsZSBlbm91Z2guICAiaGFuZGxlcnMiIGFyZSBoZXJlIHRvIGZpeCBhbGwgdGhhdC4KICoKICogIFdpdGggdGhlIHJld3JpdGUgb2YgdGhlIGFnZW50IGludGVybmFscyBmb3IgdGhlIG5ldC1zbm1wIDUuMAogKiAgcmVsZWFzZSwgd2UgaW50cm9kdWNlIGEgbW9kdWxhciBjYWxsaW5nIHNjaGVtZSB0aGF0IGFsbG93cyBhZ2VudAogKiAgbW9kdWxlcyB0byBiZSB3cml0dGVuIGluIGEgdmVyeSBmbGV4aWJsZSBtYW5uZXIsIGFuZCBtb3JlCiAqICBpbXBvcnRhbnRseSBhbGxvd3MgcmV1c2Ugb2YgY29kZSBpbiBhIGRlY2VudCB3YXkgKGFuZCB3aXRob3V0IHRoZQogKiAgbWVtb3J5IGFuZCBzcGVlZCBvdmVyaGVhZHMgb2YgT08gbGFuZ3VhZ2VzIGxpa2UgQysrKS4KICoKICogIEZ1bmN0aW9uYWxseSwgdGhlIG5vdGlvbiBvZiB3aGF0IGEgaGFuZGxlciBkb2VzIGlzIHRoZSBzYW1lIGFzIHRoZQogKiAgb2xkZXIgYXBpOiBBIGhhbmRsZXIgaXMgQGxpbmsgbmV0c25tcF9jcmVhdGVfaGFuZGxlcigpIGNyZWF0ZWRAZW5kbGluayBhbmQKICogIHRoZW4gQGxpbmsgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKCkgcmVnaXN0ZXJlZEBlbmRsaW5rIHdpdGggdGhlIG1haW4KICogIGFnZW50IGF0IGEgZ2l2ZW4gT0lEIGluIHRoZSBPSUQgdHJlZSBhbmQgZ2V0cyBjYWxsZWQgYW55IHRpbWUgYQogKiAgcmVxdWVzdCBpcyBtYWRlIHRoYXQgaXQgc2hvdWxkIHJlc3BvbmQgdG8uICBZb3UgcHJvYmFibHkgc2hvdWxkCiAqICB1c2Ugb25lIG9mIHRoZSBjb252ZW5pZW5jZSBoZWxwZXJzIGluc3RlYWQgb2YgZG9pbmcgYW55dGhpbmcgZWxzZQogKiAgeW91cnNlbGYgdGhvdWdoOgogKgogKiAgTW9zdCBpbXBvcnRhbnRseSwgdGhvdWdoLCBpcyB0aGF0IHRoZSBoYW5kbGVycyBhcmUgYnVpbHQgb24gdGhlCiAqICBub3Rpb24gb2YgbW9kdWxhcml0eSBhbmQgcmV1c2UuICBTcGVjaWZpY2FsbHksIHJhdGhlciB0aGFuIGRvIGFsbAogKiAgdGhlIHJlYWxseSBoYXJkIHdvcmsgKGxpa2UgcGFyc2luZyB0YWJsZSBpbmRleGVzIG91dCBvZiBhbgogKiAgaW5jb21pbmcgb2lkIHJlcXVlc3QpIGluIGVhY2ggbW9kdWxlLCB0aGUgQVBJIGlzIGRlc2lnbmVkIHRvIG1ha2UKICogIGl0IGVhc3kgdG8gd3JpdGUgImhlbHBlciIgaGFuZGxlcnMgdGhhdCBtZXJlbHkgcHJvY2VzcyBzb21lIGFzcGVjdAogKiAgb2YgdGhlIHJlcXVlc3QgYmVmb3JlIHBhc3NpbmcgaXQgYWxvbmcgdG8gdGhlIGZpbmFsIGhhbmRsZXIgdGhhdAogKiAgcmV0dXJucyB0aGUgcmVhbCBhbnN3ZXIuICBNb3N0IHBlb3BsZSB3aWxsIHdhbnQgdG8gbWFrZSB1c2Ugb2YgdGhlCiAqICBAbGluayBpbnN0YW5jZSBpbnN0YW5jZUBlbmRsaW5rLCBAbGluayB0YWJsZSB0YWJsZUBlbmRsaW5rLCBAbGluawogKiAgdGFibGVfaXRlcmF0b3IgdGFibGVfaXRlcmF0b3JAZW5kbGluaywgQGxpbmsgdGFibGVfZGF0YQogKiAgdGFibGVfZGF0YUBlbmRsaW5rLCBvciBAbGluayB0YWJsZV9kYXRhc2V0IHRhYmxlX2RhdGFzZXRAZW5kbGluawogKiAgaGVscGVycyB0byBtYWtlIHRoZWlyIGxpZmUgZWFzaWVyLiAgVGhlc2UgImhlbHBlcnMiIGludGVycGVydAogKiAgaW1wb3J0YW50IGFzcGVjdHMgb2YgdGhlIHJlcXVlc3QgYW5kIHBhc3MgdGhlbSBvbiB0byB5b3UuCiAqCiAqICBGb3IgaW5zdGFuY2UsIHRoZSBAbGluayB0YWJsZSB0YWJsZUBlbmRsaW5rIGhlbHBlciBpcyBkZXNpZ25lZCB0bwogKiAgaGFuZCB5b3UgYSBsaXN0IG9mIGV4dHJhY3RlZCBpbmRleCB2YWx1ZXMgZnJvbSBhbiBpbmNvbWluZwogKiAgcmVxdWVzdC4gIFRIZSBAbGluayB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvckBlbmRsaW5rIGhlbHBlcgogKiAgaXMgYnVpbHQgb24gdG9wIG9mIHRoZSB0YWJsZSBoZWxwZXIsIGFuZCBpcyBkZXNpZ25lZCB0byBoZWxwIHlvdQogKiAgaXRlcmF0ZSB0aHJvdWdoIGRhdGEgc3RvcmVkIGVsc2V3aGVyZSAobGlrZSBpbiBhIGtlcm5lbCkgdGhhdCBpcwogKiAgbm90IGluIE9JRCBsZXhvZ3JhcGhpY2FsIG9yZGVyIChpZSwgZG9uJ3Qgd3JpdGUgeW91ciBvd24gaW5kZXgvb2lkCiAqICBzb3J0aW5nIHJvdXRpbmUsIHVzZSB0aGlzIGhlbHBlciBpbnN0ZWFkKS4gIFRoZSBiZWF1dHkgb2YgdGhlCiAqICBAbGluayB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvciBoZWxwZXJAZW5kbGluaywgYXMgd2VsbCBhcyB0aGUgQGxpbmsKICogIGluc3RhbmNlIGluc3RhbmNlQGVuZGxpbmsgaGVscGVyIGlzIHRoYXQgdGhleSB0YWtlIGNhcmUgb2YgdGhlIGNvbXBsZXgKICogIEdFVE5FWFQgcHJvY2Vzc2luZyBlbnRpcmVseSBmb3IgeW91IGFuZCBoYW5kIHlvdSBldmVyeXRoaW5nIHlvdQogKiAgbmVlZCB0byBtZXJlbHkgcmV0dXJuIHRoZSBkYXRhIGFzIGlmIGl0IHdhcyBhIEdFVCByZXF1ZXN0LiAgTXVjaAogKiAgbGVzcyBjb2RlIGFuZCBoYWlyIHB1bGxpbmcuICBJJ3ZlIHB1bGxlZCBhbGwgbXkgaGFpciBvdXQgdG8gaGVscAogKiAgeW91IHNvIHRoYXQgb25seSBvbmUgb2YgdXMgaGFzIHRvIGJlIGJhbGQuCiAqCiAqIEB7CiAqLwoKLyoqIENyZWF0ZXMgYSBNSUIgaGFuZGxlciBzdHJ1Y3R1cmUuCiAqICBUaGUgbmV3IHN0cnVjdHVyZSBpcyBhbGxvY2F0ZWQgYW5kIGZpbGxlZCB1c2luZyB0aGUgZ2l2ZW4gbmFtZQogKiAgYW5kIGFjY2VzcyBtZXRob2QuCiAqICBUaGUgcmV0dXJuZWQgaGFuZGxlciBzaG91bGQgdGhlbiBiZSBAbGluayBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKQogKiAgcmVnaXN0ZXJlZCBAZW5kbGluay4KICoKICogIEBwYXJhbSBuYW1lIGlzIHRoZSBoYW5kbGVyIG5hbWUgYW5kIGlzIGNvcGllZCB0aGVuIGFzc2lnbmVkIHRvCiAqICAgICAgICAgICAgICBuZXRzbm1wX21pYl9oYW5kbGVyLT5oYW5kbGVyX25hbWUKICoKICogIEBwYXJhbSBoYW5kbGVyX2FjY2Vzc19tZXRob2QgaXMgYSBmdW5jdGlvbiBwb2ludGVyIHVzZWQgYXMgdGhlIGFjY2VzcwogKgkgICBtZXRob2QgZm9yIHRoaXMgaGFuZGxlciByZWdpc3RyYXRpb24gaW5zdGFuY2UgZm9yIHdoYXRldmVyIHJlcXVpcmVkCiAqICAgICAgICAgbmVlZHMuCiAqCiAqICBAcmV0dXJuIGEgcG9pbnRlciB0byBhIHBvcHVsYXRlZCBuZXRzbm1wX21pYl9oYW5kbGVyIHN0cnVjdCB0byBiZQogKiAgICAgICAgICByZWdpc3RlcmVkCiAqCiAqICBAc2VlIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKCkKICogIEBzZWUgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKCkKICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKiBoYW5kbGVyX2FjY2Vzc19tZXRob2QpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKnJldCA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9taWJfaGFuZGxlcik7CiAgICBpZiAocmV0KSB7CiAgICAgICAgcmV0LT5hY2Nlc3NfbWV0aG9kID0gaGFuZGxlcl9hY2Nlc3NfbWV0aG9kOwogICAgICAgIGlmIChOVUxMICE9IG5hbWUpIHsKICAgICAgICAgICAgcmV0LT5oYW5kbGVyX25hbWUgPSBzdHJkdXAobmFtZSk7CiAgICAgICAgICAgIGlmIChOVUxMID09IHJldC0+aGFuZGxlcl9uYW1lKQogICAgICAgICAgICAgICAgU05NUF9GUkVFKHJldCk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHJldDsKfQoKLyoqIENyZWF0ZXMgYSBNSUIgaGFuZGxlciBzdHJ1Y3R1cmUuCiAqICBUaGUgbmV3IHN0cnVjdHVyZSBpcyBhbGxvY2F0ZWQgYW5kIGZpbGxlZCB1c2luZyB0aGUgZ2l2ZW4gbmFtZSwKICogIGFjY2VzcyBmdW5jdGlvbiwgcmVnaXN0cmF0aW9uIGxvY2F0aW9uIE9JRCBhbmQgbGlzdCBvZiBtb2RlcyB0aGF0CiAqICB0aGUgaGFuZGxlciBzdXBwb3J0cy4gSWYgbW9kZXMgPT0gMCwgdGhlbiBtb2RlcyB3aWxsIGF1dG9tYXRpY2FsbHkKICogIGJlIHNldCB0byB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBvbmx5IEhBTkRMRVJfQ0FOX0RFRkFVTFQsIHdoaWNoIGlzCiAqICBieSBkZWZhdWx0IHJlYWQtb25seSBHRVQgYW5kIEdFVE5FWFQgcmVxdWVzdHMuIEEgaGFuZGVyIHdoaWNoIHN1cHBvcnRzCiAqICBzZXRzIGJ1dCBub3Qgcm93IGNyZWF0aW9uIHNob3VsZCBzZXQgdXMgYSBtb2RlIG9mIEhBTkRMRVJfQ0FOX1NFVF9PTkxZLgogKiAgQG5vdGUgVGhpcyBlbmRzIHVwIGNhbGxpbmcgbmV0c25tcF9jcmVhdGVfaGFuZGxlcihuYW1lLCBoYW5kbGVyX2FjY2Vzc19tZXRob2QpCiAqICBAcGFyYW0gbmFtZSBpcyB0aGUgaGFuZGxlciBuYW1lIGFuZCBpcyBjb3BpZWQgdGhlbiBhc3NpZ25lZCB0bwogKiAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbi0+aGFuZGxlck5hbWUuCiAqCiAqICBAcGFyYW0gaGFuZGxlciBpcyBhIGZ1bmN0aW9uIHBvaW50ZXIgdXNlZCBhcyB0aGUgYWNjZXNzCiAqCW1ldGhvZCBmb3IgdGhpcyBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBpbnN0YW5jZSBmb3Igd2hhdGV2ZXIgcmVxdWlyZWQKICoJbmVlZHMuCiAqCiAqICBAcGFyYW0gcmVnX29pZCBpcyB0aGUgcmVnaXN0cmF0aW9uIGxvY2F0aW9uIG9pZC4KICoKICogIEBwYXJhbSByZWdfb2lkX2xlbiBpcyB0aGUgbGVuZ3RoIG9mIHJlZ19vaWQ7IGNhbiB1c2UgdGhlIG1hY3JvLAogKiAgICAgICAgIE9JRF9MRU5HVEgKICoKICogIEBwYXJhbSBtb2RlcyBpcyB1c2VkIHRvIGNvbmZpZ3VyZSByZWFkL3dyaXRlIGFjY2Vzcy4gIElmIG1vZGVzID09IDAsIAogKgl0aGVuIG1vZGVzIHdpbGwgYXV0b21hdGljYWxseSBiZSBzZXQgdG8gdGhlIGRlZmF1bHQgCiAqCXZhbHVlIG9mIG9ubHkgSEFORExFUl9DQU5fREVGQVVMVCwgd2hpY2ggaXMgYnkgZGVmYXVsdCByZWFkLW9ubHkgR0VUIAogKglhbmQgR0VUTkVYVCByZXF1ZXN0cy4gIFRoZSBvdGhlciB0d28gbW9kZSBvcHRpb25zIGFyZSByZWFkIG9ubHksIAogKglIQU5ETEVSX0NBTl9ST05MWSwgYW5kIHJlYWQvd3JpdGUsIEhBTkRMRVJfQ0FOX1JXUklURS4KICoKICoJCS0gSEFORExFUl9DQU5fR0VUQU5ER0VUTkVYVAogKgkJLSBIQU5ETEVSX0NBTl9TRVQKICoJCS0gSEFORExFUl9DQU5fR0VUQlVMSyAgICAgIAogKgogKgkJLSBIQU5ETEVSX0NBTl9ST05MWSAgIChIQU5ETEVSX0NBTl9HRVRBTkRHRVRORVhUKQogKgkJLSBIQU5ETEVSX0NBTl9SV1JJVEUgIChIQU5ETEVSX0NBTl9HRVRBTkRHRVRORVhUIHwgCiAqCQkJSEFORExFUl9DQU5fU0VUKQogKgkJLSBIQU5ETEVSX0NBTl9ERUZBVUxUIEhBTkRMRVJfQ0FOX1JPTkxZCiAqCiAqICBAcmV0dXJuIFJldHVybnMgYSBwb2ludGVyIHRvIGEgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBzdHJ1Y3QuCiAqICAgICAgICAgIE5VTEwgaXMgcmV0dXJuZWQgb25seSB3aGVuIG1lbW9yeSBjb3VsZCBub3QgYmUgYWxsb2NhdGVkIGZvciB0aGUgCiAqICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gc3RydWN0LgogKgogKgogKiAgQHNlZSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKCkKICogIEBzZWUgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKCkKICovCm5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKgpuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2NyZWF0ZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiByZWdfb2lkLCBzaXplX3QgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtb2RlcykKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqdGhlX3JlZzsKICAgIHRoZV9yZWcgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24pOwogICAgaWYgKCF0aGVfcmVnKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmIChtb2RlcykKICAgICAgICB0aGVfcmVnLT5tb2RlcyA9IG1vZGVzOwogICAgZWxzZQogICAgICAgIHRoZV9yZWctPm1vZGVzID0gSEFORExFUl9DQU5fREVGQVVMVDsKCiAgICB0aGVfcmVnLT5oYW5kbGVyID0gaGFuZGxlcjsKICAgIHRoZV9yZWctPnByaW9yaXR5ID0gREVGQVVMVF9NSUJfUFJJT1JJVFk7CiAgICBpZiAobmFtZSkKICAgICAgICB0aGVfcmVnLT5oYW5kbGVyTmFtZSA9IHN0cmR1cChuYW1lKTsKICAgIHRoZV9yZWctPnJvb3RvaWQgPSBzbm1wX2R1cGxpY2F0ZV9vYmppZChyZWdfb2lkLCByZWdfb2lkX2xlbik7CiAgICB0aGVfcmVnLT5yb290b2lkX2xlbiA9IHJlZ19vaWRfbGVuOwogICAgcmV0dXJuIHRoZV9yZWc7Cn0KCi8qKiBDcmVhdGVzIGEgaGFuZGxlciByZWdpc3RyYXRpb24gc3RydWN0dXJlIHdpdGggYSBuZXcgTUlCIGhhbmRsZXIuCiAqICBUaGlzIGZ1bmN0aW9uIGZpcnN0IEBsaW5rIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoKSBjcmVhdGVzIEBlbmRsaW5rCiAqICBhIE1JQiBoYW5kbGVyLCB0aGVuIEBsaW5rIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fY3JlYXRlKCkKICogIG1ha2VzIHJlZ2lzdGF0aW9uIHN0cnVjdHVyZSBAZW5kbGluayBmb3IgaXQuCiAqCiAqICBAcGFyYW0gbmFtZSBpcyB0aGUgaGFuZGxlciBuYW1lIGZvciBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKCkKICoKICogIEBwYXJhbSBoYW5kbGVyX2FjY2Vzc19tZXRob2QgaXMgYSBmdW5jdGlvbiBwb2ludGVyIHVzZWQgYXMgdGhlIGFjY2VzcwogKiAgICAgbWV0aG9kIGZvciBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKCkKICoKICogIEBwYXJhbSByZWdfb2lkIGlzIHRoZSByZWdpc3RyYXRpb24gbG9jYXRpb24gb2lkLgogKgogKiAgQHBhcmFtIHJlZ19vaWRfbGVuIGlzIHRoZSBsZW5ndGggb2YgcmVnX29pZDsgY2FuIHVzZSB0aGUgbWFjcm8sCiAqICAgICAgICAgT0lEX0xFTkdUSAogKgogKiAgQHBhcmFtIG1vZGVzIGlzIHVzZWQgdG8gY29uZmlndXJlIHJlYWQvd3JpdGUgYWNjZXNzLCBhcyBpbgogKiAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fY3JlYXRlKCkKICoKICogIEByZXR1cm4gUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uIHN0cnVjdC4KICogICAgICAgICAgSWYgdGhlIHN0cnVjdHVyZXMgY3JlYXRpb24gZmFpbGVkLCBOVUxMIGlzIHJldHVybmVkLgogKgogKiAgQHNlZSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKCkKICogIEBzZWUgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbl9jcmVhdGUoKQogKi8KbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqCm5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcl9hY2Nlc3NfbWV0aG9kLCBjb25zdCBvaWQgKiByZWdfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgcmVnX29pZF9sZW4sIGludCBtb2RlcykKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcnYgPSBOVUxMOwogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciA9CiAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcihuYW1lLCBoYW5kbGVyX2FjY2Vzc19tZXRob2QpOwogICAgaWYgKGhhbmRsZXIpIHsKICAgICAgICBydiA9IG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fY3JlYXRlKAogICAgICAgICAgICBuYW1lLCBoYW5kbGVyLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgbW9kZXMpOwogICAgICAgIGlmICghcnYpCiAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKGhhbmRsZXIpOwogICAgfQogICAgcmV0dXJuIHJ2Owp9CgovKiogUmVnaXN0ZXJzIGEgTUlCIGhhbmRsZXIgaW5zaWRlIHRoZSByZWdpc3RyYXRpb24gc3RydWN0dXJlLgogKiAgQ2hlY2tzIGdpdmVuIHJlZ2lzdGF0aW9uIGhhbmRsZXIgZm9yIHNhbml0eSwgdGhlbgogKiAgQGxpbmsgbmV0c25tcF9yZWdpc3Rlcl9taWIoKSBwZXJmb3JtcyByZWdpc3RyYXRpb24gQGVuZGxpbmsKICogIGluIHRoZSBNSUIgdHJlZSwgYXMgZGVmaW5lZCBieSB0aGUgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbgogKiAgcG9pbnRlci4gT24gc3VjY2VzcywgU05NUF9DQUxMQkFDS19BUFBMSUNBVElPTiBpcyBjYWxsZWQuCiAqICBUaGUgcmVnaXN0cmF0aW9uIHN0cnVjdCBtYXkgYmUgY3JlYXRlZCBieSBjYWxsIG9mCiAqICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigpLgogKgogKiAgQHBhcmFtIHJlZ2luZm8gUG9pbnRlciB0byBhIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gc3RydWN0LgogKgogKiAgQHJldHVybiBSZXR1cm5zIFNOTVBFUlJfU1VDQ0VTUyBvciBTTk1QX0VSUl8qIGVycm9yIGNvZGUuCiAqCiAqICBAc2VlIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKCkKICogIEBzZWUgbmV0c25tcF9yZWdpc3Rlcl9taWIoKQogKi8KaW50Cm5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyOwogICAgaW50IGZsYWdzID0gMDsKCiAgICBpZiAocmVnaW5mbyA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpIGNhbGxlZCBpbGxlZ2FsbHlcbiIpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlZ2luZm8gIT0gTlVMTCk7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KCiAgICBERUJVR0lGKCJoYW5kbGVyOjpyZWdpc3RlciIpIHsKICAgICAgICBERUJVR01TR1RMKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCAiUmVnaXN0ZXJpbmcgJXMgKCIsIHJlZ2luZm8tPmhhbmRsZXJOYW1lKSk7CiAgICAgICAgZm9yIChoYW5kbGVyID0gcmVnaW5mby0+aGFuZGxlcjsgaGFuZGxlcjsgaGFuZGxlciA9IGhhbmRsZXItPm5leHQpIHsKICAgICAgICAgICAgREVCVUdNU0coKCJoYW5kbGVyOjpyZWdpc3RlciIsICI6OiVzIiwgaGFuZGxlci0+aGFuZGxlcl9uYW1lKSk7CiAgICAgICAgfQoKICAgICAgICBERUJVR01TRygoImhhbmRsZXI6OnJlZ2lzdGVyIiwgIikgYXQgIikpOwogICAgICAgIGlmIChyZWdpbmZvLT5yb290b2lkICYmIHJlZ2luZm8tPnJhbmdlX3N1YmlkKSB7CiAgICAgICAgICAgIERFQlVHTVNHT0lEUkFOR0UoKCJoYW5kbGVyOjpyZWdpc3RlciIsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuLCByZWdpbmZvLT5yYW5nZV9zdWJpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cmFuZ2VfdWJvdW5kKSk7CiAgICAgICAgfSBlbHNlIGlmIChyZWdpbmZvLT5yb290b2lkKSB7CiAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCByZWdpbmZvLT5yb290b2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4pKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBERUJVR01TRygoImhhbmRsZXI6OnJlZ2lzdGVyIiwgIltudWxsXSIpKTsKICAgICAgICB9CiAgICAgICAgREVCVUdNU0coKCJoYW5kbGVyOjpyZWdpc3RlciIsICJcbiIpKTsKICAgIH0KCiAgICAvKgogICAgICogZG9uJ3QgbGV0IHRoZW0gcmVnaXN0ZXIgZm9yIGFic29sdXRlbHkgbm90aGluZy4gIFByb2JhYmx5IGEgbWlzdGFrZSAKICAgICAqLwogICAgaWYgKDAgPT0gcmVnaW5mby0+bW9kZXMpIHsKICAgICAgICByZWdpbmZvLT5tb2RlcyA9IEhBTkRMRVJfQ0FOX0RFRkFVTFQ7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsICJubyByZWdpc3RyYXRpb24gbW9kZXMgc3BlY2lmaWVkIGZvciAlcy4gIgogICAgICAgICAgICAgICAgICJEZWZhdWx0aW5nIHRvIDB4JXhcbiIsIHJlZ2luZm8tPmhhbmRsZXJOYW1lLCByZWdpbmZvLT5tb2Rlcyk7CiAgICB9CgogICAgLyoKICAgICAqIGZvciBoYW5kbGVycyB0aGF0IGNhbid0IEdFVEJVTEssIGZvcmNlIGEgY29udmVyc2lvbiBoYW5kbGVyIG9uIHRoZW0gCiAgICAgKi8KICAgIGlmICghKHJlZ2luZm8tPm1vZGVzICYgSEFORExFUl9DQU5fR0VUQlVMSykpIHsKICAgICAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2dldF9idWxrX3RvX25leHRfaGFuZGxlcigpKTsKICAgIH0KCiAgICBmb3IgKGhhbmRsZXIgPSByZWdpbmZvLT5oYW5kbGVyOyBoYW5kbGVyOyBoYW5kbGVyID0gaGFuZGxlci0+bmV4dCkgewogICAgICAgIGlmIChoYW5kbGVyLT5mbGFncyAmIE1JQl9IQU5ETEVSX0lOU1RBTkNFKQogICAgICAgICAgICBmbGFncyA9IEZVTExZX1FVQUxJRklFRF9JTlNUQU5DRTsKICAgIH0KCiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9taWIocmVnaW5mby0+aGFuZGxlck5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5yb290b2lkLCByZWdpbmZvLT5yb290b2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5wcmlvcml0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5yYW5nZV9zdWJpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5yYW5nZV91Ym91bmQsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+Y29udGV4dE5hbWUsIHJlZ2luZm8tPnRpbWVvdXQsIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8sIDEpOwp9CgovKiogVW5yZWdpc3RlcnMgYSBNSUIgaGFuZGxlciBkZXNjcmliZWQgaW5zaWRlIHRoZSByZWdpc3RyYXRpb24gc3RydWN0dXJlLgogKiAgUmVtb3ZlcyBhIHJlZ2lzdHJhdGlvbiwgcGVyZm9ybWVkIGVhcmxpZXIgYnkKICogIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpLCBmcm9tIHRoZSBNSUIgdHJlZS4KICogIFVzZXMgdW5yZWdpc3Rlcl9taWJfY29udGV4dCgpIHRvIGRvIHRoZSB0YXNrLgogKgogKiAgQHBhcmFtIHJlZ2luZm8gUG9pbnRlciB0byBhIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gc3RydWN0LgogKgogKiAgQHJldHVybiBSZXR1cm5zIFNOTVBFUlJfU1VDQ0VTUyBvciBTTk1QX0VSUl8qIGVycm9yIGNvZGUuCiAqCiAqICBAc2VlIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpCiAqICBAc2VlIHVucmVnaXN0ZXJfbWliX2NvbnRleHQoKQogKi8KaW50Cm5ldHNubXBfdW5yZWdpc3Rlcl9oYW5kbGVyKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8pCnsKICAgIHJldHVybiB1bnJlZ2lzdGVyX21pYl9jb250ZXh0KHJlZ2luZm8tPnJvb3RvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cHJpb3JpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5yYW5nZV9zdWJpZCwgcmVnaW5mby0+cmFuZ2VfdWJvdW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+Y29udGV4dE5hbWUpOwp9CgovKiogUmVnaXN0ZXJzIGEgTUlCIGhhbmRsZXIgaW5zaWRlIHRoZSByZWdpc3RyYXRpb24gc3RydWN0dXJlLgogKiAgQ2hlY2tzIGdpdmVuIHJlZ2lzdGF0aW9uIGhhbmRsZXIgZm9yIHNhbml0eSwgdGhlbgogKiAgQGxpbmsgbmV0c25tcF9yZWdpc3Rlcl9taWIoKSBwZXJmb3JtcyByZWdpc3RyYXRpb24gQGVuZGxpbmsKICogIGluIHRoZSBNSUIgdHJlZSwgYXMgZGVmaW5lZCBieSB0aGUgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbgogKiAgcG9pbnRlci4gTmV2ZXIgY2FsbHMgU05NUF9DQUxMQkFDS19BUFBMSUNBVElPTi4KICogIFRoZSByZWdpc3RyYXRpb24gc3RydWN0IG1heSBiZSBjcmVhdGVkIGJ5IGNhbGwgb2YKICogIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKCkuCiAqCiAqICBAcGFyYW0gcmVnaW5mbyBQb2ludGVyIHRvIGEgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBzdHJ1Y3QuCiAqCiAqICBAcmV0dXJuIFJldHVybnMgU05NUEVSUl9TVUNDRVNTIG9yIFNOTVBfRVJSXyogZXJyb3IgY29kZS4KICoKICogIEBzZWUgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oKQogKiAgQHNlZSBuZXRzbm1wX3JlZ2lzdGVyX21pYigpCiAqLwppbnQKbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyX25vY2FsbGJhY2sobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlcjsKICAgIGlmIChyZWdpbmZvID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyX25vY2FsbGJhY2soKSBjYWxsZWQgaWxsZWdhbGx5XG4iKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CiAgICBERUJVR0lGKCJoYW5kbGVyOjpyZWdpc3RlciIpIHsKICAgICAgICBERUJVR01TR1RMKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICJSZWdpc3RlcmluZyAod2l0aCBubyBjYWxsYmFjaykgIikpOwogICAgICAgIGZvciAoaGFuZGxlciA9IHJlZ2luZm8tPmhhbmRsZXI7IGhhbmRsZXI7IGhhbmRsZXIgPSBoYW5kbGVyLT5uZXh0KSB7CiAgICAgICAgICAgIERFQlVHTVNHKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCAiOjolcyIsIGhhbmRsZXItPmhhbmRsZXJfbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgREVCVUdNU0coKCJoYW5kbGVyOjpyZWdpc3RlciIsICIgYXQgIikpOwogICAgICAgIGlmIChyZWdpbmZvLT5yb290b2lkICYmIHJlZ2luZm8tPnJhbmdlX3N1YmlkKSB7CiAgICAgICAgICAgIERFQlVHTVNHT0lEUkFOR0UoKCJoYW5kbGVyOjpyZWdpc3RlciIsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuLCByZWdpbmZvLT5yYW5nZV9zdWJpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cmFuZ2VfdWJvdW5kKSk7CiAgICAgICAgfSBlbHNlIGlmIChyZWdpbmZvLT5yb290b2lkKSB7CiAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCByZWdpbmZvLT5yb290b2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4pKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBERUJVR01TRygoImhhbmRsZXI6OnJlZ2lzdGVyIiwgIltudWxsXSIpKTsKICAgICAgICB9CiAgICAgICAgREVCVUdNU0coKCJoYW5kbGVyOjpyZWdpc3RlciIsICJcbiIpKTsKICAgIH0KCiAgICAvKgogICAgICogZG9uJ3QgbGV0IHRoZW0gcmVnaXN0ZXIgZm9yIGFic29sdXRlbHkgbm90aGluZy4gIFByb2JhYmx5IGEgbWlzdGFrZSAKICAgICAqLwogICAgaWYgKDAgPT0gcmVnaW5mby0+bW9kZXMpIHsKICAgICAgICByZWdpbmZvLT5tb2RlcyA9IEhBTkRMRVJfQ0FOX0RFRkFVTFQ7CiAgICB9CgogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfbWliKHJlZ2luZm8tPmhhbmRsZXItPmhhbmRsZXJfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnByaW9yaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJhbmdlX3N1YmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJhbmdlX3Vib3VuZCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5jb250ZXh0TmFtZSwgcmVnaW5mby0+dGltZW91dCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLCAwKTsKfQoKLyoqIEluamVjdHMgaGFuZGxlciBpbnRvIHRoZSBjYWxsaW5nIGNoYWluIG9mIGhhbmRsZXJzLgogKiAgVGhlIGdpdmVuIE1JQiBoYW5kbGVyIGlzIGluc2VydGVkIGFmdGVyIHRoZSBoYW5kbGVyIG5hbWVkIGJlZm9yZV93aGF0LgogKiAgSWYgYmVmb3JlX3doYXQgaXMgTlVMTCwgdGhlIGhhbmRsZXIgaXMgcHV0IGF0IHRoZSB0b3Agb2YgdGhlIGxpc3QsCiAqICBhbmQgaGVuY2Ugd2lsbCBiZSB0aGUgaGFuZGxlciB0byBiZSBjYWxsZWQgZmlyc3QuCiAqCiAqICBAcmV0dXJuIFJldHVybnMgU05NUEVSUl9TVUNDRVNTIG9yIFNOTVBfRVJSXyogZXJyb3IgY29kZS4KICoKICogIEBzZWUgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oKQogKiAgQHNlZSBuZXRzbm1wX2luamVjdF9oYW5kbGVyKCkKICovCmludApuZXRzbm1wX2luamVjdF9oYW5kbGVyX2JlZm9yZShuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpiZWZvcmVfd2hhdCkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlcjIgPSBoYW5kbGVyOwoKICAgIGlmIChoYW5kbGVyID09IE5VTEwgfHwgcmVnaW5mbyA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5ldHNubXBfaW5qZWN0X2hhbmRsZXIoKSBjYWxsZWQgaWxsZWdhbGx5XG4iKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KGhhbmRsZXIgIT0gTlVMTCk7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KICAgIHdoaWxlIChoYW5kbGVyMi0+bmV4dCkgewogICAgICAgIGhhbmRsZXIyID0gaGFuZGxlcjItPm5leHQ7ICAvKiBGaW5kIHRoZSBlbmQgb2YgYSBoYW5kbGVyIHN1Yi1jaGFpbiAqLwogICAgfQogICAgaWYgKHJlZ2luZm8tPmhhbmRsZXIgPT0gTlVMTCkgewogICAgICAgIERFQlVHTVNHVEwoKCJoYW5kbGVyOmluamVjdCIsICJpbmplY3RpbmcgJXNcbiIsIGhhbmRsZXItPmhhbmRsZXJfbmFtZSkpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgREVCVUdNU0dUTCgoImhhbmRsZXI6aW5qZWN0IiwgImluamVjdGluZyAlcyBiZWZvcmUgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+aGFuZGxlcl9uYW1lLCByZWdpbmZvLT5oYW5kbGVyLT5oYW5kbGVyX25hbWUpKTsKICAgIH0KICAgIGlmIChiZWZvcmVfd2hhdCkgewogICAgICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKm5leHRoLCAqcHJldmggPSBOVUxMOwogICAgICAgIGlmIChyZWdpbmZvLT5oYW5kbGVyID09IE5VTEwpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5vIGhhbmRsZXIgdG8gaW5qZWN0IGJlZm9yZVxuIik7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgfQogICAgICAgIGZvcihuZXh0aCA9IHJlZ2luZm8tPmhhbmRsZXI7IG5leHRoOwogICAgICAgICAgICBwcmV2aCA9IG5leHRoLCBuZXh0aCA9IG5leHRoLT5uZXh0KSB7CiAgICAgICAgICAgIGlmIChzdHJjbXAobmV4dGgtPmhhbmRsZXJfbmFtZSwgYmVmb3JlX3doYXQpID09IDApCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKCFuZXh0aCkKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICBpZiAocHJldmgpIHsKICAgICAgICAgICAgLyogYWZ0ZXIgcHJldmggYW5kIGJlZm9yZSBuZXh0aCAqLwogICAgICAgICAgICBwcmV2aC0+bmV4dCA9IGhhbmRsZXI7CiAgICAgICAgICAgIGhhbmRsZXIyLT5uZXh0ID0gbmV4dGg7CiAgICAgICAgICAgIGhhbmRsZXItPnByZXYgPSBwcmV2aDsKICAgICAgICAgICAgbmV4dGgtPnByZXYgPSBoYW5kbGVyMjsKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKICAgICAgICB9CiAgICAgICAgLyogZWxzZSB3ZSdyZSBmaXJzdCwgd2hpY2ggaXMgd2hhdCB3ZSBkbyBuZXh0IGFueXdheSBzbyBmYWxsIHRocm91Z2ggKi8KICAgIH0KICAgIGhhbmRsZXIyLT5uZXh0ID0gcmVnaW5mby0+aGFuZGxlcjsKICAgIGlmIChyZWdpbmZvLT5oYW5kbGVyKQogICAgICAgIHJlZ2luZm8tPmhhbmRsZXItPnByZXYgPSBoYW5kbGVyMjsKICAgIHJlZ2luZm8tPmhhbmRsZXIgPSBoYW5kbGVyOwogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKLyoqIEluamVjdHMgaGFuZGxlciBpbnRvIHRoZSBjYWxsaW5nIGNoYWluIG9mIGhhbmRsZXJzLgogKiAgVGhlIGdpdmVuIE1JQiBoYW5kbGVyIGlzIHB1dCBhdCB0aGUgdG9wIG9mIHRoZSBsaXN0LAogKiAgYW5kIGhlbmNlIHdpbGwgYmUgdGhlIGhhbmRsZXIgdG8gYmUgY2FsbGVkIGZpcnN0LgogKgogKiAgQHJldHVybiBSZXR1cm5zIFNOTVBFUlJfU1VDQ0VTUyBvciBTTk1QX0VSUl8qIGVycm9yIGNvZGUuCiAqCiAqICBAc2VlIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKCkKICogIEBzZWUgbmV0c25tcF9pbmplY3RfaGFuZGxlcl9iZWZvcmUoKQogKi8KaW50Cm5ldHNubXBfaW5qZWN0X2hhbmRsZXIobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyKQp7CiAgICByZXR1cm4gbmV0c25tcF9pbmplY3RfaGFuZGxlcl9iZWZvcmUocmVnaW5mbywgaGFuZGxlciwgTlVMTCk7Cn0KCi8qKiBDYWxscyBhIE1JQiBoYW5kbGVycyBjaGFpbiwgc3RhcnRpbmcgd2l0aCBzcGVjaWZpYyBoYW5kbGVyLgogKiAgVGhlIGdpdmVuIGFyZ3VtZW50cyBhbmQgTUlCIGhhbmRsZXIgYXJlIGNoZWNrZWQKICogIGZvciBzYW5pdHksIHRoZW4gdGhlIGhhbmRsZXJzIGFyZSBjYWxsZWQsIG9uZSBieSBvbmUsCiAqICB1bnRpbCBuZXh0IGhhbmRsZXIgaXMgTlVMTC4KICoKICogIEByZXR1cm4gUmV0dXJucyBTTk1QRVJSX1NVQ0NFU1Mgb3IgU05NUF9FUlJfKiBlcnJvciBjb2RlLgogKi8KTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfY2FsbF9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKm5leHRfaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKm5oOwogICAgaW50ICAgICAgICAgICAgIHJldDsKCiAgICBpZiAobmV4dF9oYW5kbGVyID09IE5VTEwgfHwgcmVnaW5mbyA9PSBOVUxMIHx8IHJlcWluZm8gPT0gTlVMTCB8fAogICAgICAgIHJlcXVlc3RzID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9jYWxsX2hhbmRsZXIoKSBjYWxsZWQgaWxsZWdhbGx5XG4iKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChuZXh0X2hhbmRsZXIgIT0gTlVMTCk7CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVxaW5mbyAhPSBOVUxMKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3RzICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgZG8gewogICAgICAgIG5oID0gbmV4dF9oYW5kbGVyLT5hY2Nlc3NfbWV0aG9kOwogICAgICAgIGlmICghbmgpIHsKICAgICAgICAgICAgaWYgKG5leHRfaGFuZGxlci0+bmV4dCkgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5vIGFjY2VzcyBtZXRob2Qgc3BlY2lmaWVkIGluIGhhbmRsZXIgJXMuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRfaGFuZGxlci0+aGFuZGxlcl9uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhlIGZpbmFsIGhhbmRsZXIgcmVnaXN0cmF0aW9uIGluIHRoZSBjaGFpbiBtYXkgd2VsbCBub3QgbmVlZAogICAgICAgICAgICAgKiB0byBpbmNsdWRlIGEgaGFuZGxlciByb3V0aW5lLCBpZiB0aGUgcHJvY2Vzc2luZyBvZiB0aGlzIG9iamVjdAogICAgICAgICAgICAgKiBpcyBoYW5kbGVkIGNvbXBsZXRlbHkgYnkgdGhlIGFnZW50IHRvb2xraXQgaGVscGVycy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgREVCVUdNU0dUTCgoImhhbmRsZXI6Y2FsbGluZyIsICJjYWxsaW5nIGhhbmRsZXIgJXMgZm9yIG1vZGUgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgbmV4dF9oYW5kbGVyLT5oYW5kbGVyX25hbWUsCiAgICAgICAgICAgICAgICAgICAgc2VfZmluZF9sYWJlbF9pbl9zbGlzdCgiYWdlbnRfbW9kZSIsIHJlcWluZm8tPm1vZGUpKSk7CgogICAgICAgIC8qCiAgICAgICAgICogWFhYOiBkZWZpbmUgYWNjZXB0YWJsZSByZXR1cm4gc3RhdHVzZXMKICAgICAgICAgKi8KICAgICAgICByZXQgPSAoKm5oKSAobmV4dF9oYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLCByZXF1ZXN0cyk7CgogICAgICAgIERFQlVHTVNHVEwoKCJoYW5kbGVyOnJldHVybmVkIiwgImhhbmRsZXIgJXMgcmV0dXJuZWQgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgbmV4dF9oYW5kbGVyLT5oYW5kbGVyX25hbWUsIHJldCkpOwoKICAgICAgICBpZiAoISAobmV4dF9oYW5kbGVyLT5mbGFncyAmIE1JQl9IQU5ETEVSX0FVVE9fTkVYVCkpCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvKgogICAgICAgICAqIGRpZCBoYW5kbGVyIHNpZ25hbCB0aGF0IGl0IGRpZG4ndCB3YW50IGF1dG8gbmV4dCB0aGlzIHRpbWUgYXJvdW5kPwogICAgICAgICAqLwogICAgICAgIGlmKG5leHRfaGFuZGxlci0+ZmxhZ3MgJiBNSUJfSEFORExFUl9BVVRPX05FWFRfT1ZFUlJJREVfT05DRSkgewogICAgICAgICAgICBuZXh0X2hhbmRsZXItPmZsYWdzICY9IH5NSUJfSEFORExFUl9BVVRPX05FWFRfT1ZFUlJJREVfT05DRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBuZXh0X2hhbmRsZXIgPSBuZXh0X2hhbmRsZXItPm5leHQ7CgogICAgfSB3aGlsZShuZXh0X2hhbmRsZXIpOwoKICAgIHJldHVybiByZXQ7Cn0KCi8qKiBAcHJpdmF0ZQogKiAgQ2FsbHMgYWxsIHRoZSBNSUIgSGFuZGxlcnMgaW4gcmVnaXN0cmF0aW9uIHN0cnVjdCBmb3IgYSBnaXZlbiBtb2RlLgogKgogKiAgQHJldHVybiBSZXR1cm5zIFNOTVBFUlJfU1VDQ0VTUyBvciBTTk1QX0VSUl8qIGVycm9yIGNvZGUuCiAqLwppbnQKbmV0c25tcF9jYWxsX2hhbmRsZXJzKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzOwoKICAgIGlmIChyZWdpbmZvID09IE5VTEwgfHwgcmVxaW5mbyA9PSBOVUxMIHx8IHJlcXVlc3RzID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9jYWxsX2hhbmRsZXJzKCkgY2FsbGVkIGlsbGVnYWxseVxuIik7CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVxaW5mbyAhPSBOVUxMKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3RzICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgaWYgKHJlZ2luZm8tPmhhbmRsZXIgPT0gTlVMTCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJubyBoYW5kbGVyIHNwZWNpZmllZC4iKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQoKICAgIHN3aXRjaCAocmVxaW5mby0+bW9kZSkgewogICAgY2FzZSBNT0RFX0dFVEJVTEs6CiAgICBjYXNlIE1PREVfR0VUOgogICAgY2FzZSBNT0RFX0dFVE5FWFQ6CiAgICAgICAgaWYgKCEocmVnaW5mby0+bW9kZXMgJiBIQU5ETEVSX0NBTl9HRVRBTkRHRVRORVhUKSkKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7ICAgIC8qIGxlZ2FsICovCiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgIGNhc2UgTU9ERV9TRVRfQ09NTUlUOgogICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgIGlmICghKHJlZ2luZm8tPm1vZGVzICYgSEFORExFUl9DQU5fU0VUKSkgewogICAgICAgICAgICBmb3IgKDsgcmVxdWVzdHM7IHJlcXVlc3RzID0gcmVxdWVzdHMtPm5leHQpIHsKICAgICAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX05PVFdSSVRBQkxFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAidW5rbm93biBtb2RlIGluIG5ldHNubXBfY2FsbF9oYW5kbGVycyEgYnVnIVxuIik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KICAgIERFQlVHTVNHVEwoKCJoYW5kbGVyOmNhbGxpbmciLCAibWFpbiBoYW5kbGVyICVzXG4iLAogICAgICAgICAgICAgICAgcmVnaW5mby0+aGFuZGxlci0+aGFuZGxlcl9uYW1lKSk7CgogICAgZm9yIChyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgIHJlcXVlc3QtPnByb2Nlc3NlZCA9IDA7CiAgICB9CgogICAgc3RhdHVzID0gbmV0c25tcF9jYWxsX2hhbmRsZXIocmVnaW5mby0+aGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qKiBAcHJpdmF0ZQogKiAgQ2FsbHMgdGhlIG5leHQgTUlCIGhhbmRsZXIgaW4gdGhlIGNoYWluLCBhZnRlciB0aGUgY3VycmVudCBvbmUuCiAqICBUaGUgZ2l2ZW4gYXJndW1lbnRzIGFuZCBNSUIgaGFuZGxlciBhcmUgY2hlY2tlZAogKiAgZm9yIHNhbml0eSwgdGhlbiB0aGUgbmV4dCBoYW5kbGVyIGlzIGNhbGxlZC4KICoKICogIEByZXR1cm4gUmV0dXJucyBTTk1QRVJSX1NVQ0NFU1Mgb3IgU05NUF9FUlJfKiBlcnJvciBjb2RlLgogKi8KTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqY3VycmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIGlmIChjdXJyZW50ID09IE5VTEwgfHwgcmVnaW5mbyA9PSBOVUxMIHx8IHJlcWluZm8gPT0gTlVMTCB8fAogICAgICAgIHJlcXVlc3RzID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9jYWxsX25leHRfaGFuZGxlcigpIGNhbGxlZCBpbGxlZ2FsbHlcbiIpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KGN1cnJlbnQgIT0gTlVMTCk7CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVnaW5mbyAhPSBOVUxMKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZXFpbmZvICE9IE5VTEwpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3RzICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgcmV0dXJuIG5ldHNubXBfY2FsbF9oYW5kbGVyKGN1cnJlbnQtPm5leHQsIHJlZ2luZm8sIHJlcWluZm8sIHJlcXVlc3RzKTsKfQoKLyoqIEBwcml2YXRlCiAqICBDYWxscyB0aGUgbmV4dCBNSUIgaGFuZGxlciBpbiB0aGUgY2hhaW4sIGFmdGVyIHRoZSBjdXJyZW50IG9uZS4KICogIFRoZSBnaXZlbiBhcmd1bWVudHMgYW5kIE1JQiBoYW5kbGVyIGFyZSBub3QgdmFsaWRhdGVkIGJlZm9yZQogKiAgdGhlIGNhbGwsIG9ubHkgcmVxdWVzdCBpcyBjaGVja2VkLgogKgogKiAgQHJldHVybiBSZXR1cm5zIFNOTVBFUlJfU1VDQ0VTUyBvciBTTk1QX0VSUl8qIGVycm9yIGNvZGUuCiAqLwpORVRTTk1QX0lOTElORSBpbnQKbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcl9vbmVfcmVxdWVzdChuZXRzbm1wX21pYl9oYW5kbGVyICpjdXJyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKICAgIGludCByZXQ7CiAgICAKICAgIGlmICghcmVxdWVzdHMpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9jYWxsX25leHRfaGFuZGxlcl9PTkVfUkVRVUVTVCgpIGNhbGxlZCBpbGxlZ2FsbHlcbiIpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3RzICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgcmVxdWVzdCA9IHJlcXVlc3RzLT5uZXh0OwogICAgcmVxdWVzdHMtPm5leHQgPSBOVUxMOwogICAgcmV0ID0gbmV0c25tcF9jYWxsX2hhbmRsZXIoY3VycmVudC0+bmV4dCwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwogICAgcmVxdWVzdHMtPm5leHQgPSByZXF1ZXN0OwogICAgcmV0dXJuIHJldDsKfQoKLyoqIERlYWxsb2NhdGVzIHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiBoYW5kbGVyLgogKiAgVGhlIGhhbmRsZXIgaXMgcmVtb3ZlZCBmcm9tIGNoYWluIGFuZCB0aGVuIGZyZWVkLgogKiAgQWZ0ZXIgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLCB0aGUgaGFuZGxlciBwb2ludGVyIGlzIGludmFsaWQKICogIGFuZCBzaG91bGQgYmUgc2V0IHRvIE5VTEwuCiAqCiAqICBAcGFyYW0gaGFuZGxlciBpcyB0aGUgTUlCIEhhbmRsZXIgdG8gYmUgZnJlZWQKICovCnZvaWQKbmV0c25tcF9oYW5kbGVyX2ZyZWUobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlcikKewogICAgaWYgKGhhbmRsZXIgIT0gTlVMTCkgewogICAgICAgIGlmIChoYW5kbGVyLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgLyoqIG1ha2Ugc3VyZSB3ZSBhcmVuJ3QgcG9pbnRpbmcgdG8gb3Vyc2VsdmVzLiAgKi8KICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQoaGFuZGxlciAhPSBoYW5kbGVyLT5uZXh0KTsgLyogYnVncyBjYXVnaHQ6IDEgKi8KICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX2ZyZWUoaGFuZGxlci0+bmV4dCk7CiAgICAgICAgICAgIGhhbmRsZXItPm5leHQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBpZiAoKGhhbmRsZXItPm15dm9pZCAhPSBOVUxMKSAmJiAoaGFuZGxlci0+ZGF0YV9mcmVlICE9IE5VTEwpKQogICAgICAgIHsKICAgICAgICAgICAgaGFuZGxlci0+ZGF0YV9mcmVlKGhhbmRsZXItPm15dm9pZCk7CiAgICAgICAgfQogICAgICAgIFNOTVBfRlJFRShoYW5kbGVyLT5oYW5kbGVyX25hbWUpOwogICAgICAgIFNOTVBfRlJFRShoYW5kbGVyKTsKICAgIH0KfQoKLyoqIER1cGxpY2F0ZXMgYSBNSUIgaGFuZGxlciBhbmQgYWxsIHN1YnNlcXVlbnQgaGFuZGxlcnMuCiAqICBDcmVhdGVzIGEgY29weSBvZiBhbGwgZGF0YSBpbiBnaXZlbiBoYW5kbGVycyBjaGFpbi4KICoKICogIEBwYXJhbSBoYW5kbGVyIGlzIHRoZSBNSUIgSGFuZGxlciB0byBiZSBkdXBsaWNhdGVkCiAqCiAqICBAcmV0dXJuIFJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBjb21wbGV0ZSBjb3B5LAogKiAgICAgICAgIG9yIE5VTEwgaWYgYW55IHByb2JsZW0gb2NjdXJlZC4KICoKICogQHNlZSBfY2xvbmVfaGFuZGxlcigpCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9oYW5kbGVyX2R1cChuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoID0gTlVMTDsKCiAgICBpZiAoaGFuZGxlciA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaCA9IF9jbG9uZV9oYW5kbGVyKGhhbmRsZXIpOwoKICAgIGlmIChoICE9IE5VTEwpIHsKICAgICAgICBoLT5teXZvaWQgPSBoYW5kbGVyLT5teXZvaWQ7CiAgICAgICAgaC0+ZGF0YV9mcmVlID0gaGFuZGxlci0+ZGF0YV9mcmVlOwoKICAgICAgICBpZiAoaGFuZGxlci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgIGgtPm5leHQgPSBuZXRzbm1wX2hhbmRsZXJfZHVwKGhhbmRsZXItPm5leHQpOwogICAgICAgICAgICBpZiAoaC0+bmV4dCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfZnJlZShoKTsKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGgtPm5leHQtPnByZXYgPSBoOwogICAgICAgIH0KICAgICAgICBoLT5wcmV2ID0gTlVMTDsKICAgICAgICByZXR1cm4gaDsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKiogRnJlZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIGEgaGFuZGxlciByZWdpc3RyYXRpb24gb2JqZWN0LgogKiAgVGhlIHJlZ2lzdHJhdGlvbiBvYmplY3QgYW5kIGFsbCBNSUIgSGFuZGxlcnMgaW4gdGhlIGNoYWluIGFyZQogKiAgZnJlZWQuIFdoZW4gdGhlIGZ1bmN0aW9uIGVuZHMsIGdpdmVuIHBvaW50ZXIgaXMgbm8gbG9uZ2VyIHZhbGlkCiAqICBhbmQgc2hvdWxkIGJlIHNldCB0byBOVUxMLgogKgogKiAgQHBhcmFtIHJlZ2luZm8gaXMgdGhlIGhhbmRsZXIgcmVnaXN0cmF0aW9uIG9iamVjdCB0byBiZSBmcmVlZAogKi8Kdm9pZApuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgaWYgKHJlZ2luZm8gIT0gTlVMTCkgewogICAgICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKHJlZ2luZm8tPmhhbmRsZXIpOwogICAgICAgIFNOTVBfRlJFRShyZWdpbmZvLT5oYW5kbGVyTmFtZSk7CiAgICAgICAgU05NUF9GUkVFKHJlZ2luZm8tPmNvbnRleHROYW1lKTsKICAgICAgICBTTk1QX0ZSRUUocmVnaW5mby0+cm9vdG9pZCk7CiAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4gPSAwOwogICAgICAgIFNOTVBfRlJFRShyZWdpbmZvKTsKICAgIH0KfQoKLyoqIER1cGxpY2F0ZXMgaGFuZGxlciByZWdpc3RyYXRpb24gb2JqZWN0IGFuZCBhbGwgc3Vic2VxdWVudCBoYW5kbGVycy4KICogIENyZWF0ZXMgYSBjb3B5IG9mIHRoZSBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBvYmplY3QgYW5kIGFsbCBpdHMgZGF0YS4KICoKICogIEBwYXJhbSByZWdpbmZvIGlzIHRoZSBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBvYmplY3QgdG8gYmUgZHVwbGljYXRlZAogKgogKiAgQHJldHVybiBSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgY29tcGxldGUgY29weSwKICogICAgICAgICBvciBOVUxMIGlmIGFueSBwcm9ibGVtIG9jY3VyZWQuCiAqCiAqIEBzZWUgbmV0c25tcF9oYW5kbGVyX2R1cCgpCiAqLwpuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICoKbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbl9kdXAobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqciA9IE5VTEw7CgogICAgaWYgKHJlZ2luZm8gPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKCiAgICByID0gKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKikgY2FsbG9jKDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbikpOwoKICAgIGlmIChyICE9IE5VTEwpIHsKICAgICAgICByLT5tb2RlcyA9IHJlZ2luZm8tPm1vZGVzOwogICAgICAgIHItPnByaW9yaXR5ID0gcmVnaW5mby0+cHJpb3JpdHk7CiAgICAgICAgci0+cmFuZ2Vfc3ViaWQgPSByZWdpbmZvLT5yYW5nZV9zdWJpZDsKICAgICAgICByLT50aW1lb3V0ID0gcmVnaW5mby0+dGltZW91dDsKICAgICAgICByLT5yYW5nZV91Ym91bmQgPSByZWdpbmZvLT5yYW5nZV91Ym91bmQ7CiAgICAgICAgci0+cm9vdG9pZF9sZW4gPSByZWdpbmZvLT5yb290b2lkX2xlbjsKCiAgICAgICAgaWYgKHJlZ2luZm8tPmhhbmRsZXJOYW1lICE9IE5VTEwpIHsKICAgICAgICAgICAgci0+aGFuZGxlck5hbWUgPSBzdHJkdXAocmVnaW5mby0+aGFuZGxlck5hbWUpOwogICAgICAgICAgICBpZiAoci0+aGFuZGxlck5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbl9mcmVlKHIpOwogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChyZWdpbmZvLT5jb250ZXh0TmFtZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHItPmNvbnRleHROYW1lID0gc3RyZHVwKHJlZ2luZm8tPmNvbnRleHROYW1lKTsKICAgICAgICAgICAgaWYgKHItPmNvbnRleHROYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fZnJlZShyKTsKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAocmVnaW5mby0+cm9vdG9pZCAhPSBOVUxMKSB7CiAgICAgICAgICAgIHItPnJvb3RvaWQgPQogICAgICAgICAgICAgICAgc25tcF9kdXBsaWNhdGVfb2JqaWQocmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4pOwogICAgICAgICAgICBpZiAoci0+cm9vdG9pZCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUocik7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgci0+aGFuZGxlciA9IG5ldHNubXBfaGFuZGxlcl9kdXAocmVnaW5mby0+aGFuZGxlcik7CiAgICAgICAgaWYgKHItPmhhbmRsZXIgPT0gTlVMTCkgewogICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUocik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQoKLyoqIENyZWF0ZXMgYSBjYWNoZSBvZiBpbmZvcm1hdGlvbiB3aGljaCBjYW4gYmUgc2F2ZWQgZm9yIGZ1dHVyZSByZWZlcmVuY2UuCiAqICBUaGUgY2FjaGUgaXMgZmlsbGVkIHdpdGggcG9pbnRlcnMgZnJvbSBwYXJhbWV0ZXJzLiBOb3RlIHRoYXQKICogIHRoZSBpbnB1dCBzdHJ1Y3R1cmVzIGFyZSBub3QgZHVwbGljYXRlZCwgYnV0IHB1dCBkaXJlY3RseSBpbnRvCiAqICB0aGUgbmV3IGNhY2hlIHN0cnVjdC4KICogIFVzZSBuZXRzbm1wX2hhbmRsZXJfY2hlY2tfY2FjaGUoKSBsYXRlciB0byBtYWtlIHN1cmUgaXQncyBzdGlsbAogKiAgdmFsaWQgYmVmb3JlIHJlZmVyZW5jaW5nIGl0IGluIHRoZSBmdXR1cmUuCiAqCiAqIEBzZWUgbmV0c25tcF9oYW5kbGVyX2NoZWNrX2NhY2hlKCkKICogQHNlZSBuZXRzbm1wX2ZyZWVfZGVsZWdhdGVkX2NhY2hlKCkKICovCk5FVFNOTVBfSU5MSU5FIG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICoKbmV0c25tcF9jcmVhdGVfZGVsZWdhdGVkX2NhY2hlKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpsb2NhbGluZm8pCnsKICAgIG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICpyZXQ7CgogICAgcmV0ID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSk7CiAgICBpZiAocmV0KSB7CiAgICAgICAgcmV0LT50cmFuc2FjdGlvbl9pZCA9IHJlcWluZm8tPmFzcC0+cGR1LT50cmFuc2lkOwogICAgICAgIHJldC0+aGFuZGxlciA9IGhhbmRsZXI7CiAgICAgICAgcmV0LT5yZWdpbmZvID0gcmVnaW5mbzsKICAgICAgICByZXQtPnJlcWluZm8gPSByZXFpbmZvOwogICAgICAgIHJldC0+cmVxdWVzdHMgPSByZXF1ZXN0czsKICAgICAgICByZXQtPmxvY2FsaW5mbyA9IGxvY2FsaW5mbzsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKiBDaGVjayBpZiBhIGdpdmVuIGRlbGVnYXRlZCBjYWNoZSBpcyBzdGlsbCB2YWxpZC4KICogIFRoZSBjYWNoZSBpcyB2YWxpZCBpZiBpdCdzIGEgcGFydCBvZiB0cmFuc2FjdGlvbgogKiAgKGllLCB0aGUgYWdlbnQgc3RpbGwgY29uc2lkZXJzIGl0IHRvIGJlIGFuIG91dHN0YW5kaW5nIHJlcXVlc3QpLgogKgogKiAgQHBhcmFtIGRjYWNoZSBpcyB0aGUgZGVsZWdhdGVkIGNhY2hlIHRvIGJlIGNoZWNrZWQuCiAqCiAqICBAcmV0dXJuIFJldHVybnMgdGhlIGNhY2hlIHBvaW50ZXIgaWYgaXQgaXMgc3RpbGwgdmFsaWQsIE5VTEwgb3RoZXJ3aXNlLgogKgogKiBAc2VlIG5ldHNubXBfY3JlYXRlX2RlbGVnYXRlZF9jYWNoZSgpCiAqIEBzZWUgbmV0c25tcF9mcmVlX2RlbGVnYXRlZF9jYWNoZSgpCiAqLwpORVRTTk1QX0lOTElORSBuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqCm5ldHNubXBfaGFuZGxlcl9jaGVja19jYWNoZShuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqZGNhY2hlKQp7CiAgICBpZiAoIWRjYWNoZSkKICAgICAgICByZXR1cm4gZGNhY2hlOwoKICAgIGlmIChuZXRzbm1wX2NoZWNrX3RyYW5zYWN0aW9uX2lkKGRjYWNoZS0+dHJhbnNhY3Rpb25faWQpID09CiAgICAgICAgU05NUEVSUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBkY2FjaGU7CgogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBGcmVlIGEgY2FjaGUgb25jZSBpdCdzIG5vIGxvbmdlciB1c2VkLgogKiAgRGVsZXRlcyB0aGUgZGF0YSBhbGxvY2F0ZWQgYnkgbmV0c25tcF9jcmVhdGVfZGVsZWdhdGVkX2NhY2hlKCkuCiAqICBTdHJ1Y3R1cmVzIHdoaWNoIHdlcmUgbm90IGFsbG9jYXRlZCBieSBuZXRzbm1wX2NyZWF0ZV9kZWxlZ2F0ZWRfY2FjaGUoKQogKiAgYXJlIG5vdCBmcmVlZCAocG9pbnRlcnMgYXJlIGRyb3BwZWQpLgogKgogKiAgQHBhcmFtIGRjYWNoZSBpcyB0aGUgZGVsZWdhdGVkIGNhY2hlIHRvIGJlIGZyZWVkLgogKgogKiBAc2VlIG5ldHNubXBfY3JlYXRlX2RlbGVnYXRlZF9jYWNoZSgpCiAqIEBzZWUgbmV0c25tcF9oYW5kbGVyX2NoZWNrX2NhY2hlKCkKICovCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9mcmVlX2RlbGVnYXRlZF9jYWNoZShuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqZGNhY2hlKQp7CiAgICAvKgogICAgICogcmlnaHQgbm93LCBubyBleHRyYSBkYXRhIGlzIHRoZXJlIHRoYXQgbmVlZHMgdG8gYmUgZnJlZWQgCiAgICAgKi8KICAgIGlmIChkY2FjaGUpCiAgICAgICAgU05NUF9GUkVFKGRjYWNoZSk7CgogICAgcmV0dXJuOwp9CgoKLyoqIFNldHMgYSBsaXN0IG9mIHJlcXVlc3RzIGFzIGRlbGVnYXRlZCBvciBub3QgZGVsZWdhdGVkLgogKiAgU3dlZXBzIHRocm91Z2ggZ2l2ZW4gY2hhaW4gb2YgcmVxdWVzdHMgYW5kIHNldHMgJ2RlbGVnYXRlZCcKICogIGZsYWcgYWNjb3JkaW5nbHkgdG8gdGhlIGlzZGVsZWdhdGVkIHBhcmFtZXRlci4KICoKICogIEBwYXJhbSByZXF1ZXN0cyBSZXF1ZXN0IGxpc3QuCiAqICBAcGFyYW0gaXNkZWxlZ2F0ZWQgTmV3IHZhbHVlIG9mIHRoZSAnZGVsZWdhdGVkJyBmbGFnLgogKi8Kdm9pZApuZXRzbm1wX2hhbmRsZXJfbWFya19yZXF1ZXN0c19hc19kZWxlZ2F0ZWQobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlzZGVsZWdhdGVkKQp7CiAgICB3aGlsZSAocmVxdWVzdHMpIHsKICAgICAgICByZXF1ZXN0cy0+ZGVsZWdhdGVkID0gaXNkZWxlZ2F0ZWQ7CiAgICAgICAgcmVxdWVzdHMgPSByZXF1ZXN0cy0+bmV4dDsKICAgIH0KfQoKLyoqIEFkZHMgZGF0YSBmcm9tIG5vZGUgbGlzdCB0byB0aGUgcmVxdWVzdCBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuCiAqICBEYXRhIGluIHRoZSByZXF1ZXN0IGNhbiBiZSBsYXRlciBleHRyYWN0ZWQgYW5kIHVzZWQgYnkgc3VibW9kdWxlcy4KICoKICogQHBhcmFtIHJlcXVlc3QgRGVzdGluYXRpb24gcmVxdWVzdCBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuCiAqCiAqIEBwYXJhbSBub2RlIFRoZSBkYXRhIHRvIGJlIGFkZGVkIHRvIHRoZSBsaW5rZWQgbGlzdAogKiAgICAgICAgICAgICByZXF1ZXN0LT5wYXJlbnRfZGF0YS4KICoKICogQHNlZSBuZXRzbm1wX3JlcXVlc3RfcmVtb3ZlX2xpc3RfZGF0YSgpCiAqIEBzZWUgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEoKQogKi8KTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9kYXRhX2xpc3QgKm5vZGUpCnsKICAgIGlmIChyZXF1ZXN0KSB7CiAgICAgICAgaWYgKHJlcXVlc3QtPnBhcmVudF9kYXRhKQogICAgICAgICAgICBuZXRzbm1wX2FkZF9saXN0X2RhdGEoJnJlcXVlc3QtPnBhcmVudF9kYXRhLCBub2RlKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJlcXVlc3QtPnBhcmVudF9kYXRhID0gbm9kZTsKICAgIH0KfQoKLyoqIFJlbW92ZXMgYWxsIGRhdGEgZnJvbSBhIHJlcXVlc3QuCiAqCiAqIEBwYXJhbSByZXF1ZXN0IHRoZSBuZXRzbm1wIHJlcXVlc3QgaW5mbyBzdHJ1Y3R1cmUKICoKICogQHBhcmFtIG5hbWUgdGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJldmlvdXNseSBhZGRlZCBkYXRhCiAqCiAqIEByZXR1cm4gMCBvbiBzdWNjZXNzZnVsIGZpbmQtYW5kLWRlbGV0ZSwgMSBvdGhlcndpc2UuCiAqCiAqIEBzZWUgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEoKQogKiBAc2VlIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKCkKICovCk5FVFNOTVBfSU5MSU5FIGludApuZXRzbm1wX3JlcXVlc3RfcmVtb3ZlX2xpc3RfZGF0YShuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgaWYgKChOVUxMID09IHJlcXVlc3QpIHx8IChOVUxMID09cmVxdWVzdC0+cGFyZW50X2RhdGEpKQogICAgICAgIHJldHVybiAxOwoKICAgIHJldHVybiBuZXRzbm1wX3JlbW92ZV9saXN0X25vZGUoJnJlcXVlc3QtPnBhcmVudF9kYXRhLCBuYW1lKTsKfQoKLyoqIEV4dHJhY3RzIGRhdGEgZnJvbSBhIHJlcXVlc3QuCiAqICBSZXRyaWV2ZXMgZGF0YSB0aGF0IHdhcyBwcmV2aW91c2x5IGFkZGVkIHRvIHRoZSByZXF1ZXN0LAogKiAgdXN1YWxseSBieSBhIHBhcmVudCBtb2R1bGUuCiAqCiAqIEBwYXJhbSByZXF1ZXN0IFNvdXJjZSByZXF1ZXN0IGluZm9ybWF0aW9uIHN0cnVjdHVyZS4KICoKICogQHBhcmFtIG5hbWUgVXNlZCB0byBjb21wYXJlIGFnYWluc3QgdGhlIHJlcXVlc3QtPnBhcmVudF9kYXRhLT5uYW1lIHZhbHVlOwogKiAgICAgICAgICAgICBpZiBhIG1hdGNoIGlzIGZvdW5kLCByZXF1ZXN0LT5wYXJlbnRfZGF0YS0+ZGF0YSBpcyByZXR1cm5lZC4KICoKICogQHJldHVybiBHaXZlcyBhIHZvaWQgcG9pbnRlcihyZXF1ZXN0LT5wYXJlbnRfZGF0YS0+ZGF0YSk7IE5VTEwgaXMKICogICAgICAgICByZXR1cm5lZCBpZiBzb3VyY2UgZGF0YSBpcyBOVUxMIG9yIHRoZSBvYmplY3QgaXMgbm90IGZvdW5kLgogKgogKiBAc2VlIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKCkKICogQHNlZSBuZXRzbm1wX3JlcXVlc3RfcmVtb3ZlX2xpc3RfZGF0YSgpCiAqLwp2b2lkICAgICoKbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIGlmIChyZXF1ZXN0KQogICAgICAgIHJldHVybiBuZXRzbm1wX2dldF9saXN0X2RhdGEocmVxdWVzdC0+cGFyZW50X2RhdGEsIG5hbWUpOwogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBGcmVlIHRoZSBleHRyYSBkYXRhIHN0b3JlZCBpbiBhIHJlcXVlc3QuCiAqICBEZWxldGVzIHRoZSBkYXRhIGluIGdpdmVuIHJlcXVlc3Qgb25seS4gT3RoZXIgY2hhaW4gaXRlbXMKICogIGFyZSB1bmFmZmVjdGVkLgogKgogKiBAcGFyYW0gcmVxdWVzdCBSZXF1ZXN0IGluZm9ybWF0aW9uIHN0cnVjdHVyZSB0byBiZSBtb2RpZmllZC4KICoKICogQHNlZSBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YSgpCiAqIEBzZWUgbmV0c25tcF9mcmVlX2xpc3RfZGF0YSgpCiAqLwpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0KG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0KQp7CiAgICBpZiAocmVxdWVzdCkKICAgICAgICBuZXRzbm1wX2ZyZWVfbGlzdF9kYXRhKHJlcXVlc3QtPnBhcmVudF9kYXRhKTsKfQoKLyoqIEZyZWUgdGhlIGV4dHJhIGRhdGEgc3RvcmVkIGluIGEgYnVuY2ggb2YgcmVxdWVzdHMuCiAqICBEZWxldGVzIGFsbCBkYXRhIGluIHRoZSBjaGFpbiBpbnNpZGUgcmVxdWVzdC4KICoKICogQHBhcmFtIHJlcXVlc3QgUmVxdWVzdCBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUgdG8gYmUgbW9kaWZpZWQuCiAqCiAqIEBzZWUgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEoKQogKiBAc2VlIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0KCkKICovCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0KQp7CiAgICBpZiAocmVxdWVzdCAmJiByZXF1ZXN0LT5wYXJlbnRfZGF0YSkgewogICAgICAgIG5ldHNubXBfZnJlZV9hbGxfbGlzdF9kYXRhKHJlcXVlc3QtPnBhcmVudF9kYXRhKTsKICAgICAgICByZXF1ZXN0LT5wYXJlbnRfZGF0YSA9IE5VTEw7CiAgICB9Cn0KCi8qKiBSZXR1cm5zIGEgTUlCIGhhbmRsZXIgZnJvbSBhIGNoYWluIGJhc2VkIG9uIHRoZSBuYW1lLgogKgogKiBAcGFyYW0gcmVnaW5mbyBIYW5kbGVyIHJlZ2lzdHJhdGlvbiBzdHJ1Y3Qgd2hpY2ggY29udGFpbnMgdGhlIGNoYWluLgogKgogKiBAcGFyYW0gbmFtZSBUYXJnZXQgTUlCIEhhbmRsZXIgbmFtZSBzdHJpbmcuIFRoZSBuYW1lIGlzIGNhc2UKICogICAgICAgIHNlbnNpdGl2ZS4KICoKICogQHJldHVybiBUaGUgTUlCIEhhbmRsZXIgaXMgcmV0dXJuZWQsIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKgogKiBAc2VlIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKCkKICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2ZpbmRfaGFuZGxlcl9ieV9uYW1lKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaXQ7CiAgICBpZiAocmVnaW5mbyA9PSBOVUxMIHx8IG5hbWUgPT0gTlVMTCApCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBmb3IgKGl0ID0gcmVnaW5mby0+aGFuZGxlcjsgaXQ7IGl0ID0gaXQtPm5leHQpIHsKICAgICAgICBpZiAoc3RyY21wKGl0LT5oYW5kbGVyX25hbWUsIG5hbWUpID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIGl0OwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKiogUmV0dXJucyBhIGhhbmRsZXIncyB2b2lkIHBvaW50ZXIgZnJvbSBhIGNoYWluIGJhc2VkIG9uIHRoZSBuYW1lLgogKgogKiBAd2FybmluZyBUaGUgdm9pZCBwb2ludGVyIGRhdGEgbWF5IGNoYW5nZSBhcyBhIGhhbmRsZXIgZXZvbHZlcy4KICogICAgICAgIEhhbmRsZXJzIHNob3VsZCByZWFsbHkgYWR2ZXJ0aXNlIHNvbWUgZnVuY3Rpb24gZm9yIHlvdQogKiAgICAgICAgdG8gdXNlIGluc3RlYWQuCiAqCiAqIEBwYXJhbSByZWdpbmZvIEhhbmRsZXIgcmVnaXN0cmF0aW9uIHN0cnVjdCB3aGljaCBjb250YWlucyB0aGUgY2hhaW4uCiAqCiAqIEBwYXJhbSBuYW1lIFRhcmdldCBNSUIgSGFuZGxlciBuYW1lIHN0cmluZy4gVGhlIG5hbWUgaXMgY2FzZQogKiAgICAgICAgc2Vuc2l0aXZlLgogKgogKiBAcmV0dXJuIFRoZSBNSUIgSGFuZGxlcidzIHZvaWQgKiBwb2ludGVyIGlzIHJldHVybmVkLAogKiAgICAgICAgb3IgTlVMTCBpZiB0aGUgaGFuZGxlciBpcyBub3QgZm91bmQuCiAqCiAqIEBzZWUgbmV0c25tcF9maW5kX2hhbmRsZXJfYnlfbmFtZSgpCiAqLwp2b2lkICAgICAgICAgICAqCm5ldHNubXBfZmluZF9oYW5kbGVyX2RhdGFfYnlfbmFtZShuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaXQgPSBuZXRzbm1wX2ZpbmRfaGFuZGxlcl9ieV9uYW1lKHJlZ2luZm8sIG5hbWUpOwogICAgaWYgKGl0KQogICAgICAgIHJldHVybiBpdC0+bXl2b2lkOwogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBAcHJpdmF0ZQogKiAgQ2xvbmVzIGEgTUlCIEhhbmRsZXIgd2l0aCBpdHMgYmFzaWMgcHJvcGVydGllcy4KICogIENyZWF0ZXMgYSBjb3B5IG9mIHRoZSBnaXZlbiBNSUIgSGFuZGxlci4gQ29waWVzIG5hbWUsIGZsYWdzIGFuZAogKiAgYWNjZXNzIG1ldGhvZHMgb25seTsgbm90IG15dm9pZC4KICoKICogIEBzZWUgbmV0c25tcF9oYW5kbGVyX2R1cCgpCiAqLwpzdGF0aWMgbmV0c25tcF9taWJfaGFuZGxlciAqCl9jbG9uZV9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKml0KQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpkdXA7CgogICAgaWYoTlVMTCA9PSBpdCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBkdXAgPSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKGl0LT5oYW5kbGVyX25hbWUsIGl0LT5hY2Nlc3NfbWV0aG9kKTsKICAgIGlmKE5VTEwgIT0gZHVwKQogICAgICAgIGR1cC0+ZmxhZ3MgPSBpdC0+ZmxhZ3M7CgogICAgcmV0dXJuIGR1cDsKfQoKc3RhdGljIG5ldHNubXBfZGF0YV9saXN0ICpoYW5kbGVyX3JlZyA9IE5VTEw7Cgp2b2lkCmhhbmRsZXJfZnJlZV9jYWxsYmFjayh2b2lkICpoYW5kbGVyKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfZnJlZSgobmV0c25tcF9taWJfaGFuZGxlciAqKWhhbmRsZXIpOwp9CgovKiogUmVnaXN0ZXJzIGEgZ2l2ZW4gaGFuZGxlciBieSBuYW1lLCBzbyB0aGF0IGl0IGNhbiBiZSBmb3VuZCBlYXNpbHkgbGF0ZXIuCiAqICBQb2ludGVyIHRvIHRoZSBoYW5kbGVyIGlzIHB1dCBpbnRvIGEgbGlzdCB3aGVyZSBpdCBjYW4gYmUgZWFzaWx5IGxvY2F0ZWQKICogIGF0IGFueSB0aW1lLgogKgogKiBAcGFyYW0gbmFtZSBOYW1lIHN0cmluZyB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIGhhbmRsZXIuCiAqCiAqIEBwYXJhbSBoYW5kbGVyIFBvaW50ZXIgdGhlIE1JQiBIYW5kbGVyLgogKgogKiBAc2VlIG5ldHNubXBfY2xlYXJfaGFuZGxlcl9saXN0KCkKICovCnZvaWQKbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyX2J5X25hbWUoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlcikKewogICAgbmV0c25tcF9hZGRfbGlzdF9kYXRhKCZoYW5kbGVyX3JlZywKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QobmFtZSwgKHZvaWQgKikgaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcl9mcmVlX2NhbGxiYWNrKSk7CiAgICBERUJVR01TR1RMKCgiaGFuZGxlcl9yZWdpc3RyeSIsICJyZWdpc3RlcmluZyBoZWxwZXIgJXNcbiIsIG5hbWUpKTsKfQoKLyoqIENsZWFycyB0aGUgZW50aXJlIE1JQiBIYW5kbGVycyByZWdpc3RyYXRpb24gbGlzdC4KICogIE1JQiBIYW5kbGVycyByZWdpc3RyYXRpb24gbGlzdCBpcyB1c2VkIHRvIGFjY2VzcyBhbnkgTUlCIEhhbmRsZXIgYnkKICogIGl0cyBuYW1lLiBUaGUgZnVuY3Rpb24gZnJlZXMgdGhlIGxpc3QgbWVtb3J5IGFuZCBzZXRzIHBvaW50ZXIgdG8gTlVMTC4KICogIEluc3RlYWQgb2YgY2FsbGluZyB0aGlzIGZ1bmN0aW9uIGRpcmVjdGx5LCB1c2Ugc2h1dGRvd25fYWdlbnQoKS4KICoKICogIEBzZWUgc2h1dGRvd25fYWdlbnQoKQogKiAgQHNlZSBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXJfYnlfbmFtZSgpCiAqLwp2b2lkCm5ldHNubXBfY2xlYXJfaGFuZGxlcl9saXN0KHZvaWQpCnsKICAgIERFQlVHTVNHVEwoKCJhZ2VudF9oYW5kbGVyIiwgIm5ldHNubXBfY2xlYXJfaGFuZGxlcl9saXN0KCkgY2FsbGVkXG4iKSk7CiAgICBuZXRzbm1wX2ZyZWVfYWxsX2xpc3RfZGF0YShoYW5kbGVyX3JlZyk7CiAgICBoYW5kbGVyX3JlZyA9IE5VTEw7Cn0KCi8qKiBAcHJpdmF0ZQogKiAgSW5qZWN0cyBhIGhhbmRsZXIgaW50byBhIHN1YnRyZWUsIHBlZXJzIGFuZCBjaGlsZHJlbiB3aGVuIGEgZ2l2ZW4KICogIHN1YnRyZWVzIG5hbWUgbWF0Y2hlcyBhIHBhc3NlZCBpbiBuYW1lLgogKi8Kdm9pZApuZXRzbm1wX2luamVjdF9oYW5kbGVyX2ludG9fc3VidHJlZShuZXRzbm1wX3N1YnRyZWUgKnRwLCBjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpiZWZvcmVfd2hhdCkKewogICAgbmV0c25tcF9zdWJ0cmVlICp0cHRyOwogICAgbmV0c25tcF9taWJfaGFuZGxlciAqbWg7CgogICAgZm9yICh0cHRyID0gdHA7IHRwdHIgIT0gTlVMTDsgdHB0ciA9IHRwdHItPm5leHQpIHsKICAgICAgICAvKiAgaWYgKHRwdHItPmNoaWxkcmVuKSB7IAogICAgICAgICAgICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXJfaW50b19zdWJ0cmVlKHRwdHItPmNoaWxkcmVuLG5hbWUsaGFuZGxlcik7CgkgICAgfSAgICovCiAgICAgICAgaWYgKHN0cmNtcCh0cHRyLT5sYWJlbF9hLCBuYW1lKSA9PSAwKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJpbmplY3RIYW5kbGVyIiwgImluamVjdGluZyBoYW5kbGVyICVzIGludG8gJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXItPmhhbmRsZXJfbmFtZSwgdHB0ci0+bGFiZWxfYSkpOwogICAgICAgICAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyX2JlZm9yZSh0cHRyLT5yZWdpbmZvLCBfY2xvbmVfaGFuZGxlcihoYW5kbGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlX3doYXQpOwogICAgICAgIH0gZWxzZSBpZiAodHB0ci0+cmVnaW5mbyAhPSBOVUxMICYmCgkJICAgdHB0ci0+cmVnaW5mby0+aGFuZGxlck5hbWUgIT0gTlVMTCAmJgogICAgICAgICAgICAgICAgICAgc3RyY21wKHRwdHItPnJlZ2luZm8tPmhhbmRsZXJOYW1lLCBuYW1lKSA9PSAwKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJpbmplY3RIYW5kbGVyIiwgImluamVjdGluZyBoYW5kbGVyIGludG8gJXMvJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRwdHItPmxhYmVsX2EsIHRwdHItPnJlZ2luZm8tPmhhbmRsZXJOYW1lKSk7CiAgICAgICAgICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXJfYmVmb3JlKHRwdHItPnJlZ2luZm8sIF9jbG9uZV9oYW5kbGVyKGhhbmRsZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWZvcmVfd2hhdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yIChtaCA9IHRwdHItPnJlZ2luZm8tPmhhbmRsZXI7IG1oICE9IE5VTEw7IG1oID0gbWgtPm5leHQpIHsKICAgICAgICAgICAgICAgIGlmIChtaC0+aGFuZGxlcl9uYW1lICYmIHN0cmNtcChtaC0+aGFuZGxlcl9uYW1lLCBuYW1lKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImluamVjdEhhbmRsZXIiLCAiaW5qZWN0aW5nIGhhbmRsZXIgaW50byAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cHRyLT5sYWJlbF9hKSk7CiAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcl9iZWZvcmUodHB0ci0+cmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2xvbmVfaGFuZGxlcihoYW5kbGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWZvcmVfd2hhdCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJpbmplY3RIYW5kbGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm90IGluamVjdGluZyBoYW5kbGVyIGludG8gJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWgtPmhhbmRsZXJfbmFtZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgaW50ICAgICAgZG9uZWl0ID0gMDsKLyoqIEBwcml2YXRlCiAqICBQYXJzZXMgdGhlICJpbmplY3RIYW5kbGVyIiB0b2tlbiBsaW5lLgogKi8Kdm9pZApwYXJzZV9pbmplY3RIYW5kbGVyX2NvbmYoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIGNoYXIgICAgICAgICAgICBoYW5kbGVyX3RvX2luc2VydFsyNTZdLCByZWdfbmFtZVsyNTZdOwogICAgc3VidHJlZV9jb250ZXh0X2NhY2hlICpzdGM7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyOwoKICAgIC8qCiAgICAgKiBYWFhXV1c6IGVuc3VyZSBpbnN0ZWFkIHRoYXQgaGFuZGxlciBpc24ndCBpbnNlcnRlZCB0d2ljZSAKICAgICAqLwogICAgaWYgKGRvbmVpdCkgICAgICAgICAgICAgICAgIC8qIHdlIG9ubHkgZG8gdGhpcyBvbmNlIHdpdGhvdXQgcmVzdGFydCB0aGUgYWdlbnQgKi8KICAgICAgICByZXR1cm47CgogICAgY3B0ciA9IGNvcHlfbndvcmQoY3B0ciwgaGFuZGxlcl90b19pbnNlcnQsIHNpemVvZihoYW5kbGVyX3RvX2luc2VydCkpOwogICAgaGFuZGxlciA9IChuZXRzbm1wX21pYl9oYW5kbGVyKiluZXRzbm1wX2dldF9saXN0X2RhdGEoaGFuZGxlcl9yZWcsIGhhbmRsZXJfdG9faW5zZXJ0KTsKICAgIGlmICghaGFuZGxlcikgewoJbmV0c25tcF9jb25maWdfZXJyb3IoIm5vIFwiJXNcIiBoYW5kbGVyIHJlZ2lzdGVyZWQuIiwKCQkJICAgICBoYW5kbGVyX3RvX2luc2VydCk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICghY3B0cikgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm5vIElOVE9OQU1FIHNwZWNpZmllZC4gIENhbid0IGRvIGluc2VydGlvbi4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjcHRyID0gY29weV9ud29yZChjcHRyLCByZWdfbmFtZSwgc2l6ZW9mKHJlZ19uYW1lKSk7CgogICAgZm9yIChzdGMgPSBnZXRfdG9wX2NvbnRleHRfY2FjaGUoKTsgc3RjOyBzdGMgPSBzdGMtPm5leHQpIHsKICAgICAgICBERUJVR01TR1RMKCgiaW5qZWN0SGFuZGxlciIsICJDaGVja2luZyBjb250ZXh0IHRyZWUgJXMgKGJlZm9yZT0lcylcbiIsCiAgICAgICAgICAgICAgICAgICAgc3RjLT5jb250ZXh0X25hbWUsIChjcHRyKT9jcHRyOiJudWxsIikpOwogICAgICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXJfaW50b19zdWJ0cmVlKHN0Yy0+Zmlyc3Rfc3VidHJlZSwgcmVnX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlciwgY3B0cik7CiAgICB9Cn0KCi8qKiBAcHJpdmF0ZQogKiAgQ2FsbGJhY2sgdG8gZW5zdXJlIGluamVjdEhhbmRsZXIgcGFyc2VyIGRvZXNuJ3QgZG8gdGhpbmdzIHR3aWNlLgogKiAgQHRvZG8gcmVwbGFjZSB0aGlzIHdpdGggYSBtZXRob2QgdG8gY2hlY2sgdGhlIGhhbmRsZXIgY2hhaW4gaW5zdGVhZC4KICovCnN0YXRpYyBpbnQKaGFuZGxlcl9tYXJrX2luamVjdF9oYW5kbGVyX2RvbmUoaW50IG1ham9ySUQsIGludCBtaW5vcklELAogICAgICAgICAgICAgICAgICAgIHZvaWQgKnNlcnZlcmFyZywgdm9pZCAqY2xpZW50YXJnKQp7CiAgICBkb25laXQgPSAxOwogICAgcmV0dXJuIDA7Cn0KCi8qKiBAcHJpdmF0ZQogKiAgUmVnaXN0ZXJzIHRoZSBpbmplY3RIYW5kbGUgcGFyc2VyIHRva2VuLgogKiAgVXNlZCBpbiBpbml0X2FnZW50X3JlYWRfY29uZmlnKCkuCiAqCiAqICBAc2VlIGluaXRfYWdlbnRfcmVhZF9jb25maWcoKQogKi8Kdm9pZApuZXRzbm1wX2luaXRfaGFuZGxlcl9jb25mKHZvaWQpCnsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJpbmplY3RIYW5kbGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlX2luamVjdEhhbmRsZXJfY29uZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICJpbmplY3RIYW5kbGVyIE5BTUUgSU5UT05BTUUgW0JFRk9SRV9PVEhFUl9OQU1FXSIpOwogICAgc25tcF9yZWdpc3Rlcl9jYWxsYmFjayhTTk1QX0NBTExCQUNLX0xJQlJBUlksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfQ0FMTEJBQ0tfUE9TVF9SRUFEX0NPTkZJRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcl9tYXJrX2luamVjdF9oYW5kbGVyX2RvbmUsIE5VTEwpOwoKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJHRVQiKSwgTU9ERV9HRVQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIkdFVE5FWFQiKSwgTU9ERV9HRVRORVhUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJHRVRCVUxLIiksIE1PREVfR0VUQlVMSyk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX0JFR0lOIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFVF9CRUdJTik7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX1JFU0VSVkUxIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFVF9SRVNFUlZFMSk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX1JFU0VSVkUyIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFVF9SRVNFUlZFMik7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX0FDVElPTiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9TRVRfQUNUSU9OKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJTRVRfQ09NTUlUIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFVF9DT01NSVQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIlNFVF9GUkVFIiksIE1PREVfU0VUX0ZSRUUpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIlNFVF9VTkRPIiksIE1PREVfU0VUX1VORE8pOwoKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJwcmUtcmVxdWVzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9QUkVfUkVRVUVTVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgib2JqZWN0X2xvb2t1cCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9PQkpFQ1RfTE9PS1VQKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJjaGVja192YWx1ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9DSEVDS19WQUxVRSk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgicm93X2NyZWF0ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9ST1dfQ1JFQVRFKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJ1bmRvX3NldHVwIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1VORE9fU0VUVVApOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoInNldF92YWx1ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9TRVRfVkFMVUUpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoImNoZWNrX2NvbnNpc3RlbmN5IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX0NIRUNLX0NPTlNJU1RFTkNZKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJ1bmRvX3NldCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9VTkRPX1NFVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgiY29tbWl0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX0NPTU1JVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgidW5kb19jb21taXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfVU5ET19DT01NSVQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoImlycmV2ZXJzaWJsZV9jb21taXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfSVJSRVZFUlNJQkxFX0NPTU1JVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgidW5kb19jbGVhbnVwIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1VORE9fQ0xFQU5VUCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgicG9zdF9yZXF1ZXN0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1BPU1RfUkVRVUVTVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgib3JpZ2luYWwiKSwgMHhmZmZmKTsKCiAgICAvKgogICAgICogeHh4LXJrczogaG1tbS4uIHdpbGwgdGhpcyB3b3JrIGZvciBtb2RlcyB3aGljaCBhcmUgb3InZCB0b2dldGhlcj8KICAgICAqICAgICAgICAgIEknbSBiZXR0aW5nIG5vdC4uLgogICAgICovCiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiaGFuZGxlcl9jYW5fbW9kZSIsIHN0cmR1cCgiR0VUL0dFVE5FWFQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX0dFVEFOREdFVE5FWFQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImhhbmRsZXJfY2FuX21vZGUiLCBzdHJkdXAoIlNFVCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFUl9DQU5fU0VUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJoYW5kbGVyX2Nhbl9tb2RlIiwgc3RyZHVwKCJHRVRCVUxLIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9HRVRCVUxLKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJoYW5kbGVyX2Nhbl9tb2RlIiwgc3RyZHVwKCJCQUJZX1NURVAiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX0JBQllfU1RFUCk7Cn0KCi8qKiBAfSAqLwo=