Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4gCiAqCiAqLwoKI2luY2x1ZGUgImlibWFzbS5oIgoKc3RhdGljIHZvaWQgZXhlY19uZXh0X2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCk7CnN0YXRpYyB2b2lkIGZyZWVfY29tbWFuZChzdHJ1Y3Qga29iamVjdCAqa29iaik7CgpzdGF0aWMgc3RydWN0IGtvYmpfdHlwZSBpYm1hc21fY21kX2tvYmpfdHlwZSA9IHsKCS5yZWxlYXNlID0gZnJlZV9jb21tYW5kLAp9OwoKCnN0cnVjdCBjb21tYW5kICppYm1hc21fbmV3X2NvbW1hbmQoc2l6ZV90IGJ1ZmZlcl9zaXplKQp7CglzdHJ1Y3QgY29tbWFuZCAqY21kOwoKCWlmIChidWZmZXJfc2l6ZSA+IElCTUFTTV9DTURfTUFYX0JVRkZFUl9TSVpFKQoJCXJldHVybiBOVUxMOwoKCWNtZCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBjb21tYW5kKSwgR0ZQX0tFUk5FTCk7CglpZiAoY21kID09IE5VTEwpCgkJcmV0dXJuIE5VTEw7CgoJbWVtc2V0KGNtZCwgMCwgc2l6ZW9mKCpjbWQpKTsKCgljbWQtPmJ1ZmZlciA9IGttYWxsb2MoYnVmZmVyX3NpemUsIEdGUF9LRVJORUwpOwoJaWYgKGNtZC0+YnVmZmVyID09IE5VTEwpIHsKCQlrZnJlZShjbWQpOwoJCXJldHVybiBOVUxMOwoJfQoJbWVtc2V0KGNtZC0+YnVmZmVyLCAwLCBidWZmZXJfc2l6ZSk7CgljbWQtPmJ1ZmZlcl9zaXplID0gYnVmZmVyX3NpemU7CgoJa29iamVjdF9pbml0KCZjbWQtPmtvYmopOwoJY21kLT5rb2JqLmt0eXBlID0gJmlibWFzbV9jbWRfa29ial90eXBlOwoKCWNtZC0+c3RhdHVzID0gSUJNQVNNX0NNRF9QRU5ESU5HOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmY21kLT53YWl0KTsKCUlOSVRfTElTVF9IRUFEKCZjbWQtPnF1ZXVlX25vZGUpOwoKCXJldHVybiBjbWQ7Cn0KCnN0YXRpYyB2b2lkIGZyZWVfY29tbWFuZChzdHJ1Y3Qga29iamVjdCAqa29iaikKewoJc3RydWN0IGNvbW1hbmQgKmNtZCA9IHRvX2NvbW1hbmQoa29iaik7CiAKCWxpc3RfZGVsKCZjbWQtPnF1ZXVlX25vZGUpOwoJa2ZyZWUoY21kLT5idWZmZXIpOwoJa2ZyZWUoY21kKTsKfQoKc3RhdGljIHZvaWQgZW5xdWV1ZV9jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBjb21tYW5kICpjbWQpCnsKCWxpc3RfYWRkX3RhaWwoJmNtZC0+cXVldWVfbm9kZSwgJnNwLT5jb21tYW5kX3F1ZXVlKTsKfQoKc3RhdGljIHN0cnVjdCBjb21tYW5kICpkZXF1ZXVlX2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJc3RydWN0IGNvbW1hbmQgKmNtZDsKCXN0cnVjdCBsaXN0X2hlYWQgKm5leHQ7CgoJaWYgKGxpc3RfZW1wdHkoJnNwLT5jb21tYW5kX3F1ZXVlKSkKCQlyZXR1cm4gTlVMTDsKCgluZXh0ID0gc3AtPmNvbW1hbmRfcXVldWUubmV4dDsKCWxpc3RfZGVsX2luaXQobmV4dCk7CgljbWQgPSBsaXN0X2VudHJ5KG5leHQsIHN0cnVjdCBjb21tYW5kLCBxdWV1ZV9ub2RlKTsKCglyZXR1cm4gY21kOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgZG9fZXhlY19jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCWlmIChpYm1hc21fc2VuZF9pMm9fbWVzc2FnZShzcCkpIHsKCQlzcC0+Y3VycmVudF9jb21tYW5kLT5zdGF0dXMgPSBJQk1BU01fQ01EX0ZBSUxFRDsKCQlleGVjX25leHRfY29tbWFuZChzcCk7Cgl9Cn0KCQovKioKICogZXhlY19jb21tYW5kCiAqIHNlbmQgYSBjb21tYW5kIHRvIGEgc2VydmljZSBwcm9jZXNzb3IKICogQ29tbWFuZHMgYXJlIGV4ZWN1dGVkIHNlcXVlbnRpYWxseS4gT25lIGNvbW1hbmQgKHNwLT5jdXJyZW50X2NvbW1hbmQpCiAqIGlzIHNlbnQgdG8gdGhlIHNlcnZpY2UgcHJvY2Vzc29yLiBPbmNlIHRoZSBpbnRlcnJ1cHQgaGFuZGxlciBnZXRzIGEKICogbWVzc2FnZSBvZiB0eXBlIGNvbW1hbmRfcmVzcG9uc2UsIHRoZSBtZXNzYWdlIGlzIGNvcGllZCBpbnRvCiAqIHRoZSBjdXJyZW50IGNvbW1hbmRzIGJ1ZmZlciwgCiAqLwp2b2lkIGlibWFzbV9leGVjX2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCwgc3RydWN0IGNvbW1hbmQgKmNtZCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCglpZiAoIXNwLT5jdXJyZW50X2NvbW1hbmQpIHsKCQljb21tYW5kX2dldChjbWQpOwoJCXNwLT5jdXJyZW50X2NvbW1hbmQgPSBjbWQ7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKCgkJZG9fZXhlY19jb21tYW5kKHNwKTsKCX0gZWxzZSB7CgkJZW5xdWV1ZV9jb21tYW5kKHNwLCBjbWQpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7Cgl9Cn0KCnN0YXRpYyB2b2lkIGV4ZWNfbmV4dF9jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJd2FrZV91cCgmc3AtPmN1cnJlbnRfY29tbWFuZC0+d2FpdCk7Cgljb21tYW5kX3B1dChzcC0+Y3VycmVudF9jb21tYW5kKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCXNwLT5jdXJyZW50X2NvbW1hbmQgPSBkZXF1ZXVlX2NvbW1hbmQoc3ApOwoJaWYgKHNwLT5jdXJyZW50X2NvbW1hbmQpIHsKCQljb21tYW5kX2dldChzcC0+Y3VycmVudF9jb21tYW5kKTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzcC0+bG9jaywgZmxhZ3MpOwoJCWRvX2V4ZWNfY29tbWFuZChzcCk7Cgl9IGVsc2UgewoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7Cgl9Cn0KCi8qKiAKICogU2xlZXAgdW50aWwgYSBjb21tYW5kIGhhcyBmYWlsZWQgb3IgYSByZXNwb25zZSBoYXMgYmVlbiByZWNlaXZlZAogKiBhbmQgdGhlIGNvbW1hbmQgc3RhdHVzIGJlZW4gdXBkYXRlZCBieSB0aGUgaW50ZXJydXB0IGhhbmRsZXIuCiAqIChzZWUgcmVjZWl2ZV9yZXNwb25zZSkuCiAqLwp2b2lkIGlibWFzbV93YWl0X2Zvcl9yZXNwb25zZShzdHJ1Y3QgY29tbWFuZCAqY21kLCBpbnQgdGltZW91dCkKewoJd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlX3RpbWVvdXQoY21kLT53YWl0LAoJCQkJY21kLT5zdGF0dXMgPT0gSUJNQVNNX0NNRF9DT01QTEVURSB8fAoJCQkJY21kLT5zdGF0dXMgPT0gSUJNQVNNX0NNRF9GQUlMRUQsCgkJCQl0aW1lb3V0ICogSFopOwp9CgovKioKICogcmVjZWl2ZV9jb21tYW5kX3Jlc3BvbnNlCiAqIGNhbGxlZCBieSB0aGUgaW50ZXJydXB0IGhhbmRsZXIgd2hlbiBhIGRvdCBjb21tYW5kIG9mIHR5cGUgY29tbWFuZF9yZXNwb25zZQogKiB3YXMgcmVjZWl2ZWQuCiAqLwp2b2lkIGlibWFzbV9yZWNlaXZlX2NvbW1hbmRfcmVzcG9uc2Uoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCwgdm9pZCAqcmVzcG9uc2UsIHNpemVfdCBzaXplKQp7CglzdHJ1Y3QgY29tbWFuZCAqY21kID0gc3AtPmN1cnJlbnRfY29tbWFuZDsKCglpZiAoIXNwLT5jdXJyZW50X2NvbW1hbmQpIAoJCXJldHVybjsgCgoJbWVtY3B5KGNtZC0+YnVmZmVyLCByZXNwb25zZSwgbWluKHNpemUsIGNtZC0+YnVmZmVyX3NpemUpKTsKCWNtZC0+c3RhdHVzID0gSUJNQVNNX0NNRF9DT01QTEVURTsKCWV4ZWNfbmV4dF9jb21tYW5kKHNwKTsKfQo=