Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBGcmVlSW1hZ2UgaW1wbGVtZW50YXRpb24KLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEZsb3JpcyB2YW4gZGVuIEJlcmcgKGZsdmRiZXJnQHd4cy5ubCkKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLyAtIERldGxldiBWZW5kdCAoZGV0bGV2LnZlbmR0QGJyaWxsaXQuZGUpCi8vIC0gUGV0ciBTdXBpbmEgKHBzdXBAY2VudHJ1bS5jeikKLy8gLSBDYXJzdGVuIEtsZWluIChjLmtsZWluQGRhdGFnaXMuY29tKQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZmRlZiBfTVNDX1ZFUiAKI3ByYWdtYSB3YXJuaW5nIChkaXNhYmxlIDogNDc4NikgLy8gaWRlbnRpZmllciB3YXMgdHJ1bmNhdGVkIHRvICdudW1iZXInIGNoYXJhY3RlcnMKI2VuZGlmIAoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaWYgZGVmaW5lZChfV0lOMzIpIHx8IGRlZmluZWQoX1dJTjY0KSB8fCBkZWZpbmVkKF9fTUlOR1czMl9fKQojaW5jbHVkZSA8bWFsbG9jLmg+CiNlbmRpZiAvLyBfV0lOMzIgfHwgX1dJTjY0IHx8IF9fTUlOR1czMl9fCgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJGcmVlSW1hZ2VJTy5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCgojaW5jbHVkZSAiLi4vTWV0YWRhdGEvRnJlZUltYWdlVGFnLmgiCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBNZXRhZGF0YSBkZWZpbml0aW9ucwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovLyBoZWxwZXIgZm9yIG1hcDxrZXksIHZhbHVlPiB3aGVyZSB2YWx1ZSBpcyBhIHBvaW50ZXIgdG8gYSBGcmVlSW1hZ2UgdGFnCnR5cGVkZWYgc3RkOjptYXA8c3RkOjpzdHJpbmcsIEZJVEFHKj4gVEFHTUFQOwoKLy8gaGVscGVyIGZvciBtYXA8RlJFRV9JTUFHRV9NRE1PREVMLCBUQUdNQVAqPgp0eXBlZGVmIHN0ZDo6bWFwPGludCwgVEFHTUFQKj4gTUVUQURBVEFNQVA7CgovLyBoZWxwZXIgZm9yIG1ldGFkYXRhIGl0ZXJhdG9yCkZJX1NUUlVDVCAoTUVUQURBVEFIRUFERVIpIHsgCglsb25nIHBvczsJCS8vIGN1cnJlbnQgcG9zaXRpb24gd2hlbiBpdGVyYXRpbmcgdGhlIG1hcAoJVEFHTUFQICp0YWdtYXA7CS8vIHBvaW50ZXIgdG8gdGhlIHRhZyBtYXAKfTsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gIEZJQklUTUFQIGRlZmluaXRpb24KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRklfU1RSVUNUIChGUkVFSU1BR0VIRUFERVIpIHsKICAgIEZSRUVfSU1BR0VfVFlQRSB0eXBlOwkJLy8gZGF0YSB0eXBlIC0gYml0bWFwLCBhcnJheSBvZiBsb25nLCBkb3VibGUsIGNvbXBsZXgsIGV0YwoKCXVuc2lnbmVkIHJlZF9tYXNrOwkJCS8vIGJpdCBsYXlvdXQgb2YgdGhlIHJlZCBjb21wb25lbnRzCgl1bnNpZ25lZCBncmVlbl9tYXNrOwkJLy8gYml0IGxheW91dCBvZiB0aGUgZ3JlZW4gY29tcG9uZW50cwoJdW5zaWduZWQgYmx1ZV9tYXNrOwkJCS8vIGJpdCBsYXlvdXQgb2YgdGhlIGJsdWUgY29tcG9uZW50cwoKCVJHQlFVQUQgYmtnbmRfY29sb3I7CQkvLyBiYWNrZ3JvdW5kIGNvbG9yIHVzZWQgZm9yIFJHQiB0cmFuc3BhcmVuY3kKCglCT09MIHRyYW5zcGFyZW50OwkJCSAvLyB3aHkgYW5vdGhlciB0YWJsZT8gZm9yIGVhc3kgdHJhbnNwYXJlbmN5IHRhYmxlIHJldHJpZXZhbCEKCWludCAgdHJhbnNwYXJlbmN5X2NvdW50OwkgLy8gdHJhbnNwYXJlbmN5IGNvdWxkIGJlIHN0b3JlZCBpbiB0aGUgcGFsZXR0ZSwgd2hpY2ggaXMgYmV0dGVyCglCWVRFIHRyYW5zcGFyZW50X3RhYmxlWzI1Nl07IC8vIG92ZXJhbGwsIGJ1dCBpdCByZXF1aXJlcyBxdWl0ZSBzb21lIGNoYW5nZXMgYW5kIGl0IHdpbGwgcmVuZGVyCgkJCQkJCQkJIC8vIEZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lUYWJsZSBvYnNvbGV0ZSBpbiBpdHMgY3VycmVudCBmb3JtOwoJRklJQ0NQUk9GSUxFIGljY1Byb2ZpbGU7CSAvLyBzcGFjZSB0byBob2xkIElDQyBwcm9maWxlCgoJTUVUQURBVEFNQVAgKm1ldGFkYXRhOwkJIC8vIGNvbnRhaW5zIGEgbGlzdCBvZiBtZXRhZGF0YSBtb2RlbHMgYXR0YWNoZWQgdG8gdGhlIGJpdG1hcAoKCS8vQllURSBmaWxsZXJbMV07CQkJIC8vIGZpbGwgdG8gMzItYml0IGFsaWdubWVudAp9OwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgTWVtb3J5IGFsbG9jYXRpb24gb24gYSBzcGVjaWZpZWQgYWxpZ25tZW50IGJvdW5kYXJ5Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNpZiAoZGVmaW5lZChfV0lOMzIpIHx8IGRlZmluZWQoX1dJTjY0KSkgJiYgIWRlZmluZWQoX19NSU5HVzMyX18pCgp2b2lkKiBGcmVlSW1hZ2VfQWxpZ25lZF9NYWxsb2Moc2l6ZV90IGFtb3VudCwgc2l6ZV90IGFsaWdubWVudCkgewoJYXNzZXJ0KGFsaWdubWVudCA9PSBGSUJJVE1BUF9BTElHTk1FTlQpOwoJcmV0dXJuIF9hbGlnbmVkX21hbGxvYyhhbW91bnQsIGFsaWdubWVudCk7Cn0KCnZvaWQgRnJlZUltYWdlX0FsaWduZWRfRnJlZSh2b2lkKiBtZW0pIHsKCV9hbGlnbmVkX2ZyZWUobWVtKTsKfQoKI2VsaWYgZGVmaW5lZCAoX19NSU5HVzMyX18pCgp2b2lkKiBGcmVlSW1hZ2VfQWxpZ25lZF9NYWxsb2Moc2l6ZV90IGFtb3VudCwgc2l6ZV90IGFsaWdubWVudCkgewoJYXNzZXJ0KGFsaWdubWVudCA9PSBGSUJJVE1BUF9BTElHTk1FTlQpOwoJcmV0dXJuIF9fbWluZ3dfYWxpZ25lZF9tYWxsb2MgKGFtb3VudCwgYWxpZ25tZW50KTsKfQoKdm9pZCBGcmVlSW1hZ2VfQWxpZ25lZF9GcmVlKHZvaWQqIG1lbSkgewoJX19taW5nd19hbGlnbmVkX2ZyZWUgKG1lbSk7Cn0KCiNlbHNlCgp2b2lkKiBGcmVlSW1hZ2VfQWxpZ25lZF9NYWxsb2Moc2l6ZV90IGFtb3VudCwgc2l6ZV90IGFsaWdubWVudCkgewoJYXNzZXJ0KGFsaWdubWVudCA9PSBGSUJJVE1BUF9BTElHTk1FTlQpOwoJLyoKCUluIHNvbWUgcmFyZSBzaXR1YXRpb25zLCB0aGUgbWFsbG9jIHJvdXRpbmVzIGNhbiByZXR1cm4gbWlzYWxpZ25lZCBtZW1vcnkuIAoJVGhlIHJvdXRpbmUgRnJlZUltYWdlX0FsaWduZWRfTWFsbG9jIGFsbG9jYXRlcyBhIGJpdCBtb3JlIG1lbW9yeSB0byBkbwoJYWxpZ25lZCB3cml0ZXMuICBOb3JtYWxseSwgaXQgKnNob3VsZCogYWxsb2NhdGUgImFsaWdubWVudCIgZXh0cmEgbWVtb3J5IGFuZCB0aGVuIHdyaXRlcwoJb25lIGR3b3JkIGJhY2sgdGhlIHRydWUgcG9pbnRlci4gIEJ1dCBpZiB0aGUgbWVtb3J5IG1hbmFnZXIgcmV0dXJucyBhCgltaXNhbGlnbmVkIGJsb2NrIHRoYXQgaXMgbGVzcyB0aGFuIGEgZHdvcmQgZnJvbSB0aGUgbmV4dCBhbGlnbm1lbnQsIAoJdGhlbiB0aGUgd3JpdGluZyBiYWNrIG9uZSBkd29yZCB3aWxsIGNvcnJ1cHQgbWVtb3J5LgoKCUZvciBleGFtcGxlLCBzdXBwb3NlIHRoYXQgYWxpZ25tZW50IGlzIDE2IGFuZCBtYWxsb2MgcmV0dXJucyB0aGUgYWRkcmVzcyAweEZGRkYuCgoJMTYgLSAweEZGRkYgJSAxNiArIDB4RkZGRiA9IDE2IC0gMTUgKyAweEZGRkYgPSAweDEwMDAwLgoKCU5vdywgeW91IHN1YnRyYWN0IG9uZSBkd29yZCBmcm9tIHRoYXQgYW5kIHdyaXRlIGFuZCB0aGF0IHdpbGwgY29ycnVwdCBtZW1vcnkuCgoJVGhhdCdzIHdoeSB0aGUgY29kZSBiZWxvdyBhbGxvY2F0ZXMgKnR3byogYWxpZ25tZW50cyBpbnN0ZWFkIG9mIG9uZS4gCgkqLwoJdm9pZCogbWVtX3JlYWwgPSBtYWxsb2MoYW1vdW50ICsgMiAqIGFsaWdubWVudCk7CglpZighbWVtX3JlYWwpIHJldHVybiBOVUxMOwoJY2hhciogbWVtX2FsaWduID0gKGNoYXIqKSgodW5zaWduZWQgbG9uZykoMiAqIGFsaWdubWVudCAtICh1bnNpZ25lZCBsb25nKW1lbV9yZWFsICUgKHVuc2lnbmVkIGxvbmcpYWxpZ25tZW50KSArICh1bnNpZ25lZCBsb25nKW1lbV9yZWFsKTsKCSooKGxvbmcqKW1lbV9hbGlnbiAtIDEpID0gKGxvbmcpbWVtX3JlYWw7CglyZXR1cm4gbWVtX2FsaWduOwp9Cgp2b2lkIEZyZWVJbWFnZV9BbGlnbmVkX0ZyZWUodm9pZCogbWVtKSB7CglmcmVlKCh2b2lkKikqKChsb25nKiltZW0gLSAxKSk7Cn0KCiNlbmRpZiAvLyBfV0lOMzIgfHwgX1dJTjY0CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBESUIgaW5mb3JtYXRpb24gZnVuY3Rpb25zCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgpDYWxjdWxhdGUgdGhlIHNpemUgb2YgYSBGcmVlSW1hZ2UgaW1hZ2UuIApBbGlnbiB0aGUgcGFsZXR0ZSBhbmQgdGhlIHBpeGVscyBvbiBhIEZJQklUTUFQX0FMSUdOTUVOVCBieXRlcyBhbGlnbm1lbnQgYm91bmRhcnkuCiovCnN0YXRpYyB1bnNpZ25lZCAKRnJlZUltYWdlX0dldEltYWdlU2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBicHApIHsKCXVuc2lnbmVkIGRpYl9zaXplID0gc2l6ZW9mKEZSRUVJTUFHRUhFQURFUik7IAoJZGliX3NpemUgKz0gKGRpYl9zaXplICUgRklCSVRNQVBfQUxJR05NRU5UID8gRklCSVRNQVBfQUxJR05NRU5UIC0gZGliX3NpemUgJSBGSUJJVE1BUF9BTElHTk1FTlQgOiAwKTsgIAoJZGliX3NpemUgKz0gRklCSVRNQVBfQUxJR05NRU5UIC0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICUgRklCSVRNQVBfQUxJR05NRU5UOyAKCWRpYl9zaXplICs9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKTsgIAoJLy8gcGFsZXR0ZSBpcyBhbGlnbmVkIG9uIGEgMTYgYnl0ZXMgYm91bmRhcnkKCWRpYl9zaXplICs9IHNpemVvZihSR0JRVUFEKSAqIENhbGN1bGF0ZVVzZWRQYWxldHRlRW50cmllcyhicHApOyAgCglkaWJfc2l6ZSArPSAoZGliX3NpemUgJSBGSUJJVE1BUF9BTElHTk1FTlQgPyBGSUJJVE1BUF9BTElHTk1FTlQgLSBkaWJfc2l6ZSAlIEZJQklUTUFQX0FMSUdOTUVOVCA6IDApOyAgCgkvLyBwaXhlbHMgYXJlIGFsaWduZWQgb24gYSAxNiBieXRlcyBib3VuZGFyeQoJZGliX3NpemUgKz0gQ2FsY3VsYXRlUGl0Y2goQ2FsY3VsYXRlTGluZSh3aWR0aCwgYnBwKSkgKiBoZWlnaHQ7IAoKCXJldHVybiBkaWJfc2l6ZTsKfQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0FsbG9jYXRlKGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGJwcCwgdW5zaWduZWQgcmVkX21hc2ssIHVuc2lnbmVkIGdyZWVuX21hc2ssIHVuc2lnbmVkIGJsdWVfbWFzaykgewoJcmV0dXJuIEZyZWVJbWFnZV9BbGxvY2F0ZVQoRklUX0JJVE1BUCwgd2lkdGgsIGhlaWdodCwgYnBwLCByZWRfbWFzaywgZ3JlZW5fbWFzaywgYmx1ZV9tYXNrKTsKfQoKRklCSVRNQVAgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0FsbG9jYXRlVChGUkVFX0lNQUdFX1RZUEUgdHlwZSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgYnBwLCB1bnNpZ25lZCByZWRfbWFzaywgdW5zaWduZWQgZ3JlZW5fbWFzaywgdW5zaWduZWQgYmx1ZV9tYXNrKSB7CglGSUJJVE1BUCAqYml0bWFwID0gKEZJQklUTUFQICopbWFsbG9jKHNpemVvZihGSUJJVE1BUCkpOwoKCWlmIChiaXRtYXAgIT0gTlVMTCkgewoJCWhlaWdodCA9IGFicyhoZWlnaHQpOwoKCQkvLyBjaGVjayBwaXhlbCBiaXQgZGVwdGgKCQlzd2l0Y2godHlwZSkgewoJCQljYXNlIEZJVF9CSVRNQVA6CgkJCQlzd2l0Y2goYnBwKSB7CgkJCQkJY2FzZSAxOgoJCQkJCWNhc2UgNDoKCQkJCQljYXNlIDg6CgkJCQkJY2FzZSAxNjoKCQkJCQljYXNlIDI0OgoJCQkJCWNhc2UgMzI6CgkJCQkJCWJyZWFrOwoJCQkJCWRlZmF1bHQ6CgkJCQkJCWJwcCA9IDg7CgkJCQkJCWJyZWFrOwoJCQkJfQoJCQkJYnJlYWs7CgkJCWNhc2UgRklUX1VJTlQxNjoKCQkJCWJwcCA9IDggKiBzaXplb2YodW5zaWduZWQgc2hvcnQpOwoJCQkJYnJlYWs7CgkJCWNhc2UgRklUX0lOVDE2OgoJCQkJYnBwID0gOCAqIHNpemVvZihzaG9ydCk7CgkJCQlicmVhazsKCQkJY2FzZSBGSVRfVUlOVDMyOgoJCQkJYnBwID0gOCAqIHNpemVvZih1bnNpZ25lZCBsb25nKTsKCQkJCWJyZWFrOwoJCQljYXNlIEZJVF9JTlQzMjoKCQkJCWJwcCA9IDggKiBzaXplb2YobG9uZyk7CgkJCQlicmVhazsKCQkJY2FzZSBGSVRfRkxPQVQ6CgkJCQlicHAgPSA4ICogc2l6ZW9mKGZsb2F0KTsKCQkJCWJyZWFrOwoJCQljYXNlIEZJVF9ET1VCTEU6CgkJCQlicHAgPSA4ICogc2l6ZW9mKGRvdWJsZSk7CgkJCQlicmVhazsKCQkJY2FzZSBGSVRfQ09NUExFWDoKCQkJCWJwcCA9IDggKiBzaXplb2YoRklDT01QTEVYKTsKCQkJCWJyZWFrOwoJCQljYXNlIEZJVF9SR0IxNjoKCQkJCWJwcCA9IDggKiBzaXplb2YoRklSR0IxNik7CgkJCQlicmVhazsKCQkJY2FzZSBGSVRfUkdCQTE2OgoJCQkJYnBwID0gOCAqIHNpemVvZihGSVJHQkExNik7CgkJCQlicmVhazsKCQkJY2FzZSBGSVRfUkdCRjoKCQkJCWJwcCA9IDggKiBzaXplb2YoRklSR0JGKTsKCQkJCWJyZWFrOwoJCQljYXNlIEZJVF9SR0JBRjoKCQkJCWJwcCA9IDggKiBzaXplb2YoRklSR0JBRik7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWZyZWUoYml0bWFwKTsKCQkJCXJldHVybiBOVUxMOwoJCX0KCgkJLy8gY2FsY3VsYXRlIHRoZSBzaXplIG9mIGEgRnJlZUltYWdlIGltYWdlCgkJLy8gYWxpZ24gdGhlIHBhbGV0dGUgYW5kIHRoZSBwaXhlbHMgb24gYSBGSUJJVE1BUF9BTElHTk1FTlQgYnl0ZXMgYWxpZ25tZW50IGJvdW5kYXJ5CgkJLy8gcGFsZXR0ZSBpcyBhbGlnbmVkIG9uIGEgMTYgYnl0ZXMgYm91bmRhcnkKCQkvLyBwaXhlbHMgYXJlIGFsaWduZWQgb24gYSAxNiBieXRlcyBib3VuZGFyeQoKCQl1bnNpZ25lZCBkaWJfc2l6ZSA9IEZyZWVJbWFnZV9HZXRJbWFnZVNpemUod2lkdGgsIGhlaWdodCwgYnBwKTsgCgoJCWJpdG1hcC0+ZGF0YSA9IChCWVRFICopRnJlZUltYWdlX0FsaWduZWRfTWFsbG9jKGRpYl9zaXplICogc2l6ZW9mKEJZVEUpLCBGSUJJVE1BUF9BTElHTk1FTlQpOwoKCQlpZiAoYml0bWFwLT5kYXRhICE9IE5VTEwpIHsKCQkJbWVtc2V0KGJpdG1hcC0+ZGF0YSwgMCwgZGliX3NpemUpOwoKCQkJLy8gd3JpdGUgb3V0IHRoZSBGUkVFSU1BR0VIRUFERVIKCgkJCUZSRUVJTUFHRUhFQURFUiAqZmloICAgID0gKEZSRUVJTUFHRUhFQURFUiAqKWJpdG1hcC0+ZGF0YTsKCQkJZmloLT50eXBlCQkJCT0gdHlwZTsKCgkJCWZpaC0+cmVkX21hc2sgICAgICAgICAgID0gcmVkX21hc2s7CgkJCWZpaC0+Z3JlZW5fbWFzayAgICAgICAgID0gZ3JlZW5fbWFzazsKCQkJZmloLT5ibHVlX21hc2sgICAgICAgICAgPSBibHVlX21hc2s7CgoJCQltZW1zZXQoJmZpaC0+YmtnbmRfY29sb3IsIDAsIHNpemVvZihSR0JRVUFEKSk7CgoJCQlmaWgtPnRyYW5zcGFyZW50ICAgICAgICA9IEZBTFNFOwoJCQlmaWgtPnRyYW5zcGFyZW5jeV9jb3VudCA9IDA7CgkJCW1lbXNldChmaWgtPnRyYW5zcGFyZW50X3RhYmxlLCAweGZmLCAyNTYpOwoKCQkJLy8gaW5pdGlhbGl6ZSBGSUlDQ1BST0ZJTEUgbGluawoKCQkJRklJQ0NQUk9GSUxFICppY2NQcm9maWxlID0gRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUoYml0bWFwKTsKCQkJaWNjUHJvZmlsZS0+c2l6ZQkJPSAwOwoJCQlpY2NQcm9maWxlLT5kYXRhCQk9IDA7CgkJCWljY1Byb2ZpbGUtPmZsYWdzCQk9IDA7CgoJCQkvLyBpbml0aWFsaXplIG1ldGFkYXRhIG1vZGVscyBsaXN0CgoJCQlmaWgtPm1ldGFkYXRhID0gbmV3IE1FVEFEQVRBTUFQOwoKCQkJLy8gd3JpdGUgb3V0IHRoZSBCSVRNQVBJTkZPSEVBREVSCgoJCQlCSVRNQVBJTkZPSEVBREVSICpiaWggICA9IEZyZWVJbWFnZV9HZXRJbmZvSGVhZGVyKGJpdG1hcCk7CgkJCWJpaC0+YmlTaXplICAgICAgICAgICAgID0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpOwoJCQliaWgtPmJpV2lkdGggICAgICAgICAgICA9IHdpZHRoOwoJCQliaWgtPmJpSGVpZ2h0ICAgICAgICAgICA9IGhlaWdodDsKCQkJYmloLT5iaVBsYW5lcyAgICAgICAgICAgPSAxOwoJCQliaWgtPmJpQ29tcHJlc3Npb24gICAgICA9IDA7CgkJCWJpaC0+YmlCaXRDb3VudCAgICAgICAgID0gKFdPUkQpYnBwOwoJCQliaWgtPmJpQ2xyVXNlZCAgICAgICAgICA9IENhbGN1bGF0ZVVzZWRQYWxldHRlRW50cmllcyhicHApOwoJCQliaWgtPmJpQ2xySW1wb3J0YW50ICAgICA9IGJpaC0+YmlDbHJVc2VkOwoJCQliaWgtPmJpWFBlbHNQZXJNZXRlcgk9IDI4MzU7CS8vIDcyIGRwaQoJCQliaWgtPmJpWVBlbHNQZXJNZXRlcgk9IDI4MzU7CS8vIDcyIGRwaQoKCQkJcmV0dXJuIGJpdG1hcDsKCQl9CgoJCWZyZWUoYml0bWFwKTsKCX0KCglyZXR1cm4gTlVMTDsKfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX1VubG9hZChGSUJJVE1BUCAqZGliKSB7CglpZiAoTlVMTCAhPSBkaWIpIHsJCgkJaWYgKE5VTEwgIT0gZGliLT5kYXRhKSB7CgkJCS8vIGRlbGV0ZSBwb3NzaWJsZSBpY2MgcHJvZmlsZSAuLi4KCQkJaWYgKEZyZWVJbWFnZV9HZXRJQ0NQcm9maWxlKGRpYiktPmRhdGEpCgkJCQlmcmVlKEZyZWVJbWFnZV9HZXRJQ0NQcm9maWxlKGRpYiktPmRhdGEpOwoKCQkJLy8gZGVsZXRlIG1ldGFkYXRhIG1vZGVscwoJCQlNRVRBREFUQU1BUCAqbWV0YWRhdGEgPSAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPm1ldGFkYXRhOwoKCQkJZm9yKE1FVEFEQVRBTUFQOjppdGVyYXRvciBpID0gKCptZXRhZGF0YSkuYmVnaW4oKTsgaSAhPSAoKm1ldGFkYXRhKS5lbmQoKTsgaSsrKSB7CgkJCQlUQUdNQVAgKnRhZ21hcCA9ICgqaSkuc2Vjb25kOwoKCQkJCWlmKHRhZ21hcCkgewoJCQkJCWZvcihUQUdNQVA6Oml0ZXJhdG9yIGogPSB0YWdtYXAtPmJlZ2luKCk7IGogIT0gdGFnbWFwLT5lbmQoKTsgaisrKSB7CgkJCQkJCUZJVEFHICp0YWcgPSAoKmopLnNlY29uZDsKCQkJCQkJRnJlZUltYWdlX0RlbGV0ZVRhZyh0YWcpOwoJCQkJCX0KCgkJCQkJZGVsZXRlIHRhZ21hcDsKCQkJCX0KCQkJfQoKCQkJZGVsZXRlIG1ldGFkYXRhOwoKCQkJLy8gZGVsZXRlIGJpdG1hcCAuLi4KCQkJRnJlZUltYWdlX0FsaWduZWRfRnJlZShkaWItPmRhdGEpOwoJCX0KCQlmcmVlKGRpYik7CQkvLyAuLi4gYW5kIHRoZSB3cmFwcGVyCgl9Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZJQklUTUFQICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9DbG9uZShGSUJJVE1BUCAqZGliKSB7CglpZighZGliKSByZXR1cm4gTlVMTDsKCgl1bnNpZ25lZCB3aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCXVuc2lnbmVkIGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKTsKCXVuc2lnbmVkIGJwcCAgICA9IEZyZWVJbWFnZV9HZXRCUFAoZGliKTsKCQoJLy8gYWxsb2NhdGUgYSBuZXcgZGliCglGSUJJVE1BUCAqbmV3X2RpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpLCB3aWR0aCwgaGVpZ2h0LCBicHAsIAoJCQlGcmVlSW1hZ2VfR2V0UmVkTWFzayhkaWIpLCBGcmVlSW1hZ2VfR2V0R3JlZW5NYXNrKGRpYiksIEZyZWVJbWFnZV9HZXRCbHVlTWFzayhkaWIpKTsKCglpZiAobmV3X2RpYikgewoJCS8vIHNhdmUgSUNDIHByb2ZpbGUgbGlua3MKCQlGSUlDQ1BST0ZJTEUgKnNyY19pY2NQcm9maWxlID0gRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUoZGliKTsKCQlGSUlDQ1BST0ZJTEUgKmRzdF9pY2NQcm9maWxlID0gRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUobmV3X2RpYik7CgoJCS8vIHNhdmUgbWV0YWRhdGEgbGlua3MKCQlNRVRBREFUQU1BUCAqc3JjX21ldGFkYXRhID0gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5tZXRhZGF0YTsKCQlNRVRBREFUQU1BUCAqZHN0X21ldGFkYXRhID0gKChGUkVFSU1BR0VIRUFERVIgKiluZXdfZGliLT5kYXRhKS0+bWV0YWRhdGE7CgoJCS8vIGNhbGN1bGF0ZSB0aGUgc2l6ZSBvZiBhIEZyZWVJbWFnZSBpbWFnZQoJCS8vIGFsaWduIHRoZSBwYWxldHRlIGFuZCB0aGUgcGl4ZWxzIG9uIGEgRklCSVRNQVBfQUxJR05NRU5UIGJ5dGVzIGFsaWdubWVudCBib3VuZGFyeQoJCS8vIHBhbGV0dGUgaXMgYWxpZ25lZCBvbiBhIDE2IGJ5dGVzIGJvdW5kYXJ5CgkJLy8gcGl4ZWxzIGFyZSBhbGlnbmVkIG9uIGEgMTYgYnl0ZXMgYm91bmRhcnkKCgkJdW5zaWduZWQgZGliX3NpemUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VTaXplKHdpZHRoLCBoZWlnaHQsIGJwcCk7IAoKCQkvLyBjb3B5IHRoZSBiaXRtYXAgKyBpbnRlcm5hbCBwb2ludGVycyAocmVtZW1iZXIgdG8gcmVzdG9yZSBuZXdfZGliIGludGVybmFsIHBvaW50ZXJzIGxhdGVyKQoJCW1lbWNweShuZXdfZGliLT5kYXRhLCBkaWItPmRhdGEsIGRpYl9zaXplKTsKCgkJLy8gcmVzZXQgSUNDIHByb2ZpbGUgbGluayBmb3IgbmV3X2RpYgoJCW1lbXNldChkc3RfaWNjUHJvZmlsZSwgMCwgc2l6ZW9mKEZJSUNDUFJPRklMRSkpOwoKCQkvLyByZXN0b3JlIG1ldGFkYXRhIGxpbmsgZm9yIG5ld19kaWIKCQkoKEZSRUVJTUFHRUhFQURFUiAqKW5ld19kaWItPmRhdGEpLT5tZXRhZGF0YSA9IGRzdF9tZXRhZGF0YTsKCgkJLy8gY29weSBwb3NzaWJsZSBJQ0MgcHJvZmlsZQoJCUZyZWVJbWFnZV9DcmVhdGVJQ0NQcm9maWxlKG5ld19kaWIsIHNyY19pY2NQcm9maWxlLT5kYXRhLCBzcmNfaWNjUHJvZmlsZS0+c2l6ZSk7CgkJZHN0X2ljY1Byb2ZpbGUtPmZsYWdzID0gc3JjX2ljY1Byb2ZpbGUtPmZsYWdzOwoKCQkvLyBjb3B5IG1ldGFkYXRhIG1vZGVscwoJCWZvcihNRVRBREFUQU1BUDo6aXRlcmF0b3IgaSA9ICgqc3JjX21ldGFkYXRhKS5iZWdpbigpOyBpICE9ICgqc3JjX21ldGFkYXRhKS5lbmQoKTsgaSsrKSB7CgkJCWludCBtb2RlbCA9ICgqaSkuZmlyc3Q7CgkJCVRBR01BUCAqc3JjX3RhZ21hcCA9ICgqaSkuc2Vjb25kOwoKCQkJaWYoc3JjX3RhZ21hcCkgewoJCQkJLy8gY3JlYXRlIGEgbWV0YWRhdGEgbW9kZWwKCQkJCVRBR01BUCAqZHN0X3RhZ21hcCA9IG5ldyBUQUdNQVAoKTsKCgkJCQkvLyBmaWxsIHRoZSBtb2RlbAoJCQkJZm9yKFRBR01BUDo6aXRlcmF0b3IgaiA9IHNyY190YWdtYXAtPmJlZ2luKCk7IGogIT0gc3JjX3RhZ21hcC0+ZW5kKCk7IGorKykgewoJCQkJCXN0ZDo6c3RyaW5nIGRzdF9rZXkgPSAoKmopLmZpcnN0OwoJCQkJCUZJVEFHICpkc3RfdGFnID0gRnJlZUltYWdlX0Nsb25lVGFnKCAoKmopLnNlY29uZCApOwoKCQkJCQkvLyBhc3NpZ24ga2V5IGFuZCB0YWcgdmFsdWUKCQkJCQkoKmRzdF90YWdtYXApW2RzdF9rZXldID0gZHN0X3RhZzsKCQkJCX0KCgkJCQkvLyBhc3NpZ24gbW9kZWwgYW5kIHRhZ21hcAoJCQkJKCpkc3RfbWV0YWRhdGEpW21vZGVsXSA9IGRzdF90YWdtYXA7CgkJCX0KCQl9CgoJCXJldHVybiBuZXdfZGliOwoJfQoKCXJldHVybiBOVUxMOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpGUkVFX0lNQUdFX0NPTE9SX1RZUEUgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRDb2xvclR5cGUoRklCSVRNQVAgKmRpYikgewoJUkdCUVVBRCAqcmdiOwoKCWNvbnN0IEZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpOwoKCS8vIHNwZWNpYWwgYml0bWFwIHR5cGUKCWlmKGltYWdlX3R5cGUgIT0gRklUX0JJVE1BUCkgewoJCXN3aXRjaChpbWFnZV90eXBlKSB7CgkJCWNhc2UgRklUX1JHQjE2OgoJCQljYXNlIEZJVF9SR0JGOgoJCQkJcmV0dXJuIEZJQ19SR0I7CgkJCWNhc2UgRklUX1JHQkExNjoKCQkJY2FzZSBGSVRfUkdCQUY6CgkJCQlyZXR1cm4gRklDX1JHQkFMUEhBOwoJCX0KCgkJcmV0dXJuIEZJQ19NSU5JU0JMQUNLOwoJfQoKCS8vIHN0YW5kYXJkIGltYWdlIHR5cGUKCXN3aXRjaCAoRnJlZUltYWdlX0dldEJQUChkaWIpKSB7CgkJY2FzZSAxOgoJCXsKCQkJcmdiID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCgkJCWlmICgocmdiLT5yZ2JSZWQgPT0gMCkgJiYgKHJnYi0+cmdiR3JlZW4gPT0gMCkgJiYgKHJnYi0+cmdiQmx1ZSA9PSAwKSkgewoJCQkJcmdiKys7CgoJCQkJaWYgKChyZ2ItPnJnYlJlZCA9PSAyNTUpICYmIChyZ2ItPnJnYkdyZWVuID09IDI1NSkgJiYgKHJnYi0+cmdiQmx1ZSA9PSAyNTUpKQoJCQkJCXJldHVybiBGSUNfTUlOSVNCTEFDSzsJCQkJCgkJCX0KCgkJCWlmICgocmdiLT5yZ2JSZWQgPT0gMjU1KSAmJiAocmdiLT5yZ2JHcmVlbiA9PSAyNTUpICYmIChyZ2ItPnJnYkJsdWUgPT0gMjU1KSkgewoJCQkJcmdiKys7CgoJCQkJaWYgKChyZ2ItPnJnYlJlZCA9PSAwKSAmJiAocmdiLT5yZ2JHcmVlbiA9PSAwKSAmJiAocmdiLT5yZ2JCbHVlID09IDApKQoJCQkJCXJldHVybiBGSUNfTUlOSVNXSElURTsJCQkJCgkJCX0KCgkJCXJldHVybiBGSUNfUEFMRVRURTsKCQl9CgoJCWNhc2UgNDoKCQljYXNlIDg6CS8vIENoZWNrIGlmIHRoZSBESUIgaGFzIGEgY29sb3Igb3IgYSBncmV5c2NhbGUgcGFsZXR0ZQoJCXsKCQkJaW50IG5jb2xvcnMgPSBGcmVlSW1hZ2VfR2V0Q29sb3JzVXNlZChkaWIpOwoJCSAgICBpbnQgbWluaXNibGFjayA9IDE7CgkJCXJnYiA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgoJCQlmb3IgKGludCBpID0gMDsgaSA8IG5jb2xvcnM7IGkrKykgewoJCQkJaWYgKChyZ2ItPnJnYlJlZCAhPSByZ2ItPnJnYkdyZWVuKSB8fCAocmdiLT5yZ2JSZWQgIT0gcmdiLT5yZ2JCbHVlKSkKCQkJCQlyZXR1cm4gRklDX1BBTEVUVEU7CgoJCQkJLy8gVGhlIERJQiBoYXMgYSBjb2xvciBwYWxldHRlIGlmIHRoZSBncmV5c2NhbGUgaXNuJ3QgYSBsaW5lYXIgcmFtcAoJCQkJLy8gVGFrZSBjYXJlIG9mIHJldmVyc2VkIGdyZXkgaW1hZ2VzCgkJCQlpZiAocmdiLT5yZ2JSZWQgIT0gaSkgewoJCQkJCWlmICgobmNvbG9ycy1pLTEpICE9IHJnYi0+cmdiUmVkKQoJCQkJCQlyZXR1cm4gRklDX1BBTEVUVEU7CgkJCQkgICAgZWxzZQoJCQkJCQltaW5pc2JsYWNrID0gMDsKCQkJCX0KCgkJCQlyZ2IrKzsKCQkJfQoKCQkJcmV0dXJuIG1pbmlzYmxhY2sgPyBGSUNfTUlOSVNCTEFDSyA6IEZJQ19NSU5JU1dISVRFOwoJCX0KCgkJY2FzZSAxNjoKCQljYXNlIDI0OgoJCQlyZXR1cm4gRklDX1JHQjsKCgkJY2FzZSAzMjoKCQl7CgkJCWlmIChGcmVlSW1hZ2VfR2V0SUNDUHJvZmlsZShkaWIpLT5mbGFncyAmIEZJSUNDX0NPTE9SX0lTX0NNWUspCgkJCQlyZXR1cm4gRklDX0NNWUs7CgoJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgRnJlZUltYWdlX0dldEhlaWdodChkaWIpOyB5KyspIHsKCQkJCXJnYiA9IChSR0JRVUFEICopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgoJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpOyB4KyspCgkJCQkJaWYgKHJnYlt4XS5yZ2JSZXNlcnZlZCAhPSAweEZGKQoJCQkJCQlyZXR1cm4gRklDX1JHQkFMUEhBOwkJCQoJCQl9CgoJCQlyZXR1cm4gRklDX1JHQjsKCQl9CgkJCQkKCQlkZWZhdWx0IDoKCQkJcmV0dXJuIEZJQ19NSU5JU0JMQUNLOwoJfQp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpGUkVFX0lNQUdFX1RZUEUgRExMX0NBTExDT05WIApGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiAoZGliICE9IE5VTEwpID8gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT50eXBlIDogRklUX1VOS05PV047Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0UmVkTWFzayhGSUJJVE1BUCAqZGliKSB7CglyZXR1cm4gZGliID8gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5yZWRfbWFzayA6IDA7Cn0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0R3JlZW5NYXNrKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiBkaWIgPyAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPmdyZWVuX21hc2sgOiAwOwp9Cgp1bnNpZ25lZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldEJsdWVNYXNrKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiBkaWIgPyAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPmJsdWVfbWFzayA6IDA7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkJPT0wgRExMX0NBTExDT05WCkZyZWVJbWFnZV9IYXNCYWNrZ3JvdW5kQ29sb3IoRklCSVRNQVAgKmRpYikgewoJaWYoZGliKSB7CgkJUkdCUVVBRCAqYmtnbmRfY29sb3IgPSAmKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5ia2duZF9jb2xvcjsKCQlyZXR1cm4gKGJrZ25kX2NvbG9yLT5yZ2JSZXNlcnZlZCAhPSAwKSA/IFRSVUUgOiBGQUxTRTsKCX0KCXJldHVybiBGQUxTRTsKfQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldEJhY2tncm91bmRDb2xvcihGSUJJVE1BUCAqZGliLCBSR0JRVUFEICpia2NvbG9yKSB7CglpZihkaWIgJiYgYmtjb2xvcikgewoJCWlmKEZyZWVJbWFnZV9IYXNCYWNrZ3JvdW5kQ29sb3IoZGliKSkgewoJCQkvLyBnZXQgdGhlIGJhY2tncm91bmQgY29sb3IKCQkJUkdCUVVBRCAqYmtnbmRfY29sb3IgPSAmKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5ia2duZF9jb2xvcjsKCQkJbWVtY3B5KGJrY29sb3IsIGJrZ25kX2NvbG9yLCBzaXplb2YoUkdCUVVBRCkpOwoJCQkvLyBnZXQgdGhlIGJhY2tncm91bmQgaW5kZXgKCQkJaWYoRnJlZUltYWdlX0dldEJQUChkaWIpID09IDgpIHsKCQkJCVJHQlFVQUQgKnBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgkJCQlmb3IodW5zaWduZWQgaSA9IDA7IGkgPCBGcmVlSW1hZ2VfR2V0Q29sb3JzVXNlZChkaWIpOyBpKyspIHsKCQkJCQlpZihia2duZF9jb2xvci0+cmdiUmVkID09IHBhbFtpXS5yZ2JSZWQpIHsKCQkJCQkJaWYoYmtnbmRfY29sb3ItPnJnYkdyZWVuID09IHBhbFtpXS5yZ2JHcmVlbikgewoJCQkJCQkJaWYoYmtnbmRfY29sb3ItPnJnYkJsdWUgPT0gcGFsW2ldLnJnYkJsdWUpIHsKCQkJCQkJCQlia2NvbG9yLT5yZ2JSZXNlcnZlZCA9IChCWVRFKWk7CgkJCQkJCQkJcmV0dXJuIFRSVUU7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCgkJCWJrY29sb3ItPnJnYlJlc2VydmVkID0gMDsKCgkJCXJldHVybiBUUlVFOwoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCkJPT0wgRExMX0NBTExDT05WIApGcmVlSW1hZ2VfU2V0QmFja2dyb3VuZENvbG9yKEZJQklUTUFQICpkaWIsIFJHQlFVQUQgKmJrY29sb3IpIHsKCWlmKGRpYikgewoJCVJHQlFVQUQgKmJrZ25kX2NvbG9yID0gJigoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+YmtnbmRfY29sb3I7CgkJaWYoYmtjb2xvcikgewoJCQkvLyBzZXQgdGhlIGJhY2tncm91bmQgY29sb3IKCQkJbWVtY3B5KGJrZ25kX2NvbG9yLCBia2NvbG9yLCBzaXplb2YoUkdCUVVBRCkpOwoJCQkvLyBlbmFibGUgdGhlIGZpbGUgYmFja2dyb3VuZCBjb2xvcgoJCQlia2duZF9jb2xvci0+cmdiUmVzZXJ2ZWQgPSAxOwoJCX0gZWxzZSB7CgkJCS8vIGNsZWFyIGFuZCBkaXNhYmxlIHRoZSBmaWxlIGJhY2tncm91bmQgY29sb3IKCQkJbWVtc2V0KGJrZ25kX2NvbG9yLCAwLCBzaXplb2YoUkdCUVVBRCkpOwoJCX0KCQlyZXR1cm4gVFJVRTsKCX0KCglyZXR1cm4gRkFMU0U7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkJPT0wgRExMX0NBTExDT05WCkZyZWVJbWFnZV9Jc1RyYW5zcGFyZW50KEZJQklUTUFQICpkaWIpIHsKCWlmKGRpYikgewoJCWlmKEZyZWVJbWFnZV9HZXRCUFAoZGliKSA9PSAzMikgewoJCQlpZihGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlKGRpYikgPT0gRklDX1JHQkFMUEhBKSB7CgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCX0gZWxzZSB7CgkJCXJldHVybiAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPnRyYW5zcGFyZW50ID8gVFJVRSA6IEZBTFNFOwoJCX0KCX0KCXJldHVybiBGQUxTRTsKfQoKQllURSAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5VGFibGUoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIGRpYiA/ICgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+dHJhbnNwYXJlbnRfdGFibGUgOiBOVUxMOwp9Cgp2b2lkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfU2V0VHJhbnNwYXJlbnQoRklCSVRNQVAgKmRpYiwgQk9PTCBlbmFibGVkKSB7CglpZiAoZGliKSB7CgkJaWYgKChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPD0gOCkgfHwgKEZyZWVJbWFnZV9HZXRCUFAoZGliKSA9PSAzMikpIHsKCQkJKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT50cmFuc3BhcmVudCA9IGVuYWJsZWQ7CgkJfSBlbHNlIHsKCQkJKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT50cmFuc3BhcmVudCA9IEZBTFNFOwoJCX0KCX0KfQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lDb3VudChGSUJJVE1BUCAqZGliKSB7CglyZXR1cm4gZGliID8gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT50cmFuc3BhcmVuY3lfY291bnQgOiAwOwp9Cgp2b2lkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfU2V0VHJhbnNwYXJlbmN5VGFibGUoRklCSVRNQVAgKmRpYiwgQllURSAqdGFibGUsIGludCBjb3VudCkgewoJaWYgKGRpYikgewoJCWlmIChGcmVlSW1hZ2VfR2V0QlBQKGRpYikgPD0gOCkgewoJCQkoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPnRyYW5zcGFyZW50ID0gVFJVRTsKCQkJKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT50cmFuc3BhcmVuY3lfY291bnQgPSBjb3VudDsKCgkJCWlmICh0YWJsZSkgewoJCQkJbWVtY3B5KCgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+dHJhbnNwYXJlbnRfdGFibGUsIHRhYmxlLCBjb3VudCk7CgkJCX0gZWxzZSB7CgkJCQltZW1zZXQoKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT50cmFuc3BhcmVudF90YWJsZSwgMHhmZiwgY291bnQpOwoJCQl9CgkJfSAKCX0KfQoKLyoqIEBicmllZiBTZXRzIHRoZSBpbmRleCBvZiB0aGUgcGFsZXR0ZSBlbnRyeSB0byBiZSB1c2VkIGFzIHRyYW5zcGFyZW50IGNvbG9yCiBmb3IgdGhlIGltYWdlIHNwZWNpZmllZC4gRG9lcyBub3RoaW5nIG9uIGhpZ2ggY29sb3IgaW1hZ2VzLiAKIAogVGhpcyBtZXRob2Qgc2V0cyB0aGUgaW5kZXggb2YgdGhlIHBhbGV0dGUgZW50cnkgdG8gYmUgdXNlZCBhcyBzaW5nbGUgdHJhbnNwYXJlbnQKIGNvbG9yIGZvciB0aGUgaW1hZ2Ugc3BlY2lmaWVkLiBUaGlzIHdvcmtzIG9uIHBhbGxldGlzZWQgaW1hZ2VzIG9ubHkgYW5kIGRvZXMKIG5vdGhpbmcgZm9yIGhpZ2ggY29sb3IgaW1hZ2VzLgogCiBBbHRob3VnaCBpdCBpcyBwb3NzaWJsZSBmb3IgcGFsbGV0aXNlZCBpbWFnZXMgdG8gaGF2ZSBtb3JlIHRoYW4gb25lIHRyYW5zcGFyZW50CiBjb2xvciwgdGhpcyBtZXRob2Qgc2V0cyB0aGUgcGFsZXR0ZSBlbnRyeSBzcGVjaWZpZWQgYXMgdGhlIHNpbmdsZSB0cmFuc3BhcmVudAogY29sb3IgZm9yIHRoZSBpbWFnZS4gQWxsIG90aGVyIGNvbG9ycyB3aWxsIGJlIHNldCB0byBiZSBub24tdHJhbnNwYXJlbnQgYnkgdGhpcwogbWV0aG9kLgogCiBBcyB3aXRoIEZyZWVJbWFnZV9TZXRUcmFuc3BhcmVuY3lUYWJsZSgpLCB0aGlzIG1ldGhvZCBhbHNvIHNldHMgdGhlIGltYWdlJ3MKIHRyYW5zcGFyZW5jeSBwcm9wZXJ0eSB0byBUUlVFIChhcyBpdCBpcyBzZXQgYW5kIG9idGFpbmVkIGJ5CiBGcmVlSW1hZ2VfU2V0VHJhbnNwYXJlbnQoKSBhbmQgRnJlZUltYWdlX0lzVHJhbnNwYXJlbnQoKSByZXNwZWN0aXZlbHkpIGZvcgogcGFsbGV0aXNlZCBpbWFnZXMuCiAKIEBwYXJhbSBkaWIgSW5wdXQgaW1hZ2UsIHdob3NlIHRyYW5zcGFyZW50IGNvbG9yIGlzIHRvIGJlIHNldC4KIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHBhbGV0dGUgZW50cnkgdG8gYmUgc2V0IGFzIHRyYW5zcGFyZW50IGNvbG9yLgogKi8Kdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX1NldFRyYW5zcGFyZW50SW5kZXgoRklCSVRNQVAgKmRpYiwgaW50IGluZGV4KSB7CglpZiAoZGliKSB7CgkJaW50IGNvdW50ID0gRnJlZUltYWdlX0dldENvbG9yc1VzZWQoZGliKTsKCQlpZiAoY291bnQpIHsKCQkJQllURSAqbmV3X3R0ID0gKEJZVEUgKiltYWxsb2MoY291bnQgKiBzaXplb2YoQllURSkpOwoJCQltZW1zZXQobmV3X3R0LCAweEZGLCBjb3VudCk7CgkJCWlmICgoaW5kZXggPj0gMCkgJiYgKGluZGV4IDwgY291bnQpKSB7CgkJCQluZXdfdHRbaW5kZXhdID0gMHgwMDsKCQkJfQoJCQlGcmVlSW1hZ2VfU2V0VHJhbnNwYXJlbmN5VGFibGUoZGliLCBuZXdfdHQsIGNvdW50KTsKCQkJZnJlZShuZXdfdHQpOwoJCX0KCX0KfQoKLyoqIEBicmllZiBSZXR1cm5zIHRoZSBwYWxldHRlIGVudHJ5IHVzZWQgYXMgdHJhbnNwYXJlbnQgY29sb3IgZm9yIHRoZSBpbWFnZQogc3BlY2lmaWVkLiBXb3JrcyBmb3IgcGFsbGV0aXNlZCBpbWFnZXMgb25seSBhbmQgcmV0dXJucyAtMSBmb3IgaGlnaCBjb2xvcgogaW1hZ2VzIG9yIGlmIHRoZSBpbWFnZSBoYXMgbm8gY29sb3Igc2V0IHRvIGJlIHRyYW5zcGFyZW50LiAKIAogQWx0aG91Z2ggaXQgaXMgcG9zc2libGUgZm9yIHBhbGxldGlzZWQgaW1hZ2VzIHRvIGhhdmUgbW9yZSB0aGFuIG9uZSB0cmFuc3BhcmVudAogY29sb3IsIHRoaXMgZnVuY3Rpb24gYWx3YXlzIHJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBwYWxldHRlIGVudHJ5LCBzZXQKIHRvIGJlIHRyYW5zcGFyZW50LiAKIAogQHBhcmFtIGRpYiBJbnB1dCBpbWFnZSwgd2hvc2UgdHJhbnNwYXJlbnQgY29sb3IgaXMgdG8gYmUgcmV0dXJuZWQuCiBAcmV0dXJuIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBwYWxldHRlIGVudHJ5IHVzZWQgYXMgdHJhbnNwYXJlbnQgY29sb3IgZm9yCiB0aGUgaW1hZ2Ugc3BlY2lmaWVkIG9yIC0xIGlmIHRoZXJlIGlzIG5vIHRyYW5zcGFyZW50IGNvbG9yIGZvdW5kIChlLmcuIHRoZSBpbWFnZQogaXMgYSBoaWdoIGNvbG9yIGltYWdlKS4KICovCmludCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldFRyYW5zcGFyZW50SW5kZXgoRklCSVRNQVAgKmRpYikgewoJaW50IGNvdW50ID0gRnJlZUltYWdlX0dldFRyYW5zcGFyZW5jeUNvdW50KGRpYik7CglCWVRFICp0dCA9IEZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lUYWJsZShkaWIpOwoJZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CgkJaWYgKHR0W2ldID09IDApIHsKCQkJcmV0dXJuIGk7CgkJfQoJfQoJcmV0dXJuIC0xOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpGSUlDQ1BST0ZJTEUgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUoRklCSVRNQVAgKmRpYikgewoJRklJQ0NQUk9GSUxFICpwcm9maWxlID0gKGRpYikgPyAoRklJQ0NQUk9GSUxFICopJigoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+aWNjUHJvZmlsZSA6IE5VTEw7CglyZXR1cm4gcHJvZmlsZTsKfQoKRklJQ0NQUk9GSUxFICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9DcmVhdGVJQ0NQcm9maWxlKEZJQklUTUFQICpkaWIsIHZvaWQgKmRhdGEsIGxvbmcgc2l6ZSkgewoJLy8gY2xlYXIgdGhlIHByb2ZpbGUgYnV0IHByZXNlcnZlIHByb2ZpbGUtPmZsYWdzCglGcmVlSW1hZ2VfRGVzdHJveUlDQ1Byb2ZpbGUoZGliKTsKCS8vIGNyZWF0ZSB0aGUgbmV3IHByb2ZpbGUKCUZJSUNDUFJPRklMRSAqcHJvZmlsZSA9IEZyZWVJbWFnZV9HZXRJQ0NQcm9maWxlKGRpYik7CglpZihzaXplICYmIHByb2ZpbGUpIHsKCQlwcm9maWxlLT5kYXRhID0gbWFsbG9jKHNpemUpOwoJCWlmKHByb2ZpbGUtPmRhdGEpIHsKCQkJbWVtY3B5KHByb2ZpbGUtPmRhdGEsIGRhdGEsIHByb2ZpbGUtPnNpemUgPSBzaXplKTsKCQl9Cgl9CglyZXR1cm4gcHJvZmlsZTsKfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0Rlc3Ryb3lJQ0NQcm9maWxlKEZJQklUTUFQICpkaWIpIHsKCUZJSUNDUFJPRklMRSAqcHJvZmlsZSA9IEZyZWVJbWFnZV9HZXRJQ0NQcm9maWxlKGRpYik7CglpZihwcm9maWxlKSB7CgkJaWYgKHByb2ZpbGUtPmRhdGEpIHsKCQkJZnJlZSAocHJvZmlsZS0+ZGF0YSk7CgkJfQoJCS8vIGNsZWFyIHRoZSBwcm9maWxlIGJ1dCBwcmVzZXJ2ZSBwcm9maWxlLT5mbGFncwoJCXByb2ZpbGUtPmRhdGEgPSBOVUxMOwoJCXByb2ZpbGUtPnNpemUgPSAwOwoJfQp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp1bnNpZ25lZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldFdpZHRoKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiBkaWIgPyBGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpLT5iaVdpZHRoIDogMDsKfQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRIZWlnaHQoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIChkaWIpID8gRnJlZUltYWdlX0dldEluZm9IZWFkZXIoZGliKS0+YmlIZWlnaHQgOiAwOwp9Cgp1bnNpZ25lZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldEJQUChGSUJJVE1BUCAqZGliKSB7CglyZXR1cm4gZGliID8gRnJlZUltYWdlX0dldEluZm9IZWFkZXIoZGliKS0+YmlCaXRDb3VudCA6IDA7Cn0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0TGluZShGSUJJVE1BUCAqZGliKSB7CglyZXR1cm4gZGliID8gKChGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKSAqIEZyZWVJbWFnZV9HZXRCUFAoZGliKSkgKyA3KSAvIDggOiAwOwp9Cgp1bnNpZ25lZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldFBpdGNoKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiBkaWIgPyBGcmVlSW1hZ2VfR2V0TGluZShkaWIpICsgMyAmIH4zIDogMDsKfQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRDb2xvcnNVc2VkKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiBkaWIgPyBGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpLT5iaUNsclVzZWQgOiAwOwp9Cgp1bnNpZ25lZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldERJQlNpemUoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIChkaWIpID8gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICsgKEZyZWVJbWFnZV9HZXRDb2xvcnNVc2VkKGRpYikgKiBzaXplb2YoUkdCUVVBRCkpICsgKEZyZWVJbWFnZV9HZXRQaXRjaChkaWIpICogRnJlZUltYWdlX0dldEhlaWdodChkaWIpKSA6IDA7Cn0KClJHQlFVQUQgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldFBhbGV0dGUoRklCSVRNQVAgKmRpYikgewoJcmV0dXJuIChkaWIgJiYgRnJlZUltYWdlX0dldEJQUChkaWIpIDwgMTYpID8gKFJHQlFVQUQgKikoKChCWVRFICopRnJlZUltYWdlX0dldEluZm9IZWFkZXIoZGliKSkgKyBzaXplb2YoQklUTUFQSU5GT0hFQURFUikpIDogTlVMTDsKfQoKdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXREb3RzUGVyTWV0ZXJYKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiAoZGliKSA/IEZyZWVJbWFnZV9HZXRJbmZvSGVhZGVyKGRpYiktPmJpWFBlbHNQZXJNZXRlciA6IDA7Cn0KCnVuc2lnbmVkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0RG90c1Blck1ldGVyWShGSUJJVE1BUCAqZGliKSB7CglyZXR1cm4gKGRpYikgPyBGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpLT5iaVlQZWxzUGVyTWV0ZXIgOiAwOwp9Cgp2b2lkIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfU2V0RG90c1Blck1ldGVyWChGSUJJVE1BUCAqZGliLCB1bnNpZ25lZCByZXMpIHsKCWlmKGRpYikgewoJCUZyZWVJbWFnZV9HZXRJbmZvSGVhZGVyKGRpYiktPmJpWFBlbHNQZXJNZXRlciA9IHJlczsKCX0KfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX1NldERvdHNQZXJNZXRlclkoRklCSVRNQVAgKmRpYiwgdW5zaWduZWQgcmVzKSB7CglpZihkaWIpIHsKCQlGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihkaWIpLT5iaVlQZWxzUGVyTWV0ZXIgPSByZXM7Cgl9Cn0KCkJJVE1BUElORk9IRUFERVIgKiBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldEluZm9IZWFkZXIoRklCSVRNQVAgKmRpYikgewoJaWYoIWRpYikgcmV0dXJuIE5VTEw7CglzaXplX3QgbHAgPSAoc2l6ZV90KWRpYi0+ZGF0YSArIHNpemVvZihGUkVFSU1BR0VIRUFERVIpOwoJbHAgKz0gKGxwICUgRklCSVRNQVBfQUxJR05NRU5UID8gRklCSVRNQVBfQUxJR05NRU5UIC0gbHAgJSBGSUJJVE1BUF9BTElHTk1FTlQgOiAwKTsKCWxwICs9IEZJQklUTUFQX0FMSUdOTUVOVCAtIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSAlIEZJQklUTUFQX0FMSUdOTUVOVDsKCXJldHVybiAoQklUTUFQSU5GT0hFQURFUiAqKWxwOwp9CgpCSVRNQVBJTkZPICogRExMX0NBTExDT05WCkZyZWVJbWFnZV9HZXRJbmZvKEZJQklUTUFQICpkaWIpIHsKCXJldHVybiAoQklUTUFQSU5GTyAqKUZyZWVJbWFnZV9HZXRJbmZvSGVhZGVyKGRpYik7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gIE1ldGFkYXRhIHJvdXRpbmVzCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkZJTUVUQURBVEEgKiBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9GaW5kRmlyc3RNZXRhZGF0YShGUkVFX0lNQUdFX01ETU9ERUwgbW9kZWwsIEZJQklUTUFQICpkaWIsIEZJVEFHICoqdGFnKSB7CglpZighZGliKQoJCXJldHVybiBOVUxMOwoKCS8vIGdldCB0aGUgbWV0YWRhdGEgbW9kZWwKCU1FVEFEQVRBTUFQICptZXRhZGF0YSA9ICgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+bWV0YWRhdGE7CglUQUdNQVAgKnRhZ21hcCA9IE5VTEw7CglpZiggKCptZXRhZGF0YSkuZmluZChtb2RlbCkgIT0gKCptZXRhZGF0YSkuZW5kKCkgKSB7CgkJdGFnbWFwID0gKCptZXRhZGF0YSlbbW9kZWxdOwoJfQoJaWYodGFnbWFwKSB7CgkJLy8gYWxsb2NhdGUgYSBoYW5kbGUKCQlGSU1FVEFEQVRBIAkqaGFuZGxlID0gKEZJTUVUQURBVEEgKiltYWxsb2Moc2l6ZW9mKEZJTUVUQURBVEEpKTsKCQlpZihoYW5kbGUpIHsKCQkJLy8gY2FsY3VsYXRlIHRoZSBzaXplIG9mIGEgTUVUQURBVEFIRUFERVIKCQkJaW50IGhlYWRlcl9zaXplID0gc2l6ZW9mKE1FVEFEQVRBSEVBREVSKTsKCgkJCWhhbmRsZS0+ZGF0YSA9IChCWVRFICopbWFsbG9jKGhlYWRlcl9zaXplICogc2l6ZW9mKEJZVEUpKTsKCQkJCgkJCWlmKGhhbmRsZS0+ZGF0YSkgewoJCQkJbWVtc2V0KGhhbmRsZS0+ZGF0YSwgMCwgaGVhZGVyX3NpemUgKiBzaXplb2YoQllURSkpOwoKCQkJCS8vIHdyaXRlIG91dCB0aGUgTUVUQURBVEFIRUFERVIKCQkJCU1FVEFEQVRBSEVBREVSICptZGggPSAoTUVUQURBVEFIRUFERVIgKiloYW5kbGUtPmRhdGE7CgoJCQkJbWRoLT5wb3MgPSAxOwoJCQkJbWRoLT50YWdtYXAgPSB0YWdtYXA7CgoJCQkJLy8gZ2V0IHRoZSBmaXJzdCBlbGVtZW50CgkJCQlUQUdNQVA6Oml0ZXJhdG9yIGkgPSB0YWdtYXAtPmJlZ2luKCk7CgkJCQkqdGFnID0gKCppKS5zZWNvbmQ7CgoJCQkJcmV0dXJuIGhhbmRsZTsKCQkJfQoKCQkJZnJlZShoYW5kbGUpOwoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKQk9PTCBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9GaW5kTmV4dE1ldGFkYXRhKEZJTUVUQURBVEEgKm1kaGFuZGxlLCBGSVRBRyAqKnRhZykgewoJaWYoIW1kaGFuZGxlKQoJCXJldHVybiBGQUxTRTsKCglNRVRBREFUQUhFQURFUiAqbWRoID0gKE1FVEFEQVRBSEVBREVSICopbWRoYW5kbGUtPmRhdGE7CglUQUdNQVAgKnRhZ21hcCA9IG1kaC0+dGFnbWFwOwoKCWludCBjdXJyZW50X3BvcyA9IG1kaC0+cG9zOwoJaW50IG1hcHNpemUgICAgID0gKGludCl0YWdtYXAtPnNpemUoKTsKCglpZihjdXJyZW50X3BvcyA8IG1hcHNpemUpIHsKCQkvLyBnZXQgdGhlIHRhZyBlbGVtZW50IGF0IHBvc2l0aW9uIHBvcwoJCWludCBjb3VudCA9IDA7CgoJCWZvcihUQUdNQVA6Oml0ZXJhdG9yIGkgPSB0YWdtYXAtPmJlZ2luKCk7IGkgIT0gdGFnbWFwLT5lbmQoKTsgaSsrKSB7CgkJCWlmKGNvdW50ID09IGN1cnJlbnRfcG9zKSB7CgkJCQkqdGFnID0gKCppKS5zZWNvbmQ7CgkJCQltZGgtPnBvcysrOwoJCQkJYnJlYWs7CgkJCX0KCQkJY291bnQrKzsKCQl9CgkJCgkJcmV0dXJuIFRSVUU7Cgl9CgoJcmV0dXJuIEZBTFNFOwp9Cgp2b2lkIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX0ZpbmRDbG9zZU1ldGFkYXRhKEZJTUVUQURBVEEgKm1kaGFuZGxlKSB7CglpZiAoTlVMTCAhPSBtZGhhbmRsZSkgewkvLyBkZWxldGUgdGhlIGhhbmRsZQoJCWlmIChOVUxMICE9IG1kaGFuZGxlLT5kYXRhKSB7CgkJCWZyZWUobWRoYW5kbGUtPmRhdGEpOwoJCX0KCQlmcmVlKG1kaGFuZGxlKTsJCS8vIC4uLiBhbmQgdGhlIHdyYXBwZXIKCX0KfQoKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkJPT0wgRExMX0NBTExDT05WCkZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKEZJQklUTUFQICpkc3QsIEZJQklUTUFQICpzcmMpIHsKCWlmKCFzcmMgfHwgIWRzdCkgcmV0dXJuIEZBTFNFOwoKCS8vIGdldCBtZXRhZGF0YSBsaW5rcwoJTUVUQURBVEFNQVAgKnNyY19tZXRhZGF0YSA9ICgoRlJFRUlNQUdFSEVBREVSICopc3JjLT5kYXRhKS0+bWV0YWRhdGE7CglNRVRBREFUQU1BUCAqZHN0X21ldGFkYXRhID0gKChGUkVFSU1BR0VIRUFERVIgKilkc3QtPmRhdGEpLT5tZXRhZGF0YTsKCgkvLyBjb3B5IG1ldGFkYXRhIG1vZGVscywgKmV4Y2VwdCogdGhlIEZJTURfQU5JTUFUSU9OIG1vZGVsCglmb3IoTUVUQURBVEFNQVA6Oml0ZXJhdG9yIGkgPSAoKnNyY19tZXRhZGF0YSkuYmVnaW4oKTsgaSAhPSAoKnNyY19tZXRhZGF0YSkuZW5kKCk7IGkrKykgewoJCWludCBtb2RlbCA9ICgqaSkuZmlyc3Q7CgkJaWYobW9kZWwgPT0gKGludClGSU1EX0FOSU1BVElPTikgewoJCQljb250aW51ZTsKCQl9CgkJVEFHTUFQICpzcmNfdGFnbWFwID0gKCppKS5zZWNvbmQ7CgoJCWlmKHNyY190YWdtYXApIHsKCQkJaWYoIGRzdF9tZXRhZGF0YS0+ZmluZChtb2RlbCkgIT0gZHN0X21ldGFkYXRhLT5lbmQoKSApIHsKCQkJCS8vIGRlc3Ryb3kgZHN0IG1vZGVsCgkJCQlGcmVlSW1hZ2VfU2V0TWV0YWRhdGEoKEZSRUVfSU1BR0VfTURNT0RFTCltb2RlbCwgZHN0LCBOVUxMLCBOVUxMKTsKCQkJfQoKCQkJLy8gY3JlYXRlIGEgbWV0YWRhdGEgbW9kZWwKCQkJVEFHTUFQICpkc3RfdGFnbWFwID0gbmV3IFRBR01BUCgpOwoKCQkJLy8gZmlsbCB0aGUgbW9kZWwKCQkJZm9yKFRBR01BUDo6aXRlcmF0b3IgaiA9IHNyY190YWdtYXAtPmJlZ2luKCk7IGogIT0gc3JjX3RhZ21hcC0+ZW5kKCk7IGorKykgewoJCQkJc3RkOjpzdHJpbmcgZHN0X2tleSA9ICgqaikuZmlyc3Q7CgkJCQlGSVRBRyAqZHN0X3RhZyA9IEZyZWVJbWFnZV9DbG9uZVRhZyggKCpqKS5zZWNvbmQgKTsKCgkJCQkvLyBhc3NpZ24ga2V5IGFuZCB0YWcgdmFsdWUKCQkJCSgqZHN0X3RhZ21hcClbZHN0X2tleV0gPSBkc3RfdGFnOwoJCQl9CgoJCQkvLyBhc3NpZ24gbW9kZWwgYW5kIHRhZ21hcAoJCQkoKmRzdF9tZXRhZGF0YSlbbW9kZWxdID0gZHN0X3RhZ21hcDsKCQl9Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCkJPT0wgRExMX0NBTExDT05WIApGcmVlSW1hZ2VfU2V0TWV0YWRhdGEoRlJFRV9JTUFHRV9NRE1PREVMIG1vZGVsLCBGSUJJVE1BUCAqZGliLCBjb25zdCBjaGFyICprZXksIEZJVEFHICp0YWcpIHsKCWlmKCFkaWIpIAoJCXJldHVybiBGQUxTRTsKCglUQUdNQVAgKnRhZ21hcCA9IE5VTEw7CgoJLy8gZ2V0IHRoZSBtZXRhZGF0YSBtb2RlbAoJTUVUQURBVEFNQVAgKm1ldGFkYXRhID0gKChGUkVFSU1BR0VIRUFERVIgKilkaWItPmRhdGEpLT5tZXRhZGF0YTsKCU1FVEFEQVRBTUFQOjppdGVyYXRvciBtb2RlbF9pdGVyYXRvciA9IG1ldGFkYXRhLT5maW5kKG1vZGVsKTsKCWlmIChtb2RlbF9pdGVyYXRvciAhPSBtZXRhZGF0YS0+ZW5kKCkpIHsKCQl0YWdtYXAgPSBtb2RlbF9pdGVyYXRvci0+c2Vjb25kOwoJfQoKCWlmKGtleSAhPSBOVUxMKSB7CgoJCWlmKCF0YWdtYXApIHsKCQkJLy8gdGhpcyBtb2RlbCwgZG9lc24ndCBleGlzdDogY3JlYXRlIGl0IAoJCQl0YWdtYXAgPSBuZXcgVEFHTUFQKCk7CgkJCSgqbWV0YWRhdGEpW21vZGVsXSA9IHRhZ21hcDsKCQl9CgkJCgkJaWYodGFnKSB7CgkJCS8vIGZpcnN0IGNoZWNrIHRoZSB0YWcKCQkJaWYoRnJlZUltYWdlX0dldFRhZ0tleSh0YWcpID09IE5VTEwpIHsKCQkJCUZyZWVJbWFnZV9TZXRUYWdLZXkodGFnLCBrZXkpOwoJCQl9IGVsc2UgaWYoc3RyY21wKGtleSwgRnJlZUltYWdlX0dldFRhZ0tleSh0YWcpKSAhPSAwKSB7CgkJCQkvLyBzZXQgdGhlIHRhZyBrZXkKCQkJCUZyZWVJbWFnZV9TZXRUYWdLZXkodGFnLCBrZXkpOwoJCQl9CgkJCWlmKEZyZWVJbWFnZV9HZXRUYWdDb3VudCh0YWcpICogRnJlZUltYWdlX1RhZ0RhdGFXaWR0aCgoV09SRClGcmVlSW1hZ2VfR2V0VGFnVHlwZSh0YWcpKSAhPSBGcmVlSW1hZ2VfR2V0VGFnTGVuZ3RoKHRhZykpIHsKCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhGSUZfVU5LTk9XTiwgIkludmFsaWQgZGF0YSBjb3VudCBmb3IgdGFnICclcyciLCBrZXkpOwoJCQkJcmV0dXJuIEZBTFNFOwoJCQl9CgoJCQkvLyBmaWxsIHRoZSB0YWcgSUQgaWYgcG9zc2libGUgYW5kIGlmIGl0J3MgbmVlZGVkCgkJCVRhZ0xpYiYgdGFnX2xpYiA9IFRhZ0xpYjo6aW5zdGFuY2UoKTsKCQkJc3dpdGNoKG1vZGVsKSB7CgkJCQljYXNlIEZJTURfSVBUQzoKCQkJCXsKCQkJCQlpbnQgaWQgPSB0YWdfbGliLmdldFRhZ0lEKFRhZ0xpYjo6SVBUQywga2V5KTsKCQkJCQkvKgoJCQkJCWlmKGlkID09IC0xKSB7CgkJCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhGSUZfVU5LTk9XTiwgIklQVEM6IEludmFsaWQga2V5ICclcyciLCBrZXkpOwoJCQkJCX0KCQkJCQkqLwoJCQkJCUZyZWVJbWFnZV9TZXRUYWdJRCh0YWcsIChXT1JEKWlkKTsKCQkJCX0KCQkJCWJyZWFrOwoKCQkJCWRlZmF1bHQ6CgkJCQkJYnJlYWs7CgkJCX0KCgkJCS8vIGRlbGV0ZSBleGlzdGluZyB0YWcKCQkJRklUQUcgKm9sZF90YWcgPSAoKnRhZ21hcClba2V5XTsKCQkJaWYob2xkX3RhZykgewoJCQkJRnJlZUltYWdlX0RlbGV0ZVRhZyhvbGRfdGFnKTsKCQkJfQoKCQkJLy8gY3JlYXRlIGEgbmV3IHRhZwoJCQkoKnRhZ21hcClba2V5XSA9IEZyZWVJbWFnZV9DbG9uZVRhZyh0YWcpOwoJCX0KCQllbHNlIHsKCQkJLy8gZGVsZXRlIGV4aXN0aW5nIHRhZwoJCQlUQUdNQVA6Oml0ZXJhdG9yIGkgPSB0YWdtYXAtPmZpbmQoa2V5KTsKCQkJaWYoaSAhPSB0YWdtYXAtPmVuZCgpKSB7CgkJCQlGSVRBRyAqb2xkX3RhZyA9ICgqaSkuc2Vjb25kOwoJCQkJRnJlZUltYWdlX0RlbGV0ZVRhZyhvbGRfdGFnKTsKCQkJCXRhZ21hcC0+ZXJhc2Uoa2V5KTsKCQkJfQoJCX0KCX0KCWVsc2UgewoJCS8vIGRlc3Ryb3kgdGhlIG1ldGFkYXRhIG1vZGVsCgkJaWYodGFnbWFwKSB7CgkJCWZvcihUQUdNQVA6Oml0ZXJhdG9yIGkgPSB0YWdtYXAtPmJlZ2luKCk7IGkgIT0gdGFnbWFwLT5lbmQoKTsgaSsrKSB7CgkJCQlGSVRBRyAqdGFnID0gKCppKS5zZWNvbmQ7CgkJCQlGcmVlSW1hZ2VfRGVsZXRlVGFnKHRhZyk7CgkJCX0KCgkJCWRlbGV0ZSB0YWdtYXA7CgkJCW1ldGFkYXRhLT5lcmFzZShtb2RlbF9pdGVyYXRvcik7CgkJfQoJfQoKCXJldHVybiBUUlVFOwp9CgpCT09MIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX0dldE1ldGFkYXRhKEZSRUVfSU1BR0VfTURNT0RFTCBtb2RlbCwgRklCSVRNQVAgKmRpYiwgY29uc3QgY2hhciAqa2V5LCBGSVRBRyAqKnRhZykgewoJaWYoIWRpYiB8fCAha2V5IHx8ICF0YWcpIAoJCXJldHVybiBGQUxTRTsKCglUQUdNQVAgKnRhZ21hcCA9IE5VTEw7CgkqdGFnID0gTlVMTDsKCgkvLyBnZXQgdGhlIG1ldGFkYXRhIG1vZGVsCglNRVRBREFUQU1BUCAqbWV0YWRhdGEgPSAoKEZSRUVJTUFHRUhFQURFUiAqKWRpYi0+ZGF0YSktPm1ldGFkYXRhOwoJaWYoISgqbWV0YWRhdGEpLmVtcHR5KCkpIHsKCQlNRVRBREFUQU1BUDo6aXRlcmF0b3IgbW9kZWxfaXRlcmF0b3IgPSBtZXRhZGF0YS0+ZmluZChtb2RlbCk7CgkJaWYgKG1vZGVsX2l0ZXJhdG9yICE9IG1ldGFkYXRhLT5lbmQoKSApIHsKCQkJLy8gdGhpcyBtb2RlbCBleGlzdHMgOiB0cnkgdG8gZ2V0IHRoZSByZXF1ZXN0ZWQgdGFnCgkJCXRhZ21hcCA9IG1vZGVsX2l0ZXJhdG9yLT5zZWNvbmQ7CgkJCVRBR01BUDo6aXRlcmF0b3IgdGFnX2l0ZXJhdG9yID0gdGFnbWFwLT5maW5kKGtleSk7CgkJCWlmICh0YWdfaXRlcmF0b3IgIT0gdGFnbWFwLT5lbmQoKSApIHsKCQkJCS8vIGdldCB0aGUgcmVxdWVzdGVkIHRhZwoJCQkJKnRhZyA9IHRhZ19pdGVyYXRvci0+c2Vjb25kOwoJCQl9IAoJCX0KCX0KCglyZXR1cm4gKCp0YWcgIT0gTlVMTCkgPyBUUlVFIDogRkFMU0U7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnVuc2lnbmVkIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX0dldE1ldGFkYXRhQ291bnQoRlJFRV9JTUFHRV9NRE1PREVMIG1vZGVsLCBGSUJJVE1BUCAqZGliKSB7CglpZighZGliKSAKCQlyZXR1cm4gRkFMU0U7CgoJVEFHTUFQICp0YWdtYXAgPSBOVUxMOwoKCS8vIGdldCB0aGUgbWV0YWRhdGEgbW9kZWwKCU1FVEFEQVRBTUFQICptZXRhZGF0YSA9ICgoRlJFRUlNQUdFSEVBREVSICopZGliLT5kYXRhKS0+bWV0YWRhdGE7CglpZiggKCptZXRhZGF0YSkuZmluZChtb2RlbCkgIT0gKCptZXRhZGF0YSkuZW5kKCkgKSB7CgkJdGFnbWFwID0gKCptZXRhZGF0YSlbbW9kZWxdOwoJfQoJaWYoIXRhZ21hcCkgewoJCS8vIHRoaXMgbW9kZWwsIGRvZXNuJ3QgZXhpc3Q6IHJldHVybgoJCXJldHVybiAwOwoJfQoKCS8vIGdldCB0aGUgdGFnIGNvdW50CglyZXR1cm4gKHVuc2lnbmVkKXRhZ21hcC0+c2l6ZSgpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoK