LyoKICogQ29weXJpZ2h0IChDKSAyMDA3IEhhYWtvbiBTcG9yc2hlaW0gPGhha29uLnNwb3JzaGVpbUB0YW5kYmVyZy5jb20+CiAqICAgICAgICAgICAgICAgMjAwOCBPbGUgQW5kcukgVmFkbGEgUmF2buVzIDxvbGUuYW5kcmUucmF2bmFzQHRhbmRiZXJnLmNvbT4KICogICAgICAgICAgICAgICAyMDA5IEtudXQgSW5nZSBIdmlkc3RlbiA8a251dC5pbmdlLmh2aWRzdGVuQHRhbmRiZXJnLmNvbT4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGlicmFyeSBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGlicmFyeSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlCiAqIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLAogKiBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQS4KICovCgojaW5jbHVkZSAia3N2aWRlb2hlbHBlcnMuaCIKCiNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDx1dWlkcy5oPgojaW5jbHVkZSAia3NoZWxwZXJzLmgiCgpHU1RfREVCVUdfQ0FURUdPUllfRVhURVJOIChnc3Rfa3NfZGVidWcpOwojZGVmaW5lIEdTVF9DQVRfREVGQVVMVCBnc3Rfa3NfZGVidWcKCnN0YXRpYyBjb25zdCBHVUlEIE1FRElBU1VCVFlQRV9GT1VSQ0MgPQogICAgeyAweDAgLyogRm91ckNDIGhlcmUgKi8gLCAweDAwMDAsIDB4MDAxMCwgezB4ODAsIDB4MDAsIDB4MDAsIDB4QUEsIDB4MDAsCiAgICAweDM4LCAweDlCLCAweDcxfQp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0tzVmlkZW9EZXZpY2VFbnRyeSBLc1ZpZGVvRGV2aWNlRW50cnk7CgpzdHJ1Y3QgX0tzVmlkZW9EZXZpY2VFbnRyeQp7CiAgS3NEZXZpY2VFbnRyeSAqZGV2aWNlOwogIGdpbnQgcHJpb3JpdHk7Cn07CgpzdGF0aWMgdm9pZAprc192aWRlb19kZXZpY2VfZW50cnlfZGVjaWRlX3ByaW9yaXR5IChLc1ZpZGVvRGV2aWNlRW50cnkgKiB2aWRlb2RldmljZSkKewogIEhBTkRMRSBmaWx0ZXJfaGFuZGxlOwoKICB2aWRlb2RldmljZS0+cHJpb3JpdHkgPSAwOwoKICBmaWx0ZXJfaGFuZGxlID0gQ3JlYXRlRmlsZSAodmlkZW9kZXZpY2UtPmRldmljZS0+cGF0aCwKICAgICAgR0VORVJJQ19SRUFEIHwgR0VORVJJQ19XUklURSwgMCwgTlVMTCwgT1BFTl9FWElTVElORywKICAgICAgRklMRV9BVFRSSUJVVEVfTk9STUFMIHwgRklMRV9GTEFHX09WRVJMQVBQRUQsIE5VTEwpOwogIGlmIChrc19pc192YWxpZF9oYW5kbGUgKGZpbHRlcl9oYW5kbGUpKSB7CiAgICBHVUlEICpwcm9wc2V0cyA9IE5VTEw7CiAgICBndWxvbmcgcHJvcHNldHNfbGVuOwoKICAgIGlmIChrc19vYmplY3RfZ2V0X3N1cHBvcnRlZF9wcm9wZXJ0eV9zZXRzIChmaWx0ZXJfaGFuZGxlLCAmcHJvcHNldHMsCiAgICAgICAgICAgICZwcm9wc2V0c19sZW4pKSB7CiAgICAgIGd1bG9uZyBpOwoKICAgICAgZm9yIChpID0gMDsgaSA8IHByb3BzZXRzX2xlbjsgaSsrKSB7CiAgICAgICAgaWYgKG1lbWNtcCAoJnByb3BzZXRzW2ldLCAmUFJPUFNFVElEX1ZJRENBUF9DQU1FUkFDT05UUk9MLAogICAgICAgICAgICAgICAgc2l6ZW9mIChHVUlEKSkgPT0gMCkgewogICAgICAgICAgdmlkZW9kZXZpY2UtPnByaW9yaXR5Kys7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGdfZnJlZSAocHJvcHNldHMpOwogICAgfQogIH0KCiAgQ2xvc2VIYW5kbGUgKGZpbHRlcl9oYW5kbGUpOwp9CgpzdGF0aWMgZ2ludAprc192aWRlb19kZXZpY2VfZW50cnlfY29tcGFyZSAoZ2NvbnN0cG9pbnRlciBhLCBnY29uc3Rwb2ludGVyIGIpCnsKICBjb25zdCBLc1ZpZGVvRGV2aWNlRW50cnkgKnZpZGVvZGV2aWNlX2EgPSBhOwogIGNvbnN0IEtzVmlkZW9EZXZpY2VFbnRyeSAqdmlkZW9kZXZpY2VfYiA9IGI7CgogIGlmICh2aWRlb2RldmljZV9hLT5wcmlvcml0eSA+IHZpZGVvZGV2aWNlX2ItPnByaW9yaXR5KQogICAgcmV0dXJuIC0xOwogIGVsc2UgaWYgKHZpZGVvZGV2aWNlX2EtPnByaW9yaXR5ID09IHZpZGVvZGV2aWNlX2ItPnByaW9yaXR5KQogICAgcmV0dXJuIDA7CiAgZWxzZQogICAgcmV0dXJuIDE7Cn0KCkdMaXN0ICoKa3NfdmlkZW9fZGV2aWNlX2xpc3Rfc29ydF9jYW1lcmFzX2ZpcnN0IChHTGlzdCAqIGRldmljZXMpCnsKICBHTGlzdCAqdmlkZW9kZXZpY2VzID0gTlVMTCwgKndhbGs7CiAgZ3VpbnQgaTsKCiAgZm9yICh3YWxrID0gZGV2aWNlczsgd2FsayAhPSBOVUxMOyB3YWxrID0gd2Fsay0+bmV4dCkgewogICAgS3NEZXZpY2VFbnRyeSAqZGV2aWNlID0gd2Fsay0+ZGF0YTsKICAgIEtzVmlkZW9EZXZpY2VFbnRyeSAqdmlkZW9kZXZpY2U7CgogICAgdmlkZW9kZXZpY2UgPSBnX25ldyAoS3NWaWRlb0RldmljZUVudHJ5LCAxKTsKICAgIHZpZGVvZGV2aWNlLT5kZXZpY2UgPSBkZXZpY2U7CiAgICBrc192aWRlb19kZXZpY2VfZW50cnlfZGVjaWRlX3ByaW9yaXR5ICh2aWRlb2RldmljZSk7CgogICAgdmlkZW9kZXZpY2VzID0gZ19saXN0X2FwcGVuZCAodmlkZW9kZXZpY2VzLCB2aWRlb2RldmljZSk7CiAgfQoKICB2aWRlb2RldmljZXMgPSBnX2xpc3Rfc29ydCAodmlkZW9kZXZpY2VzLCBrc192aWRlb19kZXZpY2VfZW50cnlfY29tcGFyZSk7CgogIGdfbGlzdF9mcmVlIChkZXZpY2VzKTsKICBkZXZpY2VzID0gTlVMTDsKCiAgZm9yICh3YWxrID0gdmlkZW9kZXZpY2VzLCBpID0gMDsgd2FsayAhPSBOVUxMOyB3YWxrID0gd2Fsay0+bmV4dCwgaSsrKSB7CiAgICBLc1ZpZGVvRGV2aWNlRW50cnkgKnZpZGVvZGV2aWNlID0gd2Fsay0+ZGF0YTsKCiAgICB2aWRlb2RldmljZS0+ZGV2aWNlLT5pbmRleCA9IGk7CiAgICBkZXZpY2VzID0gZ19saXN0X2FwcGVuZCAoZGV2aWNlcywgdmlkZW9kZXZpY2UtPmRldmljZSk7CgogICAgZ19mcmVlICh2aWRlb2RldmljZSk7CiAgfQoKICBnX2xpc3RfZnJlZSAodmlkZW9kZXZpY2VzKTsKCiAgcmV0dXJuIGRldmljZXM7Cn0KCnN0YXRpYyBHc3RTdHJ1Y3R1cmUgKgprc192aWRlb19mb3JtYXRfdG9fc3RydWN0dXJlIChHVUlEIHN1YnR5cGVfZ3VpZCwgR1VJRCBmb3JtYXRfZ3VpZCwKICAgIGdib29sZWFuICogcF9pc19yZ2IpCnsKICBHc3RTdHJ1Y3R1cmUgKnN0cnVjdHVyZSA9IE5VTEw7CiAgY29uc3QgZ2NoYXIgKm1lZGlhX3R5cGUgPSBOVUxMLCAqZm9ybWF0ID0gTlVMTDsKICAvKiBSR0IgZm9ybWF0cyBjYW4gYmUgYm90dG9tLXVwICh1cHNpZGUgZG93bikgRElCICovCiAgZ2Jvb2xlYW4gaXNfcmdiID0gRkFMU0U7CgogIGlmIChJc0VxdWFsR1VJRCAoJnN1YnR5cGVfZ3VpZCwgJk1FRElBU1VCVFlQRV9NSlBHKSB8fCBJc0VxdWFsR1VJRCAoJnN1YnR5cGVfZ3VpZCwgJk1FRElBU1VCVFlQRV9UVk1KKSB8fCAgICAgLyogRklYTUU6IE5PVCB0ZXN0ZWQgKi8KICAgICAgSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfV0FLRSkgfHwgICAgICAgIC8qIEZJWE1FOiBOT1QgdGVzdGVkICovCiAgICAgIElzRXF1YWxHVUlEICgmc3VidHlwZV9ndWlkLCAmTUVESUFTVUJUWVBFX0NGQ0MpIHx8ICAgICAgICAvKiBGSVhNRTogTk9UIHRlc3RlZCAqLwogICAgICBJc0VxdWFsR1VJRCAoJnN1YnR5cGVfZ3VpZCwgJk1FRElBU1VCVFlQRV9JSlBHKSkgeyAgICAgICAgLyogRklYTUU6IE5PVCB0ZXN0ZWQgKi8KICAgIG1lZGlhX3R5cGUgPSAiaW1hZ2UvanBlZyI7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCAoJnN1YnR5cGVfZ3VpZCwgJk1FRElBU1VCVFlQRV9SR0I1NTUpKSB7CiAgICBtZWRpYV90eXBlID0gInZpZGVvL3gtcmF3IjsKICAgIGZvcm1hdCA9ICJSR0IxNSI7CiAgICBpc19yZ2IgPSBUUlVFOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfUkdCNTY1KSkgewogICAgbWVkaWFfdHlwZSA9ICJ2aWRlby94LXJhdyI7CiAgICBmb3JtYXQgPSAiUkdCMTYiOwogICAgaXNfcmdiID0gVFJVRTsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmc3VidHlwZV9ndWlkLCAmTUVESUFTVUJUWVBFX1JHQjI0KSkgewogICAgbWVkaWFfdHlwZSA9ICJ2aWRlby94LXJhdyI7CiAgICBmb3JtYXQgPSAiQkdSIjsKICAgIGlzX3JnYiA9IFRSVUU7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCAoJnN1YnR5cGVfZ3VpZCwgJk1FRElBU1VCVFlQRV9SR0IzMikpIHsKICAgIG1lZGlhX3R5cGUgPSAidmlkZW8veC1yYXciOwogICAgZm9ybWF0ID0gIkJHUngiOwogICAgaXNfcmdiID0gVFJVRTsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmc3VidHlwZV9ndWlkLCAmTUVESUFTVUJUWVBFX0FSR0IzMikpIHsKICAgIG1lZGlhX3R5cGUgPSAidmlkZW8veC1yYXciOwogICAgZm9ybWF0ID0gIkJHUkEiOwogICAgaXNfcmdiID0gVFJVRTsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmc3VidHlwZV9ndWlkLCAmTUVESUFTVUJUWVBFX0FSR0IxNTU1KSkgewogICAgR1NUX1dBUk5JTkcgKCJVbnN1cHBvcnRlZCB2aWRlbyBmb3JtYXQgQVJHQjE1NTU1Iik7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCAoJnN1YnR5cGVfZ3VpZCwgJk1FRElBU1VCVFlQRV9BUkdCNDQ0NCkpIHsKICAgIEdTVF9XQVJOSU5HICgiVW5zdXBwb3J0ZWQgdmlkZW8gZm9ybWF0IEFSR0I0NDQ0Iik7CiAgfSBlbHNlIGlmIChtZW1jbXAgKCZzdWJ0eXBlX2d1aWQuRGF0YTIsICZNRURJQVNVQlRZUEVfRk9VUkNDLkRhdGEyLAogICAgICAgICAgc2l6ZW9mIChzdWJ0eXBlX2d1aWQpIC0gc2l6ZW9mIChzdWJ0eXBlX2d1aWQuRGF0YTEpKSA9PSAwKSB7CiAgICBndWludDggKnAgPSAoZ3VpbnQ4ICopICYgc3VidHlwZV9ndWlkLkRhdGExOwogICAgZ2NoYXIgKmZvcm1hdCA9IGdfc3RyZHVwX3ByaW50ZiAoIiVjJWMlYyVjIiwgcFswXSwgcFsxXSwgcFsyXSwgcFszXSk7CiAgICBzdHJ1Y3R1cmUgPSBnc3Rfc3RydWN0dXJlX25ldyAoInZpZGVvL3gtcmF3IiwgImZvcm1hdCIsCiAgICAgICAgR19UWVBFX1NUUklORywgZm9ybWF0LCBOVUxMKTsKICAgIGdfZnJlZSAoZm9ybWF0KTsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmc3VidHlwZV9ndWlkLCAmTUVESUFTVUJUWVBFX2R2c2QpKSB7CiAgICBpZiAoSXNFcXVhbEdVSUQgKCZmb3JtYXRfZ3VpZCwgJkZPUk1BVF9EdkluZm8pKSB7CiAgICAgIHN0cnVjdHVyZSA9IGdzdF9zdHJ1Y3R1cmVfbmV3ICgidmlkZW8veC1kdiIsCiAgICAgICAgICAic3lzdGVtc3RyZWFtIiwgR19UWVBFX0JPT0xFQU4sIFRSVUUsIE5VTEwpOwogICAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCAoJmZvcm1hdF9ndWlkLCAmRk9STUFUX1ZpZGVvSW5mbykpIHsKICAgICAgc3RydWN0dXJlID0gZ3N0X3N0cnVjdHVyZV9uZXcgKCJ2aWRlby94LWR2IiwKICAgICAgICAgICJzeXN0ZW1zdHJlYW0iLCBHX1RZUEVfQk9PTEVBTiwgRkFMU0UsCiAgICAgICAgICAiZm9ybWF0IiwgR19UWVBFX1NUUklORywgImR2c2QiLCBOVUxMKTsKICAgIH0KICB9CgogIGlmIChtZWRpYV90eXBlKSB7CiAgICBzdHJ1Y3R1cmUgPSBnc3Rfc3RydWN0dXJlX25ld19lbXB0eSAobWVkaWFfdHlwZSk7CiAgICBpZiAoZm9ybWF0KSB7CiAgICAgIGdzdF9zdHJ1Y3R1cmVfc2V0IChzdHJ1Y3R1cmUsICJmb3JtYXQiLCBHX1RZUEVfU1RSSU5HLCBmb3JtYXQsIE5VTEwpOwogICAgfQogICAgaWYgKHBfaXNfcmdiKSB7CiAgICAgICpwX2lzX3JnYiA9IGlzX3JnYjsKICAgIH0KICB9CgogIGlmICghc3RydWN0dXJlKSB7CiAgICBHU1RfREVCVUcgKCJVbmtub3duIERpcmVjdFNob3cgVmlkZW8gR1VJRCAiCiAgICAgICAgIiUwOHgtJTA0eC0lMDR4LSUwMnglMDJ4LSUwMnglMDJ4JTAyeCUwMnglMDJ4JTAyeCIsCiAgICAgICAgKGd1aW50KSBzdWJ0eXBlX2d1aWQuRGF0YTEsIHN1YnR5cGVfZ3VpZC5EYXRhMiwgc3VidHlwZV9ndWlkLkRhdGEzLAogICAgICAgIHN1YnR5cGVfZ3VpZC5EYXRhNFswXSwgc3VidHlwZV9ndWlkLkRhdGE0WzFdLCBzdWJ0eXBlX2d1aWQuRGF0YTRbMl0sCiAgICAgICAgc3VidHlwZV9ndWlkLkRhdGE0WzNdLCBzdWJ0eXBlX2d1aWQuRGF0YTRbNF0sIHN1YnR5cGVfZ3VpZC5EYXRhNFs1XSwKICAgICAgICBzdWJ0eXBlX2d1aWQuRGF0YTRbNl0sIHN1YnR5cGVfZ3VpZC5EYXRhNFs3XSk7CiAgfQoKICByZXR1cm4gc3RydWN0dXJlOwp9CgpzdGF0aWMgdm9pZApndWVzc19hc3BlY3QgKGdpbnQgd2lkdGgsIGdpbnQgaGVpZ2h0LCBnaW50ICogcGFyX3dpZHRoLCBnaW50ICogcGFyX2hlaWdodCkKewogIC8qCiAgICogQXMgd2UgZG9udCBoYXZlIGFjY2VzcyB0byB0aGUgYWN0dWFsIHBpeGVsIGFzcGVjdCwgd2Ugd2lsbCB0cnkgdG8gZG8gYQogICAqIGJlc3QtZWZmb3J0IGd1ZXNzLiBUaGUgZ3Vlc3MgaXMgYmFzZWQgb24gbW9zdCBzZW5zb3JzIGJlaW5nIGVpdGhlciA0LzMKICAgKiBvciAxNi85LCBhbmQgbW9zdCBwaXhlbCBhc3BlY3RzIGJlaW5nIGNsb3NlIHRvIDEvMS4KICAgKi8KICBpZiAoKHdpZHRoID09IDc2OCkgJiYgKGhlaWdodCA9PSA0NDgpKSB7ICAgICAgLyogc3BlY2lhbCBjYXNlIGZvciB3NDQ4cCAqLwogICAgKnBhcl93aWR0aCA9IDI4OwogICAgKnBhcl9oZWlnaHQgPSAyNzsKICB9IGVsc2UgewogICAgaWYgKCgoZmxvYXQpIHdpZHRoIC8gKGZsb2F0KSBoZWlnaHQpIDwgMS4yNzc4KSB7CiAgICAgICpwYXJfd2lkdGggPSAxMjsKICAgICAgKnBhcl9oZWlnaHQgPSAxMTsKICAgIH0gZWxzZSB7CiAgICAgICpwYXJfd2lkdGggPSAxOwogICAgICAqcGFyX2hlaWdodCA9IDE7CiAgICB9CiAgfQp9CgovKiBOT1RFOiB3b3VsZCBwcm9iYWJseSBiZSBiZXR0ZXIgdG8gdXNlIGEgY29udGludWVkIGZyYWN0aW9ucyBhcHByb2FjaCBoZXJlICovCnN0YXRpYyB2b2lkCmNvbXByZXNzX2ZyYWN0aW9uIChnaW50NjQgaW5fbnVtLCBnaW50NjQgaW5fZGVuLCBnaW50NjQgKiBvdXRfbnVtLAogICAgZ2ludDY0ICogb3V0X2RlbikKewogIGdkb3VibGUgb24sIG9kLCBvcmlnOwogIGd1aW50IGRlbm9taW5hdG9yc1tdID0geyAxLCAyLCAzLCA1LCA3IH0sIGk7CiAgY29uc3QgZ2RvdWJsZSBtYXhfbG9zcyA9IDAuMTsKCiAgb24gPSBpbl9udW07CiAgb2QgPSBpbl9kZW47CiAgb3JpZyA9IG9uIC8gb2Q7CgogIGZvciAoaSA9IDA7IGkgPCBHX05fRUxFTUVOVFMgKGRlbm9taW5hdG9ycyk7IGkrKykgewogICAgZ2ludDY0IGN1cl9uLCBjdXJfZDsKICAgIGdkb3VibGUgY3VyLCBsb3NzOwoKICAgIGN1cl9uID0gZmxvb3IgKChvbiAvIChvZCAvIChnZG91YmxlKSBkZW5vbWluYXRvcnNbaV0pKSArIDAuNSk7CiAgICBjdXJfZCA9IGRlbm9taW5hdG9yc1tpXTsKICAgIGN1ciA9IChnZG91YmxlKSBjdXJfbiAvIChnZG91YmxlKSBjdXJfZDsKICAgIGxvc3MgPSBmYWJzIChjdXIgLSBvcmlnKTsKCiAgICBpZiAobG9zcyA8PSBtYXhfbG9zcykgewogICAgICAqb3V0X251bSA9IGN1cl9uOwogICAgICAqb3V0X2RlbiA9IGN1cl9kOwoKICAgICAgcmV0dXJuOwogICAgfQogIH0KCiAgKm91dF9udW0gPSBpbl9udW07CiAgKm91dF9kZW4gPSBpbl9kZW47Cn0KCnN0YXRpYyBnYm9vbGVhbgprc192aWRlb19hcHBlbmRfdmlkZW9fc3RyZWFtX2NmZ19maWVsZHMgKEdzdFN0cnVjdHVyZSAqIHN0cnVjdHVyZSwKICAgIGNvbnN0IEtTX1ZJREVPX1NUUkVBTV9DT05GSUdfQ0FQUyAqIHZzY2MpCnsKICBHVmFsdWUgdmFsID0geyAwLCB9OwogIGdpbnQ2NCBtaW5fbiwgbWluX2Q7CiAgZ2ludDY0IG1heF9uLCBtYXhfZDsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHN0cnVjdHVyZSwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsICh2c2NjLCBGQUxTRSk7CgogIC8qIHdpZHRoICovCiAgaWYgKHZzY2MtPk1pbk91dHB1dFNpemUuY3ggPT0gdnNjYy0+TWF4T3V0cHV0U2l6ZS5jeCkgewogICAgZ3N0X3N0cnVjdHVyZV9zZXQgKHN0cnVjdHVyZSwKICAgICAgICAid2lkdGgiLCBHX1RZUEVfSU5ULCB2c2NjLT5NYXhPdXRwdXRTaXplLmN4LCBOVUxMKTsKICB9IGVsc2UgewogICAgZ3N0X3N0cnVjdHVyZV9zZXQgKHN0cnVjdHVyZSwKICAgICAgICAid2lkdGgiLCBHU1RfVFlQRV9JTlRfUkFOR0UsCiAgICAgICAgdnNjYy0+TWluT3V0cHV0U2l6ZS5jeCwgdnNjYy0+TWF4T3V0cHV0U2l6ZS5jeCwgTlVMTCk7CiAgfQoKICAvKiBoZWlnaHQgKi8KICBpZiAodnNjYy0+TWluT3V0cHV0U2l6ZS5jeSA9PSB2c2NjLT5NYXhPdXRwdXRTaXplLmN5KSB7CiAgICBnc3Rfc3RydWN0dXJlX3NldCAoc3RydWN0dXJlLAogICAgICAgICJoZWlnaHQiLCBHX1RZUEVfSU5ULCB2c2NjLT5NYXhPdXRwdXRTaXplLmN5LCBOVUxMKTsKICB9IGVsc2UgewogICAgZ3N0X3N0cnVjdHVyZV9zZXQgKHN0cnVjdHVyZSwKICAgICAgICAiaGVpZ2h0IiwgR1NUX1RZUEVfSU5UX1JBTkdFLAogICAgICAgIHZzY2MtPk1pbk91dHB1dFNpemUuY3ksIHZzY2MtPk1heE91dHB1dFNpemUuY3ksIE5VTEwpOwogIH0KCiAgLyogZnJhbWVyYXRlICovCiAgY29tcHJlc3NfZnJhY3Rpb24gKE5BTk9TRUNPTkRTLCB2c2NjLT5NaW5GcmFtZUludGVydmFsLCAmbWluX24sICZtaW5fZCk7CiAgY29tcHJlc3NfZnJhY3Rpb24gKE5BTk9TRUNPTkRTLCB2c2NjLT5NYXhGcmFtZUludGVydmFsLCAmbWF4X24sICZtYXhfZCk7CgogIGlmIChtaW5fbiA9PSBtYXhfbiAmJiBtaW5fZCA9PSBtYXhfZCkgewogICAgZ192YWx1ZV9pbml0ICgmdmFsLCBHU1RfVFlQRV9GUkFDVElPTik7CiAgICBnc3RfdmFsdWVfc2V0X2ZyYWN0aW9uICgmdmFsLCBtYXhfbiwgbWF4X2QpOwogIH0gZWxzZSB7CiAgICBnX3ZhbHVlX2luaXQgKCZ2YWwsIEdTVF9UWVBFX0ZSQUNUSU9OX1JBTkdFKTsKICAgIGdzdF92YWx1ZV9zZXRfZnJhY3Rpb25fcmFuZ2VfZnVsbCAoJnZhbCwgbWF4X24sIG1heF9kLCBtaW5fbiwgbWluX2QpOwogIH0KCiAgZ3N0X3N0cnVjdHVyZV9zZXRfdmFsdWUgKHN0cnVjdHVyZSwgImZyYW1lcmF0ZSIsICZ2YWwpOwogIGdfdmFsdWVfdW5zZXQgKCZ2YWwpOwoKICB7CiAgICBnaW50IHBhcl93aWR0aCwgcGFyX2hlaWdodDsKCiAgICBndWVzc19hc3BlY3QgKHZzY2MtPk1heE91dHB1dFNpemUuY3gsIHZzY2MtPk1heE91dHB1dFNpemUuY3ksCiAgICAgICAgJnBhcl93aWR0aCwgJnBhcl9oZWlnaHQpOwoKICAgIGdzdF9zdHJ1Y3R1cmVfc2V0IChzdHJ1Y3R1cmUsCiAgICAgICAgInBpeGVsLWFzcGVjdC1yYXRpbyIsIEdTVF9UWVBFX0ZSQUNUSU9OLCBwYXJfd2lkdGgsIHBhcl9oZWlnaHQsIE5VTEwpOwogIH0KCiAgcmV0dXJuIFRSVUU7Cn0KCktzVmlkZW9NZWRpYVR5cGUgKgprc192aWRlb19tZWRpYV90eXBlX2R1cCAoS3NWaWRlb01lZGlhVHlwZSAqIG1lZGlhX3R5cGUpCnsKICBLc1ZpZGVvTWVkaWFUeXBlICpyZXN1bHQgPSBnX25ldyAoS3NWaWRlb01lZGlhVHlwZSwgMSk7CgogIG1lbWNweSAocmVzdWx0LCBtZWRpYV90eXBlLCBzaXplb2YgKEtzVmlkZW9NZWRpYVR5cGUpKTsKCiAgcmVzdWx0LT5yYW5nZSA9IGdfbWFsbG9jIChtZWRpYV90eXBlLT5yYW5nZS0+Rm9ybWF0U2l6ZSk7CiAgbWVtY3B5ICgoZ3BvaW50ZXIpIHJlc3VsdC0+cmFuZ2UsIG1lZGlhX3R5cGUtPnJhbmdlLAogICAgICBtZWRpYV90eXBlLT5yYW5nZS0+Rm9ybWF0U2l6ZSk7CgogIHJlc3VsdC0+Zm9ybWF0ID0gZ19tYWxsb2MgKG1lZGlhX3R5cGUtPmZvcm1hdF9zaXplKTsKICBtZW1jcHkgKHJlc3VsdC0+Zm9ybWF0LCBtZWRpYV90eXBlLT5mb3JtYXQsIG1lZGlhX3R5cGUtPmZvcm1hdF9zaXplKTsKCiAgcmVzdWx0LT50cmFuc2xhdGVkX2NhcHMgPSBnc3RfY2Fwc19yZWYgKG1lZGlhX3R5cGUtPnRyYW5zbGF0ZWRfY2Fwcyk7CgogIHJldHVybiByZXN1bHQ7Cn0KCnZvaWQKa3NfdmlkZW9fbWVkaWFfdHlwZV9mcmVlIChLc1ZpZGVvTWVkaWFUeXBlICogbWVkaWFfdHlwZSkKewogIGlmIChtZWRpYV90eXBlID09IE5VTEwpCiAgICByZXR1cm47CgogIGdfZnJlZSAoKGdwb2ludGVyKSBtZWRpYV90eXBlLT5yYW5nZSk7CgogIGdfZnJlZSAobWVkaWFfdHlwZS0+Zm9ybWF0KTsKCiAgaWYgKG1lZGlhX3R5cGUtPnRyYW5zbGF0ZWRfY2FwcyAhPSBOVUxMKQogICAgZ3N0X2NhcHNfdW5yZWYgKG1lZGlhX3R5cGUtPnRyYW5zbGF0ZWRfY2Fwcyk7CgogIGdfZnJlZSAobWVkaWFfdHlwZSk7Cn0KCnN0YXRpYyBHTGlzdCAqCmtzX3ZpZGVvX21lZGlhX3R5cGVfbGlzdF9yZW1vdmVfZHVwbGljYXRlcyAoR0xpc3QgKiBtZWRpYV90eXBlcykKewogIEdMaXN0ICptYXN0ZXIsICpkdXBsaWNhdGVzOwoKICBkbyB7CiAgICBHTGlzdCAqZW50cnk7CgogICAgbWFzdGVyID0gZHVwbGljYXRlcyA9IE5VTEw7CgogICAgLyogRmluZCB0aGUgZmlyc3Qgc2V0IG9mIGR1cGxpY2F0ZXMgYW5kIHRoZWlyIG1hc3RlciAqLwogICAgZm9yIChlbnRyeSA9IG1lZGlhX3R5cGVzOyBlbnRyeSAhPSBOVUxMICYmIGR1cGxpY2F0ZXMgPT0gTlVMTDsKICAgICAgICBlbnRyeSA9IGVudHJ5LT5uZXh0KSB7CiAgICAgIEtzVmlkZW9NZWRpYVR5cGUgKm10ID0gZW50cnktPmRhdGE7CiAgICAgIEdMaXN0ICpvdGhlcl9lbnRyeTsKCiAgICAgIGZvciAob3RoZXJfZW50cnkgPSBtZWRpYV90eXBlczsgb3RoZXJfZW50cnkgIT0gTlVMTDsKICAgICAgICAgIG90aGVyX2VudHJ5ID0gb3RoZXJfZW50cnktPm5leHQpIHsKICAgICAgICBLc1ZpZGVvTWVkaWFUeXBlICpvdGhlcl9tdCA9IG90aGVyX2VudHJ5LT5kYXRhOwoKICAgICAgICBpZiAob3RoZXJfbXQgPT0gbXQpCiAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgaWYgKGdzdF9jYXBzX2lzX2VxdWFsIChtdC0+dHJhbnNsYXRlZF9jYXBzLCBvdGhlcl9tdC0+dHJhbnNsYXRlZF9jYXBzKSkKICAgICAgICAgIGR1cGxpY2F0ZXMgPSBnX2xpc3RfcHJlcGVuZCAoZHVwbGljYXRlcywgb3RoZXJfbXQpOwogICAgICB9CgogICAgICBpZiAoZHVwbGljYXRlcyAhPSBOVUxMKQogICAgICAgIG1hc3RlciA9IGVudHJ5OwogICAgfQoKICAgIGlmIChkdXBsaWNhdGVzICE9IE5VTEwpIHsKICAgICAgS3NWaWRlb01lZGlhVHlwZSAqc2VsZWN0ZWRfbXQgPSBtYXN0ZXItPmRhdGE7CgogICAgICAvKgogICAgICAgKiBQaWNrIGEgRk9STUFUX1ZpZGVvSW5mbzIgaWYgcHJlc2VudCwgaWYgbm90IHdlIGp1c3Qgc3RheSB3aXRoIHRoZQogICAgICAgKiBmaXJzdCBlbnRyeQogICAgICAgKi8KICAgICAgZm9yIChlbnRyeSA9IGR1cGxpY2F0ZXM7IGVudHJ5ICE9IE5VTEw7IGVudHJ5ID0gZW50cnktPm5leHQpIHsKICAgICAgICBLc1ZpZGVvTWVkaWFUeXBlICptdCA9IGVudHJ5LT5kYXRhOwoKICAgICAgICBpZiAoSXNFcXVhbEdVSUQgKCZtdC0+cmFuZ2UtPlNwZWNpZmllciwgJkZPUk1BVF9WaWRlb0luZm8yKSkgewogICAgICAgICAga3NfdmlkZW9fbWVkaWFfdHlwZV9mcmVlIChzZWxlY3RlZF9tdCk7CiAgICAgICAgICBzZWxlY3RlZF9tdCA9IG10OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBrc192aWRlb19tZWRpYV90eXBlX2ZyZWUgKG10KTsKICAgICAgICB9CgogICAgICAgIC8qIFJlbW92ZSB0aGUgZHVwZSBmcm9tIHRoZSBtYWluIGxpc3QgKi8KICAgICAgICBtZWRpYV90eXBlcyA9IGdfbGlzdF9yZW1vdmUgKG1lZGlhX3R5cGVzLCBtdCk7CiAgICAgIH0KCiAgICAgIC8qIFVwZGF0ZSBtYXN0ZXIgbm9kZSB3aXRoIHRoZSBzZWxlY3RlZCBNZWRpYVR5cGUgKi8KICAgICAgbWFzdGVyLT5kYXRhID0gc2VsZWN0ZWRfbXQ7CgogICAgICBnX2xpc3RfZnJlZSAoZHVwbGljYXRlcyk7CiAgICB9CiAgfQogIHdoaWxlIChtYXN0ZXIgIT0gTlVMTCk7CgogIHJldHVybiBtZWRpYV90eXBlczsKfQoKR0xpc3QgKgprc192aWRlb19wcm9iZV9maWx0ZXJfZm9yX2NhcHMgKEhBTkRMRSBmaWx0ZXJfaGFuZGxlKQp7CiAgR0xpc3QgKnJldCA9IE5VTEw7CiAgZ3Vsb25nIHBpbl9jb3VudDsKICBndWludCBwaW5faWQ7CgogIGlmICgha3NfZmlsdGVyX2dldF9waW5fcHJvcGVydHkgKGZpbHRlcl9oYW5kbGUsIDAsIEtTUFJPUFNFVElEX1BpbiwKICAgICAgICAgIEtTUFJPUEVSVFlfUElOX0NUWVBFUywgJnBpbl9jb3VudCwgc2l6ZW9mIChwaW5fY291bnQpLCBOVUxMKSkKICAgIGdvdG8gYmVhY2g7CgogIEdTVF9ERUJVRyAoInBpbl9jb3VudCA9ICVsdSIsIHBpbl9jb3VudCk7CgogIGZvciAocGluX2lkID0gMDsgcGluX2lkIDwgcGluX2NvdW50OyBwaW5faWQrKykgewogICAgS1NQSU5fQ09NTVVOSUNBVElPTiBwaW5fY29tbTsKICAgIEtTUElOX0RBVEFGTE9XIHBpbl9mbG93OwogICAgR1VJRCBwaW5fY2F0OwoKICAgIGlmICgha3NfZmlsdGVyX2dldF9waW5fcHJvcGVydHkgKGZpbHRlcl9oYW5kbGUsIHBpbl9pZCwgS1NQUk9QU0VUSURfUGluLAogICAgICAgICAgICBLU1BST1BFUlRZX1BJTl9DT01NVU5JQ0FUSU9OLCAmcGluX2NvbW0sIHNpemVvZiAocGluX2NvbW0pLCBOVUxMKSkKICAgICAgY29udGludWU7CgogICAgaWYgKCFrc19maWx0ZXJfZ2V0X3Bpbl9wcm9wZXJ0eSAoZmlsdGVyX2hhbmRsZSwgcGluX2lkLCBLU1BST1BTRVRJRF9QaW4sCiAgICAgICAgICAgIEtTUFJPUEVSVFlfUElOX0RBVEFGTE9XLCAmcGluX2Zsb3csIHNpemVvZiAocGluX2Zsb3cpLCBOVUxMKSkKICAgICAgY29udGludWU7CgogICAgaWYgKCFrc19maWx0ZXJfZ2V0X3Bpbl9wcm9wZXJ0eSAoZmlsdGVyX2hhbmRsZSwgcGluX2lkLCBLU1BST1BTRVRJRF9QaW4sCiAgICAgICAgICAgIEtTUFJPUEVSVFlfUElOX0NBVEVHT1JZLCAmcGluX2NhdCwgc2l6ZW9mIChwaW5fY2F0KSwgTlVMTCkpCiAgICAgIGNvbnRpbnVlOwoKICAgIEdTVF9ERUJVRyAoInBpblsldV06IHBpbl9jb21tPSVkLCBwaW5fZmxvdz0lZCIsIHBpbl9pZCwgcGluX2NvbW0sIHBpbl9mbG93KTsKCiAgICBpZiAocGluX2Zsb3cgPT0gS1NQSU5fREFUQUZMT1dfT1VUICYmCiAgICAgICAgbWVtY21wICgmcGluX2NhdCwgJlBJTk5BTUVfQ0FQVFVSRSwgc2l6ZW9mIChHVUlEKSkgPT0gMCkgewogICAgICBLU01VTFRJUExFX0lURU0gKml0ZW1zOwoKICAgICAgaWYgKGtzX2ZpbHRlcl9nZXRfcGluX3Byb3BlcnR5X211bHRpIChmaWx0ZXJfaGFuZGxlLCBwaW5faWQsCiAgICAgICAgICAgICAgS1NQUk9QU0VUSURfUGluLCBLU1BST1BFUlRZX1BJTl9EQVRBUkFOR0VTLCAmaXRlbXMsIE5VTEwpKSB7CiAgICAgICAgS1NEQVRBUkFOR0UgKnJhbmdlID0gKEtTREFUQVJBTkdFICopIChpdGVtcyArIDEpOwogICAgICAgIGd1aW50IGk7CgogICAgICAgIGZvciAoaSA9IDA7IGkgPCBpdGVtcy0+Q291bnQ7IGkrKykgewogICAgICAgICAgaWYgKElzRXF1YWxHVUlEICgmcmFuZ2UtPk1ham9yRm9ybWF0LCAmTUVESUFUWVBFX1ZpZGVvKQogICAgICAgICAgICAgIHx8IElzRXF1YWxHVUlEICgmcmFuZ2UtPk1ham9yRm9ybWF0LCAmTUVESUFUWVBFX0ludGVybGVhdmVkKSkgewogICAgICAgICAgICBLc1ZpZGVvTWVkaWFUeXBlICplbnRyeTsKICAgICAgICAgICAgZ3BvaW50ZXIgc3JjX3ZzY2MsIHNyY19mb3JtYXQ7CiAgICAgICAgICAgIEdzdFN0cnVjdHVyZSAqbWVkaWFfc3RydWN0dXJlOwoKICAgICAgICAgICAgZW50cnkgPSBnX25ldzAgKEtzVmlkZW9NZWRpYVR5cGUsIDEpOwogICAgICAgICAgICBlbnRyeS0+cGluX2lkID0gcGluX2lkOwoKICAgICAgICAgICAgZW50cnktPnJhbmdlID0gZ19tYWxsb2MgKHJhbmdlLT5Gb3JtYXRTaXplKTsKICAgICAgICAgICAgbWVtY3B5ICgoZ3BvaW50ZXIpIGVudHJ5LT5yYW5nZSwgcmFuZ2UsIHJhbmdlLT5Gb3JtYXRTaXplKTsKCiAgICAgICAgICAgIGlmIChJc0VxdWFsR1VJRCAoJnJhbmdlLT5TcGVjaWZpZXIsICZGT1JNQVRfVmlkZW9JbmZvKSkgewogICAgICAgICAgICAgIEtTX0RBVEFSQU5HRV9WSURFTyAqdnIgPSAoS1NfREFUQVJBTkdFX1ZJREVPICopIGVudHJ5LT5yYW5nZTsKCiAgICAgICAgICAgICAgc3JjX3ZzY2MgPSAmdnItPkNvbmZpZ0NhcHM7CiAgICAgICAgICAgICAgc3JjX2Zvcm1hdCA9ICZ2ci0+VmlkZW9JbmZvSGVhZGVyOwoKICAgICAgICAgICAgICBlbnRyeS0+Zm9ybWF0X3NpemUgPSBzaXplb2YgKHZyLT5WaWRlb0luZm9IZWFkZXIpOwogICAgICAgICAgICAgIGVudHJ5LT5zYW1wbGVfc2l6ZSA9IHZyLT5WaWRlb0luZm9IZWFkZXIuYm1pSGVhZGVyLmJpU2l6ZUltYWdlOwogICAgICAgICAgICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmcmFuZ2UtPlNwZWNpZmllciwgJkZPUk1BVF9WaWRlb0luZm8yKSkgewogICAgICAgICAgICAgIEtTX0RBVEFSQU5HRV9WSURFTzIgKnZyID0gKEtTX0RBVEFSQU5HRV9WSURFTzIgKikgZW50cnktPnJhbmdlOwoKICAgICAgICAgICAgICBzcmNfdnNjYyA9ICZ2ci0+Q29uZmlnQ2FwczsKICAgICAgICAgICAgICBzcmNfZm9ybWF0ID0gJnZyLT5WaWRlb0luZm9IZWFkZXI7CgogICAgICAgICAgICAgIGVudHJ5LT5mb3JtYXRfc2l6ZSA9IHNpemVvZiAodnItPlZpZGVvSW5mb0hlYWRlcik7CiAgICAgICAgICAgICAgZW50cnktPnNhbXBsZV9zaXplID0gdnItPlZpZGVvSW5mb0hlYWRlci5ibWlIZWFkZXIuYmlTaXplSW1hZ2U7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZyYW5nZS0+U3BlY2lmaWVyLCAmRk9STUFUX01QRUdWaWRlbykpIHsKICAgICAgICAgICAgICAvKiBVbnRlc3RlZCBhbmQgcHJvYmFibHkgd3JvbmcuLi4gKi8KICAgICAgICAgICAgICBLU19EQVRBUkFOR0VfTVBFRzFfVklERU8gKnZyID0KICAgICAgICAgICAgICAgICAgKEtTX0RBVEFSQU5HRV9NUEVHMV9WSURFTyAqKSBlbnRyeS0+cmFuZ2U7CgogICAgICAgICAgICAgIHNyY192c2NjID0gJnZyLT5Db25maWdDYXBzOwogICAgICAgICAgICAgIHNyY19mb3JtYXQgPSAmdnItPlZpZGVvSW5mb0hlYWRlcjsKCiAgICAgICAgICAgICAgZW50cnktPmZvcm1hdF9zaXplID0gc2l6ZW9mICh2ci0+VmlkZW9JbmZvSGVhZGVyKTsKICAgICAgICAgICAgICBlbnRyeS0+c2FtcGxlX3NpemUgPQogICAgICAgICAgICAgICAgICB2ci0+VmlkZW9JbmZvSGVhZGVyLmhkci5ibWlIZWFkZXIuYmlTaXplSW1hZ2U7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZyYW5nZS0+U3BlY2lmaWVyLCAmRk9STUFUX01QRUcyVmlkZW8pKSB7CiAgICAgICAgICAgICAgS1NfREFUQVJBTkdFX01QRUcyX1ZJREVPICp2ciA9CiAgICAgICAgICAgICAgICAgIChLU19EQVRBUkFOR0VfTVBFRzJfVklERU8gKikgZW50cnktPnJhbmdlOwogICAgICAgICAgICAgIHNyY192c2NjID0gJnZyLT5Db25maWdDYXBzOwogICAgICAgICAgICAgIHNyY19mb3JtYXQgPSAmdnItPlZpZGVvSW5mb0hlYWRlcjsKCiAgICAgICAgICAgICAgZW50cnktPmZvcm1hdF9zaXplID0gc2l6ZW9mICh2ci0+VmlkZW9JbmZvSGVhZGVyKTsKICAgICAgICAgICAgICBlbnRyeS0+c2FtcGxlX3NpemUgPQogICAgICAgICAgICAgICAgICB2ci0+VmlkZW9JbmZvSGVhZGVyLmhkci5ibWlIZWFkZXIuYmlTaXplSW1hZ2U7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZyYW5nZS0+U3BlY2lmaWVyLCAmRk9STUFUX0R2SW5mbykpIHsKICAgICAgICAgICAgICBLU19EQVRBUkFOR0VfRFZWSURFTyAqdnIgPSAoS1NfREFUQVJBTkdFX0RWVklERU8gKikgZW50cnktPnJhbmdlOwoKICAgICAgICAgICAgICBzcmNfdnNjYyA9IE5VTEw7CiAgICAgICAgICAgICAgc3JjX2Zvcm1hdCA9ICZ2ci0+RFZWaWRlb0luZm87CgogICAgICAgICAgICAgIGVudHJ5LT5mb3JtYXRfc2l6ZSA9IHNpemVvZiAodnItPkRWVmlkZW9JbmZvKTsKICAgICAgICAgICAgICBlbnRyeS0+c2FtcGxlX3NpemUgPSB2ci0+RGF0YVJhbmdlLlNhbXBsZVNpemU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZ2NoYXIgKmd1aWRfc3RyOwoKICAgICAgICAgICAgICBndWlkX3N0ciA9IGtzX2d1aWRfdG9fc3RyaW5nICgmcmFuZ2UtPlNwZWNpZmllcik7CiAgICAgICAgICAgICAgR1NUX0RFQlVHICgicGluWyV1XTogaWdub3JpbmcgdW5rbm93biBzcGVjaWZpZXIgR1VJRCAlcyIsCiAgICAgICAgICAgICAgICAgIHBpbl9pZCwgZ3VpZF9zdHIpOwogICAgICAgICAgICAgIGdfZnJlZSAoZ3VpZF9zdHIpOwoKICAgICAgICAgICAgICBrc192aWRlb19tZWRpYV90eXBlX2ZyZWUgKGVudHJ5KTsKICAgICAgICAgICAgICBlbnRyeSA9IE5VTEw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChlbnRyeSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgZ19hc3NlcnQgKGVudHJ5LT5zYW1wbGVfc2l6ZSAhPSAwKTsKCiAgICAgICAgICAgICAgaWYgKHNyY192c2NjICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIG1lbWNweSAoKGdwb2ludGVyKSAmIGVudHJ5LT52c2NjLCBzcmNfdnNjYywKICAgICAgICAgICAgICAgICAgICBzaXplb2YgKGVudHJ5LT52c2NjKSk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBlbnRyeS0+Zm9ybWF0ID0gZ19tYWxsb2MgKGVudHJ5LT5mb3JtYXRfc2l6ZSk7CiAgICAgICAgICAgICAgbWVtY3B5IChlbnRyeS0+Zm9ybWF0LCBzcmNfZm9ybWF0LCBlbnRyeS0+Zm9ybWF0X3NpemUpOwoKICAgICAgICAgICAgICBtZWRpYV9zdHJ1Y3R1cmUgPQogICAgICAgICAgICAgICAgICBrc192aWRlb19mb3JtYXRfdG9fc3RydWN0dXJlIChyYW5nZS0+U3ViRm9ybWF0LAogICAgICAgICAgICAgICAgICByYW5nZS0+U3BlY2lmaWVyLCAmZW50cnktPmlzX3JnYik7CgogICAgICAgICAgICAgIGlmIChtZWRpYV9zdHJ1Y3R1cmUgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgZ193YXJuaW5nICgia3NfdmlkZW9fZm9ybWF0X3RvX3N0cnVjdHVyZSByZXR1cm5lZCBOVUxMIik7CiAgICAgICAgICAgICAgICBrc192aWRlb19tZWRpYV90eXBlX2ZyZWUgKGVudHJ5KTsKICAgICAgICAgICAgICAgIGVudHJ5ID0gTlVMTDsKICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNyY192c2NjID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIGVudHJ5LT50cmFuc2xhdGVkX2NhcHMgPSBnc3RfY2Fwc19uZXdfZW1wdHkgKCk7CiAgICAgICAgICAgICAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChlbnRyeS0+dHJhbnNsYXRlZF9jYXBzLAogICAgICAgICAgICAgICAgICAgIG1lZGlhX3N0cnVjdHVyZSk7CiAgICAgICAgICAgICAgfSBlbHNlIGlmIChrc192aWRlb19hcHBlbmRfdmlkZW9fc3RyZWFtX2NmZ19maWVsZHMKICAgICAgICAgICAgICAgICAgKG1lZGlhX3N0cnVjdHVyZSwgJmVudHJ5LT52c2NjKSkgewogICAgICAgICAgICAgICAgZW50cnktPnRyYW5zbGF0ZWRfY2FwcyA9IGdzdF9jYXBzX25ld19lbXB0eSAoKTsKICAgICAgICAgICAgICAgIGdzdF9jYXBzX2FwcGVuZF9zdHJ1Y3R1cmUgKGVudHJ5LT50cmFuc2xhdGVkX2NhcHMsCiAgICAgICAgICAgICAgICAgICAgbWVkaWFfc3RydWN0dXJlKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ3N0X3N0cnVjdHVyZV9mcmVlIChtZWRpYV9zdHJ1Y3R1cmUpOwogICAgICAgICAgICAgICAga3NfdmlkZW9fbWVkaWFfdHlwZV9mcmVlIChlbnRyeSk7CiAgICAgICAgICAgICAgICBlbnRyeSA9IE5VTEw7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBpZiAoZW50cnkgIT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldCA9IGdfbGlzdF9wcmVwZW5kIChyZXQsIGVudHJ5KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIC8qIFJFVklTSVQ6IEVhY2ggS1NEQVRBUkFOR0Ugc2hvdWxkIHN0YXJ0IG9uIGEgNjQtYml0IGJvdW5kYXJ5ICovCiAgICAgICAgICByYW5nZSA9IChLU0RBVEFSQU5HRSAqKSAoKChndWNoYXIgKikgcmFuZ2UpICsgcmFuZ2UtPkZvcm1hdFNpemUpOwogICAgICAgIH0KCiAgICAgICAgZ19mcmVlIChpdGVtcyk7CiAgICAgIH0KICAgIH0KICB9CgogIGlmIChyZXQgIT0gTlVMTCkgewogICAgcmV0ID0gZ19saXN0X3JldmVyc2UgKHJldCk7CiAgICByZXQgPSBrc192aWRlb19tZWRpYV90eXBlX2xpc3RfcmVtb3ZlX2R1cGxpY2F0ZXMgKHJldCk7CiAgfQoKYmVhY2g6CiAgcmV0dXJuIHJldDsKfQoKS1NQSU5fQ09OTkVDVCAqCmtzX3ZpZGVvX2NyZWF0ZV9waW5fY29ubl9mcm9tX21lZGlhX3R5cGUgKEtzVmlkZW9NZWRpYVR5cGUgKiBtZWRpYV90eXBlKQp7CiAgS1NQSU5fQ09OTkVDVCAqY29ubiA9IE5VTEw7CiAgS1NEQVRBRk9STUFUICpmb3JtYXQgPSBOVUxMOwogIGd1aW50OCAqdmloOwoKICBjb25uID0gZ19tYWxsb2MwIChzaXplb2YgKEtTUElOX0NPTk5FQ1QpICsgc2l6ZW9mIChLU0RBVEFGT1JNQVQpICsKICAgICAgbWVkaWFfdHlwZS0+Zm9ybWF0X3NpemUpOwoKICBjb25uLT5JbnRlcmZhY2UuU2V0ID0gS1NJTlRFUkZBQ0VTRVRJRF9TdGFuZGFyZDsKICBjb25uLT5JbnRlcmZhY2UuSWQgPSBLU0lOVEVSRkFDRV9TVEFOREFSRF9TVFJFQU1JTkc7CiAgY29ubi0+SW50ZXJmYWNlLkZsYWdzID0gMDsKCiAgY29ubi0+TWVkaXVtLlNldCA9IEtTTUVESVVNU0VUSURfU3RhbmRhcmQ7CiAgY29ubi0+TWVkaXVtLklkID0gS1NNRURJVU1fVFlQRV9BTllJTlNUQU5DRTsKICBjb25uLT5NZWRpdW0uRmxhZ3MgPSAwOwoKICBjb25uLT5QaW5JZCA9IG1lZGlhX3R5cGUtPnBpbl9pZDsKICBjb25uLT5QaW5Ub0hhbmRsZSA9IE5VTEw7CiAgY29ubi0+UHJpb3JpdHkuUHJpb3JpdHlDbGFzcyA9IEtTUFJJT1JJVFlfTk9STUFMOwogIGNvbm4tPlByaW9yaXR5LlByaW9yaXR5U3ViQ2xhc3MgPSBLU1BSSU9SSVRZX05PUk1BTDsKCiAgZm9ybWF0ID0gKEtTREFUQUZPUk1BVCAqKSAoY29ubiArIDEpOwogIG1lbWNweSAoZm9ybWF0LCBtZWRpYV90eXBlLT5yYW5nZSwgc2l6ZW9mIChLU0RBVEFGT1JNQVQpKTsKICBmb3JtYXQtPkZvcm1hdFNpemUgPSBzaXplb2YgKEtTREFUQUZPUk1BVCkgKyBtZWRpYV90eXBlLT5mb3JtYXRfc2l6ZTsKCiAgdmloID0gKGd1aW50OCAqKSAoZm9ybWF0ICsgMSk7CiAgbWVtY3B5ICh2aWgsIG1lZGlhX3R5cGUtPmZvcm1hdCwgbWVkaWFfdHlwZS0+Zm9ybWF0X3NpemUpOwoKICByZXR1cm4gY29ubjsKfQoKZ2Jvb2xlYW4Ka3NfdmlkZW9fZml4YXRlX21lZGlhX3R5cGUgKGNvbnN0IEtTREFUQVJBTkdFICogcmFuZ2UsCiAgICBndWludDggKiBmb3JtYXQsIGdpbnQgd2lkdGgsIGdpbnQgaGVpZ2h0LCBnaW50IGZwc19uLCBnaW50IGZwc19kKQp7CiAgS1NfREFUQVJBTkdFX1ZJREVPICp2cjsKICBLU19WSURFT0lORk9IRUFERVIgKnZpaDsKICBLU19CSVRNQVBJTkZPSEVBREVSICpiaWg7CiAgRFdPUkQgZHdSYXRlOwoKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZm9ybWF0ICE9IE5VTEwsIEZBTFNFKTsKCiAgaWYgKElzRXF1YWxHVUlEICgmcmFuZ2UtPlNwZWNpZmllciwgJkZPUk1BVF9WaWRlb0luZm8pKSB7CiAgICBiaWggPSAmKChLU19WSURFT0lORk9IRUFERVIgKikgZm9ybWF0KS0+Ym1pSGVhZGVyOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZyYW5nZS0+U3BlY2lmaWVyLCAmRk9STUFUX1ZpZGVvSW5mbzIpKSB7CiAgICBiaWggPSAmKChLU19WSURFT0lORk9IRUFERVIyICopIGZvcm1hdCktPmJtaUhlYWRlcjsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmcmFuZ2UtPlNwZWNpZmllciwgJkZPUk1BVF9NUEVHVmlkZW8pKSB7CiAgICBiaWggPSAmKChLU19NUEVHMVZJREVPSU5GTyAqKSBmb3JtYXQpLT5oZHIuYm1pSGVhZGVyOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZyYW5nZS0+U3BlY2lmaWVyLCAmRk9STUFUX01QRUcyVmlkZW8pKSB7CiAgICBiaWggPSAmKChLU19NUEVHVklERU9JTkZPMiAqKSBmb3JtYXQpLT5oZHIuYm1pSGVhZGVyOwogIH0gZWxzZSB7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICAvKiBUaGVzZSBmb3JtYXRzJyBzdHJ1Y3R1cmVzIHNoYXJlIHRoZSBtb3N0IGJhc2ljIHN0dWZmICovCiAgdnIgPSAoS1NfREFUQVJBTkdFX1ZJREVPICopIHJhbmdlOwogIHZpaCA9IChLU19WSURFT0lORk9IRUFERVIgKikgZm9ybWF0OwoKICAvKiBGSVhNRTogTmVlZCB0byBmaWd1cmUgb3V0IGhvdyB0byBwcm9wZXJseSBoYW5kbGUgcmFuZ2VzICovCiAgaWYgKGJpaC0+YmlXaWR0aCAhPSB3aWR0aCB8fCBiaWgtPmJpSGVpZ2h0ICE9IGhlaWdodCkKICAgIHJldHVybiBGQUxTRTsKCiAgLyogRnJhbWVyYXRlLCBjbGFtcGVkIGJlY2F1c2Ugb2YgZnJhY3Rpb24gY29udmVyc2lvbiByb3VuZGluZyBlcnJvcnMgKi8KICB2aWgtPkF2Z1RpbWVQZXJGcmFtZSA9CiAgICAgIGdzdF91dGlsX3VpbnQ2NF9zY2FsZV9pbnRfcm91bmQgKE5BTk9TRUNPTkRTLCBmcHNfZCwgZnBzX24pOwogIHZpaC0+QXZnVGltZVBlckZyYW1lID0KICAgICAgTUFYICh2aWgtPkF2Z1RpbWVQZXJGcmFtZSwgdnItPkNvbmZpZ0NhcHMuTWluRnJhbWVJbnRlcnZhbCk7CiAgdmloLT5BdmdUaW1lUGVyRnJhbWUgPQogICAgICBNSU4gKHZpaC0+QXZnVGltZVBlckZyYW1lLCB2ci0+Q29uZmlnQ2Fwcy5NYXhGcmFtZUludGVydmFsKTsKCiAgLyogQml0cmF0ZSwgY2xhbXBlZCBmb3IgdGhlIHNhbWUgcmVhc29uIGFzIGZyYW1lcmF0ZSAqLwogIGR3UmF0ZSA9ICh3aWR0aCAqIGhlaWdodCAqIGZwc19uKSAvIGZwc19kOwogIHZpaC0+ZHdCaXRSYXRlID0gZHdSYXRlICogYmloLT5iaUJpdENvdW50OwogIHZpaC0+ZHdCaXRSYXRlID0gTUFYICh2aWgtPmR3Qml0UmF0ZSwgdnItPkNvbmZpZ0NhcHMuTWluQml0c1BlclNlY29uZCk7CiAgdmloLT5kd0JpdFJhdGUgPSBNSU4gKHZpaC0+ZHdCaXRSYXRlLCB2ci0+Q29uZmlnQ2Fwcy5NYXhCaXRzUGVyU2Vjb25kKTsKCiAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBHc3RTdHJ1Y3R1cmUgKgprc192aWRlb19hcHBlbmRfdmFyX3ZpZGVvX2ZpZWxkcyAoR3N0U3RydWN0dXJlICogc3RydWN0dXJlKQp7CiAgaWYgKHN0cnVjdHVyZSkgewogICAgZ3N0X3N0cnVjdHVyZV9zZXQgKHN0cnVjdHVyZSwKICAgICAgICAid2lkdGgiLCBHU1RfVFlQRV9JTlRfUkFOR0UsIDEsIEdfTUFYSU5ULAogICAgICAgICJoZWlnaHQiLCBHU1RfVFlQRV9JTlRfUkFOR0UsIDEsIEdfTUFYSU5ULAogICAgICAgICJmcmFtZXJhdGUiLCBHU1RfVFlQRV9GUkFDVElPTl9SQU5HRSwgMCwgMSwgR19NQVhJTlQsIDEsIE5VTEwpOwogIH0KCiAgcmV0dXJuIHN0cnVjdHVyZTsKfQoKR3N0Q2FwcyAqCmtzX3ZpZGVvX2dldF9hbGxfY2FwcyAodm9pZCkKewogIHN0YXRpYyBHc3RDYXBzICpjYXBzID0gTlVMTDsKCiAgaWYgKGNhcHMgPT0gTlVMTCkgewogICAgR3N0U3RydWN0dXJlICpzdHJ1Y3R1cmU7CiAgICBjYXBzID0gZ3N0X2NhcHNfbmV3X2VtcHR5ICgpOwoKICAgIC8qIGZyb20gV2luZG93cyBTREsgNi4wIHV1aWRzLmggKi8KICAgIC8qIFJHQiBmb3JtYXRzICovCiAgICBzdHJ1Y3R1cmUgPQogICAgICAgIGtzX3ZpZGVvX2FwcGVuZF92YXJfdmlkZW9fZmllbGRzIChrc192aWRlb19mb3JtYXRfdG9fc3RydWN0dXJlCiAgICAgICAgKE1FRElBU1VCVFlQRV9SR0I1NTUsIEZPUk1BVF9WaWRlb0luZm8sIE5VTEwpKTsKICAgIGdzdF9jYXBzX2FwcGVuZF9zdHJ1Y3R1cmUgKGNhcHMsIHN0cnVjdHVyZSk7CgogICAgc3RydWN0dXJlID0KICAgICAgICBrc192aWRlb19hcHBlbmRfdmFyX3ZpZGVvX2ZpZWxkcyAoa3NfdmlkZW9fZm9ybWF0X3RvX3N0cnVjdHVyZQogICAgICAgIChNRURJQVNVQlRZUEVfUkdCNTY1LCBGT1JNQVRfVmlkZW9JbmZvLCBOVUxMKSk7CiAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChjYXBzLCBzdHJ1Y3R1cmUpOwoKICAgIHN0cnVjdHVyZSA9CiAgICAgICAga3NfdmlkZW9fYXBwZW5kX3Zhcl92aWRlb19maWVsZHMgKGtzX3ZpZGVvX2Zvcm1hdF90b19zdHJ1Y3R1cmUKICAgICAgICAoTUVESUFTVUJUWVBFX1JHQjI0LCBGT1JNQVRfVmlkZW9JbmZvLCBOVUxMKSk7CiAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChjYXBzLCBzdHJ1Y3R1cmUpOwoKICAgIHN0cnVjdHVyZSA9CiAgICAgICAga3NfdmlkZW9fYXBwZW5kX3Zhcl92aWRlb19maWVsZHMgKGtzX3ZpZGVvX2Zvcm1hdF90b19zdHJ1Y3R1cmUKICAgICAgICAoTUVESUFTVUJUWVBFX1JHQjMyLCBGT1JNQVRfVmlkZW9JbmZvLCBOVUxMKSk7CiAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChjYXBzLCBzdHJ1Y3R1cmUpOwoKICAgIC8qIFlVViBmb3JtYXRzICovCiAgICBzdHJ1Y3R1cmUgPQogICAgICAgIGtzX3ZpZGVvX2FwcGVuZF92YXJfdmlkZW9fZmllbGRzIChnc3Rfc3RydWN0dXJlX25ld19lbXB0eQogICAgICAgICgidmlkZW8veC1yYXciKSk7CiAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChjYXBzLCBzdHJ1Y3R1cmUpOwoKICAgIC8qIE90aGVyIGZvcm1hdHMgKi8KICAgIHN0cnVjdHVyZSA9CiAgICAgICAga3NfdmlkZW9fYXBwZW5kX3Zhcl92aWRlb19maWVsZHMgKGtzX3ZpZGVvX2Zvcm1hdF90b19zdHJ1Y3R1cmUKICAgICAgICAoTUVESUFTVUJUWVBFX01KUEcsIEZPUk1BVF9WaWRlb0luZm8sIE5VTEwpKTsKICAgIGdzdF9jYXBzX2FwcGVuZF9zdHJ1Y3R1cmUgKGNhcHMsIHN0cnVjdHVyZSk7CgogICAgc3RydWN0dXJlID0KICAgICAgICBrc192aWRlb19hcHBlbmRfdmFyX3ZpZGVvX2ZpZWxkcyAoa3NfdmlkZW9fZm9ybWF0X3RvX3N0cnVjdHVyZQogICAgICAgIChNRURJQVNVQlRZUEVfZHZzZCwgRk9STUFUX1ZpZGVvSW5mbywgTlVMTCkpOwogICAgZ3N0X2NhcHNfYXBwZW5kX3N0cnVjdHVyZSAoY2Fwcywgc3RydWN0dXJlKTsKCiAgICBzdHJ1Y3R1cmUgPSAgICAgICAgICAgICAgICAgLyogbm8gdmFyaWFibGUgdmlkZW8gZmllbGRzICh3aWR0aCwgaGVpZ2h0LCBmcmFtZXJhdGUpICovCiAgICAgICAga3NfdmlkZW9fZm9ybWF0X3RvX3N0cnVjdHVyZSAoTUVESUFTVUJUWVBFX2R2c2QsIEZPUk1BVF9EdkluZm8sIE5VTEwpOwogICAgZ3N0X2NhcHNfYXBwZW5kX3N0cnVjdHVyZSAoY2Fwcywgc3RydWN0dXJlKTsKICB9CgogIHJldHVybiBjYXBzOwp9Cg==