Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4KICoKICovCgojaW5jbHVkZSAiaWJtYXNtLmgiCiNpbmNsdWRlICJsb3dsZXZlbC5oIgoKLyoKICogQVNNIHNlcnZpY2UgcHJvY2Vzc29yIGV2ZW50IGhhbmRsaW5nIHJvdXRpbmVzLgogKgogKiBFdmVudHMgYXJlIHNpZ25hbGxlZCB0byB0aGUgZGV2aWNlIGRyaXZlcnMgdGhyb3VnaCBpbnRlcnJ1cHRzLgogKiBUaGV5IGhhdmUgdGhlIGZvcm1hdCBvZiBkb3QgY29tbWFuZHMsIHdpdGggdGhlIHR5cGUgZmllbGQgc2V0IHRvCiAqIHNwX2V2ZW50LgogKiBUaGUgZHJpdmVyIGRvZXMgbm90IGludGVycHJldCB0aGUgZXZlbnRzLCBpdCBzaW1wbHkgc3RvcmVzIHRoZW0gaW4gYQogKiBjaXJjdWxhciBidWZmZXIuCiAqLwoKc3RhdGljIHZvaWQgd2FrZV91cF9ldmVudF9yZWFkZXJzKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCXN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlcjsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHJlYWRlciwgJnNwLT5ldmVudF9idWZmZXItPnJlYWRlcnMsIG5vZGUpCiAgICAgICAgICAgICAgICB3YWtlX3VwX2ludGVycnVwdGlibGUoJnJlYWRlci0+d2FpdCk7Cn0KCi8qKgogKiByZWNlaXZlX2V2ZW50CiAqIENhbGxlZCBieSB0aGUgaW50ZXJydXB0IGhhbmRsZXIgd2hlbiBhIGRvdCBjb21tYW5kIG9mIHR5cGUgc3BfZXZlbnQgaXMKICogcmVjZWl2ZWQuCiAqIFN0b3JlIHRoZSBldmVudCBpbiB0aGUgY2lyY3VsYXIgZXZlbnQgYnVmZmVyLCB3YWtlIHVwIGFueSBzbGVlcGluZwogKiBldmVudCByZWFkZXJzLgogKiBUaGVyZSBpcyBubyByZWFkZXIgbWFya2VyIGluIHRoZSBidWZmZXIsIHRoZXJlZm9yZSByZWFkZXJzIGFyZQogKiByZXNwb25zaWJsZSBmb3Iga2VlcGluZyB1cCB3aXRoIHRoZSB3cml0ZXIsIG9yIHRoZXkgd2lsbCBsb29zZSBldmVudHMuCiAqLwp2b2lkIGlibWFzbV9yZWNlaXZlX2V2ZW50KHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHZvaWQgKmRhdGEsIHVuc2lnbmVkIGludCBkYXRhX3NpemUpCnsKCXN0cnVjdCBldmVudF9idWZmZXIgKmJ1ZmZlciA9IHNwLT5ldmVudF9idWZmZXI7CglzdHJ1Y3QgaWJtYXNtX2V2ZW50ICpldmVudDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJZGF0YV9zaXplID0gbWluKGRhdGFfc2l6ZSwgSUJNQVNNX0VWRU5UX01BWF9TSVpFKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCS8qIGNvcHkgdGhlIGV2ZW50IGludG8gdGhlIG5leHQgc2xvdCBpbiB0aGUgY2lyY3VsYXIgYnVmZmVyICovCglldmVudCA9ICZidWZmZXItPmV2ZW50c1tidWZmZXItPm5leHRfaW5kZXhdOwoJbWVtY3B5X2Zyb21pbyhldmVudC0+ZGF0YSwgZGF0YSwgZGF0YV9zaXplKTsKCWV2ZW50LT5kYXRhX3NpemUgPSBkYXRhX3NpemU7CglldmVudC0+c2VyaWFsX251bWJlciA9IGJ1ZmZlci0+bmV4dF9zZXJpYWxfbnVtYmVyOwoKCS8qIGFkdmFuY2UgaW5kaWNlcyBpbiB0aGUgYnVmZmVyICovCglidWZmZXItPm5leHRfaW5kZXggPSAoYnVmZmVyLT5uZXh0X2luZGV4ICsgMSkgJSBJQk1BU01fTlVNX0VWRU5UUzsKCWJ1ZmZlci0+bmV4dF9zZXJpYWxfbnVtYmVyKys7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzcC0+bG9jaywgZmxhZ3MpOwoKCXdha2VfdXBfZXZlbnRfcmVhZGVycyhzcCk7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IGV2ZW50X2F2YWlsYWJsZShzdHJ1Y3QgZXZlbnRfYnVmZmVyICpiLCBzdHJ1Y3QgZXZlbnRfcmVhZGVyICpyKQp7CglyZXR1cm4gKHItPm5leHRfc2VyaWFsX251bWJlciA8IGItPm5leHRfc2VyaWFsX251bWJlcik7Cn0KCi8qKgogKiBnZXRfbmV4dF9ldmVudAogKiBDYWxsZWQgYnkgZXZlbnQgcmVhZGVycyAoaW5pdGlhdGVkIGZyb20gdXNlciBzcGFjZSB0aHJvdWdoIHRoZSBmaWxlCiAqIHN5c3RlbSkuCiAqIFNsZWVwcyB1bnRpbCBhIG5ldyBldmVudCBpcyBhdmFpbGFibGUuCiAqLwppbnQgaWJtYXNtX2dldF9uZXh0X2V2ZW50KHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlcikKewoJc3RydWN0IGV2ZW50X2J1ZmZlciAqYnVmZmVyID0gc3AtPmV2ZW50X2J1ZmZlcjsKCXN0cnVjdCBpYm1hc21fZXZlbnQgKmV2ZW50OwoJdW5zaWduZWQgaW50IGluZGV4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglyZWFkZXItPmNhbmNlbGxlZCA9IDA7CgoJaWYgKHdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZShyZWFkZXItPndhaXQsCgkJCWV2ZW50X2F2YWlsYWJsZShidWZmZXIsIHJlYWRlcikgfHwgcmVhZGVyLT5jYW5jZWxsZWQpKQoJCXJldHVybiAtRVJFU1RBUlRTWVM7CgoJaWYgKCFldmVudF9hdmFpbGFibGUoYnVmZmVyLCByZWFkZXIpKQoJCXJldHVybiAwOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZzcC0+bG9jaywgZmxhZ3MpOwoKCWluZGV4ID0gYnVmZmVyLT5uZXh0X2luZGV4OwoJZXZlbnQgPSAmYnVmZmVyLT5ldmVudHNbaW5kZXhdOwoJd2hpbGUgKGV2ZW50LT5zZXJpYWxfbnVtYmVyIDwgcmVhZGVyLT5uZXh0X3NlcmlhbF9udW1iZXIpIHsKCQlpbmRleCA9IChpbmRleCArIDEpICUgSUJNQVNNX05VTV9FVkVOVFM7CgkJZXZlbnQgPSAmYnVmZmVyLT5ldmVudHNbaW5kZXhdOwoJfQoJbWVtY3B5KHJlYWRlci0+ZGF0YSwgZXZlbnQtPmRhdGEsIGV2ZW50LT5kYXRhX3NpemUpOwoJcmVhZGVyLT5kYXRhX3NpemUgPSBldmVudC0+ZGF0YV9zaXplOwoJcmVhZGVyLT5uZXh0X3NlcmlhbF9udW1iZXIgPSBldmVudC0+c2VyaWFsX251bWJlciArIDE7CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKCglyZXR1cm4gZXZlbnQtPmRhdGFfc2l6ZTsKfQoKdm9pZCBpYm1hc21fY2FuY2VsX25leHRfZXZlbnQoc3RydWN0IGV2ZW50X3JlYWRlciAqcmVhZGVyKQp7CiAgICAgICAgcmVhZGVyLT5jYW5jZWxsZWQgPSAxOwogICAgICAgIHdha2VfdXBfaW50ZXJydXB0aWJsZSgmcmVhZGVyLT53YWl0KTsKfQoKdm9pZCBpYm1hc21fZXZlbnRfcmVhZGVyX3JlZ2lzdGVyKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlcikKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglyZWFkZXItPm5leHRfc2VyaWFsX251bWJlciA9IHNwLT5ldmVudF9idWZmZXItPm5leHRfc2VyaWFsX251bWJlcjsKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJnJlYWRlci0+d2FpdCk7CglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCWxpc3RfYWRkKCZyZWFkZXItPm5vZGUsICZzcC0+ZXZlbnRfYnVmZmVyLT5yZWFkZXJzKTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7Cn0KCnZvaWQgaWJtYXNtX2V2ZW50X3JlYWRlcl91bnJlZ2lzdGVyKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlcikKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCWxpc3RfZGVsKCZyZWFkZXItPm5vZGUpOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKfQoKaW50IGlibWFzbV9ldmVudF9idWZmZXJfaW5pdChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwKQp7CglzdHJ1Y3QgZXZlbnRfYnVmZmVyICpidWZmZXI7CglzdHJ1Y3QgaWJtYXNtX2V2ZW50ICpldmVudDsKCWludCBpOwoKCWJ1ZmZlciA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBldmVudF9idWZmZXIpLCBHRlBfS0VSTkVMKTsKCWlmICghYnVmZmVyKQoJCXJldHVybiAxOwoKCWJ1ZmZlci0+bmV4dF9pbmRleCA9IDA7CglidWZmZXItPm5leHRfc2VyaWFsX251bWJlciA9IDE7CgoJZXZlbnQgPSBidWZmZXItPmV2ZW50czsKCWZvciAoaT0wOyBpPElCTUFTTV9OVU1fRVZFTlRTOyBpKyssIGV2ZW50KyspCgkJZXZlbnQtPnNlcmlhbF9udW1iZXIgPSAwOwoKCUlOSVRfTElTVF9IRUFEKCZidWZmZXItPnJlYWRlcnMpOwoKCXNwLT5ldmVudF9idWZmZXIgPSBidWZmZXI7CgoJcmV0dXJuIDA7Cn0KCnZvaWQgaWJtYXNtX2V2ZW50X2J1ZmZlcl9leGl0KHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCWtmcmVlKHNwLT5ldmVudF9idWZmZXIpOwp9Cg==