LyoKICogSUJNIEFTTSBTZXJ2aWNlIFByb2Nlc3NvciBEZXZpY2UgRHJpdmVyCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuCiAqCiAqIENvcHlyaWdodCAoQykgSUJNIENvcnBvcmF0aW9uLCAyMDA0CiAqCiAqIEF1dGhvcjogTWF4IEFzYvZjayA8YW1heEB1cy5pYm0uY29tPiAKICoKICovCgovKgogKiBQYXJ0cyBvZiB0aGlzIGNvZGUgYXJlIGJhc2VkIG9uIGFuIGFydGljbGUgYnkgSm9uYXRoYW4gQ29yYmV0IAogKiB0aGF0IGFwcGVhcmVkIGluIExpbnV4IFdlZWtseSBOZXdzLgogKi8KCgovKgogKiBUaGUgSUJNQVNNIGZpbGUgdmlydHVhbCBmaWxlc3lzdGVtLiBJdCBjcmVhdGVzIHRoZSBmb2xsb3dpbmcgaGllcmFyY2h5CiAqIGR5bWFtaWNhbGx5IHdoZW4gbW91bnRlZCBmcm9tIHVzZXIgc3BhY2U6CiAqCiAqICAgIC9pYm1hc20KICogICAgfC0tIDAKICogICAgfCAgIHwtLSBjb21tYW5kCiAqICAgIHwgICB8LS0gZXZlbnQKICogICAgfCAgIHwtLSByZXZlcnNlX2hlYXJ0YmVhdAogKiAgICB8ICAgYC0tIHJlbW90ZV92aWRlbwogKiAgICB8ICAgICAgIHwtLSBkZXB0aAogKiAgICB8ICAgICAgIHwtLSBoZWlnaHQKICogICAgfCAgICAgICBgLS0gd2lkdGgKICogICAgLgogKiAgICAuCiAqICAgIC4KICogICAgYC0tIG4KICogICAgICAgIHwtLSBjb21tYW5kCiAqICAgICAgICB8LS0gZXZlbnQKICogICAgICAgIHwtLSByZXZlcnNlX2hlYXJ0YmVhdAogKiAgICAgICAgYC0tIHJlbW90ZV92aWRlbwogKiAgICAgICAgICAgIHwtLSBkZXB0aAogKiAgICAgICAgICAgIHwtLSBoZWlnaHQKICogICAgICAgICAgICBgLS0gd2lkdGgKICoKICogRm9yIGVhY2ggc2VydmljZSBwcm9jZXNzb3IgdGhlIGZvbGxvd2luZyBmaWxlcyBhcmUgY3JlYXRlZDoKICoKICogY29tbWFuZDogZXhlY3V0ZSBkb3QgY29tbWFuZHMKICogCXdyaXRlOiBleGVjdXRlIGEgZG90IGNvbW1hbmQgb24gdGhlIHNlcnZpY2UgcHJvY2Vzc29yCiAqIAlyZWFkOiByZXR1cm4gdGhlIHJlc3VsdCBvZiBhIHByZXZpb3VzbHkgZXhlY3V0ZWQgZG90IGNvbW1hbmQKICoKICogZXZlbnRzOiBsaXN0ZW4gZm9yIHNlcnZpY2UgcHJvY2Vzc29yIGV2ZW50cwogKiAJcmVhZDogc2xlZXAgKGludGVycnVwdGlibGUpIHVudGlsIGFuIGV2ZW50IG9jY3VycwogKiAgICAgIHdyaXRlOiB3YWtldXAgc2xlZXBpbmcgZXZlbnQgbGlzdGVuZXIKICoKICogcmV2ZXJzZV9oZWFydGJlYXQ6IHNlbmQgYSBoZWFydGJlYXQgdG8gdGhlIHNlcnZpY2UgcHJvY2Vzc29yCiAqIAlyZWFkOiBzbGVlcCAoaW50ZXJydXB0aWJsZSkgdW50aWwgdGhlIHJldmVyc2UgaGVhcnRiZWF0IGZhaWxzCiAqICAgICAgd3JpdGU6IHdha2V1cCBzbGVlcGluZyBoZWFydGJlYXQgbGlzdGVuZXIKICoKICogcmVtb3RlX3ZpZGVvL3dpZHRoCiAqIHJlbW90ZV92aWRlby9oZWlnaHQKICogcmVtb3RlX3ZpZGVvL3dpZHRoOiBjb250cm9sIHJlbW90ZSBkaXNwbGF5IHNldHRpbmdzCiAqIAl3cml0ZTogc2V0IHZhbHVlCiAqIAlyZWFkOiByZWFkIHZhbHVlCiAqLwoKI2luY2x1ZGUgPGxpbnV4L2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9wYWdlbWFwLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlICJpYm1hc20uaCIKI2luY2x1ZGUgInJlbW90ZS5oIgojaW5jbHVkZSAiZG90X2NvbW1hbmQuaCIKCiNkZWZpbmUgSUJNQVNNRlNfTUFHSUMgMHg2NjcyNmY2NwoKc3RhdGljIExJU1RfSEVBRChzZXJ2aWNlX3Byb2Nlc3NvcnMpOwoKc3RhdGljIHN0cnVjdCBpbm9kZSAqaWJtYXNtZnNfbWFrZV9pbm9kZShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCBpbnQgbW9kZSk7CnN0YXRpYyB2b2lkIGlibWFzbWZzX2NyZWF0ZV9maWxlcyAoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwgc3RydWN0IGRlbnRyeSAqcm9vdCk7CnN0YXRpYyBpbnQgaWJtYXNtZnNfZmlsbF9zdXBlciAoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwgdm9pZCAqZGF0YSwgaW50IHNpbGVudCk7CgoKc3RhdGljIHN0cnVjdCBzdXBlcl9ibG9jayAqaWJtYXNtZnNfZ2V0X3N1cGVyKHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc3QsCgkJCWludCBmbGFncywgY29uc3QgY2hhciAqbmFtZSwgdm9pZCAqZGF0YSkKewoJcmV0dXJuIGdldF9zYl9zaW5nbGUoZnN0LCBmbGFncywgZGF0YSwgaWJtYXNtZnNfZmlsbF9zdXBlcik7Cn0KCnN0YXRpYyBzdHJ1Y3Qgc3VwZXJfb3BlcmF0aW9ucyBpYm1hc21mc19zX29wcyA9IHsKCS5zdGF0ZnMJCT0gc2ltcGxlX3N0YXRmcywKCS5kcm9wX2lub2RlCT0gZ2VuZXJpY19kZWxldGVfaW5vZGUsCn07CgpzdGF0aWMgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyAqaWJtYXNtZnNfZGlyX29wcyA9ICZzaW1wbGVfZGlyX29wZXJhdGlvbnM7CgpzdGF0aWMgc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgaWJtYXNtZnNfdHlwZSA9IHsKCS5vd25lciAgICAgICAgICA9IFRISVNfTU9EVUxFLAoJLm5hbWUgICAgICAgICAgID0gImlibWFzbWZzIiwKCS5nZXRfc2IgICAgICAgICA9IGlibWFzbWZzX2dldF9zdXBlciwKCS5raWxsX3NiICAgICAgICA9IGtpbGxfbGl0dGVyX3N1cGVyLAp9OwoKc3RhdGljIGludCBpYm1hc21mc19maWxsX3N1cGVyIChzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCB2b2lkICpkYXRhLCBpbnQgc2lsZW50KQp7CglzdHJ1Y3QgaW5vZGUgKnJvb3Q7CglzdHJ1Y3QgZGVudHJ5ICpyb290X2RlbnRyeTsKCglzYi0+c19ibG9ja3NpemUgPSBQQUdFX0NBQ0hFX1NJWkU7CglzYi0+c19ibG9ja3NpemVfYml0cyA9IFBBR0VfQ0FDSEVfU0hJRlQ7CglzYi0+c19tYWdpYyA9IElCTUFTTUZTX01BR0lDOwoJc2ItPnNfb3AgPSAmaWJtYXNtZnNfc19vcHM7CglzYi0+c190aW1lX2dyYW4gPSAxOwoKCXJvb3QgPSBpYm1hc21mc19tYWtlX2lub2RlIChzYiwgU19JRkRJUiB8IDA1MDApOwoJaWYgKCFyb290KQoJCXJldHVybiAtRU5PTUVNOwoKCXJvb3QtPmlfb3AgPSAmc2ltcGxlX2Rpcl9pbm9kZV9vcGVyYXRpb25zOwoJcm9vdC0+aV9mb3AgPSBpYm1hc21mc19kaXJfb3BzOwoKCXJvb3RfZGVudHJ5ID0gZF9hbGxvY19yb290KHJvb3QpOwoJaWYgKCFyb290X2RlbnRyeSkgewoJCWlwdXQocm9vdCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CglzYi0+c19yb290ID0gcm9vdF9kZW50cnk7CgoJaWJtYXNtZnNfY3JlYXRlX2ZpbGVzKHNiLCByb290X2RlbnRyeSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBpbm9kZSAqaWJtYXNtZnNfbWFrZV9pbm9kZShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCBpbnQgbW9kZSkKewoJc3RydWN0IGlub2RlICpyZXQgPSBuZXdfaW5vZGUoc2IpOwoKCWlmIChyZXQpIHsKCQlyZXQtPmlfbW9kZSA9IG1vZGU7CgkJcmV0LT5pX3VpZCA9IHJldC0+aV9naWQgPSAwOwoJCXJldC0+aV9ibGtzaXplID0gUEFHRV9DQUNIRV9TSVpFOwoJCXJldC0+aV9ibG9ja3MgPSAwOwoJCXJldC0+aV9hdGltZSA9IHJldC0+aV9tdGltZSA9IHJldC0+aV9jdGltZSA9IENVUlJFTlRfVElNRTsKCX0KCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBzdHJ1Y3QgZGVudHJ5ICppYm1hc21mc19jcmVhdGVfZmlsZSAoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwKCQkJc3RydWN0IGRlbnRyeSAqcGFyZW50LAoJCSAgICAgICAJY29uc3QgY2hhciAqbmFtZSwKCQkJc3RydWN0IGZpbGVfb3BlcmF0aW9ucyAqZm9wcywKCQkJdm9pZCAqZGF0YSwKCQkJaW50IG1vZGUpCnsKCXN0cnVjdCBkZW50cnkgKmRlbnRyeTsKCXN0cnVjdCBpbm9kZSAqaW5vZGU7CgoJZGVudHJ5ID0gZF9hbGxvY19uYW1lKHBhcmVudCwgbmFtZSk7CglpZiAoIWRlbnRyeSkKCQlyZXR1cm4gTlVMTDsKCglpbm9kZSA9IGlibWFzbWZzX21ha2VfaW5vZGUoc2IsIFNfSUZSRUcgfCBtb2RlKTsKCWlmICghaW5vZGUpIHsKCQlkcHV0KGRlbnRyeSk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJaW5vZGUtPmlfZm9wID0gZm9wczsKCWlub2RlLT51LmdlbmVyaWNfaXAgPSBkYXRhOwoKCWRfYWRkKGRlbnRyeSwgaW5vZGUpOwoJcmV0dXJuIGRlbnRyeTsKfQoKc3RhdGljIHN0cnVjdCBkZW50cnkgKmlibWFzbWZzX2NyZWF0ZV9kaXIgKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsCgkJCQlzdHJ1Y3QgZGVudHJ5ICpwYXJlbnQsCgkJCQljb25zdCBjaGFyICpuYW1lKQp7CglzdHJ1Y3QgZGVudHJ5ICpkZW50cnk7CglzdHJ1Y3QgaW5vZGUgKmlub2RlOwoKCWRlbnRyeSA9IGRfYWxsb2NfbmFtZShwYXJlbnQsIG5hbWUpOwoJaWYgKCFkZW50cnkpCgkJcmV0dXJuIE5VTEw7CgoJaW5vZGUgPSBpYm1hc21mc19tYWtlX2lub2RlKHNiLCBTX0lGRElSIHwgMDUwMCk7CglpZiAoIWlub2RlKSB7CgkJZHB1dChkZW50cnkpOwoJCXJldHVybiBOVUxMOwoJfQoKCWlub2RlLT5pX29wID0gJnNpbXBsZV9kaXJfaW5vZGVfb3BlcmF0aW9uczsKCWlub2RlLT5pX2ZvcCA9IGlibWFzbWZzX2Rpcl9vcHM7CgoJZF9hZGQoZGVudHJ5LCBpbm9kZSk7CglyZXR1cm4gZGVudHJ5Owp9CgppbnQgaWJtYXNtZnNfcmVnaXN0ZXIodm9pZCkKewoJcmV0dXJuIHJlZ2lzdGVyX2ZpbGVzeXN0ZW0oJmlibWFzbWZzX3R5cGUpOwp9Cgp2b2lkIGlibWFzbWZzX3VucmVnaXN0ZXIodm9pZCkKewoJdW5yZWdpc3Rlcl9maWxlc3lzdGVtKCZpYm1hc21mc190eXBlKTsKfQoKdm9pZCBpYm1hc21mc19hZGRfc3Aoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJbGlzdF9hZGQoJnNwLT5ub2RlLCAmc2VydmljZV9wcm9jZXNzb3JzKTsKfQoKLyogc3RydWN0IHRvIHNhdmUgc3RhdGUgYmV0d2VlbiBjb21tYW5kIGZpbGUgb3BlcmF0aW9ucyAqLwpzdHJ1Y3QgaWJtYXNtZnNfY29tbWFuZF9kYXRhIHsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3Nvcgkqc3A7CglzdHJ1Y3QgY29tbWFuZAkJCSpjb21tYW5kOwp9OwoKLyogc3RydWN0IHRvIHNhdmUgc3RhdGUgYmV0d2VlbiBldmVudCBmaWxlIG9wZXJhdGlvbnMgKi8Kc3RydWN0IGlibWFzbWZzX2V2ZW50X2RhdGEgewoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yCSpzcDsKCXN0cnVjdCBldmVudF9yZWFkZXIJCXJlYWRlcjsKCWludAkJCQlhY3RpdmU7Cn07CgovKiBzdHJ1Y3QgdG8gc2F2ZSBzdGF0ZSBiZXR3ZWVuIHJldmVyc2UgaGVhcnRiZWF0IGZpbGUgb3BlcmF0aW9ucyAqLwpzdHJ1Y3QgaWJtYXNtZnNfaGVhcnRiZWF0X2RhdGEgewoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yCSpzcDsKCXN0cnVjdCByZXZlcnNlX2hlYXJ0YmVhdAloZWFydGJlYXQ7CglpbnQJCQkJYWN0aXZlOwp9OwoKc3RhdGljIGludCBjb21tYW5kX2ZpbGVfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IGlibWFzbWZzX2NvbW1hbmRfZGF0YSAqY29tbWFuZF9kYXRhOwoKCWlmICghaW5vZGUtPnUuZ2VuZXJpY19pcCkKCQlyZXR1cm4gLUVOT0RFVjsKCgljb21tYW5kX2RhdGEgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgaWJtYXNtZnNfY29tbWFuZF9kYXRhKSwgR0ZQX0tFUk5FTCk7CglpZiAoIWNvbW1hbmRfZGF0YSkKCQlyZXR1cm4gLUVOT01FTTsKCgljb21tYW5kX2RhdGEtPmNvbW1hbmQgPSBOVUxMOwoJY29tbWFuZF9kYXRhLT5zcCA9IGlub2RlLT51LmdlbmVyaWNfaXA7CglmaWxlLT5wcml2YXRlX2RhdGEgPSBjb21tYW5kX2RhdGE7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBjb21tYW5kX2ZpbGVfY2xvc2Uoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEgKmNvbW1hbmRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglpZiAoY29tbWFuZF9kYXRhLT5jb21tYW5kKQoJCWNvbW1hbmRfcHV0KGNvbW1hbmRfZGF0YS0+Y29tbWFuZCk7CQoKCWtmcmVlKGNvbW1hbmRfZGF0YSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHNzaXplX3QgY29tbWFuZF9maWxlX3JlYWQoc3RydWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEgKmNvbW1hbmRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBjb21tYW5kICpjbWQ7CglpbnQgbGVuOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IElCTUFTTV9DTURfTUFYX0JVRkZFUl9TSVpFKQoJCXJldHVybiAwOwoJaWYgKCpvZmZzZXQgIT0gMCkKCQlyZXR1cm4gMDsKCglzcGluX2xvY2tfaXJxc2F2ZSgmY29tbWFuZF9kYXRhLT5zcC0+bG9jaywgZmxhZ3MpOwoJY21kID0gY29tbWFuZF9kYXRhLT5jb21tYW5kOwoJaWYgKGNtZCA9PSBOVUxMKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29tbWFuZF9kYXRhLT5zcC0+bG9jaywgZmxhZ3MpOwoJCXJldHVybiAwOwoJfQoJY29tbWFuZF9kYXRhLT5jb21tYW5kID0gTlVMTDsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbW1hbmRfZGF0YS0+c3AtPmxvY2ssIGZsYWdzKTsKCglpZiAoY21kLT5zdGF0dXMgIT0gSUJNQVNNX0NNRF9DT01QTEVURSkgewoJCWNvbW1hbmRfcHV0KGNtZCk7CgkJcmV0dXJuIC1FSU87Cgl9CglsZW4gPSBtaW4oY291bnQsIGNtZC0+YnVmZmVyX3NpemUpOwoJaWYgKGNvcHlfdG9fdXNlcihidWYsIGNtZC0+YnVmZmVyLCBsZW4pKSB7CgkJY29tbWFuZF9wdXQoY21kKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCWNvbW1hbmRfcHV0KGNtZCk7CgoJcmV0dXJuIGxlbjsKfQoKc3RhdGljIHNzaXplX3QgY29tbWFuZF9maWxlX3dyaXRlKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqdWJ1ZmYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEgKmNvbW1hbmRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBjb21tYW5kICpjbWQ7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCA9PSAwIHx8IGNvdW50ID4gSUJNQVNNX0NNRF9NQVhfQlVGRkVSX1NJWkUpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCS8qIGNvbW1hbmRzIGFyZSBleGVjdXRlZCBzZXF1ZW50aWFsbHksIG9ubHkgb25lIGNvbW1hbmQgYXQgYSB0aW1lICovCglpZiAoY29tbWFuZF9kYXRhLT5jb21tYW5kKQoJCXJldHVybiAtRUFHQUlOOwoKCWNtZCA9IGlibWFzbV9uZXdfY29tbWFuZChjb3VudCk7CglpZiAoIWNtZCkKCQlyZXR1cm4gLUVOT01FTTsKCglpZiAoY29weV9mcm9tX3VzZXIoY21kLT5idWZmZXIsIHVidWZmLCBjb3VudCkpIHsKCQljb21tYW5kX3B1dChjbWQpOwoJCXJldHVybiAtRUZBVUxUOwoJfQoKCXNwaW5fbG9ja19pcnFzYXZlKCZjb21tYW5kX2RhdGEtPnNwLT5sb2NrLCBmbGFncyk7CglpZiAoY29tbWFuZF9kYXRhLT5jb21tYW5kKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29tbWFuZF9kYXRhLT5zcC0+bG9jaywgZmxhZ3MpOwoJCWNvbW1hbmRfcHV0KGNtZCk7CgkJcmV0dXJuIC1FQUdBSU47Cgl9Cgljb21tYW5kX2RhdGEtPmNvbW1hbmQgPSBjbWQ7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb21tYW5kX2RhdGEtPnNwLT5sb2NrLCBmbGFncyk7CgoJaWJtYXNtX2V4ZWNfY29tbWFuZChjb21tYW5kX2RhdGEtPnNwLCBjbWQpOwoJaWJtYXNtX3dhaXRfZm9yX3Jlc3BvbnNlKGNtZCwgZ2V0X2RvdF9jb21tYW5kX3RpbWVvdXQoY21kLT5idWZmZXIpKTsKCglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyBpbnQgZXZlbnRfZmlsZV9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSAqZXZlbnRfZGF0YTsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3A7IAoKCWlmICghaW5vZGUtPnUuZ2VuZXJpY19pcCkKCQlyZXR1cm4gLUVOT0RFVjsKCglzcCA9IGlub2RlLT51LmdlbmVyaWNfaXA7CgoJZXZlbnRfZGF0YSA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBpYm1hc21mc19ldmVudF9kYXRhKSwgR0ZQX0tFUk5FTCk7CglpZiAoIWV2ZW50X2RhdGEpCgkJcmV0dXJuIC1FTk9NRU07CgoJaWJtYXNtX2V2ZW50X3JlYWRlcl9yZWdpc3RlcihzcCwgJmV2ZW50X2RhdGEtPnJlYWRlcik7CgoJZXZlbnRfZGF0YS0+c3AgPSBzcDsKCWV2ZW50X2RhdGEtPmFjdGl2ZSA9IDA7CglmaWxlLT5wcml2YXRlX2RhdGEgPSBldmVudF9kYXRhOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgZXZlbnRfZmlsZV9jbG9zZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IGlibWFzbWZzX2V2ZW50X2RhdGEgKmV2ZW50X2RhdGEgPSBmaWxlLT5wcml2YXRlX2RhdGE7CgoJaWJtYXNtX2V2ZW50X3JlYWRlcl91bnJlZ2lzdGVyKGV2ZW50X2RhdGEtPnNwLCAmZXZlbnRfZGF0YS0+cmVhZGVyKTsKCWtmcmVlKGV2ZW50X2RhdGEpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzc2l6ZV90IGV2ZW50X2ZpbGVfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJc3RydWN0IGlibWFzbWZzX2V2ZW50X2RhdGEgKmV2ZW50X2RhdGEgPSBmaWxlLT5wcml2YXRlX2RhdGE7CglzdHJ1Y3QgZXZlbnRfcmVhZGVyICpyZWFkZXIgPSAmZXZlbnRfZGF0YS0+cmVhZGVyOwoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCA9IGV2ZW50X2RhdGEtPnNwOwoJaW50IHJldDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJaWYgKCpvZmZzZXQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvdW50ID09IDAgfHwgY291bnQgPiBJQk1BU01fRVZFTlRfTUFYX1NJWkUpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZzcC0+bG9jaywgZmxhZ3MpOwoJaWYgKGV2ZW50X2RhdGEtPmFjdGl2ZSkgewoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCWV2ZW50X2RhdGEtPmFjdGl2ZSA9IDE7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzcC0+bG9jaywgZmxhZ3MpOwoKCXJldCA9IGlibWFzbV9nZXRfbmV4dF9ldmVudChzcCwgcmVhZGVyKTsKCWlmIChyZXQgPD0gMCkKCQlnb3RvIG91dDsKCglpZiAoY291bnQgPCByZWFkZXItPmRhdGFfc2l6ZSkgewoJCXJldCA9IC1FSU5WQUw7CgkJZ290byBvdXQ7Cgl9CgogICAgICAgIGlmIChjb3B5X3RvX3VzZXIoYnVmLCByZWFkZXItPmRhdGEsIHJlYWRlci0+ZGF0YV9zaXplKSkgewoJCXJldCA9IC1FRkFVTFQ7CgkJZ290byBvdXQ7Cgl9CglyZXQgPSByZWFkZXItPmRhdGFfc2l6ZTsKCm91dDoKCWV2ZW50X2RhdGEtPmFjdGl2ZSA9IDA7CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgc3NpemVfdCBldmVudF9maWxlX3dyaXRlKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7CglzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSAqZXZlbnRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgIT0gMSkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJaWJtYXNtX2NhbmNlbF9uZXh0X2V2ZW50KCZldmVudF9kYXRhLT5yZWFkZXIpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcl9oZWFydGJlYXRfZmlsZV9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfaGVhcnRiZWF0X2RhdGEgKnJoYmVhdDsKCglpZiAoIWlub2RlLT51LmdlbmVyaWNfaXApCgkJcmV0dXJuIC1FTk9ERVY7CgoJcmhiZWF0ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IGlibWFzbWZzX2hlYXJ0YmVhdF9kYXRhKSwgR0ZQX0tFUk5FTCk7CglpZiAoIXJoYmVhdCkKCQlyZXR1cm4gLUVOT01FTTsKCglyaGJlYXQtPnNwID0gKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqKWlub2RlLT51LmdlbmVyaWNfaXA7CglyaGJlYXQtPmFjdGl2ZSA9IDA7CglpYm1hc21faW5pdF9yZXZlcnNlX2hlYXJ0YmVhdChyaGJlYXQtPnNwLCAmcmhiZWF0LT5oZWFydGJlYXQpOwoJZmlsZS0+cHJpdmF0ZV9kYXRhID0gcmhiZWF0OwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcl9oZWFydGJlYXRfZmlsZV9jbG9zZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IGlibWFzbWZzX2hlYXJ0YmVhdF9kYXRhICpyaGJlYXQgPSBmaWxlLT5wcml2YXRlX2RhdGE7CgoJa2ZyZWUocmhiZWF0KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgc3NpemVfdCByX2hlYXJ0YmVhdF9maWxlX3JlYWQoc3RydWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXN0cnVjdCBpYm1hc21mc19oZWFydGJlYXRfZGF0YSAqcmhiZWF0ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCByZXN1bHQ7CgoJaWYgKCpvZmZzZXQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvdW50ID09IDAgfHwgY291bnQgPiAxMDI0KQoJCXJldHVybiAwOwoJaWYgKCpvZmZzZXQgIT0gMCkKCQlyZXR1cm4gMDsKCgkvKiBhbGxvdyBvbmx5IG9uZSByZXZlcnNlIGhlYXJ0YmVhdCBwZXIgcHJvY2VzcyAqLwoJc3Bpbl9sb2NrX2lycXNhdmUoJnJoYmVhdC0+c3AtPmxvY2ssIGZsYWdzKTsKCWlmIChyaGJlYXQtPmFjdGl2ZSkgewoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnJoYmVhdC0+c3AtPmxvY2ssIGZsYWdzKTsKCQlyZXR1cm4gLUVCVVNZOwoJfQoJcmhiZWF0LT5hY3RpdmUgPSAxOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcmhiZWF0LT5zcC0+bG9jaywgZmxhZ3MpOwoKCXJlc3VsdCA9IGlibWFzbV9zdGFydF9yZXZlcnNlX2hlYXJ0YmVhdChyaGJlYXQtPnNwLCAmcmhiZWF0LT5oZWFydGJlYXQpOwoJcmhiZWF0LT5hY3RpdmUgPSAwOwoKCXJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBzc2l6ZV90IHJfaGVhcnRiZWF0X2ZpbGVfd3JpdGUoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXN0cnVjdCBpYm1hc21mc19oZWFydGJlYXRfZGF0YSAqcmhiZWF0ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCAhPSAxKQoJCXJldHVybiAwOwoJaWYgKCpvZmZzZXQgIT0gMCkKCQlyZXR1cm4gMDsKCglpZiAocmhiZWF0LT5hY3RpdmUpCgkJaWJtYXNtX3N0b3BfcmV2ZXJzZV9oZWFydGJlYXQoJnJoYmVhdC0+aGVhcnRiZWF0KTsKCglyZXR1cm4gMTsKfQoKc3RhdGljIGludCByZW1vdGVfc2V0dGluZ3NfZmlsZV9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglmaWxlLT5wcml2YXRlX2RhdGEgPSBpbm9kZS0+dS5nZW5lcmljX2lwOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcmVtb3RlX3NldHRpbmdzX2ZpbGVfY2xvc2Uoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXJldHVybiAwOwp9CgpzdGF0aWMgc3NpemVfdCByZW1vdGVfc2V0dGluZ3NfZmlsZV9yZWFkKHN0cnVjdCBmaWxlICpmaWxlLCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7Cgl2b2lkIF9faW9tZW0gKmFkZHJlc3MgPSAodm9pZCBfX2lvbWVtICopZmlsZS0+cHJpdmF0ZV9kYXRhOwoJdW5zaWduZWQgY2hhciAqcGFnZTsKCWludCByZXR2YWw7CglpbnQgbGVuID0gMDsKCXVuc2lnbmVkIGludCB2YWx1ZTsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IDEwMjQpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCXBhZ2UgPSAodW5zaWduZWQgY2hhciAqKV9fZ2V0X2ZyZWVfcGFnZShHRlBfS0VSTkVMKTsKCWlmICghcGFnZSkKCQlyZXR1cm4gLUVOT01FTTsKCgl2YWx1ZSA9IHJlYWRsKGFkZHJlc3MpOwoJbGVuID0gc3ByaW50ZihwYWdlLCAiJWRcbiIsIHZhbHVlKTsKCglpZiAoY29weV90b191c2VyKGJ1ZiwgcGFnZSwgbGVuKSkgewoJCXJldHZhbCA9IC1FRkFVTFQ7CgkJZ290byBleGl0OwoJfQoJKm9mZnNldCArPSBsZW47CglyZXR2YWwgPSBsZW47CgpleGl0OgoJZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKXBhZ2UpOwoJcmV0dXJuIHJldHZhbDsKfQoKc3RhdGljIHNzaXplX3QgcmVtb3RlX3NldHRpbmdzX2ZpbGVfd3JpdGUoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICp1YnVmZiwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJdm9pZCBfX2lvbWVtICphZGRyZXNzID0gKHZvaWQgX19pb21lbSAqKWZpbGUtPnByaXZhdGVfZGF0YTsKCWNoYXIgKmJ1ZmY7Cgl1bnNpZ25lZCBpbnQgdmFsdWU7CgoJaWYgKCpvZmZzZXQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvdW50ID09IDAgfHwgY291bnQgPiAxMDI0KQoJCXJldHVybiAwOwoJaWYgKCpvZmZzZXQgIT0gMCkKCQlyZXR1cm4gMDsKCglidWZmID0ga21hbGxvYyAoY291bnQgKyAxLCBHRlBfS0VSTkVMKTsKCWlmICghYnVmZikKCQlyZXR1cm4gLUVOT01FTTsKCgltZW1zZXQoYnVmZiwgMHgwLCBjb3VudCArIDEpOwoKCWlmIChjb3B5X2Zyb21fdXNlcihidWZmLCB1YnVmZiwgY291bnQpKSB7CgkJa2ZyZWUoYnVmZik7CgkJcmV0dXJuIC1FRkFVTFQ7Cgl9CgkKCXZhbHVlID0gc2ltcGxlX3N0cnRvdWwoYnVmZiwgTlVMTCwgMTApOwoJd3JpdGVsKHZhbHVlLCBhZGRyZXNzKTsKCWtmcmVlKGJ1ZmYpOwoKCXJldHVybiBjb3VudDsKfQoKc3RhdGljIHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgY29tbWFuZF9mb3BzID0gewoJLm9wZW4gPQkJY29tbWFuZF9maWxlX29wZW4sCgkucmVsZWFzZSA9CWNvbW1hbmRfZmlsZV9jbG9zZSwKCS5yZWFkID0JCWNvbW1hbmRfZmlsZV9yZWFkLAoJLndyaXRlID0JY29tbWFuZF9maWxlX3dyaXRlLAp9OwoKc3RhdGljIHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgZXZlbnRfZm9wcyA9IHsKCS5vcGVuID0JCWV2ZW50X2ZpbGVfb3BlbiwKCS5yZWxlYXNlID0JZXZlbnRfZmlsZV9jbG9zZSwKCS5yZWFkID0JCWV2ZW50X2ZpbGVfcmVhZCwKCS53cml0ZSA9CWV2ZW50X2ZpbGVfd3JpdGUsCn07CgpzdGF0aWMgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyByX2hlYXJ0YmVhdF9mb3BzID0gewoJLm9wZW4gPQkJcl9oZWFydGJlYXRfZmlsZV9vcGVuLAoJLnJlbGVhc2UgPQlyX2hlYXJ0YmVhdF9maWxlX2Nsb3NlLAoJLnJlYWQgPQkJcl9oZWFydGJlYXRfZmlsZV9yZWFkLAoJLndyaXRlID0Jcl9oZWFydGJlYXRfZmlsZV93cml0ZSwKfTsKCnN0YXRpYyBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHJlbW90ZV9zZXR0aW5nc19mb3BzID0gewoJLm9wZW4gPQkJcmVtb3RlX3NldHRpbmdzX2ZpbGVfb3BlbiwKCS5yZWxlYXNlID0JcmVtb3RlX3NldHRpbmdzX2ZpbGVfY2xvc2UsCgkucmVhZCA9CQlyZW1vdGVfc2V0dGluZ3NfZmlsZV9yZWFkLAoJLndyaXRlID0JcmVtb3RlX3NldHRpbmdzX2ZpbGVfd3JpdGUsCn07CgoKc3RhdGljIHZvaWQgaWJtYXNtZnNfY3JlYXRlX2ZpbGVzIChzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCBzdHJ1Y3QgZGVudHJ5ICpyb290KQp7CglzdHJ1Y3QgbGlzdF9oZWFkICplbnRyeTsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3A7CgoJbGlzdF9mb3JfZWFjaChlbnRyeSwgJnNlcnZpY2VfcHJvY2Vzc29ycykgewoJCXN0cnVjdCBkZW50cnkgKmRpcjsKCQlzdHJ1Y3QgZGVudHJ5ICpyZW1vdGVfZGlyOwoJCXNwID0gbGlzdF9lbnRyeShlbnRyeSwgc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yLCBub2RlKTsKCQlkaXIgPSBpYm1hc21mc19jcmVhdGVfZGlyKHNiLCByb290LCBzcC0+ZGlybmFtZSk7CgkJaWYgKCFkaXIpCgkJCWNvbnRpbnVlOwoKCQlpYm1hc21mc19jcmVhdGVfZmlsZShzYiwgZGlyLCAiY29tbWFuZCIsICZjb21tYW5kX2ZvcHMsIHNwLCBTX0lSVVNSfFNfSVdVU1IpOwoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCBkaXIsICJldmVudCIsICZldmVudF9mb3BzLCBzcCwgU19JUlVTUnxTX0lXVVNSKTsKCQlpYm1hc21mc19jcmVhdGVfZmlsZShzYiwgZGlyLCAicmV2ZXJzZV9oZWFydGJlYXQiLCAmcl9oZWFydGJlYXRfZm9wcywgc3AsIFNfSVJVU1J8U19JV1VTUik7CgoJCXJlbW90ZV9kaXIgPSBpYm1hc21mc19jcmVhdGVfZGlyKHNiLCBkaXIsICJyZW1vdGVfdmlkZW8iKTsKCQlpZiAoIXJlbW90ZV9kaXIpCgkJCWNvbnRpbnVlOwoKCQlpYm1hc21mc19jcmVhdGVfZmlsZShzYiwgcmVtb3RlX2RpciwgIndpZHRoIiwgJnJlbW90ZV9zZXR0aW5nc19mb3BzLCAodm9pZCAqKWRpc3BsYXlfd2lkdGgoc3ApLCBTX0lSVVNSfFNfSVdVU1IpOwoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCByZW1vdGVfZGlyLCAiaGVpZ2h0IiwgJnJlbW90ZV9zZXR0aW5nc19mb3BzLCAodm9pZCAqKWRpc3BsYXlfaGVpZ2h0KHNwKSwgU19JUlVTUnxTX0lXVVNSKTsKCQlpYm1hc21mc19jcmVhdGVfZmlsZShzYiwgcmVtb3RlX2RpciwgImRlcHRoIiwgJnJlbW90ZV9zZXR0aW5nc19mb3BzLCAodm9pZCAqKWRpc3BsYXlfZGVwdGgoc3ApLCBTX0lSVVNSfFNfSVdVU1IpOwoJfQp9Cg==