Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4KICoKICovCgojaW5jbHVkZSAiaWJtYXNtLmgiCiNpbmNsdWRlICJsb3dsZXZlbC5oIgoKc3RhdGljIHZvaWQgZXhlY19uZXh0X2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCk7CnN0YXRpYyB2b2lkIGZyZWVfY29tbWFuZChzdHJ1Y3Qga29iamVjdCAqa29iaik7CgpzdGF0aWMgc3RydWN0IGtvYmpfdHlwZSBpYm1hc21fY21kX2tvYmpfdHlwZSA9IHsKCS5yZWxlYXNlID0gZnJlZV9jb21tYW5kLAp9OwoKc3RhdGljIGF0b21pY190IGNvbW1hbmRfY291bnQgPSBBVE9NSUNfSU5JVCgwKTsKCnN0cnVjdCBjb21tYW5kICppYm1hc21fbmV3X2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCwgc2l6ZV90IGJ1ZmZlcl9zaXplKQp7CglzdHJ1Y3QgY29tbWFuZCAqY21kOwoKCWlmIChidWZmZXJfc2l6ZSA+IElCTUFTTV9DTURfTUFYX0JVRkZFUl9TSVpFKQoJCXJldHVybiBOVUxMOwoKCWNtZCA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBjb21tYW5kKSwgR0ZQX0tFUk5FTCk7CglpZiAoY21kID09IE5VTEwpCgkJcmV0dXJuIE5VTEw7CgoKCWNtZC0+YnVmZmVyID0ga3phbGxvYyhidWZmZXJfc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoY21kLT5idWZmZXIgPT0gTlVMTCkgewoJCWtmcmVlKGNtZCk7CgkJcmV0dXJuIE5VTEw7Cgl9CgljbWQtPmJ1ZmZlcl9zaXplID0gYnVmZmVyX3NpemU7CgoJa29iamVjdF9pbml0KCZjbWQtPmtvYmopOwoJY21kLT5rb2JqLmt0eXBlID0gJmlibWFzbV9jbWRfa29ial90eXBlOwoJY21kLT5sb2NrID0gJnNwLT5sb2NrOwoKCWNtZC0+c3RhdHVzID0gSUJNQVNNX0NNRF9QRU5ESU5HOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmY21kLT53YWl0KTsKCUlOSVRfTElTVF9IRUFEKCZjbWQtPnF1ZXVlX25vZGUpOwoKCWF0b21pY19pbmMoJmNvbW1hbmRfY291bnQpOwoJZGJnKCJjb21tYW5kIGNvdW50OiAlZFxuIiwgYXRvbWljX3JlYWQoJmNvbW1hbmRfY291bnQpKTsKCglyZXR1cm4gY21kOwp9CgpzdGF0aWMgdm9pZCBmcmVlX2NvbW1hbmQoc3RydWN0IGtvYmplY3QgKmtvYmopCnsKCXN0cnVjdCBjb21tYW5kICpjbWQgPSB0b19jb21tYW5kKGtvYmopOwoKCWxpc3RfZGVsKCZjbWQtPnF1ZXVlX25vZGUpOwoJYXRvbWljX2RlYygmY29tbWFuZF9jb3VudCk7CglkYmcoImNvbW1hbmQgY291bnQ6ICVkXG4iLCBhdG9taWNfcmVhZCgmY29tbWFuZF9jb3VudCkpOwoJa2ZyZWUoY21kLT5idWZmZXIpOwoJa2ZyZWUoY21kKTsKfQoKc3RhdGljIHZvaWQgZW5xdWV1ZV9jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBjb21tYW5kICpjbWQpCnsKCWxpc3RfYWRkX3RhaWwoJmNtZC0+cXVldWVfbm9kZSwgJnNwLT5jb21tYW5kX3F1ZXVlKTsKfQoKc3RhdGljIHN0cnVjdCBjb21tYW5kICpkZXF1ZXVlX2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJc3RydWN0IGNvbW1hbmQgKmNtZDsKCXN0cnVjdCBsaXN0X2hlYWQgKm5leHQ7CgoJaWYgKGxpc3RfZW1wdHkoJnNwLT5jb21tYW5kX3F1ZXVlKSkKCQlyZXR1cm4gTlVMTDsKCgluZXh0ID0gc3AtPmNvbW1hbmRfcXVldWUubmV4dDsKCWxpc3RfZGVsX2luaXQobmV4dCk7CgljbWQgPSBsaXN0X2VudHJ5KG5leHQsIHN0cnVjdCBjb21tYW5kLCBxdWV1ZV9ub2RlKTsKCglyZXR1cm4gY21kOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgZG9fZXhlY19jb21tYW5kKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCWNoYXIgdHNidWZbMzJdOwoKCWRiZygiJXM6JWQgYXQgJXNcbiIsIF9fRlVOQ1RJT05fXywgX19MSU5FX18sIGdldF90aW1lc3RhbXAodHNidWYpKTsKCglpZiAoaWJtYXNtX3NlbmRfaTJvX21lc3NhZ2Uoc3ApKSB7CgkJc3AtPmN1cnJlbnRfY29tbWFuZC0+c3RhdHVzID0gSUJNQVNNX0NNRF9GQUlMRUQ7CgkJd2FrZV91cCgmc3AtPmN1cnJlbnRfY29tbWFuZC0+d2FpdCk7CgkJY29tbWFuZF9wdXQoc3AtPmN1cnJlbnRfY29tbWFuZCk7CgkJZXhlY19uZXh0X2NvbW1hbmQoc3ApOwoJfQp9CgovKioKICogZXhlY19jb21tYW5kCiAqIHNlbmQgYSBjb21tYW5kIHRvIGEgc2VydmljZSBwcm9jZXNzb3IKICogQ29tbWFuZHMgYXJlIGV4ZWN1dGVkIHNlcXVlbnRpYWxseS4gT25lIGNvbW1hbmQgKHNwLT5jdXJyZW50X2NvbW1hbmQpCiAqIGlzIHNlbnQgdG8gdGhlIHNlcnZpY2UgcHJvY2Vzc29yLiBPbmNlIHRoZSBpbnRlcnJ1cHQgaGFuZGxlciBnZXRzIGEKICogbWVzc2FnZSBvZiB0eXBlIGNvbW1hbmRfcmVzcG9uc2UsIHRoZSBtZXNzYWdlIGlzIGNvcGllZCBpbnRvCiAqIHRoZSBjdXJyZW50IGNvbW1hbmRzIGJ1ZmZlciwKICovCnZvaWQgaWJtYXNtX2V4ZWNfY29tbWFuZChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCBzdHJ1Y3QgY29tbWFuZCAqY21kKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJY2hhciB0c2J1ZlszMl07CgoJZGJnKCIlczolZCBhdCAlc1xuIiwgX19GVU5DVElPTl9fLCBfX0xJTkVfXywgZ2V0X3RpbWVzdGFtcCh0c2J1ZikpOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZzcC0+bG9jaywgZmxhZ3MpOwoKCWlmICghc3AtPmN1cnJlbnRfY29tbWFuZCkgewoJCXNwLT5jdXJyZW50X2NvbW1hbmQgPSBjbWQ7CgkJY29tbWFuZF9nZXQoc3AtPmN1cnJlbnRfY29tbWFuZCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKCQlkb19leGVjX2NvbW1hbmQoc3ApOwoJfSBlbHNlIHsKCQllbnF1ZXVlX2NvbW1hbmQoc3AsIGNtZCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKCX0KfQoKc3RhdGljIHZvaWQgZXhlY19uZXh0X2NvbW1hbmQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWNoYXIgdHNidWZbMzJdOwoKCWRiZygiJXM6JWQgYXQgJXNcbiIsIF9fRlVOQ1RJT05fXywgX19MSU5FX18sIGdldF90aW1lc3RhbXAodHNidWYpKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCXNwLT5jdXJyZW50X2NvbW1hbmQgPSBkZXF1ZXVlX2NvbW1hbmQoc3ApOwoJaWYgKHNwLT5jdXJyZW50X2NvbW1hbmQpIHsKCQljb21tYW5kX2dldChzcC0+Y3VycmVudF9jb21tYW5kKTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzcC0+bG9jaywgZmxhZ3MpOwoJCWRvX2V4ZWNfY29tbWFuZChzcCk7Cgl9IGVsc2UgewoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7Cgl9Cn0KCi8qKgogKiBTbGVlcCB1bnRpbCBhIGNvbW1hbmQgaGFzIGZhaWxlZCBvciBhIHJlc3BvbnNlIGhhcyBiZWVuIHJlY2VpdmVkCiAqIGFuZCB0aGUgY29tbWFuZCBzdGF0dXMgYmVlbiB1cGRhdGVkIGJ5IHRoZSBpbnRlcnJ1cHQgaGFuZGxlci4KICogKHNlZSByZWNlaXZlX3Jlc3BvbnNlKS4KICovCnZvaWQgaWJtYXNtX3dhaXRfZm9yX3Jlc3BvbnNlKHN0cnVjdCBjb21tYW5kICpjbWQsIGludCB0aW1lb3V0KQp7Cgl3YWl0X2V2ZW50X2ludGVycnVwdGlibGVfdGltZW91dChjbWQtPndhaXQsCgkJCQljbWQtPnN0YXR1cyA9PSBJQk1BU01fQ01EX0NPTVBMRVRFIHx8CgkJCQljbWQtPnN0YXR1cyA9PSBJQk1BU01fQ01EX0ZBSUxFRCwKCQkJCXRpbWVvdXQgKiBIWik7Cn0KCi8qKgogKiByZWNlaXZlX2NvbW1hbmRfcmVzcG9uc2UKICogY2FsbGVkIGJ5IHRoZSBpbnRlcnJ1cHQgaGFuZGxlciB3aGVuIGEgZG90IGNvbW1hbmQgb2YgdHlwZSBjb21tYW5kX3Jlc3BvbnNlCiAqIHdhcyByZWNlaXZlZC4KICovCnZvaWQgaWJtYXNtX3JlY2VpdmVfY29tbWFuZF9yZXNwb25zZShzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCB2b2lkICpyZXNwb25zZSwgc2l6ZV90IHNpemUpCnsKCXN0cnVjdCBjb21tYW5kICpjbWQgPSBzcC0+Y3VycmVudF9jb21tYW5kOwoKCWlmICghc3AtPmN1cnJlbnRfY29tbWFuZCkKCQlyZXR1cm47CgoJbWVtY3B5X2Zyb21pbyhjbWQtPmJ1ZmZlciwgcmVzcG9uc2UsIG1pbihzaXplLCBjbWQtPmJ1ZmZlcl9zaXplKSk7CgljbWQtPnN0YXR1cyA9IElCTUFTTV9DTURfQ09NUExFVEU7Cgl3YWtlX3VwKCZzcC0+Y3VycmVudF9jb21tYW5kLT53YWl0KTsKCWNvbW1hbmRfcHV0KHNwLT5jdXJyZW50X2NvbW1hbmQpOwoJZXhlY19uZXh0X2NvbW1hbmQoc3ApOwp9Cg==