LyogcGVyaW9kaWNfd29yay5jCiAqCiAqIENvcHlyaWdodCCpIDIwMTAgLSAyMDEzIFVOSVNZUyBDT1JQT1JBVElPTgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQKICogeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0CiAqIFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLCBHT09EIFRJVExFIG9yCiAqIE5PTiBJTkZSSU5HRU1FTlQuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCiAqIGRldGFpbHMuCiAqLwoKLyoKICogIEhlbHBlciBmdW5jdGlvbnMgdG8gc2NoZWR1bGUgcGVyaW9kaWMgd29yayBpbiBMaW51eCBrZXJuZWwgbW9kZS4KICovCgojaW5jbHVkZSAidW5pa2xvZy5oIgojaW5jbHVkZSAidGltc2ttb2QuaCIKI2luY2x1ZGUgInBlcmlvZGljX3dvcmsuaCIKCiNkZWZpbmUgTVlEUlZOQU1FICJwZXJpb2RpY193b3JrIgoKCgpzdHJ1Y3QgUEVSSU9ESUNfV09SS19UYWcgewoJcndsb2NrX3QgbG9jazsKCXN0cnVjdCBkZWxheWVkX3dvcmsgd29yazsKCXZvaWQgKCp3b3JrZnVuYykodm9pZCAqKTsKCXZvaWQgKndvcmtmdW5jYXJnOwoJQk9PTCBpc19zY2hlZHVsZWQ7CglCT09MIHdhbnRfdG9fc3RvcDsKCXVsb25nIGppZmZ5X2ludGVydmFsOwoJc3RydWN0IHdvcmtxdWV1ZV9zdHJ1Y3QgKndvcmtxdWV1ZTsKCWNvbnN0IGNoYXIgKmRldm5hbTsKfTsKCgoKc3RhdGljIHZvaWQgcGVyaW9kaWNfd29ya19mdW5jKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKewoJUEVSSU9ESUNfV09SSyAqcGVyaW9kaWNfd29yayA9CgkJY29udGFpbmVyX29mKHdvcmssIHN0cnVjdCBQRVJJT0RJQ19XT1JLX1RhZywgd29yay53b3JrKTsKCSgqcGVyaW9kaWNfd29yay0+d29ya2Z1bmMpKHBlcmlvZGljX3dvcmstPndvcmtmdW5jYXJnKTsKfQoKCgpQRVJJT0RJQ19XT1JLICp2aXNvcl9wZXJpb2RpY193b3JrX2NyZWF0ZSh1bG9uZyBqaWZmeV9pbnRlcnZhbCwKCQkJCQkgIHN0cnVjdCB3b3JrcXVldWVfc3RydWN0ICp3b3JrcXVldWUsCgkJCQkJICB2b2lkICgqd29ya2Z1bmMpKHZvaWQgKiksCgkJCQkJICB2b2lkICp3b3JrZnVuY2FyZywKCQkJCQkgIGNvbnN0IGNoYXIgKmRldm5hbSkKewoJUEVSSU9ESUNfV09SSyAqcGVyaW9kaWNfd29yayA9IGt6YWxsb2Moc2l6ZW9mKFBFUklPRElDX1dPUkspLAoJCQkJCSAgICAgICBHRlBfS0VSTkVMIHwgX19HRlBfTk9SRVRSWSk7CglpZiAocGVyaW9kaWNfd29yayA9PSBOVUxMKSB7CgkJRVJSRFJWKCJwZXJpb2RpY193b3JrIGFsbG9jYXRpb24gZmFpbGVkICIpOwoJCXJldHVybiBOVUxMOwoJfQoJcndsb2NrX2luaXQoJnBlcmlvZGljX3dvcmstPmxvY2spOwoJcGVyaW9kaWNfd29yay0+amlmZnlfaW50ZXJ2YWwgPSBqaWZmeV9pbnRlcnZhbDsKCXBlcmlvZGljX3dvcmstPndvcmtxdWV1ZSA9IHdvcmtxdWV1ZTsKCXBlcmlvZGljX3dvcmstPndvcmtmdW5jID0gd29ya2Z1bmM7CglwZXJpb2RpY193b3JrLT53b3JrZnVuY2FyZyA9IHdvcmtmdW5jYXJnOwoJcGVyaW9kaWNfd29yay0+ZGV2bmFtID0gZGV2bmFtOwoJcmV0dXJuIHBlcmlvZGljX3dvcms7Cn0KRVhQT1JUX1NZTUJPTF9HUEwodmlzb3JfcGVyaW9kaWNfd29ya19jcmVhdGUpOwoKCgp2b2lkIHZpc29yX3BlcmlvZGljX3dvcmtfZGVzdHJveShQRVJJT0RJQ19XT1JLICpwZXJpb2RpY193b3JrKQp7CglpZiAocGVyaW9kaWNfd29yayA9PSBOVUxMKQoJCXJldHVybjsKCWtmcmVlKHBlcmlvZGljX3dvcmspOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHZpc29yX3BlcmlvZGljX3dvcmtfZGVzdHJveSk7CgoKCi8qKiBDYWxsIHRoaXMgZnJvbSB5b3VyIHBlcmlvZGljIHdvcmsgd29ya2VyIGZ1bmN0aW9uIHRvIHNjaGVkdWxlIHRoZSBuZXh0CiAqICBjYWxsLgogKiAgSWYgdGhpcyBmdW5jdGlvbiByZXR1cm5zIEZBTFNFLCB0aGVyZSB3YXMgYSBmYWlsdXJlIGFuZCB0aGUKICogIHBlcmlvZGljIHdvcmsgaXMgbm8gbG9uZ2VyIHNjaGVkdWxlZAogKi8KQk9PTCB2aXNvcl9wZXJpb2RpY193b3JrX25leHRwZXJpb2QoUEVSSU9ESUNfV09SSyAqcGVyaW9kaWNfd29yaykKewoJQk9PTCByYyA9IEZBTFNFOwoJd3JpdGVfbG9jaygmcGVyaW9kaWNfd29yay0+bG9jayk7CglpZiAocGVyaW9kaWNfd29yay0+d2FudF90b19zdG9wKSB7CgkJcGVyaW9kaWNfd29yay0+aXNfc2NoZWR1bGVkID0gRkFMU0U7CgkJcGVyaW9kaWNfd29yay0+d2FudF90b19zdG9wID0gRkFMU0U7CgkJcmMgPSBUUlVFOyAgLyogeWVzLCBUUlVFOyBzZWUgdmlzb3JfcGVyaW9kaWNfd29ya19zdG9wKCkgKi8KCQlnb3RvIEF3YXk7Cgl9IGVsc2UgaWYgKHF1ZXVlX2RlbGF5ZWRfd29yayhwZXJpb2RpY193b3JrLT53b3JrcXVldWUsCgkJCQkgICAgICAmcGVyaW9kaWNfd29yay0+d29yaywKCQkJCSAgICAgIHBlcmlvZGljX3dvcmstPmppZmZ5X2ludGVydmFsKSA8IDApIHsKCQlFUlJERVYocGVyaW9kaWNfd29yay0+ZGV2bmFtLCAicXVldWVfZGVsYXllZF93b3JrIGZhaWxlZCEiKTsKCQlwZXJpb2RpY193b3JrLT5pc19zY2hlZHVsZWQgPSBGQUxTRTsKCQlyYyA9IEZBTFNFOwoJCWdvdG8gQXdheTsKCX0KCXJjID0gVFJVRTsKQXdheToKCXdyaXRlX3VubG9jaygmcGVyaW9kaWNfd29yay0+bG9jayk7CglyZXR1cm4gcmM7Cn0KRVhQT1JUX1NZTUJPTF9HUEwodmlzb3JfcGVyaW9kaWNfd29ya19uZXh0cGVyaW9kKTsKCgoKLyoqIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmZiBuZXcgcGVyaW9kaWMgd29yayB3YXMgYWN0dWFsbHkgc3RhcnRlZC4KICogIElmIHRoaXMgZnVuY3Rpb24gcmV0dXJucyBGQUxTRSwgdGhlbiBubyB3b3JrIHdhcyBzdGFydGVkCiAqICAoZWl0aGVyIGJlY2F1c2UgaXQgd2FzIGFscmVhZHkgc3RhcnRlZCwgb3IgYmVjYXVzZSBvZiBhIGZhaWx1cmUpLgogKi8KQk9PTCB2aXNvcl9wZXJpb2RpY193b3JrX3N0YXJ0KFBFUklPRElDX1dPUksgKnBlcmlvZGljX3dvcmspCnsKCUJPT0wgcmMgPSBGQUxTRTsKCgl3cml0ZV9sb2NrKCZwZXJpb2RpY193b3JrLT5sb2NrKTsKCWlmIChwZXJpb2RpY193b3JrLT5pc19zY2hlZHVsZWQpIHsKCQlyYyA9IEZBTFNFOwoJCWdvdG8gQXdheTsKCX0KCWlmIChwZXJpb2RpY193b3JrLT53YW50X3RvX3N0b3ApIHsKCQlFUlJERVYocGVyaW9kaWNfd29yay0+ZGV2bmFtLAoJCSAgICAgICAiZGV2X3N0YXJ0X3BlcmlvZGljX3dvcmsgZmFpbGVkISIpOwoJCXJjID0gRkFMU0U7CgkJZ290byBBd2F5OwoJfQoJSU5JVF9ERUxBWUVEX1dPUksoJnBlcmlvZGljX3dvcmstPndvcmssICZwZXJpb2RpY193b3JrX2Z1bmMpOwoJaWYgKHF1ZXVlX2RlbGF5ZWRfd29yayhwZXJpb2RpY193b3JrLT53b3JrcXVldWUsCgkJCSAgICAgICAmcGVyaW9kaWNfd29yay0+d29yaywKCQkJICAgICAgIHBlcmlvZGljX3dvcmstPmppZmZ5X2ludGVydmFsKSA8IDApIHsKCQlFUlJERVYocGVyaW9kaWNfd29yay0+ZGV2bmFtLAoJCSAgICAgICAiJXMgcXVldWVfZGVsYXllZF93b3JrIGZhaWxlZCEiLCBfX2Z1bmNfXyk7CgkJcmMgPSBGQUxTRTsKCQlnb3RvIEF3YXk7Cgl9CglwZXJpb2RpY193b3JrLT5pc19zY2hlZHVsZWQgPSBUUlVFOwoJcmMgPSBUUlVFOwpBd2F5OgoJd3JpdGVfdW5sb2NrKCZwZXJpb2RpY193b3JrLT5sb2NrKTsKCXJldHVybiByYzsKCn0KRVhQT1JUX1NZTUJPTF9HUEwodmlzb3JfcGVyaW9kaWNfd29ya19zdGFydCk7CgoKCgovKiogVGhpcyBmdW5jdGlvbiByZXR1cm5zIFRSVUUgaWZmIHlvdXIgY2FsbCBhY3R1YWxseSBzdG9wcGVkIHRoZSBwZXJpb2RpYwogKiAgd29yay4KICoKICogIC0tIFBBWSBBVFRFTlRJT04uLi4gdGhpcyBpcyBpbXBvcnRhbnQgLS0KICoKICogIE5PIE5PICMxCiAqCiAqICAgICBEbyBOT1QgY2FsbCB0aGlzIGZ1bmN0aW9uIGZyb20gc29tZSBmdW5jdGlvbiB0aGF0IGlzIHJ1bm5pbmcgb24gdGhlCiAqICAgICBzYW1lIHdvcmtxdWV1ZSBhcyB0aGUgd29yayB5b3UgYXJlIHRyeWluZyB0byBzdG9wIG1pZ2h0IGJlIHJ1bm5pbmcKICogICAgIG9uISAgSWYgeW91IHZpb2xhdGUgdGhpcyBydWxlLCB2aXNvcl9wZXJpb2RpY193b3JrX3N0b3AoKSBNSUdIVCB3b3JrLAogKiAgICAgYnV0IGl0IGFsc28gTUlHSFQgZ2V0IGh1bmcgdXAgaW4gYW4gaW5maW5pdGUgbG9vcCBzYXlpbmcKICogICAgICJ3YWl0aW5nIGZvciBkZWxheWVkIHdvcmsuLi4iLiAgVGhpcyB3aWxsIGhhcHBlbiBpZiB0aGUgZGVsYXllZCB3b3JrCiAqICAgICB5b3UgYXJlIHRyeWluZyB0byBjYW5jZWwgaGFzIGJlZW4gcHV0IGluIHRoZSB3b3JrcXVldWUgbGlzdCwgYnV0IGNhbid0CiAqICAgICBydW4geWV0IGJlY2F1c2Ugd2UgYXJlIHJ1bm5pbmcgdGhhdCBzYW1lIHdvcmtxdWV1ZSB0aHJlYWQgcmlnaHQgbm93LgogKgogKiAgICAgQm90dG9tIGxpbmU6IElmIHlvdSBuZWVkIHRvIGNhbGwgdmlzb3JfcGVyaW9kaWNfd29ya19zdG9wKCkgZnJvbSBhCiAqICAgICB3b3JraXRlbSwgYmUgc3VyZSB0aGUgd29ya2l0ZW0gaXMgb24gYSBESUZGRVJFTlQgd29ya3F1ZXVlIHRoYW4gdGhlCiAqICAgICB3b3JraXRlbSB0aGF0IHlvdSBhcmUgdHJ5aW5nIHRvIGNhbmNlbC4KICoKICogICAgIElmIEkgY291bGQgZmlndXJlIG91dCBzb21lIHdheSB0byBjaGVjayBmb3IgdGhpcyAibm8gbm8iIGNvbmRpdGlvbiBpbgogKiAgICAgdGhlIGNvZGUsIEkgd291bGQuICBJdCB3b3VsZCBoYXZlIHNhdmVkIG1lIHRoZSB0cm91YmxlIG9mIHdyaXRpbmcgdGhpcwogKiAgICAgbG9uZyBjb21tZW50LiAgQW5kIGFsc28sIGRvbid0IHRoaW5rIHRoaXMgaXMgc29tZSAidGhlb3JldGljYWwiIHJhY2UKICogICAgIGNvbmRpdGlvbi4gIEl0IGlzIFJFQUwsIGFzIEkgaGF2ZSBzcGVudCB0aGUgZGF5IGNoYXNpbmcgaXQuCiAqCiAqICBOTyBOTyAjMgogKgogKiAgICAgVGFrZSBjbG9zZSBub3RlIG9mIHRoZSBsb2NrcyB0aGF0IHlvdSBvd24gd2hlbiB5b3UgY2FsbCB0aGlzIGZ1bmN0aW9uLgogKiAgICAgWW91IG11c3QgTk9UIG93biBhbnkgbG9ja3MgdGhhdCBhcmUgbmVlZGVkIGJ5IHRoZSBwZXJpb2RpYyB3b3JrCiAqICAgICBmdW5jdGlvbiB0aGF0IGlzIGN1cnJlbnRseSBpbnN0YWxsZWQuICBJZiB5b3UgRE8sIGEgZGVhZGxvY2sgbWF5IHJlc3VsdCwKICogICAgIGJlY2F1c2Ugc3RvcHBpbmcgdGhlIHBlcmlvZGljIHdvcmsgb2Z0ZW4gaW52b2x2ZXMgd2FpdGluZyBmb3IgdGhlIGxhc3QKICogICAgIGl0ZXJhdGlvbiBvZiB0aGUgcGVyaW9kaWMgd29yayBmdW5jdGlvbiB0byBjb21wbGV0ZS4gIEFnYWluLCBpZiB5b3UgaGl0CiAqICAgICB0aGlzIGRlYWRsb2NrLCB5b3Ugd2lsbCBnZXQgaHVuZyB1cCBpbiBhbiBpbmZpbml0ZSBsb29wIHNheWluZwogKiAgICAgIndhaXRpbmcgZm9yIGRlbGF5ZWQgd29yay4uLiIuCiAqLwpCT09MIHZpc29yX3BlcmlvZGljX3dvcmtfc3RvcChQRVJJT0RJQ19XT1JLICpwZXJpb2RpY193b3JrKQp7CglCT09MIHN0b3BwZWRfc29tZXRoaW5nID0gRkFMU0U7CgoJd3JpdGVfbG9jaygmcGVyaW9kaWNfd29yay0+bG9jayk7CglzdG9wcGVkX3NvbWV0aGluZyA9IHBlcmlvZGljX3dvcmstPmlzX3NjaGVkdWxlZCAmJgoJCSghcGVyaW9kaWNfd29yay0+d2FudF90b19zdG9wKTsKCXdoaWxlIChwZXJpb2RpY193b3JrLT5pc19zY2hlZHVsZWQpIHsKCQlwZXJpb2RpY193b3JrLT53YW50X3RvX3N0b3AgPSBUUlVFOwoJCWlmIChjYW5jZWxfZGVsYXllZF93b3JrKCZwZXJpb2RpY193b3JrLT53b3JrKSkgewoJCQkvKiBXZSBnZXQgaGVyZSBpZiB0aGUgZGVsYXllZCB3b3JrIHdhcyBwZW5kaW5nIGFzCgkJCSAqIGRlbGF5ZWQgd29yaywgYnV0IHdhcyBOT1QgcnVuLgoJCQkgKi8KCQkJQVNTRVJUKHBlcmlvZGljX3dvcmstPmlzX3NjaGVkdWxlZCk7CgkJCXBlcmlvZGljX3dvcmstPmlzX3NjaGVkdWxlZCA9IEZBTFNFOwoJCX0gZWxzZSB7CgkJCS8qIElmIHdlIGdldCBoZXJlLCBlaXRoZXIgdGhlIGRlbGF5ZWQgd29yazoKCQkJICogLSB3YXMgcnVuLCBPUiwKCQkJICogLSBpcyBydW5uaW5nIFJJR0hUIE5PVyBvbiBhbm90aGVyIHByb2Nlc3NvciwgT1IsCgkJCSAqIC0gd2Fzbid0IGV2ZW4gc2NoZWR1bGVkICh0aGVyZSBpcyBhIG1pbmlzY3VsZQoJCQkgKiAgIHRpbWluZyB3aW5kb3cgd2hlcmUgdGhpcyBjb3VsZCBiZSB0aGUgY2FzZSkKCQkJICogZmx1c2hfd29ya3F1ZXVlKCkgd291bGQgbWFrZSBzdXJlIGl0IGlzIGZpbmlzaGVkCgkJCSAqIGV4ZWN1dGluZywgYnV0IHRoYXQgc3RpbGwgaXNuJ3QgdmVyeSB1c2VmdWwsIHdoaWNoCgkJCSAqIGV4cGxhaW5zIHRoZSBsb29wLi4uCgkJCSAqLwoJCX0KCQlpZiAocGVyaW9kaWNfd29yay0+aXNfc2NoZWR1bGVkKSB7CgkJCXdyaXRlX3VubG9jaygmcGVyaW9kaWNfd29yay0+bG9jayk7CgkJCVdBUk5ERVYocGVyaW9kaWNfd29yay0+ZGV2bmFtLAoJCQkJIndhaXRpbmcgZm9yIGRlbGF5ZWQgd29yay4uLiIpOwoJCQkvKiBXZSByZWx5IG9uIHRoZSBkZWxheWVkIHdvcmsgZnVuY3Rpb24gcnVubmluZyBoZXJlLAoJCQkgKiBhbmQgZXZlbnR1YWxseSBjYWxsaW5nCgkJCSAqIHZpc29yX3BlcmlvZGljX3dvcmtfbmV4dHBlcmlvZCgpLAoJCQkgKiB3aGljaCB3aWxsIHNlZSB0aGF0IHdhbnRfdG9fc3RvcCBpcyBzZXQsIGFuZAoJCQkgKiBzdWJzZXF1ZW50bHkgY2xlYXIgaXNfc2NoZWR1bGVkLgoJCQkgKi8KCQkJU0xFRVBKSUZGSUVTKDEwKTsKCQkJd3JpdGVfbG9jaygmcGVyaW9kaWNfd29yay0+bG9jayk7CgkJfSBlbHNlCgkJCXBlcmlvZGljX3dvcmstPndhbnRfdG9fc3RvcCA9IEZBTFNFOwoJfQoJd3JpdGVfdW5sb2NrKCZwZXJpb2RpY193b3JrLT5sb2NrKTsKCXJldHVybiBzdG9wcGVkX3NvbWV0aGluZzsKfQpFWFBPUlRfU1lNQk9MX0dQTCh2aXNvcl9wZXJpb2RpY193b3JrX3N0b3ApOwo=