LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpZm5kZWYgX19XSU5FX1JQQ19CSU5ESU5HX0gKI2RlZmluZSBfX1dJTkVfUlBDX0JJTkRJTkdfSAoKI2luY2x1ZGUgIndpbmUvcnBjc3Nfc2hhcmVkLmgiCiNpbmNsdWRlICJzZWN1cml0eS5oIgojaW5jbHVkZSAid2luZS9saXN0LmgiCgoKdHlwZWRlZiBzdHJ1Y3QgX1JwY0F1dGhJbmZvCnsKICBMT05HIHJlZnM7CgogIFVMT05HIEF1dGhuTGV2ZWw7CiAgVUxPTkcgQXV0aG5TdmM7CiAgQ3JlZEhhbmRsZSBjcmVkOwogIFRpbWVTdGFtcCBleHA7CiAgVUxPTkcgY2JNYXhUb2tlbjsKfSBScGNBdXRoSW5mbzsKCnR5cGVkZWYgc3RydWN0IF9ScGNRdWFsaXR5T2ZTZXJ2aWNlCnsKICAgIExPTkcgcmVmczsKCiAgICBSUENfU0VDVVJJVFlfUU9TX1YyX1cgKnFvczsKfSBScGNRdWFsaXR5T2ZTZXJ2aWNlOwoKdHlwZWRlZiBzdHJ1Y3QgX1JwY0Fzc29jCnsKICAgIHN0cnVjdCBsaXN0IGVudHJ5OyAvKiBlbnRyeSBpbiB0aGUgZ2xvYmFsIGxpc3Qgb2YgYXNzb2NpYXRpb25zICovCiAgICBMT05HIHJlZnM7CgogICAgTFBTVFIgUHJvdHNlcTsKICAgIExQU1RSIE5ldHdvcmtBZGRyOwogICAgTFBTVFIgRW5kcG9pbnQ7CiAgICBMUFdTVFIgTmV0d29ya09wdGlvbnM7CiAgICBScGNBdXRoSW5mbyAqQXV0aEluZm87CgogICAgQ1JJVElDQUxfU0VDVElPTiBjczsKICAgIHN0cnVjdCBsaXN0IGNvbm5lY3Rpb25fcG9vbDsKfSBScGNBc3NvYzsKCnN0cnVjdCBjb25uZWN0aW9uX29wczsKCnR5cGVkZWYgc3RydWN0IF9ScGNDb25uZWN0aW9uCnsKICBzdHJ1Y3QgX1JwY0Nvbm5lY3Rpb24qIE5leHQ7CiAgc3RydWN0IF9ScGNCaW5kaW5nKiBVc2VkOwogIEJPT0wgc2VydmVyOwogIExQU1RSIE5ldHdvcmtBZGRyOwogIExQU1RSIEVuZHBvaW50OwogIExQV1NUUiBOZXR3b3JrT3B0aW9uczsKICBjb25zdCBzdHJ1Y3QgY29ubmVjdGlvbl9vcHMgKm9wczsKICBVU0hPUlQgTWF4VHJhbnNtaXNzaW9uU2l6ZTsKICAvKiBUaGUgYWN0aXZlIGludGVyZmFjZSBib3VuZCB0byBzZXJ2ZXIuICovCiAgUlBDX1NZTlRBWF9JREVOVElGSUVSIEFjdGl2ZUludGVyZmFjZTsKICBVU0hPUlQgTmV4dENhbGxJZDsKCiAgLyogYXV0aGVudGljYXRpb24gKi8KICBDdHh0SGFuZGxlIGN0eDsKICBUaW1lU3RhbXAgZXhwOwogIFVMT05HIGF0dHI7CiAgUnBjQXV0aEluZm8gKkF1dGhJbmZvOwogIFVMT05HIGVuY3J5cHRpb25fYXV0aF9sZW47CiAgVUxPTkcgc2lnbmF0dXJlX2F1dGhfbGVuOwogIFJwY1F1YWxpdHlPZlNlcnZpY2UgKlFPUzsKCiAgLyogY2xpZW50LW9ubHkgKi8KICBzdHJ1Y3QgbGlzdCBjb25uX3Bvb2xfZW50cnk7Cn0gUnBjQ29ubmVjdGlvbjsKCnN0cnVjdCBjb25uZWN0aW9uX29wcyB7CiAgY29uc3QgY2hhciAqbmFtZTsKICB1bnNpZ25lZCBjaGFyIGVwbV9wcm90b2NvbHNbMl07IC8qIG9ubHkgZmxvb3JzIDMgYW5kIDQuIHNlZSBodHRwOi8vd3d3Lm9wZW5ncm91cC5vcmcvb25saW5lcHVicy85NjI5Mzk5L2FwZHhsLmh0bSAqLwogIFJwY0Nvbm5lY3Rpb24gKigqYWxsb2MpKHZvaWQpOwogIFJQQ19TVEFUVVMgKCpvcGVuX2Nvbm5lY3Rpb25fY2xpZW50KShScGNDb25uZWN0aW9uICpjb25uKTsKICBSUENfU1RBVFVTICgqaGFuZG9mZikoUnBjQ29ubmVjdGlvbiAqb2xkX2Nvbm4sIFJwY0Nvbm5lY3Rpb24gKm5ld19jb25uKTsKICBpbnQgKCpyZWFkKShScGNDb25uZWN0aW9uICpjb25uLCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBsZW4pOwogIGludCAoKndyaXRlKShScGNDb25uZWN0aW9uICpjb25uLCBjb25zdCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBsZW4pOwogIGludCAoKmNsb3NlKShScGNDb25uZWN0aW9uICpjb25uKTsKICBzaXplX3QgKCpnZXRfdG9wX29mX3Rvd2VyKSh1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLCBjb25zdCBjaGFyICpuZXR3b3JrYWRkciwgY29uc3QgY2hhciAqZW5kcG9pbnQpOwogIFJQQ19TVEFUVVMgKCpwYXJzZV90b3Bfb2ZfdG93ZXIpKGNvbnN0IHVuc2lnbmVkIGNoYXIgKnRvd2VyX2RhdGEsIHNpemVfdCB0b3dlcl9zaXplLCBjaGFyICoqbmV0d29ya2FkZHIsIGNoYXIgKiplbmRwb2ludCk7Cn07CgovKiBkb24ndCBrbm93IHdoYXQgTVMncyBzdHJ1Y3R1cmUgbG9va3MgbGlrZSAqLwp0eXBlZGVmIHN0cnVjdCBfUnBjQmluZGluZwp7CiAgTE9ORyByZWZzOwogIHN0cnVjdCBfUnBjQmluZGluZyogTmV4dDsKICBCT09MIHNlcnZlcjsKICBVVUlEIE9iamVjdFV1aWQ7CiAgTFBTVFIgUHJvdHNlcTsKICBMUFNUUiBOZXR3b3JrQWRkcjsKICBMUFNUUiBFbmRwb2ludDsKICBMUFdTVFIgTmV0d29ya09wdGlvbnM7CiAgUlBDX0JMT0NLSU5HX0ZOIEJsb2NraW5nRm47CiAgVUxPTkcgU2VydmVyVGlkOwogIFJwY0Nvbm5lY3Rpb24qIEZyb21Db25uOwogIFJwY0Fzc29jICpBc3NvYzsKCiAgLyogYXV0aGVudGljYXRpb24gKi8KICBScGNBdXRoSW5mbyAqQXV0aEluZm87CiAgUnBjUXVhbGl0eU9mU2VydmljZSAqUU9TOwp9IFJwY0JpbmRpbmc7CgpMUFNUUiBSUENSVDRfc3RybmR1cEEoTFBDU1RSIHNyYywgSU5UIGxlbik7CkxQV1NUUiBSUENSVDRfc3RybmR1cFcoTFBDV1NUUiBzcmMsIElOVCBsZW4pOwpMUFNUUiBSUENSVDRfc3RyZHVwV3RvQShMUENXU1RSIHNyYyk7CkxQV1NUUiBSUENSVDRfc3RyZHVwQXRvVyhMUENTVFIgc3JjKTsKdm9pZCBSUENSVDRfc3RyZnJlZShMUFNUUiBzcmMpOwoKI2RlZmluZSBSUENSVDRfc3RyZHVwQSh4KSBSUENSVDRfc3RybmR1cEEoKHgpLC0xKQojZGVmaW5lIFJQQ1JUNF9zdHJkdXBXKHgpIFJQQ1JUNF9zdHJuZHVwVygoeCksLTEpCgpVTE9ORyBScGNBdXRoSW5mb19BZGRSZWYoUnBjQXV0aEluZm8gKkF1dGhJbmZvKTsKVUxPTkcgUnBjQXV0aEluZm9fUmVsZWFzZShScGNBdXRoSW5mbyAqQXV0aEluZm8pOwpVTE9ORyBScGNRdWFsaXR5T2ZTZXJ2aWNlX0FkZFJlZihScGNRdWFsaXR5T2ZTZXJ2aWNlICpxb3MpOwpVTE9ORyBScGNRdWFsaXR5T2ZTZXJ2aWNlX1JlbGVhc2UoUnBjUXVhbGl0eU9mU2VydmljZSAqcW9zKTsKClJQQ19TVEFUVVMgUlBDUlQ0X0dldEFzc29jaWF0aW9uKExQQ1NUUiBQcm90c2VxLCBMUENTVFIgTmV0d29ya0FkZHIsIExQQ1NUUiBFbmRwb2ludCwgTFBDV1NUUiBOZXR3b3JrT3B0aW9ucywgUnBjQXNzb2MgKiphc3NvYyk7ClJwY0Nvbm5lY3Rpb24gKlJwY0Fzc29jX0dldElkbGVDb25uZWN0aW9uKFJwY0Fzc29jICphc3NvYywgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpJbnRlcmZhY2VJZCwgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpUcmFuc2ZlclN5bnRheCwgY29uc3QgUnBjQXV0aEluZm8gKkF1dGhJbmZvLCBjb25zdCBScGNRdWFsaXR5T2ZTZXJ2aWNlICpRT1MpOwp2b2lkIFJwY0Fzc29jX1JlbGVhc2VJZGxlQ29ubmVjdGlvbihScGNBc3NvYyAqYXNzb2MsIFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pOwpVTE9ORyBScGNBc3NvY19SZWxlYXNlKFJwY0Fzc29jICphc3NvYyk7CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBCT09MIHNlcnZlciwgTFBDU1RSIFByb3RzZXEsIExQQ1NUUiBOZXR3b3JrQWRkciwgTFBDU1RSIEVuZHBvaW50LCBMUENXU1RSIE5ldHdvcmtPcHRpb25zLCBScGNBdXRoSW5mbyogQXV0aEluZm8sIFJwY1F1YWxpdHlPZlNlcnZpY2UgKlFPUywgUnBjQmluZGluZyogQmluZGluZyk7ClJQQ19TVEFUVVMgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pOwpSUENfU1RBVFVTIFJQQ1JUNF9PcGVuQ2xpZW50Q29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKTsKUlBDX1NUQVRVUyBSUENSVDRfQ2xvc2VDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pOwpSUENfU1RBVFVTIFJQQ1JUNF9TcGF3bkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbioqIENvbm5lY3Rpb24sIFJwY0Nvbm5lY3Rpb24qIE9sZENvbm5lY3Rpb24pOwoKUlBDX1NUQVRVUyBSUENSVDRfUmVzb2x2ZUJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZywgTFBDU1RSIEVuZHBvaW50KTsKUlBDX1NUQVRVUyBSUENSVDRfU2V0QmluZGluZ09iamVjdChScGNCaW5kaW5nKiBCaW5kaW5nLCBjb25zdCBVVUlEKiBPYmplY3RVdWlkKTsKUlBDX1NUQVRVUyBSUENSVDRfTWFrZUJpbmRpbmcoUnBjQmluZGluZyoqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pOwpSUENfU1RBVFVTIFJQQ1JUNF9FeHBvcnRCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNCaW5kaW5nKiBPbGRCaW5kaW5nKTsKUlBDX1NUQVRVUyBSUENSVDRfRGVzdHJveUJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZyk7ClJQQ19TVEFUVVMgUlBDUlQ0X09wZW5CaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBQUlBDX1NZTlRBWF9JREVOVElGSUVSIFRyYW5zZmVyU3ludGF4LCBQUlBDX1NZTlRBWF9JREVOVElGSUVSIEludGVyZmFjZUlkKTsKUlBDX1NUQVRVUyBSUENSVDRfQ2xvc2VCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pOwpCT09MIFJQQ1JUNF9SUENTU09uRGVtYW5kQ2FsbChQUlBDU1NfTlBfTUVTU0FHRSBtc2csIGNoYXIgKnZhcmRhdGFfcGF5bG9hZCwgUFJQQ1NTX05QX1JFUExZIHJlcGx5KTsKSEFORExFIFJQQ1JUNF9HZXRNYXN0ZXJNdXRleCh2b2lkKTsKSEFORExFIFJQQ1JUNF9ScGNzc05QQ29ubmVjdCh2b2lkKTsKCnN0YXRpYyBpbmxpbmUgY29uc3QgY2hhciAqcnBjcnQ0X2Nvbm5fZ2V0X25hbWUoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbikKewogIHJldHVybiBDb25uZWN0aW9uLT5vcHMtPm5hbWU7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IHJwY3J0NF9jb25uX3JlYWQoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgdm9pZCAqYnVmZmVyLCB1bnNpZ25lZCBpbnQgbGVuKQp7CiAgcmV0dXJuIENvbm5lY3Rpb24tPm9wcy0+cmVhZChDb25uZWN0aW9uLCBidWZmZXIsIGxlbik7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IHJwY3J0NF9jb25uX3dyaXRlKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgaW50IGxlbikKewogIHJldHVybiBDb25uZWN0aW9uLT5vcHMtPndyaXRlKENvbm5lY3Rpb24sIGJ1ZmZlciwgbGVuKTsKfQoKc3RhdGljIGlubGluZSBpbnQgcnBjcnQ0X2Nvbm5fY2xvc2UoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbikKewogIHJldHVybiBDb25uZWN0aW9uLT5vcHMtPmNsb3NlKENvbm5lY3Rpb24pOwp9CgpzdGF0aWMgaW5saW5lIFJQQ19TVEFUVVMgcnBjcnQ0X2Nvbm5faGFuZG9mZihScGNDb25uZWN0aW9uICpvbGRfY29ubiwgUnBjQ29ubmVjdGlvbiAqbmV3X2Nvbm4pCnsKICByZXR1cm4gb2xkX2Nvbm4tPm9wcy0+aGFuZG9mZihvbGRfY29ubiwgbmV3X2Nvbm4pOwp9CgovKiBmbG9vcnMgMyBhbmQgdXAgKi8KUlBDX1NUQVRVUyBScGNUcmFuc3BvcnRfR2V0VG9wT2ZUb3dlcih1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLCBzaXplX3QgKnRvd2VyX3NpemUsIGNvbnN0IGNoYXIgKnByb3RzZXEsIGNvbnN0IGNoYXIgKm5ldHdvcmthZGRyLCBjb25zdCBjaGFyICplbmRwb2ludCk7ClJQQ19TVEFUVVMgUnBjVHJhbnNwb3J0X1BhcnNlVG9wT2ZUb3dlcihjb25zdCB1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLCBzaXplX3QgdG93ZXJfc2l6ZSwgY2hhciAqKnByb3RzZXEsIGNoYXIgKipuZXR3b3JrYWRkciwgY2hhciAqKmVuZHBvaW50KTsKCiNlbmRpZgo=