Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4gCiAqCiAqLwoKI2luY2x1ZGUgPGxpbnV4L25vdGlmaWVyLmg+CiNpbmNsdWRlICJpYm1hc20uaCIKI2luY2x1ZGUgImRvdF9jb21tYW5kLmgiCiNpbmNsdWRlICJsb3dsZXZlbC5oIgoKc3RhdGljIGludCBzdXNwZW5kX2hlYXJ0YmVhdHMgPSAwOwoKLyoKICogT25jZSB0aGUgZHJpdmVyIGluZGljYXRlcyB0byB0aGUgc2VydmljZSBwcm9jZXNzb3IgdGhhdCBpdCBpcyBydW5uaW5nCiAqIC0gc2VlIHNlbmRfb3Nfc3RhdGUoKSAtIHRoZSBzZXJ2aWNlIHByb2Nlc3NvciBzZW5kcyBwZXJpb2RpYyBoZWFydGJlYXRzCiAqIHRvIHRoZSBkcml2ZXIuIFRoZSBkcml2ZXIgbXVzdCByZXNwb25kIHRvIHRoZSBoZWFydGJlYXRzIG9yIGVsc2UgdGhlIE9TCiAqIHdpbGwgYmUgcmVib290ZWQuCiAqIEluIHRoZSBjYXNlIG9mIGEgcGFuaWMgdGhlIGludGVycnVwdCBoYW5kbGVyIGNvbnRpbnVlcyB0byB3b3JrIGFuZCB0aHVzCiAqIGNvbnRpbnVlcyB0byByZXNwb25kIHRvIGhlYXJ0YmVhdHMsIG1ha2luZyB0aGUgc2VydmljZSBwcm9jZXNzb3IgYmVsaWV2ZQogKiB0aGUgT1MgaXMgc3RpbGwgcnVubmluZyBhbmQgdGh1cyBwcmV2ZW50aW5nIGEgcmVib290LgogKiBUbyBwcmV2ZW50IHRoaXMgZnJvbSBoYXBwZW5pbmcgYSBjYWxsYmFjayBpcyBhZGRlZCB0aGUgcGFuaWNfbm90aWZpZXJfbGlzdC4KICogQmVmb3JlIHJlc3BvbmRpbmcgdG8gYSBoZWFydGJlYXQgdGhlIGRyaXZlciBjaGVja3MgaWYgYSBwYW5pYyBoYXMgaGFwcGVuZWQsCiAqIGlmIHllcyBpdCBzdXNwZW5kcyBoZWFydGJlYXQsIGNhdXNpbmcgdGhlIHNlcnZpY2UgcHJvY2Vzc29yIHRvIHJlYm9vdCBhcwogKiBleHBlY3RlZC4KICovCnN0YXRpYyBpbnQgcGFuaWNfaGFwcGVuZWQoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpuLCB1bnNpZ25lZCBsb25nIHZhbCwgdm9pZCAqdikKewoJc3VzcGVuZF9oZWFydGJlYXRzID0gMTsKCXJldHVybiAwOwp9CgpzdGF0aWMgc3RydWN0IG5vdGlmaWVyX2Jsb2NrIHBhbmljX25vdGlmaWVyID0geyBwYW5pY19oYXBwZW5lZCwgTlVMTCwgMSB9OwoKdm9pZCBpYm1hc21fcmVnaXN0ZXJfcGFuaWNfbm90aWZpZXIodm9pZCkKewoJbm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIoJnBhbmljX25vdGlmaWVyX2xpc3QsICZwYW5pY19ub3RpZmllcik7Cn0KCnZvaWQgaWJtYXNtX3VucmVnaXN0ZXJfcGFuaWNfbm90aWZpZXIodm9pZCkKewoJbm90aWZpZXJfY2hhaW5fdW5yZWdpc3RlcigmcGFuaWNfbm90aWZpZXJfbGlzdCwgJnBhbmljX25vdGlmaWVyKTsKfQoKCmludCBpYm1hc21faGVhcnRiZWF0X2luaXQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJc3AtPmhlYXJ0YmVhdCA9IGlibWFzbV9uZXdfY29tbWFuZChzcCwgSEVBUlRCRUFUX0JVRkZFUl9TSVpFKTsKCWlmIChzcC0+aGVhcnRiZWF0ID09IE5VTEwpCgkJcmV0dXJuIC1FTk9NRU07CgoJcmV0dXJuIDA7Cn0KCnZvaWQgaWJtYXNtX2hlYXJ0YmVhdF9leGl0KHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCWNoYXIgdHNidWZbMzJdOwoKCWRiZygiJXM6JWQgYXQgJXNcbiIsIF9fRlVOQ1RJT05fXywgX19MSU5FX18sIGdldF90aW1lc3RhbXAodHNidWYpKTsKCWlibWFzbV93YWl0X2Zvcl9yZXNwb25zZShzcC0+aGVhcnRiZWF0LCBJQk1BU01fQ01EX1RJTUVPVVRfTk9STUFMKTsKCWRiZygiJXM6JWQgYXQgJXNcbiIsIF9fRlVOQ1RJT05fXywgX19MSU5FX18sIGdldF90aW1lc3RhbXAodHNidWYpKTsKCXN1c3BlbmRfaGVhcnRiZWF0cyA9IDE7Cgljb21tYW5kX3B1dChzcC0+aGVhcnRiZWF0KTsKfQoKdm9pZCBpYm1hc21fcmVjZWl2ZV9oZWFydGJlYXQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCwgIHZvaWQgKm1lc3NhZ2UsIHNpemVfdCBzaXplKQp7CglzdHJ1Y3QgY29tbWFuZCAqY21kID0gc3AtPmhlYXJ0YmVhdDsKCXN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIgKmhlYWRlciA9IChzdHJ1Y3QgZG90X2NvbW1hbmRfaGVhZGVyICopY21kLT5idWZmZXI7CgljaGFyIHRzYnVmWzMyXTsKCglkYmcoIiVzOiVkIGF0ICVzXG4iLCBfX0ZVTkNUSU9OX18sIF9fTElORV9fLCBnZXRfdGltZXN0YW1wKHRzYnVmKSk7CglpZiAoc3VzcGVuZF9oZWFydGJlYXRzKQoJCXJldHVybjsKCgkvKiByZXR1cm4gdGhlIHJlY2VpdmVkIGRvdCBjb21tYW5kIHRvIHNlbmRlciAqLwoJY21kLT5zdGF0dXMgPSBJQk1BU01fQ01EX1BFTkRJTkc7CglzaXplID0gbWluKHNpemUsIGNtZC0+YnVmZmVyX3NpemUpOwoJbWVtY3B5X2Zyb21pbyhjbWQtPmJ1ZmZlciwgbWVzc2FnZSwgc2l6ZSk7CgloZWFkZXItPnR5cGUgPSBzcF93cml0ZTsKCWlibWFzbV9leGVjX2NvbW1hbmQoc3AsIGNtZCk7Cn0K