LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIFN05HVibGkgRmF2ZXJnZXMgLSA8d3d3LnN0YXVibGkuY29tPgogKiBQaWVycmUgQVVCRVJUICBwLmF1YmVydEBzdGF1YmxpLmNvbQogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGNvbmZpZy5oPgojaW5jbHVkZSA8bWFsbG9jLmg+CgojaW5jbHVkZSAiZG9zLmgiCiNpbmNsdWRlICJmZG9zLmgiCgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBmYXRfZGVjb2RlIC0tCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCnVuc2lnbmVkIGludCBmYXRfZGVjb2RlIChGc190ICpmcywgdW5zaWduZWQgaW50IG51bSkKewogICAgdW5zaWduZWQgaW50IHN0YXJ0ID0gbnVtICogMyAvIDI7CiAgICB1bnNpZ25lZCBjaGFyICphZGRyZXNzID0gZnMgLT4gZmF0X2J1ZiArIHN0YXJ0OwoKICAgIGlmIChudW0gPCAyIHx8IHN0YXJ0ICsgMSA+IChmcyAtPiBmYXRfbGVuICogU1pfU1REX1NFQ1RPUikpCglyZXR1cm4gMTsKCiAgICBpZiAobnVtICYgMSkKCXJldHVybiAoKGFkZHJlc3MgWzFdICYgMHhmZikgPDwgNCkgfCAoKGFkZHJlc3MgWzBdICYgMHhmMCApID4+IDQpOwogICAgZWxzZQoJcmV0dXJuICgoYWRkcmVzcyBbMV0gJiAweGYpIDw8IDgpIHwgKGFkZHJlc3MgWzBdICYgMHhmZiApOwp9Ci8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogY2hlY2tfZmF0IC0tCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCnN0YXRpYyBpbnQgY2hlY2tfZmF0IChGc190ICpmcykKewogICAgaW50IGksIGY7CgogICAgLyogQ2x1c3RlciB2ZXJpZmljYXRpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBmb3IgKGkgPSAzIDsgaSA8IGZzIC0+IG51bV9jbHVzOyBpKyspewoJZiA9IGZhdF9kZWNvZGUgKGZzLCBpKTsKCWlmIChmIDwgRkFUMTJfTEFTVCAmJiBmID4gZnMgLT4gbnVtX2NsdXMpewoJICAgIC8qIFdyb25nIGNsdXN0ZXIgbnVtYmVyIGRldGVjdGVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIHJldHVybiAoMCk7Cn0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiByZWFkX29uZV9mYXQgLS0KICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8Kc3RhdGljIGludCByZWFkX29uZV9mYXQgKEJvb3RTZWN0b3JfdCAqYm9vdCwgRnNfdCAqZnMsIGludCBuZmF0KQp7CiAgICBpZiAoZGV2X3JlYWQgKGZzIC0+IGZhdF9idWYsCgkJICAoZnMgLT4gZmF0X3N0YXJ0ICsgbmZhdCAqIGZzIC0+IGZhdF9sZW4pLAoJCSAgZnMgLT4gZmF0X2xlbikgPCAwKSB7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAoZnMgLT4gZmF0X2J1ZiBbMF0gfHwgZnMgLT4gZmF0X2J1ZiBbMV0gfHwgZnMgLT4gZmF0X2J1ZiBbMl0pIHsKCWlmICgoZnMgLT4gZmF0X2J1ZiBbMF0gIT0gYm9vdCAtPiBkZXNjciAmJgoJICAgICAoZnMgLT4gZmF0X2J1ZiBbMF0gIT0gMHhmOSB8fCBib290IC0+IGRlc2NyICE9IE1FRElBX1NURCkpIHx8CgkgICAgZnMgLT4gZmF0X2J1ZiBbMF0gPCBNRURJQV9TVEQpewoJICAgIC8qIFVua25vd24gTWVkaWEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCSAgICByZXR1cm4gKC0xKTsKCX0KCWlmIChmcyAtPiBmYXRfYnVmIFsxXSAhPSAweGZmIHx8IGZzIC0+IGZhdF9idWYgWzJdICE9IDB4ZmYpewoJICAgIC8qIEZBVCBkb2Vzbid0IHN0YXJ0IHdpdGggZ29vZCB2YWx1ZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KCiAgICBpZiAoZnMgLT4gbnVtX2NsdXMgPj0gRkFUMTJfTUFYX05CKSB7CgkvKiBUb28gbXVjaCBjbHVzdGVycyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwoJcmV0dXJuICgtMSk7CiAgICB9CgogICAgcmV0dXJuIGNoZWNrX2ZhdCAoZnMpOwp9Ci8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogcmVhZF9mYXQgLS0KICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KaW50IHJlYWRfZmF0IChCb290U2VjdG9yX3QgKmJvb3QsIEZzX3QgKmZzKQp7CiAgICB1bnNpZ25lZCBpbnQgYnVmbGVuOwogICAgaW50IGk7CgogICAgLyogQWxsb2NhdGUgRmF0IEJ1ZmZlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBidWZsZW4gPSBmcyAtPiBmYXRfbGVuICogU1pfU1REX1NFQ1RPUjsKICAgIGlmIChmcyAtPiBmYXRfYnVmKSB7CglmcmVlIChmcyAtPiBmYXRfYnVmKTsKICAgIH0KCiAgICBpZiAoKGZzIC0+IGZhdF9idWYgPSBtYWxsb2MgKGJ1ZmxlbikpID09IE5VTEwpIHsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIC8qIFRyeSB0byByZWFkIGVhY2ggRmF0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgZm9yIChpID0gMDsgaTwgZnMgLT4gbmJfZmF0OyBpKyspewoJaWYgKHJlYWRfb25lX2ZhdCAoYm9vdCwgZnMsIGkpID09IDApIHsKCSAgICAvKiBGYXQgaXMgT0sgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCgkgICAgZnMgLT4gbnVtX2ZhdCA9IGk7CgkgICAgYnJlYWs7Cgl9CiAgICB9CgogICAgaWYgKGkgPT0gZnMgLT4gbmJfZmF0KXsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGlmIChmcyAtPiBmYXRfbGVuID4gKCgoZnMgLT4gbnVtX2NsdXMgKyAyKSAqCgkJCSAgKEZBVF9CSVRTIC8gNCkgLTEgKSAvIDIgLwoJCQkgU1pfU1REX1NFQ1RPUiArIDEpKSB7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0K