LyoKICogSUJNIEFTTSBTZXJ2aWNlIFByb2Nlc3NvciBEZXZpY2UgRHJpdmVyCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuCiAqCiAqIENvcHlyaWdodCAoQykgSUJNIENvcnBvcmF0aW9uLCAyMDA0CiAqCiAqIEF1dGhvcjogTWF4IEFzYvZjayA8YW1heEB1cy5pYm0uY29tPgogKgogKi8KCiNpbmNsdWRlICJpYm1hc20uaCIKI2luY2x1ZGUgImRvdF9jb21tYW5kLmgiCgovKioKICogRGlzcGF0Y2ggYW4gaW5jb21pbmcgbWVzc2FnZSB0byB0aGUgc3BlY2lmaWMgaGFuZGxlciBmb3IgdGhlIG1lc3NhZ2UuCiAqIENhbGxlZCBmcm9tIGludGVycnVwdCBjb250ZXh0LgogKi8Kdm9pZCBpYm1hc21fcmVjZWl2ZV9tZXNzYWdlKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHZvaWQgKm1lc3NhZ2UsIGludCBtZXNzYWdlX3NpemUpCnsKCXUzMiBzaXplOwoJc3RydWN0IGRvdF9jb21tYW5kX2hlYWRlciAqaGVhZGVyID0gKHN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIgKiltZXNzYWdlOwoKCWlmIChtZXNzYWdlX3NpemUgPT0gMCkKCQlyZXR1cm47CgoJc2l6ZSA9IGdldF9kb3RfY29tbWFuZF9zaXplKG1lc3NhZ2UpOwoJaWYgKHNpemUgPT0gMCkKCQlyZXR1cm47CgoJaWYgKHNpemUgPiBtZXNzYWdlX3NpemUpCgkJc2l6ZSA9IG1lc3NhZ2Vfc2l6ZTsKCglzd2l0Y2ggKGhlYWRlci0+dHlwZSkgewoJY2FzZSBzcF9ldmVudDoKCQlpYm1hc21fcmVjZWl2ZV9ldmVudChzcCwgbWVzc2FnZSwgc2l6ZSk7CgkJYnJlYWs7CgljYXNlIHNwX2NvbW1hbmRfcmVzcG9uc2U6CgkJaWJtYXNtX3JlY2VpdmVfY29tbWFuZF9yZXNwb25zZShzcCwgbWVzc2FnZSwgc2l6ZSk7CgkJYnJlYWs7CgljYXNlIHNwX2hlYXJ0YmVhdDoKCQlpYm1hc21fcmVjZWl2ZV9oZWFydGJlYXQoc3AsIG1lc3NhZ2UsIHNpemUpOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlkZXZfZXJyKHNwLT5kZXYsICJSZWNlaXZlZCB1bmtub3duIG1lc3NhZ2UgZnJvbSBzZXJ2aWNlIHByb2Nlc3NvclxuIik7Cgl9Cn0KCgojZGVmaW5lIElOSVRfQlVGRkVSX1NJWkUgMzIKCgovKioKICogc2VuZCB0aGUgNC4zLjUuMTAgZG90IGNvbW1hbmQgKGRyaXZlciBWUEQpIHRvIHRoZSBzZXJ2aWNlIHByb2Nlc3NvcgogKi8KaW50IGlibWFzbV9zZW5kX2RyaXZlcl92cGQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJc3RydWN0IGNvbW1hbmQgKmNvbW1hbmQ7CglzdHJ1Y3QgZG90X2NvbW1hbmRfaGVhZGVyICpoZWFkZXI7Cgl1OCAqdnBkX2NvbW1hbmQ7Cgl1OCAqdnBkX2RhdGE7CglpbnQgcmVzdWx0ID0gMDsKCgljb21tYW5kID0gaWJtYXNtX25ld19jb21tYW5kKHNwLCBJTklUX0JVRkZFUl9TSVpFKTsKCWlmIChjb21tYW5kID09IE5VTEwpCgkJcmV0dXJuIC1FTk9NRU07CgoJaGVhZGVyID0gKHN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIgKiljb21tYW5kLT5idWZmZXI7CgloZWFkZXItPnR5cGUgICAgICAgICAgICAgICAgPSBzcF93cml0ZTsKCWhlYWRlci0+Y29tbWFuZF9zaXplICAgICAgICA9IDQ7CgloZWFkZXItPmRhdGFfc2l6ZSAgICAgICAgICAgPSAxNjsKCWhlYWRlci0+c3RhdHVzICAgICAgICAgICAgICA9IDA7CgloZWFkZXItPnJlc2VydmVkICAgICAgICAgICAgPSAwOwoKCXZwZF9jb21tYW5kID0gY29tbWFuZC0+YnVmZmVyICsgc2l6ZW9mKHN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIpOwoJdnBkX2NvbW1hbmRbMF0gPSAweDQ7Cgl2cGRfY29tbWFuZFsxXSA9IDB4MzsKCXZwZF9jb21tYW5kWzJdID0gMHg1OwoJdnBkX2NvbW1hbmRbM10gPSAweGE7CgoJdnBkX2RhdGEgPSB2cGRfY29tbWFuZCArIGhlYWRlci0+Y29tbWFuZF9zaXplOwoJdnBkX2RhdGFbMF0gPSAwOwoJc3RyY2F0KHZwZF9kYXRhLCBJQk1BU01fRFJJVkVSX1ZQRCk7Cgl2cGRfZGF0YVsxMF0gPSAwOwoJdnBkX2RhdGFbMTVdID0gMDsKCglpYm1hc21fZXhlY19jb21tYW5kKHNwLCBjb21tYW5kKTsKCWlibWFzbV93YWl0X2Zvcl9yZXNwb25zZShjb21tYW5kLCBJQk1BU01fQ01EX1RJTUVPVVRfTk9STUFMKTsKCglpZiAoY29tbWFuZC0+c3RhdHVzICE9IElCTUFTTV9DTURfQ09NUExFVEUpCgkJcmVzdWx0ID0gLUVOT0RFVjsKCgljb21tYW5kX3B1dChjb21tYW5kKTsKCglyZXR1cm4gcmVzdWx0Owp9CgpzdHJ1Y3Qgb3Nfc3RhdGVfY29tbWFuZCB7CglzdHJ1Y3QgZG90X2NvbW1hbmRfaGVhZGVyCWhlYWRlcjsKCXVuc2lnbmVkIGNoYXIJCQljb21tYW5kWzNdOwoJdW5zaWduZWQgY2hhcgkJCWRhdGE7Cn07CgovKioKICogc2VuZCB0aGUgNC4zLjYgZG90IGNvbW1hbmQgKG9zIHN0YXRlKSB0byB0aGUgc2VydmljZSBwcm9jZXNzb3IKICogRHVyaW5nIGRyaXZlciBpbml0IHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggb3Mgc3RhdGUgInVwIi4KICogVGhpcyBjYXVzZXMgdGhlIHNlcnZpY2UgcHJvY2Vzc29yIHRvIHN0YXJ0IHNlbmRpbmcgaGVhcnRiZWF0cyB0aGUKICogZHJpdmVyLgogKiBEdXJpbmcgZHJpdmVyIGV4aXQgdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIG9zIHN0YXRlICJkb3duIiwKICogY2F1c2luZyB0aGUgc2VydmljZSBwcm9jZXNzb3IgdG8gc3RvcCB0aGUgaGVhcnRiZWF0cy4KICovCmludCBpYm1hc21fc2VuZF9vc19zdGF0ZShzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCBpbnQgb3Nfc3RhdGUpCnsKCXN0cnVjdCBjb21tYW5kICpjbWQ7CglzdHJ1Y3Qgb3Nfc3RhdGVfY29tbWFuZCAqb3Nfc3RhdGVfY21kOwoJaW50IHJlc3VsdCA9IDA7CgoJY21kID0gaWJtYXNtX25ld19jb21tYW5kKHNwLCBzaXplb2Yoc3RydWN0IG9zX3N0YXRlX2NvbW1hbmQpKTsKCWlmIChjbWQgPT0gTlVMTCkKCQlyZXR1cm4gLUVOT01FTTsKCglvc19zdGF0ZV9jbWQgPSAoc3RydWN0IG9zX3N0YXRlX2NvbW1hbmQgKiljbWQtPmJ1ZmZlcjsKCW9zX3N0YXRlX2NtZC0+aGVhZGVyLnR5cGUJCT0gc3Bfd3JpdGU7Cglvc19zdGF0ZV9jbWQtPmhlYWRlci5jb21tYW5kX3NpemUJPSAzOwoJb3Nfc3RhdGVfY21kLT5oZWFkZXIuZGF0YV9zaXplCQk9IDE7Cglvc19zdGF0ZV9jbWQtPmhlYWRlci5zdGF0dXMJCT0gMDsKCW9zX3N0YXRlX2NtZC0+Y29tbWFuZFswXQkJPSA0OwoJb3Nfc3RhdGVfY21kLT5jb21tYW5kWzFdCQk9IDM7Cglvc19zdGF0ZV9jbWQtPmNvbW1hbmRbMl0JCT0gNjsKCW9zX3N0YXRlX2NtZC0+ZGF0YQkJCT0gb3Nfc3RhdGU7CgoJaWJtYXNtX2V4ZWNfY29tbWFuZChzcCwgY21kKTsKCWlibWFzbV93YWl0X2Zvcl9yZXNwb25zZShjbWQsIElCTUFTTV9DTURfVElNRU9VVF9OT1JNQUwpOwoKCWlmIChjbWQtPnN0YXR1cyAhPSBJQk1BU01fQ01EX0NPTVBMRVRFKQoJCXJlc3VsdCA9IC1FTk9ERVY7CgoJY29tbWFuZF9wdXQoY21kKTsKCXJldHVybiByZXN1bHQ7Cn0K