LyoKICogSUJNIEFTTSBTZXJ2aWNlIFByb2Nlc3NvciBEZXZpY2UgRHJpdmVyCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuCiAqCiAqIENvcHlyaWdodCAoQykgSUJNIENvcnBvcmF0aW9uLCAyMDA0CiAqCiAqIEF1dGhvcjogTWF4IEFzYvZjayA8YW1heEB1cy5pYm0uY29tPiAKICoKICovCgojaW5jbHVkZSAiaWJtYXNtLmgiCiNpbmNsdWRlICJkb3RfY29tbWFuZC5oIgoKLyoqCiAqIERpc3BhdGNoIGFuIGluY29taW5nIG1lc3NhZ2UgdG8gdGhlIHNwZWNpZmljIGhhbmRsZXIgZm9yIHRoZSBtZXNzYWdlLgogKiBDYWxsZWQgZnJvbSBpbnRlcnJ1cHQgY29udGV4dC4KICovCnZvaWQgaWJtYXNtX3JlY2VpdmVfbWVzc2FnZShzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCB2b2lkICptZXNzYWdlLCBpbnQgbWVzc2FnZV9zaXplKQp7Cgl1MzIgc2l6ZTsKCXN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIgKmhlYWRlciA9IChzdHJ1Y3QgZG90X2NvbW1hbmRfaGVhZGVyICopbWVzc2FnZTsKCglpZiAobWVzc2FnZV9zaXplID09IDApCgkJcmV0dXJuOwoKCXNpemUgPSBnZXRfZG90X2NvbW1hbmRfc2l6ZShtZXNzYWdlKTsKCWlmIChzaXplID09IDApCgkJcmV0dXJuOwoKCWlmIChzaXplID4gbWVzc2FnZV9zaXplKQoJCXNpemUgPSBtZXNzYWdlX3NpemU7CgoJc3dpdGNoIChoZWFkZXItPnR5cGUpIHsKCWNhc2Ugc3BfZXZlbnQ6IAoJCWlibWFzbV9yZWNlaXZlX2V2ZW50KHNwLCBtZXNzYWdlLCBzaXplKTsKCQlicmVhazsKCWNhc2Ugc3BfY29tbWFuZF9yZXNwb25zZToKCQlpYm1hc21fcmVjZWl2ZV9jb21tYW5kX3Jlc3BvbnNlKHNwLCBtZXNzYWdlLCBzaXplKTsgCgkJYnJlYWs7CgljYXNlIHNwX2hlYXJ0YmVhdDoKCQlpYm1hc21fcmVjZWl2ZV9oZWFydGJlYXQoc3AsIG1lc3NhZ2UsIHNpemUpOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlkZXZfZXJyKHNwLT5kZXYsICJSZWNlaXZlZCB1bmtub3duIG1lc3NhZ2UgZnJvbSBzZXJ2aWNlIHByb2Nlc3NvclxuIik7Cgl9Cn0KCgojZGVmaW5lIElOSVRfQlVGRkVSX1NJWkUgMzIKCgovKioKICogc2VuZCB0aGUgNC4zLjUuMTAgZG90IGNvbW1hbmQgKGRyaXZlciBWUEQpIHRvIHRoZSBzZXJ2aWNlIHByb2Nlc3NvcgogKi8KaW50IGlibWFzbV9zZW5kX2RyaXZlcl92cGQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJc3RydWN0IGNvbW1hbmQgKmNvbW1hbmQ7CglzdHJ1Y3QgZG90X2NvbW1hbmRfaGVhZGVyICpoZWFkZXI7Cgl1OCAqdnBkX2NvbW1hbmQ7Cgl1OCAqdnBkX2RhdGE7CglpbnQgcmVzdWx0ID0gMDsKCgljb21tYW5kID0gaWJtYXNtX25ld19jb21tYW5kKHNwLCBJTklUX0JVRkZFUl9TSVpFKTsKCWlmIChjb21tYW5kID09IE5VTEwpCgkJcmV0dXJuIC1FTk9NRU07CgoJaGVhZGVyID0gKHN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIgKiljb21tYW5kLT5idWZmZXI7CgloZWFkZXItPnR5cGUgICAgICAgICAgICAgICAgPSBzcF93cml0ZTsKCWhlYWRlci0+Y29tbWFuZF9zaXplICAgICAgICA9IDQ7CgloZWFkZXItPmRhdGFfc2l6ZSAgICAgICAgICAgPSAxNjsKCWhlYWRlci0+c3RhdHVzICAgICAgICAgICAgICA9IDA7CgloZWFkZXItPnJlc2VydmVkICAgICAgICAgICAgPSAwOwoKCXZwZF9jb21tYW5kID0gY29tbWFuZC0+YnVmZmVyICsgc2l6ZW9mKHN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIpOwoJdnBkX2NvbW1hbmRbMF0gPSAweDQ7Cgl2cGRfY29tbWFuZFsxXSA9IDB4MzsKCXZwZF9jb21tYW5kWzJdID0gMHg1OwoJdnBkX2NvbW1hbmRbM10gPSAweGE7CgoJdnBkX2RhdGEgPSB2cGRfY29tbWFuZCArIGhlYWRlci0+Y29tbWFuZF9zaXplOwoJdnBkX2RhdGFbMF0gPSAwOwoJc3RyY2F0KHZwZF9kYXRhLCBJQk1BU01fRFJJVkVSX1ZQRCk7Cgl2cGRfZGF0YVsxMF0gPSAwOwoJdnBkX2RhdGFbMTVdID0gMDsKCQoJaWJtYXNtX2V4ZWNfY29tbWFuZChzcCwgY29tbWFuZCk7CglpYm1hc21fd2FpdF9mb3JfcmVzcG9uc2UoY29tbWFuZCwgSUJNQVNNX0NNRF9USU1FT1VUX05PUk1BTCk7CgoJaWYgKGNvbW1hbmQtPnN0YXR1cyAhPSBJQk1BU01fQ01EX0NPTVBMRVRFKQoJCXJlc3VsdCA9IC1FTk9ERVY7CgoJY29tbWFuZF9wdXQoY29tbWFuZCk7CgoJcmV0dXJuIHJlc3VsdDsKfQoKc3RydWN0IG9zX3N0YXRlX2NvbW1hbmQgewoJc3RydWN0IGRvdF9jb21tYW5kX2hlYWRlcgloZWFkZXI7Cgl1bnNpZ25lZCBjaGFyCQkJY29tbWFuZFszXTsKCXVuc2lnbmVkIGNoYXIJCQlkYXRhOwp9OwoKLyoqCiAqIHNlbmQgdGhlIDQuMy42IGRvdCBjb21tYW5kIChvcyBzdGF0ZSkgdG8gdGhlIHNlcnZpY2UgcHJvY2Vzc29yCiAqIER1cmluZyBkcml2ZXIgaW5pdCB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIG9zIHN0YXRlICJ1cCIuCiAqIFRoaXMgY2F1c2VzIHRoZSBzZXJ2aWNlIHByb2Nlc3NvciB0byBzdGFydCBzZW5kaW5nIGhlYXJ0YmVhdHMgdGhlCiAqIGRyaXZlci4KICogRHVyaW5nIGRyaXZlciBleGl0IHRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgd2l0aCBvcyBzdGF0ZSAiZG93biIsIAogKiBjYXVzaW5nIHRoZSBzZXJ2aWNlIHByb2Nlc3NvciB0byBzdG9wIHRoZSBoZWFydGJlYXRzLgogKi8KaW50IGlibWFzbV9zZW5kX29zX3N0YXRlKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIGludCBvc19zdGF0ZSkKewoJc3RydWN0IGNvbW1hbmQgKmNtZDsKCXN0cnVjdCBvc19zdGF0ZV9jb21tYW5kICpvc19zdGF0ZV9jbWQ7CglpbnQgcmVzdWx0ID0gMDsKCgljbWQgPSBpYm1hc21fbmV3X2NvbW1hbmQoc3AsIHNpemVvZihzdHJ1Y3Qgb3Nfc3RhdGVfY29tbWFuZCkpOwoJaWYgKGNtZCA9PSBOVUxMKQoJCXJldHVybiAtRU5PTUVNOwoKCW9zX3N0YXRlX2NtZCA9IChzdHJ1Y3Qgb3Nfc3RhdGVfY29tbWFuZCAqKWNtZC0+YnVmZmVyOwoJb3Nfc3RhdGVfY21kLT5oZWFkZXIudHlwZQkJPSBzcF93cml0ZTsKCW9zX3N0YXRlX2NtZC0+aGVhZGVyLmNvbW1hbmRfc2l6ZQk9IDM7Cglvc19zdGF0ZV9jbWQtPmhlYWRlci5kYXRhX3NpemUJCT0gMTsKCW9zX3N0YXRlX2NtZC0+aGVhZGVyLnN0YXR1cwkJPSAwOwoJb3Nfc3RhdGVfY21kLT5jb21tYW5kWzBdCQk9IDQ7Cglvc19zdGF0ZV9jbWQtPmNvbW1hbmRbMV0JCT0gMzsKCW9zX3N0YXRlX2NtZC0+Y29tbWFuZFsyXQkJPSA2OwoJb3Nfc3RhdGVfY21kLT5kYXRhCQkJPSBvc19zdGF0ZTsKCglpYm1hc21fZXhlY19jb21tYW5kKHNwLCBjbWQpOwoJaWJtYXNtX3dhaXRfZm9yX3Jlc3BvbnNlKGNtZCwgSUJNQVNNX0NNRF9USU1FT1VUX05PUk1BTCk7CgoJaWYgKGNtZC0+c3RhdHVzICE9IElCTUFTTV9DTURfQ09NUExFVEUpCgkJcmVzdWx0ID0gLUVOT0RFVjsKCgljb21tYW5kX3B1dChjbWQpOwoJcmV0dXJuIHJlc3VsdDsKfQo=