LyoKICogQmFja2VuZCB2YXJpYWJsZXMgYW5kIGZ1bmN0aW9ucy4KICoKICogQ29weXJpZ2h0IDIwMDAtMjAwOCBXaWxseSBUYXJyZWF1IDx3QDF3dC5ldT4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24KICogMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICovCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzeXNsb2cuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCiNpbmNsdWRlIDxjb21tb24vY29tcGF0Lmg+CiNpbmNsdWRlIDxjb21tb24vY29uZmlnLmg+CiNpbmNsdWRlIDxjb21tb24vZGVidWcuaD4KI2luY2x1ZGUgPGNvbW1vbi9lYjMydHJlZS5oPgojaW5jbHVkZSA8Y29tbW9uL3RpbWUuaD4KCiNpbmNsdWRlIDx0eXBlcy9hY2wuaD4KI2luY2x1ZGUgPHR5cGVzL2J1ZmZlcnMuaD4KI2luY2x1ZGUgPHR5cGVzL2dsb2JhbC5oPgojaW5jbHVkZSA8dHlwZXMvcG9sbGluZy5oPgojaW5jbHVkZSA8dHlwZXMvcHJveHkuaD4KI2luY2x1ZGUgPHR5cGVzL3NlcnZlci5oPgojaW5jbHVkZSA8dHlwZXMvc2Vzc2lvbi5oPgoKI2luY2x1ZGUgPHByb3RvL2FjbC5oPgojaW5jbHVkZSA8cHJvdG8vYmFja2VuZC5oPgojaW5jbHVkZSA8cHJvdG8vY2xpZW50Lmg+CiNpbmNsdWRlIDxwcm90by9mZC5oPgojaW5jbHVkZSA8cHJvdG8vaHR0cGVyci5oPgojaW5jbHVkZSA8cHJvdG8vbG9nLmg+CiNpbmNsdWRlIDxwcm90by9wcm90b19odHRwLmg+CiNpbmNsdWRlIDxwcm90by9wcm90b190Y3AuaD4KI2luY2x1ZGUgPHByb3RvL3F1ZXVlLmg+CiNpbmNsdWRlIDxwcm90by9zZXNzaW9uLmg+CiNpbmNsdWRlIDxwcm90by9zdHJlYW1fc29jay5oPgojaW5jbHVkZSA8cHJvdG8vdGFzay5oPgoKI2lmZGVmIENPTkZJR19IQVBfVENQU1BMSUNFCiNpbmNsdWRlIDxsaWJ0Y3BzcGxpY2UuaD4KI2VuZGlmCgpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9yZW1vdmVfZnJvbV90cmVlKHN0cnVjdCBzZXJ2ZXIgKnMpOwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9xdWV1ZV9ieV93ZWlnaHQoc3RydWN0IGViX3Jvb3QgKnJvb3QsIHN0cnVjdCBzZXJ2ZXIgKnMpOwpzdGF0aWMgaW5saW5lIHZvaWQgZndycl9kZXF1ZXVlX3NydihzdHJ1Y3Qgc2VydmVyICpzKTsKc3RhdGljIHZvaWQgZndycl9nZXRfc3J2KHN0cnVjdCBzZXJ2ZXIgKnMpOwpzdGF0aWMgdm9pZCBmd3JyX3F1ZXVlX3NydihzdHJ1Y3Qgc2VydmVyICpzKTsKCi8qIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBub24temVybyBpZiBhIHNlcnZlciB3aXRoIHRoZSBnaXZlbiB3ZWlnaHQgYW5kIHN0YXRlCiAqIGlzIHVzYWJsZSBmb3IgTEIsIG90aGVyd2lzZSB6ZXJvLgogKi8Kc3RhdGljIGlubGluZSBpbnQgc3J2X2lzX3VzYWJsZShpbnQgc3RhdGUsIGludCB3ZWlnaHQpCnsKCWlmICghd2VpZ2h0KQoJCXJldHVybiAwOwoJaWYgKHN0YXRlICYgU1JWX0dPSU5HRE9XTikKCQlyZXR1cm4gMDsKCWlmICghKHN0YXRlICYgU1JWX1JVTk5JTkcpKQoJCXJldHVybiAwOwoJcmV0dXJuIDE7Cn0KCi8qCiAqIFRoaXMgZnVuY3Rpb24gcmVjb3VudHMgdGhlIG51bWJlciBvZiB1c2FibGUgYWN0aXZlIGFuZCBiYWNrdXAgc2VydmVycyBmb3IKICogcHJveHkgPHA+LiBUaGVzZSBudW1iZXJzIGFyZSByZXR1cm5lZCBpbnRvIHRoZSBwLT5zcnZfYWN0IGFuZCBwLT5zcnZfYmNrLgogKiBUaGlzIGZ1bmN0aW9uIGFsc28gcmVjb21wdXRlcyB0aGUgdG90YWwgYWN0aXZlIGFuZCBiYWNrdXAgd2VpZ2h0cy4gSG93ZXZlciwKICogaXQgZG9lcyBub3QgdXBkYXRlIHRvdF93ZWlnaHQgbm9yIHRvdF91c2VkLiBVc2UgdXBkYXRlX2JhY2tlbmRfd2VpZ2h0KCkgZm9yCiAqIHRoaXMuCiAqLwpzdGF0aWMgdm9pZCByZWNvdW50X3NlcnZlcnMoc3RydWN0IHByb3h5ICpweCkKewoJc3RydWN0IHNlcnZlciAqc3J2OwoKCXB4LT5zcnZfYWN0ID0gcHgtPnNydl9iY2sgPSAwOwoJcHgtPmxicHJtLnRvdF93YWN0ID0gcHgtPmxicHJtLnRvdF93YmNrID0gMDsKCXB4LT5sYnBybS5mYmNrID0gTlVMTDsKCWZvciAoc3J2ID0gcHgtPnNydjsgc3J2ICE9IE5VTEw7IHNydiA9IHNydi0+bmV4dCkgewoJCWlmICghc3J2X2lzX3VzYWJsZShzcnYtPnN0YXRlLCBzcnYtPmV3ZWlnaHQpKQoJCQljb250aW51ZTsKCgkJaWYgKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSB7CgkJCWlmICghcHgtPnNydl9iY2sgJiYKCQkJICAgICEocHgtPm9wdGlvbnMgJiBQUl9PX1VTRV9BTExfQkspKQoJCQkJcHgtPmxicHJtLmZiY2sgPSBzcnY7CgkJCXB4LT5zcnZfYmNrKys7CgkJCXB4LT5sYnBybS50b3Rfd2JjayArPSBzcnYtPmV3ZWlnaHQ7CgkJfSBlbHNlIHsKCQkJcHgtPnNydl9hY3QrKzsKCQkJcHgtPmxicHJtLnRvdF93YWN0ICs9IHNydi0+ZXdlaWdodDsKCQl9Cgl9Cn0KCi8qIFRoaXMgZnVuY3Rpb24gc2ltcGx5IHVwZGF0ZXMgdGhlIGJhY2tlbmQncyB0b3Rfd2VpZ2h0IGFuZCB0b3RfdXNlZCB2YWx1ZXMKICogYWZ0ZXIgc2VydmVycyB3ZWlnaHRzIGhhdmUgYmVlbiB1cGRhdGVkLiBJdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGFmdGVyCiAqIHJlY291bnRfc2VydmVycygpIG9yIGVxdWl2YWxlbnQuCiAqLwpzdGF0aWMgdm9pZCB1cGRhdGVfYmFja2VuZF93ZWlnaHQoc3RydWN0IHByb3h5ICpweCkKewoJaWYgKHB4LT5zcnZfYWN0KSB7CgkJcHgtPmxicHJtLnRvdF93ZWlnaHQgPSBweC0+bGJwcm0udG90X3dhY3Q7CgkJcHgtPmxicHJtLnRvdF91c2VkICAgPSBweC0+c3J2X2FjdDsKCX0KCWVsc2UgaWYgKHB4LT5sYnBybS5mYmNrKSB7CgkJLyogdXNlIG9ubHkgdGhlIGZpcnN0IGJhY2t1cCBzZXJ2ZXIgKi8KCQlweC0+bGJwcm0udG90X3dlaWdodCA9IHB4LT5sYnBybS5mYmNrLT5ld2VpZ2h0OwoJCXB4LT5sYnBybS50b3RfdXNlZCA9IDE7Cgl9CgllbHNlIHsKCQlweC0+bGJwcm0udG90X3dlaWdodCA9IHB4LT5sYnBybS50b3Rfd2JjazsKCQlweC0+bGJwcm0udG90X3VzZWQgICA9IHB4LT5zcnZfYmNrOwoJfQp9CgovKiB0aGlzIGZ1bmN0aW9uIHVwZGF0ZXMgdGhlIG1hcCBhY2NvcmRpbmcgdG8gc2VydmVyIDxzcnY+J3MgbmV3IHN0YXRlICovCnN0YXRpYyB2b2lkIG1hcF9zZXRfc2VydmVyX3N0YXR1c19kb3duKHN0cnVjdCBzZXJ2ZXIgKnNydikKewoJc3RydWN0IHByb3h5ICpwID0gc3J2LT5wcm94eTsKCglpZiAoc3J2LT5zdGF0ZSA9PSBzcnYtPnByZXZfc3RhdGUgJiYKCSAgICBzcnYtPmV3ZWlnaHQgPT0gc3J2LT5wcmV2X2V3ZWlnaHQpCgkJcmV0dXJuOwoKCWlmIChzcnZfaXNfdXNhYmxlKHNydi0+c3RhdGUsIHNydi0+ZXdlaWdodCkpCgkJZ290byBvdXRfdXBkYXRlX3N0YXRlOwoKCS8qIEZJWE1FOiBjb3VsZCBiZSBvcHRpbWl6ZWQgc2luY2Ugd2Uga25vdyB3aGF0IGNoYW5nZWQgKi8KCXJlY291bnRfc2VydmVycyhwKTsKCXVwZGF0ZV9iYWNrZW5kX3dlaWdodChwKTsKCXAtPmxicHJtLm1hcC5zdGF0ZSB8PSBQUl9NQVBfUkVDQUxDOwogb3V0X3VwZGF0ZV9zdGF0ZToKCXNydi0+cHJldl9zdGF0ZSA9IHNydi0+c3RhdGU7CglzcnYtPnByZXZfZXdlaWdodCA9IHNydi0+ZXdlaWdodDsKfQoKLyogVGhpcyBmdW5jdGlvbiB1cGRhdGVzIHRoZSBtYXAgYWNjb3JkaW5nIHRvIHNlcnZlciA8c3J2PidzIG5ldyBzdGF0ZSAqLwpzdGF0aWMgdm9pZCBtYXBfc2V0X3NlcnZlcl9zdGF0dXNfdXAoc3RydWN0IHNlcnZlciAqc3J2KQp7CglzdHJ1Y3QgcHJveHkgKnAgPSBzcnYtPnByb3h5OwoKCWlmIChzcnYtPnN0YXRlID09IHNydi0+cHJldl9zdGF0ZSAmJgoJICAgIHNydi0+ZXdlaWdodCA9PSBzcnYtPnByZXZfZXdlaWdodCkKCQlyZXR1cm47CgoJaWYgKCFzcnZfaXNfdXNhYmxlKHNydi0+c3RhdGUsIHNydi0+ZXdlaWdodCkpCgkJZ290byBvdXRfdXBkYXRlX3N0YXRlOwoKCS8qIEZJWE1FOiBjb3VsZCBiZSBvcHRpbWl6ZWQgc2luY2Ugd2Uga25vdyB3aGF0IGNoYW5nZWQgKi8KCXJlY291bnRfc2VydmVycyhwKTsKCXVwZGF0ZV9iYWNrZW5kX3dlaWdodChwKTsKCXAtPmxicHJtLm1hcC5zdGF0ZSB8PSBQUl9NQVBfUkVDQUxDOwogb3V0X3VwZGF0ZV9zdGF0ZToKCXNydi0+cHJldl9zdGF0ZSA9IHNydi0+c3RhdGU7CglzcnYtPnByZXZfZXdlaWdodCA9IHNydi0+ZXdlaWdodDsKfQoKLyogVGhpcyBmdW5jdGlvbiByZWNvbXB1dGVzIHRoZSBzZXJ2ZXIgbWFwIGZvciBwcm94eSBweC4gSXQgcmVsaWVzIG9uCiAqIHB4LT5sYnBybS50b3Rfd2FjdCwgdG90X3diY2ssIHRvdF91c2VkLCB0b3Rfd2VpZ2h0LCBzbyBpdCBtdXN0IGJlCiAqIGNhbGxlZCBhZnRlciByZWNvdW50X3NlcnZlcnMoKS4gSXQgYWxzbyBleHBlY3RzIHB4LT5sYnBybS5tYXAuc3J2CiAqIHRvIGJlIGFsbG9jYXRlZCB3aXRoIHRoZSBsYXJnZXN0IHNpemUgbmVlZGVkLiBJdCB1cGRhdGVzIHRvdF93ZWlnaHQuCiAqLwp2b2lkIHJlY2FsY19zZXJ2ZXJfbWFwKHN0cnVjdCBwcm94eSAqcHgpCnsKCWludCBvLCB0b3QsIGZsYWc7CglzdHJ1Y3Qgc2VydmVyICpjdXIsICpiZXN0OwoKCXN3aXRjaCAocHgtPmxicHJtLnRvdF91c2VkKSB7CgljYXNlIDA6CS8qIG5vIHNlcnZlciAqLwoJCXB4LT5sYnBybS5tYXAuc3RhdGUgJj0gflBSX01BUF9SRUNBTEM7CgkJcmV0dXJuOwoJY2FzZSAxOiAvKiBvbmx5IG9uZSBzZXJ2ZXIsIGp1c3QgZmlsbCBmaXJzdCBlbnRyeSAqLwoJCXRvdCA9IDE7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXRvdCA9IHB4LT5sYnBybS50b3Rfd2VpZ2h0OwoJCWJyZWFrOwoJfQoKCS8qIGhlcmUgd2UgKmtub3cqIHRoYXQgd2UgaGF2ZSBzb21lIHNlcnZlcnMgKi8KCWlmIChweC0+c3J2X2FjdCkKCQlmbGFnID0gU1JWX1JVTk5JTkc7CgllbHNlCgkJZmxhZyA9IFNSVl9SVU5OSU5HIHwgU1JWX0JBQ0tVUDsKCgkvKiB0aGlzIGFsZ29yaXRobSBnaXZlcyBwcmlvcml0eSB0byB0aGUgZmlyc3Qgc2VydmVyLCB3aGljaCBtZWFucyB0aGF0CgkgKiBpdCB3aWxsIHJlc3BlY3QgdGhlIGRlY2xhcmF0aW9uIG9yZGVyIGZvciBlcXVpdmFsZW50IHdlaWdodHMsIGFuZAoJICogdGhhdCB3aGF0ZXZlciB0aGUgd2VpZ2h0cywgdGhlIGZpcnN0IHNlcnZlciBjYWxsZWQgd2lsbCBhbHdheXMgYmUKCSAqIHRoZSBmaXJzdCBkZWNsYXJlZC4gVGhpcyBpcyBhbiBpbXBvcnRhbnQgYXN1bXB0aW9uIGZvciB0aGUgYmFja3VwCgkgKiBjYXNlLCB3aGVyZSB3ZSB3YW50IHRoZSBmaXJzdCBzZXJ2ZXIgb25seS4KCSAqLwoJZm9yIChjdXIgPSBweC0+c3J2OyBjdXI7IGN1ciA9IGN1ci0+bmV4dCkKCQljdXItPndzY29yZSA9IDA7CgoJZm9yIChvID0gMDsgbyA8IHRvdDsgbysrKSB7CgkJaW50IG1heCA9IDA7CgkJYmVzdCA9IE5VTEw7CgkJZm9yIChjdXIgPSBweC0+c3J2OyBjdXI7IGN1ciA9IGN1ci0+bmV4dCkgewoJCQlpZiAoZmxhZyA9PSAoY3VyLT5zdGF0ZSAmCgkJCQkgICAgIChTUlZfUlVOTklORyB8IFNSVl9HT0lOR0RPV04gfCBTUlZfQkFDS1VQKSkpIHsKCQkJCWludCB2OwoKCQkJCS8qIElmIHdlIGFyZSBmb3JjZWQgdG8gcmV0dXJuIG9ubHkgb25lIHNlcnZlciwgd2UgZG9uJ3Qgd2FudCB0bwoJCQkJICogZ28gZnVydGhlciwgYmVjYXVzZSB3ZSB3b3VsZCByZXR1cm4gdGhlIHdyb25nIG9uZSBkdWUgdG8KCQkJCSAqIGRpdmlkZSBvdmVyZmxvdy4KCQkJCSAqLwoJCQkJaWYgKHRvdCA9PSAxKSB7CgkJCQkJYmVzdCA9IGN1cjsKCQkJCQkvKiBub3RlIHRoYXQgYmVzdC0+d3Njb3JlIHdpbGwgYmUgd3JvbmcgYnV0IHdlIGRvbid0IGNhcmUgKi8KCQkJCQlicmVhazsKCQkJCX0KCgkJCQljdXItPndzY29yZSArPSBjdXItPmV3ZWlnaHQ7CgkJCQl2ID0gKGN1ci0+d3Njb3JlICsgdG90KSAvIHRvdDsgLyogcmVzdWx0IGJldHdlZW4gMCBhbmQgMyAqLwoJCQkJaWYgKGJlc3QgPT0gTlVMTCB8fCB2ID4gbWF4KSB7CgkJCQkJbWF4ID0gdjsKCQkJCQliZXN0ID0gY3VyOwoJCQkJfQoJCQl9CgkJfQoJCXB4LT5sYnBybS5tYXAuc3J2W29dID0gYmVzdDsKCQliZXN0LT53c2NvcmUgLT0gdG90OwoJfQoJcHgtPmxicHJtLm1hcC5zdGF0ZSAmPSB+UFJfTUFQX1JFQ0FMQzsKfQoKLyogVGhpcyBmdW5jdGlvbiBpcyByZXNwb25zaWJsZSBvZiBidWlsZGluZyB0aGUgc2VydmVyIE1BUCBmb3IgbWFwLWJhc2VkIExCCiAqIGFsZ29yaXRobXMsIGFsbG9jYXRpbmcgdGhlIG1hcCwgYW5kIHNldHRpbmcgcC0+bGJwcm0ud211bHQgdG8gdGhlIEdDRCBvZiB0aGUKICogd2VpZ2h0cyBpZiBhcHBsaWNhYmxlLiBJdCBzaG91bGQgYmUgY2FsbGVkIG9ubHkgb25jZSBwZXIgcHJveHksIGF0IGNvbmZpZwogKiB0aW1lLgogKi8Kdm9pZCBpbml0X3NlcnZlcl9tYXAoc3RydWN0IHByb3h5ICpwKQp7CglzdHJ1Y3Qgc2VydmVyICpzcnY7CglpbnQgcGdjZDsKCWludCBhY3QsIGJjazsKCglwLT5sYnBybS5zZXRfc2VydmVyX3N0YXR1c191cCAgID0gbWFwX3NldF9zZXJ2ZXJfc3RhdHVzX3VwOwoJcC0+bGJwcm0uc2V0X3NlcnZlcl9zdGF0dXNfZG93biA9IG1hcF9zZXRfc2VydmVyX3N0YXR1c19kb3duOwoJcC0+bGJwcm0udXBkYXRlX3NlcnZlcl9ld2VpZ2h0ID0gTlVMTDsKIAoJaWYgKCFwLT5zcnYpCgkJcmV0dXJuOwoKCS8qIFdlIHdpbGwgZmFjdG9yIHRoZSB3ZWlnaHRzIHRvIHJlZHVjZSB0aGUgdGFibGUsCgkgKiB1c2luZyBFdWNsaWRlJ3MgbGFyZ2VzdCBjb21tb24gZGl2aXNvciBhbGdvcml0aG0KCSAqLwoJcGdjZCA9IHAtPnNydi0+dXdlaWdodDsKCWZvciAoc3J2ID0gcC0+c3J2LT5uZXh0OyBzcnYgJiYgcGdjZCA+IDE7IHNydiA9IHNydi0+bmV4dCkgewoJCWludCB3ID0gc3J2LT51d2VpZ2h0OwoJCXdoaWxlICh3KSB7CgkJCWludCB0ID0gcGdjZCAlIHc7CgkJCXBnY2QgPSB3OwoJCQl3ID0gdDsKCQl9Cgl9CgoJLyogSXQgaXMgc29tZXRpbWVzIHVzZWZ1bCB0byBrbm93IHdoYXQgZmFjdG9yIHRvIGFwcGx5CgkgKiB0byB0aGUgYmFja2VuZCdzIGVmZmVjdGl2ZSB3ZWlnaHQgdG8ga25vdyBpdHMgcmVhbAoJICogd2VpZ2h0LgoJICovCglwLT5sYnBybS53bXVsdCA9IHBnY2Q7CgoJYWN0ID0gYmNrID0gMDsKCWZvciAoc3J2ID0gcC0+c3J2OyBzcnY7IHNydiA9IHNydi0+bmV4dCkgewoJCXNydi0+ZXdlaWdodCA9IHNydi0+dXdlaWdodCAvIHBnY2Q7CgkJc3J2LT5wcmV2X2V3ZWlnaHQgPSBzcnYtPmV3ZWlnaHQ7CgkJc3J2LT5wcmV2X3N0YXRlID0gc3J2LT5zdGF0ZTsKCQlpZiAoc3J2LT5zdGF0ZSAmIFNSVl9CQUNLVVApCgkJCWJjayArPSBzcnYtPmV3ZWlnaHQ7CgkJZWxzZQoJCQlhY3QgKz0gc3J2LT5ld2VpZ2h0OwoJfQoKCS8qIHRoaXMgaXMgdGhlIGxhcmdlc3QgbWFwIHdlIHdpbGwgZXZlciBuZWVkIGZvciB0aGlzIHNlcnZlcnMgbGlzdCAqLwoJaWYgKGFjdCA8IGJjaykKCQlhY3QgPSBiY2s7CgoJcC0+bGJwcm0ubWFwLnNydiA9IChzdHJ1Y3Qgc2VydmVyICoqKWNhbGxvYyhhY3QsIHNpemVvZihzdHJ1Y3Qgc2VydmVyICopKTsKCS8qIHJlY291bnRzIHNlcnZlcnMgYW5kIHRoZWlyIHdlaWdodHMgKi8KCXAtPmxicHJtLm1hcC5zdGF0ZSA9IFBSX01BUF9SRUNBTEM7CglyZWNvdW50X3NlcnZlcnMocCk7Cgl1cGRhdGVfYmFja2VuZF93ZWlnaHQocCk7CglyZWNhbGNfc2VydmVyX21hcChwKTsKfQoKLyogVGhpcyBmdW5jdGlvbiB1cGRhdGVzIHRoZSBzZXJ2ZXIgdHJlZXMgYWNjb3JkaW5nIHRvIHNlcnZlciA8c3J2PidzIG5ldwogKiBzdGF0ZS4gSXQgc2hvdWxkIGJlIGNhbGxlZCB3aGVuIHNlcnZlciA8c3J2PidzIHN0YXR1cyBjaGFuZ2VzIHRvIGRvd24uCiAqIEl0IGlzIG5vdCBpbXBvcnRhbnQgd2hldGhlciB0aGUgc2VydmVyIHdhcyBhbHJlYWR5IGRvd24gb3Igbm90LiBJdCBpcyBub3QKICogaW1wb3J0YW50IGVpdGhlciB0aGF0IHRoZSBuZXcgc3RhdGUgaXMgY29tcGxldGVseSBkb3duICh0aGUgY2FsbGVyIG1heSBub3QKICoga25vdyBhbGwgdGhlIHZhcmlhYmxlcyBvZiBhIHNlcnZlcidzIHN0YXRlKS4KICovCnN0YXRpYyB2b2lkIGZ3cnJfc2V0X3NlcnZlcl9zdGF0dXNfZG93bihzdHJ1Y3Qgc2VydmVyICpzcnYpCnsKCXN0cnVjdCBwcm94eSAqcCA9IHNydi0+cHJveHk7CglzdHJ1Y3QgZndycl9ncm91cCAqZ3JwOwoKCWlmIChzcnYtPnN0YXRlID09IHNydi0+cHJldl9zdGF0ZSAmJgoJICAgIHNydi0+ZXdlaWdodCA9PSBzcnYtPnByZXZfZXdlaWdodCkKCQlyZXR1cm47CgoJaWYgKHNydl9pc191c2FibGUoc3J2LT5zdGF0ZSwgc3J2LT5ld2VpZ2h0KSkKCQlnb3RvIG91dF91cGRhdGVfc3RhdGU7CgoJaWYgKCFzcnZfaXNfdXNhYmxlKHNydi0+cHJldl9zdGF0ZSwgc3J2LT5wcmV2X2V3ZWlnaHQpKQoJCS8qIHNlcnZlciB3YXMgYWxyZWFkeSBkb3duICovCgkJZ290byBvdXRfdXBkYXRlX2JhY2tlbmQ7CgoJZ3JwID0gKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSA/ICZwLT5sYnBybS5md3JyLmJjayA6ICZwLT5sYnBybS5md3JyLmFjdDsKCWdycC0+bmV4dF93ZWlnaHQgLT0gc3J2LT5wcmV2X2V3ZWlnaHQ7CgoJaWYgKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSB7CgkJcC0+bGJwcm0udG90X3diY2sgPSBwLT5sYnBybS5md3JyLmJjay5uZXh0X3dlaWdodDsKCQlwLT5zcnZfYmNrLS07CgoJCWlmIChzcnYgPT0gcC0+bGJwcm0uZmJjaykgewoJCQkvKiB3ZSBsb3N0IHRoZSBmaXJzdCBiYWNrdXAgc2VydmVyIGluIGEgc2luZ2xlLWJhY2t1cAoJCQkgKiBjb25maWd1cmF0aW9uLCB3ZSBtdXN0IHNlYXJjaCBhbm90aGVyIG9uZS4KCQkJICovCgkJCXN0cnVjdCBzZXJ2ZXIgKnNydjIgPSBwLT5sYnBybS5mYmNrOwoJCQlkbyB7CgkJCQlzcnYyID0gc3J2Mi0+bmV4dDsKCQkJfSB3aGlsZSAoc3J2MiAmJgoJCQkJICEoKHNydjItPnN0YXRlICYgU1JWX0JBQ0tVUCkgJiYKCQkJCSAgIHNydl9pc191c2FibGUoc3J2Mi0+c3RhdGUsIHNydjItPmV3ZWlnaHQpKSk7CgkJCXAtPmxicHJtLmZiY2sgPSBzcnYyOwoJCX0KCX0gZWxzZSB7CgkJcC0+bGJwcm0udG90X3dhY3QgPSBwLT5sYnBybS5md3JyLmFjdC5uZXh0X3dlaWdodDsKCQlwLT5zcnZfYWN0LS07Cgl9CgoJZndycl9kZXF1ZXVlX3NydihzcnYpOwoJZndycl9yZW1vdmVfZnJvbV90cmVlKHNydik7CgpvdXRfdXBkYXRlX2JhY2tlbmQ6CgkvKiBjaGVjay91cGRhdGUgdG90X3VzZWQsIHRvdF93ZWlnaHQgKi8KCXVwZGF0ZV9iYWNrZW5kX3dlaWdodChwKTsKIG91dF91cGRhdGVfc3RhdGU6CglzcnYtPnByZXZfc3RhdGUgPSBzcnYtPnN0YXRlOwoJc3J2LT5wcmV2X2V3ZWlnaHQgPSBzcnYtPmV3ZWlnaHQ7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gdXBkYXRlcyB0aGUgc2VydmVyIHRyZWVzIGFjY29yZGluZyB0byBzZXJ2ZXIgPHNydj4ncyBuZXcKICogc3RhdGUuIEl0IHNob3VsZCBiZSBjYWxsZWQgd2hlbiBzZXJ2ZXIgPHNydj4ncyBzdGF0dXMgY2hhbmdlcyB0byB1cC4KICogSXQgaXMgbm90IGltcG9ydGFudCB3aGV0aGVyIHRoZSBzZXJ2ZXIgd2FzIGFscmVhZHkgZG93biBvciBub3QuIEl0IGlzIG5vdAogKiBpbXBvcnRhbnQgZWl0aGVyIHRoYXQgdGhlIG5ldyBzdGF0ZSBpcyBjb21wbGV0ZWx5IFVQICh0aGUgY2FsbGVyIG1heSBub3QKICoga25vdyBhbGwgdGhlIHZhcmlhYmxlcyBvZiBhIHNlcnZlcidzIHN0YXRlKS4gVGhpcyBmdW5jdGlvbiB3aWxsIG5vdCBjaGFuZ2UKICogdGhlIHdlaWdodCBvZiBhIHNlcnZlciB3aGljaCB3YXMgYWxyZWFkeSB1cC4KICovCnN0YXRpYyB2b2lkIGZ3cnJfc2V0X3NlcnZlcl9zdGF0dXNfdXAoc3RydWN0IHNlcnZlciAqc3J2KQp7CglzdHJ1Y3QgcHJveHkgKnAgPSBzcnYtPnByb3h5OwoJc3RydWN0IGZ3cnJfZ3JvdXAgKmdycDsKCglpZiAoc3J2LT5zdGF0ZSA9PSBzcnYtPnByZXZfc3RhdGUgJiYKCSAgICBzcnYtPmV3ZWlnaHQgPT0gc3J2LT5wcmV2X2V3ZWlnaHQpCgkJcmV0dXJuOwoKCWlmICghc3J2X2lzX3VzYWJsZShzcnYtPnN0YXRlLCBzcnYtPmV3ZWlnaHQpKQoJCWdvdG8gb3V0X3VwZGF0ZV9zdGF0ZTsKCglpZiAoc3J2X2lzX3VzYWJsZShzcnYtPnByZXZfc3RhdGUsIHNydi0+cHJldl9ld2VpZ2h0KSkKCQkvKiBzZXJ2ZXIgd2FzIGFscmVhZHkgdXAgKi8KCQlnb3RvIG91dF91cGRhdGVfYmFja2VuZDsKCglncnAgPSAoc3J2LT5zdGF0ZSAmIFNSVl9CQUNLVVApID8gJnAtPmxicHJtLmZ3cnIuYmNrIDogJnAtPmxicHJtLmZ3cnIuYWN0OwoJZ3JwLT5uZXh0X3dlaWdodCArPSBzcnYtPmV3ZWlnaHQ7CgoJaWYgKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSB7CgkJcC0+bGJwcm0udG90X3diY2sgPSBwLT5sYnBybS5md3JyLmJjay5uZXh0X3dlaWdodDsKCQlwLT5zcnZfYmNrKys7CgoJCWlmICghKHAtPm9wdGlvbnMgJiBQUl9PX1VTRV9BTExfQkspKSB7CgkJCWlmICghcC0+bGJwcm0uZmJjaykgewoJCQkJLyogdGhlcmUgd2FzIG5vIGJhY2t1cCBzZXJ2ZXIgYW55bW9yZSAqLwoJCQkJcC0+bGJwcm0uZmJjayA9IHNydjsKCQkJfSBlbHNlIHsKCQkJCS8qIHdlIG1heSBoYXZlIHJlc3RvcmVkIGEgYmFja3VwIHNlcnZlciBwcmlvciB0byBmYmNrLAoJCQkJICogaW4gd2hpY2ggY2FzZSBpdCBzaG91bGQgcmVwbGFjZSBpdC4KCQkJCSAqLwoJCQkJc3RydWN0IHNlcnZlciAqc3J2MiA9IHNydjsKCQkJCWRvIHsKCQkJCQlzcnYyID0gc3J2Mi0+bmV4dDsKCQkJCX0gd2hpbGUgKHNydjIgJiYgKHNydjIgIT0gcC0+bGJwcm0uZmJjaykpOwoJCQkJaWYgKHNydjIpCgkJCQkJcC0+bGJwcm0uZmJjayA9IHNydjsKCQkJfQoJCX0KCX0gZWxzZSB7CgkJcC0+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+ZXdlaWdodCkgewoJCQlzLT5yd2VpZ2h0IC09IHMtPmV3ZWlnaHQ7CgkJCXMtPm5wb3MrKzsKCQl9Cgl9Cn0KCi8qIFJldHVybiBuZXh0IHNlcnZlciBmcm9tIHRoZSBjdXJyZW50IHRyZWUgaW4gYmFja2VuZCA8cD4sIG9yIGEgc2VydmVyIGZyb20KICogdGhlIGluaXQgdHJlZSBpZiBhcHByb3ByaWF0ZS4gSWYgYm90aCB0cmVlcyBhcmUgZW1wdHksIHJldHVybiBOVUxMLgogKiBTYXR1cmF0ZWQgc2VydmVycyBhcmUgc2tpcHBlZCBhbmQgcmVxdWV1ZWQuCiAqLwpzdGF0aWMgc3RydWN0IHNlcnZlciAqZndycl9nZXRfbmV4dF9zZXJ2ZXIoc3RydWN0IHByb3h5ICpwLCBzdHJ1Y3Qgc2VydmVyICpzcnZ0b2F2b2lkKQp7CglzdHJ1Y3Qgc2VydmVyICpzcnYsICpmdWxsLCAqYXZvaWRlZDsKCXN0cnVjdCBmd3JyX2dyb3VwICpncnA7CglpbnQgc3dpdGNoZWQ7CgoJaWYgKHAtPnNydl9hY3QpCgkJZ3JwID0gJnAtPmxicHJtLmZ3cnIuYWN0OwoJZWxzZSBpZiAocC0+bGJwcm0uZmJjaykKCQlyZXR1cm4gcC0+bGJwcm0uZmJjazsKCWVsc2UgaWYgKHAtPnNydl9iY2spCgkJZ3JwID0gJnAtPmxicHJtLmZ3cnIuYmNrOwoJZWxzZQoJCXJldHVybiBOVUxMOwoKCXN3aXRjaGVkID0gMDsKCWF2b2lkZWQgPSBOVUxMOwoJZnVsbCA9IE5VTEw7IC8qIE5VTEwtdGVybWluYXRlZCBsaXN0IG9mIHNhdHVyYXRlZCBzZXJ2ZXJzICovCgl3aGlsZSAoMSkgewoJCS8qIGlmIHdlIHNlZSBhbiBlbXB0eSBncm91cCwgbGV0J3MgZmlyc3QgdHJ5IHRvIGNvbGxlY3Qgd2VpZ2h0cwoJCSAqIHdoaWNoIG1pZ2h0IGhhdmUgcmVjZW50bHkgY2hhbmdlZC4KCQkgKi8KCQlpZiAoIWdycC0+Y3Vycl93ZWlnaHQpCgkJCWdycC0+Y3Vycl9wb3MgPSBncnAtPmN1cnJfd2VpZ2h0ID0gZ3JwLT5uZXh0X3dlaWdodDsKCgkJLyogZ2V0IGZpcnN0IHNlcnZlciBmcm9tIHRoZSAiY3VycmVudCIgdHJlZS4gV2hlbiB0aGUgZW5kIG9mCgkJICogdGhlIHRyZWUgaXMgcmVhY2hlZCwgd2UgbWF5IGhhdmUgdG8gc3dpdGNoLCBidXQgb25seSBvbmNlLgoJCSAqLwoJCXdoaWxlICgxKSB7CgkJCXNydiA9IGZ3cnJfZ2V0X3NlcnZlcl9mcm9tX2dyb3VwKGdycCk7CgkJCWlmIChzcnYpCgkJCQlicmVhazsKCQkJaWYgKHN3aXRjaGVkKSB7CgkJCQlpZiAoYXZvaWRlZCkgewoJCQkJCXNydiA9IGF2b2lkZWQ7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlnb3RvIHJlcXVldWVfc2VydmVyczsKCQkJfQoJCQlzd2l0Y2hlZCA9IDE7CgkJCWZ3cnJfc3dpdGNoX3RyZWVzKGdycCk7CgoJCX0KCgkJLyogT0ssIHdlIGhhdmUgYSBzZXJ2ZXIuIEhvd2V2ZXIsIGl0IG1heSBiZSBzYXR1cmF0ZWQsIGluIHdoaWNoCgkJICogY2FzZSB3ZSBkb24ndCB3YW50IHRvIHJlY29uc2lkZXIgaXQgZm9yIG5vdy4gV2UnbGwgdXBkYXRlCgkJICogaXRzIHBvc2l0aW9uIGFuZCBkZXF1ZXVlIGl0IGFueXdheSwgc28gdGhhdCB3ZSBjYW4gbW92ZSBpdAoJCSAqIHRvIGEgYmV0dGVyIHBsYWNlIGFmdGVyd2FyZHMuCgkJICovCgkJZndycl91cGRhdGVfcG9zaXRpb24oZ3JwLCBzcnYpOwoJCWZ3cnJfZGVxdWV1ZV9zcnYoc3J2KTsKCQlncnAtPmN1cnJfcG9zKys7CgkJaWYgKCFzcnYtPm1heGNvbm4gfHwgKCFzcnYtPm5icGVuZCAmJiBzcnYtPnNlcnZlZCA8IHNydl9keW5hbWljX21heGNvbm4oc3J2KSkpIHsKCQkJLyogbWFrZSBzdXJlIGl0IGlzIG5vdCB0aGUgc2VydmVyIHdlIGFyZSB0cnlpbmcgdG8gZXhjbHVkZS4uLiAqLwoJCQlpZiAoc3J2ICE9IHNydnRvYXZvaWQgfHwgYXZvaWRlZCkKCQkJCWJyZWFrOwoKCQkJYXZvaWRlZCA9IHNydjsgLyogLi4uYnV0IHJlbWVtYmVyIHRoYXQgaXMgd2FzIHNlbGVjdGVkIHlldCBhdm9pZGVkICovCgkJfQoKCQkvKiB0aGUgc2VydmVyIGlzIHNhdHVyYXRlZCBvciBhdm9pZGVkLCBsZXQncyBjaGFpbiBpdCBmb3IgbGF0ZXIgcmVpbnNlcnRpb24gKi8KCQlzcnYtPm5leHRfZnVsbCA9IGZ1bGw7CgkJZnVsbCA9IHNydjsKCX0KCgkvKiBPSywgd2UgZ290IHRoZSBiZXN0IHNlcnZlciwgbGV0J3MgdXBkYXRlIGl0ICovCglmd3JyX3F1ZXVlX3NydihzcnYpOwoKIHJlcXVldWVfc2VydmVyczoKCS8qIFJlcXVldWUgYWxsIGV4dHJhY3RlZCBzZXJ2ZXJzLiBJZiBmdWxsPT1zcnYgdGhlbiBpdCB3YXMKCSAqIGF2b2lkZWQgKHVuc3VjZXNzZnVsbHkpIGFuZCBjaGFpbmVkLCBvbWl0IGl0IG5vdy4KCSAqLwoJaWYgKHVubGlrZWx5KGZ1bGwgIT0gTlVMTCkpIHsKCQlpZiAoc3dpdGNoZWQpIHsKCQkJLyogdGhlIHRyZWUgaGFzIHN3aXRjaGVkLCByZXF1ZXVlIGFsbCBleHRyYWN0ZWQgc2VydmVycwoJCQkgKiBpbnRvICJpbml0IiwgYmVjYXVzZSB0aGVpciBwbGFjZSB3YXMgbG9zdCwgYW5kIG9ubHkKCQkJICogdGhlaXIgd2VpZ2h0IG1hdHRlcnMuCgkJCSAqLwoJCQlkbyB7CgkJCQlpZiAobGlrZWx5KGZ1bGwgIT0gc3J2KSkKCQkJCQlmd3JyX3F1ZXVlX2J5X3dlaWdodChncnAtPmluaXQsIGZ1bGwpOwoJCQkJZnVsbCA9IGZ1bGwtPm5leHRfZnVsbDsKCQkJfSB3aGlsZSAoZnVsbCk7CgkJfSBlbHNlIHsKCQkJLyogcmVxdWV1ZSBhbGwgZXh0cmFjdGVkIHNlcnZlcnMganVzdCBhcyBpZiB0aGV5IHdlcmUgY29uc3VtZWQKCQkJICogc28gdGhhdCB0aGV5IHJlZ2FpbiB0aGVpciBleHBlY3RlZCBwbGFjZS4KCQkJICovCgkJCWRvIHsKCQkJCWlmIChsaWtlbHkoZnVsbCAhPSBzcnYpKQoJCQkJCWZ3cnJfcXVldWVfc3J2KGZ1bGwpOwoJCQkJZnVsbCA9IGZ1bGwtPm5leHRfZnVsbDsKCQkJfSB3aGlsZSAoZnVsbCk7CgkJfQoJfQoJcmV0dXJuIHNydjsKfQoKLyogUmVtb3ZlIGEgc2VydmVyIGZyb20gYSB0cmVlLiBJdCBtdXN0IGhhdmUgcHJldmlvdXNseSBiZWVuIGRlcXVldWVkLiBUaGlzCiAqIGZ1bmN0aW9uIGlzIG1lYW50IHRvIGJlIGNhbGxlZCB3aGVuIGEgc2VydmVyIGlzIGdvaW5nIGRvd24gb3IgaGFzIGl0cwogKiB3ZWlnaHQgZGlzYWJsZWQuCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZndsY19yZW1vdmVfZnJvbV90cmVlKHN0cnVjdCBzZXJ2ZXIgKnMpCnsKCXMtPmxiX3RyZWUgPSBOVUxMOwp9CgovKiBzaW1wbHkgcmVtb3ZlcyBhIHNlcnZlciBmcm9tIGEgdHJlZSAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZndsY19kZXF1ZXVlX3NydihzdHJ1Y3Qgc2VydmVyICpzKQp7CgllYjMyX2RlbGV0ZSgmcy0+bGJfbm9kZSk7Cn0KCi8qIFF1ZXVlIGEgc2VydmVyIGluIGl0cyBhc3NvY2lhdGVkIHRyZWUsIGFzc3VtaW5nIHRoZSB3ZWlnaHQgaXMgPjAuCiAqIFNlcnZlcnMgYXJlIHNvcnRlZCBieSAjY29ubnMvd2VpZ2h0LiBUbyBlbnN1cmUgbWF4aW11bSBhY2N1cmFjeSwKICogd2UgdXNlICNjb25ucypTUlZfRVdHSFRfTUFYL2V3ZWlnaHQgYXMgdGhlIHNvcnRpbmcga2V5LgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZ3bGNfcXVldWVfc3J2KHN0cnVjdCBzZXJ2ZXIgKnMpCnsKCXMtPmxiX25vZGUua2V5ID0gcy0+c2VydmVkICogU1JWX0VXR0hUX01BWCAvIHMtPmV3ZWlnaHQ7CgllYjMyX2luc2VydChzLT5sYl90cmVlLCAmcy0+bGJfbm9kZSk7Cn0KCi8qIFJlLXBvc2l0aW9uIHRoZSBzZXJ2ZXIgaW4gdGhlIEZXTEMgdHJlZSBhZnRlciBpdCBoYXMgYmVlbiBhc3NpZ25lZCBvbmUKICogY29ubmVjdGlvbiBvciBhZnRlciBpdCBoYXMgcmVsZWFzZWQgb25lLiBOb3RlIHRoYXQgaXQgaXMgcG9zc2libGUgdGhhdAogKiB0aGUgc2VydmVyIGhhcyBiZWVuIG1vdmVkIG91dCBvZiB0aGUgdHJlZSBkdWUgdG8gZmFpbGVkIGhlYWx0aC1jaGVja3MuCiAqLwpzdGF0aWMgdm9pZCBmd2xjX3Nydl9yZXBvc2l0aW9uKHN0cnVjdCBzZXJ2ZXIgKnMpCnsKCWlmICghcy0+bGJfdHJlZSkKCQlyZXR1cm47Cglmd2xjX2RlcXVldWVfc3J2KHMpOwoJZndsY19xdWV1ZV9zcnYocyk7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gdXBkYXRlcyB0aGUgc2VydmVyIHRyZWVzIGFjY29yZGluZyB0byBzZXJ2ZXIgPHNydj4ncyBuZXcKICogc3RhdGUuIEl0IHNob3VsZCBiZSBjYWxsZWQgd2hlbiBzZXJ2ZXIgPHNydj4ncyBzdGF0dXMgY2hhbmdlcyB0byBkb3duLgogKiBJdCBpcyBub3QgaW1wb3J0YW50IHdoZXRoZXIgdGhlIHNlcnZlciB3YXMgYWxyZWFkeSBkb3duIG9yIG5vdC4gSXQgaXMgbm90CiAqIGltcG9ydGFudCBlaXRoZXIgdGhhdCB0aGUgbmV3IHN0YXRlIGlzIGNvbXBsZXRlbHkgZG93biAodGhlIGNhbGxlciBtYXkgbm90CiAqIGtub3cgYWxsIHRoZSB2YXJpYWJsZXMgb2YgYSBzZXJ2ZXIncyBzdGF0ZSkuCiAqLwpzdGF0aWMgdm9pZCBmd2xjX3NldF9zZXJ2ZXJfc3RhdHVzX2Rvd24oc3RydWN0IHNlcnZlciAqc3J2KQp7CglzdHJ1Y3QgcHJveHkgKnAgPSBzcnYtPnByb3h5OwoKCWlmIChzcnYtPnN0YXRlID09IHNydi0+cHJldl9zdGF0ZSAmJgoJICAgIHNydi0+ZXdlaWdodCA9PSBzcnYtPnByZXZfZXdlaWdodCkKCQlyZXR1cm47CgoJaWYgKHNydl9pc191c2FibGUoc3J2LT5zdGF0ZSwgc3J2LT5ld2VpZ2h0KSkKCQlnb3RvIG91dF91cGRhdGVfc3RhdGU7CgoJaWYgKCFzcnZfaXNfdXNhYmxlKHNydi0+cHJldl9zdGF0ZSwgc3J2LT5wcmV2X2V3ZWlnaHQpKQoJCS8qIHNlcnZlciB3YXMgYWxyZWFkeSBkb3duICovCgkJZ290byBvdXRfdXBkYXRlX2JhY2tlbmQ7CgoJaWYgKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSB7CgkJcC0+bGJwcm0udG90X3diY2sgLT0gc3J2LT5wcmV2X2V3ZWlnaHQ7CgkJcC0+c3J2X2Jjay0tOwoKCQlpZiAoc3J2ID09IHAtPmxicHJtLmZiY2spIHsKCQkJLyogd2UgbG9zdCB0aGUgZmlyc3QgYmFja3VwIHNlcnZlciBpbiBhIHNpbmdsZS1iYWNrdXAKCQkJICogY29uZmlndXJhdGlvbiwgd2UgbXVzdCBzZWFyY2ggYW5vdGhlciBvbmUuCgkJCSAqLwoJCQlzdHJ1Y3Qgc2VydmVyICpzcnYyID0gcC0+bGJwcm0uZmJjazsKCQkJZG8gewoJCQkJc3J2MiA9IHNydjItPm5leHQ7CgkJCX0gd2hpbGUgKHNydjIgJiYKCQkJCSAhKChzcnYyLT5zdGF0ZSAmIFNSVl9CQUNLVVApICYmCgkJCQkgICBzcnZfaXNfdXNhYmxlKHNydjItPnN0YXRlLCBzcnYyLT5ld2VpZ2h0KSkpOwoJCQlwLT5sYnBybS5mYmNrID0gc3J2MjsKCQl9Cgl9IGVsc2UgewoJCXAtPmxicHJtLnRvdF93YWN0IC09IHNydi0+cHJldl9ld2VpZ2h0OwoJCXAtPnNydl9hY3QtLTsKCX0KCglmd2xjX2RlcXVldWVfc3J2KHNydik7Cglmd2xjX3JlbW92ZV9mcm9tX3RyZWUoc3J2KTsKCm91dF91cGRhdGVfYmFja2VuZDoKCS8qIGNoZWNrL3VwZGF0ZSB0b3RfdXNlZCwgdG90X3dlaWdodCAqLwoJdXBkYXRlX2JhY2tlbmRfd2VpZ2h0KHApOwogb3V0X3VwZGF0ZV9zdGF0ZToKCXNydi0+cHJldl9zdGF0ZSA9IHNydi0+c3RhdGU7CglzcnYtPnByZXZfZXdlaWdodCA9IHNydi0+ZXdlaWdodDsKfQoKLyogVGhpcyBmdW5jdGlvbiB1cGRhdGVzIHRoZSBzZXJ2ZXIgdHJlZXMgYWNjb3JkaW5nIHRvIHNlcnZlciA8c3J2PidzIG5ldwogKiBzdGF0ZS4gSXQgc2hvdWxkIGJlIGNhbGxlZCB3aGVuIHNlcnZlciA8c3J2PidzIHN0YXR1cyBjaGFuZ2VzIHRvIHVwLgogKiBJdCBpcyBub3QgaW1wb3J0YW50IHdoZXRoZXIgdGhlIHNlcnZlciB3YXMgYWxyZWFkeSBkb3duIG9yIG5vdC4gSXQgaXMgbm90CiAqIGltcG9ydGFudCBlaXRoZXIgdGhhdCB0aGUgbmV3IHN0YXRlIGlzIGNvbXBsZXRlbHkgVVAgKHRoZSBjYWxsZXIgbWF5IG5vdAogKiBrbm93IGFsbCB0aGUgdmFyaWFibGVzIG9mIGEgc2VydmVyJ3Mgc3RhdGUpLiBUaGlzIGZ1bmN0aW9uIHdpbGwgbm90IGNoYW5nZQogKiB0aGUgd2VpZ2h0IG9mIGEgc2VydmVyIHdoaWNoIHdhcyBhbHJlYWR5IHVwLgogKi8Kc3RhdGljIHZvaWQgZndsY19zZXRfc2VydmVyX3N0YXR1c191cChzdHJ1Y3Qgc2VydmVyICpzcnYpCnsKCXN0cnVjdCBwcm94eSAqcCA9IHNydi0+cHJveHk7CgoJaWYgKHNydi0+c3RhdGUgPT0gc3J2LT5wcmV2X3N0YXRlICYmCgkgICAgc3J2LT5ld2VpZ2h0ID09IHNydi0+cHJldl9ld2VpZ2h0KQoJCXJldHVybjsKCglpZiAoIXNydl9pc191c2FibGUoc3J2LT5zdGF0ZSwgc3J2LT5ld2VpZ2h0KSkKCQlnb3RvIG91dF91cGRhdGVfc3RhdGU7CgoJaWYgKHNydl9pc191c2FibGUoc3J2LT5wcmV2X3N0YXRlLCBzcnYtPnByZXZfZXdlaWdodCkpCgkJLyogc2VydmVyIHdhcyBhbHJlYWR5IHVwICovCgkJZ290byBvdXRfdXBkYXRlX2JhY2tlbmQ7CgoJaWYgKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSB7CgkJc3J2LT5sYl90cmVlID0gJnAtPmxicHJtLmZ3bGMuYmNrOwoJCXAtPmxicHJtLnRvdF93YmNrICs9IHNydi0+ZXdlaWdodDsKCQlwLT5zcnZfYmNrKys7CgoJCWlmICghKHAtPm9wdGlvbnMgJiBQUl9PX1VTRV9BTExfQkspKSB7CgkJCWlmICghcC0+bGJwcm0uZmJjaykgewoJCQkJLyogdGhlcmUgd2FzIG5vIGJhY2t1cCBzZXJ2ZXIgYW55bW9yZSAqLwoJCQkJcC0+bGJwcm0uZmJjayA9IHNydjsKCQkJfSBlbHNlIHsKCQkJCS8qIHdlIG1heSBoYXZlIHJlc3RvcmVkIGEgYmFja3VwIHNlcnZlciBwcmlvciB0byBmYmNrLAoJCQkJICogaW4gd2hpY2ggY2FzZSBpdCBzaG91bGQgcmVwbGFjZSBpdC4KCQkJCSAqLwoJCQkJc3RydWN0IHNlcnZlciAqc3J2MiA9IHNydjsKCQkJCWRvIHsKCQkJCQlzcnYyID0gc3J2Mi0+bmV4dDsKCQkJCX0gd2hpbGUgKHNydjIgJiYgKHNydjIgIT0gcC0+bGJwcm0uZmJjaykpOwoJCQkJaWYgKHNydjIpCgkJCQkJcC0+bGJwcm0uZmJjayA9IHNydjsKCQkJfQoJCX0KCX0gZWxzZSB7CgkJc3J2LT5sYl90cmVlID0gJnAtPmxicHJtLmZ3bGMuYWN0OwoJCXAtPmxicHJtLnRvdF93YWN0ICs9IHNydi0+ZXdlaWdodDsKCQlwLT5zcnZfYWN0Kys7Cgl9CgoJLyogbm90ZSB0aGF0IGV3ZWlnaHQgY2Fubm90IGJlIDAgaGVyZSAqLwoJZndsY19xdWV1ZV9zcnYoc3J2KTsKCiBvdXRfdXBkYXRlX2JhY2tlbmQ6CgkvKiBjaGVjay91cGRhdGUgdG90X3VzZWQsIHRvdF93ZWlnaHQgKi8KCXVwZGF0ZV9iYWNrZW5kX3dlaWdodChwKTsKIG91dF91cGRhdGVfc3RhdGU6CglzcnYtPnByZXZfc3RhdGUgPSBzcnYtPnN0YXRlOwoJc3J2LT5wcmV2X2V3ZWlnaHQgPSBzcnYtPmV3ZWlnaHQ7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gbXVzdCBiZSBjYWxsZWQgYWZ0ZXIgYW4gdXBkYXRlIHRvIHNlcnZlciA8c3J2PidzIGVmZmVjdGl2ZQogKiB3ZWlnaHQuIEl0IG1heSBiZSBjYWxsZWQgYWZ0ZXIgYSBzdGF0ZSBjaGFuZ2UgdG9vLgogKi8Kc3RhdGljIHZvaWQgZndsY191cGRhdGVfc2VydmVyX3dlaWdodChzdHJ1Y3Qgc2VydmVyICpzcnYpCnsKCWludCBvbGRfc3RhdGUsIG5ld19zdGF0ZTsKCXN0cnVjdCBwcm94eSAqcCA9IHNydi0+cHJveHk7CgoJaWYgKHNydi0+c3RhdGUgPT0gc3J2LT5wcmV2X3N0YXRlICYmCgkgICAgc3J2LT5ld2VpZ2h0ID09IHNydi0+cHJldl9ld2VpZ2h0KQoJCXJldHVybjsKCgkvKiBJZiBjaGFuZ2luZyB0aGUgc2VydmVyJ3Mgd2VpZ2h0IGNoYW5nZXMgaXRzIHN0YXRlLCB3ZSBzaW1wbHkgYXBwbHkKCSAqIHRoZSBwcm9jZWR1cmVzIHdlIGFscmVhZHkgaGF2ZSBmb3Igc3RhdHVzIGNoYW5nZS4gSWYgdGhlIHN0YXRlCgkgKiByZW1haW5zIGRvd24sIHRoZSBzZXJ2ZXIgaXMgbm90IGluIGFueSB0cmVlLCBzbyBpdCdzIGFzIGVhc3kgYXMKCSAqIHVwZGF0aW5nIGl0cyB2YWx1ZXMuIElmIHRoZSBzdGF0ZSByZW1haW5zIHVwIHdpdGggZGlmZmVyZW50IHdlaWdodHMsCgkgKiB0aGVyZSBhcmUgc29tZSBjb21wdXRhdGlvbnMgdG8gcGVyZm9ybSB0byBmaW5kIGEgbmV3IHBsYWNlIGFuZAoJICogcG9zc2libHkgYSBuZXcgdHJlZSBmb3IgdGhpcyBzZXJ2ZXIuCgkgKi8KCSAKCW9sZF9zdGF0ZSA9IHNydl9pc191c2FibGUoc3J2LT5wcmV2X3N0YXRlLCBzcnYtPnByZXZfZXdlaWdodCk7CgluZXdfc3RhdGUgPSBzcnZfaXNfdXNhYmxlKHNydi0+c3RhdGUsIHNydi0+ZXdlaWdodCk7CgoJaWYgKCFvbGRfc3RhdGUgJiYgIW5ld19zdGF0ZSkgewoJCXNydi0+cHJldl9zdGF0ZSA9IHNydi0+c3RhdGU7CgkJc3J2LT5wcmV2X2V3ZWlnaHQgPSBzcnYtPmV3ZWlnaHQ7CgkJcmV0dXJuOwoJfQoJZWxzZSBpZiAoIW9sZF9zdGF0ZSAmJiBuZXdfc3RhdGUpIHsKCQlmd2xjX3NldF9zZXJ2ZXJfc3RhdHVzX3VwKHNydik7CgkJcmV0dXJuOwoJfQoJZWxzZSBpZiAob2xkX3N0YXRlICYmICFuZXdfc3RhdGUpIHsKCQlmd2xjX3NldF9zZXJ2ZXJfc3RhdHVzX2Rvd24oc3J2KTsKCQlyZXR1cm47Cgl9CgoJaWYgKHNydi0+bGJfdHJlZSkKCQlmd2xjX2RlcXVldWVfc3J2KHNydik7CgoJaWYgKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSB7CgkJcC0+bGJwcm0udG90X3diY2sgKz0gc3J2LT5ld2VpZ2h0IC0gc3J2LT5wcmV2X2V3ZWlnaHQ7CgkJc3J2LT5sYl90cmVlID0gJnAtPmxicHJtLmZ3bGMuYmNrOwoJfSBlbHNlIHsKCQlwLT5sYnBybS50b3Rfd2FjdCArPSBzcnYtPmV3ZWlnaHQgLSBzcnYtPnByZXZfZXdlaWdodDsKCQlzcnYtPmxiX3RyZWUgPSAmcC0+bGJwcm0uZndsYy5hY3Q7Cgl9CgoJZndsY19xdWV1ZV9zcnYoc3J2KTsKCgl1cGRhdGVfYmFja2VuZF93ZWlnaHQocCk7CglzcnYtPnByZXZfc3RhdGUgPSBzcnYtPnN0YXRlOwoJc3J2LT5wcmV2X2V3ZWlnaHQgPSBzcnYtPmV3ZWlnaHQ7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gaXMgcmVzcG9uc2libGUgZm9yIGJ1aWxkaW5nIHRoZSB0cmVlcyBpbiBjYXNlIG9mIGZhc3QKICogd2VpZ2h0ZWQgbGVhc3QtY29ubnMuIEl0IGFsc28gc2V0cyBwLT5sYnBybS53ZGl2IHRvIHRoZSBld2VpZ2h0IHRvCiAqIHV3ZWlnaHQgcmF0aW8uIEJvdGggYWN0aXZlIGFuZCBiYWNrdXAgZ3JvdXBzIGFyZSBpbml0aWFsaXplZC4KICovCnZvaWQgZndsY19pbml0X3NlcnZlcl90cmVlKHN0cnVjdCBwcm94eSAqcCkKewoJc3RydWN0IHNlcnZlciAqc3J2OwoJc3RydWN0IGViX3Jvb3QgaW5pdF9oZWFkID0gRUJfUk9PVDsKCglwLT5sYnBybS5zZXRfc2VydmVyX3N0YXR1c191cCAgID0gZndsY19zZXRfc2VydmVyX3N0YXR1c191cDsKCXAtPmxicHJtLnNldF9zZXJ2ZXJfc3RhdHVzX2Rvd24gPSBmd2xjX3NldF9zZXJ2ZXJfc3RhdHVzX2Rvd247CglwLT5sYnBybS51cGRhdGVfc2VydmVyX2V3ZWlnaHQgID0gZndsY191cGRhdGVfc2VydmVyX3dlaWdodDsKCXAtPmxicHJtLnNlcnZlcl90YWtlX2Nvbm4gPSBmd2xjX3Nydl9yZXBvc2l0aW9uOwoJcC0+bGJwcm0uc2VydmVyX2Ryb3BfY29ubiA9IGZ3bGNfc3J2X3JlcG9zaXRpb247CgoJcC0+bGJwcm0ud2RpdiA9IEJFX1dFSUdIVF9TQ0FMRTsKCWZvciAoc3J2ID0gcC0+c3J2OyBzcnY7IHNydiA9IHNydi0+bmV4dCkgewoJCXNydi0+cHJldl9ld2VpZ2h0ID0gc3J2LT5ld2VpZ2h0ID0gc3J2LT51d2VpZ2h0ICogQkVfV0VJR0hUX1NDQUxFOwoJCXNydi0+cHJldl9zdGF0ZSA9IHNydi0+c3RhdGU7Cgl9CgoJcmVjb3VudF9zZXJ2ZXJzKHApOwoJdXBkYXRlX2JhY2tlbmRfd2VpZ2h0KHApOwoKCXAtPmxicHJtLmZ3bGMuYWN0ID0gaW5pdF9oZWFkOwoJcC0+bGJwcm0uZndsYy5iY2sgPSBpbml0X2hlYWQ7CgoJLyogcXVldWUgYWN0aXZlIGFuZCBiYWNrdXAgc2VydmVycyBpbiB0d28gZGlzdGluY3QgZ3JvdXBzICovCglmb3IgKHNydiA9IHAtPnNydjsgc3J2OyBzcnYgPSBzcnYtPm5leHQpIHsKCQlpZiAoIXNydl9pc191c2FibGUoc3J2LT5zdGF0ZSwgc3J2LT5ld2VpZ2h0KSkKCQkJY29udGludWU7CgkJc3J2LT5sYl90cmVlID0gKHNydi0+c3RhdGUgJiBTUlZfQkFDS1VQKSA/ICZwLT5sYnBybS5md2xjLmJjayA6ICZwLT5sYnBybS5md2xjLmFjdDsKCQlmd2xjX3F1ZXVlX3NydihzcnYpOwoJfQp9CgovKiBSZXR1cm4gbmV4dCBzZXJ2ZXIgZnJvbSB0aGUgRldMQyB0cmVlIGluIGJhY2tlbmQgPHA+LiBJZiB0aGUgdHJlZSBpcyBlbXB0eSwKICogcmV0dXJuIE5VTEwuIFNhdHVyYXRlZCBzZXJ2ZXJzIGFyZSBza2lwcGVkLgogKi8Kc3RhdGljIHN0cnVjdCBzZXJ2ZXIgKmZ3bGNfZ2V0X25leHRfc2VydmVyKHN0cnVjdCBwcm94eSAqcCwgc3RydWN0IHNlcnZlciAqc3J2dG9hdm9pZCkKewoJc3RydWN0IHNlcnZlciAqc3J2LCAqYXZvaWRlZDsKCXN0cnVjdCBlYjMyX25vZGUgKm5vZGU7CgoJc3J2ID0gYXZvaWRlZCA9IE5VTEw7CgoJaWYgKHAtPnNydl9hY3QpCgkJbm9kZSA9IGViMzJfZmlyc3QoJnAtPmxicHJtLmZ3bGMuYWN0KTsKCWVsc2UgaWYgKHAtPmxicHJtLmZiY2spCgkJcmV0dXJuIHAtPmxicHJtLmZiY2s7CgllbHNlIGlmIChwLT5zcnZfYmNrKQoJCW5vZGUgPSBlYjMyX2ZpcnN0KCZwLT5sYnBybS5md2xjLmJjayk7CgllbHNlCgkJcmV0dXJuIE5VTEw7CgoJd2hpbGUgKG5vZGUpIHsKCQkvKiBPSywgd2UgaGF2ZSBhIHNlcnZlci4gSG93ZXZlciwgaXQgbWF5IGJlIHNhdHVyYXRlZCwgaW4gd2hpY2gKCQkgKiBjYXNlIHdlIGRvbid0IHdhbnQgdG8gcmVjb25zaWRlciBpdCBmb3Igbm93LCBzbyB3ZSdsbCBzaW1wbHkKCQkgKiBza2lwIGl0LiBTYW1lIGlmIGl0J3MgdGhlIHNlcnZlciB3ZSB0cnkgdG8gYXZvaWQsIGluIHdoaWNoCgkJICogY2FzZSB3ZSBzaW1wbHkgcmVtZW1iZXIgaXQgZm9yIGxhdGVyIHVzZSBpZiBuZWVkZWQuCgkJICovCgkJc3RydWN0IHNlcnZlciAqczsKCgkJcyA9IGViMzJfZW50cnkobm9kZSwgc3RydWN0IHNlcnZlciwgbGJfbm9kZSk7CgkJaWYgKCFzLT5tYXhjb25uIHx8ICghcy0+bmJwZW5kICYmIHMtPnNlcnZlZCA8IHNydl9keW5hbWljX21heGNvbm4ocykpKSB7CgkJCWlmIChzICE9IHNydnRvYXZvaWQpIHsKCQkJCXNydiA9IHM7CgkJCQlicmVhazsKCQkJfQoJCQlhdm9pZGVkID0gczsKCQl9CgkJbm9kZSA9IGViMzJfbmV4dChub2RlKTsKCX0KCglpZiAoIXNydikKCQlzcnYgPSBhdm9pZGVkOwoKCXJldHVybiBzcnY7Cn0KCi8qIAogKiBUaGlzIGZ1bmN0aW9uIHRyaWVzIHRvIGZpbmQgYSBydW5uaW5nIHNlcnZlciBmb3IgdGhlIHByb3h5IDxweD4gZm9sbG93aW5nCiAqIHRoZSBVUkwgcGFyYW1ldGVyIGhhc2ggbWV0aG9kLiBJdCBsb29rcyBmb3IgYSBzcGVjaWZpYyBwYXJhbWV0ZXIgaW4gdGhlCiAqIFVSTCBhbmQgaGFzaGVzIGl0IHRvIGNvbXB1dGUgdGhlIHNlcnZlciBJRC4gVGhpcyBpcyB1c2VmdWwgdG8gb3B0aW1pemUKICogcGVyZm9ybWFuY2UgYnkgYXZvaWRpbmcgYm91bmNlcyBiZXR3ZWVuIHNlcnZlcnMgaW4gY29udGV4dHMgd2hlcmUgc2Vzc2lvbnMKICogYXJlIHNoYXJlZCBidXQgY29va2llcyBhcmUgbm90IHVzYWJsZS4gSWYgdGhlIHBhcmFtZXRlciBpcyBub3QgZm91bmQsIE5VTEwKICogaXMgcmV0dXJuZWQuIElmIGFueSBzZXJ2ZXIgaXMgZm91bmQsIGl0IHdpbGwgYmUgcmV0dXJuZWQuIElmIG5vIHZhbGlkIHNlcnZlcgogKiBpcyBmb3VuZCwgTlVMTCBpcyByZXR1cm5lZC4KICovCnN0cnVjdCBzZXJ2ZXIgKmdldF9zZXJ2ZXJfcGgoc3RydWN0IHByb3h5ICpweCwgY29uc3QgY2hhciAqdXJpLCBpbnQgdXJpX2xlbikKewoJdW5zaWduZWQgbG9uZyBoYXNoID0gMDsKCWNvbnN0IGNoYXIgKnA7Cgljb25zdCBjaGFyICpwYXJhbXM7CglpbnQgcGxlbjsKCgkvKiB3aGVuIHRvdF93ZWlnaHQgaXMgMCB0aGVuIHNvIGlzIHNydl9jb3VudCAqLwoJaWYgKHB4LT5sYnBybS50b3Rfd2VpZ2h0ID09IDApCgkJcmV0dXJuIE5VTEw7CgoJaWYgKChwID0gbWVtY2hyKHVyaSwgJz8nLCB1cmlfbGVuKSkgPT0gTlVMTCkKCQlyZXR1cm4gTlVMTDsKCglpZiAocHgtPmxicHJtLm1hcC5zdGF0ZSAmIFBSX01BUF9SRUNBTEMpCgkJcmVjYWxjX3NlcnZlcl9tYXAocHgpOwoKCXArKzsKCgl1cmlfbGVuIC09IChwIC0gdXJpKTsKCXBsZW4gPSBweC0+dXJsX3BhcmFtX2xlbjsKCXBhcmFtcyA9IHA7CgoJd2hpbGUgKHVyaV9sZW4gPiBwbGVuKSB7CgkJLyogTG9vayBmb3IgdGhlIHBhcmFtZXRlciBuYW1lIGZvbGxvd2VkIGJ5IGFuIGVxdWFsIHN5bWJvbCAqLwoJCWlmIChwYXJhbXNbcGxlbl0gPT0gJz0nKSB7CgkJCWlmIChtZW1jbXAocGFyYW1zLCBweC0+dXJsX3BhcmFtX25hbWUsIHBsZW4pID09IDApIHsKCQkJCS8qIE9LLCB3ZSBoYXZlIHRoZSBwYXJhbWV0ZXIgaGVyZSBhdCA8cGFyYW1zPiwgYW5kCgkJCQkgKiB0aGUgdmFsdWUgYWZ0ZXIgdGhlIGVxdWFsIHNpZ24sIGF0IDxwPgoJCQkJICogc2tpcCB0aGUgZXF1YWwgc3ltYm9sCgkJCQkgKi8KCQkJCXAgKz0gcGxlbiArIDE7CgkJCQl1cmlfbGVuIC09IHBsZW4gKyAxOwoKCQkJCXdoaWxlICh1cmlfbGVuICYmICpwICE9ICcmJykgewoJCQkJCWhhc2ggPSAqcCArIChoYXNoIDw8IDYpICsgKGhhc2ggPDwgMTYpIC0gaGFzaDsKCQkJCQl1cmlfbGVuLS07CgkJCQkJcCsrOwoJCQkJfQoJCQkJcmV0dXJuIHB4LT5sYnBybS5tYXAuc3J2W2hhc2ggJSBweC0+bGJwcm0udG90X3dlaWdodF07CgkJCX0KCQl9CgkJLyogc2tpcCB0byBuZXh0IHBhcmFtZXRlciAqLwoJCXAgPSBtZW1jaHIocGFyYW1zLCAnJicsIHVyaV9sZW4pOwoJCWlmICghcCkKCQkJcmV0dXJuIE5VTEw7CgkJcCsrOwoJCXVyaV9sZW4gLT0gKHAgLSBwYXJhbXMpOwoJCXBhcmFtcyA9IHA7Cgl9CglyZXR1cm4gTlVMTDsKfQoKLyoKICogdGhpcyBkb2VzIHRoZSBzYW1lIGFzIHRoZSBwcmV2aW91cyBzZXJ2ZXJfcGgsIGJ1dCBjaGVjayB0aGUgYm9keSBjb250ZW50cwogKi8Kc3RydWN0IHNlcnZlciAqZ2V0X3NlcnZlcl9waF9wb3N0KHN0cnVjdCBzZXNzaW9uICpzKQp7Cgl1bnNpZ25lZCBsb25nICAgIGhhc2ggPSAwOwoJc3RydWN0IGh0dHBfdHhuICp0eG4gID0gJnMtPnR4bjsKCXN0cnVjdCBidWZmZXIgICAqcmVxICA9IHMtPnJlcTsKCXN0cnVjdCBodHRwX21zZyAqbXNnICA9ICZ0eG4tPnJlcTsKCXN0cnVjdCBwcm94eSAgICAqcHggICA9IHMtPmJlOwoJdW5zaWduZWQgaW50ICAgICBwbGVuID0gcHgtPnVybF9wYXJhbV9sZW47Cgl1bnNpZ25lZCBsb25nIGJvZHk7Cgl1bnNpZ25lZCBsb25nIGxlbjsKCWNvbnN0IGNoYXIgKnBhcmFtczsKCXN0cnVjdCBoZHJfY3R4IGN0eDsKCWNvbnN0IGNoYXIgICAqcDsKCgkvKiB0b3Rfd2VpZ2h0IGFwcGVhcnMgdG8gbWVhbiBzcnZfY291bnQgKi8KCWlmIChweC0+bGJwcm0udG90X3dlaWdodCA9PSAwKQoJCXJldHVybiBOVUxMOwoKICAgICAgICBib2R5ID0gbXNnLT5zb2xbbXNnLT5lb2hdID09ICdccicgPyBtc2ctPmVvaCArIDIgOiBtc2ctPmVvaCArIDE7CiAgICAgICAgbGVuICA9IHJlcS0+dG90YWwgLSBib2R5OwogICAgICAgIHBhcmFtcyA9IHJlcS0+ZGF0YSArIGJvZHk7CgoJaWYgKCBsZW4gPT0gMCApCgkJcmV0dXJuIE5VTEw7CgoJaWYgKHB4LT5sYnBybS5tYXAuc3RhdGUgJiBQUl9NQVBfUkVDQUxDKQoJCXJlY2FsY19zZXJ2ZXJfbWFwKHB4KTsKCgljdHguaWR4ID0gMDsKCgkvKiBpZiB0aGUgbWVzc2FnZSBpcyBjaHVua2VkLCB3ZSBza2lwIHRoZSBjaHVuayBzaXplLCBidXQgdXNlIHRoZSB2YWx1ZSBhcyBsZW4gKi8KCWh0dHBfZmluZF9oZWFkZXIyKCJUcmFuc2Zlci1FbmNvZGluZyIsIDE3LCBtc2ctPnNvbCwgJnR4bi0+aGRyX2lkeCwgJmN0eCk7CglpZiAoIGN0eC5pZHggJiYgc3RybmNhc2VjbXAoY3R4LmxpbmUrY3R4LnZhbCwiY2h1bmtlZCIsY3R4LnZsZW4pPT0wKSB7CgkJdW5zaWduZWQgaW50IGNodW5rID0gMDsKCQl3aGlsZSAoIHBhcmFtcyA8IHJlcS0+cmxpbSAmJiAhSFRUUF9JU19DUkxGKCpwYXJhbXMpKSB7CgkJCWNoYXIgYyA9ICpwYXJhbXM7CgkJCWlmIChpc2hleChjKSkgewoJCQkJdW5zaWduZWQgaW50IGhleCA9IHRvdXBwZXIoYykgLSAnMCc7CgkJCQlpZiAoIGhleCA+IDkgKQoJCQkJCWhleCAtPSAnQScgLSAnOScgLSAxOwoJCQkJY2h1bmsgPSAoY2h1bmsgPDwgNCkgfCBoZXg7CgkJCX0KCQkJZWxzZQoJCQkJcmV0dXJuIE5VTEw7CgkJCXBhcmFtcysrOwoJCQlsZW4tLTsKCQl9CgkJLyogc3BlYyBzYXlzIHdlIGdldCBDUkxGICovCgkJaWYgKEhUVFBfSVNfQ1JMRigqcGFyYW1zKSAmJiBIVFRQX0lTX0NSTEYocGFyYW1zWzFdKSkKCQkJcGFyYW1zICs9IDI7CgkJZWxzZQoJCQlyZXR1cm4gTlVMTDsKCQkvKiBvayB3ZSBoYXZlIHNvbWUgZW5jb2RlZCBsZW5ndGgsIGp1c3QgaW5zcGVjdCB0aGUgZmlyc3QgY2h1bmsgKi8KCQlsZW4gPSBjaHVuazsKCX0KCglwID0gcGFyYW1zOwoKCXdoaWxlIChsZW4gPiBwbGVuKSB7CgkJLyogTG9vayBmb3IgdGhlIHBhcmFtZXRlciBuYW1lIGZvbGxvd2VkIGJ5IGFuIGVxdWFsIHN5bWJvbCAqLwoJCWlmIChwYXJhbXNbcGxlbl0gPT0gJz0nKSB7CgkJCWlmIChtZW1jbXAocGFyYW1zLCBweC0+dXJsX3BhcmFtX25hbWUsIHBsZW4pID09IDApIHsKCQkJCS8qIE9LLCB3ZSBoYXZlIHRoZSBwYXJhbWV0ZXIgaGVyZSBhdCA8cGFyYW1zPiwgYW5kCgkJCQkgKiB0aGUgdmFsdWUgYWZ0ZXIgdGhlIGVxdWFsIHNpZ24sIGF0IDxwPgoJCQkJICogc2tpcCB0aGUgZXF1YWwgc3ltYm9sCgkJCQkgKi8KCQkJCXAgKz0gcGxlbiArIDE7CgkJCQlsZW4gLT0gcGxlbiArIDE7CgoJCQkJd2hpbGUgKGxlbiAmJiAqcCAhPSAnJicpIHsKCQkJCQlpZiAodW5saWtlbHkoIUhUVFBfSVNfVE9LRU4oKnApKSkgewoJCQkJCS8qIGlmIGluIGEgUE9TVCwgYm9keSBtdXN0IGJlIFVSSSBlbmNvZGVkIG9yIGl0cyBub3QgYSBVUkkuCgkJCQkJICogRG8gbm90IGludGVycHJldGUgYW55IHBvc3NpYmxlIGJpbmFyeSBkYXRhIGFzIGEgcGFyYW1ldGVyLgoJCQkJCSAqLwoJCQkJCQlpZiAobGlrZWx5KEhUVFBfSVNfTFdTKCpwKSkpIC8qIGVvbCwgdW5jZXJ0YWluIHVyaSBsZW4gKi8KCQkJCQkJCWJyZWFrOwoJCQkJCQlyZXR1cm4gTlVMTDsgICAgICAgICAgICAgICAgIC8qIG9oLCBubzsgdGhpcyBpcyBub3QgdXJpLWVuY29kZWQuCgkJCQkJCQkJCSAgICAgICogVGhpcyBib2R5IGRvZXMgbm90IGNvbnRhaW4gcGFyYW1ldGVycy4KCQkJCQkJCQkJICAgICAgKi8KCQkJCQl9CgkJCQkJaGFzaCA9ICpwICsgKGhhc2ggPDwgNikgKyAoaGFzaCA8PCAxNikgLSBoYXNoOwoJCQkJCWxlbi0tOwoJCQkJCXArKzsKCQkJCQkvKiBzaG91bGQgd2UgYnJlYWsgaWYgdmxlbiBleGNlZWRzIGxpbWl0PyAqLwoJCQkJfQoJCQkJcmV0dXJuIHB4LT5sYnBybS5tYXAuc3J2W2hhc2ggJSBweC0+bGJwcm0udG90X3dlaWdodF07CgkJCX0KCQl9CgkJLyogc2tpcCB0byBuZXh0IHBhcmFtZXRlciAqLwoJCXAgPSBtZW1jaHIocGFyYW1zLCAnJicsIGxlbik7CgkJaWYgKCFwKQoJCQlyZXR1cm4gTlVMTDsKCQlwKys7CgkJbGVuIC09IChwIC0gcGFyYW1zKTsKCQlwYXJhbXMgPSBwOwoJfQoJcmV0dXJuIE5VTEw7Cn0KCgovKgogKiBUaGlzIGZ1bmN0aW9uIGFwcGxpZXMgdGhlIGxvYWQtYmFsYW5jaW5nIGFsZ29yaXRobSB0byB0aGUgc2Vzc2lvbiwgYXMKICogZGVmaW5lZCBieSB0aGUgYmFja2VuZCBpdCBpcyBhc3NpZ25lZCB0by4gVGhlIHNlc3Npb24gaXMgdGhlbiBtYXJrZWQgYXMKICogJ2Fzc2lnbmVkJy4KICoKICogVGhpcyBmdW5jdGlvbiBNQVkgTk9UIGJlIGNhbGxlZCB3aXRoIFNOX0FTU0lHTkVEIGFscmVhZHkgc2V0LiBJZiB0aGUgc2Vzc2lvbgogKiBoYWQgYSBzZXJ2ZXIgcHJldmlvdXNseSBhc3NpZ25lZCwgaXQgaXMgcmViYWxhbmNlZCwgdHJ5aW5nIHRvIGF2b2lkIHRoZSBzYW1lCiAqIHNlcnZlci4KICogVGhlIGZ1bmN0aW9uIHRyaWVzIHRvIGtlZXAgdGhlIG9yaWdpbmFsIGNvbm5lY3Rpb24gc2xvdCBpZiBpdCByZWNvbm5lY3RzIHRvCiAqIHRoZSBzYW1lIHNlcnZlciwgb3RoZXJ3aXNlIGl0IHJlbGVhc2VzIGl0IGFuZCB0cmllcyB0byBvZmZlciBpdC4KICoKICogSXQgaXMgaWxsZWdhbCB0byBjYWxsIHRoaXMgZnVuY3Rpb24gd2l0aCBhIHNlc3Npb24gaW4gYSBxdWV1ZS4KICoKICogSXQgbWF5IHJldHVybiA6CiAqICAgU1JWX1NUQVRVU19PSyAgICAgICBpZiBldmVyeXRoaW5nIGlzIE9LLiBTZXNzaW9uIGFzc2lnbmVkIHRvIC0+c3J2CiAqICAgU1JWX1NUQVRVU19OT1NSViAgICBpZiBubyBzZXJ2ZXIgaXMgYXZhaWxhYmxlLiBTZXNzaW9uIGlzIG5vdCBBU1NJR05FRAogKiAgIFNSVl9TVEFUVVNfRlVMTCAgICAgaWYgYWxsIHNlcnZlcnMgYXJlIHNhdHVyYXRlZC4gU2Vzc2lvbiBpcyBub3QgQVNTSUdORUQKICogICBTUlZfU1RBVFVTX0lOVEVSTkFMIGZvciBvdGhlciB1bnJlY292ZXJhYmxlIGVycm9ycy4KICoKICogVXBvbiBzdWNjZXNzZnVsIHJldHVybiwgdGhlIHNlc3Npb24gZmxhZyBTTl9BU1NJR05FRCBpcyBzZXQgdG8gaW5kaWNhdGUgdGhhdAogKiBpdCBkb2VzIG5vdCBuZWVkIHRvIGJlIGNhbGxlZCBhbnltb3JlLiBUaGlzIG1lYW5zIHRoYXQgcy0+c3J2IGNhbiBiZSB0cnVzdGVkCiAqIGluIGJhbGFuY2UgYW5kIGRpcmVjdCBtb2Rlcy4KICoKICovCgppbnQgYXNzaWduX3NlcnZlcihzdHJ1Y3Qgc2Vzc2lvbiAqcykKewoKCXN0cnVjdCBzZXJ2ZXIgKmNvbm5fc2xvdDsKCWludCBlcnI7CgojaWZkZWYgREVCVUdfRlVMTAoJZnByaW50ZihzdGRlcnIsImFzc2lnbl9zZXJ2ZXIgOiBzPSVwXG4iLHMpOwojZW5kaWYKCgllcnIgPSBTUlZfU1RBVFVTX0lOVEVSTkFMOwoJaWYgKHVubGlrZWx5KHMtPnBlbmRfcG9zIHx8IHMtPmZsYWdzICYgU05fQVNTSUdORUQpKQoJCWdvdG8gb3V0X2VycjsKCglzLT5wcmV2X3NydiA9IHMtPnByZXZfc3J2OwoJY29ubl9zbG90ID0gcy0+c3J2X2Nvbm47CgoJLyogV2UgaGF2ZSB0byByZWxlYXNlIGFueSBjb25uZWN0aW9uIHNsb3QgYmVmb3JlIGFwcGx5aW5nIGFueSBMQiBhbGdvLAoJICogb3RoZXJ3aXNlIHdlIG1heSBlcnJvbmVvdXNseSBlbmQgdXAgd2l0aCBubyBhdmFpbGFibGUgc2xvdC4KCSAqLwoJaWYgKGNvbm5fc2xvdCkKCQlzZXNzX2NoYW5nZV9zZXJ2ZXIocywgTlVMTCk7CgoJLyogV2Ugd2lsbCBub3cgdHJ5IHRvIGZpbmQgdGhlIGdvb2Qgc2VydmVyIGFuZCBzdG9yZSBpdCBpbnRvIDxzLT5zcnY+LgoJICogTm90ZSB0aGF0IDxzLT5zcnY+IG1heSBiZSBOVUxMIGluIGNhc2Ugb2YgZGlzcGF0Y2ggb3IgcHJveHkgbW9kZSwKCSAqIGFzIHdlbGwgYXMgaWYgbm8gc2VydmVyIGlzIGF2YWlsYWJsZSAoY2hlY2sgZXJyb3IgY29kZSkuCgkgKi8KCglzLT5zcnYgPSBOVUxMOwoJaWYgKHMtPmJlLT5sYnBybS5hbGdvICYgQkVfTEJfQUxHTykgewoJCWludCBsZW47CgkJLyogd2UgbXVzdCBjaGVjayBpZiB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBzZXJ2ZXIgYXZhaWxhYmxlICovCgkJaWYgKCFzLT5iZS0+bGJwcm0udG90X3dlaWdodCkgewoJCQllcnIgPSBTUlZfU1RBVFVTX05PU1JWOwoJCQlnb3RvIG91dDsKCQl9CgoJCXN3aXRjaCAocy0+YmUtPmxicHJtLmFsZ28gJiBCRV9MQl9BTEdPKSB7CgkJY2FzZSBCRV9MQl9BTEdPX1JSOgoJCQlzLT5zcnYgPSBmd3JyX2dldF9uZXh0X3NlcnZlcihzLT5iZSwgcy0+cHJldl9zcnYpOwoJCQlpZiAoIXMtPnNydikgewoJCQkJZXJyID0gU1JWX1NUQVRVU19GVUxMOwoJCQkJZ290byBvdXQ7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBCRV9MQl9BTEdPX0xDOgoJCQlzLT5zcnYgPSBmd2xjX2dldF9uZXh0X3NlcnZlcihzLT5iZSwgcy0+cHJldl9zcnYpOwoJCQlpZiAoIXMtPnNydikgewoJCQkJZXJyID0gU1JWX1NUQVRVU19GVUxMOwoJCQkJZ290byBvdXQ7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBCRV9MQl9BTEdPX1NIOgoJCQlpZiAocy0+Y2xpX2FkZHIuc3NfZmFtaWx5ID09IEFGX0lORVQpCgkJCQlsZW4gPSA0OwoJCQllbHNlIGlmIChzLT5jbGlfYWRkci5zc19mYW1pbHkgPT0gQUZfSU5FVDYpCgkJCQlsZW4gPSAxNjsKCQkJZWxzZSB7CgkJCQkvKiB1bmtub3duIElQIGZhbWlseSAqLwoJCQkJZXJyID0gU1JWX1NUQVRVU19JTlRFUk5BTDsKCQkJCWdvdG8gb3V0OwoJCQl9CgkJCgkJCXMtPnNydiA9IGdldF9zZXJ2ZXJfc2gocy0+YmUsCgkJCQkJICAgICAgICh2b2lkICopJigoc3RydWN0IHNvY2thZGRyX2luICopJnMtPmNsaV9hZGRyKS0+c2luX2FkZHIsCgkJCQkJICAgICAgIGxlbik7CgkJCWJyZWFrOwoJCWNhc2UgQkVfTEJfQUxHT19VSDoKCQkJLyogVVJJIGhhc2hpbmcgKi8KCQkJcy0+c3J2ID0gZ2V0X3NlcnZlcl91aChzLT5iZSwKCQkJCQkgICAgICAgcy0+dHhuLnJlcS5zb2wgKyBzLT50eG4ucmVxLnNsLnJxLnUsCgkJCQkJICAgICAgIHMtPnR4bi5yZXEuc2wucnEudV9sKTsKCQkJYnJlYWs7CgkJY2FzZSBCRV9MQl9BTEdPX1BIOgoJCQkvKiBVUkwgUGFyYW1ldGVyIGhhc2hpbmcgKi8KCQkJaWYgKHMtPnR4bi5tZXRoID09IEhUVFBfTUVUSF9QT1NUICYmCgkJCSAgICBtZW1jaHIocy0+dHhuLnJlcS5zb2wgKyBzLT50eG4ucmVxLnNsLnJxLnUsICcmJywKCQkJCSAgIHMtPnR4bi5yZXEuc2wucnEudV9sICkgPT0gTlVMTCkKCQkJCXMtPnNydiA9IGdldF9zZXJ2ZXJfcGhfcG9zdChzKTsKCQkJZWxzZQoJCQkJcy0+c3J2ID0gZ2V0X3NlcnZlcl9waChzLT5iZSwKCQkJCQkJICAgICAgIHMtPnR4bi5yZXEuc29sICsgcy0+dHhuLnJlcS5zbC5ycS51LAoJCQkJCQkgICAgICAgcy0+dHhuLnJlcS5zbC5ycS51X2wpOwoKCQkJaWYgKCFzLT5zcnYpIHsKCQkJCS8qIHBhcmFtZXRlciBub3QgZm91bmQsIGZhbGwgYmFjayB0byByb3VuZCByb2JpbiBvbiB0aGUgbWFwICovCgkJCQlzLT5zcnYgPSBnZXRfc2VydmVyX3JyX3dpdGhfY29ubnMocy0+YmUsIHMtPnByZXZfc3J2KTsKCQkJCWlmICghcy0+c3J2KSB7CgkJCQkJZXJyID0gU1JWX1NUQVRVU19GVUxMOwoJCQkJCWdvdG8gb3V0OwoJCQkJfQoJCQl9CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCS8qIHVua25vd24gYmFsYW5jaW5nIGFsZ29yaXRobSAqLwoJCQllcnIgPSBTUlZfU1RBVFVTX0lOVEVSTkFMOwoJCQlnb3RvIG91dDsKCQl9CgkJaWYgKHMtPnNydiAhPSBzLT5wcmV2X3NydikgewoJCQlzLT5iZS0+Y3VtX2xiY29ubisrOwoJCQlzLT5zcnYtPmN1bV9sYmNvbm4rKzsKCQl9Cgl9CgllbHNlIGlmIChzLT5iZS0+b3B0aW9ucyAmIFBSX09fSFRUUF9QUk9YWSkgewoJCWlmICghcy0+c3J2X2FkZHIuc2luX2FkZHIuc19hZGRyKSB7CgkJCWVyciA9IFNSVl9TVEFUVVNfTk9TUlY7CgkJCWdvdG8gb3V0OwoJCX0KCX0KCWVsc2UgaWYgKCEqKGludCAqKSZzLT5iZS0+ZGlzcGF0Y2hfYWRkci5zaW5fYWRkciAmJgoJCSAhKHMtPmZlLT5vcHRpb25zICYgUFJfT19UUkFOU1ApKSB7CgkJZXJyID0gU1JWX1NUQVRVU19OT1NSVjsKCQlnb3RvIG91dDsKCX0KCglzLT5mbGFncyB8PSBTTl9BU1NJR05FRDsKCWVyciA9IFNSVl9TVEFUVVNfT0s7CiBvdXQ6CgoJLyogRWl0aGVyIHdlIHRha2UgYmFjayBvdXIgY29ubmVjdGlvbiBzbG90LCBvciB3ZSBvZmZlciBpdCB0byBzb21lb25lCgkgKiBlbHNlIGlmIHdlIGRvbid0IG5lZWQgaXQgYW55bW9yZS4KCSAqLwoJaWYgKGNvbm5fc2xvdCkgewoJCWlmIChjb25uX3Nsb3QgPT0gcy0+c3J2KSB7CgkJCXNlc3NfY2hhbmdlX3NlcnZlcihzLCBzLT5zcnYpOwoJCX0gZWxzZSB7CgkJCWlmIChtYXlfZGVxdWV1ZV90YXNrcyhjb25uX3Nsb3QsIHMtPmJlKSkKCQkJCXByb2Nlc3Nfc3J2X3F1ZXVlKGNvbm5fc2xvdCk7CgkJfQoJfQoKIG91dF9lcnI6CglyZXR1cm4gZXJyOwp9CgoKLyoKICogVGhpcyBmdW5jdGlvbiBhc3NpZ25zIGEgc2VydmVyIGFkZHJlc3MgdG8gYSBzZXNzaW9uLCBhbmQgc2V0cyBTTl9BRERSX1NFVC4KICogVGhlIGFkZHJlc3MgaXMgdGFrZW4gZnJvbSB0aGUgY3VycmVudGx5IGFzc2lnbmVkIHNlcnZlciwgb3IgZnJvbSB0aGUKICogZGlzcGF0Y2ggb3IgdHJhbnNwYXJlbnQgYWRkcmVzcy4KICoKICogSXQgbWF5IHJldHVybiA6CiAqICAgU1JWX1NUQVRVU19PSyAgICAgICBpZiBldmVyeXRoaW5nIGlzIE9LLgogKiAgIFNSVl9TVEFUVVNfSU5URVJOQUwgZm9yIG90aGVyIHVucmVjb3ZlcmFibGUgZXJyb3JzLgogKgogKiBVcG9uIHN1Y2Nlc3NmdWwgcmV0dXJuLCB0aGUgc2Vzc2lvbiBmbGFnIFNOX0FERFJfU0VUIGlzIHNldC4gVGhpcyBmbGFnIGlzCiAqIG5vdCBjbGVhcmVkLCBzbyBpdCdzIHRvIHRoZSBjYWxsZXIgdG8gY2xlYXIgaXQgaWYgcmVxdWlyZWQuCiAqCiAqLwppbnQgYXNzaWduX3NlcnZlcl9hZGRyZXNzKHN0cnVjdCBzZXNzaW9uICpzKQp7CiNpZmRlZiBERUJVR19GVUxMCglmcHJpbnRmKHN0ZGVyciwiYXNzaWduX3NlcnZlcl9hZGRyZXNzIDogcz0lcFxuIixzKTsKI2VuZGlmCgoJaWYgKChzLT5mbGFncyAmIFNOX0RJUkVDVCkgfHwgKHMtPmJlLT5sYnBybS5hbGdvICYgQkVfTEJfQUxHTykpIHsKCQkvKiBBIHNlcnZlciBpcyBuZWNlc3NhcmlseSBrbm93biBmb3IgdGhpcyBzZXNzaW9uICovCgkJaWYgKCEocy0+ZmxhZ3MgJiBTTl9BU1NJR05FRCkpCgkJCXJldHVybiBTUlZfU1RBVFVTX0lOVEVSTkFMOwoKCQlzLT5zcnZfYWRkciA9IHMtPnNydi0+YWRkcjsKCgkJLyogaWYgdGhpcyBzZXJ2ZXIgcmVtYXBzIHByb3hpZWQgcG9ydHMsIHdlJ2xsIHVzZQoJCSAqIHRoZSBwb3J0IHRoZSBjbGllbnQgY29ubmVjdGVkIHRvIHdpdGggYW4gb2Zmc2V0LiAqLwoJCWlmIChzLT5zcnYtPnN0YXRlICYgU1JWX01BUFBPUlRTKSB7CgkJCWlmICghKHMtPmZlLT5vcHRpb25zICYgUFJfT19UUkFOU1ApICYmICEocy0+ZmxhZ3MgJiBTTl9GUlRfQUREUl9TRVQpKQoJCQkJZ2V0X2ZydF9hZGRyKHMpOwoJCQlpZiAocy0+ZnJ0X2FkZHIuc3NfZmFtaWx5ID09IEFGX0lORVQpIHsKCQkJCXMtPnNydl9hZGRyLnNpbl9wb3J0ID0gaHRvbnMobnRvaHMocy0+c3J2X2FkZHIuc2luX3BvcnQpICsKCQkJCQkJCSAgICAgbnRvaHMoKChzdHJ1Y3Qgc29ja2FkZHJfaW4gKikmcy0+ZnJ0X2FkZHIpLT5zaW5fcG9ydCkpOwoJCQl9IGVsc2UgewoJCQkJcy0+c3J2X2FkZHIuc2luX3BvcnQgPSBodG9ucyhudG9ocyhzLT5zcnZfYWRkci5zaW5fcG9ydCkgKwoJCQkJCQkJICAgICBudG9ocygoKHN0cnVjdCBzb2NrYWRkcl9pbjYgKikmcy0+ZnJ0X2FkZHIpLT5zaW42X3BvcnQpKTsKCQkJfQoJCX0KCX0KCWVsc2UgaWYgKCooaW50ICopJnMtPmJlLT5kaXNwYXRjaF9hZGRyLnNpbl9hZGRyKSB7CgkJLyogY29ubmVjdCB0byB0aGUgZGVmaW5lZCBkaXNwYXRjaCBhZGRyICovCgkJcy0+c3J2X2FkZHIgPSBzLT5iZS0+ZGlzcGF0Y2hfYWRkcjsKCX0KCWVsc2UgaWYgKHMtPmZlLT5vcHRpb25zICYgUFJfT19UUkFOU1ApIHsKCQkvKiBpbiB0cmFuc3BhcmVudCBtb2RlLCB1c2UgdGhlIG9yaWdpbmFsIGRlc3QgYWRkciBpZiBubyBkaXNwYXRjaCBzcGVjaWZpZWQgKi8KCQlpZiAoIShzLT5mbGFncyAmIFNOX0ZSVF9BRERSX1NFVCkpCgkJCWdldF9mcnRfYWRkcihzKTsKCgkJbWVtY3B5KCZzLT5zcnZfYWRkciwgJnMtPmZydF9hZGRyLCBNSU4oc2l6ZW9mKHMtPnNydl9hZGRyKSwgc2l6ZW9mKHMtPmZydF9hZGRyKSkpOwoJCS8qIHdoZW4gd2Ugc3VwcG9ydCBJUHY2IG9uIHRoZSBiYWNrZW5kLCB3ZSBtYXkgYWRkIG90aGVyIHRlc3RzICovCgkJLy9xZnByaW50ZihzdGRlcnIsICJDYW5ub3QgZ2V0IG9yaWdpbmFsIHNlcnZlciBhZGRyZXNzLlxuIik7CgkJLy9yZXR1cm4gU1JWX1NUQVRVU19JTlRFUk5BTDsKCX0KCWVsc2UgaWYgKHMtPmJlLT5vcHRpb25zICYgUFJfT19IVFRQX1BST1hZKSB7CgkJLyogSWYgSFRUUCBQUk9YWSBvcHRpb24gaXMgc2V0LCB0aGVuIHNlcnZlciBpcyBhbHJlYWR5IGFzc2lnbmVkCgkJICogZHVyaW5nIGluY29taW5nIGNsaWVudCByZXF1ZXN0IHBhcnNpbmcuICovCgl9CgllbHNlIHsKCQkvKiBubyBzZXJ2ZXIgYW5kIG5vIExCIGFsZ29yaXRobSAhICovCgkJcmV0dXJuIFNSVl9TVEFUVVNfSU5URVJOQUw7Cgl9CgoJcy0+ZmxhZ3MgfD0gU05fQUREUl9TRVQ7CglyZXR1cm4gU1JWX1NUQVRVU19PSzsKfQoKCi8qIFRoaXMgZnVuY3Rpb24gYXNzaWducyBhIHNlcnZlciB0byBzZXNzaW9uIDxzPiBpZiByZXF1aXJlZCwgYW5kIGNhbiBhZGQgdGhlCiAqIGNvbm5lY3Rpb24gdG8gZWl0aGVyIHRoZSBhc3NpZ25lZCBzZXJ2ZXIncyBxdWV1ZSBvciB0byB0aGUgcHJveHkncyBxdWV1ZS4KICogSWYgLT5zcnZfY29ubiBpcyBzZXQsIHRoZSBzZXNzaW9uIGlzIGZpcnN0IHJlbGVhc2VkIGZyb20gdGhlIHNlcnZlci4KICogSXQgbWF5IGFsc28gYmUgY2FsbGVkIHdpdGggU05fRElSRUNUIGFuZC9vciBTTl9BU1NJR05FRCB0aG91Z2guIEl0IHdpbGwKICogYmUgY2FsbGVkIGJlZm9yZSBhbnkgY29ubmVjdGlvbiBhbmQgYWZ0ZXIgYW55IHJldHJ5IG9yIHJlZGlzcGF0Y2ggb2NjdXJzLgogKgogKiBJdCBpcyBub3QgYWxsb3dlZCB0byBjYWxsIHRoaXMgZnVuY3Rpb24gd2l0aCBhIHNlc3Npb24gaW4gYSBxdWV1ZS4KICoKICogUmV0dXJucyA6CiAqCiAqICAgU1JWX1NUQVRVU19PSyAgICAgICBpZiBldmVyeXRoaW5nIGlzIE9LLgogKiAgIFNSVl9TVEFUVVNfTk9TUlYgICAgaWYgbm8gc2VydmVyIGlzIGF2YWlsYWJsZS4gcy0+c3J2ID0gTlVMTC4KICogICBTUlZfU1RBVFVTX1FVRVVFRCAgIGlmIHRoZSBjb25uZWN0aW9uIGhhcyBiZWVuIHF1ZXVlZC4KICogICBTUlZfU1RBVFVTX0ZVTEwgICAgIGlmIHRoZSBzZXJ2ZXIocykgaXMvYXJlIHNhdHVyYXRlZCBhbmQgdGhlCiAqICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uIGNvdWxkIG5vdCBiZSBxdWV1ZWQgaW4gcy0+c3J2LAogKiAgICAgICAgICAgICAgICAgICAgICAgd2hpY2ggbWF5IGJlIE5VTEwgaWYgd2UgcXVldWUgb24gdGhlIGJhY2tlbmQuCiAqICAgU1JWX1NUQVRVU19JTlRFUk5BTCBmb3Igb3RoZXIgdW5yZWNvdmVyYWJsZSBlcnJvcnMuCiAqCiAqLwppbnQgYXNzaWduX3NlcnZlcl9hbmRfcXVldWUoc3RydWN0IHNlc3Npb24gKnMpCnsKCXN0cnVjdCBwZW5kY29ubiAqcDsKCWludCBlcnI7CgoJaWYgKHMtPnBlbmRfcG9zKQoJCXJldHVybiBTUlZfU1RBVFVTX0lOVEVSTkFMOwoKCWVyciA9IFNSVl9TVEFUVVNfT0s7CglpZiAoIShzLT5mbGFncyAmIFNOX0FTU0lHTkVEKSkgewoJCWVyciA9IGFzc2lnbl9zZXJ2ZXIocyk7CgkJaWYgKHMtPnByZXZfc3J2KSB7CgkJCS8qIFRoaXMgc2Vzc2lvbiB3YXMgcHJldmlvdXNseSBhc3NpZ25lZCB0byBhIHNlcnZlci4gV2UgaGF2ZSB0bwoJCQkgKiB1cGRhdGUgdGhlIHNlc3Npb24ncyBhbmQgdGhlIHNlcnZlcidzIHN0YXRzIDoKCQkJICogIC0gaWYgdGhlIHNlcnZlciBjaGFuZ2VkIDoKCQkJICogICAgLSBzZXQgVFhfQ0tfRE9XTiBpZiB0eG4uZmxhZ3Mgd2FzIFRYX0NLX1ZBTElECgkJCSAqICAgIC0gc2V0IFNOX1JFRElTUCBpZiBpdCB3YXMgc3VjY2Vzc2Z1bGx5IHJlZGlzcGF0Y2hlZAoJCQkgKiAgICAtIGluY3JlbWVudCBzcnYtPnJlZGlzcGF0Y2hlcyBhbmQgYmUtPnJlZGlzcGF0Y2hlcwoJCQkgKiAgLSBpZiB0aGUgc2VydmVyIHJlbWFpbmVkIHRoZSBzYW1lIDogdXBkYXRlIHJldHJpZXMuCgkJCSAqLwoKCQkJaWYgKHMtPnByZXZfc3J2ICE9IHMtPnNydikgewoJCQkJaWYgKChzLT50eG4uZmxhZ3MgJiBUWF9DS19NQVNLKSA9PSBUWF9DS19WQUxJRCkgewoJCQkJCXMtPnR4bi5mbGFncyAmPSB+VFhfQ0tfTUFTSzsKCQkJCQlzLT50eG4uZmxhZ3MgfD0gVFhfQ0tfRE9XTjsKCQkJCX0KCQkJCXMtPmZsYWdzIHw9IFNOX1JFRElTUDsKCQkJCXMtPnByZXZfc3J2LT5yZWRpc3BhdGNoZXMrKzsKCQkJCXMtPmJlLT5yZWRpc3BhdGNoZXMrKzsKCQkJfSBlbHNlIHsKCQkJCXMtPnByZXZfc3J2LT5yZXRyaWVzKys7CgkJCQlzLT5iZS0+cmV0cmllcysrOwoJCQl9CgkJfQoJfQoKCXN3aXRjaCAoZXJyKSB7CgljYXNlIFNSVl9TVEFUVVNfT0s6CgkJLyogd2UgaGF2ZSBTTl9BU1NJR05FRCBzZXQgKi8KCQlpZiAoIXMtPnNydikKCQkJcmV0dXJuIFNSVl9TVEFUVVNfT0s7ICAgLyogZGlzcGF0Y2ggb3IgcHJveHkgbW9kZSAqLwoKCQkvKiBJZiB3ZSBhbHJlYWR5IGhhdmUgYSBjb25uZWN0aW9uIHNsb3QsIG5vIG5lZWQgdG8gY2hlY2sgYW55IHF1ZXVlICovCgkJaWYgKHMtPnNydl9jb25uID09IHMtPnNydikKCQkJcmV0dXJuIFNSVl9TVEFUVVNfT0s7CgoJCS8qIE9LLCB0aGlzIHNlc3Npb24gYWxyZWFkeSBoYXMgYW4gYXNzaWduZWQgc2VydmVyLCBidXQgbm8KCQkgKiBjb25uZWN0aW9uIHNsb3QgeWV0LiBFaXRoZXIgaXQgaXMgYSByZWRpc3BhdGNoLCBvciBpdCB3YXMKCQkgKiBhc3NpZ25lZCBmcm9tIHBlcnNpc3RlbmNlIGluZm9ybWF0aW9uIChkaXJlY3QgbW9kZSkuCgkJICovCgkJaWYgKChzLT5mbGFncyAmIFNOX1JFRElSRUNUQUJMRSkgJiYgcy0+c3J2LT5yZHJfbGVuKSB7CgkJCS8qIHNlcnZlciBzY2hlZHVsZWQgZm9yIHJlZGlyZWN0aW9uLCBhbmQgYWxyZWFkeSBhc3NpZ25lZC4gV2UKCQkJICogZG9uJ3Qgd2FudCB0byBnbyBmdXJ0aGVyIG5vciBjaGVjayB0aGUgcXVldWUuCgkJCSAqLwoJCQlzZXNzX2NoYW5nZV9zZXJ2ZXIocywgcy0+c3J2KTsgLyogbm90IHJlYWxseSBuZWVkZWQgaW4gZmFjdCAqLwoJCQlyZXR1cm4gU1JWX1NUQVRVU19PSzsKCQl9CgoJCS8qIFdlIG1pZ2h0IGhhdmUgdG8gcXVldWUgdGhpcyBzZXNzaW9uIGlmIHRoZSBhc3NpZ25lZCBzZXJ2ZXIgaXMgZnVsbC4KCQkgKiBXZSBrbm93IHdlIGhhdmUgdG8gcXVldWUgaXQgaW50byB0aGUgc2VydmVyJ3MgcXVldWUsIHNvIGlmIGEgbWF4cXVldWUKCQkgKiBpcyBzZXQgb24gdGhlIHNlcnZlciwgd2UgbXVzdCBhbHNvIGNoZWNrIHRoYXQgdGhlIHNlcnZlcidzIHF1ZXVlIGlzCgkJICogbm90IGZ1bGwsIGluIHdoaWNoIGNhc2Ugd2UgaGF2ZSB0byByZXR1cm4gRlVMTC4KCQkgKi8KCQlpZiAocy0+c3J2LT5tYXhjb25uICYmCgkJICAgIChzLT5zcnYtPm5icGVuZCB8fCBzLT5zcnYtPnNlcnZlZCA+PSBzcnZfZHluYW1pY19tYXhjb25uKHMtPnNydikpKSB7CgoJCQlpZiAocy0+c3J2LT5tYXhxdWV1ZSA+IDAgJiYgcy0+c3J2LT5uYnBlbmQgPj0gcy0+c3J2LT5tYXhxdWV1ZSkKCQkJCXJldHVybiBTUlZfU1RBVFVTX0ZVTEw7CgoJCQlwID0gcGVuZGNvbm5fYWRkKHMpOwoJCQlpZiAocCkKCQkJCXJldHVybiBTUlZfU1RBVFVTX1FVRVVFRDsKCQkJZWxzZQoJCQkJcmV0dXJuIFNSVl9TVEFUVVNfSU5URVJOQUw7CgkJfQoKCQkvKiBPSywgd2UgY2FuIHVzZSB0aGlzIHNlcnZlci4gTGV0J3MgcmVzZXJ2ZSBvdXIgcGxhY2UgKi8KCQlzZXNzX2NoYW5nZV9zZXJ2ZXIocywgcy0+c3J2KTsKCQlyZXR1cm4gU1JWX1NUQVRVU19PSzsKCgljYXNlIFNSVl9TVEFUVVNfRlVMTDoKCQkvKiBxdWV1ZSB0aGlzIHNlc3Npb24gaW50byB0aGUgcHJveHkncyBxdWV1ZSAqLwoJCXAgPSBwZW5kY29ubl9hZGQocyk7CgkJaWYgKHApCgkJCXJldHVybiBTUlZfU1RBVFVTX1FVRVVFRDsKCQllbHNlCgkJCXJldHVybiBTUlZfU1RBVFVTX0lOVEVSTkFMOwoKCWNhc2UgU1JWX1NUQVRVU19OT1NSVjoKCQlyZXR1cm4gZXJyOwoKCWNhc2UgU1JWX1NUQVRVU19JTlRFUk5BTDoKCQlyZXR1cm4gZXJyOwoKCWRlZmF1bHQ6CgkJcmV0dXJuIFNSVl9TVEFUVVNfSU5URVJOQUw7Cgl9Cn0KCi8qCiAqIFRoaXMgZnVuY3Rpb24gaW5pdGlhdGVzIGEgY29ubmVjdGlvbiB0byB0aGUgc2VydmVyIGFzc2lnbmVkIHRvIHRoaXMgc2Vzc2lvbgogKiAocy0+c3J2LCBzLT5zcnZfYWRkcikuIEl0IHdpbGwgYXNzaWduIGEgc2VydmVyIGlmIG5vbmUgaXMgYXNzaWduZWQgeWV0LgogKiBJdCBjYW4gcmV0dXJuIG9uZSBvZiA6CiAqICAtIFNOX0VSUl9OT05FIGlmIGV2ZXJ5dGhpbmcncyBPSwogKiAgLSBTTl9FUlJfU1JWVE8gaWYgdGhlcmUgYXJlIG5vIG1vcmUgc2VydmVycwogKiAgLSBTTl9FUlJfU1JWQ0wgaWYgdGhlIGNvbm5lY3Rpb24gd2FzIHJlZnVzZWQgYnkgdGhlIHNlcnZlcgogKiAgLSBTTl9FUlJfUFJYQ09ORCBpZiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBsaW1pdGVkIGJ5IHRoZSBwcm94eSAobWF4Y29ubikKICogIC0gU05fRVJSX1JFU09VUkNFIGlmIGEgc3lzdGVtIHJlc291cmNlIGlzIGxhY2tpbmcgKGVnOiBmZCBsaW1pdHMsIHBvcnRzLCAuLi4pCiAqICAtIFNOX0VSUl9JTlRFUk5BTCBmb3IgYW55IG90aGVyIHB1cmVseSBpbnRlcm5hbCBlcnJvcnMKICogQWRkaXRpb25uYWxseSwgaW4gdGhlIGNhc2Ugb2YgU05fRVJSX1JFU09VUkNFLCBhbiBlbWVyZ2VuY3kgbG9nIHdpbGwgYmUgZW1pdHRlZC4KICovCmludCBjb25uZWN0X3NlcnZlcihzdHJ1Y3Qgc2Vzc2lvbiAqcykKewoJaW50IGZkLCBlcnI7CgoJaWYgKCEocy0+ZmxhZ3MgJiBTTl9BRERSX1NFVCkpIHsKCQllcnIgPSBhc3NpZ25fc2VydmVyX2FkZHJlc3Mocyk7CgkJaWYgKGVyciAhPSBTUlZfU1RBVFVTX09LKQoJCQlyZXR1cm4gU05fRVJSX0lOVEVSTkFMOwoJfQoKCWlmICgoZmQgPSBzLT5zcnZfZmQgPSBzb2NrZXQoQUZfSU5FVCwgU09DS19TVFJFQU0sIElQUFJPVE9fVENQKSkgPT0gLTEpIHsKCQlxZnByaW50ZihzdGRlcnIsICJDYW5ub3QgZ2V0IGEgc2VydmVyIHNvY2tldC5cbiIpOwoKCQlpZiAoZXJybm8gPT0gRU5GSUxFKQoJCQlzZW5kX2xvZyhzLT5iZSwgTE9HX0VNRVJHLAoJCQkJICJQcm94eSAlcyByZWFjaGVkIHN5c3RlbSBGRCBsaW1pdCBhdCAlZC4gUGxlYXNlIGNoZWNrIHN5c3RlbSB0dW5hYmxlcy5cbiIsCgkJCQkgcy0+YmUtPmlkLCBtYXhmZCk7CgkJZWxzZSBpZiAoZXJybm8gPT0gRU1GSUxFKQoJCQlzZW5kX2xvZyhzLT5iZSwgTE9HX0VNRVJHLAoJCQkJICJQcm94eSAlcyByZWFjaGVkIHByb2Nlc3MgRkQgbGltaXQgYXQgJWQuIFBsZWFzZSBjaGVjayAndWxpbWl0LW4nIGFuZCByZXN0YXJ0LlxuIiwKCQkJCSBzLT5iZS0+aWQsIG1heGZkKTsKCQllbHNlIGlmIChlcnJubyA9PSBFTk9CVUZTIHx8IGVycm5vID09IEVOT01FTSkKCQkJc2VuZF9sb2cocy0+YmUsIExPR19FTUVSRywKCQkJCSAiUHJveHkgJXMgcmVhY2hlZCBzeXN0ZW0gbWVtb3J5IGxpbWl0IGF0ICVkIHNvY2tldHMuIFBsZWFzZSBjaGVjayBzeXN0ZW0gdHVuYWJsZXMuXG4iLAoJCQkJIHMtPmJlLT5pZCwgbWF4ZmQpOwoJCS8qIHRoaXMgaXMgYSByZXNvdXJjZSBlcnJvciAqLwoJCXJldHVybiBTTl9FUlJfUkVTT1VSQ0U7Cgl9CgkKCWlmIChmZCA+PSBnbG9iYWwubWF4c29jaykgewoJCS8qIGRvIG5vdCBsb2cgYW55dGhpbmcgdGhlcmUsIGl0J3MgYSBub3JtYWwgY29uZGl0aW9uIHdoZW4gdGhpcyBvcHRpb24KCQkgKiBpcyB1c2VkIHRvIHNlcmlhbGl6ZSBjb25uZWN0aW9ucyB0byBhIHNlcnZlciAhCgkJICovCgkJQWxlcnQoInNvY2tldCgpOiBub3QgZW5vdWdoIGZyZWUgc29ja2V0cy4gUmFpc2UgLW4gYXJndW1lbnQuIEdpdmluZyB1cC5cbiIpOwoJCWNsb3NlKGZkKTsKCQlyZXR1cm4gU05fRVJSX1BSWENPTkQ7IC8qIGl0IGlzIGEgY29uZmlndXJhdGlvbiBsaW1pdCAqLwoJfQoKI2lmZGVmIENPTkZJR19IQVBfVENQU1BMSUNFCglpZiAoKHMtPmZlLT5vcHRpb25zICYgcy0+YmUtPm9wdGlvbnMpICYgUFJfT19UQ1BTUExJQ0UpIHsKCQkvKiBUQ1Agc3BsaWNpbmcgc3VwcG9ydGVkIGJ5IGJvdGggRkUgYW5kIEJFICovCgkJdGNwX3NwbGljZV9pbml0ZmQocy0+Y2xpX2ZkLCBmZCk7Cgl9CiNlbmRpZgoKCWlmICgoZmNudGwoZmQsIEZfU0VURkwsIE9fTk9OQkxPQ0spPT0tMSkgfHwKCSAgICAoc2V0c29ja29wdChmZCwgSVBQUk9UT19UQ1AsIFRDUF9OT0RFTEFZLCAoY2hhciAqKSAmb25lLCBzaXplb2Yob25lKSkgPT0gLTEpKSB7CgkJcWZwcmludGYoc3RkZXJyLCJDYW5ub3Qgc2V0IGNsaWVudCBzb2NrZXQgdG8gbm9uIGJsb2NraW5nIG1vZGUuXG4iKTsKCQljbG9zZShmZCk7CgkJcmV0dXJuIFNOX0VSUl9JTlRFUk5BTDsKCX0KCglpZiAocy0+YmUtPm9wdGlvbnMgJiBQUl9PX1RDUF9TUlZfS0EpCgkJc2V0c29ja29wdChmZCwgU09MX1NPQ0tFVCwgU09fS0VFUEFMSVZFLCAoY2hhciAqKSAmb25lLCBzaXplb2Yob25lKSk7CgoJaWYgKHMtPmJlLT5vcHRpb25zICYgUFJfT19UQ1BfTk9MSU5HKQoJCXNldHNvY2tvcHQoZmQsIFNPTF9TT0NLRVQsIFNPX0xJTkdFUiwgKHN0cnVjdCBsaW5nZXIgKikgJm5vbGluZ2VyLCBzaXplb2Yoc3RydWN0IGxpbmdlcikpOwoKCS8qIGFsbG93IHNwZWNpZmljIGJpbmRpbmcgOgoJICogLSBzZXJ2ZXItc3BlY2lmaWMgYXQgZmlyc3QKCSAqIC0gcHJveHktc3BlY2lmaWMgbmV4dAoJICovCglpZiAocy0+c3J2ICE9IE5VTEwgJiYgcy0+c3J2LT5zdGF0ZSAmIFNSVl9CSU5EX1NSQykgewoJCXN0cnVjdCBzb2NrYWRkcl9pbiAqcmVtb3RlID0gTlVMTDsKCQlpbnQgcmV0LCBmbGFncyA9IDA7CgojaWYgZGVmaW5lZChDT05GSUdfSEFQX0NUVFBST1hZKSB8fCBkZWZpbmVkKENPTkZJR19IQVBfTElOVVhfVFBST1hZKQoJCXN3aXRjaCAocy0+c3J2LT5zdGF0ZSAmIFNSVl9UUFJPWFlfTUFTSykgewoJCWNhc2UgU1JWX1RQUk9YWV9BRERSOgoJCQlyZW1vdGUgPSAoc3RydWN0IHNvY2thZGRyX2luICopJnMtPnNydi0+dHByb3h5X2FkZHI7CgkJCWZsYWdzICA9IDM7CgkJCWJyZWFrOwoJCWNhc2UgU1JWX1RQUk9YWV9DTEk6CgkJCWZsYWdzIHw9IDI7CgkJCS8qIGZhbGwgdGhyb3VnaCAqLwoJCWNhc2UgU1JWX1RQUk9YWV9DSVA6CgkJCS8qIEZJWE1FOiB3aGF0IGNhbiB3ZSBkbyBpZiB0aGUgY2xpZW50IGNvbm5lY3RzIGluIElQdjYgPyAqLwoJCQlmbGFncyB8PSAxOwoJCQlyZW1vdGUgPSAoc3RydWN0IHNvY2thZGRyX2luICopJnMtPmNsaV9hZGRyOwoJCQlicmVhazsKCQl9CiNlbmRpZgoJCXJldCA9IHRjcHY0X2JpbmRfc29ja2V0KGZkLCBmbGFncywgJnMtPnNydi0+c291cmNlX2FkZHIsIHJlbW90ZSk7CgkJaWYgKHJldCkgewoJCQljbG9zZShmZCk7CgkJCWlmIChyZXQgPT0gMSkgewoJCQkJQWxlcnQoIkNhbm5vdCBiaW5kIHRvIHNvdXJjZSBhZGRyZXNzIGJlZm9yZSBjb25uZWN0KCkgZm9yIHNlcnZlciAlcy8lcy4gQWJvcnRpbmcuXG4iLAoJCQkJICAgICAgcy0+YmUtPmlkLCBzLT5zcnYtPmlkKTsKCQkJCXNlbmRfbG9nKHMtPmJlLCBMT0dfRU1FUkcsCgkJCQkJICJDYW5ub3QgYmluZCB0byBzb3VyY2UgYWRkcmVzcyBiZWZvcmUgY29ubmVjdCgpIGZvciBzZXJ2ZXIgJXMvJXMuXG4iLAoJCQkJCSBzLT5iZS0+aWQsIHMtPnNydi0+aWQpOwoJCQl9IGVsc2UgewoJCQkJQWxlcnQoIkNhbm5vdCBiaW5kIHRvIHRwcm94eSBzb3VyY2UgYWRkcmVzcyBiZWZvcmUgY29ubmVjdCgpIGZvciBzZXJ2ZXIgJXMvJXMuIEFib3J0aW5nLlxuIiwKCQkJCSAgICAgIHMtPmJlLT5pZCwgcy0+c3J2LT5pZCk7CgkJCQlzZW5kX2xvZyhzLT5iZSwgTE9HX0VNRVJHLAoJCQkJCSAiQ2Fubm90IGJpbmQgdG8gdHByb3h5IHNvdXJjZSBhZGRyZXNzIGJlZm9yZSBjb25uZWN0KCkgZm9yIHNlcnZlciAlcy8lcy5cbiIsCgkJCQkJIHMtPmJlLT5pZCwgcy0+c3J2LT5pZCk7CgkJCX0KCQkJcmV0dXJuIFNOX0VSUl9SRVNPVVJDRTsKCQl9Cgl9CgllbHNlIGlmIChzLT5iZS0+b3B0aW9ucyAmIFBSX09fQklORF9TUkMpIHsKCQlzdHJ1Y3Qgc29ja2FkZHJfaW4gKnJlbW90ZSA9IE5VTEw7CgkJaW50IHJldCwgZmxhZ3MgPSAwOwoKI2lmIGRlZmluZWQoQ09ORklHX0hBUF9DVFRQUk9YWSkgfHwgZGVmaW5lZChDT05GSUdfSEFQX0xJTlVYX1RQUk9YWSkKCQlzd2l0Y2ggKHMtPmJlLT5vcHRpb25zICYgUFJfT19UUFhZX01BU0spIHsKCQljYXNlIFBSX09fVFBYWV9BRERSOgoJCQlyZW1vdGUgPSAoc3RydWN0IHNvY2thZGRyX2luICopJnMtPmJlLT50cHJveHlfYWRkcjsKCQkJZmxhZ3MgID0gMzsKCQkJYnJlYWs7CgkJY2FzZSBQUl9PX1RQWFlfQ0xJOgoJCQlmbGFncyB8PSAyOwoJCQkvKiBmYWxsIHRocm91Z2ggKi8KCQljYXNlIFBSX09fVFBYWV9DSVA6CgkJCS8qIEZJWE1FOiB3aGF0IGNhbiB3ZSBkbyBpZiB0aGUgY2xpZW50IGNvbm5lY3RzIGluIElQdjYgPyAqLwoJCQlmbGFncyB8PSAxOwoJCQlyZW1vdGUgPSAoc3RydWN0IHNvY2thZGRyX2luICopJnMtPmNsaV9hZGRyOwoJCQlicmVhazsKCQl9CiNlbmRpZgoJCXJldCA9IHRjcHY0X2JpbmRfc29ja2V0KGZkLCBmbGFncywgJnMtPmJlLT5zb3VyY2VfYWRkciwgcmVtb3RlKTsKCQlpZiAocmV0KSB7CgkJCWNsb3NlKGZkKTsKCQkJaWYgKHJldCA9PSAxKSB7CgkJCQlBbGVydCgiQ2Fubm90IGJpbmQgdG8gc291cmNlIGFkZHJlc3MgYmVmb3JlIGNvbm5lY3QoKSBmb3IgcHJveHkgJXMuIEFib3J0aW5nLlxuIiwKCQkJCSAgICAgIHMtPmJlLT5pZCk7CgkJCQlzZW5kX2xvZyhzLT5iZSwgTE9HX0VNRVJHLAoJCQkJCSAiQ2Fubm90IGJpbmQgdG8gc291cmNlIGFkZHJlc3MgYmVmb3JlIGNvbm5lY3QoKSBmb3IgcHJveHkgJXMuXG4iLAoJCQkJCSBzLT5iZS0+aWQpOwoJCQl9IGVsc2UgewoJCQkJQWxlcnQoIkNhbm5vdCBiaW5kIHRvIHRwcm94eSBzb3VyY2UgYWRkcmVzcyBiZWZvcmUgY29ubmVjdCgpIGZvciBwcm94eSAlcy4gQWJvcnRpbmcuXG4iLAoJCQkJICAgICAgcy0+YmUtPmlkKTsKCQkJCXNlbmRfbG9nKHMtPmJlLCBMT0dfRU1FUkcsCgkJCQkJICJDYW5ub3QgYmluZCB0byB0cHJveHkgc291cmNlIGFkZHJlc3MgYmVmb3JlIGNvbm5lY3QoKSBmb3IgcHJveHkgJXMuXG4iLAoJCQkJCSBzLT5iZS0+aWQpOwoJCQl9CgkJCXJldHVybiBTTl9FUlJfUkVTT1VSQ0U7CgkJfQoJfQoKCWlmICgoY29ubmVjdChmZCwgKHN0cnVjdCBzb2NrYWRkciAqKSZzLT5zcnZfYWRkciwgc2l6ZW9mKHMtPnNydl9hZGRyKSkgPT0gLTEpICYmCgkgICAgKGVycm5vICE9IEVJTlBST0dSRVNTKSAmJiAoZXJybm8gIT0gRUFMUkVBRFkpICYmIChlcnJubyAhPSBFSVNDT05OKSkgewoKCQlpZiAoZXJybm8gPT0gRUFHQUlOIHx8IGVycm5vID09IEVBRERSSU5VU0UpIHsKCQkJY2hhciAqbXNnOwoJCQlpZiAoZXJybm8gPT0gRUFHQUlOKSAvKiBubyBmcmVlIHBvcnRzIGxlZnQsIHRyeSBhZ2FpbiBsYXRlciAqLwoJCQkJbXNnID0gIm5vIGZyZWUgcG9ydHMiOwoJCQllbHNlCgkJCQltc2cgPSAibG9jYWwgYWRkcmVzcyBhbHJlYWR5IGluIHVzZSI7CgoJCQlxZnByaW50ZihzdGRlcnIsIkNhbm5vdCBjb25uZWN0OiAlcy5cbiIsbXNnKTsKCQkJY2xvc2UoZmQpOwoJCQlzZW5kX2xvZyhzLT5iZSwgTE9HX0VNRVJHLAoJCQkJICJDb25uZWN0KCkgZmFpbGVkIGZvciBzZXJ2ZXIgJXMvJXM6ICVzLlxuIiwKCQkJCSBzLT5iZS0+aWQsIHMtPnNydi0+aWQsIG1zZyk7CgkJCXJldHVybiBTTl9FUlJfUkVTT1VSQ0U7CgkJfSBlbHNlIGlmIChlcnJubyA9PSBFVElNRURPVVQpIHsKCQkJLy9xZnByaW50ZihzdGRlcnIsIkNvbm5lY3QoKTogRVRJTUVET1VUIik7CgkJCWNsb3NlKGZkKTsKCQkJcmV0dXJuIFNOX0VSUl9TUlZUTzsKCQl9IGVsc2UgewoJCQkvLyAoZXJybm8gPT0gRUNPTk5SRUZVU0VEIHx8IGVycm5vID09IEVORVRVTlJFQUNIIHx8IGVycm5vID09IEVBQ0NFUyB8fCBlcnJubyA9PSBFUEVSTSkKCQkJLy9xZnByaW50ZihzdGRlcnIsIkNvbm5lY3QoKTogJWQiLCBlcnJubyk7CgkJCWNsb3NlKGZkKTsKCQkJcmV0dXJuIFNOX0VSUl9TUlZDTDsKCQl9Cgl9CgoJZmR0YWJbZmRdLm93bmVyID0gcy0+dGFzazsKCWZkdGFiW2ZkXS5zdGF0ZSA9IEZEX1NUQ09OTjsgLyogY29ubmVjdGlvbiBpbiBwcm9ncmVzcyAqLwoJZmR0YWJbZmRdLmNiW0RJUl9SRF0uZiA9ICZzdHJlYW1fc29ja19yZWFkOwoJZmR0YWJbZmRdLmNiW0RJUl9SRF0uYiA9IHMtPnJlcDsKCWZkdGFiW2ZkXS5jYltESVJfV1JdLmYgPSAmc3RyZWFtX3NvY2tfd3JpdGU7CglmZHRhYltmZF0uY2JbRElSX1dSXS5iID0gcy0+cmVxOwoKCWZkdGFiW2ZkXS5wZWVyYWRkciA9IChzdHJ1Y3Qgc29ja2FkZHIgKikmcy0+c3J2X2FkZHI7CglmZHRhYltmZF0ucGVlcmxlbiA9IHNpemVvZihzLT5zcnZfYWRkcik7CgoJRVZfRkRfU0VUKGZkLCBESVJfV1IpOyAgLyogZm9yIGNvbm5lY3Qgc3RhdHVzICovCiAgICAKCWZkX2luc2VydChmZCk7CglpZiAocy0+c3J2KSB7CgkJcy0+c3J2LT5jdXJfc2VzcysrOwoJCWlmIChzLT5zcnYtPmN1cl9zZXNzID4gcy0+c3J2LT5jdXJfc2Vzc19tYXgpCgkJCXMtPnNydi0+Y3VyX3Nlc3NfbWF4ID0gcy0+c3J2LT5jdXJfc2VzczsKCQlpZiAocy0+YmUtPmxicHJtLnNlcnZlcl90YWtlX2Nvbm4pCgkJCXMtPmJlLT5sYnBybS5zZXJ2ZXJfdGFrZV9jb25uKHMtPnNydik7Cgl9CgoJaWYgKCF0dl9hZGRfaWZzZXQoJnMtPnJlcS0+Y2V4LCAmbm93LCAmcy0+YmUtPnRpbWVvdXQuY29ubmVjdCkpCgkJdHZfZXRlcm5pdHkoJnMtPnJlcS0+Y2V4KTsKCXJldHVybiBTTl9FUlJfTk9ORTsgIC8qIGNvbm5lY3Rpb24gaXMgT0sgKi8KfQoKCi8qCiAqIFRoaXMgZnVuY3Rpb24gY2hlY2tzIHRoZSByZXRyeSBjb3VudCBkdXJpbmcgdGhlIGNvbm5lY3QoKSBqb2IuCiAqIEl0IHVwZGF0ZXMgdGhlIHNlc3Npb24ncyBzcnZfc3RhdGUgYW5kIHJldHJpZXMsIHNvIHRoYXQgdGhlIGNhbGxlciBrbm93cwogKiB3aGF0IGl0IGhhcyB0byBkby4gSXQgdXNlcyB0aGUgbGFzdCBjb25uZWN0aW9uIGVycm9yIHRvIHNldCB0aGUgbG9nIHdoZW4KICogaXQgZXhwaXJlcy4gSXQgcmV0dXJucyAxIHdoZW4gaXQgaGFzIGV4cGlyZWQsIGFuZCAwIG90aGVyd2lzZS4KICovCmludCBzcnZfY291bnRfcmV0cnlfZG93bihzdHJ1Y3Qgc2Vzc2lvbiAqdCwgaW50IGNvbm5fZXJyKQp7CgkvKiB3ZSBhcmUgaW4gZnJvbnQgb2YgYSByZXRyeWFibGUgZXJyb3IgKi8KCXQtPmNvbm5fcmV0cmllcy0tOwoKCWlmICh0LT5jb25uX3JldHJpZXMgPCAwKSB7CgkJLyogaWYgbm90IHJldHJ5YWJsZSBhbnltb3JlLCBsZXQncyBhYm9ydCAqLwoJCXR2X2V0ZXJuaXR5KCZ0LT5yZXEtPmNleCk7CgkJc3J2X2Nsb3NlX3dpdGhfZXJyKHQsIGNvbm5fZXJyLCBTTl9GSU5TVF9DLAoJCQkJICAgNTAzLCBlcnJvcl9tZXNzYWdlKHQsIEhUVFBfRVJSXzUwMykpOwoJCWlmICh0LT5zcnYpCgkJCXQtPnNydi0+ZmFpbGVkX2Nvbm5zKys7CgkJdC0+YmUtPmZhaWxlZF9jb25ucysrOwoKCQkvKiBXZSB1c2VkIHRvIGhhdmUgYSBmcmVlIGNvbm5lY3Rpb24gc2xvdC4gU2luY2Ugd2UnbGwgbmV2ZXIgdXNlIGl0LAoJCSAqIHdlIGhhdmUgdG8gaW5mb3JtIHRoZSBzZXJ2ZXIgdGhhdCBpdCBtYXkgYmUgdXNlZCBieSBhbm90aGVyIHNlc3Npb24uCgkJICovCgkJaWYgKG1heV9kZXF1ZXVlX3Rhc2tzKHQtPnNydiwgdC0+YmUpKQoJCQlwcm9jZXNzX3Nydl9xdWV1ZSh0LT5zcnYpOwoJCXJldHVybiAxOwoJfQoJcmV0dXJuIDA7Cn0KCiAgICAKLyoKICogVGhpcyBmdW5jdGlvbiBwZXJmb3JtcyB0aGUgcmV0cnlhYmxlIHBhcnQgb2YgdGhlIGNvbm5lY3QoKSBqb2IuCiAqIEl0IHVwZGF0ZXMgdGhlIHNlc3Npb24ncyBzcnZfc3RhdGUgYW5kIHJldHJpZXMsIHNvIHRoYXQgdGhlIGNhbGxlciBrbm93cwogKiB3aGF0IGl0IGhhcyB0byBkby4gSXQgcmV0dXJucyAxIHdoZW4gaXQgYnJlYWtzIG91dCBvZiB0aGUgbG9vcCwgb3IgMCBpZgogKiBpdCBuZWVkcyB0byByZWRpc3BhdGNoLgogKi8KaW50IHNydl9yZXRyeWFibGVfY29ubmVjdChzdHJ1Y3Qgc2Vzc2lvbiAqdCkKewoJaW50IGNvbm5fZXJyOwoKCS8qIFRoaXMgbG9vcCBlbnN1cmVzIHRoYXQgd2Ugc3RvcCBiZWZvcmUgdGhlIGxhc3QgcmV0cnkgaW4gY2FzZSBvZiBhCgkgKiByZWRpc3BhdGNoYWJsZSBzZXJ2ZXIuCgkgKi8KCWRvIHsKCQkvKiBpbml0aWF0ZSBhIGNvbm5lY3Rpb24gdG8gdGhlIHNlcnZlciAqLwoJCWNvbm5fZXJyID0gY29ubmVjdF9zZXJ2ZXIodCk7CgkJc3dpdGNoIChjb25uX2VycikgewoJCgkJY2FzZSBTTl9FUlJfTk9ORToKCQkJLy9mcHJpbnRmKHN0ZGVyciwiMDogYz0lZCwgcz0lZFxuIiwgYywgcyk7CgkJCXQtPnNydl9zdGF0ZSA9IFNWX1NUQ09OTjsKCQkJaWYgKHQtPnNydikKCQkJCXQtPnNydi0+Y3VtX3Nlc3MrKzsKCQkJcmV0dXJuIDE7CgkgICAgCgkJY2FzZSBTTl9FUlJfSU5URVJOQUw6CgkJCXR2X2V0ZXJuaXR5KCZ0LT5yZXEtPmNleCk7CgkJCXNydl9jbG9zZV93aXRoX2Vycih0LCBTTl9FUlJfSU5URVJOQUwsIFNOX0ZJTlNUX0MsCgkJCQkJICAgNTAwLCBlcnJvcl9tZXNzYWdlKHQsIEhUVFBfRVJSXzUwMCkpOwoJCQlpZiAodC0+c3J2KQoJCQkJdC0+c3J2LT5jdW1fc2VzcysrOwoJCQlpZiAodC0+c3J2KQoJCQkJdC0+c3J2LT5mYWlsZWRfY29ubnMrKzsKCQkJdC0+YmUtPmZhaWxlZF9jb25ucysrOwoJCQkvKiByZWxlYXNlIG90aGVyIHNlc3Npb25zIHdhaXRpbmcgZm9yIHRoaXMgc2VydmVyICovCgkJCWlmIChtYXlfZGVxdWV1ZV90YXNrcyh0LT5zcnYsIHQtPmJlKSkKCQkJCXByb2Nlc3Nfc3J2X3F1ZXVlKHQtPnNydik7CgkJCXJldHVybiAxOwoJCX0KCQkvKiBlbnN1cmUgdGhhdCB3ZSBoYXZlIGVub3VnaCByZXRyaWVzIGxlZnQgKi8KCQlpZiAoc3J2X2NvdW50X3JldHJ5X2Rvd24odCwgY29ubl9lcnIpKSB7CgkJCXJldHVybiAxOwoJCX0KCX0gd2hpbGUgKHQtPnNydiA9PSBOVUxMIHx8IHQtPmNvbm5fcmV0cmllcyA+IDAgfHwgISh0LT5iZS0+b3B0aW9ucyAmIFBSX09fUkVESVNQKSk7CgoJLyogV2UncmUgb24gb3VyIGxhc3QgY2hhbmNlLCBhbmQgdGhlIFJFRElTUCBvcHRpb24gd2FzIHNwZWNpZmllZC4KCSAqIFdlIHdpbGwgaWdub3JlIGNvb2tpZSBhbmQgZm9yY2UgdG8gYmFsYW5jZSBvciB1c2UgdGhlIGRpc3BhdGNoZXIuCgkgKi8KCS8qIGxldCdzIHRyeSB0byBvZmZlciB0aGlzIHNsb3QgdG8gYW55Ym9keSAqLwoJaWYgKG1heV9kZXF1ZXVlX3Rhc2tzKHQtPnNydiwgdC0+YmUpKQoJCXByb2Nlc3Nfc3J2X3F1ZXVlKHQtPnNydik7CgoJaWYgKHQtPnNydikKCQl0LT5zcnYtPmN1bV9zZXNzKys7CQkvL0ZJWE1FPwoKCS8qIGl0J3MgbGVmdCB0byB0aGUgZGlzcGF0Y2hlciB0byBjaG9vc2UgYSBzZXJ2ZXIgKi8KCXQtPmZsYWdzICY9IH4oU05fRElSRUNUIHwgU05fQVNTSUdORUQgfCBTTl9BRERSX1NFVCk7Cgl0LT5wcmV2X3NydiA9IHQtPnNydjsKCXJldHVybiAwOwp9CgogICAgCi8qIFRoaXMgZnVuY3Rpb24gcGVyZm9ybXMgdGhlICJyZWRpc3BhdGNoIiBwYXJ0IG9mIGEgY29ubmVjdGlvbiBhdHRlbXB0LiBJdAogKiB3aWxsIGFzc2lnbiBhIHNlcnZlciBpZiByZXF1aXJlZCwgcXVldWUgdGhlIGNvbm5lY3Rpb24gaWYgcmVxdWlyZWQsIGFuZAogKiBoYW5kbGUgZXJyb3JzIHRoYXQgbWlnaHQgYXJpc2UgYXQgdGhpcyBsZXZlbC4gSXQgY2FuIGNoYW5nZSB0aGUgc2VydmVyCiAqIHN0YXRlLiBJdCB3aWxsIHJldHVybiAxIGlmIGl0IGVuY291bnRlcnMgYW4gZXJyb3IsIHN3aXRjaGVzIHRoZSBzZXJ2ZXIKICogc3RhdGUsIG9yIGhhcyB0byBxdWV1ZSBhIGNvbm5lY3Rpb24uIE90aGVyd2lzZSwgaXQgd2lsbCByZXR1cm4gMCBpbmRpY2F0aW5nCiAqIHRoYXQgdGhlIGNvbm5lY3Rpb24gaXMgcmVhZHkgdG8gdXNlLgogKi8KCmludCBzcnZfcmVkaXNwYXRjaF9jb25uZWN0KHN0cnVjdCBzZXNzaW9uICp0KQp7CglpbnQgY29ubl9lcnI7CgoJLyogV2Uga25vdyB0aGF0IHdlIGRvbid0IGhhdmUgYW55IGNvbm5lY3Rpb24gcGVuZGluZywgc28gd2Ugd2lsbAoJICogdHJ5IHRvIGdldCBhIG5ldyBvbmUsIGFuZCB3YWl0IGluIHRoaXMgc3RhdGUgaWYgaXQncyBxdWV1ZWQKCSAqLwogcmVkaXNwYXRjaDoKCWNvbm5fZXJyID0gYXNzaWduX3NlcnZlcl9hbmRfcXVldWUodCk7Cglzd2l0Y2ggKGNvbm5fZXJyKSB7CgljYXNlIFNSVl9TVEFUVVNfT0s6CgkJYnJlYWs7CgoJY2FzZSBTUlZfU1RBVFVTX0ZVTEw6CgkJLyogVGhlIHNlcnZlciBoYXMgcmVhY2hlZCBpdHMgbWF4cXVldWUgbGltaXQuIEVpdGhlciBQUl9PX1JFRElTUCBpcyBzZXQKCQkgKiBhbmQgd2UgY2FuIHJlZGlzcGF0Y2ggdG8gYW5vdGhlciBzZXJ2ZXIsIG9yIGl0IGlzIG5vdCBhbmQgd2UgcmV0dXJuCgkJICogNTAzLiBUaGlzIG9ubHkgbWFrZXMgc2Vuc2UgaW4gRElSRUNUIG1vZGUgaG93ZXZlciwgYmVjYXVzZSBub3JtYWwgTEIKCQkgKiBhbGdvcml0aG1zIHdvdWxkIG5ldmVyIHNlbGVjdCBzdWNoIGEgc2VydmVyLCBhbmQgaGFzaCBhbGdvcml0aG1zCgkJICogd291bGQgYnJpbmcgdXMgb24gdGhlIHNhbWUgc2VydmVyIGFnYWluLiBOb3RlIHRoYXQgdC0+c3J2IGlzIHNldCBpbgoJCSAqIHRoaXMgY2FzZS4KCQkgKi8KCQlpZiAoKHQtPmZsYWdzICYgU05fRElSRUNUKSAmJiAodC0+YmUtPm9wdGlvbnMgJiBQUl9PX1JFRElTUCkpIHsKCQkJdC0+ZmxhZ3MgJj0gfihTTl9ESVJFQ1QgfCBTTl9BU1NJR05FRCB8IFNOX0FERFJfU0VUKTsKCQkJdC0+cHJldl9zcnYgPSB0LT5zcnY7CgkJCWdvdG8gcmVkaXNwYXRjaDsKCQl9CgoJCXR2X2V0ZXJuaXR5KCZ0LT5yZXEtPmNleCk7CgkJc3J2X2Nsb3NlX3dpdGhfZXJyKHQsIFNOX0VSUl9TUlZUTywgU05fRklOU1RfUSwKCQkJCSAgIDUwMywgZXJyb3JfbWVzc2FnZSh0LCBIVFRQX0VSUl81MDMpKTsKCgkJdC0+c3J2LT5mYWlsZWRfY29ubnMrKzsKCQl0LT5iZS0+ZmFpbGVkX2Nvbm5zKys7CgkJcmV0dXJuIDE7CgoJY2FzZSBTUlZfU1RBVFVTX05PU1JWOgoJCS8qIG5vdGU6IGl0IGlzIGd1YXJhbnRlZWQgdGhhdCB0LT5zcnYgPT0gTlVMTCBoZXJlICovCgkJdHZfZXRlcm5pdHkoJnQtPnJlcS0+Y2V4KTsKCQlzcnZfY2xvc2Vfd2l0aF9lcnIodCwgU05fRVJSX1NSVlRPLCBTTl9GSU5TVF9DLAoJCQkJICAgNTAzLCBlcnJvcl9tZXNzYWdlKHQsIEhUVFBfRVJSXzUwMykpOwoKCQl0LT5iZS0+ZmFpbGVkX2Nvbm5zKys7CgkJcmV0dXJuIDE7CgoJY2FzZSBTUlZfU1RBVFVTX1FVRVVFRDoKCQlpZiAoIXR2X2FkZF9pZnNldCgmdC0+cmVxLT5jZXgsICZub3csICZ0LT5iZS0+dGltZW91dC5xdWV1ZSkpCgkJCXR2X2V0ZXJuaXR5KCZ0LT5yZXEtPmNleCk7CgkJdC0+c3J2X3N0YXRlID0gU1ZfU1RJRExFOwoJCS8qIGRvIG5vdGhpbmcgZWxzZSBhbmQgZG8gbm90IHdha2UgYW55IG90aGVyIHNlc3Npb24gdXAgKi8KCQlyZXR1cm4gMTsKCgljYXNlIFNSVl9TVEFUVVNfSU5URVJOQUw6CglkZWZhdWx0OgoJCXR2X2V0ZXJuaXR5KCZ0LT5yZXEtPmNleCk7CgkJc3J2X2Nsb3NlX3dpdGhfZXJyKHQsIFNOX0VSUl9JTlRFUk5BTCwgU05fRklOU1RfQywKCQkJCSAgIDUwMCwgZXJyb3JfbWVzc2FnZSh0LCBIVFRQX0VSUl81MDApKTsKCQlpZiAodC0+c3J2KQoJCQl0LT5zcnYtPmN1bV9zZXNzKys7CgkJaWYgKHQtPnNydikKCQkJdC0+c3J2LT5mYWlsZWRfY29ubnMrKzsKCQl0LT5iZS0+ZmFpbGVkX2Nvbm5zKys7CgoJCS8qIHJlbGVhc2Ugb3RoZXIgc2Vzc2lvbnMgd2FpdGluZyBmb3IgdGhpcyBzZXJ2ZXIgKi8KCQlpZiAobWF5X2RlcXVldWVfdGFza3ModC0+c3J2LCB0LT5iZSkpCgkJCXByb2Nlc3Nfc3J2X3F1ZXVlKHQtPnNydik7CgkJcmV0dXJuIDE7Cgl9CgkvKiBpZiB3ZSBnZXQgaGVyZSwgaXQncyBiZWNhdXNlIHdlIGdvdCBTUlZfU1RBVFVTX09LLCB3aGljaCBhbHNvCgkgKiBtZWFucyB0aGF0IHRoZSBjb25uZWN0aW9uIGhhcyBub3QgYmVlbiBxdWV1ZWQuCgkgKi8KCXJldHVybiAwOwp9CgppbnQgYmVfZG93bnRpbWUoc3RydWN0IHByb3h5ICpweCkgewoJaWYgKHB4LT5sYnBybS50b3Rfd2VpZ2h0ICYmIHB4LT5sYXN0X2NoYW5nZSA8IG5vdy50dl9zZWMpICAvLyBpZ25vcmUgbmVnYXRpdmUgdGltZQoJCXJldHVybiBweC0+ZG93bl90aW1lOwoKCXJldHVybiBub3cudHZfc2VjIC0gcHgtPmxhc3RfY2hhbmdlICsgcHgtPmRvd25fdGltZTsKfQoKLyogVGhpcyBmdW5jdGlvbiBwYXJzZXMgYSAiYmFsYW5jZSIgc3RhdGVtZW50IGluIGEgYmFja2VuZCBzZWN0aW9uIGRlc2NyaWJpbmcKICogPGN1cnByb3h5Pi4gSXQgcmV0dXJucyAtMSBpZiB0aGVyZSBpcyBhbnkgZXJyb3IsIG90aGVyd2lzZSB6ZXJvLiBJZiBpdAogKiByZXR1cm5zIC0xLCBpdCBtYXkgd3JpdGUgYW4gZXJyb3IgbWVzc2FnZSBpbnRvIHRoZXIgPGVycj4gYnVmZmVyLCBmb3IgYXQKICogbW9zdCA8ZXJybGVuPiBieXRlcywgdHJhaWxpbmcgemVybyBpbmNsdWRlZC4gVGhlIHRyYWlsaW5nICdcbicgd2lsbCBub3QgYmUKICogd3JpdHRlbi4gVGhlIGZ1bmN0aW9uIG11c3QgYmUgY2FsbGVkIHdpdGggPGFyZ3M+IHBvaW50aW5nIHRvIHRoZSBmaXJzdCB3b3JkCiAqIGFmdGVyICJiYWxhbmNlIi4KICovCmludCBiYWNrZW5kX3BhcnNlX2JhbGFuY2UoY29uc3QgY2hhciAqKmFyZ3MsIGNoYXIgKmVyciwgaW50IGVycmxlbiwgc3RydWN0IHByb3h5ICpjdXJwcm94eSkKewoJaWYgKCEqKGFyZ3NbMF0pKSB7CgkJLyogaWYgbm8gb3B0aW9uIGlzIHNldCwgdXNlIHJvdW5kLXJvYmluIGJ5IGRlZmF1bHQgKi8KCQljdXJwcm94eS0+bGJwcm0uYWxnbyAmPSB+QkVfTEJfQUxHTzsKCQljdXJwcm94eS0+bGJwcm0uYWxnbyB8PSBCRV9MQl9BTEdPX1JSOwoJCXJldHVybiAwOwoJfQoKCWlmICghc3RyY21wKGFyZ3NbMF0sICJyb3VuZHJvYmluIikpIHsKCQljdXJwcm94eS0+bGJwcm0uYWxnbyAmPSB+QkVfTEJfQUxHTzsKCQljdXJwcm94eS0+bGJwcm0uYWxnbyB8PSBCRV9MQl9BTEdPX1JSOwoJfQoJZWxzZSBpZiAoIXN0cmNtcChhcmdzWzBdLCAibGVhc3Rjb25uIikpIHsKCQljdXJwcm94eS0+bGJwcm0uYWxnbyAmPSB+QkVfTEJfQUxHTzsKCQljdXJwcm94eS0+bGJwcm0uYWxnbyB8PSBCRV9MQl9BTEdPX0xDOwoJfQoJZWxzZSBpZiAoIXN0cmNtcChhcmdzWzBdLCAic291cmNlIikpIHsKCQljdXJwcm94eS0+bGJwcm0uYWxnbyAmPSB+QkVfTEJfQUxHTzsKCQljdXJwcm94eS0+bGJwcm0uYWxnbyB8PSBCRV9MQl9BTEdPX1NIOwoJfQoJZWxzZSBpZiAoIXN0cmNtcChhcmdzWzBdLCAidXJpIikpIHsKCQlpbnQgYXJnID0gMTsKCgkJY3VycHJveHktPmxicHJtLmFsZ28gJj0gfkJFX0xCX0FMR087CgkJY3VycHJveHktPmxicHJtLmFsZ28gfD0gQkVfTEJfQUxHT19VSDsKCgkJd2hpbGUgKCphcmdzW2FyZ10pIHsKCQkJaWYgKCFzdHJjbXAoYXJnc1thcmddLCAibGVuIikpIHsKCQkJCWlmICghKmFyZ3NbYXJnKzFdIHx8IChhdG9pKGFyZ3NbYXJnKzFdKSA8PSAwKSkgewoJCQkJCXNucHJpbnRmKGVyciwgZXJybGVuLCAiJ2JhbGFuY2UgdXJpIGxlbicgZXhwZWN0cyBhIHBvc2l0aXZlIGludGVnZXIgKGdvdCAnJXMnKS4iLCBhcmdzW2FyZysxXSk7CgkJCQkJcmV0dXJuIC0xOwoJCQkJfQoJCQkJY3VycHJveHktPnVyaV9sZW5fbGltaXQgPSBhdG9pKGFyZ3NbYXJnKzFdKTsKCQkJCWFyZyArPSAyOwoJCQl9CgkJCWVsc2UgaWYgKCFzdHJjbXAoYXJnc1thcmddLCAiZGVwdGgiKSkgewoJCQkJaWYgKCEqYXJnc1thcmcrMV0gfHwgKGF0b2koYXJnc1thcmcrMV0pIDw9IDApKSB7CgkJCQkJc25wcmludGYoZXJyLCBlcnJsZW4sICInYmFsYW5jZSB1cmkgZGVwdGgnIGV4cGVjdHMgYSBwb3NpdGl2ZSBpbnRlZ2VyIChnb3QgJyVzJykuIiwgYXJnc1thcmcrMV0pOwoJCQkJCXJldHVybiAtMTsKCQkJCX0KCQkJCS8qIGhpbnQ6IHdlIHN0b3JlIHRoZSBwb3NpdGlvbiBvZiB0aGUgZW5kaW5nICcvJyAoZGVwdGgrMSkgc28KCQkJCSAqIHRoYXQgd2UgYXZvaWQgYSBjb21wYXJpc29uIHdoaWxlIGNvbXB1dGluZyB0aGUgaGFzaC4KCQkJCSAqLwoJCQkJY3VycHJveHktPnVyaV9kaXJzX2RlcHRoMSA9IGF0b2koYXJnc1thcmcrMV0pICsgMTsKCQkJCWFyZyArPSAyOwoJCQl9CgkJCWVsc2UgewoJCQkJc25wcmludGYoZXJyLCBlcnJsZW4sICInYmFsYW5jZSB1cmknIG9ubHkgYWNjZXB0cyBwYXJhbWV0ZXJzICdsZW4nIGFuZCAnZGVwdGgnIChnb3QgJyVzJykuIiwgYXJnc1thcmddKTsKCQkJCXJldHVybiAtMTsKCQkJfQoJCX0KCX0KCWVsc2UgaWYgKCFzdHJjbXAoYXJnc1swXSwgInVybF9wYXJhbSIpKSB7CgkJaWYgKCEqYXJnc1sxXSkgewoJCQlzbnByaW50ZihlcnIsIGVycmxlbiwgIidiYWxhbmNlIHVybF9wYXJhbScgcmVxdWlyZXMgYW4gVVJMIHBhcmFtZXRlciBuYW1lLiIpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCWN1cnByb3h5LT5sYnBybS5hbGdvICY9IH5CRV9MQl9BTEdPOwoJCWN1cnByb3h5LT5sYnBybS5hbGdvIHw9IEJFX0xCX0FMR09fUEg7CgkJaWYgKGN1cnByb3h5LT51cmxfcGFyYW1fbmFtZSkKCQkJZnJlZShjdXJwcm94eS0+dXJsX3BhcmFtX25hbWUpOwoJCWN1cnByb3h5LT51cmxfcGFyYW1fbmFtZSA9IHN0cmR1cChhcmdzWzFdKTsKCQljdXJwcm94eS0+dXJsX3BhcmFtX2xlbiA9IHN0cmxlbihhcmdzWzFdKTsKCQlpZiAoKmFyZ3NbMl0pIHsKCQkJaWYgKHN0cmNtcChhcmdzWzJdLCAiY2hlY2tfcG9zdCIpKSB7CgkJCQlzbnByaW50ZihlcnIsIGVycmxlbiwgIidiYWxhbmNlIHVybF9wYXJhbScgb25seSBhY2NlcHRzIGNoZWNrX3Bvc3QgbW9kaWZpZXIuIik7CgkJCQlyZXR1cm4gLTE7CgkJCX0KCQkJaWYgKCphcmdzWzNdKSB7CgkJCQkvKiBUT0RPOiBtYXliZSBpc3N1ZSBhIHdhcm5pbmcgaWYgdGhlcmUgaXMgbm8gdmFsdWUsIG5vIGRpZ2l0cyBvciB0b28gbG9uZyAqLwoJCQkJY3VycHJveHktPnVybF9wYXJhbV9wb3N0X2xpbWl0ID0gc3RyMnVpKGFyZ3NbM10pOwoJCQl9CgkJCS8qIGlmIG5vIGxpbWl0LCBvciBmYXVsIHZhbHVlIGluIGFyZ3NbM10sIHRoZW4gZGVmYXVsdCB0byBhIG1vZGVyYXRlIHdvcmRsZW4gKi8KCQkJaWYgKCFjdXJwcm94eS0+dXJsX3BhcmFtX3Bvc3RfbGltaXQpCgkJCQljdXJwcm94eS0+dXJsX3BhcmFtX3Bvc3RfbGltaXQgPSA0ODsKCQkJZWxzZSBpZiAoIGN1cnByb3h5LT51cmxfcGFyYW1fcG9zdF9saW1pdCA8IDMgKQoJCQkJY3VycHJveHktPnVybF9wYXJhbV9wb3N0X2xpbWl0ID0gMzsgLyogbWluaW11bSBleGFtcGxlOiBTPTMgb3IgXHJcblM9NiYgKi8KCQl9Cgl9CgllbHNlIHsKCQlzbnByaW50ZihlcnIsIGVycmxlbiwgIidiYWxhbmNlJyBvbmx5IHN1cHBvcnRzICdyb3VuZHJvYmluJywgJ2xlYXN0Y29ubicsICdzb3VyY2UnLCAndXJpJyBhbmQgJ3VybF9wYXJhbScgb3B0aW9ucy4iKTsKCQlyZXR1cm4gLTE7Cgl9CglyZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgIEFsbCBzdXBwb3J0ZWQga2V5d29yZHMgbXVzdCBiZSBkZWNsYXJlZCBoZXJlLiAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBzZXQgdGVzdC0+aSB0byB0aGUgbnVtYmVyIG9mIGVuYWJsZWQgc2VydmVycyBvbiB0aGUgcHJveHkgKi8Kc3RhdGljIGludAphY2xfZmV0Y2hfbmJzcnYoc3RydWN0IHByb3h5ICpweCwgc3RydWN0IHNlc3Npb24gKmw0LCB2b2lkICpsNywgaW50IGRpciwKICAgICAgICAgICAgICAgIHN0cnVjdCBhY2xfZXhwciAqZXhwciwgc3RydWN0IGFjbF90ZXN0ICp0ZXN0KQp7Cgl0ZXN0LT5mbGFncyA9IEFDTF9URVNUX0ZfVk9MX1RFU1Q7CglpZiAoZXhwci0+YXJnX2xlbikgewoJCS8qIGFub3RoZXIgcHJveHkgd2FzIGRlc2lnbmF0ZWQsIHdlIG11c3QgbG9vayBmb3IgaXQgKi8KCQlmb3IgKHB4ID0gcHJveHk7IHB4OyBweCA9IHB4LT5uZXh0KQoJCQlpZiAoKHB4LT5jYXAgJiBQUl9DQVBfQkUpICYmICFzdHJjbXAocHgtPmlkLCBleHByLT5hcmcuc3RyKSkKCQkJCWJyZWFrOwoJfQoJaWYgKCFweCkKCQlyZXR1cm4gMDsKCglpZiAocHgtPnNydl9hY3QpCgkJdGVzdC0+aSA9IHB4LT5zcnZfYWN0OwoJZWxzZSBpZiAocHgtPmxicHJtLmZiY2spCgkJdGVzdC0+aSA9IDE7CgllbHNlCgkJdGVzdC0+aSA9IHB4LT5zcnZfYmNrOwoKCXJldHVybiAxOwp9CgoKLyogTm90ZTogbXVzdCBub3QgYmUgZGVjbGFyZWQgPGNvbnN0PiBhcyBpdHMgbGlzdCB3aWxsIGJlIG92ZXJ3cml0dGVuICovCnN0YXRpYyBzdHJ1Y3QgYWNsX2t3X2xpc3QgYWNsX2t3cyA9IHt7IH0sewoJeyAibmJzcnYiLCAgIGFjbF9wYXJzZV9pbnQsICAgYWNsX2ZldGNoX25ic3J2LCAgICBhY2xfbWF0Y2hfaW50IH0sCgl7IE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwgfSwKfX07CgoKX19hdHRyaWJ1dGVfXygoY29uc3RydWN0b3IpKQpzdGF0aWMgdm9pZCBfX2JhY2tlbmRfaW5pdCh2b2lkKQp7CglhY2xfcmVnaXN0ZXJfa2V5d29yZHMoJmFjbF9rd3MpOwp9CgoKLyoKICogTG9jYWwgdmFyaWFibGVzOgogKiAgYy1pbmRlbnQtbGV2ZWw6IDgKICogIGMtYmFzaWMtb2Zmc2V0OiA4CiAqIEVuZDoKICovCg==