LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWZlYXR1cmVzLmg+CgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L2J1bGtfdG9fbmV4dC5oPgoKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKGFnZW50X2hhbmRsZXIsIGxpYm5ldHNubXBhZ2VudCkKCm5ldHNubXBfZmVhdHVyZV9jaGlsZF9vZihoYW5kbGVyX21hcmtfcmVxdWVzdHNfYXNfZGVsZWdhdGVkLCBhZ2VudF9oYW5kbGVyKQoKc3RhdGljIG5ldHNubXBfbWliX2hhbmRsZXIgKl9jbG9uZV9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKml0KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogTmV3IEhhbmRsZXIgYmFzZWQgQVBJIAogKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiogQGRlZmdyb3VwIGhhbmRsZXIgTmV0LVNOTVAgQWdlbnQgaGFuZGxlciBhbmQgZXh0ZW5zaWJpbGl0eSBBUEkKICogIEBpbmdyb3VwIGFnZW50CiAqCiAqICBUaGUgYmFzaWMgdGhlb3J5IGdvZXMgc29tZXRoaW5nIGxpa2UgdGhpczogSW4gdGhlIHBhc3QsIHdpdGggdGhlCiAqICBvcmlnaW5hbCBtaWIgbW9kdWxlIGFwaSAod2hpY2ggZGVyaXZlZCBmcm9tIHRoZSBvcmlnaW5hbCBDTVUgU05NUAogKiAgY29kZSkgdGhlIHVuZGVybHlpbmcgbWliIG1vZHVsZXMgd2VyZSBwYXNzZWQgdmVyeSBsaXR0bGUKICogIGluZm9ybWF0aW9uIChvbmx5IHRoZSB0cnVseSBtb3N0IGJhc2ljIGluZm9ybWF0aW9uIGFib3V0IGEKICogIHJlcXVlc3QpLiAgVGhpcyB3b3JrZWQgd2VsbCBhdCB0aGUgdGltZSBidXQgaW4gdG9kYXlzIHdvcmxkIG9mCiAqICBzdWJhZ2VudHMsIGRldmljZSBpbnN0cnVtZW50YXRpb24sIGxvdyByZXNvdXJjZSBjb25zdW1wdGlvbiwgZXRjLAogKiAgaXQganVzdCBpc24ndCBmbGV4aWJsZSBlbm91Z2guICAiaGFuZGxlcnMiIGFyZSBoZXJlIHRvIGZpeCBhbGwgdGhhdC4KICoKICogIFdpdGggdGhlIHJld3JpdGUgb2YgdGhlIGFnZW50IGludGVybmFscyBmb3IgdGhlIG5ldC1zbm1wIDUuMAogKiAgcmVsZWFzZSwgd2UgaW50cm9kdWNlIGEgbW9kdWxhciBjYWxsaW5nIHNjaGVtZSB0aGF0IGFsbG93cyBhZ2VudAogKiAgbW9kdWxlcyB0byBiZSB3cml0dGVuIGluIGEgdmVyeSBmbGV4aWJsZSBtYW5uZXIsIGFuZCBtb3JlCiAqICBpbXBvcnRhbnRseSBhbGxvd3MgcmV1c2Ugb2YgY29kZSBpbiBhIGRlY2VudCB3YXkgKGFuZCB3aXRob3V0IHRoZQogKiAgbWVtb3J5IGFuZCBzcGVlZCBvdmVyaGVhZHMgb2YgT08gbGFuZ3VhZ2VzIGxpa2UgQysrKS4KICoKICogIEZ1bmN0aW9uYWxseSwgdGhlIG5vdGlvbiBvZiB3aGF0IGEgaGFuZGxlciBkb2VzIGlzIHRoZSBzYW1lIGFzIHRoZQogKiAgb2xkZXIgYXBpOiBBIGhhbmRsZXIgaXMgQGxpbmsgbmV0c25tcF9jcmVhdGVfaGFuZGxlcigpIGNyZWF0ZWRAZW5kbGluayBhbmQKICogIHRoZW4gQGxpbmsgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKCkgcmVnaXN0ZXJlZEBlbmRsaW5rIHdpdGggdGhlIG1haW4KICogIGFnZW50IGF0IGEgZ2l2ZW4gT0lEIGluIHRoZSBPSUQgdHJlZSBhbmQgZ2V0cyBjYWxsZWQgYW55IHRpbWUgYQogKiAgcmVxdWVzdCBpcyBtYWRlIHRoYXQgaXQgc2hvdWxkIHJlc3BvbmQgdG8uICBZb3UgcHJvYmFibHkgc2hvdWxkCiAqICB1c2Ugb25lIG9mIHRoZSBjb252ZW5pZW5jZSBoZWxwZXJzIGluc3RlYWQgb2YgZG9pbmcgYW55dGhpbmcgZWxzZQogKiAgeW91cnNlbGYgdGhvdWdoOgogKgogKiAgTW9zdCBpbXBvcnRhbnRseSwgdGhvdWdoLCBpcyB0aGF0IHRoZSBoYW5kbGVycyBhcmUgYnVpbHQgb24gdGhlCiAqICBub3Rpb24gb2YgbW9kdWxhcml0eSBhbmQgcmV1c2UuICBTcGVjaWZpY2FsbHksIHJhdGhlciB0aGFuIGRvIGFsbAogKiAgdGhlIHJlYWxseSBoYXJkIHdvcmsgKGxpa2UgcGFyc2luZyB0YWJsZSBpbmRleGVzIG91dCBvZiBhbgogKiAgaW5jb21pbmcgb2lkIHJlcXVlc3QpIGluIGVhY2ggbW9kdWxlLCB0aGUgQVBJIGlzIGRlc2lnbmVkIHRvIG1ha2UKICogIGl0IGVhc3kgdG8gd3JpdGUgImhlbHBlciIgaGFuZGxlcnMgdGhhdCBtZXJlbHkgcHJvY2VzcyBzb21lIGFzcGVjdAogKiAgb2YgdGhlIHJlcXVlc3QgYmVmb3JlIHBhc3NpbmcgaXQgYWxvbmcgdG8gdGhlIGZpbmFsIGhhbmRsZXIgdGhhdAogKiAgcmV0dXJucyB0aGUgcmVhbCBhbnN3ZXIuICBNb3N0IHBlb3BsZSB3aWxsIHdhbnQgdG8gbWFrZSB1c2Ugb2YgdGhlCiAqICBAbGluayBpbnN0YW5jZSBpbnN0YW5jZUBlbmRsaW5rLCBAbGluayB0YWJsZSB0YWJsZUBlbmRsaW5rLCBAbGluawogKiAgdGFibGVfaXRlcmF0b3IgdGFibGVfaXRlcmF0b3JAZW5kbGluaywgQGxpbmsgdGFibGVfZGF0YQogKiAgdGFibGVfZGF0YUBlbmRsaW5rLCBvciBAbGluayB0YWJsZV9kYXRhc2V0IHRhYmxlX2RhdGFzZXRAZW5kbGluawogKiAgaGVscGVycyB0byBtYWtlIHRoZWlyIGxpZmUgZWFzaWVyLiAgVGhlc2UgImhlbHBlcnMiIGludGVycGVydAogKiAgaW1wb3J0YW50IGFzcGVjdHMgb2YgdGhlIHJlcXVlc3QgYW5kIHBhc3MgdGhlbSBvbiB0byB5b3UuCiAqCiAqICBGb3IgaW5zdGFuY2UsIHRoZSBAbGluayB0YWJsZSB0YWJsZUBlbmRsaW5rIGhlbHBlciBpcyBkZXNpZ25lZCB0bwogKiAgaGFuZCB5b3UgYSBsaXN0IG9mIGV4dHJhY3RlZCBpbmRleCB2YWx1ZXMgZnJvbSBhbiBpbmNvbWluZwogKiAgcmVxdWVzdC4gIFRIZSBAbGluayB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvckBlbmRsaW5rIGhlbHBlcgogKiAgaXMgYnVpbHQgb24gdG9wIG9mIHRoZSB0YWJsZSBoZWxwZXIsIGFuZCBpcyBkZXNpZ25lZCB0byBoZWxwIHlvdQogKiAgaXRlcmF0ZSB0aHJvdWdoIGRhdGEgc3RvcmVkIGVsc2V3aGVyZSAobGlrZSBpbiBhIGtlcm5lbCkgdGhhdCBpcwogKiAgbm90IGluIE9JRCBsZXhvZ3JhcGhpY2FsIG9yZGVyIChpZSwgZG9uJ3Qgd3JpdGUgeW91ciBvd24gaW5kZXgvb2lkCiAqICBzb3J0aW5nIHJvdXRpbmUsIHVzZSB0aGlzIGhlbHBlciBpbnN0ZWFkKS4gIFRoZSBiZWF1dHkgb2YgdGhlCiAqICBAbGluayB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvciBoZWxwZXJAZW5kbGluaywgYXMgd2VsbCBhcyB0aGUgQGxpbmsKICogIGluc3RhbmNlIGluc3RhbmNlQGVuZGxpbmsgaGVscGVyIGlzIHRoYXQgdGhleSB0YWtlIGNhcmUgb2YgdGhlIGNvbXBsZXgKICogIEdFVE5FWFQgcHJvY2Vzc2luZyBlbnRpcmVseSBmb3IgeW91IGFuZCBoYW5kIHlvdSBldmVyeXRoaW5nIHlvdQogKiAgbmVlZCB0byBtZXJlbHkgcmV0dXJuIHRoZSBkYXRhIGFzIGlmIGl0IHdhcyBhIEdFVCByZXF1ZXN0LiAgTXVjaAogKiAgbGVzcyBjb2RlIGFuZCBoYWlyIHB1bGxpbmcuICBJJ3ZlIHB1bGxlZCBhbGwgbXkgaGFpciBvdXQgdG8gaGVscAogKiAgeW91IHNvIHRoYXQgb25seSBvbmUgb2YgdXMgaGFzIHRvIGJlIGJhbGQuCiAqCiAqIEB7CiAqLwoKLyoqIENyZWF0ZXMgYSBNSUIgaGFuZGxlciBzdHJ1Y3R1cmUuCiAqICBUaGUgbmV3IHN0cnVjdHVyZSBpcyBhbGxvY2F0ZWQgYW5kIGZpbGxlZCB1c2luZyB0aGUgZ2l2ZW4gbmFtZQogKiAgYW5kIGFjY2VzcyBtZXRob2QuCiAqICBUaGUgcmV0dXJuZWQgaGFuZGxlciBzaG91bGQgdGhlbiBiZSBAbGluayBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKQogKiAgcmVnaXN0ZXJlZCBAZW5kbGluay4KICoKICogIEBwYXJhbSBuYW1lIGlzIHRoZSBoYW5kbGVyIG5hbWUgYW5kIGlzIGNvcGllZCB0aGVuIGFzc2lnbmVkIHRvCiAqICAgICAgICAgICAgICBuZXRzbm1wX21pYl9oYW5kbGVyLT5oYW5kbGVyX25hbWUKICoKICogIEBwYXJhbSBoYW5kbGVyX2FjY2Vzc19tZXRob2QgaXMgYSBmdW5jdGlvbiBwb2ludGVyIHVzZWQgYXMgdGhlIGFjY2VzcwogKgkgICBtZXRob2QgZm9yIHRoaXMgaGFuZGxlciByZWdpc3RyYXRpb24gaW5zdGFuY2UgZm9yIHdoYXRldmVyIHJlcXVpcmVkCiAqICAgICAgICAgbmVlZHMuCiAqCiAqICBAcmV0dXJuIGEgcG9pbnRlciB0byBhIHBvcHVsYXRlZCBuZXRzbm1wX21pYl9oYW5kbGVyIHN0cnVjdCB0byBiZQogKiAgICAgICAgICByZWdpc3RlcmVkCiAqCiAqICBAc2VlIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKCkKICogIEBzZWUgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKCkKICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKiBoYW5kbGVyX2FjY2Vzc19tZXRob2QpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKnJldCA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9taWJfaGFuZGxlcik7CiAgICBpZiAocmV0KSB7CiAgICAgICAgcmV0LT5hY2Nlc3NfbWV0aG9kID0gaGFuZGxlcl9hY2Nlc3NfbWV0aG9kOwogICAgICAgIGlmIChOVUxMICE9IG5hbWUpIHsKICAgICAgICAgICAgcmV0LT5oYW5kbGVyX25hbWUgPSBzdHJkdXAobmFtZSk7CiAgICAgICAgICAgIGlmIChOVUxMID09IHJldC0+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+bW9kZXMgJiBIQU5ETEVSX0NBTl9HRVRBTkRHRVRORVhUKSkKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7ICAgIC8qIGxlZ2FsICovCiAgICAgICAgYnJlYWs7CgojaWZuZGVmIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVAogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgIGNhc2UgTU9ERV9TRVRfQ09NTUlUOgogICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgIGlmICghKHJlZ2luZm8tPm1vZGVzICYgSEFORExFUl9DQU5fU0VUKSkgewogICAgICAgICAgICBmb3IgKDsgcmVxdWVzdHM7IHJlcXVlc3RzID0gcmVxdWVzdHMtPm5leHQpIHsKICAgICAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX05PVFdSSVRBQkxFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQgKi8KCiAgICBkZWZhdWx0OgogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJ1bmtub3duIG1vZGUgaW4gbmV0c25tcF9jYWxsX2hhbmRsZXJzISBidWchXG4iKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQogICAgREVCVUdNU0dUTCgoImhhbmRsZXI6Y2FsbGluZyIsICJtYWluIGhhbmRsZXIgJXNcbiIsCiAgICAgICAgICAgICAgICByZWdpbmZvLT5oYW5kbGVyLT5oYW5kbGVyX25hbWUpKTsKCiAgICBmb3IgKHJlcXVlc3QgPSByZXF1ZXN0cyA7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgcmVxdWVzdC0+cHJvY2Vzc2VkID0gMDsKICAgIH0KCiAgICBzdGF0dXMgPSBuZXRzbm1wX2NhbGxfaGFuZGxlcihyZWdpbmZvLT5oYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLCByZXF1ZXN0cyk7CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyoqIEBwcml2YXRlCiAqICBDYWxscyB0aGUgbmV4dCBNSUIgaGFuZGxlciBpbiB0aGUgY2hhaW4sIGFmdGVyIHRoZSBjdXJyZW50IG9uZS4KICogIFRoZSBnaXZlbiBhcmd1bWVudHMgYW5kIE1JQiBoYW5kbGVyIGFyZSBjaGVja2VkCiAqICBmb3Igc2FuaXR5LCB0aGVuIHRoZSBuZXh0IGhhbmRsZXIgaXMgY2FsbGVkLgogKgogKiAgQHJldHVybiBSZXR1cm5zIFNOTVBFUlJfU1VDQ0VTUyBvciBTTk1QX0VSUl8qIGVycm9yIGNvZGUuCiAqLwpORVRTTk1QX0lOTElORSBpbnQKbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpjdXJyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgaWYgKGN1cnJlbnQgPT0gTlVMTCB8fCByZWdpbmZvID09IE5VTEwgfHwgcmVxaW5mbyA9PSBOVUxMIHx8CiAgICAgICAgcmVxdWVzdHMgPT0gTlVMTCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKCkgY2FsbGVkIGlsbGVnYWxseVxuIik7CiAgICAgICAgbmV0c25tcF9hc3NlcnQoY3VycmVudCAhPSBOVUxMKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcWluZm8gIT0gTlVMTCk7CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVxdWVzdHMgIT0gTlVMTCk7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KCiAgICByZXR1cm4gbmV0c25tcF9jYWxsX2hhbmRsZXIoY3VycmVudC0+bmV4dCwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwp9CgovKiogQHByaXZhdGUKICogIENhbGxzIHRoZSBuZXh0IE1JQiBoYW5kbGVyIGluIHRoZSBjaGFpbiwgYWZ0ZXIgdGhlIGN1cnJlbnQgb25lLgogKiAgVGhlIGdpdmVuIGFyZ3VtZW50cyBhbmQgTUlCIGhhbmRsZXIgYXJlIG5vdCB2YWxpZGF0ZWQgYmVmb3JlCiAqICB0aGUgY2FsbCwgb25seSByZXF1ZXN0IGlzIGNoZWNrZWQuCiAqCiAqICBAcmV0dXJuIFJldHVybnMgU05NUEVSUl9TVUNDRVNTIG9yIFNOTVBfRVJSXyogZXJyb3IgY29kZS4KICovCm5ldHNubXBfZmVhdHVyZV9jaGlsZF9vZihuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyX29uZV9yZXF1ZXN0LG5ldHNubXBfdW51c2VkKQojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfTkVUU05NUF9DQUxMX05FWFRfSEFORExFUl9PTkVfUkVRVUVTVApORVRTTk1QX0lOTElORSBpbnQKbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcl9vbmVfcmVxdWVzdChuZXRzbm1wX21pYl9oYW5kbGVyICpjdXJyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKICAgIGludCByZXQ7CiAgICAKICAgIGlmICghcmVxdWVzdHMpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9jYWxsX25leHRfaGFuZGxlcl9PTkVfUkVRVUVTVCgpIGNhbGxlZCBpbGxlZ2FsbHlcbiIpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3RzICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgcmVxdWVzdCA9IHJlcXVlc3RzLT5uZXh0OwogICAgcmVxdWVzdHMtPm5leHQgPSBOVUxMOwogICAgcmV0ID0gbmV0c25tcF9jYWxsX2hhbmRsZXIoY3VycmVudC0+bmV4dCwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwogICAgcmVxdWVzdHMtPm5leHQgPSByZXF1ZXN0OwogICAgcmV0dXJuIHJldDsKfQojZW5kaWYgLyogTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9ORVRTTk1QX0NBTExfTkVYVF9IQU5ETEVSX09ORV9SRVFVRVNUICovCgovKiogRGVhbGxvY2F0ZXMgcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIGhhbmRsZXIuCiAqICBUaGUgaGFuZGxlciBpcyByZW1vdmVkIGZyb20gY2hhaW4gYW5kIHRoZW4gZnJlZWQuCiAqICBBZnRlciBjYWxsaW5nIHRoaXMgZnVuY3Rpb24sIHRoZSBoYW5kbGVyIHBvaW50ZXIgaXMgaW52YWxpZAogKiAgYW5kIHNob3VsZCBiZSBzZXQgdG8gTlVMTC4KICoKICogIEBwYXJhbSBoYW5kbGVyIGlzIHRoZSBNSUIgSGFuZGxlciB0byBiZSBmcmVlZAogKi8Kdm9pZApuZXRzbm1wX2hhbmRsZXJfZnJlZShuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyKQp7CiAgICBpZiAoaGFuZGxlciAhPSBOVUxMKSB7CiAgICAgICAgaWYgKGhhbmRsZXItPm5leHQgIT0gTlVMTCkgewogICAgICAgICAgICAvKiogbWFrZSBzdXJlIHdlIGFyZW4ndCBwb2ludGluZyB0byBvdXJzZWx2ZXMuICAqLwogICAgICAgICAgICBuZXRzbm1wX2Fzc2VydChoYW5kbGVyICE9IGhhbmRsZXItPm5leHQpOyAvKiBidWdzIGNhdWdodDogMSAqLwogICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfZnJlZShoYW5kbGVyLT5uZXh0KTsKICAgICAgICAgICAgaGFuZGxlci0+bmV4dCA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmICgoaGFuZGxlci0+bXl2b2lkICE9IE5VTEwpICYmIChoYW5kbGVyLT5kYXRhX2ZyZWUgIT0gTlVMTCkpCiAgICAgICAgewogICAgICAgICAgICBoYW5kbGVyLT5kYXRhX2ZyZWUoaGFuZGxlci0+bXl2b2lkKTsKICAgICAgICB9CiAgICAgICAgU05NUF9GUkVFKGhhbmRsZXItPmhhbmRsZXJfbmFtZSk7CiAgICAgICAgU05NUF9GUkVFKGhhbmRsZXIpOwogICAgfQp9CgovKiogRHVwbGljYXRlcyBhIE1JQiBoYW5kbGVyIGFuZCBhbGwgc3Vic2VxdWVudCBoYW5kbGVycy4KICogIENyZWF0ZXMgYSBjb3B5IG9mIGFsbCBkYXRhIGluIGdpdmVuIGhhbmRsZXJzIGNoYWluLgogKgogKiAgQHBhcmFtIGhhbmRsZXIgaXMgdGhlIE1JQiBIYW5kbGVyIHRvIGJlIGR1cGxpY2F0ZWQKICoKICogIEByZXR1cm4gUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIGNvbXBsZXRlIGNvcHksCiAqICAgICAgICAgb3IgTlVMTCBpZiBhbnkgcHJvYmxlbSBvY2N1cmVkLgogKgogKiBAc2VlIF9jbG9uZV9oYW5kbGVyKCkKICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2hhbmRsZXJfZHVwKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmggPSBOVUxMOwoKICAgIGlmICghaGFuZGxlcikKICAgICAgICBnb3RvIGVycjsKCiAgICBoID0gX2Nsb25lX2hhbmRsZXIoaGFuZGxlcik7CiAgICBpZiAoIWgpCiAgICAgICAgZ290byBlcnI7CgogICAgLyoKICAgICAqIFByb3ZpZGluZyBhIGNsb25lIGZ1bmN0aW9uIHdpdGhvdXQgYSBmcmVlIGZ1bmN0aW9uIGlzIGFza2luZyBmb3IKICAgICAqIG1lbW9yeSBsZWFrcywgYW5kIHByb3ZpZGluZyBhIGZyZWUgZnVuY3Rpb24gd2l0aG91dCBjbG9uZSBmdW5jdGlvbgogICAgICogaXMgYXNraW5nIGZvciBtZW1vcnkgY29ycnVwdGlvbi4gSGVuY2UgdGhlIGxvZyBzdGF0ZW1lbnQgYmVsb3cuCiAgICAgKi8KICAgIGlmICghIWhhbmRsZXItPmRhdGFfY2xvbmUgIT0gISFoYW5kbGVyLT5kYXRhX2ZyZWUpCiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgImRhdGFfY2xvbmUgLyBkYXRhX2ZyZWUgaW5jb25zaXN0ZW50ICglcylcbiIsCiAgICAgICAgICAgICAgICAgaGFuZGxlci0+aGFuZGxlcl9uYW1lKTsKICAgIGlmIChoYW5kbGVyLT5teXZvaWQgJiYgaGFuZGxlci0+ZGF0YV9jbG9uZSkgewogICAgICAgIGgtPm15dm9pZCA9IGhhbmRsZXItPmRhdGFfY2xvbmUoaGFuZGxlci0+bXl2b2lkKTsKICAgICAgICBpZiAoIWgtPm15dm9pZCkKICAgICAgICAgICAgZ290byBlcnI7CiAgICB9IGVsc2UKICAgICAgICBoLT5teXZvaWQgPSBoYW5kbGVyLT5teXZvaWQ7CiAgICBoLT5kYXRhX2Nsb25lID0gaGFuZGxlci0+ZGF0YV9jbG9uZTsKICAgIGgtPmRhdGFfZnJlZSA9IGhhbmRsZXItPmRhdGFfZnJlZTsKCiAgICBpZiAoaGFuZGxlci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgaC0+bmV4dCA9IG5ldHNubXBfaGFuZGxlcl9kdXAoaGFuZGxlci0+bmV4dCk7CiAgICAgICAgaWYgKCFoLT5uZXh0KQogICAgICAgICAgICBnb3RvIGVycjsKICAgICAgICBoLT5uZXh0LT5wcmV2ID0gaDsKICAgIH0KICAgIGgtPnByZXYgPSBOVUxMOwogICAgcmV0dXJuIGg7CgplcnI6CiAgICBuZXRzbm1wX2hhbmRsZXJfZnJlZShoKTsKICAgIHJldHVybiBOVUxMOwp9CgovKiogRnJlZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIGEgaGFuZGxlciByZWdpc3RyYXRpb24gb2JqZWN0LgogKiAgVGhlIHJlZ2lzdHJhdGlvbiBvYmplY3QgYW5kIGFsbCBNSUIgSGFuZGxlcnMgaW4gdGhlIGNoYWluIGFyZQogKiAgZnJlZWQuIFdoZW4gdGhlIGZ1bmN0aW9uIGVuZHMsIGdpdmVuIHBvaW50ZXIgaXMgbm8gbG9uZ2VyIHZhbGlkCiAqICBhbmQgc2hvdWxkIGJlIHNldCB0byBOVUxMLgogKgogKiAgQHBhcmFtIHJlZ2luZm8gaXMgdGhlIGhhbmRsZXIgcmVnaXN0cmF0aW9uIG9iamVjdCB0byBiZSBmcmVlZAogKi8Kdm9pZApuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgaWYgKHJlZ2luZm8gIT0gTlVMTCkgewogICAgICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKHJlZ2luZm8tPmhhbmRsZXIpOwogICAgICAgIFNOTVBfRlJFRShyZWdpbmZvLT5oYW5kbGVyTmFtZSk7CiAgICAgICAgU05NUF9GUkVFKHJlZ2luZm8tPmNvbnRleHROYW1lKTsKICAgICAgICBTTk1QX0ZSRUUocmVnaW5mby0+cm9vdG9pZCk7CiAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4gPSAwOwogICAgICAgIFNOTVBfRlJFRShyZWdpbmZvKTsKICAgIH0KfQoKLyoqIER1cGxpY2F0ZXMgaGFuZGxlciByZWdpc3RyYXRpb24gb2JqZWN0IGFuZCBhbGwgc3Vic2VxdWVudCBoYW5kbGVycy4KICogIENyZWF0ZXMgYSBjb3B5IG9mIHRoZSBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBvYmplY3QgYW5kIGFsbCBpdHMgZGF0YS4KICoKICogIEBwYXJhbSByZWdpbmZvIGlzIHRoZSBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBvYmplY3QgdG8gYmUgZHVwbGljYXRlZAogKgogKiAgQHJldHVybiBSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgY29tcGxldGUgY29weSwKICogICAgICAgICBvciBOVUxMIGlmIGFueSBwcm9ibGVtIG9jY3VyZWQuCiAqCiAqIEBzZWUgbmV0c25tcF9oYW5kbGVyX2R1cCgpCiAqLwpuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICoKbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbl9kdXAobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqciA9IE5VTEw7CgogICAgaWYgKHJlZ2luZm8gPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKCiAgICByID0gKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKikgY2FsbG9jKDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbikpOwoKICAgIGlmIChyICE9IE5VTEwpIHsKICAgICAgICByLT5tb2RlcyA9IHJlZ2luZm8tPm1vZGVzOwogICAgICAgIHItPnByaW9yaXR5ID0gcmVnaW5mby0+cHJpb3JpdHk7CiAgICAgICAgci0+cmFuZ2Vfc3ViaWQgPSByZWdpbmZvLT5yYW5nZV9zdWJpZDsKICAgICAgICByLT50aW1lb3V0ID0gcmVnaW5mby0+dGltZW91dDsKICAgICAgICByLT5yYW5nZV91Ym91bmQgPSByZWdpbmZvLT5yYW5nZV91Ym91bmQ7CiAgICAgICAgci0+cm9vdG9pZF9sZW4gPSByZWdpbmZvLT5yb290b2lkX2xlbjsKCiAgICAgICAgaWYgKHJlZ2luZm8tPmhhbmRsZXJOYW1lICE9IE5VTEwpIHsKICAgICAgICAgICAgci0+aGFuZGxlck5hbWUgPSBzdHJkdXAocmVnaW5mby0+aGFuZGxlck5hbWUpOwogICAgICAgICAgICBpZiAoci0+aGFuZGxlck5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbl9mcmVlKHIpOwogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChyZWdpbmZvLT5jb250ZXh0TmFtZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHItPmNvbnRleHROYW1lID0gc3RyZHVwKHJlZ2luZm8tPmNvbnRleHROYW1lKTsKICAgICAgICAgICAgaWYgKHItPmNvbnRleHROYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fZnJlZShyKTsKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAocmVnaW5mby0+cm9vdG9pZCAhPSBOVUxMKSB7CiAgICAgICAgICAgIHItPnJvb3RvaWQgPQogICAgICAgICAgICAgICAgc25tcF9kdXBsaWNhdGVfb2JqaWQocmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4pOwogICAgICAgICAgICBpZiAoci0+cm9vdG9pZCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUocik7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgci0+aGFuZGxlciA9IG5ldHNubXBfaGFuZGxlcl9kdXAocmVnaW5mby0+aGFuZGxlcik7CiAgICAgICAgaWYgKHItPmhhbmRsZXIgPT0gTlVMTCkgewogICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUocik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQoKLyoqIENyZWF0ZXMgYSBjYWNoZSBvZiBpbmZvcm1hdGlvbiB3aGljaCBjYW4gYmUgc2F2ZWQgZm9yIGZ1dHVyZSByZWZlcmVuY2UuCiAqICBUaGUgY2FjaGUgaXMgZmlsbGVkIHdpdGggcG9pbnRlcnMgZnJvbSBwYXJhbWV0ZXJzLiBOb3RlIHRoYXQKICogIHRoZSBpbnB1dCBzdHJ1Y3R1cmVzIGFyZSBub3QgZHVwbGljYXRlZCwgYnV0IHB1dCBkaXJlY3RseSBpbnRvCiAqICB0aGUgbmV3IGNhY2hlIHN0cnVjdC4KICogIFVzZSBuZXRzbm1wX2hhbmRsZXJfY2hlY2tfY2FjaGUoKSBsYXRlciB0byBtYWtlIHN1cmUgaXQncyBzdGlsbAogKiAgdmFsaWQgYmVmb3JlIHJlZmVyZW5jaW5nIGl0IGluIHRoZSBmdXR1cmUuCiAqCiAqIEBzZWUgbmV0c25tcF9oYW5kbGVyX2NoZWNrX2NhY2hlKCkKICogQHNlZSBuZXRzbm1wX2ZyZWVfZGVsZWdhdGVkX2NhY2hlKCkKICovCk5FVFNOTVBfSU5MSU5FIG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICoKbmV0c25tcF9jcmVhdGVfZGVsZWdhdGVkX2NhY2hlKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpsb2NhbGluZm8pCnsKICAgIG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICpyZXQ7CgogICAgcmV0ID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSk7CiAgICBpZiAocmV0KSB7CiAgICAgICAgcmV0LT50cmFuc2FjdGlvbl9pZCA9IHJlcWluZm8tPmFzcC0+cGR1LT50cmFuc2lkOwogICAgICAgIHJldC0+aGFuZGxlciA9IGhhbmRsZXI7CiAgICAgICAgcmV0LT5yZWdpbmZvID0gcmVnaW5mbzsKICAgICAgICByZXQtPnJlcWluZm8gPSByZXFpbmZvOwogICAgICAgIHJldC0+cmVxdWVzdHMgPSByZXF1ZXN0czsKICAgICAgICByZXQtPmxvY2FsaW5mbyA9IGxvY2FsaW5mbzsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKiBDaGVjayBpZiBhIGdpdmVuIGRlbGVnYXRlZCBjYWNoZSBpcyBzdGlsbCB2YWxpZC4KICogIFRoZSBjYWNoZSBpcyB2YWxpZCBpZiBpdCdzIGEgcGFydCBvZiB0cmFuc2FjdGlvbgogKiAgKGllLCB0aGUgYWdlbnQgc3RpbGwgY29uc2lkZXJzIGl0IHRvIGJlIGFuIG91dHN0YW5kaW5nIHJlcXVlc3QpLgogKgogKiAgQHBhcmFtIGRjYWNoZSBpcyB0aGUgZGVsZWdhdGVkIGNhY2hlIHRvIGJlIGNoZWNrZWQuCiAqCiAqICBAcmV0dXJuIFJldHVybnMgdGhlIGNhY2hlIHBvaW50ZXIgaWYgaXQgaXMgc3RpbGwgdmFsaWQsIE5VTEwgb3RoZXJ3aXNlLgogKgogKiBAc2VlIG5ldHNubXBfY3JlYXRlX2RlbGVnYXRlZF9jYWNoZSgpCiAqIEBzZWUgbmV0c25tcF9mcmVlX2RlbGVnYXRlZF9jYWNoZSgpCiAqLwpORVRTTk1QX0lOTElORSBuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqCm5ldHNubXBfaGFuZGxlcl9jaGVja19jYWNoZShuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqZGNhY2hlKQp7CiAgICBpZiAoIWRjYWNoZSkKICAgICAgICByZXR1cm4gZGNhY2hlOwoKICAgIGlmIChuZXRzbm1wX2NoZWNrX3RyYW5zYWN0aW9uX2lkKGRjYWNoZS0+dHJhbnNhY3Rpb25faWQpID09CiAgICAgICAgU05NUEVSUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBkY2FjaGU7CgogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBGcmVlIGEgY2FjaGUgb25jZSBpdCdzIG5vIGxvbmdlciB1c2VkLgogKiAgRGVsZXRlcyB0aGUgZGF0YSBhbGxvY2F0ZWQgYnkgbmV0c25tcF9jcmVhdGVfZGVsZWdhdGVkX2NhY2hlKCkuCiAqICBTdHJ1Y3R1cmVzIHdoaWNoIHdlcmUgbm90IGFsbG9jYXRlZCBieSBuZXRzbm1wX2NyZWF0ZV9kZWxlZ2F0ZWRfY2FjaGUoKQogKiAgYXJlIG5vdCBmcmVlZCAocG9pbnRlcnMgYXJlIGRyb3BwZWQpLgogKgogKiAgQHBhcmFtIGRjYWNoZSBpcyB0aGUgZGVsZWdhdGVkIGNhY2hlIHRvIGJlIGZyZWVkLgogKgogKiBAc2VlIG5ldHNubXBfY3JlYXRlX2RlbGVnYXRlZF9jYWNoZSgpCiAqIEBzZWUgbmV0c25tcF9oYW5kbGVyX2NoZWNrX2NhY2hlKCkKICovCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9mcmVlX2RlbGVnYXRlZF9jYWNoZShuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqZGNhY2hlKQp7CiAgICAvKgogICAgICogcmlnaHQgbm93LCBubyBleHRyYSBkYXRhIGlzIHRoZXJlIHRoYXQgbmVlZHMgdG8gYmUgZnJlZWQgCiAgICAgKi8KICAgIGlmIChkY2FjaGUpCiAgICAgICAgU05NUF9GUkVFKGRjYWNoZSk7CgogICAgcmV0dXJuOwp9CgoKI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX0hBTkRMRVJfTUFSS19SRVFVRVNUU19BU19ERUxFR0FURUQKLyoqIFNldHMgYSBsaXN0IG9mIHJlcXVlc3RzIGFzIGRlbGVnYXRlZCBvciBub3QgZGVsZWdhdGVkLgogKiAgU3dlZXBzIHRocm91Z2ggZ2l2ZW4gY2hhaW4gb2YgcmVxdWVzdHMgYW5kIHNldHMgJ2RlbGVnYXRlZCcKICogIGZsYWcgYWNjb3JkaW5nbHkgdG8gdGhlIGlzZGVsZWdhZGVkIHBhcmFtZXRlci4KICoKICogIEBwYXJhbSByZXF1ZXN0cyBSZXF1ZXN0IGxpc3QuCiAqICBAcGFyYW0gaXNkZWxlZ2F0ZWQgTmV3IHZhbHVlIG9mIHRoZSAnZGVsZWdhdGVkJyBmbGFnLgogKi8Kdm9pZApuZXRzbm1wX2hhbmRsZXJfbWFya19yZXF1ZXN0c19hc19kZWxlZ2F0ZWQobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlzZGVsZWdhdGVkKQp7CiAgICB3aGlsZSAocmVxdWVzdHMpIHsKICAgICAgICByZXF1ZXN0cy0+ZGVsZWdhdGVkID0gaXNkZWxlZ2F0ZWQ7CiAgICAgICAgcmVxdWVzdHMgPSByZXF1ZXN0cy0+bmV4dDsKICAgIH0KfQojZW5kaWYgLyogTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9IQU5ETEVSX01BUktfUkVRVUVTVFNfQVNfREVMRUdBVEVEICovCgovKiogQWRkcyBkYXRhIGZyb20gbm9kZSBsaXN0IHRvIHRoZSByZXF1ZXN0IGluZm9ybWF0aW9uIHN0cnVjdHVyZS4KICogIERhdGEgaW4gdGhlIHJlcXVlc3QgY2FuIGJlIGxhdGVyIGV4dHJhY3RlZCBhbmQgdXNlZCBieSBzdWJtb2R1bGVzLgogKgogKiBAcGFyYW0gcmVxdWVzdCBEZXN0aW5hdGlvbiByZXF1ZXN0IGluZm9ybWF0aW9uIHN0cnVjdHVyZS4KICoKICogQHBhcmFtIG5vZGUgVGhlIGRhdGEgdG8gYmUgYWRkZWQgdG8gdGhlIGxpbmtlZCBsaXN0CiAqICAgICAgICAgICAgIHJlcXVlc3QtPnBhcmVudF9kYXRhLgogKgogKiBAc2VlIG5ldHNubXBfcmVxdWVzdF9yZW1vdmVfbGlzdF9kYXRhKCkKICogQHNlZSBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YSgpCiAqLwpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2RhdGFfbGlzdCAqbm9kZSkKewogICAgaWYgKHJlcXVlc3QpIHsKICAgICAgICBpZiAocmVxdWVzdC0+cGFyZW50X2RhdGEpCiAgICAgICAgICAgIG5ldHNubXBfYWRkX2xpc3RfZGF0YSgmcmVxdWVzdC0+cGFyZW50X2RhdGEsIG5vZGUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmVxdWVzdC0+cGFyZW50X2RhdGEgPSBub2RlOwogICAgfQp9CgovKiogUmVtb3ZlcyBhbGwgZGF0YSBmcm9tIGEgcmVxdWVzdC4KICoKICogQHBhcmFtIHJlcXVlc3QgdGhlIG5ldHNubXAgcmVxdWVzdCBpbmZvIHN0cnVjdHVyZQogKgogKiBAcGFyYW0gbmFtZSB0aGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBwcmV2aW91c2x5IGFkZGVkIGRhdGEKICoKICogQHJldHVybiAwIG9uIHN1Y2Nlc3NmdWwgZmluZC1hbmQtZGVsZXRlLCAxIG90aGVyd2lzZS4KICoKICogQHNlZSBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YSgpCiAqIEBzZWUgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEoKQogKi8KTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfcmVxdWVzdF9yZW1vdmVfbGlzdF9kYXRhKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICBpZiAoKE5VTEwgPT0gcmVxdWVzdCkgfHwgKE5VTEwgPT1yZXF1ZXN0LT5wYXJlbnRfZGF0YSkpCiAgICAgICAgcmV0dXJuIDE7CgogICAgcmV0dXJuIG5ldHNubXBfcmVtb3ZlX2xpc3Rfbm9kZSgmcmVxdWVzdC0+cGFyZW50X2RhdGEsIG5hbWUpOwp9CgovKiogRXh0cmFjdHMgZGF0YSBmcm9tIGEgcmVxdWVzdC4KICogIFJldHJpZXZlcyBkYXRhIHRoYXQgd2FzIHByZXZpb3VzbHkgYWRkZWQgdG8gdGhlIHJlcXVlc3QsCiAqICB1c3VhbGx5IGJ5IGEgcGFyZW50IG1vZHVsZS4KICoKICogQHBhcmFtIHJlcXVlc3QgU291cmNlIHJlcXVlc3QgaW5mb3JtYXRpb24gc3RydWN0dXJlLgogKgogKiBAcGFyYW0gbmFtZSBVc2VkIHRvIGNvbXBhcmUgYWdhaW5zdCB0aGUgcmVxdWVzdC0+cGFyZW50X2RhdGEtPm5hbWUgdmFsdWU7CiAqICAgICAgICAgICAgIGlmIGEgbWF0Y2ggaXMgZm91bmQsIHJlcXVlc3QtPnBhcmVudF9kYXRhLT5kYXRhIGlzIHJldHVybmVkLgogKgogKiBAcmV0dXJuIEdpdmVzIGEgdm9pZCBwb2ludGVyKHJlcXVlc3QtPnBhcmVudF9kYXRhLT5kYXRhKTsgTlVMTCBpcwogKiAgICAgICAgIHJldHVybmVkIGlmIHNvdXJjZSBkYXRhIGlzIE5VTEwgb3IgdGhlIG9iamVjdCBpcyBub3QgZm91bmQuCiAqCiAqIEBzZWUgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEoKQogKiBAc2VlIG5ldHNubXBfcmVxdWVzdF9yZW1vdmVfbGlzdF9kYXRhKCkKICovCnZvaWQgICAgKgpuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgaWYgKHJlcXVlc3QpCiAgICAgICAgcmV0dXJuIG5ldHNubXBfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LT5wYXJlbnRfZGF0YSwgbmFtZSk7CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqIEZyZWUgdGhlIGV4dHJhIGRhdGEgc3RvcmVkIGluIGEgcmVxdWVzdC4KICogIERlbGV0ZXMgdGhlIGRhdGEgaW4gZ2l2ZW4gcmVxdWVzdCBvbmx5LiBPdGhlciBjaGFpbiBpdGVtcwogKiAgYXJlIHVuYWZmZWN0ZWQuCiAqCiAqIEBwYXJhbSByZXF1ZXN0IFJlcXVlc3QgaW5mb3JtYXRpb24gc3RydWN0dXJlIHRvIGJlIG1vZGlmaWVkLgogKgogKiBAc2VlIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKCkKICogQHNlZSBuZXRzbm1wX2ZyZWVfbGlzdF9kYXRhKCkKICovCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXQobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QpCnsKICAgIGlmIChyZXF1ZXN0KQogICAgICAgIG5ldHNubXBfZnJlZV9saXN0X2RhdGEocmVxdWVzdC0+cGFyZW50X2RhdGEpOwp9CgovKiogRnJlZSB0aGUgZXh0cmEgZGF0YSBzdG9yZWQgaW4gYSBidW5jaCBvZiByZXF1ZXN0cy4KICogIERlbGV0ZXMgYWxsIGRhdGEgaW4gdGhlIGNoYWluIGluc2lkZSByZXF1ZXN0LgogKgogKiBAcGFyYW0gcmVxdWVzdCBSZXF1ZXN0IGluZm9ybWF0aW9uIHN0cnVjdHVyZSB0byBiZSBtb2RpZmllZC4KICoKICogQHNlZSBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YSgpCiAqIEBzZWUgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXQoKQogKi8KTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QpCnsKICAgIGlmIChyZXF1ZXN0ICYmIHJlcXVlc3QtPnBhcmVudF9kYXRhKSB7CiAgICAgICAgbmV0c25tcF9mcmVlX2FsbF9saXN0X2RhdGEocmVxdWVzdC0+cGFyZW50X2RhdGEpOwogICAgICAgIHJlcXVlc3QtPnBhcmVudF9kYXRhID0gTlVMTDsKICAgIH0KfQoKLyoqIFJldHVybnMgYSBNSUIgaGFuZGxlciBmcm9tIGEgY2hhaW4gYmFzZWQgb24gdGhlIG5hbWUuCiAqCiAqIEBwYXJhbSByZWdpbmZvIEhhbmRsZXIgcmVnaXN0cmF0aW9uIHN0cnVjdCB3aGljaCBjb250YWlucyB0aGUgY2hhaW4uCiAqCiAqIEBwYXJhbSBuYW1lIFRhcmdldCBNSUIgSGFuZGxlciBuYW1lIHN0cmluZy4gVGhlIG5hbWUgaXMgY2FzZQogKiAgICAgICAgc2Vuc2l0aXZlLgogKgogKiBAcmV0dXJuIFRoZSBNSUIgSGFuZGxlciBpcyByZXR1cm5lZCwgb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqCiAqIEBzZWUgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEoKQogKi8KbmV0c25tcF9taWJfaGFuZGxlciAqCm5ldHNubXBfZmluZF9oYW5kbGVyX2J5X25hbWUobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICppdDsKICAgIGlmIChyZWdpbmZvID09IE5VTEwgfHwgbmFtZSA9PSBOVUxMICkKICAgICAgICByZXR1cm4gTlVMTDsKICAgIGZvciAoaXQgPSByZWdpbmZvLT5oYW5kbGVyOyBpdDsgaXQgPSBpdC0+bmV4dCkgewogICAgICAgIGlmIChzdHJjbXAoaXQtPmhhbmRsZXJfbmFtZSwgbmFtZSkgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gaXQ7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBSZXR1cm5zIGEgaGFuZGxlcidzIHZvaWQgcG9pbnRlciBmcm9tIGEgY2hhaW4gYmFzZWQgb24gdGhlIG5hbWUuCiAqCiAqIEB3YXJuaW5nIFRoZSB2b2lkIHBvaW50ZXIgZGF0YSBtYXkgY2hhbmdlIGFzIGEgaGFuZGxlciBldm9sdmVzLgogKiAgICAgICAgSGFuZGxlcnMgc2hvdWxkIHJlYWxseSBhZHZlcnRpc2Ugc29tZSBmdW5jdGlvbiBmb3IgeW91CiAqICAgICAgICB0byB1c2UgaW5zdGVhZC4KICoKICogQHBhcmFtIHJlZ2luZm8gSGFuZGxlciByZWdpc3RyYXRpb24gc3RydWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBjaGFpbi4KICoKICogQHBhcmFtIG5hbWUgVGFyZ2V0IE1JQiBIYW5kbGVyIG5hbWUgc3RyaW5nLiBUaGUgbmFtZSBpcyBjYXNlCiAqICAgICAgICBzZW5zaXRpdmUuCiAqCiAqIEByZXR1cm4gVGhlIE1JQiBIYW5kbGVyJ3Mgdm9pZCAqIHBvaW50ZXIgaXMgcmV0dXJuZWQsCiAqICAgICAgICBvciBOVUxMIGlmIHRoZSBoYW5kbGVyIGlzIG5vdCBmb3VuZC4KICoKICogQHNlZSBuZXRzbm1wX2ZpbmRfaGFuZGxlcl9ieV9uYW1lKCkKICovCnZvaWQgICAgICAgICAgICoKbmV0c25tcF9maW5kX2hhbmRsZXJfZGF0YV9ieV9uYW1lKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICppdCA9IG5ldHNubXBfZmluZF9oYW5kbGVyX2J5X25hbWUocmVnaW5mbywgbmFtZSk7CiAgICBpZiAoaXQpCiAgICAgICAgcmV0dXJuIGl0LT5teXZvaWQ7CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqIEBwcml2YXRlCiAqICBDbG9uZXMgYSBNSUIgSGFuZGxlciB3aXRoIGl0cyBiYXNpYyBwcm9wZXJ0aWVzLgogKiAgQ3JlYXRlcyBhIGNvcHkgb2YgdGhlIGdpdmVuIE1JQiBIYW5kbGVyLiBDb3BpZXMgbmFtZSwgZmxhZ3MgYW5kCiAqICBhY2Nlc3MgbWV0aG9kcyBvbmx5OyBub3QgbXl2b2lkLgogKgogKiAgQHNlZSBuZXRzbm1wX2hhbmRsZXJfZHVwKCkKICovCnN0YXRpYyBuZXRzbm1wX21pYl9oYW5kbGVyICoKX2Nsb25lX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaXQpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmR1cDsKCiAgICBpZihOVUxMID09IGl0KQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGR1cCA9IG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoaXQtPmhhbmRsZXJfbmFtZSwgaXQtPmFjY2Vzc19tZXRob2QpOwogICAgaWYoTlVMTCAhPSBkdXApCiAgICAgICAgZHVwLT5mbGFncyA9IGl0LT5mbGFnczsKCiAgICByZXR1cm4gZHVwOwp9CgpzdGF0aWMgbmV0c25tcF9kYXRhX2xpc3QgKmhhbmRsZXJfcmVnID0gTlVMTDsKCnZvaWQKaGFuZGxlcl9mcmVlX2NhbGxiYWNrKHZvaWQgKmhhbmRsZXIpCnsKICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKChuZXRzbm1wX21pYl9oYW5kbGVyICopaGFuZGxlcik7Cn0KCi8qKiBSZWdpc3RlcnMgYSBnaXZlbiBoYW5kbGVyIGJ5IG5hbWUsIHNvIHRoYXQgaXQgY2FuIGJlIGZvdW5kIGVhc2lseSBsYXRlci4KICogIFBvaW50ZXIgdG8gdGhlIGhhbmRsZXIgaXMgcHV0IGludG8gYSBsaXN0IHdoZXJlIGl0IGNhbiBiZSBlYXNpbHkgbG9jYXRlZAogKiAgYXQgYW55IHRpbWUuCiAqCiAqIEBwYXJhbSBuYW1lIE5hbWUgc3RyaW5nIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgaGFuZGxlci4KICoKICogQHBhcmFtIGhhbmRsZXIgUG9pbnRlciB0aGUgTUlCIEhhbmRsZXIuCiAqCiAqIEBzZWUgbmV0c25tcF9jbGVhcl9oYW5kbGVyX2xpc3QoKQogKi8Kdm9pZApuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXJfYnlfbmFtZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyKQp7CiAgICBuZXRzbm1wX2FkZF9saXN0X2RhdGEoJmhhbmRsZXJfcmVnLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdChuYW1lLCAodm9pZCAqKSBoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyX2ZyZWVfY2FsbGJhY2spKTsKICAgIERFQlVHTVNHVEwoKCJoYW5kbGVyX3JlZ2lzdHJ5IiwgInJlZ2lzdGVyaW5nIGhlbHBlciAlc1xuIiwgbmFtZSkpOwp9CgovKiogQ2xlYXJzIHRoZSBlbnRpcmUgTUlCIEhhbmRsZXJzIHJlZ2lzdHJhdGlvbiBsaXN0LgogKiAgTUlCIEhhbmRsZXJzIHJlZ2lzdHJhdGlvbiBsaXN0IGlzIHVzZWQgdG8gYWNjZXNzIGFueSBNSUIgSGFuZGxlciBieQogKiAgaXRzIG5hbWUuIFRoZSBmdW5jdGlvbiBmcmVlcyB0aGUgbGlzdCBtZW1vcnkgYW5kIHNldHMgcG9pbnRlciB0byBOVUxMLgogKiAgSW5zdGVhZCBvZiBjYWxsaW5nIHRoaXMgZnVuY3Rpb24gZGlyZWN0bHksIHVzZSBzaHV0ZG93bl9hZ2VudCgpLgogKgogKiAgQHNlZSBzaHV0ZG93bl9hZ2VudCgpCiAqICBAc2VlIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcl9ieV9uYW1lKCkKICovCnZvaWQKbmV0c25tcF9jbGVhcl9oYW5kbGVyX2xpc3Qodm9pZCkKewogICAgREVCVUdNU0dUTCgoImFnZW50X2hhbmRsZXIiLCAibmV0c25tcF9jbGVhcl9oYW5kbGVyX2xpc3QoKSBjYWxsZWRcbiIpKTsKICAgIG5ldHNubXBfZnJlZV9hbGxfbGlzdF9kYXRhKGhhbmRsZXJfcmVnKTsKICAgIGhhbmRsZXJfcmVnID0gTlVMTDsKfQoKLyoqIEBwcml2YXRlCiAqICBJbmplY3RzIGEgaGFuZGxlciBpbnRvIGEgc3VidHJlZSwgcGVlcnMgYW5kIGNoaWxkcmVuIHdoZW4gYSBnaXZlbgogKiAgc3VidHJlZXMgbmFtZSBtYXRjaGVzIGEgcGFzc2VkIGluIG5hbWUuCiAqLwp2b2lkCm5ldHNubXBfaW5qZWN0X2hhbmRsZXJfaW50b19zdWJ0cmVlKG5ldHNubXBfc3VidHJlZSAqdHAsIGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmJlZm9yZV93aGF0KQp7CiAgICBuZXRzbm1wX3N1YnRyZWUgKnRwdHI7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICptaDsKCiAgICBmb3IgKHRwdHIgPSB0cDsgdHB0ciAhPSBOVUxMOyB0cHRyID0gdHB0ci0+bmV4dCkgewogICAgICAgIC8qICBpZiAodHB0ci0+Y2hpbGRyZW4pIHsgCiAgICAgICAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcl9pbnRvX3N1YnRyZWUodHB0ci0+Y2hpbGRyZW4sbmFtZSxoYW5kbGVyKTsKCSAgICB9ICAgKi8KICAgICAgICBpZiAoc3RyY21wKHRwdHItPmxhYmVsX2EsIG5hbWUpID09IDApIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImluamVjdEhhbmRsZXIiLCAiaW5qZWN0aW5nIGhhbmRsZXIgJXMgaW50byAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+aGFuZGxlcl9uYW1lLCB0cHRyLT5sYWJlbF9hKSk7CiAgICAgICAgICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXJfYmVmb3JlKHRwdHItPnJlZ2luZm8sIF9jbG9uZV9oYW5kbGVyKGhhbmRsZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWZvcmVfd2hhdCk7CiAgICAgICAgfSBlbHNlIGlmICh0cHRyLT5yZWdpbmZvICE9IE5VTEwgJiYKCQkgICB0cHRyLT5yZWdpbmZvLT5oYW5kbGVyTmFtZSAhPSBOVUxMICYmCiAgICAgICAgICAgICAgICAgICBzdHJjbXAodHB0ci0+cmVnaW5mby0+aGFuZGxlck5hbWUsIG5hbWUpID09IDApIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImluamVjdEhhbmRsZXIiLCAiaW5qZWN0aW5nIGhhbmRsZXIgaW50byAlcy8lc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgdHB0ci0+bGFiZWxfYSwgdHB0ci0+cmVnaW5mby0+aGFuZGxlck5hbWUpKTsKICAgICAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcl9iZWZvcmUodHB0ci0+cmVnaW5mbywgX2Nsb25lX2hhbmRsZXIoaGFuZGxlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZV93aGF0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3IgKG1oID0gdHB0ci0+cmVnaW5mby0+aGFuZGxlcjsgbWggIT0gTlVMTDsgbWggPSBtaC0+bmV4dCkgewogICAgICAgICAgICAgICAgaWYgKG1oLT5oYW5kbGVyX25hbWUgJiYgc3RyY21wKG1oLT5oYW5kbGVyX25hbWUsIG5hbWUpID09IDApIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaW5qZWN0SGFuZGxlciIsICJpbmplY3RpbmcgaGFuZGxlciBpbnRvICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwdHItPmxhYmVsX2EpKTsKICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyX2JlZm9yZSh0cHRyLT5yZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jbG9uZV9oYW5kbGVyKGhhbmRsZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZV93aGF0KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImluamVjdEhhbmRsZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgaW5qZWN0aW5nIGhhbmRsZXIgaW50byAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaC0+aGFuZGxlcl9uYW1lKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCnN0YXRpYyBpbnQgICAgICBkb25laXQgPSAwOwovKiogQHByaXZhdGUKICogIFBhcnNlcyB0aGUgImluamVjdEhhbmRsZXIiIHRva2VuIGxpbmUuCiAqLwp2b2lkCnBhcnNlX2luamVjdEhhbmRsZXJfY29uZihjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgIGhhbmRsZXJfdG9faW5zZXJ0WzI1Nl0sIHJlZ19uYW1lWzI1Nl07CiAgICBzdWJ0cmVlX2NvbnRleHRfY2FjaGUgKnN0YzsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXI7CgogICAgLyoKICAgICAqIFhYWFdXVzogZW5zdXJlIGluc3RlYWQgdGhhdCBoYW5kbGVyIGlzbid0IGluc2VydGVkIHR3aWNlIAogICAgICovCiAgICBpZiAoZG9uZWl0KSAgICAgICAgICAgICAgICAgLyogd2Ugb25seSBkbyB0aGlzIG9uY2Ugd2l0aG91dCByZXN0YXJ0IHRoZSBhZ2VudCAqLwogICAgICAgIHJldHVybjsKCiAgICBjcHRyID0gY29weV9ud29yZChjcHRyLCBoYW5kbGVyX3RvX2luc2VydCwgc2l6ZW9mKGhhbmRsZXJfdG9faW5zZXJ0KSk7CiAgICBoYW5kbGVyID0gKG5ldHNubXBfbWliX2hhbmRsZXIqKW5ldHNubXBfZ2V0X2xpc3RfZGF0YShoYW5kbGVyX3JlZywgaGFuZGxlcl90b19pbnNlcnQpOwogICAgaWYgKCFoYW5kbGVyKSB7CgluZXRzbm1wX2NvbmZpZ19lcnJvcigibm8gXCIlc1wiIGhhbmRsZXIgcmVnaXN0ZXJlZC4iLAoJCQkgICAgIGhhbmRsZXJfdG9faW5zZXJ0KTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCFjcHRyKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigibm8gSU5UT05BTUUgc3BlY2lmaWVkLiAgQ2FuJ3QgZG8gaW5zZXJ0aW9uLiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNwdHIgPSBjb3B5X253b3JkKGNwdHIsIHJlZ19uYW1lLCBzaXplb2YocmVnX25hbWUpKTsKCiAgICBmb3IgKHN0YyA9IGdldF90b3BfY29udGV4dF9jYWNoZSgpOyBzdGM7IHN0YyA9IHN0Yy0+bmV4dCkgewogICAgICAgIERFQlVHTVNHVEwoKCJpbmplY3RIYW5kbGVyIiwgIkNoZWNraW5nIGNvbnRleHQgdHJlZSAlcyAoYmVmb3JlPSVzKVxuIiwKICAgICAgICAgICAgICAgICAgICBzdGMtPmNvbnRleHRfbmFtZSwgKGNwdHIpP2NwdHI6Im51bGwiKSk7CiAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcl9pbnRvX3N1YnRyZWUoc3RjLT5maXJzdF9zdWJ0cmVlLCByZWdfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLCBjcHRyKTsKICAgIH0KfQoKLyoqIEBwcml2YXRlCiAqICBDYWxsYmFjayB0byBlbnN1cmUgaW5qZWN0SGFuZGxlciBwYXJzZXIgZG9lc24ndCBkbyB0aGluZ3MgdHdpY2UuCiAqICBAdG9kbyByZXBsYWNlIHRoaXMgd2l0aCBhIG1ldGhvZCB0byBjaGVjayB0aGUgaGFuZGxlciBjaGFpbiBpbnN0ZWFkLgogKi8Kc3RhdGljIGludApoYW5kbGVyX21hcmtfaW5qZWN0X2hhbmRsZXJfZG9uZShpbnQgbWFqb3JJRCwgaW50IG1pbm9ySUQsCiAgICAgICAgICAgICAgICAgICAgdm9pZCAqc2VydmVyYXJnLCB2b2lkICpjbGllbnRhcmcpCnsKICAgIGRvbmVpdCA9IDE7CiAgICByZXR1cm4gMDsKfQoKLyoqIEBwcml2YXRlCiAqICBSZWdpc3RlcnMgdGhlIGluamVjdEhhbmRsZSBwYXJzZXIgdG9rZW4uCiAqICBVc2VkIGluIGluaXRfYWdlbnRfcmVhZF9jb25maWcoKS4KICoKICogIEBzZWUgaW5pdF9hZ2VudF9yZWFkX2NvbmZpZygpCiAqLwp2b2lkCm5ldHNubXBfaW5pdF9oYW5kbGVyX2NvbmYodm9pZCkKewogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoImluamVjdEhhbmRsZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VfaW5qZWN0SGFuZGxlcl9jb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgImluamVjdEhhbmRsZXIgTkFNRSBJTlRPTkFNRSBbQkVGT1JFX09USEVSX05BTUVdIik7CiAgICBzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9DQUxMQkFDS19QT1NUX1JFQURfQ09ORklHLAogICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyX21hcmtfaW5qZWN0X2hhbmRsZXJfZG9uZSwgTlVMTCk7CgogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIkdFVCIpLCBNT0RFX0dFVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiR0VUTkVYVCIpLCBNT0RFX0dFVE5FWFQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIkdFVEJVTEsiKSwgTU9ERV9HRVRCVUxLKTsKI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJTRVRfQkVHSU4iKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfU0VUX0JFR0lOKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJTRVRfUkVTRVJWRTEiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfU0VUX1JFU0VSVkUxKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJTRVRfUkVTRVJWRTIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfU0VUX1JFU0VSVkUyKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJTRVRfQUNUSU9OIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFVF9BQ1RJT04pOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIlNFVF9DT01NSVQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfU0VUX0NPTU1JVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX0ZSRUUiKSwgTU9ERV9TRVRfRlJFRSk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX1VORE8iKSwgTU9ERV9TRVRfVU5ETyk7CgogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoInByZS1yZXF1ZXN0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1BSRV9SRVFVRVNUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJvYmplY3RfbG9va3VwIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX09CSkVDVF9MT09LVVApOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoImNoZWNrX3ZhbHVlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX0NIRUNLX1ZBTFVFKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJyb3dfY3JlYXRlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1JPV19DUkVBVEUpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoInVuZG9fc2V0dXAiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfVU5ET19TRVRVUCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgic2V0X3ZhbHVlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1NFVF9WQUxVRSk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgiY2hlY2tfY29uc2lzdGVuY3kiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfQ0hFQ0tfQ09OU0lTVEVOQ1kpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoInVuZG9fc2V0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1VORE9fU0VUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJjb21taXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfQ09NTUlUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJ1bmRvX2NvbW1pdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9VTkRPX0NPTU1JVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgiaXJyZXZlcnNpYmxlX2NvbW1pdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9JUlJFVkVSU0lCTEVfQ09NTUlUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJ1bmRvX2NsZWFudXAiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfVU5ET19DTEVBTlVQKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJwb3N0X3JlcXVlc3QiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfUE9TVF9SRVFVRVNUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJvcmlnaW5hbCIpLCAweGZmZmYpOwojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCgogICAgLyoKICAgICAqIHh4eC1ya3M6IGhtbW0uLiB3aWxsIHRoaXMgd29yayBmb3IgbW9kZXMgd2hpY2ggYXJlIG9yJ2QgdG9nZXRoZXI/CiAgICAgKiAgICAgICAgICBJJ20gYmV0dGluZyBub3QuLi4KICAgICAqLwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImhhbmRsZXJfY2FuX21vZGUiLCBzdHJkdXAoIkdFVC9HRVRORVhUIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9HRVRBTkRHRVRORVhUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJoYW5kbGVyX2Nhbl9tb2RlIiwgc3RyZHVwKCJTRVQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1NFVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiaGFuZGxlcl9jYW5fbW9kZSIsIHN0cmR1cCgiR0VUQlVMSyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFUl9DQU5fR0VUQlVMSyk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiaGFuZGxlcl9jYW5fbW9kZSIsIHN0cmR1cCgiQkFCWV9TVEVQIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9CQUJZX1NURVApOwp9CgovKiogQH0gKi8K