LyoKICogQ29weXJpZ2h0IDE5OTUgTWFydGluIHZvbiBMb2V3aXMKICogQ29weXJpZ2h0IDE5OTggSnVzdGluIEJyYWRmb3JkCiAqIENvcHlyaWdodCAxOTk5IEZyYW5jaXMgQmVhdWRldAogKiBDb3B5cmlnaHQgMTk5OSBTeWx2YWluIFN0LUdlcm1haW4KICogQ29weXJpZ2h0IDIwMDIgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAzIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDA0IE1pa2UgSGVhcm4sIENvZGVXZWF2ZXJzIEluYwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaWZuZGVmIF9fV0lORV9PTEVfQ09NUE9CSl9ICiNkZWZpbmUgX19XSU5FX09MRV9DT01QT0JKX0gKCi8qIEFsbCBwcml2YXRlIHByb3RvdHlwZSBmdW5jdGlvbnMgdXNlZCBieSBPTEUgd2lsbCBiZSBhZGRlZCB0byB0aGlzIGhlYWRlciBmaWxlICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZS9saXN0LmgiCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3dHlwZXMuaCIKI2luY2x1ZGUgImRjb20uaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2ludGVybmwuaCIKCi8qIFdpbmRvd3MgbWFwcyBDT0lOSVQgdmFsdWVzIHRvIDB4ODAgZm9yIGFwYXJ0bWVudCB0aHJlYWRlZCwgMHgxNDAKICogZm9yIGZyZWUgdGhyZWFkZWQsIGFuZCAwIGZvciB1bmluaXRpYWxpemVkIGFwYXJ0bWVudHMuIFRoZXJlIGlzCiAqIG5vIHJlYWwgYWR2YW50YWdlIGluIHVzIGRvaW5nIHRoaXMgYW5kIGNlcnRhaW5seSBubyByZWxlYXNlIHZlcnNpb24KICogb2YgYW4gYXBwIHNob3VsZCBiZSBwb2tpbmcgYXJvdW5kIHdpdGggdGhlc2UgZmxhZ3MuIFNvIHdlIG5lZWQgYQogKiBzcGVjaWFsIHZhbHVlIGZvciB1bmluaXRpYWxpemVkICovCiNkZWZpbmUgQ09JTklUX1VOSU5JVElBTElaRUQgMHgxMDAKCi8qIGV4cG9ydGVkIGludGVyZmFjZSAqLwp0eXBlZGVmIHN0cnVjdCB0YWdYSUYgewogIHN0cnVjdCB0YWdYSUYgKm5leHQ7CiAgTFBWT0lEIGlmYWNlOyAgICAgICAgICAgIC8qIGludGVyZmFjZSBwb2ludGVyICovCiAgSUlEIGlpZDsgICAgICAgICAgICAgICAgIC8qIGludGVyZmFjZSBJRCAqLwogIElQSUQgaXBpZDsgICAgICAgICAgICAgICAvKiBleHBvcnRlZCBpbnRlcmZhY2UgSUQgKi8KICBMUFJQQ1NUVUJCVUZGRVIgc3R1YjsgICAgLyogaW50ZXJmYWNlIHN0dWIgKi8KICBEV09SRCByZWZzOyAgICAgICAgICAgICAgLyogZXh0ZXJuYWwgcmVmZXJlbmNlIGNvdW50ICovCiAgSFJFU1VMVCBocmVzOyAgICAgICAgICAgIC8qIHJlc3VsdCBvZiBzdHViIGNyZWF0aW9uIGF0dGVtcHQgKi8KfSBYSUY7CgovKiBleHBvcnRlZCBvYmplY3QgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnWE9CSkVDVCB7CiAgSVJwY1N0dWJCdWZmZXJWdGJsICpscFZ0Ymw7CiAgc3RydWN0IHRhZ0FQQVJUTUVOVCAqcGFyZW50OwogIHN0cnVjdCB0YWdYT0JKRUNUICpuZXh0OwogIExQVU5LTk9XTiBvYmo7ICAgICAgICAgICAvKiBvYmplY3QgaWRlbnRpdHkgKElVbmtub3duKSAqLwogIE9JRCBvaWQ7ICAgICAgICAgICAgICAgICAvKiBvYmplY3QgSUQgKi8KICBEV09SRCBpZmM7ICAgICAgICAgICAgICAgLyogaW50ZXJmYWNlIElEIGNvdW50ZXIgKi8KICBYSUYgKmlmYWNlczsgICAgICAgICAgICAgLyogZXhwb3J0ZWQgaW50ZXJmYWNlcyAqLwogIERXT1JEIHJlZnM7ICAgICAgICAgICAgICAvKiBleHRlcm5hbCByZWZlcmVuY2UgY291bnQgKi8KfSBYT0JKRUNUOwoKLyogaW1wb3J0ZWQgaW50ZXJmYWNlICovCnR5cGVkZWYgc3RydWN0IHRhZ0lJRiB7CiAgc3RydWN0IHRhZ0lJRiAqbmV4dDsKICBMUFZPSUQgaWZhY2U7ICAgICAgICAgICAgLyogaW50ZXJmYWNlIHBvaW50ZXIgKi8KICBJSUQgaWlkOyAgICAgICAgICAgICAgICAgLyogaW50ZXJmYWNlIElEICovCiAgSVBJRCBpcGlkOyAgICAgICAgICAgICAgIC8qIGltcG9ydGVkIGludGVyZmFjZSBJRCAqLwogIExQUlBDUFJPWFlCVUZGRVIgcHJveHk7ICAvKiBpbnRlcmZhY2UgcHJveHkgKi8KICBEV09SRCByZWZzOyAgICAgICAgICAgICAgLyogaW1wb3J0ZWQgKHB1YmxpYykgcmVmZXJlbmNlcyAqLwogIEhSRVNVTFQgaHJlczsgICAgICAgICAgICAvKiByZXN1bHQgb2YgcHJveHkgY3JlYXRpb24gYXR0ZW1wdCAqLwp9IElJRjsKCi8qIGltcG9ydGVkIG9iamVjdCAqLwp0eXBlZGVmIHN0cnVjdCB0YWdJT0JKRUNUIHsKICBJUmVtVW5rbm93blZ0YmwgKmxwVnRibDsKICBzdHJ1Y3QgdGFnQVBBUlRNRU5UICpwYXJlbnQ7CiAgc3RydWN0IHRhZ0lPQkpFQ1QgKm5leHQ7CiAgTFBSUENDSEFOTkVMQlVGRkVSIGNoYW47IC8qIGNoYW5uZWwgdG8gb2JqZWN0ICovCiAgT1hJRCBveGlkOyAgICAgICAgICAgICAgIC8qIG9iamVjdCBleHBvcnRlZCBJRCAqLwogIE9JRCBvaWQ7ICAgICAgICAgICAgICAgICAvKiBvYmplY3QgSUQgKi8KICBJUElEIGlwaWQ7ICAgICAgICAgICAgICAgLyogZmlyc3QgaW1wb3J0ZWQgaW50ZXJmYWNlIElEICovCiAgSUlGICppZmFjZXM7ICAgICAgICAgICAgIC8qIGltcG9ydGVkIGludGVyZmFjZXMgKi8KICBEV09SRCByZWZzOyAgICAgICAgICAgICAgLyogcHJveHkgcmVmZXJlbmNlIGNvdW50ICovCn0gSU9CSkVDVDsKCi8qIGFwYXJ0bWVudCAqLwp0eXBlZGVmIHN0cnVjdCB0YWdBUEFSVE1FTlQgewogIHN0cnVjdCB0YWdBUEFSVE1FTlQgKm5leHQsICpwcmV2LCAqcGFyZW50OwogIERXT1JEIG1vZGVsOyAgICAgICAgICAgICAvKiB0aHJlYWRpbmcgbW9kZWwgKi8KICBEV09SRCBpbml0czsgICAgICAgICAgICAgLyogQ29Jbml0aWFsaXplIGNvdW50ICovCiAgRFdPUkQgdGlkOyAgICAgICAgICAgICAgIC8qIHRocmVhZCBpZCAqLwogIEhBTkRMRSB0aHJlYWQ7ICAgICAgICAgICAvKiB0aHJlYWQgaGFuZGxlICovCiAgT1hJRCBveGlkOyAgICAgICAgICAgICAgIC8qIG9iamVjdCBleHBvcnRlciBJRCAqLwogIE9JRCBvaWRjOyAgICAgICAgICAgICAgICAvKiBvYmplY3QgSUQgY291bnRlciwgc3RhcnRzIGF0IDEsIHplcm8gaXMgaW52YWxpZCBPSUQgKi8KICBIV05EIHdpbjsgICAgICAgICAgICAgICAgLyogbWVzc2FnZSB3aW5kb3cgKi8KICBDUklUSUNBTF9TRUNUSU9OIGNzOyAgICAgLyogdGhyZWFkIHNhZmV0eSAqLwogIExQTUVTU0FHRUZJTFRFUiBmaWx0ZXI7ICAvKiBtZXNzYWdlIGZpbHRlciAqLwogIFhPQkpFQ1QgKm9ianM7ICAgICAgICAgICAvKiBleHBvcnRlZCBvYmplY3RzICovCiAgSU9CSkVDVCAqcHJveGllczsgICAgICAgIC8qIGltcG9ydGVkIG9iamVjdHMgKi8gIAogIExQVU5LTk9XTiBzdGF0ZTsgICAgICAgICAvKiBzdGF0ZSBvYmplY3QgKHNlZSBDb1tHZXQsU2V0XVN0YXRlKSAqLwogIExQVk9JRCBFcnJvckluZm87ICAgICAgICAvKiB0aHJlYWQgZXJyb3IgaW5mbyAqLwogIERXT1JEIGxpc3RlbmVydGlkOyAgICAgICAvKiBpZCBvZiBhcGFydG1lbnRfbGlzdGVuZXJfdGhyZWFkICovCiAgc3RydWN0IGxpc3Qgc3R1Ym1ncnM7ICAgIC8qIHN0dWIgbWFuYWdlcnMgZm9yIGV4cG9ydGVkIG9iamVjdHMgKi8KfSBBUEFSVE1FTlQ7CgpleHRlcm4gQVBBUlRNRU5UIE1UQSwgKmFwdHM7CgpleHRlcm4gdm9pZCogU3RkR2xvYmFsSW50ZXJmYWNlVGFibGVfQ29uc3RydWN0KHZvaWQpOwpleHRlcm4gdm9pZCAgU3RkR2xvYmFsSW50ZXJmYWNlVGFibGVfRGVzdHJveSh2b2lkKiBzZWxmKTsKZXh0ZXJuIEhSRVNVTFQgU3RkR2xvYmFsSW50ZXJmYWNlVGFibGVfR2V0RmFjdG9yeShMUFZPSUQgKnBwdik7CgpleHRlcm4gSFJFU1VMVCBXSU5FX1N0cmluZ0Zyb21DTFNJRChjb25zdCBDTFNJRCAqaWQsTFBTVFIgaWRzdHIpOwpleHRlcm4gSFJFU1VMVCBjcmVhdGVfbWFyc2hhbGxlZF9wcm94eShSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KTsKCmV4dGVybiB2b2lkKiBTdGRHbG9iYWxJbnRlcmZhY2VUYWJsZUluc3RhbmNlOwoKLyogU3RhbmRhcmQgTWFyc2hhbGxpbmcgZGVmaW5pdGlvbnMgKi8KdHlwZWRlZiBzdHJ1Y3QgX3dpbmVfbWFyc2hhbF9pZCB7CiAgICBPWElEICAgIG94aWQ7ICAgICAgIC8qIGlkIG9mIGFwYXJ0bWVudCAqLwogICAgT0lEICAgICBvaWQ7ICAgICAgICAvKiBpZCBvZiBzdHViIG1hbmFnZXIgKi8KICAgIElJRCAgICAgaWlkOyAgICAgICAgLyogaWQgb2YgaW50ZXJmYWNlIChOT1QgaWZwdHIpICovCn0gd2luZV9tYXJzaGFsX2lkOwoKaW5saW5lIHN0YXRpYyBCT09MCk1BUlNIQUxfQ29tcGFyZV9NaWRzKHdpbmVfbWFyc2hhbF9pZCAqbWlkMSx3aW5lX21hcnNoYWxfaWQgKm1pZDIpIHsKICAgIHJldHVybgoJKG1pZDEtPm94aWQgPT0gbWlkMi0+b3hpZCkJJiYKCShtaWQxLT5vaWQgPT0gbWlkMi0+b2lkKQkmJgoJSXNFcXVhbElJRCgmKG1pZDEtPmlpZCksJihtaWQyLT5paWQpKQogICAgOwp9CgpIUkVTVUxUIE1BUlNIQUxfRGlzY29ubmVjdF9Qcm94aWVzKHZvaWQpOwpIUkVTVUxUIE1BUlNIQUxfR2V0U3RhbmRhcmRNYXJzaGFsQ0YoTFBWT0lEICpwcHYpOwoKLyogYW4gaW50ZXJmYWNlIHN0dWIgKi8Kc3RydWN0IGlmc3R1YiAgIAp7CiAgICBzdHJ1Y3QgbGlzdCAgICAgICBlbnRyeTsKICAgIElScGNTdHViQnVmZmVyICAgKnN0dWJidWZmZXI7CiAgICBJSUQgICAgICAgICAgICAgICBpaWQ7ICAgICAgICAgLyogZml4bWU6IHRoaXMgc2hvdWxkIGJlIGFuIElQSUQgbm90IGFuIElJRCAqLwogICAgSVVua25vd24gICAgICAgICAqaWZhY2U7CgogICAgQk9PTCAgICAgICAgICAgICAgdGFibGU7Cn07CgoKLyogc3R1YiBtYW5hZ2VycyBob2xkIHJlZnMgb24gdGhlIG9iamVjdCBhbmQgZWFjaCBpbnRlcmZhY2Ugc3R1YiAqLwpzdHJ1Y3Qgc3R1Yl9tYW5hZ2VyCnsKICAgIHN0cnVjdCBsaXN0ICAgICAgIGVudHJ5OwogICAgc3RydWN0IGxpc3QgICAgICAgaWZzdHViczsKICAgIENSSVRJQ0FMX1NFQ1RJT04gIGxvY2s7CiAgICBBUEFSVE1FTlQgICAgICAgICphcHQ7ICAgICAgICAvKiBvd25pbmcgYXB0ICovCgogICAgRFdPUkQgICAgICAgICAgICAgcmVmY291bnQ7ICAgLyogY291bnQgb2YgJ2V4dGVybmFsJyByZWZlcmVuY2VzICovCiAgICBPSUQgICAgICAgICAgICAgICBvaWQ7ICAgICAgICAvKiBhcGFydG1lbnQtc2NvcGVkIHVuaXF1ZSBpZGVudGlmaWVyICovCiAgICBJVW5rbm93biAgICAgICAgICpvYmplY3Q7ICAgICAvKiB0aGUgb2JqZWN0IHdlIGFyZSBtYW5hZ2luZyB0aGUgc3R1YiBmb3IgKi8KICAgIERXT1JEICAgICAgICAgICAgIG5leHRfaXBpZDsgIC8qIGN1cnJlbnRseSB1bnVzZWQgKi8KfTsKCnN0cnVjdCBzdHViX21hbmFnZXIgKm5ld19zdHViX21hbmFnZXIoQVBBUlRNRU5UICphcHQsIElVbmtub3duICpvYmplY3QpOwppbnQgc3R1Yl9tYW5hZ2VyX3JlZihzdHJ1Y3Qgc3R1Yl9tYW5hZ2VyICptLCBpbnQgcmVmcyk7CmludCBzdHViX21hbmFnZXJfdW5yZWYoc3RydWN0IHN0dWJfbWFuYWdlciAqbSwgaW50IHJlZnMpOwpJUnBjU3R1YkJ1ZmZlciAqc3R1Yl9tYW5hZ2VyX2lpZF90b19zdHViYnVmZmVyKHN0cnVjdCBzdHViX21hbmFnZXIgKm0sIElJRCAqaWlkKTsKc3RydWN0IGlmc3R1YiAqc3R1Yl9tYW5hZ2VyX25ld19pZnN0dWIoc3RydWN0IHN0dWJfbWFuYWdlciAqbSwgSVJwY1N0dWJCdWZmZXIgKnNiLCBJVW5rbm93biAqaXB0ciwgSUlEICppaWQsIEJPT0wgdGFibGVtYXJzaGFsKTsKc3RydWN0IHN0dWJfbWFuYWdlciAqZ2V0X3N0dWJfbWFuYWdlcihPWElEIG94aWQsIE9JRCBvaWQpOwpzdHJ1Y3Qgc3R1Yl9tYW5hZ2VyICpnZXRfc3R1Yl9tYW5hZ2VyX2Zyb21fb2JqZWN0KE9YSUQgb3hpZCwgdm9pZCAqb2JqZWN0KTsKdm9pZCBzdHViX21hbmFnZXJfZGVsZXRlX2lmc3R1YihzdHJ1Y3Qgc3R1Yl9tYW5hZ2VyICptLCBJSUQgKmlpZCk7ICAgLyogZml4bWU6IHNob3VsZCBiZSBpcGlkICovCgpJUnBjU3R1YkJ1ZmZlciAqbWlkX3RvX3N0dWJidWZmZXIod2luZV9tYXJzaGFsX2lkICptaWQpOwoKdm9pZCBzdGFydF9hcGFydG1lbnRfbGlzdGVuZXJfdGhyZWFkKHZvaWQpOwoKZXh0ZXJuIEhSRVNVTFQgUElQRV9HZXROZXdQaXBlQnVmKHdpbmVfbWFyc2hhbF9pZCAqbWlkLCBJUnBjQ2hhbm5lbEJ1ZmZlciAqKnBpcGVidWYpOwp2b2lkIFJQQ19TdGFydExvY2FsU2VydmVyKFJFRkNMU0lEIGNsc2lkLCBJU3RyZWFtICpzdHJlYW0pOwoKLyogVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplIHRoZSBSdW5uaW5nIE9iamVjdCBUYWJsZSAqLwpIUkVTVUxUIFdJTkFQSSBSdW5uaW5nT2JqZWN0VGFibGVJbXBsX0luaXRpYWxpemUodm9pZCk7CgovKiBUaGlzIGZ1bmN0aW9uIHVuaW5pdGlhbGl6ZSB0aGUgUnVubmluZyBPYmplY3QgVGFibGUgKi8KSFJFU1VMVCBXSU5BUEkgUnVubmluZ09iamVjdFRhYmxlSW1wbF9VbkluaXRpYWxpemUodm9pZCk7CgovKiBUaGlzIGZ1bmN0aW9uIGRlY29tcG9zZXMgYSBTdHJpbmcgcGF0aCB0byBhIFN0cmluZyBUYWJsZSBjb250YWluaW5nIGFsbCB0aGUgZWxlbWVudHMgKCJcIiBvciAic3ViRGlyZWN0b3J5IiBvciAiRGlyZWN0b3J5IiBvciAiRmlsZU5hbWUiKSBvZiB0aGUgcGF0aCAqLwppbnQgV0lOQVBJIEZpbGVNb25pa2VySW1wbF9EZWNvbXBvc2VQYXRoKExQQ09MRVNUUiBzdHIsIExQT0xFU1RSKiogc3RyaW5nVGFibGUpOwoKSFJFU1VMVCBXSU5BUEkgX19DTFNJREZyb21TdHJpbmdBKExQQ1NUUiBpZHN0ciwgQ0xTSUQgKmlkKTsKCi8qCiAqIFBlci10aHJlYWQgdmFsdWVzIGFyZSBzdG9yZWQgaW4gdGhlIFRFQiBvbiBvZmZzZXQgMHhGODAsCiAqIHNlZSBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vbXNqLzEwOTkvYnVnc2xheWVyL2J1Z3NsYXllcjEwOTkuaHRtCiAqLwpzdGF0aWMgaW5saW5lIEFQQVJUTUVOVCogQ09NX0N1cnJlbnRJbmZvKHZvaWQpCnsKICBBUEFSVE1FTlQqIGFwdCA9IE50Q3VycmVudFRlYigpLT5SZXNlcnZlZEZvck9sZTsKICByZXR1cm4gYXB0Owp9CnN0YXRpYyBpbmxpbmUgQVBBUlRNRU5UKiBDT01fQ3VycmVudEFwdCh2b2lkKQp7CiAgQVBBUlRNRU5UKiBhcHQgPSBDT01fQ3VycmVudEluZm8oKTsKICBpZiAoYXB0ICYmIGFwdC0+cGFyZW50KSBhcHQgPSBhcHQtPnBhcmVudDsKICByZXR1cm4gYXB0Owp9CgovKiBjb21wb2JqLmMgKi8KQVBBUlRNRU5UICpDT01fQ3JlYXRlQXBhcnRtZW50KERXT1JEIG1vZGVsKTsKSFdORCBDT01fR2V0QXBhcnRtZW50V2luKE9YSUQgb3hpZCk7CkFQQVJUTUVOVCAqQ09NX0FwYXJ0bWVudEZyb21PWElEKE9YSUQgb3hpZCk7CgojZGVmaW5lIElDT01fVEhJU19NVUxUSShpbXBsLGZpZWxkLGlmYWNlKSBpbXBsKiBjb25zdCBUaGlzPShpbXBsKikoKGNoYXIqKShpZmFjZSkgLSBvZmZzZXRvZihpbXBsLGZpZWxkKSkKCiNlbmRpZiAvKiBfX1dJTkVfT0xFX0NPTVBPQkpfSCAqLwo=