LyoKICogUlBDIHRyYW5zcG9ydCBsYXllcgogKgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKiBDb3B5cmlnaHQgMjAwMyBNaWtlIEhlYXJuCiAqIENvcHlyaWdodCAyMDA0IEZpbGlwIE5hdmFyYQogKiBDb3B5cmlnaHQgMjAwNiBNaWtlIE1jQ29ybWFjawogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPGVycm5vLmg+CgojaWZkZWYgSEFWRV9VTklTVERfSAojIGluY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfU09DS0VUX0gKIyBpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNlbmRpZgojaWZkZWYgSEFWRV9ORVRJTkVUX0lOX0gKIyBpbmNsdWRlIDxuZXRpbmV0L2luLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9BUlBBX0lORVRfSAojIGluY2x1ZGUgPGFycGEvaW5ldC5oPgojZW5kaWYKI2lmZGVmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbnRlcm5sLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgInJwY25kci5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlICJycGNfYmluZGluZy5oIgojaW5jbHVkZSAicnBjX21lc3NhZ2UuaCIKI2luY2x1ZGUgImVwbV90b3dlcnMuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHJwYyk7CgpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBjb25uZWN0aW9uX3Bvb2xfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNvbm5lY3Rpb25fcG9vbF9jc19kZWJ1ZyA9CnsKICAgIDAsIDAsICZjb25uZWN0aW9uX3Bvb2xfY3MsCiAgICB7ICZjb25uZWN0aW9uX3Bvb2xfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNvbm5lY3Rpb25fcG9vbF9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAgIDAsIDAsIHsgKERXT1JEX1BUUikoX19GSUxFX18gIjogY29ubmVjdGlvbl9wb29sIikgfQp9OwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBjb25uZWN0aW9uX3Bvb2xfY3MgPSB7ICZjb25uZWN0aW9uX3Bvb2xfY3NfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07CgpzdGF0aWMgc3RydWN0IGxpc3QgY29ubmVjdGlvbl9wb29sID0gTElTVF9JTklUKGNvbm5lY3Rpb25fcG9vbCk7CgovKioqKiBuY2Fjbl9ucCBzdXBwb3J0ICoqKiovCgp0eXBlZGVmIHN0cnVjdCBfUnBjQ29ubmVjdGlvbl9ucAp7CiAgUnBjQ29ubmVjdGlvbiBjb21tb247CiAgSEFORExFIHBpcGUsIHRocmVhZDsKICBPVkVSTEFQUEVEIG92bDsKfSBScGNDb25uZWN0aW9uX25wOwoKc3RhdGljIFJwY0Nvbm5lY3Rpb24gKnJwY3J0NF9jb25uX25wX2FsbG9jKHZvaWQpCnsKICByZXR1cm4gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihScGNDb25uZWN0aW9uX25wKSk7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIHJwY3J0NF9jb25uZWN0X3BpcGUoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwgTFBDU1RSIHBuYW1lKQp7CiAgUnBjQ29ubmVjdGlvbl9ucCAqbnBjID0gKFJwY0Nvbm5lY3Rpb25fbnAgKikgQ29ubmVjdGlvbjsKICBUUkFDRSgibGlzdGVuaW5nIG9uICVzXG4iLCBwbmFtZSk7CgogIG5wYy0+cGlwZSA9IENyZWF0ZU5hbWVkUGlwZUEocG5hbWUsIFBJUEVfQUNDRVNTX0RVUExFWCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBJUEVfVFlQRV9NRVNTQUdFIHwgUElQRV9SRUFETU9ERV9NRVNTQUdFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUElQRV9VTkxJTUlURURfSU5TVEFOQ0VTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX01BWF9QQUNLRVRfU0laRSwgUlBDX01BWF9QQUNLRVRfU0laRSwgNTAwMCwgTlVMTCk7CiAgaWYgKG5wYy0+cGlwZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgewogICAgV0FSTigiQ3JlYXRlTmFtZWRQaXBlIGZhaWxlZCB3aXRoIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKICB9CgogIG1lbXNldCgmbnBjLT5vdmwsIDAsIHNpemVvZihucGMtPm92bCkpOwogIG5wYy0+b3ZsLmhFdmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgaWYgKENvbm5lY3ROYW1lZFBpcGUobnBjLT5waXBlLCAmbnBjLT5vdmwpKQogICAgIHJldHVybiBSUENfU19PSzsKCiAgV0FSTigiQ291bGRuJ3QgQ29ubmVjdE5hbWVkUGlwZSAoZXJyb3Igd2FzICVsZClcbiIsIEdldExhc3RFcnJvcigpKTsKICBpZiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfUElQRV9DT05ORUNURUQpIHsKICAgIFNldEV2ZW50KG5wYy0+b3ZsLmhFdmVudCk7CiAgICByZXR1cm4gUlBDX1NfT0s7CiAgfQogIGlmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9JT19QRU5ESU5HKSB7CiAgICAvKiBGSVhNRTogbG9va3MgbGlrZSB3ZSBuZWVkIHRvIEdldE92ZXJsYXBwZWRSZXN1bHQgaGVyZT8gKi8KICAgIHJldHVybiBSUENfU19PSzsKICB9CiAgcmV0dXJuIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X29wZW5fcGlwZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLCBMUENTVFIgcG5hbWUsIEJPT0wgd2FpdCkKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgSEFORExFIHBpcGU7CiAgRFdPUkQgZXJyLCBkd01vZGU7CgogIFRSQUNFKCJjb25uZWN0aW5nIHRvICVzXG4iLCBwbmFtZSk7CgogIHdoaWxlIChUUlVFKSB7CiAgICBwaXBlID0gQ3JlYXRlRmlsZUEocG5hbWUsIEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFLCAwLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgIE9QRU5fRVhJU1RJTkcsIDAsIDApOwogICAgaWYgKHBpcGUgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIGJyZWFrOwogICAgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICBpZiAoZXJyID09IEVSUk9SX1BJUEVfQlVTWSkgewogICAgICBUUkFDRSgiY29ubmVjdGlvbiBmYWlsZWQsIGVycm9yPSVseFxuIiwgZXJyKTsKICAgICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9UT09fQlVTWTsKICAgIH0KICAgIGlmICghd2FpdCkKICAgICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKICAgIGlmICghV2FpdE5hbWVkUGlwZUEocG5hbWUsIE5NUFdBSVRfV0FJVF9GT1JFVkVSKSkgewogICAgICBlcnIgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgV0FSTigiY29ubmVjdGlvbiBmYWlsZWQsIGVycm9yPSVseFxuIiwgZXJyKTsKICAgICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKICAgIH0KICB9CgogIC8qIHN1Y2Nlc3MgKi8KICBtZW1zZXQoJm5wYy0+b3ZsLCAwLCBzaXplb2YobnBjLT5vdmwpKTsKICAvKiBwaXBlIGlzIGNvbm5lY3RlZDsgY2hhbmdlIHRvIG1lc3NhZ2UtcmVhZCBtb2RlLiAqLwogIGR3TW9kZSA9IFBJUEVfUkVBRE1PREVfTUVTU0FHRTsKICBTZXROYW1lZFBpcGVIYW5kbGVTdGF0ZShwaXBlLCAmZHdNb2RlLCBOVUxMLCBOVUxMKTsKICBucGMtPm92bC5oRXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogIG5wYy0+cGlwZSA9IHBpcGU7CgogIHJldHVybiBSUENfU19PSzsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X25jYWxycGNfb3BlbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgUnBjQ29ubmVjdGlvbl9ucCAqbnBjID0gKFJwY0Nvbm5lY3Rpb25fbnAgKikgQ29ubmVjdGlvbjsKICBzdGF0aWMgTFBDU1RSIHByZWZpeCA9ICJcXFxcLlxccGlwZVxcbHJwY1xcIjsKICBSUENfU1RBVFVTIHI7CiAgTFBTVFIgcG5hbWU7CgogIC8qIGFscmVhZHkgY29ubmVjdGVkPyAqLwogIGlmIChucGMtPnBpcGUpCiAgICByZXR1cm4gUlBDX1NfT0s7CgogIC8qIHByb3RzZXE9bmNhbHJwYzogc3VwcG9zZWQgdG8gdXNlIE5UIExQQyBwb3J0cywKICAgKiBidXQgd2UnbGwgaW1wbGVtZW50IGl0IHdpdGggbmFtZWQgcGlwZXMgZm9yIG5vdyAqLwogIHBuYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihwcmVmaXgpICsgc3RybGVuKENvbm5lY3Rpb24tPkVuZHBvaW50KSArIDEpOwogIHN0cmNhdChzdHJjcHkocG5hbWUsIHByZWZpeCksIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKCiAgaWYgKENvbm5lY3Rpb24tPnNlcnZlcikKICAgIHIgPSBycGNydDRfY29ubmVjdF9waXBlKENvbm5lY3Rpb24sIHBuYW1lKTsKICBlbHNlCiAgICByID0gcnBjcnQ0X29wZW5fcGlwZShDb25uZWN0aW9uLCBwbmFtZSwgVFJVRSk7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwoKICByZXR1cm4gcjsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X25jYWNuX25wX29wZW4oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgc3RhdGljIExQQ1NUUiBwcmVmaXggPSAiXFxcXC4iOwogIFJQQ19TVEFUVVMgcjsKICBMUFNUUiBwbmFtZTsKCiAgLyogYWxyZWFkeSBjb25uZWN0ZWQ/ICovCiAgaWYgKG5wYy0+cGlwZSkKICAgIHJldHVybiBSUENfU19PSzsKCiAgLyogcHJvdHNlcT1uY2Fjbl9ucDogbmFtZWQgcGlwZXMgKi8KICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgaWYgKENvbm5lY3Rpb24tPnNlcnZlcikKICAgIHIgPSBycGNydDRfY29ubmVjdF9waXBlKENvbm5lY3Rpb24sIHBuYW1lKTsKICBlbHNlCiAgICByID0gcnBjcnQ0X29wZW5fcGlwZShDb25uZWN0aW9uLCBwbmFtZSwgRkFMU0UpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKCiAgcmV0dXJuIHI7Cn0KCnN0YXRpYyBIQU5ETEUgcnBjcnQ0X2Nvbm5fbnBfZ2V0X2Nvbm5lY3RfZXZlbnQoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgcmV0dXJuIG5wYy0+b3ZsLmhFdmVudDsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X2Nvbm5fbnBfaGFuZG9mZihScGNDb25uZWN0aW9uICpvbGRfY29ubiwgUnBjQ29ubmVjdGlvbiAqbmV3X2Nvbm4pCnsKICBScGNDb25uZWN0aW9uX25wICpvbGRfbnBjID0gKFJwY0Nvbm5lY3Rpb25fbnAgKikgb2xkX2Nvbm47CiAgUnBjQ29ubmVjdGlvbl9ucCAqbmV3X25wYyA9IChScGNDb25uZWN0aW9uX25wICopIG5ld19jb25uOwogIC8qIGJlY2F1c2Ugb2YgdGhlIHdheSBuYW1lZCBwaXBlcyB3b3JrLCB3ZSdsbCB0cmFuc2ZlciB0aGUgY29ubmVjdGVkIHBpcGUKICAgKiB0byB0aGUgY2hpbGQsIHRoZW4gcmVvcGVuIHRoZSBzZXJ2ZXIgYmluZGluZyB0byBjb250aW51ZSBsaXN0ZW5pbmcgKi8KCiAgbmV3X25wYy0+cGlwZSA9IG9sZF9ucGMtPnBpcGU7CiAgbmV3X25wYy0+b3ZsID0gb2xkX25wYy0+b3ZsOwogIG9sZF9ucGMtPnBpcGUgPSAwOwogIG1lbXNldCgmb2xkX25wYy0+b3ZsLCAwLCBzaXplb2Yob2xkX25wYy0+b3ZsKSk7CiAgcmV0dXJuIFJQQ1JUNF9PcGVuQ29ubmVjdGlvbihvbGRfY29ubik7Cn0KCnN0YXRpYyBpbnQgcnBjcnQ0X2Nvbm5fbnBfcmVhZChScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBjb3VudCkKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgRFdPUkQgZHdSZWFkID0gMDsKICBpZiAoIVJlYWRGaWxlKG5wYy0+cGlwZSwgYnVmZmVyLCBjb3VudCwgJmR3UmVhZCwgTlVMTCkgJiYKICAgICAgKEdldExhc3RFcnJvcigpICE9IEVSUk9SX01PUkVfREFUQSkpCiAgICByZXR1cm4gLTE7CiAgcmV0dXJuIGR3UmVhZDsKfQoKc3RhdGljIGludCBycGNydDRfY29ubl9ucF93cml0ZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgaW50IGNvdW50KQp7CiAgUnBjQ29ubmVjdGlvbl9ucCAqbnBjID0gKFJwY0Nvbm5lY3Rpb25fbnAgKikgQ29ubmVjdGlvbjsKICBEV09SRCBkd1dyaXR0ZW4gPSAwOwogIGlmICghV3JpdGVGaWxlKG5wYy0+cGlwZSwgYnVmZmVyLCBjb3VudCwgJmR3V3JpdHRlbiwgTlVMTCkpCiAgICByZXR1cm4gLTE7CiAgcmV0dXJuIGR3V3JpdHRlbjsKfQoKc3RhdGljIGludCBycGNydDRfY29ubl9ucF9jbG9zZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uKQp7CiAgUnBjQ29ubmVjdGlvbl9ucCAqbnBjID0gKFJwY0Nvbm5lY3Rpb25fbnAgKikgQ29ubmVjdGlvbjsKICBpZiAobnBjLT5waXBlKSB7CiAgICBGbHVzaEZpbGVCdWZmZXJzKG5wYy0+cGlwZSk7CiAgICBDbG9zZUhhbmRsZShucGMtPnBpcGUpOwogICAgbnBjLT5waXBlID0gMDsKICB9CiAgaWYgKG5wYy0+b3ZsLmhFdmVudCkgewogICAgQ2xvc2VIYW5kbGUobnBjLT5vdmwuaEV2ZW50KTsKICAgIG5wYy0+b3ZsLmhFdmVudCA9IDA7CiAgfQogIHJldHVybiAwOwp9CgpzdGF0aWMgc2l6ZV90IHJwY3J0NF9uY2Fjbl9ucF9nZXRfdG9wX29mX3Rvd2VyKHVuc2lnbmVkIGNoYXIgKnRvd2VyX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmV0d29ya2FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5kcG9pbnQpCnsKICAgIHR3cl9lbXB0eV9mbG9vcl90ICpzbWJfZmxvb3I7CiAgICB0d3JfZW1wdHlfZmxvb3JfdCAqbmJfZmxvb3I7CiAgICBzaXplX3Qgc2l6ZTsKICAgIHNpemVfdCBuZXR3b3JrYWRkcl9zaXplOwogICAgc2l6ZV90IGVuZHBvaW50X3NpemU7CgogICAgVFJBQ0UoIiglcCwgJXMsICVzKVxuIiwgdG93ZXJfZGF0YSwgbmV0d29ya2FkZHIsIGVuZHBvaW50KTsKCiAgICBuZXR3b3JrYWRkcl9zaXplID0gc3RybGVuKG5ldHdvcmthZGRyKSArIDE7CiAgICBlbmRwb2ludF9zaXplID0gc3RybGVuKGVuZHBvaW50KSArIDE7CiAgICBzaXplID0gc2l6ZW9mKCpzbWJfZmxvb3IpICsgZW5kcG9pbnRfc2l6ZSArIHNpemVvZigqbmJfZmxvb3IpICsgbmV0d29ya2FkZHJfc2l6ZTsKCiAgICBpZiAoIXRvd2VyX2RhdGEpCiAgICAgICAgcmV0dXJuIHNpemU7CgogICAgc21iX2Zsb29yID0gKHR3cl9lbXB0eV9mbG9vcl90ICopdG93ZXJfZGF0YTsKCiAgICB0b3dlcl9kYXRhICs9IHNpemVvZigqc21iX2Zsb29yKTsKCiAgICBzbWJfZmxvb3ItPmNvdW50X2xocyA9IHNpemVvZihzbWJfZmxvb3ItPnByb3RpZCk7CiAgICBzbWJfZmxvb3ItPnByb3RpZCA9IEVQTV9QUk9UT0NPTF9TTUI7CiAgICBzbWJfZmxvb3ItPmNvdW50X3JocyA9IGVuZHBvaW50X3NpemU7CgogICAgbWVtY3B5KHRvd2VyX2RhdGEsIGVuZHBvaW50LCBlbmRwb2ludF9zaXplKTsKICAgIHRvd2VyX2RhdGEgKz0gZW5kcG9pbnRfc2l6ZTsKCiAgICBuYl9mbG9vciA9ICh0d3JfZW1wdHlfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CgogICAgdG93ZXJfZGF0YSArPSBzaXplb2YoKm5iX2Zsb29yKTsKCiAgICBuYl9mbG9vci0+Y291bnRfbGhzID0gc2l6ZW9mKG5iX2Zsb29yLT5wcm90aWQpOwogICAgbmJfZmxvb3ItPnByb3RpZCA9IEVQTV9QUk9UT0NPTF9ORVRCSU9TOwogICAgbmJfZmxvb3ItPmNvdW50X3JocyA9IG5ldHdvcmthZGRyX3NpemU7CgogICAgbWVtY3B5KHRvd2VyX2RhdGEsIG5ldHdvcmthZGRyLCBuZXR3b3JrYWRkcl9zaXplKTsKICAgIHRvd2VyX2RhdGEgKz0gbmV0d29ya2FkZHJfc2l6ZTsKCiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X25jYWNuX25wX3BhcnNlX3RvcF9vZl90b3dlcihjb25zdCB1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCB0b3dlcl9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKipuZXR3b3JrYWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICoqZW5kcG9pbnQpCnsKICAgIGNvbnN0IHR3cl9lbXB0eV9mbG9vcl90ICpzbWJfZmxvb3IgPSAoY29uc3QgdHdyX2VtcHR5X2Zsb29yX3QgKil0b3dlcl9kYXRhOwogICAgY29uc3QgdHdyX2VtcHR5X2Zsb29yX3QgKm5iX2Zsb29yOwoKICAgIFRSQUNFKCIoJXAsICVkLCAlcCwgJXApXG4iLCB0b3dlcl9kYXRhLCAoaW50KXRvd2VyX3NpemUsIG5ldHdvcmthZGRyLCBlbmRwb2ludCk7CgogICAgaWYgKHRvd2VyX3NpemUgPCBzaXplb2YoKnNtYl9mbG9vcikpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIHRvd2VyX2RhdGEgKz0gc2l6ZW9mKCpzbWJfZmxvb3IpOwogICAgdG93ZXJfc2l6ZSAtPSBzaXplb2YoKnNtYl9mbG9vcik7CgogICAgaWYgKChzbWJfZmxvb3ItPmNvdW50X2xocyAhPSBzaXplb2Yoc21iX2Zsb29yLT5wcm90aWQpKSB8fAogICAgICAgIChzbWJfZmxvb3ItPnByb3RpZCAhPSBFUE1fUFJPVE9DT0xfU01CKSB8fAogICAgICAgIChzbWJfZmxvb3ItPmNvdW50X3JocyA+IHRvd2VyX3NpemUpKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICBpZiAoZW5kcG9pbnQpCiAgICB7CiAgICAgICAgKmVuZHBvaW50ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNtYl9mbG9vci0+Y291bnRfcmhzKTsKICAgICAgICBpZiAoISplbmRwb2ludCkKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgbWVtY3B5KCplbmRwb2ludCwgdG93ZXJfZGF0YSwgc21iX2Zsb29yLT5jb3VudF9yaHMpOwogICAgfQogICAgdG93ZXJfZGF0YSArPSBzbWJfZmxvb3ItPmNvdW50X3JoczsKICAgIHRvd2VyX3NpemUgLT0gc21iX2Zsb29yLT5jb3VudF9yaHM7CgogICAgaWYgKHRvd2VyX3NpemUgPCBzaXplb2YoKm5iX2Zsb29yKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgbmJfZmxvb3IgPSAoY29uc3QgdHdyX2VtcHR5X2Zsb29yX3QgKil0b3dlcl9kYXRhOwoKICAgIHRvd2VyX2RhdGEgKz0gc2l6ZW9mKCpuYl9mbG9vcik7CiAgICB0b3dlcl9zaXplIC09IHNpemVvZigqbmJfZmxvb3IpOwoKICAgIGlmICgobmJfZmxvb3ItPmNvdW50X2xocyAhPSBzaXplb2YobmJfZmxvb3ItPnByb3RpZCkpIHx8CiAgICAgICAgKG5iX2Zsb29yLT5wcm90aWQgIT0gRVBNX1BST1RPQ09MX05FVEJJT1MpIHx8CiAgICAgICAgKG5iX2Zsb29yLT5jb3VudF9yaHMgPiB0b3dlcl9zaXplKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgaWYgKG5ldHdvcmthZGRyKQogICAgewogICAgICAgICpuZXR3b3JrYWRkciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBuYl9mbG9vci0+Y291bnRfcmhzKTsKICAgICAgICBpZiAoISpuZXR3b3JrYWRkcikKICAgICAgICB7CiAgICAgICAgICAgIGlmIChlbmRwb2ludCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKmVuZHBvaW50KTsKICAgICAgICAgICAgICAgICplbmRwb2ludCA9IE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgfQogICAgICAgIG1lbWNweSgqbmV0d29ya2FkZHIsIHRvd2VyX2RhdGEsIG5iX2Zsb29yLT5jb3VudF9yaHMpOwogICAgfQoKICAgIHJldHVybiBSUENfU19PSzsKfQoKc3RhdGljIHNpemVfdCBycGNydDRfbmNhbHJwY19nZXRfdG9wX29mX3Rvd2VyKHVuc2lnbmVkIGNoYXIgKnRvd2VyX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuZXR3b3JrYWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVuZHBvaW50KQp7CiAgICB0d3JfZW1wdHlfZmxvb3JfdCAqcGlwZV9mbG9vcjsKICAgIHNpemVfdCBzaXplOwogICAgc2l6ZV90IGVuZHBvaW50X3NpemU7CgogICAgVFJBQ0UoIiglcCwgJXMsICVzKVxuIiwgdG93ZXJfZGF0YSwgbmV0d29ya2FkZHIsIGVuZHBvaW50KTsKCiAgICBlbmRwb2ludF9zaXplID0gc3RybGVuKG5ldHdvcmthZGRyKSArIDE7CiAgICBzaXplID0gc2l6ZW9mKCpwaXBlX2Zsb29yKSArIGVuZHBvaW50X3NpemU7CgogICAgaWYgKCF0b3dlcl9kYXRhKQogICAgICAgIHJldHVybiBzaXplOwoKICAgIHBpcGVfZmxvb3IgPSAodHdyX2VtcHR5X2Zsb29yX3QgKil0b3dlcl9kYXRhOwoKICAgIHRvd2VyX2RhdGEgKz0gc2l6ZW9mKCpwaXBlX2Zsb29yKTsKCiAgICBwaXBlX2Zsb29yLT5jb3VudF9saHMgPSBzaXplb2YocGlwZV9mbG9vci0+cHJvdGlkKTsKICAgIHBpcGVfZmxvb3ItPnByb3RpZCA9IEVQTV9QUk9UT0NPTF9TTUI7CiAgICBwaXBlX2Zsb29yLT5jb3VudF9yaHMgPSBlbmRwb2ludF9zaXplOwoKICAgIG1lbWNweSh0b3dlcl9kYXRhLCBlbmRwb2ludCwgZW5kcG9pbnRfc2l6ZSk7CiAgICB0b3dlcl9kYXRhICs9IGVuZHBvaW50X3NpemU7CgogICAgcmV0dXJuIHNpemU7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIHJwY3J0NF9uY2FscnBjX3BhcnNlX3RvcF9vZl90b3dlcihjb25zdCB1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHRvd2VyX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICoqbmV0d29ya2FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICoqZW5kcG9pbnQpCnsKICAgIGNvbnN0IHR3cl9lbXB0eV9mbG9vcl90ICpwaXBlX2Zsb29yID0gKGNvbnN0IHR3cl9lbXB0eV9mbG9vcl90ICopdG93ZXJfZGF0YTsKCiAgICBUUkFDRSgiKCVwLCAlZCwgJXAsICVwKVxuIiwgdG93ZXJfZGF0YSwgKGludCl0b3dlcl9zaXplLCBuZXR3b3JrYWRkciwgZW5kcG9pbnQpOwoKICAgICpuZXR3b3JrYWRkciA9IE5VTEw7CiAgICAqZW5kcG9pbnQgPSBOVUxMOwoKICAgIGlmICh0b3dlcl9zaXplIDwgc2l6ZW9mKCpwaXBlX2Zsb29yKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgdG93ZXJfZGF0YSArPSBzaXplb2YoKnBpcGVfZmxvb3IpOwogICAgdG93ZXJfc2l6ZSAtPSBzaXplb2YoKnBpcGVfZmxvb3IpOwoKICAgIGlmICgocGlwZV9mbG9vci0+Y291bnRfbGhzICE9IHNpemVvZihwaXBlX2Zsb29yLT5wcm90aWQpKSB8fAogICAgICAgIChwaXBlX2Zsb29yLT5wcm90aWQgIT0gRVBNX1BST1RPQ09MX1NNQikgfHwKICAgICAgICAocGlwZV9mbG9vci0+Y291bnRfcmhzID4gdG93ZXJfc2l6ZSkpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIGlmIChlbmRwb2ludCkKICAgIHsKICAgICAgICAqZW5kcG9pbnQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGlwZV9mbG9vci0+Y291bnRfcmhzKTsKICAgICAgICBpZiAoISplbmRwb2ludCkKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgbWVtY3B5KCplbmRwb2ludCwgdG93ZXJfZGF0YSwgcGlwZV9mbG9vci0+Y291bnRfcmhzKTsKICAgIH0KCiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqIG5jYWNuX2lwX3RjcCBzdXBwb3J0ICoqKiovCgp0eXBlZGVmIHN0cnVjdCBfUnBjQ29ubmVjdGlvbl90Y3AKewogIFJwY0Nvbm5lY3Rpb24gY29tbW9uOwogIGludCBzb2NrOwp9IFJwY0Nvbm5lY3Rpb25fdGNwOwoKc3RhdGljIFJwY0Nvbm5lY3Rpb24gKnJwY3J0NF9jb25uX3RjcF9hbGxvYyh2b2lkKQp7CiAgUnBjQ29ubmVjdGlvbl90Y3AgKnRjcGM7CiAgdGNwYyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUnBjQ29ubmVjdGlvbl90Y3ApKTsKICB0Y3BjLT5zb2NrID0gLTE7CiAgcmV0dXJuICZ0Y3BjLT5jb21tb247Cn0KCnN0YXRpYyBSUENfU1RBVFVTIHJwY3J0NF9uY2Fjbl9pcF90Y3Bfb3BlbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgUnBjQ29ubmVjdGlvbl90Y3AgKnRjcGMgPSAoUnBjQ29ubmVjdGlvbl90Y3AgKikgQ29ubmVjdGlvbjsKICBpbnQgc29jazsKICBpbnQgcmV0OwogIHN0cnVjdCBhZGRyaW5mbyAqYWk7CiAgc3RydWN0IGFkZHJpbmZvICphaV9jdXI7CiAgc3RydWN0IGFkZHJpbmZvIGhpbnRzOwoKICBUUkFDRSgiKCVzLCAlcylcbiIsIENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CgogIGlmIChDb25uZWN0aW9uLT5zZXJ2ZXIpCiAgewogICAgRVJSKCJuY2Fjbl9pcF90Y3Agc2VydmVycyBub3Qgc3VwcG9ydGVkIHlldFxuIik7CiAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwogIH0KCiAgaWYgKHRjcGMtPnNvY2sgIT0gLTEpCiAgICByZXR1cm4gUlBDX1NfT0s7CgogIGhpbnRzLmFpX2ZsYWdzICAgICAgICAgID0gMDsKICBoaW50cy5haV9mYW1pbHkgICAgICAgICA9IFBGX1VOU1BFQzsKICBoaW50cy5haV9zb2NrdHlwZSAgICAgICA9IFNPQ0tfU1RSRUFNOwogIGhpbnRzLmFpX3Byb3RvY29sICAgICAgID0gSVBQUk9UT19UQ1A7CiAgaGludHMuYWlfYWRkcmxlbiAgICAgICAgPSAwOwogIGhpbnRzLmFpX2FkZHIgICAgICAgICAgID0gTlVMTDsKICBoaW50cy5haV9jYW5vbm5hbWUgICAgICA9IE5VTEw7CiAgaGludHMuYWlfbmV4dCAgICAgICAgICAgPSBOVUxMOwoKICByZXQgPSBnZXRhZGRyaW5mbyhDb25uZWN0aW9uLT5OZXR3b3JrQWRkciwgQ29ubmVjdGlvbi0+RW5kcG9pbnQsICZoaW50cywgJmFpKTsKICBpZiAocmV0KQogIHsKICAgIEVSUigiZ2V0YWRkcmluZm8gZmFpbGVkOiAlc1xuIiwgZ2FpX3N0cmVycm9yKHJldCkpOwogICAgcmV0dXJuIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKICB9CgogIGZvciAoYWlfY3VyID0gYWk7IGFpX2N1cjsgYWlfY3VyID0gYWktPmFpX25leHQpCiAgewogICAgaWYgKFRSQUNFX09OKHJwYykpCiAgICB7CiAgICAgIGNoYXIgaG9zdFsyNTZdOwogICAgICBjaGFyIHNlcnZpY2VbMjU2XTsKICAgICAgZ2V0bmFtZWluZm8oYWlfY3VyLT5haV9hZGRyLCBhaV9jdXItPmFpX2FkZHJsZW4sCiAgICAgICAgaG9zdCwgc2l6ZW9mKGhvc3QpLCBzZXJ2aWNlLCBzaXplb2Yoc2VydmljZSksCiAgICAgICAgTklfTlVNRVJJQ0hPU1QgfCBOSV9OVU1FUklDU0VSVik7CiAgICAgIFRSQUNFKCJ0cnlpbmcgJXM6JXNcbiIsIGhvc3QsIHNlcnZpY2UpOwogICAgfQoKICAgIHNvY2sgPSBzb2NrZXQoYWlfY3VyLT5haV9mYW1pbHksIGFpX2N1ci0+YWlfc29ja3R5cGUsIGFpX2N1ci0+YWlfcHJvdG9jb2wpOwogICAgaWYgKHNvY2sgPCAwKQogICAgewogICAgICBXQVJOKCJzb2NrZXQoKSBmYWlsZWRcbiIpOwogICAgICBjb250aW51ZTsKICAgIH0KCiAgICBpZiAoMD5jb25uZWN0KHNvY2ssIGFpX2N1ci0+YWlfYWRkciwgYWlfY3VyLT5haV9hZGRybGVuKSkKICAgIHsKICAgICAgV0FSTigiY29ubmVjdCgpIGZhaWxlZFxuIik7CiAgICAgIGNsb3NlKHNvY2spOwogICAgICBjb250aW51ZTsKICAgIH0KCiAgICB0Y3BjLT5zb2NrID0gc29jazsKCiAgICBmcmVlYWRkcmluZm8oYWkpOwogICAgVFJBQ0UoImNvbm5lY3RlZFxuIik7CiAgICByZXR1cm4gUlBDX1NfT0s7CiAgfQoKICBmcmVlYWRkcmluZm8oYWkpOwogIEVSUigiY291bGRuJ3QgY29ubmVjdCB0byAlczolc1xuIiwgQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIsIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwp9CgpzdGF0aWMgSEFORExFIHJwY3J0NF9jb25uX3RjcF9nZXRfd2FpdF9oYW5kbGUoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbikKewogIGFzc2VydCgwKTsKICByZXR1cm4gMDsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X2Nvbm5fdGNwX2hhbmRvZmYoUnBjQ29ubmVjdGlvbiAqb2xkX2Nvbm4sIFJwY0Nvbm5lY3Rpb24gKm5ld19jb25uKQp7CiAgYXNzZXJ0KDApOwogIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7Cn0KCnN0YXRpYyBpbnQgcnBjcnQ0X2Nvbm5fdGNwX3JlYWQoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBjb3VudCkKewogIFJwY0Nvbm5lY3Rpb25fdGNwICp0Y3BjID0gKFJwY0Nvbm5lY3Rpb25fdGNwICopIENvbm5lY3Rpb247CiAgaW50IHIgPSByZWN2KHRjcGMtPnNvY2ssIGJ1ZmZlciwgY291bnQsIE1TR19XQUlUQUxMKTsKICBUUkFDRSgiJWQgJXAgJXUgLT4gJWRcbiIsIHRjcGMtPnNvY2ssIGJ1ZmZlciwgY291bnQsIHIpOwogIHJldHVybiByOwp9CgpzdGF0aWMgaW50IHJwY3J0NF9jb25uX3RjcF93cml0ZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBjb3VudCkKewogIFJwY0Nvbm5lY3Rpb25fdGNwICp0Y3BjID0gKFJwY0Nvbm5lY3Rpb25fdGNwICopIENvbm5lY3Rpb247CiAgaW50IHIgPSB3cml0ZSh0Y3BjLT5zb2NrLCBidWZmZXIsIGNvdW50KTsKICBUUkFDRSgiJWQgJXAgJXUgLT4gJWRcbiIsIHRjcGMtPnNvY2ssIGJ1ZmZlciwgY291bnQsIHIpOwogIHJldHVybiByOwp9CgpzdGF0aWMgaW50IHJwY3J0NF9jb25uX3RjcF9jbG9zZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uKQp7CiAgUnBjQ29ubmVjdGlvbl90Y3AgKnRjcGMgPSAoUnBjQ29ubmVjdGlvbl90Y3AgKikgQ29ubmVjdGlvbjsKCiAgVFJBQ0UoIiVkXG4iLCB0Y3BjLT5zb2NrKTsKICBpZiAodGNwYy0+c29jayAhPSAtMSkKICAgIGNsb3NlKHRjcGMtPnNvY2spOwogIHRjcGMtPnNvY2sgPSAtMTsKICByZXR1cm4gMDsKfQoKc3RhdGljIHNpemVfdCBycGNydDRfbmNhY25faXBfdGNwX2dldF90b3Bfb2ZfdG93ZXIodW5zaWduZWQgY2hhciAqdG93ZXJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmV0d29ya2FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVuZHBvaW50KQp7CiAgICB0d3JfdGNwX2Zsb29yX3QgKnRjcF9mbG9vcjsKICAgIHR3cl9pcHY0X2Zsb29yX3QgKmlwdjRfZmxvb3I7CiAgICBzdHJ1Y3QgYWRkcmluZm8gKmFpOwogICAgc3RydWN0IGFkZHJpbmZvIGhpbnRzOwogICAgaW50IHJldDsKICAgIHNpemVfdCBzaXplID0gc2l6ZW9mKCp0Y3BfZmxvb3IpICsgc2l6ZW9mKCppcHY0X2Zsb29yKTsKCiAgICBUUkFDRSgiKCVwLCAlcywgJXMpXG4iLCB0b3dlcl9kYXRhLCBuZXR3b3JrYWRkciwgZW5kcG9pbnQpOwoKICAgIGlmICghdG93ZXJfZGF0YSkKICAgICAgICByZXR1cm4gc2l6ZTsKCiAgICB0Y3BfZmxvb3IgPSAodHdyX3RjcF9mbG9vcl90ICopdG93ZXJfZGF0YTsKICAgIHRvd2VyX2RhdGEgKz0gc2l6ZW9mKCp0Y3BfZmxvb3IpOwoKICAgIGlwdjRfZmxvb3IgPSAodHdyX2lwdjRfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CgogICAgdGNwX2Zsb29yLT5jb3VudF9saHMgPSBzaXplb2YodGNwX2Zsb29yLT5wcm90aWQpOwogICAgdGNwX2Zsb29yLT5wcm90aWQgPSBFUE1fUFJPVE9DT0xfVENQOwogICAgdGNwX2Zsb29yLT5jb3VudF9yaHMgPSBzaXplb2YodGNwX2Zsb29yLT5wb3J0KTsKCiAgICBpcHY0X2Zsb29yLT5jb3VudF9saHMgPSBzaXplb2YoaXB2NF9mbG9vci0+cHJvdGlkKTsKICAgIGlwdjRfZmxvb3ItPnByb3RpZCA9IEVQTV9QUk9UT0NPTF9JUDsKICAgIGlwdjRfZmxvb3ItPmNvdW50X3JocyA9IHNpemVvZihpcHY0X2Zsb29yLT5pcHY0YWRkcik7CgogICAgaGludHMuYWlfZmxhZ3MgICAgICAgICAgPSBBSV9OVU1FUklDSE9TVDsKICAgIC8qIEZJWE1FOiBvbmx5IHN1cHBvcnQgSVB2NCBhdCB0aGUgbW9tZW50LiBob3cgaXMgSVB2NiByZXByZXNlbnRlZCBieSB0aGUgRVBNPyAqLwogICAgaGludHMuYWlfZmFtaWx5ICAgICAgICAgPSBQRl9JTkVUOwogICAgaGludHMuYWlfc29ja3R5cGUgICAgICAgPSBTT0NLX1NUUkVBTTsKICAgIGhpbnRzLmFpX3Byb3RvY29sICAgICAgID0gSVBQUk9UT19UQ1A7CiAgICBoaW50cy5haV9hZGRybGVuICAgICAgICA9IDA7CiAgICBoaW50cy5haV9hZGRyICAgICAgICAgICA9IE5VTEw7CiAgICBoaW50cy5haV9jYW5vbm5hbWUgICAgICA9IE5VTEw7CiAgICBoaW50cy5haV9uZXh0ICAgICAgICAgICA9IE5VTEw7CgogICAgcmV0ID0gZ2V0YWRkcmluZm8obmV0d29ya2FkZHIsIGVuZHBvaW50LCAmaGludHMsICZhaSk7CiAgICBpZiAocmV0KQogICAgewogICAgICAgIHJldCA9IGdldGFkZHJpbmZvKCIwLjAuMC4wIiwgZW5kcG9pbnQsICZoaW50cywgJmFpKTsKICAgICAgICBpZiAocmV0KQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJnZXRhZGRyaW5mbyBmYWlsZWQ6ICVzXG4iLCBnYWlfc3RyZXJyb3IocmV0KSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoYWktPmFpX2ZhbWlseSA9PSBQRl9JTkVUKQogICAgewogICAgICAgIGNvbnN0IHN0cnVjdCBzb2NrYWRkcl9pbiAqc2luID0gKGNvbnN0IHN0cnVjdCBzb2NrYWRkcl9pbiAqKWFpLT5haV9hZGRyOwogICAgICAgIHRjcF9mbG9vci0+cG9ydCA9IHNpbi0+c2luX3BvcnQ7CiAgICAgICAgaXB2NF9mbG9vci0+aXB2NGFkZHIgPSBzaW4tPnNpbl9hZGRyLnNfYWRkcjsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBFUlIoInVuZXhwZWN0ZWQgcHJvdG9jb2wgZmFtaWx5ICVkXG4iLCBhaS0+YWlfZmFtaWx5KTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBmcmVlYWRkcmluZm8oYWkpOwoKICAgIHJldHVybiBzaXplOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBycGNydDRfbmNhY25faXBfdGNwX3BhcnNlX3RvcF9vZl90b3dlcihjb25zdCB1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgdG93ZXJfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqKm5ldHdvcmthZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICoqZW5kcG9pbnQpCnsKICAgIGNvbnN0IHR3cl90Y3BfZmxvb3JfdCAqdGNwX2Zsb29yID0gKGNvbnN0IHR3cl90Y3BfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CiAgICBjb25zdCB0d3JfaXB2NF9mbG9vcl90ICppcHY0X2Zsb29yOwogICAgc3RydWN0IGluX2FkZHIgaW5fYWRkcjsKCiAgICBUUkFDRSgiKCVwLCAlZCwgJXAsICVwKVxuIiwgdG93ZXJfZGF0YSwgKGludCl0b3dlcl9zaXplLCBuZXR3b3JrYWRkciwgZW5kcG9pbnQpOwoKICAgIGlmICh0b3dlcl9zaXplIDwgc2l6ZW9mKCp0Y3BfZmxvb3IpKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICB0b3dlcl9kYXRhICs9IHNpemVvZigqdGNwX2Zsb29yKTsKICAgIHRvd2VyX3NpemUgLT0gc2l6ZW9mKCp0Y3BfZmxvb3IpOwoKICAgIGlmICh0b3dlcl9zaXplIDwgc2l6ZW9mKCppcHY0X2Zsb29yKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgaXB2NF9mbG9vciA9IChjb25zdCB0d3JfaXB2NF9mbG9vcl90ICopdG93ZXJfZGF0YTsKCiAgICBpZiAoKHRjcF9mbG9vci0+Y291bnRfbGhzICE9IHNpemVvZih0Y3BfZmxvb3ItPnByb3RpZCkpIHx8CiAgICAgICAgKHRjcF9mbG9vci0+cHJvdGlkICE9IEVQTV9QUk9UT0NPTF9UQ1ApIHx8CiAgICAgICAgKHRjcF9mbG9vci0+Y291bnRfcmhzICE9IHNpemVvZih0Y3BfZmxvb3ItPnBvcnQpKSB8fAogICAgICAgIChpcHY0X2Zsb29yLT5jb3VudF9saHMgIT0gc2l6ZW9mKGlwdjRfZmxvb3ItPnByb3RpZCkpIHx8CiAgICAgICAgKGlwdjRfZmxvb3ItPnByb3RpZCAhPSBFUE1fUFJPVE9DT0xfSVApIHx8CiAgICAgICAgKGlwdjRfZmxvb3ItPmNvdW50X3JocyAhPSBzaXplb2YoaXB2NF9mbG9vci0+aXB2NGFkZHIpKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgaWYgKGVuZHBvaW50KQogICAgewogICAgICAgICplbmRwb2ludCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCA2KTsKICAgICAgICBpZiAoISplbmRwb2ludCkKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgc3ByaW50ZigqZW5kcG9pbnQsICIldSIsIG50b2hzKHRjcF9mbG9vci0+cG9ydCkpOwogICAgfQoKICAgIGlmIChuZXR3b3JrYWRkcikKICAgIHsKICAgICAgICAqbmV0d29ya2FkZHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgSU5FVF9BRERSU1RSTEVOKTsKICAgICAgICBpZiAoISpuZXR3b3JrYWRkcikKICAgICAgICB7CiAgICAgICAgICAgIGlmIChlbmRwb2ludCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKmVuZHBvaW50KTsKICAgICAgICAgICAgICAgICplbmRwb2ludCA9IE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgfQogICAgICAgIGluX2FkZHIuc19hZGRyID0gaXB2NF9mbG9vci0+aXB2NGFkZHI7CiAgICAgICAgaWYgKCFpbmV0X250b3AoQUZfSU5FVCwgJmluX2FkZHIsICpuZXR3b3JrYWRkciwgSU5FVF9BRERSU1RSTEVOKSkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiaW5ldF9udG9wOiAlc1xuIiwgc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKm5ldHdvcmthZGRyKTsKICAgICAgICAgICAgKm5ldHdvcmthZGRyID0gTlVMTDsKICAgICAgICAgICAgaWYgKGVuZHBvaW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCAqZW5kcG9pbnQpOwogICAgICAgICAgICAgICAgKmVuZHBvaW50ID0gTlVMTDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBSUENfU19PSzsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBwcm90c2VxX29wcyBwcm90c2VxX2xpc3RbXSA9IHsKICB7ICJuY2Fjbl9ucCIsCiAgICB7IEVQTV9QUk9UT0NPTF9OQ0FDTiwgRVBNX1BST1RPQ09MX1NNQiB9LAogICAgcnBjcnQ0X2Nvbm5fbnBfYWxsb2MsCiAgICBycGNydDRfbmNhY25fbnBfb3BlbiwKICAgIHJwY3J0NF9jb25uX25wX2dldF9jb25uZWN0X2V2ZW50LAogICAgcnBjcnQ0X2Nvbm5fbnBfaGFuZG9mZiwKICAgIHJwY3J0NF9jb25uX25wX3JlYWQsCiAgICBycGNydDRfY29ubl9ucF93cml0ZSwKICAgIHJwY3J0NF9jb25uX25wX2Nsb3NlLAogICAgcnBjcnQ0X25jYWNuX25wX2dldF90b3Bfb2ZfdG93ZXIsCiAgICBycGNydDRfbmNhY25fbnBfcGFyc2VfdG9wX29mX3Rvd2VyLAogIH0sCiAgeyAibmNhbHJwYyIsCiAgICB7IEVQTV9QUk9UT0NPTF9OQ0FMUlBDLCBFUE1fUFJPVE9DT0xfUElQRSB9LAogICAgcnBjcnQ0X2Nvbm5fbnBfYWxsb2MsCiAgICBycGNydDRfbmNhbHJwY19vcGVuLAogICAgcnBjcnQ0X2Nvbm5fbnBfZ2V0X2Nvbm5lY3RfZXZlbnQsCiAgICBycGNydDRfY29ubl9ucF9oYW5kb2ZmLAogICAgcnBjcnQ0X2Nvbm5fbnBfcmVhZCwKICAgIHJwY3J0NF9jb25uX25wX3dyaXRlLAogICAgcnBjcnQ0X2Nvbm5fbnBfY2xvc2UsCiAgICBycGNydDRfbmNhbHJwY19nZXRfdG9wX29mX3Rvd2VyLAogICAgcnBjcnQ0X25jYWxycGNfcGFyc2VfdG9wX29mX3Rvd2VyLAogIH0sCiAgeyAibmNhY25faXBfdGNwIiwKICAgIHsgRVBNX1BST1RPQ09MX05DQUNOLCBFUE1fUFJPVE9DT0xfVENQIH0sCiAgICBycGNydDRfY29ubl90Y3BfYWxsb2MsCiAgICBycGNydDRfbmNhY25faXBfdGNwX29wZW4sCiAgICBycGNydDRfY29ubl90Y3BfZ2V0X3dhaXRfaGFuZGxlLAogICAgcnBjcnQ0X2Nvbm5fdGNwX2hhbmRvZmYsCiAgICBycGNydDRfY29ubl90Y3BfcmVhZCwKICAgIHJwY3J0NF9jb25uX3RjcF93cml0ZSwKICAgIHJwY3J0NF9jb25uX3RjcF9jbG9zZSwKICAgIHJwY3J0NF9uY2Fjbl9pcF90Y3BfZ2V0X3RvcF9vZl90b3dlciwKICAgIHJwY3J0NF9uY2Fjbl9pcF90Y3BfcGFyc2VfdG9wX29mX3Rvd2VyLAogIH0KfTsKCiNkZWZpbmUgTUFYX1BST1RTRVEgKHNpemVvZiBwcm90c2VxX2xpc3QgLyBzaXplb2YgcHJvdHNlcV9saXN0WzBdKQoKc3RhdGljIGNvbnN0IHN0cnVjdCBwcm90c2VxX29wcyAqcnBjcnQ0X2dldF9wcm90c2VxX29wcyhjb25zdCBjaGFyICpwcm90c2VxKQp7CiAgaW50IGk7CiAgZm9yKGk9MDsgaTxNQVhfUFJPVFNFUTsgaSsrKQogICAgaWYgKCFzdHJjbXAocHJvdHNlcV9saXN0W2ldLm5hbWUsIHByb3RzZXEpKQogICAgICByZXR1cm4gJnByb3RzZXFfbGlzdFtpXTsKICByZXR1cm4gTlVMTDsKfQoKLyoqKiogaW50ZXJmYWNlIHRvIHJlc3Qgb2YgY29kZSAqKioqLwoKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKCiAgcmV0dXJuIENvbm5lY3Rpb24tPm9wcy0+b3Blbl9jb25uZWN0aW9uKENvbm5lY3Rpb24pOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKICBycGNydDRfY29ubl9jbG9zZShDb25uZWN0aW9uKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0NyZWF0ZUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbioqIENvbm5lY3Rpb24sIEJPT0wgc2VydmVyLAogICAgTFBDU1RSIFByb3RzZXEsIExQQ1NUUiBOZXR3b3JrQWRkciwgTFBDU1RSIEVuZHBvaW50LAogICAgTFBDU1RSIE5ldHdvcmtPcHRpb25zLCBScGNBdXRoSW5mbyogQXV0aEluZm8sIFJwY0JpbmRpbmcqIEJpbmRpbmcpCnsKICBjb25zdCBzdHJ1Y3QgcHJvdHNlcV9vcHMgKm9wczsKICBScGNDb25uZWN0aW9uKiBOZXdDb25uZWN0aW9uOwoKICBvcHMgPSBycGNydDRfZ2V0X3Byb3RzZXFfb3BzKFByb3RzZXEpOwogIGlmICghb3BzKQogICAgcmV0dXJuIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRDsKCiAgTmV3Q29ubmVjdGlvbiA9IG9wcy0+YWxsb2MoKTsKICBOZXdDb25uZWN0aW9uLT5zZXJ2ZXIgPSBzZXJ2ZXI7CiAgTmV3Q29ubmVjdGlvbi0+b3BzID0gb3BzOwogIE5ld0Nvbm5lY3Rpb24tPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIE5ld0Nvbm5lY3Rpb24tPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIE5ld0Nvbm5lY3Rpb24tPlVzZWQgPSBCaW5kaW5nOwogIE5ld0Nvbm5lY3Rpb24tPk1heFRyYW5zbWlzc2lvblNpemUgPSBSUENfTUFYX1BBQ0tFVF9TSVpFOwogIE5ld0Nvbm5lY3Rpb24tPk5leHRDYWxsSWQgPSAxOwogIGlmIChBdXRoSW5mbykgUnBjQXV0aEluZm9fQWRkUmVmKEF1dGhJbmZvKTsKICBOZXdDb25uZWN0aW9uLT5BdXRoSW5mbyA9IEF1dGhJbmZvOwogIGxpc3RfaW5pdCgmTmV3Q29ubmVjdGlvbi0+Y29ubl9wb29sX2VudHJ5KTsKCiAgVFJBQ0UoImNvbm5lY3Rpb246ICVwXG4iLCBOZXdDb25uZWN0aW9uKTsKICAqQ29ubmVjdGlvbiA9IE5ld0Nvbm5lY3Rpb247CgogIHJldHVybiBSUENfU19PSzsKfQoKUnBjQ29ubmVjdGlvbiAqUlBDUlQ0X0dldElkbGVDb25uZWN0aW9uKGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqSW50ZXJmYWNlSWQsCiAgICBjb25zdCBSUENfU1lOVEFYX0lERU5USUZJRVIgKlRyYW5zZmVyU3ludGF4LCBMUENTVFIgUHJvdHNlcSwgTFBDU1RSIE5ldHdvcmtBZGRyLAogICAgTFBDU1RSIEVuZHBvaW50LCBScGNBdXRoSW5mbyogQXV0aEluZm8pCnsKICBScGNDb25uZWN0aW9uICpDb25uZWN0aW9uOwogIC8qIHRyeSB0byBmaW5kIGEgY29tcGF0aWJsZSBjb25uZWN0aW9uIGZyb20gdGhlIGNvbm5lY3Rpb24gcG9vbCAqLwogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjb25uZWN0aW9uX3Bvb2xfY3MpOwogIExJU1RfRk9SX0VBQ0hfRU5UUlkoQ29ubmVjdGlvbiwgJmNvbm5lY3Rpb25fcG9vbCwgUnBjQ29ubmVjdGlvbiwgY29ubl9wb29sX2VudHJ5KQogICAgaWYgKChDb25uZWN0aW9uLT5BdXRoSW5mbyA9PSBBdXRoSW5mbykgJiYKICAgICAgICAhbWVtY21wKCZDb25uZWN0aW9uLT5BY3RpdmVJbnRlcmZhY2UsIEludGVyZmFjZUlkLAogICAgICAgICAgIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKSAmJgogICAgICAgICFzdHJjbXAocnBjcnQ0X2Nvbm5fZ2V0X25hbWUoQ29ubmVjdGlvbiksIFByb3RzZXEpICYmCiAgICAgICAgIXN0cmNtcChDb25uZWN0aW9uLT5OZXR3b3JrQWRkciwgTmV0d29ya0FkZHIpICYmCiAgICAgICAgIXN0cmNtcChDb25uZWN0aW9uLT5FbmRwb2ludCwgRW5kcG9pbnQpKQogICAgewogICAgICBsaXN0X3JlbW92ZSgmQ29ubmVjdGlvbi0+Y29ubl9wb29sX2VudHJ5KTsKICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNvbm5lY3Rpb25fcG9vbF9jcyk7CiAgICAgIFRSQUNFKCJnb3QgY29ubmVjdGlvbiBmcm9tIHBvb2wgJXBcbiIsIENvbm5lY3Rpb24pOwogICAgICByZXR1cm4gQ29ubmVjdGlvbjsKICAgIH0KCiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNvbm5lY3Rpb25fcG9vbF9jcyk7CiAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgUlBDUlQ0X1JlbGVhc2VJZGxlQ29ubmVjdGlvbihScGNDb25uZWN0aW9uICpDb25uZWN0aW9uKQp7CiAgYXNzZXJ0KCFDb25uZWN0aW9uLT5zZXJ2ZXIpOwogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjb25uZWN0aW9uX3Bvb2xfY3MpOwogIGxpc3RfYWRkX2hlYWQoJmNvbm5lY3Rpb25fcG9vbCwgJkNvbm5lY3Rpb24tPmNvbm5fcG9vbF9lbnRyeSk7CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNvbm5lY3Rpb25fcG9vbF9jcyk7Cn0KCgpSUENfU1RBVFVTIFJQQ1JUNF9TcGF3bkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbioqIENvbm5lY3Rpb24sIFJwY0Nvbm5lY3Rpb24qIE9sZENvbm5lY3Rpb24pCnsKICBSUENfU1RBVFVTIGVycjsKCiAgZXJyID0gUlBDUlQ0X0NyZWF0ZUNvbm5lY3Rpb24oQ29ubmVjdGlvbiwgT2xkQ29ubmVjdGlvbi0+c2VydmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJwY3J0NF9jb25uX2dldF9uYW1lKE9sZENvbm5lY3Rpb24pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9sZENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9sZENvbm5lY3Rpb24tPkVuZHBvaW50LCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9sZENvbm5lY3Rpb24tPkF1dGhJbmZvLCBOVUxMKTsKICBpZiAoZXJyID09IFJQQ19TX09LKQogICAgcnBjcnQ0X2Nvbm5faGFuZG9mZihPbGRDb25uZWN0aW9uLCAqQ29ubmVjdGlvbik7CiAgcmV0dXJuIGVycjsKfQoKUlBDX1NUQVRVUyBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCJjb25uZWN0aW9uOiAlcFxuIiwgQ29ubmVjdGlvbik7CgogIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oQ29ubmVjdGlvbik7CiAgUlBDUlQ0X3N0cmZyZWUoQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIFJQQ1JUNF9zdHJmcmVlKENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyKTsKICBpZiAoQ29ubmVjdGlvbi0+QXV0aEluZm8pIFJwY0F1dGhJbmZvX1JlbGVhc2UoQ29ubmVjdGlvbi0+QXV0aEluZm8pOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIENvbm5lY3Rpb24pOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBScGNUcmFuc3BvcnRfR2V0VG9wT2ZUb3dlcih1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqdG93ZXJfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpwcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5ldHdvcmthZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVuZHBvaW50KQp7CiAgICB0d3JfZW1wdHlfZmxvb3JfdCAqcHJvdG9jb2xfZmxvb3I7CiAgICBjb25zdCBzdHJ1Y3QgcHJvdHNlcV9vcHMgKnByb3RzZXFfb3BzID0gcnBjcnQ0X2dldF9wcm90c2VxX29wcyhwcm90c2VxKTsKCiAgICAqdG93ZXJfc2l6ZSA9IDA7CgogICAgaWYgKCFwcm90c2VxX29wcykKICAgICAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9SUENfUFJPVFNFUTsKCiAgICBpZiAoIXRvd2VyX2RhdGEpCiAgICB7CiAgICAgICAgKnRvd2VyX3NpemUgPSBzaXplb2YoKnByb3RvY29sX2Zsb29yKTsKICAgICAgICAqdG93ZXJfc2l6ZSArPSBwcm90c2VxX29wcy0+Z2V0X3RvcF9vZl90b3dlcihOVUxMLCBuZXR3b3JrYWRkciwgZW5kcG9pbnQpOwogICAgICAgIHJldHVybiBSUENfU19PSzsKICAgIH0KCiAgICBwcm90b2NvbF9mbG9vciA9ICh0d3JfZW1wdHlfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CiAgICBwcm90b2NvbF9mbG9vci0+Y291bnRfbGhzID0gc2l6ZW9mKHByb3RvY29sX2Zsb29yLT5wcm90aWQpOwogICAgcHJvdG9jb2xfZmxvb3ItPnByb3RpZCA9IHByb3RzZXFfb3BzLT5lcG1fcHJvdG9jb2xzWzBdOwogICAgcHJvdG9jb2xfZmxvb3ItPmNvdW50X3JocyA9IDA7CgogICAgdG93ZXJfZGF0YSArPSBzaXplb2YoKnByb3RvY29sX2Zsb29yKTsKCiAgICAqdG93ZXJfc2l6ZSA9IHByb3RzZXFfb3BzLT5nZXRfdG9wX29mX3Rvd2VyKHRvd2VyX2RhdGEsIG5ldHdvcmthZGRyLCBlbmRwb2ludCk7CiAgICBpZiAoISp0b3dlcl9zaXplKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICAqdG93ZXJfc2l6ZSArPSBzaXplb2YoKnByb3RvY29sX2Zsb29yKTsKCiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUnBjVHJhbnNwb3J0X1BhcnNlVG9wT2ZUb3dlcihjb25zdCB1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHRvd2VyX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICoqcHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKipuZXR3b3JrYWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKiplbmRwb2ludCkKewogICAgdHdyX2VtcHR5X2Zsb29yX3QgKnByb3RvY29sX2Zsb29yOwogICAgdHdyX2VtcHR5X2Zsb29yX3QgKmZsb29yNDsKICAgIGNvbnN0IHN0cnVjdCBwcm90c2VxX29wcyAqcHJvdHNlcV9vcHMgPSBOVUxMOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICBpbnQgaTsKCiAgICBpZiAodG93ZXJfc2l6ZSA8IHNpemVvZigqcHJvdG9jb2xfZmxvb3IpKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICBwcm90b2NvbF9mbG9vciA9ICh0d3JfZW1wdHlfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CiAgICB0b3dlcl9kYXRhICs9IHNpemVvZigqcHJvdG9jb2xfZmxvb3IpOwogICAgdG93ZXJfc2l6ZSAtPSBzaXplb2YoKnByb3RvY29sX2Zsb29yKTsKICAgIGlmICgocHJvdG9jb2xfZmxvb3ItPmNvdW50X2xocyAhPSBzaXplb2YocHJvdG9jb2xfZmxvb3ItPnByb3RpZCkpIHx8CiAgICAgICAgKHByb3RvY29sX2Zsb29yLT5jb3VudF9yaHMgPiB0b3dlcl9zaXplKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CiAgICB0b3dlcl9kYXRhICs9IHByb3RvY29sX2Zsb29yLT5jb3VudF9yaHM7CiAgICB0b3dlcl9zaXplIC09IHByb3RvY29sX2Zsb29yLT5jb3VudF9yaHM7CgogICAgZmxvb3I0ID0gKHR3cl9lbXB0eV9mbG9vcl90ICopdG93ZXJfZGF0YTsKICAgIGlmICgodG93ZXJfc2l6ZSA8IHNpemVvZigqZmxvb3I0KSkgfHwKICAgICAgICAoZmxvb3I0LT5jb3VudF9saHMgIT0gc2l6ZW9mKGZsb29yNC0+cHJvdGlkKSkpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIGZvcihpID0gMDsgaSA8IE1BWF9QUk9UU0VROyBpKyspCiAgICAgICAgaWYgKChwcm90b2NvbF9mbG9vci0+cHJvdGlkID09IHByb3RzZXFfbGlzdFtpXS5lcG1fcHJvdG9jb2xzWzBdKSAmJgogICAgICAgICAgICAoZmxvb3I0LT5wcm90aWQgPT0gcHJvdHNlcV9saXN0W2ldLmVwbV9wcm90b2NvbHNbMV0pKQogICAgICAgIHsKICAgICAgICAgICAgcHJvdHNlcV9vcHMgPSAmcHJvdHNlcV9saXN0W2ldOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgaWYgKCFwcm90c2VxX29wcykKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgc3RhdHVzID0gcHJvdHNlcV9vcHMtPnBhcnNlX3RvcF9vZl90b3dlcih0b3dlcl9kYXRhLCB0b3dlcl9zaXplLCBuZXR3b3JrYWRkciwgZW5kcG9pbnQpOwoKICAgIGlmICgoc3RhdHVzID09IFJQQ19TX09LKSAmJiBwcm90c2VxKQogICAgewogICAgICAgICpwcm90c2VxID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cmxlbihwcm90c2VxX29wcy0+bmFtZSkgKyAxKTsKICAgICAgICBzdHJjcHkoKnByb3RzZXEsIHByb3RzZXFfb3BzLT5uYW1lKTsKICAgIH0KCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyAoUlBDUlQ0LkApCiAqCiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gcHJvdG9jb2wgc2VxdWVuY2UgaXMga25vd24gYnkgdGhlIFJQQyBzeXN0ZW0uCiAqIElmIGl0IGlzLCByZXR1cm5zIFJQQ19TX09LLCBvdGhlcndpc2UgUlBDX1NfUFJPVFNFUV9OT1RfU1VQUE9SVEVELgogKgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyhMUFdTVFIgcHJvdHNlcSkKewogIGNoYXIgcHNbMHgxMF07CgogIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBwcm90c2VxLCAtMSwKICAgICAgICAgICAgICAgICAgICAgIHBzLCBzaXplb2YgcHMsIE5VTEwsIE5VTEwpOwogIGlmIChycGNydDRfZ2V0X3Byb3RzZXFfb3BzKHBzKSkKICAgIHJldHVybiBSUENfU19PSzsKCiAgRklYTUUoIlVua25vd24gcHJvdHNlcSAlc1xuIiwgZGVidWdzdHJfdyhwcm90c2VxKSk7CgogIHJldHVybiBSUENfU19JTlZBTElEX1JQQ19QUk9UU0VROwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNOZXR3b3JrSXNQcm90c2VxVmFsaWRBKHVuc2lnbmVkIGNoYXIgKnByb3RzZXEpCnsKICBVTklDT0RFX1NUUklORyBwcm90c2VxVzsKCiAgaWYgKFJ0bENyZWF0ZVVuaWNvZGVTdHJpbmdGcm9tQXNjaWl6KCZwcm90c2VxVywgKGNoYXIqKXByb3RzZXEpKQogIHsKICAgIFJQQ19TVEFUVVMgcmV0ID0gUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyhwcm90c2VxVy5CdWZmZXIpOwogICAgUnRsRnJlZVVuaWNvZGVTdHJpbmcoJnByb3RzZXFXKTsKICAgIHJldHVybiByZXQ7CiAgfQogIHJldHVybiBSUENfU19PVVRfT0ZfTUVNT1JZOwp9Cg==