LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCi8qCiAqIEBmaWxlIHRhYmxlLmgKICoKICogQGFkZHRvZ3JvdXAgdGFibGUKICoKICogQHsKICovCiNpZm5kZWYgX1RBQkxFX0hBTkRMRVJfSF8KI2RlZmluZSBfVEFCTEVfSEFORExFUl9IXwoKI2lmZGVmIF9fY3BsdXNwbHVzCmV4dGVybiAgICAgICAgICAiQyIgewojZW5kaWYKCi8qKgogKiBUaGUgdGFibGUgaGVscGVyIGlzIGRlc2lnbmVkIHRvIHNpbXBsaWZ5IHRoZSB0YXNrIG9mIHdyaXRpbmcgYQogKiB0YWJsZSBoYW5kbGVyIGZvciB0aGUgbmV0LXNubXAgYWdlbnQuICBZb3Ugc2hvdWxkIGNyZWF0ZSBhIG5vcm1hbAogKiBoYW5kbGVyIGFuZCByZWdpc3RlciBpdCB1c2luZyB0aGUgbmV0c25tcF9yZWdpc3Rlcl90YWJsZSgpIGZ1bmN0aW9uCiAqIGluc3RlYWQgb2YgdGhlIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpIGZ1bmN0aW9uLgogKi8KCi8qKgogKiBOb3RlczoKICoKICogICAxKSBpbGxlZ2FsIGluZGV4ZXMgYXV0b21hdGljYWxseSBnZXQgaGFuZGxlZCBmb3IgZ2V0L3NldCBjYXNlcy4KICogICAgICBTaW1wbHkgY2hlY2sgdG8gbWFrZSBzdXJlIHRoZSB2YWx1ZSBpcyB0eXBlIEFTTl9OVUxMIGJlZm9yZQogKiAgICAgIHlvdSBhbnN3ZXIgYSByZXF1ZXN0LgogKi8KCQovKioKICogdXNlZCBhcyBhbiBpbmRleCB0byBwYXJlbnRfZGF0YSBsb29rdXBzIAogKi8KI2RlZmluZSBUQUJMRV9IQU5ETEVSX05BTUUgInRhYmxlIgoKLyoqIEB0eXBlZGVmIHN0cnVjdCBuZXRzbm1wX2NvbHVtbl9pbmZvX3QgbmV0c25tcF9jb2x1bW5faW5mbwogKiBUeXBlZGVmcyB0aGUgbmV0c25tcF9jb2x1bW5faW5mb190IHN0cnVjdCBpbnRvIG5ldHNubXBfY29sdW1uX2luZm8gKi8KCi8qKgogKiBAc3RydWN0IG5ldHNubXBfY29sdW1uX2luZm9fdAogKiBjb2x1bW4gaW5mbyBzdHJ1Y3QuICBPVkVSTEFQUElORyBSQU5HRVMgQVJFIE5PVCBTVVBQT1JURUQuCiAqLwogICAgdHlwZWRlZiBzdHJ1Y3QgbmV0c25tcF9jb2x1bW5faW5mb190IHsKICAgICAgICBjaGFyICAgICAgICAgICAgaXNSYW5nZTsKIAkvKiogb25seSB1c2VmdWwgaWYgaXNSYW5nZSA9PSAwICovCiAgICAgICAgY2hhciAgICAgICAgICAgIGxpc3RfY291bnQ7CgogICAgICAgIHVuaW9uIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50ICAgIHJhbmdlWzJdOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgICAqbGlzdDsKICAgICAgICB9IGRldGFpbHM7CgogICAgICAgIHN0cnVjdCBuZXRzbm1wX2NvbHVtbl9pbmZvX3QgKm5leHQ7CgogICAgfSBuZXRzbm1wX2NvbHVtbl9pbmZvOwoKLyoqIEB0eXBlZGVmIHN0cnVjdCBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvX3MgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbwogICogVHlwZWRlZnMgdGhlIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm9fcyAgc3RydWN0IGludG8KICAqIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKi8KCi8qKgogKiBAc3RydWN0IG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm9fcwogKiBUYWJsZSByZWdpc3RyYXRpb24gc3RydWN0dXJlLgogKi8KICAgIHR5cGVkZWYgc3RydWN0IG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm9fcyB7CiAJLyoqIGxpc3Qgb2YgdmFyYmluZHMgd2l0aCBvbmx5ICd0eXBlJyBzZXQgKi8KICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmluZGV4ZXM7CiAJLyoqIGNhbGN1bGF0ZWQgYXV0b21hdGljYWxseSAqLwogICAgICAgIHVuc2lnbmVkIGludCAgICBudW1iZXJfaW5kZXhlczsKCiAgICAgICAvKioKICAgICAgICAqIHRoZSBtaW5pbXVtIGNvbHVtbnMgbnVtYmVyLiBJZiB0aGVyZSBhcmUgY29sdW1ucwogICAgICAgICogaW4tYmV0d2VlbiB3aGljaCBhcmUgbm90IHZhbGlkLCB1c2UgdmFsaWRfY29sdW1ucyB0byBnZXQKICAgICAgICAqIGF1dG9tYXRpYyBjb2x1bW4gcmFuZ2UgY2hlY2tpbmcuCiAgICAgICAgKi8KICAgICAgICB1bnNpZ25lZCBpbnQgICAgbWluX2NvbHVtbjsKIAkvKiogdGhlIG1heGltdW0gY29sdW1ucyBudW1iZXIgKi8KICAgICAgICB1bnNpZ25lZCBpbnQgICAgbWF4X2NvbHVtbjsKCiAJLyoqIG1vcmUgZGV0YWlscyBvbiBjb2x1bW5zICovCiAgICAgICAgbmV0c25tcF9jb2x1bW5faW5mbyAqdmFsaWRfY29sdW1uczsKCiAgICB9IG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm87CgovKiogQHR5cGVkZWYgc3RydWN0IG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvX3MgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8KICAqIFR5cGVkZWZzIHRoZSBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mb19zICBzdHJ1Y3QgaW50bwogICogbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKi8KCi8qKgogKiBAc3RydWN0IG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvX3MKICogVGhlIHRhYmxlIHJlcXVlc3QgaW5mbyBzdHJ1Y3R1cmUuCiAqLwogICAgdHlwZWRlZiBzdHJ1Y3QgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm9fcyB7CiAJLyoqIDAgaWYgT0lEIG5vdCBsb25nIGVub3VnaCAqLwogICAgICAgIHVuc2lnbmVkIGludCAgICBjb2xudW07CiAgICAgICAgLyoqIDAgaWYgZmFpbHVyZSB0byBwYXJzZSBhbnkgKi8KICAgICAgICB1bnNpZ25lZCBpbnQgICAgbnVtYmVyX2luZGV4ZXM7CiAJLyoqIGNvbnRlbnRzIGZyZWVkIGJ5IGhlbHBlciB1cG9uIGV4aXQgKi8KICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmluZGV4ZXM7CgogICAgICAgIG9pZCAgICAgICAgICAgICBpbmRleF9vaWRbTUFYX09JRF9MRU5dOwogICAgICAgIHNpemVfdCAgICAgICAgICBpbmRleF9vaWRfbGVuOwogICAgICAgIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnJlZ19pbmZvOwogICAgfSBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbzsKCiAgICBuZXRzbm1wX21pYl9oYW5kbGVyCiAgICAgICAgKm5ldHNubXBfZ2V0X3RhYmxlX2hhbmRsZXIobmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICp0YWJyZXEpOwogICAgaW50ICAgICAgICAgICAgIG5ldHNubXBfcmVnaXN0ZXJfdGFibGUobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqdGFicmVxKTsKICAgIGludCAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX2J1aWxkX29pZChuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqdGFibGVfaW5mbyk7CiAgICBpbnQgICAgICAgICAgICAKICAgICAgICBuZXRzbm1wX3RhYmxlX2J1aWxkX29pZF9mcm9tX2luZGV4KG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnRhYmxlX2luZm8pOwogICAgaW50ICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfYnVpbGRfcmVzdWx0KG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnRhYmxlX2luZm8sIHVfY2hhciB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgcmVzdWx0X2xlbik7CiAgICBpbnQgICAgICAgICAgICAKICAgICAgICBuZXRzbm1wX3VwZGF0ZV92YXJpYWJsZV9saXN0X2Zyb21faW5kZXgobmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKik7CiAgICBpbnQgICAgICAgICAgICAKICAgICAgICBuZXRzbm1wX3VwZGF0ZV9pbmRleGVzX2Zyb21fdmFyaWFibGVfbGlzdAogICAgICAgIChuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdHJpKTsKICAgIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8KICAgICAgICAqbmV0c25tcF9maW5kX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpyZWdpbmZvKTsKICAgIG5ldHNubXBfaW5kZXggKiBuZXRzbm1wX3RhYmxlX2luZGV4X2ZpbmRfbmV4dF9yb3cobmV0c25tcF9jb250YWluZXIgKmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YmxyZXEpOwoKICAgIHVuc2lnbmVkIGludCAgICBuZXRzbm1wX2Nsb3Nlc3RfY29sdW1uKHVuc2lnbmVkIGludCBjdXJyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jb2x1bW5faW5mbwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnZhbGlkX2NvbHVtbnMpOwoKICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyIHRhYmxlX2hlbHBlcl9oYW5kbGVyOwoKI2RlZmluZSBuZXRzbm1wX3RhYmxlX2hlbHBlcl9hZGRfaW5kZXgodGluZm8sIHR5cGUpIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnRpbmZvLT5pbmRleGVzLCBOVUxMLCAwLCAodV9jaGFyKXR5cGUsIE5VTEwsIDApOwoKI2lmIEhBVkVfU1REQVJHX0gKICAgIHZvaWQgICAgICAgICAgIAogICAgICAgIG5ldHNubXBfdGFibGVfaGVscGVyX2FkZF9pbmRleGVzKG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqdGluZm8sIC4uLik7CiNlbHNlCiAgICB2b2lkICAgICAgICAgICAgbmV0c25tcF90YWJsZV9oZWxwZXJfYWRkX2luZGV4ZXModmFfYWxpc3QpOwojZW5kaWYKCiAgICBpbnQgbmV0c25tcF9jaGVja19nZXRuZXh0X3JlcGx5KG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiBwcmVmaXgsIHNpemVfdCBwcmVmaXhfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiBuZXd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqKiBvdXR2YXIpOwoKICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvCiAgICAgICAgKm5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKG5ldHNubXBfcmVxdWVzdF9pbmZvICopOwogICAgbmV0c25tcF9vaWRfc3Rhc2hfbm9kZQogICAgICAgICoqbmV0c25tcF90YWJsZV9nZXRfb3JfY3JlYXRlX3Jvd19zdGFzaChuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdV9jaGFyICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmFnZV9uYW1lKTsKCXVuc2lnbmVkIGludAoJCW5ldHNubXBfdGFibGVfbmV4dF9jb2x1bW4obmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRhYmxlX2luZm8pOwoKCiAgICBpbnQgICBuZXRzbm1wX3NwYXJzZV90YWJsZV9yZWdpc3RlcihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICAgICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGFicmVxKTsKCiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpuZXRzbm1wX3NwYXJzZV90YWJsZV9oYW5kbGVyX2dldCh2b2lkKTsKCiNpZmRlZiBfX2NwbHVzcGx1cwp9CiNlbmRpZgoKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBfVEFCTEVfSEFORExFUl9IXyAqLwovKiogQH0gKi8K