LyoKICogUlBDIGVuZHBvaW50IG1hcHBlcgogKgogKiBDb3B5cmlnaHQgMjAwMiBHcmVnIFR1cm5lcgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICoKICogVE9ETzoKICogIC0gYWN0dWFsbHkgZG8gdGhpbmdzIHJpZ2h0CiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKCiNpbmNsdWRlICJycGMuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAicnBjX2JpbmRpbmcuaCIKI2luY2x1ZGUgImVwbV90b3dlcnMuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgovKiBUaGUgInJlYWwiIFJQQyBwb3J0bWFwcGVyIGVuZHBvaW50cyB0aGF0IEkga25vdyBvZiBhcmU6CiAqCiAqICBuY2FkZ19pcF91ZHA6IDEzNQogKiAgbmNhY25faXBfdGNwOiAxMzUKICogIG5jYWNuX25wOiBcXHBpcGVcZXBtYXBwZXIgKD8pCiAqICBuY2FscnBjOiBlcG1hcHBlcgogKgogKiBJZiB0aGUgdXNlcidzIG1hY2hpbmUgcmFuIGEgRENFIFJQQyBkYWVtb24sIGl0IHdvdWxkCiAqIHByb2JhYmx5IGJlIHBvc3NpYmxlIHRvIGNvbm5lY3QgdG8gaXQsIGJ1dCB0aGVyZSBhcmUgbWFueQogKiByZWFzb25zIG5vdCB0bywgbGlrZToKICogIC0gdGhlIHVzZXIgcHJvYmFibHkgZG9lcyAqbm90KiBydW4gb25lLCBhbmQgcHJvYmFibHkKICogICAgc2hvdWxkbid0IGJlIGZvcmNlZCB0byBydW4gb25lIGp1c3QgZm9yIGxvY2FsIENPTQogKiAgLSB2ZXJ5IGZldyBVbml4IHN5c3RlbXMgdXNlIERDRSBSUEMuLi4gaWYgdGhleSBydW4gYSBSUEMKICogICAgZGFlbW9uIGF0IGFsbCwgaXQncyB1c3VhbGx5IFN1biBSUEMKICogIC0gRENFIFJQQyByZWdpc3RyYXRpb25zIGFyZSBwZXJzaXN0ZW50IGFuZCBzYXZlZCBvbiBkaXNrLAogKiAgICB3aGlsZSBNUy1SUEMgcmVnaXN0cmF0aW9ucyBhcmUgZG9jdW1lbnRlZCBhcyBub24tcGVyc2lzdGVudAogKiAgICBhbmQgc3RvcmVkIG9ubHkgaW4gUkFNLCBhbmQgYXV0by1kZXN0cm95ZWQgd2hlbiB0aGUgcHJvY2VzcwogKiAgICBkaWVzIChzb21ldGhpbmcgRENFIFJQQyBjYW4ndCBkbykKICoKICogT2YgY291cnNlLCBpZiB0aGUgdXNlciAqZGlkKiB3YW50IHRvIHJ1biBhIERDRSBSUEMgZGFlbW9uIGFueXdheSwKICogdGhlcmUgd291bGQgYmUgaW50ZXJvcGVyYWJpbGl0eSBhZHZhbnRhZ2VzLCBsaWtlIHRoZSBwb3NzaWJpbGl0eQogKiBvZiBydW5uaW5nIGEgZnVsbHkgZnVuY3Rpb25hbCBEQ09NIHNlcnZlciB1c2luZyBXaW5lLi4uCiAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0VwUmVnaXN0ZXJBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0VwUmVnaXN0ZXJBKCBSUENfSUZfSEFORExFIElmU3BlYywgUlBDX0JJTkRJTkdfVkVDVE9SICpCaW5kaW5nVmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVVJRF9WRUNUT1IgKlV1aWRWZWN0b3IsIFJQQ19DU1RSIEFubm90YXRpb24gKQp7CiAgUlBDU1NfTlBfTUVTU0FHRSBtc2c7CiAgUlBDU1NfTlBfUkVQTFkgcmVwbHk7CiAgY2hhciAqdmFyZGF0YV9wYXlsb2FkLCAqdnA7CiAgUFJQQ19TRVJWRVJfSU5URVJGQUNFIElmID0gKFBSUENfU0VSVkVSX0lOVEVSRkFDRSlJZlNwZWM7CiAgdW5zaWduZWQgbG9uZyBjOwogIFJQQ19TVEFUVVMgcnNsdCA9IFJQQ19TX09LOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVzKVxuIiwgSWZTcGVjLCBCaW5kaW5nVmVjdG9yLCBVdWlkVmVjdG9yLCBkZWJ1Z3N0cl9hKChjaGFyKilBbm5vdGF0aW9uKSk7CiAgVFJBQ0UoIiBpZmlkPSVzXG4iLCBkZWJ1Z3N0cl9ndWlkKCZJZi0+SW50ZXJmYWNlSWQuU3ludGF4R1VJRCkpOwogIGZvciAoYz0wOyBjPEJpbmRpbmdWZWN0b3ItPkNvdW50OyBjKyspIHsKICAgIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopKEJpbmRpbmdWZWN0b3ItPkJpbmRpbmdIW2NdKTsKICAgIFRSQUNFKCIgcHJvdHNlcVslbGRdPSVzXG4iLCBjLCBkZWJ1Z3N0cl9hKGJpbmQtPlByb3RzZXEpKTsKICAgIFRSQUNFKCIgZW5kcG9pbnRbJWxkXT0lc1xuIiwgYywgZGVidWdzdHJfYShiaW5kLT5FbmRwb2ludCkpOwogIH0KICBpZiAoVXVpZFZlY3RvcikgewogICAgZm9yIChjPTA7IGM8VXVpZFZlY3Rvci0+Q291bnQ7IGMrKykKICAgICAgVFJBQ0UoIiBvYmpbJWxkXT0lc1xuIiwgYywgZGVidWdzdHJfZ3VpZChVdWlkVmVjdG9yLT5VdWlkW2NdKSk7CiAgfQoKICAvKiBGSVhNRTogRG8gc29tZXRoaW5nIHdpdGggYW5ub3RhdGlvbi4gKi8KCiAgLyogY29uc3RydWN0IHRoZSBtZXNzYWdlIHRvIHJwY3NzICovCiAgbXNnLm1lc3NhZ2VfdHlwZSA9IFJQQ1NTX05QX01FU1NBR0VfVFlQRUlEX1JFR0lTVEVSRVBNU0c7CiAgbXNnLm1lc3NhZ2UucmVnaXN0ZXJlcG1zZy5pZmFjZSA9IElmLT5JbnRlcmZhY2VJZDsKICBtc2cubWVzc2FnZS5yZWdpc3RlcmVwbXNnLm5vX3JlcGxhY2UgPSAwOwoKICBtc2cubWVzc2FnZS5yZWdpc3RlcmVwbXNnLm9iamVjdF9jb3VudCA9IChVdWlkVmVjdG9yKSA/IFV1aWRWZWN0b3ItPkNvdW50IDogMDsKICBtc2cubWVzc2FnZS5yZWdpc3RlcmVwbXNnLmJpbmRpbmdfY291bnQgPSBCaW5kaW5nVmVjdG9yLT5Db3VudDsKCiAgLyogY2FsY3VsYXRlIHZhcmRhdGEgcGF5bG9hZCBzaXplICovCiAgbXNnLnZhcmRhdGFfcGF5bG9hZF9zaXplID0gbXNnLm1lc3NhZ2UucmVnaXN0ZXJlcG1zZy5vYmplY3RfY291bnQgKiBzaXplb2YoVVVJRCk7CiAgZm9yIChjPTA7IGMgPCBtc2cubWVzc2FnZS5yZWdpc3RlcmVwbXNnLmJpbmRpbmdfY291bnQ7IGMrKykgewogICAgUnBjQmluZGluZyAqYmluZCA9IChScGNCaW5kaW5nICopKEJpbmRpbmdWZWN0b3ItPkJpbmRpbmdIW2NdKTsKICAgIG1zZy52YXJkYXRhX3BheWxvYWRfc2l6ZSArPSBzdHJsZW4oYmluZC0+UHJvdHNlcSkgKyAxOwogICAgbXNnLnZhcmRhdGFfcGF5bG9hZF9zaXplICs9IHN0cmxlbihiaW5kLT5FbmRwb2ludCkgKyAxOwogIH0KCiAgLyogYWxsb2NhdGUgdGhlIHBheWxvYWQgYnVmZmVyICovCiAgdnAgPSB2YXJkYXRhX3BheWxvYWQgPSBMb2NhbEFsbG9jKExQVFIsIG1zZy52YXJkYXRhX3BheWxvYWRfc2l6ZSk7CiAgaWYgKCF2YXJkYXRhX3BheWxvYWQpCiAgICByZXR1cm4gUlBDX1NfT1VUX09GX01FTU9SWTsKCiAgLyogcG9wdWxhdGUgdGhlIHBheWxvYWQgZGF0YSAqLwogIGZvciAoYz0wOyBjIDwgbXNnLm1lc3NhZ2UucmVnaXN0ZXJlcG1zZy5vYmplY3RfY291bnQ7IGMrKykgewogICAgQ29weU1lbW9yeSh2cCwgVXVpZFZlY3Rvci0+VXVpZFtjXSwgc2l6ZW9mKFVVSUQpKTsKICAgIHZwICs9IHNpemVvZihVVUlEKTsKICB9CgogIGZvciAoYz0wOyBjIDwgbXNnLm1lc3NhZ2UucmVnaXN0ZXJlcG1zZy5iaW5kaW5nX2NvdW50OyBjKyspIHsKICAgIFJwY0JpbmRpbmcgKmJpbmQgPSAoUnBjQmluZGluZyopKEJpbmRpbmdWZWN0b3ItPkJpbmRpbmdIW2NdKTsKICAgIHVuc2lnbmVkIGxvbmcgcHNsZW4gPSBzdHJsZW4oYmluZC0+UHJvdHNlcSkgKyAxLCBlcGxlbiA9IHN0cmxlbihiaW5kLT5FbmRwb2ludCkgKyAxOwogICAgQ29weU1lbW9yeSh2cCwgYmluZC0+UHJvdHNlcSwgcHNsZW4pOwogICAgdnAgKz0gcHNsZW47CiAgICBDb3B5TWVtb3J5KHZwLCBiaW5kLT5FbmRwb2ludCwgZXBsZW4pOwogICAgdnAgKz0gZXBsZW47CiAgfQoKICAvKiBzZW5kIG91ciByZXF1ZXN0ICovCiAgaWYgKCFSUENSVDRfUlBDU1NPbkRlbWFuZENhbGwoJm1zZywgdmFyZGF0YV9wYXlsb2FkLCAmcmVwbHkpKQogICAgcnNsdCA9IFJQQ19TX09VVF9PRl9NRU1PUlk7CgogIC8qIGZyZWUgdGhlIHBheWxvYWQgYnVmZmVyICovCiAgTG9jYWxGcmVlKHZhcmRhdGFfcGF5bG9hZCk7CgogIHJldHVybiByc2x0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjRXBVbnJlZ2lzdGVyIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0VwVW5yZWdpc3RlciggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFJQQ19CSU5ESU5HX1ZFQ1RPUiAqQmluZGluZ1ZlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVUlEX1ZFQ1RPUiAqVXVpZFZlY3RvciApCnsKICBSUENTU19OUF9NRVNTQUdFIG1zZzsKICBSUENTU19OUF9SRVBMWSByZXBseTsKICBjaGFyICp2YXJkYXRhX3BheWxvYWQsICp2cDsKICBQUlBDX1NFUlZFUl9JTlRFUkZBQ0UgSWYgPSAoUFJQQ19TRVJWRVJfSU5URVJGQUNFKUlmU3BlYzsKICB1bnNpZ25lZCBsb25nIGM7CiAgUlBDX1NUQVRVUyByc2x0ID0gUlBDX1NfT0s7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBJZlNwZWMsIEJpbmRpbmdWZWN0b3IsIFV1aWRWZWN0b3IpOwogIFRSQUNFKCIgaWZpZD0lc1xuIiwgZGVidWdzdHJfZ3VpZCgmSWYtPkludGVyZmFjZUlkLlN5bnRheEdVSUQpKTsKICBmb3IgKGM9MDsgYzxCaW5kaW5nVmVjdG9yLT5Db3VudDsgYysrKSB7CiAgICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKShCaW5kaW5nVmVjdG9yLT5CaW5kaW5nSFtjXSk7CiAgICBUUkFDRSgiIHByb3RzZXFbJWxkXT0lc1xuIiwgYywgZGVidWdzdHJfYShiaW5kLT5Qcm90c2VxKSk7CiAgICBUUkFDRSgiIGVuZHBvaW50WyVsZF09JXNcbiIsIGMsIGRlYnVnc3RyX2EoYmluZC0+RW5kcG9pbnQpKTsKICB9CiAgaWYgKFV1aWRWZWN0b3IpIHsKICAgIGZvciAoYz0wOyBjPFV1aWRWZWN0b3ItPkNvdW50OyBjKyspCiAgICAgIFRSQUNFKCIgb2JqWyVsZF09JXNcbiIsIGMsIGRlYnVnc3RyX2d1aWQoVXVpZFZlY3Rvci0+VXVpZFtjXSkpOwogIH0KCiAgLyogY29uc3RydWN0IHRoZSBtZXNzYWdlIHRvIHJwY3NzICovCiAgbXNnLm1lc3NhZ2VfdHlwZSA9IFJQQ1NTX05QX01FU1NBR0VfVFlQRUlEX1VOUkVHSVNURVJFUE1TRzsKICBtc2cubWVzc2FnZS51bnJlZ2lzdGVyZXBtc2cuaWZhY2UgPSBJZi0+SW50ZXJmYWNlSWQ7CgogIG1zZy5tZXNzYWdlLnVucmVnaXN0ZXJlcG1zZy5vYmplY3RfY291bnQgPSAoVXVpZFZlY3RvcikgPyBVdWlkVmVjdG9yLT5Db3VudCA6IDA7CiAgbXNnLm1lc3NhZ2UudW5yZWdpc3RlcmVwbXNnLmJpbmRpbmdfY291bnQgPSBCaW5kaW5nVmVjdG9yLT5Db3VudDsKCiAgLyogY2FsY3VsYXRlIHZhcmRhdGEgcGF5bG9hZCBzaXplICovCiAgbXNnLnZhcmRhdGFfcGF5bG9hZF9zaXplID0gbXNnLm1lc3NhZ2UudW5yZWdpc3RlcmVwbXNnLm9iamVjdF9jb3VudCAqIHNpemVvZihVVUlEKTsKICBmb3IgKGM9MDsgYyA8IG1zZy5tZXNzYWdlLnVucmVnaXN0ZXJlcG1zZy5iaW5kaW5nX2NvdW50OyBjKyspIHsKICAgIFJwY0JpbmRpbmcgKmJpbmQgPSAoUnBjQmluZGluZyAqKShCaW5kaW5nVmVjdG9yLT5CaW5kaW5nSFtjXSk7CiAgICBtc2cudmFyZGF0YV9wYXlsb2FkX3NpemUgKz0gc3RybGVuKGJpbmQtPlByb3RzZXEpICsgMTsKICAgIG1zZy52YXJkYXRhX3BheWxvYWRfc2l6ZSArPSBzdHJsZW4oYmluZC0+RW5kcG9pbnQpICsgMTsKICB9CgogIC8qIGFsbG9jYXRlIHRoZSBwYXlsb2FkIGJ1ZmZlciAqLwogIHZwID0gdmFyZGF0YV9wYXlsb2FkID0gTG9jYWxBbGxvYyhMUFRSLCBtc2cudmFyZGF0YV9wYXlsb2FkX3NpemUpOwogIGlmICghdmFyZGF0YV9wYXlsb2FkKQogICAgcmV0dXJuIFJQQ19TX09VVF9PRl9NRU1PUlk7CgogIC8qIHBvcHVsYXRlIHRoZSBwYXlsb2FkIGRhdGEgKi8KICBmb3IgKGM9MDsgYyA8IG1zZy5tZXNzYWdlLnVucmVnaXN0ZXJlcG1zZy5vYmplY3RfY291bnQ7IGMrKykgewogICAgQ29weU1lbW9yeSh2cCwgVXVpZFZlY3Rvci0+VXVpZFtjXSwgc2l6ZW9mKFVVSUQpKTsKICAgIHZwICs9IHNpemVvZihVVUlEKTsKICB9CgogIGZvciAoYz0wOyBjIDwgbXNnLm1lc3NhZ2UudW5yZWdpc3RlcmVwbXNnLmJpbmRpbmdfY291bnQ7IGMrKykgewogICAgUnBjQmluZGluZyAqYmluZCA9IChScGNCaW5kaW5nKikoQmluZGluZ1ZlY3Rvci0+QmluZGluZ0hbY10pOwogICAgdW5zaWduZWQgbG9uZyBwc2xlbiA9IHN0cmxlbihiaW5kLT5Qcm90c2VxKSArIDEsIGVwbGVuID0gc3RybGVuKGJpbmQtPkVuZHBvaW50KSArIDE7CiAgICBDb3B5TWVtb3J5KHZwLCBiaW5kLT5Qcm90c2VxLCBwc2xlbik7CiAgICB2cCArPSBwc2xlbjsKICAgIENvcHlNZW1vcnkodnAsIGJpbmQtPkVuZHBvaW50LCBlcGxlbik7CiAgICB2cCArPSBlcGxlbjsKICB9CgogIC8qIHNlbmQgb3VyIHJlcXVlc3QgKi8KICBpZiAoIVJQQ1JUNF9SUENTU09uRGVtYW5kQ2FsbCgmbXNnLCB2YXJkYXRhX3BheWxvYWQsICZyZXBseSkpCiAgICByc2x0ID0gUlBDX1NfT1VUX09GX01FTU9SWTsKCiAgLyogZnJlZSB0aGUgcGF5bG9hZCBidWZmZXIgKi8KICBMb2NhbEZyZWUodmFyZGF0YV9wYXlsb2FkKTsKCiAgcmV0dXJuIHJzbHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNFcFJlc29sdmVCaW5kaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0VwUmVzb2x2ZUJpbmRpbmcoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfSUZfSEFORExFIElmU3BlYyApCnsKICBSUENTU19OUF9NRVNTQUdFIG1zZzsKICBSUENTU19OUF9SRVBMWSByZXBseTsKICBQUlBDX0NMSUVOVF9JTlRFUkZBQ0UgSWYgPSAoUFJQQ19DTElFTlRfSU5URVJGQUNFKUlmU3BlYzsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBJZlNwZWMpOwogIFRSQUNFKCIgcHJvdHNlcT0lc1xuIiwgZGVidWdzdHJfYShiaW5kLT5Qcm90c2VxKSk7CiAgVFJBQ0UoIiBvYmo9JXNcbiIsIGRlYnVnc3RyX2d1aWQoJmJpbmQtPk9iamVjdFV1aWQpKTsKICBUUkFDRSgiIGlmaWQ9JXNcbiIsIGRlYnVnc3RyX2d1aWQoJklmLT5JbnRlcmZhY2VJZC5TeW50YXhHVUlEKSk7CgogIC8qIEZJWE1FOiB0b3RhbGx5IHVudGVzdGVkICovCgogIC8qIGp1c3QgcmV0dXJuIGZvciBmdWxseSBib3VuZCBoYW5kbGVzICovCiAgaWYgKGJpbmQtPkVuZHBvaW50ICYmIChiaW5kLT5FbmRwb2ludFswXSAhPSAnXDAnKSkKICAgIHJldHVybiBSUENfU19PSzsKCiAgLyogY29uc3RydWN0IHRoZSBtZXNzYWdlIHRvIHJwY3NzICovCiAgbXNnLm1lc3NhZ2VfdHlwZSA9IFJQQ1NTX05QX01FU1NBR0VfVFlQRUlEX1JFU09MVkVFUE1TRzsKICBtc2cubWVzc2FnZS5yZXNvbHZlZXBtc2cuaWZhY2UgPSBJZi0+SW50ZXJmYWNlSWQ7CiAgbXNnLm1lc3NhZ2UucmVzb2x2ZWVwbXNnLm9iamVjdCA9IGJpbmQtPk9iamVjdFV1aWQ7CiAKICBtc2cudmFyZGF0YV9wYXlsb2FkX3NpemUgPSBzdHJsZW4oYmluZC0+UHJvdHNlcSkgKyAxOwoKICAvKiBzZW5kIHRoZSBtZXNzYWdlICovCiAgaWYgKCFSUENSVDRfUlBDU1NPbkRlbWFuZENhbGwoJm1zZywgYmluZC0+UHJvdHNlcSwgJnJlcGx5KSkKICAgIHJldHVybiBSUENfU19PVVRfT0ZfTUVNT1JZOwoKICAvKiBlbXB0eS1zdHJpbmcgcmVzdWx0IG1lYW5zIG5vdCByZWdpc3RlcmVkICovCiAgaWYgKHJlcGx5LmFzX3N0cmluZ1swXSA9PSAnXDAnKQogICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwogIAogIC8qIG90aGVyd2lzZSB3ZSBmdWxseSBiaW5kIHRoZSBoYW5kbGUgJiByZXR1cm4gUlBDX1NfT0sgKi8KICByZXR1cm4gUlBDUlQ0X1Jlc29sdmVCaW5kaW5nKEJpbmRpbmcsIHJlcGx5LmFzX3N0cmluZyk7Cn0KCnR5cGVkZWYgdW5zaWduZWQgaW50IHVuc2lnbmVkMzI7CnR5cGVkZWYgc3RydWN0IHR3cl90CiAgICB7CiAgICB1bnNpZ25lZDMyIHRvd2VyX2xlbmd0aDsKICAgIC8qIFtzaXplX2lzXSAqLyBCWVRFIHRvd2VyX29jdGV0X3N0cmluZ1sgMSBdOwogICAgfSAJdHdyX3Q7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgVG93ZXJFeHBsb2RlIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFRvd2VyRXhwbG9kZSgKICAgIGNvbnN0IHR3cl90ICp0b3dlciwgUFJQQ19TWU5UQVhfSURFTlRJRklFUiBvYmplY3QsIFBSUENfU1lOVEFYX0lERU5USUZJRVIgc3ludGF4LAogICAgY2hhciAqKnByb3RzZXEsIGNoYXIgKiplbmRwb2ludCwgY2hhciAqKmFkZHJlc3MpCnsKICAgIHNpemVfdCB0b3dlcl9zaXplOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICBjb25zdCB1bnNpZ25lZCBjaGFyICpwOwogICAgdV9pbnQxNiBmbG9vcl9jb3VudDsKICAgIGNvbnN0IHR3cl91dWlkX2Zsb29yX3QgKm9iamVjdF9mbG9vcjsKICAgIGNvbnN0IHR3cl91dWlkX2Zsb29yX3QgKnN5bnRheF9mbG9vcjsKCiAgICBpZiAocHJvdHNlcSkKICAgICAgICAqcHJvdHNlcSA9IE5VTEw7CiAgICBpZiAoZW5kcG9pbnQpCiAgICAgICAgKmVuZHBvaW50ID0gTlVMTDsKICAgIGlmIChhZGRyZXNzKQogICAgICAgICphZGRyZXNzID0gTlVMTDsKCiAgICB0b3dlcl9zaXplID0gdG93ZXItPnRvd2VyX2xlbmd0aDsKCiAgICBpZiAodG93ZXJfc2l6ZSA8IHNpemVvZih1X2ludDE2KSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgcCA9ICZ0b3dlci0+dG93ZXJfb2N0ZXRfc3RyaW5nWzBdOwoKICAgIGZsb29yX2NvdW50ID0gKihjb25zdCB1X2ludDE2ICopcDsKICAgIHAgKz0gc2l6ZW9mKHVfaW50MTYpOwogICAgdG93ZXJfc2l6ZSAtPSBzaXplb2YodV9pbnQxNik7CiAgICBUUkFDRSgiZmxvb3JfY291bnQ6ICVkXG4iLCBmbG9vcl9jb3VudCk7CiAgICAvKiBGSVhNRTogc2hvdWxkIHdlIGRvIHNvbWV0aGluZyB3aXRoIHRoZSBmbG9vciBjb3VudD8gYXQgdGhlIG1vbWVudCB3ZSBkb24ndCAqLwoKICAgIGlmICh0b3dlcl9zaXplIDwgc2l6ZW9mKCpvYmplY3RfZmxvb3IpICsgc2l6ZW9mKCpzeW50YXhfZmxvb3IpKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICBvYmplY3RfZmxvb3IgPSAoY29uc3QgdHdyX3V1aWRfZmxvb3JfdCAqKXA7CiAgICBwICs9IHNpemVvZigqb2JqZWN0X2Zsb29yKTsKICAgIHRvd2VyX3NpemUgLT0gc2l6ZW9mKCpvYmplY3RfZmxvb3IpOwogICAgc3ludGF4X2Zsb29yID0gKGNvbnN0IHR3cl91dWlkX2Zsb29yX3QgKilwOwogICAgcCArPSBzaXplb2YoKnN5bnRheF9mbG9vcik7CiAgICB0b3dlcl9zaXplIC09IHNpemVvZigqc3ludGF4X2Zsb29yKTsKCiAgICBpZiAoKG9iamVjdF9mbG9vci0+Y291bnRfbGhzICE9IHNpemVvZihvYmplY3RfZmxvb3ItPnByb3RpZCkgKwogICAgICAgIHNpemVvZihvYmplY3RfZmxvb3ItPnV1aWQpICsgc2l6ZW9mKG9iamVjdF9mbG9vci0+bWFqb3JfdmVyc2lvbikpIHx8CiAgICAgICAgKG9iamVjdF9mbG9vci0+cHJvdGlkICE9IEVQTV9QUk9UT0NPTF9VVUlEKSB8fAogICAgICAgIChvYmplY3RfZmxvb3ItPmNvdW50X3JocyAhPSBzaXplb2Yob2JqZWN0X2Zsb29yLT5taW5vcl92ZXJzaW9uKSkpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIGlmICgoc3ludGF4X2Zsb29yLT5jb3VudF9saHMgIT0gc2l6ZW9mKHN5bnRheF9mbG9vci0+cHJvdGlkKSArCiAgICAgICAgc2l6ZW9mKHN5bnRheF9mbG9vci0+dXVpZCkgKyBzaXplb2Yoc3ludGF4X2Zsb29yLT5tYWpvcl92ZXJzaW9uKSkgfHwKICAgICAgICAoc3ludGF4X2Zsb29yLT5wcm90aWQgIT0gRVBNX1BST1RPQ09MX1VVSUQpIHx8CiAgICAgICAgKHN5bnRheF9mbG9vci0+Y291bnRfcmhzICE9IHNpemVvZihzeW50YXhfZmxvb3ItPm1pbm9yX3ZlcnNpb24pKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgc3RhdHVzID0gUnBjVHJhbnNwb3J0X1BhcnNlVG9wT2ZUb3dlcihwLCB0b3dlcl9zaXplLCBwcm90c2VxLCBhZGRyZXNzLCBlbmRwb2ludCk7CiAgICBpZiAoKHN0YXR1cyA9PSBSUENfU19PSykgJiYgc3ludGF4ICYmIG9iamVjdCkKICAgIHsKICAgICAgICBzeW50YXgtPlN5bnRheEdVSUQgPSBzeW50YXhfZmxvb3ItPnV1aWQ7CiAgICAgICAgc3ludGF4LT5TeW50YXhWZXJzaW9uLk1ham9yVmVyc2lvbiA9IHN5bnRheF9mbG9vci0+bWFqb3JfdmVyc2lvbjsKICAgICAgICBzeW50YXgtPlN5bnRheFZlcnNpb24uTWlub3JWZXJzaW9uID0gc3ludGF4X2Zsb29yLT5taW5vcl92ZXJzaW9uOwogICAgICAgIG9iamVjdC0+U3ludGF4R1VJRCA9IG9iamVjdF9mbG9vci0+dXVpZDsKICAgICAgICBvYmplY3QtPlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uID0gb2JqZWN0X2Zsb29yLT5tYWpvcl92ZXJzaW9uOwogICAgICAgIG9iamVjdC0+U3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24gPSBvYmplY3RfZmxvb3ItPm1pbm9yX3ZlcnNpb247CiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgVG93ZXJDb25zdHJ1Y3QgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgVG93ZXJDb25zdHJ1Y3QoCiAgICBjb25zdCBSUENfU1lOVEFYX0lERU5USUZJRVIgKm9iamVjdCwgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpzeW50YXgsCiAgICBjb25zdCBjaGFyICpwcm90c2VxLCBjb25zdCBjaGFyICplbmRwb2ludCwgY29uc3QgY2hhciAqYWRkcmVzcywKICAgIHR3cl90ICoqdG93ZXIpCnsKICAgIHNpemVfdCB0b3dlcl9zaXplOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICB1bnNpZ25lZCBjaGFyICpwOwogICAgdHdyX3V1aWRfZmxvb3JfdCAqb2JqZWN0X2Zsb29yOwogICAgdHdyX3V1aWRfZmxvb3JfdCAqc3ludGF4X2Zsb29yOwoKICAgICp0b3dlciA9IE5VTEw7CgogICAgc3RhdHVzID0gUnBjVHJhbnNwb3J0X0dldFRvcE9mVG93ZXIoTlVMTCwgJnRvd2VyX3NpemUsIHByb3RzZXEsIGFkZHJlc3MsIGVuZHBvaW50KTsKCiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgIHJldHVybiBzdGF0dXM7CgogICAgdG93ZXJfc2l6ZSArPSBzaXplb2YodV9pbnQxNikgKyBzaXplb2YoKm9iamVjdF9mbG9vcikgKyBzaXplb2YoKnN5bnRheF9mbG9vcik7CiAgICAqdG93ZXIgPSBJX1JwY0FsbG9jYXRlKEZJRUxEX09GRlNFVCh0d3JfdCwgdG93ZXJfb2N0ZXRfc3RyaW5nW3Rvd2VyX3NpemVdKSk7CiAgICBpZiAoISp0b3dlcikKICAgICAgICByZXR1cm4gUlBDX1NfT1VUX09GX1JFU09VUkNFUzsKCiAgICAoKnRvd2VyKS0+dG93ZXJfbGVuZ3RoID0gdG93ZXJfc2l6ZTsKICAgIHAgPSAmKCp0b3dlciktPnRvd2VyX29jdGV0X3N0cmluZ1swXTsKICAgICoodV9pbnQxNiAqKXAgPSA1OyAvKiBudW1iZXIgb2YgZmxvb3JzICovCiAgICBwICs9IHNpemVvZih1X2ludDE2KTsKICAgIG9iamVjdF9mbG9vciA9ICh0d3JfdXVpZF9mbG9vcl90ICopcDsKICAgIHAgKz0gc2l6ZW9mKCpvYmplY3RfZmxvb3IpOwogICAgc3ludGF4X2Zsb29yID0gKHR3cl91dWlkX2Zsb29yX3QgKilwOwogICAgcCArPSBzaXplb2YoKnN5bnRheF9mbG9vcik7CgogICAgb2JqZWN0X2Zsb29yLT5jb3VudF9saHMgPSBzaXplb2Yob2JqZWN0X2Zsb29yLT5wcm90aWQpICsgc2l6ZW9mKG9iamVjdF9mbG9vci0+dXVpZCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yob2JqZWN0X2Zsb29yLT5tYWpvcl92ZXJzaW9uKTsKICAgIG9iamVjdF9mbG9vci0+cHJvdGlkID0gRVBNX1BST1RPQ09MX1VVSUQ7CiAgICBvYmplY3RfZmxvb3ItPmNvdW50X3JocyA9IHNpemVvZihvYmplY3RfZmxvb3ItPm1pbm9yX3ZlcnNpb24pOwogICAgb2JqZWN0X2Zsb29yLT51dWlkID0gb2JqZWN0LT5TeW50YXhHVUlEOwogICAgb2JqZWN0X2Zsb29yLT5tYWpvcl92ZXJzaW9uID0gb2JqZWN0LT5TeW50YXhWZXJzaW9uLk1ham9yVmVyc2lvbjsKICAgIG9iamVjdF9mbG9vci0+bWlub3JfdmVyc2lvbiA9IG9iamVjdC0+U3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb247CgogICAgc3ludGF4X2Zsb29yLT5jb3VudF9saHMgPSBzaXplb2Yoc3ludGF4X2Zsb29yLT5wcm90aWQpICsgc2l6ZW9mKHN5bnRheF9mbG9vci0+dXVpZCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3ludGF4X2Zsb29yLT5tYWpvcl92ZXJzaW9uKTsKICAgIHN5bnRheF9mbG9vci0+cHJvdGlkID0gRVBNX1BST1RPQ09MX1VVSUQ7CiAgICBzeW50YXhfZmxvb3ItPmNvdW50X3JocyA9IHNpemVvZihzeW50YXhfZmxvb3ItPm1pbm9yX3ZlcnNpb24pOwogICAgc3ludGF4X2Zsb29yLT51dWlkID0gc3ludGF4LT5TeW50YXhHVUlEOwogICAgc3ludGF4X2Zsb29yLT5tYWpvcl92ZXJzaW9uID0gc3ludGF4LT5TeW50YXhWZXJzaW9uLk1ham9yVmVyc2lvbjsKICAgIHN5bnRheF9mbG9vci0+bWlub3JfdmVyc2lvbiA9IHN5bnRheC0+U3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb247CgogICAgc3RhdHVzID0gUnBjVHJhbnNwb3J0X0dldFRvcE9mVG93ZXIocCwgJnRvd2VyX3NpemUsIHByb3RzZXEsIGFkZHJlc3MsIGVuZHBvaW50KTsKICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICB7CiAgICAgICAgSV9ScGNGcmVlKCp0b3dlcik7CiAgICAgICAgKnRvd2VyID0gTlVMTDsKICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQogICAgcmV0dXJuIFJQQ19TX09LOwp9Cg==