LyoKICogSUJNIEFTTSBTZXJ2aWNlIFByb2Nlc3NvciBEZXZpY2UgRHJpdmVyCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuCiAqCiAqIENvcHlyaWdodCAoQykgSUJNIENvcnBvcmF0aW9uLCAyMDA0CiAqCiAqIEF1dGhvcjogTWF4IEFzYvZjayA8YW1heEB1cy5pYm0uY29tPgogKgogKi8KCi8qCiAqIFBhcnRzIG9mIHRoaXMgY29kZSBhcmUgYmFzZWQgb24gYW4gYXJ0aWNsZSBieSBKb25hdGhhbiBDb3JiZXQKICogdGhhdCBhcHBlYXJlZCBpbiBMaW51eCBXZWVrbHkgTmV3cy4KICovCgoKLyoKICogVGhlIElCTUFTTSBmaWxlIHZpcnR1YWwgZmlsZXN5c3RlbS4gSXQgY3JlYXRlcyB0aGUgZm9sbG93aW5nIGhpZXJhcmNoeQogKiBkeW1hbWljYWxseSB3aGVuIG1vdW50ZWQgZnJvbSB1c2VyIHNwYWNlOgogKgogKiAgICAvaWJtYXNtCiAqICAgIHwtLSAwCiAqICAgIHwgICB8LS0gY29tbWFuZAogKiAgICB8ICAgfC0tIGV2ZW50CiAqICAgIHwgICB8LS0gcmV2ZXJzZV9oZWFydGJlYXQKICogICAgfCAgIGAtLSByZW1vdGVfdmlkZW8KICogICAgfCAgICAgICB8LS0gZGVwdGgKICogICAgfCAgICAgICB8LS0gaGVpZ2h0CiAqICAgIHwgICAgICAgYC0tIHdpZHRoCiAqICAgIC4KICogICAgLgogKiAgICAuCiAqICAgIGAtLSBuCiAqICAgICAgICB8LS0gY29tbWFuZAogKiAgICAgICAgfC0tIGV2ZW50CiAqICAgICAgICB8LS0gcmV2ZXJzZV9oZWFydGJlYXQKICogICAgICAgIGAtLSByZW1vdGVfdmlkZW8KICogICAgICAgICAgICB8LS0gZGVwdGgKICogICAgICAgICAgICB8LS0gaGVpZ2h0CiAqICAgICAgICAgICAgYC0tIHdpZHRoCiAqCiAqIEZvciBlYWNoIHNlcnZpY2UgcHJvY2Vzc29yIHRoZSBmb2xsb3dpbmcgZmlsZXMgYXJlIGNyZWF0ZWQ6CiAqCiAqIGNvbW1hbmQ6IGV4ZWN1dGUgZG90IGNvbW1hbmRzCiAqCXdyaXRlOiBleGVjdXRlIGEgZG90IGNvbW1hbmQgb24gdGhlIHNlcnZpY2UgcHJvY2Vzc29yCiAqCXJlYWQ6IHJldHVybiB0aGUgcmVzdWx0IG9mIGEgcHJldmlvdXNseSBleGVjdXRlZCBkb3QgY29tbWFuZAogKgogKiBldmVudHM6IGxpc3RlbiBmb3Igc2VydmljZSBwcm9jZXNzb3IgZXZlbnRzCiAqCXJlYWQ6IHNsZWVwIChpbnRlcnJ1cHRpYmxlKSB1bnRpbCBhbiBldmVudCBvY2N1cnMKICogICAgICB3cml0ZTogd2FrZXVwIHNsZWVwaW5nIGV2ZW50IGxpc3RlbmVyCiAqCiAqIHJldmVyc2VfaGVhcnRiZWF0OiBzZW5kIGEgaGVhcnRiZWF0IHRvIHRoZSBzZXJ2aWNlIHByb2Nlc3NvcgogKglyZWFkOiBzbGVlcCAoaW50ZXJydXB0aWJsZSkgdW50aWwgdGhlIHJldmVyc2UgaGVhcnRiZWF0IGZhaWxzCiAqICAgICAgd3JpdGU6IHdha2V1cCBzbGVlcGluZyBoZWFydGJlYXQgbGlzdGVuZXIKICoKICogcmVtb3RlX3ZpZGVvL3dpZHRoCiAqIHJlbW90ZV92aWRlby9oZWlnaHQKICogcmVtb3RlX3ZpZGVvL3dpZHRoOiBjb250cm9sIHJlbW90ZSBkaXNwbGF5IHNldHRpbmdzCiAqCXdyaXRlOiBzZXQgdmFsdWUKICoJcmVhZDogcmVhZCB2YWx1ZQogKi8KCiNpbmNsdWRlIDxsaW51eC9mcy5oPgojaW5jbHVkZSA8bGludXgvcGFnZW1hcC5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSAiaWJtYXNtLmgiCiNpbmNsdWRlICJyZW1vdGUuaCIKI2luY2x1ZGUgImRvdF9jb21tYW5kLmgiCgojZGVmaW5lIElCTUFTTUZTX01BR0lDIDB4NjY3MjZmNjcKCnN0YXRpYyBMSVNUX0hFQUQoc2VydmljZV9wcm9jZXNzb3JzKTsKCnN0YXRpYyBzdHJ1Y3QgaW5vZGUgKmlibWFzbWZzX21ha2VfaW5vZGUoc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwgaW50IG1vZGUpOwpzdGF0aWMgdm9pZCBpYm1hc21mc19jcmVhdGVfZmlsZXMgKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIHN0cnVjdCBkZW50cnkgKnJvb3QpOwpzdGF0aWMgaW50IGlibWFzbWZzX2ZpbGxfc3VwZXIgKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIHZvaWQgKmRhdGEsIGludCBzaWxlbnQpOwoKCnN0YXRpYyBpbnQgaWJtYXNtZnNfZ2V0X3N1cGVyKHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc3QsCgkJCWludCBmbGFncywgY29uc3QgY2hhciAqbmFtZSwgdm9pZCAqZGF0YSwKCQkJc3RydWN0IHZmc21vdW50ICptbnQpCnsKCXJldHVybiBnZXRfc2Jfc2luZ2xlKGZzdCwgZmxhZ3MsIGRhdGEsIGlibWFzbWZzX2ZpbGxfc3VwZXIsIG1udCk7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3Qgc3VwZXJfb3BlcmF0aW9ucyBpYm1hc21mc19zX29wcyA9IHsKCS5zdGF0ZnMJCT0gc2ltcGxlX3N0YXRmcywKCS5kcm9wX2lub2RlCT0gZ2VuZXJpY19kZWxldGVfaW5vZGUsCn07CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyAqaWJtYXNtZnNfZGlyX29wcyA9ICZzaW1wbGVfZGlyX29wZXJhdGlvbnM7CgpzdGF0aWMgc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgaWJtYXNtZnNfdHlwZSA9IHsKCS5vd25lciAgICAgICAgICA9IFRISVNfTU9EVUxFLAoJLm5hbWUgICAgICAgICAgID0gImlibWFzbWZzIiwKCS5nZXRfc2IgICAgICAgICA9IGlibWFzbWZzX2dldF9zdXBlciwKCS5raWxsX3NiICAgICAgICA9IGtpbGxfbGl0dGVyX3N1cGVyLAp9OwoKc3RhdGljIGludCBpYm1hc21mc19maWxsX3N1cGVyIChzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCB2b2lkICpkYXRhLCBpbnQgc2lsZW50KQp7CglzdHJ1Y3QgaW5vZGUgKnJvb3Q7CglzdHJ1Y3QgZGVudHJ5ICpyb290X2RlbnRyeTsKCglzYi0+c19ibG9ja3NpemUgPSBQQUdFX0NBQ0hFX1NJWkU7CglzYi0+c19ibG9ja3NpemVfYml0cyA9IFBBR0VfQ0FDSEVfU0hJRlQ7CglzYi0+c19tYWdpYyA9IElCTUFTTUZTX01BR0lDOwoJc2ItPnNfb3AgPSAmaWJtYXNtZnNfc19vcHM7CglzYi0+c190aW1lX2dyYW4gPSAxOwoKCXJvb3QgPSBpYm1hc21mc19tYWtlX2lub2RlIChzYiwgU19JRkRJUiB8IDA1MDApOwoJaWYgKCFyb290KQoJCXJldHVybiAtRU5PTUVNOwoKCXJvb3QtPmlfb3AgPSAmc2ltcGxlX2Rpcl9pbm9kZV9vcGVyYXRpb25zOwoJcm9vdC0+aV9mb3AgPSBpYm1hc21mc19kaXJfb3BzOwoKCXJvb3RfZGVudHJ5ID0gZF9hbGxvY19yb290KHJvb3QpOwoJaWYgKCFyb290X2RlbnRyeSkgewoJCWlwdXQocm9vdCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CglzYi0+c19yb290ID0gcm9vdF9kZW50cnk7CgoJaWJtYXNtZnNfY3JlYXRlX2ZpbGVzKHNiLCByb290X2RlbnRyeSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBpbm9kZSAqaWJtYXNtZnNfbWFrZV9pbm9kZShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCBpbnQgbW9kZSkKewoJc3RydWN0IGlub2RlICpyZXQgPSBuZXdfaW5vZGUoc2IpOwoKCWlmIChyZXQpIHsKCQlyZXQtPmlfbW9kZSA9IG1vZGU7CgkJcmV0LT5pX2F0aW1lID0gcmV0LT5pX210aW1lID0gcmV0LT5pX2N0aW1lID0gQ1VSUkVOVF9USU1FOwoJfQoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHN0cnVjdCBkZW50cnkgKmlibWFzbWZzX2NyZWF0ZV9maWxlIChzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLAoJCQlzdHJ1Y3QgZGVudHJ5ICpwYXJlbnQsCgkJCWNvbnN0IGNoYXIgKm5hbWUsCgkJCWNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgKmZvcHMsCgkJCXZvaWQgKmRhdGEsCgkJCWludCBtb2RlKQp7CglzdHJ1Y3QgZGVudHJ5ICpkZW50cnk7CglzdHJ1Y3QgaW5vZGUgKmlub2RlOwoKCWRlbnRyeSA9IGRfYWxsb2NfbmFtZShwYXJlbnQsIG5hbWUpOwoJaWYgKCFkZW50cnkpCgkJcmV0dXJuIE5VTEw7CgoJaW5vZGUgPSBpYm1hc21mc19tYWtlX2lub2RlKHNiLCBTX0lGUkVHIHwgbW9kZSk7CglpZiAoIWlub2RlKSB7CgkJZHB1dChkZW50cnkpOwoJCXJldHVybiBOVUxMOwoJfQoKCWlub2RlLT5pX2ZvcCA9IGZvcHM7Cglpbm9kZS0+aV9wcml2YXRlID0gZGF0YTsKCglkX2FkZChkZW50cnksIGlub2RlKTsKCXJldHVybiBkZW50cnk7Cn0KCnN0YXRpYyBzdHJ1Y3QgZGVudHJ5ICppYm1hc21mc19jcmVhdGVfZGlyIChzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLAoJCQkJc3RydWN0IGRlbnRyeSAqcGFyZW50LAoJCQkJY29uc3QgY2hhciAqbmFtZSkKewoJc3RydWN0IGRlbnRyeSAqZGVudHJ5OwoJc3RydWN0IGlub2RlICppbm9kZTsKCglkZW50cnkgPSBkX2FsbG9jX25hbWUocGFyZW50LCBuYW1lKTsKCWlmICghZGVudHJ5KQoJCXJldHVybiBOVUxMOwoKCWlub2RlID0gaWJtYXNtZnNfbWFrZV9pbm9kZShzYiwgU19JRkRJUiB8IDA1MDApOwoJaWYgKCFpbm9kZSkgewoJCWRwdXQoZGVudHJ5KTsKCQlyZXR1cm4gTlVMTDsKCX0KCglpbm9kZS0+aV9vcCA9ICZzaW1wbGVfZGlyX2lub2RlX29wZXJhdGlvbnM7Cglpbm9kZS0+aV9mb3AgPSBpYm1hc21mc19kaXJfb3BzOwoKCWRfYWRkKGRlbnRyeSwgaW5vZGUpOwoJcmV0dXJuIGRlbnRyeTsKfQoKaW50IGlibWFzbWZzX3JlZ2lzdGVyKHZvaWQpCnsKCXJldHVybiByZWdpc3Rlcl9maWxlc3lzdGVtKCZpYm1hc21mc190eXBlKTsKfQoKdm9pZCBpYm1hc21mc191bnJlZ2lzdGVyKHZvaWQpCnsKCXVucmVnaXN0ZXJfZmlsZXN5c3RlbSgmaWJtYXNtZnNfdHlwZSk7Cn0KCnZvaWQgaWJtYXNtZnNfYWRkX3NwKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCWxpc3RfYWRkKCZzcC0+bm9kZSwgJnNlcnZpY2VfcHJvY2Vzc29ycyk7Cn0KCi8qIHN0cnVjdCB0byBzYXZlIHN0YXRlIGJldHdlZW4gY29tbWFuZCBmaWxlIG9wZXJhdGlvbnMgKi8Kc3RydWN0IGlibWFzbWZzX2NvbW1hbmRfZGF0YSB7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IJKnNwOwoJc3RydWN0IGNvbW1hbmQJCQkqY29tbWFuZDsKfTsKCi8qIHN0cnVjdCB0byBzYXZlIHN0YXRlIGJldHdlZW4gZXZlbnQgZmlsZSBvcGVyYXRpb25zICovCnN0cnVjdCBpYm1hc21mc19ldmVudF9kYXRhIHsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3Nvcgkqc3A7CglzdHJ1Y3QgZXZlbnRfcmVhZGVyCQlyZWFkZXI7CglpbnQJCQkJYWN0aXZlOwp9OwoKLyogc3RydWN0IHRvIHNhdmUgc3RhdGUgYmV0d2VlbiByZXZlcnNlIGhlYXJ0YmVhdCBmaWxlIG9wZXJhdGlvbnMgKi8Kc3RydWN0IGlibWFzbWZzX2hlYXJ0YmVhdF9kYXRhIHsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3Nvcgkqc3A7CglzdHJ1Y3QgcmV2ZXJzZV9oZWFydGJlYXQJaGVhcnRiZWF0OwoJaW50CQkJCWFjdGl2ZTsKfTsKCnN0YXRpYyBpbnQgY29tbWFuZF9maWxlX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEgKmNvbW1hbmRfZGF0YTsKCglpZiAoIWlub2RlLT5pX3ByaXZhdGUpCgkJcmV0dXJuIC1FTk9ERVY7CgoJY29tbWFuZF9kYXRhID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IGlibWFzbWZzX2NvbW1hbmRfZGF0YSksIEdGUF9LRVJORUwpOwoJaWYgKCFjb21tYW5kX2RhdGEpCgkJcmV0dXJuIC1FTk9NRU07CgoJY29tbWFuZF9kYXRhLT5jb21tYW5kID0gTlVMTDsKCWNvbW1hbmRfZGF0YS0+c3AgPSBpbm9kZS0+aV9wcml2YXRlOwoJZmlsZS0+cHJpdmF0ZV9kYXRhID0gY29tbWFuZF9kYXRhOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgY29tbWFuZF9maWxlX2Nsb3NlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfY29tbWFuZF9kYXRhICpjb21tYW5kX2RhdGEgPSBmaWxlLT5wcml2YXRlX2RhdGE7CgoJaWYgKGNvbW1hbmRfZGF0YS0+Y29tbWFuZCkKCQljb21tYW5kX3B1dChjb21tYW5kX2RhdGEtPmNvbW1hbmQpOwoKCWtmcmVlKGNvbW1hbmRfZGF0YSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHNzaXplX3QgY29tbWFuZF9maWxlX3JlYWQoc3RydWN0IGZpbGUgKmZpbGUsIGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEgKmNvbW1hbmRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBjb21tYW5kICpjbWQ7CglpbnQgbGVuOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IElCTUFTTV9DTURfTUFYX0JVRkZFUl9TSVpFKQoJCXJldHVybiAwOwoJaWYgKCpvZmZzZXQgIT0gMCkKCQlyZXR1cm4gMDsKCglzcGluX2xvY2tfaXJxc2F2ZSgmY29tbWFuZF9kYXRhLT5zcC0+bG9jaywgZmxhZ3MpOwoJY21kID0gY29tbWFuZF9kYXRhLT5jb21tYW5kOwoJaWYgKGNtZCA9PSBOVUxMKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29tbWFuZF9kYXRhLT5zcC0+bG9jaywgZmxhZ3MpOwoJCXJldHVybiAwOwoJfQoJY29tbWFuZF9kYXRhLT5jb21tYW5kID0gTlVMTDsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNvbW1hbmRfZGF0YS0+c3AtPmxvY2ssIGZsYWdzKTsKCglpZiAoY21kLT5zdGF0dXMgIT0gSUJNQVNNX0NNRF9DT01QTEVURSkgewoJCWNvbW1hbmRfcHV0KGNtZCk7CgkJcmV0dXJuIC1FSU87Cgl9CglsZW4gPSBtaW4oY291bnQsIGNtZC0+YnVmZmVyX3NpemUpOwoJaWYgKGNvcHlfdG9fdXNlcihidWYsIGNtZC0+YnVmZmVyLCBsZW4pKSB7CgkJY29tbWFuZF9wdXQoY21kKTsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCWNvbW1hbmRfcHV0KGNtZCk7CgoJcmV0dXJuIGxlbjsKfQoKc3RhdGljIHNzaXplX3QgY29tbWFuZF9maWxlX3dyaXRlKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqdWJ1ZmYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXN0cnVjdCBpYm1hc21mc19jb21tYW5kX2RhdGEgKmNvbW1hbmRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBjb21tYW5kICpjbWQ7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCA9PSAwIHx8IGNvdW50ID4gSUJNQVNNX0NNRF9NQVhfQlVGRkVSX1NJWkUpCgkJcmV0dXJuIDA7CglpZiAoKm9mZnNldCAhPSAwKQoJCXJldHVybiAwOwoKCS8qIGNvbW1hbmRzIGFyZSBleGVjdXRlZCBzZXF1ZW50aWFsbHksIG9ubHkgb25lIGNvbW1hbmQgYXQgYSB0aW1lICovCglpZiAoY29tbWFuZF9kYXRhLT5jb21tYW5kKQoJCXJldHVybiAtRUFHQUlOOwoKCWNtZCA9IGlibWFzbV9uZXdfY29tbWFuZChjb21tYW5kX2RhdGEtPnNwLCBjb3VudCk7CglpZiAoIWNtZCkKCQlyZXR1cm4gLUVOT01FTTsKCglpZiAoY29weV9mcm9tX3VzZXIoY21kLT5idWZmZXIsIHVidWZmLCBjb3VudCkpIHsKCQljb21tYW5kX3B1dChjbWQpOwoJCXJldHVybiAtRUZBVUxUOwoJfQoKCXNwaW5fbG9ja19pcnFzYXZlKCZjb21tYW5kX2RhdGEtPnNwLT5sb2NrLCBmbGFncyk7CglpZiAoY29tbWFuZF9kYXRhLT5jb21tYW5kKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY29tbWFuZF9kYXRhLT5zcC0+bG9jaywgZmxhZ3MpOwoJCWNvbW1hbmRfcHV0KGNtZCk7CgkJcmV0dXJuIC1FQUdBSU47Cgl9Cgljb21tYW5kX2RhdGEtPmNvbW1hbmQgPSBjbWQ7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjb21tYW5kX2RhdGEtPnNwLT5sb2NrLCBmbGFncyk7CgoJaWJtYXNtX2V4ZWNfY29tbWFuZChjb21tYW5kX2RhdGEtPnNwLCBjbWQpOwoJaWJtYXNtX3dhaXRfZm9yX3Jlc3BvbnNlKGNtZCwgZ2V0X2RvdF9jb21tYW5kX3RpbWVvdXQoY21kLT5idWZmZXIpKTsKCglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyBpbnQgZXZlbnRfZmlsZV9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSAqZXZlbnRfZGF0YTsKCXN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3A7CgoJaWYgKCFpbm9kZS0+aV9wcml2YXRlKQoJCXJldHVybiAtRU5PREVWOwoKCXNwID0gaW5vZGUtPmlfcHJpdmF0ZTsKCglldmVudF9kYXRhID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IGlibWFzbWZzX2V2ZW50X2RhdGEpLCBHRlBfS0VSTkVMKTsKCWlmICghZXZlbnRfZGF0YSkKCQlyZXR1cm4gLUVOT01FTTsKCglpYm1hc21fZXZlbnRfcmVhZGVyX3JlZ2lzdGVyKHNwLCAmZXZlbnRfZGF0YS0+cmVhZGVyKTsKCglldmVudF9kYXRhLT5zcCA9IHNwOwoJZXZlbnRfZGF0YS0+YWN0aXZlID0gMDsKCWZpbGUtPnByaXZhdGVfZGF0YSA9IGV2ZW50X2RhdGE7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBldmVudF9maWxlX2Nsb3NlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSAqZXZlbnRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglpYm1hc21fZXZlbnRfcmVhZGVyX3VucmVnaXN0ZXIoZXZlbnRfZGF0YS0+c3AsICZldmVudF9kYXRhLT5yZWFkZXIpOwoJa2ZyZWUoZXZlbnRfZGF0YSk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHNzaXplX3QgZXZlbnRfZmlsZV9yZWFkKHN0cnVjdCBmaWxlICpmaWxlLCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7CglzdHJ1Y3QgaWJtYXNtZnNfZXZlbnRfZGF0YSAqZXZlbnRfZGF0YSA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlciA9ICZldmVudF9kYXRhLT5yZWFkZXI7CglzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwID0gZXZlbnRfZGF0YS0+c3A7CglpbnQgcmV0OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgPT0gMCB8fCBjb3VudCA+IElCTUFTTV9FVkVOVF9NQVhfU0laRSkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJnNwLT5sb2NrLCBmbGFncyk7CglpZiAoZXZlbnRfZGF0YS0+YWN0aXZlKSB7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKCQlyZXR1cm4gLUVCVVNZOwoJfQoJZXZlbnRfZGF0YS0+YWN0aXZlID0gMTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7CgoJcmV0ID0gaWJtYXNtX2dldF9uZXh0X2V2ZW50KHNwLCByZWFkZXIpOwoJaWYgKHJldCA8PSAwKQoJCWdvdG8gb3V0OwoKCWlmIChjb3VudCA8IHJlYWRlci0+ZGF0YV9zaXplKSB7CgkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIG91dDsKCX0KCiAgICAgICAgaWYgKGNvcHlfdG9fdXNlcihidWYsIHJlYWRlci0+ZGF0YSwgcmVhZGVyLT5kYXRhX3NpemUpKSB7CgkJcmV0ID0gLUVGQVVMVDsKCQlnb3RvIG91dDsKCX0KCXJldCA9IHJlYWRlci0+ZGF0YV9zaXplOwoKb3V0OgoJZXZlbnRfZGF0YS0+YWN0aXZlID0gMDsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBzc2l6ZV90IGV2ZW50X2ZpbGVfd3JpdGUoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICpidWYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXN0cnVjdCBpYm1hc21mc19ldmVudF9kYXRhICpldmVudF9kYXRhID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCAhPSAxKQoJCXJldHVybiAwOwoJaWYgKCpvZmZzZXQgIT0gMCkKCQlyZXR1cm4gMDsKCglpYm1hc21fY2FuY2VsX25leHRfZXZlbnQoJmV2ZW50X2RhdGEtPnJlYWRlcik7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByX2hlYXJ0YmVhdF9maWxlX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBpYm1hc21mc19oZWFydGJlYXRfZGF0YSAqcmhiZWF0OwoKCWlmICghaW5vZGUtPmlfcHJpdmF0ZSkKCQlyZXR1cm4gLUVOT0RFVjsKCglyaGJlYXQgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgaWJtYXNtZnNfaGVhcnRiZWF0X2RhdGEpLCBHRlBfS0VSTkVMKTsKCWlmICghcmhiZWF0KQoJCXJldHVybiAtRU5PTUVNOwoKCXJoYmVhdC0+c3AgPSBpbm9kZS0+aV9wcml2YXRlOwoJcmhiZWF0LT5hY3RpdmUgPSAwOwoJaWJtYXNtX2luaXRfcmV2ZXJzZV9oZWFydGJlYXQocmhiZWF0LT5zcCwgJnJoYmVhdC0+aGVhcnRiZWF0KTsKCWZpbGUtPnByaXZhdGVfZGF0YSA9IHJoYmVhdDsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJfaGVhcnRiZWF0X2ZpbGVfY2xvc2Uoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBpYm1hc21mc19oZWFydGJlYXRfZGF0YSAqcmhiZWF0ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwoKCWtmcmVlKHJoYmVhdCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHNzaXplX3Qgcl9oZWFydGJlYXRfZmlsZV9yZWFkKHN0cnVjdCBmaWxlICpmaWxlLCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7CglzdHJ1Y3QgaWJtYXNtZnNfaGVhcnRiZWF0X2RhdGEgKnJoYmVhdCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgcmVzdWx0OwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCA9PSAwIHx8IGNvdW50ID4gMTAyNCkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJLyogYWxsb3cgb25seSBvbmUgcmV2ZXJzZSBoZWFydGJlYXQgcGVyIHByb2Nlc3MgKi8KCXNwaW5fbG9ja19pcnFzYXZlKCZyaGJlYXQtPnNwLT5sb2NrLCBmbGFncyk7CglpZiAocmhiZWF0LT5hY3RpdmUpIHsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZyaGJlYXQtPnNwLT5sb2NrLCBmbGFncyk7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCXJoYmVhdC0+YWN0aXZlID0gMTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnJoYmVhdC0+c3AtPmxvY2ssIGZsYWdzKTsKCglyZXN1bHQgPSBpYm1hc21fc3RhcnRfcmV2ZXJzZV9oZWFydGJlYXQocmhiZWF0LT5zcCwgJnJoYmVhdC0+aGVhcnRiZWF0KTsKCXJoYmVhdC0+YWN0aXZlID0gMDsKCglyZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgc3NpemVfdCByX2hlYXJ0YmVhdF9maWxlX3dyaXRlKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgY291bnQsIGxvZmZfdCAqb2Zmc2V0KQp7CglzdHJ1Y3QgaWJtYXNtZnNfaGVhcnRiZWF0X2RhdGEgKnJoYmVhdCA9IGZpbGUtPnByaXZhdGVfZGF0YTsKCglpZiAoKm9mZnNldCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAoY291bnQgIT0gMSkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJaWYgKHJoYmVhdC0+YWN0aXZlKQoJCWlibWFzbV9zdG9wX3JldmVyc2VfaGVhcnRiZWF0KCZyaGJlYXQtPmhlYXJ0YmVhdCk7CgoJcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgcmVtb3RlX3NldHRpbmdzX2ZpbGVfb3BlbihzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJZmlsZS0+cHJpdmF0ZV9kYXRhID0gaW5vZGUtPmlfcHJpdmF0ZTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJlbW90ZV9zZXR0aW5nc19maWxlX2Nsb3NlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglyZXR1cm4gMDsKfQoKc3RhdGljIHNzaXplX3QgcmVtb3RlX3NldHRpbmdzX2ZpbGVfcmVhZChzdHJ1Y3QgZmlsZSAqZmlsZSwgY2hhciBfX3VzZXIgKmJ1Ziwgc2l6ZV90IGNvdW50LCBsb2ZmX3QgKm9mZnNldCkKewoJdm9pZCBfX2lvbWVtICphZGRyZXNzID0gKHZvaWQgX19pb21lbSAqKWZpbGUtPnByaXZhdGVfZGF0YTsKCXVuc2lnbmVkIGNoYXIgKnBhZ2U7CglpbnQgcmV0dmFsOwoJaW50IGxlbiA9IDA7Cgl1bnNpZ25lZCBpbnQgdmFsdWU7CgoJaWYgKCpvZmZzZXQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvdW50ID09IDAgfHwgY291bnQgPiAxMDI0KQoJCXJldHVybiAwOwoJaWYgKCpvZmZzZXQgIT0gMCkKCQlyZXR1cm4gMDsKCglwYWdlID0gKHVuc2lnbmVkIGNoYXIgKilfX2dldF9mcmVlX3BhZ2UoR0ZQX0tFUk5FTCk7CglpZiAoIXBhZ2UpCgkJcmV0dXJuIC1FTk9NRU07CgoJdmFsdWUgPSByZWFkbChhZGRyZXNzKTsKCWxlbiA9IHNwcmludGYocGFnZSwgIiVkXG4iLCB2YWx1ZSk7CgoJaWYgKGNvcHlfdG9fdXNlcihidWYsIHBhZ2UsIGxlbikpIHsKCQlyZXR2YWwgPSAtRUZBVUxUOwoJCWdvdG8gZXhpdDsKCX0KCSpvZmZzZXQgKz0gbGVuOwoJcmV0dmFsID0gbGVuOwoKZXhpdDoKCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylwYWdlKTsKCXJldHVybiByZXR2YWw7Cn0KCnN0YXRpYyBzc2l6ZV90IHJlbW90ZV9zZXR0aW5nc19maWxlX3dyaXRlKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqdWJ1ZmYsIHNpemVfdCBjb3VudCwgbG9mZl90ICpvZmZzZXQpCnsKCXZvaWQgX19pb21lbSAqYWRkcmVzcyA9ICh2b2lkIF9faW9tZW0gKilmaWxlLT5wcml2YXRlX2RhdGE7CgljaGFyICpidWZmOwoJdW5zaWduZWQgaW50IHZhbHVlOwoKCWlmICgqb2Zmc2V0IDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChjb3VudCA9PSAwIHx8IGNvdW50ID4gMTAyNCkKCQlyZXR1cm4gMDsKCWlmICgqb2Zmc2V0ICE9IDApCgkJcmV0dXJuIDA7CgoJYnVmZiA9IGt6YWxsb2MgKGNvdW50ICsgMSwgR0ZQX0tFUk5FTCk7CglpZiAoIWJ1ZmYpCgkJcmV0dXJuIC1FTk9NRU07CgoKCWlmIChjb3B5X2Zyb21fdXNlcihidWZmLCB1YnVmZiwgY291bnQpKSB7CgkJa2ZyZWUoYnVmZik7CgkJcmV0dXJuIC1FRkFVTFQ7Cgl9CgoJdmFsdWUgPSBzaW1wbGVfc3RydG91bChidWZmLCBOVUxMLCAxMCk7Cgl3cml0ZWwodmFsdWUsIGFkZHJlc3MpOwoJa2ZyZWUoYnVmZik7CgoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBjb21tYW5kX2ZvcHMgPSB7Cgkub3BlbiA9CQljb21tYW5kX2ZpbGVfb3BlbiwKCS5yZWxlYXNlID0JY29tbWFuZF9maWxlX2Nsb3NlLAoJLnJlYWQgPQkJY29tbWFuZF9maWxlX3JlYWQsCgkud3JpdGUgPQljb21tYW5kX2ZpbGVfd3JpdGUsCn07CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBldmVudF9mb3BzID0gewoJLm9wZW4gPQkJZXZlbnRfZmlsZV9vcGVuLAoJLnJlbGVhc2UgPQlldmVudF9maWxlX2Nsb3NlLAoJLnJlYWQgPQkJZXZlbnRfZmlsZV9yZWFkLAoJLndyaXRlID0JZXZlbnRfZmlsZV93cml0ZSwKfTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHJfaGVhcnRiZWF0X2ZvcHMgPSB7Cgkub3BlbiA9CQlyX2hlYXJ0YmVhdF9maWxlX29wZW4sCgkucmVsZWFzZSA9CXJfaGVhcnRiZWF0X2ZpbGVfY2xvc2UsCgkucmVhZCA9CQlyX2hlYXJ0YmVhdF9maWxlX3JlYWQsCgkud3JpdGUgPQlyX2hlYXJ0YmVhdF9maWxlX3dyaXRlLAp9OwoKc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgcmVtb3RlX3NldHRpbmdzX2ZvcHMgPSB7Cgkub3BlbiA9CQlyZW1vdGVfc2V0dGluZ3NfZmlsZV9vcGVuLAoJLnJlbGVhc2UgPQlyZW1vdGVfc2V0dGluZ3NfZmlsZV9jbG9zZSwKCS5yZWFkID0JCXJlbW90ZV9zZXR0aW5nc19maWxlX3JlYWQsCgkud3JpdGUgPQlyZW1vdGVfc2V0dGluZ3NfZmlsZV93cml0ZSwKfTsKCgpzdGF0aWMgdm9pZCBpYm1hc21mc19jcmVhdGVfZmlsZXMgKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIHN0cnVjdCBkZW50cnkgKnJvb3QpCnsKCXN0cnVjdCBsaXN0X2hlYWQgKmVudHJ5OwoJc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcDsKCglsaXN0X2Zvcl9lYWNoKGVudHJ5LCAmc2VydmljZV9wcm9jZXNzb3JzKSB7CgkJc3RydWN0IGRlbnRyeSAqZGlyOwoJCXN0cnVjdCBkZW50cnkgKnJlbW90ZV9kaXI7CgkJc3AgPSBsaXN0X2VudHJ5KGVudHJ5LCBzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IsIG5vZGUpOwoJCWRpciA9IGlibWFzbWZzX2NyZWF0ZV9kaXIoc2IsIHJvb3QsIHNwLT5kaXJuYW1lKTsKCQlpZiAoIWRpcikKCQkJY29udGludWU7CgoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCBkaXIsICJjb21tYW5kIiwgJmNvbW1hbmRfZm9wcywgc3AsIFNfSVJVU1J8U19JV1VTUik7CgkJaWJtYXNtZnNfY3JlYXRlX2ZpbGUoc2IsIGRpciwgImV2ZW50IiwgJmV2ZW50X2ZvcHMsIHNwLCBTX0lSVVNSfFNfSVdVU1IpOwoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCBkaXIsICJyZXZlcnNlX2hlYXJ0YmVhdCIsICZyX2hlYXJ0YmVhdF9mb3BzLCBzcCwgU19JUlVTUnxTX0lXVVNSKTsKCgkJcmVtb3RlX2RpciA9IGlibWFzbWZzX2NyZWF0ZV9kaXIoc2IsIGRpciwgInJlbW90ZV92aWRlbyIpOwoJCWlmICghcmVtb3RlX2RpcikKCQkJY29udGludWU7CgoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCByZW1vdGVfZGlyLCAid2lkdGgiLCAmcmVtb3RlX3NldHRpbmdzX2ZvcHMsICh2b2lkICopZGlzcGxheV93aWR0aChzcCksIFNfSVJVU1J8U19JV1VTUik7CgkJaWJtYXNtZnNfY3JlYXRlX2ZpbGUoc2IsIHJlbW90ZV9kaXIsICJoZWlnaHQiLCAmcmVtb3RlX3NldHRpbmdzX2ZvcHMsICh2b2lkICopZGlzcGxheV9oZWlnaHQoc3ApLCBTX0lSVVNSfFNfSVdVU1IpOwoJCWlibWFzbWZzX2NyZWF0ZV9maWxlKHNiLCByZW1vdGVfZGlyLCAiZGVwdGgiLCAmcmVtb3RlX3NldHRpbmdzX2ZvcHMsICh2b2lkICopZGlzcGxheV9kZXB0aChzcCksIFNfSVJVU1J8U19JV1VTUik7Cgl9Cn0K