LyoKICogQUlYNCBtZW1vcnkgc3RhdGlzdGljcyBtb2R1bGUgZm9yIG5ldC1zbm1wCiAqCiAqIFZlcnNpb24gMC4xIC0gSW5pdGlhbCByZWxlYXNlIC0gMDUvSnVuLzIwMDMKICoKICogRGVyaXZlZCBmcm9tIG1lbW9yeV9zb2xhcmlzMi5jCiAqIFVzaW5nIGxpYnBlcmZzdGF0IGZvciBzdGF0aXN0aWNzIChSZWRib29rIFNHMjQtNjAzOSkKICoKICogUG9ydGVkIHRvIEFJWCBieSBNaWNoYWVsIEt1a2F0IDxtaWNoYWVsLmt1a2F0QHRvLmNvbT4KICogVGhpbmtpbmcgT2JqZWN0cyBTb2Z0d2FyZSBHbWJICiAqIExpbGllbnRoYWxzdHJh32UgMgogKiA3MDgyNSBTdHV0dGdhcnQtS29ybnRhbAogKiBodHRwOi8vd3d3LnRvLmNvbS8KICoKICogVGhhbmtzIGdvIHRvIEpvY2hlbiBLbWlldHNjaCBmb3IgdGhlIHNvbGFyaXMyIHN1cHBvcnQgYW5kCiAqIHRvIERhaW1sZXJDaHJ5c2xlciBBRyBTdHV0dGdhcnQgZm9yIG1ha2luZyB0aGlzIHBvcnQgcG9zc2libGUKICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+ICAgLyogbG9jYWwgU05NUCBjb25maWd1cmF0aW9uIGRldGFpbHMgKi8KI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZW5kaWYKI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L2F1dG9fbmxpc3QuaD4KCiNpbmNsdWRlICJ1dGlsX2Z1bmNzL2hlYWRlcl9nZW5lcmljLmgiIC8qIHV0aWxpdHkgZnVuY3Rpb24gZGVjbGFyYXRpb25zICovCiNpbmNsdWRlICJtZW1vcnkuaCIgICAgICAgICAgICAgLyogdGhlIG1vZHVsZS1zcGVjaWZpYyBoZWFkZXIgKi8KI2luY2x1ZGUgIm1lbW9yeV9haXg0LmgiICAgIC8qIHRoZSBtb2R1bGUtc3BlY2lmaWMgaGVhZGVyICovCgojaWZkZWYgSEFWRV9TWVNfUFJPVE9TV19ICiNpbmNsdWRlIDxzeXMvcHJvdG9zdy5oPgojZW5kaWYKI2luY2x1ZGUgPGxpYnBlcmZzdGF0Lmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CgojZGVmaW5lIE1BWFNUUlNJWkUJODAKCmludCAgICAgICAgICAgICBtaW5pbXVtc3dhcDsKc3RhdGljIGNoYXIgICAgIGVycm1zZ1sxMDI0XTsKCnN0YXRpYyBGaW5kVmFyTWV0aG9kIHZhcl9leHRlbnNpYmxlX21lbTsKc3RhdGljIGxvbmcgICAgIGdldEZyZWVTd2FwKHZvaWQpOwpzdGF0aWMgbG9uZyAgICAgZ2V0VG90YWxGcmVlKHZvaWQpOwpzdGF0aWMgbG9uZyAgICAgZ2V0VG90YWxTd2FwKHZvaWQpOwpzdGF0aWMgbG9uZyAgICAgZ2V0RnJlZVJlYWwodm9pZCk7CnN0YXRpYyBsb25nICAgICBnZXRUb3RhbFJlYWwodm9pZCk7Cgp2b2lkCmluaXRfbWVtb3J5X2FpeDQodm9pZCkKewoKICAgIHN0cnVjdCB2YXJpYWJsZTIgZXh0ZW5zaWJsZV9tZW1fdmFyaWFibGVzW10gPSB7CiAgICAgICAge01JQklOREVYLCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge01JQklOREVYfX0sCiAgICAgICAge0VSUk9STkFNRSwgQVNOX09DVEVUX1NUUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge0VSUk9STkFNRX19LAogICAgICAgIHtNRU1UT1RBTFNXQVAsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUVNVE9UQUxTV0FQfX0sCiAgICAgICAge01FTUFWQUlMU1dBUCwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNRU1BVkFJTFNXQVB9fSwKICAgICAgICB7TUVNVE9UQUxSRUFMLCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge01FTVRPVEFMUkVBTH19LAogICAgICAgIHtNRU1BVkFJTFJFQUwsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUVNQVZBSUxSRUFMfX0sCiAgICAgICAge01FTVRPVEFMU1dBUFRYVCwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNRU1UT1RBTFNXQVBUWFR9fSwKICAgICAgICB7TUVNVVNFRFNXQVBUWFQsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUVNVVNFRFNXQVBUWFR9fSwKICAgICAgICB7TUVNVE9UQUxSRUFMVFhULCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge01FTVRPVEFMUkVBTFRYVH19LAogICAgICAgIHtNRU1VU0VEUkVBTFRYVCwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNRU1VU0VEUkVBTFRYVH19LAogICAgICAgIHtNRU1UT1RBTEZSRUUsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUVNVE9UQUxGUkVFfX0sCiAgICAgICAge01FTVNXQVBNSU5JTVVNLCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge01FTVNXQVBNSU5JTVVNfX0sCiAgICAgICAge01FTVNIQVJFRCwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNRU1TSEFSRUR9fSwKICAgICAgICB7TUVNQlVGRkVSLCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge01FTUJVRkZFUn19LAogICAgICAgIHtNRU1DQUNIRUQsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUVNQ0FDSEVEfX0sCiAgICAgICAge0VSUk9SRkxBRywgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtFUlJPUkZMQUd9fSwKICAgICAgICB7RVJST1JNU0csIEFTTl9PQ1RFVF9TVFIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtFUlJPUk1TR319CiAgICB9OwoKICAgIC8qCiAgICAgKiBEZWZpbmUgdGhlIE9JRCBwb2ludGVyIHRvIHRoZSB0b3Agb2YgdGhlIG1pYiB0cmVlIHRoYXQgd2UncmUKICAgICAqIHJlZ2lzdGVyaW5nIHVuZGVybmVhdGggCiAgICAgKi8KICAgIG9pZCAgICAgICAgICAgICBtZW1fdmFyaWFibGVzX29pZFtdID0geyBORVRTTk1QX1VDREFWSVNfTUlCLCBORVRTTk1QX01FTU1JQk5VTSB9OwoKICAgIC8qCiAgICAgKiByZWdpc3RlciBvdXJzZWx2ZXMgd2l0aCB0aGUgYWdlbnQgdG8gaGFuZGxlIG91ciBtaWIgdHJlZSAKICAgICAqLwogICAgUkVHSVNURVJfTUlCKCJ1Y2Qtc25tcC9tZW1vcnkiLCBleHRlbnNpYmxlX21lbV92YXJpYWJsZXMsIHZhcmlhYmxlMiwKICAgICAgICAgICAgICAgICBtZW1fdmFyaWFibGVzX29pZCk7CgogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoInN3YXAiLCBtZW1vcnlfcGFyc2VfY29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtb3J5X2ZyZWVfY29uZmlnLCAibWluLWF2YWlsIik7Cgp9CgpzdGF0aWMgdV9jaGFyICAqCnZhcl9leHRlbnNpYmxlX21lbShzdHJ1Y3QgdmFyaWFibGUgKnZwLAogICAgICAgICAgICAgICAgICAgb2lkICogbmFtZSwKICAgICAgICAgICAgICAgICAgIHNpemVfdCAqIGxlbmd0aCwKICAgICAgICAgICAgICAgICAgIGludCBleGFjdCwKICAgICAgICAgICAgICAgICAgIHNpemVfdCAqIHZhcl9sZW4sIFdyaXRlTWV0aG9kICoqIHdyaXRlX21ldGhvZCkKewogICAgc3RhdGljIGxvbmcgICAgIGxvbmdfcmV0OwoKICAgIC8qCiAgICAgKiBJbml0aWFsaXplIHRoZSByZXR1cm4gdmFsdWUgdG8gMCAKICAgICAqLwogICAgbG9uZ19yZXQgPSAwOwoKICAgIGlmIChoZWFkZXJfZ2VuZXJpYyh2cCwgbmFtZSwgbGVuZ3RoLCBleGFjdCwgdmFyX2xlbiwgd3JpdGVfbWV0aG9kKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHN3aXRjaCAodnAtPm1hZ2ljKSB7CiAgICBjYXNlIE1JQklOREVYOgogICAgICAgIGxvbmdfcmV0ID0gMDsKICAgICAgICByZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwogICAgY2FzZSBFUlJPUk5BTUU6ICAgICAgICAgICAgLyogZHVtbXkgbmFtZSAqLwogICAgICAgIHNwcmludGYoZXJybXNnLCAic3dhcCIpOwogICAgICAgICp2YXJfbGVuID0gc3RybGVuKGVycm1zZyk7CiAgICAgICAgcmV0dXJuICgodV9jaGFyICopIChlcnJtc2cpKTsKICAgIGNhc2UgTUVNVE9UQUxTV0FQOgogICAgICAgIGxvbmdfcmV0ID0gZ2V0VG90YWxTd2FwKCkgKiAoZ2V0cGFnZXNpemUoKSAvIDEwMjQpOwogICAgICAgIHJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CiAgICBjYXNlIE1FTUFWQUlMU1dBUDoKICAgICAgICBsb25nX3JldCA9IGdldEZyZWVTd2FwKCkgKiAoZ2V0cGFnZXNpemUoKSAvIDEwMjQpOwogICAgICAgIHJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CiAgICBjYXNlIE1FTVNXQVBNSU5JTVVNOgogICAgICAgIGxvbmdfcmV0ID0gbWluaW11bXN3YXA7CiAgICAgICAgcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKICAgIGNhc2UgTUVNVE9UQUxSRUFMOgoJCSAgbG9uZ19yZXQgPSBnZXRUb3RhbFJlYWwoKSAqIChnZXRwYWdlc2l6ZSgpIC8gMTAyNCk7CgkJICByZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwogICAgY2FzZSBNRU1BVkFJTFJFQUw6CgkJICBsb25nX3JldCA9IGdldEZyZWVSZWFsKCkgKiAoZ2V0cGFnZXNpemUoKSAvIDEwMjQpOwoJCSAgcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKICAgIGNhc2UgTUVNVE9UQUxGUkVFOgogICAgICAgIGxvbmdfcmV0ID0gZ2V0VG90YWxGcmVlKCkgKiAoZ2V0cGFnZXNpemUoKSAvIDEwMjQpOwogICAgICAgIHJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CgogICAgY2FzZSBFUlJPUkZMQUc6CiAgICAgICAgbG9uZ19yZXQgPSBnZXRUb3RhbEZyZWUoKSAqIChnZXRwYWdlc2l6ZSgpIC8gMTAyNCk7CiAgICAgICAgbG9uZ19yZXQgPSAobG9uZ19yZXQgPiBtaW5pbXVtc3dhcCkgPyAwIDogMTsKICAgICAgICByZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwoKICAgIGNhc2UgRVJST1JNU0c6CiAgICAgICAgbG9uZ19yZXQgPSBnZXRUb3RhbEZyZWUoKSAqIChnZXRwYWdlc2l6ZSgpIC8gMTAyNCk7CiAgICAgICAgaWYgKChsb25nX3JldCA+IG1pbmltdW1zd2FwKSA/IDAgOiAxKQogICAgICAgICAgICBzcHJpbnRmKGVycm1zZywgIlJ1bm5pbmcgb3V0IG9mIHN3YXAgc3BhY2UgKCVsZCkiLCBsb25nX3JldCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBlcnJtc2dbMF0gPSAwOwogICAgICAgICp2YXJfbGVuID0gc3RybGVuKGVycm1zZyk7CiAgICAgICAgcmV0dXJuICgodV9jaGFyICopIChlcnJtc2cpKTsKCiAgICB9CgogICAgcmV0dXJuIChOVUxMKTsKfQoKI2RlZmluZSBERUZBVUxUTUlOSU1VTVNXQVAgMTYwMDAgICAgICAgIC8qIGtpbG9ieXRlcyAqLwoKdm9pZAptZW1vcnlfcGFyc2VfY29uZmlnKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBtaW5pbXVtc3dhcCA9IGF0b2koY3B0cik7Cn0KCnZvaWQKbWVtb3J5X2ZyZWVfY29uZmlnKHZvaWQpCnsKICAgIG1pbmltdW1zd2FwID0gREVGQVVMVE1JTklNVU1TV0FQOwp9CgpzdGF0aWMgbG9uZwpnZXRUb3RhbFN3YXAodm9pZCkKewogICAgbG9uZyAgICAgICAgICAgIHRvdGFsX21lbSA9IC0xOwoJIHBlcmZzdGF0X21lbW9yeV90b3RhbF90IG1lbTsKCgkgaWYocGVyZnN0YXRfbWVtb3J5X3RvdGFsKChwZXJmc3RhdF9pZF90ICopTlVMTCwgJm1lbSwgc2l6ZW9mKHBlcmZzdGF0X21lbW9yeV90b3RhbF90KSwgMSkgPj0gMSkgewoJCSB0b3RhbF9tZW0gPSBtZW0ucGdzcF90b3RhbDsKCSB9CgogICAgcmV0dXJuICh0b3RhbF9tZW0pOwp9CgpzdGF0aWMgbG9uZwpnZXRGcmVlU3dhcCh2b2lkKQp7CiAgICBsb25nICAgICAgICAgICAgZnJlZV9tZW0gPSAtMTsKCSBwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCBtZW07CgoJIGlmKHBlcmZzdGF0X21lbW9yeV90b3RhbCgocGVyZnN0YXRfaWRfdCAqKU5VTEwsICZtZW0sIHNpemVvZihwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCksIDEpID49IDEpIHsKCQkgZnJlZV9tZW0gPSBtZW0ucGdzcF9mcmVlOwoJIH0KCiAgICByZXR1cm4gKGZyZWVfbWVtKTsKfQoKc3RhdGljIGxvbmcKZ2V0VG90YWxGcmVlKHZvaWQpCnsKICAgIGxvbmcgICAgICAgICAgICBmcmVlX21lbSA9IC0xOwoJIHBlcmZzdGF0X21lbW9yeV90b3RhbF90IG1lbTsKCgkgaWYocGVyZnN0YXRfbWVtb3J5X3RvdGFsKChwZXJmc3RhdF9pZF90ICopTlVMTCwgJm1lbSwgc2l6ZW9mKHBlcmZzdGF0X21lbW9yeV90b3RhbF90KSwgMSkgPj0gMSkgewoJCSBmcmVlX21lbSA9IG1lbS5wZ3NwX2ZyZWUgKyBtZW0ucmVhbF9mcmVlOwoJIH0KCiAgICByZXR1cm4gKGZyZWVfbWVtKTsKfQoKc3RhdGljIGxvbmcKZ2V0VG90YWxSZWFsKHZvaWQpCnsKICAgIGxvbmcgICAgICAgICAgICB0b3RhbF9tZW0gPSAtMTsKCSBwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCBtZW07CgoJIGlmKHBlcmZzdGF0X21lbW9yeV90b3RhbCgocGVyZnN0YXRfaWRfdCAqKU5VTEwsICZtZW0sIHNpemVvZihwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCksIDEpID49IDEpIHsKCQkgdG90YWxfbWVtID0gbWVtLnJlYWxfdG90YWw7CgkgfQoKICAgIHJldHVybiAodG90YWxfbWVtKTsKfQoKc3RhdGljIGxvbmcKZ2V0RnJlZVJlYWwodm9pZCkKewogICAgbG9uZyAgICAgICAgICAgIGZyZWVfbWVtID0gLTE7CgkgcGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QgbWVtOwoKCSBpZihwZXJmc3RhdF9tZW1vcnlfdG90YWwoKHBlcmZzdGF0X2lkX3QgKilOVUxMLCAmbWVtLCBzaXplb2YocGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QpLCAxKSA+PSAxKSB7CgkJIGZyZWVfbWVtID0gbWVtLnJlYWxfZnJlZTsKCSB9CgogICAgcmV0dXJuIChmcmVlX21lbSk7Cn0K