LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYnVsa190b19uZXh0Lmg+CgoKc3RhdGljIG5ldHNubXBfbWliX2hhbmRsZXIgKl9jbG9uZV9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKml0KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogTmV3IEhhbmRsZXIgYmFzZWQgQVBJIAogKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiogQGRlZmdyb3VwIGhhbmRsZXIgTmV0LVNOTVAgQWdlbnQgaGFuZGxlciBhbmQgZXh0ZW5zaWJpbGl0eSBBUEkKICogIEBpbmdyb3VwIGFnZW50CiAqCiAqICBUaGUgYmFzaWMgdGhlb3J5IGdvZXMgc29tZXRoaW5nIGxpa2UgdGhpczogSW4gdGhlIHBhc3QsIHdpdGggdGhlCiAqICBvcmlnaW5hbCBtaWIgbW9kdWxlIGFwaSAod2hpY2ggZGVyaXZlZCBmcm9tIHRoZSBvcmlnaW5hbCBDTVUgU05NUAogKiAgY29kZSkgdGhlIHVuZGVybHlpbmcgbWliIG1vZHVsZXMgd2VyZSBwYXNzZWQgdmVyeSBsaXR0bGUKICogIGluZm9ybWF0aW9uIChvbmx5IHRoZSB0cnVseSBtb3N0IGJhc2ljIGluZm9ybWF0aW9uIGFib3V0IGEKICogIHJlcXVlc3QpLiAgVGhpcyB3b3JrZWQgd2VsbCBhdCB0aGUgdGltZSBidXQgaW4gdG9kYXlzIHdvcmxkIG9mCiAqICBzdWJhZ2VudHMsIGRldmljZSBpbnN0cnVtZW50YXRpb24sIGxvdyByZXNvdXJjZSBjb25zdW1wdGlvbiwgZXRjLAogKiAgaXQganVzdCBpc24ndCBmbGV4aWJsZSBlbm91Z2guICAiaGFuZGxlcnMiIGFyZSBoZXJlIHRvIGZpeCBhbGwgdGhhdC4KICoKICogIFdpdGggdGhlIHJld3JpdGUgb2YgdGhlIGFnZW50IGludGVybmFscyBmb3IgdGhlIG5ldC1zbm1wIDUuMAogKiAgcmVsZWFzZSwgd2UgaW50cm9kdWNlIGEgbW9kdWxhciBjYWxsaW5nIHNjaGVtZSB0aGF0IGFsbG93cyBhZ2VudAogKiAgbW9kdWxlcyB0byBiZSB3cml0dGVuIGluIGEgdmVyeSBmbGV4aWJsZSBtYW5uZXIsIGFuZCBtb3JlCiAqICBpbXBvcnRhbnRseSBhbGxvd3MgcmV1c2Ugb2YgY29kZSBpbiBhIGRlY2VudCB3YXkgKGFuZCB3aXRob3V0IHRoZQogKiAgbWVtb3J5IGFuZCBzcGVlZCBvdmVyaGVhZHMgb2YgT08gbGFuZ3VhZ2VzIGxpa2UgQysrKS4KICoKICogIEZ1bmN0aW9uYWxseSwgdGhlIG5vdGlvbiBvZiB3aGF0IGEgaGFuZGxlciBkb2VzIGlzIHRoZSBzYW1lIGFzIHRoZQogKiAgb2xkZXIgYXBpOiBBIGhhbmRsZXIgaXMgQGxpbmsgbmV0c25tcF9jcmVhdGVfaGFuZGxlcigpIGNyZWF0ZWRAZW5kbGluayBhbmQKICogIHRoZW4gQGxpbmsgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKCkgcmVnaXN0ZXJlZEBlbmRsaW5rIHdpdGggdGhlIG1haW4KICogIGFnZW50IGF0IGEgZ2l2ZW4gT0lEIGluIHRoZSBPSUQgdHJlZSBhbmQgZ2V0cyBjYWxsZWQgYW55IHRpbWUgYQogKiAgcmVxdWVzdCBpcyBtYWRlIHRoYXQgaXQgc2hvdWxkIHJlc3BvbmQgdG8uICBZb3UgcHJvYmFibHkgc2hvdWxkCiAqICB1c2Ugb25lIG9mIHRoZSBjb252ZW5pZW5jZSBoZWxwZXJzIGluc3RlYWQgb2YgZG9pbmcgYW55dGhpbmcgZWxzZQogKiAgeW91cnNlbGYgdGhvdWdoOgogKgogKiAgTW9zdCBpbXBvcnRhbnRseSwgdGhvdWdoLCBpcyB0aGF0IHRoZSBoYW5kbGVycyBhcmUgYnVpbHQgb24gdGhlCiAqICBub3Rpb24gb2YgbW9kdWxhcml0eSBhbmQgcmV1c2UuICBTcGVjaWZpY2FsbHksIHJhdGhlciB0aGFuIGRvIGFsbAogKiAgdGhlIHJlYWxseSBoYXJkIHdvcmsgKGxpa2UgcGFyc2luZyB0YWJsZSBpbmRleGVzIG91dCBvZiBhbgogKiAgaW5jb21pbmcgb2lkIHJlcXVlc3QpIGluIGVhY2ggbW9kdWxlLCB0aGUgQVBJIGlzIGRlc2lnbmVkIHRvIG1ha2UKICogIGl0IGVhc3kgdG8gd3JpdGUgImhlbHBlciIgaGFuZGxlcnMgdGhhdCBtZXJlbHkgcHJvY2VzcyBzb21lIGFzcGVjdAogKiAgb2YgdGhlIHJlcXVlc3QgYmVmb3JlIHBhc3NpbmcgaXQgYWxvbmcgdG8gdGhlIGZpbmFsIGhhbmRsZXIgdGhhdAogKiAgcmV0dXJucyB0aGUgcmVhbCBhbnN3ZXIuICBNb3N0IHBlb3BsZSB3aWxsIHdhbnQgdG8gbWFrZSB1c2Ugb2YgdGhlCiAqICBAbGluayBpbnN0YW5jZSBpbnN0YW5jZUBlbmRsaW5rLCBAbGluayB0YWJsZSB0YWJsZUBlbmRsaW5rLCBAbGluawogKiAgdGFibGVfaXRlcmF0b3IgdGFibGVfaXRlcmF0b3JAZW5kbGluaywgQGxpbmsgdGFibGVfZGF0YQogKiAgdGFibGVfZGF0YUBlbmRsaW5rLCBvciBAbGluayB0YWJsZV9kYXRhc2V0IHRhYmxlX2RhdGFzZXRAZW5kbGluawogKiAgaGVscGVycyB0byBtYWtlIHRoZWlyIGxpZmUgZWFzaWVyLiAgVGhlc2UgImhlbHBlcnMiIGludGVycGVydAogKiAgaW1wb3J0YW50IGFzcGVjdHMgb2YgdGhlIHJlcXVlc3QgYW5kIHBhc3MgdGhlbSBvbiB0byB5b3UuCiAqCiAqICBGb3IgaW5zdGFuY2UsIHRoZSBAbGluayB0YWJsZSB0YWJsZUBlbmRsaW5rIGhlbHBlciBpcyBkZXNpZ25lZCB0bwogKiAgaGFuZCB5b3UgYSBsaXN0IG9mIGV4dHJhY3RlZCBpbmRleCB2YWx1ZXMgZnJvbSBhbiBpbmNvbWluZwogKiAgcmVxdWVzdC4gIFRIZSBAbGluayB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvckBlbmRsaW5rIGhlbHBlcgogKiAgaXMgYnVpbHQgb24gdG9wIG9mIHRoZSB0YWJsZSBoZWxwZXIsIGFuZCBpcyBkZXNpZ25lZCB0byBoZWxwIHlvdQogKiAgaXRlcmF0ZSB0aHJvdWdoIGRhdGEgc3RvcmVkIGVsc2V3aGVyZSAobGlrZSBpbiBhIGtlcm5lbCkgdGhhdCBpcwogKiAgbm90IGluIE9JRCBsZXhvZ3JhcGhpY2FsIG9yZGVyIChpZSwgZG9uJ3Qgd3JpdGUgeW91ciBvd24gaW5kZXgvb2lkCiAqICBzb3J0aW5nIHJvdXRpbmUsIHVzZSB0aGlzIGhlbHBlciBpbnN0ZWFkKS4gIFRoZSBiZWF1dHkgb2YgdGhlCiAqICBAbGluayB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvciBoZWxwZXJAZW5kbGluaywgYXMgd2VsbCBhcyB0aGUgQGxpbmsKICogIGluc3RhbmNlIGluc3RhbmNlQGVuZGxpbmsgaGVscGVyIGlzIHRoYXQgdGhleSB0YWtlIGNhcmUgb2YgdGhlIGNvbXBsZXgKICogIEdFVE5FWFQgcHJvY2Vzc2luZyBlbnRpcmVseSBmb3IgeW91IGFuZCBoYW5kIHlvdSBldmVyeXRoaW5nIHlvdQogKiAgbmVlZCB0byBtZXJlbHkgcmV0dXJuIHRoZSBkYXRhIGFzIGlmIGl0IHdhcyBhIEdFVCByZXF1ZXN0LiAgTXVjaAogKiAgbGVzcyBjb2RlIGFuZCBoYWlyIHB1bGxpbmcuICBJJ3ZlIHB1bGxlZCBhbGwgbXkgaGFpciBvdXQgdG8gaGVscAogKiAgeW91IHNvIHRoYXQgb25seSBvbmUgb2YgdXMgaGFzIHRvIGJlIGJhbGQuCiAqCiAqIEB7CiAqLwoKLyoqIGNyZWF0ZXMgYSBuZXRzbm1wX21pYl9oYW5kbGVyIHN0cnVjdHVyZSBnaXZlbiBhIG5hbWUgYW5kIGEgYWNjZXNzIG1ldGhvZC4KICogIFRoZSByZXR1cm5lZCBoYW5kbGVyIHNob3VsZCB0aGVuIGJlIEBsaW5rIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpCiAqICByZWdpc3RlcmVkLkBlbmRsaW5rCiAqCiAqICBAcGFyYW0gbmFtZSBpcyB0aGUgaGFuZGxlciBuYW1lIGFuZCBpcyBjb3BpZWQgdGhlbiBhc3NpZ25lZCB0bwogKiAgICAgICAgICAgICAgbmV0c25tcF9taWJfaGFuZGxlci0+aGFuZGxlcl9uYW1lCiAqCiAqICBAcGFyYW0gaGFuZGxlcl9hY2Nlc3NfbWV0aG9kIGlzIGEgZnVuY3Rpb24gcG9pbnRlciB1c2VkIGFzIHRoZSBhY2Nlc3MKICoJICAgbWV0aG9kIGZvciB0aGlzIGhhbmRsZXIgcmVnaXN0cmF0aW9uIGluc3RhbmNlIGZvciB3aGF0ZXZlciByZXF1aXJlZAogKiAgICAgICAgIG5lZWRzLgogKgogKiAgQHJldHVybiBhIHBvaW50ZXIgdG8gYSBwb3B1bGF0ZWQgbmV0c25tcF9taWJfaGFuZGxlciBzdHJ1Y3QgdG8gYmUKICogICAgICAgICAgcmVnaXN0ZXJlZAogKgogKiAgQHNlZSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigpCiAqICBAc2VlIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9jcmVhdGVfaGFuZGxlcihjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogaGFuZGxlcl9hY2Nlc3NfbWV0aG9kKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpyZXQgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfbWliX2hhbmRsZXIpOwogICAgaWYgKHJldCkgewogICAgICAgIHJldC0+YWNjZXNzX21ldGhvZCA9IGhhbmRsZXJfYWNjZXNzX21ldGhvZDsKICAgICAgICBpZiAoTlVMTCAhPSBuYW1lKSB7CiAgICAgICAgICAgIHJldC0+aGFuZGxlcl9uYW1lID0gc3RyZHVwKG5hbWUpOwogICAgICAgICAgICBpZiAoTlVMTCA9PSByZXQtPmhhbmRsZXJfbmFtZSkKICAgICAgICAgICAgICAgIFNOTVBfRlJFRShyZXQpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKiBjcmVhdGVzIGEgaGFuZGxlciByZWdpc3RyYXRpb24gc3RydWN0dXJlIGdpdmVuIGEgbmFtZSwgYQogKiAgYWNjZXNzX21ldGhvZCBmdW5jdGlvbiwgYSByZWdpc3RyYXRpb24gbG9jYXRpb24gb2lkIGFuZCB0aGUgbW9kZXMKICogIHRoZSBoYW5kbGVyIHN1cHBvcnRzLiBJZiBtb2RlcyA9PSAwLCB0aGVuIG1vZGVzIHdpbGwgYXV0b21hdGljYWxseQogKiAgYmUgc2V0IHRvIHRoZSBkZWZhdWx0IHZhbHVlIG9mIG9ubHkgSEFORExFUl9DQU5fREVGQVVMVCwgd2hpY2ggaXMKICogIGJ5IGRlZmF1bHQgcmVhZC1vbmx5IEdFVCBhbmQgR0VUTkVYVCByZXF1ZXN0cy4gQSBoYW5kZXIgd2hpY2ggc3VwcG9ydHMKICogIHNldHMgYnV0IG5vdCByb3cgY3JlYXRpb24gc2hvdWxkIHNldCB1cyBhIG1vZGUgb2YgSEFORExFUl9DQU5fU0VUX09OTFkuCiAqICBAbm90ZSBUaGlzIGVuZHMgdXAgY2FsbGluZyBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKG5hbWUsIGhhbmRsZXJfYWNjZXNzX21ldGhvZCkKICogIEBwYXJhbSBuYW1lIGlzIHRoZSBoYW5kbGVyIG5hbWUgYW5kIGlzIGNvcGllZCB0aGVuIGFzc2lnbmVkIHRvCiAqICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uLT5oYW5kbGVyTmFtZS4KICoKICogIEBwYXJhbSBoYW5kbGVyIGlzIGEgZnVuY3Rpb24gcG9pbnRlciB1c2VkIGFzIHRoZSBhY2Nlc3MKICoJbWV0aG9kIGZvciB0aGlzIGhhbmRsZXIgcmVnaXN0cmF0aW9uIGluc3RhbmNlIGZvciB3aGF0ZXZlciByZXF1aXJlZAogKgluZWVkcy4KICoKICogIEBwYXJhbSByZWdfb2lkIGlzIHRoZSByZWdpc3RyYXRpb24gbG9jYXRpb24gb2lkLgogKgogKiAgQHBhcmFtIHJlZ19vaWRfbGVuIGlzIHRoZSBsZW5ndGggb2YgcmVnX29pZCwgY2FuIHVzZSB0aGUgbWFjcm8sCiAqICAgICAgICAgT0lEX0xFTkdUSAogKgogKiAgQHBhcmFtIG1vZGVzIGlzIHVzZWQgdG8gY29uZmlndXJlIHJlYWQvd3JpdGUgYWNjZXNzLiAgSWYgbW9kZXMgPT0gMCwgCiAqCXRoZW4gbW9kZXMgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIHNldCB0byB0aGUgZGVmYXVsdCAKICoJdmFsdWUgb2Ygb25seSBIQU5ETEVSX0NBTl9ERUZBVUxULCB3aGljaCBpcyBieSBkZWZhdWx0IHJlYWQtb25seSBHRVQgCiAqCWFuZCBHRVRORVhUIHJlcXVlc3RzLiAgVGhlIG90aGVyIHR3byBtb2RlIG9wdGlvbnMgYXJlIHJlYWQgb25seSwgCiAqCUhBTkRMRVJfQ0FOX1JPTkxZLCBhbmQgcmVhZC93cml0ZSwgSEFORExFUl9DQU5fUldSSVRFLgogKgogKgkJLSBIQU5ETEVSX0NBTl9HRVRBTkRHRVRORVhUCiAqCQktIEhBTkRMRVJfQ0FOX1NFVAogKgkJLSBIQU5ETEVSX0NBTl9HRVRCVUxLICAgICAgCiAqCiAqCQktIEhBTkRMRVJfQ0FOX1JPTkxZICAgKEhBTkRMRVJfQ0FOX0dFVEFOREdFVE5FWFQpCiAqCQktIEhBTkRMRVJfQ0FOX1JXUklURSAgKEhBTkRMRVJfQ0FOX0dFVEFOREdFVE5FWFQgfCAKICoJCQlIQU5ETEVSX0NBTl9TRVQpCiAqCQktIEhBTkRMRVJfQ0FOX0RFRkFVTFQgSEFORExFUl9DQU5fUk9OTFkKICoKICogIEByZXR1cm4gUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uIHN0cnVjdC4KICogICAgICAgICAgTlVMTCBpcyByZXR1cm5lZCBvbmx5IHdoZW4gbWVtb3J5IGNvdWxkIG5vdCBiZSBhbGxvY2F0ZWQgZm9yIHRoZSAKICogICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBzdHJ1Y3QuCiAqCiAqCiAqICBAc2VlIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoKQogKiAgQHNlZSBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKQogKi8KbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqCm5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fY3JlYXRlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIHJlZ19vaWQsIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1vZGVzKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICp0aGVfcmVnOwogICAgdGhlX3JlZyA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbik7CiAgICBpZiAoIXRoZV9yZWcpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKG1vZGVzKQogICAgICAgIHRoZV9yZWctPm1vZGVzID0gbW9kZXM7CiAgICBlbHNlCiAgICAgICAgdGhlX3JlZy0+bW9kZXMgPSBIQU5ETEVSX0NBTl9ERUZBVUxUOwoKICAgIHRoZV9yZWctPmhhbmRsZXIgPSBoYW5kbGVyOwogICAgdGhlX3JlZy0+cHJpb3JpdHkgPSBERUZBVUxUX01JQl9QUklPUklUWTsKICAgIGlmIChuYW1lKQogICAgICAgIHRoZV9yZWctPmhhbmRsZXJOYW1lID0gc3RyZHVwKG5hbWUpOwogICAgdGhlX3JlZy0+cm9vdG9pZCA9IHNubXBfZHVwbGljYXRlX29iamlkKHJlZ19vaWQsIHJlZ19vaWRfbGVuKTsKICAgIHRoZV9yZWctPnJvb3RvaWRfbGVuID0gcmVnX29pZF9sZW47CiAgICByZXR1cm4gdGhlX3JlZzsKfQoKbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqCm5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcl9hY2Nlc3NfbWV0aG9kLCBjb25zdCBvaWQgKiByZWdfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgcmVnX29pZF9sZW4sIGludCBtb2RlcykKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcnYgPSBOVUxMOwogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciA9CiAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcihuYW1lLCBoYW5kbGVyX2FjY2Vzc19tZXRob2QpOwogICAgaWYgKGhhbmRsZXIpIHsKICAgICAgICBydiA9IG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fY3JlYXRlKAogICAgICAgICAgICBuYW1lLCBoYW5kbGVyLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgbW9kZXMpOwogICAgICAgIGlmICghcnYpCiAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKGhhbmRsZXIpOwogICAgfQogICAgcmV0dXJuIHJ2Owp9CgovKiogcmVnaXN0ZXIgYSBoYW5kbGVyLCBhcyBkZWZpbmVkIGJ5IHRoZSBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uIHBvaW50ZXIuICovCmludApuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlcjsKICAgIGludCBmbGFncyA9IDA7CgogICAgaWYgKHJlZ2luZm8gPT0gTlVMTCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKSBjYWxsZWQgaWxsZWdhbGx5XG4iKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgREVCVUdJRigiaGFuZGxlcjo6cmVnaXN0ZXIiKSB7CiAgICAgICAgREVCVUdNU0dUTCgoImhhbmRsZXI6OnJlZ2lzdGVyIiwgIlJlZ2lzdGVyaW5nICVzICgiLCByZWdpbmZvLT5oYW5kbGVyTmFtZSkpOwogICAgICAgIGZvciAoaGFuZGxlciA9IHJlZ2luZm8tPmhhbmRsZXI7IGhhbmRsZXI7IGhhbmRsZXIgPSBoYW5kbGVyLT5uZXh0KSB7CiAgICAgICAgICAgIERFQlVHTVNHKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCAiOjolcyIsIGhhbmRsZXItPmhhbmRsZXJfbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgREVCVUdNU0coKCJoYW5kbGVyOjpyZWdpc3RlciIsICIpIGF0ICIpKTsKICAgICAgICBpZiAocmVnaW5mby0+cm9vdG9pZCAmJiByZWdpbmZvLT5yYW5nZV9zdWJpZCkgewogICAgICAgICAgICBERUJVR01TR09JRFJBTkdFKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCByZWdpbmZvLT5yb290b2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5yb290b2lkX2xlbiwgcmVnaW5mby0+cmFuZ2Vfc3ViaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJhbmdlX3Vib3VuZCkpOwogICAgICAgIH0gZWxzZSBpZiAocmVnaW5mby0+cm9vdG9pZCkgewogICAgICAgICAgICBERUJVR01TR09JRCgoImhhbmRsZXI6OnJlZ2lzdGVyIiwgcmVnaW5mby0+cm9vdG9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdNU0coKCJoYW5kbGVyOjpyZWdpc3RlciIsICJbbnVsbF0iKSk7CiAgICAgICAgfQogICAgICAgIERFQlVHTVNHKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCAiXG4iKSk7CiAgICB9CgogICAgLyoKICAgICAqIGRvbid0IGxldCB0aGVtIHJlZ2lzdGVyIGZvciBhYnNvbHV0ZWx5IG5vdGhpbmcuICBQcm9iYWJseSBhIG1pc3Rha2UgCiAgICAgKi8KICAgIGlmICgwID09IHJlZ2luZm8tPm1vZGVzKSB7CiAgICAgICAgcmVnaW5mby0+bW9kZXMgPSBIQU5ETEVSX0NBTl9ERUZBVUxUOwogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLCAibm8gcmVnaXN0cmF0aW9uIG1vZGVzIHNwZWNpZmllZCBmb3IgJXMuICIKICAgICAgICAgICAgICAgICAiRGVmYXVsdGluZyB0byAweCV4XG4iLCByZWdpbmZvLT5oYW5kbGVyTmFtZSwgcmVnaW5mby0+bW9kZXMpOwogICAgfQoKICAgIC8qCiAgICAgKiBmb3IgaGFuZGxlcnMgdGhhdCBjYW4ndCBHRVRCVUxLLCBmb3JjZSBhIGNvbnZlcnNpb24gaGFuZGxlciBvbiB0aGVtIAogICAgICovCiAgICBpZiAoIShyZWdpbmZvLT5tb2RlcyAmIEhBTkRMRVJfQ0FOX0dFVEJVTEspKSB7CiAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9nZXRfYnVsa190b19uZXh0X2hhbmRsZXIoKSk7CiAgICB9CgogICAgZm9yIChoYW5kbGVyID0gcmVnaW5mby0+aGFuZGxlcjsgaGFuZGxlcjsgaGFuZGxlciA9IGhhbmRsZXItPm5leHQpIHsKICAgICAgICBpZiAoaGFuZGxlci0+ZmxhZ3MgJiBNSUJfSEFORExFUl9JTlNUQU5DRSkKICAgICAgICAgICAgZmxhZ3MgPSBGVUxMWV9RVUFMSUZJRURfSU5TVEFOQ0U7CiAgICB9CgogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfbWliKHJlZ2luZm8tPmhhbmRsZXJOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cHJpb3JpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cmFuZ2Vfc3ViaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cmFuZ2VfdWJvdW5kLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPmNvbnRleHROYW1lLCByZWdpbmZvLT50aW1lb3V0LCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLCAxKTsKfQoKLyoqIHVucmVnaXN0ZXIgYSBoYW5kbGVyLCBhcyBkZWZpbmVkIGJ5IHRoZSBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uIHBvaW50ZXIuICovCmludApuZXRzbm1wX3VucmVnaXN0ZXJfaGFuZGxlcihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvKQp7CiAgICByZXR1cm4gdW5yZWdpc3Rlcl9taWJfY29udGV4dChyZWdpbmZvLT5yb290b2lkLCByZWdpbmZvLT5yb290b2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnByaW9yaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cmFuZ2Vfc3ViaWQsIHJlZ2luZm8tPnJhbmdlX3Vib3VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPmNvbnRleHROYW1lKTsKfQoKLyoqIHJlZ2lzdGVyIGEgaGFuZGxlciwgYXMgZGVmaW5lZCBieSB0aGUgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBwb2ludGVyLiAqLwppbnQKbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyX25vY2FsbGJhY2sobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlcjsKICAgIGlmIChyZWdpbmZvID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyX25vY2FsbGJhY2soKSBjYWxsZWQgaWxsZWdhbGx5XG4iKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CiAgICBERUJVR0lGKCJoYW5kbGVyOjpyZWdpc3RlciIpIHsKICAgICAgICBERUJVR01TR1RMKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICJSZWdpc3RlcmluZyAod2l0aCBubyBjYWxsYmFjaykgIikpOwogICAgICAgIGZvciAoaGFuZGxlciA9IHJlZ2luZm8tPmhhbmRsZXI7IGhhbmRsZXI7IGhhbmRsZXIgPSBoYW5kbGVyLT5uZXh0KSB7CiAgICAgICAgICAgIERFQlVHTVNHKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCAiOjolcyIsIGhhbmRsZXItPmhhbmRsZXJfbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgREVCVUdNU0coKCJoYW5kbGVyOjpyZWdpc3RlciIsICIgYXQgIikpOwogICAgICAgIGlmIChyZWdpbmZvLT5yb290b2lkICYmIHJlZ2luZm8tPnJhbmdlX3N1YmlkKSB7CiAgICAgICAgICAgIERFQlVHTVNHT0lEUkFOR0UoKCJoYW5kbGVyOjpyZWdpc3RlciIsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuLCByZWdpbmZvLT5yYW5nZV9zdWJpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cmFuZ2VfdWJvdW5kKSk7CiAgICAgICAgfSBlbHNlIGlmIChyZWdpbmZvLT5yb290b2lkKSB7CiAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCByZWdpbmZvLT5yb290b2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4pKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBERUJVR01TRygoImhhbmRsZXI6OnJlZ2lzdGVyIiwgIltudWxsXSIpKTsKICAgICAgICB9CiAgICAgICAgREVCVUdNU0coKCJoYW5kbGVyOjpyZWdpc3RlciIsICJcbiIpKTsKICAgIH0KCiAgICAvKgogICAgICogZG9uJ3QgbGV0IHRoZW0gcmVnaXN0ZXIgZm9yIGFic29sdXRlbHkgbm90aGluZy4gIFByb2JhYmx5IGEgbWlzdGFrZSAKICAgICAqLwogICAgaWYgKDAgPT0gcmVnaW5mby0+bW9kZXMpIHsKICAgICAgICByZWdpbmZvLT5tb2RlcyA9IEhBTkRMRVJfQ0FOX0RFRkFVTFQ7CiAgICB9CgogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfbWliKHJlZ2luZm8tPmhhbmRsZXItPmhhbmRsZXJfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnByaW9yaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJhbmdlX3N1YmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJhbmdlX3Vib3VuZCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5jb250ZXh0TmFtZSwgcmVnaW5mby0+dGltZW91dCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLCAwKTsKfQoKLyoqIGluamVjdCBhIG5ldyBoYW5kbGVyIGludG8gdGhlIGNhbGxpbmcgY2hhaW4gb2YgdGhlIGhhbmRsZXJzCiAgIGRlZmluZWQgYnkgdGhlIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gcG9pbnRlci4gIFRoZSBuZXcKICAgaGFuZGxlciBpcyBpbmplY3RlZCBhZnRlciB0aGUgYmVmb3JlX3doYXQgaGFuZGxlciwgb3IgaWYgTlVMTCBhdAogICB0aGUgdG9wIG9mIHRoZSBsaXN0IGFuZCBoZW5jZSB3aWxsIGJlIHRoZSBuZXcgaGFuZGxlciB0byBiZSBjYWxsZWQKICAgZmlyc3QuKi8KaW50Cm5ldHNubXBfaW5qZWN0X2hhbmRsZXJfYmVmb3JlKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmJlZm9yZV93aGF0KQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyMiA9IGhhbmRsZXI7CgogICAgaWYgKGhhbmRsZXIgPT0gTlVMTCB8fCByZWdpbmZvID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9pbmplY3RfaGFuZGxlcigpIGNhbGxlZCBpbGxlZ2FsbHlcbiIpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlZ2luZm8gIT0gTlVMTCk7CiAgICAgICAgbmV0c25tcF9hc3NlcnQoaGFuZGxlciAhPSBOVUxMKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQogICAgd2hpbGUgKGhhbmRsZXIyLT5uZXh0KSB7CiAgICAgICAgaGFuZGxlcjIgPSBoYW5kbGVyMi0+bmV4dDsgIC8qIEZpbmQgdGhlIGVuZCBvZiBhIGhhbmRsZXIgc3ViLWNoYWluICovCiAgICB9CiAgICBpZiAocmVnaW5mby0+aGFuZGxlciA9PSBOVUxMKSB7CiAgICAgICAgREVCVUdNU0dUTCgoImhhbmRsZXI6aW5qZWN0IiwgImluamVjdGluZyAlc1xuIiwgaGFuZGxlci0+aGFuZGxlcl9uYW1lKSk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBERUJVR01TR1RMKCgiaGFuZGxlcjppbmplY3QiLCAiaW5qZWN0aW5nICVzIGJlZm9yZSAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLT5oYW5kbGVyX25hbWUsIHJlZ2luZm8tPmhhbmRsZXItPmhhbmRsZXJfbmFtZSkpOwogICAgfQogICAgaWYgKGJlZm9yZV93aGF0KSB7CiAgICAgICAgbmV0c25tcF9taWJfaGFuZGxlciAqbmV4dGgsICpwcmV2aCA9IE5VTEw7CiAgICAgICAgaWYgKHJlZ2luZm8tPmhhbmRsZXIgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibm8gaGFuZGxlciB0byBpbmplY3QgYmVmb3JlXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICB9CiAgICAgICAgZm9yKG5leHRoID0gcmVnaW5mby0+aGFuZGxlcjsgbmV4dGg7CiAgICAgICAgICAgIHByZXZoID0gbmV4dGgsIG5leHRoID0gbmV4dGgtPm5leHQpIHsKICAgICAgICAgICAgaWYgKHN0cmNtcChuZXh0aC0+aGFuZGxlcl9uYW1lLCBiZWZvcmVfd2hhdCkgPT0gMCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoIW5leHRoKQogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgICAgIGlmIChwcmV2aCkgewogICAgICAgICAgICAvKiBhZnRlciBwcmV2aCBhbmQgYmVmb3JlIG5leHRoICovCiAgICAgICAgICAgIHByZXZoLT5uZXh0ID0gaGFuZGxlcjsKICAgICAgICAgICAgaGFuZGxlcjItPm5leHQgPSBuZXh0aDsKICAgICAgICAgICAgaGFuZGxlci0+cHJldiA9IHByZXZoOwogICAgICAgICAgICBuZXh0aC0+cHJldiA9IGhhbmRsZXIyOwogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwogICAgICAgIH0KICAgICAgICAvKiBlbHNlIHdlJ3JlIGZpcnN0LCB3aGljaCBpcyB3aGF0IHdlIGRvIG5leHQgYW55d2F5IHNvIGZhbGwgdGhyb3VnaCAqLwogICAgfQogICAgaGFuZGxlcjItPm5leHQgPSByZWdpbmZvLT5oYW5kbGVyOwogICAgaWYgKHJlZ2luZm8tPmhhbmRsZXIpCiAgICAgICAgcmVnaW5mby0+aGFuZGxlci0+cHJldiA9IGhhbmRsZXIyOwogICAgcmVnaW5mby0+aGFuZGxlciA9IGhhbmRsZXI7CiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgovKiogaW5qZWN0IGEgbmV3IGhhbmRsZXIgaW50byB0aGUgY2FsbGluZyBjaGFpbiBvZiB0aGUgaGFuZGxlcnMKICAgZGVmaW5lZCBieSB0aGUgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBwb2ludGVyLiAgVGhlIG5ldyBoYW5kbGVyIGlzCiAgIGluamVjdGVkIGF0IHRoZSB0b3Agb2YgdGhlIGxpc3QgYW5kIGhlbmNlIHdpbGwgYmUgdGhlIG5ldyBoYW5kbGVyCiAgIHRvIGJlIGNhbGxlZCBmaXJzdC4qLwppbnQKbmV0c25tcF9pbmplY3RfaGFuZGxlcihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIpCnsKICAgIHJldHVybiBuZXRzbm1wX2luamVjdF9oYW5kbGVyX2JlZm9yZShyZWdpbmZvLCBoYW5kbGVyLCBOVUxMKTsKfQoKLyoqIGNhbGxzIGEgaGFuZGxlciB3aXRoIHdpdGggYXBwcm9wcmlhdGUgTlVMTCBjaGVja2luZyBvZiBhcmd1bWVudHMsIGV0Yy4gKi8KTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfY2FsbF9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKm5leHRfaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKm5oOwogICAgaW50ICAgICAgICAgICAgIHJldDsKCiAgICBpZiAobmV4dF9oYW5kbGVyID09IE5VTEwgfHwgcmVnaW5mbyA9PSBOVUxMIHx8IHJlcWluZm8gPT0gTlVMTCB8fAogICAgICAgIHJlcXVlc3RzID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9jYWxsX2hhbmRsZXIoKSBjYWxsZWQgaWxsZWdhbGx5XG4iKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChuZXh0X2hhbmRsZXIgIT0gTlVMTCk7CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVxaW5mbyAhPSBOVUxMKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3RzICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgZG8gewogICAgbmggPSBuZXh0X2hhbmRsZXItPmFjY2Vzc19tZXRob2Q7CiAgICBpZiAoIW5oKSB7CiAgICAgICAgaWYgKG5leHRfaGFuZGxlci0+bmV4dCkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibm8gYWNjZXNzIG1ldGhvZCBzcGVjaWZpZWQgaW4gaGFuZGxlciAlcy4iLAogICAgICAgICAgICAgICAgICAgICBuZXh0X2hhbmRsZXItPmhhbmRsZXJfbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogVGhlIGZpbmFsIGhhbmRsZXIgcmVnaXN0cmF0aW9uIGluIHRoZSBjaGFpbiBtYXkgd2VsbCBub3QgbmVlZAogICAgICAgICAqIHRvIGluY2x1ZGUgYSBoYW5kbGVyIHJvdXRpbmUsIGlmIHRoZSBwcm9jZXNzaW5nIG9mIHRoaXMgb2JqZWN0CiAgICAgICAgICogaXMgaGFuZGxlZCBjb21wbGV0ZWx5IGJ5IHRoZSBhZ2VudCB0b29sa2l0IGhlbHBlcnMuCiAgICAgICAgICovCiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICB9CgogICAgREVCVUdNU0dUTCgoImhhbmRsZXI6Y2FsbGluZyIsICJjYWxsaW5nIGhhbmRsZXIgJXMgZm9yIG1vZGUgJXNcbiIsCiAgICAgICAgICAgICAgICBuZXh0X2hhbmRsZXItPmhhbmRsZXJfbmFtZSwKICAgICAgICAgICAgICAgIHNlX2ZpbmRfbGFiZWxfaW5fc2xpc3QoImFnZW50X21vZGUiLCByZXFpbmZvLT5tb2RlKSkpOwoKICAgIC8qCiAgICAgKiBYWFg6IGRlZmluZSBhY2NlcHRhYmxlIHJldHVybiBzdGF0dXNlcyAKICAgICAqLwogICAgcmV0ID0gKCpuaCkgKG5leHRfaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwoKICAgIERFQlVHTVNHVEwoKCJoYW5kbGVyOnJldHVybmVkIiwgImhhbmRsZXIgJXMgcmV0dXJuZWQgJWRcbiIsCiAgICAgICAgICAgICAgICBuZXh0X2hhbmRsZXItPmhhbmRsZXJfbmFtZSwgcmV0KSk7CgogICAgaWYgKCEgKG5leHRfaGFuZGxlci0+ZmxhZ3MgJiBNSUJfSEFORExFUl9BVVRPX05FWFQpKQogICAgICAgIGJyZWFrOwoKICAgIC8qCiAgICAgKiBkaWQgaGFuZGxlciBzaWduYWwgdGhhdCBpdCBkaWRuJ3Qgd2FudCBhdXRvIG5leHQgdGhpcyB0aW1lIGFyb3VuZD8KICAgICAqLwogICAgaWYobmV4dF9oYW5kbGVyLT5mbGFncyAmIE1JQl9IQU5ETEVSX0FVVE9fTkVYVF9PVkVSUklERV9PTkNFKSB7CiAgICAgICAgbmV4dF9oYW5kbGVyLT5mbGFncyAmPSB+TUlCX0hBTkRMRVJfQVVUT19ORVhUX09WRVJSSURFX09OQ0U7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgbmV4dF9oYW5kbGVyID0gbmV4dF9oYW5kbGVyLT5uZXh0OwoKICAgIH0gd2hpbGUobmV4dF9oYW5kbGVyKTsKCiAgICByZXR1cm4gcmV0Owp9CgovKiogQGludGVybmFsCiAqICBjYWxscyBhbGwgdGhlIGhhbmRsZXJzIGZvciBhIGdpdmVuIG1vZGUuCiAqLwppbnQKbmV0c25tcF9jYWxsX2hhbmRsZXJzKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzOwoKICAgIGlmIChyZWdpbmZvID09IE5VTEwgfHwgcmVxaW5mbyA9PSBOVUxMIHx8IHJlcXVlc3RzID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9jYWxsX2hhbmRsZXJzKCkgY2FsbGVkIGlsbGVnYWxseVxuIik7CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVxaW5mbyAhPSBOVUxMKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3RzICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgaWYgKHJlZ2luZm8tPmhhbmRsZXIgPT0gTlVMTCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJubyBoYW5kbGVyIHNwZWNpZmllZC4iKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQoKICAgIHN3aXRjaCAocmVxaW5mby0+bW9kZSkgewogICAgY2FzZSBNT0RFX0dFVEJVTEs6CiAgICBjYXNlIE1PREVfR0VUOgogICAgY2FzZSBNT0RFX0dFVE5FWFQ6CiAgICAgICAgaWYgKCEocmVnaW5mby0+bW9kZXMgJiBIQU5ETEVSX0NBTl9HRVRBTkRHRVRORVhUKSkKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7ICAgIC8qIGxlZ2FsICovCiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgIGNhc2UgTU9ERV9TRVRfQ09NTUlUOgogICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgIGlmICghKHJlZ2luZm8tPm1vZGVzICYgSEFORExFUl9DQU5fU0VUKSkgewogICAgICAgICAgICBmb3IgKDsgcmVxdWVzdHM7IHJlcXVlc3RzID0gcmVxdWVzdHMtPm5leHQpIHsKICAgICAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX05PVFdSSVRBQkxFKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAidW5rbm93biBtb2RlIGluIG5ldHNubXBfY2FsbF9oYW5kbGVycyEgYnVnIVxuIik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KICAgIERFQlVHTVNHVEwoKCJoYW5kbGVyOmNhbGxpbmciLCAibWFpbiBoYW5kbGVyICVzXG4iLAogICAgICAgICAgICAgICAgcmVnaW5mby0+aGFuZGxlci0+aGFuZGxlcl9uYW1lKSk7CgogICAgZm9yIChyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgIHJlcXVlc3QtPnByb2Nlc3NlZCA9IDA7CiAgICB9CgogICAgc3RhdHVzID0gbmV0c25tcF9jYWxsX2hhbmRsZXIocmVnaW5mby0+aGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qKiBjYWxscyB0aGUgbmV4dCBoYW5kbGVyIGluIHRoZSBjaGFpbiBhZnRlciB0aGUgY3VycmVudCBvbmUgd2l0aAogICB3aXRoIGFwcHJvcHJpYXRlIE5VTEwgY2hlY2tpbmcsIGV0Yy4gKi8KTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqY3VycmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIGlmIChjdXJyZW50ID09IE5VTEwgfHwgcmVnaW5mbyA9PSBOVUxMIHx8IHJlcWluZm8gPT0gTlVMTCB8fAogICAgICAgIHJlcXVlc3RzID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9jYWxsX25leHRfaGFuZGxlcigpIGNhbGxlZCBpbGxlZ2FsbHlcbiIpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KGN1cnJlbnQgIT0gTlVMTCk7CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVnaW5mbyAhPSBOVUxMKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZXFpbmZvICE9IE5VTEwpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3RzICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgcmV0dXJuIG5ldHNubXBfY2FsbF9oYW5kbGVyKGN1cnJlbnQtPm5leHQsIHJlZ2luZm8sIHJlcWluZm8sIHJlcXVlc3RzKTsKfQoKLyoqIGNhbGxzIHRoZSBuZXh0IGhhbmRsZXIgaW4gdGhlIGNoYWluIGFmdGVyIHRoZSBjdXJyZW50IG9uZSB3aXRoCiAgIHdpdGggYXBwcm9wcmlhdGUgTlVMTCBjaGVja2luZywgZXRjLiAqLwpORVRTTk1QX0lOTElORSBpbnQKbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcl9vbmVfcmVxdWVzdChuZXRzbm1wX21pYl9oYW5kbGVyICpjdXJyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKICAgIGludCByZXQ7CiAgICAKICAgIGlmICghcmVxdWVzdHMpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmV0c25tcF9jYWxsX25leHRfaGFuZGxlcl9PTkVfUkVRVUVTVCgpIGNhbGxlZCBpbGxlZ2FsbHlcbiIpOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3RzICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgcmVxdWVzdCA9IHJlcXVlc3RzLT5uZXh0OwogICAgcmVxdWVzdHMtPm5leHQgPSBOVUxMOwogICAgcmV0ID0gbmV0c25tcF9jYWxsX2hhbmRsZXIoY3VycmVudC0+bmV4dCwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwogICAgcmVxdWVzdHMtPm5leHQgPSByZXF1ZXN0OwogICAgcmV0dXJuIHJldDsKfQoKLyoqIGZyZWVzIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gaGFuZGxlciAqLwp2b2lkCm5ldHNubXBfaGFuZGxlcl9mcmVlKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIpCnsKICAgIGlmIChoYW5kbGVyICE9IE5VTEwpIHsKICAgICAgICBpZiAoaGFuZGxlci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgIC8qKiBtYWtlIHN1cmUgd2UgYXJlbid0IHBvaW50aW5nIHRvIG91cnNlbHZlcy4gICovCiAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KGhhbmRsZXIgIT0gaGFuZGxlci0+bmV4dCk7IC8qIGJ1Z3MgY2F1Z2h0OiAxICovCiAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKGhhbmRsZXItPm5leHQpOwogICAgICAgICAgICBoYW5kbGVyLT5uZXh0ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYgKChoYW5kbGVyLT5teXZvaWQgIT0gTlVMTCkgJiYgKGhhbmRsZXItPmRhdGFfZnJlZSAhPSBOVUxMKSkKICAgICAgICB7CiAgICAgICAgICAgIGhhbmRsZXItPmRhdGFfZnJlZShoYW5kbGVyLT5teXZvaWQpOwogICAgICAgIH0KICAgICAgICBTTk1QX0ZSRUUoaGFuZGxlci0+aGFuZGxlcl9uYW1lKTsKICAgICAgICBTTk1QX0ZSRUUoaGFuZGxlcik7CiAgICB9Cn0KCi8qKiBkdXBsaWNhdGVzIGEgaGFuZGxlciBhbmQgYWxsIHN1YnNlcXVlbnQgaGFuZGxlcnMKICogc2VlIGFsc28gX2Nsb25lX2hhbmRsZXIKICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2hhbmRsZXJfZHVwKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmggPSBOVUxMOwoKICAgIGlmIChoYW5kbGVyID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBoID0gX2Nsb25lX2hhbmRsZXIoaGFuZGxlcik7CgogICAgaWYgKGggIT0gTlVMTCkgewogICAgICAgIGgtPm15dm9pZCA9IGhhbmRsZXItPm15dm9pZDsKICAgICAgICBoLT5kYXRhX2ZyZWUgPSBoYW5kbGVyLT5kYXRhX2ZyZWU7CgogICAgICAgIGlmIChoYW5kbGVyLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgaC0+bmV4dCA9IG5ldHNubXBfaGFuZGxlcl9kdXAoaGFuZGxlci0+bmV4dCk7CiAgICAgICAgICAgIGlmIChoLT5uZXh0ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKGgpOwogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaC0+bmV4dC0+cHJldiA9IGg7CiAgICAgICAgfQogICAgICAgIGgtPnByZXYgPSBOVUxMOwogICAgICAgIHJldHVybiBoOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBmcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIGEgaGFuZGxlciByZWdpc3RyYXRpb24gb2JqZWN0ICovCnZvaWQKbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbl9mcmVlKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8pCnsKICAgIGlmIChyZWdpbmZvICE9IE5VTEwpIHsKICAgICAgICBuZXRzbm1wX2hhbmRsZXJfZnJlZShyZWdpbmZvLT5oYW5kbGVyKTsKICAgICAgICBTTk1QX0ZSRUUocmVnaW5mby0+aGFuZGxlck5hbWUpOwogICAgICAgIFNOTVBfRlJFRShyZWdpbmZvLT5jb250ZXh0TmFtZSk7CiAgICAgICAgU05NUF9GUkVFKHJlZ2luZm8tPnJvb3RvaWQpOwogICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuID0gMDsKICAgICAgICBTTk1QX0ZSRUUocmVnaW5mbyk7CiAgICB9Cn0KCi8qKiBkdXBsaWNhdGVzIHRoZSBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBvYmplY3QgKi8KbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqCm5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fZHVwKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8pCnsKICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnIgPSBOVUxMOwoKICAgIGlmIChyZWdpbmZvID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCgogICAgciA9IChuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICopIGNhbGxvYygxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24pKTsKCiAgICBpZiAociAhPSBOVUxMKSB7CiAgICAgICAgci0+bW9kZXMgPSByZWdpbmZvLT5tb2RlczsKICAgICAgICByLT5wcmlvcml0eSA9IHJlZ2luZm8tPnByaW9yaXR5OwogICAgICAgIHItPnJhbmdlX3N1YmlkID0gcmVnaW5mby0+cmFuZ2Vfc3ViaWQ7CiAgICAgICAgci0+dGltZW91dCA9IHJlZ2luZm8tPnRpbWVvdXQ7CiAgICAgICAgci0+cmFuZ2VfdWJvdW5kID0gcmVnaW5mby0+cmFuZ2VfdWJvdW5kOwogICAgICAgIHItPnJvb3RvaWRfbGVuID0gcmVnaW5mby0+cm9vdG9pZF9sZW47CgogICAgICAgIGlmIChyZWdpbmZvLT5oYW5kbGVyTmFtZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHItPmhhbmRsZXJOYW1lID0gc3RyZHVwKHJlZ2luZm8tPmhhbmRsZXJOYW1lKTsKICAgICAgICAgICAgaWYgKHItPmhhbmRsZXJOYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fZnJlZShyKTsKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAocmVnaW5mby0+Y29udGV4dE5hbWUgIT0gTlVMTCkgewogICAgICAgICAgICByLT5jb250ZXh0TmFtZSA9IHN0cmR1cChyZWdpbmZvLT5jb250ZXh0TmFtZSk7CiAgICAgICAgICAgIGlmIChyLT5jb250ZXh0TmFtZSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUocik7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHJlZ2luZm8tPnJvb3RvaWQgIT0gTlVMTCkgewogICAgICAgICAgICByLT5yb290b2lkID0KICAgICAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKHJlZ2luZm8tPnJvb3RvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuKTsKICAgICAgICAgICAgaWYgKHItPnJvb3RvaWQgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbl9mcmVlKHIpOwogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHItPmhhbmRsZXIgPSBuZXRzbm1wX2hhbmRsZXJfZHVwKHJlZ2luZm8tPmhhbmRsZXIpOwogICAgICAgIGlmIChyLT5oYW5kbGVyID09IE5VTEwpIHsKICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbl9mcmVlKHIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBjcmVhdGVzIGEgY2FjaGUgb2YgaW5mb3JtYXRpb24gd2hpY2ggY2FuIGJlIHNhdmVkIGZvciBmdXR1cmUKICAgcmVmZXJlbmNlLiAgVXNlIG5ldHNubXBfaGFuZGxlcl9jaGVja19jYWNoZSgpIGxhdGVyIHRvIG1ha2Ugc3VyZSBpdCdzIHN0aWxsCiAgIHZhbGlkIGJlZm9yZSByZWZlcmVuY2luZyBpdCBpbiB0aGUgZnV0dXJlLiAqLwpORVRTTk1QX0lOTElORSBuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqCm5ldHNubXBfY3JlYXRlX2RlbGVnYXRlZF9jYWNoZShuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqbG9jYWxpbmZvKQp7CiAgICBuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqcmV0OwoKICAgIHJldCA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9kZWxlZ2F0ZWRfY2FjaGUpOwogICAgaWYgKHJldCkgewogICAgICAgIHJldC0+dHJhbnNhY3Rpb25faWQgPSByZXFpbmZvLT5hc3AtPnBkdS0+dHJhbnNpZDsKICAgICAgICByZXQtPmhhbmRsZXIgPSBoYW5kbGVyOwogICAgICAgIHJldC0+cmVnaW5mbyA9IHJlZ2luZm87CiAgICAgICAgcmV0LT5yZXFpbmZvID0gcmVxaW5mbzsKICAgICAgICByZXQtPnJlcXVlc3RzID0gcmVxdWVzdHM7CiAgICAgICAgcmV0LT5sb2NhbGluZm8gPSBsb2NhbGluZm87CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKiogY2hlY2sncyBhIGdpdmVuIGNhY2hlIGFuZCByZXR1cm5zIGl0IGlmIGl0IGlzIHN0aWxsIHZhbGlkIChpZSwgdGhlCiAgIGFnZW50IHN0aWxsIGNvbnNpZGVycyBpdCB0byBiZSBhbiBvdXRzdGFuZGluZyByZXF1ZXN0LiAgUmV0dXJucwogICBOVUxMIGlmIGl0J3Mgbm8gbG9uZ2VyIHZhbGlkLiAqLwpORVRTTk1QX0lOTElORSBuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqCm5ldHNubXBfaGFuZGxlcl9jaGVja19jYWNoZShuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqZGNhY2hlKQp7CiAgICBpZiAoIWRjYWNoZSkKICAgICAgICByZXR1cm4gZGNhY2hlOwoKICAgIGlmIChuZXRzbm1wX2NoZWNrX3RyYW5zYWN0aW9uX2lkKGRjYWNoZS0+dHJhbnNhY3Rpb25faWQpID09CiAgICAgICAgU05NUEVSUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBkY2FjaGU7CgogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBmcmVlcyBhIGNhY2hlIG9uY2UgeW91J3JlIGZpbmlzaGVkIHVzaW5nIGl0ICovCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9mcmVlX2RlbGVnYXRlZF9jYWNoZShuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqZGNhY2hlKQp7CiAgICAvKgogICAgICogcmlnaHQgbm93LCBubyBleHRyYSBkYXRhIGlzIHRoZXJlIHRoYXQgbmVlZHMgdG8gYmUgZnJlZWQgCiAgICAgKi8KICAgIGlmIChkY2FjaGUpCiAgICAgICAgU05NUF9GUkVFKGRjYWNoZSk7CgogICAgcmV0dXJuOwp9CgoKLyoqIG1hcmtzIGEgbGlzdCBvZiByZXF1ZXN0cyBhcyBkZWxlZ2F0ZWQgKG9yIG5vdCBpZiBpc2RlbGVnYWRlZCA9IDApICovCnZvaWQKbmV0c25tcF9oYW5kbGVyX21hcmtfcmVxdWVzdHNfYXNfZGVsZWdhdGVkKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpc2RlbGVnYXRlZCkKewogICAgd2hpbGUgKHJlcXVlc3RzKSB7CiAgICAgICAgcmVxdWVzdHMtPmRlbGVnYXRlZCA9IGlzZGVsZWdhdGVkOwogICAgICAgIHJlcXVlc3RzID0gcmVxdWVzdHMtPm5leHQ7CiAgICB9Cn0KCi8qKiBhZGQgZGF0YSB0byBhIHJlcXVlc3QgdGhhdCBjYW4gYmUgZXh0cmFjdGVkIGxhdGVyIGJ5IHN1Ym1vZHVsZXMKICoKICogQHBhcmFtIHJlcXVlc3QgdGhlIG5ldHNubXAgcmVxdWVzdCBpbmZvIHN0cnVjdHVyZQogKgogKiBAcGFyYW0gbm9kZSB0aGlzIGlzIHRoZSBkYXRhIHRvIGJlIGFkZGVkIHRvIHRoZSBsaW5rZWQgbGlzdAogKiAgICAgICAgICAgICByZXF1ZXN0LT5wYXJlbnRfZGF0YQogKgogKiBAcmV0dXJuIHZvaWQKICoKICovCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZGF0YV9saXN0ICpub2RlKQp7CiAgICBpZiAocmVxdWVzdCkgewogICAgICAgIGlmIChyZXF1ZXN0LT5wYXJlbnRfZGF0YSkKICAgICAgICAgICAgbmV0c25tcF9hZGRfbGlzdF9kYXRhKCZyZXF1ZXN0LT5wYXJlbnRfZGF0YSwgbm9kZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXF1ZXN0LT5wYXJlbnRfZGF0YSA9IG5vZGU7CiAgICB9Cn0KCi8qKiByZW1vdmUgZGF0YSBmcm9tIGEgcmVxdWVzdAogKgogKiBAcGFyYW0gcmVxdWVzdCB0aGUgbmV0c25tcCByZXF1ZXN0IGluZm8gc3RydWN0dXJlCiAqCiAqIEBwYXJhbSBuYW1lIHRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIHByZXZpb3VzbHkgYWRkZWQgZGF0YQogKgogKiBAcmV0dXJuIDAgb24gc3VjY2Vzc2Z1bCBmaW5kLWFuZC1kZWxldGUsIDEgb3RoZXJ3aXNlLgogKgogKi8KTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfcmVxdWVzdF9yZW1vdmVfbGlzdF9kYXRhKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICBpZiAoKE5VTEwgPT0gcmVxdWVzdCkgfHwgKE5VTEwgPT1yZXF1ZXN0LT5wYXJlbnRfZGF0YSkpCiAgICAgICAgcmV0dXJuIDE7CgogICAgcmV0dXJuIG5ldHNubXBfcmVtb3ZlX2xpc3Rfbm9kZSgmcmVxdWVzdC0+cGFyZW50X2RhdGEsIG5hbWUpOwp9CgovKiogZXh0cmFjdCBkYXRhIGZyb20gYSByZXF1ZXN0IHRoYXQgd2FzIGFkZGVkIHByZXZpb3VzbHkgYnkgYSBwYXJlbnQgbW9kdWxlCiAqCiAqIEBwYXJhbSByZXF1ZXN0IHRoZSBuZXRzbm1wIHJlcXVlc3QgaW5mbyBmdW5jdGlvbgogKgogKiBAcGFyYW0gbmFtZSB1c2VkIHRvIGNvbXBhcmUgYWdhaW5zdCB0aGUgcmVxdWVzdC0+cGFyZW50X2RhdGEtPm5hbWUgdmFsdWUsCiAqICAgICAgICAgICAgIGlmIGEgbWF0Y2ggaXMgZm91bmQgcmVxdWVzdC0+cGFyZW50X2RhdGEtPmRhdGEgaXMgcmV0dXJuZWQKICoKICogQHJldHVybiBhIHZvaWQgcG9pbnRlcihyZXF1ZXN0LT5wYXJlbnRfZGF0YS0+ZGF0YSksIG90aGVyd2lzZSBOVUxMIGlzCiAqICAgICAgICAgcmV0dXJuZWQgaWYgcmVxdWVzdCBpcyBOVUxMIG9yIHJlcXVlc3QtPnBhcmVudF9kYXRhIGlzIE5VTEwgb3IKICogICAgICAgICByZXF1ZXN0LT5wYXJlbnRfZGF0YSBvYmplY3QgaXMgbm90IGZvdW5kLgogKi8Kdm9pZCAgICAqCm5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICBpZiAocmVxdWVzdCkKICAgICAgICByZXR1cm4gbmV0c25tcF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QtPnBhcmVudF9kYXRhLCBuYW1lKTsKICAgIHJldHVybiBOVUxMOwp9CgovKiogRnJlZSB0aGUgZXh0cmEgZGF0YSBzdG9yZWQgaW4gYSByZXF1ZXN0ICovCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXQobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QpCnsKICAgIGlmIChyZXF1ZXN0KQogICAgICAgIG5ldHNubXBfZnJlZV9saXN0X2RhdGEocmVxdWVzdC0+cGFyZW50X2RhdGEpOwp9CgovKiogRnJlZSB0aGUgZXh0cmEgZGF0YSBzdG9yZWQgaW4gYSBidW5jaCBvZiByZXF1ZXN0cyAoYWxsIGRhdGEgaW4gdGhlIGNoYWluKSAqLwpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cyhuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCkKewogICAgaWYgKHJlcXVlc3QgJiYgcmVxdWVzdC0+cGFyZW50X2RhdGEpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfYWxsX2xpc3RfZGF0YShyZXF1ZXN0LT5wYXJlbnRfZGF0YSk7CiAgICAgICAgcmVxdWVzdC0+cGFyZW50X2RhdGEgPSBOVUxMOwogICAgfQp9CgovKiogUmV0dXJucyBhIGhhbmRsZXIgZnJvbSBhIGNoYWluIGJhc2VkIG9uIHRoZSBuYW1lICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2ZpbmRfaGFuZGxlcl9ieV9uYW1lKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaXQ7CiAgICBpZiAocmVnaW5mbyA9PSBOVUxMIHx8IG5hbWUgPT0gTlVMTCApCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBmb3IgKGl0ID0gcmVnaW5mby0+aGFuZGxlcjsgaXQ7IGl0ID0gaXQtPm5leHQpIHsKICAgICAgICBpZiAoc3RyY21wKGl0LT5oYW5kbGVyX25hbWUsIG5hbWUpID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIGl0OwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKiogUmV0dXJucyBhIGhhbmRsZXIncyB2b2lkICogcG9pbnRlciBmcm9tIGEgY2hhaW4gYmFzZWQgb24gdGhlIG5hbWUuCiBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSB1c2VkIGJ5IHRoZSBnZW5lcmFsIHB1YmxpYyBhcyB0aGUgdm9pZCAqCiBkYXRhIG1heSBjaGFuZ2UgYXMgYSBoYW5kbGVyIGV2b2x2ZXMuICBIYW5kbGVycyBzaG91bGQgcmVhbGx5CiBhZHZlcnRpc2Ugc29tZSBmdW5jdGlvbiBmb3IgeW91IHRvIHVzZSBpbnN0ZWFkLiAqLwp2b2lkICAgICAgICAgICAqCm5ldHNubXBfZmluZF9oYW5kbGVyX2RhdGFfYnlfbmFtZShuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaXQgPSBuZXRzbm1wX2ZpbmRfaGFuZGxlcl9ieV9uYW1lKHJlZ2luZm8sIG5hbWUpOwogICAgaWYgKGl0KQogICAgICAgIHJldHVybiBpdC0+bXl2b2lkOwogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBjbG9uZXMgYSBtaWIgaGFuZGxlciAobmFtZSwgZmxhZ3MgYW5kIGFjY2VzcyBtZXRob2RzIG9ubHk7IG5vdCBteXZvaWQpCiAqIHNlZSBhbHNvIG5ldHNubXBfaGFuZGxlcl9kdXAKICovCnN0YXRpYyBuZXRzbm1wX21pYl9oYW5kbGVyICoKX2Nsb25lX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaXQpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmR1cDsKCiAgICBpZihOVUxMID09IGl0KQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGR1cCA9IG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoaXQtPmhhbmRsZXJfbmFtZSwgaXQtPmFjY2Vzc19tZXRob2QpOwogICAgaWYoTlVMTCAhPSBkdXApCiAgICAgICAgZHVwLT5mbGFncyA9IGl0LT5mbGFnczsKCiAgICByZXR1cm4gZHVwOwp9CgpzdGF0aWMgbmV0c25tcF9kYXRhX2xpc3QgKmhhbmRsZXJfcmVnID0gTlVMTDsKCnZvaWQKaGFuZGxlcl9mcmVlX2NhbGxiYWNrKHZvaWQgKmhhbmRsZXIpCnsKICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKChuZXRzbm1wX21pYl9oYW5kbGVyICopaGFuZGxlcik7Cn0KCi8qKiByZWdpc3RlcnMgYSBnaXZlbiBoYW5kbGVyIGJ5IG5hbWUgc28gdGhhdCBpdCBjYW4gYmUgZm91bmQgZWFzaWx5IGxhdGVyLgogKi8Kdm9pZApuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXJfYnlfbmFtZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyKQp7CiAgICBuZXRzbm1wX2FkZF9saXN0X2RhdGEoJmhhbmRsZXJfcmVnLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdChuYW1lLCAodm9pZCAqKSBoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyX2ZyZWVfY2FsbGJhY2spKTsKICAgIERFQlVHTVNHVEwoKCJoYW5kbGVyX3JlZ2lzdHJ5IiwgInJlZ2lzdGVyaW5nIGhlbHBlciAlc1xuIiwgbmFtZSkpOwp9CgovKiogY2xlYXJzIHRoZSBlbnRpcmUgaGFuZGxlci1yZWdpc3RyYXRpb24gbGlzdAogKi8Kdm9pZApuZXRzbm1wX2NsZWFyX2hhbmRsZXJfbGlzdCh2b2lkKQp7CiAgICBERUJVR01TR1RMKCgiYWdlbnRfaGFuZGxlciIsICJuZXRzbm1wX2NsZWFyX2hhbmRsZXJfbGlzdCgpIGNhbGxlZFxuIikpOwogICAgbmV0c25tcF9mcmVlX2FsbF9saXN0X2RhdGEoaGFuZGxlcl9yZWcpOwogICAgaGFuZGxlcl9yZWcgPSBOVUxMOwp9CgovKiogQGludGVybmFsCiAqICBpbmplY3RzIGEgaGFuZGxlciBpbnRvIGEgc3VidHJlZSwgcGVlcnMgYW5kIGNoaWxkcmVuIHdoZW4gYSBnaXZlbgogKiAgc3VidHJlZXMgbmFtZSBtYXRjaGVzIGEgcGFzc2VkIGluIG5hbWUuCiAqLwp2b2lkCm5ldHNubXBfaW5qZWN0X2hhbmRsZXJfaW50b19zdWJ0cmVlKG5ldHNubXBfc3VidHJlZSAqdHAsIGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmJlZm9yZV93aGF0KQp7CiAgICBuZXRzbm1wX3N1YnRyZWUgKnRwdHI7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICptaDsKCiAgICBmb3IgKHRwdHIgPSB0cDsgdHB0ciAhPSBOVUxMOyB0cHRyID0gdHB0ci0+bmV4dCkgewogICAgICAgIC8qICBpZiAodHB0ci0+Y2hpbGRyZW4pIHsgCiAgICAgICAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcl9pbnRvX3N1YnRyZWUodHB0ci0+Y2hpbGRyZW4sbmFtZSxoYW5kbGVyKTsKCSAgICB9ICAgKi8KICAgICAgICBpZiAoc3RyY21wKHRwdHItPmxhYmVsX2EsIG5hbWUpID09IDApIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImluamVjdEhhbmRsZXIiLCAiaW5qZWN0aW5nIGhhbmRsZXIgJXMgaW50byAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+aGFuZGxlcl9uYW1lLCB0cHRyLT5sYWJlbF9hKSk7CiAgICAgICAgICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXJfYmVmb3JlKHRwdHItPnJlZ2luZm8sIF9jbG9uZV9oYW5kbGVyKGhhbmRsZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWZvcmVfd2hhdCk7CiAgICAgICAgfSBlbHNlIGlmICh0cHRyLT5yZWdpbmZvICE9IE5VTEwgJiYKCQkgICB0cHRyLT5yZWdpbmZvLT5oYW5kbGVyTmFtZSAhPSBOVUxMICYmCiAgICAgICAgICAgICAgICAgICBzdHJjbXAodHB0ci0+cmVnaW5mby0+aGFuZGxlck5hbWUsIG5hbWUpID09IDApIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImluamVjdEhhbmRsZXIiLCAiaW5qZWN0aW5nIGhhbmRsZXIgaW50byAlcy8lc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgdHB0ci0+bGFiZWxfYSwgdHB0ci0+cmVnaW5mby0+aGFuZGxlck5hbWUpKTsKICAgICAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcl9iZWZvcmUodHB0ci0+cmVnaW5mbywgX2Nsb25lX2hhbmRsZXIoaGFuZGxlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZV93aGF0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3IgKG1oID0gdHB0ci0+cmVnaW5mby0+aGFuZGxlcjsgbWggIT0gTlVMTDsgbWggPSBtaC0+bmV4dCkgewogICAgICAgICAgICAgICAgaWYgKG1oLT5oYW5kbGVyX25hbWUgJiYgc3RyY21wKG1oLT5oYW5kbGVyX25hbWUsIG5hbWUpID09IDApIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaW5qZWN0SGFuZGxlciIsICJpbmplY3RpbmcgaGFuZGxlciBpbnRvICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwdHItPmxhYmVsX2EpKTsKICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyX2JlZm9yZSh0cHRyLT5yZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jbG9uZV9oYW5kbGVyKGhhbmRsZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZV93aGF0KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImluamVjdEhhbmRsZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgaW5qZWN0aW5nIGhhbmRsZXIgaW50byAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaC0+aGFuZGxlcl9uYW1lKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCnN0YXRpYyBpbnQgICAgICBkb25laXQgPSAwOwovKiogQGludGVybmFsCiAqICBwYXJzZXMgdGhlICJpbmplY3RIYW5kbGVyIiB0b2tlbiBsaW5lLgogKi8Kdm9pZApwYXJzZV9pbmplY3RIYW5kbGVyX2NvbmYoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIGNoYXIgICAgICAgICAgICBoYW5kbGVyX3RvX2luc2VydFsyNTZdLCByZWdfbmFtZVsyNTZdOwogICAgc3VidHJlZV9jb250ZXh0X2NhY2hlICpzdGM7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyOwoKICAgIC8qCiAgICAgKiBYWFhXV1c6IGVuc3VyZSBpbnN0ZWFkIHRoYXQgaGFuZGxlciBpc24ndCBpbnNlcnRlZCB0d2ljZSAKICAgICAqLwogICAgaWYgKGRvbmVpdCkgICAgICAgICAgICAgICAgIC8qIHdlIG9ubHkgZG8gdGhpcyBvbmNlIHdpdGhvdXQgcmVzdGFydCB0aGUgYWdlbnQgKi8KICAgICAgICByZXR1cm47CgogICAgY3B0ciA9IGNvcHlfbndvcmQoY3B0ciwgaGFuZGxlcl90b19pbnNlcnQsIHNpemVvZihoYW5kbGVyX3RvX2luc2VydCkpOwogICAgaGFuZGxlciA9IG5ldHNubXBfZ2V0X2xpc3RfZGF0YShoYW5kbGVyX3JlZywgaGFuZGxlcl90b19pbnNlcnQpOwogICAgaWYgKCFoYW5kbGVyKSB7CgluZXRzbm1wX2NvbmZpZ19lcnJvcigibm8gXCIlc1wiIGhhbmRsZXIgcmVnaXN0ZXJlZC4iLAoJCQkgICAgIGhhbmRsZXJfdG9faW5zZXJ0KTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCFjcHRyKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigibm8gSU5UT05BTUUgc3BlY2lmaWVkLiAgQ2FuJ3QgZG8gaW5zZXJ0aW9uLiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNwdHIgPSBjb3B5X253b3JkKGNwdHIsIHJlZ19uYW1lLCBzaXplb2YocmVnX25hbWUpKTsKCiAgICBmb3IgKHN0YyA9IGdldF90b3BfY29udGV4dF9jYWNoZSgpOyBzdGM7IHN0YyA9IHN0Yy0+bmV4dCkgewogICAgICAgIERFQlVHTVNHVEwoKCJpbmplY3RIYW5kbGVyIiwgIkNoZWNraW5nIGNvbnRleHQgdHJlZSAlcyAoYmVmb3JlPSVzKVxuIiwKICAgICAgICAgICAgICAgICAgICBzdGMtPmNvbnRleHRfbmFtZSwgKGNwdHIpP2NwdHI6Im51bGwiKSk7CiAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcl9pbnRvX3N1YnRyZWUoc3RjLT5maXJzdF9zdWJ0cmVlLCByZWdfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLCBjcHRyKTsKICAgIH0KfQoKLyoqIEBpbnRlcm5hbAogKiAgY2FsbGJhY2sgdG8gZW5zdXJlIGluamVjdEhhbmRsZXIgcGFyc2VyIGRvZXNuJ3QgZG8gdGhpbmdzIHR3aWNlCiAqICBAdG9kbyByZXBsYWNlIHRoaXMgd2l0aCBhIG1ldGhvZCB0byBjaGVjayB0aGUgaGFuZGxlciBjaGFpbiBpbnN0ZWFkLgogKi8Kc3RhdGljIGludApoYW5kbGVyX21hcmtfaW5qZWN0X2hhbmRsZXJfZG9uZShpbnQgbWFqb3JJRCwgaW50IG1pbm9ySUQsCiAgICAgICAgICAgICAgICAgICAgdm9pZCAqc2VydmVyYXJnLCB2b2lkICpjbGllbnRhcmcpCnsKICAgIGRvbmVpdCA9IDE7CiAgICByZXR1cm4gMDsKfQoKLyoqIEBpbnRlcm5hbAogKiAgUmVnaXN0ZXJzIHRoZSBpbmplY3RIYW5kbGUgcGFyc2VyIHRva2VuLgogKi8Kdm9pZApuZXRzbm1wX2luaXRfaGFuZGxlcl9jb25mKHZvaWQpCnsKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJpbmplY3RIYW5kbGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlX2luamVjdEhhbmRsZXJfY29uZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICJpbmplY3RIYW5kbGVyIE5BTUUgSU5UT05BTUUgW0JFRk9SRV9PVEhFUl9OQU1FXSIpOwogICAgc25tcF9yZWdpc3Rlcl9jYWxsYmFjayhTTk1QX0NBTExCQUNLX0xJQlJBUlksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfQ0FMTEJBQ0tfUE9TVF9SRUFEX0NPTkZJRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcl9tYXJrX2luamVjdF9oYW5kbGVyX2RvbmUsIE5VTEwpOwoKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJHRVQiKSwgTU9ERV9HRVQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIkdFVE5FWFQiKSwgTU9ERV9HRVRORVhUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJHRVRCVUxLIiksIE1PREVfR0VUQlVMSyk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX0JFR0lOIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFVF9CRUdJTik7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX1JFU0VSVkUxIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFVF9SRVNFUlZFMSk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX1JFU0VSVkUyIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFVF9SRVNFUlZFMik7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX0FDVElPTiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9TRVRfQUNUSU9OKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJTRVRfQ09NTUlUIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFVF9DT01NSVQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIlNFVF9GUkVFIiksIE1PREVfU0VUX0ZSRUUpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIlNFVF9VTkRPIiksIE1PREVfU0VUX1VORE8pOwoKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJwcmUtcmVxdWVzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9QUkVfUkVRVUVTVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgib2JqZWN0X2xvb2t1cCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9PQkpFQ1RfTE9PS1VQKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJjaGVja192YWx1ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9DSEVDS19WQUxVRSk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgicm93X2NyZWF0ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9ST1dfQ1JFQVRFKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJ1bmRvX3NldHVwIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1VORE9fU0VUVVApOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoInNldF92YWx1ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9TRVRfVkFMVUUpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoImNoZWNrX2NvbnNpc3RlbmN5IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX0NIRUNLX0NPTlNJU1RFTkNZKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJ1bmRvX3NldCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9VTkRPX1NFVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgiY29tbWl0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX0NPTU1JVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgidW5kb19jb21taXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfVU5ET19DT01NSVQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoImlycmV2ZXJzaWJsZV9jb21taXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfSVJSRVZFUlNJQkxFX0NPTU1JVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgidW5kb19jbGVhbnVwIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1VORE9fQ0xFQU5VUCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgicG9zdF9yZXF1ZXN0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1BPU1RfUkVRVUVTVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgib3JpZ2luYWwiKSwgMHhmZmZmKTsKCiAgICAvKgogICAgICogeHh4LXJrczogaG1tbS4uIHdpbGwgdGhpcyB3b3JrIGZvciBtb2RlcyB3aGljaCBhcmUgb3InZCB0b2dldGhlcj8KICAgICAqICAgICAgICAgIEknbSBiZXR0aW5nIG5vdC4uLgogICAgICovCiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiaGFuZGxlcl9jYW5fbW9kZSIsIHN0cmR1cCgiR0VUL0dFVE5FWFQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX0dFVEFOREdFVE5FWFQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImhhbmRsZXJfY2FuX21vZGUiLCBzdHJkdXAoIlNFVCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFUl9DQU5fU0VUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJoYW5kbGVyX2Nhbl9tb2RlIiwgc3RyZHVwKCJHRVRCVUxLIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9HRVRCVUxLKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJoYW5kbGVyX2Nhbl9tb2RlIiwgc3RyZHVwKCJCQUJZX1NURVAiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX0JBQllfU1RFUCk7Cn0KCi8qKiBAfSAqLwo=