LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpZm5kZWYgX19XSU5FX1JQQ19CSU5ESU5HX0gKI2RlZmluZSBfX1dJTkVfUlBDX0JJTkRJTkdfSAoKI2luY2x1ZGUgIndpbmUvcnBjc3Nfc2hhcmVkLmgiCgpzdHJ1Y3QgcHJvdHNlcV9vcHM7Cgp0eXBlZGVmIHN0cnVjdCBfUnBjQ29ubmVjdGlvbgp7CiAgc3RydWN0IF9ScGNDb25uZWN0aW9uKiBOZXh0OwogIHN0cnVjdCBfUnBjQmluZGluZyogVXNlZDsKICBCT09MIHNlcnZlcjsKICBMUFNUUiBOZXR3b3JrQWRkcjsKICBMUFNUUiBFbmRwb2ludDsKICBzdHJ1Y3QgcHJvdHNlcV9vcHMgKm9wczsKICBVU0hPUlQgTWF4VHJhbnNtaXNzaW9uU2l6ZTsKICAvKiBUaGUgYWN0aXZlIGludGVyZmFjZSBib3VuZCB0byBzZXJ2ZXIuICovCiAgUlBDX1NZTlRBWF9JREVOVElGSUVSIEFjdGl2ZUludGVyZmFjZTsKfSBScGNDb25uZWN0aW9uOwoKc3RydWN0IHByb3RzZXFfb3BzIHsKICBjaGFyICpuYW1lOwogIFJwY0Nvbm5lY3Rpb24gKigqYWxsb2MpKHZvaWQpOwogIFJQQ19TVEFUVVMgKCpvcGVuX2Nvbm5lY3Rpb24pKFJwY0Nvbm5lY3Rpb24gKmNvbm4pOwogIEhBTkRMRSAoKmdldF9jb25uZWN0X3dhaXRfaGFuZGxlKShScGNDb25uZWN0aW9uICpjb25uKTsKICBSUENfU1RBVFVTICgqaGFuZG9mZikoUnBjQ29ubmVjdGlvbiAqb2xkX2Nvbm4sIFJwY0Nvbm5lY3Rpb24gKm5ld19jb25uKTsKICBpbnQgKCpyZWFkKShScGNDb25uZWN0aW9uICpjb25uLCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBsZW4pOwogIGludCAoKndyaXRlKShScGNDb25uZWN0aW9uICpjb25uLCBjb25zdCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBsZW4pOwogIGludCAoKmNsb3NlKShScGNDb25uZWN0aW9uICpjb25uKTsKfTsKCi8qIGRvbid0IGtub3cgd2hhdCBNUydzIHN0cnVjdHVyZSBsb29rcyBsaWtlICovCnR5cGVkZWYgc3RydWN0IF9ScGNCaW5kaW5nCnsKICBMT05HIHJlZnM7CiAgc3RydWN0IF9ScGNCaW5kaW5nKiBOZXh0OwogIEJPT0wgc2VydmVyOwogIFVVSUQgT2JqZWN0VXVpZDsKICBMUFNUUiBQcm90c2VxOwogIExQU1RSIE5ldHdvcmtBZGRyOwogIExQU1RSIEVuZHBvaW50OwogIFJQQ19CTE9DS0lOR19GTiBCbG9ja2luZ0ZuOwogIFVMT05HIFNlcnZlclRpZDsKICBScGNDb25uZWN0aW9uKiBGcm9tQ29ubjsKfSBScGNCaW5kaW5nOwoKTFBTVFIgUlBDUlQ0X3N0cm5kdXBBKExQQ1NUUiBzcmMsIElOVCBsZW4pOwpMUFdTVFIgUlBDUlQ0X3N0cm5kdXBXKExQV1NUUiBzcmMsIElOVCBsZW4pOwpMUFNUUiBSUENSVDRfc3RyZHVwV3RvQShMUFdTVFIgc3JjKTsKTFBXU1RSIFJQQ1JUNF9zdHJkdXBBdG9XKExQU1RSIHNyYyk7CnZvaWQgUlBDUlQ0X3N0cmZyZWUoTFBTVFIgc3JjKTsKCiNkZWZpbmUgUlBDUlQ0X3N0cmR1cEEoeCkgUlBDUlQ0X3N0cm5kdXBBKCh4KSwtMSkKI2RlZmluZSBSUENSVDRfc3RyZHVwVyh4KSBSUENSVDRfc3RybmR1cFcoKHgpLC0xKQoKUlBDX1NUQVRVUyBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwgQk9PTCBzZXJ2ZXIsIExQQ1NUUiBQcm90c2VxLCBMUENTVFIgTmV0d29ya0FkZHIsIExQQ1NUUiBFbmRwb2ludCwgTFBDU1RSIE5ldHdvcmtPcHRpb25zLCBScGNCaW5kaW5nKiBCaW5kaW5nKTsKUlBDX1NUQVRVUyBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbik7ClJQQ19TVEFUVVMgUlBDUlQ0X09wZW5Db25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pOwpSUENfU1RBVFVTIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbik7ClJQQ19TVEFUVVMgUlBDUlQ0X1NwYXduQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwgUnBjQ29ubmVjdGlvbiogT2xkQ29ubmVjdGlvbik7CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVCaW5kaW5nQShScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIsIExQU1RSIFByb3RzZXEpOwpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVCaW5kaW5nVyhScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIsIExQV1NUUiBQcm90c2VxKTsKUlBDX1NUQVRVUyBSUENSVDRfQ29tcGxldGVCaW5kaW5nQShScGNCaW5kaW5nKiBCaW5kaW5nLCBMUFNUUiBOZXR3b3JrQWRkciwgIExQU1RSIEVuZHBvaW50LCAgTFBTVFIgTmV0d29ya09wdGlvbnMpOwpSUENfU1RBVFVTIFJQQ1JUNF9Db21wbGV0ZUJpbmRpbmdXKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQV1NUUiBOZXR3b3JrQWRkciwgTFBXU1RSIEVuZHBvaW50LCBMUFdTVFIgTmV0d29ya09wdGlvbnMpOwpSUENfU1RBVFVTIFJQQ1JUNF9SZXNvbHZlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBMUFNUUiBFbmRwb2ludCk7ClJQQ19TVEFUVVMgUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoUnBjQmluZGluZyogQmluZGluZywgVVVJRCogT2JqZWN0VXVpZCk7ClJQQ19TVEFUVVMgUlBDUlQ0X01ha2VCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKTsKUlBDX1NUQVRVUyBSUENSVDRfRXhwb3J0QmluZGluZyhScGNCaW5kaW5nKiogQmluZGluZywgUnBjQmluZGluZyogT2xkQmluZGluZyk7ClJQQ19TVEFUVVMgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcpOwpSUENfU1RBVFVTIFJQQ1JUNF9PcGVuQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwgUFJQQ19TWU5UQVhfSURFTlRJRklFUiBUcmFuc2ZlclN5bnRheCwgUFJQQ19TWU5UQVhfSURFTlRJRklFUiBJbnRlcmZhY2VJZCk7ClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKTsKQk9PTCBSUENSVDRfUlBDU1NPbkRlbWFuZENhbGwoUFJQQ1NTX05QX01FU1NBR0UgbXNnLCBjaGFyICp2YXJkYXRhX3BheWxvYWQsIFBSUENTU19OUF9SRVBMWSByZXBseSk7CkhBTkRMRSBSUENSVDRfR2V0TWFzdGVyTXV0ZXgodm9pZCk7CkhBTkRMRSBSUENSVDRfUnBjc3NOUENvbm5lY3Qodm9pZCk7CgpzdGF0aWMgaW5saW5lIGNvbnN0IGNoYXIgKnJwY3J0NF9jb25uX2dldF9uYW1lKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICByZXR1cm4gQ29ubmVjdGlvbi0+b3BzLT5uYW1lOwp9CgpzdGF0aWMgaW5saW5lIGludCBycGNydDRfY29ubl9yZWFkKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgaW50IGxlbikKewogIHJldHVybiBDb25uZWN0aW9uLT5vcHMtPnJlYWQoQ29ubmVjdGlvbiwgYnVmZmVyLCBsZW4pOwp9CgpzdGF0aWMgaW5saW5lIGludCBycGNydDRfY29ubl93cml0ZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBsZW4pCnsKICByZXR1cm4gQ29ubmVjdGlvbi0+b3BzLT53cml0ZShDb25uZWN0aW9uLCBidWZmZXIsIGxlbik7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IHJwY3J0NF9jb25uX2Nsb3NlKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICByZXR1cm4gQ29ubmVjdGlvbi0+b3BzLT5jbG9zZShDb25uZWN0aW9uKTsKfQoKc3RhdGljIGlubGluZSBIQU5ETEUgcnBjcnQ0X2Nvbm5fZ2V0X3dhaXRfb2JqZWN0KFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICByZXR1cm4gQ29ubmVjdGlvbi0+b3BzLT5nZXRfY29ubmVjdF93YWl0X2hhbmRsZShDb25uZWN0aW9uKTsKfQoKc3RhdGljIGlubGluZSBSUENfU1RBVFVTIHJwY3J0NF9jb25uX2hhbmRvZmYoUnBjQ29ubmVjdGlvbiAqb2xkX2Nvbm4sIFJwY0Nvbm5lY3Rpb24gKm5ld19jb25uKQp7CiAgcmV0dXJuIG9sZF9jb25uLT5vcHMtPmhhbmRvZmYob2xkX2Nvbm4sIG5ld19jb25uKTsKfQoKI2VuZGlmCg==