LyoKICogQmFja2VuZCB2YXJpYWJsZXMgYW5kIGZ1bmN0aW9ucy4KICoKICogQ29weXJpZ2h0IDIwMDAtMjAwOCBXaWxseSBUYXJyZWF1IDx3QDF3dC5ldT4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24KICogMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICovCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzeXNsb2cuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgPGNvbW1vbi9jb21wYXQuaD4KI2luY2x1ZGUgPGNvbW1vbi9jb25maWcuaD4KI2luY2x1ZGUgPGNvbW1vbi9lYjMydHJlZS5oPgojaW5jbHVkZSA8Y29tbW9uL3RpbWUuaD4KCiNpbmNsdWRlIDx0eXBlcy9hY2wuaD4KI2luY2x1ZGUgPHR5cGVzL2J1ZmZlcnMuaD4KI2luY2x1ZGUgPHR5cGVzL2dsb2JhbC5oPgojaW5jbHVkZSA8dHlwZXMvcG9sbGluZy5oPgojaW5jbHVkZSA8dHlwZXMvcHJveHkuaD4KI2luY2x1ZGUgPHR5cGVzL3NlcnZlci5oPgojaW5jbHVkZSA8dHlwZXMvc2Vzc2lvbi5oPgoKI2luY2x1ZGUgPHByb3RvL2FjbC5oPgojaW5jbHVkZSA8cHJvdG8vYmFja2VuZC5oPgojaW5jbHVkZSA8cHJvdG8vY2xpZW50Lmg+CiNpbmNsdWRlIDxwcm90by9mZC5oPgojaW5jbHVkZSA8cHJvdG8vaHR0cGVyci5oPgojaW5jbHVkZSA8cHJvdG8vbG9nLmg+CiNpbmNsdWRlIDxwcm90by9wcm90b19odHRwLmg+CiNpbmNsdWRlIDxwcm90by9wcm90b190Y3AuaD4KI2luY2x1ZGUgPHByb3RvL3F1ZXVlLmg+CiNpbmNsdWRlIDxwcm90by9zdHJlYW1fc29jay5oPgojaW5jbHVkZSA8cHJvdG8vdGFzay5oPgoKI2lmZGVmIENPTkZJR19IQVBfVENQU1BMSUNFCiNpbmNsdWRlIDxsaWJ0Y3BzcGxpY2UuaD4KI2VuZGlmCgpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9yZW1vdmVfZnJvbV90cmVlKHN0cnVjdCBzZXJ2ZXIgKnMpOwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9xdWV1ZV9ieV93ZWlnaHQoc3RydWN0IGViX3Jvb3QgKnJvb3QsIHN0cnVjdCBzZXJ2ZXIgKnMpOwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9kZXF1ZXVlX3NydihzdHJ1Y3Qgc2VydmVyICpzKTsKc3RhdGljIHZvaWQgZndycl9nZXRfc3J2KHN0cnVjdCBzZXJ2ZXIgKnMpOwpzdGF0aWMgdm9pZCBmd3JyX3F1ZXVlX3NydihzdHJ1Y3Qgc2VydmVyICpzKTsKCi8qIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBub24temVybyBpZiBhIHNlcnZlciB3aXRoIHRoZSBnaXZlbiB3ZWlnaHQgYW5kIHN0YXRlCiAqIGlzIHVzYWJsZSBmb3IgTEIsIG90aGVyd2lzZSB6ZXJvLgogKi8Kc3RhdGljIGlubGluZSBpbnQgc3J2X2lzX3VzYWJsZShpbnQgc3RhdGUsIGludCB3ZWlnaHQpCnsKCWlmICghd2VpZ2h0KQoJCXJldHVybiAwOwoJaWYgKHN0YXRlICYgU1JWX0dPSU5HRE9XTikKCQlyZXR1cm4gMDsKCWlmICghKHN0YXRlICYgU1JWX1JVTk5JTkcpKQoJCXJldHVybiAwOwoJcmV0dXJuIDE7Cn0KCi8qCiAqIFRoaXMgZnVuY3Rpb24gcmVjb3VudHMgdGhlIG51bWJlciBvZiB1c2FibGUgYWN0aXZlIGFuZCBiYWNrdXAgc2VydmVycyBmb3IKICogcHJveHkgPHA+LiBUaGVzZSBudW1iZXJzIGFyZSByZXR1cm5lZCBpbnRvIHRoZSBwLT5zcnZfYWN0IGFuZCBwLT5zcnZfYmNrLgogKiBUaGlzIGZ1bmN0aW9uIGFsc28gcmVjb21wdXRlcyB0aGUgdG90YWwgYWN0aXZlIGFuZCBiYWNrdXAgd2VpZ2h0cy4gSG93ZXZlciwKICogaXQgZG9lcyBub3V0IHVwZGF0ZSB0b3Rfd2VpZ2h0IG5vciB0b3RfdXNlZC4gVXNlIHVwZGF0ZV9iYWNrZW5kX3dlaWdodCgpIGZvcgogKiB0aGlzLgogKi8Kc3RhdGljIHZvaWQgcmVjb3VudF9zZXJ2ZXJzKHN0cnVjdCBwcm94eSAqcHgpCnsKCXN0cnVjdCBzZXJ2ZXIgKnNydjsKCglweC0+c3J2X2FjdCA9IHB4LT5zcnZfYmNrID0gMDsKCXB4LT5sYnBybS50b3Rfd2FjdCA9IHB4LT5sYnBybS50b3Rfd2JjayA9IDA7CglweC0+bGJwcm0uZmJjayA9IE5VTEw7Cglmb3IgKHNydiA9IHB4LT5zcnY7IHNydiAhPSBOVUxMOyBzcnYgPSBzcnYtPm5leHQpIHsKCQlpZiAoIXNydl9pc191c2FibGUoc3J2LT5zdGF0ZSwgc3J2LT5ld2VpZ2h0KSkKCQkJY29udGludWU7CgoJCWlmIChzcnYtPnN0YXRlICYgU1JWX0JBQ0tVUCkgewoJCQlpZiAoIXB4LT5zcnZfYmNrICYmCgkJCSAgICAhKHB4LT5sYnBybS5hbGdvICYgUFJfT19VU0VfQUxMX0JLKSkKCQkJCXB4LT5sYnBybS5mYmNrID0gc3J2OwoJCQlweC0+c3J2X2JjaysrOwoJCQlweC0+bGJwcm0udG90X3diY2sgKz0gc3J2LT5ld2VpZ2h0OwoJCX0gZWxzZSB7CgkJCXB4LT5zcnZfYWN0Kys7CgkJCXB4LT5sYnBybS50b3Rfd2FjdCArPSBzcnYtPmV3ZWlnaHQ7CgkJfQoJfQp9CgovKiBUaGlzIGZ1bmN0aW9uIHNpbXBseSB1cGRhdGVzIHRoZSBiYWNrZW5kJ3MgdG90X3dlaWdodCBhbmQgdG90X3VzZWQgdmFsdWVzCiAqIGFmdGVyIHNlcnZlcnMgd2VpZ2h0cyBoYXZlIGJlZW4gdXBkYXRlZC4gSXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBhZnRlcgogKiByZWNvdW50X3NlcnZlcnMoKSBvciBlcXVpdmFsZW50LgogKi8Kc3RhdGljIHZvaWQgdXBkYXRlX2JhY2tlbmRfd2VpZ2h0KHN0cnVjdCBwcm94eSAqcHgpCnsKCWlmIChweC0+c3J2X2FjdCkgewoJCXB4LT5sYnBybS50b3Rfd2VpZ2h0ID0gcHgtPmxicHJtLnRvdF93YWN0OwoJCXB4LT5sYnBybS50b3RfdXNlZCAgID0gcHgtPnNydl9hY3Q7Cgl9CgllbHNlIGlmIChweC0+bGJwcm0uZmJjaykgewoJCS8qIHVzZSBvbmx5IHRoZSBmaXJzdCBiYWNrdXAgc2VydmVyICovCgkJcHgtPmxicHJtLnRvdF93ZWlnaHQgPSBweC0+bGJwcm0uZmJjay0+ZXdlaWdodDsKCQlweC0+bGJwcm0udG90X3VzZWQgPSAxOwoJfQoJZWxzZSB7CgkJcHgtPmxicHJtLnRvdF93ZWlnaHQgPSBweC0+bGJwcm0udG90X3diY2s7CgkJcHgtPmxicHJtLnRvdF91c2VkICAgPSBweC0+c3J2X2JjazsKCX0KfQoKLyogdGhpcyBmdW5jdGlvbiB1cGRhdGVzIHRoZSBtYXAgYWNjb3JkaW5nIHRvIHNlcnZlciA8c3J2PidzIG5ldyBzdGF0ZSAqLwpzdGF0aWMgdm9pZCBtYXBfc2V0X3NlcnZlcl9zdGF0dXNfZG93bihzdHJ1Y3Qgc2VydmVyICpzcnYpCnsKCXN0cnVjdCBwcm94eSAqcCA9IHNydi0+cHJveHk7CgoJaWYgKHNydi0+c3RhdGUgPT0gc3J2LT5wcmV2X3N0YXRlICYmCgkgICAgc3J2LT5ld2VpZ2h0ID09IHNydi0+cHJldl9ld2VpZ2h0KQoJCXJldHVybjsKCglpZiAoc3J2X2lzX3VzYWJsZShzcnYtPnN0YXRlLCBzcnYtPmV3ZWlnaHQpKQoJCWdvdG8gb3V0X3VwZGF0ZV9zdGF0ZTsKCgkvKiBGSVhNRTogY291bGQgYmUgb3B0aW1pemVkIHNpbmNlIHdlIGtub3cgd2hhdCBjaGFuZ2VkICovCglyZWNvdW50X3NlcnZlcnMocCk7Cgl1cGRhdGVfYmFja2VuZF93ZWlnaHQocCk7CglwLT5sYnBybS5tYXAuc3RhdGUgfD0gUFJfTUFQX1JFQ0FMQzsKIG91dF91cGRhdGVfc3RhdGU6CglzcnYtPnByZXZfc3RhdGUgPSBzcnYtPnN0YXRlOwoJc3J2LT5wcmV2X2V3ZWlnaHQgPSBzcnYtPmV3ZWlnaHQ7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gdXBkYXRlcyB0aGUgbWFwIGFjY29yZGluZyB0byBzZXJ2ZXIgPHNydj4ncyBuZXcgc3RhdGUgKi8Kc3RhdGljIHZvaWQgbWFwX3NldF9zZXJ2ZXJfc3RhdHVzX3VwKHN0cnVjdCBzZXJ2ZXIgKnNydikKewoJc3RydWN0IHByb3h5ICpwID0gc3J2LT5wcm94eTsKCglpZiAoc3J2LT5zdGF0ZSA9PSBzcnYtPnByZXZfc3RhdGUgJiYKCSAgICBzcnYtPmV3ZWlnaHQgPT0gc3J2LT5wcmV2X2V3ZWlnaHQpCgkJcmV0dXJuOwoKCWlmICghc3J2X2lzX3VzYWJsZShzcnYtPnN0YXRlLCBzcnYtPmV3ZWlnaHQpKQoJCWdvdG8gb3V0X3VwZGF0ZV9zdGF0ZTsKCgkvKiBGSVhNRTogY291bGQgYmUgb3B0aW1pemVkIHNpbmNlIHdlIGtub3cgd2hhdCBjaGFuZ2VkICovCglyZWNvdW50X3NlcnZlcnMocCk7Cgl1cGRhdGVfYmFja2VuZF93ZWlnaHQocCk7CglwLT5sYnBybS5tYXAuc3RhdGUgfD0gUFJfTUFQX1JFQ0FMQzsKIG91dF91cGRhdGVfc3RhdGU6CglzcnYtPnByZXZfc3RhdGUgPSBzcnYtPnN0YXRlOwoJc3J2LT5wcmV2X2V3ZWlnaHQgPSBzcnYtPmV3ZWlnaHQ7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gcmVjb21wdXRlcyB0aGUgc2VydmVyIG1hcCBmb3IgcHJveHkgcHguIEl0IHJlbGllcyBvbgogKiBweC0+bGJwcm0udG90X3dhY3QsIHRvdF93YmNrLCB0b3RfdXNlZCwgdG90X3dlaWdodCwgc28gaXQgbXVzdCBiZQogKiBjYWxsZWQgYWZ0ZXIgcmVjb3VudF9zZXJ2ZXJzKCkuIEl0IGFsc28gZXhwZWN0cyBweC0+bGJwcm0ubWFwLnNydgogKiB0byBiZSBhbGxvY2F0ZWQgd2l0aCB0aGUgbGFyZ2VzdCBzaXplIG5lZWRlZC4gSXQgdXBkYXRlcyB0b3Rfd2VpZ2h0LgogKi8Kdm9pZCByZWNhbGNfc2VydmVyX21hcChzdHJ1Y3QgcHJveHkgKnB4KQp7CglpbnQgbywgdG90LCBmbGFnOwoJc3RydWN0IHNlcnZlciAqY3VyLCAqYmVzdDsKCglzd2l0Y2ggKHB4LT5sYnBybS50b3RfdXNlZCkgewoJY2FzZSAwOgkvKiBubyBzZXJ2ZXIgKi8KCQlweC0+bGJwcm0ubWFwLnN0YXRlICY9IH5QUl9NQVBfUkVDQUxDOwoJCXJldHVybjsKCWNhc2UgMTogLyogb25seSBvbmUgc2VydmVyLCBqdXN0IGZpbGwgZmlyc3QgZW50cnkgKi8KCQl0b3QgPSAxOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQl0b3QgPSBweC0+bGJwcm0udG90X3dlaWdodDsKCQlicmVhazsKCX0KCgkvKiBoZXJlIHdlICprbm93KiB0aGF0IHdlIGhhdmUgc29tZSBzZXJ2ZXJzICovCglpZiAocHgtPnNydl9hY3QpCgkJZmxhZyA9IFNSVl9SVU5OSU5HOwoJZWxzZQoJCWZsYWcgPSBTUlZfUlVOTklORyB8IFNSVl9CQUNLVVA7CgoJLyogdGhpcyBhbGdvcml0aG0gZ2l2ZXMgcHJpb3JpdHkgdG8gdGhlIGZpcnN0IHNlcnZlciwgd2hpY2ggbWVhbnMgdGhhdAoJICogaXQgd2lsbCByZXNwZWN0IHRoZSBkZWNsYXJhdGlvbiBvcmRlciBmb3IgZXF1aXZhbGVudCB3ZWlnaHRzLCBhbmQKCSAqIHRoYXQgd2hhdGV2ZXIgdGhlIHdlaWdodHMsIHRoZSBmaXJzdCBzZXJ2ZXIgY2FsbGVkIHdpbGwgYWx3YXlzIGJlCgkgKiB0aGUgZmlyc3QgZGVjbGFyZWQuIFRoaXMgaXMgYW4gaW1wb3J0YW50IGFzdW1wdGlvbiBmb3IgdGhlIGJhY2t1cAoJICogY2FzZSwgd2hlcmUgd2Ugd2FudCB0aGUgZmlyc3Qgc2VydmVyIG9ubHkuCgkgKi8KCWZvciAoY3VyID0gcHgtPnNydjsgY3VyOyBjdXIgPSBjdXItPm5leHQpCgkJY3VyLT53c2NvcmUgPSAwOwoKCWZvciAobyA9IDA7IG8gPCB0b3Q7IG8rKykgewoJCWludCBtYXggPSAwOwoJCWJlc3QgPSBOVUxMOwoJCWZvciAoY3VyID0gcHgtPnNydjsgY3VyOyBjdXIgPSBjdXItPm5leHQpIHsKCQkJaWYgKGZsYWcgPT0gKGN1ci0+c3RhdGUgJgoJCQkJICAgICAoU1JWX1JVTk5JTkcgfCBTUlZfR09JTkdET1dOIHwgU1JWX0JBQ0tVUCkpKSB7CgkJCQlpbnQgdjsKCgkJCQkvKiBJZiB3ZSBhcmUgZm9yY2VkIHRvIHJldHVybiBvbmx5IG9uZSBzZXJ2ZXIsIHdlIGRvbid0IHdhbnQgdG8KCQkJCSAqIGdvIGZ1cnRoZXIsIGJlY2F1c2Ugd2Ugd291bGQgcmV0dXJuIHRoZSB3cm9uZyBvbmUgZHVlIHRvCgkJCQkgKiBkaXZpZGUgb3ZlcmZsb3cuCgkJCQkgKi8KCQkJCWlmICh0b3QgPT0gMSkgewoJCQkJCWJlc3QgPSBjdXI7CgkJCQkJLyogbm90ZSB0aGF0IGJlc3QtPndzY29yZSB3aWxsIGJlIHdyb25nIGJ1dCB3ZSBkb24ndCBjYXJlICovCgkJCQkJYnJlYWs7CgkJCQl9CgoJCQkJY3VyLT53c2NvcmUgKz0gY3VyLT5ld2VpZ2h0OwoJCQkJdiA9IChjdXItPndzY29yZSArIHRvdCkgLyB0b3Q7IC8qIHJlc3VsdCBiZXR3ZWVuIDAgYW5kIDMgKi8KCQkJCWlmIChiZXN0ID09IE5VTEwgfHwgdiA+IG1heCkgewoJCQkJCW1heCA9IHY7CgkJCQkJYmVzdCA9IGN1cjsKCQkJCX0KCQkJfQoJCX0KCQlweC0+bGJwcm0ubWFwLnNydltvXSA9IGJlc3Q7CgkJYmVzdC0+d3Njb3JlIC09IHRvdDsKCX0KCXB4LT5sYnBybS5tYXAuc3RhdGUgJj0gflBSX01BUF9SRUNBTEM7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gaXMgcmVzcG9uc2libGUgb2YgYnVpbGRpbmcgdGhlIHNlcnZlciBNQVAgZm9yIG1hcC1iYXNlZCBMQgogKiBhbGdvcml0aG1zLCBhbGxvY2F0aW5nIHRoZSBtYXAsIGFuZCBzZXR0aW5nIHAtPmxicHJtLndtdWx0IHRvIHRoZSBHQ0Qgb2YgdGhlCiAqIHdlaWdodHMgaWYgYXBwbGljYWJsZS4gSXQgc2hvdWxkIGJlIGNhbGxlZCBvbmx5IG9uY2UgcGVyIHByb3h5LCBhdCBjb25maWcKICogdGltZS4KICovCnZvaWQgaW5pdF9zZXJ2ZXJfbWFwKHN0cnVjdCBwcm94eSAqcCkKewoJc3RydWN0IHNlcnZlciAqc3J2OwoJaW50IHBnY2Q7CglpbnQgYWN0LCBiY2s7CgoJcC0+bGJwcm0uc2V0X3NlcnZlcl9zdGF0dXNfdXAgICA9IG1hcF9zZXRfc2VydmVyX3N0YXR1c191cDsKCXAtPmxicHJtLnNldF9zZXJ2ZXJfc3RhdHVzX2Rvd24gPSBtYXBfc2V0X3NlcnZlcl9zdGF0dXNfZG93bjsKCXAtPmxicHJtLnVwZGF0ZV9zZXJ2ZXJfZXdlaWdodCA9IE5VTEw7CiAKCWlmICghcC0+c3J2KQoJCXJldHVybjsKCgkvKiBXZSB3aWxsIGZhY3RvciB0aGUgd2VpZ2h0cyB0byByZWR1Y2UgdGhlIHRhYmxlLAoJICogdXNpbmcgRXVjbGlkZSdzIGxhcmdlc3QgY29tbW9uIGRpdmlzb3IgYWxnb3JpdGhtCgkgKi8KCXBnY2QgPSBwLT5zcnYtPnV3ZWlnaHQ7Cglmb3IgKHNydiA9IHAtPnNydi0+bmV4dDsgc3J2ICYmIHBnY2QgPiAxOyBzcnYgPSBzcnYtPm5leHQpIHsKCQlpbnQgdyA9IHNydi0+dXdlaWdodDsKCQl3aGlsZSAodykgewoJCQlpbnQgdCA9IHBnY2QgJSB3OwoJCQlwZ2NkID0gdzsKCQkJdyA9IHQ7CgkJfQoJfQoKCS8qIEl0IGlzIHNvbWV0aW1lcyB1c2VmdWwgdG8ga25vdyB3aGF0IGZhY3RvciB0byBhcHBseQoJICogdG8gdGhlIGJhY2tlbmQncyBlZmZlY3RpdmUgd2VpZ2h0IHRvIGtub3cgaXRzIHJlYWwKCSAqIHdlaWdodC4KCSAqLwoJcC0+bGJwcm0ud211bHQgPSBwZ2NkOwoKCWFjdCA9IGJjayA9IDA7Cglmb3IgKHNydiA9IHAtPnNydjsgc3J2OyBzcnYgPSBzcnYtPm5leHQpIHsKCQlzcnYtPmV3ZWlnaHQgPSBzcnYtPnV3ZWlnaHQgLyBwZ2NkOwoJCXNydi0+cHJldl9ld2VpZ2h0ID0gc3J2LT5ld2VpZ2h0OwoJCXNydi0+cHJldl9zdGF0ZSA9IHNydi0+c3RhdGU7CgkJaWYgKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKQoJCQliY2sgKz0gc3J2LT5ld2VpZ2h0OwoJCWVsc2UKCQkJYWN0ICs9IHNydi0+ZXdlaWdodDsKCX0KCgkvKiB0aGlzIGlzIHRoZSBsYXJnZXN0IG1hcCB3ZSB3aWxsIGV2ZXIgbmVlZCBmb3IgdGhpcyBzZXJ2ZXJzIGxpc3QgKi8KCWlmIChhY3QgPCBiY2spCgkJYWN0ID0gYmNrOwoKCXAtPmxicHJtLm1hcC5zcnYgPSAoc3RydWN0IHNlcnZlciAqKiljYWxsb2MoYWN0LCBzaXplb2Yoc3RydWN0IHNlcnZlciAqKSk7CgkvKiByZWNvdW50cyBzZXJ2ZXJzIGFuZCB0aGVpciB3ZWlnaHRzICovCglwLT5sYnBybS5tYXAuc3RhdGUgPSBQUl9NQVBfUkVDQUxDOwoJcmVjb3VudF9zZXJ2ZXJzKHApOwoJdXBkYXRlX2JhY2tlbmRfd2VpZ2h0KHApOwoJcmVjYWxjX3NlcnZlcl9tYXAocCk7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gdXBkYXRlcyB0aGUgc2VydmVyIHRyZWVzIGFjY29yZGluZyB0byBzZXJ2ZXIgPHNydj4ncyBuZXcKICogc3RhdGUuIEl0IHNob3VsZCBiZSBjYWxsZWQgd2hlbiBzZXJ2ZXIgPHNydj4ncyBzdGF0dXMgY2hhbmdlcyB0byBkb3duLgogKiBJdCBpcyBub3QgaW1wb3J0YW50IHdoZXRoZXIgdGhlIHNlcnZlciB3YXMgYWxyZWFkeSBkb3duIG9yIG5vdC4gSXQgaXMgbm90CiAqIGltcG9ydGFudCBlaXRoZXIgdGhhdCB0aGUgbmV3IHN0YXRlIGlzIGNvbXBsZXRlbHkgZG93biAodGhlIGNhbGxlciBtYXkgbm90CiAqIGtub3cgYWxsIHRoZSB2YXJpYWJsZXMgb2YgYSBzZXJ2ZXIncyBzdGF0ZSkuCiAqLwpzdGF0aWMgdm9pZCBmd3JyX3NldF9zZXJ2ZXJfc3RhdHVzX2Rvd24oc3RydWN0IHNlcnZlciAqc3J2KQp7CglzdHJ1Y3QgcHJveHkgKnAgPSBzcnYtPnByb3h5OwoJc3RydWN0IGZ3cnJfZ3JvdXAgKmdycDsKCglpZiAoc3J2LT5zdGF0ZSA9PSBzcnYtPnByZXZfc3RhdGUgJiYKCSAgICBzcnYtPmV3ZWlnaHQgPT0gc3J2LT5wcmV2X2V3ZWlnaHQpCgkJcmV0dXJuOwoKCWlmIChzcnZfaXNfdXNhYmxlKHNydi0+c3RhdGUsIHNydi0+ZXdlaWdodCkpCgkJZ290byBvdXRfdXBkYXRlX3N0YXRlOwoKCWlmICghc3J2X2lzX3VzYWJsZShzcnYtPnByZXZfc3RhdGUsIHNydi0+cHJldl9ld2VpZ2h0KSkKCQkvKiBzZXJ2ZXIgd2FzIGFscmVhZHkgZG93biAqLwoJCWdvdG8gb3V0X3VwZGF0ZV9iYWNrZW5kOwoKCWdycCA9IChzcnYtPnN0YXRlICYgU1JWX0JBQ0tVUCkgPyAmcC0+bGJwcm0uZndyci5iY2sgOiAmcC0+bGJwcm0uZndyci5hY3Q7CglncnAtPm5leHRfd2VpZ2h0IC09IHNydi0+cHJldl9ld2VpZ2h0OwoKCWlmIChzcnYtPnN0YXRlICYgU1JWX0JBQ0tVUCkgewoJCXAtPmxicHJtLnRvdF93YmNrID0gcC0+bGJwcm0uZndyci5iY2submV4dF93ZWlnaHQ7CgkJcC0+c3J2X2Jjay0tOwoKCQlpZiAoc3J2ID09IHAtPmxicHJtLmZiY2spIHsKCQkJLyogd2UgbG9zdCB0aGUgZmlyc3QgYmFja3VwIHNlcnZlciBpbiBhIHNpbmdsZS1iYWNrdXAKCQkJICogY29uZmlndXJhdGlvbiwgd2UgbXVzdCBzZWFyY2ggYW5vdGhlciBvbmUuCgkJCSAqLwoJCQlzdHJ1Y3Qgc2VydmVyICpzcnYyID0gcC0+bGJwcm0uZmJjazsKCQkJZG8gewoJCQkJc3J2MiA9IHNydjItPm5leHQ7CgkJCX0gd2hpbGUgKHNydjIgJiYKCQkJCSAhKChzcnYyLT5zdGF0ZSAmIFNSVl9CQUNLVVApICYmCgkJCQkgICBzcnZfaXNfdXNhYmxlKHNydjItPnN0YXRlLCBzcnYyLT5ld2VpZ2h0KSkpOwoJCQlwLT5sYnBybS5mYmNrID0gc3J2MjsKCQl9Cgl9IGVsc2UgewoJCXAtPmxicHJtLnRvdF93YWN0ID0gcC0+bGJwcm0uZndyci5hY3QubmV4dF93ZWlnaHQ7CgkJcC0+c3J2X2FjdC0tOwoJfQoKCWZ3cnJfZGVxdWV1ZV9zcnYoc3J2KTsKCWZ3cnJfcmVtb3ZlX2Zyb21fdHJlZShzcnYpOwoKb3V0X3VwZGF0ZV9iYWNrZW5kOgoJLyogY2hlY2svdXBkYXRlIHRvdF91c2VkLCB0b3Rfd2VpZ2h0ICovCgl1cGRhdGVfYmFja2VuZF93ZWlnaHQocCk7CiBvdXRfdXBkYXRlX3N0YXRlOgoJc3J2LT5wcmV2X3N0YXRlID0gc3J2LT5zdGF0ZTsKCXNydi0+cHJldl9ld2VpZ2h0ID0gc3J2LT5ld2VpZ2h0Owp9CgovKiBUaGlzIGZ1bmN0aW9uIHVwZGF0ZXMgdGhlIHNlcnZlciB0cmVlcyBhY2NvcmRpbmcgdG8gc2VydmVyIDxzcnY+J3MgbmV3CiAqIHN0YXRlLiBJdCBzaG91bGQgYmUgY2FsbGVkIHdoZW4gc2VydmVyIDxzcnY+J3Mgc3RhdHVzIGNoYW5nZXMgdG8gdXAuCiAqIEl0IGlzIG5vdCBpbXBvcnRhbnQgd2hldGhlciB0aGUgc2VydmVyIHdhcyBhbHJlYWR5IGRvd24gb3Igbm90LiBJdCBpcyBub3QKICogaW1wb3J0YW50IGVpdGhlciB0aGF0IHRoZSBuZXcgc3RhdGUgaXMgY29tcGxldGVseSBVUCAodGhlIGNhbGxlciBtYXkgbm90CiAqIGtub3cgYWxsIHRoZSB2YXJpYWJsZXMgb2YgYSBzZXJ2ZXIncyBzdGF0ZSkuIFRoaXMgZnVuY3Rpb24gd2lsbCBub3QgY2hhbmdlCiAqIHRoZSB3ZWlnaHQgb2YgYSBzZXJ2ZXIgd2hpY2ggd2FzIGFscmVhZHkgdXAuCiAqLwpzdGF0aWMgdm9pZCBmd3JyX3NldF9zZXJ2ZXJfc3RhdHVzX3VwKHN0cnVjdCBzZXJ2ZXIgKnNydikKewoJc3RydWN0IHByb3h5ICpwID0gc3J2LT5wcm94eTsKCXN0cnVjdCBmd3JyX2dyb3VwICpncnA7CgoJaWYgKHNydi0+c3RhdGUgPT0gc3J2LT5wcmV2X3N0YXRlICYmCgkgICAgc3J2LT5ld2VpZ2h0ID09IHNydi0+cHJldl9ld2VpZ2h0KQoJCXJldHVybjsKCglpZiAoIXNydl9pc191c2FibGUoc3J2LT5zdGF0ZSwgc3J2LT5ld2VpZ2h0KSkKCQlnb3RvIG91dF91cGRhdGVfc3RhdGU7CgoJaWYgKHNydl9pc191c2FibGUoc3J2LT5wcmV2X3N0YXRlLCBzcnYtPnByZXZfZXdlaWdodCkpCgkJLyogc2VydmVyIHdhcyBhbHJlYWR5IHVwICovCgkJZ290byBvdXRfdXBkYXRlX2JhY2tlbmQ7CgoJZ3JwID0gKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSA/ICZwLT5sYnBybS5md3JyLmJjayA6ICZwLT5sYnBybS5md3JyLmFjdDsKCWdycC0+bmV4dF93ZWlnaHQgKz0gc3J2LT5ld2VpZ2h0OwoKCWlmIChzcnYtPnN0YXRlICYgU1JWX0JBQ0tVUCkgewoJCXAtPmxicHJtLnRvdF93YmNrID0gcC0+bGJwcm0uZndyci5iY2submV4dF93ZWlnaHQ7CgkJcC0+c3J2X2JjaysrOwoKCQlpZiAocC0+bGJwcm0uZmJjaykgewoJCQkvKiB3ZSBtYXkgaGF2ZSByZXN0b3JlZCBhIGJhY2t1cCBzZXJ2ZXIgcHJpb3IgdG8gZmJjaywKCQkJICogaW4gd2hpY2ggY2FzZSBpdCBzaG91bGQgcmVwbGFjZSBpdC4KCQkJICovCgkJCXN0cnVjdCBzZXJ2ZXIgKnNydjIgPSBzcnY7CgkJCWRvIHsKCQkJCXNydjIgPSBzcnYyLT5uZXh0OwoJCQl9IHdoaWxlIChzcnYyICYmIChzcnYyICE9IHAtPmxicHJtLmZiY2spKTsKCQkJaWYgKHNydjIpCgkJCQlwLT5sYnBybS5mYmNrID0gc3J2OwoJCX0KCX0gZWxzZSB7CgkJcC0+bGJwcm0udG90X3dhY3QgPSBwLT5sYnBybS5md3JyLmFjdC5uZXh0X3dlaWdodDsKCQlwLT5zcnZfYWN0Kys7Cgl9CgoJLyogbm90ZSB0aGF0IGV3ZWlnaHQgY2Fubm90IGJlIDAgaGVyZSAqLwoJZndycl9nZXRfc3J2KHNydik7CglzcnYtPm5wb3MgPSBncnAtPmN1cnJfcG9zICsgKGdycC0+bmV4dF93ZWlnaHQgKyBncnAtPmN1cnJfd2VpZ2h0IC0gZ3JwLT5jdXJyX3BvcykgLyBzcnYtPmV3ZWlnaHQ7Cglmd3JyX3F1ZXVlX3NydihzcnYpOwoKb3V0X3VwZGF0ZV9iYWNrZW5kOgoJLyogY2hlY2svdXBkYXRlIHRvdF91c2VkLCB0b3Rfd2VpZ2h0ICovCgl1cGRhdGVfYmFja2VuZF93ZWlnaHQocCk7CiBvdXRfdXBkYXRlX3N0YXRlOgoJc3J2LT5wcmV2X3N0YXRlID0gc3J2LT5zdGF0ZTsKCXNydi0+cHJldl9ld2VpZ2h0ID0gc3J2LT5ld2VpZ2h0Owp9CgovKiBUaGlzIGZ1bmN0aW9uIG11c3QgYmUgY2FsbGVkIGFmdGVyIGFuIHVwZGF0ZSB0byBzZXJ2ZXIgPHNydj4ncyBlZmZlY3RpdmUKICogd2VpZ2h0LiBJdCBtYXkgYmUgY2FsbGVkIGFmdGVyIGEgc3RhdGUgY2hhbmdlIHRvby4KICovCnN0YXRpYyB2b2lkIGZ3cnJfdXBkYXRlX3NlcnZlcl93ZWlnaHQoc3RydWN0IHNlcnZlciAqc3J2KQp7CglpbnQgb2xkX3N0YXRlLCBuZXdfc3RhdGU7CglzdHJ1Y3QgcHJveHkgKnAgPSBzcnYtPnByb3h5OwoJc3RydWN0IGZ3cnJfZ3JvdXAgKmdycDsKCglpZiAoc3J2LT5zdGF0ZSA9PSBzcnYtPnByZXZfc3RhdGUgJiYKCSAgICBzcnYtPmV3ZWlnaHQgPT0gc3J2LT5wcmV2X2V3ZWlnaHQpCgkJcmV0dXJuOwoKCS8qIElmIGNoYW5naW5nIHRoZSBzZXJ2ZXIncyB3ZWlnaHQgY2hhbmdlcyBpdHMgc3RhdGUsIHdlIHNpbXBseSBhcHBseQoJICogdGhlIHByb2NlZHVyZXMgd2UgYWxyZWFkeSBoYXZlIGZvciBzdGF0dXMgY2hhbmdlLiBJZiB0aGUgc3RhdGUKCSAqIHJlbWFpbnMgZG93biwgdGhlIHNlcnZlciBpcyBub3QgaW4gYW55IHRyZWUsIHNvIGl0J3MgYXMgZWFzeSBhcwoJICogdXBkYXRpbmcgaXRzIHZhbHVlcy4gSWYgdGhlIHN0YXRlIHJlbWFpbnMgdXAgd2l0aCBkaWZmZXJlbnQgd2VpZ2h0cywKCSAqIHRoZXJlIGFyZSBzb21lIGNvbXB1dGF0aW9ucyB0byBwZXJmb3JtIHRvIGZpbmQgYSBuZXcgcGxhY2UgYW5kCgkgKiBwb3NzaWJseSBhIG5ldyB0cmVlIGZvciB0aGlzIHNlcnZlci4KCSAqLwoJIAoJb2xkX3N0YXRlID0gc3J2X2lzX3VzYWJsZShzcnYtPnByZXZfc3RhdGUsIHNydi0+cHJldl9ld2VpZ2h0KTsKCW5ld19zdGF0ZSA9IHNydl9pc191c2FibGUoc3J2LT5zdGF0ZSwgc3J2LT5ld2VpZ2h0KTsKCglpZiAoIW9sZF9zdGF0ZSAmJiAhbmV3X3N0YXRlKSB7CgkJc3J2LT5wcmV2X3N0YXRlID0gc3J2LT5zdGF0ZTsKCQlzcnYtPnByZXZfZXdlaWdodCA9IHNydi0+ZXdlaWdodDsKCQlyZXR1cm47Cgl9CgllbHNlIGlmICghb2xkX3N0YXRlICYmIG5ld19zdGF0ZSkgewoJCWZ3cnJfc2V0X3NlcnZlcl9zdGF0dXNfdXAoc3J2KTsKCQlyZXR1cm47Cgl9CgllbHNlIGlmIChvbGRfc3RhdGUgJiYgIW5ld19zdGF0ZSkgewoJCWZ3cnJfc2V0X3NlcnZlcl9zdGF0dXNfZG93bihzcnYpOwoJCXJldHVybjsKCX0KCglncnAgPSAoc3J2LT5zdGF0ZSAmIFNSVl9CQUNLVVApID8gJnAtPmxicHJtLmZ3cnIuYmNrIDogJnAtPmxicHJtLmZ3cnIuYWN0OwoJZ3JwLT5uZXh0X3dlaWdodCA9IGdycC0+bmV4dF93ZWlnaHQgLSBzcnYtPnByZXZfZXdlaWdodCArIHNydi0+ZXdlaWdodDsKCglwLT5sYnBybS50b3Rfd2FjdCA9IHAtPmxicHJtLmZ3cnIuYWN0Lm5leHRfd2VpZ2h0OwoJcC0+bGJwcm0udG90X3diY2sgPSBwLT5sYnBybS5md3JyLmJjay5uZXh0X3dlaWdodDsKCglpZiAoc3J2LT5sYl90cmVlID09IGdycC0+aW5pdCkgewoJCWZ3cnJfZGVxdWV1ZV9zcnYoc3J2KTsKCQlmd3JyX3F1ZXVlX2J5X3dlaWdodChncnAtPmluaXQsIHNydik7Cgl9CgllbHNlIGlmICghc3J2LT5sYl90cmVlKSB7CgkJLyogRklYTUU6IHNlcnZlciB3YXMgZG93bi4gVGhpcyBpcyBub3QgcG9zc2libGUgcmlnaHQgbm93IGJ1dAoJCSAqIG1heSBiZSBuZWVkZWQgc29vbiBmb3Igc2xvd3N0YXJ0IG9yIGdyYWNlZnVsIHNodXRkb3duLgoJCSAqLwoJCWZ3cnJfZGVxdWV1ZV9zcnYoc3J2KTsKCQlmd3JyX2dldF9zcnYoc3J2KTsKCQlzcnYtPm5wb3MgPSBncnAtPmN1cnJfcG9zICsgKGdycC0+bmV4dF93ZWlnaHQgKyBncnAtPmN1cnJfd2VpZ2h0IC0gZ3JwLT5jdXJyX3BvcykgLyBzcnYtPmV3ZWlnaHQ7CgkJZndycl9xdWV1ZV9zcnYoc3J2KTsKCX0gZWxzZSB7CgkJLyogVGhlIHNlcnZlciBpcyBlaXRoZXIgYWN0aXZlIG9yIGluIHRoZSBuZXh0IHF1ZXVlLiBJZiBpdCdzCgkJICogc3RpbGwgaW4gdGhlIGFjdGl2ZSBxdWV1ZSBhbmQgaXQgaGFzIG5vdCBjb25zdW1lZCBhbGwgb2YgaXRzCgkJICogcGxhY2VzLCBsZXQncyBhZGp1c3QgaXRzIG5leHQgcG9zaXRpb24uCgkJICovCgkJZndycl9nZXRfc3J2KHNydik7CgoJCWlmIChzcnYtPmV3ZWlnaHQgPiAwKSB7CgkJCWludCBwcmV2X25leHQgPSBzcnYtPm5wb3M7CgkJCWludCBzdGVwID0gZ3JwLT5uZXh0X3dlaWdodCAvIHNydi0+ZXdlaWdodDsKCgkJCXNydi0+bnBvcyA9IHNydi0+bHBvcyArIHN0ZXA7CgkJCXNydi0+cndlaWdodCA9IDA7CgoJCQlpZiAoc3J2LT5ucG9zID4gcHJldl9uZXh0KQoJCQkJc3J2LT5ucG9zID0gcHJldl9uZXh0OwoJCQlpZiAoc3J2LT5ucG9zIDwgZ3JwLT5jdXJyX3BvcyArIDIpCgkJCQlzcnYtPm5wb3MgPSBncnAtPmN1cnJfcG9zICsgc3RlcDsKCQl9IGVsc2UgewoJCQkvKiBwdXNoIGl0IGludG8gdGhlIG5leHQgdHJlZSAqLwoJCQlzcnYtPm5wb3MgPSBncnAtPmN1cnJfcG9zICsgZ3JwLT5jdXJyX3dlaWdodDsKCQl9CgoJCWZ3cnJfZGVxdWV1ZV9zcnYoc3J2KTsKCQlmd3JyX3F1ZXVlX3NydihzcnYpOwoJfQoKCXVwZGF0ZV9iYWNrZW5kX3dlaWdodChwKTsKCXNydi0+cHJldl9zdGF0ZSA9IHNydi0+c3RhdGU7CglzcnYtPnByZXZfZXdlaWdodCA9IHNydi0+ZXdlaWdodDsKfQoKLyogUmVtb3ZlIGEgc2VydmVyIGZyb20gYSB0cmVlLiBJdCBtdXN0IGhhdmUgcHJldmlvdXNseSBiZWVuIGRlcXVldWVkLiBUaGlzCiAqIGZ1bmN0aW9uIGlzIG1lYW50IHRvIGJlIGNhbGxlZCB3aGVuIGEgc2VydmVyIGlzIGdvaW5nIGRvd24gb3IgaGFzIGl0cwogKiB3ZWlnaHQgZGlzYWJsZWQuCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9yZW1vdmVfZnJvbV90cmVlKHN0cnVjdCBzZXJ2ZXIgKnMpCnsKCXMtPmxiX3RyZWUgPSBOVUxMOwp9CgovKiBRdWV1ZSBhIHNlcnZlciBpbiB0aGUgd2VpZ2h0IHRyZWUgPHJvb3Q+LCBhc3N1bWluZyB0aGUgd2VpZ2h0IGlzID4wLgogKiBXZSB3YW50IHRvIHNvcnQgdGhlbSBieSBpbnZlcnRlZCB3ZWlnaHRzLCBiZWNhdXNlIHdlIG5lZWQgdG8gcGxhY2UKICogaGVhdnkgc2VydmVycyBmaXJzdCBpbiBvcmRlciB0byBnZXQgYSBzbW9vdGggZGlzdHJpYnV0aW9uLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZ3cnJfcXVldWVfYnlfd2VpZ2h0KHN0cnVjdCBlYl9yb290ICpyb290LCBzdHJ1Y3Qgc2VydmVyICpzKQp7CglzLT5sYl9ub2RlLmtleSA9IFNSVl9FV0dIVF9NQVggLSBzLT5ld2VpZ2h0OwoJZWIzMl9pbnNlcnQocm9vdCwgJnMtPmxiX25vZGUpOwoJcy0+bGJfdHJlZSA9IHJvb3Q7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gaXMgcmVzcG9uc2libGUgZm9yIGJ1aWxkaW5nIHRoZSB3ZWlnaHQgdHJlZXMgaW4gY2FzZSBvZiBmYXN0CiAqIHdlaWdodGVkIHJvdW5kLXJvYmluLiBJdCBhbHNvIHNldHMgcC0+bGJwcm0ud2RpdiB0byB0aGUgZXdlaWdodCB0byB1d2VpZ2h0CiAqIHJhdGlvLiBCb3RoIGFjdGl2ZSBhbmQgYmFja3VwIGdyb3VwcyBhcmUgaW5pdGlhbGl6ZWQuCiAqLwp2b2lkIGZ3cnJfaW5pdF9zZXJ2ZXJfZ3JvdXBzKHN0cnVjdCBwcm94eSAqcCkKewoJc3RydWN0IHNlcnZlciAqc3J2OwoJc3RydWN0IGViX3Jvb3QgaW5pdF9oZWFkID0gRUJfUk9PVDsKCglwLT5sYnBybS5zZXRfc2VydmVyX3N0YXR1c191cCAgID0gZndycl9zZXRfc2VydmVyX3N0YXR1c191cDsKCXAtPmxicHJtLnNldF9zZXJ2ZXJfc3RhdHVzX2Rvd24gPSBmd3JyX3NldF9zZXJ2ZXJfc3RhdHVzX2Rvd247CglwLT5sYnBybS51cGRhdGVfc2VydmVyX2V3ZWlnaHQgID0gZndycl91cGRhdGVfc2VydmVyX3dlaWdodDsKCglwLT5sYnBybS53ZGl2ID0gQkVfV0VJR0hUX1NDQUxFOwoJZm9yIChzcnYgPSBwLT5zcnY7IHNydjsgc3J2ID0gc3J2LT5uZXh0KSB7CgkJc3J2LT5wcmV2X2V3ZWlnaHQgPSBzcnYtPmV3ZWlnaHQgPSBzcnYtPnV3ZWlnaHQgKiBCRV9XRUlHSFRfU0NBTEU7CgkJc3J2LT5wcmV2X3N0YXRlID0gc3J2LT5zdGF0ZTsKCX0KCglyZWNvdW50X3NlcnZlcnMocCk7Cgl1cGRhdGVfYmFja2VuZF93ZWlnaHQocCk7CgoJLyogcHJlcGFyZSB0aGUgYWN0aXZlIHNlcnZlcnMgZ3JvdXAgKi8KCXAtPmxicHJtLmZ3cnIuYWN0LmN1cnJfcG9zID0gcC0+bGJwcm0uZndyci5hY3QuY3Vycl93ZWlnaHQgPQoJCXAtPmxicHJtLmZ3cnIuYWN0Lm5leHRfd2VpZ2h0ID0gcC0+bGJwcm0udG90X3dhY3Q7CglwLT5sYnBybS5md3JyLmFjdC5jdXJyID0gcC0+bGJwcm0uZndyci5hY3QudDAgPQoJCXAtPmxicHJtLmZ3cnIuYWN0LnQxID0gaW5pdF9oZWFkOwoJcC0+bGJwcm0uZndyci5hY3QuaW5pdCA9ICZwLT5sYnBybS5md3JyLmFjdC50MDsKCXAtPmxicHJtLmZ3cnIuYWN0Lm5leHQgPSAmcC0+bGJwcm0uZndyci5hY3QudDE7CgoJLyogcHJlcGFyZSB0aGUgYmFja3VwIHNlcnZlcnMgZ3JvdXAgKi8KCXAtPmxicHJtLmZ3cnIuYmNrLmN1cnJfcG9zID0gcC0+bGJwcm0uZndyci5iY2suY3Vycl93ZWlnaHQgPQoJCXAtPmxicHJtLmZ3cnIuYmNrLm5leHRfd2VpZ2h0ID0gcC0+bGJwcm0udG90X3diY2s7CglwLT5sYnBybS5md3JyLmJjay5jdXJyID0gcC0+bGJwcm0uZndyci5iY2sudDAgPQoJCXAtPmxicHJtLmZ3cnIuYmNrLnQxID0gaW5pdF9oZWFkOwoJcC0+bGJwcm0uZndyci5iY2suaW5pdCA9ICZwLT5sYnBybS5md3JyLmJjay50MDsKCXAtPmxicHJtLmZ3cnIuYmNrLm5leHQgPSAmcC0+bGJwcm0uZndyci5iY2sudDE7CgoJLyogcXVldWUgYWN0aXZlIGFuZCBiYWNrdXAgc2VydmVycyBpbiB0d28gZGlzdGluY3QgZ3JvdXBzICovCglmb3IgKHNydiA9IHAtPnNydjsgc3J2OyBzcnYgPSBzcnYtPm5leHQpIHsKCQlpZiAoIXNydl9pc191c2FibGUoc3J2LT5zdGF0ZSwgc3J2LT5ld2VpZ2h0KSkKCQkJY29udGludWU7CgkJZndycl9xdWV1ZV9ieV93ZWlnaHQoKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSA/CgkJCQlwLT5sYnBybS5md3JyLmJjay5pbml0IDoKCQkJCXAtPmxicHJtLmZ3cnIuYWN0LmluaXQsCgkJCQlzcnYpOwoJfQp9CgovKiBzaW1wbHkgcmVtb3ZlcyBhIHNlcnZlciBmcm9tIGEgd2VpZ2h0IHRyZWUgKi8Kc3RhdGljIGlubGluZSB2b2lkIGZ3cnJfZGVxdWV1ZV9zcnYoc3RydWN0IHNlcnZlciAqcykKewoJZWIzMl9kZWxldGUoJnMtPmxiX25vZGUpOwp9CgovKiBxdWV1ZXMgYSBzZXJ2ZXIgaW50byB0aGUgYXBwcm9wcmlhdGUgZ3JvdXAgYW5kIHRyZWUgZGVwZW5kaW5nIG9uIGl0cwogKiBiYWNrdXAgc3RhdHVzLCBhbmQgLT5ucG9zLiBJZiB0aGUgc2VydmVyIGlzIGRpc2FibGVkLCBzaW1wbHkgYXNzaWduCiAqIGl0IHRvIHRoZSBOVUxMIHRyZWUuCiAqLwpzdGF0aWMgdm9pZCBmd3JyX3F1ZXVlX3NydihzdHJ1Y3Qgc2VydmVyICpzKQp7CglzdHJ1Y3QgcHJveHkgKnAgPSBzLT5wcm94eTsKCXN0cnVjdCBmd3JyX2dyb3VwICpncnA7CgoJZ3JwID0gKHMtPnN0YXRlICYgU1JWX0JBQ0tVUCkgPyAmcC0+bGJwcm0uZndyci5iY2sgOiAmcC0+bGJwcm0uZndyci5hY3Q7CgkKCS8qIERlbGF5IGV2ZXJ5dGhpbmcgd2hpY2ggZG9lcyBub3QgZml0IGludG8gdGhlIHdpbmRvdyBhbmQgZXZlcnl0aGluZwoJICogd2hpY2ggZG9lcyBub3QgZml0IGludG8gdGhlIHRoZW9yaWNhbCBuZXcgd2luZG93LgoJICovCglpZiAoIXNydl9pc191c2FibGUocy0+c3RhdGUsIHMtPmV3ZWlnaHQpKSB7CgkJZndycl9yZW1vdmVfZnJvbV90cmVlKHMpOwoJfQoJZWxzZSBpZiAocy0+ZXdlaWdodCA8PSAwIHx8CgkJIHMtPm5wb3MgPj0gMiAqIGdycC0+Y3Vycl93ZWlnaHQgfHwKCQkgcy0+bnBvcyA+PSBncnAtPmN1cnJfd2VpZ2h0ICsgZ3JwLT5uZXh0X3dlaWdodCkgewoJCS8qIHB1dCBpbnRvIG5leHQgdHJlZSwgYW5kIHJlYWRqdXN0IG5wb3MgaW4gY2FzZSB3ZSBjb3VsZAoJCSAqIGZpbmFsbHkgdGFrZSB0aGlzIGJhY2sgdG8gY3VycmVudC4gKi8KCQlzLT5ucG9zIC09IGdycC0+Y3Vycl93ZWlnaHQ7CgkJZndycl9xdWV1ZV9ieV93ZWlnaHQoZ3JwLT5uZXh0LCBzKTsKCX0KCWVsc2UgewoJCS8qIFRoZSBzb3J0aW5nIGtleSBpcyBzdG9yZWQgaW4gdW5pdHMgb2Ygcy0+bnBvcyAqIHVzZXJfd2VpZ2h0CgkJICogaW4gb3JkZXIgdG8gYXZvaWQgb3ZlcmZsb3dzLiBBcyBzdGF0ZWQgaW4gYmFja2VuZC5oLCB0aGUKCQkgKiBsb3dlciB0aGUgc2NhbGUsIHRoZSByb3VnaGVyIHRoZSB3ZWlnaHRzIG1vZHVsYXRpb24sIGFuZCB0aGUKCQkgKiBoaWdoZXIgdGhlIHNjYWxlLCB0aGUgbG93ZXIgdGhlIG51bWJlciBvZiBzZXJ2ZXJzIHdpdGhvdXQKCQkgKiBvdmVyZmxvdy4gV2l0aCB0aGlzIGZvcm11bGEsIHRoZSByZXN1bHQgaXMgYWx3YXlzIHBvc2l0aXZlLAoJCSAqIHNvIHdlIGNhbiB1c2UgZWIz6V9pbnNlcnQoKS4KCQkgKi8KCQlzLT5sYl9ub2RlLmtleSA9IFNSVl9VV0dIVF9SQU5HRSAqIHMtPm5wb3MgKwoJCQkodW5zaWduZWQpKFNSVl9FV0dIVF9NQVggKyBzLT5yd2VpZ2h0IC0gcy0+ZXdlaWdodCkgLyBCRV9XRUlHSFRfU0NBTEU7CgoJCWViMzJfaW5zZXJ0KCZncnAtPmN1cnIsICZzLT5sYl9ub2RlKTsKCQlzLT5sYl90cmVlID0gJmdycC0+Y3VycjsKCX0KfQoKLyogcHJlcGFyZXMgYSBzZXJ2ZXIgd2hlbiBleHRyYWN0aW5nIGl0IGZyb20gdGhlICJpbml0IiB0cmVlICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmd3JyX2dldF9zcnZfaW5pdChzdHJ1Y3Qgc2VydmVyICpzKQp7CglzLT5ucG9zID0gcy0+cndlaWdodCA9IDA7Cn0KCi8qIHByZXBhcmVzIGEgc2VydmVyIHdoZW4gZXh0cmFjdGluZyBpdCBmcm9tIHRoZSAibmV4dCIgdHJlZSAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9nZXRfc3J2X25leHQoc3RydWN0IHNlcnZlciAqcykKewoJc3RydWN0IGZ3cnJfZ3JvdXAgKmdycCA9IChzLT5zdGF0ZSAmIFNSVl9CQUNLVVApID8KCQkmcy0+cHJveHktPmxicHJtLmZ3cnIuYmNrIDoKCQkmcy0+cHJveHktPmxicHJtLmZ3cnIuYWN0OwoKCXMtPm5wb3MgKz0gZ3JwLT5jdXJyX3dlaWdodDsKfQoKLyogcHJlcGFyZXMgYSBzZXJ2ZXIgd2hlbiBpdCB3YXMgbWFya2VkIGRvd24gKi8Kc3RhdGljIGlubGluZSB2b2lkIGZ3cnJfZ2V0X3Nydl9kb3duKHN0cnVjdCBzZXJ2ZXIgKnMpCnsKCXN0cnVjdCBmd3JyX2dyb3VwICpncnAgPSAocy0+c3RhdGUgJiBTUlZfQkFDS1VQKSA/CgkJJnMtPnByb3h5LT5sYnBybS5md3JyLmJjayA6CgkJJnMtPnByb3h5LT5sYnBybS5md3JyLmFjdDsKCglzLT5ucG9zID0gZ3JwLT5jdXJyX3BvczsKfQoKLyogcHJlcGFyZXMgYSBzZXJ2ZXIgd2hlbiBleHRyYWN0aW5nIGl0IGZyb20gaXRzIHRyZWUgKi8Kc3RhdGljIHZvaWQgZndycl9nZXRfc3J2KHN0cnVjdCBzZXJ2ZXIgKnMpCnsKCXN0cnVjdCBwcm94eSAqcCA9IHMtPnByb3h5OwoJc3RydWN0IGZ3cnJfZ3JvdXAgKmdycCA9IChzLT5zdGF0ZSAmIFNSVl9CQUNLVVApID8KCQkmcC0+bGJwcm0uZndyci5iY2sgOgoJCSZwLT5sYnBybS5md3JyLmFjdDsKCglpZiAocy0+bGJfdHJlZSA9PSBncnAtPmluaXQpIHsKCQlmd3JyX2dldF9zcnZfaW5pdChzKTsKCX0KCWVsc2UgaWYgKHMtPmxiX3RyZWUgPT0gZ3JwLT5uZXh0KSB7CgkJZndycl9nZXRfc3J2X25leHQocyk7Cgl9CgllbHNlIGlmIChzLT5sYl90cmVlID09IE5VTEwpIHsKCQlmd3JyX2dldF9zcnZfZG93bihzKTsKCX0KfQoKLyogc3dpdGNoZXMgdHJlZXMgImluaXQiIGFuZCAibmV4dCIgZm9yIEZXUlIgZ3JvdXAgPGdycD4uICJpbml0IiBzaG91bGQgYmUgZW1wdHkKICogd2hlbiB0aGlzIGhhcHBlbnMsIGFuZCAibmV4dCIgZmlsbGVkIHdpdGggc2VydmVycyBzb3J0ZWQgYnkgd2VpZ2h0cy4KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmd3JyX3N3aXRjaF90cmVlcyhzdHJ1Y3QgZndycl9ncm91cCAqZ3JwKQp7CglzdHJ1Y3QgZWJfcm9vdCAqc3dhcDsKCXN3YXAgPSBncnAtPmluaXQ7CglncnAtPmluaXQgPSBncnAtPm5leHQ7CglncnAtPm5leHQgPSBzd2FwOwoJZ3JwLT5jdXJyX3dlaWdodCA9IGdycC0+bmV4dF93ZWlnaHQ7CglncnAtPmN1cnJfcG9zID0gZ3JwLT5jdXJyX3dlaWdodDsKfQoKLyogcmV0dXJuIG5leHQgc2VydmVyIGZyb20gdGhlIGN1cnJlbnQgdHJlZSBpbiBGV1JSIGdyb3VwIDxncnA+LCBvciBhIHNlcnZlcgogKiBmcm9tIHRoZSAiaW5pdCIgdHJlZSBpZiBhcHByb3ByaWF0ZS4gSWYgYm90aCB0cmVlcyBhcmUgZW1wdHksIHJldHVybiBOVUxMLgogKi8Kc3RhdGljIHN0cnVjdCBzZXJ2ZXIgKmZ3cnJfZ2V0X3NlcnZlcl9mcm9tX2dyb3VwKHN0cnVjdCBmd3JyX2dyb3VwICpncnApCnsKCXN0cnVjdCBlYjMyX25vZGUgKm5vZGU7CglzdHJ1Y3Qgc2VydmVyICpzOwoKCW5vZGUgPSBlYjMyX2ZpcnN0KCZncnAtPmN1cnIpOwoJcyA9IGViMzJfZW50cnkobm9kZSwgc3RydWN0IHNlcnZlciwgbGJfbm9kZSk7CgkKCWlmICghbm9kZSB8fCBzLT5ucG9zID4gZ3JwLT5jdXJyX3BvcykgewoJCS8qIGVpdGhlciB3ZSBoYXZlIG5vIHNlcnZlciBsZWZ0LCBvciB3ZSBoYXZlIGEgaG9sZSAqLwoJCXN0cnVjdCBlYjMyX25vZGUgKm5vZGUyOwoJCW5vZGUyID0gZWIzMl9maXJzdChncnAtPmluaXQpOwoJCWlmIChub2RlMikgewoJCQlub2RlID0gbm9kZTI7CgkJCXMgPSBlYjMyX2VudHJ5KG5vZGUsIHN0cnVjdCBzZXJ2ZXIsIGxiX25vZGUpOwoJCQlmd3JyX2dldF9zcnZfaW5pdChzKTsKCQkJaWYgKHMtPmV3ZWlnaHQgPT0gMCkgLyogRklYTUU6IGlzIGl0IHBvc3NpYmxlIGF0IGFsbCA/ICovCgkJCQlub2RlID0gTlVMTDsKCQl9Cgl9CglpZiAobm9kZSkKCQlyZXR1cm4gczsKCWVsc2UKCQlyZXR1cm4gTlVMTDsKfQoKLyogQ29tcHV0ZXMgbmV4dCBwb3NpdGlvbiBvZiBzZXJ2ZXIgPHM+IGluIHRoZSBncm91cC4gSXQgaXMgbWFuZGF0b3J5IGZvciA8cz4KICogdG8gaGF2ZSBhIG5vbi16ZXJvLCBwb3NpdGl2ZSBld2VpZ2h0LgoqLwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl91cGRhdGVfcG9zaXRpb24oc3RydWN0IGZ3cnJfZ3JvdXAgKmdycCwgc3RydWN0IHNlcnZlciAqcykKewoJaWYgKCFzLT5ucG9zKSB7CgkJLyogZmlyc3QgdGltZSBldmVyIGZvciB0aGlzIHNlcnZlciAqLwoJCXMtPmxwb3MgPSBncnAtPmN1cnJfcG9zOwoJCXMtPm5wb3MgPSBncnAtPmN1cnJfcG9zICsgZ3JwLT5uZXh0X3dlaWdodCAvIHMtPmV3ZWlnaHQ7CgkJcy0+cndlaWdodCArPSBncnAtPm5leHRfd2VpZ2h0ICUgcy0+ZXdlaWdodDsKCgkJaWYgKHMtPnJ3ZWlnaHQgPj0gcy0+ZXdlaWdodCkgewoJCQlzLT5yd2VpZ2h0IC09IHMtPmV3ZWlnaHQ7CgkJCXMtPm5wb3MrKzsKCQl9Cgl9IGVsc2UgewoJCXMtPmxwb3MgPSBzLT5ucG9zOwoJCXMtPm5wb3MgKz0gZ3JwLT5uZXh0X3dlaWdodCAvIHMtPmV3ZWlnaHQ7CgkJcy0+cndlaWdodCArPSBncnAtPm5leHRfd2VpZ2h0ICUgcy0+ZXdlaWdodDsKCgkJaWYgKHMtPnJ3ZWlnaHQgPj0gcy0+ZXdlaWdodCkgewoJCQlzLT5yd2VpZ2h0IC09IHMtPmV3ZWlnaHQ7CgkJCXMtPm5wb3MrKzsKCQl9Cgl9Cn0KCi8qIFJldHVybiBuZXh0IHNlcnZlciBmcm9tIHRoZSBjdXJyZW50IHRyZWUgaW4gYmFja2VuZCA8cD4sIG9yIGEgc2VydmVyIGZyb20KICogdGhlIGluaXQgdHJlZSBpZiBhcHByb3ByaWF0ZS4gSWYgYm90aCB0cmVlcyBhcmUgZW1wdHksIHJldHVybiBOVUxMLgogKiBTYXR1cmF0ZWQgc2VydmVycyBhcmUgc2tpcHBlZCBhbmQgcmVxdWV1ZWQuCiAqLwpzdGF0aWMgc3RydWN0IHNlcnZlciAqZndycl9nZXRfbmV4dF9zZXJ2ZXIoc3RydWN0IHByb3h5ICpwKQp7CglzdHJ1Y3Qgc2VydmVyICpzcnY7CglzdHJ1Y3QgZndycl9ncm91cCAqZ3JwOwoJc3RydWN0IHNlcnZlciAqZnVsbDsKCWludCBzd2l0Y2hlZDsKCglpZiAocC0+c3J2X2FjdCkKCQlncnAgPSAmcC0+bGJwcm0uZndyci5hY3Q7CgllbHNlIGlmIChwLT5sYnBybS5mYmNrKQoJCXJldHVybiBwLT5sYnBybS5mYmNrOwoJZWxzZSBpZiAocC0+c3J2X2JjaykKCQlncnAgPSAmcC0+bGJwcm0uZndyci5iY2s7CgllbHNlCgkJcmV0dXJuIE5VTEw7CgoJc3dpdGNoZWQgPSAwOwoJZnVsbCA9IE5VTEw7IC8qIE5VTEwtdGVybWluYXRlZCBsaXN0IG9mIHNhdHVyYXRlZCBzZXJ2ZXJzICovCgl3aGlsZSAoMSkgewoJCS8qIGlmIHdlIHNlZSBhbiBlbXB0eSBncm91cCwgbGV0J3MgZmlyc3QgdHJ5IHRvIGNvbGxlY3Qgd2VpZ2h0cwoJCSAqIHdoaWNoIG1pZ2h0IGhhdmUgcmVjZW50bHkgY2hhbmdlZC4KCQkgKi8KCQlpZiAoIWdycC0+Y3Vycl93ZWlnaHQpCgkJCWdycC0+Y3Vycl9wb3MgPSBncnAtPmN1cnJfd2VpZ2h0ID0gZ3JwLT5uZXh0X3dlaWdodDsKCgkJLyogZ2V0IGZpcnN0IHNlcnZlciBmcm9tIHRoZSAiY3VycmVudCIgdHJlZS4gV2hlbiB0aGUgZW5kIG9mCgkJICogdGhlIHRyZWUgaXMgcmVhY2hlZCwgd2UgbWF5IGhhdmUgdG8gc3dpdGNoLCBidXQgb25seSBvbmNlLgoJCSAqLwoJCXdoaWxlICgxKSB7CgkJCXNydiA9IGZ3cnJfZ2V0X3NlcnZlcl9mcm9tX2dyb3VwKGdycCk7CgkJCWlmIChzcnYpCgkJCQlicmVhazsKCQkJaWYgKHN3aXRjaGVkKQoJCQkJZ290byByZXF1ZXVlX3NlcnZlcnM7CgkJCXN3aXRjaGVkID0gMTsKCQkJZndycl9zd2l0Y2hfdHJlZXMoZ3JwKTsKCgkJfQoKCQkvKiBPSywgd2UgaGF2ZSBhIHNlcnZlci4gSG93ZXZlciwgaXQgbWF5IGJlIHNhdHVyYXRlZCwgaW4gd2hpY2gKCQkgKiBjYXNlIHdlIGRvbid0IHdhbnQgdG8gcmVjb25zaWRlciBpdCBmb3Igbm93LiBXZSdsbCB1cGRhdGUKCQkgKiBpdHMgcG9zaXRpb24gYW5kIGRlcXVldWUgaXQgYW55d2F5LCBzbyB0aGF0IHdlIGNhbiBtb3ZlIGl0CgkJICogdG8gYSBiZXR0ZXIgcGxhY2UgYWZ0ZXJ3YXJkcy4KCQkgKi8KCQlmd3JyX3VwZGF0ZV9wb3NpdGlvbihncnAsIHNydik7CgkJZndycl9kZXF1ZXVlX3NydihzcnYpOwoJCWdycC0+Y3Vycl9wb3MrKzsKCQlpZiAoIXNydi0+bWF4Y29ubiB8fCBzcnYtPmN1cl9zZXNzIDwgc3J2X2R5bmFtaWNfbWF4Y29ubihzcnYpKQoJCQlicmVhazsKCgkJLyogdGhlIHNlcnZlciBpcyBzYXR1cmF0ZWQsIGxldCdzIGNoYWluIGl0IGZvciBsYXRlciByZWluc2VydGlvbiAqLwoJCXNydi0+bmV4dF9mdWxsID0gZnVsbDsKCQlmdWxsID0gc3J2OwoJfQoKCS8qIE9LLCB3ZSBnb3QgdGhlIGJlc3Qgc2VydmVyLCBsZXQncyB1cGRhdGUgaXQgKi8KCWZ3cnJfcXVldWVfc3J2KHNydik7CgogcmVxdWV1ZV9zZXJ2ZXJzOgoJaWYgKHVubGlrZWx5KGZ1bGwgIT0gTlVMTCkpIHsKCQlpZiAoc3dpdGNoZWQpIHsKCQkJLyogdGhlIHRyZWUgaGFzIHN3aXRjaGVkLCByZXF1ZXVlIGFsbCBleHRyYWN0ZWQgc2VydmVycwoJCQkgKiBpbnRvICJpbml0IiwgYmVjYXVzZSB0aGVpciBwbGFjZSB3YXMgbG9zdCwgYW5kIG9ubHkKCQkJICogdGhlaXIgd2VpZ2h0IG1hdHRlcnMuCgkJCSAqLwoJCQlkbyB7CgkJCQlmd3JyX3F1ZXVlX2J5X3dlaWdodChncnAtPmluaXQsIGZ1bGwpOwoJCQkJZnVsbCA9IGZ1bGwtPm5leHRfZnVsbDsKCQkJfSB3aGlsZSAoZnVsbCk7CgkJfSBlbHNlIHsKCQkJLyogcmVxdWV1ZSBhbGwgZXh0cmFjdGVkIHNlcnZlcnMganVzdCBhcyBpZiB0aGV5IHdlcmUgY29uc3VtZWQKCQkJICogc28gdGhhdCB0aGV5IHJlZ2FpbiB0aGVpciBleHBlY3RlZCBwbGFjZS4KCQkJICovCgkJCWRvIHsKCQkJCWZ3cnJfcXVldWVfc3J2KGZ1bGwpOwoJCQkJZnVsbCA9IGZ1bGwtPm5leHRfZnVsbDsKCQkJfSB3aGlsZSAoZnVsbCk7CgkJfQoJfQoJcmV0dXJuIHNydjsKfQoKLyogCiAqIFRoaXMgZnVuY3Rpb24gdHJpZXMgdG8gZmluZCBhIHJ1bm5pbmcgc2VydmVyIGZvciB0aGUgcHJveHkgPHB4PiBmb2xsb3dpbmcKICogdGhlIFVSTCBwYXJhbWV0ZXIgaGFzaCBtZXRob2QuIEl0IGxvb2tzIGZvciBhIHNwZWNpZmljIHBhcmFtZXRlciBpbiB0aGUKICogVVJMIGFuZCBoYXNoZXMgaXQgdG8gY29tcHV0ZSB0aGUgc2VydmVyIElELiBUaGlzIGlzIHVzZWZ1bCB0byBvcHRpbWl6ZQogKiBwZXJmb3JtYW5jZSBieSBhdm9pZGluZyBib3VuY2VzIGJldHdlZW4gc2VydmVycyBpbiBjb250ZXh0cyB3aGVyZSBzZXNzaW9ucwogKiBhcmUgc2hhcmVkIGJ1dCBjb29raWVzIGFyZSBub3QgdXNhYmxlLiBJZiB0aGUgcGFyYW1ldGVyIGlzIG5vdCBmb3VuZCwgTlVMTAogKiBpcyByZXR1cm5lZC4gSWYgYW55IHNlcnZlciBpcyBmb3VuZCwgaXQgd2lsbCBiZSByZXR1cm5lZC4gSWYgbm8gdmFsaWQgc2VydmVyCiAqIGlzIGZvdW5kLCBOVUxMIGlzIHJldHVybmVkLgogKgogKi8Kc3RydWN0IHNlcnZlciAqZ2V0X3NlcnZlcl9waChzdHJ1Y3QgcHJveHkgKnB4LCBjb25zdCBjaGFyICp1cmksIGludCB1cmlfbGVuKQp7Cgl1bnNpZ25lZCBsb25nIGhhc2ggPSAwOwoJY2hhciAqcDsKCWludCBwbGVuOwoKCWlmIChweC0+bGJwcm0udG90X3dlaWdodCA9PSAwKQoJCXJldHVybiBOVUxMOwoKCWlmIChweC0+bGJwcm0ubWFwLnN0YXRlICYgUFJfTUFQX1JFQ0FMQykKCQlyZWNhbGNfc2VydmVyX21hcChweCk7CgoJcCA9IG1lbWNocih1cmksICc/JywgdXJpX2xlbik7CglpZiAoIXApCgkJcmV0dXJuIE5VTEw7CglwKys7CgoJdXJpX2xlbiAtPSAocCAtIHVyaSk7CglwbGVuID0gcHgtPnVybF9wYXJhbV9sZW47CgoJaWYgKHVyaV9sZW4gPD0gcGxlbikKCQlyZXR1cm4gTlVMTDsKCgl3aGlsZSAodXJpX2xlbiA+IHBsZW4pIHsKCQkvKiBMb29rIGZvciB0aGUgcGFyYW1ldGVyIG5hbWUgZm9sbG93ZWQgYnkgYW4gZXF1YWwgc3ltYm9sICovCgkJaWYgKHBbcGxlbl0gPT0gJz0nKSB7CgkJCS8qIHNraXAgdGhlIGVxdWFsIHN5bWJvbCAqLwoJCQl1cmkgPSBwOwoJCQlwICs9IHBsZW4gKyAxOwoJCQl1cmlfbGVuIC09IHBsZW4gKyAxOwoJCQlpZiAobWVtY21wKHVyaSwgcHgtPnVybF9wYXJhbV9uYW1lLCBwbGVuKSA9PSAwKSB7CgkJCQkvKiBPSywgd2UgaGF2ZSB0aGUgcGFyYW1ldGVyIGhlcmUgYXQgPHVyaT4sIGFuZAoJCQkJICogdGhlIHZhbHVlIGFmdGVyIHRoZSBlcXVhbCBzaWduLCBhdCA8cD4KCQkJCSAqLwoJCQkJd2hpbGUgKHVyaV9sZW4gJiYgKnAgIT0gJyYnKSB7CgkJCQkJaGFzaCA9ICpwICsgKGhhc2ggPDwgNikgKyAoaGFzaCA8PCAxNikgLSBoYXNoOwoJCQkJCXVyaV9sZW4tLTsKCQkJCQlwKys7CgkJCQl9CgkJCQlyZXR1cm4gcHgtPmxicHJtLm1hcC5zcnZbaGFzaCAlIHB4LT5sYnBybS50b3Rfd2VpZ2h0XTsKCQkJfQoJCX0KCgkJLyogc2tpcCB0byBuZXh0IHBhcmFtZXRlciAqLwoJCXVyaSA9IHA7CgkJcCA9IG1lbWNocih1cmksICcmJywgdXJpX2xlbik7CgkJaWYgKCFwKQoJCQlyZXR1cm4gTlVMTDsKCQlwKys7CgkJdXJpX2xlbiAtPSAocCAtIHVyaSk7Cgl9CglyZXR1cm4gTlVMTDsKfQoKLyoKICogVGhpcyBmdW5jdGlvbiBtYXJrcyB0aGUgc2Vzc2lvbiBhcyAnYXNzaWduZWQnIGluIGRpcmVjdCBvciBkaXNwYXRjaCBtb2RlcywKICogb3IgdHJpZXMgdG8gYXNzaWduIG9uZSBpbiBiYWxhbmNlIG1vZGUsIGFjY29yZGluZyB0byB0aGUgYWxnb3JpdGhtLiBJdCBkb2VzCiAqIG5vdGhpbmcgaWYgdGhlIHNlc3Npb24gaGFkIGFscmVhZHkgYmVlbiBhc3NpZ25lZCBhIHNlcnZlci4KICoKICogSXQgbWF5IHJldHVybiA6CiAqICAgU1JWX1NUQVRVU19PSyAgICAgICBpZiBldmVyeXRoaW5nIGlzIE9LLiBzLT5zcnYgd2lsbCBiZSB2YWxpZC4KICogICBTUlZfU1RBVFVTX05PU1JWICAgIGlmIG5vIHNlcnZlciBpcyBhdmFpbGFibGUuIHMtPnNydiA9IE5VTEwuCiAqICAgU1JWX1NUQVRVU19GVUxMICAgICBpZiBhbGwgc2VydmVycyBhcmUgc2F0dXJhdGVkLiBzLT5zcnYgPSBOVUxMLgogKiAgIFNSVl9TVEFUVVNfSU5URVJOQUwgZm9yIG90aGVyIHVucmVjb3ZlcmFibGUgZXJyb3JzLgogKgogKiBVcG9uIHN1Y2Nlc3NmdWwgcmV0dXJuLCB0aGUgc2Vzc2lvbiBmbGFnIFNOX0FTU0lHTkVEIHRvIGluZGljYXRlIHRoYXQgaXQgZG9lcwogKiBub3QgbmVlZCB0byBiZSBjYWxsZWQgYW55bW9yZS4gVGhpcyB1c3VhbGx5IG1lYW5zIHRoYXQgcy0+c3J2IGNhbiBiZSB0cnVzdGVkCiAqIGluIGJhbGFuY2UgYW5kIGRpcmVjdCBtb2Rlcy4gVGhpcyBmbGFnIGlzIG5vdCBjbGVhcmVkLCBzbyBpdCdzIHRvIHRoZSBjYWxsZXIKICogdG8gY2xlYXIgaXQgaWYgcmVxdWlyZWQgKGVnOiByZWRpc3BhdGNoKS4KICoKICovCgppbnQgYXNzaWduX3NlcnZlcihzdHJ1Y3Qgc2Vzc2lvbiAqcykKewojaWZkZWYgREVCVUdfRlVMTAoJZnByaW50ZihzdGRlcnIsImFzc2lnbl9zZXJ2ZXIgOiBzPSVwXG4iLHMpOwojZW5kaWYKCglpZiAocy0+cGVuZF9wb3MpCgkJcmV0dXJuIFNSVl9TVEFUVVNfSU5URVJOQUw7CgoJaWYgKCEocy0+ZmxhZ3MgJiBTTl9BU1NJR05FRCkpIHsKCQlpZiAocy0+YmUtPmxicHJtLmFsZ28gJiBCRV9MQl9BTEdPKSB7CgkJCWludCBsZW47CgkJCgkJCWlmIChzLT5mbGFncyAmIFNOX0RJUkVDVCkgewoJCQkJcy0+ZmxhZ3MgfD0gU05fQVNTSUdORUQ7CgkJCQlyZXR1cm4gU1JWX1NUQVRVU19PSzsKCQkJfQoKCQkJaWYgKCFzLT5iZS0+bGJwcm0udG90X3dlaWdodCkKCQkJCXJldHVybiBTUlZfU1RBVFVTX05PU1JWOwoKCQkJc3dpdGNoIChzLT5iZS0+bGJwcm0uYWxnbyAmIEJFX0xCX0FMR08pIHsKCQkJY2FzZSBCRV9MQl9BTEdPX1JSOgoJCQkJcy0+c3J2ID0gZndycl9nZXRfbmV4dF9zZXJ2ZXIocy0+YmUpOwoJCQkJaWYgKCFzLT5zcnYpCgkJCQkJcmV0dXJuIFNSVl9TVEFUVVNfRlVMTDsKCQkJCWJyZWFrOwoJCQljYXNlIEJFX0xCX0FMR09fU0g6CgkJCQlpZiAocy0+Y2xpX2FkZHIuc3NfZmFtaWx5ID09IEFGX0lORVQpCgkJCQkJbGVuID0gNDsKCQkJCWVsc2UgaWYgKHMtPmNsaV9hZGRyLnNzX2ZhbWlseSA9PSBBRl9JTkVUNikKCQkJCQlsZW4gPSAxNjsKCQkJCWVsc2UgLyogdW5rbm93biBJUCBmYW1pbHkgKi8KCQkJCQlyZXR1cm4gU1JWX1NUQVRVU19JTlRFUk5BTDsKCQkKCQkJCXMtPnNydiA9IGdldF9zZXJ2ZXJfc2gocy0+YmUsCgkJCQkJCSAgICAgICAodm9pZCAqKSYoKHN0cnVjdCBzb2NrYWRkcl9pbiAqKSZzLT5jbGlfYWRkciktPnNpbl9hZGRyLAoJCQkJCQkgICAgICAgbGVuKTsKCQkJCWJyZWFrOwoJCQljYXNlIEJFX0xCX0FMR09fVUg6CgkJCQkvKiBVUkkgaGFzaGluZyAqLwoJCQkJcy0+c3J2ID0gZ2V0X3NlcnZlcl91aChzLT5iZSwKCQkJCQkJICAgICAgIHMtPnR4bi5yZXEuc29sICsgcy0+dHhuLnJlcS5zbC5ycS51LAoJCQkJCQkgICAgICAgcy0+dHhuLnJlcS5zbC5ycS51X2wpOwoJCQkJYnJlYWs7CgkJCWNhc2UgQkVfTEJfQUxHT19QSDoKCQkJCS8qIFVSTCBQYXJhbWV0ZXIgaGFzaGluZyAqLwoJCQkJcy0+c3J2ID0gZ2V0X3NlcnZlcl9waChzLT5iZSwKCQkJCQkJICAgICAgIHMtPnR4bi5yZXEuc29sICsgcy0+dHhuLnJlcS5zbC5ycS51LAoJCQkJCQkgICAgICAgcy0+dHhuLnJlcS5zbC5ycS51X2wpOwoJCQkJaWYgKCFzLT5zcnYpIHsKCQkJCQkvKiBwYXJhbWV0ZXIgbm90IGZvdW5kLCBmYWxsIGJhY2sgdG8gcm91bmQgcm9iaW4gb24gdGhlIG1hcCAqLwoJCQkJCXMtPnNydiA9IGdldF9zZXJ2ZXJfcnJfd2l0aF9jb25ucyhzLT5iZSk7CgkJCQkJaWYgKCFzLT5zcnYpCgkJCQkJCXJldHVybiBTUlZfU1RBVFVTX0ZVTEw7CgkJCQl9CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCS8qIHVua25vd24gYmFsYW5jaW5nIGFsZ29yaXRobSAqLwoJCQkJcmV0dXJuIFNSVl9TVEFUVVNfSU5URVJOQUw7CgkJCX0KCQkJcy0+YmUtPmN1bV9sYmNvbm4rKzsKCQkJcy0+c3J2LT5jdW1fbGJjb25uKys7CgkJfQoJCWVsc2UgaWYgKHMtPmJlLT5vcHRpb25zICYgUFJfT19IVFRQX1BST1hZKSB7CgkJCWlmICghcy0+c3J2X2FkZHIuc2luX2FkZHIuc19hZGRyKQoJCQkJcmV0dXJuIFNSVl9TVEFUVVNfTk9TUlY7CgkJfQoJCWVsc2UgaWYgKCEqKGludCAqKSZzLT5iZS0+ZGlzcGF0Y2hfYWRkci5zaW5fYWRkciAmJgoJCQkgIShzLT5mZS0+b3B0aW9ucyAmIFBSX09fVFJBTlNQKSkgewoJCQlyZXR1cm4gU1JWX1NUQVRVU19OT1NSVjsKCQl9CgkJcy0+ZmxhZ3MgfD0gU05fQVNTSUdORUQ7Cgl9CglyZXR1cm4gU1JWX1NUQVRVU19PSzsKfQoKCi8qCiAqIFRoaXMgZnVuY3Rpb24gYXNzaWducyBhIHNlcnZlciBhZGRyZXNzIHRvIGEgc2Vzc2lvbiwgYW5kIHNldHMgU05fQUREUl9TRVQuCiAqIFRoZSBhZGRyZXNzIGlzIHRha2VuIGZyb20gdGhlIGN1cnJlbnRseSBhc3NpZ25lZCBzZXJ2ZXIsIG9yIGZyb20gdGhlCiAqIGRpc3BhdGNoIG9yIHRyYW5zcGFyZW50IGFkZHJlc3MuCiAqCiAqIEl0IG1heSByZXR1cm4gOgogKiAgIFNSVl9TVEFUVVNfT0sgICAgICAgaWYgZXZlcnl0aGluZyBpcyBPSy4KICogICBTUlZfU1RBVFVTX0lOVEVSTkFMIGZvciBvdGhlciB1bnJlY292ZXJhYmxlIGVycm9ycy4KICoKICogVXBvbiBzdWNjZXNzZnVsIHJldHVybiwgdGhlIHNlc3Npb24gZmxhZyBTTl9BRERSX1NFVCBpcyBzZXQuIFRoaXMgZmxhZyBpcwogKiBub3QgY2xlYXJlZCwgc28gaXQncyB0byB0aGUgY2FsbGVyIHRvIGNsZWFyIGl0IGlmIHJlcXVpcmVkLgogKgogKi8KaW50IGFzc2lnbl9zZXJ2ZXJfYWRkcmVzcyhzdHJ1Y3Qgc2Vzc2lvbiAqcykKewojaWZkZWYgREVCVUdfRlVMTAoJZnByaW50ZihzdGRlcnIsImFzc2lnbl9zZXJ2ZXJfYWRkcmVzcyA6IHM9JXBcbiIscyk7CiNlbmRpZgoKCWlmICgocy0+ZmxhZ3MgJiBTTl9ESVJFQ1QpIHx8IChzLT5iZS0+bGJwcm0uYWxnbyAmIEJFX0xCX0FMR08pKSB7CgkJLyogQSBzZXJ2ZXIgaXMgbmVjZXNzYXJpbHkga25vd24gZm9yIHRoaXMgc2Vzc2lvbiAqLwoJCWlmICghKHMtPmZsYWdzICYgU05fQVNTSUdORUQpKQoJCQlyZXR1cm4gU1JWX1NUQVRVU19JTlRFUk5BTDsKCgkJcy0+c3J2X2FkZHIgPSBzLT5zcnYtPmFkZHI7CgoJCS8qIGlmIHRoaXMgc2VydmVyIHJlbWFwcyBwcm94aWVkIHBvcnRzLCB3ZSdsbCB1c2UKCQkgKiB0aGUgcG9ydCB0aGUgY2xpZW50IGNvbm5lY3RlZCB0byB3aXRoIGFuIG9mZnNldC4gKi8KCQlpZiAocy0+c3J2LT5zdGF0ZSAmIFNSVl9NQVBQT1JUUykgewoJCQlpZiAoIShzLT5mZS0+b3B0aW9ucyAmIFBSX09fVFJBTlNQKSAmJiAhKHMtPmZsYWdzICYgU05fRlJUX0FERFJfU0VUKSkKCQkJCWdldF9mcnRfYWRkcihzKTsKCQkJaWYgKHMtPmZydF9hZGRyLnNzX2ZhbWlseSA9PSBBRl9JTkVUKSB7CgkJCQlzLT5zcnZfYWRkci5zaW5fcG9ydCA9IGh0b25zKG50b2hzKHMtPnNydl9hZGRyLnNpbl9wb3J0KSArCgkJCQkJCQkgICAgIG50b2hzKCgoc3RydWN0IHNvY2thZGRyX2luICopJnMtPmZydF9hZGRyKS0+c2luX3BvcnQpKTsKCQkJfSBlbHNlIHsKCQkJCXMtPnNydl9hZGRyLnNpbl9wb3J0ID0gaHRvbnMobnRvaHMocy0+c3J2X2FkZHIuc2luX3BvcnQpICsKCQkJCQkJCSAgICAgbnRvaHMoKChzdHJ1Y3Qgc29ja2FkZHJfaW42ICopJnMtPmZydF9hZGRyKS0+c2luNl9wb3J0KSk7CgkJCX0KCQl9Cgl9CgllbHNlIGlmICgqKGludCAqKSZzLT5iZS0+ZGlzcGF0Y2hfYWRkci5zaW5fYWRkcikgewoJCS8qIGNvbm5lY3QgdG8gdGhlIGRlZmluZWQgZGlzcGF0Y2ggYWRkciAqLwoJCXMtPnNydl9hZGRyID0gcy0+YmUtPmRpc3BhdGNoX2FkZHI7Cgl9CgllbHNlIGlmIChzLT5mZS0+b3B0aW9ucyAmIFBSX09fVFJBTlNQKSB7CgkJLyogaW4gdHJhbnNwYXJlbnQgbW9kZSwgdXNlIHRoZSBvcmlnaW5hbCBkZXN0IGFkZHIgaWYgbm8gZGlzcGF0Y2ggc3BlY2lmaWVkICovCgkJaWYgKCEocy0+ZmxhZ3MgJiBTTl9GUlRfQUREUl9TRVQpKQoJCQlnZXRfZnJ0X2FkZHIocyk7CgoJCW1lbWNweSgmcy0+c3J2X2FkZHIsICZzLT5mcnRfYWRkciwgTUlOKHNpemVvZihzLT5zcnZfYWRkciksIHNpemVvZihzLT5mcnRfYWRkcikpKTsKCQkvKiB3aGVuIHdlIHN1cHBvcnQgSVB2NiBvbiB0aGUgYmFja2VuZCwgd2UgbWF5IGFkZCBvdGhlciB0ZXN0cyAqLwoJCS8vcWZwcmludGYoc3RkZXJyLCAiQ2Fubm90IGdldCBvcmlnaW5hbCBzZXJ2ZXIgYWRkcmVzcy5cbiIpOwoJCS8vcmV0dXJuIFNSVl9TVEFUVVNfSU5URVJOQUw7Cgl9CgllbHNlIGlmIChzLT5iZS0+b3B0aW9ucyAmIFBSX09fSFRUUF9QUk9YWSkgewoJCS8qIElmIEhUVFAgUFJPWFkgb3B0aW9uIGlzIHNldCwgdGhlbiBzZXJ2ZXIgaXMgYWxyZWFkeSBhc3NpZ25lZAoJCSAqIGR1cmluZyBpbmNvbWluZyBjbGllbnQgcmVxdWVzdCBwYXJzaW5nLiAqLwoJfQoJZWxzZSB7CgkJLyogbm8gc2VydmVyIGFuZCBubyBMQiBhbGdvcml0aG0gISAqLwoJCXJldHVybiBTUlZfU1RBVFVTX0lOVEVSTkFMOwoJfQoKCXMtPmZsYWdzIHw9IFNOX0FERFJfU0VUOwoJcmV0dXJuIFNSVl9TVEFUVVNfT0s7Cn0KCgovKiBUaGlzIGZ1bmN0aW9uIGFzc2lnbnMgYSBzZXJ2ZXIgdG8gc2Vzc2lvbiA8cz4gaWYgcmVxdWlyZWQsIGFuZCBjYW4gYWRkIHRoZQogKiBjb25uZWN0aW9uIHRvIGVpdGhlciB0aGUgYXNzaWduZWQgc2VydmVyJ3MgcXVldWUgb3IgdG8gdGhlIHByb3h5J3MgcXVldWUuCiAqCiAqIFJldHVybnMgOgogKgogKiAgIFNSVl9TVEFUVVNfT0sgICAgICAgaWYgZXZlcnl0aGluZyBpcyBPSy4KICogICBTUlZfU1RBVFVTX05PU1JWICAgIGlmIG5vIHNlcnZlciBpcyBhdmFpbGFibGUuIHMtPnNydiA9IE5VTEwuCiAqICAgU1JWX1NUQVRVU19RVUVVRUQgICBpZiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBxdWV1ZWQuCiAqICAgU1JWX1NUQVRVU19GVUxMICAgICBpZiB0aGUgc2VydmVyKHMpIGlzL2FyZSBzYXR1cmF0ZWQgYW5kIHRoZQogKiAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbiBjb3VsZCBub3QgYmUgcXVldWVkLgogKiAgIFNSVl9TVEFUVVNfSU5URVJOQUwgZm9yIG90aGVyIHVucmVjb3ZlcmFibGUgZXJyb3JzLgogKgogKi8KaW50IGFzc2lnbl9zZXJ2ZXJfYW5kX3F1ZXVlKHN0cnVjdCBzZXNzaW9uICpzKQp7CglzdHJ1Y3QgcGVuZGNvbm4gKnA7CglpbnQgZXJyOwoKCWlmIChzLT5wZW5kX3BvcykKCQlyZXR1cm4gU1JWX1NUQVRVU19JTlRFUk5BTDsKCglpZiAocy0+ZmxhZ3MgJiBTTl9BU1NJR05FRCkgewoJCWlmICgocy0+ZmxhZ3MgJiBTTl9SRURJUkVDVEFCTEUpICYmIHMtPnNydiAmJiBzLT5zcnYtPnJkcl9sZW4pIHsKCQkJLyogc2VydmVyIHNjaGVkdWxlZCBmb3IgcmVkaXJlY3Rpb24sIGFuZCBhbHJlYWR5IGFzc2lnbmVkLiBXZQoJCQkgKiBkb24ndCB3YW50IHRvIGdvIGZ1cnRoZXIgbm9yIGNoZWNrIHRoZSBxdWV1ZS4KCQkJICovCgkJCXJldHVybiBTUlZfU1RBVFVTX09LOwoJCX0KCgkJaWYgKHMtPnNydiAmJiBzLT5zcnYtPm1heHF1ZXVlID4gMCAmJiBzLT5zcnYtPm5icGVuZCA+PSBzLT5zcnYtPm1heHF1ZXVlKSB7CgkJCXMtPmZsYWdzICY9IH4oU05fRElSRUNUIHwgU05fQVNTSUdORUQgfCBTTl9BRERSX1NFVCk7CgkJCXMtPnNydiA9IE5VTEw7CgkJCWh0dHBfZmx1c2hfY29va2llX2ZsYWdzKCZzLT50eG4pOwoJCX0gZWxzZSB7CgkJCS8qIGEgc2VydmVyIGRvZXMgbm90IG5lZWQgdG8gYmUgYXNzaWduZWQsIHBlcmhhcHMgYmVjYXVzZSB3ZSdyZSBpbgoJCQkgKiBkaXJlY3QgbW9kZSwgb3IgaW4gZGlzcGF0Y2ggb3IgdHJhbnNwYXJlbnQgbW9kZXMgd2hlcmUgdGhlIHNlcnZlcgoJCQkgKiBpcyBub3QgbmVlZGVkLgoJCQkgKi8KCQkJaWYgKHMtPnNydiAmJgoJCQkgICAgcy0+c3J2LT5tYXhjb25uICYmIHMtPnNydi0+Y3VyX3Nlc3MgPj0gc3J2X2R5bmFtaWNfbWF4Y29ubihzLT5zcnYpKSB7CgkJCQlwID0gcGVuZGNvbm5fYWRkKHMpOwoJCQkJaWYgKHApCgkJCQkJcmV0dXJuIFNSVl9TVEFUVVNfUVVFVUVEOwoJCQkJZWxzZQoJCQkJCXJldHVybiBTUlZfU1RBVFVTX0ZVTEw7CgkJCX0KCQkJcmV0dXJuIFNSVl9TVEFUVVNfT0s7CgkJfQoJfQoKCS8qIGEgc2VydmVyIG5lZWRzIHRvIGJlIGFzc2lnbmVkICovCgllcnIgPSBhc3NpZ25fc2VydmVyKHMpOwoJc3dpdGNoIChlcnIpIHsKCWNhc2UgU1JWX1NUQVRVU19PSzoKCQlpZiAoKHMtPmZsYWdzICYgU05fUkVESVJFQ1RBQkxFKSAmJiBzLT5zcnYgJiYgcy0+c3J2LT5yZHJfbGVuKSB7CgkJCS8qIHNlcnZlciBzdXBwb3J0aW5nIHJlZGlyZWN0aW9uIGFuZCBpdCBpcyBwb3NzaWJsZS4KCQkJICogTGV0J3MgcmVwb3J0IHRoYXQgYW5kIGlnbm9yZSBtYXhjb25uICEKCQkJICovCgkJCXJldHVybiBTUlZfU1RBVFVTX09LOwoJCX0KCgkJLyogaW4gYmFsYW5jZSBtb2RlLCB3ZSBtaWdodCBoYXZlIHNlcnZlcnMgd2l0aCBjb25uZWN0aW9uIGxpbWl0cyAqLwoJCWlmIChzLT5zcnYgJiYKCQkgICAgcy0+c3J2LT5tYXhjb25uICYmIHMtPnNydi0+Y3VyX3Nlc3MgPj0gc3J2X2R5bmFtaWNfbWF4Y29ubihzLT5zcnYpKSB7CgkJCXAgPSBwZW5kY29ubl9hZGQocyk7CgkJCWlmIChwKQoJCQkJcmV0dXJuIFNSVl9TVEFUVVNfUVVFVUVEOwoJCQllbHNlCgkJCQlyZXR1cm4gU1JWX1NUQVRVU19GVUxMOwoJCX0KCQlyZXR1cm4gU1JWX1NUQVRVU19PSzsKCgljYXNlIFNSVl9TVEFUVVNfRlVMTDoKCQkvKiBxdWV1ZSB0aGlzIHNlc3Npb24gaW50byB0aGUgcHJveHkncyBxdWV1ZSAqLwoJCXAgPSBwZW5kY29ubl9hZGQocyk7CgkJaWYgKHApCgkJCXJldHVybiBTUlZfU1RBVFVTX1FVRVVFRDsKCQllbHNlCgkJCXJldHVybiBTUlZfU1RBVFVTX0ZVTEw7CgoJY2FzZSBTUlZfU1RBVFVTX05PU1JWOgoJY2FzZSBTUlZfU1RBVFVTX0lOVEVSTkFMOgoJCXJldHVybiBlcnI7CglkZWZhdWx0OgoJCXJldHVybiBTUlZfU1RBVFVTX0lOVEVSTkFMOwoJfQp9CgovKgogKiBUaGlzIGZ1bmN0aW9uIGluaXRpYXRlcyBhIGNvbm5lY3Rpb24gdG8gdGhlIHNlcnZlciBhc3NpZ25lZCB0byB0aGlzIHNlc3Npb24KICogKHMtPnNydiwgcy0+c3J2X2FkZHIpLiBJdCB3aWxsIGFzc2lnbiBhIHNlcnZlciBpZiBub25lIGlzIGFzc2lnbmVkIHlldC4KICogSXQgY2FuIHJldHVybiBvbmUgb2YgOgogKiAgLSBTTl9FUlJfTk9ORSBpZiBldmVyeXRoaW5nJ3MgT0sKICogIC0gU05fRVJSX1NSVlRPIGlmIHRoZXJlIGFyZSBubyBtb3JlIHNlcnZlcnMKICogIC0gU05fRVJSX1NSVkNMIGlmIHRoZSBjb25uZWN0aW9uIHdhcyByZWZ1c2VkIGJ5IHRoZSBzZXJ2ZXIKICogIC0gU05fRVJSX1BSWENPTkQgaWYgdGhlIGNvbm5lY3Rpb24gaGFzIGJlZW4gbGltaXRlZCBieSB0aGUgcHJveHkgKG1heGNvbm4pCiAqICAtIFNOX0VSUl9SRVNPVVJDRSBpZiBhIHN5c3RlbSByZXNvdXJjZSBpcyBsYWNraW5nIChlZzogZmQgbGltaXRzLCBwb3J0cywgLi4uKQogKiAgLSBTTl9FUlJfSU5URVJOQUwgZm9yIGFueSBvdGhlciBwdXJlbHkgaW50ZXJuYWwgZXJyb3JzCiAqIEFkZGl0aW9ubmFsbHksIGluIHRoZSBjYXNlIG9mIFNOX0VSUl9SRVNPVVJDRSwgYW4gZW1lcmdlbmN5IGxvZyB3aWxsIGJlIGVtaXR0ZWQuCiAqLwppbnQgY29ubmVjdF9zZXJ2ZXIoc3RydWN0IHNlc3Npb24gKnMpCnsKCWludCBmZCwgZXJyOwoKCWlmICghKHMtPmZsYWdzICYgU05fQUREUl9TRVQpKSB7CgkJZXJyID0gYXNzaWduX3NlcnZlcl9hZGRyZXNzKHMpOwoJCWlmIChlcnIgIT0gU1JWX1NUQVRVU19PSykKCQkJcmV0dXJuIFNOX0VSUl9JTlRFUk5BTDsKCX0KCglpZiAoKGZkID0gcy0+c3J2X2ZkID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCBJUFBST1RPX1RDUCkpID09IC0xKSB7CgkJcWZwcmludGYoc3RkZXJyLCAiQ2Fubm90IGdldCBhIHNlcnZlciBzb2NrZXQuXG4iKTsKCgkJaWYgKGVycm5vID09IEVORklMRSkKCQkJc2VuZF9sb2cocy0+YmUsIExPR19FTUVSRywKCQkJCSAiUHJveHkgJXMgcmVhY2hlZCBzeXN0ZW0gRkQgbGltaXQgYXQgJWQuIFBsZWFzZSBjaGVjayBzeXN0ZW0gdHVuYWJsZXMuXG4iLAoJCQkJIHMtPmJlLT5pZCwgbWF4ZmQpOwoJCWVsc2UgaWYgKGVycm5vID09IEVNRklMRSkKCQkJc2VuZF9sb2cocy0+YmUsIExPR19FTUVSRywKCQkJCSAiUHJveHkgJXMgcmVhY2hlZCBwcm9jZXNzIEZEIGxpbWl0IGF0ICVkLiBQbGVhc2UgY2hlY2sgJ3VsaW1pdC1uJyBhbmQgcmVzdGFydC5cbiIsCgkJCQkgcy0+YmUtPmlkLCBtYXhmZCk7CgkJZWxzZSBpZiAoZXJybm8gPT0gRU5PQlVGUyB8fCBlcnJubyA9PSBFTk9NRU0pCgkJCXNlbmRfbG9nKHMtPmJlLCBMT0dfRU1FUkcsCgkJCQkgIlByb3h5ICVzIHJlYWNoZWQgc3lzdGVtIG1lbW9yeSBsaW1pdCBhdCAlZCBzb2NrZXRzLiBQbGVhc2UgY2hlY2sgc3lzdGVtIHR1bmFibGVzLlxuIiwKCQkJCSBzLT5iZS0+aWQsIG1heGZkKTsKCQkvKiB0aGlzIGlzIGEgcmVzb3VyY2UgZXJyb3IgKi8KCQlyZXR1cm4gU05fRVJSX1JFU09VUkNFOwoJfQoJCglpZiAoZmQgPj0gZ2xvYmFsLm1heHNvY2spIHsKCQkvKiBkbyBub3QgbG9nIGFueXRoaW5nIHRoZXJlLCBpdCdzIGEgbm9ybWFsIGNvbmRpdGlvbiB3aGVuIHRoaXMgb3B0aW9uCgkJICogaXMgdXNlZCB0byBzZXJpYWxpemUgY29ubmVjdGlvbnMgdG8gYSBzZXJ2ZXIgIQoJCSAqLwoJCUFsZXJ0KCJzb2NrZXQoKTogbm90IGVub3VnaCBmcmVlIHNvY2tldHMuIFJhaXNlIC1uIGFyZ3VtZW50LiBHaXZpbmcgdXAuXG4iKTsKCQljbG9zZShmZCk7CgkJcmV0dXJuIFNOX0VSUl9QUlhDT05EOyAvKiBpdCBpcyBhIGNvbmZpZ3VyYXRpb24gbGltaXQgKi8KCX0KCiNpZmRlZiBDT05GSUdfSEFQX1RDUFNQTElDRQoJaWYgKChzLT5mZS0+b3B0aW9ucyAmIHMtPmJlLT5vcHRpb25zKSAmIFBSX09fVENQU1BMSUNFKSB7CgkJLyogVENQIHNwbGljaW5nIHN1cHBvcnRlZCBieSBib3RoIEZFIGFuZCBCRSAqLwoJCXRjcF9zcGxpY2VfaW5pdGZkKHMtPmNsaV9mZCwgZmQpOwoJfQojZW5kaWYKCglpZiAoKGZjbnRsKGZkLCBGX1NFVEZMLCBPX05PTkJMT0NLKT09LTEpIHx8CgkgICAgKHNldHNvY2tvcHQoZmQsIElQUFJPVE9fVENQLCBUQ1BfTk9ERUxBWSwgKGNoYXIgKikgJm9uZSwgc2l6ZW9mKG9uZSkpID09IC0xKSkgewoJCXFmcHJpbnRmKHN0ZGVyciwiQ2Fubm90IHNldCBjbGllbnQgc29ja2V0IHRvIG5vbiBibG9ja2luZyBtb2RlLlxuIik7CgkJY2xvc2UoZmQpOwoJCXJldHVybiBTTl9FUlJfSU5URVJOQUw7Cgl9CgoJaWYgKHMtPmJlLT5vcHRpb25zICYgUFJfT19UQ1BfU1JWX0tBKQoJCXNldHNvY2tvcHQoZmQsIFNPTF9TT0NLRVQsIFNPX0tFRVBBTElWRSwgKGNoYXIgKikgJm9uZSwgc2l6ZW9mKG9uZSkpOwoKCWlmIChzLT5iZS0+b3B0aW9ucyAmIFBSX09fVENQX05PTElORykKCQlzZXRzb2Nrb3B0KGZkLCBTT0xfU09DS0VULCBTT19MSU5HRVIsIChzdHJ1Y3QgbGluZ2VyICopICZub2xpbmdlciwgc2l6ZW9mKHN0cnVjdCBsaW5nZXIpKTsKCgkvKiBhbGxvdyBzcGVjaWZpYyBiaW5kaW5nIDoKCSAqIC0gc2VydmVyLXNwZWNpZmljIGF0IGZpcnN0CgkgKiAtIHByb3h5LXNwZWNpZmljIG5leHQKCSAqLwoJaWYgKHMtPnNydiAhPSBOVUxMICYmIHMtPnNydi0+c3RhdGUgJiBTUlZfQklORF9TUkMpIHsKCQlzdHJ1Y3Qgc29ja2FkZHJfaW4gKnJlbW90ZSA9IE5VTEw7CgkJaW50IHJldCwgZmxhZ3MgPSAwOwoKI2lmIGRlZmluZWQoQ09ORklHX0hBUF9DVFRQUk9YWSkgfHwgZGVmaW5lZChDT05GSUdfSEFQX0xJTlVYX1RQUk9YWSkKCQlzd2l0Y2ggKHMtPnNydi0+c3RhdGUgJiBTUlZfVFBST1hZX01BU0spIHsKCQljYXNlIFNSVl9UUFJPWFlfQUREUjoKCQkJcmVtb3RlID0gKHN0cnVjdCBzb2NrYWRkcl9pbiAqKSZzLT5zcnYtPnRwcm94eV9hZGRyOwoJCQlmbGFncyAgPSAzOwoJCQlicmVhazsKCQljYXNlIFNSVl9UUFJPWFlfQ0xJOgoJCQlmbGFncyB8PSAyOwoJCQkvKiBmYWxsIHRocm91Z2ggKi8KCQljYXNlIFNSVl9UUFJPWFlfQ0lQOgoJCQkvKiBGSVhNRTogd2hhdCBjYW4gd2UgZG8gaWYgdGhlIGNsaWVudCBjb25uZWN0cyBpbiBJUHY2ID8gKi8KCQkJZmxhZ3MgfD0gMTsKCQkJcmVtb3RlID0gKHN0cnVjdCBzb2NrYWRkcl9pbiAqKSZzLT5jbGlfYWRkcjsKCQkJYnJlYWs7CgkJfQojZW5kaWYKCQlyZXQgPSB0Y3B2NF9iaW5kX3NvY2tldChmZCwgZmxhZ3MsICZzLT5zcnYtPnNvdXJjZV9hZGRyLCByZW1vdGUpOwoJCWlmIChyZXQpIHsKCQkJY2xvc2UoZmQpOwoJCQlpZiAocmV0ID09IDEpIHsKCQkJCUFsZXJ0KCJDYW5ub3QgYmluZCB0byBzb3VyY2UgYWRkcmVzcyBiZWZvcmUgY29ubmVjdCgpIGZvciBzZXJ2ZXIgJXMvJXMuIEFib3J0aW5nLlxuIiwKCQkJCSAgICAgIHMtPmJlLT5pZCwgcy0+c3J2LT5pZCk7CgkJCQlzZW5kX2xvZyhzLT5iZSwgTE9HX0VNRVJHLAoJCQkJCSAiQ2Fubm90IGJpbmQgdG8gc291cmNlIGFkZHJlc3MgYmVmb3JlIGNvbm5lY3QoKSBmb3Igc2VydmVyICVzLyVzLlxuIiwKCQkJCQkgcy0+YmUtPmlkLCBzLT5zcnYtPmlkKTsKCQkJfSBlbHNlIHsKCQkJCUFsZXJ0KCJDYW5ub3QgYmluZCB0byB0cHJveHkgc291cmNlIGFkZHJlc3MgYmVmb3JlIGNvbm5lY3QoKSBmb3Igc2VydmVyICVzLyVzLiBBYm9ydGluZy5cbiIsCgkJCQkgICAgICBzLT5iZS0+aWQsIHMtPnNydi0+aWQpOwoJCQkJc2VuZF9sb2cocy0+YmUsIExPR19FTUVSRywKCQkJCQkgIkNhbm5vdCBiaW5kIHRvIHRwcm94eSBzb3VyY2UgYWRkcmVzcyBiZWZvcmUgY29ubmVjdCgpIGZvciBzZXJ2ZXIgJXMvJXMuXG4iLAoJCQkJCSBzLT5iZS0+aWQsIHMtPnNydi0+aWQpOwoJCQl9CgkJCXJldHVybiBTTl9FUlJfUkVTT1VSQ0U7CgkJfQoJfQoJZWxzZSBpZiAocy0+YmUtPm9wdGlvbnMgJiBQUl9PX0JJTkRfU1JDKSB7CgkJc3RydWN0IHNvY2thZGRyX2luICpyZW1vdGUgPSBOVUxMOwoJCWludCByZXQsIGZsYWdzID0gMDsKCiNpZiBkZWZpbmVkKENPTkZJR19IQVBfQ1RUUFJPWFkpIHx8IGRlZmluZWQoQ09ORklHX0hBUF9MSU5VWF9UUFJPWFkpCgkJc3dpdGNoIChzLT5iZS0+b3B0aW9ucyAmIFBSX09fVFBYWV9NQVNLKSB7CgkJY2FzZSBQUl9PX1RQWFlfQUREUjoKCQkJcmVtb3RlID0gKHN0cnVjdCBzb2NrYWRkcl9pbiAqKSZzLT5iZS0+dHByb3h5X2FkZHI7CgkJCWZsYWdzICA9IDM7CgkJCWJyZWFrOwoJCWNhc2UgUFJfT19UUFhZX0NMSToKCQkJZmxhZ3MgfD0gMjsKCQkJLyogZmFsbCB0aHJvdWdoICovCgkJY2FzZSBQUl9PX1RQWFlfQ0lQOgoJCQkvKiBGSVhNRTogd2hhdCBjYW4gd2UgZG8gaWYgdGhlIGNsaWVudCBjb25uZWN0cyBpbiBJUHY2ID8gKi8KCQkJZmxhZ3MgfD0gMTsKCQkJcmVtb3RlID0gKHN0cnVjdCBzb2NrYWRkcl9pbiAqKSZzLT5jbGlfYWRkcjsKCQkJYnJlYWs7CgkJfQojZW5kaWYKCQlyZXQgPSB0Y3B2NF9iaW5kX3NvY2tldChmZCwgZmxhZ3MsICZzLT5iZS0+c291cmNlX2FkZHIsIHJlbW90ZSk7CgkJaWYgKHJldCkgewoJCQljbG9zZShmZCk7CgkJCWlmIChyZXQgPT0gMSkgewoJCQkJQWxlcnQoIkNhbm5vdCBiaW5kIHRvIHNvdXJjZSBhZGRyZXNzIGJlZm9yZSBjb25uZWN0KCkgZm9yIHByb3h5ICVzLiBBYm9ydGluZy5cbiIsCgkJCQkgICAgICBzLT5iZS0+aWQpOwoJCQkJc2VuZF9sb2cocy0+YmUsIExPR19FTUVSRywKCQkJCQkgIkNhbm5vdCBiaW5kIHRvIHNvdXJjZSBhZGRyZXNzIGJlZm9yZSBjb25uZWN0KCkgZm9yIHByb3h5ICVzLlxuIiwKCQkJCQkgcy0+YmUtPmlkKTsKCQkJfSBlbHNlIHsKCQkJCUFsZXJ0KCJDYW5ub3QgYmluZCB0byB0cHJveHkgc291cmNlIGFkZHJlc3MgYmVmb3JlIGNvbm5lY3QoKSBmb3IgcHJveHkgJXMuIEFib3J0aW5nLlxuIiwKCQkJCSAgICAgIHMtPmJlLT5pZCk7CgkJCQlzZW5kX2xvZyhzLT5iZSwgTE9HX0VNRVJHLAoJCQkJCSAiQ2Fubm90IGJpbmQgdG8gdHByb3h5IHNvdXJjZSBhZGRyZXNzIGJlZm9yZSBjb25uZWN0KCkgZm9yIHByb3h5ICVzLlxuIiwKCQkJCQkgcy0+YmUtPmlkKTsKCQkJfQoJCQlyZXR1cm4gU05fRVJSX1JFU09VUkNFOwoJCX0KCX0KCQoJaWYgKChjb25uZWN0KGZkLCAoc3RydWN0IHNvY2thZGRyICopJnMtPnNydl9hZGRyLCBzaXplb2Yocy0+c3J2X2FkZHIpKSA9PSAtMSkgJiYKCSAgICAoZXJybm8gIT0gRUlOUFJPR1JFU1MpICYmIChlcnJubyAhPSBFQUxSRUFEWSkgJiYgKGVycm5vICE9IEVJU0NPTk4pKSB7CgoJCWlmIChlcnJubyA9PSBFQUdBSU4gfHwgZXJybm8gPT0gRUFERFJJTlVTRSkgewoJCQljaGFyICptc2c7CgkJCWlmIChlcnJubyA9PSBFQUdBSU4pIC8qIG5vIGZyZWUgcG9ydHMgbGVmdCwgdHJ5IGFnYWluIGxhdGVyICovCgkJCQltc2cgPSAibm8gZnJlZSBwb3J0cyI7CgkJCWVsc2UKCQkJCW1zZyA9ICJsb2NhbCBhZGRyZXNzIGFscmVhZHkgaW4gdXNlIjsKCgkJCXFmcHJpbnRmKHN0ZGVyciwiQ2Fubm90IGNvbm5lY3Q6ICVzLlxuIixtc2cpOwoJCQljbG9zZShmZCk7CgkJCXNlbmRfbG9nKHMtPmJlLCBMT0dfRU1FUkcsCgkJCQkgIkNvbm5lY3QoKSBmYWlsZWQgZm9yIHNlcnZlciAlcy8lczogJXMuXG4iLAoJCQkJIHMtPmJlLT5pZCwgcy0+c3J2LT5pZCwgbXNnKTsKCQkJcmV0dXJuIFNOX0VSUl9SRVNPVVJDRTsKCQl9IGVsc2UgaWYgKGVycm5vID09IEVUSU1FRE9VVCkgewoJCQkvL3FmcHJpbnRmKHN0ZGVyciwiQ29ubmVjdCgpOiBFVElNRURPVVQiKTsKCQkJY2xvc2UoZmQpOwoJCQlyZXR1cm4gU05fRVJSX1NSVlRPOwoJCX0gZWxzZSB7CgkJCS8vIChlcnJubyA9PSBFQ09OTlJFRlVTRUQgfHwgZXJybm8gPT0gRU5FVFVOUkVBQ0ggfHwgZXJybm8gPT0gRUFDQ0VTIHx8IGVycm5vID09IEVQRVJNKQoJCQkvL3FmcHJpbnRmKHN0ZGVyciwiQ29ubmVjdCgpOiAlZCIsIGVycm5vKTsKCQkJY2xvc2UoZmQpOwoJCQlyZXR1cm4gU05fRVJSX1NSVkNMOwoJCX0KCX0KCglmZHRhYltmZF0ub3duZXIgPSBzLT50YXNrOwoJZmR0YWJbZmRdLnN0YXRlID0gRkRfU1RDT05OOyAvKiBjb25uZWN0aW9uIGluIHByb2dyZXNzICovCglmZHRhYltmZF0uY2JbRElSX1JEXS5mID0gJnN0cmVhbV9zb2NrX3JlYWQ7CglmZHRhYltmZF0uY2JbRElSX1JEXS5iID0gcy0+cmVwOwoJZmR0YWJbZmRdLmNiW0RJUl9XUl0uZiA9ICZzdHJlYW1fc29ja193cml0ZTsKCWZkdGFiW2ZkXS5jYltESVJfV1JdLmIgPSBzLT5yZXE7CgoJZmR0YWJbZmRdLnBlZXJhZGRyID0gKHN0cnVjdCBzb2NrYWRkciAqKSZzLT5zcnZfYWRkcjsKCWZkdGFiW2ZkXS5wZWVybGVuID0gc2l6ZW9mKHMtPnNydl9hZGRyKTsKCglFVl9GRF9TRVQoZmQsIERJUl9XUik7ICAvKiBmb3IgY29ubmVjdCBzdGF0dXMgKi8KICAgIAoJZmRfaW5zZXJ0KGZkKTsKCWlmIChzLT5zcnYpIHsKCQlzLT5zcnYtPmN1cl9zZXNzKys7CgkJaWYgKHMtPnNydi0+Y3VyX3Nlc3MgPiBzLT5zcnYtPmN1cl9zZXNzX21heCkKCQkJcy0+c3J2LT5jdXJfc2Vzc19tYXggPSBzLT5zcnYtPmN1cl9zZXNzOwoJfQoKCWlmICghdHZfYWRkX2lmc2V0KCZzLT5yZXEtPmNleCwgJm5vdywgJnMtPmJlLT50aW1lb3V0LmNvbm5lY3QpKQoJCXR2X2V0ZXJuaXR5KCZzLT5yZXEtPmNleCk7CglyZXR1cm4gU05fRVJSX05PTkU7ICAvKiBjb25uZWN0aW9uIGlzIE9LICovCn0KCgovKgogKiBUaGlzIGZ1bmN0aW9uIGNoZWNrcyB0aGUgcmV0cnkgY291bnQgZHVyaW5nIHRoZSBjb25uZWN0KCkgam9iLgogKiBJdCB1cGRhdGVzIHRoZSBzZXNzaW9uJ3Mgc3J2X3N0YXRlIGFuZCByZXRyaWVzLCBzbyB0aGF0IHRoZSBjYWxsZXIga25vd3MKICogd2hhdCBpdCBoYXMgdG8gZG8uIEl0IHVzZXMgdGhlIGxhc3QgY29ubmVjdGlvbiBlcnJvciB0byBzZXQgdGhlIGxvZyB3aGVuCiAqIGl0IGV4cGlyZXMuIEl0IHJldHVybnMgMSB3aGVuIGl0IGhhcyBleHBpcmVkLCBhbmQgMCBvdGhlcndpc2UuCiAqLwppbnQgc3J2X2NvdW50X3JldHJ5X2Rvd24oc3RydWN0IHNlc3Npb24gKnQsIGludCBjb25uX2VycikKewoJLyogd2UgYXJlIGluIGZyb250IG9mIGEgcmV0cnlhYmxlIGVycm9yICovCgl0LT5jb25uX3JldHJpZXMtLTsKCWlmICh0LT5zcnYpCgkJdC0+c3J2LT5yZXRyaWVzKys7Cgl0LT5iZS0+cmV0cmllcysrOwoKCWlmICh0LT5jb25uX3JldHJpZXMgPCAwKSB7CgkJLyogaWYgbm90IHJldHJ5YWJsZSBhbnltb3JlLCBsZXQncyBhYm9ydCAqLwoJCXR2X2V0ZXJuaXR5KCZ0LT5yZXEtPmNleCk7CgkJc3J2X2Nsb3NlX3dpdGhfZXJyKHQsIGNvbm5fZXJyLCBTTl9GSU5TVF9DLAoJCQkJICAgNTAzLCBlcnJvcl9tZXNzYWdlKHQsIEhUVFBfRVJSXzUwMykpOwoJCWlmICh0LT5zcnYpCgkJCXQtPnNydi0+Y3VtX3Nlc3MrKzsKCQlpZiAodC0+c3J2KQoJCQl0LT5zcnYtPmZhaWxlZF9jb25ucysrOwoJCXQtPmJlLT5mYWlsZWRfY29ubnMrKzsKCgkJLyogV2UgdXNlZCB0byBoYXZlIGEgZnJlZSBjb25uZWN0aW9uIHNsb3QuIFNpbmNlIHdlJ2xsIG5ldmVyIHVzZSBpdCwKCQkgKiB3ZSBoYXZlIHRvIGluZm9ybSB0aGUgc2VydmVyIHRoYXQgaXQgbWF5IGJlIHVzZWQgYnkgYW5vdGhlciBzZXNzaW9uLgoJCSAqLwoJCWlmIChtYXlfZGVxdWV1ZV90YXNrcyh0LT5zcnYsIHQtPmJlKSkKCQkJdGFza193YWtldXAodC0+c3J2LT5xdWV1ZV9tZ3QpOwoJCXJldHVybiAxOwoJfQoJcmV0dXJuIDA7Cn0KCiAgICAKLyoKICogVGhpcyBmdW5jdGlvbiBwZXJmb3JtcyB0aGUgcmV0cnlhYmxlIHBhcnQgb2YgdGhlIGNvbm5lY3QoKSBqb2IuCiAqIEl0IHVwZGF0ZXMgdGhlIHNlc3Npb24ncyBzcnZfc3RhdGUgYW5kIHJldHJpZXMsIHNvIHRoYXQgdGhlIGNhbGxlciBrbm93cwogKiB3aGF0IGl0IGhhcyB0byBkby4gSXQgcmV0dXJucyAxIHdoZW4gaXQgYnJlYWtzIG91dCBvZiB0aGUgbG9vcCwgb3IgMCBpZgogKiBpdCBuZWVkcyB0byByZWRpc3BhdGNoLgogKi8KaW50IHNydl9yZXRyeWFibGVfY29ubmVjdChzdHJ1Y3Qgc2Vzc2lvbiAqdCkKewoJaW50IGNvbm5fZXJyOwoKCS8qIFRoaXMgbG9vcCBlbnN1cmVzIHRoYXQgd2Ugc3RvcCBiZWZvcmUgdGhlIGxhc3QgcmV0cnkgaW4gY2FzZSBvZiBhCgkgKiByZWRpc3BhdGNoYWJsZSBzZXJ2ZXIuCgkgKi8KCWRvIHsKCQkvKiBpbml0aWF0ZSBhIGNvbm5lY3Rpb24gdG8gdGhlIHNlcnZlciAqLwoJCWNvbm5fZXJyID0gY29ubmVjdF9zZXJ2ZXIodCk7CgkJc3dpdGNoIChjb25uX2VycikgewoJCgkJY2FzZSBTTl9FUlJfTk9ORToKCQkJLy9mcHJpbnRmKHN0ZGVyciwiMDogYz0lZCwgcz0lZFxuIiwgYywgcyk7CgkJCXQtPnNydl9zdGF0ZSA9IFNWX1NUQ09OTjsKCQkJaWYgKHQtPnNydikKCQkJCXQtPnNydi0+Y3VtX3Nlc3MrKzsKCQkJcmV0dXJuIDE7CgkgICAgCgkJY2FzZSBTTl9FUlJfSU5URVJOQUw6CgkJCXR2X2V0ZXJuaXR5KCZ0LT5yZXEtPmNleCk7CgkJCXNydl9jbG9zZV93aXRoX2Vycih0LCBTTl9FUlJfSU5URVJOQUwsIFNOX0ZJTlNUX0MsCgkJCQkJICAgNTAwLCBlcnJvcl9tZXNzYWdlKHQsIEhUVFBfRVJSXzUwMCkpOwoJCQlpZiAodC0+c3J2KQoJCQkJdC0+c3J2LT5jdW1fc2VzcysrOwoJCQlpZiAodC0+c3J2KQoJCQkJdC0+c3J2LT5mYWlsZWRfY29ubnMrKzsKCQkJdC0+YmUtPmZhaWxlZF9jb25ucysrOwoJCQkvKiByZWxlYXNlIG90aGVyIHNlc3Npb25zIHdhaXRpbmcgZm9yIHRoaXMgc2VydmVyICovCgkJCWlmIChtYXlfZGVxdWV1ZV90YXNrcyh0LT5zcnYsIHQtPmJlKSkKCQkJCXRhc2tfd2FrZXVwKHQtPnNydi0+cXVldWVfbWd0KTsKCQkJcmV0dXJuIDE7CgkJfQoJCS8qIGVuc3VyZSB0aGF0IHdlIGhhdmUgZW5vdWdoIHJldHJpZXMgbGVmdCAqLwoJCWlmIChzcnZfY291bnRfcmV0cnlfZG93bih0LCBjb25uX2VycikpIHsKCQkJcmV0dXJuIDE7CgkJfQoJfSB3aGlsZSAodC0+c3J2ID09IE5VTEwgfHwgdC0+Y29ubl9yZXRyaWVzID4gMCB8fCAhKHQtPmJlLT5vcHRpb25zICYgUFJfT19SRURJU1ApKTsKCgkvKiBXZSdyZSBvbiBvdXIgbGFzdCBjaGFuY2UsIGFuZCB0aGUgUkVESVNQIG9wdGlvbiB3YXMgc3BlY2lmaWVkLgoJICogV2Ugd2lsbCBpZ25vcmUgY29va2llIGFuZCBmb3JjZSB0byBiYWxhbmNlIG9yIHVzZSB0aGUgZGlzcGF0Y2hlci4KCSAqLwoJLyogbGV0J3MgdHJ5IHRvIG9mZmVyIHRoaXMgc2xvdCB0byBhbnlib2R5ICovCglpZiAobWF5X2RlcXVldWVfdGFza3ModC0+c3J2LCB0LT5iZSkpCgkJdGFza193YWtldXAodC0+c3J2LT5xdWV1ZV9tZ3QpOwoKCWlmICh0LT5zcnYpIHsKCQl0LT5zcnYtPmN1bV9zZXNzKys7CgkJdC0+c3J2LT5mYWlsZWRfY29ubnMrKzsKCQl0LT5zcnYtPnJlZGlzcGF0Y2hlcysrOwoJfQoJdC0+YmUtPnJlZGlzcGF0Y2hlcysrOwoKCXQtPmZsYWdzICY9IH4oU05fRElSRUNUIHwgU05fQVNTSUdORUQgfCBTTl9BRERSX1NFVCk7Cgl0LT5mbGFncyB8PSBTTl9SRURJU1A7Cgl0LT5zcnYgPSBOVUxMOyAvKiBpdCdzIGxlZnQgdG8gdGhlIGRpc3BhdGNoZXIgdG8gY2hvb3NlIGEgc2VydmVyICovCglodHRwX2ZsdXNoX2Nvb2tpZV9mbGFncygmdC0+dHhuKTsKCXJldHVybiAwOwp9CgogICAgCi8qIFRoaXMgZnVuY3Rpb24gcGVyZm9ybXMgdGhlICJyZWRpc3BhdGNoIiBwYXJ0IG9mIGEgY29ubmVjdGlvbiBhdHRlbXB0LiBJdAogKiB3aWxsIGFzc2lnbiBhIHNlcnZlciBpZiByZXF1aXJlZCwgcXVldWUgdGhlIGNvbm5lY3Rpb24gaWYgcmVxdWlyZWQsIGFuZAogKiBoYW5kbGUgZXJyb3JzIHRoYXQgbWlnaHQgYXJpc2UgYXQgdGhpcyBsZXZlbC4gSXQgY2FuIGNoYW5nZSB0aGUgc2VydmVyCiAqIHN0YXRlLiBJdCB3aWxsIHJldHVybiAxIGlmIGl0IGVuY291bnRlcnMgYW4gZXJyb3IsIHN3aXRjaGVzIHRoZSBzZXJ2ZXIKICogc3RhdGUsIG9yIGhhcyB0byBxdWV1ZSBhIGNvbm5lY3Rpb24uIE90aGVyd2lzZSwgaXQgd2lsbCByZXR1cm4gMCBpbmRpY2F0aW5nCiAqIHRoYXQgdGhlIGNvbm5lY3Rpb24gaXMgcmVhZHkgdG8gdXNlLgogKi8KCmludCBzcnZfcmVkaXNwYXRjaF9jb25uZWN0KHN0cnVjdCBzZXNzaW9uICp0KQp7CglpbnQgY29ubl9lcnI7CgoJLyogV2Uga25vdyB0aGF0IHdlIGRvbid0IGhhdmUgYW55IGNvbm5lY3Rpb24gcGVuZGluZywgc28gd2Ugd2lsbAoJICogdHJ5IHRvIGdldCBhIG5ldyBvbmUsIGFuZCB3YWl0IGluIHRoaXMgc3RhdGUgaWYgaXQncyBxdWV1ZWQKCSAqLwoJY29ubl9lcnIgPSBhc3NpZ25fc2VydmVyX2FuZF9xdWV1ZSh0KTsKCXN3aXRjaCAoY29ubl9lcnIpIHsKCWNhc2UgU1JWX1NUQVRVU19PSzoKCQlicmVhazsKCgljYXNlIFNSVl9TVEFUVVNfTk9TUlY6CgkJLyogbm90ZTogaXQgaXMgZ3VhcmFudGVlZCB0aGF0IHQtPnNydiA9PSBOVUxMIGhlcmUgKi8KCQl0dl9ldGVybml0eSgmdC0+cmVxLT5jZXgpOwoJCXNydl9jbG9zZV93aXRoX2Vycih0LCBTTl9FUlJfU1JWVE8sIFNOX0ZJTlNUX0MsCgkJCQkgICA1MDMsIGVycm9yX21lc3NhZ2UodCwgSFRUUF9FUlJfNTAzKSk7CgkJaWYgKHQtPnNydikKCQkJdC0+c3J2LT5jdW1fc2VzcysrOwoJCWlmICh0LT5zcnYpCgkJCXQtPnNydi0+ZmFpbGVkX2Nvbm5zKys7CgkJdC0+YmUtPmZhaWxlZF9jb25ucysrOwoKCQlyZXR1cm4gMTsKCgljYXNlIFNSVl9TVEFUVVNfUVVFVUVEOgoJCS8qIG5vdGU6IHdlIHVzZSB0aGUgY29ubmVjdCBleHBpcmF0aW9uIGRhdGUgZm9yIHRoZSBxdWV1ZS4gKi8KCQlpZiAoIXR2X2FkZF9pZnNldCgmdC0+cmVxLT5jZXgsICZub3csICZ0LT5iZS0+dGltZW91dC5xdWV1ZSkpCgkJCXR2X2V0ZXJuaXR5KCZ0LT5yZXEtPmNleCk7CgkJdC0+c3J2X3N0YXRlID0gU1ZfU1RJRExFOwoJCS8qIGRvIG5vdGhpbmcgZWxzZSBhbmQgZG8gbm90IHdha2UgYW55IG90aGVyIHNlc3Npb24gdXAgKi8KCQlyZXR1cm4gMTsKCgljYXNlIFNSVl9TVEFUVVNfRlVMTDoKCWNhc2UgU1JWX1NUQVRVU19JTlRFUk5BTDoKCWRlZmF1bHQ6CgkJdHZfZXRlcm5pdHkoJnQtPnJlcS0+Y2V4KTsKCQlzcnZfY2xvc2Vfd2l0aF9lcnIodCwgU05fRVJSX0lOVEVSTkFMLCBTTl9GSU5TVF9DLAoJCQkJICAgNTAwLCBlcnJvcl9tZXNzYWdlKHQsIEhUVFBfRVJSXzUwMCkpOwoJCWlmICh0LT5zcnYpCgkJCXQtPnNydi0+Y3VtX3Nlc3MrKzsKCQlpZiAodC0+c3J2KQoJCQl0LT5zcnYtPmZhaWxlZF9jb25ucysrOwoJCXQtPmJlLT5mYWlsZWRfY29ubnMrKzsKCgkJLyogcmVsZWFzZSBvdGhlciBzZXNzaW9ucyB3YWl0aW5nIGZvciB0aGlzIHNlcnZlciAqLwoJCWlmIChtYXlfZGVxdWV1ZV90YXNrcyh0LT5zcnYsIHQtPmJlKSkKCQkJdGFza193YWtldXAodC0+c3J2LT5xdWV1ZV9tZ3QpOwoJCXJldHVybiAxOwoJfQoJLyogaWYgd2UgZ2V0IGhlcmUsIGl0J3MgYmVjYXVzZSB3ZSBnb3QgU1JWX1NUQVRVU19PSywgd2hpY2ggYWxzbwoJICogbWVhbnMgdGhhdCB0aGUgY29ubmVjdGlvbiBoYXMgbm90IGJlZW4gcXVldWVkLgoJICovCglyZXR1cm4gMDsKfQoKaW50IGJlX2Rvd250aW1lKHN0cnVjdCBwcm94eSAqcHgpIHsKCWlmIChweC0+bGJwcm0udG90X3dlaWdodCAmJiBweC0+bGFzdF9jaGFuZ2UgPCBub3cudHZfc2VjKSAgLy8gaWdub3JlIG5lZ2F0aXZlIHRpbWUKCQlyZXR1cm4gcHgtPmRvd25fdGltZTsKCglyZXR1cm4gbm93LnR2X3NlYyAtIHB4LT5sYXN0X2NoYW5nZSArIHB4LT5kb3duX3RpbWU7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gcGFyc2VzIGEgImJhbGFuY2UiIHN0YXRlbWVudCBpbiBhIGJhY2tlbmQgc2VjdGlvbiBkZXNjcmliaW5nCiAqIDxjdXJwcm94eT4uIEl0IHJldHVybnMgLTEgaWYgdGhlcmUgaXMgYW55IGVycm9yLCBvdGhlcndpc2UgemVyby4gSWYgaXQKICogcmV0dXJucyAtMSwgaXQgbWF5IHdyaXRlIGFuIGVycm9yIG1lc3NhZ2UgaW50byB0aGVyIDxlcnI+IGJ1ZmZlciwgZm9yIGF0CiAqIG1vc3QgPGVycmxlbj4gYnl0ZXMsIHRyYWlsaW5nIHplcm8gaW5jbHVkZWQuIFRoZSB0cmFpbGluZyAnXG4nIHdpbGwgbm90IGJlCiAqIHdyaXR0ZW4uIFRoZSBmdW5jdGlvbiBtdXN0IGJlIGNhbGxlZCB3aXRoIDxhcmdzPiBwb2ludGluZyB0byB0aGUgZmlyc3Qgd29yZAogKiBhZnRlciAiYmFsYW5jZSIuCiAqLwppbnQgYmFja2VuZF9wYXJzZV9iYWxhbmNlKGNvbnN0IGNoYXIgKiphcmdzLCBjaGFyICplcnIsIGludCBlcnJsZW4sIHN0cnVjdCBwcm94eSAqY3VycHJveHkpCnsKCWlmICghKihhcmdzWzBdKSkgewoJCS8qIGlmIG5vIG9wdGlvbiBpcyBzZXQsIHVzZSByb3VuZC1yb2JpbiBieSBkZWZhdWx0ICovCgkJY3VycHJveHktPmxicHJtLmFsZ28gJj0gfkJFX0xCX0FMR087CgkJY3VycHJveHktPmxicHJtLmFsZ28gfD0gQkVfTEJfQUxHT19SUjsKCQlyZXR1cm4gMDsKCX0KCglpZiAoIXN0cmNtcChhcmdzWzBdLCAicm91bmRyb2JpbiIpKSB7CgkJY3VycHJveHktPmxicHJtLmFsZ28gJj0gfkJFX0xCX0FMR087CgkJY3VycHJveHktPmxicHJtLmFsZ28gfD0gQkVfTEJfQUxHT19SUjsKCX0KCWVsc2UgaWYgKCFzdHJjbXAoYXJnc1swXSwgInNvdXJjZSIpKSB7CgkJY3VycHJveHktPmxicHJtLmFsZ28gJj0gfkJFX0xCX0FMR087CgkJY3VycHJveHktPmxicHJtLmFsZ28gfD0gQkVfTEJfQUxHT19TSDsKCX0KCWVsc2UgaWYgKCFzdHJjbXAoYXJnc1swXSwgInVyaSIpKSB7CgkJY3VycHJveHktPmxicHJtLmFsZ28gJj0gfkJFX0xCX0FMR087CgkJY3VycHJveHktPmxicHJtLmFsZ28gfD0gQkVfTEJfQUxHT19VSDsKCX0KCWVsc2UgaWYgKCFzdHJjbXAoYXJnc1swXSwgInVybF9wYXJhbSIpKSB7CgkJaWYgKCEqYXJnc1sxXSkgewoJCQlzbnByaW50ZihlcnIsIGVycmxlbiwgIidiYWxhbmNlIHVybF9wYXJhbScgcmVxdWlyZXMgYW4gVVJMIHBhcmFtZXRlciBuYW1lLiIpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCWN1cnByb3h5LT5sYnBybS5hbGdvICY9IH5CRV9MQl9BTEdPOwoJCWN1cnByb3h5LT5sYnBybS5hbGdvIHw9IEJFX0xCX0FMR09fUEg7CgkJaWYgKGN1cnByb3h5LT51cmxfcGFyYW1fbmFtZSkKCQkJZnJlZShjdXJwcm94eS0+dXJsX3BhcmFtX25hbWUpOwoJCWN1cnByb3h5LT51cmxfcGFyYW1fbmFtZSA9IHN0cmR1cChhcmdzWzFdKTsKCQljdXJwcm94eS0+dXJsX3BhcmFtX2xlbiA9IHN0cmxlbihhcmdzWzFdKTsKCX0KCWVsc2UgewoJCXNucHJpbnRmKGVyciwgZXJybGVuLCAiJ2JhbGFuY2UnIG9ubHkgc3VwcG9ydHMgJ3JvdW5kcm9iaW4nLCAnc291cmNlJywgJ3VyaScgYW5kICd1cmxfcGFyYW0nIG9wdGlvbnMuIik7CgkJcmV0dXJuIC0xOwoJfQoJcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICBBbGwgc3VwcG9ydGVkIGtleXdvcmRzIG11c3QgYmUgZGVjbGFyZWQgaGVyZS4gICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogc2V0IHRlc3QtPmkgdG8gdGhlIG51bWJlciBvZiBlbmFibGVkIHNlcnZlcnMgb24gdGhlIHByb3h5ICovCnN0YXRpYyBpbnQKYWNsX2ZldGNoX25ic3J2KHN0cnVjdCBwcm94eSAqcHgsIHN0cnVjdCBzZXNzaW9uICpsNCwgdm9pZCAqbDcsIGludCBkaXIsCiAgICAgICAgICAgICAgICBzdHJ1Y3QgYWNsX2V4cHIgKmV4cHIsIHN0cnVjdCBhY2xfdGVzdCAqdGVzdCkKewoJdGVzdC0+ZmxhZ3MgPSBBQ0xfVEVTVF9GX1ZPTF9URVNUOwoJaWYgKGV4cHItPmFyZ19sZW4pIHsKCQkvKiBhbm90aGVyIHByb3h5IHdhcyBkZXNpZ25hdGVkLCB3ZSBtdXN0IGxvb2sgZm9yIGl0ICovCgkJZm9yIChweCA9IHByb3h5OyBweDsgcHggPSBweC0+bmV4dCkKCQkJaWYgKChweC0+Y2FwICYgUFJfQ0FQX0JFKSAmJiAhc3RyY21wKHB4LT5pZCwgZXhwci0+YXJnLnN0cikpCgkJCQlicmVhazsKCX0KCWlmICghcHgpCgkJcmV0dXJuIDA7CgoJaWYgKHB4LT5zcnZfYWN0KQoJCXRlc3QtPmkgPSBweC0+c3J2X2FjdDsKCWVsc2UgaWYgKHB4LT5sYnBybS5mYmNrKQoJCXRlc3QtPmkgPSAxOwoJZWxzZQoJCXRlc3QtPmkgPSBweC0+c3J2X2JjazsKCglyZXR1cm4gMTsKfQoKCi8qIE5vdGU6IG11c3Qgbm90IGJlIGRlY2xhcmVkIDxjb25zdD4gYXMgaXRzIGxpc3Qgd2lsbCBiZSBvdmVyd3JpdHRlbiAqLwpzdGF0aWMgc3RydWN0IGFjbF9rd19saXN0IGFjbF9rd3MgPSB7eyB9LHsKCXsgIm5ic3J2IiwgICBhY2xfcGFyc2VfaW50LCAgIGFjbF9mZXRjaF9uYnNydiwgICAgYWNsX21hdGNoX2ludCB9LAoJeyBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMIH0sCn19OwoKCl9fYXR0cmlidXRlX18oKGNvbnN0cnVjdG9yKSkKc3RhdGljIHZvaWQgX19iYWNrZW5kX2luaXQodm9pZCkKewoJYWNsX3JlZ2lzdGVyX2tleXdvcmRzKCZhY2xfa3dzKTsKfQoKCi8qCiAqIExvY2FsIHZhcmlhYmxlczoKICogIGMtaW5kZW50LWxldmVsOiA4CiAqICBjLWJhc2ljLW9mZnNldDogOAogKiBFbmQ6CiAqLwo=