LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9pbnN0YW5jZS5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvc2VyaWFsaXplLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9yZWFkX29ubHkuaD4KCnR5cGVkZWYgc3RydWN0IG5ldHNubXBfbnVtX2ZpbGVfaW5zdGFuY2VfcyB7CiAgICBjaGFyICpmaWxlX25hbWU7CiAgICBGSUxFICpmaWxlcDsKICAgIGludCAgIHR5cGU7CiAgICBpbnQgICBmbGFnczsKfSBuZXRzbm1wX251bV9maWxlX2luc3RhbmNlOwoKLyoqIEBkZWZncm91cCBpbnN0YW5jZSBpbnN0YW5jZQogKiAgUHJvY2VzcyBpbmRpdmlkdWFsIE1JQiBpbnN0YW5jZXMgZWFzaWx5LgogKiAgQGluZ3JvdXAgbGVhZgogKiAgQHsKICovCgovKioKICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBoZWxwZXIgaGFuZGxlciwgY2FsbHMgbmV0c25tcF9jcmVhdGVfaGFuZGxlciwgd2hpY2gKICogdGhlbiBjb3VsZCBiZSByZWdpc3RlcmVkLCB1c2luZyBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKS4KICoKICogQHJldHVybiBSZXR1cm5zIGEgcG9pbnRlciB0byBhIG5ldHNubXBfbWliX2hhbmRsZXIgc3RydWN0IHdoaWNoIGNvbnRhaW5zCiAqCXRoZSBoYW5kbGVyJ3MgbmFtZSBhbmQgdGhlIGFjY2VzcyBtZXRob2QKICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2dldF9pbnN0YW5jZV9oYW5kbGVyKHZvaWQpCnsKICAgIHJldHVybiBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKCJpbnN0YW5jZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2luc3RhbmNlX2hlbHBlcl9oYW5kbGVyKTsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gcmVnaXN0ZXJzIGFuIGluc3RhbmNlIGhlbHBlciBoYW5kbGVyLCB3aGljaCBpcyBhIHdheSBvZiAKICogcmVnaXN0ZXJpbmcgYW4gZXhhY3QgT0lEIHN1Y2ggdGhhdCBHRU5FWFQgcmVxdWVzdHMgYXJlIGhhbmRsZWQgZW50aXJlbHkKICogYnkgdGhlIGhlbHBlci4gRmlyc3QgbmVlZCB0byBpbmplY3QgaXQgaW50byB0aGUgY2FsbGluZyBjaGFpbiBvZiB0aGUgCiAqIGhhbmRsZXIgZGVmaW5lZCBieSB0aGUgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBzdHJ1Y3QsIHJlZ2luZm8uICAKICogVGhlIG5ldyBoYW5kbGVyIGlzIGluamVjdGVkIGF0IHRoZSB0b3Agb2YgdGhlIGxpc3QgYW5kIHdpbGwgYmUgdGhlIG5ldwogKiBoYW5kbGVyIHRvIGJlIGNhbGxlZCBmaXJzdC4gIFRoaXMgZnVuY3Rpb24gYWxzbyBpbmplY3RzIGEgc2VyaWFsaXplIAogKiBoYW5kbGVyIGJlZm9yZSBhY3R1YWxseSBjYWxsaW5nIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlLCByZWdpc3RlcmluZyAKICogcmVnaW5mby4KICoKICogQHBhcmFtIHJlZ2luZm8gYSBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBzdHJ1Y3R1cmUgd2hpY2ggY291bGQgZ2V0IGNyZWF0ZWQKICogICAgICAgICAgICAgICAgdXNpbmcgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24uICBVc2VkIHRvIHJlZ2lzdGVyCiAqICAgICAgICAgICAgICAgIGFuIGluc3RhbmNlIGhlbHBlciBoYW5kbGVyLgogKgogKiBAcmV0dXJuCiAqICAgICAgTUlCX1JFR0lTVEVSRURfT0sgaXMgcmV0dXJuZWQgaWYgdGhlIHJlZ2lzdHJhdGlvbiB3YXMgYSBzdWNjZXNzLgogKglGYWlsdXJlcyBhcmUgTUlCX1JFR0lTVFJBVElPTl9GQUlMRUQgYW5kIE1JQl9EVVBMSUNBVEVfUkVHSVNUUkFUSU9OLgogKi8KaW50Cm5ldHNubXBfcmVnaXN0ZXJfaW5zdGFuY2UobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciA9IG5ldHNubXBfZ2V0X2luc3RhbmNlX2hhbmRsZXIoKTsKICAgIGhhbmRsZXItPmZsYWdzIHw9IE1JQl9IQU5ETEVSX0lOU1RBTkNFOwogICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLCBoYW5kbGVyKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3NlcmlhbGl6ZShyZWdpbmZvKTsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gaW5qZWN0cyBhICJyZWFkIG9ubHkiIGhhbmRsZXIgaW50byB0aGUgaGFuZGxlciBjaGFpbiAKICogcHJpb3IgdG8gc2VyaWFsaXppbmcvcmVnaXN0ZXJpbmcgdGhlIGhhbmRsZXIuCiAqCiAqIFRoZSBvbmx5IHB1cnBvc2Ugb2YgdGhpcyAicmVhZCBvbmx5IiBoYW5kbGVyIGlzIHRvIHJldHVybiBhbgogKiBhcHByb3ByaWF0ZSBlcnJvciBmb3IgYW55IHJlcXVlc3RzIHBhc3NlZCB0byBpdCBpbiBhIFNFVCBtb2RlLgogKiBJbnNlcnRpbmcgaXQgaW50byB5b3VyIGhhbmRsZXIgY2hhaW4gd2lsbCBlbnN1cmUgeW91J3JlIG5ldmVyCiAqIGFza2VkIHRvIHBlcmZvcm0gYSBTRVQgcmVxdWVzdCBzbyB5b3UgY2FuIGlnbm9yZSB0aG9zZSBlcnJvcgogKiBjb25kaXRpb25zLgogKgogKiBAcGFyYW0gcmVnaW5mbyBhIGhhbmRsZXIgcmVnaXN0cmF0aW9uIHN0cnVjdHVyZSB3aGljaCBjb3VsZCBnZXQgY3JlYXRlZAogKiAgICAgICAgICAgICAgICB1c2luZyBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbi4gIFVzZWQgdG8gcmVnaXN0ZXIKICogICAgICAgICAgICAgICAgYSByZWFkIG9ubHkgaW5zdGFuY2UgaGVscGVyIGhhbmRsZXIuCiAqCiAqIEByZXR1cm4KICogICAgICBNSUJfUkVHSVNURVJFRF9PSyBpcyByZXR1cm5lZCBpZiB0aGUgcmVnaXN0cmF0aW9uIHdhcyBhIHN1Y2Nlc3MuCiAqCUZhaWx1cmVzIGFyZSBNSUJfUkVHSVNUUkFUSU9OX0ZBSUxFRCBhbmQgTUlCX0RVUExJQ0FURV9SRUdJU1RSQVRJT04uCiAqLwppbnQKbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW5zdGFuY2UobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLCBuZXRzbm1wX2dldF9pbnN0YW5jZV9oYW5kbGVyKCkpOwogICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLCBuZXRzbm1wX2dldF9yZWFkX29ubHlfaGFuZGxlcigpKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3NlcmlhbGl6ZShyZWdpbmZvKTsKfQoKc3RhdGljCm5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKgpnZXRfcmVnKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgY29uc3QgY2hhciAqb3VybmFtZSwKICAgICAgICBvaWQgKiByZWdfb2lkLCBzaXplX3QgcmVnX29pZF9sZW4sCiAgICAgICAgdm9pZCAqaXQsCiAgICAgICAgaW50IG1vZGVzLAogICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc2NhbGFyaCwgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKiBzdWJoYW5kbGVyLAogICAgICAgIGNvbnN0IGNoYXIgKmNvbnRleHROYW1lKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpteXJlZzsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKm15aGFuZGxlcjsKCiAgICBpZiAoc3ViaGFuZGxlcikgewogICAgICAgIG15cmVnID0KICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24obmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnX29pZCwgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVzKTsKICAgICAgICBteWhhbmRsZXIgPSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKG91cm5hbWUsIHNjYWxhcmgpOwogICAgICAgIG15aGFuZGxlci0+bXl2b2lkID0gKHZvaWQgKikgaXQ7CiAgICAgICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcihteXJlZywgbXloYW5kbGVyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgbXlyZWcgPQogICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbihuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsYXJoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdfb2lkLCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZXMpOwogICAgICAgIG15cmVnLT5oYW5kbGVyLT5teXZvaWQgPSAodm9pZCAqKSBpdDsKICAgIH0KICAgIGlmIChjb250ZXh0TmFtZSkKICAgICAgICBteXJlZy0+Y29udGV4dE5hbWUgPSBzdHJkdXAoY29udGV4dE5hbWUpOwogICAgcmV0dXJuIG15cmVnOwp9CgovKiBXYXRjaGVkICdsb25nJyBpbnN0YW5jZXMgYXJlIHdyaXRhYmxlIG9uIGJvdGggMzItYml0IGFuZCA2NC1iaXQgc3lzdGVtcyAgKi8KaW50Cm5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X3Vsb25nX2luc3RhbmNlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqIHJlZ19vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCByZWdfb2lkX2xlbiwgdV9sb25nICogaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlcikKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWc7CgogICAgbXlyZWcgPSBnZXRfcmVnKG5hbWUsICJ1bG9uZ19oYW5kbGVyIiwgcmVnX29pZCwgcmVnX29pZF9sZW4sIGl0LAogICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JPTkxZLCBuZXRzbm1wX2luc3RhbmNlX3Vsb25nX2hhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlciwgTlVMTCk7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW5zdGFuY2UobXlyZWcpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl91bG9uZ19pbnN0YW5jZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqIHJlZ19vaWQsIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2xvbmcgKiBpdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIpCnsKICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKm15cmVnOwoKICAgIG15cmVnID0gZ2V0X3JlZyhuYW1lLCAidWxvbmdfaGFuZGxlciIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBpdCwKICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9SV1JJVEUsIG5ldHNubXBfaW5zdGFuY2VfdWxvbmdfaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICBzdWJoYW5kbGVyLCBOVUxMKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX2luc3RhbmNlKG15cmVnKTsKfQoKaW50Cm5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X2NvdW50ZXIzMl9pbnN0YW5jZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICogcmVnX29pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfbG9uZyAqIGl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlcikKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWc7CgogICAgbXlyZWcgPSBnZXRfcmVnKG5hbWUsICJjb3VudGVyMzJfaGFuZGxlciIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBpdCwKICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9ST05MWSwgbmV0c25tcF9pbnN0YW5jZV9jb3VudGVyMzJfaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICBzdWJoYW5kbGVyLCBOVUxMKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9pbnN0YW5jZShteXJlZyk7Cn0KCmludApuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9sb25nX2luc3RhbmNlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgKml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlcikKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWc7CgogICAgbXlyZWcgPSBnZXRfcmVnKG5hbWUsICJsb25nX2hhbmRsZXIiLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgaXQsCiAgICAgICAgICAgICAgICAgICAgSEFORExFUl9DQU5fUk9OTFksIG5ldHNubXBfaW5zdGFuY2VfbG9uZ19oYW5kbGVyLAogICAgICAgICAgICAgICAgICAgIHN1YmhhbmRsZXIsIE5VTEwpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X2luc3RhbmNlKG15cmVnKTsKfQoKaW50Cm5ldHNubXBfcmVnaXN0ZXJfbG9uZ19pbnN0YW5jZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyAqaXQsIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlcikKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWc7CgogICAgbXlyZWcgPSBnZXRfcmVnKG5hbWUsICJsb25nX2hhbmRsZXIiLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgaXQsCiAgICAgICAgICAgICAgICAgICAgSEFORExFUl9DQU5fUldSSVRFLCBuZXRzbm1wX2luc3RhbmNlX2xvbmdfaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICBzdWJoYW5kbGVyLCBOVUxMKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX2luc3RhbmNlKG15cmVnKTsKfQoKLyogV2F0Y2hlZCAnaW50JyBpbnN0YW5jZXMgYXJlIG9ubHkgd3JpdGFibGUgb24gMzItYml0IHN5c3RlbXMgICovCmludApuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV91aW50X2luc3RhbmNlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCAqaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKiBzdWJoYW5kbGVyKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpteXJlZzsKCiAgICBteXJlZyA9IGdldF9yZWcobmFtZSwgInVpbnRfaGFuZGxlciIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBpdCwKICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9ST05MWSwgbmV0c25tcF9pbnN0YW5jZV91aW50X2hhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlciwgTlVMTCk7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW5zdGFuY2UobXlyZWcpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl91aW50X2luc3RhbmNlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiByZWdfb2lkLCBzaXplX3QgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgKml0LCBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIpCnsKICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKm15cmVnOwoKICAgIG15cmVnID0gZ2V0X3JlZyhuYW1lLCAidWludF9oYW5kbGVyIiwgcmVnX29pZCwgcmVnX29pZF9sZW4sIGl0LAogICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JXUklURSwgbmV0c25tcF9pbnN0YW5jZV91aW50X2hhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlciwgTlVMTCk7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9pbnN0YW5jZShteXJlZyk7Cn0KCmludApuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9pbnRfaW5zdGFuY2UoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiByZWdfb2lkLCBzaXplX3QgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICppdCwgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKiBzdWJoYW5kbGVyKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpteXJlZzsKCiAgICBteXJlZyA9IGdldF9yZWcobmFtZSwgImludF9oYW5kbGVyIiwgcmVnX29pZCwgcmVnX29pZF9sZW4sIGl0LAogICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JPTkxZLCBuZXRzbm1wX2luc3RhbmNlX2ludF9oYW5kbGVyLAogICAgICAgICAgICAgICAgICAgIHN1YmhhbmRsZXIsIE5VTEwpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X2luc3RhbmNlKG15cmVnKTsKfQoKICAvKgogICAqIENvbXBhdGliaWxpdHkgd2l0aCBlYXJsaWVyIChpbmNvbnNpc3RlbnRseSBuYW1lZCkgcm91dGluZQogICAqLwppbnQKcmVnaXN0ZXJfcmVhZF9vbmx5X2ludF9pbnN0YW5jZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqIHJlZ19vaWQsIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKml0LCBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIpCnsKICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW50X2luc3RhbmNlKG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnX29pZCwgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQsIHN1YmhhbmRsZXIpOwp9CgovKgogKiBDb250ZXh0IHJlZ2lzdHJhdGlvbnMKICovCgppbnQKbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfdWxvbmdfaW5zdGFuY2VfY29udGV4dChjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqIHJlZ19vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfbG9uZyAqIGl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNvbnRleHROYW1lKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpteXJlZzsKCiAgICBteXJlZyA9IGdldF9yZWcobmFtZSwgInVsb25nX2hhbmRsZXIiLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgaXQsCiAgICAgICAgICAgICAgICAgICAgSEFORExFUl9DQU5fUk9OTFksIG5ldHNubXBfaW5zdGFuY2VfdWxvbmdfaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICBzdWJoYW5kbGVyLCBjb250ZXh0TmFtZSk7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW5zdGFuY2UobXlyZWcpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl91bG9uZ19pbnN0YW5jZV9jb250ZXh0KGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiByZWdfb2lkLCBzaXplX3QgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2xvbmcgKiBpdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNvbnRleHROYW1lKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpteXJlZzsKCiAgICBteXJlZyA9IGdldF9yZWcobmFtZSwgInVsb25nX2hhbmRsZXIiLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgaXQsCiAgICAgICAgICAgICAgICAgICAgSEFORExFUl9DQU5fUldSSVRFLCBuZXRzbm1wX2luc3RhbmNlX3Vsb25nX2hhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlciwgY29udGV4dE5hbWUpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfaW5zdGFuY2UobXlyZWcpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfY291bnRlcjMyX2luc3RhbmNlX2NvbnRleHQoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICogcmVnX29pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2xvbmcgKiBpdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpjb250ZXh0TmFtZSkKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWc7CgogICAgbXlyZWcgPSBnZXRfcmVnKG5hbWUsICJjb3VudGVyMzJfaGFuZGxlciIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBpdCwKICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9ST05MWSwgbmV0c25tcF9pbnN0YW5jZV9jb3VudGVyMzJfaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICBzdWJoYW5kbGVyLCBjb250ZXh0TmFtZSk7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW5zdGFuY2UobXlyZWcpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfbG9uZ19pbnN0YW5jZV9jb250ZXh0KGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiByZWdfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyAqaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnN1YmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpjb250ZXh0TmFtZSkKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWc7CgogICAgbXlyZWcgPSBnZXRfcmVnKG5hbWUsICJsb25nX2hhbmRsZXIiLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgaXQsCiAgICAgICAgICAgICAgICAgICAgSEFORExFUl9DQU5fUk9OTFksIG5ldHNubXBfaW5zdGFuY2VfbG9uZ19oYW5kbGVyLAogICAgICAgICAgICAgICAgICAgIHN1YmhhbmRsZXIsIGNvbnRleHROYW1lKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9pbnN0YW5jZShteXJlZyk7Cn0KCmludApuZXRzbm1wX3JlZ2lzdGVyX2xvbmdfaW5zdGFuY2VfY29udGV4dChjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiByZWdfb2lkLCBzaXplX3QgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgKml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNvbnRleHROYW1lKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpteXJlZzsKCiAgICBteXJlZyA9IGdldF9yZWcobmFtZSwgImxvbmdfaGFuZGxlciIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBpdCwKICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9SV1JJVEUsIG5ldHNubXBfaW5zdGFuY2VfbG9uZ19oYW5kbGVyLAogICAgICAgICAgICAgICAgICAgIHN1YmhhbmRsZXIsIGNvbnRleHROYW1lKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX2luc3RhbmNlKG15cmVnKTsKfQoKaW50Cm5ldHNubXBfcmVnaXN0ZXJfaW50X2luc3RhbmNlX2NvbnRleHQoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiByZWdfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpjb250ZXh0TmFtZSkKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWc7CgogICAgbXlyZWcgPSBnZXRfcmVnKG5hbWUsICJpbnRfaGFuZGxlciIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBpdCwKICAgICAgICAgICAgICAgICAgICBIQU5ETEVSX0NBTl9SV1JJVEUsIG5ldHNubXBfaW5zdGFuY2VfaW50X2hhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlciwgY29udGV4dE5hbWUpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfaW5zdGFuY2UobXlyZWcpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW50X2luc3RhbmNlX2NvbnRleHQoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICogcmVnX29pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNvbnRleHROYW1lKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpteXJlZzsKCiAgICBteXJlZyA9IGdldF9yZWcobmFtZSwgImludF9oYW5kbGVyIiwgcmVnX29pZCwgcmVnX29pZF9sZW4sIGl0LAogICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JPTkxZLCBuZXRzbm1wX2luc3RhbmNlX2ludF9oYW5kbGVyLAogICAgICAgICAgICAgICAgICAgIHN1YmhhbmRsZXIsIGNvbnRleHROYW1lKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9pbnN0YW5jZShteXJlZyk7Cn0KCi8qCiAqIENvbXBhdGliaWxpdHkgd2l0aCBlYXJsaWVyIChpbmNvbnNpc3RlbnRseSBuYW1lZCkgcm91dGluZQogKi8KaW50CnJlZ2lzdGVyX3JlYWRfb25seV9pbnRfaW5zdGFuY2VfY29udGV4dChjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICppdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNvbnRleHROYW1lKQp7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW50X2luc3RhbmNlX2NvbnRleHQobmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdfb2lkLCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCwgc3ViaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0TmFtZSk7Cn0KCmludApuZXRzbm1wX3JlZ2lzdGVyX251bV9maWxlX2luc3RhbmNlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmZpbGVfbmFtZSwgaW50IGFzbl90eXBlLCBpbnQgbW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqY29udGV4dE5hbWUpCnsKICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKm15cmVnOwogICAgbmV0c25tcF9udW1fZmlsZV9pbnN0YW5jZSAqbmZpOwoKICAgIGlmICgoTlVMTCA9PSBuYW1lKSB8fCAoTlVMTCA9PSByZWdfb2lkKSB8fCAoTlVMTCA9PSBmaWxlX25hbWUpKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgImJhZCBwYXJhbWV0ZXIgdG8gbmV0c25tcF9yZWdpc3Rlcl9udW1fZmlsZV9pbnN0YW5jZVxuIik7CiAgICAgICAgcmV0dXJuIE1JQl9SRUdJU1RSQVRJT05fRkFJTEVEOwogICAgfQoKICAgIG5maSA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9udW1fZmlsZV9pbnN0YW5jZSk7CiAgICBpZiAoKE5VTEwgPT0gbmZpKSB8fAogICAgICAgIChOVUxMID09IChuZmktPmZpbGVfbmFtZSA9IHN0cmR1cChmaWxlX25hbWUpKSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiY291bGQgbm90IG5vdCBhbGxvY2F0ZSBtZW1vcnlcbiIpOwogICAgICAgIGlmIChOVUxMICE9IG5maSkKICAgICAgICAgICAgZnJlZShuZmkpOyAvKiBTTk1QX0ZSRUUgb3ZlcmtpbGwgb24gbG9jYWwgdmFyICovCiAgICAgICAgcmV0dXJuIE1JQl9SRUdJU1RSQVRJT05fRkFJTEVEOwogICAgfQoKICAgIG15cmVnID0gZ2V0X3JlZyhuYW1lLCAiZmlsZV9udW1faGFuZGxlciIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBuZmksCiAgICAgICAgICAgICAgICAgICAgbW9kZSwgbmV0c25tcF9pbnN0YW5jZV9udW1fZmlsZV9oYW5kbGVyLAogICAgICAgICAgICAgICAgICAgIHN1YmhhbmRsZXIsIGNvbnRleHROYW1lKTsKICAgIGlmIChOVUxMID09IG15cmVnKSB7CiAgICAgICAgZnJlZShuZmkpOyAvKiBTTk1QX0ZSRUUgb3ZlcmtpbGwgb24gbG9jYWwgdmFyICovCiAgICAgICAgcmV0dXJuIE1JQl9SRUdJU1RSQVRJT05fRkFJTEVEOwogICAgfQoKICAgIG5maS0+dHlwZSA9IGFzbl90eXBlOwoKICAgIGlmIChIQU5ETEVSX0NBTl9ST05MWSA9PSBtb2RlKQogICAgICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9pbnN0YW5jZShteXJlZyk7CgogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfaW5zdGFuY2UobXlyZWcpOwp9CgovKioKICogVGhpcyBmdW5jdGlvbiByZWdpc3RlcnMgYW4gaW50IGhlbHBlciBoYW5kbGVyIHRvIGEgc3BlY2lmaWVkIE9JRC4KICoKICogQHBhcmFtIG5hbWUgICAgICAgICB0aGUgbmFtZSB1c2VkIGZvciByZWdpc3RyYXRpb24gcHJ1cG9zZXMuCiAqCiAqIEBwYXJhbSByZWdfb2lkICAgICAgdGhlIE9JRCB3aGVyZSB5b3Ugd2FudCB0byByZWdpc3RlciB5b3VyIGludGVnZXIgYXQKICoKICogQHBhcmFtIHJlZ19vaWRfbGVuICB0aGUgbGVuZ3RoIG9mIHRoZSBPSUQKICoKICogQHBhcmFtIGl0ICAgICAgICAgICB0aGUgaW50ZWdlciB2YWx1ZSB0byBiZSByZWdpc3RlcmVkIGR1cmluZyBpbml0aWFsaXphdGlvbgogKgogKiBAcGFyYW0gc3ViaGFuZGxlciAgIGEgaGFuZGxlciB0byBkbyB3aGF0ZXZlciB5b3Ugd2FudCB0byBkbywgb3RoZXJ3aXNlIHVzZQogKiAgICAgICAgICAgICAgICAgICAgIE5VTEwgdG8gdXNlIHRoZSBkZWZhdWx0IGludCBoYW5kbGVyLgogKgogKiBAcmV0dXJuCiAqICAgICAgTUlCX1JFR0lTVEVSRURfT0sgaXMgcmV0dXJuZWQgaWYgdGhlIHJlZ2lzdHJhdGlvbiB3YXMgYSBzdWNjZXNzLgogKglGYWlsdXJlcyBhcmUgTUlCX1JFR0lTVFJBVElPTl9GQUlMRUQgYW5kIE1JQl9EVVBMSUNBVEVfUkVHSVNUUkFUSU9OLgogKi8KaW50Cm5ldHNubXBfcmVnaXN0ZXJfaW50X2luc3RhbmNlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqIHJlZ19vaWQsIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICppdCwgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKiBzdWJoYW5kbGVyKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpteXJlZzsKCiAgICBteXJlZyA9IGdldF9yZWcobmFtZSwgImludF9oYW5kbGVyIiwgcmVnX29pZCwgcmVnX29pZF9sZW4sIGl0LAogICAgICAgICAgICAgICAgICAgIEhBTkRMRVJfQ0FOX1JXUklURSwgbmV0c25tcF9pbnN0YW5jZV9pbnRfaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICBzdWJoYW5kbGVyLCBOVUxMKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX2luc3RhbmNlKG15cmVnKTsKfQoKaW50Cm5ldHNubXBfaW5zdGFuY2VfdWxvbmdfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgdV9sb25nICAgICAgICAgKml0ID0gKHVfbG9uZyAqKSBoYW5kbGVyLT5teXZvaWQ7CiAgICB1X2xvbmcgICAgICAgICAqaXRfc2F2ZTsKCiAgICBERUJVR01TR1RMKCgibmV0c25tcF9pbnN0YW5jZV91bG9uZ19oYW5kbGVyIiwgIkdvdCByZXF1ZXN0OiAgJWRcbiIsCiAgICAgICAgICAgICAgICByZXFpbmZvLT5tb2RlKSk7CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkYXRhIHJlcXVlc3RzIAogICAgICAgICAqLwogICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdHMtPnJlcXVlc3R2YiwgQVNOX1VOU0lHTkVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIGl0LCBzaXplb2YoKml0KSk7CiAgICAgICAgYnJlYWs7CgogICAgICAgIC8qCiAgICAgICAgICogU0VUIHJlcXVlc3RzLiAgU2hvdWxkIG9ubHkgZ2V0IGhlcmUgaWYgcmVnaXN0ZXJlZCBSV1JJVEUgCiAgICAgICAgICovCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgICAgIGlmIChyZXF1ZXN0cy0+cmVxdWVzdHZiLT50eXBlICE9IEFTTl9VTlNJR05FRCkKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9XUk9OR1RZUEUpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICAgICAgLyoKICAgICAgICAgKiBzdG9yZSBvbGQgaW5mbyBmb3IgdW5kbyBsYXRlciAKICAgICAgICAgKi8KICAgICAgICBtZW1kdXAoKHVfY2hhciAqKikgJiBpdF9zYXZlLCAodV9jaGFyICopIGl0LCBzaXplb2YodV9sb25nKSk7CiAgICAgICAgaWYgKGl0X3NhdmUgPT0gTlVMTCkgewogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1JFU09VUkNFVU5BVkFJTEFCTEUpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElOU1RBTkNFX0hBTkRMRVJfTkFNRSwgaXRfc2F2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZSkpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfQUNUSU9OOgogICAgICAgIC8qCiAgICAgICAgICogdXBkYXRlIGN1cnJlbnQgCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoInRlc3RoYW5kbGVyIiwgInVwZGF0ZWQgdV9sb25nICVsdSAtPiAlbHVcbiIsICppdCwKICAgICAgICAgICAgICAgICAgICAqKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5pbnRlZ2VyKSkpOwogICAgICAgICppdCA9ICoocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsLmludGVnZXIpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfVU5ETzoKICAgICAgICAqaXQgPQogICAgICAgICAgICAqKCh1X2xvbmcgKikgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlNUQU5DRV9IQU5ETEVSX05BTUUpKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICAvKgogICAgICAgICAqIG5vdGhpbmcgdG8gZG8gCiAgICAgICAgICovCiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGhhbmRsZXItPm5leHQgJiYgaGFuZGxlci0+bmV4dC0+YWNjZXNzX21ldGhvZCkKICAgICAgICByZXR1cm4gbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKCiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKaW50Cm5ldHNubXBfaW5zdGFuY2VfY291bnRlcjMyX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIHVfbG9uZyAgICAgICAgICppdCA9ICh1X2xvbmcgKikgaGFuZGxlci0+bXl2b2lkOwoKICAgIERFQlVHTVNHVEwoKCJuZXRzbm1wX2luc3RhbmNlX2NvdW50ZXIzMl9oYW5kbGVyIiwKICAgICAgICAgICAgICAgICJHb3QgcmVxdWVzdDogICVkXG4iLCByZXFpbmZvLT5tb2RlKSk7CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkYXRhIHJlcXVlc3RzIAogICAgICAgICAqLwogICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdHMtPnJlcXVlc3R2YiwgQVNOX0NPVU5URVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgaXQsIHNpemVvZigqaXQpKTsKICAgICAgICBicmVhazsKCiAgICAgICAgLyoKICAgICAgICAgKiBTRVQgcmVxdWVzdHMuICBTaG91bGQgb25seSBnZXQgaGVyZSBpZiByZWdpc3RlcmVkIFJXUklURSAKICAgICAgICAgKi8KICAgIGRlZmF1bHQ6CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAibmV0c25tcF9pbnN0YW5jZV9jb3VudGVyMzJfaGFuZGxlcjogaWxsZWdhbCBtb2RlXG4iKTsKICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgfQogICAgaWYgKGhhbmRsZXItPm5leHQgJiYgaGFuZGxlci0+bmV4dC0+YWNjZXNzX21ldGhvZCkKICAgICAgICByZXR1cm4gbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwp9CgppbnQKbmV0c25tcF9pbnN0YW5jZV9sb25nX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIGxvbmcgICAgICAgICAgICppdCA9IChsb25nICopIGhhbmRsZXItPm15dm9pZDsKICAgIGxvbmcgICAgICAgICAgICppdF9zYXZlOwoKICAgIERFQlVHTVNHVEwoKCJuZXRzbm1wX2luc3RhbmNlX2xvbmdfaGFuZGxlciIsICJHb3QgcmVxdWVzdDogICVkXG4iLAogICAgICAgICAgICAgICAgcmVxaW5mby0+bW9kZSkpOwoKICAgIHN3aXRjaCAocmVxaW5mby0+bW9kZSkgewogICAgICAgIC8qCiAgICAgICAgICogZGF0YSByZXF1ZXN0cyAKICAgICAgICAgKi8KICAgIGNhc2UgTU9ERV9HRVQ6CiAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3RzLT5yZXF1ZXN0dmIsIEFTTl9JTlRFR0VSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIGl0LCBzaXplb2YoKml0KSk7CiAgICAgICAgYnJlYWs7CgogICAgICAgIC8qCiAgICAgICAgICogU0VUIHJlcXVlc3RzLiAgU2hvdWxkIG9ubHkgZ2V0IGhlcmUgaWYgcmVnaXN0ZXJlZCBSV1JJVEUgCiAgICAgICAgICovCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgICAgIGlmIChyZXF1ZXN0cy0+cmVxdWVzdHZiLT50eXBlICE9IEFTTl9JTlRFR0VSKQogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1dST05HVFlQRSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMjoKICAgICAgICAvKgogICAgICAgICAqIHN0b3JlIG9sZCBpbmZvIGZvciB1bmRvIGxhdGVyIAogICAgICAgICAqLwogICAgICAgIG1lbWR1cCgodV9jaGFyICoqKSAmIGl0X3NhdmUsICh1X2NoYXIgKikgaXQsIHNpemVvZihsb25nKSk7CiAgICAgICAgaWYgKGl0X3NhdmUgPT0gTlVMTCkgewogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1JFU09VUkNFVU5BVkFJTEFCTEUpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElOU1RBTkNFX0hBTkRMRVJfTkFNRSwgaXRfc2F2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZSkpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfQUNUSU9OOgogICAgICAgIC8qCiAgICAgICAgICogdXBkYXRlIGN1cnJlbnQgCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoInRlc3RoYW5kbGVyIiwgInVwZGF0ZWQgdV9sb25nICVsdSAtPiAlbHVcbiIsICppdCwKICAgICAgICAgICAgICAgICAgICAqKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5pbnRlZ2VyKSkpOwogICAgICAgICppdCA9ICoocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsLmludGVnZXIpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfVU5ETzoKICAgICAgICAqaXQgPQogICAgICAgICAgICAqKCh1X2xvbmcgKikgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlNUQU5DRV9IQU5ETEVSX05BTUUpKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICAvKgogICAgICAgICAqIG5vdGhpbmcgdG8gZG8gCiAgICAgICAgICovCiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoaGFuZGxlci0+bmV4dCAmJiBoYW5kbGVyLT5uZXh0LT5hY2Nlc3NfbWV0aG9kKQogICAgICAgIHJldHVybiBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMpOwogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCmludApuZXRzbm1wX2luc3RhbmNlX2ludF9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKCiAgICBpbnQgKml0ID0gKGludCAqKSBoYW5kbGVyLT5teXZvaWQ7CiAgICBpbnQgKml0X3NhdmU7CiAgICBsb25nIHRtcF9pdDsKICAgIAogICAgREVCVUdNU0dUTCgoIm5ldHNubXBfaW5zdGFuY2VfaW50X2hhbmRsZXIiLCAiR290IHJlcXVlc3Q6ICAlZFxuIiwKICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUpKTsKCiAgICBzd2l0Y2ggKHJlcWluZm8tPm1vZGUpIHsKICAgICAgICAvKgogICAgICAgICAqIGRhdGEgcmVxdWVzdHMgCiAgICAgICAgICovCiAgICBjYXNlIE1PREVfR0VUOgoJLyoKCSAqIFVzZSBhIGxvbmcgaGVyZSwgb3RoZXJ3aXNlIG9uIDY0IGJpdCB1c2Ugb2YgYW4gaW50IHdvdWxkIGZhaWwKCSAqLwoJdG1wX2l0ID0gKml0OwogICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0cy0+cmVxdWVzdHZiLCBBU05fSU5URUdFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSAmdG1wX2l0LCBzaXplb2YodG1wX2l0KSk7CiAgICAgICAgYnJlYWs7CgogICAgICAgIC8qCiAgICAgICAgICogU0VUIHJlcXVlc3RzLiAgU2hvdWxkIG9ubHkgZ2V0IGhlcmUgaWYgcmVnaXN0ZXJlZCBSV1JJVEUgCiAgICAgICAgICovCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgICAgIGlmIChyZXF1ZXN0cy0+cmVxdWVzdHZiLT50eXBlICE9IEFTTl9JTlRFR0VSKQogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1dST05HVFlQRSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMjoKICAgICAgICAvKgogICAgICAgICAqIHN0b3JlIG9sZCBpbmZvIGZvciB1bmRvIGxhdGVyIAogICAgICAgICAqLwogICAgICAgIG1lbWR1cCgodV9jaGFyICoqKSAmIGl0X3NhdmUsICh1X2NoYXIgKikgaXQsIHNpemVvZihpbnQpKTsKICAgICAgICBpZiAoaXRfc2F2ZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRSk7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSU5TVEFOQ0VfSEFORExFUl9OQU1FLCBpdF9zYXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICAgICAgLyoKICAgICAgICAgKiB1cGRhdGUgY3VycmVudCAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgidGVzdGhhbmRsZXIiLCAidXBkYXRlZCBpbnQgJWQgLT4gJWxkXG4iLCAqaXQsCiAgICAgICAgICAgICAgICAgICAgKihyZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWwuaW50ZWdlcikpKTsKICAgICAgICAqaXQgPSAoaW50KSAqKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5pbnRlZ2VyKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgKml0ID0KICAgICAgICAgICAgKigodV9pbnQgKikgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOU1RBTkNFX0hBTkRMRVJfTkFNRSkpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfQ09NTUlUOgogICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgICAgIC8qCiAgICAgICAgICogbm90aGluZyB0byBkbyAKICAgICAgICAgKi8KICAgICAgICBicmVhazsKICAgIH0KICAgIGlmIChoYW5kbGVyLT5uZXh0ICYmIGhhbmRsZXItPm5leHQtPmFjY2Vzc19tZXRob2QpCiAgICAgICAgcmV0dXJuIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0cyk7CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKaW50Cm5ldHNubXBfaW5zdGFuY2VfbnVtX2ZpbGVfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBuZXRzbm1wX251bV9maWxlX2luc3RhbmNlICpuZmk7CiAgICB1X2xvbmcgaXQsICppdF9zYXZlOwogICAgaW50IHJjOwoKICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gaGFuZGxlcik7CiAgICBuZmkgPSAobmV0c25tcF9udW1fZmlsZV9pbnN0YW5jZSAqKWhhbmRsZXItPm15dm9pZDsKICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gbmZpKTsKICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gbmZpLT5maWxlX25hbWUpOwoKICAgIERFQlVHTVNHVEwoKCJuZXRzbm1wX2luc3RhbmNlX2ludF9oYW5kbGVyIiwgIkdvdCByZXF1ZXN0OiAgJWRcbiIsCiAgICAgICAgICAgICAgICByZXFpbmZvLT5tb2RlKSk7CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkYXRhIHJlcXVlc3RzIAogICAgICAgICAqLwogICAgY2FzZSBNT0RFX0dFVDoKCS8qCgkgKiBVc2UgYSBsb25nIGhlcmUsIG90aGVyd2lzZSBvbiA2NCBiaXQgdXNlIG9mIGFuIGludCB3b3VsZCBmYWlsCgkgKi8KICAgICAgICBuZXRzbm1wX2Fzc2VydChOVUxMID09IG5maS0+ZmlsZXApOwogICAgICAgIG5maS0+ZmlsZXAgPSBmb3BlbihuZmktPmZpbGVfbmFtZSwgInIiKTsKICAgICAgICBpZiAoTlVMTCA9PSBuZmktPmZpbGVwKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9OT1NVQ0hJTlNUQU5DRSk7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICByYyA9IGZzY2FuZihuZmktPmZpbGVwLCAobmZpLT50eXBlID09IEFTTl9JTlRFR0VSKSA/ICIlbGQiIDogIiVsdSIsCiAgICAgICAgICAgICAgICAgICAgJml0KTsKICAgICAgICBmY2xvc2UobmZpLT5maWxlcCk7CiAgICAgICAgbmZpLT5maWxlcCA9IE5VTEw7CiAgICAgICAgaWYgKHJjICE9IDEpIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX05PU1VDSElOU1RBTkNFKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfQogICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0cy0+cmVxdWVzdHZiLCBuZmktPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgJml0LCBzaXplb2YoaXQpKTsKICAgICAgICBicmVhazsKCiAgICAgICAgLyoKICAgICAgICAgKiBTRVQgcmVxdWVzdHMuICBTaG91bGQgb25seSBnZXQgaGVyZSBpZiByZWdpc3RlcmVkIFJXUklURSAKICAgICAgICAgKi8KICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICAgICAgbmV0c25tcF9hc3NlcnQoTlVMTCA9PSBuZmktPmZpbGVwKTsKICAgICAgICBpZiAocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dHlwZSAhPSBuZmktPnR5cGUpCiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfV1JPTkdUWVBFKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgPT0gbmZpLT5maWxlcCk7CiAgICAgICAgbmZpLT5maWxlcCA9IGZvcGVuKG5maS0+ZmlsZV9uYW1lLCAidysiKTsKICAgICAgICBpZiAoTlVMTCA9PSBuZmktPmZpbGVwKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfTk9UV1JJVEFCTEUpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBzdG9yZSBvbGQgaW5mbyBmb3IgdW5kbyBsYXRlciAKICAgICAgICAgKi8KICAgICAgICBpZiAoZnNjYW5mKG5maS0+ZmlsZXAsIChuZmktPnR5cGUgPT0gQVNOX0lOVEVHRVIpID8gIiVsZCIgOiAiJWx1IiwKICAgICAgICAgICAgICAgICAgICZpdCkgIT0gMSkgewogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1JFU09VUkNFVU5BVkFJTEFCTEUpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CgogICAgICAgIG1lbWR1cCgodV9jaGFyICoqKSAmIGl0X3NhdmUsICh1X2NoYXIgKikmaXQsIHNpemVvZih1X2xvbmcpKTsKICAgICAgICBpZiAoaXRfc2F2ZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRSk7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSU5TVEFOQ0VfSEFORExFUl9OQU1FLCBpdF9zYXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICAgICAgLyoKICAgICAgICAgKiB1cGRhdGUgY3VycmVudCAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmluc3RhbmNlIiwgInVwZGF0ZWQgJXMgLT4gJWxkXG4iLCBuZmktPmZpbGVfbmFtZSwKICAgICAgICAgICAgICAgICAgICAqKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5pbnRlZ2VyKSkpOwogICAgICAgIGl0ID0gKihyZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWwuaW50ZWdlcik7CiAgICAgICAgcmV3aW5kKG5maS0+ZmlsZXApOyAvKiByZXdpbmQgdG8gbWFrZSBzdXJlIHdlIGFyZSBhdCB0aGUgYmVnaW5uaW5nICovCiAgICAgICAgcmMgPSBmcHJpbnRmKG5maS0+ZmlsZXAsIChuZmktPnR5cGUgPT0gQVNOX0lOVEVHRVIpID8gIiVsZCIgOiAiJWx1IiwKICAgICAgICAgICAgICAgICAgICAgaXQpOwogICAgICAgIGlmIChyYyA8IDApIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgIGl0ID0KICAgICAgICAgICAgKigodV9pbnQgKikgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOU1RBTkNFX0hBTkRMRVJfTkFNRSkpOwogICAgICAgIHJjID0gZnByaW50ZihuZmktPmZpbGVwLCAobmZpLT50eXBlID09IEFTTl9JTlRFR0VSKSA/ICIlbGQiIDogIiVsdSIsCiAgICAgICAgICAgICAgICAgICAgIGl0KTsKICAgICAgICBpZiAocmMgPCAwKQogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1VORE9GQUlMRUQpOwogICAgICAgIC8qKiBmYWxsIHRocm91Z2ggKi8KCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICBpZiAoTlVMTCAhPSBuZmktPmZpbGVwKSB7CiAgICAgICAgICAgIGZjbG9zZShuZmktPmZpbGVwKTsKICAgICAgICAgICAgbmZpLT5maWxlcCA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChoYW5kbGVyLT5uZXh0ICYmIGhhbmRsZXItPm5leHQtPmFjY2Vzc19tZXRob2QpCiAgICAgICAgcmV0dXJuIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0cyk7CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKaW50Cm5ldHNubXBfaW5zdGFuY2VfdWludF9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKCiAgICB1bnNpZ25lZCBpbnQgKml0ID0gKHVuc2lnbmVkIGludCAqKSBoYW5kbGVyLT5teXZvaWQ7CiAgICB1bnNpZ25lZCBpbnQgKml0X3NhdmU7CiAgICB1bnNpZ25lZCBsb25nIHRtcF9pdDsKICAgIAogICAgREVCVUdNU0dUTCgoIm5ldHNubXBfaW5zdGFuY2VfdWludF9oYW5kbGVyIiwgIkdvdCByZXF1ZXN0OiAgJWRcbiIsCiAgICAgICAgICAgICAgICByZXFpbmZvLT5tb2RlKSk7CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkYXRhIHJlcXVlc3RzIAogICAgICAgICAqLwogICAgY2FzZSBNT0RFX0dFVDoKCS8qCgkgKiBVc2UgYSBsb25nIGhlcmUsIG90aGVyd2lzZSBvbiA2NCBiaXQgdXNlIG9mIGFuIGludCB3b3VsZCBmYWlsCgkgKi8KCXRtcF9pdCA9ICppdDsKICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdHMtPnJlcXVlc3R2YiwgQVNOX1VOU0lHTkVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopICZ0bXBfaXQsIHNpemVvZih1bnNpZ25lZCBsb25nKSk7CiAgICAgICAgYnJlYWs7CgogICAgICAgIC8qCiAgICAgICAgICogU0VUIHJlcXVlc3RzLiAgU2hvdWxkIG9ubHkgZ2V0IGhlcmUgaWYgcmVnaXN0ZXJlZCBSV1JJVEUgCiAgICAgICAgICovCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgICAgIGlmIChyZXF1ZXN0cy0+cmVxdWVzdHZiLT50eXBlICE9IEFTTl9VTlNJR05FRCkKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9XUk9OR1RZUEUpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICAgICAgLyoKICAgICAgICAgKiBzdG9yZSBvbGQgaW5mbyBmb3IgdW5kbyBsYXRlciAKICAgICAgICAgKi8KICAgICAgICBtZW1kdXAoKHVfY2hhciAqKikgJiBpdF9zYXZlLCAodV9jaGFyICopIGl0LCBzaXplb2YodV9pbnQpKTsKICAgICAgICBpZiAoaXRfc2F2ZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRSk7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSU5TVEFOQ0VfSEFORExFUl9OQU1FLCBpdF9zYXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICAgICAgLyoKICAgICAgICAgKiB1cGRhdGUgY3VycmVudCAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgidGVzdGhhbmRsZXIiLCAidXBkYXRlZCB1aW50ICVkIC0+ICVsZFxuIiwgKml0LAogICAgICAgICAgICAgICAgICAgICoocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsLmludGVnZXIpKSk7CiAgICAgICAgKml0ID0gKHVuc2lnbmVkIGludCkgKihyZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWwuaW50ZWdlcik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgICppdCA9CiAgICAgICAgICAgICooKHVfaW50ICopIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlNUQU5DRV9IQU5ETEVSX05BTUUpKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICAvKgogICAgICAgICAqIG5vdGhpbmcgdG8gZG8gCiAgICAgICAgICovCiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoaGFuZGxlci0+bmV4dCAmJiBoYW5kbGVyLT5uZXh0LT5hY2Nlc3NfbWV0aG9kKQogICAgICAgIHJldHVybiBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMpOwogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCmludApuZXRzbm1wX2luc3RhbmNlX2hlbHBlcl9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKCiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhciA9IHJlcXVlc3RzLT5yZXF1ZXN0dmI7CgogICAgaW50ICAgICAgICAgICAgIHJldCwgY21wOwoKICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6aW5zdGFuY2UiLCAiR290IHJlcXVlc3Q6XG4iKSk7CiAgICBjbXAgPSBzbm1wX29pZF9jb21wYXJlKHJlcXVlc3RzLT5yZXF1ZXN0dmItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzLT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5yb290b2lkLCByZWdpbmZvLT5yb290b2lkX2xlbik7CgogICAgREVCVUdNU0dUTCgoImhlbHBlcjppbnN0YW5jZSIsICIgIG9pZDoiKSk7CiAgICBERUJVR01TR09JRCgoImhlbHBlcjppbnN0YW5jZSIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgREVCVUdNU0coKCJoZWxwZXI6aW5zdGFuY2UiLCAiXG4iKSk7CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICBjYXNlIE1PREVfR0VUOgogICAgICAgIGlmIChjbXAgIT0gMCkgewogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfTk9TVUNISU5TVEFOQ0UpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0cyk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgIGNhc2UgTU9ERV9TRVRfVU5ETzoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICBpZiAoY21wICE9IDApIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9OT0NSRUFUSU9OKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfR0VUTkVYVDoKICAgICAgICBpZiAoY21wIDwgMCB8fCAoY21wID09IDAgJiYgcmVxdWVzdHMtPmluY2x1c2l2ZSkpIHsKICAgICAgICAgICAgcmVxaW5mby0+bW9kZSA9IE1PREVfR0VUOwogICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQocmVxdWVzdHMtPnJlcXVlc3R2YiwgcmVnaW5mby0+cm9vdG9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuKTsKICAgICAgICAgICAgcmV0ID0KICAgICAgICAgICAgICAgIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMpOwogICAgICAgICAgICByZXFpbmZvLT5tb2RlID0gTU9ERV9HRVRORVhUOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpZiB0aGUgaW5zdGFuY2UgZG9lc24ndCBoYXZlIGRhdGEsIHNldCB0eXBlIHRvIEFTTl9OVUxMCiAgICAgICAgICAgICAqIHRvIG1vdmUgdG8gdGhlIG5leHQgc3ViLXRyZWUuIElnbm9yZSBkZWxlZ2F0ZWQgcmVxdWVzdHM7IHRoZXkKICAgICAgICAgICAgICogbWlnaHQgaGF2ZSBkYXRhIGxhdGVyIG9uLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFyZXF1ZXN0cy0+ZGVsZWdhdGVkICYmCiAgICAgICAgICAgICAgICAocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dHlwZSA9PSBTTk1QX05PU1VDSElOU1RBTkNFIHx8CiAgICAgICAgICAgICAgICAgcmVxdWVzdHMtPnJlcXVlc3R2Yi0+dHlwZSA9PSBTTk1QX05PU1VDSE9CSkVDVCkpIHsKICAgICAgICAgICAgICAgIHJlcXVlc3RzLT5yZXF1ZXN0dmItPnR5cGUgPSBBU05fTlVMTDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICAgIC8qCiAgICAgKiBnb3QgaGVyZSBvbmx5IGlmIGlsbGVnYWwgbW9kZSBmb3VuZCAKICAgICAqLwogICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKfQoKLyoqIEB9IAogKi8K