Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4gCiAqCiAqLwoKI2luY2x1ZGUgImlibWFzbS5oIgojaW5jbHVkZSAibG93bGV2ZWwuaCIKCnN0YXRpYyB2b2lkIGV4ZWNfbmV4dF9jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApOwpzdGF0aWMgdm9pZCBmcmVlX2NvbW1hbmQoc3RydWN0IGtvYmplY3QgKmtvYmopOwoKc3RhdGljIHN0cnVjdCBrb2JqX3R5cGUgaWJtYXNtX2NtZF9rb2JqX3R5cGUgPSB7CgkucmVsZWFzZSA9IGZyZWVfY29tbWFuZCwKfTsKCnN0YXRpYyBhdG9taWNfdCBjb21tYW5kX2NvdW50ID0gQVRPTUlDX0lOSVQoMCk7CgpzdHJ1Y3QgY29tbWFuZCAqaWJtYXNtX25ld19jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHNpemVfdCBidWZmZXJfc2l6ZSkKewoJc3RydWN0IGNvbW1hbmQgKmNtZDsKCglpZiAoYnVmZmVyX3NpemUgPiBJQk1BU01fQ01EX01BWF9CVUZGRVJfU0laRSkKCQlyZXR1cm4gTlVMTDsKCgljbWQgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgY29tbWFuZCksIEdGUF9LRVJORUwpOwoJaWYgKGNtZCA9PSBOVUxMKQoJCXJldHVybiBOVUxMOwoKCW1lbXNldChjbWQsIDAsIHNpemVvZigqY21kKSk7CgoJY21kLT5idWZmZXIgPSBrbWFsbG9jKGJ1ZmZlcl9zaXplLCBHRlBfS0VSTkVMKTsKCWlmIChjbWQtPmJ1ZmZlciA9PSBOVUxMKSB7CgkJa2ZyZWUoY21kKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW1lbXNldChjbWQtPmJ1ZmZlciwgMCwgYnVmZmVyX3NpemUpOwoJY21kLT5idWZmZXJfc2l6ZSA9IGJ1ZmZlcl9zaXplOwoKCWtvYmplY3RfaW5pdCgmY21kLT5rb2JqKTsKCWNtZC0+a29iai5rdHlwZSA9ICZpYm1hc21fY21kX2tvYmpfdHlwZTsKCWNtZC0+bG9jayA9ICZzcC0+bG9jazsKCgljbWQtPnN0YXR1cyA9IElCTUFTTV9DTURfUEVORElORzsKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmNtZC0+d2FpdCk7CglJTklUX0xJU1RfSEVBRCgmY21kLT5xdWV1ZV9ub2RlKTsKCglhdG9taWNfaW5jKCZjb21tYW5kX2NvdW50KTsKCWRiZygiY29tbWFuZCBjb3VudDogJWRcbiIsIGF0b21pY19yZWFkKCZjb21tYW5kX2NvdW50KSk7CgoJcmV0dXJuIGNtZDsKfQoKc3RhdGljIHZvaWQgZnJlZV9jb21tYW5kKHN0cnVjdCBrb2JqZWN0ICprb2JqKQp7CglzdHJ1Y3QgY29tbWFuZCAqY21kID0gdG9fY29tbWFuZChrb2JqKTsKIAoJbGlzdF9kZWwoJmNtZC0+cXVldWVfbm9kZSk7CglhdG9taWNfZGVjKCZjb21tYW5kX2NvdW50KTsKCWRiZygiY29tbWFuZCBjb3VudDogJWRcbiIsIGF0b21pY19yZWFkKCZjb21tYW5kX2NvdW50KSk7CglrZnJlZShjbWQtPmJ1ZmZlcik7CglrZnJlZShjbWQpOwp9CgpzdGF0aWMgdm9pZCBlbnF1ZXVlX2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCwgc3RydWN0IGNvbW1hbmQgKmNtZCkKewoJbGlzdF9hZGRfdGFpbCgmY21kLT5xdWV1ZV9ub2RlLCAmc3AtPmNvbW1hbmRfcXVldWUpOwp9CgpzdGF0aWMgc3RydWN0IGNvbW1hbmQgKmRlcXVldWVfY29tbWFuZChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwKQp7CglzdHJ1Y3QgY29tbWFuZCAqY21kOwoJc3RydWN0IGxpc3RfaGVhZCAqbmV4dDsKCglpZiAobGlzdF9lbXB0eSgmc3AtPmNvbW1hbmRfcXVldWUpKQoJCXJldHVybiBOVUxMOwoKCW5leHQgPSBzcC0+Y29tbWFuZF9xdWV1ZS5uZXh0OwoJbGlzdF9kZWxfaW5pdChuZXh0KTsKCWNtZCA9IGxpc3RfZW50cnkobmV4dCwgc3RydWN0IGNvbW1hbmQsIHF1ZXVlX25vZGUpOwoKCXJldHVybiBjbWQ7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBkb19leGVjX2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJY2hhciB0c2J1ZlszMl07CgoJZGJnKCIlczolZCBhdCAlc1xuIiwgX19GVU5DVElPTl9fLCBfX0xJTkVfXywgZ2V0X3RpbWVzdGFtcCh0c2J1ZikpOwoKCWlmIChpYm1hc21fc2VuZF9pMm9fbWVzc2FnZShzcCkpIHsKCQlzcC0+Y3VycmVudF9jb21tYW5kLT5zdGF0dXMgPSBJQk1BU01fQ01EX0ZBSUxFRDsKCQl3YWtlX3VwKCZzcC0+Y3VycmVudF9jb21tYW5kLT53YWl0KTsKCQljb21tYW5kX3B1dChzcC0+Y3VycmVudF9jb21tYW5kKTsKCQlleGVjX25leHRfY29tbWFuZChzcCk7Cgl9Cn0KCQovKioKICogZXhlY19jb21tYW5kCiAqIHNlbmQgYSBjb21tYW5kIHRvIGEgc2VydmljZSBwcm9jZXNzb3IKICogQ29tbWFuZHMgYXJlIGV4ZWN1dGVkIHNlcXVlbnRpYWxseS4gT25lIGNvbW1hbmQgKHNwLT5jdXJyZW50X2NvbW1hbmQpCiAqIGlzIHNlbnQgdG8gdGhlIHNlcnZpY2UgcHJvY2Vzc29yLiBPbmNlIHRoZSBpbnRlcnJ1cHQgaGFuZGxlciBnZXRzIGEKICogbWVzc2FnZSBvZiB0eXBlIGNvbW1hbmRfcmVzcG9uc2UsIHRoZSBtZXNzYWdlIGlzIGNvcGllZCBpbnRvCiAqIHRoZSBjdXJyZW50IGNvbW1hbmRzIGJ1ZmZlciwgCiAqLwp2b2lkIGlibWFzbV9leGVjX2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCwgc3RydWN0IGNvbW1hbmQgKmNtZCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWNoYXIgdHNidWZbMzJdOwoKCWRiZygiJXM6JWQgYXQgJXNcbiIsIF9fRlVOQ1RJT05fXywgX19MSU5FX18sIGdldF90aW1lc3RhbXAodHNidWYpKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCglpZiAoIXNwLT5jdXJyZW50X2NvbW1hbmQpIHsKCQlzcC0+Y3VycmVudF9jb21tYW5kID0gY21kOwoJCWNvbW1hbmRfZ2V0KHNwLT5jdXJyZW50X2NvbW1hbmQpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7CgkJZG9fZXhlY19jb21tYW5kKHNwKTsKCX0gZWxzZSB7CgkJZW5xdWV1ZV9jb21tYW5kKHNwLCBjbWQpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7Cgl9Cn0KCnN0YXRpYyB2b2lkIGV4ZWNfbmV4dF9jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgljaGFyIHRzYnVmWzMyXTsKCglkYmcoIiVzOiVkIGF0ICVzXG4iLCBfX0ZVTkNUSU9OX18sIF9fTElORV9fLCBnZXRfdGltZXN0YW1wKHRzYnVmKSk7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJnNwLT5sb2NrLCBmbGFncyk7CglzcC0+Y3VycmVudF9jb21tYW5kID0gZGVxdWV1ZV9jb21tYW5kKHNwKTsKCWlmIChzcC0+Y3VycmVudF9jb21tYW5kKSB7CgkJY29tbWFuZF9nZXQoc3AtPmN1cnJlbnRfY29tbWFuZCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKCQlkb19leGVjX2NvbW1hbmQoc3ApOwoJfSBlbHNlIHsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzcC0+bG9jaywgZmxhZ3MpOwoJfQp9CgovKiogCiAqIFNsZWVwIHVudGlsIGEgY29tbWFuZCBoYXMgZmFpbGVkIG9yIGEgcmVzcG9uc2UgaGFzIGJlZW4gcmVjZWl2ZWQKICogYW5kIHRoZSBjb21tYW5kIHN0YXR1cyBiZWVuIHVwZGF0ZWQgYnkgdGhlIGludGVycnVwdCBoYW5kbGVyLgogKiAoc2VlIHJlY2VpdmVfcmVzcG9uc2UpLgogKi8Kdm9pZCBpYm1hc21fd2FpdF9mb3JfcmVzcG9uc2Uoc3RydWN0IGNvbW1hbmQgKmNtZCwgaW50IHRpbWVvdXQpCnsKCXdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZV90aW1lb3V0KGNtZC0+d2FpdCwKCQkJCWNtZC0+c3RhdHVzID09IElCTUFTTV9DTURfQ09NUExFVEUgfHwKCQkJCWNtZC0+c3RhdHVzID09IElCTUFTTV9DTURfRkFJTEVELAoJCQkJdGltZW91dCAqIEhaKTsKfQoKLyoqCiAqIHJlY2VpdmVfY29tbWFuZF9yZXNwb25zZQogKiBjYWxsZWQgYnkgdGhlIGludGVycnVwdCBoYW5kbGVyIHdoZW4gYSBkb3QgY29tbWFuZCBvZiB0eXBlIGNvbW1hbmRfcmVzcG9uc2UKICogd2FzIHJlY2VpdmVkLgogKi8Kdm9pZCBpYm1hc21fcmVjZWl2ZV9jb21tYW5kX3Jlc3BvbnNlKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHZvaWQgKnJlc3BvbnNlLCBzaXplX3Qgc2l6ZSkKewoJc3RydWN0IGNvbW1hbmQgKmNtZCA9IHNwLT5jdXJyZW50X2NvbW1hbmQ7CgoJaWYgKCFzcC0+Y3VycmVudF9jb21tYW5kKSAKCQlyZXR1cm47IAoKCW1lbWNweV9mcm9taW8oY21kLT5idWZmZXIsIHJlc3BvbnNlLCBtaW4oc2l6ZSwgY21kLT5idWZmZXJfc2l6ZSkpOwoJY21kLT5zdGF0dXMgPSBJQk1BU01fQ01EX0NPTVBMRVRFOwoJd2FrZV91cCgmc3AtPmN1cnJlbnRfY29tbWFuZC0+d2FpdCk7Cgljb21tYW5kX3B1dChzcC0+Y3VycmVudF9jb21tYW5kKTsKCWV4ZWNfbmV4dF9jb21tYW5kKHNwKTsKfQo=