Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4KICoKICovCgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgImlibWFzbS5oIgojaW5jbHVkZSAibG93bGV2ZWwuaCIKCnN0YXRpYyB2b2lkIGV4ZWNfbmV4dF9jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApOwoKc3RhdGljIGF0b21pY190IGNvbW1hbmRfY291bnQgPSBBVE9NSUNfSU5JVCgwKTsKCnN0cnVjdCBjb21tYW5kICppYm1hc21fbmV3X2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCwgc2l6ZV90IGJ1ZmZlcl9zaXplKQp7CglzdHJ1Y3QgY29tbWFuZCAqY21kOwoKCWlmIChidWZmZXJfc2l6ZSA+IElCTUFTTV9DTURfTUFYX0JVRkZFUl9TSVpFKQoJCXJldHVybiBOVUxMOwoKCWNtZCA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBjb21tYW5kKSwgR0ZQX0tFUk5FTCk7CglpZiAoY21kID09IE5VTEwpCgkJcmV0dXJuIE5VTEw7CgoKCWNtZC0+YnVmZmVyID0ga3phbGxvYyhidWZmZXJfc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoY21kLT5idWZmZXIgPT0gTlVMTCkgewoJCWtmcmVlKGNtZCk7CgkJcmV0dXJuIE5VTEw7Cgl9CgljbWQtPmJ1ZmZlcl9zaXplID0gYnVmZmVyX3NpemU7CgoJa3JlZl9pbml0KCZjbWQtPmtyZWYpOwoJY21kLT5sb2NrID0gJnNwLT5sb2NrOwoKCWNtZC0+c3RhdHVzID0gSUJNQVNNX0NNRF9QRU5ESU5HOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmY21kLT53YWl0KTsKCUlOSVRfTElTVF9IRUFEKCZjbWQtPnF1ZXVlX25vZGUpOwoKCWF0b21pY19pbmMoJmNvbW1hbmRfY291bnQpOwoJZGJnKCJjb21tYW5kIGNvdW50OiAlZFxuIiwgYXRvbWljX3JlYWQoJmNvbW1hbmRfY291bnQpKTsKCglyZXR1cm4gY21kOwp9Cgp2b2lkIGlibWFzbV9mcmVlX2NvbW1hbmQoc3RydWN0IGtyZWYgKmtyZWYpCnsKCXN0cnVjdCBjb21tYW5kICpjbWQgPSB0b19jb21tYW5kKGtyZWYpOwoKCWxpc3RfZGVsKCZjbWQtPnF1ZXVlX25vZGUpOwoJYXRvbWljX2RlYygmY29tbWFuZF9jb3VudCk7CglkYmcoImNvbW1hbmQgY291bnQ6ICVkXG4iLCBhdG9taWNfcmVhZCgmY29tbWFuZF9jb3VudCkpOwoJa2ZyZWUoY21kLT5idWZmZXIpOwoJa2ZyZWUoY21kKTsKfQoKc3RhdGljIHZvaWQgZW5xdWV1ZV9jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBjb21tYW5kICpjbWQpCnsKCWxpc3RfYWRkX3RhaWwoJmNtZC0+cXVldWVfbm9kZSwgJnNwLT5jb21tYW5kX3F1ZXVlKTsKfQoKc3RhdGljIHN0cnVjdCBjb21tYW5kICpkZXF1ZXVlX2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJc3RydWN0IGNvbW1hbmQgKmNtZDsKCXN0cnVjdCBsaXN0X2hlYWQgKm5leHQ7CgoJaWYgKGxpc3RfZW1wdHkoJnNwLT5jb21tYW5kX3F1ZXVlKSkKCQlyZXR1cm4gTlVMTDsKCgluZXh0ID0gc3AtPmNvbW1hbmRfcXVldWUubmV4dDsKCWxpc3RfZGVsX2luaXQobmV4dCk7CgljbWQgPSBsaXN0X2VudHJ5KG5leHQsIHN0cnVjdCBjb21tYW5kLCBxdWV1ZV9ub2RlKTsKCglyZXR1cm4gY21kOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgZG9fZXhlY19jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCWNoYXIgdHNidWZbMzJdOwoKCWRiZygiJXM6JWQgYXQgJXNcbiIsIF9fZnVuY19fLCBfX0xJTkVfXywgZ2V0X3RpbWVzdGFtcCh0c2J1ZikpOwoKCWlmIChpYm1hc21fc2VuZF9pMm9fbWVzc2FnZShzcCkpIHsKCQlzcC0+Y3VycmVudF9jb21tYW5kLT5zdGF0dXMgPSBJQk1BU01fQ01EX0ZBSUxFRDsKCQl3YWtlX3VwKCZzcC0+Y3VycmVudF9jb21tYW5kLT53YWl0KTsKCQljb21tYW5kX3B1dChzcC0+Y3VycmVudF9jb21tYW5kKTsKCQlleGVjX25leHRfY29tbWFuZChzcCk7Cgl9Cn0KCi8qKgogKiBleGVjX2NvbW1hbmQKICogc2VuZCBhIGNvbW1hbmQgdG8gYSBzZXJ2aWNlIHByb2Nlc3NvcgogKiBDb21tYW5kcyBhcmUgZXhlY3V0ZWQgc2VxdWVudGlhbGx5LiBPbmUgY29tbWFuZCAoc3AtPmN1cnJlbnRfY29tbWFuZCkKICogaXMgc2VudCB0byB0aGUgc2VydmljZSBwcm9jZXNzb3IuIE9uY2UgdGhlIGludGVycnVwdCBoYW5kbGVyIGdldHMgYQogKiBtZXNzYWdlIG9mIHR5cGUgY29tbWFuZF9yZXNwb25zZSwgdGhlIG1lc3NhZ2UgaXMgY29waWVkIGludG8KICogdGhlIGN1cnJlbnQgY29tbWFuZHMgYnVmZmVyLAogKi8Kdm9pZCBpYm1hc21fZXhlY19jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBjb21tYW5kICpjbWQpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgljaGFyIHRzYnVmWzMyXTsKCglkYmcoIiVzOiVkIGF0ICVzXG4iLCBfX2Z1bmNfXywgX19MSU5FX18sIGdldF90aW1lc3RhbXAodHNidWYpKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCglpZiAoIXNwLT5jdXJyZW50X2NvbW1hbmQpIHsKCQlzcC0+Y3VycmVudF9jb21tYW5kID0gY21kOwoJCWNvbW1hbmRfZ2V0KHNwLT5jdXJyZW50X2NvbW1hbmQpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7CgkJZG9fZXhlY19jb21tYW5kKHNwKTsKCX0gZWxzZSB7CgkJZW5xdWV1ZV9jb21tYW5kKHNwLCBjbWQpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7Cgl9Cn0KCnN0YXRpYyB2b2lkIGV4ZWNfbmV4dF9jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgljaGFyIHRzYnVmWzMyXTsKCglkYmcoIiVzOiVkIGF0ICVzXG4iLCBfX2Z1bmNfXywgX19MSU5FX18sIGdldF90aW1lc3RhbXAodHNidWYpKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCXNwLT5jdXJyZW50X2NvbW1hbmQgPSBkZXF1ZXVlX2NvbW1hbmQoc3ApOwoJaWYgKHNwLT5jdXJyZW50X2NvbW1hbmQpIHsKCQljb21tYW5kX2dldChzcC0+Y3VycmVudF9jb21tYW5kKTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzcC0+bG9jaywgZmxhZ3MpOwoJCWRvX2V4ZWNfY29tbWFuZChzcCk7Cgl9IGVsc2UgewoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7Cgl9Cn0KCi8qKgogKiBTbGVlcCB1bnRpbCBhIGNvbW1hbmQgaGFzIGZhaWxlZCBvciBhIHJlc3BvbnNlIGhhcyBiZWVuIHJlY2VpdmVkCiAqIGFuZCB0aGUgY29tbWFuZCBzdGF0dXMgYmVlbiB1cGRhdGVkIGJ5IHRoZSBpbnRlcnJ1cHQgaGFuZGxlci4KICogKHNlZSByZWNlaXZlX3Jlc3BvbnNlKS4KICovCnZvaWQgaWJtYXNtX3dhaXRfZm9yX3Jlc3BvbnNlKHN0cnVjdCBjb21tYW5kICpjbWQsIGludCB0aW1lb3V0KQp7Cgl3YWl0X2V2ZW50X2ludGVycnVwdGlibGVfdGltZW91dChjbWQtPndhaXQsCgkJCQljbWQtPnN0YXR1cyA9PSBJQk1BU01fQ01EX0NPTVBMRVRFIHx8CgkJCQljbWQtPnN0YXR1cyA9PSBJQk1BU01fQ01EX0ZBSUxFRCwKCQkJCXRpbWVvdXQgKiBIWik7Cn0KCi8qKgogKiByZWNlaXZlX2NvbW1hbmRfcmVzcG9uc2UKICogY2FsbGVkIGJ5IHRoZSBpbnRlcnJ1cHQgaGFuZGxlciB3aGVuIGEgZG90IGNvbW1hbmQgb2YgdHlwZSBjb21tYW5kX3Jlc3BvbnNlCiAqIHdhcyByZWNlaXZlZC4KICovCnZvaWQgaWJtYXNtX3JlY2VpdmVfY29tbWFuZF9yZXNwb25zZShzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCB2b2lkICpyZXNwb25zZSwgc2l6ZV90IHNpemUpCnsKCXN0cnVjdCBjb21tYW5kICpjbWQgPSBzcC0+Y3VycmVudF9jb21tYW5kOwoKCWlmICghc3AtPmN1cnJlbnRfY29tbWFuZCkKCQlyZXR1cm47CgoJbWVtY3B5X2Zyb21pbyhjbWQtPmJ1ZmZlciwgcmVzcG9uc2UsIG1pbihzaXplLCBjbWQtPmJ1ZmZlcl9zaXplKSk7CgljbWQtPnN0YXR1cyA9IElCTUFTTV9DTURfQ09NUExFVEU7Cgl3YWtlX3VwKCZzcC0+Y3VycmVudF9jb21tYW5kLT53YWl0KTsKCWNvbW1hbmRfcHV0KHNwLT5jdXJyZW50X2NvbW1hbmQpOwoJZXhlY19uZXh0X2NvbW1hbmQoc3ApOwp9Cg==