LyoKICogRmFzdCBXZWlnaHRlZCBSb3VuZCBSb2JpbiBsb2FkIGJhbGFuY2luZyBhbGdvcml0aG0uCiAqCiAqIENvcHlyaWdodCAyMDAwLTIwMDkgV2lsbHkgVGFycmVhdSA8d0Axd3QuZXU+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uCiAqIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi9jb21wYXQuaD4KI2luY2x1ZGUgPGNvbW1vbi9jb25maWcuaD4KI2luY2x1ZGUgPGNvbW1vbi9kZWJ1Zy5oPgojaW5jbHVkZSA8ZWIzMnRyZWUuaD4KCiNpbmNsdWRlIDx0eXBlcy9nbG9iYWwuaD4KI2luY2x1ZGUgPHR5cGVzL3NlcnZlci5oPgoKI2luY2x1ZGUgPHByb3RvL2JhY2tlbmQuaD4KI2luY2x1ZGUgPHByb3RvL3F1ZXVlLmg+CgpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9yZW1vdmVfZnJvbV90cmVlKHN0cnVjdCBzZXJ2ZXIgKnMpOwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9xdWV1ZV9ieV93ZWlnaHQoc3RydWN0IGViX3Jvb3QgKnJvb3QsIHN0cnVjdCBzZXJ2ZXIgKnMpOwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9kZXF1ZXVlX3NydihzdHJ1Y3Qgc2VydmVyICpzKTsKc3RhdGljIHZvaWQgZndycl9nZXRfc3J2KHN0cnVjdCBzZXJ2ZXIgKnMpOwpzdGF0aWMgdm9pZCBmd3JyX3F1ZXVlX3NydihzdHJ1Y3Qgc2VydmVyICpzKTsKCgovKiBUaGlzIGZ1bmN0aW9uIHVwZGF0ZXMgdGhlIHNlcnZlciB0cmVlcyBhY2NvcmRpbmcgdG8gc2VydmVyIDxzcnY+J3MgbmV3CiAqIHN0YXRlLiBJdCBzaG91bGQgYmUgY2FsbGVkIHdoZW4gc2VydmVyIDxzcnY+J3Mgc3RhdHVzIGNoYW5nZXMgdG8gZG93bi4KICogSXQgaXMgbm90IGltcG9ydGFudCB3aGV0aGVyIHRoZSBzZXJ2ZXIgd2FzIGFscmVhZHkgZG93biBvciBub3QuIEl0IGlzIG5vdAogKiBpbXBvcnRhbnQgZWl0aGVyIHRoYXQgdGhlIG5ldyBzdGF0ZSBpcyBjb21wbGV0ZWx5IGRvd24gKHRoZSBjYWxsZXIgbWF5IG5vdAogKiBrbm93IGFsbCB0aGUgdmFyaWFibGVzIG9mIGEgc2VydmVyJ3Mgc3RhdGUpLgogKi8Kc3RhdGljIHZvaWQgZndycl9zZXRfc2VydmVyX3N0YXR1c19kb3duKHN0cnVjdCBzZXJ2ZXIgKnNydikKewoJc3RydWN0IHByb3h5ICpwID0gc3J2LT5wcm94eTsKCXN0cnVjdCBmd3JyX2dyb3VwICpncnA7CgoJaWYgKHNydi0+c3RhdGUgPT0gc3J2LT5wcmV2X3N0YXRlICYmCgkgICAgc3J2LT5ld2VpZ2h0ID09IHNydi0+cHJldl9ld2VpZ2h0KQoJCXJldHVybjsKCglpZiAoc3J2X2lzX3VzYWJsZShzcnYtPnN0YXRlLCBzcnYtPmV3ZWlnaHQpKQoJCWdvdG8gb3V0X3VwZGF0ZV9zdGF0ZTsKCglpZiAoIXNydl9pc191c2FibGUoc3J2LT5wcmV2X3N0YXRlLCBzcnYtPnByZXZfZXdlaWdodCkpCgkJLyogc2VydmVyIHdhcyBhbHJlYWR5IGRvd24gKi8KCQlnb3RvIG91dF91cGRhdGVfYmFja2VuZDsKCglncnAgPSAoc3J2LT5zdGF0ZSAmIFNSVl9CQUNLVVApID8gJnAtPmxicHJtLmZ3cnIuYmNrIDogJnAtPmxicHJtLmZ3cnIuYWN0OwoJZ3JwLT5uZXh0X3dlaWdodCAtPSBzcnYtPnByZXZfZXdlaWdodDsKCglpZiAoc3J2LT5zdGF0ZSAmIFNSVl9CQUNLVVApIHsKCQlwLT5sYnBybS50b3Rfd2JjayA9IHAtPmxicHJtLmZ3cnIuYmNrLm5leHRfd2VpZ2h0OwoJCXAtPnNydl9iY2stLTsKCgkJaWYgKHNydiA9PSBwLT5sYnBybS5mYmNrKSB7CgkJCS8qIHdlIGxvc3QgdGhlIGZpcnN0IGJhY2t1cCBzZXJ2ZXIgaW4gYSBzaW5nbGUtYmFja3VwCgkJCSAqIGNvbmZpZ3VyYXRpb24sIHdlIG11c3Qgc2VhcmNoIGFub3RoZXIgb25lLgoJCQkgKi8KCQkJc3RydWN0IHNlcnZlciAqc3J2MiA9IHAtPmxicHJtLmZiY2s7CgkJCWRvIHsKCQkJCXNydjIgPSBzcnYyLT5uZXh0OwoJCQl9IHdoaWxlIChzcnYyICYmCgkJCQkgISgoc3J2Mi0+c3RhdGUgJiBTUlZfQkFDS1VQKSAmJgoJCQkJICAgc3J2X2lzX3VzYWJsZShzcnYyLT5zdGF0ZSwgc3J2Mi0+ZXdlaWdodCkpKTsKCQkJcC0+bGJwcm0uZmJjayA9IHNydjI7CgkJfQoJfSBlbHNlIHsKCQlwLT5sYnBybS50b3Rfd2FjdCA9IHAtPmxicHJtLmZ3cnIuYWN0Lm5leHRfd2VpZ2h0OwoJCXAtPnNydl9hY3QtLTsKCX0KCglmd3JyX2RlcXVldWVfc3J2KHNydik7Cglmd3JyX3JlbW92ZV9mcm9tX3RyZWUoc3J2KTsKCm91dF91cGRhdGVfYmFja2VuZDoKCS8qIGNoZWNrL3VwZGF0ZSB0b3RfdXNlZCwgdG90X3dlaWdodCAqLwoJdXBkYXRlX2JhY2tlbmRfd2VpZ2h0KHApOwogb3V0X3VwZGF0ZV9zdGF0ZToKCXNydi0+cHJldl9zdGF0ZSA9IHNydi0+c3RhdGU7CglzcnYtPnByZXZfZXdlaWdodCA9IHNydi0+ZXdlaWdodDsKfQoKLyogVGhpcyBmdW5jdGlvbiB1cGRhdGVzIHRoZSBzZXJ2ZXIgdHJlZXMgYWNjb3JkaW5nIHRvIHNlcnZlciA8c3J2PidzIG5ldwogKiBzdGF0ZS4gSXQgc2hvdWxkIGJlIGNhbGxlZCB3aGVuIHNlcnZlciA8c3J2PidzIHN0YXR1cyBjaGFuZ2VzIHRvIHVwLgogKiBJdCBpcyBub3QgaW1wb3J0YW50IHdoZXRoZXIgdGhlIHNlcnZlciB3YXMgYWxyZWFkeSBkb3duIG9yIG5vdC4gSXQgaXMgbm90CiAqIGltcG9ydGFudCBlaXRoZXIgdGhhdCB0aGUgbmV3IHN0YXRlIGlzIGNvbXBsZXRlbHkgVVAgKHRoZSBjYWxsZXIgbWF5IG5vdAogKiBrbm93IGFsbCB0aGUgdmFyaWFibGVzIG9mIGEgc2VydmVyJ3Mgc3RhdGUpLiBUaGlzIGZ1bmN0aW9uIHdpbGwgbm90IGNoYW5nZQogKiB0aGUgd2VpZ2h0IG9mIGEgc2VydmVyIHdoaWNoIHdhcyBhbHJlYWR5IHVwLgogKi8Kc3RhdGljIHZvaWQgZndycl9zZXRfc2VydmVyX3N0YXR1c191cChzdHJ1Y3Qgc2VydmVyICpzcnYpCnsKCXN0cnVjdCBwcm94eSAqcCA9IHNydi0+cHJveHk7CglzdHJ1Y3QgZndycl9ncm91cCAqZ3JwOwoKCWlmIChzcnYtPnN0YXRlID09IHNydi0+cHJldl9zdGF0ZSAmJgoJICAgIHNydi0+ZXdlaWdodCA9PSBzcnYtPnByZXZfZXdlaWdodCkKCQlyZXR1cm47CgoJaWYgKCFzcnZfaXNfdXNhYmxlKHNydi0+c3RhdGUsIHNydi0+ZXdlaWdodCkpCgkJZ290byBvdXRfdXBkYXRlX3N0YXRlOwoKCWlmIChzcnZfaXNfdXNhYmxlKHNydi0+cHJldl9zdGF0ZSwgc3J2LT5wcmV2X2V3ZWlnaHQpKQoJCS8qIHNlcnZlciB3YXMgYWxyZWFkeSB1cCAqLwoJCWdvdG8gb3V0X3VwZGF0ZV9iYWNrZW5kOwoKCWdycCA9IChzcnYtPnN0YXRlICYgU1JWX0JBQ0tVUCkgPyAmcC0+bGJwcm0uZndyci5iY2sgOiAmcC0+bGJwcm0uZndyci5hY3Q7CglncnAtPm5leHRfd2VpZ2h0ICs9IHNydi0+ZXdlaWdodDsKCglpZiAoc3J2LT5zdGF0ZSAmIFNSVl9CQUNLVVApIHsKCQlwLT5sYnBybS50b3Rfd2JjayA9IHAtPmxicHJtLmZ3cnIuYmNrLm5leHRfd2VpZ2h0OwoJCXAtPnNydl9iY2srKzsKCgkJaWYgKCEocC0+b3B0aW9ucyAmIFBSX09fVVNFX0FMTF9CSykpIHsKCQkJaWYgKCFwLT5sYnBybS5mYmNrKSB7CgkJCQkvKiB0aGVyZSB3YXMgbm8gYmFja3VwIHNlcnZlciBhbnltb3JlICovCgkJCQlwLT5sYnBybS5mYmNrID0gc3J2OwoJCQl9IGVsc2UgewoJCQkJLyogd2UgbWF5IGhhdmUgcmVzdG9yZWQgYSBiYWNrdXAgc2VydmVyIHByaW9yIHRvIGZiY2ssCgkJCQkgKiBpbiB3aGljaCBjYXNlIGl0IHNob3VsZCByZXBsYWNlIGl0LgoJCQkJICovCgkJCQlzdHJ1Y3Qgc2VydmVyICpzcnYyID0gc3J2OwoJCQkJZG8gewoJCQkJCXNydjIgPSBzcnYyLT5uZXh0OwoJCQkJfSB3aGlsZSAoc3J2MiAmJiAoc3J2MiAhPSBwLT5sYnBybS5mYmNrKSk7CgkJCQlpZiAoc3J2MikKCQkJCQlwLT5sYnBybS5mYmNrID0gc3J2OwoJCQl9CgkJfQoJfSBlbHNlIHsKCQlwLT5sYnBybS50b3Rfd2FjdCA9IHAtPmxicHJtLmZ3cnIuYWN0Lm5leHRfd2VpZ2h0OwoJCXAtPnNydl9hY3QrKzsKCX0KCgkvKiBub3RlIHRoYXQgZXdlaWdodCBjYW5ub3QgYmUgMCBoZXJlICovCglmd3JyX2dldF9zcnYoc3J2KTsKCXNydi0+bnBvcyA9IGdycC0+Y3Vycl9wb3MgKyAoZ3JwLT5uZXh0X3dlaWdodCArIGdycC0+Y3Vycl93ZWlnaHQgLSBncnAtPmN1cnJfcG9zKSAvIHNydi0+ZXdlaWdodDsKCWZ3cnJfcXVldWVfc3J2KHNydik7CgpvdXRfdXBkYXRlX2JhY2tlbmQ6CgkvKiBjaGVjay91cGRhdGUgdG90X3VzZWQsIHRvdF93ZWlnaHQgKi8KCXVwZGF0ZV9iYWNrZW5kX3dlaWdodChwKTsKIG91dF91cGRhdGVfc3RhdGU6CglzcnYtPnByZXZfc3RhdGUgPSBzcnYtPnN0YXRlOwoJc3J2LT5wcmV2X2V3ZWlnaHQgPSBzcnYtPmV3ZWlnaHQ7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gbXVzdCBiZSBjYWxsZWQgYWZ0ZXIgYW4gdXBkYXRlIHRvIHNlcnZlciA8c3J2PidzIGVmZmVjdGl2ZQogKiB3ZWlnaHQuIEl0IG1heSBiZSBjYWxsZWQgYWZ0ZXIgYSBzdGF0ZSBjaGFuZ2UgdG9vLgogKi8Kc3RhdGljIHZvaWQgZndycl91cGRhdGVfc2VydmVyX3dlaWdodChzdHJ1Y3Qgc2VydmVyICpzcnYpCnsKCWludCBvbGRfc3RhdGUsIG5ld19zdGF0ZTsKCXN0cnVjdCBwcm94eSAqcCA9IHNydi0+cHJveHk7CglzdHJ1Y3QgZndycl9ncm91cCAqZ3JwOwoKCWlmIChzcnYtPnN0YXRlID09IHNydi0+cHJldl9zdGF0ZSAmJgoJICAgIHNydi0+ZXdlaWdodCA9PSBzcnYtPnByZXZfZXdlaWdodCkKCQlyZXR1cm47CgoJLyogSWYgY2hhbmdpbmcgdGhlIHNlcnZlcidzIHdlaWdodCBjaGFuZ2VzIGl0cyBzdGF0ZSwgd2Ugc2ltcGx5IGFwcGx5CgkgKiB0aGUgcHJvY2VkdXJlcyB3ZSBhbHJlYWR5IGhhdmUgZm9yIHN0YXR1cyBjaGFuZ2UuIElmIHRoZSBzdGF0ZQoJICogcmVtYWlucyBkb3duLCB0aGUgc2VydmVyIGlzIG5vdCBpbiBhbnkgdHJlZSwgc28gaXQncyBhcyBlYXN5IGFzCgkgKiB1cGRhdGluZyBpdHMgdmFsdWVzLiBJZiB0aGUgc3RhdGUgcmVtYWlucyB1cCB3aXRoIGRpZmZlcmVudCB3ZWlnaHRzLAoJICogdGhlcmUgYXJlIHNvbWUgY29tcHV0YXRpb25zIHRvIHBlcmZvcm0gdG8gZmluZCBhIG5ldyBwbGFjZSBhbmQKCSAqIHBvc3NpYmx5IGEgbmV3IHRyZWUgZm9yIHRoaXMgc2VydmVyLgoJICovCgkgCglvbGRfc3RhdGUgPSBzcnZfaXNfdXNhYmxlKHNydi0+cHJldl9zdGF0ZSwgc3J2LT5wcmV2X2V3ZWlnaHQpOwoJbmV3X3N0YXRlID0gc3J2X2lzX3VzYWJsZShzcnYtPnN0YXRlLCBzcnYtPmV3ZWlnaHQpOwoKCWlmICghb2xkX3N0YXRlICYmICFuZXdfc3RhdGUpIHsKCQlzcnYtPnByZXZfc3RhdGUgPSBzcnYtPnN0YXRlOwoJCXNydi0+cHJldl9ld2VpZ2h0ID0gc3J2LT5ld2VpZ2h0OwoJCXJldHVybjsKCX0KCWVsc2UgaWYgKCFvbGRfc3RhdGUgJiYgbmV3X3N0YXRlKSB7CgkJZndycl9zZXRfc2VydmVyX3N0YXR1c191cChzcnYpOwoJCXJldHVybjsKCX0KCWVsc2UgaWYgKG9sZF9zdGF0ZSAmJiAhbmV3X3N0YXRlKSB7CgkJZndycl9zZXRfc2VydmVyX3N0YXR1c19kb3duKHNydik7CgkJcmV0dXJuOwoJfQoKCWdycCA9IChzcnYtPnN0YXRlICYgU1JWX0JBQ0tVUCkgPyAmcC0+bGJwcm0uZndyci5iY2sgOiAmcC0+bGJwcm0uZndyci5hY3Q7CglncnAtPm5leHRfd2VpZ2h0ID0gZ3JwLT5uZXh0X3dlaWdodCAtIHNydi0+cHJldl9ld2VpZ2h0ICsgc3J2LT5ld2VpZ2h0OwoKCXAtPmxicHJtLnRvdF93YWN0ID0gcC0+bGJwcm0uZndyci5hY3QubmV4dF93ZWlnaHQ7CglwLT5sYnBybS50b3Rfd2JjayA9IHAtPmxicHJtLmZ3cnIuYmNrLm5leHRfd2VpZ2h0OwoKCWlmIChzcnYtPmxiX3RyZWUgPT0gZ3JwLT5pbml0KSB7CgkJZndycl9kZXF1ZXVlX3NydihzcnYpOwoJCWZ3cnJfcXVldWVfYnlfd2VpZ2h0KGdycC0+aW5pdCwgc3J2KTsKCX0KCWVsc2UgaWYgKCFzcnYtPmxiX3RyZWUpIHsKCQkvKiBGSVhNRTogc2VydmVyIHdhcyBkb3duLiBUaGlzIGlzIG5vdCBwb3NzaWJsZSByaWdodCBub3cgYnV0CgkJICogbWF5IGJlIG5lZWRlZCBzb29uIGZvciBzbG93c3RhcnQgb3IgZ3JhY2VmdWwgc2h1dGRvd24uCgkJICovCgkJZndycl9kZXF1ZXVlX3NydihzcnYpOwoJCWZ3cnJfZ2V0X3NydihzcnYpOwoJCXNydi0+bnBvcyA9IGdycC0+Y3Vycl9wb3MgKyAoZ3JwLT5uZXh0X3dlaWdodCArIGdycC0+Y3Vycl93ZWlnaHQgLSBncnAtPmN1cnJfcG9zKSAvIHNydi0+ZXdlaWdodDsKCQlmd3JyX3F1ZXVlX3NydihzcnYpOwoJfSBlbHNlIHsKCQkvKiBUaGUgc2VydmVyIGlzIGVpdGhlciBhY3RpdmUgb3IgaW4gdGhlIG5leHQgcXVldWUuIElmIGl0J3MKCQkgKiBzdGlsbCBpbiB0aGUgYWN0aXZlIHF1ZXVlIGFuZCBpdCBoYXMgbm90IGNvbnN1bWVkIGFsbCBvZiBpdHMKCQkgKiBwbGFjZXMsIGxldCdzIGFkanVzdCBpdHMgbmV4dCBwb3NpdGlvbi4KCQkgKi8KCQlmd3JyX2dldF9zcnYoc3J2KTsKCgkJaWYgKHNydi0+ZXdlaWdodCA+IDApIHsKCQkJaW50IHByZXZfbmV4dCA9IHNydi0+bnBvczsKCQkJaW50IHN0ZXAgPSBncnAtPm5leHRfd2VpZ2h0IC8gc3J2LT5ld2VpZ2h0OwoKCQkJc3J2LT5ucG9zID0gc3J2LT5scG9zICsgc3RlcDsKCQkJc3J2LT5yd2VpZ2h0ID0gMDsKCgkJCWlmIChzcnYtPm5wb3MgPiBwcmV2X25leHQpCgkJCQlzcnYtPm5wb3MgPSBwcmV2X25leHQ7CgkJCWlmIChzcnYtPm5wb3MgPCBncnAtPmN1cnJfcG9zICsgMikKCQkJCXNydi0+bnBvcyA9IGdycC0+Y3Vycl9wb3MgKyBzdGVwOwoJCX0gZWxzZSB7CgkJCS8qIHB1c2ggaXQgaW50byB0aGUgbmV4dCB0cmVlICovCgkJCXNydi0+bnBvcyA9IGdycC0+Y3Vycl9wb3MgKyBncnAtPmN1cnJfd2VpZ2h0OwoJCX0KCgkJZndycl9kZXF1ZXVlX3NydihzcnYpOwoJCWZ3cnJfcXVldWVfc3J2KHNydik7Cgl9CgoJdXBkYXRlX2JhY2tlbmRfd2VpZ2h0KHApOwoJc3J2LT5wcmV2X3N0YXRlID0gc3J2LT5zdGF0ZTsKCXNydi0+cHJldl9ld2VpZ2h0ID0gc3J2LT5ld2VpZ2h0Owp9CgovKiBSZW1vdmUgYSBzZXJ2ZXIgZnJvbSBhIHRyZWUuIEl0IG11c3QgaGF2ZSBwcmV2aW91c2x5IGJlZW4gZGVxdWV1ZWQuIFRoaXMKICogZnVuY3Rpb24gaXMgbWVhbnQgdG8gYmUgY2FsbGVkIHdoZW4gYSBzZXJ2ZXIgaXMgZ29pbmcgZG93biBvciBoYXMgaXRzCiAqIHdlaWdodCBkaXNhYmxlZC4KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmd3JyX3JlbW92ZV9mcm9tX3RyZWUoc3RydWN0IHNlcnZlciAqcykKewoJcy0+bGJfdHJlZSA9IE5VTEw7Cn0KCi8qIFF1ZXVlIGEgc2VydmVyIGluIHRoZSB3ZWlnaHQgdHJlZSA8cm9vdD4sIGFzc3VtaW5nIHRoZSB3ZWlnaHQgaXMgPjAuCiAqIFdlIHdhbnQgdG8gc29ydCB0aGVtIGJ5IGludmVydGVkIHdlaWdodHMsIGJlY2F1c2Ugd2UgbmVlZCB0byBwbGFjZQogKiBoZWF2eSBzZXJ2ZXJzIGZpcnN0IGluIG9yZGVyIHRvIGdldCBhIHNtb290aCBkaXN0cmlidXRpb24uCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9xdWV1ZV9ieV93ZWlnaHQoc3RydWN0IGViX3Jvb3QgKnJvb3QsIHN0cnVjdCBzZXJ2ZXIgKnMpCnsKCXMtPmxiX25vZGUua2V5ID0gU1JWX0VXR0hUX01BWCAtIHMtPmV3ZWlnaHQ7CgllYjMyX2luc2VydChyb290LCAmcy0+bGJfbm9kZSk7CglzLT5sYl90cmVlID0gcm9vdDsKfQoKLyogVGhpcyBmdW5jdGlvbiBpcyByZXNwb25zaWJsZSBmb3IgYnVpbGRpbmcgdGhlIHdlaWdodCB0cmVlcyBpbiBjYXNlIG9mIGZhc3QKICogd2VpZ2h0ZWQgcm91bmQtcm9iaW4uIEl0IGFsc28gc2V0cyBwLT5sYnBybS53ZGl2IHRvIHRoZSBld2VpZ2h0IHRvIHV3ZWlnaHQKICogcmF0aW8uIEJvdGggYWN0aXZlIGFuZCBiYWNrdXAgZ3JvdXBzIGFyZSBpbml0aWFsaXplZC4KICovCnZvaWQgZndycl9pbml0X3NlcnZlcl9ncm91cHMoc3RydWN0IHByb3h5ICpwKQp7CglzdHJ1Y3Qgc2VydmVyICpzcnY7CglzdHJ1Y3QgZWJfcm9vdCBpbml0X2hlYWQgPSBFQl9ST09UOwoKCXAtPmxicHJtLnNldF9zZXJ2ZXJfc3RhdHVzX3VwICAgPSBmd3JyX3NldF9zZXJ2ZXJfc3RhdHVzX3VwOwoJcC0+bGJwcm0uc2V0X3NlcnZlcl9zdGF0dXNfZG93biA9IGZ3cnJfc2V0X3NlcnZlcl9zdGF0dXNfZG93bjsKCXAtPmxicHJtLnVwZGF0ZV9zZXJ2ZXJfZXdlaWdodCAgPSBmd3JyX3VwZGF0ZV9zZXJ2ZXJfd2VpZ2h0OwoKCXAtPmxicHJtLndkaXYgPSBCRV9XRUlHSFRfU0NBTEU7Cglmb3IgKHNydiA9IHAtPnNydjsgc3J2OyBzcnYgPSBzcnYtPm5leHQpIHsKCQlzcnYtPnByZXZfZXdlaWdodCA9IHNydi0+ZXdlaWdodCA9IHNydi0+dXdlaWdodCAqIEJFX1dFSUdIVF9TQ0FMRTsKCQlzcnYtPnByZXZfc3RhdGUgPSBzcnYtPnN0YXRlOwoJfQoKCXJlY291bnRfc2VydmVycyhwKTsKCXVwZGF0ZV9iYWNrZW5kX3dlaWdodChwKTsKCgkvKiBwcmVwYXJlIHRoZSBhY3RpdmUgc2VydmVycyBncm91cCAqLwoJcC0+bGJwcm0uZndyci5hY3QuY3Vycl9wb3MgPSBwLT5sYnBybS5md3JyLmFjdC5jdXJyX3dlaWdodCA9CgkJcC0+bGJwcm0uZndyci5hY3QubmV4dF93ZWlnaHQgPSBwLT5sYnBybS50b3Rfd2FjdDsKCXAtPmxicHJtLmZ3cnIuYWN0LmN1cnIgPSBwLT5sYnBybS5md3JyLmFjdC50MCA9CgkJcC0+bGJwcm0uZndyci5hY3QudDEgPSBpbml0X2hlYWQ7CglwLT5sYnBybS5md3JyLmFjdC5pbml0ID0gJnAtPmxicHJtLmZ3cnIuYWN0LnQwOwoJcC0+bGJwcm0uZndyci5hY3QubmV4dCA9ICZwLT5sYnBybS5md3JyLmFjdC50MTsKCgkvKiBwcmVwYXJlIHRoZSBiYWNrdXAgc2VydmVycyBncm91cCAqLwoJcC0+bGJwcm0uZndyci5iY2suY3Vycl9wb3MgPSBwLT5sYnBybS5md3JyLmJjay5jdXJyX3dlaWdodCA9CgkJcC0+bGJwcm0uZndyci5iY2submV4dF93ZWlnaHQgPSBwLT5sYnBybS50b3Rfd2JjazsKCXAtPmxicHJtLmZ3cnIuYmNrLmN1cnIgPSBwLT5sYnBybS5md3JyLmJjay50MCA9CgkJcC0+bGJwcm0uZndyci5iY2sudDEgPSBpbml0X2hlYWQ7CglwLT5sYnBybS5md3JyLmJjay5pbml0ID0gJnAtPmxicHJtLmZ3cnIuYmNrLnQwOwoJcC0+bGJwcm0uZndyci5iY2submV4dCA9ICZwLT5sYnBybS5md3JyLmJjay50MTsKCgkvKiBxdWV1ZSBhY3RpdmUgYW5kIGJhY2t1cCBzZXJ2ZXJzIGluIHR3byBkaXN0aW5jdCBncm91cHMgKi8KCWZvciAoc3J2ID0gcC0+c3J2OyBzcnY7IHNydiA9IHNydi0+bmV4dCkgewoJCWlmICghc3J2X2lzX3VzYWJsZShzcnYtPnN0YXRlLCBzcnYtPmV3ZWlnaHQpKQoJCQljb250aW51ZTsKCQlmd3JyX3F1ZXVlX2J5X3dlaWdodCgoc3J2LT5zdGF0ZSAmIFNSVl9CQUNLVVApID8KCQkJCXAtPmxicHJtLmZ3cnIuYmNrLmluaXQgOgoJCQkJcC0+bGJwcm0uZndyci5hY3QuaW5pdCwKCQkJCXNydik7Cgl9Cn0KCi8qIHNpbXBseSByZW1vdmVzIGEgc2VydmVyIGZyb20gYSB3ZWlnaHQgdHJlZSAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9kZXF1ZXVlX3NydihzdHJ1Y3Qgc2VydmVyICpzKQp7CgllYjMyX2RlbGV0ZSgmcy0+bGJfbm9kZSk7Cn0KCi8qIHF1ZXVlcyBhIHNlcnZlciBpbnRvIHRoZSBhcHByb3ByaWF0ZSBncm91cCBhbmQgdHJlZSBkZXBlbmRpbmcgb24gaXRzCiAqIGJhY2t1cCBzdGF0dXMsIGFuZCAtPm5wb3MuIElmIHRoZSBzZXJ2ZXIgaXMgZGlzYWJsZWQsIHNpbXBseSBhc3NpZ24KICogaXQgdG8gdGhlIE5VTEwgdHJlZS4KICovCnN0YXRpYyB2b2lkIGZ3cnJfcXVldWVfc3J2KHN0cnVjdCBzZXJ2ZXIgKnMpCnsKCXN0cnVjdCBwcm94eSAqcCA9IHMtPnByb3h5OwoJc3RydWN0IGZ3cnJfZ3JvdXAgKmdycDsKCglncnAgPSAocy0+c3RhdGUgJiBTUlZfQkFDS1VQKSA/ICZwLT5sYnBybS5md3JyLmJjayA6ICZwLT5sYnBybS5md3JyLmFjdDsKCQoJLyogRGVsYXkgZXZlcnl0aGluZyB3aGljaCBkb2VzIG5vdCBmaXQgaW50byB0aGUgd2luZG93IGFuZCBldmVyeXRoaW5nCgkgKiB3aGljaCBkb2VzIG5vdCBmaXQgaW50byB0aGUgdGhlb3JpY2FsIG5ldyB3aW5kb3cuCgkgKi8KCWlmICghc3J2X2lzX3VzYWJsZShzLT5zdGF0ZSwgcy0+ZXdlaWdodCkpIHsKCQlmd3JyX3JlbW92ZV9mcm9tX3RyZWUocyk7Cgl9CgllbHNlIGlmIChzLT5ld2VpZ2h0IDw9IDAgfHwKCQkgcy0+bnBvcyA+PSAyICogZ3JwLT5jdXJyX3dlaWdodCB8fAoJCSBzLT5ucG9zID49IGdycC0+Y3Vycl93ZWlnaHQgKyBncnAtPm5leHRfd2VpZ2h0KSB7CgkJLyogcHV0IGludG8gbmV4dCB0cmVlLCBhbmQgcmVhZGp1c3QgbnBvcyBpbiBjYXNlIHdlIGNvdWxkCgkJICogZmluYWxseSB0YWtlIHRoaXMgYmFjayB0byBjdXJyZW50LiAqLwoJCXMtPm5wb3MgLT0gZ3JwLT5jdXJyX3dlaWdodDsKCQlmd3JyX3F1ZXVlX2J5X3dlaWdodChncnAtPm5leHQsIHMpOwoJfQoJZWxzZSB7CgkJLyogVGhlIHNvcnRpbmcga2V5IGlzIHN0b3JlZCBpbiB1bml0cyBvZiBzLT5ucG9zICogdXNlcl93ZWlnaHQKCQkgKiBpbiBvcmRlciB0byBhdm9pZCBvdmVyZmxvd3MuIEFzIHN0YXRlZCBpbiBiYWNrZW5kLmgsIHRoZQoJCSAqIGxvd2VyIHRoZSBzY2FsZSwgdGhlIHJvdWdoZXIgdGhlIHdlaWdodHMgbW9kdWxhdGlvbiwgYW5kIHRoZQoJCSAqIGhpZ2hlciB0aGUgc2NhbGUsIHRoZSBsb3dlciB0aGUgbnVtYmVyIG9mIHNlcnZlcnMgd2l0aG91dAoJCSAqIG92ZXJmbG93LiBXaXRoIHRoaXMgZm9ybXVsYSwgdGhlIHJlc3VsdCBpcyBhbHdheXMgcG9zaXRpdmUsCgkJICogc28gd2UgY2FuIHVzZSBlYjPpX2luc2VydCgpLgoJCSAqLwoJCXMtPmxiX25vZGUua2V5ID0gU1JWX1VXR0hUX1JBTkdFICogcy0+bnBvcyArCgkJCSh1bnNpZ25lZCkoU1JWX0VXR0hUX01BWCArIHMtPnJ3ZWlnaHQgLSBzLT5ld2VpZ2h0KSAvIEJFX1dFSUdIVF9TQ0FMRTsKCgkJZWIzMl9pbnNlcnQoJmdycC0+Y3VyciwgJnMtPmxiX25vZGUpOwoJCXMtPmxiX3RyZWUgPSAmZ3JwLT5jdXJyOwoJfQp9CgovKiBwcmVwYXJlcyBhIHNlcnZlciB3aGVuIGV4dHJhY3RpbmcgaXQgZnJvbSB0aGUgImluaXQiIHRyZWUgKi8Kc3RhdGljIGlubGluZSB2b2lkIGZ3cnJfZ2V0X3Nydl9pbml0KHN0cnVjdCBzZXJ2ZXIgKnMpCnsKCXMtPm5wb3MgPSBzLT5yd2VpZ2h0ID0gMDsKfQoKLyogcHJlcGFyZXMgYSBzZXJ2ZXIgd2hlbiBleHRyYWN0aW5nIGl0IGZyb20gdGhlICJuZXh0IiB0cmVlICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmd3JyX2dldF9zcnZfbmV4dChzdHJ1Y3Qgc2VydmVyICpzKQp7CglzdHJ1Y3QgZndycl9ncm91cCAqZ3JwID0gKHMtPnN0YXRlICYgU1JWX0JBQ0tVUCkgPwoJCSZzLT5wcm94eS0+bGJwcm0uZndyci5iY2sgOgoJCSZzLT5wcm94eS0+bGJwcm0uZndyci5hY3Q7CgoJcy0+bnBvcyArPSBncnAtPmN1cnJfd2VpZ2h0Owp9CgovKiBwcmVwYXJlcyBhIHNlcnZlciB3aGVuIGl0IHdhcyBtYXJrZWQgZG93biAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9nZXRfc3J2X2Rvd24oc3RydWN0IHNlcnZlciAqcykKewoJc3RydWN0IGZ3cnJfZ3JvdXAgKmdycCA9IChzLT5zdGF0ZSAmIFNSVl9CQUNLVVApID8KCQkmcy0+cHJveHktPmxicHJtLmZ3cnIuYmNrIDoKCQkmcy0+cHJveHktPmxicHJtLmZ3cnIuYWN0OwoKCXMtPm5wb3MgPSBncnAtPmN1cnJfcG9zOwp9CgovKiBwcmVwYXJlcyBhIHNlcnZlciB3aGVuIGV4dHJhY3RpbmcgaXQgZnJvbSBpdHMgdHJlZSAqLwpzdGF0aWMgdm9pZCBmd3JyX2dldF9zcnYoc3RydWN0IHNlcnZlciAqcykKewoJc3RydWN0IHByb3h5ICpwID0gcy0+cHJveHk7CglzdHJ1Y3QgZndycl9ncm91cCAqZ3JwID0gKHMtPnN0YXRlICYgU1JWX0JBQ0tVUCkgPwoJCSZwLT5sYnBybS5md3JyLmJjayA6CgkJJnAtPmxicHJtLmZ3cnIuYWN0OwoKCWlmIChzLT5sYl90cmVlID09IGdycC0+aW5pdCkgewoJCWZ3cnJfZ2V0X3Nydl9pbml0KHMpOwoJfQoJZWxzZSBpZiAocy0+bGJfdHJlZSA9PSBncnAtPm5leHQpIHsKCQlmd3JyX2dldF9zcnZfbmV4dChzKTsKCX0KCWVsc2UgaWYgKHMtPmxiX3RyZWUgPT0gTlVMTCkgewoJCWZ3cnJfZ2V0X3Nydl9kb3duKHMpOwoJfQp9CgovKiBzd2l0Y2hlcyB0cmVlcyAiaW5pdCIgYW5kICJuZXh0IiBmb3IgRldSUiBncm91cCA8Z3JwPi4gImluaXQiIHNob3VsZCBiZSBlbXB0eQogKiB3aGVuIHRoaXMgaGFwcGVucywgYW5kICJuZXh0IiBmaWxsZWQgd2l0aCBzZXJ2ZXJzIHNvcnRlZCBieSB3ZWlnaHRzLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZ3cnJfc3dpdGNoX3RyZWVzKHN0cnVjdCBmd3JyX2dyb3VwICpncnApCnsKCXN0cnVjdCBlYl9yb290ICpzd2FwOwoJc3dhcCA9IGdycC0+aW5pdDsKCWdycC0+aW5pdCA9IGdycC0+bmV4dDsKCWdycC0+bmV4dCA9IHN3YXA7CglncnAtPmN1cnJfd2VpZ2h0ID0gZ3JwLT5uZXh0X3dlaWdodDsKCWdycC0+Y3Vycl9wb3MgPSBncnAtPmN1cnJfd2VpZ2h0Owp9CgovKiByZXR1cm4gbmV4dCBzZXJ2ZXIgZnJvbSB0aGUgY3VycmVudCB0cmVlIGluIEZXUlIgZ3JvdXAgPGdycD4sIG9yIGEgc2VydmVyCiAqIGZyb20gdGhlICJpbml0IiB0cmVlIGlmIGFwcHJvcHJpYXRlLiBJZiBib3RoIHRyZWVzIGFyZSBlbXB0eSwgcmV0dXJuIE5VTEwuCiAqLwpzdGF0aWMgc3RydWN0IHNlcnZlciAqZndycl9nZXRfc2VydmVyX2Zyb21fZ3JvdXAoc3RydWN0IGZ3cnJfZ3JvdXAgKmdycCkKewoJc3RydWN0IGViMzJfbm9kZSAqbm9kZTsKCXN0cnVjdCBzZXJ2ZXIgKnM7CgoJbm9kZSA9IGViMzJfZmlyc3QoJmdycC0+Y3Vycik7CglzID0gZWIzMl9lbnRyeShub2RlLCBzdHJ1Y3Qgc2VydmVyLCBsYl9ub2RlKTsKCQoJaWYgKCFub2RlIHx8IHMtPm5wb3MgPiBncnAtPmN1cnJfcG9zKSB7CgkJLyogZWl0aGVyIHdlIGhhdmUgbm8gc2VydmVyIGxlZnQsIG9yIHdlIGhhdmUgYSBob2xlICovCgkJc3RydWN0IGViMzJfbm9kZSAqbm9kZTI7CgkJbm9kZTIgPSBlYjMyX2ZpcnN0KGdycC0+aW5pdCk7CgkJaWYgKG5vZGUyKSB7CgkJCW5vZGUgPSBub2RlMjsKCQkJcyA9IGViMzJfZW50cnkobm9kZSwgc3RydWN0IHNlcnZlciwgbGJfbm9kZSk7CgkJCWZ3cnJfZ2V0X3Nydl9pbml0KHMpOwoJCQlpZiAocy0+ZXdlaWdodCA9PSAwKSAvKiBGSVhNRTogaXMgaXQgcG9zc2libGUgYXQgYWxsID8gKi8KCQkJCW5vZGUgPSBOVUxMOwoJCX0KCX0KCWlmIChub2RlKQoJCXJldHVybiBzOwoJZWxzZQoJCXJldHVybiBOVUxMOwp9CgovKiBDb21wdXRlcyBuZXh0IHBvc2l0aW9uIG9mIHNlcnZlciA8cz4gaW4gdGhlIGdyb3VwLiBJdCBpcyBtYW5kYXRvcnkgZm9yIDxzPgogKiB0byBoYXZlIGEgbm9uLXplcm8sIHBvc2l0aXZlIGV3ZWlnaHQuCiovCnN0YXRpYyBpbmxpbmUgdm9pZCBmd3JyX3VwZGF0ZV9wb3NpdGlvbihzdHJ1Y3QgZndycl9ncm91cCAqZ3JwLCBzdHJ1Y3Qgc2VydmVyICpzKQp7CglpZiAoIXMtPm5wb3MpIHsKCQkvKiBmaXJzdCB0aW1lIGV2ZXIgZm9yIHRoaXMgc2VydmVyICovCgkJcy0+bHBvcyA9IGdycC0+Y3Vycl9wb3M7CgkJcy0+bnBvcyA9IGdycC0+Y3Vycl9wb3MgKyBncnAtPm5leHRfd2VpZ2h0IC8gcy0+ZXdlaWdodDsKCQlzLT5yd2VpZ2h0ICs9IGdycC0+bmV4dF93ZWlnaHQgJSBzLT5ld2VpZ2h0OwoKCQlpZiAocy0+cndlaWdodCA+PSBzLT5ld2VpZ2h0KSB7CgkJCXMtPnJ3ZWlnaHQgLT0gcy0+ZXdlaWdodDsKCQkJcy0+bnBvcysrOwoJCX0KCX0gZWxzZSB7CgkJcy0+bHBvcyA9IHMtPm5wb3M7CgkJcy0+bnBvcyArPSBncnAtPm5leHRfd2VpZ2h0IC8gcy0+ZXdlaWdodDsKCQlzLT5yd2VpZ2h0ICs9IGdycC0+bmV4dF93ZWlnaHQgJSBzLT5ld2VpZ2h0OwoKCQlpZiAocy0+cndlaWdodCA+PSBzLT5ld2VpZ2h0KSB7CgkJCXMtPnJ3ZWlnaHQgLT0gcy0+ZXdlaWdodDsKCQkJcy0+bnBvcysrOwoJCX0KCX0KfQoKLyogUmV0dXJuIG5leHQgc2VydmVyIGZyb20gdGhlIGN1cnJlbnQgdHJlZSBpbiBiYWNrZW5kIDxwPiwgb3IgYSBzZXJ2ZXIgZnJvbQogKiB0aGUgaW5pdCB0cmVlIGlmIGFwcHJvcHJpYXRlLiBJZiBib3RoIHRyZWVzIGFyZSBlbXB0eSwgcmV0dXJuIE5VTEwuCiAqIFNhdHVyYXRlZCBzZXJ2ZXJzIGFyZSBza2lwcGVkIGFuZCByZXF1ZXVlZC4KICovCnN0cnVjdCBzZXJ2ZXIgKmZ3cnJfZ2V0X25leHRfc2VydmVyKHN0cnVjdCBwcm94eSAqcCwgc3RydWN0IHNlcnZlciAqc3J2dG9hdm9pZCkKewoJc3RydWN0IHNlcnZlciAqc3J2LCAqZnVsbCwgKmF2b2lkZWQ7CglzdHJ1Y3QgZndycl9ncm91cCAqZ3JwOwoJaW50IHN3aXRjaGVkOwoKCWlmIChwLT5zcnZfYWN0KQoJCWdycCA9ICZwLT5sYnBybS5md3JyLmFjdDsKCWVsc2UgaWYgKHAtPmxicHJtLmZiY2spCgkJcmV0dXJuIHAtPmxicHJtLmZiY2s7CgllbHNlIGlmIChwLT5zcnZfYmNrKQoJCWdycCA9ICZwLT5sYnBybS5md3JyLmJjazsKCWVsc2UKCQlyZXR1cm4gTlVMTDsKCglzd2l0Y2hlZCA9IDA7Cglhdm9pZGVkID0gTlVMTDsKCWZ1bGwgPSBOVUxMOyAvKiBOVUxMLXRlcm1pbmF0ZWQgbGlzdCBvZiBzYXR1cmF0ZWQgc2VydmVycyAqLwoJd2hpbGUgKDEpIHsKCQkvKiBpZiB3ZSBzZWUgYW4gZW1wdHkgZ3JvdXAsIGxldCdzIGZpcnN0IHRyeSB0byBjb2xsZWN0IHdlaWdodHMKCQkgKiB3aGljaCBtaWdodCBoYXZlIHJlY2VudGx5IGNoYW5nZWQuCgkJICovCgkJaWYgKCFncnAtPmN1cnJfd2VpZ2h0KQoJCQlncnAtPmN1cnJfcG9zID0gZ3JwLT5jdXJyX3dlaWdodCA9IGdycC0+bmV4dF93ZWlnaHQ7CgoJCS8qIGdldCBmaXJzdCBzZXJ2ZXIgZnJvbSB0aGUgImN1cnJlbnQiIHRyZWUuIFdoZW4gdGhlIGVuZCBvZgoJCSAqIHRoZSB0cmVlIGlzIHJlYWNoZWQsIHdlIG1heSBoYXZlIHRvIHN3aXRjaCwgYnV0IG9ubHkgb25jZS4KCQkgKi8KCQl3aGlsZSAoMSkgewoJCQlzcnYgPSBmd3JyX2dldF9zZXJ2ZXJfZnJvbV9ncm91cChncnApOwoJCQlpZiAoc3J2KQoJCQkJYnJlYWs7CgkJCWlmIChzd2l0Y2hlZCkgewoJCQkJaWYgKGF2b2lkZWQpIHsKCQkJCQlzcnYgPSBhdm9pZGVkOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJZ290byByZXF1ZXVlX3NlcnZlcnM7CgkJCX0KCQkJc3dpdGNoZWQgPSAxOwoJCQlmd3JyX3N3aXRjaF90cmVlcyhncnApOwoKCQl9CgoJCS8qIE9LLCB3ZSBoYXZlIGEgc2VydmVyLiBIb3dldmVyLCBpdCBtYXkgYmUgc2F0dXJhdGVkLCBpbiB3aGljaAoJCSAqIGNhc2Ugd2UgZG9uJ3Qgd2FudCB0byByZWNvbnNpZGVyIGl0IGZvciBub3cuIFdlJ2xsIHVwZGF0ZQoJCSAqIGl0cyBwb3NpdGlvbiBhbmQgZGVxdWV1ZSBpdCBhbnl3YXksIHNvIHRoYXQgd2UgY2FuIG1vdmUgaXQKCQkgKiB0byBhIGJldHRlciBwbGFjZSBhZnRlcndhcmRzLgoJCSAqLwoJCWZ3cnJfdXBkYXRlX3Bvc2l0aW9uKGdycCwgc3J2KTsKCQlmd3JyX2RlcXVldWVfc3J2KHNydik7CgkJZ3JwLT5jdXJyX3BvcysrOwoJCWlmICghc3J2LT5tYXhjb25uIHx8ICghc3J2LT5uYnBlbmQgJiYgc3J2LT5zZXJ2ZWQgPCBzcnZfZHluYW1pY19tYXhjb25uKHNydikpKSB7CgkJCS8qIG1ha2Ugc3VyZSBpdCBpcyBub3QgdGhlIHNlcnZlciB3ZSBhcmUgdHJ5aW5nIHRvIGV4Y2x1ZGUuLi4gKi8KCQkJaWYgKHNydiAhPSBzcnZ0b2F2b2lkIHx8IGF2b2lkZWQpCgkJCQlicmVhazsKCgkJCWF2b2lkZWQgPSBzcnY7IC8qIC4uLmJ1dCByZW1lbWJlciB0aGF0IGlzIHdhcyBzZWxlY3RlZCB5ZXQgYXZvaWRlZCAqLwoJCX0KCgkJLyogdGhlIHNlcnZlciBpcyBzYXR1cmF0ZWQgb3IgYXZvaWRlZCwgbGV0J3MgY2hhaW4gaXQgZm9yIGxhdGVyIHJlaW5zZXJ0aW9uICovCgkJc3J2LT5uZXh0X2Z1bGwgPSBmdWxsOwoJCWZ1bGwgPSBzcnY7Cgl9CgoJLyogT0ssIHdlIGdvdCB0aGUgYmVzdCBzZXJ2ZXIsIGxldCdzIHVwZGF0ZSBpdCAqLwoJZndycl9xdWV1ZV9zcnYoc3J2KTsKCiByZXF1ZXVlX3NlcnZlcnM6CgkvKiBSZXF1ZXVlIGFsbCBleHRyYWN0ZWQgc2VydmVycy4gSWYgZnVsbD09c3J2IHRoZW4gaXQgd2FzCgkgKiBhdm9pZGVkICh1bnN1Y2Vzc2Z1bGx5KSBhbmQgY2hhaW5lZCwgb21pdCBpdCBub3cuCgkgKi8KCWlmICh1bmxpa2VseShmdWxsICE9IE5VTEwpKSB7CgkJaWYgKHN3aXRjaGVkKSB7CgkJCS8qIHRoZSB0cmVlIGhhcyBzd2l0Y2hlZCwgcmVxdWV1ZSBhbGwgZXh0cmFjdGVkIHNlcnZlcnMKCQkJICogaW50byAiaW5pdCIsIGJlY2F1c2UgdGhlaXIgcGxhY2Ugd2FzIGxvc3QsIGFuZCBvbmx5CgkJCSAqIHRoZWlyIHdlaWdodCBtYXR0ZXJzLgoJCQkgKi8KCQkJZG8gewoJCQkJaWYgKGxpa2VseShmdWxsICE9IHNydikpCgkJCQkJZndycl9xdWV1ZV9ieV93ZWlnaHQoZ3JwLT5pbml0LCBmdWxsKTsKCQkJCWZ1bGwgPSBmdWxsLT5uZXh0X2Z1bGw7CgkJCX0gd2hpbGUgKGZ1bGwpOwoJCX0gZWxzZSB7CgkJCS8qIHJlcXVldWUgYWxsIGV4dHJhY3RlZCBzZXJ2ZXJzIGp1c3QgYXMgaWYgdGhleSB3ZXJlIGNvbnN1bWVkCgkJCSAqIHNvIHRoYXQgdGhleSByZWdhaW4gdGhlaXIgZXhwZWN0ZWQgcGxhY2UuCgkJCSAqLwoJCQlkbyB7CgkJCQlpZiAobGlrZWx5KGZ1bGwgIT0gc3J2KSkKCQkJCQlmd3JyX3F1ZXVlX3NydihmdWxsKTsKCQkJCWZ1bGwgPSBmdWxsLT5uZXh0X2Z1bGw7CgkJCX0gd2hpbGUgKGZ1bGwpOwoJCX0KCX0KCXJldHVybiBzcnY7Cn0KCi8qCiAqIExvY2FsIHZhcmlhYmxlczoKICogIGMtaW5kZW50LWxldmVsOiA4CiAqICBjLWJhc2ljLW9mZnNldDogOAogKiBFbmQ6CiAqLwo=