LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYnVsa190b19uZXh0Lmg+CgoKc3RhdGljIG5ldHNubXBfbWliX2hhbmRsZXIgKl9jbG9uZV9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKml0KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogTmV3IEhhbmRsZXIgYmFzZWQgQVBJIAogKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiogQGRlZmdyb3VwIGhhbmRsZXIgTmV0LVNOTVAgQWdlbnQgaGFuZGxlciBhbmQgZXh0ZW5zaWJpbGl0eSBBUEkKICogIEBpbmdyb3VwIGFnZW50CiAqCiAqICBUaGUgYmFzaWMgdGhlb3J5IGdvZXMgc29tZXRoaW5nIGxpa2UgdGhpczogSW4gdGhlIHBhc3QsIHdpdGggdGhlCiAqICBvcmlnaW5hbCBtaWIgbW9kdWxlIGFwaSAod2hpY2ggZGVyaXZlZCBmcm9tIHRoZSBvcmlnaW5hbCBDTVUgU05NUAogKiAgY29kZSkgdGhlIHVuZGVybHlpbmcgbWliIG1vZHVsZXMgd2VyZSBwYXNzZWQgdmVyeSBsaXR0bGUKICogIGluZm9ybWF0aW9uIChvbmx5IHRoZSB0cnVseSBtb3N0IGJhc2ljIGluZm9ybWF0aW9uIGFib3V0IGEKICogIHJlcXVlc3QpLiAgVGhpcyB3b3JrZWQgd2VsbCBhdCB0aGUgdGltZSBidXQgaW4gdG9kYXlzIHdvcmxkIG9mCiAqICBzdWJhZ2VudHMsIGRldmljZSBpbnN0cnVtZW50YXRpb24sIGxvdyByZXNvdXJjZSBjb25zdW1wdGlvbiwgZXRjLAogKiAgaXQganVzdCBpc24ndCBmbGV4aWJsZSBlbm91Z2guICAiaGFuZGxlcnMiIGFyZSBoZXJlIHRvIGZpeCBhbGwgdGhhdC4KICoKICogIFdpdGggdGhlIHJld3JpdGUgb2YgdGhlIGFnZW50IGludGVybmFscyBmb3IgdGhlIG5ldC1zbm1wIDUuMAogKiAgcmVsZWFzZSwgd2UgaW50cm9kdWNlIGEgbW9kdWxhciBjYWxsaW5nIHNjaGVtZSB0aGF0IGFsbG93cyBhZ2VudAogKiAgbW9kdWxlcyB0byBiZSB3cml0dGVuIGluIGEgdmVyeSBmbGV4aWJsZSBtYW5uZXIsIGFuZCBtb3JlCiAqICBpbXBvcnRhbnRseSBhbGxvd3MgcmV1c2Ugb2YgY29kZSBpbiBhIGRlY2VudCB3YXkgKGFuZCB3aXRob3V0IHRoZQogKiAgbWVtb3J5IGFuZCBzcGVlZCBvdmVyaGVhZHMgb2YgT08gbGFuZ3VhZ2VzIGxpa2UgQysrKS4KICoKICogIEZ1bmN0aW9uYWxseSwgdGhlIG5vdGlvbiBvZiB3aGF0IGEgaGFuZGxlciBkb2VzIGlzIHRoZSBzYW1lIGFzIHRoZQogKiAgb2xkZXIgYXBpOiBBIGhhbmRsZXIgaXMgQGxpbmsgbmV0c25tcF9jcmVhdGVfaGFuZGxlcigpIGNyZWF0ZWRAZW5kbGluayBhbmQKICogIHRoZW4gQGxpbmsgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKCkgcmVnaXN0ZXJlZEBlbmRsaW5rIHdpdGggdGhlIG1haW4KICogIGFnZW50IGF0IGEgZ2l2ZW4gT0lEIGluIHRoZSBPSUQgdHJlZSBhbmQgZ2V0cyBjYWxsZWQgYW55IHRpbWUgYQogKiAgcmVxdWVzdCBpcyBtYWRlIHRoYXQgaXQgc2hvdWxkIHJlc3BvbmQgdG8uICBZb3UgcHJvYmFibHkgc2hvdWxkCiAqICB1c2Ugb25lIG9mIHRoZSBjb252ZW5pZW5jZSBoZWxwZXJzIGluc3RlYWQgb2YgZG9pbmcgYW55dGhpbmcgZWxzZQogKiAgeW91cnNlbGYgdGhvdWdoOgogKgogKiAgTW9zdCBpbXBvcnRhbnRseSwgdGhvdWdoLCBpcyB0aGF0IHRoZSBoYW5kbGVycyBhcmUgYnVpbHQgb24gdGhlCiAqICBub3Rpb24gb2YgbW9kdWxhcml0eSBhbmQgcmV1c2UuICBTcGVjaWZpY2FsbHksIHJhdGhlciB0aGFuIGRvIGFsbAogKiAgdGhlIHJlYWxseSBoYXJkIHdvcmsgKGxpa2UgcGFyc2luZyB0YWJsZSBpbmRleGVzIG91dCBvZiBhbgogKiAgaW5jb21pbmcgb2lkIHJlcXVlc3QpIGluIGVhY2ggbW9kdWxlLCB0aGUgQVBJIGlzIGRlc2lnbmVkIHRvIG1ha2UKICogIGl0IGVhc3kgdG8gd3JpdGUgImhlbHBlciIgaGFuZGxlcnMgdGhhdCBtZXJlbHkgcHJvY2VzcyBzb21lIGFzcGVjdAogKiAgb2YgdGhlIHJlcXVlc3QgYmVmb3JlIHBhc3NpbmcgaXQgYWxvbmcgdG8gdGhlIGZpbmFsIGhhbmRsZXIgdGhhdAogKiAgcmV0dXJucyB0aGUgcmVhbCBhbnN3ZXIuICBNb3N0IHBlb3BsZSB3aWxsIHdhbnQgdG8gbWFrZSB1c2Ugb2YgdGhlCiAqICBAbGluayBpbnN0YW5jZSBpbnN0YW5jZUBlbmRsaW5rLCBAbGluayB0YWJsZSB0YWJsZUBlbmRsaW5rLCBAbGluawogKiAgdGFibGVfaXRlcmF0b3IgdGFibGVfaXRlcmF0b3JAZW5kbGluaywgQGxpbmsgdGFibGVfZGF0YQogKiAgdGFibGVfZGF0YUBlbmRsaW5rLCBvciBAbGluayB0YWJsZV9kYXRhc2V0IHRhYmxlX2RhdGFzZXRAZW5kbGluawogKiAgaGVscGVycyB0byBtYWtlIHRoZWlyIGxpZmUgZWFzaWVyLiAgVGhlc2UgImhlbHBlcnMiIGludGVycGVydAogKiAgaW1wb3J0YW50IGFzcGVjdHMgb2YgdGhlIHJlcXVlc3QgYW5kIHBhc3MgdGhlbSBvbiB0byB5b3UuCiAqCiAqICBGb3IgaW5zdGFuY2UsIHRoZSBAbGluayB0YWJsZSB0YWJsZUBlbmRsaW5rIGhlbHBlciBpcyBkZXNpZ25lZCB0bwogKiAgaGFuZCB5b3UgYSBsaXN0IG9mIGV4dHJhY3RlZCBpbmRleCB2YWx1ZXMgZnJvbSBhbiBpbmNvbWluZwogKiAgcmVxdWVzdC4gIFRIZSBAbGluayB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvckBlbmRsaW5rIGhlbHBlcgogKiAgaXMgYnVpbHQgb24gdG9wIG9mIHRoZSB0YWJsZSBoZWxwZXIsIGFuZCBpcyBkZXNpZ25lZCB0byBoZWxwIHlvdQogKiAgaXRlcmF0ZSB0aHJvdWdoIGRhdGEgc3RvcmVkIGVsc2V3aGVyZSAobGlrZSBpbiBhIGtlcm5lbCkgdGhhdCBpcwogKiAgbm90IGluIE9JRCBsZXhvZ3JhcGhpY2FsIG9yZGVyIChpZSwgZG9uJ3Qgd3JpdGUgeW91ciBvd24gaW5kZXgvb2lkCiAqICBzb3J0aW5nIHJvdXRpbmUsIHVzZSB0aGlzIGhlbHBlciBpbnN0ZWFkKS4gIFRoZSBiZWF1dHkgb2YgdGhlCiAqICBAbGluayB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvciBoZWxwZXJAZW5kbGluaywgYXMgd2VsbCBhcyB0aGUgQGxpbmsKICogIGluc3RhbmNlIGluc3RhbmNlQGVuZGxpbmsgaGVscGVyIGlzIHRoYXQgdGhleSB0YWtlIGNhcmUgb2YgdGhlIGNvbXBsZXgKICogIEdFVE5FWFQgcHJvY2Vzc2luZyBlbnRpcmVseSBmb3IgeW91IGFuZCBoYW5kIHlvdSBldmVyeXRoaW5nIHlvdQogKiAgbmVlZCB0byBtZXJlbHkgcmV0dXJuIHRoZSBkYXRhIGFzIGlmIGl0IHdhcyBhIEdFVCByZXF1ZXN0LiAgTXVjaAogKiAgbGVzcyBjb2RlIGFuZCBoYWlyIHB1bGxpbmcuICBJJ3ZlIHB1bGxlZCBhbGwgbXkgaGFpciBvdXQgdG8gaGVscAogKiAgeW91IHNvIHRoYXQgb25seSBvbmUgb2YgdXMgaGFzIHRvIGJlIGJhbGQuCiAqCiAqIEB7CiAqLwoKLyoqIGNyZWF0ZXMgYSBuZXRzbm1wX21pYl9oYW5kbGVyIHN0cnVjdHVyZSBnaXZlbiBhIG5hbWUgYW5kIGEgYWNjZXNzIG1ldGhvZC4KICogIFRoZSByZXR1cm5lZCBoYW5kbGVyIHNob3VsZCB0aGVuIGJlIEBsaW5rIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpCiAqICByZWdpc3RlcmVkLkBlbmRsaW5rCiAqCiAqICBAcGFyYW0gbmFtZSBpcyB0aGUgaGFuZGxlciBuYW1lIGFuZCBpcyBjb3BpZWQgdGhlbiBhc3NpZ25lZCB0bwogKiAgICAgICAgICAgICAgbmV0c25tcF9taWJfaGFuZGxlci0+aGFuZGxlcl9uYW1lCiAqCiAqICBAcGFyYW0gaGFuZGxlcl9hY2Nlc3NfbWV0aG9kIGlzIGEgZnVuY3Rpb24gcG9pbnRlciB1c2VkIGFzIHRoZSBhY2Nlc3MKICoJICAgbWV0aG9kIGZvciB0aGlzIGhhbmRsZXIgcmVnaXN0cmF0aW9uIGluc3RhbmNlIGZvciB3aGF0ZXZlciByZXF1aXJlZAogKiAgICAgICAgIG5lZWRzLgogKgogKiAgQHJldHVybiBhIHBvaW50ZXIgdG8gYSBwb3B1bGF0ZWQgbmV0c25tcF9taWJfaGFuZGxlciBzdHJ1Y3QgdG8gYmUKICogICAgICAgICAgcmVnaXN0ZXJlZAogKgogKiAgQHNlZSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigpCiAqICBAc2VlIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9jcmVhdGVfaGFuZGxlcihjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogaGFuZGxlcl9hY2Nlc3NfbWV0aG9kKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpyZXQgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfbWliX2hhbmRsZXIpOwogICAgaWYgKHJldCkgewogICAgICAgIHJldC0+YWNjZXNzX21ldGhvZCA9IGhhbmRsZXJfYWNjZXNzX21ldGhvZDsKICAgICAgICBpZiAoTlVMTCAhPSBuYW1lKSB7CiAgICAgICAgICAgIHJldC0+aGFuZGxlcl9uYW1lID0gc3RyZHVwKG5hbWUpOwogICAgICAgICAgICBpZiAoTlVMTCA9PSByZXQtPmhhbmRsZXJfbmFtZSkKICAgICAgICAgICAgICAgIFNOTVBfRlJFRShyZXQpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKiBjcmVhdGVzIGEgaGFuZGxlciByZWdpc3RyYXRpb24gc3RydWN0dXJlIGdpdmVuIGEgbmFtZSwgYQogKiAgYWNjZXNzX21ldGhvZCBmdW5jdGlvbiwgYSByZWdpc3RyYXRpb24gbG9jYXRpb24gb2lkIGFuZCB0aGUgbW9kZXMKICogIHRoZSBoYW5kbGVyIHN1cHBvcnRzLiBJZiBtb2RlcyA9PSAwLCB0aGVuIG1vZGVzIHdpbGwgYXV0b21hdGljYWxseQogKiAgYmUgc2V0IHRvIHRoZSBkZWZhdWx0IHZhbHVlIG9mIG9ubHkgSEFORExFUl9DQU5fREVGQVVMVCwgd2hpY2ggaXMKICogIGJ5IGRlZmF1bHQgcmVhZC1vbmx5IEdFVCBhbmQgR0VUTkVYVCByZXF1ZXN0cy4gQSBoYW5kZXIgd2hpY2ggc3VwcG9ydHMKICogIHNldHMgYnV0IG5vdCByb3cgY3JlYXRpb24gc2hvdWxkIHNldCB1cyBhIG1vZGUgb2YgSEFORExFUl9DQU5fU0VUX09OTFkuCiAqICBAbm90ZSBUaGlzIGVuZHMgdXAgY2FsbGluZyBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKG5hbWUsIGhhbmRsZXJfYWNjZXNzX21ldGhvZCkKICogIEBwYXJhbSBuYW1lIGlzIHRoZSBoYW5kbGVyIG5hbWUgYW5kIGlzIGNvcGllZCB0aGVuIGFzc2lnbmVkIHRvCiAqICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uLT5oYW5kbGVyTmFtZS4KICoKICogIEBwYXJhbSBoYW5kbGVyIGlzIGEgZnVuY3Rpb24gcG9pbnRlciB1c2VkIGFzIHRoZSBhY2Nlc3MKICoJbWV0aG9kIGZvciB0aGlzIGhhbmRsZXIgcmVnaXN0cmF0aW9uIGluc3RhbmNlIGZvciB3aGF0ZXZlciByZXF1aXJlZAogKgluZWVkcy4KICoKICogIEBwYXJhbSByZWdfb2lkIGlzIHRoZSByZWdpc3RyYXRpb24gbG9jYXRpb24gb2lkLgogKgogKiAgQHBhcmFtIHJlZ19vaWRfbGVuIGlzIHRoZSBsZW5ndGggb2YgcmVnX29pZCwgY2FuIHVzZSB0aGUgbWFjcm8sCiAqICAgICAgICAgT0lEX0xFTkdUSAogKgogKiAgQHBhcmFtIG1vZGVzIGlzIHVzZWQgdG8gY29uZmlndXJlIHJlYWQvd3JpdGUgYWNjZXNzLiAgSWYgbW9kZXMgPT0gMCwgCiAqCXRoZW4gbW9kZXMgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIHNldCB0byB0aGUgZGVmYXVsdCAKICoJdmFsdWUgb2Ygb25seSBIQU5ETEVSX0NBTl9ERUZBVUxULCB3aGljaCBpcyBieSBkZWZhdWx0IHJlYWQtb25seSBHRVQgCiAqCWFuZCBHRVRORVhUIHJlcXVlc3RzLiAgVGhlIG90aGVyIHR3byBtb2RlIG9wdGlvbnMgYXJlIHJlYWQgb25seSwgCiAqCUhBTkRMRVJfQ0FOX1JPTkxZLCBhbmQgcmVhZC93cml0ZSwgSEFORExFUl9DQU5fUldSSVRFLgogKgogKgkJLSBIQU5ETEVSX0NBTl9HRVRBTkRHRVRORVhUCiAqCQktIEhBTkRMRVJfQ0FOX1NFVAogKgkJLSBIQU5ETEVSX0NBTl9HRVRCVUxLICAgICAgCiAqCiAqCQktIEhBTkRMRVJfQ0FOX1JPTkxZICAgKEhBTkRMRVJfQ0FOX0dFVEFOREdFVE5FWFQpCiAqCQktIEhBTkRMRVJfQ0FOX1JXUklURSAgKEhBTkRMRVJfQ0FOX0dFVEFOREdFVE5FWFQgfCAKICoJCQlIQU5ETEVSX0NBTl9TRVQpCiAqCQktIEhBTkRMRVJfQ0FOX0RFRkFVTFQgSEFORExFUl9DQU5fUk9OTFkKICoKICogIEByZXR1cm4gUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uIHN0cnVjdC4KICogICAgICAgICAgTlVMTCBpcyByZXR1cm5lZCBvbmx5IHdoZW4gbWVtb3J5IGNvdWxkIG5vdCBiZSBhbGxvY2F0ZWQgZm9yIHRoZSAKICogICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBzdHJ1Y3QuCiAqCiAqCiAqICBAc2VlIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoKQogKiAgQHNlZSBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKQogKi8KbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqCm5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb25fY3JlYXRlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqIHJlZ19vaWQsIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1vZGVzKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICp0aGVfcmVnOwogICAgdGhlX3JlZyA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbik7CiAgICBpZiAoIXRoZV9yZWcpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKG1vZGVzKQogICAgICAgIHRoZV9yZWctPm1vZGVzID0gbW9kZXM7CiAgICBlbHNlCiAgICAgICAgdGhlX3JlZy0+bW9kZXMgPSBIQU5ETEVSX0NBTl9ERUZBVUxUOwoKICAgIHRoZV9yZWctPmhhbmRsZXIgPSBoYW5kbGVyOwogICAgdGhlX3JlZy0+cHJpb3JpdHkgPSBERUZBVUxUX01JQl9QUklPUklUWTsKICAgIGlmIChuYW1lKQogICAgICAgIHRoZV9yZWctPmhhbmRsZXJOYW1lID0gc3RyZHVwKG5hbWUpOwogICAgdGhlX3JlZy0+cm9vdG9pZCA9IG5ldHNubXBfbWVtZHVwKHJlZ19vaWQsIHJlZ19vaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgdGhlX3JlZy0+cm9vdG9pZF9sZW4gPSByZWdfb2lkX2xlbjsKICAgIHJldHVybiB0aGVfcmVnOwp9CgpuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICoKbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyX2FjY2Vzc19tZXRob2QsIG9pZCAqIHJlZ19vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCByZWdfb2lkX2xlbiwgaW50IG1vZGVzKQp7CiAgICByZXR1cm4KICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2NyZWF0ZShuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIobmFtZSwgaGFuZGxlcl9hY2Nlc3NfbWV0aG9kKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdfb2lkLCByZWdfb2lkX2xlbiwgbW9kZXMpOwp9CgovKiogcmVnaXN0ZXIgYSBoYW5kbGVyLCBhcyBkZWZpbmVkIGJ5IHRoZSBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uIHBvaW50ZXIuICovCmludApuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlcjsKICAgIGludCBmbGFncyA9IDA7CgogICAgaWYgKHJlZ2luZm8gPT0gTlVMTCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKSBjYWxsZWQgaWxsZWdhbGx5XG4iKTsKICAgICAgICBuZXRzbm1wX2Fzc2VydChyZWdpbmZvICE9IE5VTEwpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgREVCVUdJRigiaGFuZGxlcjo6cmVnaXN0ZXIiKSB7CiAgICAgICAgREVCVUdNU0dUTCgoImhhbmRsZXI6OnJlZ2lzdGVyIiwgIlJlZ2lzdGVyaW5nICVzICgiLCByZWdpbmZvLT5oYW5kbGVyTmFtZSkpOwogICAgICAgIGZvciAoaGFuZGxlciA9IHJlZ2luZm8tPmhhbmRsZXI7IGhhbmRsZXI7IGhhbmRsZXIgPSBoYW5kbGVyLT5uZXh0KSB7CiAgICAgICAgICAgIERFQlVHTVNHKCgiaGFuZGxlcjo6cmVnaXN0ZXIiLCAiOjolcyIsIGhhbmRsZXItPmhhbmRsZXJfbmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgREVCVUdNU0coKCJoYW5kbGVyOjpyZWdpc3RlciIsICIpIGF0ICIpKTsKICAgICAgICBpZiAocmVnaW5mby0+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+Y29udGV4dE5hbWUgIT0gTlVMTCkgewogICAgICAgICAgICByLT5jb250ZXh0TmFtZSA9IHN0cmR1cChyZWdpbmZvLT5jb250ZXh0TmFtZSk7CiAgICAgICAgICAgIGlmIChyLT5jb250ZXh0TmFtZSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUocik7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHJlZ2luZm8tPnJvb3RvaWQgIT0gTlVMTCkgewogICAgICAgICAgICByLT5yb290b2lkID0gbmV0c25tcF9tZW1kdXAocmVnaW5mby0+cm9vdG9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgICAgICBpZiAoci0+cm9vdG9pZCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUocik7CiAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgci0+aGFuZGxlciA9IG5ldHNubXBfaGFuZGxlcl9kdXAocmVnaW5mby0+aGFuZGxlcik7CiAgICAgICAgaWYgKHItPmhhbmRsZXIgPT0gTlVMTCkgewogICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uX2ZyZWUocik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQoKLyoqIGNyZWF0ZXMgYSBjYWNoZSBvZiBpbmZvcm1hdGlvbiB3aGljaCBjYW4gYmUgc2F2ZWQgZm9yIGZ1dHVyZQogICByZWZlcmVuY2UuICBVc2UgbmV0c25tcF9oYW5kbGVyX2NoZWNrX2NhY2hlKCkgbGF0ZXIgdG8gbWFrZSBzdXJlIGl0J3Mgc3RpbGwKICAgdmFsaWQgYmVmb3JlIHJlZmVyZW5jaW5nIGl0IGluIHRoZSBmdXR1cmUuICovCk5FVFNOTVBfSU5MSU5FIG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICoKbmV0c25tcF9jcmVhdGVfZGVsZWdhdGVkX2NhY2hlKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpsb2NhbGluZm8pCnsKICAgIG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICpyZXQ7CgogICAgcmV0ID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSk7CiAgICBpZiAocmV0KSB7CiAgICAgICAgcmV0LT50cmFuc2FjdGlvbl9pZCA9IHJlcWluZm8tPmFzcC0+cGR1LT50cmFuc2lkOwogICAgICAgIHJldC0+aGFuZGxlciA9IGhhbmRsZXI7CiAgICAgICAgcmV0LT5yZWdpbmZvID0gcmVnaW5mbzsKICAgICAgICByZXQtPnJlcWluZm8gPSByZXFpbmZvOwogICAgICAgIHJldC0+cmVxdWVzdHMgPSByZXF1ZXN0czsKICAgICAgICByZXQtPmxvY2FsaW5mbyA9IGxvY2FsaW5mbzsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKiBjaGVjaydzIGEgZ2l2ZW4gY2FjaGUgYW5kIHJldHVybnMgaXQgaWYgaXQgaXMgc3RpbGwgdmFsaWQgKGllLCB0aGUKICAgYWdlbnQgc3RpbGwgY29uc2lkZXJzIGl0IHRvIGJlIGFuIG91dHN0YW5kaW5nIHJlcXVlc3QuICBSZXR1cm5zCiAgIE5VTEwgaWYgaXQncyBubyBsb25nZXIgdmFsaWQuICovCk5FVFNOTVBfSU5MSU5FIG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICoKbmV0c25tcF9oYW5kbGVyX2NoZWNrX2NhY2hlKG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICpkY2FjaGUpCnsKICAgIGlmICghZGNhY2hlKQogICAgICAgIHJldHVybiBkY2FjaGU7CgogICAgaWYgKG5ldHNubXBfY2hlY2tfdHJhbnNhY3Rpb25faWQoZGNhY2hlLT50cmFuc2FjdGlvbl9pZCkgPT0KICAgICAgICBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIGRjYWNoZTsKCiAgICByZXR1cm4gTlVMTDsKfQoKLyoqIGZyZWVzIGEgY2FjaGUgb25jZSB5b3UncmUgZmluaXNoZWQgdXNpbmcgaXQgKi8KTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX2ZyZWVfZGVsZWdhdGVkX2NhY2hlKG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICpkY2FjaGUpCnsKICAgIC8qCiAgICAgKiByaWdodCBub3csIG5vIGV4dHJhIGRhdGEgaXMgdGhlcmUgdGhhdCBuZWVkcyB0byBiZSBmcmVlZCAKICAgICAqLwogICAgaWYgKGRjYWNoZSkKICAgICAgICBTTk1QX0ZSRUUoZGNhY2hlKTsKCiAgICByZXR1cm47Cn0KCgovKiogbWFya3MgYSBsaXN0IG9mIHJlcXVlc3RzIGFzIGRlbGVnYXRlZCAob3Igbm90IGlmIGlzZGVsZWdhZGVkID0gMCkgKi8Kdm9pZApuZXRzbm1wX2hhbmRsZXJfbWFya19yZXF1ZXN0c19hc19kZWxlZ2F0ZWQobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlzZGVsZWdhdGVkKQp7CiAgICB3aGlsZSAocmVxdWVzdHMpIHsKICAgICAgICByZXF1ZXN0cy0+ZGVsZWdhdGVkID0gaXNkZWxlZ2F0ZWQ7CiAgICAgICAgcmVxdWVzdHMgPSByZXF1ZXN0cy0+bmV4dDsKICAgIH0KfQoKLyoqIGFkZCBkYXRhIHRvIGEgcmVxdWVzdCB0aGF0IGNhbiBiZSBleHRyYWN0ZWQgbGF0ZXIgYnkgc3VibW9kdWxlcwogKgogKiBAcGFyYW0gcmVxdWVzdCB0aGUgbmV0c25tcCByZXF1ZXN0IGluZm8gc3RydWN0dXJlCiAqCiAqIEBwYXJhbSBub2RlIHRoaXMgaXMgdGhlIGRhdGEgdG8gYmUgYWRkZWQgdG8gdGhlIGxpbmtlZCBsaXN0CiAqICAgICAgICAgICAgIHJlcXVlc3QtPnBhcmVudF9kYXRhCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKi8KTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9kYXRhX2xpc3QgKm5vZGUpCnsKICAgIGlmIChyZXF1ZXN0KSB7CiAgICAgICAgaWYgKHJlcXVlc3QtPnBhcmVudF9kYXRhKQogICAgICAgICAgICBuZXRzbm1wX2FkZF9saXN0X2RhdGEoJnJlcXVlc3QtPnBhcmVudF9kYXRhLCBub2RlKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJlcXVlc3QtPnBhcmVudF9kYXRhID0gbm9kZTsKICAgIH0KfQoKLyoqIHJlbW92ZSBkYXRhIGZyb20gYSByZXF1ZXN0CiAqCiAqIEBwYXJhbSByZXF1ZXN0IHRoZSBuZXRzbm1wIHJlcXVlc3QgaW5mbyBzdHJ1Y3R1cmUKICoKICogQHBhcmFtIG5hbWUgdGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcHJldmlvdXNseSBhZGRlZCBkYXRhCiAqCiAqIEByZXR1cm4gMCBvbiBzdWNjZXNzZnVsIGZpbmQtYW5kLWRlbGV0ZSwgMSBvdGhlcndpc2UuCiAqCiAqLwpORVRTTk1QX0lOTElORSBpbnQKbmV0c25tcF9yZXF1ZXN0X3JlbW92ZV9saXN0X2RhdGEobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIGlmICgoTlVMTCA9PSByZXF1ZXN0KSB8fCAoTlVMTCA9PXJlcXVlc3QtPnBhcmVudF9kYXRhKSkKICAgICAgICByZXR1cm4gMTsKCiAgICByZXR1cm4gbmV0c25tcF9yZW1vdmVfbGlzdF9ub2RlKCZyZXF1ZXN0LT5wYXJlbnRfZGF0YSwgbmFtZSk7Cn0KCi8qKiBleHRyYWN0IGRhdGEgZnJvbSBhIHJlcXVlc3QgdGhhdCB3YXMgYWRkZWQgcHJldmlvdXNseSBieSBhIHBhcmVudCBtb2R1bGUKICoKICogQHBhcmFtIHJlcXVlc3QgdGhlIG5ldHNubXAgcmVxdWVzdCBpbmZvIGZ1bmN0aW9uCiAqCiAqIEBwYXJhbSBuYW1lIHVzZWQgdG8gY29tcGFyZSBhZ2FpbnN0IHRoZSByZXF1ZXN0LT5wYXJlbnRfZGF0YS0+bmFtZSB2YWx1ZSwKICogICAgICAgICAgICAgaWYgYSBtYXRjaCBpcyBmb3VuZCByZXF1ZXN0LT5wYXJlbnRfZGF0YS0+ZGF0YSBpcyByZXR1cm5lZAogKgogKiBAcmV0dXJuIGEgdm9pZCBwb2ludGVyKHJlcXVlc3QtPnBhcmVudF9kYXRhLT5kYXRhKSwgb3RoZXJ3aXNlIE5VTEwgaXMKICogICAgICAgICByZXR1cm5lZCBpZiByZXF1ZXN0IGlzIE5VTEwgb3IgcmVxdWVzdC0+cGFyZW50X2RhdGEgaXMgTlVMTCBvcgogKiAgICAgICAgIHJlcXVlc3QtPnBhcmVudF9kYXRhIG9iamVjdCBpcyBub3QgZm91bmQuCiAqLwp2b2lkICAgICoKbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIGlmIChyZXF1ZXN0KQogICAgICAgIHJldHVybiBuZXRzbm1wX2dldF9saXN0X2RhdGEocmVxdWVzdC0+cGFyZW50X2RhdGEsIG5hbWUpOwogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBGcmVlIHRoZSBleHRyYSBkYXRhIHN0b3JlZCBpbiBhIHJlcXVlc3QgKi8KTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldChuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCkKewogICAgaWYgKHJlcXVlc3QpCiAgICAgICAgbmV0c25tcF9mcmVlX2xpc3RfZGF0YShyZXF1ZXN0LT5wYXJlbnRfZGF0YSk7Cn0KCi8qKiBGcmVlIHRoZSBleHRyYSBkYXRhIHN0b3JlZCBpbiBhIGJ1bmNoIG9mIHJlcXVlc3RzIChhbGwgZGF0YSBpbiB0aGUgY2hhaW4pICovCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0KQp7CiAgICBpZiAocmVxdWVzdCAmJiByZXF1ZXN0LT5wYXJlbnRfZGF0YSkgewogICAgICAgIG5ldHNubXBfZnJlZV9hbGxfbGlzdF9kYXRhKHJlcXVlc3QtPnBhcmVudF9kYXRhKTsKICAgICAgICByZXF1ZXN0LT5wYXJlbnRfZGF0YSA9IE5VTEw7CiAgICB9Cn0KCi8qKiBSZXR1cm5zIGEgaGFuZGxlciBmcm9tIGEgY2hhaW4gYmFzZWQgb24gdGhlIG5hbWUgKi8KbmV0c25tcF9taWJfaGFuZGxlciAqCm5ldHNubXBfZmluZF9oYW5kbGVyX2J5X25hbWUobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICppdDsKICAgIGlmIChyZWdpbmZvID09IE5VTEwgfHwgbmFtZSA9PSBOVUxMICkKICAgICAgICByZXR1cm4gTlVMTDsKICAgIGZvciAoaXQgPSByZWdpbmZvLT5oYW5kbGVyOyBpdDsgaXQgPSBpdC0+bmV4dCkgewogICAgICAgIGlmIChzdHJjbXAoaXQtPmhhbmRsZXJfbmFtZSwgbmFtZSkgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gaXQ7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKiBSZXR1cm5zIGEgaGFuZGxlcidzIHZvaWQgKiBwb2ludGVyIGZyb20gYSBjaGFpbiBiYXNlZCBvbiB0aGUgbmFtZS4KIFRoaXMgcHJvYmFibHkgc2hvdWxkbid0IGJlIHVzZWQgYnkgdGhlIGdlbmVyYWwgcHVibGljIGFzIHRoZSB2b2lkICoKIGRhdGEgbWF5IGNoYW5nZSBhcyBhIGhhbmRsZXIgZXZvbHZlcy4gIEhhbmRsZXJzIHNob3VsZCByZWFsbHkKIGFkdmVydGlzZSBzb21lIGZ1bmN0aW9uIGZvciB5b3UgdG8gdXNlIGluc3RlYWQuICovCnZvaWQgICAgICAgICAgICoKbmV0c25tcF9maW5kX2hhbmRsZXJfZGF0YV9ieV9uYW1lKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICppdCA9IG5ldHNubXBfZmluZF9oYW5kbGVyX2J5X25hbWUocmVnaW5mbywgbmFtZSk7CiAgICBpZiAoaXQpCiAgICAgICAgcmV0dXJuIGl0LT5teXZvaWQ7CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqIGNsb25lcyBhIG1pYiBoYW5kbGVyIChuYW1lLCBmbGFncyBhbmQgYWNjZXNzIG1ldGhvZHMgb25seTsgbm90IG15dm9pZCkKICogc2VlIGFsc28gbmV0c25tcF9oYW5kbGVyX2R1cAogKi8Kc3RhdGljIG5ldHNubXBfbWliX2hhbmRsZXIgKgpfY2xvbmVfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICppdCkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqZHVwOwoKICAgIGlmKE5VTEwgPT0gaXQpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgZHVwID0gbmV0c25tcF9jcmVhdGVfaGFuZGxlcihpdC0+aGFuZGxlcl9uYW1lLCBpdC0+YWNjZXNzX21ldGhvZCk7CiAgICBpZihOVUxMICE9IGR1cCkKICAgICAgICBkdXAtPmZsYWdzID0gaXQtPmZsYWdzOwoKICAgIHJldHVybiBkdXA7Cn0KCnN0YXRpYyBuZXRzbm1wX2RhdGFfbGlzdCAqaGFuZGxlcl9yZWcgPSBOVUxMOwoKdm9pZApoYW5kbGVyX2ZyZWVfY2FsbGJhY2sodm9pZCAqaGFuZGxlcikKewogICAgbmV0c25tcF9oYW5kbGVyX2ZyZWUoKG5ldHNubXBfbWliX2hhbmRsZXIgKiloYW5kbGVyKTsKfQoKLyoqIHJlZ2lzdGVycyBhIGdpdmVuIGhhbmRsZXIgYnkgbmFtZSBzbyB0aGF0IGl0IGNhbiBiZSBmb3VuZCBlYXNpbHkgbGF0ZXIuCiAqLwp2b2lkCm5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcl9ieV9uYW1lKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIpCnsKICAgIG5ldHNubXBfYWRkX2xpc3RfZGF0YSgmaGFuZGxlcl9yZWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0KG5hbWUsICh2b2lkICopIGhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXJfZnJlZV9jYWxsYmFjaykpOwogICAgREVCVUdNU0dUTCgoImhhbmRsZXJfcmVnaXN0cnkiLCAicmVnaXN0ZXJpbmcgaGVscGVyICVzXG4iLCBuYW1lKSk7Cn0KCi8qKiBjbGVhcnMgdGhlIGVudGlyZSBoYW5kbGVyLXJlZ2lzdHJhdGlvbiBsaXN0CiAqLwp2b2lkCm5ldHNubXBfY2xlYXJfaGFuZGxlcl9saXN0KHZvaWQpCnsKICAgIERFQlVHTVNHVEwoKCJhZ2VudF9oYW5kbGVyIiwgIm5ldHNubXBfY2xlYXJfaGFuZGxlcl9saXN0KCkgY2FsbGVkXG4iKSk7CiAgICBuZXRzbm1wX2ZyZWVfYWxsX2xpc3RfZGF0YShoYW5kbGVyX3JlZyk7CiAgICBoYW5kbGVyX3JlZyA9IE5VTEw7Cn0KCi8qKiBAaW50ZXJuYWwKICogIGluamVjdHMgYSBoYW5kbGVyIGludG8gYSBzdWJ0cmVlLCBwZWVycyBhbmQgY2hpbGRyZW4gd2hlbiBhIGdpdmVuCiAqICBzdWJ0cmVlcyBuYW1lIG1hdGNoZXMgYSBwYXNzZWQgaW4gbmFtZS4KICovCnZvaWQKbmV0c25tcF9pbmplY3RfaGFuZGxlcl9pbnRvX3N1YnRyZWUobmV0c25tcF9zdWJ0cmVlICp0cCwgY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYmVmb3JlX3doYXQpCnsKICAgIG5ldHNubXBfc3VidHJlZSAqdHB0cjsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKm1oOwoKICAgIGZvciAodHB0ciA9IHRwOyB0cHRyICE9IE5VTEw7IHRwdHIgPSB0cHRyLT5uZXh0KSB7CiAgICAgICAgLyogIGlmICh0cHRyLT5jaGlsZHJlbikgeyAKICAgICAgICAgICAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyX2ludG9fc3VidHJlZSh0cHRyLT5jaGlsZHJlbixuYW1lLGhhbmRsZXIpOwoJICAgIH0gICAqLwogICAgICAgIGlmIChzdHJjbXAodHB0ci0+bGFiZWxfYSwgbmFtZSkgPT0gMCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgiaW5qZWN0SGFuZGxlciIsICJpbmplY3RpbmcgaGFuZGxlciAlcyBpbnRvICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLT5oYW5kbGVyX25hbWUsIHRwdHItPmxhYmVsX2EpKTsKICAgICAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcl9iZWZvcmUodHB0ci0+cmVnaW5mbywgX2Nsb25lX2hhbmRsZXIoaGFuZGxlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZV93aGF0KTsKICAgICAgICB9IGVsc2UgaWYgKHRwdHItPnJlZ2luZm8gIT0gTlVMTCAmJgoJCSAgIHRwdHItPnJlZ2luZm8tPmhhbmRsZXJOYW1lICE9IE5VTEwgJiYKICAgICAgICAgICAgICAgICAgIHN0cmNtcCh0cHRyLT5yZWdpbmZvLT5oYW5kbGVyTmFtZSwgbmFtZSkgPT0gMCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgiaW5qZWN0SGFuZGxlciIsICJpbmplY3RpbmcgaGFuZGxlciBpbnRvICVzLyVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICB0cHRyLT5sYWJlbF9hLCB0cHRyLT5yZWdpbmZvLT5oYW5kbGVyTmFtZSkpOwogICAgICAgICAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyX2JlZm9yZSh0cHRyLT5yZWdpbmZvLCBfY2xvbmVfaGFuZGxlcihoYW5kbGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlX3doYXQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvciAobWggPSB0cHRyLT5yZWdpbmZvLT5oYW5kbGVyOyBtaCAhPSBOVUxMOyBtaCA9IG1oLT5uZXh0KSB7CiAgICAgICAgICAgICAgICBpZiAobWgtPmhhbmRsZXJfbmFtZSAmJiBzdHJjbXAobWgtPmhhbmRsZXJfbmFtZSwgbmFtZSkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJpbmplY3RIYW5kbGVyIiwgImluamVjdGluZyBoYW5kbGVyIGludG8gJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHB0ci0+bGFiZWxfYSkpOwogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXJfYmVmb3JlKHRwdHItPnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Nsb25lX2hhbmRsZXIoaGFuZGxlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlX3doYXQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaW5qZWN0SGFuZGxlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vdCBpbmplY3RpbmcgaGFuZGxlciBpbnRvICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1oLT5oYW5kbGVyX25hbWUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIGludCAgICAgIGRvbmVpdCA9IDA7Ci8qKiBAaW50ZXJuYWwKICogIHBhcnNlcyB0aGUgImluamVjdEhhbmRsZXIiIHRva2VuIGxpbmUuCiAqLwp2b2lkCnBhcnNlX2luamVjdEhhbmRsZXJfY29uZihjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgIGhhbmRsZXJfdG9faW5zZXJ0WzI1Nl0sIHJlZ19uYW1lWzI1Nl07CiAgICBzdWJ0cmVlX2NvbnRleHRfY2FjaGUgKnN0YzsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXI7CgogICAgLyoKICAgICAqIFhYWFdXVzogZW5zdXJlIGluc3RlYWQgdGhhdCBoYW5kbGVyIGlzbid0IGluc2VydGVkIHR3aWNlIAogICAgICovCiAgICBpZiAoZG9uZWl0KSAgICAgICAgICAgICAgICAgLyogd2Ugb25seSBkbyB0aGlzIG9uY2Ugd2l0aG91dCByZXN0YXJ0IHRoZSBhZ2VudCAqLwogICAgICAgIHJldHVybjsKCiAgICBjcHRyID0gY29weV9ud29yZChjcHRyLCBoYW5kbGVyX3RvX2luc2VydCwgc2l6ZW9mKGhhbmRsZXJfdG9faW5zZXJ0KSk7CiAgICBoYW5kbGVyID0gbmV0c25tcF9nZXRfbGlzdF9kYXRhKGhhbmRsZXJfcmVnLCBoYW5kbGVyX3RvX2luc2VydCk7CiAgICBpZiAoIWhhbmRsZXIpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJubyBzdWNoIFwiJXNcIiBoYW5kbGVyIHJlZ2lzdGVyZWQuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICghY3B0cikgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm5vIElOVE9OQU1FIHNwZWNpZmllZC4gIENhbid0IGRvIGluc2VydGlvbi4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjcHRyID0gY29weV9ud29yZChjcHRyLCByZWdfbmFtZSwgc2l6ZW9mKHJlZ19uYW1lKSk7CgogICAgZm9yIChzdGMgPSBnZXRfdG9wX2NvbnRleHRfY2FjaGUoKTsgc3RjOyBzdGMgPSBzdGMtPm5leHQpIHsKICAgICAgICBERUJVR01TR1RMKCgiaW5qZWN0SGFuZGxlciIsICJDaGVja2luZyBjb250ZXh0IHRyZWUgJXMgKGJlZm9yZT0lcylcbiIsCiAgICAgICAgICAgICAgICAgICAgc3RjLT5jb250ZXh0X25hbWUsIChjcHRyKT9jcHRyOiJudWxsIikpOwogICAgICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXJfaW50b19zdWJ0cmVlKHN0Yy0+Zmlyc3Rfc3VidHJlZSwgcmVnX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlciwgY3B0cik7CiAgICB9Cn0KCi8qKiBAaW50ZXJuYWwKICogIGNhbGxiYWNrIHRvIGVuc3VyZSBpbmplY3RIYW5kbGVyIHBhcnNlciBkb2Vzbid0IGRvIHRoaW5ncyB0d2ljZQogKiAgQHRvZG8gcmVwbGFjZSB0aGlzIHdpdGggYSBtZXRob2QgdG8gY2hlY2sgdGhlIGhhbmRsZXIgY2hhaW4gaW5zdGVhZC4KICovCnN0YXRpYyBpbnQKaGFuZGxlcl9tYXJrX2luamVjdF9oYW5kbGVyX2RvbmUoaW50IG1ham9ySUQsIGludCBtaW5vcklELAogICAgICAgICAgICAgICAgICAgIHZvaWQgKnNlcnZlcmFyZywgdm9pZCAqY2xpZW50YXJnKQp7CiAgICBkb25laXQgPSAxOwogICAgcmV0dXJuIDA7Cn0KCi8qKiBAaW50ZXJuYWwKICogIFJlZ2lzdGVycyB0aGUgaW5qZWN0SGFuZGxlIHBhcnNlciB0b2tlbi4KICovCnZvaWQKbmV0c25tcF9pbml0X2hhbmRsZXJfY29uZih2b2lkKQp7CiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigiaW5qZWN0SGFuZGxlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZV9pbmplY3RIYW5kbGVyX2NvbmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAiaW5qZWN0SGFuZGxlciBOQU1FIElOVE9OQU1FIFtCRUZPUkVfT1RIRVJfTkFNRV0iKTsKICAgIHNubXBfcmVnaXN0ZXJfY2FsbGJhY2soU05NUF9DQUxMQkFDS19MSUJSQVJZLAogICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0NBTExCQUNLX1BPU1RfUkVBRF9DT05GSUcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXJfbWFya19pbmplY3RfaGFuZGxlcl9kb25lLCBOVUxMKTsKCiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiR0VUIiksIE1PREVfR0VUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJHRVRORVhUIiksIE1PREVfR0VUTkVYVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiR0VUQlVMSyIpLCBNT0RFX0dFVEJVTEspOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIlNFVF9CRUdJTiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9TRVRfQkVHSU4pOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIlNFVF9SRVNFUlZFMSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9TRVRfUkVTRVJWRTEpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIlNFVF9SRVNFUlZFMiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9TRVRfUkVTRVJWRTIpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImFnZW50X21vZGUiLCBzdHJkdXAoIlNFVF9BQ1RJT04iKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfU0VUX0FDVElPTik7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYWdlbnRfbW9kZSIsIHN0cmR1cCgiU0VUX0NPTU1JVCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9TRVRfQ09NTUlUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJTRVRfRlJFRSIpLCBNT0RFX1NFVF9GUkVFKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJhZ2VudF9tb2RlIiwgc3RyZHVwKCJTRVRfVU5ETyIpLCBNT0RFX1NFVF9VTkRPKTsKCiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgicHJlLXJlcXVlc3QiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfUFJFX1JFUVVFU1QpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoIm9iamVjdF9sb29rdXAiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfT0JKRUNUX0xPT0tVUCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgiY2hlY2tfdmFsdWUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfQ0hFQ0tfVkFMVUUpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoInJvd19jcmVhdGUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfUk9XX0NSRUFURSk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgidW5kb19zZXR1cCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9VTkRPX1NFVFVQKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJzZXRfdmFsdWUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfU0VUX1ZBTFVFKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJjaGVja19jb25zaXN0ZW5jeSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9DSEVDS19DT05TSVNURU5DWSk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiYmFieXN0ZXBfbW9kZSIsIHN0cmR1cCgidW5kb19zZXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIE1PREVfQlNURVBfVU5ET19TRVQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoImNvbW1pdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9DT01NSVQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoInVuZG9fY29tbWl0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX1VORE9fQ09NTUlUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJiYWJ5c3RlcF9tb2RlIiwgc3RyZHVwKCJpcnJldmVyc2libGVfY29tbWl0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFX0JTVEVQX0lSUkVWRVJTSUJMRV9DT01NSVQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoInVuZG9fY2xlYW51cCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9VTkRPX0NMRUFOVVApOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoInBvc3RfcmVxdWVzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgTU9ERV9CU1RFUF9QT1NUX1JFUVVFU1QpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImJhYnlzdGVwX21vZGUiLCBzdHJkdXAoIm9yaWdpbmFsIiksIDB4ZmZmZik7CgogICAgLyoKICAgICAqIHh4eC1ya3M6IGhtbW0uLiB3aWxsIHRoaXMgd29yayBmb3IgbW9kZXMgd2hpY2ggYXJlIG9yJ2QgdG9nZXRoZXI/CiAgICAgKiAgICAgICAgICBJJ20gYmV0dGluZyBub3QuLi4KICAgICAqLwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoImhhbmRsZXJfY2FuX21vZGUiLCBzdHJkdXAoIkdFVC9HRVRORVhUIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9HRVRBTkRHRVRORVhUKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KCJoYW5kbGVyX2Nhbl9tb2RlIiwgc3RyZHVwKCJTRVQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1NFVCk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiaGFuZGxlcl9jYW5fbW9kZSIsIHN0cmR1cCgiR0VUQlVMSyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFUl9DQU5fR0VUQlVMSyk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdCgiaGFuZGxlcl9jYW5fbW9kZSIsIHN0cmR1cCgiQkFCWV9TVEVQIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9CQUJZX1NURVApOwp9CgovKiogQH0gKi8K