Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBGcmVlSW1hZ2UgaW1wbGVtZW50YXRpb24KLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEZsb3JpcyB2YW4gZGVuIEJlcmcgKGZsdmRiZXJnQHd4cy5ubCkKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLyAtIERldGxldiBWZW5kdCAoZGV0bGV2LnZlbmR0QGJyaWxsaXQuZGUpCi8vIC0gUGV0ciBTdXBpbmEgKHBzdXBAY2VudHJ1bS5jeikKLy8gLSBDYXJzdGVuIEtsZWluIChjLmtsZWluQGRhdGFnaXMuY29tKQovLyAtIE1paGFpbCBOYXlkZW5vdiAobW5heWRlbm92QHVzZXJzLnNvdXJjZWZvcmdlLm5ldCkKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaWZkZWYgX01TQ19WRVIgCiNwcmFnbWEgd2FybmluZyAoZGlzYWJsZSA6IDQ3ODYpIC8vIGlkZW50aWZpZXIgd2FzIHRydW5jYXRlZCB0byAnbnVtYmVyJyBjaGFyYWN0ZXJzCiNlbmRpZiAKCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2lmIGRlZmluZWQoX1dJTjMyKSB8fCBkZWZpbmVkKF9XSU42NCkgfHwgZGVmaW5lZChfX01JTkdXMzJfXykKI2luY2x1ZGUgPG1hbGxvYy5oPgojZW5kaWYgLy8gX1dJTjMyIHx8IF9XSU42NCB8fCBfX01JTkdXMzJfXwoKI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiRnJlZUltYWdlSU8uaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgojaW5jbHVkZSAiTWFwSW50cm9zcGVjdG9yLmgiCgojaW5jbHVkZSAiLi4vTWV0YWRhdGEvRnJlZUltYWdlVGFnLmgiCgovKioKQ29uc3RhbnRzIGZvciB0aGUgQklUTUFQSU5GT0hFQURFUjo6YmlDb21wcmVzc2lvbiBmaWVsZApCSV9SR0I6ClRoZSBiaXRtYXAgaXMgaW4gdW5jb21wcmVzc2VkIHJlZCBncmVlbiBibHVlIChSR0IpIGZvcm1hdCB0aGF0IGlzIG5vdCBjb21wcmVzc2VkIGFuZCBkb2VzIG5vdCB1c2UgY29sb3IgbWFza3MuCkJJX0JJVEZJRUxEUzoKVGhlIGJpdG1hcCBpcyBub3QgY29tcHJlc3NlZCBhbmQgdGhlIGNvbG9yIHRhYmxlIGNvbnNpc3RzIG9mIHRocmVlIERXT1JEIGNvbG9yIG1hc2tzIHRoYXQgc3BlY2lmeSB0aGUgcmVkLCBncmVlbiwgYW5kIGJsdWUgY29tcG9uZW50cywgCnJlc3BlY3RpdmVseSwgb2YgZWFjaCBwaXhlbC4gVGhpcyBpcyB2YWxpZCB3aGVuIHVzZWQgd2l0aCAxNiBhbmQgMzItYml0cyBwZXIgcGl4ZWwgYml0bWFwcy4KKi8KI2lmbmRlZiBfV0lOR0RJXwojZGVmaW5lIEJJX1JHQiAgICAgICAwTAojZGVmaW5lIEJJX0JJVEZJRUxEUyAzTAojZW5kaWYgLy8gX1dJTkdESV8KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gIE1ldGFkYXRhIGRlZmluaXRpb25zCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKiBoZWxwZXIgZm9yIG1hcDxrZXksIHZhbHVlPiB3aGVyZSB2YWx1ZSBpcyBhIHBvaW50ZXIgdG8gYSBGcmVlSW1hZ2UgdGFnICovCnR5cGVkZWYgc3RkOjptYXA8c3RkOjpzdHJpbmcsIEZJVEFHKj4gVEFHTUFQOwoKLyoqIGhlbHBlciBmb3IgbWFwPEZSRUVfSU1BR0VfTURNT0RFTCwgVEFHTUFQKj4gKi8KdHlwZWRlZiBzdGQ6Om1hcDxpbnQsIFRBR01BUCo+IE1FVEFEQVRBTUFQOwoKLyoqIGhlbHBlciBmb3IgbWV0YWRhdGEgaXRlcmF0b3IgKi8KRklfU1RSVUNUIChNRVRBREFUQUhFQURFUikgeyAKCWxvbmcgcG9zOwkJLy8hIGN1cnJlbnQgcG9zaXRpb24gd2hlbiBpdGVyYXRpbmcgdGhlIG1hcAoJVEFHTUFQICp0YWdtYXA7CS8vISBwb2ludGVyIHRvIHRoZSB0YWcgbWFwCn07CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBGSUJJVE1BUCBkZWZpbml0aW9uCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgpGcmVlSW1hZ2UgaGVhZGVyIHN0cnVjdHVyZQoqLwpGSV9TVFJVQ1QgKEZSRUVJTUFHRUhFQURFUikgewoJLyoqIGRhdGEgdHlwZSAtIGJpdG1hcCwgYXJyYXkgb2YgbG9uZywgZG91YmxlLCBjb21wbGV4LCBldGMgKi8KCUZSRUVfSU1BR0VfVFlQRSB0eXBlOwoKCS8qKiBiYWNrZ3JvdW5kIGNvbG9yIHVzZWQgZm9yIFJHQiB0cmFuc3BhcmVuY3kgKi8KCVJHQlFVQUQgYmtnbmRfY29sb3I7CgoJLyoqQG5hbWUgdHJhbnNwYXJlbmN5IG1hbmFnZW1lbnQgKi8KCS8vQHsKCS8qKgoJd2h5IGFub3RoZXIgdGFibGUgPyBmb3IgZWFzeSB0cmFuc3BhcmVuY3kgdGFibGUgcmV0cmlldmFsICEKCXRyYW5zcGFyZW5jeSBjb3VsZCBiZSBzdG9yZWQgaW4gdGhlIHBhbGV0dGUsIHdoaWNoIGlzIGJldHRlcgoJb3ZlcmFsbCwgYnV0IGl0IHJlcXVpcmVzIHF1aXRlIHNvbWUgY2hhbmdlcyBhbmQgaXQgd2lsbCByZW5kZXIKCUZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lUYWJsZSBvYnNvbGV0ZSBpbiBpdHMgY3VycmVudCBmb3JtOwoJKi8KCUJZVEUgdHJhbnNwYXJlbnRfdGFibGVbMjU2XTsKCS8qKiBudW1iZXIgb2YgdHJhbnNwYXJlbnQgY29sb3JzICovCglpbnQgIHRyYW5zcGFyZW5jeV9jb3VudDsKCS8qKiBUUlVFIGlmIHRoZSBpbWFnZSBpcyB0cmFuc3BhcmVudCAqLwoJQk9PTCB0cmFuc3BhcmVudDsKCS8vQH0KCgkvKiogc3BhY2UgdG8gaG9sZCBJQ0MgcHJvZmlsZSAqLwoJRklJQ0NQUk9GSUxFIGljY1Byb2ZpbGU7CgoJLyoqIGNvbnRhaW5zIGEgbGlzdCBvZiBtZXRhZGF0YSBtb2RlbHMgYXR0YWNoZWQgdG8gdGhlIGJpdG1hcCAqLwoJTUVUQURBVEFNQVAgKm1ldGFkYXRhOwoKCS8qKiBGQUxTRSBpZiB0aGUgRklCSVRNQVAgb25seSBjb250YWlucyB0aGUgaGVhZGVyIGFuZCBubyBwaXhlbCBkYXRhICovCglCT09MIGhhc19waXhlbHM7CgoJLyoqIG9wdGlvbmFsbHkgY29udGFpbnMgYSB0aHVtYm5haWwgYXR0YWNoZWQgdG8gdGhlIGJpdG1hcCAqLwoJRklCSVRNQVAgKnRodW1ibmFpbDsKCgkvKipAbmFtZSBleHRlcm5hbCBwaXhlbCBidWZmZXIgbWFuYWdlbWVudCAqLwoJLy9AewoJLyoqIHBvaW50ZXIgdG8gdXNlciBwcm92aWRlZCBwaXhlbHMsIE5VTEwgb3RoZXJ3aXNlICovCglCWVRFICpleHRlcm5hbF9iaXRzOwoJLyoqIHVzZXIgcHJvdmlkZWQgcGl0Y2gsIDAgb3RoZXJ3aXNlICovCgl1bnNpZ25lZCBleHRlcm5hbF9waXRjaDsKCS8vQH0KCgkvL0JZVEUgZmlsbGVyWzFdOwkJCSAvLyBmaWxsIHRvIDMyLWJpdCBhbGlnbm1lbnQKfTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gIEZSRUVJTUFHRVJHQk1BU0tTIGRlZmluaXRpb24KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqClJHQiBtYXNrIHN0cnVjdHVyZSAtIG1haW5seSB1c2VkIGZvciAxNi1iaXQgUkdCNTU1IC8gUkdCIDU2NSBGSUJJVE1BUAoqLwpGSV9TVFJVQ1QgKEZSRUVJTUFHRVJHQk1BU0tTKSB7Cgl1bnNpZ25lZCByZWRfbWFzazsJCS8vISBiaXQgbGF5b3V0IG9mIHRoZSByZWQgY29tcG9uZW50cwoJdW5zaWduZWQgZ3JlZW5fbWFzazsJLy8hIGJpdCBsYXlvdXQgb2YgdGhlIGdyZWVuIGNvbXBvbmVudHMKCXVuc2lnbmVkIGJsdWVfbWFzazsJCS8vISBiaXQgbGF5b3V0IG9mIHRoZSBibHVlIGNvbXBvbmVudHMKfTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gIE1lbW9yeSBhbGxvY2F0aW9uIG9uIGEgc3BlY2lmaWVkIGFsaWdubWVudCBib3VuZGFyeQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojaWYgKGRlZmluZWQoX1dJTjMyKSB8fCBkZWZpbmVkKF9XSU42NCkpICYmICFkZWZpbmVkKF9fTUlOR1czMl9fKQoKdm9pZCogRnJlZUltYWdlX0FsaWduZWRfTWFsbG9jKHNpemVfdCBhbW91bnQsIHNpemVfdCBhbGlnbm1lbnQpIHsKCWFzc2VydChhbGlnbm1lbnQgPT0gRklCSVRNQVBfQUxJR05NRU5UKTsKCXJldHVybiBfYWxpZ25lZF9tYWxsb2MoYW1vdW50LCBhbGlnbm1lbnQpOwp9Cgp2b2lkIEZyZWVJbWFnZV9BbGlnbmVkX0ZyZWUodm9pZCogbWVtKSB7CglfYWxpZ25lZF9mcmVlKG1lbSk7Cn0KCiNlbGlmIGRlZmluZWQgKF9fTUlOR1czMl9fKQoKdm9pZCogRnJlZUltYWdlX0FsaWduZWRfTWFsbG9jKHNpemVfdCBhbW91bnQsIHNpemVfdCBhbGlnbm1lbnQpIHsKCWFzc2VydChhbGlnbm1lbnQgPT0gRklCSVRNQVBfQUxJR05NRU5UKTsKCXJldHVybiBfX21pbmd3X2FsaWduZWRfbWFsbG9jIChhbW91bnQsIGFsaWdubWVudCk7Cn0KCnZvaWQgRnJlZUltYWdlX0FsaWduZWRfRnJlZSh2b2lkKiBtZW0pIHsKCV9fbWluZ3dfYWxpZ25lZF9mcmVlIChtZW0pOwp9CgojZWxzZQoKdm9pZCogRnJlZUltYWdlX0FsaWduZWRfTWFsbG9jKHNpemVfdCBhbW91bnQsIHNpemVfdCBhbGlnbm1lbnQpIHsKCWFzc2VydChhbGlnbm1lbnQgPT0gRklCSVRNQVBfQUxJR05NRU5UKTsKCS8qCglJbiBzb21lIHJhcmUgc2l0dWF0aW9ucywgdGhlIG1hbGxvYyByb3V0aW5lcyBjYW4gcmV0dXJuIG1pc2FsaWduZWQgbWVtb3J5LiAKCVRoZSByb3V0aW5lIEZyZWVJbWFnZV9BbGlnbmVkX01hbGxvYyBhbGxvY2F0ZXMgYSBiaXQgbW9yZSBtZW1vcnkgdG8gZG8KCWFsaWduZWQgd3JpdGVzLiAgTm9ybWFsbHksIGl0ICpzaG91bGQqIGFsbG9jYXRlICJhbGlnbm1lbnQiIGV4dHJhIG1lbW9yeSBhbmQgdGhlbiB3cml0ZXMKCW9uZSBkd29yZCBiYWNrIHRoZSB0cnVlIHBvaW50ZXIuICBCdXQgaWYgdGhlIG1lbW9yeSBtYW5hZ2VyIHJldHVybnMgYQoJbWlzYWxpZ25lZCBibG9jayB0aGF0IGlzIGxlc3MgdGhhbiBhIGR3b3JkIGZyb20gdGhlIG5leHQgYWxpZ25tZW50LCAKCXRoZW4gdGhlIHdyaXRpbmcgYmFjayBvbmUgZHdvcmQgd2lsbCBjb3JydXB0IG1lbW9yeS4KCglGb3IgZXhhbXBsZSwgc3VwcG9zZSB0aGF0IGFsaWdubWVudCBpcyAxNiBhbmQgbWFsbG9jIHJldHVybnMgdGhlIGFkZHJlc3MgMHhGRkZGLgoKCTE2IC0gMHhGRkZGICUgMTYgKyAweEZGRkYgPSAxNiAtIDE1ICsgMHhGRkZGID0gMHgxMDAwMC4KCglOb3csIHlvdSBzdWJ0cmFjdCBvbmUgZHdvcmQgZnJvbSB0aGF0IGFuZCB3cml0ZSBhbmQgdGhhdCB3aWxsIGNvcnJ1cHQgbWVtb3J5LgoKCVRoYXQncyB3aHkgdGhlIGNvZGUgYmVsb3cgYWxsb2NhdGVzICp0d28qIGFsaWdubWVudHMgaW5zdGVhZCBvZiBvbmUuIAoJKi8KCXZvaWQqIG1lbV9yZWFsID0gbWFsbG9jKGFtb3VudCArIDIgKiBhbGlnbm1lbnQpOwoJaWYoIW1lbV9yZWFsKSByZXR1cm4gTlVMTDsKCWNoYXIqIG1lbV9hbGlnbiA9IChjaGFyKikoKHVuc2lnbmVkIGxvbmcpKDIgKiBhbGlnbm1lbnQgLSAodW5zaWduZWQgbG9uZyltZW1fcmVhbCAlICh1bnNpZ25lZCBsb25nKWFsaWdubWVudCkgKyAodW5zaWduZWQgbG9uZyltZW1fcmVhbCk7CgkqKChsb25nKiltZW1fYWxpZ24gLSAxKSA9IChsb25nKW1lbV9yZWFsOwoJcmV0dXJuIG1lbV9hbGlnbjsKfQoKdm9pZCBGcmVlSW1hZ2VfQWxpZ25lZF9GcmVlKHZvaWQqIG1lbSkgewoJZnJlZSgodm9pZCopKigobG9uZyopbWVtIC0gMSkpOwp9CgojZW5kaWYgLy8gX1dJTjMyIHx8IF9XSU42NAoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgRklCSVRNQVAgbWVtb3J5IG1hbmFnZW1lbnQKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCkNhbGN1bGF0ZSB0aGUgc2l6ZSBvZiBhIEZyZWVJbWFnZSBpbWFnZS4gCkFsaWduIHRoZSBwYWxldHRlIGFuZCB0aGUgcGl4ZWxzIG9uIGEgRklCSVRNQVBfQUxJR05NRU5UIGJ5dGVzIGFsaWdubWVudCBib3VuZGFyeS4KVGhpcyBmdW5jdGlvbiBpbmNsdWRlcyBhIHByb3RlY3Rpb24gYWdhaW5zdCBtYWxpY2lvdXMgaW1hZ2VzLCBiYXNlZCBvbiBhIEtJU1MgaW50ZWdlciBvdmVyZmxvdyBkZXRlY3Rpb24gbWVjaGFuaXNtLiAKCkBwYXJhbSBoZWFkZXJfb25seSBJZiBUUlVFLCBjYWxjdWxhdGUgYSAnaGVhZGVyIG9ubHknIEZJQklUTUFQIHNpemUsIG90aGVyd2lzZSBjYWxjdWxhdGUgYSBmdWxsIEZJQklUTUFQIHNpemUKQHBhcmFtIHdpZHRoIEltYWdlIHdpZHRoCkBwYXJhbSBoZWlnaHQgSW1hZ2UgaGVpZ2h0CkBwYXJhbSBicHAgTnVtYmVyIG9mIGJpdHMtcGVyLXBpeGVsCkBwYXJhbSBuZWVkX21hc2tzIFdlIG9ubHkgc3RvcmUgdGhlIG1hc2tzIChhbmQgYWxsb2NhdGUgbWVtb3J5IGZvciB0aGVtKSBmb3IgMTYtYml0IGltYWdlcyBvZiB0eXBlIEZJVF9CSVRNQVAKQHJldHVybiBSZXR1cm5zIGEgc2l6ZSBpbiBCWVRFIHVuaXRzCkBzZWUgRnJlZUltYWdlX0FsbG9jYXRlQml0bWFwCiovCnN0YXRpYyBzaXplX3QgCkZyZWVJbWFnZV9HZXRJbnRlcm5hbEltYWdlU2l6ZShCT09MIGhlYWRlcl9vbmx5LCB1bnNpZ25lZCB3aWR0aCwgdW5zaWduZWQgaGVpZ2h0LCB1bnNpZ25lZCBicHAsIEJPT0wgbmVlZF9tYXNrcykgewoJc2l6ZV90IGRpYl9zaXplID0gc2l6ZW9mKEZSRUVJTUFHRUhFQURFUik7CglkaWJfc2l6ZSArPSAoZGliX3NpemUgJSBGSUJJVE1BUF9BTElHTk1FTlQgPyBGSUJJVE1BUF9BTElHTk1FTlQgLSBkaWJfc2l6ZSAlIEZJQklUTUFQX0FMSUdOTUVOVCA6IDApOwoJZGliX3NpemUgKz0gRklCSVRNQVBfQUxJR05NRU5UIC0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICUgRklCSVRNQVBfQUxJR05NRU5UOwoJZGliX3NpemUgKz0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpOwoJLy8gcGFsZXR0ZSBpcyBhbGlnbmVkIG9uIGEgMTYgYnl0ZXMgYm91bmRhcnkKCWRpYl9zaXplICs9IHNpemVvZihSR0JRVUFEKSAqIENhbGN1bGF0ZVVzZWRQYWxldHRlRW50cmllcyhicHApOwoJLy8gd2UgYm90aCBhZGQgcGFsZXR0ZSBzaXplIGFuZCBtYXNrcyBzaXplIGlmIG5lZWRfbWFza3MgaXMgdHJ1ZSwgc2luY2UgQ2FsY3VsYXRlVXNlZFBhbGV0dGVFbnRyaWVzCgkvLyBhbHdheXMgcmV0dXJucyAwIGlmIG5lZWRfbWFza3MgaXMgdHJ1ZSAod2hpY2ggaXMgb25seSB0cnVlIGZvciAxNiBiaXQgaW1hZ2VzKS4KCWRpYl9zaXplICs9IG5lZWRfbWFza3MgPyBzaXplb2YoRFdPUkQpICogMyA6IDA7CglkaWJfc2l6ZSArPSAoZGliX3NpemUgJSBGSUJJVE1BUF9BTElHTk1FTlQgPyBGSUJJVE1BUF9BTElHTk1FTlQgLSBkaWJfc2l6ZSAlIEZJQklUTUFQX0FMSUdOTUVOVCA6IDApOwoKCWlmKCFoZWFkZXJfb25seSkgewoJCWNvbnN0IHNpemVfdCBoZWFkZXJfc2l6ZSA9IGRpYl9zaXplOwoKCQkvLyBwaXhlbHMgYXJlIGFsaWduZWQgb24gYSAxNiBieXRlcyBib3VuZGFyeQoJCWRpYl9zaXplICs9IChzaXplX3QpQ2FsY3VsYXRlUGl0Y2goQ2FsY3VsYXRlTGluZSh3aWR0aCwgYnBwKSkgKiAoc2l6ZV90KWhlaWdodDsKCgkJLy8gY2hlY2sgZm9yIHBvc3NpYmxlIG1hbGxvYyBvdmVyZmxvdyB1c2luZyBhIEtJU1MgaW50ZWdlciBvdmVyZmxvdyBkZXRlY3Rpb24gbWVjaGFuaXNtCgkJewoJCQljb25zdCBkb3VibGUgZFBpdGNoID0gZmxvb3IoICgoZG91YmxlKWJwcCAqIHdpZHRoICsgMzEuMCkgLyAzMi4wICkgKiA0LjA7CgkJCWNvbnN0IGRvdWJsZSBkSW1hZ2VTaXplID0gKGRvdWJsZSloZWFkZXJfc2l6ZSArIGRQaXRjaCAqIGhlaWdodDsKCQkJaWYoZEltYWdlU2l6ZSAhPSAoZG91YmxlKWRpYl9zaXplKSB7CgkJCQkvLyBoZXJlLCB3ZSBhcmUgc3VyZSB0byBlbmNvdW50ZXIgYSBtYWxsb2Mgb3ZlcmZsb3c6IHRyeSB0byBhdm9pZCBpdCAuLi4KCQkJCXJldHVybiAwOwoJCQl9CgoJCQkvKgoJCQlUaGUgZm9sbG93aW5nIGNvbnN0YW50IHRha2UgaW50byBhY2NvdW50IHRoZSBhZGRpdGlvbm5hbCBtZW1vcnkgdXNlZCBieSAKCQkJYWxpZ25lZCBtYWxsb2MgZnVuY3Rpb25zIGFzIHdlbGwgYXMgZGVidWcgbWFsbG9jIGZ1bmN0aW9ucy4gCgkJCUl0IGlzIHN1cHBvc2VkIGhlcmUgdGhhdCB1c2luZyBhICg4ICogRklCSVRNQVBfQUxJR05NRU5UKSByaXNrIG1hcmdpbiB3aWxsIGJlIGVub3VnaAoJCQlmb3IgdGhlIHRhcmdldCBjb21waWxlci4gCgkJCSovCgkJCWNvbnN0IGRvdWJsZSBGSUJJVE1BUF9NQVhfTUVNT1JZID0gKGRvdWJsZSkoKHNpemVfdCktMSkgLSA4ICogRklCSVRNQVBfQUxJR05NRU5UOwoKCQkJaWYoZEltYWdlU2l6ZSA+IEZJQklUTUFQX01BWF9NRU1PUlkpIHsKCQkJCS8vIGF2b2lkIHBvc3NpYmxlIG92ZXJmbG93IGluc2lkZSBDIGFsbG9jYXRpb24gZnVuY3Rpb25zCgkJCQlyZXR1cm4gMDsKCQkJfQoJCX0KCX0KCglyZXR1cm4gZGliX3NpemU7Cn0KCi8qKgpIZWxwZXIgZm9yIDE2LWJpdCBGSVRfQklUTUFQClJldHVybnMgYSBwb2ludGVyIHRvIHRoZSBiaXRtYXAncyByZWQtLCBncmVlbi0gYW5kIGJsdWUgbWFza3MuCkBwYXJhbSBkaWIgVGhlIGJpdG1hcCB0byBvYnRhaW4gbWFza3MgZnJvbS4KQHJldHVybiBSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgYml0bWFwJ3MgcmVkLSwgZ3JlZW4tIGFuZCBibHVlIG1hc2tzCm9yIE5VTEwsIGlmIG5vIG1hc2tzIGFyZSBwcmVzZW50IChlLmcuIGZvciAyNCBiaXQgaW1hZ2VzKS4KKi8Kc3RhdGljIEZSRUVJTUFHRVJHQk1BU0tTICoKRnJlZUltYWdlX0dldFJHQk1hc2tzKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiBGcmVlSW1hZ2VfSGFzUkdCTWFza3MoZGliKSA/IChGUkVFSU1BR0VSR0JNQVNLUyAqKSgoKEJZVEUgKilGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpKSArIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSkgOiBOVUxMOwp9CgovKioKSW50ZXJuYWwgRklCSVRNQVAgYWxsb2NhdGlvbi4KClRoaXMgZnVuY3Rpb24gYWNjZXB0cyAoZXh0X2JpdHMsIGV4dF9waXRjaCkgYXJndW1lbnRzLiBJZiB0aGVzZSBhcmUgcHJvdmlkZWQgdGhlIEZJQklUTUFQIAp3aWxsIGJlIGFsbG9jYXRlZCBhcyAiaGVhZGVyIG9ubHkiLCBidXQgYml0cyBhbmQgcGl0Y2ggd2lsbCBiZSBzdG9yZWQgd2l0aGluIHRoZSBGUkVFSU1BR0VIRUFERVIgCmFuZCB0aGUgcmVzdWx0aW5nIEZJQklUTUFQIHdpbGwgaGF2ZSBwaXhlbHMsIGkuZS4gSGFzUGl4ZWxzKCkgd2lsbCByZXR1cm4gVFJVRS4KLSBHZXRCaXRzKCkgYW5kIEdldFBpdGNoIHJldHVybiB0aGUgY29ycmVjdCB2YWx1ZXMgLSBlaXRoZXIgb2Zmc2V0cyBvciB0aGUgc3RvcmVkIHZhbHVlcyAodXNlci1wcm92aWRlZCBiaXRzIGFuZCBwaXRjaCkuCi0gQ2xvbmUoKSBjcmVhdGVzIGEgbmV3IEZJQklUTUFQIHdpdGggY29weSBvZiB0aGUgdXNlciBwaXhlbCBkYXRhLgotIFVubG9hZCdzIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IG5lZWQgdG8gY2hhbmdlIC0gaXQganVzdCByZWxlYXNlIGEgImhlYWRlciBvbmx5IiBkaWIuCk5vdGUgdGhhdCB3aGVuIHVzaW5nIGV4dGVybmFsIGRhdGEsIHRoZSBkYXRhIGRvZXMgbm90IG5lZWQgdG8gaGF2ZSB0aGUgc2FtZSBhbGlnbm1lbnQgYXMgdGhlIGRlZmF1bHQgNC1ieXRlIGFsaWdubWVudC4gClRoaXMgZW5hYmxlcyB0aGUgcG9zc2liaWxpdHkgdG8gYWNjZXNzIGJ1ZmZlcnMgd2l0aCwgZm9yIGluc3RhbmNlLCBzdHJpY3RlciBhbGlnbm1lbnQsCmxpa2UgdGhlIG9uZXMgdXNlZCBpbiBsb3ctbGV2ZWwgQVBJcyBsaWtlIE9wZW5DTCBvciBpbnRyaW5zaWNzLgoKQHBhcmFtIGhlYWRlcl9vbmx5IElmIFRSVUUsIGFsbG9jYXRlIGEgJ2hlYWRlciBvbmx5JyBGSUJJVE1BUCwgb3RoZXJ3aXNlIGFsbG9jYXRlIGEgZnVsbCBGSUJJVE1BUApAcGFyYW0gZXh0X2JpdHMgUG9pbnRlciB0byBleHRlcm5hbCB1c2VyJ3MgcGl4ZWwgYnVmZmVyIGlmIHVzaW5nIHdyYXBwZWQgYnVmZmVyLCBOVUxMIG90aGVyd2lzZQpAcGFyYW0gZXh0X3BpdGNoIFBvaW50ZXIgdG8gZXh0ZXJuYWwgdXNlcidzIHBpeGVsIGJ1ZmZlciBwaXRjaCBpZiB1c2luZyB3cmFwcGVkIGJ1ZmZlciwgMCBvdGhlcndpc2UKQHBhcmFtIHR5cGUgSW1hZ2UgdHlwZQpAcGFyYW0gd2lkdGggSW1hZ2Ugd2lkdGgKQHBhcmFtIGhlaWdodCBJbWFnZSBoZWlnaHQKQHBhcmFtIGJwcCBOdW1iZXIgb2YgYml0cyBwZXIgcGl4ZWwKQHBhcmFtIHJlZF9tYXNrIEltYWdlIHJlZCBtYXNrIApAcGFyYW0gZ3JlZW5fbWFzayBJbWFnZSBncmVlbiBtYXNrCkBwYXJhbSBibHVlX21hc2sgSW1hZ2UgYmx1ZSBtYXNrCkByZXR1cm4gUmV0dXJucyB0aGUgYWxsb2NhdGVkIEZJQklUTUFQIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UKKi8Kc3RhdGljIEZJQklUTUFQICogCkZyZWVJbWFnZV9BbGxvY2F0ZUJpdG1hcChCT09MIGhlYWRlcl9vbmx5LCBCWVRFICpleHRfYml0cywgdW5zaWduZWQgZXh0X3BpdGNoLCBGUkVFX0lNQUdFX1RZUEUgdHlwZSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgYnBwLCB1bnNpZ25lZCByZWRfbWFzaywgdW5zaWduZWQgZ3JlZW5fbWFzaywgdW5zaWduZWQgYmx1ZV9tYXNrKSB7CgoJLy8gY2hlY2sgaW5wdXQgdmFyaWFibGVzCgl3aWR0aCA9IGFicyh3aWR0aCk7CgloZWlnaHQgPSBhYnMoaGVpZ2h0KTsKCWlmKCEoKHdpZHRoID4gMCkgJiYgKGhlaWdodCA+IDApKSkgewoJCXJldHVybiBOVUxMOwoJfQoJaWYoZXh0X2JpdHMpIHsKCQlpZihleHRfcGl0Y2ggPT0gMCkgewoJCQlyZXR1cm4gTlVMTDsKCQl9CgkJYXNzZXJ0KGhlYWRlcl9vbmx5ID09IEZBTFNFKTsKCX0KCgkvLyB3ZSBvbmx5IHN0b3JlIHRoZSBtYXNrcyAoYW5kIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlbSkgZm9yIDE2LWJpdCBpbWFnZXMgb2YgdHlwZSBGSVRfQklUTUFQCglCT09MIG5lZWRfbWFza3MgPSBGQUxTRTsKCgkvLyBjaGVjayBwaXhlbCBiaXQgZGVwdGgKCXN3aXRjaCh0eXBlKSB7CgkJY2FzZSBGSVRfQklUTUFQOgoJCQlzd2l0Y2goYnBwKSB7CgkJCQljYXNlIDE6CgkJCQljYXNlIDQ6CgkJCQljYXNlIDg6CgkJCQkJYnJlYWs7CgkJCQljYXNlIDE2OgoJCQkJCW5lZWRfbWFza3MgPSBUUlVFOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAyNDoKCQkJCWNhc2UgMzI6CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJCWJwcCA9IDg7CgkJCQkJYnJlYWs7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBGSVRfVUlOVDE2OgoJCQlicHAgPSA4ICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KTsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfSU5UMTY6CgkJCWJwcCA9IDggKiBzaXplb2Yoc2hvcnQpOwoJCQlicmVhazsKCQljYXNlIEZJVF9VSU5UMzI6CgkJCWJwcCA9IDggKiBzaXplb2YoRFdPUkQpOwoJCQlicmVhazsKCQljYXNlIEZJVF9JTlQzMjoKCQkJYnBwID0gOCAqIHNpemVvZihMT05HKTsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfRkxPQVQ6CgkJCWJwcCA9IDggKiBzaXplb2YoZmxvYXQpOwoJCQlicmVhazsKCQljYXNlIEZJVF9ET1VCTEU6CgkJCWJwcCA9IDggKiBzaXplb2YoZG91YmxlKTsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfQ09NUExFWDoKCQkJYnBwID0gOCAqIHNpemVvZihGSUNPTVBMRVgpOwoJCQlicmVhazsKCQljYXNlIEZJVF9SR0IxNjoKCQkJYnBwID0gOCAqIHNpemVvZihGSVJHQjE2KTsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCQTE2OgoJCQlicHAgPSA4ICogc2l6ZW9mKEZJUkdCQTE2KTsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfUkdCRjoKCQkJYnBwID0gOCAqIHNpemVvZihGSVJHQkYpOwoJCQlicmVhazsKCQljYXNlIEZJVF9SR0JBRjoKCQkJYnBwID0gOCAqIHNpemVvZihGSVJHQkFGKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcmV0dXJuIE5VTEw7Cgl9CgoJRklCSVRNQVAgKmJpdG1hcCA9IChGSUJJVE1BUCAqKW1hbGxvYyhzaXplb2YoRklCSVRNQVApKTsKCglpZiAoYml0bWFwICE9IE5VTEwpIHsKCgkJLy8gY2FsY3VsYXRlIHRoZSBzaXplIG9mIGEgRnJlZUltYWdlIGltYWdlCgkJLy8gYWxpZ24gdGhlIHBhbGV0dGUgYW5kIHRoZSBwaXhlbHMgb24gYSBGSUJJVE1BUF9BTElHTk1FTlQgYnl0ZXMgYWxpZ25tZW50IGJvdW5kYXJ5CgkJLy8gcGFsZXR0ZSBpcyBhbGlnbmVkIG9uIGEgMTYgYnl0ZXMgYm91bmRhcnkKCQkvLyBwaXhlbHMgYXJlIGFsaWduZWQgb24gYSAxNiBieXRlcyBib3VuZGFyeQoKCQkvLyB3aGVuIHVzaW5nIGEgdXNlciBwcm92aWRlZCBwaXhlbCBidWZmZXIsIGZvcmNlIGEgJ2hlYWRlciBvbmx5JyBhbGxvY2F0aW9uCgoJCXNpemVfdCBkaWJfc2l6ZSA9IEZyZWVJbWFnZV9HZXRJbnRlcm5hbEltYWdlU2l6ZShoZWFkZXJfb25seSB8fCBleHRfYml0cywgd2lkdGgsIGhlaWdodCwgYnBwLCBuZWVkX21hc2tzKTsKCgkJaWYoZGliX3NpemUgPT0gMCkgewoJCQkvLyBtZW1vcnkgYWxsb2NhdGlvbiB3aWxsIGZhaWwgKHByb2JhYmx5IGEgbWFsbG9jIG92ZXJmbG93KQoJCQlmcmVlKGJpdG1hcCk7CgkJCXJldHVybiBOVUxMOwoJCX0KCgkJYml0bWFwLT5kYXRhID0gKEJZVEUgKilGcmVlSW1hZ2VfQWxpZ25lZF9NYWxsb2MoZGliX3NpemUgKiBzaXplb2YoQllURSksIEZJQklUTUFQX0FMSUdOTUVOVCk7CgoJCWlmIChiaXRtYXAtPmRhdGEgIT0gTlVMTCkgewoJCQltZW1zZXQoYml0bWFwLT5kYXRhLCAwLCBkaWJfc2l6ZSk7CgoJCQkvLyB3cml0ZSBvdXQgdGhlIEZSRUVJTUFHRUhFQURFUgoKCQkJRlJFRUlNQUdFSEVBREVSICpmaWggPSAoRlJFRUlNQUdFSEVBREVSICopYml0bWFwLT5kYXRhOwoKCQkJZmloLT50eXBlID0gdHlwZTsKCgkJCW1lbXNldCgmZmloLT5ia2duZF9jb2xvciwgMCwgc2l6ZW9mKFJHQlFVQUQpKTsKCgkJCWZpaC0+dHJhbnNwYXJlbnQgPSBGQUxTRTsKCQkJZmloLT50cmFuc3BhcmVuY3lfY291bnQgPSAwOwoJCQltZW1zZXQoZmloLT50cmFuc3BhcmVudF90YWJsZSwgMHhmZiwgMjU2KTsKCgkJCWZpaC0+aGFzX3BpeGVscyA9IGhlYWRlcl9vbmx5ID8gRkFMU0UgOiBUUlVFOwoKCQkJLy8gaW5pdGlhbGl6ZSBGSUlDQ1BST0ZJTEUgbGluawoKCQkJRklJQ0NQUk9GSUxFICppY2NQcm9maWxlID0gRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUoYml0bWFwKTsKCQkJaWNjUHJvZmlsZS0+c2l6ZSA9IDA7CgkJCWljY1Byb2ZpbGUtPmRhdGEgPSAwOwoJCQlpY2NQcm9maWxlLT5mbGFncyA9IDA7CgoJCQkvLyBpbml0aWFsaXplIG1ldGFkYXRhIG1vZGVscyBsaXN0CgoJCQlmaWgtPm1ldGFkYXRhID0gbmV3KHN0ZDo6bm90aHJvdykgTUVUQURBVEFNQVA7CgoJCQkvLyBpbml0aWFsaXplIGF0dGFjaGVkIHRodW1ibmFpbAoKCQkJZmloLT50aHVtYm5haWwgPSBOVUxMOwoKCQkJLy8gc3RvcmUgYSBwb2ludGVyIHRvIHVzZXIgcHJvdmlkZWQgcGl4ZWwgYnVmZmVyIChpZiBhbnkpCgoJCQlmaWgtPmV4dGVybmFsX2JpdHMgPSBleHRfYml0czsKCQkJZmloLT5leHRlcm5hbF9waXRjaCA9IGV4dF9waXRjaDsKCgkJCS8vIHdyaXRlIG91dCB0aGUgQklUTUFQSU5GT0hFQURFUgoKCQkJQklUTUFQSU5GT0hFQURFUiAqYmloICAgPSBGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihiaXRtYXApOwoJCQliaWgtPmJpU2l6ZSAgICAgICAgICAgICA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKTsKCQkJYmloLT5iaVdpZHRoICAgICAgICAgICAgPSB3aWR0aDsKCQkJYmloLT5iaUhlaWdodCAgICAgICAgICAgPSBoZWlnaHQ7CgkJCWJpaC0+YmlQbGFuZXMgICAgICAgICAgID0gMTsKCQkJYmloLT5iaUNvbXByZXNzaW9uICAgICAgPSBuZWVkX21hc2tzID8gQklfQklURklFTERTIDogQklfUkdCOwoJCQliaWgtPmJpQml0Q291bnQgICAgICAgICA9IChXT1JEKWJwcDsKCQkJYmloLT5iaUNsclVzZWQgICAgICAgICAgPSBDYWxjdWxhdGVVc2VkUGFsZXR0ZUVudHJpZXMoYnBwKTsKCQkJYmloLT5iaUNsckltcG9ydGFudCAgICAgPSBiaWgtPmJpQ2xyVXNlZDsKCQkJYmloLT5iaVhQZWxzUGVyTWV0ZXIJPSAyODM1OwkvLyA3MiBkcGkKCQkJYmloLT5iaVlQZWxzUGVyTWV0ZXIJPSAyODM1OwkvLyA3MiBkcGkKCgkJCWlmKGJwcCA9PSA4KSB7CgkJCQkvLyBidWlsZCBhIGRlZmF1bHQgZ3JleXNjYWxlIHBhbGV0dGUgKHZlcnkgdXNlZnVsIGZvciBpbWFnZSBwcm9jZXNzaW5nKQoJCQkJUkdCUVVBRCAqcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoYml0bWFwKTsKCQkJCWZvcihpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgewoJCQkJCXBhbFtpXS5yZ2JSZWQJPSAoQllURSlpOwoJCQkJCXBhbFtpXS5yZ2JHcmVlbiA9IChCWVRFKWk7CgkJCQkJcGFsW2ldLnJnYkJsdWUJPSAoQllURSlpOwoJCQkJfQoJCQl9CgoJCQkvLyBqdXN0IHNldHRpbmcgdGhlIG1hc2tzIChvbmx5IGlmIG5lZWRlZCkganVzdCBsaWtlIHRoZSBwYWxldHRlLgoJCQlpZiAobmVlZF9tYXNrcykgewoJCQkJRlJFRUlNQUdFUkdCTUFTS1MgKm1hc2tzID0gRnJlZUltYWdlX0dldFJHQk1hc2tzKGJpdG1hcCk7CgkJCQltYXNrcy0+cmVkX21hc2sgPSByZWRfbWFzazsKCQkJCW1hc2tzLT5ncmVlbl9tYXNrID0gZ3JlZW5fbWFzazsKCQkJCW1hc2tzLT5ibHVlX21hc2sgPSBibHVlX21hc2s7CgkJCX0KCgkJCXJldHVybiBiaXRtYXA7CgkJfQoKCQlmcmVlKGJpdG1hcCk7Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCkZJQklUTUFQICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9BbGxvY2F0ZUhlYWRlckZvckJpdHMoQllURSAqZXh0X2JpdHMsIHVuc2lnbmVkIGV4dF9waXRjaCwgRlJFRV9JTUFHRV9UWVBFIHR5cGUsIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGJwcCwgdW5zaWduZWQgcmVkX21hc2ssIHVuc2lnbmVkIGdyZWVuX21hc2ssIHVuc2lnbmVkIGJsdWVfbWFzaykgewoJcmV0dXJuIEZyZWVJbWFnZV9BbGxvY2F0ZUJpdG1hcChGQUxTRSwgZXh0X2JpdHMsIGV4dF9waXRjaCwgdHlwZSwgd2lkdGgsIGhlaWdodCwgYnBwLCByZWRfbWFzaywgZ3JlZW5fbWFzaywgYmx1ZV9tYXNrKTsKfQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0FsbG9jYXRlSGVhZGVyVChCT09MIGhlYWRlcl9vbmx5LCBGUkVFX0lNQUdFX1RZUEUgdHlwZSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgYnBwLCB1bnNpZ25lZCByZWRfbWFzaywgdW5zaWduZWQgZ3JlZW5fbWFzaywgdW5zaWduZWQgYmx1ZV9tYXNrKSB7CglyZXR1cm4gRnJlZUltYWdlX0FsbG9jYXRlQml0bWFwKGhlYWRlcl9vbmx5LCBOVUxMLCAwLCB0eXBlLCB3aWR0aCwgaGVpZ2h0LCBicHAsIHJlZF9tYXNrLCBncmVlbl9tYXNrLCBibHVlX21hc2spOwp9CgpGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQWxsb2NhdGVIZWFkZXIoQk9PTCBoZWFkZXJfb25seSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgYnBwLCB1bnNpZ25lZCByZWRfbWFzaywgdW5zaWduZWQgZ3JlZW5fbWFzaywgdW5zaWduZWQgYmx1ZV9tYXNrKSB7CglyZXR1cm4gRnJlZUltYWdlX0FsbG9jYXRlQml0bWFwKGhlYWRlcl9vbmx5LCBOVUxMLCAwLCBGSVRfQklUTUFQLCB3aWR0aCwgaGVpZ2h0LCBicHAsIHJlZF9tYXNrLCBncmVlbl9tYXNrLCBibHVlX21hc2spOwp9CgpGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQWxsb2NhdGUoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgYnBwLCB1bnNpZ25lZCByZWRfbWFzaywgdW5zaWduZWQgZ3JlZW5fbWFzaywgdW5zaWduZWQgYmx1ZV9tYXNrKSB7CglyZXR1cm4gRnJlZUltYWdlX0FsbG9jYXRlQml0bWFwKEZBTFNFLCBOVUxMLCAwLCBGSVRfQklUTUFQLCB3aWR0aCwgaGVpZ2h0LCBicHAsIHJlZF9tYXNrLCBncmVlbl9tYXNrLCBibHVlX21hc2spOwp9CgpGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQWxsb2NhdGVUKEZSRUVfSU1BR0VfVFlQRSB0eXBlLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBicHAsIHVuc2lnbmVkIHJlZF9tYXNrLCB1bnNpZ25lZCBncmVlbl9tYXNrLCB1bnNpZ25lZCBibHVlX21hc2spIHsKCXJldHVybiBGcmVlSW1hZ2VfQWxsb2NhdGVCaXRtYXAoRkFMU0UsIE5VTEwsIDAsIHR5cGUsIHdpZHRoLCBoZWlnaHQsIGJwcCwgcmVkX21hc2ssIGdyZWVuX21hc2ssIGJsdWVfbWFzayk7Cn0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9VbmxvYWQoRklCSVRNQVAgKmRpYikgewoJaWYgKE5VTEwgIT0gZGliKSB7CQoJCWlmIChOVUxMICE9IGRpYi0+ZGF0YSkgewoJCQkvLyBkZWxldGUgcG9zc2libGUgaWNjIHByb2ZpbGUgLi4uCgkJCWlmIChGcmVlSW1hZ2VfR2V0SUNDUHJvZmlsZShkaWIpLT5kYXRhKSB7CgkJCQlmcmVlKEZyZWVJbWFnZV9HZXRJQ0NQcm9maWxlKGRpYiktPmRhdGEpOwoJCQl9CgoJCQkvLyBkZWxldGUgbWV0YWRhdGEgbW9kZWxzCgkJCU1FVEFEQVRBTUFQICptZXRhZGF0YSA9ICgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+bWV0YWRhdGE7CgoJCQlmb3IoTUVUQURBVEFNQVA6Oml0ZXJhdG9yIGkgPSAoKm1ldGFkYXRhKS5iZWdpbigpOyBpICE9ICgqbWV0YWRhdGEpLmVuZCgpOyBpKyspIHsKCQkJCVRBR01BUCAqdGFnbWFwID0gKCppKS5zZWNvbmQ7CgoJCQkJaWYodGFnbWFwKSB7CgkJCQkJZm9yKFRBR01BUDo6aXRlcmF0b3IgaiA9IHRhZ21hcC0+YmVnaW4oKTsgaiAhPSB0YWdtYXAtPmVuZCgpOyBqKyspIHsKCQkJCQkJRklUQUcgKnRhZyA9ICgqaikuc2Vjb25kOwoJCQkJCQlGcmVlSW1hZ2VfRGVsZXRlVGFnKHRhZyk7CgkJCQkJfQoKCQkJCQlkZWxldGUgdGFnbWFwOwoJCQkJfQoJCQl9CgoJCQlkZWxldGUgbWV0YWRhdGE7CgoJCQkvLyBkZWxldGUgZW1iZWRkZWQgdGh1bWJuYWlsCgkJCUZyZWVJbWFnZV9VbmxvYWQoRnJlZUltYWdlX0dldFRodW1ibmFpbChkaWIpKTsKCgkJCS8vIGRlbGV0ZSBiaXRtYXAgLi4uCgkJCUZyZWVJbWFnZV9BbGlnbmVkX0ZyZWUoZGliLT5kYXRhKTsKCQl9CgoJCWZyZWUoZGliKTsJCS8vIC4uLiBhbmQgdGhlIHdyYXBwZXIKCX0KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0Nsb25lKEZJQklUTUFQICpkaWIpIHsKCWlmKCFkaWIpIHsKCQlyZXR1cm4gTlVMTDsKCX0KCglGUkVFX0lNQUdFX1RZUEUgdHlwZSA9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKTsKCXVuc2lnbmVkIHdpZHRoCT0gRnJlZUltYWdlX0dldFdpZHRoKGRpYik7Cgl1bnNpZ25lZCBoZWlnaHQJPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7Cgl1bnNpZ25lZCBicHAJPSBGcmVlSW1hZ2VfR2V0QlBQKGRpYik7CgoJY29uc3QgQllURSAqZXh0X2JpdHMgPSAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPmV4dGVybmFsX2JpdHM7CgkKCS8vIGNoZWNrIGZvciBwaXhlbCBhdmFpbGFiaWxpdHkgLi4uCglCT09MIGhlYWRlcl9vbmx5ID0gRnJlZUltYWdlX0hhc1BpeGVscyhkaWIpID8gRkFMU0UgOiBUUlVFOwoKCS8vIGNoZWNrIHdoZXRoZXIgdGhpcyBpbWFnZSBoYXMgbWFza3MgZGVmaW5lZCAuLi4KCUJPT0wgbmVlZF9tYXNrcyA9IChicHAgPT0gMTYgJiYgdHlwZSA9PSBGSVRfQklUTUFQKSA/IFRSVUUgOiBGQUxTRTsKCgkvLyBhbGxvY2F0ZSBhIG5ldyBkaWIKCUZJQklUTUFQICpuZXdfZGliID0gRnJlZUltYWdlX0FsbG9jYXRlSGVhZGVyVChoZWFkZXJfb25seSwgdHlwZSwgd2lkdGgsIGhlaWdodCwgYnBwLAoJCQlGcmVlSW1hZ2VfR2V0UmVkTWFzayhkaWIpLCBGcmVlSW1hZ2VfR2V0R3JlZW5NYXNrKGRpYiksIEZyZWVJbWFnZV9HZXRCbHVlTWFzayhkaWIpKTsKCglpZiAobmV3X2RpYikgewoJCS8vIHNhdmUgSUNDIHByb2ZpbGUgbGlua3MKCQlGSUlDQ1BST0ZJTEUgKnNyY19pY2NQcm9maWxlID0gRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUoZGliKTsKCQlGSUlDQ1BST0ZJTEUgKmRzdF9pY2NQcm9maWxlID0gRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUobmV3X2RpYik7CgoJCS8vIHNhdmUgbWV0YWRhdGEgbGlua3MKCQlNRVRBREFUQU1BUCAqc3JjX21ldGFkYXRhID0gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5tZXRhZGF0YTsKCQlNRVRBREFUQU1BUCAqZHN0X21ldGFkYXRhID0gKChGUkVFSU1BR0VIRUFERVIgKiluZXdfZGliLT5kYXRhKS0+bWV0YWRhdGE7CgoJCS8vIGNhbGN1bGF0ZSB0aGUgc2l6ZSBvZiB0aGUgc3JjIGltYWdlCgkJLy8gYWxpZ24gdGhlIHBhbGV0dGUgYW5kIHRoZSBwaXhlbHMgb24gYSBGSUJJVE1BUF9BTElHTk1FTlQgYnl0ZXMgYWxpZ25tZW50IGJvdW5kYXJ5CgkJLy8gcGFsZXR0ZSBpcyBhbGlnbmVkIG9uIGEgMTYgYnl0ZXMgYm91bmRhcnkKCQkvLyBwaXhlbHMgYXJlIGFsaWduZWQgb24gYSAxNiBieXRlcyBib3VuZGFyeQoJCQoJCS8vIHdoZW4gdXNpbmcgYSB1c2VyIHByb3ZpZGVkIHBpeGVsIGJ1ZmZlciwgZm9yY2UgYSAnaGVhZGVyIG9ubHknIGNhbGN1bGF0aW9uCQkKCgkJc2l6ZV90IGRpYl9zaXplID0gRnJlZUltYWdlX0dldEludGVybmFsSW1hZ2VTaXplKGhlYWRlcl9vbmx5IHx8IGV4dF9iaXRzLCB3aWR0aCwgaGVpZ2h0LCBicHAsIG5lZWRfbWFza3MpOwoKCQkvLyBjb3B5IHRoZSBiaXRtYXAgKyBpbnRlcm5hbCBwb2ludGVycyAocmVtZW1iZXIgdG8gcmVzdG9yZSBuZXdfZGliIGludGVybmFsIHBvaW50ZXJzIGxhdGVyKQoJCW1lbWNweShuZXdfZGliLT5kYXRhLCBkaWItPmRhdGEsIGRpYl9zaXplKTsKCgkJLy8gcmVzZXQgSUNDIHByb2ZpbGUgbGluayBmb3IgbmV3X2RpYgoJCW1lbXNldChkc3RfaWNjUHJvZmlsZSwgMCwgc2l6ZW9mKEZJSUNDUFJPRklMRSkpOwoKCQkvLyByZXN0b3JlIG1ldGFkYXRhIGxpbmsgZm9yIG5ld19kaWIKCQkoKEZSRUVJTUFHRUhFQURFUiAqKW5ld19kaWItPmRhdGEpLT5tZXRhZGF0YSA9IGRzdF9tZXRhZGF0YTsKCgkJLy8gcmVzZXQgdGh1bWJuYWlsIGxpbmsgZm9yIG5ld19kaWIKCQkoKEZSRUVJTUFHRUhFQURFUiAqKW5ld19kaWItPmRhdGEpLT50aHVtYm5haWwgPSBOVUxMOwoKCQkvLyBjb3B5IHBvc3NpYmxlIElDQyBwcm9maWxlCgkJRnJlZUltYWdlX0NyZWF0ZUlDQ1Byb2ZpbGUobmV3X2RpYiwgc3JjX2ljY1Byb2ZpbGUtPmRhdGEsIHNyY19pY2NQcm9maWxlLT5zaXplKTsKCQlkc3RfaWNjUHJvZmlsZS0+ZmxhZ3MgPSBzcmNfaWNjUHJvZmlsZS0+ZmxhZ3M7CgoJCS8vIGNvcHkgbWV0YWRhdGEgbW9kZWxzCgkJZm9yKE1FVEFEQVRBTUFQOjppdGVyYXRvciBpID0gKCpzcmNfbWV0YWRhdGEpLmJlZ2luKCk7IGkgIT0gKCpzcmNfbWV0YWRhdGEpLmVuZCgpOyBpKyspIHsKCQkJaW50IG1vZGVsID0gKCppKS5maXJzdDsKCQkJVEFHTUFQICpzcmNfdGFnbWFwID0gKCppKS5zZWNvbmQ7CgoJCQlpZihzcmNfdGFnbWFwKSB7CgkJCQkvLyBjcmVhdGUgYSBtZXRhZGF0YSBtb2RlbAoJCQkJVEFHTUFQICpkc3RfdGFnbWFwID0gbmV3KHN0ZDo6bm90aHJvdykgVEFHTUFQKCk7CgoJCQkJaWYoZHN0X3RhZ21hcCkgewoJCQkJCS8vIGZpbGwgdGhlIG1vZGVsCgkJCQkJZm9yKFRBR01BUDo6aXRlcmF0b3IgaiA9IHNyY190YWdtYXAtPmJlZ2luKCk7IGogIT0gc3JjX3RhZ21hcC0+ZW5kKCk7IGorKykgewoJCQkJCQlzdGQ6OnN0cmluZyBkc3Rfa2V5ID0gKCpqKS5maXJzdDsKCQkJCQkJRklUQUcgKmRzdF90YWcgPSBGcmVlSW1hZ2VfQ2xvbmVUYWcoICgqaikuc2Vjb25kICk7CgoJCQkJCQkvLyBhc3NpZ24ga2V5IGFuZCB0YWcgdmFsdWUKCQkJCQkJKCpkc3RfdGFnbWFwKVtkc3Rfa2V5XSA9IGRzdF90YWc7CgkJCQkJfQoKCQkJCQkvLyBhc3NpZ24gbW9kZWwgYW5kIHRhZ21hcAoJCQkJCSgqZHN0X21ldGFkYXRhKVttb2RlbF0gPSBkc3RfdGFnbWFwOwoJCQkJfQoJCQl9CgkJfQoKCQkvLyBjb3B5IHRoZSB0aHVtYm5haWwKCQlGcmVlSW1hZ2VfU2V0VGh1bWJuYWlsKG5ld19kaWIsIEZyZWVJbWFnZV9HZXRUaHVtYm5haWwoZGliKSk7CgoJCS8vIGNvcHkgdXNlciBwcm92aWRlZCBwaXhlbCBidWZmZXIgKGlmIGFueSkKCQlpZihleHRfYml0cykgewoJCQljb25zdCB1bnNpZ25lZCBwaXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChkaWIpOwoJCQljb25zdCB1bnNpZ25lZCBsaW5lc2l6ZSA9IEZyZWVJbWFnZV9HZXRMaW5lKGRpYik7CgkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQltZW1jcHkoRnJlZUltYWdlX0dldFNjYW5MaW5lKG5ld19kaWIsIHkpLCBleHRfYml0cywgbGluZXNpemUpOwoJCQkJZXh0X2JpdHMgKz0gcGl0Y2g7CgkJCX0KCQl9CgoJCXJldHVybiBuZXdfZGliOwoJfQoKCXJldHVybiBOVUxMOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpCWVRFICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRCaXRzKEZJQklUTUFQICpkaWIpIHsKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKGRpYikpIHsKCQlyZXR1cm4gTlVMTDsKCX0KCglpZigoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPmV4dGVybmFsX2JpdHMpIHsKCQlyZXR1cm4gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5leHRlcm5hbF9iaXRzOwoJfQoKCS8vIHJldHVybnMgdGhlIHBpeGVscyBhbGlnbmVkIG9uIGEgRklCSVRNQVBfQUxJR05NRU5UIGJ5dGVzIGFsaWdubWVudCBib3VuZGFyeQoJc2l6ZV90IGxwID0gKHNpemVfdClGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpOwoJbHAgKz0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICsgc2l6ZW9mKFJHQlFVQUQpICogRnJlZUltYWdlX0dldENvbG9yc1VzZWQoZGliKTsKCWxwICs9IEZyZWVJbWFnZV9IYXNSR0JNYXNrcyhkaWIpID8gc2l6ZW9mKERXT1JEKSAqIDMgOiAwOwoJbHAgKz0gKGxwICUgRklCSVRNQVBfQUxJR05NRU5UID8gRklCSVRNQVBfQUxJR05NRU5UIC0gbHAgJSBGSUJJVE1BUF9BTElHTk1FTlQgOiAwKTsKCXJldHVybiAoQllURSAqKWxwOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBESUIgaW5mb3JtYXRpb24gZnVuY3Rpb25zCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZJQklUTUFQKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldFRodW1ibmFpbChGSUJJVE1BUCAqZGliKSB7CglyZXR1cm4gKGRpYiAhPSBOVUxMKSA/ICgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+dGh1bWJuYWlsIDogTlVMTDsKfQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX1NldFRodW1ibmFpbChGSUJJVE1BUCAqZGliLCBGSUJJVE1BUCAqdGh1bWJuYWlsKSB7CglpZihkaWIgPT0gTlVMTCkgewoJCXJldHVybiBGQUxTRTsKCX0KCUZJQklUTUFQICpjdXJyZW50VGh1bWJuYWlsID0gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT50aHVtYm5haWw7CglpZihjdXJyZW50VGh1bWJuYWlsID09IHRodW1ibmFpbCkgewoJCXJldHVybiBUUlVFOwoJfQoJRnJlZUltYWdlX1VubG9hZChjdXJyZW50VGh1bWJuYWlsKTsKCgkoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPnRodW1ibmFpbCA9IEZyZWVJbWFnZV9IYXNQaXhlbHModGh1bWJuYWlsKSA/IEZyZWVJbWFnZV9DbG9uZSh0aHVtYm5haWwpIDogTlVMTDsKCglyZXR1cm4gVFJVRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRlJFRV9JTUFHRV9DT0xPUl9UWVBFIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlKEZJQklUTUFQICpkaWIpIHsKCVJHQlFVQUQgKnJnYjsKCgljb25zdCBGUkVFX0lNQUdFX1RZUEUgaW1hZ2VfdHlwZSA9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKTsKCgkvLyBzcGVjaWFsIGJpdG1hcCB0eXBlCglpZihpbWFnZV90eXBlICE9IEZJVF9CSVRNQVApIHsKCQlzd2l0Y2goaW1hZ2VfdHlwZSkgewoJCQljYXNlIEZJVF9VSU5UMTY6CgkJCXsKCQkJCS8vIDE2LWJpdCBncmV5c2NhbGUgVElGIGNhbiBiZSBlaXRoZXIgRklDX01JTklTQkxBQ0sgKHRoZSBtb3N0IGNvbW1vbiBjYXNlKSBvciBGSUNfTUlOSVNXSElURQoJCQkJLy8geW91IGNhbiBjaGVjayB0aGlzIHVzaW5nIEVYSUZfTUFJTiBtZXRhZGF0YQoJCQkJRklUQUcgKnBob3RvbWV0cmljVGFnID0gTlVMTDsKCQkJCWlmKEZyZWVJbWFnZV9HZXRNZXRhZGF0YShGSU1EX0VYSUZfTUFJTiwgZGliLCAiUGhvdG9tZXRyaWNJbnRlcnByZXRhdGlvbiIsICZwaG90b21ldHJpY1RhZykpIHsKCQkJCQljb25zdCBzaG9ydCAqdmFsdWUgPSAoc2hvcnQqKUZyZWVJbWFnZV9HZXRUYWdWYWx1ZShwaG90b21ldHJpY1RhZyk7CgkJCQkJLy8gUEhPVE9NRVRSSUNfTUlOSVNXSElURSA9IDAgPT4gbWluIHZhbHVlIGlzIHdoaXRlCgkJCQkJLy8gUEhPVE9NRVRSSUNfTUlOSVNCTEFDSyA9IDEgPT4gbWluIHZhbHVlIGlzIGJsYWNrCgkJCQkJcmV0dXJuICgqdmFsdWUgPT0gMCkgPyBGSUNfTUlOSVNXSElURSA6IEZJQ19NSU5JU0JMQUNLOwoJCQkJfQoJCQkJcmV0dXJuIEZJQ19NSU5JU0JMQUNLOwoJCQl9CgkJCWJyZWFrOwoJCQljYXNlIEZJVF9SR0IxNjoKCQkJY2FzZSBGSVRfUkdCRjoKCQkJCXJldHVybiBGSUNfUkdCOwoJCQljYXNlIEZJVF9SR0JBMTY6CgkJCWNhc2UgRklUX1JHQkFGOgoJCQkJcmV0dXJuIEZJQ19SR0JBTFBIQTsKCQl9CgoJCXJldHVybiBGSUNfTUlOSVNCTEFDSzsKCX0KCgkvLyBzdGFuZGFyZCBpbWFnZSB0eXBlCglzd2l0Y2ggKEZyZWVJbWFnZV9HZXRCUFAoZGliKSkgewoJCWNhc2UgMToKCQl7CgkJCXJnYiA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgoJCQlpZiAoKHJnYi0+cmdiUmVkID09IDApICYmIChyZ2ItPnJnYkdyZWVuID09IDApICYmIChyZ2ItPnJnYkJsdWUgPT0gMCkpIHsKCQkJCXJnYisrOwoKCQkJCWlmICgocmdiLT5yZ2JSZWQgPT0gMjU1KSAmJiAocmdiLT5yZ2JHcmVlbiA9PSAyNTUpICYmIChyZ2ItPnJnYkJsdWUgPT0gMjU1KSkgewoJCQkJCXJldHVybiBGSUNfTUlOSVNCTEFDSzsKCQkJCX0KCQkJfQoKCQkJaWYgKChyZ2ItPnJnYlJlZCA9PSAyNTUpICYmIChyZ2ItPnJnYkdyZWVuID09IDI1NSkgJiYgKHJnYi0+cmdiQmx1ZSA9PSAyNTUpKSB7CgkJCQlyZ2IrKzsKCgkJCQlpZiAoKHJnYi0+cmdiUmVkID09IDApICYmIChyZ2ItPnJnYkdyZWVuID09IDApICYmIChyZ2ItPnJnYkJsdWUgPT0gMCkpIHsKCQkJCQlyZXR1cm4gRklDX01JTklTV0hJVEU7CgkJCQl9CgkJCX0KCgkJCXJldHVybiBGSUNfUEFMRVRURTsKCQl9CgoJCWNhc2UgNDoKCQljYXNlIDg6CS8vIENoZWNrIGlmIHRoZSBESUIgaGFzIGEgY29sb3Igb3IgYSBncmV5c2NhbGUgcGFsZXR0ZQoJCXsKCQkJaW50IG5jb2xvcnMgPSBGcmVlSW1hZ2VfR2V0Q29sb3JzVXNlZChkaWIpOwoJCSAgICBpbnQgbWluaXNibGFjayA9IDE7CgkJCXJnYiA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgoJCQlmb3IgKGludCBpID0gMDsgaSA8IG5jb2xvcnM7IGkrKykgewoJCQkJaWYgKChyZ2ItPnJnYlJlZCAhPSByZ2ItPnJnYkdyZWVuKSB8fCAocmdiLT5yZ2JSZWQgIT0gcmdiLT5yZ2JCbHVlKSkgewoJCQkJCXJldHVybiBGSUNfUEFMRVRURTsKCQkJCX0KCgkJCQkvLyBUaGUgRElCIGhhcyBhIGNvbG9yIHBhbGV0dGUgaWYgdGhlIGdyZXlzY2FsZSBpc24ndCBhIGxpbmVhciByYW1wCgkJCQkvLyBUYWtlIGNhcmUgb2YgcmV2ZXJzZWQgZ3JleSBpbWFnZXMKCQkJCWlmIChyZ2ItPnJnYlJlZCAhPSBpKSB7CgkJCQkJaWYgKChuY29sb3JzLWktMSkgIT0gcmdiLT5yZ2JSZWQpIHsKCQkJCQkJcmV0dXJuIEZJQ19QQUxFVFRFOwoJCQkJCX0gZWxzZSB7CgkJCQkJCW1pbmlzYmxhY2sgPSAwOwoJCQkJCX0KCQkJCX0KCgkJCQlyZ2IrKzsKCQkJfQoKCQkJcmV0dXJuIG1pbmlzYmxhY2sgPyBGSUNfTUlOSVNCTEFDSyA6IEZJQ19NSU5JU1dISVRFOwoJCX0KCgkJY2FzZSAxNjoKCQljYXNlIDI0OgoJCQlyZXR1cm4gRklDX1JHQjsKCgkJY2FzZSAzMjoKCQl7CgkJCWlmIChGcmVlSW1hZ2VfR2V0SUNDUHJvZmlsZShkaWIpLT5mbGFncyAmIEZJSUNDX0NPTE9SX0lTX0NNWUspIHsKCQkJCXJldHVybiBGSUNfQ01ZSzsKCQkJfQoKCQkJaWYoIEZyZWVJbWFnZV9IYXNQaXhlbHMoZGliKSApIHsKCQkJCS8vIGNoZWNrIGZvciBmdWxseSBvcGFxdWUgYWxwaGEgbGF5ZXIKCQkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7IHkrKykgewoJCQkJCXJnYiA9IChSR0JRVUFEICopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgoJCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsgeCsrKSB7CgkJCQkJCWlmIChyZ2JbeF0ucmdiUmVzZXJ2ZWQgIT0gMHhGRikgewoJCQkJCQkJcmV0dXJuIEZJQ19SR0JBTFBIQTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCXJldHVybiBGSUNfUkdCOwoJCQl9CgoJCQlyZXR1cm4gRklDX1JHQkFMUEhBOwoJCX0KCQkJCQoJCWRlZmF1bHQgOgoJCQlyZXR1cm4gRklDX01JTklTQkxBQ0s7Cgl9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZSRUVfSU1BR0VfVFlQRSBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIChkaWIgIT0gTlVMTCkgPyAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPnR5cGUgOiBGSVRfVU5LTk9XTjsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQk9PTCBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9IYXNQaXhlbHMoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIChkaWIgIT0gTlVMTCkgPyAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPmhhc19waXhlbHMgOiBGQUxTRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0hhc1JHQk1hc2tzKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiBkaWIgJiYgRnJlZUltYWdlX0dldEluZm9IZWFkZXIoZGliKS0+YmlDb21wcmVzc2lvbiA9PSBCSV9CSVRGSUVMRFM7Cn0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0UmVkTWFzayhGSUJJVE1BUCAqZGliKSB7CglGUkVFSU1BR0VSR0JNQVNLUyAqbWFza3MgPSBOVUxMOwoJRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYik7Cglzd2l0Y2goaW1hZ2VfdHlwZSkgewoJCWNhc2UgRklUX0JJVE1BUDoKCQkJLy8gY2hlY2sgZm9yIDE2LWJpdCBSR0IgKDU2NSBvciA1NTUpCgkJCW1hc2tzID0gRnJlZUltYWdlX0dldFJHQk1hc2tzKGRpYik7CgkJCWlmIChtYXNrcykgewoJCQkJcmV0dXJuIG1hc2tzLT5yZWRfbWFzazsKCQkJfQoJCQlyZXR1cm4gRnJlZUltYWdlX0dldEJQUChkaWIpID49IDI0ID8gRklfUkdCQV9SRURfTUFTSyA6IDA7CgkJZGVmYXVsdDoKCQkJcmV0dXJuIDA7Cgl9Cn0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0R3JlZW5NYXNrKEZJQklUTUFQICpkaWIpIHsKCUZSRUVJTUFHRVJHQk1BU0tTICptYXNrcyA9IE5VTEw7CglGUkVFX0lNQUdFX1RZUEUgaW1hZ2VfdHlwZSA9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKTsKCXN3aXRjaChpbWFnZV90eXBlKSB7CgkJY2FzZSBGSVRfQklUTUFQOgoJCQkvLyBjaGVjayBmb3IgMTYtYml0IFJHQiAoNTY1IG9yIDU1NSkKCQkJbWFza3MgPSBGcmVlSW1hZ2VfR2V0UkdCTWFza3MoZGliKTsKCQkJaWYgKG1hc2tzKSB7CgkJCQlyZXR1cm4gbWFza3MtPmdyZWVuX21hc2s7CgkJCX0KCQkJcmV0dXJuIEZyZWVJbWFnZV9HZXRCUFAoZGliKSA+PSAyNCA/IEZJX1JHQkFfR1JFRU5fTUFTSyA6IDA7CgkJZGVmYXVsdDoKCQkJcmV0dXJuIDA7Cgl9Cn0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0Qmx1ZU1hc2soRklCSVRNQVAgKmRpYikgewoJRlJFRUlNQUdFUkdCTUFTS1MgKm1hc2tzID0gTlVMTDsKCUZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpOwoJc3dpdGNoKGltYWdlX3R5cGUpIHsKCQljYXNlIEZJVF9CSVRNQVA6CgkJCS8vIGNoZWNrIGZvciAxNi1iaXQgUkdCICg1NjUgb3IgNTU1KQoJCQltYXNrcyA9IEZyZWVJbWFnZV9HZXRSR0JNYXNrcyhkaWIpOwoJCQlpZiAobWFza3MpIHsKCQkJCXJldHVybiBtYXNrcy0+Ymx1ZV9tYXNrOwoJCQl9CgkJCXJldHVybiBGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPj0gMjQgPyBGSV9SR0JBX0JMVUVfTUFTSyA6IDA7CgkJZGVmYXVsdDoKCQkJcmV0dXJuIDA7Cgl9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkJPT0wgRExMX0NBTExDT05WCkZyZWVJbWFnZV9IYXNCYWNrZ3JvdW5kQ29sb3IoRklCSVRNQVAgKmRpYikgewoJaWYoZGliKSB7CgkJUkdCUVVBRCAqYmtnbmRfY29sb3IgPSAmKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5ia2duZF9jb2xvcjsKCQlyZXR1cm4gKGJrZ25kX2NvbG9yLT5yZ2JSZXNlcnZlZCAhPSAwKSA/IFRSVUUgOiBGQUxTRTsKCX0KCXJldHVybiBGQUxTRTsKfQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldEJhY2tncm91bmRDb2xvcihGSUJJVE1BUCAqZGliLCBSR0JRVUFEICpia2NvbG9yKSB7CglpZihkaWIgJiYgYmtjb2xvcikgewoJCWlmKEZyZWVJbWFnZV9IYXNCYWNrZ3JvdW5kQ29sb3IoZGliKSkgewoJCQkvLyBnZXQgdGhlIGJhY2tncm91bmQgY29sb3IKCQkJUkdCUVVBRCAqYmtnbmRfY29sb3IgPSAmKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5ia2duZF9jb2xvcjsKCQkJbWVtY3B5KGJrY29sb3IsIGJrZ25kX2NvbG9yLCBzaXplb2YoUkdCUVVBRCkpOwoJCQkvLyBnZXQgdGhlIGJhY2tncm91bmQgaW5kZXgKCQkJaWYoRnJlZUltYWdlX0dldEJQUChkaWIpID09IDgpIHsKCQkJCVJHQlFVQUQgKnBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgkJCQlmb3IodW5zaWduZWQgaSA9IDA7IGkgPCBGcmVlSW1hZ2VfR2V0Q29sb3JzVXNlZChkaWIpOyBpKyspIHsKCQkJCQlpZihia2duZF9jb2xvci0+cmdiUmVkID09IHBhbFtpXS5yZ2JSZWQpIHsKCQkJCQkJaWYoYmtnbmRfY29sb3ItPnJnYkdyZWVuID09IHBhbFtpXS5yZ2JHcmVlbikgewoJCQkJCQkJaWYoYmtnbmRfY29sb3ItPnJnYkJsdWUgPT0gcGFsW2ldLnJnYkJsdWUpIHsKCQkJCQkJCQlia2NvbG9yLT5yZ2JSZXNlcnZlZCA9IChCWVRFKWk7CgkJCQkJCQkJcmV0dXJuIFRSVUU7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCgkJCWJrY29sb3ItPnJnYlJlc2VydmVkID0gMDsKCgkJCXJldHVybiBUUlVFOwoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCkJPT0wgRExMX0NBTExDT05WIApGcmVlSW1hZ2VfU2V0QmFja2dyb3VuZENvbG9yKEZJQklUTUFQICpkaWIsIFJHQlFVQUQgKmJrY29sb3IpIHsKCWlmKGRpYikgewoJCVJHQlFVQUQgKmJrZ25kX2NvbG9yID0gJigoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+YmtnbmRfY29sb3I7CgkJaWYoYmtjb2xvcikgewoJCQkvLyBzZXQgdGhlIGJhY2tncm91bmQgY29sb3IKCQkJbWVtY3B5KGJrZ25kX2NvbG9yLCBia2NvbG9yLCBzaXplb2YoUkdCUVVBRCkpOwoJCQkvLyBlbmFibGUgdGhlIGZpbGUgYmFja2dyb3VuZCBjb2xvcgoJCQlia2duZF9jb2xvci0+cmdiUmVzZXJ2ZWQgPSAxOwoJCX0gZWxzZSB7CgkJCS8vIGNsZWFyIGFuZCBkaXNhYmxlIHRoZSBmaWxlIGJhY2tncm91bmQgY29sb3IKCQkJbWVtc2V0KGJrZ25kX2NvbG9yLCAwLCBzaXplb2YoUkdCUVVBRCkpOwoJCX0KCQlyZXR1cm4gVFJVRTsKCX0KCglyZXR1cm4gRkFMU0U7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkJPT0wgRExMX0NBTExDT05WCkZyZWVJbWFnZV9Jc1RyYW5zcGFyZW50KEZJQklUTUFQICpkaWIpIHsKCWlmKGRpYikgewoJCUZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpOwoJCXN3aXRjaChpbWFnZV90eXBlKSB7CgkJCWNhc2UgRklUX0JJVE1BUDoKCQkJCWlmKEZyZWVJbWFnZV9HZXRCUFAoZGliKSA9PSAzMikgewoJCQkJCWlmKEZyZWVJbWFnZV9HZXRDb2xvclR5cGUoZGliKSA9PSBGSUNfUkdCQUxQSEEpIHsKCQkJCQkJcmV0dXJuIFRSVUU7CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQlyZXR1cm4gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT50cmFuc3BhcmVudCA/IFRSVUUgOiBGQUxTRTsKCQkJCX0KCQkJCWJyZWFrOwoJCQljYXNlIEZJVF9SR0JBMTY6CgkJCWNhc2UgRklUX1JHQkFGOgoJCQkJcmV0dXJuIFRSVUU7CgkJCWRlZmF1bHQ6CgkJCQlicmVhazsKCQl9Cgl9CglyZXR1cm4gRkFMU0U7Cn0KCkJZVEUgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldFRyYW5zcGFyZW5jeVRhYmxlKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiBkaWIgPyAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPnRyYW5zcGFyZW50X3RhYmxlIDogTlVMTDsKfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX1NldFRyYW5zcGFyZW50KEZJQklUTUFQICpkaWIsIEJPT0wgZW5hYmxlZCkgewoJaWYgKGRpYikgewoJCWlmICgoRnJlZUltYWdlX0dldEJQUChkaWIpIDw9IDgpIHx8IChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPT0gMzIpKSB7CgkJCSgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+dHJhbnNwYXJlbnQgPSBlbmFibGVkOwoJCX0gZWxzZSB7CgkJCSgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+dHJhbnNwYXJlbnQgPSBGQUxTRTsKCQl9Cgl9Cn0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5Q291bnQoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIGRpYiA/ICgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+dHJhbnNwYXJlbmN5X2NvdW50IDogMDsKfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX1NldFRyYW5zcGFyZW5jeVRhYmxlKEZJQklUTUFQICpkaWIsIEJZVEUgKnRhYmxlLCBpbnQgY291bnQpIHsKCWlmIChkaWIpIHsKCQljb3VudCA9IE1BWCgwLCBNSU4oY291bnQsIDI1NikpOwoJCWlmIChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPD0gOCkgewoJCQkoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPnRyYW5zcGFyZW50ID0gKGNvdW50ID4gMCkgPyBUUlVFIDogRkFMU0U7CgkJCSgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+dHJhbnNwYXJlbmN5X2NvdW50ID0gY291bnQ7CgoJCQlpZiAodGFibGUpIHsKCQkJCW1lbWNweSgoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPnRyYW5zcGFyZW50X3RhYmxlLCB0YWJsZSwgY291bnQpOwoJCQl9IGVsc2UgewoJCQkJbWVtc2V0KCgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+dHJhbnNwYXJlbnRfdGFibGUsIDB4ZmYsIGNvdW50KTsKCQkJfQoJCX0gCgl9Cn0KCi8qKiBAYnJpZWYgU2V0cyB0aGUgaW5kZXggb2YgdGhlIHBhbGV0dGUgZW50cnkgdG8gYmUgdXNlZCBhcyB0cmFuc3BhcmVudCBjb2xvcgogZm9yIHRoZSBpbWFnZSBzcGVjaWZpZWQuIERvZXMgbm90aGluZyBvbiBoaWdoIGNvbG9yIGltYWdlcy4gCiAKIFRoaXMgbWV0aG9kIHNldHMgdGhlIGluZGV4IG9mIHRoZSBwYWxldHRlIGVudHJ5IHRvIGJlIHVzZWQgYXMgc2luZ2xlIHRyYW5zcGFyZW50CiBjb2xvciBmb3IgdGhlIGltYWdlIHNwZWNpZmllZC4gVGhpcyB3b3JrcyBvbiBwYWxsZXRpc2VkIGltYWdlcyBvbmx5IGFuZCBkb2VzCiBub3RoaW5nIGZvciBoaWdoIGNvbG9yIGltYWdlcy4KIAogQWx0aG91Z2ggaXQgaXMgcG9zc2libGUgZm9yIHBhbGxldGlzZWQgaW1hZ2VzIHRvIGhhdmUgbW9yZSB0aGFuIG9uZSB0cmFuc3BhcmVudAogY29sb3IsIHRoaXMgbWV0aG9kIHNldHMgdGhlIHBhbGV0dGUgZW50cnkgc3BlY2lmaWVkIGFzIHRoZSBzaW5nbGUgdHJhbnNwYXJlbnQKIGNvbG9yIGZvciB0aGUgaW1hZ2UuIEFsbCBvdGhlciBjb2xvcnMgd2lsbCBiZSBzZXQgdG8gYmUgbm9uLXRyYW5zcGFyZW50IGJ5IHRoaXMKIG1ldGhvZC4KIAogQXMgd2l0aCBGcmVlSW1hZ2VfU2V0VHJhbnNwYXJlbmN5VGFibGUoKSwgdGhpcyBtZXRob2QgYWxzbyBzZXRzIHRoZSBpbWFnZSdzCiB0cmFuc3BhcmVuY3kgcHJvcGVydHkgdG8gVFJVRSAoYXMgaXQgaXMgc2V0IGFuZCBvYnRhaW5lZCBieQogRnJlZUltYWdlX1NldFRyYW5zcGFyZW50KCkgYW5kIEZyZWVJbWFnZV9Jc1RyYW5zcGFyZW50KCkgcmVzcGVjdGl2ZWx5KSBmb3IKIHBhbGxldGlzZWQgaW1hZ2VzLgogCiBAcGFyYW0gZGliIElucHV0IGltYWdlLCB3aG9zZSB0cmFuc3BhcmVudCBjb2xvciBpcyB0byBiZSBzZXQuCiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBwYWxldHRlIGVudHJ5IHRvIGJlIHNldCBhcyB0cmFuc3BhcmVudCBjb2xvci4KICovCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9TZXRUcmFuc3BhcmVudEluZGV4KEZJQklUTUFQICpkaWIsIGludCBpbmRleCkgewoJaWYgKGRpYikgewoJCWludCBjb3VudCA9IEZyZWVJbWFnZV9HZXRDb2xvcnNVc2VkKGRpYik7CgkJaWYgKGNvdW50KSB7CgkJCUJZVEUgKm5ld190dCA9IChCWVRFICopbWFsbG9jKGNvdW50ICogc2l6ZW9mKEJZVEUpKTsKCQkJbWVtc2V0KG5ld190dCwgMHhGRiwgY291bnQpOwoJCQlpZiAoKGluZGV4ID49IDApICYmIChpbmRleCA8IGNvdW50KSkgewoJCQkJbmV3X3R0W2luZGV4XSA9IDB4MDA7CgkJCX0KCQkJRnJlZUltYWdlX1NldFRyYW5zcGFyZW5jeVRhYmxlKGRpYiwgbmV3X3R0LCBjb3VudCk7CgkJCWZyZWUobmV3X3R0KTsKCQl9Cgl9Cn0KCi8qKiBAYnJpZWYgUmV0dXJucyB0aGUgcGFsZXR0ZSBlbnRyeSB1c2VkIGFzIHRyYW5zcGFyZW50IGNvbG9yIGZvciB0aGUgaW1hZ2UKIHNwZWNpZmllZC4gV29ya3MgZm9yIHBhbGxldGlzZWQgaW1hZ2VzIG9ubHkgYW5kIHJldHVybnMgLTEgZm9yIGhpZ2ggY29sb3IKIGltYWdlcyBvciBpZiB0aGUgaW1hZ2UgaGFzIG5vIGNvbG9yIHNldCB0byBiZSB0cmFuc3BhcmVudC4gCiAKIEFsdGhvdWdoIGl0IGlzIHBvc3NpYmxlIGZvciBwYWxsZXRpc2VkIGltYWdlcyB0byBoYXZlIG1vcmUgdGhhbiBvbmUgdHJhbnNwYXJlbnQKIGNvbG9yLCB0aGlzIGZ1bmN0aW9uIGFsd2F5cyByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgcGFsZXR0ZSBlbnRyeSwgc2V0CiB0byBiZSB0cmFuc3BhcmVudC4gCiAKIEBwYXJhbSBkaWIgSW5wdXQgaW1hZ2UsIHdob3NlIHRyYW5zcGFyZW50IGNvbG9yIGlzIHRvIGJlIHJldHVybmVkLgogQHJldHVybiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgcGFsZXR0ZSBlbnRyeSB1c2VkIGFzIHRyYW5zcGFyZW50IGNvbG9yIGZvcgogdGhlIGltYWdlIHNwZWNpZmllZCBvciAtMSBpZiB0aGVyZSBpcyBubyB0cmFuc3BhcmVudCBjb2xvciBmb3VuZCAoZS5nLiB0aGUgaW1hZ2UKIGlzIGEgaGlnaCBjb2xvciBpbWFnZSkuCiAqLwppbnQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRUcmFuc3BhcmVudEluZGV4KEZJQklUTUFQICpkaWIpIHsKCWludCBjb3VudCA9IEZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lDb3VudChkaWIpOwoJQllURSAqdHQgPSBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5VGFibGUoZGliKTsKCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCWlmICh0dFtpXSA9PSAwKSB7CgkJCXJldHVybiBpOwoJCX0KCX0KCXJldHVybiAtMTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRklJQ0NQUk9GSUxFICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRJQ0NQcm9maWxlKEZJQklUTUFQICpkaWIpIHsKCUZJSUNDUFJPRklMRSAqcHJvZmlsZSA9IChkaWIpID8gKEZJSUNDUFJPRklMRSAqKSYoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPmljY1Byb2ZpbGUgOiBOVUxMOwoJcmV0dXJuIHByb2ZpbGU7Cn0KCkZJSUNDUFJPRklMRSAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQ3JlYXRlSUNDUHJvZmlsZShGSUJJVE1BUCAqZGliLCB2b2lkICpkYXRhLCBsb25nIHNpemUpIHsKCS8vIGNsZWFyIHRoZSBwcm9maWxlIGJ1dCBwcmVzZXJ2ZSBwcm9maWxlLT5mbGFncwoJRnJlZUltYWdlX0Rlc3Ryb3lJQ0NQcm9maWxlKGRpYik7CgkvLyBjcmVhdGUgdGhlIG5ldyBwcm9maWxlCglGSUlDQ1BST0ZJTEUgKnByb2ZpbGUgPSBGcmVlSW1hZ2VfR2V0SUNDUHJvZmlsZShkaWIpOwoJaWYoc2l6ZSAmJiBwcm9maWxlKSB7CgkJcHJvZmlsZS0+ZGF0YSA9IG1hbGxvYyhzaXplKTsKCQlpZihwcm9maWxlLT5kYXRhKSB7CgkJCW1lbWNweShwcm9maWxlLT5kYXRhLCBkYXRhLCBwcm9maWxlLT5zaXplID0gc2l6ZSk7CgkJfQoJfQoJcmV0dXJuIHByb2ZpbGU7Cn0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9EZXN0cm95SUNDUHJvZmlsZShGSUJJVE1BUCAqZGliKSB7CglGSUlDQ1BST0ZJTEUgKnByb2ZpbGUgPSBGcmVlSW1hZ2VfR2V0SUNDUHJvZmlsZShkaWIpOwoJaWYocHJvZmlsZSkgewoJCWlmIChwcm9maWxlLT5kYXRhKSB7CgkJCWZyZWUgKHByb2ZpbGUtPmRhdGEpOwoJCX0KCQkvLyBjbGVhciB0aGUgcHJvZmlsZSBidXQgcHJlc2VydmUgcHJvZmlsZS0+ZmxhZ3MKCQlwcm9maWxlLT5kYXRhID0gTlVMTDsKCQlwcm9maWxlLT5zaXplID0gMDsKCX0KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRXaWR0aChGSUJJVE1BUCAqZGliKSB7CglyZXR1cm4gZGliID8gRnJlZUltYWdlX0dldEluZm9IZWFkZXIoZGliKS0+YmlXaWR0aCA6IDA7Cn0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0SGVpZ2h0KEZJQklUTUFQICpkaWIpIHsKCXJldHVybiAoZGliKSA/IEZyZWVJbWFnZV9HZXRJbmZvSGVhZGVyKGRpYiktPmJpSGVpZ2h0IDogMDsKfQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRCUFAoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIGRpYiA/IEZyZWVJbWFnZV9HZXRJbmZvSGVhZGVyKGRpYiktPmJpQml0Q291bnQgOiAwOwp9Cgp1bnNpZ25lZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldExpbmUoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIGRpYiA/ICgoRnJlZUltYWdlX0dldFdpZHRoKGRpYikgKiBGcmVlSW1hZ2VfR2V0QlBQKGRpYikpICsgNykgLyA4IDogMDsKfQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRQaXRjaChGSUJJVE1BUCAqZGliKSB7CglpZihkaWIpIHsKCQlGUkVFSU1BR0VIRUFERVIgKmZpaCA9IChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGE7CgkJcmV0dXJuIGZpaC0+ZXh0ZXJuYWxfYml0cyA/IGZpaC0+ZXh0ZXJuYWxfcGl0Y2ggOiAoRnJlZUltYWdlX0dldExpbmUoZGliKSArIDMgJiB+Myk7Cgl9CglyZXR1cm4gMDsKfQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRDb2xvcnNVc2VkKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiBkaWIgPyBGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpLT5iaUNsclVzZWQgOiAwOwp9Cgp1bnNpZ25lZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldERJQlNpemUoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIChkaWIpID8gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICsgKEZyZWVJbWFnZV9HZXRDb2xvcnNVc2VkKGRpYikgKiBzaXplb2YoUkdCUVVBRCkpICsgKEZyZWVJbWFnZV9HZXRQaXRjaChkaWIpICogRnJlZUltYWdlX0dldEhlaWdodChkaWIpKSA6IDA7Cn0KClJHQlFVQUQgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldFBhbGV0dGUoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIChkaWIgJiYgRnJlZUltYWdlX0dldEJQUChkaWIpIDwgMTYpID8gKFJHQlFVQUQgKikoKChCWVRFICopRnJlZUltYWdlX0dldEluZm9IZWFkZXIoZGliKSkgKyBzaXplb2YoQklUTUFQSU5GT0hFQURFUikpIDogTlVMTDsKfQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXREb3RzUGVyTWV0ZXJYKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiAoZGliKSA/IEZyZWVJbWFnZV9HZXRJbmZvSGVhZGVyKGRpYiktPmJpWFBlbHNQZXJNZXRlciA6IDA7Cn0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0RG90c1Blck1ldGVyWShGSUJJVE1BUCAqZGliKSB7CglyZXR1cm4gKGRpYikgPyBGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpLT5iaVlQZWxzUGVyTWV0ZXIgOiAwOwp9Cgp2b2lkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfU2V0RG90c1Blck1ldGVyWChGSUJJVE1BUCAqZGliLCB1bnNpZ25lZCByZXMpIHsKCWlmKGRpYikgewoJCUZyZWVJbWFnZV9HZXRJbmZvSGVhZGVyKGRpYiktPmJpWFBlbHNQZXJNZXRlciA9IHJlczsKCX0KfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX1NldERvdHNQZXJNZXRlclkoRklCSVRNQVAgKmRpYiwgdW5zaWduZWQgcmVzKSB7CglpZihkaWIpIHsKCQlGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpLT5iaVlQZWxzUGVyTWV0ZXIgPSByZXM7Cgl9Cn0KCkJJVE1BUElORk9IRUFERVIgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldEluZm9IZWFkZXIoRklCSVRNQVAgKmRpYikgewoJaWYoIWRpYikgewoJCXJldHVybiBOVUxMOwoJfQoJc2l6ZV90IGxwID0gKHNpemVfdClkaWItPmRhdGEgKyBzaXplb2YoRlJFRUlNQUdFSEVBREVSKTsKCWxwICs9IChscCAlIEZJQklUTUFQX0FMSUdOTUVOVCA/IEZJQklUTUFQX0FMSUdOTUVOVCAtIGxwICUgRklCSVRNQVBfQUxJR05NRU5UIDogMCk7CglscCArPSBGSUJJVE1BUF9BTElHTk1FTlQgLSBzaXplb2YoQklUTUFQSU5GT0hFQURFUikgJSBGSUJJVE1BUF9BTElHTk1FTlQ7CglyZXR1cm4gKEJJVE1BUElORk9IRUFERVIgKilscDsKfQoKQklUTUFQSU5GTyAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0SW5mbyhGSUJJVE1BUCAqZGliKSB7CglyZXR1cm4gKEJJVE1BUElORk8gKilGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBNZXRhZGF0YSByb3V0aW5lcwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpGSU1FVEFEQVRBICogRExMX0NBTExDT05WIApGcmVlSW1hZ2VfRmluZEZpcnN0TWV0YWRhdGEoRlJFRV9JTUFHRV9NRE1PREVMIG1vZGVsLCBGSUJJVE1BUCAqZGliLCBGSVRBRyAqKnRhZykgewoJaWYoIWRpYikgewoJCXJldHVybiBOVUxMOwoJfQoKCS8vIGdldCB0aGUgbWV0YWRhdGEgbW9kZWwKCU1FVEFEQVRBTUFQICptZXRhZGF0YSA9ICgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+bWV0YWRhdGE7CglUQUdNQVAgKnRhZ21hcCA9IE5VTEw7CglpZiggKCptZXRhZGF0YSkuZmluZChtb2RlbCkgIT0gKCptZXRhZGF0YSkuZW5kKCkgKSB7CgkJdGFnbWFwID0gKCptZXRhZGF0YSlbbW9kZWxdOwoJfQoJaWYodGFnbWFwKSB7CgkJLy8gYWxsb2NhdGUgYSBoYW5kbGUKCQlGSU1FVEFEQVRBIAkqaGFuZGxlID0gKEZJTUVUQURBVEEgKiltYWxsb2Moc2l6ZW9mKEZJTUVUQURBVEEpKTsKCQlpZihoYW5kbGUpIHsKCQkJLy8gY2FsY3VsYXRlIHRoZSBzaXplIG9mIGEgTUVUQURBVEFIRUFERVIKCQkJaW50IGhlYWRlcl9zaXplID0gc2l6ZW9mKE1FVEFEQVRBSEVBREVSKTsKCgkJCWhhbmRsZS0+ZGF0YSA9IChCWVRFICopbWFsbG9jKGhlYWRlcl9zaXplICogc2l6ZW9mKEJZVEUpKTsKCQkJCgkJCWlmKGhhbmRsZS0+ZGF0YSkgewoJCQkJbWVtc2V0KGhhbmRsZS0+ZGF0YSwgMCwgaGVhZGVyX3NpemUgKiBzaXplb2YoQllURSkpOwoKCQkJCS8vIHdyaXRlIG91dCB0aGUgTUVUQURBVEFIRUFERVIKCQkJCU1FVEFEQVRBSEVBREVSICptZGggPSAoTUVUQURBVEFIRUFERVIgKiloYW5kbGUtPmRhdGE7CgoJCQkJbWRoLT5wb3MgPSAxOwoJCQkJbWRoLT50YWdtYXAgPSB0YWdtYXA7CgoJCQkJLy8gZ2V0IHRoZSBmaXJzdCBlbGVtZW50CgkJCQlUQUdNQVA6Oml0ZXJhdG9yIGkgPSB0YWdtYXAtPmJlZ2luKCk7CgkJCQkqdGFnID0gKCppKS5zZWNvbmQ7CgoJCQkJcmV0dXJuIGhhbmRsZTsKCQkJfQoKCQkJZnJlZShoYW5kbGUpOwoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKQk9PTCBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9GaW5kTmV4dE1ldGFkYXRhKEZJTUVUQURBVEEgKm1kaGFuZGxlLCBGSVRBRyAqKnRhZykgewoJaWYoIW1kaGFuZGxlKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCU1FVEFEQVRBSEVBREVSICptZGggPSAoTUVUQURBVEFIRUFERVIgKiltZGhhbmRsZS0+ZGF0YTsKCVRBR01BUCAqdGFnbWFwID0gbWRoLT50YWdtYXA7CgoJaW50IGN1cnJlbnRfcG9zID0gbWRoLT5wb3M7CglpbnQgbWFwc2l6ZSAgICAgPSAoaW50KXRhZ21hcC0+c2l6ZSgpOwoKCWlmKGN1cnJlbnRfcG9zIDwgbWFwc2l6ZSkgewoJCS8vIGdldCB0aGUgdGFnIGVsZW1lbnQgYXQgcG9zaXRpb24gcG9zCgkJaW50IGNvdW50ID0gMDsKCgkJZm9yKFRBR01BUDo6aXRlcmF0b3IgaSA9IHRhZ21hcC0+YmVnaW4oKTsgaSAhPSB0YWdtYXAtPmVuZCgpOyBpKyspIHsKCQkJaWYoY291bnQgPT0gY3VycmVudF9wb3MpIHsKCQkJCSp0YWcgPSAoKmkpLnNlY29uZDsKCQkJCW1kaC0+cG9zKys7CgkJCQlicmVhazsKCQkJfQoJCQljb3VudCsrOwoJCX0KCQkKCQlyZXR1cm4gVFJVRTsKCX0KCglyZXR1cm4gRkFMU0U7Cn0KCnZvaWQgRExMX0NBTExDT05WIApGcmVlSW1hZ2VfRmluZENsb3NlTWV0YWRhdGEoRklNRVRBREFUQSAqbWRoYW5kbGUpIHsKCWlmIChOVUxMICE9IG1kaGFuZGxlKSB7CS8vIGRlbGV0ZSB0aGUgaGFuZGxlCgkJaWYgKE5VTEwgIT0gbWRoYW5kbGUtPmRhdGEpIHsKCQkJZnJlZShtZGhhbmRsZS0+ZGF0YSk7CgkJfQoJCWZyZWUobWRoYW5kbGUpOwkJLy8gLi4uIGFuZCB0aGUgd3JhcHBlcgoJfQp9CgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0Nsb25lTWV0YWRhdGEoRklCSVRNQVAgKmRzdCwgRklCSVRNQVAgKnNyYykgewoJaWYoIXNyYyB8fCAhZHN0KSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCS8vIGdldCBtZXRhZGF0YSBsaW5rcwoJTUVUQURBVEFNQVAgKnNyY19tZXRhZGF0YSA9ICgoRlJFRUlNQUdFSEVBREVSICopc3JjLT5kYXRhKS0+bWV0YWRhdGE7CglNRVRBREFUQU1BUCAqZHN0X21ldGFkYXRhID0gKChGUkVFSU1BR0VIRUFERVIgKilkc3QtPmRhdGEpLT5tZXRhZGF0YTsKCgkvLyBjb3B5IG1ldGFkYXRhIG1vZGVscywgKmV4Y2VwdCogdGhlIEZJTURfQU5JTUFUSU9OIG1vZGVsCglmb3IoTUVUQURBVEFNQVA6Oml0ZXJhdG9yIGkgPSAoKnNyY19tZXRhZGF0YSkuYmVnaW4oKTsgaSAhPSAoKnNyY19tZXRhZGF0YSkuZW5kKCk7IGkrKykgewoJCWludCBtb2RlbCA9ICgqaSkuZmlyc3Q7CgkJaWYobW9kZWwgPT0gKGludClGSU1EX0FOSU1BVElPTikgewoJCQljb250aW51ZTsKCQl9CgkJVEFHTUFQICpzcmNfdGFnbWFwID0gKCppKS5zZWNvbmQ7CgoJCWlmKHNyY190YWdtYXApIHsKCQkJaWYoIGRzdF9tZXRhZGF0YS0+ZmluZChtb2RlbCkgIT0gZHN0X21ldGFkYXRhLT5lbmQoKSApIHsKCQkJCS8vIGRlc3Ryb3kgZHN0IG1vZGVsCgkJCQlGcmVlSW1hZ2VfU2V0TWV0YWRhdGEoKEZSRUVfSU1BR0VfTURNT0RFTCltb2RlbCwgZHN0LCBOVUxMLCBOVUxMKTsKCQkJfQoKCQkJLy8gY3JlYXRlIGEgbWV0YWRhdGEgbW9kZWwKCQkJVEFHTUFQICpkc3RfdGFnbWFwID0gbmV3KHN0ZDo6bm90aHJvdykgVEFHTUFQKCk7CgoJCQlpZihkc3RfdGFnbWFwKSB7CgkJCQkvLyBmaWxsIHRoZSBtb2RlbAoJCQkJZm9yKFRBR01BUDo6aXRlcmF0b3IgaiA9IHNyY190YWdtYXAtPmJlZ2luKCk7IGogIT0gc3JjX3RhZ21hcC0+ZW5kKCk7IGorKykgewoJCQkJCXN0ZDo6c3RyaW5nIGRzdF9rZXkgPSAoKmopLmZpcnN0OwoJCQkJCUZJVEFHICpkc3RfdGFnID0gRnJlZUltYWdlX0Nsb25lVGFnKCAoKmopLnNlY29uZCApOwoKCQkJCQkvLyBhc3NpZ24ga2V5IGFuZCB0YWcgdmFsdWUKCQkJCQkoKmRzdF90YWdtYXApW2RzdF9rZXldID0gZHN0X3RhZzsKCQkJCX0KCgkJCQkvLyBhc3NpZ24gbW9kZWwgYW5kIHRhZ21hcAoJCQkJKCpkc3RfbWV0YWRhdGEpW21vZGVsXSA9IGRzdF90YWdtYXA7CgkJCX0KCQl9Cgl9CgoJLy8gY2xvbmUgcmVzb2x1dGlvbiAKCUZyZWVJbWFnZV9TZXREb3RzUGVyTWV0ZXJYKGRzdCwgRnJlZUltYWdlX0dldERvdHNQZXJNZXRlclgoc3JjKSk7IAoJRnJlZUltYWdlX1NldERvdHNQZXJNZXRlclkoZHN0LCBGcmVlSW1hZ2VfR2V0RG90c1Blck1ldGVyWShzcmMpKTsgCgoJcmV0dXJuIFRSVUU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkJPT0wgRExMX0NBTExDT05WIApGcmVlSW1hZ2VfU2V0TWV0YWRhdGEoRlJFRV9JTUFHRV9NRE1PREVMIG1vZGVsLCBGSUJJVE1BUCAqZGliLCBjb25zdCBjaGFyICprZXksIEZJVEFHICp0YWcpIHsKCWlmKCFkaWIpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJVEFHTUFQICp0YWdtYXAgPSBOVUxMOwoKCS8vIGdldCB0aGUgbWV0YWRhdGEgbW9kZWwKCU1FVEFEQVRBTUFQICptZXRhZGF0YSA9ICgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+bWV0YWRhdGE7CglNRVRBREFUQU1BUDo6aXRlcmF0b3IgbW9kZWxfaXRlcmF0b3IgPSBtZXRhZGF0YS0+ZmluZChtb2RlbCk7CglpZiAobW9kZWxfaXRlcmF0b3IgIT0gbWV0YWRhdGEtPmVuZCgpKSB7CgkJdGFnbWFwID0gbW9kZWxfaXRlcmF0b3ItPnNlY29uZDsKCX0KCglpZihrZXkgIT0gTlVMTCkgewoKCQlpZighdGFnbWFwKSB7CgkJCS8vIHRoaXMgbW9kZWwsIGRvZXNuJ3QgZXhpc3Q6IGNyZWF0ZSBpdCAKCQkJdGFnbWFwID0gbmV3KHN0ZDo6bm90aHJvdykgVEFHTUFQKCk7CgkJCSgqbWV0YWRhdGEpW21vZGVsXSA9IHRhZ21hcDsKCQl9CgkJCgkJaWYodGFnKSB7CgkJCS8vIGZpcnN0IGNoZWNrIHRoZSB0YWcKCQkJaWYoRnJlZUltYWdlX0dldFRhZ0tleSh0YWcpID09IE5VTEwpIHsKCQkJCUZyZWVJbWFnZV9TZXRUYWdLZXkodGFnLCBrZXkpOwoJCQl9IGVsc2UgaWYoc3RyY21wKGtleSwgRnJlZUltYWdlX0dldFRhZ0tleSh0YWcpKSAhPSAwKSB7CgkJCQkvLyBzZXQgdGhlIHRhZyBrZXkKCQkJCUZyZWVJbWFnZV9TZXRUYWdLZXkodGFnLCBrZXkpOwoJCQl9CgkJCWlmKEZyZWVJbWFnZV9HZXRUYWdDb3VudCh0YWcpICogRnJlZUltYWdlX1RhZ0RhdGFXaWR0aChGcmVlSW1hZ2VfR2V0VGFnVHlwZSh0YWcpKSAhPSBGcmVlSW1hZ2VfR2V0VGFnTGVuZ3RoKHRhZykpIHsKCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhGSUZfVU5LTk9XTiwgIkludmFsaWQgZGF0YSBjb3VudCBmb3IgdGFnICclcyciLCBrZXkpOwoJCQkJcmV0dXJuIEZBTFNFOwoJCQl9CgoJCQkvLyBmaWxsIHRoZSB0YWcgSUQgaWYgcG9zc2libGUgYW5kIGlmIGl0J3MgbmVlZGVkCgkJCVRhZ0xpYiYgdGFnX2xpYiA9IFRhZ0xpYjo6aW5zdGFuY2UoKTsKCQkJc3dpdGNoKG1vZGVsKSB7CgkJCQljYXNlIEZJTURfSVBUQzoKCQkJCXsKCQkJCQlpbnQgaWQgPSB0YWdfbGliLmdldFRhZ0lEKFRhZ0xpYjo6SVBUQywga2V5KTsKCQkJCQkvKgoJCQkJCWlmKGlkID09IC0xKSB7CgkJCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhGSUZfVU5LTk9XTiwgIklQVEM6IEludmFsaWQga2V5ICclcyciLCBrZXkpOwoJCQkJCX0KCQkJCQkqLwoJCQkJCUZyZWVJbWFnZV9TZXRUYWdJRCh0YWcsIChXT1JEKWlkKTsKCQkJCX0KCQkJCWJyZWFrOwoKCQkJCWRlZmF1bHQ6CgkJCQkJYnJlYWs7CgkJCX0KCgkJCS8vIGRlbGV0ZSBleGlzdGluZyB0YWcKCQkJRklUQUcgKm9sZF90YWcgPSAoKnRhZ21hcClba2V5XTsKCQkJaWYob2xkX3RhZykgewoJCQkJRnJlZUltYWdlX0RlbGV0ZVRhZyhvbGRfdGFnKTsKCQkJfQoKCQkJLy8gY3JlYXRlIGEgbmV3IHRhZwoJCQkoKnRhZ21hcClba2V5XSA9IEZyZWVJbWFnZV9DbG9uZVRhZyh0YWcpOwoJCX0KCQllbHNlIHsKCQkJLy8gZGVsZXRlIGV4aXN0aW5nIHRhZwoJCQlUQUdNQVA6Oml0ZXJhdG9yIGkgPSB0YWdtYXAtPmZpbmQoa2V5KTsKCQkJaWYoaSAhPSB0YWdtYXAtPmVuZCgpKSB7CgkJCQlGSVRBRyAqb2xkX3RhZyA9ICgqaSkuc2Vjb25kOwoJCQkJRnJlZUltYWdlX0RlbGV0ZVRhZyhvbGRfdGFnKTsKCQkJCXRhZ21hcC0+ZXJhc2Uoa2V5KTsKCQkJfQoJCX0KCX0KCWVsc2UgewoJCS8vIGRlc3Ryb3kgdGhlIG1ldGFkYXRhIG1vZGVsCgkJaWYodGFnbWFwKSB7CgkJCWZvcihUQUdNQVA6Oml0ZXJhdG9yIGkgPSB0YWdtYXAtPmJlZ2luKCk7IGkgIT0gdGFnbWFwLT5lbmQoKTsgaSsrKSB7CgkJCQlGSVRBRyAqdGFnID0gKCppKS5zZWNvbmQ7CgkJCQlGcmVlSW1hZ2VfRGVsZXRlVGFnKHRhZyk7CgkJCX0KCgkJCWRlbGV0ZSB0YWdtYXA7CgkJCW1ldGFkYXRhLT5lcmFzZShtb2RlbF9pdGVyYXRvcik7CgkJfQoJfQoKCXJldHVybiBUUlVFOwp9CgpCT09MIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX0dldE1ldGFkYXRhKEZSRUVfSU1BR0VfTURNT0RFTCBtb2RlbCwgRklCSVRNQVAgKmRpYiwgY29uc3QgY2hhciAqa2V5LCBGSVRBRyAqKnRhZykgewoJaWYoIWRpYiB8fCAha2V5IHx8ICF0YWcpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJVEFHTUFQICp0YWdtYXAgPSBOVUxMOwoJKnRhZyA9IE5VTEw7CgoJLy8gZ2V0IHRoZSBtZXRhZGF0YSBtb2RlbAoJTUVUQURBVEFNQVAgKm1ldGFkYXRhID0gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5tZXRhZGF0YTsKCWlmKCEoKm1ldGFkYXRhKS5lbXB0eSgpKSB7CgkJTUVUQURBVEFNQVA6Oml0ZXJhdG9yIG1vZGVsX2l0ZXJhdG9yID0gbWV0YWRhdGEtPmZpbmQobW9kZWwpOwoJCWlmIChtb2RlbF9pdGVyYXRvciAhPSBtZXRhZGF0YS0+ZW5kKCkgKSB7CgkJCS8vIHRoaXMgbW9kZWwgZXhpc3RzIDogdHJ5IHRvIGdldCB0aGUgcmVxdWVzdGVkIHRhZwoJCQl0YWdtYXAgPSBtb2RlbF9pdGVyYXRvci0+c2Vjb25kOwoJCQlUQUdNQVA6Oml0ZXJhdG9yIHRhZ19pdGVyYXRvciA9IHRhZ21hcC0+ZmluZChrZXkpOwoJCQlpZiAodGFnX2l0ZXJhdG9yICE9IHRhZ21hcC0+ZW5kKCkgKSB7CgkJCQkvLyBnZXQgdGhlIHJlcXVlc3RlZCB0YWcKCQkJCSp0YWcgPSB0YWdfaXRlcmF0b3ItPnNlY29uZDsKCQkJfSAKCQl9Cgl9CgoJcmV0dXJuICgqdGFnICE9IE5VTEwpID8gVFJVRSA6IEZBTFNFOwp9CgovKioKQnVpbGQgYW5kIHNldCBhIEZJVEFHIHdob3NlIHR5cGUgaXMgRklEVF9BU0NJSS4gCkBwYXJhbSBtb2RlbCBNZXRhZGF0YSBtb2RlbCB0byBiZSBmaWxsZWQKQHBhcmFtIGRpYiBJbWFnZSB0byBiZSBmaWxsZWQKQHBhcmFtIGtleSBUYWcga2V5CkBwYXJhbSB2YWx1ZSBUYWcgdmFsdWUgYXMgYSBBU0NJSSBzdHJpbmcKQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKKi8KQk9PTCBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9TZXRNZXRhZGF0YUtleVZhbHVlKEZSRUVfSU1BR0VfTURNT0RFTCBtb2RlbCwgRklCSVRNQVAgKmRpYiwgY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSkgewoJaWYoIWRpYiB8fCAha2V5IHx8ICF2YWx1ZSkgewoJCXJldHVybiBGQUxTRTsKCX0KCS8vIGNyZWF0ZSBhIHRhZwoJRklUQUcgKnRhZyA9IEZyZWVJbWFnZV9DcmVhdGVUYWcoKTsKCWlmKHRhZykgewoJCUJPT0wgYlN1Y2Nlc3MgPSBUUlVFOwoJCS8vIGZpbGwgdGhlIHRhZwoJCURXT1JEIHRhZ19sZW5ndGggPSAoRFdPUkQpKHN0cmxlbih2YWx1ZSkgKyAxKTsKCQliU3VjY2VzcyAmPSBGcmVlSW1hZ2VfU2V0VGFnS2V5KHRhZywga2V5KTsKCQliU3VjY2VzcyAmPSBGcmVlSW1hZ2VfU2V0VGFnTGVuZ3RoKHRhZywgdGFnX2xlbmd0aCk7CgkJYlN1Y2Nlc3MgJj0gRnJlZUltYWdlX1NldFRhZ0NvdW50KHRhZywgdGFnX2xlbmd0aCk7CgkJYlN1Y2Nlc3MgJj0gRnJlZUltYWdlX1NldFRhZ1R5cGUodGFnLCBGSURUX0FTQ0lJKTsKCQliU3VjY2VzcyAmPSBGcmVlSW1hZ2VfU2V0VGFnVmFsdWUodGFnLCB2YWx1ZSk7CgkJaWYoYlN1Y2Nlc3MpIHsKCQkJLy8gc2V0IHRoZSB0YWcKCQkJYlN1Y2Nlc3MgJj0gRnJlZUltYWdlX1NldE1ldGFkYXRhKG1vZGVsLCBkaWIsIEZyZWVJbWFnZV9HZXRUYWdLZXkodGFnKSwgdGFnKTsKCQl9CgkJLy8gZGVsZXRlIHRoZSB0YWcKCQlGcmVlSW1hZ2VfRGVsZXRlVGFnKHRhZyk7CgoJCXJldHVybiBiU3VjY2VzczsKCX0KCglyZXR1cm4gRkFMU0U7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnVuc2lnbmVkIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX0dldE1ldGFkYXRhQ291bnQoRlJFRV9JTUFHRV9NRE1PREVMIG1vZGVsLCBGSUJJVE1BUCAqZGliKSB7CglpZighZGliKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCVRBR01BUCAqdGFnbWFwID0gTlVMTDsKCgkvLyBnZXQgdGhlIG1ldGFkYXRhIG1vZGVsCglNRVRBREFUQU1BUCAqbWV0YWRhdGEgPSAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPm1ldGFkYXRhOwoJaWYoICgqbWV0YWRhdGEpLmZpbmQobW9kZWwpICE9ICgqbWV0YWRhdGEpLmVuZCgpICkgewoJCXRhZ21hcCA9ICgqbWV0YWRhdGEpW21vZGVsXTsKCX0KCWlmKCF0YWdtYXApIHsKCQkvLyB0aGlzIG1vZGVsLCBkb2Vzbid0IGV4aXN0OiByZXR1cm4KCQlyZXR1cm4gMDsKCX0KCgkvLyBnZXQgdGhlIHRhZyBjb3VudAoJcmV0dXJuICh1bnNpZ25lZCl0YWdtYXAtPnNpemUoKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRNZW1vcnlTaXplKEZJQklUTUFQICpkaWIpIHsKCWlmICghZGliKSB7CgkJcmV0dXJuIDA7Cgl9CglGUkVFSU1BR0VIRUFERVIgKmhlYWRlciA9IChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGE7CglCSVRNQVBJTkZPSEVBREVSICpiaWggPSBGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpOwoKCUJPT0wgaGVhZGVyX29ubHkgPSAhaGVhZGVyLT5oYXNfcGl4ZWxzIHx8IGhlYWRlci0+ZXh0ZXJuYWxfYml0cyAhPSBOVUxMOwoJQk9PTCBuZWVkX21hc2tzID0gYmloLT5iaUNvbXByZXNzaW9uID09IEJJX0JJVEZJRUxEUzsKCXVuc2lnbmVkIHdpZHRoID0gYmloLT5iaVdpZHRoOwoJdW5zaWduZWQgaGVpZ2h0ID0gYmloLT5iaUhlaWdodDsKCXVuc2lnbmVkIGJwcCA9IGJpaC0+YmlCaXRDb3VudDsKCQoJLy8gc3RhcnQgb2ZmIHdpdGggdGhlIHNpemUgb2YgdGhlIEZJQklUTUFQIHN0cnVjdHVyZQoJc2l6ZV90IHNpemUgPSBzaXplb2YoRklCSVRNQVApOwoJCgkvLyBhZGQgc2l6ZXMgb2YgRlJFRUlNQUdFSEVBREVSLCBCSVRNQVBJTkZPSEVBREVSLCBwYWxldHRlIGFuZCBESUIgZGF0YQoJc2l6ZSArPSBGcmVlSW1hZ2VfR2V0SW50ZXJuYWxJbWFnZVNpemUoaGVhZGVyX29ubHksIHdpZHRoLCBoZWlnaHQsIGJwcCwgbmVlZF9tYXNrcyk7CgoJLy8gYWRkIElDQyBwcm9maWxlIHNpemUKCXNpemUgKz0gaGVhZGVyLT5pY2NQcm9maWxlLnNpemU7CgoJLy8gYWRkIHRodW1ibmFpbCBpbWFnZSBzaXplCglpZiAoaGVhZGVyLT50aHVtYm5haWwpIHsKCQkvLyB3ZSBhc3N1bWUgYSB0aHVtYm5haWwgbm90IGhhdmluZyBhIHRodW1ibmFpbCBhcyB3ZWxsLCAKCQkvLyBzbyB0aGlzIHJlY3Vyc2l2ZSBjYWxsIHNob3VsZCBub3QgY3JlYXRlIGFuIGluZmluaXRlIGxvb3AKCQlzaXplICs9IEZyZWVJbWFnZV9HZXRNZW1vcnlTaXplKGhlYWRlci0+dGh1bWJuYWlsKTsKCX0KCgkvLyBhZGQgbWV0YWRhdGEgc2l6ZQoJTUVUQURBVEFNQVAgKm1kID0gaGVhZGVyLT5tZXRhZGF0YTsKCWlmICghbWQpIHsKCQlyZXR1cm4gKHVuc2lnbmVkKXNpemU7Cgl9CgoJLy8gYWRkIHNpemUgb2YgTUVUQURBVEFNQVAKCXNpemUgKz0gc2l6ZW9mKE1FVEFEQVRBTUFQKTsKCgljb25zdCBzaXplX3QgbW9kZWxzID0gbWQtPnNpemUoKTsKCWlmIChtb2RlbHMgPT0gMCkgewoJCXJldHVybiAodW5zaWduZWQpc2l6ZTsKCX0KCgl1bnNpZ25lZCB0YWdzID0gMDsKCglmb3IgKE1FVEFEQVRBTUFQOjppdGVyYXRvciBpID0gbWQtPmJlZ2luKCk7IGkgIT0gbWQtPmVuZCgpOyBpKyspIHsKCQlUQUdNQVAgKnRtID0gaS0+c2Vjb25kOwoJCWlmICh0bSkgewoJCQlmb3IgKFRBR01BUDo6aXRlcmF0b3IgaiA9IHRtLT5iZWdpbigpOyBqICE9IHRtLT5lbmQoKTsgaisrKSB7CgkJCQkrK3RhZ3M7CgkJCQljb25zdCBzdGQ6OnN0cmluZyAmIGtleSA9IGotPmZpcnN0OwoJCQkJc2l6ZSArPSBrZXkuY2FwYWNpdHkoKTsKCQkJCXNpemUgKz0gRnJlZUltYWdlX0dldFRhZ01lbW9yeVNpemUoai0+c2Vjb25kKTsKCQkJfQoJCX0KCX0KCgkvLyBhZGQgc2l6ZSBvZiBhbGwgVEFHTUFQIGluc3RhbmNlcwoJc2l6ZSArPSBtb2RlbHMgKiBzaXplb2YoVEFHTUFQKTsKCS8vIGFkZCBzaXplIG9mIHRyZWUgbm9kZXMgaW4gTUVUQURBVEFNQVAKCXNpemUgKz0gTWFwSW50cm9zcGVjdG9yPE1FVEFEQVRBTUFQPjo6R2V0Tm9kZXNNZW1vcnlTaXplKG1vZGVscyk7CgkvLyBhZGQgc2l6ZSBvZiB0cmVlIG5vZGVzIGluIFRBR01BUAoJc2l6ZSArPSBNYXBJbnRyb3NwZWN0b3I8VEFHTUFQPjo6R2V0Tm9kZXNNZW1vcnlTaXplKHRhZ3MpOwoKCXJldHVybiAodW5zaWduZWQpc2l6ZTsKfQoK