LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9pbnN0YW5jZS5oPgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3NlcmlhbGl6ZS5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvcmVhZF9vbmx5Lmg+Cgp0eXBlZGVmIHN0cnVjdCBuZXRzbm1wX251bV9maWxlX2luc3RhbmNlX3MgewogICAgY2hhciAqZmlsZV9uYW1lOwogICAgRklMRSAqZmlsZXA7CiAgICBpbnQgICB0eXBlOwogICAgaW50ICAgZmxhZ3M7Cn0gbmV0c25tcF9udW1fZmlsZV9pbnN0YW5jZTsKCi8qKiBAZGVmZ3JvdXAgaW5zdGFuY2UgaW5zdGFuY2UKICogIFByb2Nlc3MgaW5kaXZpZHVhbCBNSUIgaW5zdGFuY2VzIGVhc2lseS4KICogIEBpbmdyb3VwIGxlYWYKICogIEB7CiAqLwoKLyoqCiAqIENyZWF0ZXMgYW4gaW5zdGFuY2UgaGVscGVyIGhhbmRsZXIsIGNhbGxzIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIsIHdoaWNoCiAqIHRoZW4gY291bGQgYmUgcmVnaXN0ZXJlZCwgdXNpbmcgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKCkuCiAqCiAqIEByZXR1cm4gUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX21pYl9oYW5kbGVyIHN0cnVjdCB3aGljaCBjb250YWlucwogKgl0aGUgaGFuZGxlcidzIG5hbWUgYW5kIHRoZSBhY2Nlc3MgbWV0aG9kCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9nZXRfaW5zdGFuY2VfaGFuZGxlcih2b2lkKQp7CiAgICByZXR1cm4gbmV0c25tcF9jcmVhdGVfaGFuZGxlcigiaW5zdGFuY2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9pbnN0YW5jZV9oZWxwZXJfaGFuZGxlcik7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHJlZ2lzdGVycyBhbiBpbnN0YW5jZSBoZWxwZXIgaGFuZGxlciwgd2hpY2ggaXMgYSB3YXkgb2YgCiAqIHJlZ2lzdGVyaW5nIGFuIGV4YWN0IE9JRCBzdWNoIHRoYXQgR0VORVhUIHJlcXVlc3RzIGFyZSBoYW5kbGVkIGVudGlyZWx5CiAqIGJ5IHRoZSBoZWxwZXIuIEZpcnN0IG5lZWQgdG8gaW5qZWN0IGl0IGludG8gdGhlIGNhbGxpbmcgY2hhaW4gb2YgdGhlIAogKiBoYW5kbGVyIGRlZmluZWQgYnkgdGhlIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gc3RydWN0LCByZWdpbmZvLiAgCiAqIFRoZSBuZXcgaGFuZGxlciBpcyBpbmplY3RlZCBhdCB0aGUgdG9wIG9mIHRoZSBsaXN0IGFuZCB3aWxsIGJlIHRoZSBuZXcKICogaGFuZGxlciB0byBiZSBjYWxsZWQgZmlyc3QuICBUaGlzIGZ1bmN0aW9uIGFsc28gaW5qZWN0cyBhIHNlcmlhbGl6ZSAKICogaGFuZGxlciBiZWZvcmUgYWN0dWFsbHkgY2FsbGluZyBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZSwgcmVnaXN0ZXJpbmcgCiAqIHJlZ2luZm8uCiAqCiAqIEBwYXJhbSByZWdpbmZvIGEgaGFuZGxlciByZWdpc3RyYXRpb24gc3RydWN0dXJlIHdoaWNoIGNvdWxkIGdldCBjcmVhdGVkCiAqICAgICAgICAgICAgICAgIHVzaW5nIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uLiAgVXNlZCB0byByZWdpc3RlcgogKiAgICAgICAgICAgICAgICBhbiBpbnN0YW5jZSBoZWxwZXIgaGFuZGxlci4KICoKICogQHJldHVybgogKiAgICAgIE1JQl9SRUdJU1RFUkVEX09LIGlzIHJldHVybmVkIGlmIHRoZSByZWdpc3RyYXRpb24gd2FzIGEgc3VjY2Vzcy4KICoJRmFpbHVyZXMgYXJlIE1JQl9SRUdJU1RSQVRJT05fRkFJTEVEIGFuZCBNSUJfRFVQTElDQVRFX1JFR0lTVFJBVElPTi4KICovCmludApuZXRzbm1wX3JlZ2lzdGVyX2luc3RhbmNlKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8pCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIgPSBuZXRzbm1wX2dldF9pbnN0YW5jZV9oYW5kbGVyKCk7CiAgICBoYW5kbGVyLT5mbGFncyB8PSBNSUJfSEFORExFUl9JTlNUQU5DRTsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgaGFuZGxlcik7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9zZXJpYWxpemUocmVnaW5mbyk7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIGluamVjdHMgYSAicmVhZCBvbmx5IiBoYW5kbGVyIGludG8gdGhlIGhhbmRsZXIgY2hhaW4gCiAqIHByaW9yIHRvIHNlcmlhbGl6aW5nL3JlZ2lzdGVyaW5nIHRoZSBoYW5kbGVyLgogKgogKiBUaGUgb25seSBwdXJwb3NlIG9mIHRoaXMgInJlYWQgb25seSIgaGFuZGxlciBpcyB0byByZXR1cm4gYW4KICogYXBwcm9wcmlhdGUgZXJyb3IgZm9yIGFueSByZXF1ZXN0cyBwYXNzZWQgdG8gaXQgaW4gYSBTRVQgbW9kZS4KICogSW5zZXJ0aW5nIGl0IGludG8geW91ciBoYW5kbGVyIGNoYWluIHdpbGwgZW5zdXJlIHlvdSdyZSBuZXZlcgogKiBhc2tlZCB0byBwZXJmb3JtIGEgU0VUIHJlcXVlc3Qgc28geW91IGNhbiBpZ25vcmUgdGhvc2UgZXJyb3IKICogY29uZGl0aW9ucy4KICoKICogQHBhcmFtIHJlZ2luZm8gYSBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBzdHJ1Y3R1cmUgd2hpY2ggY291bGQgZ2V0IGNyZWF0ZWQKICogICAgICAgICAgICAgICAgdXNpbmcgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24uICBVc2VkIHRvIHJlZ2lzdGVyCiAqICAgICAgICAgICAgICAgIGEgcmVhZCBvbmx5IGluc3RhbmNlIGhlbHBlciBoYW5kbGVyLgogKgogKiBAcmV0dXJuCiAqICAgICAgTUlCX1JFR0lTVEVSRURfT0sgaXMgcmV0dXJuZWQgaWYgdGhlIHJlZ2lzdHJhdGlvbiB3YXMgYSBzdWNjZXNzLgogKglGYWlsdXJlcyBhcmUgTUlCX1JFR0lTVFJBVElPTl9GQUlMRUQgYW5kIE1JQl9EVVBMSUNBVEVfUkVHSVNUUkFUSU9OLgogKi8KaW50Cm5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X2luc3RhbmNlKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8pCnsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgbmV0c25tcF9nZXRfaW5zdGFuY2VfaGFuZGxlcigpKTsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgbmV0c25tcF9nZXRfcmVhZF9vbmx5X2hhbmRsZXIoKSk7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9zZXJpYWxpemUocmVnaW5mbyk7Cn0KCnN0YXRpYwpuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICoKZ2V0X3JlZyhjb25zdCBjaGFyICpuYW1lLAogICAgICAgIGNvbnN0IGNoYXIgKm91cm5hbWUsCiAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgIHZvaWQgKml0LAogICAgICAgIGludCBtb2RlcywKICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHNjYWxhcmgsIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlciwKICAgICAgICBjb25zdCBjaGFyICpjb250ZXh0TmFtZSkKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWc7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpteWhhbmRsZXI7CgogICAgaWYgKHN1YmhhbmRsZXIpIHsKICAgICAgICBteXJlZyA9CiAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ19vaWQsIHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2Rlcyk7CiAgICAgICAgbXloYW5kbGVyID0gbmV0c25tcF9jcmVhdGVfaGFuZGxlcihvdXJuYW1lLCBzY2FsYXJoKTsKICAgICAgICBteWhhbmRsZXItPm15dm9pZCA9ICh2b2lkICopIGl0OwogICAgICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIobXlyZWcsIG15aGFuZGxlcik7CiAgICB9IGVsc2UgewogICAgICAgIG15cmVnID0KICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24obmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGFyaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnX29pZCwgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVzKTsKICAgICAgICBteXJlZy0+aGFuZGxlci0+bXl2b2lkID0gKHZvaWQgKikgaXQ7CiAgICB9CiAgICBpZiAoY29udGV4dE5hbWUpCiAgICAgICAgbXlyZWctPmNvbnRleHROYW1lID0gc3RyZHVwKGNvbnRleHROYW1lKTsKICAgIHJldHVybiBteXJlZzsKfQoKLyogV2F0Y2hlZCAnbG9uZycgaW5zdGFuY2VzIGFyZSB3cml0YWJsZSBvbiBib3RoIDMyLWJpdCBhbmQgNjQtYml0IHN5c3RlbXMgICovCmludApuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV91bG9uZ19pbnN0YW5jZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiByZWdfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgcmVnX29pZF9sZW4sIHVfbG9uZyAqIGl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YmhhbmRsZXIpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfaW5zdGFuY2UoCiAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgICAgbmFtZSwgc3ViaGFuZGxlciwgcmVnX29pZCwgcmVnX29pZF9sZW4sIEhBTkRMRVJfQ0FOX1JPTkxZKSwKICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAgICAgICAgKHZvaWQgKilpdCwgc2l6ZW9mKHVfbG9uZyksCiAgICAgICAgICAgICAgICAgICBBU05fVU5TSUdORUQsIFdBVENIRVJfRklYRURfU0laRSkpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl91bG9uZ19pbnN0YW5jZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIHJlZ19vaWQsIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2xvbmcgKiBpdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfaW5zdGFuY2UoCiAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgICAgbmFtZSwgc3ViaGFuZGxlciwgcmVnX29pZCwgcmVnX29pZF9sZW4sIEhBTkRMRVJfQ0FOX1JXUklURSksCiAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX3dhdGNoZXJfaW5mbygKICAgICAgICAgICAgICAgICAgICh2b2lkICopaXQsIHNpemVvZih1X2xvbmcpLAogICAgICAgICAgICAgICAgICAgQVNOX1VOU0lHTkVELCBXQVRDSEVSX0ZJWEVEX1NJWkUpKTsKfQoKaW50Cm5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X2NvdW50ZXIzMl9pbnN0YW5jZShjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfbG9uZyAqIGl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlcikKewogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9pbnN0YW5jZSgKICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oCiAgICAgICAgICAgICAgICAgICBuYW1lLCBzdWJoYW5kbGVyLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgSEFORExFUl9DQU5fUk9OTFkpLAogICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV93YXRjaGVyX2luZm8oCiAgICAgICAgICAgICAgICAgICAodm9pZCAqKWl0LCBzaXplb2YodV9sb25nKSwKICAgICAgICAgICAgICAgICAgIEFTTl9DT1VOVEVSLCBXQVRDSEVSX0ZJWEVEX1NJWkUpKTsKfQoKaW50Cm5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X2xvbmdfaW5zdGFuY2UoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiByZWdfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb25nICppdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfaW5zdGFuY2UoCiAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgICAgbmFtZSwgc3ViaGFuZGxlciwgcmVnX29pZCwgcmVnX29pZF9sZW4sIEhBTkRMRVJfQ0FOX1JPTkxZKSwKICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAgICAgICAgKHZvaWQgKilpdCwgc2l6ZW9mKGxvbmcpLCBBU05fSU5URUdFUiwgV0FUQ0hFUl9GSVhFRF9TSVpFKSk7Cn0KCmludApuZXRzbm1wX3JlZ2lzdGVyX2xvbmdfaW5zdGFuY2UoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIHJlZ19vaWQsIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgKml0LCBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfaW5zdGFuY2UoCiAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgICAgbmFtZSwgc3ViaGFuZGxlciwgcmVnX29pZCwgcmVnX29pZF9sZW4sIEhBTkRMRVJfQ0FOX1JXUklURSksCiAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX3dhdGNoZXJfaW5mbygKICAgICAgICAgICAgICAgICAgICh2b2lkICopaXQsIHNpemVvZihsb25nKSwgQVNOX0lOVEVHRVIsIFdBVENIRVJfRklYRURfU0laRSkpOwp9CgovKiBXYXRjaGVkICdpbnQnIGluc3RhbmNlcyBhcmUgb25seSB3cml0YWJsZSBvbiAzMi1iaXQgc3lzdGVtcyAgKi8KaW50Cm5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X3VpbnRfaW5zdGFuY2UoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiByZWdfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgKml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlcikKewogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9pbnN0YW5jZSgKICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oCiAgICAgICAgICAgICAgICAgICBuYW1lLCBzdWJoYW5kbGVyLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgSEFORExFUl9DQU5fUk9OTFkpLAogICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV93YXRjaGVyX2luZm8oCiAgICAgICAgICAgICAgICAgICAodm9pZCAqKWl0LCBzaXplb2YodW5zaWduZWQgaW50KSwKICAgICAgICAgICAgICAgICAgIEFTTl9VTlNJR05FRCwgV0FUQ0hFUl9GSVhFRF9TSVpFKSk7Cn0KCmludApuZXRzbm1wX3JlZ2lzdGVyX3VpbnRfaW5zdGFuY2UoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIHJlZ19vaWQsIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCAqaXQsIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlcikKewogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9pbnN0YW5jZSgKICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oCiAgICAgICAgICAgICAgICAgICBuYW1lLCBzdWJoYW5kbGVyLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgSEFORExFUl9DQU5fUldSSVRFKSwKICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAgICAgICAgKHZvaWQgKilpdCwgc2l6ZW9mKHVuc2lnbmVkIGludCksCiAgICAgICAgICAgICAgICAgICBBU05fVU5TSUdORUQsIFdBVENIRVJfRklYRURfU0laRSkpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW50X2luc3RhbmNlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqaXQsIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlcikKewogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9pbnN0YW5jZSgKICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oCiAgICAgICAgICAgICAgICAgICBuYW1lLCBzdWJoYW5kbGVyLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgSEFORExFUl9DQU5fUk9OTFkpLAogICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV93YXRjaGVyX2luZm8oCiAgICAgICAgICAgICAgICAgICAodm9pZCAqKWl0LCBzaXplb2YoaW50KSwgQVNOX0lOVEVHRVIsIFdBVENIRVJfRklYRURfU0laRSkpOwp9CgogIC8qCiAgICogQ29tcGF0aWJpbGl0eSB3aXRoIGVhcmxpZXIgKGluY29uc2lzdGVudGx5IG5hbWVkKSByb3V0aW5lCiAgICovCmludApyZWdpc3Rlcl9yZWFkX29ubHlfaW50X2luc3RhbmNlKGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqaXQsIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlcikKewogIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9pbnRfaW5zdGFuY2UobmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdfb2lkLCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdCwgc3ViaGFuZGxlcik7Cn0KCi8qCiAqIENvbnRleHQgcmVnaXN0cmF0aW9ucwogKi8KCmludApuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV91bG9uZ19pbnN0YW5jZV9jb250ZXh0KGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9sb25nICogaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqY29udGV4dE5hbWUpCnsKICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKm15cmVnID0KICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oCiAgICAgICAgICBuYW1lLCBzdWJoYW5kbGVyLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgSEFORExFUl9DQU5fUk9OTFkpOwogICAgaWYgKG15cmVnICYmIGNvbnRleHROYW1lKQogICAgICBteXJlZy0+Y29udGV4dE5hbWUgPSBzdHJkdXAoY29udGV4dE5hbWUpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9pbnN0YW5jZSgKICAgICAgICBteXJlZywgbmV0c25tcF9jcmVhdGVfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAodm9pZCAqKWl0LCBzaXplb2YodV9sb25nKSwgQVNOX1VOU0lHTkVELCBXQVRDSEVSX0ZJWEVEX1NJWkUpKTsKfQoKaW50Cm5ldHNubXBfcmVnaXN0ZXJfdWxvbmdfaW5zdGFuY2VfY29udGV4dChjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9sb25nICogaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpjb250ZXh0TmFtZSkKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWcgPQogICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigKICAgICAgICAgIG5hbWUsIHN1YmhhbmRsZXIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBIQU5ETEVSX0NBTl9SV1JJVEUpOwogICAgaWYgKG15cmVnICYmIGNvbnRleHROYW1lKQogICAgICBteXJlZy0+Y29udGV4dE5hbWUgPSBzdHJkdXAoY29udGV4dE5hbWUpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9pbnN0YW5jZSgKICAgICAgICBteXJlZywgbmV0c25tcF9jcmVhdGVfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAodm9pZCAqKWl0LCBzaXplb2YodV9sb25nKSwgQVNOX1VOU0lHTkVELCBXQVRDSEVSX0ZJWEVEX1NJWkUpKTsKfQoKaW50Cm5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X2NvdW50ZXIzMl9pbnN0YW5jZV9jb250ZXh0KGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIHJlZ19vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9sb25nICogaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqY29udGV4dE5hbWUpCnsKICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKm15cmVnID0KICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24oCiAgICAgICAgICBuYW1lLCBzdWJoYW5kbGVyLCByZWdfb2lkLCByZWdfb2lkX2xlbiwgSEFORExFUl9DQU5fUk9OTFkpOwogICAgaWYgKG15cmVnICYmIGNvbnRleHROYW1lKQogICAgICBteXJlZy0+Y29udGV4dE5hbWUgPSBzdHJkdXAoY29udGV4dE5hbWUpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9pbnN0YW5jZSgKICAgICAgICBteXJlZywgbmV0c25tcF9jcmVhdGVfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAodm9pZCAqKWl0LCBzaXplb2YodV9sb25nKSwgQVNOX0NPVU5URVIsIFdBVENIRVJfRklYRURfU0laRSkpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfbG9uZ19pbnN0YW5jZV9jb250ZXh0KGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiByZWdfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyAqaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnN1YmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpjb250ZXh0TmFtZSkKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWcgPQogICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigKICAgICAgICAgIG5hbWUsIHN1YmhhbmRsZXIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBIQU5ETEVSX0NBTl9ST05MWSk7CiAgICBpZiAobXlyZWcgJiYgY29udGV4dE5hbWUpCiAgICAgIG15cmVnLT5jb250ZXh0TmFtZSA9IHN0cmR1cChjb250ZXh0TmFtZSk7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl93YXRjaGVkX2luc3RhbmNlKAogICAgICAgIG15cmVnLCBuZXRzbm1wX2NyZWF0ZV93YXRjaGVyX2luZm8oCiAgICAgICAgICAgICh2b2lkICopaXQsIHNpemVvZihsb25nKSwgQVNOX0lOVEVHRVIsIFdBVENIRVJfRklYRURfU0laRSkpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl9sb25nX2luc3RhbmNlX2NvbnRleHQoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb25nICppdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKiBzdWJoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpjb250ZXh0TmFtZSkKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWcgPQogICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigKICAgICAgICAgIG5hbWUsIHN1YmhhbmRsZXIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBIQU5ETEVSX0NBTl9SV1JJVEUpOwogICAgaWYgKG15cmVnICYmIGNvbnRleHROYW1lKQogICAgICBteXJlZy0+Y29udGV4dE5hbWUgPSBzdHJkdXAoY29udGV4dE5hbWUpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9pbnN0YW5jZSgKICAgICAgICBteXJlZywgbmV0c25tcF9jcmVhdGVfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAodm9pZCAqKWl0LCBzaXplb2YobG9uZyksIEFTTl9JTlRFR0VSLCBXQVRDSEVSX0ZJWEVEX1NJWkUpKTsKfQoKaW50Cm5ldHNubXBfcmVnaXN0ZXJfaW50X2luc3RhbmNlX2NvbnRleHQoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiByZWdfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCByZWdfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpjb250ZXh0TmFtZSkKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWcgPQogICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbigKICAgICAgICAgIG5hbWUsIHN1YmhhbmRsZXIsIHJlZ19vaWQsIHJlZ19vaWRfbGVuLCBIQU5ETEVSX0NBTl9SV1JJVEUpOwogICAgaWYgKG15cmVnICYmIGNvbnRleHROYW1lKQogICAgICBteXJlZy0+Y29udGV4dE5hbWUgPSBzdHJkdXAoY29udGV4dE5hbWUpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfd2F0Y2hlZF9pbnN0YW5jZSgKICAgICAgICBteXJlZywgbmV0c25tcF9jcmVhdGVfd2F0Y2hlcl9pbmZvKAogICAgICAgICAgICAodm9pZCAqKWl0LCBzaXplb2YoaW50KSwgQVNOX0lOVEVHRVIsIFdBVENIRVJfRklYRURfU0laRSkpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfaW50X2luc3RhbmNlX2NvbnRleHQoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNvbnRleHROYW1lKQp7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpteXJlZyA9CiAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgbmFtZSwgc3ViaGFuZGxlciwgcmVnX29pZCwgcmVnX29pZF9sZW4sIEhBTkRMRVJfQ0FOX1JPTkxZKTsKICAgIGlmIChteXJlZyAmJiBjb250ZXh0TmFtZSkKICAgICAgbXlyZWctPmNvbnRleHROYW1lID0gc3RyZHVwKGNvbnRleHROYW1lKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfaW5zdGFuY2UoCiAgICAgICAgbXlyZWcsIG5ldHNubXBfY3JlYXRlX3dhdGNoZXJfaW5mbygKICAgICAgICAgICAgKHZvaWQgKilpdCwgc2l6ZW9mKGludCksIEFTTl9JTlRFR0VSLCBXQVRDSEVSX0ZJWEVEX1NJWkUpKTsKfQoKLyoKICogQ29tcGF0aWJpbGl0eSB3aXRoIGVhcmxpZXIgKGluY29uc2lzdGVudGx5IG5hbWVkKSByb3V0aW5lCiAqLwppbnQKcmVnaXN0ZXJfcmVhZF9vbmx5X2ludF9pbnN0YW5jZV9jb250ZXh0KGNvbnN0IGNoYXIgKm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiByZWdfb2lkLCBzaXplX3QgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9Ob2RlX0hhbmRsZXIgKiBzdWJoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqY29udGV4dE5hbWUpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9pbnRfaW5zdGFuY2VfY29udGV4dChuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ19vaWQsIHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0LCBzdWJoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHROYW1lKTsKfQoKaW50Cm5ldHNubXBfcmVnaXN0ZXJfbnVtX2ZpbGVfaW5zdGFuY2UoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiByZWdfb2lkLCBzaXplX3QgcmVnX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZmlsZV9uYW1lLCBpbnQgYXNuX3R5cGUsIGludCBtb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTm9kZV9IYW5kbGVyICogc3ViaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpjb250ZXh0TmFtZSkKewogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqbXlyZWc7CiAgICBuZXRzbm1wX251bV9maWxlX2luc3RhbmNlICpuZmk7CgogICAgaWYgKChOVUxMID09IG5hbWUpIHx8IChOVUxMID09IHJlZ19vaWQpIHx8IChOVUxMID09IGZpbGVfbmFtZSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiYmFkIHBhcmFtZXRlciB0byBuZXRzbm1wX3JlZ2lzdGVyX251bV9maWxlX2luc3RhbmNlXG4iKTsKICAgICAgICByZXR1cm4gTUlCX1JFR0lTVFJBVElPTl9GQUlMRUQ7CiAgICB9CgogICAgbmZpID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX251bV9maWxlX2luc3RhbmNlKTsKICAgIGlmICgoTlVMTCA9PSBuZmkpIHx8CiAgICAgICAgKE5VTEwgPT0gKG5maS0+ZmlsZV9uYW1lID0gc3RyZHVwKGZpbGVfbmFtZSkpKSkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJjb3VsZCBub3Qgbm90IGFsbG9jYXRlIG1lbW9yeVxuIik7CiAgICAgICAgaWYgKE5VTEwgIT0gbmZpKQogICAgICAgICAgICBmcmVlKG5maSk7IC8qIFNOTVBfRlJFRSBvdmVya2lsbCBvbiBsb2NhbCB2YXIgKi8KICAgICAgICByZXR1cm4gTUlCX1JFR0lTVFJBVElPTl9GQUlMRUQ7CiAgICB9CgogICAgbXlyZWcgPSBnZXRfcmVnKG5hbWUsICJmaWxlX251bV9oYW5kbGVyIiwgcmVnX29pZCwgcmVnX29pZF9sZW4sIG5maSwKICAgICAgICAgICAgICAgICAgICBtb2RlLCBuZXRzbm1wX2luc3RhbmNlX251bV9maWxlX2hhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgc3ViaGFuZGxlciwgY29udGV4dE5hbWUpOwogICAgaWYgKE5VTEwgPT0gbXlyZWcpIHsKICAgICAgICBmcmVlKG5maSk7IC8qIFNOTVBfRlJFRSBvdmVya2lsbCBvbiBsb2NhbCB2YXIgKi8KICAgICAgICByZXR1cm4gTUlCX1JFR0lTVFJBVElPTl9GQUlMRUQ7CiAgICB9CgogICAgbmZpLT50eXBlID0gYXNuX3R5cGU7CgogICAgaWYgKEhBTkRMRVJfQ0FOX1JPTkxZID09IG1vZGUpCiAgICAgICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X2luc3RhbmNlKG15cmVnKTsKCiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9pbnN0YW5jZShteXJlZyk7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHJlZ2lzdGVycyBhbiBpbnQgaGVscGVyIGhhbmRsZXIgdG8gYSBzcGVjaWZpZWQgT0lELgogKgogKiBAcGFyYW0gbmFtZSAgICAgICAgIHRoZSBuYW1lIHVzZWQgZm9yIHJlZ2lzdHJhdGlvbiBwcnVwb3Nlcy4KICoKICogQHBhcmFtIHJlZ19vaWQgICAgICB0aGUgT0lEIHdoZXJlIHlvdSB3YW50IHRvIHJlZ2lzdGVyIHlvdXIgaW50ZWdlciBhdAogKgogKiBAcGFyYW0gcmVnX29pZF9sZW4gIHRoZSBsZW5ndGggb2YgdGhlIE9JRAogKgogKiBAcGFyYW0gaXQgICAgICAgICAgIHRoZSBpbnRlZ2VyIHZhbHVlIHRvIGJlIHJlZ2lzdGVyZWQgZHVyaW5nIGluaXRpYWxpemF0aW9uCiAqCiAqIEBwYXJhbSBzdWJoYW5kbGVyICAgYSBoYW5kbGVyIHRvIGRvIHdoYXRldmVyIHlvdSB3YW50IHRvIGRvLCBvdGhlcndpc2UgdXNlCiAqICAgICAgICAgICAgICAgICAgICAgTlVMTCB0byB1c2UgdGhlIGRlZmF1bHQgaW50IGhhbmRsZXIuCiAqCiAqIEByZXR1cm4KICogICAgICBNSUJfUkVHSVNURVJFRF9PSyBpcyByZXR1cm5lZCBpZiB0aGUgcmVnaXN0cmF0aW9uIHdhcyBhIHN1Y2Nlc3MuCiAqCUZhaWx1cmVzIGFyZSBNSUJfUkVHSVNUUkFUSU9OX0ZBSUxFRCBhbmQgTUlCX0RVUExJQ0FURV9SRUdJU1RSQVRJT04uCiAqLwppbnQKbmV0c25tcF9yZWdpc3Rlcl9pbnRfaW5zdGFuY2UoY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogcmVnX29pZCwgc2l6ZV90IHJlZ19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKml0LCBOZXRzbm1wX05vZGVfSGFuZGxlciAqIHN1YmhhbmRsZXIpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3dhdGNoZWRfaW5zdGFuY2UoCiAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKAogICAgICAgICAgICAgICAgICAgbmFtZSwgc3ViaGFuZGxlciwgcmVnX29pZCwgcmVnX29pZF9sZW4sIEhBTkRMRVJfQ0FOX1JXUklURSksCiAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX3dhdGNoZXJfaW5mbygKICAgICAgICAgICAgICAgICAgICh2b2lkICopaXQsIHNpemVvZihpbnQpLCBBU05fSU5URUdFUiwgV0FUQ0hFUl9GSVhFRF9TSVpFKSk7Cn0KCiNpZm5kZWYgTkVUU05NUF9OT19ERVBSRUNBVEVEX0ZVTkNUSU9OUwoKLyoqCiAqIFxkZXByZWNhdGVkIFRoaXMgZnVuY3Rpb24gaXMgdW51c2VkIGFuZCBzY2hlZHVsZWQgZm9yIHJlbW92YWwgaW4gTmV0LVNOTVAgNS42CiAqLwppbnQKbmV0c25tcF9pbnN0YW5jZV91bG9uZ19oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKCiAgICB1X2xvbmcgICAgICAgICAqaXQgPSAodV9sb25nICopIGhhbmRsZXItPm15dm9pZDsKICAgIHVfbG9uZyAgICAgICAgICppdF9zYXZlOwoKICAgIERFQlVHTVNHVEwoKCJuZXRzbm1wX2luc3RhbmNlX3Vsb25nX2hhbmRsZXIiLCAiR290IHJlcXVlc3Q6ICAlZFxuIiwKICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUpKTsKCiAgICBzd2l0Y2ggKHJlcWluZm8tPm1vZGUpIHsKICAgICAgICAvKgogICAgICAgICAqIGRhdGEgcmVxdWVzdHMgCiAgICAgICAgICovCiAgICBjYXNlIE1PREVfR0VUOgogICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0cy0+cmVxdWVzdHZiLCBBU05fVU5TSUdORUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgaXQsIHNpemVvZigqaXQpKTsKICAgICAgICBicmVhazsKCiAgICAgICAgLyoKICAgICAgICAgKiBTRVQgcmVxdWVzdHMuICBTaG91bGQgb25seSBnZXQgaGVyZSBpZiByZWdpc3RlcmVkIFJXUklURSAKICAgICAgICAgKi8KICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICAgICAgaWYgKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnR5cGUgIT0gQVNOX1VOU0lHTkVEKQogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1dST05HVFlQRSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMjoKICAgICAgICAvKgogICAgICAgICAqIHN0b3JlIG9sZCBpbmZvIGZvciB1bmRvIGxhdGVyIAogICAgICAgICAqLwogICAgICAgIGl0X3NhdmUgPSBuZXRzbm1wX21lbWR1cChpdCwgc2l6ZW9mKHVfbG9uZykpOwogICAgICAgIGlmIChpdF9zYXZlID09IE5VTEwpIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9SRVNPVVJDRVVOQVZBSUxBQkxFKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfQogICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJTlNUQU5DRV9IQU5ETEVSX05BTUUsIGl0X3NhdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWUpKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgICAgICAvKgogICAgICAgICAqIHVwZGF0ZSBjdXJyZW50IAogICAgICAgICAqLwogICAgICAgIERFQlVHTVNHVEwoKCJ0ZXN0aGFuZGxlciIsICJ1cGRhdGVkIHVfbG9uZyAlbHUgLT4gJWx1XG4iLCAqaXQsCiAgICAgICAgICAgICAgICAgICAgKihyZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWwuaW50ZWdlcikpKTsKICAgICAgICAqaXQgPSAqKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5pbnRlZ2VyKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgKml0ID0KICAgICAgICAgICAgKigodV9sb25nICopIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5TVEFOQ0VfSEFORExFUl9OQU1FKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgICAgLyoKICAgICAgICAgKiBub3RoaW5nIHRvIGRvIAogICAgICAgICAqLwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChoYW5kbGVyLT5uZXh0ICYmIGhhbmRsZXItPm5leHQtPmFjY2Vzc19tZXRob2QpCiAgICAgICAgcmV0dXJuIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0cyk7CgogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCi8qKgogKiBcZGVwcmVjYXRlZCBUaGlzIGZ1bmN0aW9uIGlzIHVudXNlZCBhbmQgc2NoZWR1bGVkIGZvciByZW1vdmFsIGluIE5ldC1TTk1QIDUuNgogKi8KaW50Cm5ldHNubXBfaW5zdGFuY2VfY291bnRlcjMyX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIHVfbG9uZyAgICAgICAgICppdCA9ICh1X2xvbmcgKikgaGFuZGxlci0+bXl2b2lkOwoKICAgIERFQlVHTVNHVEwoKCJuZXRzbm1wX2luc3RhbmNlX2NvdW50ZXIzMl9oYW5kbGVyIiwKICAgICAgICAgICAgICAgICJHb3QgcmVxdWVzdDogICVkXG4iLCByZXFpbmZvLT5tb2RlKSk7CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkYXRhIHJlcXVlc3RzIAogICAgICAgICAqLwogICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdHMtPnJlcXVlc3R2YiwgQVNOX0NPVU5URVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgaXQsIHNpemVvZigqaXQpKTsKICAgICAgICBicmVhazsKCiAgICAgICAgLyoKICAgICAgICAgKiBTRVQgcmVxdWVzdHMuICBTaG91bGQgb25seSBnZXQgaGVyZSBpZiByZWdpc3RlcmVkIFJXUklURSAKICAgICAgICAgKi8KICAgIGRlZmF1bHQ6CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAibmV0c25tcF9pbnN0YW5jZV9jb3VudGVyMzJfaGFuZGxlcjogaWxsZWdhbCBtb2RlXG4iKTsKICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgfQogICAgaWYgKGhhbmRsZXItPm5leHQgJiYgaGFuZGxlci0+bmV4dC0+YWNjZXNzX21ldGhvZCkKICAgICAgICByZXR1cm4gbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwp9CgovKioKICogXGRlcHJlY2F0ZWQgVGhpcyBmdW5jdGlvbiBpcyB1bnVzZWQgYW5kIHNjaGVkdWxlZCBmb3IgcmVtb3ZhbCBpbiBOZXQtU05NUCA1LjYKICovCmludApuZXRzbm1wX2luc3RhbmNlX2xvbmdfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgbG9uZyAgICAgICAgICAgKml0ID0gKGxvbmcgKikgaGFuZGxlci0+bXl2b2lkOwogICAgbG9uZyAgICAgICAgICAgKml0X3NhdmU7CgogICAgREVCVUdNU0dUTCgoIm5ldHNubXBfaW5zdGFuY2VfbG9uZ19oYW5kbGVyIiwgIkdvdCByZXF1ZXN0OiAgJWRcbiIsCiAgICAgICAgICAgICAgICByZXFpbmZvLT5tb2RlKSk7CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkYXRhIHJlcXVlc3RzIAogICAgICAgICAqLwogICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdHMtPnJlcXVlc3R2YiwgQVNOX0lOVEVHRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgaXQsIHNpemVvZigqaXQpKTsKICAgICAgICBicmVhazsKCiAgICAgICAgLyoKICAgICAgICAgKiBTRVQgcmVxdWVzdHMuICBTaG91bGQgb25seSBnZXQgaGVyZSBpZiByZWdpc3RlcmVkIFJXUklURSAKICAgICAgICAgKi8KICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICAgICAgaWYgKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnR5cGUgIT0gQVNOX0lOVEVHRVIpCiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfV1JPTkdUWVBFKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgICAgIC8qCiAgICAgICAgICogc3RvcmUgb2xkIGluZm8gZm9yIHVuZG8gbGF0ZXIgCiAgICAgICAgICovCiAgICAgICAgaXRfc2F2ZSA9IG5ldHNubXBfbWVtZHVwKGl0LCBzaXplb2YobG9uZykpOwogICAgICAgIGlmIChpdF9zYXZlID09IE5VTEwpIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9SRVNPVVJDRVVOQVZBSUxBQkxFKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfQogICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJTlNUQU5DRV9IQU5ETEVSX05BTUUsIGl0X3NhdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWUpKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgICAgICAvKgogICAgICAgICAqIHVwZGF0ZSBjdXJyZW50IAogICAgICAgICAqLwogICAgICAgIERFQlVHTVNHVEwoKCJ0ZXN0aGFuZGxlciIsICJ1cGRhdGVkIHVfbG9uZyAlbHUgLT4gJWx1XG4iLCAqaXQsCiAgICAgICAgICAgICAgICAgICAgKihyZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWwuaW50ZWdlcikpKTsKICAgICAgICAqaXQgPSAqKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5pbnRlZ2VyKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgKml0ID0KICAgICAgICAgICAgKigodV9sb25nICopIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5TVEFOQ0VfSEFORExFUl9OQU1FKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgICAgLyoKICAgICAgICAgKiBub3RoaW5nIHRvIGRvIAogICAgICAgICAqLwogICAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKGhhbmRsZXItPm5leHQgJiYgaGFuZGxlci0+bmV4dC0+YWNjZXNzX21ldGhvZCkKICAgICAgICByZXR1cm4gbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwp9CgovKioKICogXGRlcHJlY2F0ZWQgVGhpcyBmdW5jdGlvbiBpcyB1bnVzZWQgYW5kIHNjaGVkdWxlZCBmb3IgcmVtb3ZhbCBpbiBOZXQtU05NUCA1LjYKICovCmludApuZXRzbm1wX2luc3RhbmNlX2ludF9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKCiAgICBpbnQgKml0ID0gKGludCAqKSBoYW5kbGVyLT5teXZvaWQ7CiAgICBpbnQgKml0X3NhdmU7CiAgICBsb25nIHRtcF9pdDsKICAgIAogICAgREVCVUdNU0dUTCgoIm5ldHNubXBfaW5zdGFuY2VfaW50X2hhbmRsZXIiLCAiR290IHJlcXVlc3Q6ICAlZFxuIiwKICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUpKTsKCiAgICBzd2l0Y2ggKHJlcWluZm8tPm1vZGUpIHsKICAgICAgICAvKgogICAgICAgICAqIGRhdGEgcmVxdWVzdHMgCiAgICAgICAgICovCiAgICBjYXNlIE1PREVfR0VUOgoJLyoKCSAqIFVzZSBhIGxvbmcgaGVyZSwgb3RoZXJ3aXNlIG9uIDY0IGJpdCB1c2Ugb2YgYW4gaW50IHdvdWxkIGZhaWwKCSAqLwoJdG1wX2l0ID0gKml0OwogICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0cy0+cmVxdWVzdHZiLCBBU05fSU5URUdFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSAmdG1wX2l0LCBzaXplb2YodG1wX2l0KSk7CiAgICAgICAgYnJlYWs7CgogICAgICAgIC8qCiAgICAgICAgICogU0VUIHJlcXVlc3RzLiAgU2hvdWxkIG9ubHkgZ2V0IGhlcmUgaWYgcmVnaXN0ZXJlZCBSV1JJVEUgCiAgICAgICAgICovCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgICAgIGlmIChyZXF1ZXN0cy0+cmVxdWVzdHZiLT50eXBlICE9IEFTTl9JTlRFR0VSKQogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1dST05HVFlQRSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMjoKICAgICAgICAvKgogICAgICAgICAqIHN0b3JlIG9sZCBpbmZvIGZvciB1bmRvIGxhdGVyIAogICAgICAgICAqLwogICAgICAgIGl0X3NhdmUgPSBuZXRzbm1wX21lbWR1cChpdCwgc2l6ZW9mKGludCkpOwogICAgICAgIGlmIChpdF9zYXZlID09IE5VTEwpIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9SRVNPVVJDRVVOQVZBSUxBQkxFKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfQogICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJTlNUQU5DRV9IQU5ETEVSX05BTUUsIGl0X3NhdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyZWUpKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgICAgICAvKgogICAgICAgICAqIHVwZGF0ZSBjdXJyZW50IAogICAgICAgICAqLwogICAgICAgIERFQlVHTVNHVEwoKCJ0ZXN0aGFuZGxlciIsICJ1cGRhdGVkIGludCAlZCAtPiAlbGRcbiIsICppdCwKICAgICAgICAgICAgICAgICAgICAqKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5pbnRlZ2VyKSkpOwogICAgICAgICppdCA9IChpbnQpICoocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsLmludGVnZXIpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfVU5ETzoKICAgICAgICAqaXQgPQogICAgICAgICAgICAqKCh1X2ludCAqKSBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5TVEFOQ0VfSEFORExFUl9OQU1FKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgICAgLyoKICAgICAgICAgKiBub3RoaW5nIHRvIGRvIAogICAgICAgICAqLwogICAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKGhhbmRsZXItPm5leHQgJiYgaGFuZGxlci0+bmV4dC0+YWNjZXNzX21ldGhvZCkKICAgICAgICByZXR1cm4gbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwp9CgojZW5kaWYgLyogTkVUU05NUF9OT19ERVBSRUNBVEVEX0ZVTkNUSU9OUyAqLwoKaW50Cm5ldHNubXBfaW5zdGFuY2VfbnVtX2ZpbGVfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBuZXRzbm1wX251bV9maWxlX2luc3RhbmNlICpuZmk7CiAgICB1X2xvbmcgaXQsICppdF9zYXZlOwogICAgaW50IHJjOwoKICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gaGFuZGxlcik7CiAgICBuZmkgPSAobmV0c25tcF9udW1fZmlsZV9pbnN0YW5jZSAqKWhhbmRsZXItPm15dm9pZDsKICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gbmZpKTsKICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gbmZpLT5maWxlX25hbWUpOwoKICAgIERFQlVHTVNHVEwoKCJuZXRzbm1wX2luc3RhbmNlX2ludF9oYW5kbGVyIiwgIkdvdCByZXF1ZXN0OiAgJWRcbiIsCiAgICAgICAgICAgICAgICByZXFpbmZvLT5tb2RlKSk7CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkYXRhIHJlcXVlc3RzIAogICAgICAgICAqLwogICAgY2FzZSBNT0RFX0dFVDoKCS8qCgkgKiBVc2UgYSBsb25nIGhlcmUsIG90aGVyd2lzZSBvbiA2NCBiaXQgdXNlIG9mIGFuIGludCB3b3VsZCBmYWlsCgkgKi8KICAgICAgICBuZXRzbm1wX2Fzc2VydChOVUxMID09IG5maS0+ZmlsZXApOwogICAgICAgIG5maS0+ZmlsZXAgPSBmb3BlbihuZmktPmZpbGVfbmFtZSwgInIiKTsKICAgICAgICBpZiAoTlVMTCA9PSBuZmktPmZpbGVwKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9OT1NVQ0hJTlNUQU5DRSk7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICByYyA9IGZzY2FuZihuZmktPmZpbGVwLCAobmZpLT50eXBlID09IEFTTl9JTlRFR0VSKSA/ICIlbGQiIDogIiVsdSIsCiAgICAgICAgICAgICAgICAgICAgJml0KTsKICAgICAgICBmY2xvc2UobmZpLT5maWxlcCk7CiAgICAgICAgbmZpLT5maWxlcCA9IE5VTEw7CiAgICAgICAgaWYgKHJjICE9IDEpIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX05PU1VDSElOU1RBTkNFKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfQogICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0cy0+cmVxdWVzdHZiLCBuZmktPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgJml0LCBzaXplb2YoaXQpKTsKICAgICAgICBicmVhazsKCiAgICAgICAgLyoKICAgICAgICAgKiBTRVQgcmVxdWVzdHMuICBTaG91bGQgb25seSBnZXQgaGVyZSBpZiByZWdpc3RlcmVkIFJXUklURSAKICAgICAgICAgKi8KICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICAgICAgbmV0c25tcF9hc3NlcnQoTlVMTCA9PSBuZmktPmZpbGVwKTsKICAgICAgICBpZiAocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dHlwZSAhPSBuZmktPnR5cGUpCiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfV1JPTkdUWVBFKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgPT0gbmZpLT5maWxlcCk7CiAgICAgICAgbmZpLT5maWxlcCA9IGZvcGVuKG5maS0+ZmlsZV9uYW1lLCAidysiKTsKICAgICAgICBpZiAoTlVMTCA9PSBuZmktPmZpbGVwKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfTk9UV1JJVEFCTEUpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBzdG9yZSBvbGQgaW5mbyBmb3IgdW5kbyBsYXRlciAKICAgICAgICAgKi8KICAgICAgICBpZiAoZnNjYW5mKG5maS0+ZmlsZXAsIChuZmktPnR5cGUgPT0gQVNOX0lOVEVHRVIpID8gIiVsZCIgOiAiJWx1IiwKICAgICAgICAgICAgICAgICAgICZpdCkgIT0gMSkgewogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1JFU09VUkNFVU5BVkFJTEFCTEUpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CgogICAgICAgIGl0X3NhdmUgPSBuZXRzbm1wX21lbWR1cCgmaXQsIHNpemVvZih1X2xvbmcpKTsKICAgICAgICBpZiAoaXRfc2F2ZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRSk7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSU5TVEFOQ0VfSEFORExFUl9OQU1FLCBpdF9zYXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICAgICAgLyoKICAgICAgICAgKiB1cGRhdGUgY3VycmVudCAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmluc3RhbmNlIiwgInVwZGF0ZWQgJXMgLT4gJWxkXG4iLCBuZmktPmZpbGVfbmFtZSwKICAgICAgICAgICAgICAgICAgICAqKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5pbnRlZ2VyKSkpOwogICAgICAgIGl0ID0gKihyZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWwuaW50ZWdlcik7CiAgICAgICAgcmV3aW5kKG5maS0+ZmlsZXApOyAvKiByZXdpbmQgdG8gbWFrZSBzdXJlIHdlIGFyZSBhdCB0aGUgYmVnaW5uaW5nICovCiAgICAgICAgcmMgPSBmcHJpbnRmKG5maS0+ZmlsZXAsIChuZmktPnR5cGUgPT0gQVNOX0lOVEVHRVIpID8gIiVsZCIgOiAiJWx1IiwKICAgICAgICAgICAgICAgICAgICAgaXQpOwogICAgICAgIGlmIChyYyA8IDApIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgIGl0ID0KICAgICAgICAgICAgKigodV9pbnQgKikgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOU1RBTkNFX0hBTkRMRVJfTkFNRSkpOwogICAgICAgIHJjID0gZnByaW50ZihuZmktPmZpbGVwLCAobmZpLT50eXBlID09IEFTTl9JTlRFR0VSKSA/ICIlbGQiIDogIiVsdSIsCiAgICAgICAgICAgICAgICAgICAgIGl0KTsKICAgICAgICBpZiAocmMgPCAwKQogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1VORE9GQUlMRUQpOwogICAgICAgIC8qKiBmYWxsIHRocm91Z2ggKi8KCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICBpZiAoTlVMTCAhPSBuZmktPmZpbGVwKSB7CiAgICAgICAgICAgIGZjbG9zZShuZmktPmZpbGVwKTsKICAgICAgICAgICAgbmZpLT5maWxlcCA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChoYW5kbGVyLT5uZXh0ICYmIGhhbmRsZXItPm5leHQtPmFjY2Vzc19tZXRob2QpCiAgICAgICAgcmV0dXJuIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0cyk7CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKI2lmbmRlZiBORVRTTk1QX05PX0RFUFJFQ0FURURfRlVOQ1RJT05TCgovKioKICogXGRlcHJlY2F0ZWQgVGhpcyBmdW5jdGlvbiBpcyB1bnVzZWQgYW5kIHNjaGVkdWxlZCBmb3IgcmVtb3ZhbCBpbiBOZXQtU05NUCA1LjYKICovCmludApuZXRzbm1wX2luc3RhbmNlX3VpbnRfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgdW5zaWduZWQgaW50ICppdCA9ICh1bnNpZ25lZCBpbnQgKikgaGFuZGxlci0+bXl2b2lkOwogICAgdW5zaWduZWQgaW50ICppdF9zYXZlOwogICAgdW5zaWduZWQgbG9uZyB0bXBfaXQ7CiAgICAKICAgIERFQlVHTVNHVEwoKCJuZXRzbm1wX2luc3RhbmNlX3VpbnRfaGFuZGxlciIsICJHb3QgcmVxdWVzdDogICVkXG4iLAogICAgICAgICAgICAgICAgcmVxaW5mby0+bW9kZSkpOwoKICAgIHN3aXRjaCAocmVxaW5mby0+bW9kZSkgewogICAgICAgIC8qCiAgICAgICAgICogZGF0YSByZXF1ZXN0cyAKICAgICAgICAgKi8KICAgIGNhc2UgTU9ERV9HRVQ6CgkvKgoJICogVXNlIGEgbG9uZyBoZXJlLCBvdGhlcndpc2Ugb24gNjQgYml0IHVzZSBvZiBhbiBpbnQgd291bGQgZmFpbAoJICovCgl0bXBfaXQgPSAqaXQ7CiAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3RzLT5yZXF1ZXN0dmIsIEFTTl9VTlNJR05FRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSAmdG1wX2l0LCBzaXplb2YodW5zaWduZWQgbG9uZykpOwogICAgICAgIGJyZWFrOwoKICAgICAgICAvKgogICAgICAgICAqIFNFVCByZXF1ZXN0cy4gIFNob3VsZCBvbmx5IGdldCBoZXJlIGlmIHJlZ2lzdGVyZWQgUldSSVRFIAogICAgICAgICAqLwogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgICAgICBpZiAocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dHlwZSAhPSBBU05fVU5TSUdORUQpCiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfV1JPTkdUWVBFKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgICAgIC8qCiAgICAgICAgICogc3RvcmUgb2xkIGluZm8gZm9yIHVuZG8gbGF0ZXIgCiAgICAgICAgICovCiAgICAgICAgaXRfc2F2ZSA9IG5ldHNubXBfbWVtZHVwKGl0LCBzaXplb2YodV9pbnQpKTsKICAgICAgICBpZiAoaXRfc2F2ZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRSk7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSU5TVEFOQ0VfSEFORExFUl9OQU1FLCBpdF9zYXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVlKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICAgICAgLyoKICAgICAgICAgKiB1cGRhdGUgY3VycmVudCAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgidGVzdGhhbmRsZXIiLCAidXBkYXRlZCB1aW50ICVkIC0+ICVsZFxuIiwgKml0LAogICAgICAgICAgICAgICAgICAgICoocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsLmludGVnZXIpKSk7CiAgICAgICAgKml0ID0gKHVuc2lnbmVkIGludCkgKihyZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWwuaW50ZWdlcik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgICppdCA9CiAgICAgICAgICAgICooKHVfaW50ICopIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlNUQU5DRV9IQU5ETEVSX05BTUUpKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICAvKgogICAgICAgICAqIG5vdGhpbmcgdG8gZG8gCiAgICAgICAgICovCiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoaGFuZGxlci0+bmV4dCAmJiBoYW5kbGVyLT5uZXh0LT5hY2Nlc3NfbWV0aG9kKQogICAgICAgIHJldHVybiBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMpOwogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCiNlbmRpZiAvKiBORVRTTk1QX05PX0RFUFJFQ0FURURfRlVOQ1RJT05TICovCgppbnQKbmV0c25tcF9pbnN0YW5jZV9oZWxwZXJfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXIgPSByZXF1ZXN0cy0+cmVxdWVzdHZiOwoKICAgIGludCAgICAgICAgICAgICByZXQsIGNtcDsKCiAgICBERUJVR01TR1RMKCgiaGVscGVyOmluc3RhbmNlIiwgIkdvdCByZXF1ZXN0OlxuIikpOwogICAgY21wID0gc25tcF9vaWRfY29tcGFyZShyZXF1ZXN0cy0+cmVxdWVzdHZiLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0cy0+cmVxdWVzdHZiLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4pOwoKICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6aW5zdGFuY2UiLCAiICBvaWQ6IikpOwogICAgREVCVUdNU0dPSUQoKCJoZWxwZXI6aW5zdGFuY2UiLCB2YXItPm5hbWUsIHZhci0+bmFtZV9sZW5ndGgpKTsKICAgIERFQlVHTVNHKCgiaGVscGVyOmluc3RhbmNlIiwgIlxuIikpOwoKICAgIHN3aXRjaCAocmVxaW5mby0+bW9kZSkgewogICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICBpZiAoY21wICE9IDApIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX05PU1VDSElOU1RBTkNFKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMjoKICAgIGNhc2UgTU9ERV9TRVRfQUNUSU9OOgogICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgICAgaWYgKGNtcCAhPSAwKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfTk9DUkVBVElPTik7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX0dFVE5FWFQ6CiAgICAgICAgaWYgKGNtcCA8IDAgfHwgKGNtcCA9PSAwICYmIHJlcXVlc3RzLT5pbmNsdXNpdmUpKSB7CiAgICAgICAgICAgIHJlcWluZm8tPm1vZGUgPSBNT0RFX0dFVDsKICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3RzLT5yZXF1ZXN0dmIsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5yb290b2lkX2xlbik7CiAgICAgICAgICAgIHJldCA9CiAgICAgICAgICAgICAgICBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgICAgICAgICAgcmVxaW5mby0+bW9kZSA9IE1PREVfR0VUTkVYVDsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaWYgdGhlIGluc3RhbmNlIGRvZXNuJ3QgaGF2ZSBkYXRhLCBzZXQgdHlwZSB0byBBU05fTlVMTAogICAgICAgICAgICAgKiB0byBtb3ZlIHRvIHRoZSBuZXh0IHN1Yi10cmVlLiBJZ25vcmUgZGVsZWdhdGVkIHJlcXVlc3RzOyB0aGV5CiAgICAgICAgICAgICAqIG1pZ2h0IGhhdmUgZGF0YSBsYXRlciBvbi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICghcmVxdWVzdHMtPmRlbGVnYXRlZCAmJgogICAgICAgICAgICAgICAgKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hJTlNUQU5DRSB8fAogICAgICAgICAgICAgICAgIHJlcXVlc3RzLT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hPQkpFQ1QpKSB7CiAgICAgICAgICAgICAgICByZXF1ZXN0cy0+cmVxdWVzdHZiLT50eXBlID0gQVNOX05VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICAvKgogICAgICogZ290IGhlcmUgb25seSBpZiBpbGxlZ2FsIG1vZGUgZm91bmQgCiAgICAgKi8KICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7Cn0KCi8qKiBAfSAKICovCg==