LyogVGhpcyBzb3VyY2UgY29kZSB3YXMgbW9kaWZpZWQgYnkgTWFydGluIEhlZGVuZmFsayA8bWhlQHN0YWNrZW4ua3RoLnNlPiBmb3IKICogdXNlIGluIEN1cmwuIEhpcyBsYXRlc3QgY2hhbmdlcyB3ZXJlIGRvbmUgMjAwMC0wOS0xOC4KICoKICogSXQgaGFzIHNpbmNlIGJlZW4gcGF0Y2hlZCBhbmQgbW9kaWZpZWQgYSBsb3QgYnkgRGFuaWVsIFN0ZW5iZXJnCiAqIDxkYW5pZWxAaGF4eC5zZT4gdG8gbWFrZSBpdCBiZXR0ZXIgYXBwbGllZCB0byBjdXJsIGNvbmRpdGlvbnMsIGFuZCB0byBtYWtlCiAqIGl0IG5vdCB1c2UgZ2xvYmFscywgcG9sbHV0ZSBuYW1lIHNwYWNlIGFuZCBtb3JlLiBUaGlzIHNvdXJjZSBjb2RlIGF3YWl0cyBhCiAqIHJld3JpdGUgdG8gd29yayBhcm91bmQgdGhlIHBhcmFncmFwaCAyIGluIHRoZSBCU0QgbGljZW5zZXMgYXMgZXhwbGFpbmVkCiAqIGJlbG93LgogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTgsIDE5OTkgS3VuZ2xpZ2EgVGVrbmlza2EgSPZnc2tvbGFuCiAqIChSb3lhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neSwgU3RvY2tob2xtLCBTd2VkZW4pLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKiAKICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogKiAKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAKICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgSW5zdGl0dXRlIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBJTlNUSVRVVEUgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBJTlNUSVRVVEUgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUwogKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKICogSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLiAgKi8KCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmbmRlZiBDVVJMX0RJU0FCTEVfRlRQCiNpZmRlZiBLUkI0CgojZGVmaW5lIF9NUFJJTlRGX1JFUExBQ0UgLyogd2Ugd2FudCBjdXJsLWZ1bmN0aW9ucyBpbnN0ZWFkIG9mIG5hdGl2ZSBvbmVzICovCiNpbmNsdWRlIDxjdXJsL21wcmludGYuaD4KCiNpbmNsdWRlICJzZWN1cml0eS5oIgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPG5ldGRiLmg+CgojaWZkZWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgoKI2luY2x1ZGUgImJhc2U2NC5oIgojaW5jbHVkZSAic2VuZGYuaCIKI2luY2x1ZGUgImZ0cC5oIgoKLyogVGhlIGxhc3QgI2luY2x1ZGUgZmlsZSBzaG91bGQgYmU6ICovCiNpZmRlZiBNQUxMT0NERUJVRwojaW5jbHVkZSAibWVtZGVidWcuaCIKI2VuZGlmCgojZGVmaW5lIG1pbihhLCBiKSAgICgoYSkgPCAoYikgPyAoYSkgOiAoYikpCgpzdGF0aWMgc3RydWN0IHsKICAgIGVudW0gcHJvdGVjdGlvbl9sZXZlbCBsZXZlbDsKICAgIGNvbnN0IGNoYXIgKm5hbWU7Cn0gbGV2ZWxfbmFtZXNbXSA9IHsKICAgIHsgcHJvdF9jbGVhciwgImNsZWFyIiB9LAogICAgeyBwcm90X3NhZmUsICJzYWZlIiB9LAogICAgeyBwcm90X2NvbmZpZGVudGlhbCwgImNvbmZpZGVudGlhbCIgfSwKICAgIHsgcHJvdF9wcml2YXRlLCAicHJpdmF0ZSIgfQp9OwoKc3RhdGljIGVudW0gcHJvdGVjdGlvbl9sZXZlbCAKbmFtZV90b19sZXZlbChjb25zdCBjaGFyICpuYW1lKQp7CiAgaW50IGk7CiAgZm9yKGkgPSAwOyBpIDwgKGludClzaXplb2YobGV2ZWxfbmFtZXMpLyhpbnQpc2l6ZW9mKGxldmVsX25hbWVzWzBdKTsgaSsrKQogICAgaWYoIXN0cm5jYXNlY21wKGxldmVsX25hbWVzW2ldLm5hbWUsIG5hbWUsIHN0cmxlbihuYW1lKSkpCiAgICAgIHJldHVybiBsZXZlbF9uYW1lc1tpXS5sZXZlbDsKICByZXR1cm4gKGVudW0gcHJvdGVjdGlvbl9sZXZlbCktMTsKfQoKc3RhdGljIHN0cnVjdCBDdXJsX3NlY19jbGllbnRfbWVjaCAqbWVjaHNbXSA9IHsKI2lmZGVmIEtSQjUKICAvKiBub3Qgc3VwcG9ydGVkICovCiNlbmRpZgojaWZkZWYgS1JCNAogICAgJkN1cmxfa3JiNF9jbGllbnRfbWVjaCwKI2VuZGlmCiAgICBOVUxMCn07CgppbnQKQ3VybF9zZWNfZ2V0YyhzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIEZJTEUgKkYpCnsKICBpZihjb25uLT5zZWNfY29tcGxldGUgJiYgY29ubi0+ZGF0YV9wcm90KSB7CiAgICBjaGFyIGM7CiAgICBpZihDdXJsX3NlY19yZWFkKGNvbm4sIGZpbGVubyhGKSwgJmMsIDEpIDw9IDApCiAgICAgIHJldHVybiBFT0Y7CiAgICByZXR1cm4gYzsKICB9CiAgZWxzZQogICAgcmV0dXJuIGdldGMoRik7Cn0KCnN0YXRpYyBpbnQKYmxvY2tfcmVhZChpbnQgZmQsIHZvaWQgKmJ1Ziwgc2l6ZV90IGxlbikKewogIHVuc2lnbmVkIGNoYXIgKnAgPSBidWY7CiAgaW50IGI7CiAgd2hpbGUobGVuKSB7CiAgICBiID0gcmVhZChmZCwgcCwgbGVuKTsKICAgIGlmIChiID09IDApCiAgICAgIHJldHVybiAwOwogICAgZWxzZSBpZiAoYiA8IDApCiAgICAgIHJldHVybiAtMTsKICAgIGxlbiAtPSBiOwogICAgcCArPSBiOwogIH0KICByZXR1cm4gcCAtICh1bnNpZ25lZCBjaGFyKilidWY7Cn0KCnN0YXRpYyBpbnQKYmxvY2tfd3JpdGUoaW50IGZkLCB2b2lkICpidWYsIHNpemVfdCBsZW4pCnsKICB1bnNpZ25lZCBjaGFyICpwID0gYnVmOwogIGludCBiOwogIHdoaWxlKGxlbikgewogICAgYiA9IHdyaXRlKGZkLCBwLCBsZW4pOwogICAgaWYoYiA8IDApCiAgICAgIHJldHVybiAtMTsKICAgIGxlbiAtPSBiOwogICAgcCArPSBiOwogIH0KICByZXR1cm4gcCAtICh1bnNpZ25lZCBjaGFyKilidWY7Cn0KCnN0YXRpYyBpbnQKc2VjX2dldF9kYXRhKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwKICAgICAgICAgICAgIGludCBmZCwgc3RydWN0IGtyYjRidWZmZXIgKmJ1ZikKewogIGludCBsZW47CiAgaW50IGI7CiAgCiAgYiA9IGJsb2NrX3JlYWQoZmQsICZsZW4sIHNpemVvZihsZW4pKTsKICBpZiAoYiA9PSAwKQogICAgcmV0dXJuIDA7CiAgZWxzZSBpZiAoYiA8IDApCiAgICByZXR1cm4gLTE7CiAgbGVuID0gbnRvaGwobGVuKTsKICBidWYtPmRhdGEgPSByZWFsbG9jKGJ1Zi0+ZGF0YSwgbGVuKTsKICBiID0gYmxvY2tfcmVhZChmZCwgYnVmLT5kYXRhLCBsZW4pOwogIGlmIChiID09IDApCiAgICByZXR1cm4gMDsKICBlbHNlIGlmIChiIDwgMCkKICAgIHJldHVybiAtMTsKICBidWYtPnNpemUgPSAoY29ubi0+bWVjaC0+ZGVjb2RlKShjb25uLT5hcHBfZGF0YSwgYnVmLT5kYXRhLCBsZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubi0+ZGF0YV9wcm90LCBjb25uKTsKICBidWYtPmluZGV4ID0gMDsKICByZXR1cm4gMDsKfQoKc3RhdGljIHNpemVfdApidWZmZXJfcmVhZChzdHJ1Y3Qga3JiNGJ1ZmZlciAqYnVmLCB2b2lkICpkYXRhLCBzaXplX3QgbGVuKQp7CiAgICBsZW4gPSBtaW4obGVuLCBidWYtPnNpemUgLSBidWYtPmluZGV4KTsKICAgIG1lbWNweShkYXRhLCAoY2hhciopYnVmLT5kYXRhICsgYnVmLT5pbmRleCwgbGVuKTsKICAgIGJ1Zi0+aW5kZXggKz0gbGVuOwogICAgcmV0dXJuIGxlbjsKfQoKc3RhdGljIHNpemVfdApidWZmZXJfd3JpdGUoc3RydWN0IGtyYjRidWZmZXIgKmJ1Ziwgdm9pZCAqZGF0YSwgc2l6ZV90IGxlbikKewogICAgaWYoYnVmLT5pbmRleCArIGxlbiA+IGJ1Zi0+c2l6ZSkgewoJdm9pZCAqdG1wOwoJaWYoYnVmLT5kYXRhID09IE5VTEwpCgkgICAgdG1wID0gbWFsbG9jKDEwMjQpOwoJZWxzZQoJICAgIHRtcCA9IHJlYWxsb2MoYnVmLT5kYXRhLCBidWYtPmluZGV4ICsgbGVuKTsKCWlmKHRtcCA9PSBOVUxMKQoJICAgIHJldHVybiAtMTsKCWJ1Zi0+ZGF0YSA9IHRtcDsKCWJ1Zi0+c2l6ZSA9IGJ1Zi0+aW5kZXggKyBsZW47CiAgICB9CiAgICBtZW1jcHkoKGNoYXIqKWJ1Zi0+ZGF0YSArIGJ1Zi0+aW5kZXgsIGRhdGEsIGxlbik7CiAgICBidWYtPmluZGV4ICs9IGxlbjsKICAgIHJldHVybiBsZW47Cn0KCmludApDdXJsX3NlY19yZWFkKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IGZkLCB2b2lkICpidWZmZXIsIGludCBsZW5ndGgpCnsKICAgIHNpemVfdCBsZW47CiAgICBpbnQgcnggPSAwOwoKICAgIGlmKGNvbm4tPnNlY19jb21wbGV0ZSA9PSAwIHx8IGNvbm4tPmRhdGFfcHJvdCA9PSAwKQogICAgICByZXR1cm4gcmVhZChmZCwgYnVmZmVyLCBsZW5ndGgpOwoKICAgIGlmKGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyl7CiAgICAgIGNvbm4tPmluX2J1ZmZlci5lb2ZfZmxhZyA9IDA7CiAgICAgIHJldHVybiAwOwogICAgfQogICAgCiAgICBsZW4gPSBidWZmZXJfcmVhZCgmY29ubi0+aW5fYnVmZmVyLCBidWZmZXIsIGxlbmd0aCk7CiAgICBsZW5ndGggLT0gbGVuOwogICAgcnggKz0gbGVuOwogICAgYnVmZmVyID0gKGNoYXIqKWJ1ZmZlciArIGxlbjsKICAgIAogICAgd2hpbGUobGVuZ3RoKSB7CiAgICAgIGlmKHNlY19nZXRfZGF0YShjb25uLCBmZCwgJmNvbm4tPmluX2J1ZmZlcikgPCAwKQogICAgICAgIHJldHVybiAtMTsKICAgICAgaWYoY29ubi0+aW5fYnVmZmVyLnNpemUgPT0gMCkgewogICAgICAgIGlmKHJ4KQogICAgICAgICAgY29ubi0+aW5fYnVmZmVyLmVvZl9mbGFnID0gMTsKICAgICAgICByZXR1cm4gcng7CiAgICAgIH0KICAgICAgbGVuID0gYnVmZmVyX3JlYWQoJmNvbm4tPmluX2J1ZmZlciwgYnVmZmVyLCBsZW5ndGgpOwogICAgICBsZW5ndGggLT0gbGVuOwogICAgICByeCArPSBsZW47CiAgICAgIGJ1ZmZlciA9IChjaGFyKilidWZmZXIgKyBsZW47CiAgICB9CiAgICByZXR1cm4gcng7Cn0KCnN0YXRpYyBpbnQKc2VjX3NlbmQoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgZmQsIGNoYXIgKmZyb20sIGludCBsZW5ndGgpCnsKICBpbnQgYnl0ZXM7CiAgdm9pZCAqYnVmOwogIGJ5dGVzID0gKGNvbm4tPm1lY2gtPmVuY29kZSkoY29ubi0+YXBwX2RhdGEsIGZyb20sIGxlbmd0aCwgY29ubi0+ZGF0YV9wcm90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJ1ZiwgY29ubik7CiAgYnl0ZXMgPSBodG9ubChieXRlcyk7CiAgYmxvY2tfd3JpdGUoZmQsICZieXRlcywgc2l6ZW9mKGJ5dGVzKSk7CiAgYmxvY2tfd3JpdGUoZmQsIGJ1ZiwgbnRvaGwoYnl0ZXMpKTsKICBmcmVlKGJ1Zik7CiAgcmV0dXJuIGxlbmd0aDsKfQoKaW50CkN1cmxfc2VjX2ZmbHVzaF9mZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBmZCkKewogIGlmKGNvbm4tPmRhdGFfcHJvdCAhPSBwcm90X2NsZWFyKSB7CiAgICBpZihjb25uLT5vdXRfYnVmZmVyLmluZGV4ID4gMCl7CiAgICAgIEN1cmxfc2VjX3dyaXRlKGNvbm4sIGZkLAogICAgICAgICAgICAgICAgY29ubi0+b3V0X2J1ZmZlci5kYXRhLCBjb25uLT5vdXRfYnVmZmVyLmluZGV4KTsKICAgICAgY29ubi0+b3V0X2J1ZmZlci5pbmRleCA9IDA7CiAgICB9CiAgICBzZWNfc2VuZChjb25uLCBmZCwgTlVMTCwgMCk7CiAgfQogIHJldHVybiAwOwp9CgppbnQKQ3VybF9zZWNfd3JpdGUoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBpbnQgZmQsIGNoYXIgKmJ1ZmZlciwgaW50IGxlbmd0aCkKewogIGludCBsZW4gPSBjb25uLT5idWZmZXJfc2l6ZTsKICBpbnQgdHggPSAwOwogICAgICAKICBpZihjb25uLT5kYXRhX3Byb3QgPT0gcHJvdF9jbGVhcikKICAgIHJldHVybiB3cml0ZShmZCwgYnVmZmVyLCBsZW5ndGgpOwoKICBsZW4gLT0gKGNvbm4tPm1lY2gtPm92ZXJoZWFkKShjb25uLT5hcHBfZGF0YSwgY29ubi0+ZGF0YV9wcm90LCBsZW4pOwogIHdoaWxlKGxlbmd0aCl7CiAgICBpZihsZW5ndGggPCBsZW4pCiAgICAgIGxlbiA9IGxlbmd0aDsKICAgIHNlY19zZW5kKGNvbm4sIGZkLCBidWZmZXIsIGxlbik7CiAgICBsZW5ndGggLT0gbGVuOwogICAgYnVmZmVyICs9IGxlbjsKICAgIHR4ICs9IGxlbjsKICB9CiAgcmV0dXJuIHR4Owp9CgppbnQKQ3VybF9zZWNfdmZwcmludGYyKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgRklMRSAqZiwgY29uc3QgY2hhciAqZm10LCB2YV9saXN0IGFwKQp7CiAgY2hhciAqYnVmOwogIGludCByZXQ7CiAgaWYoY29ubi0+ZGF0YV9wcm90ID09IHByb3RfY2xlYXIpCiAgICByZXR1cm4gdmZwcmludGYoZiwgZm10LCBhcCk7CiAgZWxzZSB7CiAgICBidWYgPSBhcHJpbnRmKGZtdCwgYXApOwogICAgcmV0ID0gYnVmZmVyX3dyaXRlKCZjb25uLT5vdXRfYnVmZmVyLCBidWYsIHN0cmxlbihidWYpKTsKICAgIGZyZWUoYnVmKTsKICAgIHJldHVybiByZXQ7CiAgfQp9CgppbnQKQ3VybF9zZWNfZnByaW50ZjIoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBGSUxFICpmLCBjb25zdCBjaGFyICpmbXQsIC4uLikKewogICAgaW50IHJldDsKICAgIHZhX2xpc3QgYXA7CiAgICB2YV9zdGFydChhcCwgZm10KTsKICAgIHJldCA9IEN1cmxfc2VjX3ZmcHJpbnRmMihjb25uLCBmLCBmbXQsIGFwKTsKICAgIHZhX2VuZChhcCk7CiAgICByZXR1cm4gcmV0Owp9CgppbnQKQ3VybF9zZWNfcHV0YyhzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGludCBjLCBGSUxFICpGKQp7CiAgY2hhciBjaCA9IGM7CiAgaWYoY29ubi0+ZGF0YV9wcm90ID09IHByb3RfY2xlYXIpCiAgICByZXR1cm4gcHV0YyhjLCBGKTsKICAgIAogIGJ1ZmZlcl93cml0ZSgmY29ubi0+b3V0X2J1ZmZlciwgJmNoLCAxKTsKICBpZihjID09ICdcbicgfHwgY29ubi0+b3V0X2J1ZmZlci5pbmRleCA+PSAxMDI0IC8qIFhYWCAqLykgewogICAgQ3VybF9zZWNfd3JpdGUoY29ubiwgZmlsZW5vKEYpLCBjb25uLT5vdXRfYnVmZmVyLmRhdGEsIGNvbm4tPm91dF9idWZmZXIuaW5kZXgpOwogICAgY29ubi0+b3V0X2J1ZmZlci5pbmRleCA9IDA7CiAgfQogIHJldHVybiBjOwp9CgppbnQKQ3VybF9zZWNfcmVhZF9tc2coc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBjaGFyICpzLCBpbnQgbGV2ZWwpCnsKICAgIGludCBsZW47CiAgICBjaGFyICpidWY7CiAgICBpbnQgY29kZTsKICAgIAogICAgYnVmID0gbWFsbG9jKHN0cmxlbihzKSk7CiAgICBsZW4gPSBDdXJsX2Jhc2U2NF9kZWNvZGUocyArIDQsIGJ1Zik7IC8qIFhYWCAqLwogICAgCiAgICBsZW4gPSAoY29ubi0+bWVjaC0+ZGVjb2RlKShjb25uLT5hcHBfZGF0YSwgYnVmLCBsZW4sIGxldmVsLCBjb25uKTsKICAgIGlmKGxlbiA8IDApCglyZXR1cm4gLTE7CiAgICAKICAgIGJ1ZltsZW5dID0gJ1wwJzsKCiAgICBpZihidWZbM10gPT0gJy0nKQoJY29kZSA9IDA7CiAgICBlbHNlCglzc2NhbmYoYnVmLCAiJWQiLCAmY29kZSk7CiAgICBpZihidWZbbGVuLTFdID09ICdcbicpCglidWZbbGVuLTFdID0gJ1wwJzsKICAgIHN0cmNweShzLCBidWYpOwogICAgZnJlZShidWYpOwogICAgcmV0dXJuIGNvZGU7Cn0KCi8qIG1vZGlmaWVkIHRvIHJldHVybiBob3cgbWFueSBieXRlcyB3cml0dGVuLCBvciAtMSBvbiBlcnJvciAqKiovCmludApDdXJsX3NlY192ZnByaW50ZihzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIEZJTEUgKmYsIGNvbnN0IGNoYXIgKmZtdCwgdmFfbGlzdCBhcCkKewogICAgaW50IHJldCA9IDA7CiAgICBjaGFyICpidWY7CiAgICB2b2lkICplbmM7CiAgICBpbnQgbGVuOwogICAgaWYoIWNvbm4tPnNlY19jb21wbGV0ZSkKCXJldHVybiB2ZnByaW50ZihmLCBmbXQsIGFwKTsKICAgIAogICAgYnVmID0gYXByaW50ZihmbXQsIGFwKTsKICAgIGxlbiA9IChjb25uLT5tZWNoLT5lbmNvZGUpKGNvbm4tPmFwcF9kYXRhLCBidWYsIHN0cmxlbihidWYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubi0+Y29tbWFuZF9wcm90LCAmZW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubik7CiAgICBmcmVlKGJ1Zik7CiAgICBpZihsZW4gPCAwKSB7CglmYWlsZihjb25uLT5kYXRhLCAiRmFpbGVkIHRvIGVuY29kZSBjb21tYW5kLiIpOwoJcmV0dXJuIC0xOwogICAgfQogICAgaWYoQ3VybF9iYXNlNjRfZW5jb2RlKGVuYywgbGVuLCAmYnVmKSA8IDApewogICAgICBmYWlsZihjb25uLT5kYXRhLCAiT3V0IG9mIG1lbW9yeSBiYXNlNjQtZW5jb2RpbmcuIik7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGlmKGNvbm4tPmNvbW1hbmRfcHJvdCA9PSBwcm90X3NhZmUpCglyZXQgPSBmcHJpbnRmKGYsICJNSUMgJXMiLCBidWYpOwogICAgZWxzZSBpZihjb25uLT5jb21tYW5kX3Byb3QgPT0gcHJvdF9wcml2YXRlKQoJcmV0ID0gZnByaW50ZihmLCAiRU5DICVzIiwgYnVmKTsKICAgIGVsc2UgaWYoY29ubi0+Y29tbWFuZF9wcm90ID09IHByb3RfY29uZmlkZW50aWFsKQoJcmV0ID0gZnByaW50ZihmLCAiQ09ORiAlcyIsIGJ1Zik7CgogICAgZnJlZShidWYpOwogICAgcmV0dXJuIHJldDsKfQoKaW50CkN1cmxfc2VjX2ZwcmludGYoc3RydWN0IGNvbm5lY3RkYXRhICpjb25uLCBGSUxFICpmLCBjb25zdCBjaGFyICpmbXQsIC4uLikKewogICAgdmFfbGlzdCBhcDsKICAgIGludCByZXQ7CiAgICB2YV9zdGFydChhcCwgZm10KTsKICAgIHJldCA9IEN1cmxfc2VjX3ZmcHJpbnRmKGNvbm4sIGYsIGZtdCwgYXApOwogICAgdmFfZW5kKGFwKTsKICAgIHJldHVybiByZXQ7Cn0KCgplbnVtIHByb3RlY3Rpb25fbGV2ZWwKQ3VybF9zZXRfY29tbWFuZF9wcm90KHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgZW51bSBwcm90ZWN0aW9uX2xldmVsIGxldmVsKQp7CiAgICBlbnVtIHByb3RlY3Rpb25fbGV2ZWwgb2xkID0gY29ubi0+Y29tbWFuZF9wcm90OwogICAgY29ubi0+Y29tbWFuZF9wcm90ID0gbGV2ZWw7CiAgICByZXR1cm4gb2xkOwp9CgpzdGF0aWMgaW50CnNlY19wcm90X2ludGVybmFsKHN0cnVjdCBjb25uZWN0ZGF0YSAqY29ubiwgaW50IGxldmVsKQp7CiAgY2hhciAqcDsKICB1bnNpZ25lZCBpbnQgcyA9IDEwNDg1NzY7CiAgc3NpemVfdCBucmVhZDsKCiAgaWYoIWNvbm4tPnNlY19jb21wbGV0ZSl7CiAgICBpbmZvZihjb25uLT5kYXRhLCAiTm8gc2VjdXJpdHkgZGF0YSBleGNoYW5nZSBoYXMgdGFrZW4gcGxhY2UuXG4iKTsKICAgIHJldHVybiAtMTsKICB9CgogIGlmKGxldmVsKXsKICAgIGlmKEN1cmxfZnRwc2VuZGYoY29ubiwgIlBCU1ogJXUiLCBzKSkKICAgICAgcmV0dXJuIC0xOwoKICAgIG5yZWFkID0gQ3VybF9HZXRGVFBSZXNwb25zZShjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsIGNvbm4sIE5VTEwpOwogICAgaWYobnJlYWQgPCAwKQogICAgICByZXR1cm4gLTE7CgogICAgaWYoY29ubi0+ZGF0YS0+c3RhdGUuYnVmZmVyWzBdICE9ICcyJyl7CiAgICAgIGZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gc2V0IHByb3RlY3Rpb24gYnVmZmVyIHNpemUuIik7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gczsKCiAgICBwID0gc3Ryc3RyKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgIlBCU1o9Iik7CiAgICBpZihwKQogICAgICBzc2NhbmYocCwgIlBCU1o9JXUiLCAmcyk7CiAgICBpZihzIDwgY29ubi0+YnVmZmVyX3NpemUpCiAgICAgIGNvbm4tPmJ1ZmZlcl9zaXplID0gczsKICB9CgogIGlmKEN1cmxfZnRwc2VuZGYoY29ubiwgIlBST1QgJWMiLCBsZXZlbFsiQ1NFUCJdKSkKICAgIHJldHVybiAtMTsKCiAgbnJlYWQgPSBDdXJsX0dldEZUUFJlc3BvbnNlKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlciwgY29ubiwgTlVMTCk7CiAgaWYobnJlYWQgPCAwKQogICAgcmV0dXJuIC0xOwoKICBpZihjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXJbMF0gIT0gJzInKXsKICAgIGZhaWxmKGNvbm4tPmRhdGEsICJGYWlsZWQgdG8gc2V0IHByb3RlY3Rpb24gbGV2ZWwuIik7CiAgICByZXR1cm4gLTE7CiAgfQogICAgCiAgY29ubi0+ZGF0YV9wcm90ID0gKGVudW0gcHJvdGVjdGlvbl9sZXZlbClsZXZlbDsKICByZXR1cm4gMDsKfQoKdm9pZApDdXJsX3NlY19zZXRfcHJvdGVjdGlvbl9sZXZlbChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpZihjb25uLT5zZWNfY29tcGxldGUgJiYgY29ubi0+ZGF0YV9wcm90ICE9IGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90KQogICAgc2VjX3Byb3RfaW50ZXJuYWwoY29ubiwgY29ubi0+cmVxdWVzdF9kYXRhX3Byb3QpOwp9CgoKaW50CkN1cmxfc2VjX3JlcXVlc3RfcHJvdChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4sIGNvbnN0IGNoYXIgKmxldmVsKQp7CiAgaW50IGwgPSBuYW1lX3RvX2xldmVsKGxldmVsKTsKICBpZihsID09IC0xKQogICAgcmV0dXJuIC0xOwogIGNvbm4tPnJlcXVlc3RfZGF0YV9wcm90ID0gKGVudW0gcHJvdGVjdGlvbl9sZXZlbClsOwogIHJldHVybiAwOwp9CgppbnQKQ3VybF9zZWNfbG9naW4oc3RydWN0IGNvbm5lY3RkYXRhICpjb25uKQp7CiAgaW50IHJldDsKICBzdHJ1Y3QgQ3VybF9zZWNfY2xpZW50X21lY2ggKiptOwogIHNzaXplX3QgbnJlYWQ7CiAgc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGE9Y29ubi0+ZGF0YTsKICBpbnQgZnRwY29kZTsKCiAgZm9yKG0gPSBtZWNoczsgKm0gJiYgKCptKS0+bmFtZTsgbSsrKSB7CiAgICB2b2lkICp0bXA7CgogICAgdG1wID0gcmVhbGxvYyhjb25uLT5hcHBfZGF0YSwgKCptKS0+c2l6ZSk7CiAgICBpZiAodG1wID09IE5VTEwpIHsKICAgICAgZmFpbGYgKGRhdGEsICJyZWFsbG9jICV1IGZhaWxlZCIsICgqbSktPnNpemUpOwogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBjb25uLT5hcHBfZGF0YSA9IHRtcDsKCSAgICAKICAgIGlmKCgqbSktPmluaXQgJiYgKCooKm0pLT5pbml0KShjb25uLT5hcHBfZGF0YSkgIT0gMCkgewogICAgICBpbmZvZihkYXRhLCAiU2tpcHBpbmcgJXMuLi5cbiIsICgqbSktPm5hbWUpOwogICAgICBjb250aW51ZTsKICAgIH0KICAgIGluZm9mKGRhdGEsICJUcnlpbmcgJXMuLi5cbiIsICgqbSktPm5hbWUpOwoKICAgIGlmKEN1cmxfZnRwc2VuZGYoY29ubiwgIkFVVEggJXMiLCAoKm0pLT5uYW1lKSkKICAgICAgcmV0dXJuIC0xOwoKICAgIG5yZWFkID0gQ3VybF9HZXRGVFBSZXNwb25zZShjb25uLT5kYXRhLT5zdGF0ZS5idWZmZXIsIGNvbm4sICZmdHBjb2RlKTsKICAgIGlmKG5yZWFkIDwgMCkKICAgICAgcmV0dXJuIC0xOwoKICAgIGlmKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlclswXSAhPSAnMycpewogICAgICBzd2l0Y2goZnRwY29kZSkgewogICAgICBjYXNlIDUwNDoKICAgICAgICBpbmZvZihkYXRhLAogICAgICAgICAgICAgICIlcyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBzZXJ2ZXIuXG4iLCAoKm0pLT5uYW1lKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSA1MzQ6CiAgICAgICAgaW5mb2YoZGF0YSwgIiVzIHJlamVjdGVkIGFzIHNlY3VyaXR5IG1lY2hhbmlzbS5cbiIsICgqbSktPm5hbWUpOwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIGlmKGNvbm4tPmRhdGEtPnN0YXRlLmJ1ZmZlclswXSA9PSAnNScpIHsKICAgICAgICAgIGluZm9mKGRhdGEsICJUaGUgc2VydmVyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgRlRQICIKICAgICAgICAgICAgICAgICJzZWN1cml0eSBleHRlbnNpb25zLlxuIik7CiAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIHJldCA9ICgqKCptKS0+YXV0aCkoY29ubi0+YXBwX2RhdGEsIGNvbm4pOwoJCiAgICBpZihyZXQgPT0gQVVUSF9DT05USU5VRSkKICAgICAgY29udGludWU7CiAgICBlbHNlIGlmKHJldCAhPSBBVVRIX09LKXsKICAgICAgLyogbWVjaGFuaXNtIGlzIHN1cHBvc2VkIHRvIG91dHB1dCBlcnJvciBzdHJpbmcgKi8KICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgY29ubi0+bWVjaCA9ICptOwogICAgY29ubi0+c2VjX2NvbXBsZXRlID0gMTsKICAgIGNvbm4tPmNvbW1hbmRfcHJvdCA9IHByb3Rfc2FmZTsKICAgIGJyZWFrOwogIH0KICAgIAogIHJldHVybiAqbSA9PSBOVUxMOwp9Cgp2b2lkCkN1cmxfc2VjX2VuZChzdHJ1Y3QgY29ubmVjdGRhdGEgKmNvbm4pCnsKICBpZiAoY29ubi0+bWVjaCAhPSBOVUxMKSB7CiAgICBpZihjb25uLT5tZWNoLT5lbmQpCiAgICAgIChjb25uLT5tZWNoLT5lbmQpKGNvbm4tPmFwcF9kYXRhKTsKICAgIG1lbXNldChjb25uLT5hcHBfZGF0YSwgMCwgY29ubi0+bWVjaC0+c2l6ZSk7CiAgICBmcmVlKGNvbm4tPmFwcF9kYXRhKTsKICAgIGNvbm4tPmFwcF9kYXRhID0gTlVMTDsKICB9CiAgY29ubi0+c2VjX2NvbXBsZXRlID0gMDsKICBjb25uLT5kYXRhX3Byb3QgPSAoZW51bSBwcm90ZWN0aW9uX2xldmVsKTA7CiAgY29ubi0+bWVjaD1OVUxMOwp9CgojZW5kaWYgLyogS1JCNCAqLwojZW5kaWYgLyogQ1VSTF9ESVNBQkxFX0ZUUCAqLwoKLyoKICogbG9jYWwgdmFyaWFibGVzOgogKiBldmFsOiAobG9hZC1maWxlICIuLi9jdXJsLW1vZGUuZWwiKQogKiBlbmQ6CiAqIHZpbTYwMDogZmRtPW1hcmtlcgogKiB2aW06IGV0IHN3PTIgdHM9MiBzdHM9MiB0dz03OAogKi8K