LyogUHJpdmF0ZSB2ZXJzaW9uIG9mIHRoZSBsaWJjICptbnRlbnQoKSByb3V0aW5lcy4gKi8KLyogTm90ZSBzbGlnaHRseSBkaWZmZXJlbnQgcHJvdG90eXBlcy4gKi8KCi8qIDE5OTktMDItMjIgQXJrYWRpdXN6IE1ptmtpZXdpY3ogPG1pc2lla0BwbGQuT1JHLlBMPgogKiAtIGFkZGVkIE5hdGl2ZSBMYW5ndWFnZSBTdXBwb3J0CiAqCiAqIDIwMDYtMDYtMDggQW1pdCBHdWQgPGFndWRAcmVkaGF0LmNvbT4KICogLSBNb3ZlZCB0byBuZnMtdXRpbHMvc3VwcG9ydC9uZnMgZnJvbSB1dGlsLWxpbnV4L21vdW50CiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4JCS8qIGZvciBpbmRleCAqLwojaW5jbHVkZSA8Y3R5cGUuaD4JCS8qIGZvciBpc2RpZ2l0ICovCiNpbmNsdWRlIDxzeXMvc3RhdC5oPgkJLyogZm9yIHVtYXNrICovCgojaW5jbHVkZSAibmZzX21udGVudC5oIgojaW5jbHVkZSAibmxzLmgiCiNpbmNsdWRlICJ4Y29tbW9uLmgiCgovKiBVbmZvcnR1bmF0ZWx5IHRoZSBjbGFzc2ljYWwgVW5peCAvZXRjL210YWIgYW5kIC9ldGMvZnN0YWIKICAgZG8gbm90IGhhbmRsZSBkaXJlY3RvcnkgbmFtZXMgY29udGFpbmluZyBzcGFjZXMuCiAgIEhlcmUgd2UgbWFuZ2xlIHRoZW0sIHJlcGxhY2luZyBhIHNwYWNlIGJ5IFwwNDAuCiAgIFdoYXQgZG8gb3RoZXIgVW5pY2VzIGRvPyAqLwoKc3RhdGljIHVuc2lnbmVkIGNoYXIgbmVlZF9lc2NhcGluZ1tdID0geyAnICcsICdcdCcsICdcbicsICdcXCcgfTsKCnN0YXRpYyBjaGFyICoKbWFuZ2xlKGNvbnN0IGNoYXIgKmFyZykgewoJY29uc3QgdW5zaWduZWQgY2hhciAqcyA9IChjb25zdCB1bnNpZ25lZCBjaGFyICopYXJnOwoJY2hhciAqc3MsICpzcDsKCWludCBuOwoKCW4gPSBzdHJsZW4oYXJnKTsKCXNzID0gc3AgPSB4bWFsbG9jKDQqbisxKTsKCXdoaWxlKDEpIHsKCQlmb3IgKG4gPSAwOyBuIDwgc2l6ZW9mKG5lZWRfZXNjYXBpbmcpOyBuKyspIHsKCQkJaWYgKCpzID09IG5lZWRfZXNjYXBpbmdbbl0pIHsKCQkJCSpzcCsrID0gJ1xcJzsKCQkJCSpzcCsrID0gJzAnICsgKCgqcyAmIDAzMDApID4+IDYpOwoJCQkJKnNwKysgPSAnMCcgKyAoKCpzICYgMDcwKSA+PiAzKTsKCQkJCSpzcCsrID0gJzAnICsgKCpzICYgMDcpOwoJCQkJZ290byBuZXh0OwoJCQl9CgkJfQoJCSpzcCsrID0gKnM7CgkJaWYgKCpzID09IDApCgkJCWJyZWFrOwoJbmV4dDoKCQlzKys7Cgl9CglyZXR1cm4gc3M7Cn0KCnN0YXRpYyBpbnQKaXNfc3BhY2Vfb3JfdGFiIChjaGFyIGMpIHsKCXJldHVybiAoYyA9PSAnICcgfHwgYyA9PSAnXHQnKTsKfQoKc3RhdGljIGNoYXIgKgpza2lwX3NwYWNlcyhjaGFyICpzKSB7Cgl3aGlsZSAoaXNfc3BhY2Vfb3JfdGFiKCpzKSkKCQlzKys7CglyZXR1cm4gczsKfQoKc3RhdGljIGNoYXIgKgpza2lwX25vbnNwYWNlcyhjaGFyICpzKSB7Cgl3aGlsZSAoKnMgJiYgIWlzX3NwYWNlX29yX3RhYigqcykpCgkJcysrOwoJcmV0dXJuIHM7Cn0KCiNkZWZpbmUgaXNvY3RhbChhKSAoKChhKSAmIH43KSA9PSAnMCcpCgovKiByZXR1cm5zIG1hbGxvY2VkIHBvaW50ZXIgLSBubyBtb3JlIHN0cmR1cCByZXF1aXJlZCAqLwpzdGF0aWMgY2hhciAqCnVubWFuZ2xlKGNoYXIgKnMpIHsKCWNoYXIgKnJldCwgKnNzLCAqc3A7CgoJc3MgPSBza2lwX25vbnNwYWNlcyhzKTsKCXJldCA9IHNwID0geG1hbGxvYyhzcy1zKzEpOwoJd2hpbGUocyAhPSBzcykgewoJCWlmICgqcyA9PSAnXFwnICYmIGlzb2N0YWwoc1sxXSkgJiYgaXNvY3RhbChzWzJdKSAmJiBpc29jdGFsKHNbM10pKSB7CgkJCSpzcCsrID0gNjQqKHNbMV0gJiA3KSArIDgqKHNbMl0gJiA3KSArIChzWzNdICYgNyk7CgkJCXMgKz0gNDsKCQl9IGVsc2UKCQkJKnNwKysgPSAqcysrOwoJfQoJKnNwID0gMDsKCXJldHVybiByZXQ7Cn0KCi8qCiAqIGZzdGF0J2luZyB0aGUgZmlsZSBhbmQgYWxsb2NhdGluZyBhIGJ1ZmZlciBob2xkaW5nIGFsbCBvZiBpdAogKiBtYXkgYmUgYSBiYWQgaWRlYTogaWYgdGhlIGZpbGUgaXMgL3Byb2MvbW91bnRzLCB0aGUgc3RhdAogKiByZXR1cm5zIDAuCiAqIChPbiB0aGUgb3RoZXIgaGFuZCwgbWFuZ2xpbmcgYW5kIHVubWFuZ2xpbmcgaXMgbWVhbmluZ2xlc3MKICogIGZvciAvcHJvYy9tb3VudHMuKQogKi8KCm1udEZJTEUgKgpuZnNfc2V0bW50ZW50IChjb25zdCBjaGFyICpmaWxlLCBjaGFyICptb2RlKSB7CgltbnRGSUxFICptZnAgPSB4bWFsbG9jKHNpemVvZigqbWZwKSk7Cgltb2RlX3Qgb2xkX3VtYXNrID0gdW1hc2soMDc3KTsKCgltZnAtPm1udGVudF9mcCA9IGZvcGVuKGZpbGUsIG1vZGUpOwoJdW1hc2sob2xkX3VtYXNrKTsKCW1mcC0+bW50ZW50X2ZpbGUgPSB4c3RyZHVwKGZpbGUpOwoJbWZwLT5tbnRlbnRfZXJycyA9IChtZnAtPm1udGVudF9mcCA9PSBOVUxMKTsKCW1mcC0+bW50ZW50X3NvZnRlcnJzID0gMDsKCW1mcC0+bW50ZW50X2xpbmVubyA9IDA7CglyZXR1cm4gbWZwOwp9Cgp2b2lkCm5mc19lbmRtbnRlbnQgKG1udEZJTEUgKm1mcCkgewoJaWYgKG1mcCkgewoJCWlmIChtZnAtPm1udGVudF9mcCkKCQkJZmNsb3NlKG1mcC0+bW50ZW50X2ZwKTsKCQlpZiAobWZwLT5tbnRlbnRfZmlsZSkKCQkJZnJlZShtZnAtPm1udGVudF9maWxlKTsKCQlmcmVlKG1mcCk7Cgl9Cn0KCmludApuZnNfYWRkbW50ZW50IChtbnRGSUxFICptZnAsIHN0cnVjdCBtbnRlbnQgKm1udCkgewoJY2hhciAqbTEsICptMiwgKm0zLCAqbTQ7CglpbnQgcmVzOwoKCWlmIChmc2VlayAobWZwLT5tbnRlbnRfZnAsIDAsIFNFRUtfRU5EKSkKCQlyZXR1cm4gMTsJCQkvKiBmYWlsdXJlICovCgoJbTEgPSBtYW5nbGUobW50LT5tbnRfZnNuYW1lKTsKCW0yID0gbWFuZ2xlKG1udC0+bW50X2Rpcik7CgltMyA9IG1hbmdsZShtbnQtPm1udF90eXBlKTsKCW00ID0gbWFuZ2xlKG1udC0+bW50X29wdHMpOwoKCXJlcyA9IGZwcmludGYgKG1mcC0+bW50ZW50X2ZwLCAiJXMgJXMgJXMgJXMgJWQgJWRcbiIsCgkJICAgICAgIG0xLCBtMiwgbTMsIG00LCBtbnQtPm1udF9mcmVxLCBtbnQtPm1udF9wYXNzbm8pOwoKCWZyZWUobTEpOwoJZnJlZShtMik7CglmcmVlKG0zKTsKCWZyZWUobTQpOwoJcmV0dXJuIChyZXMgPCAwKSA/IDEgOiAwOwp9CgovKiBSZWFkIHRoZSBuZXh0IGVudHJ5IGZyb20gdGhlIGZpbGUgZnAuIFN0b3AgcmVhZGluZyBhdCBhbiBpbmNvcnJlY3QgZW50cnkuICovCnN0cnVjdCBtbnRlbnQgKgpuZnNfZ2V0bW50ZW50IChtbnRGSUxFICptZnApIHsKCXN0YXRpYyBjaGFyIGJ1Zls0MDk2XTsKCXN0YXRpYyBzdHJ1Y3QgbW50ZW50IG1lOwoJY2hhciAqczsKCiBhZ2FpbjoKCWlmIChtZnAtPm1udGVudF9lcnJzIHx8IG1mcC0+bW50ZW50X3NvZnRlcnJzID49IEVSUl9NQVgpCgkJcmV0dXJuIE5VTEw7CgoJLyogcmVhZCB0aGUgbmV4dCBub24tYmxhbmsgbm9uLWNvbW1lbnQgbGluZSAqLwoJZG8gewoJCWlmIChmZ2V0cyAoYnVmLCBzaXplb2YoYnVmKSwgbWZwLT5tbnRlbnRfZnApID09IE5VTEwpCgkJCXJldHVybiBOVUxMOwoKCQltZnAtPm1udGVudF9saW5lbm8rKzsKCQlzID0gaW5kZXggKGJ1ZiwgJ1xuJyk7CgkJaWYgKHMgPT0gTlVMTCkgewoJCQkvKiBNaXNzaW5nIGZpbmFsIG5ld2xpbmU/ICBPdGhlcndpc2UgZXh0cmVtZWx5ICovCgkJCS8qIGxvbmcgbGluZSAtIGFzc3VtZSBmaWxlIHdhcyBjb3JydXB0ZWQgKi8KCQkJaWYgKGZlb2YobWZwLT5tbnRlbnRfZnApKSB7CgkJCQlmcHJpbnRmKHN0ZGVyciwgXygiW21udGVudF06IHdhcm5pbmc6IG5vIGZpbmFsICIKCQkJCQkibmV3bGluZSBhdCB0aGUgZW5kIG9mICVzXG4iKSwKCQkJCQltZnAtPm1udGVudF9maWxlKTsKCQkJCXMgPSBpbmRleCAoYnVmLCAwKTsKCQkJfSBlbHNlIHsKCQkJCW1mcC0+bW50ZW50X2VycnMgPSAxOwoJCQkJZ290byBlcnI7CgkJCX0KCQl9CgkJKnMgPSAwOwoJCWlmICgtLXMgPj0gYnVmICYmICpzID09ICdccicpCgkJCSpzID0gMDsKCQlzID0gc2tpcF9zcGFjZXMoYnVmKTsKCX0gd2hpbGUgKCpzID09ICdcMCcgfHwgKnMgPT0gJyMnKTsKCgltZS5tbnRfZnNuYW1lID0gdW5tYW5nbGUocyk7CglzID0gc2tpcF9ub25zcGFjZXMocyk7CglzID0gc2tpcF9zcGFjZXMocyk7CgltZS5tbnRfZGlyID0gdW5tYW5nbGUocyk7CglzID0gc2tpcF9ub25zcGFjZXMocyk7CglzID0gc2tpcF9zcGFjZXMocyk7CgltZS5tbnRfdHlwZSA9IHVubWFuZ2xlKHMpOwoJcyA9IHNraXBfbm9uc3BhY2VzKHMpOwoJcyA9IHNraXBfc3BhY2VzKHMpOwoJbWUubW50X29wdHMgPSB1bm1hbmdsZShzKTsKCXMgPSBza2lwX25vbnNwYWNlcyhzKTsKCXMgPSBza2lwX3NwYWNlcyhzKTsKCglpZiAoaXNkaWdpdCgqcykpIHsKCQltZS5tbnRfZnJlcSA9IGF0b2kocyk7CgkJd2hpbGUoaXNkaWdpdCgqcykpIHMrKzsKCX0gZWxzZQoJCW1lLm1udF9mcmVxID0gMDsKCWlmKCpzICYmICFpc19zcGFjZV9vcl90YWIoKnMpKQoJCWdvdG8gZXJyOwoKCXMgPSBza2lwX3NwYWNlcyhzKTsKCWlmKGlzZGlnaXQoKnMpKSB7CgkJbWUubW50X3Bhc3NubyA9IGF0b2kocyk7CgkJd2hpbGUoaXNkaWdpdCgqcykpIHMrKzsKCX0gZWxzZQoJCW1lLm1udF9wYXNzbm8gPSAwOwoJaWYoKnMgJiYgIWlzX3NwYWNlX29yX3RhYigqcykpCgkJZ290byBlcnI7CgoJLyogYWxsb3cgbW9yZSBzdHVmZiwgZS5nLiBjb21tZW50cywgb24gdGhpcyBsaW5lICovCgoJcmV0dXJuICZtZTsKCiBlcnI6CgltZnAtPm1udGVudF9zb2Z0ZXJycysrOwoJZnByaW50ZihzdGRlcnIsIF8oIlttbnRlbnRdOiBsaW5lICVkIGluICVzIGlzIGJhZCVzXG4iKSwKCQltZnAtPm1udGVudF9saW5lbm8sIG1mcC0+bW50ZW50X2ZpbGUsCgkJKG1mcC0+bW50ZW50X2VycnMgfHwgbWZwLT5tbnRlbnRfc29mdGVycnMgPj0gRVJSX01BWCkgPwoJCV8oIjsgcmVzdCBvZiBmaWxlIGlnbm9yZWQiKSA6ICIiKTsKCWdvdG8gYWdhaW47Cn0K