LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpZm5kZWYgX19XSU5FX1JQQ19CSU5ESU5HX0gKI2RlZmluZSBfX1dJTkVfUlBDX0JJTkRJTkdfSAoKI2luY2x1ZGUgIndpbmUvcnBjc3Nfc2hhcmVkLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKI2luY2x1ZGUgInNlY3VyaXR5LmgiCiNpbmNsdWRlICJ3aW5lL2xpc3QuaCIKCgp0eXBlZGVmIHN0cnVjdCBfUnBjQXV0aEluZm8KewogIExPTkcgcmVmczsKCiAgVUxPTkcgQXV0aG5MZXZlbDsKICBVTE9ORyBBdXRoblN2YzsKICBDcmVkSGFuZGxlIGNyZWQ7CiAgVGltZVN0YW1wIGV4cDsKICBVTE9ORyBjYk1heFRva2VuOwogIC8qIHRoZSBhdXRoIGlkZW50aXR5IHBvaW50ZXIgdGhhdCB0aGUgYXBwbGljYXRpb24gcGFzc2VkIHVzIChmcmVlZCBieSBhcHBsaWNhdGlvbikgKi8KICBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgKmlkZW50aXR5OwogIC8qIG91ciBjb3B5IG9mIE5UIGF1dGggaWRlbnRpdHkgc3RydWN0dXJlLCBpZiB0aGUgYXV0aGVudGljYXRpb24gc2VydmljZQogICAqIHRha2VzIGFuIE5UIGF1dGggaWRlbnRpdHkgKi8KICBTRUNfV0lOTlRfQVVUSF9JREVOVElUWV9XICpudF9pZGVudGl0eTsKICBMUFdTVFIgc2VydmVyX3ByaW5jaXBhbF9uYW1lOwp9IFJwY0F1dGhJbmZvOwoKdHlwZWRlZiBzdHJ1Y3QgX1JwY1F1YWxpdHlPZlNlcnZpY2UKewogICAgTE9ORyByZWZzOwoKICAgIFJQQ19TRUNVUklUWV9RT1NfVjJfVyAqcW9zOwp9IFJwY1F1YWxpdHlPZlNlcnZpY2U7CgpzdHJ1Y3QgY29ubmVjdGlvbl9vcHM7Cgp0eXBlZGVmIHN0cnVjdCBfUnBjQ29ubmVjdGlvbgp7CiAgQk9PTCBzZXJ2ZXI7CiAgTFBTVFIgTmV0d29ya0FkZHI7CiAgTFBTVFIgRW5kcG9pbnQ7CiAgTFBXU1RSIE5ldHdvcmtPcHRpb25zOwogIGNvbnN0IHN0cnVjdCBjb25uZWN0aW9uX29wcyAqb3BzOwogIFVTSE9SVCBNYXhUcmFuc21pc3Npb25TaXplOwoKICAvKiBhdXRoZW50aWNhdGlvbiAqLwogIEN0eHRIYW5kbGUgY3R4OwogIFRpbWVTdGFtcCBleHA7CiAgVUxPTkcgYXR0cjsKICBScGNBdXRoSW5mbyAqQXV0aEluZm87CiAgVUxPTkcgZW5jcnlwdGlvbl9hdXRoX2xlbjsKICBVTE9ORyBzaWduYXR1cmVfYXV0aF9sZW47CiAgUnBjUXVhbGl0eU9mU2VydmljZSAqUU9TOwoKICAvKiBjbGllbnQtb25seSAqLwogIHN0cnVjdCBsaXN0IGNvbm5fcG9vbF9lbnRyeTsKICBVTE9ORyBhc3NvY19ncm91cF9pZDsgLyogYXNzb2NpYXRpb24gZ3JvdXAgcmV0dXJuZWQgZHVyaW5nIGJpbmRpbmcgKi8KICBSUENfQVNZTkNfU1RBVEUgKmFzeW5jX3N0YXRlOwoKICAvKiBzZXJ2ZXItb25seSAqLwogIC8qIFRoZSBhY3RpdmUgaW50ZXJmYWNlIGJvdW5kIHRvIHNlcnZlci4gKi8KICBSUENfU1lOVEFYX0lERU5USUZJRVIgQWN0aXZlSW50ZXJmYWNlOwogIFVTSE9SVCBOZXh0Q2FsbElkOwogIHN0cnVjdCBfUnBjQ29ubmVjdGlvbiogTmV4dDsKICBzdHJ1Y3QgX1JwY0JpbmRpbmcgKnNlcnZlcl9iaW5kaW5nOwp9IFJwY0Nvbm5lY3Rpb247CgpzdHJ1Y3QgY29ubmVjdGlvbl9vcHMgewogIGNvbnN0IGNoYXIgKm5hbWU7CiAgdW5zaWduZWQgY2hhciBlcG1fcHJvdG9jb2xzWzJdOyAvKiBvbmx5IGZsb29ycyAzIGFuZCA0LiBzZWUgaHR0cDovL3d3dy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvOTYyOTM5OS9hcGR4bC5odG0gKi8KICBScGNDb25uZWN0aW9uICooKmFsbG9jKSh2b2lkKTsKICBSUENfU1RBVFVTICgqb3Blbl9jb25uZWN0aW9uX2NsaWVudCkoUnBjQ29ubmVjdGlvbiAqY29ubik7CiAgUlBDX1NUQVRVUyAoKmhhbmRvZmYpKFJwY0Nvbm5lY3Rpb24gKm9sZF9jb25uLCBScGNDb25uZWN0aW9uICpuZXdfY29ubik7CiAgaW50ICgqcmVhZCkoUnBjQ29ubmVjdGlvbiAqY29ubiwgdm9pZCAqYnVmZmVyLCB1bnNpZ25lZCBpbnQgbGVuKTsKICBpbnQgKCp3cml0ZSkoUnBjQ29ubmVjdGlvbiAqY29ubiwgY29uc3Qgdm9pZCAqYnVmZmVyLCB1bnNpZ25lZCBpbnQgbGVuKTsKICBpbnQgKCpjbG9zZSkoUnBjQ29ubmVjdGlvbiAqY29ubik7CiAgdm9pZCAoKmNhbmNlbF9jYWxsKShScGNDb25uZWN0aW9uICpjb25uKTsKICBpbnQgKCp3YWl0X2Zvcl9pbmNvbWluZ19kYXRhKShScGNDb25uZWN0aW9uICpjb25uKTsKICBzaXplX3QgKCpnZXRfdG9wX29mX3Rvd2VyKSh1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLCBjb25zdCBjaGFyICpuZXR3b3JrYWRkciwgY29uc3QgY2hhciAqZW5kcG9pbnQpOwogIFJQQ19TVEFUVVMgKCpwYXJzZV90b3Bfb2ZfdG93ZXIpKGNvbnN0IHVuc2lnbmVkIGNoYXIgKnRvd2VyX2RhdGEsIHNpemVfdCB0b3dlcl9zaXplLCBjaGFyICoqbmV0d29ya2FkZHIsIGNoYXIgKiplbmRwb2ludCk7Cn07CgovKiBkb24ndCBrbm93IHdoYXQgTVMncyBzdHJ1Y3R1cmUgbG9va3MgbGlrZSAqLwp0eXBlZGVmIHN0cnVjdCBfUnBjQmluZGluZwp7CiAgTE9ORyByZWZzOwogIHN0cnVjdCBfUnBjQmluZGluZyogTmV4dDsKICBCT09MIHNlcnZlcjsKICBVVUlEIE9iamVjdFV1aWQ7CiAgTFBTVFIgUHJvdHNlcTsKICBMUFNUUiBOZXR3b3JrQWRkcjsKICBMUFNUUiBFbmRwb2ludDsKICBMUFdTVFIgTmV0d29ya09wdGlvbnM7CiAgUlBDX0JMT0NLSU5HX0ZOIEJsb2NraW5nRm47CiAgVUxPTkcgU2VydmVyVGlkOwogIFJwY0Nvbm5lY3Rpb24qIEZyb21Db25uOwogIHN0cnVjdCBfUnBjQXNzb2MgKkFzc29jOwoKICAvKiBhdXRoZW50aWNhdGlvbiAqLwogIFJwY0F1dGhJbmZvICpBdXRoSW5mbzsKICBScGNRdWFsaXR5T2ZTZXJ2aWNlICpRT1M7Cn0gUnBjQmluZGluZzsKCkxQU1RSIFJQQ1JUNF9zdHJuZHVwQShMUENTVFIgc3JjLCBJTlQgbGVuKTsKTFBXU1RSIFJQQ1JUNF9zdHJuZHVwVyhMUENXU1RSIHNyYywgSU5UIGxlbik7CkxQU1RSIFJQQ1JUNF9zdHJkdXBXdG9BKExQQ1dTVFIgc3JjKTsKTFBXU1RSIFJQQ1JUNF9zdHJkdXBBdG9XKExQQ1NUUiBzcmMpOwp2b2lkIFJQQ1JUNF9zdHJmcmVlKExQU1RSIHNyYyk7CgojZGVmaW5lIFJQQ1JUNF9zdHJkdXBBKHgpIFJQQ1JUNF9zdHJuZHVwQSgoeCksLTEpCiNkZWZpbmUgUlBDUlQ0X3N0cmR1cFcoeCkgUlBDUlQ0X3N0cm5kdXBXKCh4KSwtMSkKClVMT05HIFJwY0F1dGhJbmZvX0FkZFJlZihScGNBdXRoSW5mbyAqQXV0aEluZm8pOwpVTE9ORyBScGNBdXRoSW5mb19SZWxlYXNlKFJwY0F1dGhJbmZvICpBdXRoSW5mbyk7CkJPT0wgUnBjQXV0aEluZm9fSXNFcXVhbChjb25zdCBScGNBdXRoSW5mbyAqQXV0aEluZm8xLCBjb25zdCBScGNBdXRoSW5mbyAqQXV0aEluZm8yKTsKVUxPTkcgUnBjUXVhbGl0eU9mU2VydmljZV9BZGRSZWYoUnBjUXVhbGl0eU9mU2VydmljZSAqcW9zKTsKVUxPTkcgUnBjUXVhbGl0eU9mU2VydmljZV9SZWxlYXNlKFJwY1F1YWxpdHlPZlNlcnZpY2UgKnFvcyk7CkJPT0wgUnBjUXVhbGl0eU9mU2VydmljZV9Jc0VxdWFsKGNvbnN0IFJwY1F1YWxpdHlPZlNlcnZpY2UgKnFvczEsIGNvbnN0IFJwY1F1YWxpdHlPZlNlcnZpY2UgKnFvczIpOwoKUlBDX1NUQVRVUyBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwgQk9PTCBzZXJ2ZXIsIExQQ1NUUiBQcm90c2VxLCBMUENTVFIgTmV0d29ya0FkZHIsIExQQ1NUUiBFbmRwb2ludCwgTFBDV1NUUiBOZXR3b3JrT3B0aW9ucywgUnBjQXV0aEluZm8qIEF1dGhJbmZvLCBScGNRdWFsaXR5T2ZTZXJ2aWNlICpRT1MpOwpSUENfU1RBVFVTIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKTsKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkNsaWVudENvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbik7ClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKTsKUlBDX1NUQVRVUyBSUENSVDRfU3Bhd25Db25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBScGNDb25uZWN0aW9uKiBPbGRDb25uZWN0aW9uKTsKClJQQ19TVEFUVVMgUlBDUlQ0X1Jlc29sdmVCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQQ1NUUiBFbmRwb2ludCk7ClJQQ19TVEFUVVMgUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoUnBjQmluZGluZyogQmluZGluZywgY29uc3QgVVVJRCogT2JqZWN0VXVpZCk7ClJQQ19TVEFUVVMgUlBDUlQ0X01ha2VCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKTsKUlBDX1NUQVRVUyBSUENSVDRfRXhwb3J0QmluZGluZyhScGNCaW5kaW5nKiogQmluZGluZywgUnBjQmluZGluZyogT2xkQmluZGluZyk7ClJQQ19TVEFUVVMgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcpOwpSUENfU1RBVFVTIFJQQ1JUNF9PcGVuQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpUcmFuc2ZlclN5bnRheCwgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpJbnRlcmZhY2VJZCk7ClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKTsKQk9PTCBSUENSVDRfUlBDU1NPbkRlbWFuZENhbGwoUFJQQ1NTX05QX01FU1NBR0UgbXNnLCBjaGFyICp2YXJkYXRhX3BheWxvYWQsIFBSUENTU19OUF9SRVBMWSByZXBseSk7CkhBTkRMRSBSUENSVDRfR2V0TWFzdGVyTXV0ZXgodm9pZCk7CkhBTkRMRSBSUENSVDRfUnBjc3NOUENvbm5lY3Qodm9pZCk7CgpzdGF0aWMgaW5saW5lIGNvbnN0IGNoYXIgKnJwY3J0NF9jb25uX2dldF9uYW1lKGNvbnN0IFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICByZXR1cm4gQ29ubmVjdGlvbi0+b3BzLT5uYW1lOwp9CgpzdGF0aWMgaW5saW5lIGludCBycGNydDRfY29ubl9yZWFkKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgaW50IGxlbikKewogIHJldHVybiBDb25uZWN0aW9uLT5vcHMtPnJlYWQoQ29ubmVjdGlvbiwgYnVmZmVyLCBsZW4pOwp9CgpzdGF0aWMgaW5saW5lIGludCBycGNydDRfY29ubl93cml0ZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBsZW4pCnsKICByZXR1cm4gQ29ubmVjdGlvbi0+b3BzLT53cml0ZShDb25uZWN0aW9uLCBidWZmZXIsIGxlbik7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IHJwY3J0NF9jb25uX2Nsb3NlKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICByZXR1cm4gQ29ubmVjdGlvbi0+b3BzLT5jbG9zZShDb25uZWN0aW9uKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHJwY3J0NF9jb25uX2NhbmNlbF9jYWxsKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICBDb25uZWN0aW9uLT5vcHMtPmNhbmNlbF9jYWxsKENvbm5lY3Rpb24pOwp9CgpzdGF0aWMgaW5saW5lIFJQQ19TVEFUVVMgcnBjcnQ0X2Nvbm5faGFuZG9mZihScGNDb25uZWN0aW9uICpvbGRfY29ubiwgUnBjQ29ubmVjdGlvbiAqbmV3X2Nvbm4pCnsKICByZXR1cm4gb2xkX2Nvbm4tPm9wcy0+aGFuZG9mZihvbGRfY29ubiwgbmV3X2Nvbm4pOwp9CgovKiBmbG9vcnMgMyBhbmQgdXAgKi8KUlBDX1NUQVRVUyBScGNUcmFuc3BvcnRfR2V0VG9wT2ZUb3dlcih1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLCBzaXplX3QgKnRvd2VyX3NpemUsIGNvbnN0IGNoYXIgKnByb3RzZXEsIGNvbnN0IGNoYXIgKm5ldHdvcmthZGRyLCBjb25zdCBjaGFyICplbmRwb2ludCk7ClJQQ19TVEFUVVMgUnBjVHJhbnNwb3J0X1BhcnNlVG9wT2ZUb3dlcihjb25zdCB1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLCBzaXplX3QgdG93ZXJfc2l6ZSwgY2hhciAqKnByb3RzZXEsIGNoYXIgKipuZXR3b3JrYWRkciwgY2hhciAqKmVuZHBvaW50KTsKCnZvaWQgUlBDUlQ0X1NldFRocmVhZEN1cnJlbnRDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pOwp2b2lkIFJQQ1JUNF9TZXRUaHJlYWRDdXJyZW50Q2FsbEhhbmRsZShScGNCaW5kaW5nICpCaW5kaW5nKTsKUnBjQmluZGluZyAqUlBDUlQ0X0dldFRocmVhZEN1cnJlbnRDYWxsSGFuZGxlKHZvaWQpOwp2b2lkIFJQQ1JUNF9QdXNoVGhyZWFkQ29udGV4dEhhbmRsZShORFJfU0NPTlRFWFQgU0NvbnRleHQpOwp2b2lkIFJQQ1JUNF9SZW1vdmVUaHJlYWRDb250ZXh0SGFuZGxlKE5EUl9TQ09OVEVYVCBTQ29udGV4dCk7Ck5EUl9TQ09OVEVYVCBSUENSVDRfUG9wVGhyZWFkQ29udGV4dEhhbmRsZSh2b2lkKTsKCiNlbmRpZgo=