Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4KICoKICovCgojaW5jbHVkZSA8bGludXgvbm90aWZpZXIuaD4KI2luY2x1ZGUgImlibWFzbS5oIgojaW5jbHVkZSAiZG90X2NvbW1hbmQuaCIKI2luY2x1ZGUgImxvd2xldmVsLmgiCgpzdGF0aWMgaW50IHN1c3BlbmRfaGVhcnRiZWF0cyA9IDA7CgovKgogKiBPbmNlIHRoZSBkcml2ZXIgaW5kaWNhdGVzIHRvIHRoZSBzZXJ2aWNlIHByb2Nlc3NvciB0aGF0IGl0IGlzIHJ1bm5pbmcKICogLSBzZWUgc2VuZF9vc19zdGF0ZSgpIC0gdGhlIHNlcnZpY2UgcHJvY2Vzc29yIHNlbmRzIHBlcmlvZGljIGhlYXJ0YmVhdHMKICogdG8gdGhlIGRyaXZlci4gVGhlIGRyaXZlciBtdXN0IHJlc3BvbmQgdG8gdGhlIGhlYXJ0YmVhdHMgb3IgZWxzZSB0aGUgT1MKICogd2lsbCBiZSByZWJvb3RlZC4KICogSW4gdGhlIGNhc2Ugb2YgYSBwYW5pYyB0aGUgaW50ZXJydXB0IGhhbmRsZXIgY29udGludWVzIHRvIHdvcmsgYW5kIHRodXMKICogY29udGludWVzIHRvIHJlc3BvbmQgdG8gaGVhcnRiZWF0cywgbWFraW5nIHRoZSBzZXJ2aWNlIHByb2Nlc3NvciBiZWxpZXZlCiAqIHRoZSBPUyBpcyBzdGlsbCBydW5uaW5nIGFuZCB0aHVzIHByZXZlbnRpbmcgYSByZWJvb3QuCiAqIFRvIHByZXZlbnQgdGhpcyBmcm9tIGhhcHBlbmluZyBhIGNhbGxiYWNrIGlzIGFkZGVkIHRoZSBwYW5pY19ub3RpZmllcl9saXN0LgogKiBCZWZvcmUgcmVzcG9uZGluZyB0byBhIGhlYXJ0YmVhdCB0aGUgZHJpdmVyIGNoZWNrcyBpZiBhIHBhbmljIGhhcyBoYXBwZW5lZCwKICogaWYgeWVzIGl0IHN1c3BlbmRzIGhlYXJ0YmVhdCwgY2F1c2luZyB0aGUgc2VydmljZSBwcm9jZXNzb3IgdG8gcmVib290IGFzCiAqIGV4cGVjdGVkLgogKi8Kc3RhdGljIGludCBwYW5pY19oYXBwZW5lZChzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm4sIHVuc2lnbmVkIGxvbmcgdmFsLCB2b2lkICp2KQp7CglzdXNwZW5kX2hlYXJ0YmVhdHMgPSAxOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgcGFuaWNfbm90aWZpZXIgPSB7IHBhbmljX2hhcHBlbmVkLCBOVUxMLCAxIH07Cgp2b2lkIGlibWFzbV9yZWdpc3Rlcl9wYW5pY19ub3RpZmllcih2b2lkKQp7CglhdG9taWNfbm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIoJnBhbmljX25vdGlmaWVyX2xpc3QsICZwYW5pY19ub3RpZmllcik7Cn0KCnZvaWQgaWJtYXNtX3VucmVnaXN0ZXJfcGFuaWNfbm90aWZpZXIodm9pZCkKewoJYXRvbWljX25vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIoJnBhbmljX25vdGlmaWVyX2xpc3QsCgkJCSZwYW5pY19ub3RpZmllcik7Cn0KCgppbnQgaWJtYXNtX2hlYXJ0YmVhdF9pbml0KHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCXNwLT5oZWFydGJlYXQgPSBpYm1hc21fbmV3X2NvbW1hbmQoc3AsIEhFQVJUQkVBVF9CVUZGRVJfU0laRSk7CglpZiAoc3AtPmhlYXJ0YmVhdCA9PSBOVUxMKQoJCXJldHVybiAtRU5PTUVNOwoKCXJldHVybiAwOwp9Cgp2b2lkIGlibWFzbV9oZWFydGJlYXRfZXhpdChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwKQp7CgljaGFyIHRzYnVmWzMyXTsKCglkYmcoIiVzOiVkIGF0ICVzXG4iLCBfX2Z1bmNfXywgX19MSU5FX18sIGdldF90aW1lc3RhbXAodHNidWYpKTsKCWlibWFzbV93YWl0X2Zvcl9yZXNwb25zZShzcC0+aGVhcnRiZWF0LCBJQk1BU01fQ01EX1RJTUVPVVRfTk9STUFMKTsKCWRiZygiJXM6JWQgYXQgJXNcbiIsIF9fZnVuY19fLCBfX0xJTkVfXywgZ2V0X3RpbWVzdGFtcCh0c2J1ZikpOwoJc3VzcGVuZF9oZWFydGJlYXRzID0gMTsKCWNvbW1hbmRfcHV0KHNwLT5oZWFydGJlYXQpOwp9Cgp2b2lkIGlibWFzbV9yZWNlaXZlX2hlYXJ0YmVhdChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCAgdm9pZCAqbWVzc2FnZSwgc2l6ZV90IHNpemUpCnsKCXN0cnVjdCBjb21tYW5kICpjbWQgPSBzcC0+aGVhcnRiZWF0OwoJc3RydWN0IGRvdF9jb21tYW5kX2hlYWRlciAqaGVhZGVyID0gKHN0cnVjdCBkb3RfY29tbWFuZF9oZWFkZXIgKiljbWQtPmJ1ZmZlcjsKCWNoYXIgdHNidWZbMzJdOwoKCWRiZygiJXM6JWQgYXQgJXNcbiIsIF9fZnVuY19fLCBfX0xJTkVfXywgZ2V0X3RpbWVzdGFtcCh0c2J1ZikpOwoJaWYgKHN1c3BlbmRfaGVhcnRiZWF0cykKCQlyZXR1cm47CgoJLyogcmV0dXJuIHRoZSByZWNlaXZlZCBkb3QgY29tbWFuZCB0byBzZW5kZXIgKi8KCWNtZC0+c3RhdHVzID0gSUJNQVNNX0NNRF9QRU5ESU5HOwoJc2l6ZSA9IG1pbihzaXplLCBjbWQtPmJ1ZmZlcl9zaXplKTsKCW1lbWNweV9mcm9taW8oY21kLT5idWZmZXIsIG1lc3NhZ2UsIHNpemUpOwoJaGVhZGVyLT50eXBlID0gc3Bfd3JpdGU7CglpYm1hc21fZXhlY19jb21tYW5kKHNwLCBjbWQpOwp9Cg==