LyoKICogQmFja2VuZCB2YXJpYWJsZXMgYW5kIGZ1bmN0aW9ucy4KICoKICogQ29weXJpZ2h0IDIwMDAtMjAwOCBXaWxseSBUYXJyZWF1IDx3QDF3dC5ldT4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24KICogMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICovCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzeXNsb2cuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCiNpbmNsdWRlIDxjb21tb24vY29tcGF0Lmg+CiNpbmNsdWRlIDxjb21tb24vY29uZmlnLmg+CiNpbmNsdWRlIDxjb21tb24vZGVidWcuaD4KI2luY2x1ZGUgPGNvbW1vbi9lYjMydHJlZS5oPgojaW5jbHVkZSA8Y29tbW9uL3RpY2tzLmg+CiNpbmNsdWRlIDxjb21tb24vdGltZS5oPgoKI2luY2x1ZGUgPHR5cGVzL2dsb2JhbC5oPgoKI2luY2x1ZGUgPHByb3RvL2FjbC5oPgojaW5jbHVkZSA8cHJvdG8vYmFja2VuZC5oPgojaW5jbHVkZSA8cHJvdG8vY2xpZW50Lmg+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+bCAtIGJvZHk7CiAgICAgICAgcGFyYW1zID0gcmVxLT5kYXRhICsgYm9keTsKCglpZiAoIGxlbiA9PSAwICkKCQlyZXR1cm4gTlVMTDsKCglpZiAocHgtPmxicHJtLm1hcC5zdGF0ZSAmIFBSX01BUF9SRUNBTEMpCgkJcmVjYWxjX3NlcnZlcl9tYXAocHgpOwoKCWN0eC5pZHggPSAwOwoKCS8qIGlmIHRoZSBtZXNzYWdlIGlzIGNodW5rZWQsIHdlIHNraXAgdGhlIGNodW5rIHNpemUsIGJ1dCB1c2UgdGhlIHZhbHVlIGFzIGxlbiAqLwoJaHR0cF9maW5kX2hlYWRlcjIoIlRyYW5zZmVyLUVuY29kaW5nIiwgMTcsIG1zZy0+c29sLCAmdHhuLT5oZHJfaWR4LCAmY3R4KTsKCWlmIChjdHguaWR4ICYmIGN0eC52bGVuID49IDcgJiYgc3RybmNhc2VjbXAoY3R4LmxpbmUrY3R4LnZhbCwgImNodW5rZWQiLCA3KSA9PSAwKSB7CgkJdW5zaWduZWQgaW50IGNodW5rID0gMDsKCQl3aGlsZSAoIHBhcmFtcyA8IChyZXEtPmRhdGErcmVxLT5tYXhfbGVuKSAmJiAhSFRUUF9JU19DUkxGKCpwYXJhbXMpKSB7CgkJCWNoYXIgYyA9ICpwYXJhbXM7CgkJCWlmIChpc2hleChjKSkgewoJCQkJdW5zaWduZWQgaW50IGhleCA9IHRvdXBwZXIoYykgLSAnMCc7CgkJCQlpZiAoIGhleCA+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+ZGlzcGF0Y2hfYWRkci5zaW5fYWRkciAmJgoJCSAhKHMtPmJlLT5vcHRpb25zICYgUFJfT19UUkFOU1ApKSB7CgkJZXJyID0gU1JWX1NUQVRVU19OT1NSVjsKCQlnb3RvIG91dDsKCX0KCglzLT5mbGFncyB8PSBTTl9BU1NJR05FRDsKCWVyciA9IFNSVl9TVEFUVVNfT0s7CiBvdXQ6CgoJLyogRWl0aGVyIHdlIHRha2UgYmFjayBvdXIgY29ubmVjdGlvbiBzbG90LCBvciB3ZSBvZmZlciBpdCB0byBzb21lb25lCgkgKiBlbHNlIGlmIHdlIGRvbid0IG5lZWQgaXQgYW55bW9yZS4KCSAqLwoJaWYgKGNvbm5fc2xvdCkgewoJCWlmIChjb25uX3Nsb3QgPT0gcy0+c3J2KSB7CgkJCXNlc3NfY2hhbmdlX3NlcnZlcihzLCBzLT5zcnYpOwoJCX0gZWxzZSB7CgkJCWlmIChtYXlfZGVxdWV1ZV90YXNrcyhjb25uX3Nsb3QsIHMtPmJlKSkKCQkJCXByb2Nlc3Nfc3J2X3F1ZXVlKGNvbm5fc2xvdCk7CgkJfQoJfQoKIG91dF9lcnI6CglyZXR1cm4gZXJyOwp9CgoKLyoKICogVGhpcyBmdW5jdGlvbiBhc3NpZ25zIGEgc2VydmVyIGFkZHJlc3MgdG8gYSBzZXNzaW9uLCBhbmQgc2V0cyBTTl9BRERSX1NFVC4KICogVGhlIGFkZHJlc3MgaXMgdGFrZW4gZnJvbSB0aGUgY3VycmVudGx5IGFzc2lnbmVkIHNlcnZlciwgb3IgZnJvbSB0aGUKICogZGlzcGF0Y2ggb3IgdHJhbnNwYXJlbnQgYWRkcmVzcy4KICoKICogSXQgbWF5IHJldHVybiA6CiAqICAgU1JWX1NUQVRVU19PSyAgICAgICBpZiBldmVyeXRoaW5nIGlzIE9LLgogKiAgIFNSVl9TVEFUVVNfSU5URVJOQUwgZm9yIG90aGVyIHVucmVjb3ZlcmFibGUgZXJyb3JzLgogKgogKiBVcG9uIHN1Y2Nlc3NmdWwgcmV0dXJuLCB0aGUgc2Vzc2lvbiBmbGFnIFNOX0FERFJfU0VUIGlzIHNldC4gVGhpcyBmbGFnIGlzCiAqIG5vdCBjbGVhcmVkLCBzbyBpdCdzIHRvIHRoZSBjYWxsZXIgdG8gY2xlYXIgaXQgaWYgcmVxdWlyZWQuCiAqCiAqLwppbnQgYXNzaWduX3NlcnZlcl9hZGRyZXNzKHN0cnVjdCBzZXNzaW9uICpzKQp7CiNpZmRlZiBERUJVR19GVUxMCglmcHJpbnRmKHN0ZGVyciwiYXNzaWduX3NlcnZlcl9hZGRyZXNzIDogcz0lcFxuIixzKTsKI2VuZGlmCgoJaWYgKChzLT5mbGFncyAmIFNOX0RJUkVDVCkgfHwgKHMtPmJlLT5sYnBybS5hbGdvICYgQkVfTEJfQUxHTykpIHsKCQkvKiBBIHNlcnZlciBpcyBuZWNlc3NhcmlseSBrbm93biBmb3IgdGhpcyBzZXNzaW9uICovCgkJaWYgKCEocy0+ZmxhZ3MgJiBTTl9BU1NJR05FRCkpCgkJCXJldHVybiBTUlZfU1RBVFVTX0lOVEVSTkFMOwoKCQlzLT5zcnZfYWRkciA9IHMtPnNydi0+YWRkcjsKCgkJLyogaWYgdGhpcyBzZXJ2ZXIgcmVtYXBzIHByb3hpZWQgcG9ydHMsIHdlJ2xsIHVzZQoJCSAqIHRoZSBwb3J0IHRoZSBjbGllbnQgY29ubmVjdGVkIHRvIHdpdGggYW4gb2Zmc2V0LiAqLwoJCWlmIChzLT5zcnYtPnN0YXRlICYgU1JWX01BUFBPUlRTKSB7CgkJCWlmICghKHMtPmJlLT5vcHRpb25zICYgUFJfT19UUkFOU1ApICYmICEocy0+ZmxhZ3MgJiBTTl9GUlRfQUREUl9TRVQpKQoJCQkJZ2V0X2ZydF9hZGRyKHMpOwoJCQlpZiAocy0+ZnJ0X2FkZHIuc3NfZmFtaWx5ID09IEFGX0lORVQpIHsKCQkJCXMtPnNydl9hZGRyLnNpbl9wb3J0ID0gaHRvbnMobnRvaHMocy0+c3J2X2FkZHIuc2luX3BvcnQpICsKCQkJCQkJCSAgICAgbnRvaHMoKChzdHJ1Y3Qgc29ja2FkZHJfaW4gKikmcy0+ZnJ0X2FkZHIpLT5zaW5fcG9ydCkpOwoJCQl9IGVsc2UgewoJCQkJcy0+c3J2X2FkZHIuc2luX3BvcnQgPSBodG9ucyhudG9ocyhzLT5zcnZfYWRkci5zaW5fcG9ydCkgKwoJCQkJCQkJICAgICBudG9ocygoKHN0cnVjdCBzb2NrYWRkcl9pbjYgKikmcy0+ZnJ0X2FkZHIpLT5zaW42X3BvcnQpKTsKCQkJfQoJCX0KCX0KCWVsc2UgaWYgKCooaW50ICopJnMtPmJlLT5kaXNwYXRjaF9hZGRyLnNpbl9hZGRyKSB7CgkJLyogY29ubmVjdCB0byB0aGUgZGVmaW5lZCBkaXNwYXRjaCBhZGRyICovCgkJcy0+c3J2X2FkZHIgPSBzLT5iZS0+ZGlzcGF0Y2hfYWRkcjsKCX0KCWVsc2UgaWYgKHMtPmJlLT5vcHRpb25zICYgUFJfT19UUkFOU1ApIHsKCQkvKiBpbiB0cmFuc3BhcmVudCBtb2RlLCB1c2UgdGhlIG9yaWdpbmFsIGRlc3QgYWRkciBpZiBubyBkaXNwYXRjaCBzcGVjaWZpZWQgKi8KCQlpZiAoIShzLT5mbGFncyAmIFNOX0ZSVF9BRERSX1NFVCkpCgkJCWdldF9mcnRfYWRkcihzKTsKCgkJbWVtY3B5KCZzLT5zcnZfYWRkciwgJnMtPmZydF9hZGRyLCBNSU4oc2l6ZW9mKHMtPnNydl9hZGRyKSwgc2l6ZW9mKHMtPmZydF9hZGRyKSkpOwoJCS8qIHdoZW4gd2Ugc3VwcG9ydCBJUHY2IG9uIHRoZSBiYWNrZW5kLCB3ZSBtYXkgYWRkIG90aGVyIHRlc3RzICovCgkJLy9xZnByaW50ZihzdGRlcnIsICJDYW5ub3QgZ2V0IG9yaWdpbmFsIHNlcnZlciBhZGRyZXNzLlxuIik7CgkJLy9yZXR1cm4gU1JWX1NUQVRVU19JTlRFUk5BTDsKCX0KCWVsc2UgaWYgKHMtPmJlLT5vcHRpb25zICYgUFJfT19IVFRQX1BST1hZKSB7CgkJLyogSWYgSFRUUCBQUk9YWSBvcHRpb24gaXMgc2V0LCB0aGVuIHNlcnZlciBpcyBhbHJlYWR5IGFzc2lnbmVkCgkJICogZHVyaW5nIGluY29taW5nIGNsaWVudCByZXF1ZXN0IHBhcnNpbmcuICovCgl9CgllbHNlIHsKCQkvKiBubyBzZXJ2ZXIgYW5kIG5vIExCIGFsZ29yaXRobSAhICovCgkJcmV0dXJuIFNSVl9TVEFUVVNfSU5URVJOQUw7Cgl9CgoJcy0+ZmxhZ3MgfD0gU05fQUREUl9TRVQ7CglyZXR1cm4gU1JWX1NUQVRVU19PSzsKfQoKCi8qIFRoaXMgZnVuY3Rpb24gYXNzaWducyBhIHNlcnZlciB0byBzZXNzaW9uIDxzPiBpZiByZXF1aXJlZCwgYW5kIGNhbiBhZGQgdGhlCiAqIGNvbm5lY3Rpb24gdG8gZWl0aGVyIHRoZSBhc3NpZ25lZCBzZXJ2ZXIncyBxdWV1ZSBvciB0byB0aGUgcHJveHkncyBxdWV1ZS4KICogSWYgLT5zcnZfY29ubiBpcyBzZXQsIHRoZSBzZXNzaW9uIGlzIGZpcnN0IHJlbGVhc2VkIGZyb20gdGhlIHNlcnZlci4KICogSXQgbWF5IGFsc28gYmUgY2FsbGVkIHdpdGggU05fRElSRUNUIGFuZC9vciBTTl9BU1NJR05FRCB0aG91Z2guIEl0IHdpbGwKICogYmUgY2FsbGVkIGJlZm9yZSBhbnkgY29ubmVjdGlvbiBhbmQgYWZ0ZXIgYW55IHJldHJ5IG9yIHJlZGlzcGF0Y2ggb2NjdXJzLgogKgogKiBJdCBpcyBub3QgYWxsb3dlZCB0byBjYWxsIHRoaXMgZnVuY3Rpb24gd2l0aCBhIHNlc3Npb24gaW4gYSBxdWV1ZS4KICoKICogUmV0dXJucyA6CiAqCiAqICAgU1JWX1NUQVRVU19PSyAgICAgICBpZiBldmVyeXRoaW5nIGlzIE9LLgogKiAgIFNSVl9TVEFUVVNfTk9TUlYgICAgaWYgbm8gc2VydmVyIGlzIGF2YWlsYWJsZS4gcy0+c3J2ID0gTlVMTC4KICogICBTUlZfU1RBVFVTX1FVRVVFRCAgIGlmIHRoZSBjb25uZWN0aW9uIGhhcyBiZWVuIHF1ZXVlZC4KICogICBTUlZfU1RBVFVTX0ZVTEwgICAgIGlmIHRoZSBzZXJ2ZXIocykgaXMvYXJlIHNhdHVyYXRlZCBhbmQgdGhlCiAqICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uIGNvdWxkIG5vdCBiZSBxdWV1ZWQgaW4gcy0+c3J2LAogKiAgICAgICAgICAgICAgICAgICAgICAgd2hpY2ggbWF5IGJlIE5VTEwgaWYgd2UgcXVldWUgb24gdGhlIGJhY2tlbmQuCiAqICAgU1JWX1NUQVRVU19JTlRFUk5BTCBmb3Igb3RoZXIgdW5yZWNvdmVyYWJsZSBlcnJvcnMuCiAqCiAqLwppbnQgYXNzaWduX3NlcnZlcl9hbmRfcXVldWUoc3RydWN0IHNlc3Npb24gKnMpCnsKCXN0cnVjdCBwZW5kY29ubiAqcDsKCWludCBlcnI7CgoJaWYgKHMtPnBlbmRfcG9zKQoJCXJldHVybiBTUlZfU1RBVFVTX0lOVEVSTkFMOwoKCWVyciA9IFNSVl9TVEFUVVNfT0s7CglpZiAoIShzLT5mbGFncyAmIFNOX0FTU0lHTkVEKSkgewoJCWVyciA9IGFzc2lnbl9zZXJ2ZXIocyk7CgkJaWYgKHMtPnByZXZfc3J2KSB7CgkJCS8qIFRoaXMgc2Vzc2lvbiB3YXMgcHJldmlvdXNseSBhc3NpZ25lZCB0byBhIHNlcnZlci4gV2UgaGF2ZSB0bwoJCQkgKiB1cGRhdGUgdGhlIHNlc3Npb24ncyBhbmQgdGhlIHNlcnZlcidzIHN0YXRzIDoKCQkJICogIC0gaWYgdGhlIHNlcnZlciBjaGFuZ2VkIDoKCQkJICogICAgLSBzZXQgVFhfQ0tfRE9XTiBpZiB0eG4uZmxhZ3Mgd2FzIFRYX0NLX1ZBTElECgkJCSAqICAgIC0gc2V0IFNOX1JFRElTUCBpZiBpdCB3YXMgc3VjY2Vzc2Z1bGx5IHJlZGlzcGF0Y2hlZAoJCQkgKiAgICAtIGluY3JlbWVudCBzcnYtPnJlZGlzcGF0Y2hlcyBhbmQgYmUtPnJlZGlzcGF0Y2hlcwoJCQkgKiAgLSBpZiB0aGUgc2VydmVyIHJlbWFpbmVkIHRoZSBzYW1lIDogdXBkYXRlIHJldHJpZXMuCgkJCSAqLwoKCQkJaWYgKHMtPnByZXZfc3J2ICE9IHMtPnNydikgewoJCQkJaWYgKChzLT50eG4uZmxhZ3MgJiBUWF9DS19NQVNLKSA9PSBUWF9DS19WQUxJRCkgewoJCQkJCXMtPnR4bi5mbGFncyAmPSB+VFhfQ0tfTUFTSzsKCQkJCQlzLT50eG4uZmxhZ3MgfD0gVFhfQ0tfRE9XTjsKCQkJCX0KCQkJCXMtPmZsYWdzIHw9IFNOX1JFRElTUDsKCQkJCXMtPnByZXZfc3J2LT5yZWRpc3BhdGNoZXMrKzsKCQkJCXMtPmJlLT5yZWRpc3BhdGNoZXMrKzsKCQkJfSBlbHNlIHsKCQkJCXMtPnByZXZfc3J2LT5yZXRyaWVzKys7CgkJCQlzLT5iZS0+cmV0cmllcysrOwoJCQl9CgkJfQoJfQoKCXN3aXRjaCAoZXJyKSB7CgljYXNlIFNSVl9TVEFUVVNfT0s6CgkJLyogd2UgaGF2ZSBTTl9BU1NJR05FRCBzZXQgKi8KCQlpZiAoIXMtPnNydikKCQkJcmV0dXJuIFNSVl9TVEFUVVNfT0s7ICAgLyogZGlzcGF0Y2ggb3IgcHJveHkgbW9kZSAqLwoKCQkvKiBJZiB3ZSBhbHJlYWR5IGhhdmUgYSBjb25uZWN0aW9uIHNsb3QsIG5vIG5lZWQgdG8gY2hlY2sgYW55IHF1ZXVlICovCgkJaWYgKHMtPnNydl9jb25uID09IHMtPnNydikKCQkJcmV0dXJuIFNSVl9TVEFUVVNfT0s7CgoJCS8qIE9LLCB0aGlzIHNlc3Npb24gYWxyZWFkeSBoYXMgYW4gYXNzaWduZWQgc2VydmVyLCBidXQgbm8KCQkgKiBjb25uZWN0aW9uIHNsb3QgeWV0LiBFaXRoZXIgaXQgaXMgYSByZWRpc3BhdGNoLCBvciBpdCB3YXMKCQkgKiBhc3NpZ25lZCBmcm9tIHBlcnNpc3RlbmNlIGluZm9ybWF0aW9uIChkaXJlY3QgbW9kZSkuCgkJICovCgkJaWYgKChzLT5mbGFncyAmIFNOX1JFRElSRUNUQUJMRSkgJiYgcy0+c3J2LT5yZHJfbGVuKSB7CgkJCS8qIHNlcnZlciBzY2hlZHVsZWQgZm9yIHJlZGlyZWN0aW9uLCBhbmQgYWxyZWFkeSBhc3NpZ25lZC4gV2UKCQkJICogZG9uJ3Qgd2FudCB0byBnbyBmdXJ0aGVyIG5vciBjaGVjayB0aGUgcXVldWUuCgkJCSAqLwoJCQlzZXNzX2NoYW5nZV9zZXJ2ZXIocywgcy0+c3J2KTsgLyogbm90IHJlYWxseSBuZWVkZWQgaW4gZmFjdCAqLwoJCQlyZXR1cm4gU1JWX1NUQVRVU19PSzsKCQl9CgoJCS8qIFdlIG1pZ2h0IGhhdmUgdG8gcXVldWUgdGhpcyBzZXNzaW9uIGlmIHRoZSBhc3NpZ25lZCBzZXJ2ZXIgaXMgZnVsbC4KCQkgKiBXZSBrbm93IHdlIGhhdmUgdG8gcXVldWUgaXQgaW50byB0aGUgc2VydmVyJ3MgcXVldWUsIHNvIGlmIGEgbWF4cXVldWUKCQkgKiBpcyBzZXQgb24gdGhlIHNlcnZlciwgd2UgbXVzdCBhbHNvIGNoZWNrIHRoYXQgdGhlIHNlcnZlcidzIHF1ZXVlIGlzCgkJICogbm90IGZ1bGwsIGluIHdoaWNoIGNhc2Ugd2UgaGF2ZSB0byByZXR1cm4gRlVMTC4KCQkgKi8KCQlpZiAocy0+c3J2LT5tYXhjb25uICYmCgkJICAgIChzLT5zcnYtPm5icGVuZCB8fCBzLT5zcnYtPnNlcnZlZCA+PSBzcnZfZHluYW1pY19tYXhjb25uKHMtPnNydikpKSB7CgoJCQlpZiAocy0+c3J2LT5tYXhxdWV1ZSA+IDAgJiYgcy0+c3J2LT5uYnBlbmQgPj0gcy0+c3J2LT5tYXhxdWV1ZSkKCQkJCXJldHVybiBTUlZfU1RBVFVTX0ZVTEw7CgoJCQlwID0gcGVuZGNvbm5fYWRkKHMpOwoJCQlpZiAocCkKCQkJCXJldHVybiBTUlZfU1RBVFVTX1FVRVVFRDsKCQkJZWxzZQoJCQkJcmV0dXJuIFNSVl9TVEFUVVNfSU5URVJOQUw7CgkJfQoKCQkvKiBPSywgd2UgY2FuIHVzZSB0aGlzIHNlcnZlci4gTGV0J3MgcmVzZXJ2ZSBvdXIgcGxhY2UgKi8KCQlzZXNzX2NoYW5nZV9zZXJ2ZXIocywgcy0+c3J2KTsKCQlyZXR1cm4gU1JWX1NUQVRVU19PSzsKCgljYXNlIFNSVl9TVEFUVVNfRlVMTDoKCQkvKiBxdWV1ZSB0aGlzIHNlc3Npb24gaW50byB0aGUgcHJveHkncyBxdWV1ZSAqLwoJCXAgPSBwZW5kY29ubl9hZGQocyk7CgkJaWYgKHApCgkJCXJldHVybiBTUlZfU1RBVFVTX1FVRVVFRDsKCQllbHNlCgkJCXJldHVybiBTUlZfU1RBVFVTX0lOVEVSTkFMOwoKCWNhc2UgU1JWX1NUQVRVU19OT1NSVjoKCQlyZXR1cm4gZXJyOwoKCWNhc2UgU1JWX1NUQVRVU19JTlRFUk5BTDoKCQlyZXR1cm4gZXJyOwoKCWRlZmF1bHQ6CgkJcmV0dXJuIFNSVl9TVEFUVVNfSU5URVJOQUw7Cgl9Cn0KCi8qCiAqIFRoaXMgZnVuY3Rpb24gaW5pdGlhdGVzIGEgY29ubmVjdGlvbiB0byB0aGUgc2VydmVyIGFzc2lnbmVkIHRvIHRoaXMgc2Vzc2lvbgogKiAocy0+c3J2LCBzLT5zcnZfYWRkcikuIEl0IHdpbGwgYXNzaWduIGEgc2VydmVyIGlmIG5vbmUgaXMgYXNzaWduZWQgeWV0LgogKiBJdCBjYW4gcmV0dXJuIG9uZSBvZiA6CiAqICAtIFNOX0VSUl9OT05FIGlmIGV2ZXJ5dGhpbmcncyBPSwogKiAgLSBTTl9FUlJfU1JWVE8gaWYgdGhlcmUgYXJlIG5vIG1vcmUgc2VydmVycwogKiAgLSBTTl9FUlJfU1JWQ0wgaWYgdGhlIGNvbm5lY3Rpb24gd2FzIHJlZnVzZWQgYnkgdGhlIHNlcnZlcgogKiAgLSBTTl9FUlJfUFJYQ09ORCBpZiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBsaW1pdGVkIGJ5IHRoZSBwcm94eSAobWF4Y29ubikKICogIC0gU05fRVJSX1JFU09VUkNFIGlmIGEgc3lzdGVtIHJlc291cmNlIGlzIGxhY2tpbmcgKGVnOiBmZCBsaW1pdHMsIHBvcnRzLCAuLi4pCiAqICAtIFNOX0VSUl9JTlRFUk5BTCBmb3IgYW55IG90aGVyIHB1cmVseSBpbnRlcm5hbCBlcnJvcnMKICogQWRkaXRpb25uYWxseSwgaW4gdGhlIGNhc2Ugb2YgU05fRVJSX1JFU09VUkNFLCBhbiBlbWVyZ2VuY3kgbG9nIHdpbGwgYmUgZW1pdHRlZC4KICovCmludCBjb25uZWN0X3NlcnZlcihzdHJ1Y3Qgc2Vzc2lvbiAqcykKewoJaW50IGZkLCBlcnI7CgoJaWYgKCEocy0+ZmxhZ3MgJiBTTl9BRERSX1NFVCkpIHsKCQllcnIgPSBhc3NpZ25fc2VydmVyX2FkZHJlc3Mocyk7CgkJaWYgKGVyciAhPSBTUlZfU1RBVFVTX09LKQoJCQlyZXR1cm4gU05fRVJSX0lOVEVSTkFMOwoJfQoKCWlmICgoZmQgPSBzLT5yZXEtPmNvbnMtPmZkID0gc29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCBJUFBST1RPX1RDUCkpID09IC0xKSB7CgkJcWZwcmludGYoc3RkZXJyLCAiQ2Fubm90IGdldCBhIHNlcnZlciBzb2NrZXQuXG4iKTsKCgkJaWYgKGVycm5vID09IEVORklMRSkKCQkJc2VuZF9sb2cocy0+YmUsIExPR19FTUVSRywKCQkJCSAiUHJveHkgJXMgcmVhY2hlZCBzeXN0ZW0gRkQgbGltaXQgYXQgJWQuIFBsZWFzZSBjaGVjayBzeXN0ZW0gdHVuYWJsZXMuXG4iLAoJCQkJIHMtPmJlLT5pZCwgbWF4ZmQpOwoJCWVsc2UgaWYgKGVycm5vID09IEVNRklMRSkKCQkJc2VuZF9sb2cocy0+YmUsIExPR19FTUVSRywKCQkJCSAiUHJveHkgJXMgcmVhY2hlZCBwcm9jZXNzIEZEIGxpbWl0IGF0ICVkLiBQbGVhc2UgY2hlY2sgJ3VsaW1pdC1uJyBhbmQgcmVzdGFydC5cbiIsCgkJCQkgcy0+YmUtPmlkLCBtYXhmZCk7CgkJZWxzZSBpZiAoZXJybm8gPT0gRU5PQlVGUyB8fCBlcnJubyA9PSBFTk9NRU0pCgkJCXNlbmRfbG9nKHMtPmJlLCBMT0dfRU1FUkcsCgkJCQkgIlByb3h5ICVzIHJlYWNoZWQgc3lzdGVtIG1lbW9yeSBsaW1pdCBhdCAlZCBzb2NrZXRzLiBQbGVhc2UgY2hlY2sgc3lzdGVtIHR1bmFibGVzLlxuIiwKCQkJCSBzLT5iZS0+aWQsIG1heGZkKTsKCQkvKiB0aGlzIGlzIGEgcmVzb3VyY2UgZXJyb3IgKi8KCQlyZXR1cm4gU05fRVJSX1JFU09VUkNFOwoJfQoKCWlmIChmZCA+PSBnbG9iYWwubWF4c29jaykgewoJCS8qIGRvIG5vdCBsb2cgYW55dGhpbmcgdGhlcmUsIGl0J3MgYSBub3JtYWwgY29uZGl0aW9uIHdoZW4gdGhpcyBvcHRpb24KCQkgKiBpcyB1c2VkIHRvIHNlcmlhbGl6ZSBjb25uZWN0aW9ucyB0byBhIHNlcnZlciAhCgkJICovCgkJQWxlcnQoInNvY2tldCgpOiBub3QgZW5vdWdoIGZyZWUgc29ja2V0cy4gUmFpc2UgLW4gYXJndW1lbnQuIEdpdmluZyB1cC5cbiIpOwoJCWNsb3NlKGZkKTsKCQlyZXR1cm4gU05fRVJSX1BSWENPTkQ7IC8qIGl0IGlzIGEgY29uZmlndXJhdGlvbiBsaW1pdCAqLwoJfQoKI2lmZGVmIENPTkZJR19IQVBfVENQU1BMSUNFCglpZiAoKGdsb2JhbC50dW5lLm9wdGlvbnMgJiBHVFVORV9VU0VfU1BMSUNFKSAmJgoJICAgIChzLT5mZS0+b3B0aW9ucyAmIHMtPmJlLT5vcHRpb25zKSAmIFBSX09fVENQU1BMSUNFKSB7CgkJLyogVENQIHNwbGljaW5nIHN1cHBvcnRlZCBieSBib3RoIEZFIGFuZCBCRSAqLwoJCXRjcF9zcGxpY2VfaW5pdGZkKHMtPnJlcS0+cHJvZC0+ZmQsIGZkKTsKCX0KI2VuZGlmCgoJaWYgKChmY250bChmZCwgRl9TRVRGTCwgT19OT05CTE9DSyk9PS0xKSB8fAoJICAgIChzZXRzb2Nrb3B0KGZkLCBJUFBST1RPX1RDUCwgVENQX05PREVMQVksIChjaGFyICopICZvbmUsIHNpemVvZihvbmUpKSA9PSAtMSkpIHsKCQlxZnByaW50ZihzdGRlcnIsIkNhbm5vdCBzZXQgY2xpZW50IHNvY2tldCB0byBub24gYmxvY2tpbmcgbW9kZS5cbiIpOwoJCWNsb3NlKGZkKTsKCQlyZXR1cm4gU05fRVJSX0lOVEVSTkFMOwoJfQoKCWlmIChzLT5iZS0+b3B0aW9ucyAmIFBSX09fVENQX1NSVl9LQSkKCQlzZXRzb2Nrb3B0KGZkLCBTT0xfU09DS0VULCBTT19LRUVQQUxJVkUsIChjaGFyICopICZvbmUsIHNpemVvZihvbmUpKTsKCglpZiAocy0+YmUtPm9wdGlvbnMgJiBQUl9PX1RDUF9OT0xJTkcpCgkJc2V0c29ja29wdChmZCwgU09MX1NPQ0tFVCwgU09fTElOR0VSLCAoc3RydWN0IGxpbmdlciAqKSAmbm9saW5nZXIsIHNpemVvZihzdHJ1Y3QgbGluZ2VyKSk7CgoJLyogYWxsb3cgc3BlY2lmaWMgYmluZGluZyA6CgkgKiAtIHNlcnZlci1zcGVjaWZpYyBhdCBmaXJzdAoJICogLSBwcm94eS1zcGVjaWZpYyBuZXh0CgkgKi8KCWlmIChzLT5zcnYgIT0gTlVMTCAmJiBzLT5zcnYtPnN0YXRlICYgU1JWX0JJTkRfU1JDKSB7CgkJc3RydWN0IHNvY2thZGRyX2luICpyZW1vdGUgPSBOVUxMOwoJCWludCByZXQsIGZsYWdzID0gMDsKCiNpZiBkZWZpbmVkKENPTkZJR19IQVBfQ1RUUFJPWFkpIHx8IGRlZmluZWQoQ09ORklHX0hBUF9MSU5VWF9UUFJPWFkpCgkJc3dpdGNoIChzLT5zcnYtPnN0YXRlICYgU1JWX1RQUk9YWV9NQVNLKSB7CgkJY2FzZSBTUlZfVFBST1hZX0FERFI6CgkJCXJlbW90ZSA9IChzdHJ1Y3Qgc29ja2FkZHJfaW4gKikmcy0+c3J2LT50cHJveHlfYWRkcjsKCQkJZmxhZ3MgID0gMzsKCQkJYnJlYWs7CgkJY2FzZSBTUlZfVFBST1hZX0NMSToKCQkJZmxhZ3MgfD0gMjsKCQkJLyogZmFsbCB0aHJvdWdoICovCgkJY2FzZSBTUlZfVFBST1hZX0NJUDoKCQkJLyogRklYTUU6IHdoYXQgY2FuIHdlIGRvIGlmIHRoZSBjbGllbnQgY29ubmVjdHMgaW4gSVB2NiA/ICovCgkJCWZsYWdzIHw9IDE7CgkJCXJlbW90ZSA9IChzdHJ1Y3Qgc29ja2FkZHJfaW4gKikmcy0+Y2xpX2FkZHI7CgkJCWJyZWFrOwoJCX0KI2VuZGlmCiNpZmRlZiBTT19CSU5EVE9ERVZJQ0UKCQkvKiBOb3RlOiB0aGlzIG1pZ2h0IGZhaWwgaWYgbm90IENBUF9ORVRfUkFXICovCgkJaWYgKHMtPnNydi0+aWZhY2VfbmFtZSkKCQkJc2V0c29ja29wdChmZCwgU09MX1NPQ0tFVCwgU09fQklORFRPREVWSUNFLCBzLT5zcnYtPmlmYWNlX25hbWUsIHMtPnNydi0+aWZhY2VfbGVuKTsKI2VuZGlmCgkJcmV0ID0gdGNwdjRfYmluZF9zb2NrZXQoZmQsIGZsYWdzLCAmcy0+c3J2LT5zb3VyY2VfYWRkciwgcmVtb3RlKTsKCQlpZiAocmV0KSB7CgkJCWNsb3NlKGZkKTsKCQkJaWYgKHJldCA9PSAxKSB7CgkJCQlBbGVydCgiQ2Fubm90IGJpbmQgdG8gc291cmNlIGFkZHJlc3MgYmVmb3JlIGNvbm5lY3QoKSBmb3Igc2VydmVyICVzLyVzLiBBYm9ydGluZy5cbiIsCgkJCQkgICAgICBzLT5iZS0+aWQsIHMtPnNydi0+aWQpOwoJCQkJc2VuZF9sb2cocy0+YmUsIExPR19FTUVSRywKCQkJCQkgIkNhbm5vdCBiaW5kIHRvIHNvdXJjZSBhZGRyZXNzIGJlZm9yZSBjb25uZWN0KCkgZm9yIHNlcnZlciAlcy8lcy5cbiIsCgkJCQkJIHMtPmJlLT5pZCwgcy0+c3J2LT5pZCk7CgkJCX0gZWxzZSB7CgkJCQlBbGVydCgiQ2Fubm90IGJpbmQgdG8gdHByb3h5IHNvdXJjZSBhZGRyZXNzIGJlZm9yZSBjb25uZWN0KCkgZm9yIHNlcnZlciAlcy8lcy4gQWJvcnRpbmcuXG4iLAoJCQkJICAgICAgcy0+YmUtPmlkLCBzLT5zcnYtPmlkKTsKCQkJCXNlbmRfbG9nKHMtPmJlLCBMT0dfRU1FUkcsCgkJCQkJICJDYW5ub3QgYmluZCB0byB0cHJveHkgc291cmNlIGFkZHJlc3MgYmVmb3JlIGNvbm5lY3QoKSBmb3Igc2VydmVyICVzLyVzLlxuIiwKCQkJCQkgcy0+YmUtPmlkLCBzLT5zcnYtPmlkKTsKCQkJfQoJCQlyZXR1cm4gU05fRVJSX1JFU09VUkNFOwoJCX0KCX0KCWVsc2UgaWYgKHMtPmJlLT5vcHRpb25zICYgUFJfT19CSU5EX1NSQykgewoJCXN0cnVjdCBzb2NrYWRkcl9pbiAqcmVtb3RlID0gTlVMTDsKCQlpbnQgcmV0LCBmbGFncyA9IDA7CgojaWYgZGVmaW5lZChDT05GSUdfSEFQX0NUVFBST1hZKSB8fCBkZWZpbmVkKENPTkZJR19IQVBfTElOVVhfVFBST1hZKQoJCXN3aXRjaCAocy0+YmUtPm9wdGlvbnMgJiBQUl9PX1RQWFlfTUFTSykgewoJCWNhc2UgUFJfT19UUFhZX0FERFI6CgkJCXJlbW90ZSA9IChzdHJ1Y3Qgc29ja2FkZHJfaW4gKikmcy0+YmUtPnRwcm94eV9hZGRyOwoJCQlmbGFncyAgPSAzOwoJCQlicmVhazsKCQljYXNlIFBSX09fVFBYWV9DTEk6CgkJCWZsYWdzIHw9IDI7CgkJCS8qIGZhbGwgdGhyb3VnaCAqLwoJCWNhc2UgUFJfT19UUFhZX0NJUDoKCQkJLyogRklYTUU6IHdoYXQgY2FuIHdlIGRvIGlmIHRoZSBjbGllbnQgY29ubmVjdHMgaW4gSVB2NiA/ICovCgkJCWZsYWdzIHw9IDE7CgkJCXJlbW90ZSA9IChzdHJ1Y3Qgc29ja2FkZHJfaW4gKikmcy0+Y2xpX2FkZHI7CgkJCWJyZWFrOwoJCX0KI2VuZGlmCiNpZmRlZiBTT19CSU5EVE9ERVZJQ0UKCQkvKiBOb3RlOiB0aGlzIG1pZ2h0IGZhaWwgaWYgbm90IENBUF9ORVRfUkFXICovCgkJaWYgKHMtPmJlLT5pZmFjZV9uYW1lKQoJCQlzZXRzb2Nrb3B0KGZkLCBTT0xfU09DS0VULCBTT19CSU5EVE9ERVZJQ0UsIHMtPmJlLT5pZmFjZV9uYW1lLCBzLT5iZS0+aWZhY2VfbGVuKTsKI2VuZGlmCgkJcmV0ID0gdGNwdjRfYmluZF9zb2NrZXQoZmQsIGZsYWdzLCAmcy0+YmUtPnNvdXJjZV9hZGRyLCByZW1vdGUpOwoJCWlmIChyZXQpIHsKCQkJY2xvc2UoZmQpOwoJCQlpZiAocmV0ID09IDEpIHsKCQkJCUFsZXJ0KCJDYW5ub3QgYmluZCB0byBzb3VyY2UgYWRkcmVzcyBiZWZvcmUgY29ubmVjdCgpIGZvciBwcm94eSAlcy4gQWJvcnRpbmcuXG4iLAoJCQkJICAgICAgcy0+YmUtPmlkKTsKCQkJCXNlbmRfbG9nKHMtPmJlLCBMT0dfRU1FUkcsCgkJCQkJICJDYW5ub3QgYmluZCB0byBzb3VyY2UgYWRkcmVzcyBiZWZvcmUgY29ubmVjdCgpIGZvciBwcm94eSAlcy5cbiIsCgkJCQkJIHMtPmJlLT5pZCk7CgkJCX0gZWxzZSB7CgkJCQlBbGVydCgiQ2Fubm90IGJpbmQgdG8gdHByb3h5IHNvdXJjZSBhZGRyZXNzIGJlZm9yZSBjb25uZWN0KCkgZm9yIHByb3h5ICVzLiBBYm9ydGluZy5cbiIsCgkJCQkgICAgICBzLT5iZS0+aWQpOwoJCQkJc2VuZF9sb2cocy0+YmUsIExPR19FTUVSRywKCQkJCQkgIkNhbm5vdCBiaW5kIHRvIHRwcm94eSBzb3VyY2UgYWRkcmVzcyBiZWZvcmUgY29ubmVjdCgpIGZvciBwcm94eSAlcy5cbiIsCgkJCQkJIHMtPmJlLT5pZCk7CgkJCX0KCQkJcmV0dXJuIFNOX0VSUl9SRVNPVVJDRTsKCQl9Cgl9CgoJaWYgKChjb25uZWN0KGZkLCAoc3RydWN0IHNvY2thZGRyICopJnMtPnNydl9hZGRyLCBzaXplb2Yocy0+c3J2X2FkZHIpKSA9PSAtMSkgJiYKCSAgICAoZXJybm8gIT0gRUlOUFJPR1JFU1MpICYmIChlcnJubyAhPSBFQUxSRUFEWSkgJiYgKGVycm5vICE9IEVJU0NPTk4pKSB7CgoJCWlmIChlcnJubyA9PSBFQUdBSU4gfHwgZXJybm8gPT0gRUFERFJJTlVTRSkgewoJCQljaGFyICptc2c7CgkJCWlmIChlcnJubyA9PSBFQUdBSU4pIC8qIG5vIGZyZWUgcG9ydHMgbGVmdCwgdHJ5IGFnYWluIGxhdGVyICovCgkJCQltc2cgPSAibm8gZnJlZSBwb3J0cyI7CgkJCWVsc2UKCQkJCW1zZyA9ICJsb2NhbCBhZGRyZXNzIGFscmVhZHkgaW4gdXNlIjsKCgkJCXFmcHJpbnRmKHN0ZGVyciwiQ2Fubm90IGNvbm5lY3Q6ICVzLlxuIixtc2cpOwoJCQljbG9zZShmZCk7CgkJCXNlbmRfbG9nKHMtPmJlLCBMT0dfRU1FUkcsCgkJCQkgIkNvbm5lY3QoKSBmYWlsZWQgZm9yIHNlcnZlciAlcy8lczogJXMuXG4iLAoJCQkJIHMtPmJlLT5pZCwgcy0+c3J2LT5pZCwgbXNnKTsKCQkJcmV0dXJuIFNOX0VSUl9SRVNPVVJDRTsKCQl9IGVsc2UgaWYgKGVycm5vID09IEVUSU1FRE9VVCkgewoJCQkvL3FmcHJpbnRmKHN0ZGVyciwiQ29ubmVjdCgpOiBFVElNRURPVVQiKTsKCQkJY2xvc2UoZmQpOwoJCQlyZXR1cm4gU05fRVJSX1NSVlRPOwoJCX0gZWxzZSB7CgkJCS8vIChlcnJubyA9PSBFQ09OTlJFRlVTRUQgfHwgZXJybm8gPT0gRU5FVFVOUkVBQ0ggfHwgZXJybm8gPT0gRUFDQ0VTIHx8IGVycm5vID09IEVQRVJNKQoJCQkvL3FmcHJpbnRmKHN0ZGVyciwiQ29ubmVjdCgpOiAlZCIsIGVycm5vKTsKCQkJY2xvc2UoZmQpOwoJCQlyZXR1cm4gU05fRVJSX1NSVkNMOwoJCX0KCX0KCglmZHRhYltmZF0ub3duZXIgPSBzLT5yZXEtPmNvbnM7CglmZHRhYltmZF0uc3RhdGUgPSBGRF9TVENPTk47IC8qIGNvbm5lY3Rpb24gaW4gcHJvZ3Jlc3MgKi8KCWZkdGFiW2ZkXS5jYltESVJfUkRdLmYgPSAmc3RyZWFtX3NvY2tfcmVhZDsKCWZkdGFiW2ZkXS5jYltESVJfUkRdLmIgPSBzLT5yZXA7CglmZHRhYltmZF0uY2JbRElSX1dSXS5mID0gJnN0cmVhbV9zb2NrX3dyaXRlOwoJZmR0YWJbZmRdLmNiW0RJUl9XUl0uYiA9IHMtPnJlcTsKCglmZHRhYltmZF0ucGVlcmFkZHIgPSAoc3RydWN0IHNvY2thZGRyICopJnMtPnNydl9hZGRyOwoJZmR0YWJbZmRdLnBlZXJsZW4gPSBzaXplb2Yocy0+c3J2X2FkZHIpOwoKCWZkX2luc2VydChmZCk7CglFVl9GRF9TRVQoZmQsIERJUl9XUik7ICAvKiBmb3IgY29ubmVjdCBzdGF0dXMgKi8KCglzLT5yZXEtPmNvbnMtPnN0YXRlID0gU0lfU1RfQ09OOwoJaWYgKHMtPnNydikgewoJCXMtPmZsYWdzIHw9IFNOX0NVUlJfU0VTUzsKCQlzLT5zcnYtPmN1cl9zZXNzKys7CgkJaWYgKHMtPnNydi0+Y3VyX3Nlc3MgPiBzLT5zcnYtPmN1cl9zZXNzX21heCkKCQkJcy0+c3J2LT5jdXJfc2Vzc19tYXggPSBzLT5zcnYtPmN1cl9zZXNzOwoJCWlmIChzLT5iZS0+bGJwcm0uc2VydmVyX3Rha2VfY29ubikKCQkJcy0+YmUtPmxicHJtLnNlcnZlcl90YWtlX2Nvbm4ocy0+c3J2KTsKCX0KCglzLT5yZXEtPndleCA9IHRpY2tfYWRkX2lmc2V0KG5vd19tcywgcy0+YmUtPnRpbWVvdXQuY29ubmVjdCk7CglyZXR1cm4gU05fRVJSX05PTkU7ICAvKiBjb25uZWN0aW9uIGlzIE9LICovCn0KCgovKiBUaGlzIGZ1bmN0aW9uIHBlcmZvcm1zIHRoZSAicmVkaXNwYXRjaCIgcGFydCBvZiBhIGNvbm5lY3Rpb24gYXR0ZW1wdC4gSXQKICogd2lsbCBhc3NpZ24gYSBzZXJ2ZXIgaWYgcmVxdWlyZWQsIHF1ZXVlIHRoZSBjb25uZWN0aW9uIGlmIHJlcXVpcmVkLCBhbmQKICogaGFuZGxlIGVycm9ycyB0aGF0IG1pZ2h0IGFyaXNlIGF0IHRoaXMgbGV2ZWwuIEl0IGNhbiBjaGFuZ2UgdGhlIHNlcnZlcgogKiBzdGF0ZS4gSXQgd2lsbCByZXR1cm4gMSBpZiBpdCBlbmNvdW50ZXJzIGFuIGVycm9yLCBzd2l0Y2hlcyB0aGUgc2VydmVyCiAqIHN0YXRlLCBvciBoYXMgdG8gcXVldWUgYSBjb25uZWN0aW9uLiBPdGhlcndpc2UsIGl0IHdpbGwgcmV0dXJuIDAgaW5kaWNhdGluZwogKiB0aGF0IHRoZSBjb25uZWN0aW9uIGlzIHJlYWR5IHRvIHVzZS4KICovCgppbnQgc3J2X3JlZGlzcGF0Y2hfY29ubmVjdChzdHJ1Y3Qgc2Vzc2lvbiAqdCkKewoJaW50IGNvbm5fZXJyOwoKCS8qIFdlIGtub3cgdGhhdCB3ZSBkb24ndCBoYXZlIGFueSBjb25uZWN0aW9uIHBlbmRpbmcsIHNvIHdlIHdpbGwKCSAqIHRyeSB0byBnZXQgYSBuZXcgb25lLCBhbmQgd2FpdCBpbiB0aGlzIHN0YXRlIGlmIGl0J3MgcXVldWVkCgkgKi8KIHJlZGlzcGF0Y2g6Cgljb25uX2VyciA9IGFzc2lnbl9zZXJ2ZXJfYW5kX3F1ZXVlKHQpOwoJc3dpdGNoIChjb25uX2VycikgewoJY2FzZSBTUlZfU1RBVFVTX09LOgoJCWJyZWFrOwoKCWNhc2UgU1JWX1NUQVRVU19GVUxMOgoJCS8qIFRoZSBzZXJ2ZXIgaGFzIHJlYWNoZWQgaXRzIG1heHF1ZXVlIGxpbWl0LiBFaXRoZXIgUFJfT19SRURJU1AgaXMgc2V0CgkJICogYW5kIHdlIGNhbiByZWRpc3BhdGNoIHRvIGFub3RoZXIgc2VydmVyLCBvciBpdCBpcyBub3QgYW5kIHdlIHJldHVybgoJCSAqIDUwMy4gVGhpcyBvbmx5IG1ha2VzIHNlbnNlIGluIERJUkVDVCBtb2RlIGhvd2V2ZXIsIGJlY2F1c2Ugbm9ybWFsIExCCgkJICogYWxnb3JpdGhtcyB3b3VsZCBuZXZlciBzZWxlY3Qgc3VjaCBhIHNlcnZlciwgYW5kIGhhc2ggYWxnb3JpdGhtcwoJCSAqIHdvdWxkIGJyaW5nIHVzIG9uIHRoZSBzYW1lIHNlcnZlciBhZ2Fpbi4gTm90ZSB0aGF0IHQtPnNydiBpcyBzZXQgaW4KCQkgKiB0aGlzIGNhc2UuCgkJICovCgkJaWYgKCh0LT5mbGFncyAmIFNOX0RJUkVDVCkgJiYgKHQtPmJlLT5vcHRpb25zICYgUFJfT19SRURJU1ApKSB7CgkJCXQtPmZsYWdzICY9IH4oU05fRElSRUNUIHwgU05fQVNTSUdORUQgfCBTTl9BRERSX1NFVCk7CgkJCXQtPnByZXZfc3J2ID0gdC0+c3J2OwoJCQlnb3RvIHJlZGlzcGF0Y2g7CgkJfQoKCQlpZiAoIXQtPnJlcS0+Y29ucy0+ZXJyX3R5cGUpIHsKCQkJdC0+cmVxLT5jb25zLT5lcnJfdHlwZSA9IFNJX0VUX1FVRVVFX0VSUjsKCQkJdC0+cmVxLT5jb25zLT5lcnJfbG9jID0gdC0+c3J2OwoJCX0KCgkJdC0+c3J2LT5mYWlsZWRfY29ubnMrKzsKCQl0LT5iZS0+ZmFpbGVkX2Nvbm5zKys7CgkJcmV0dXJuIDE7CgoJY2FzZSBTUlZfU1RBVFVTX05PU1JWOgoJCS8qIG5vdGU6IGl0IGlzIGd1YXJhbnRlZWQgdGhhdCB0LT5zcnYgPT0gTlVMTCBoZXJlICovCgkJaWYgKCF0LT5yZXEtPmNvbnMtPmVycl90eXBlKSB7CgkJCXQtPnJlcS0+Y29ucy0+ZXJyX3R5cGUgPSBTSV9FVF9DT05OX0VSUjsKCQkJdC0+cmVxLT5jb25zLT5lcnJfbG9jID0gTlVMTDsKCQl9CgoJCXQtPmJlLT5mYWlsZWRfY29ubnMrKzsKCQlyZXR1cm4gMTsKCgljYXNlIFNSVl9TVEFUVVNfUVVFVUVEOgoJCXQtPnJlcS0+Y29ucy0+ZXhwID0gdGlja19hZGRfaWZzZXQobm93X21zLCB0LT5iZS0+dGltZW91dC5xdWV1ZSk7CgkJdC0+cmVxLT5jb25zLT5zdGF0ZSA9IFNJX1NUX1FVRTsKCQkvKiBkbyBub3RoaW5nIGVsc2UgYW5kIGRvIG5vdCB3YWtlIGFueSBvdGhlciBzZXNzaW9uIHVwICovCgkJcmV0dXJuIDE7CgoJY2FzZSBTUlZfU1RBVFVTX0lOVEVSTkFMOgoJZGVmYXVsdDoKCQlpZiAoIXQtPnJlcS0+Y29ucy0+ZXJyX3R5cGUpIHsKCQkJdC0+cmVxLT5jb25zLT5lcnJfdHlwZSA9IFNJX0VUX0NPTk5fT1RIRVI7CgkJCXQtPnJlcS0+Y29ucy0+ZXJyX2xvYyA9IHQtPnNydjsKCQl9CgoJCWlmICh0LT5zcnYpCgkJCXQtPnNydi0+Y3VtX3Nlc3MrKzsKCQlpZiAodC0+c3J2KQoJCQl0LT5zcnYtPmZhaWxlZF9jb25ucysrOwoJCXQtPmJlLT5mYWlsZWRfY29ubnMrKzsKCgkJLyogcmVsZWFzZSBvdGhlciBzZXNzaW9ucyB3YWl0aW5nIGZvciB0aGlzIHNlcnZlciAqLwoJCWlmIChtYXlfZGVxdWV1ZV90YXNrcyh0LT5zcnYsIHQtPmJlKSkKCQkJcHJvY2Vzc19zcnZfcXVldWUodC0+c3J2KTsKCQlyZXR1cm4gMTsKCX0KCS8qIGlmIHdlIGdldCBoZXJlLCBpdCdzIGJlY2F1c2Ugd2UgZ290IFNSVl9TVEFUVVNfT0ssIHdoaWNoIGFsc28KCSAqIG1lYW5zIHRoYXQgdGhlIGNvbm5lY3Rpb24gaGFzIG5vdCBiZWVuIHF1ZXVlZC4KCSAqLwoJcmV0dXJuIDA7Cn0KCmludCBiZV9kb3dudGltZShzdHJ1Y3QgcHJveHkgKnB4KSB7CglpZiAocHgtPmxicHJtLnRvdF93ZWlnaHQgJiYgcHgtPmxhc3RfY2hhbmdlIDwgbm93LnR2X3NlYykgIC8vIGlnbm9yZSBuZWdhdGl2ZSB0aW1lCgkJcmV0dXJuIHB4LT5kb3duX3RpbWU7CgoJcmV0dXJuIG5vdy50dl9zZWMgLSBweC0+bGFzdF9jaGFuZ2UgKyBweC0+ZG93bl90aW1lOwp9CgovKiBUaGlzIGZ1bmN0aW9uIHBhcnNlcyBhICJiYWxhbmNlIiBzdGF0ZW1lbnQgaW4gYSBiYWNrZW5kIHNlY3Rpb24gZGVzY3JpYmluZwogKiA8Y3VycHJveHk+LiBJdCByZXR1cm5zIC0xIGlmIHRoZXJlIGlzIGFueSBlcnJvciwgb3RoZXJ3aXNlIHplcm8uIElmIGl0CiAqIHJldHVybnMgLTEsIGl0IG1heSB3cml0ZSBhbiBlcnJvciBtZXNzYWdlIGludG8gdGhlciA8ZXJyPiBidWZmZXIsIGZvciBhdAogKiBtb3N0IDxlcnJsZW4+IGJ5dGVzLCB0cmFpbGluZyB6ZXJvIGluY2x1ZGVkLiBUaGUgdHJhaWxpbmcgJ1xuJyB3aWxsIG5vdCBiZQogKiB3cml0dGVuLiBUaGUgZnVuY3Rpb24gbXVzdCBiZSBjYWxsZWQgd2l0aCA8YXJncz4gcG9pbnRpbmcgdG8gdGhlIGZpcnN0IHdvcmQKICogYWZ0ZXIgImJhbGFuY2UiLgogKi8KaW50IGJhY2tlbmRfcGFyc2VfYmFsYW5jZShjb25zdCBjaGFyICoqYXJncywgY2hhciAqZXJyLCBpbnQgZXJybGVuLCBzdHJ1Y3QgcHJveHkgKmN1cnByb3h5KQp7CglpZiAoISooYXJnc1swXSkpIHsKCQkvKiBpZiBubyBvcHRpb24gaXMgc2V0LCB1c2Ugcm91bmQtcm9iaW4gYnkgZGVmYXVsdCAqLwoJCWN1cnByb3h5LT5sYnBybS5hbGdvICY9IH5CRV9MQl9BTEdPOwoJCWN1cnByb3h5LT5sYnBybS5hbGdvIHw9IEJFX0xCX0FMR09fUlI7CgkJcmV0dXJuIDA7Cgl9CgoJaWYgKCFzdHJjbXAoYXJnc1swXSwgInJvdW5kcm9iaW4iKSkgewoJCWN1cnByb3h5LT5sYnBybS5hbGdvICY9IH5CRV9MQl9BTEdPOwoJCWN1cnByb3h5LT5sYnBybS5hbGdvIHw9IEJFX0xCX0FMR09fUlI7Cgl9CgllbHNlIGlmICghc3RyY21wKGFyZ3NbMF0sICJsZWFzdGNvbm4iKSkgewoJCWN1cnByb3h5LT5sYnBybS5hbGdvICY9IH5CRV9MQl9BTEdPOwoJCWN1cnByb3h5LT5sYnBybS5hbGdvIHw9IEJFX0xCX0FMR09fTEM7Cgl9CgllbHNlIGlmICghc3RyY21wKGFyZ3NbMF0sICJzb3VyY2UiKSkgewoJCWN1cnByb3h5LT5sYnBybS5hbGdvICY9IH5CRV9MQl9BTEdPOwoJCWN1cnByb3h5LT5sYnBybS5hbGdvIHw9IEJFX0xCX0FMR09fU0g7Cgl9CgllbHNlIGlmICghc3RyY21wKGFyZ3NbMF0sICJ1cmkiKSkgewoJCWludCBhcmcgPSAxOwoKCQljdXJwcm94eS0+bGJwcm0uYWxnbyAmPSB+QkVfTEJfQUxHTzsKCQljdXJwcm94eS0+bGJwcm0uYWxnbyB8PSBCRV9MQl9BTEdPX1VIOwoKCQl3aGlsZSAoKmFyZ3NbYXJnXSkgewoJCQlpZiAoIXN0cmNtcChhcmdzW2FyZ10sICJsZW4iKSkgewoJCQkJaWYgKCEqYXJnc1thcmcrMV0gfHwgKGF0b2koYXJnc1thcmcrMV0pIDw9IDApKSB7CgkJCQkJc25wcmludGYoZXJyLCBlcnJsZW4sICInYmFsYW5jZSB1cmkgbGVuJyBleHBlY3RzIGEgcG9zaXRpdmUgaW50ZWdlciAoZ290ICclcycpLiIsIGFyZ3NbYXJnKzFdKTsKCQkJCQlyZXR1cm4gLTE7CgkJCQl9CgkJCQljdXJwcm94eS0+dXJpX2xlbl9saW1pdCA9IGF0b2koYXJnc1thcmcrMV0pOwoJCQkJYXJnICs9IDI7CgkJCX0KCQkJZWxzZSBpZiAoIXN0cmNtcChhcmdzW2FyZ10sICJkZXB0aCIpKSB7CgkJCQlpZiAoISphcmdzW2FyZysxXSB8fCAoYXRvaShhcmdzW2FyZysxXSkgPD0gMCkpIHsKCQkJCQlzbnByaW50ZihlcnIsIGVycmxlbiwgIidiYWxhbmNlIHVyaSBkZXB0aCcgZXhwZWN0cyBhIHBvc2l0aXZlIGludGVnZXIgKGdvdCAnJXMnKS4iLCBhcmdzW2FyZysxXSk7CgkJCQkJcmV0dXJuIC0xOwoJCQkJfQoJCQkJLyogaGludDogd2Ugc3RvcmUgdGhlIHBvc2l0aW9uIG9mIHRoZSBlbmRpbmcgJy8nIChkZXB0aCsxKSBzbwoJCQkJICogdGhhdCB3ZSBhdm9pZCBhIGNvbXBhcmlzb24gd2hpbGUgY29tcHV0aW5nIHRoZSBoYXNoLgoJCQkJICovCgkJCQljdXJwcm94eS0+dXJpX2RpcnNfZGVwdGgxID0gYXRvaShhcmdzW2FyZysxXSkgKyAxOwoJCQkJYXJnICs9IDI7CgkJCX0KCQkJZWxzZSB7CgkJCQlzbnByaW50ZihlcnIsIGVycmxlbiwgIidiYWxhbmNlIHVyaScgb25seSBhY2NlcHRzIHBhcmFtZXRlcnMgJ2xlbicgYW5kICdkZXB0aCcgKGdvdCAnJXMnKS4iLCBhcmdzW2FyZ10pOwoJCQkJcmV0dXJuIC0xOwoJCQl9CgkJfQoJfQoJZWxzZSBpZiAoIXN0cmNtcChhcmdzWzBdLCAidXJsX3BhcmFtIikpIHsKCQlpZiAoISphcmdzWzFdKSB7CgkJCXNucHJpbnRmKGVyciwgZXJybGVuLCAiJ2JhbGFuY2UgdXJsX3BhcmFtJyByZXF1aXJlcyBhbiBVUkwgcGFyYW1ldGVyIG5hbWUuIik7CgkJCXJldHVybiAtMTsKCQl9CgkJY3VycHJveHktPmxicHJtLmFsZ28gJj0gfkJFX0xCX0FMR087CgkJY3VycHJveHktPmxicHJtLmFsZ28gfD0gQkVfTEJfQUxHT19QSDsKCgkJZnJlZShjdXJwcm94eS0+dXJsX3BhcmFtX25hbWUpOwoJCWN1cnByb3h5LT51cmxfcGFyYW1fbmFtZSA9IHN0cmR1cChhcmdzWzFdKTsKCQljdXJwcm94eS0+dXJsX3BhcmFtX2xlbiAgPSBzdHJsZW4oYXJnc1sxXSk7CgkJaWYgKCphcmdzWzJdKSB7CgkJCWlmIChzdHJjbXAoYXJnc1syXSwgImNoZWNrX3Bvc3QiKSkgewoJCQkJc25wcmludGYoZXJyLCBlcnJsZW4sICInYmFsYW5jZSB1cmxfcGFyYW0nIG9ubHkgYWNjZXB0cyBjaGVja19wb3N0IG1vZGlmaWVyLiIpOwoJCQkJcmV0dXJuIC0xOwoJCQl9CgkJCWlmICgqYXJnc1szXSkgewoJCQkJLyogVE9ETzogbWF5YmUgaXNzdWUgYSB3YXJuaW5nIGlmIHRoZXJlIGlzIG5vIHZhbHVlLCBubyBkaWdpdHMgb3IgdG9vIGxvbmcgKi8KCQkJCWN1cnByb3h5LT51cmxfcGFyYW1fcG9zdF9saW1pdCA9IHN0cjJ1aShhcmdzWzNdKTsKCQkJfQoJCQkvKiBpZiBubyBsaW1pdCwgb3IgZmF1bCB2YWx1ZSBpbiBhcmdzWzNdLCB0aGVuIGRlZmF1bHQgdG8gYSBtb2RlcmF0ZSB3b3JkbGVuICovCgkJCWlmICghY3VycHJveHktPnVybF9wYXJhbV9wb3N0X2xpbWl0KQoJCQkJY3VycHJveHktPnVybF9wYXJhbV9wb3N0X2xpbWl0ID0gNDg7CgkJCWVsc2UgaWYgKCBjdXJwcm94eS0+dXJsX3BhcmFtX3Bvc3RfbGltaXQgPCAzICkKCQkJCWN1cnByb3h5LT51cmxfcGFyYW1fcG9zdF9saW1pdCA9IDM7IC8qIG1pbmltdW0gZXhhbXBsZTogUz0zIG9yIFxyXG5TPTYmICovCgkJfQoJfQoJZWxzZSB7CgkJc25wcmludGYoZXJyLCBlcnJsZW4sICInYmFsYW5jZScgb25seSBzdXBwb3J0cyAncm91bmRyb2JpbicsICdsZWFzdGNvbm4nLCAnc291cmNlJywgJ3VyaScgYW5kICd1cmxfcGFyYW0nIG9wdGlvbnMuIik7CgkJcmV0dXJuIC0xOwoJfQoJcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICBBbGwgc3VwcG9ydGVkIGtleXdvcmRzIG11c3QgYmUgZGVjbGFyZWQgaGVyZS4gICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogc2V0IHRlc3QtPmkgdG8gdGhlIG51bWJlciBvZiBlbmFibGVkIHNlcnZlcnMgb24gdGhlIHByb3h5ICovCnN0YXRpYyBpbnQKYWNsX2ZldGNoX25ic3J2KHN0cnVjdCBwcm94eSAqcHgsIHN0cnVjdCBzZXNzaW9uICpsNCwgdm9pZCAqbDcsIGludCBkaXIsCiAgICAgICAgICAgICAgICBzdHJ1Y3QgYWNsX2V4cHIgKmV4cHIsIHN0cnVjdCBhY2xfdGVzdCAqdGVzdCkKewoJdGVzdC0+ZmxhZ3MgPSBBQ0xfVEVTVF9GX1ZPTF9URVNUOwoJaWYgKGV4cHItPmFyZ19sZW4pIHsKCQkvKiBhbm90aGVyIHByb3h5IHdhcyBkZXNpZ25hdGVkLCB3ZSBtdXN0IGxvb2sgZm9yIGl0ICovCgkJZm9yIChweCA9IHByb3h5OyBweDsgcHggPSBweC0+bmV4dCkKCQkJaWYgKChweC0+Y2FwICYgUFJfQ0FQX0JFKSAmJiAhc3RyY21wKHB4LT5pZCwgZXhwci0+YXJnLnN0cikpCgkJCQlicmVhazsKCX0KCWlmICghcHgpCgkJcmV0dXJuIDA7CgoJaWYgKHB4LT5zcnZfYWN0KQoJCXRlc3QtPmkgPSBweC0+c3J2X2FjdDsKCWVsc2UgaWYgKHB4LT5sYnBybS5mYmNrKQoJCXRlc3QtPmkgPSAxOwoJZWxzZQoJCXRlc3QtPmkgPSBweC0+c3J2X2JjazsKCglyZXR1cm4gMTsKfQoKLyogc2V0IHRlc3QtPmkgdG8gdGhlIG51bWJlciBvZiBlbmFibGVkIHNlcnZlcnMgb24gdGhlIHByb3h5ICovCnN0YXRpYyBpbnQKYWNsX2ZldGNoX2Nvbm5zbG90cyhzdHJ1Y3QgcHJveHkgKnB4LCBzdHJ1Y3Qgc2Vzc2lvbiAqbDQsIHZvaWQgKmw3LCBpbnQgZGlyLAoJCSAgICBzdHJ1Y3QgYWNsX2V4cHIgKmV4cHIsIHN0cnVjdCBhY2xfdGVzdCAqdGVzdCkKewoJc3RydWN0IHNlcnZlciAqaXRlcmF0b3I7Cgl0ZXN0LT5mbGFncyA9IEFDTF9URVNUX0ZfVk9MX1RFU1Q7CglpZiAoZXhwci0+YXJnX2xlbikgewoJCS8qIGFub3RoZXIgcHJveHkgd2FzIGRlc2lnbmF0ZWQsIHdlIG11c3QgbG9vayBmb3IgaXQgKi8KCQlmb3IgKHB4ID0gcHJveHk7IHB4OyBweCA9IHB4LT5uZXh0KQoJCQlpZiAoKHB4LT5jYXAgJiBQUl9DQVBfQkUpICYmICFzdHJjbXAocHgtPmlkLCBleHByLT5hcmcuc3RyKSkKCQkJCWJyZWFrOwoJfQoJaWYgKCFweCkKCQlyZXR1cm4gMDsKCgl0ZXN0LT5pID0gMDsKCWl0ZXJhdG9yID0gcHgtPnNydjsKCXdoaWxlIChpdGVyYXRvcikgewoJCWlmICgoaXRlcmF0b3ItPnN0YXRlICYgMSkgPT0gMCkgewoJCQlpdGVyYXRvciA9IGl0ZXJhdG9yLT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJaWYgKGl0ZXJhdG9yLT5tYXhjb25uID09IDAgfHwgaXRlcmF0b3ItPm1heHF1ZXVlID09IDApIHsKCQkJdGVzdC0+aSA9IC0xOwoJCQlyZXR1cm4gMTsKCQl9CgoJCXRlc3QtPmkgKz0gKGl0ZXJhdG9yLT5tYXhjb25uIC0gaXRlcmF0b3ItPmN1cl9zZXNzKQoJCQkrICAoaXRlcmF0b3ItPm1heHF1ZXVlIC0gaXRlcmF0b3ItPm5icGVuZCk7CgkJaXRlcmF0b3IgPSBpdGVyYXRvci0+bmV4dDsKCX0KCglyZXR1cm4gMTsKfQoKCi8qIE5vdGU6IG11c3Qgbm90IGJlIGRlY2xhcmVkIDxjb25zdD4gYXMgaXRzIGxpc3Qgd2lsbCBiZSBvdmVyd3JpdHRlbiAqLwpzdGF0aWMgc3RydWN0IGFjbF9rd19saXN0IGFjbF9rd3MgPSB7eyB9LHsKCXsgIm5ic3J2IiwgICAgYWNsX3BhcnNlX2ludCwgICBhY2xfZmV0Y2hfbmJzcnYsICAgICBhY2xfbWF0Y2hfaW50LCBBQ0xfVVNFX05PVEhJTkcgfSwKCXsgImNvbm5sb3RzIiwgYWNsX3BhcnNlX2ludCwgICBhY2xfZmV0Y2hfY29ubnNsb3RzLCBhY2xfbWF0Y2hfaW50LCBBQ0xfVVNFX05PVEhJTkcgfSwKCXsgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCB9LAp9fTsKCgpfX2F0dHJpYnV0ZV9fKChjb25zdHJ1Y3RvcikpCnN0YXRpYyB2b2lkIF9fYmFja2VuZF9pbml0KHZvaWQpCnsKCWFjbF9yZWdpc3Rlcl9rZXl3b3JkcygmYWNsX2t3cyk7Cn0KCgovKgogKiBMb2NhbCB2YXJpYWJsZXM6CiAqICBjLWluZGVudC1sZXZlbDogOAogKiAgYy1iYXNpYy1vZmZzZXQ6IDgKICogRW5kOgogKi8K