LyogU2hhcmVkIGxpYnJhcnkgYWRkLW9uIHRvIGlwdGFibGVzIHRvIGFkZCB1MzIgbWF0Y2hpbmcsCiAqIGdlbmVyYWxpemVkIG1hdGNoaW5nIG9uIHZhbHVlcyBmb3VuZCBhdCBwYWNrZXQgb2Zmc2V0cwogKgogKiBEZXRhaWxlZCBkb2MgaXMgaW4gdGhlIGtlcm5lbCBtb2R1bGUgc291cmNlCiAqIG5ldC9uZXRmaWx0ZXIveHRfdTMyLmMKICoKICogKEMpIDIwMDIgYnkgRG9uIENvaGVuIDxkb24tbmV0ZkBpc2lzLmNzMy1pbmMuY29tPgogKiBDb3B5cmlnaHQgqSBKYW4gRW5nZWxoYXJkdCA8amVuZ2VsaEBnbXguZGU+LCAyMDA3CiAqIFJlbGVhc2VkIHVuZGVyIHRoZSB0ZXJtcyBvZiBHTlUgR1BMIHYyCiAqLwojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGdldG9wdC5oPgojaW5jbHVkZSA8bmV0ZGIuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgPHh0YWJsZXMuaD4KI2luY2x1ZGUgIi4uL2luY2x1ZGUvbGludXgvbmV0ZmlsdGVyL3h0X3UzMi5oIgoKc3RhdGljIGNvbnN0IHN0cnVjdCBvcHRpb24gdTMyX29wdHNbXSA9IHsKCXsidTMyIiwgMSwgTlVMTCwgJ3UnfSwKCXtOVUxMfSwKfTsKCnN0YXRpYyB2b2lkIHUzMl9oZWxwKHZvaWQpCnsKCXByaW50ZigKCQkidTMyIHYlcyBvcHRpb25zOlxuIgoJCSJbIV0gLS11MzIgdGVzdHNcbiIKCQkiXHRcdCIidGVzdHMgOj0gbG9jYXRpb24gXCI9XCIgdmFsdWUgfCB0ZXN0cyBcIiYmXCIgbG9jYXRpb24gXCI9XCIgdmFsdWVcbiIKCQkiXHRcdCIidmFsdWUgOj0gcmFuZ2UgfCB2YWx1ZSBcIixcIiByYW5nZVxuIgoJCSJcdFx0IiJyYW5nZSA6PSBudW1iZXIgfCBudW1iZXIgXCI6XCIgbnVtYmVyXG4iCgkJIlx0XHQiImxvY2F0aW9uIDo9IG51bWJlciB8IGxvY2F0aW9uIG9wZXJhdG9yIG51bWJlclxuIgoJCSJcdFx0IiJvcGVyYXRvciA6PSBcIiZcIiB8IFwiPDxcIiB8IFwiPj5cIiB8IFwiQFwiXG4iLAoJCUlQVEFCTEVTX1ZFUlNJT04pOwoJcmV0dXJuOwp9CgpzdGF0aWMgdm9pZCB1MzJfZHVtcChjb25zdCBzdHJ1Y3QgeHRfdTMyICpkYXRhKQp7Cgljb25zdCBzdHJ1Y3QgeHRfdTMyX3Rlc3QgKmN0OwoJdW5zaWduZWQgaW50IHRlc3RpbmQsIGk7CgoJZm9yICh0ZXN0aW5kID0gMDsgdGVzdGluZCA8IGRhdGEtPm50ZXN0czsgKyt0ZXN0aW5kKSB7CgkJY3QgPSAmZGF0YS0+dGVzdHNbdGVzdGluZF07CgoJCWlmICh0ZXN0aW5kID4gMCkKCQkJcHJpbnRmKCImJiIpOwoKCQlwcmludGYoIjB4JXgiLCBjdC0+bG9jYXRpb25bMF0ubnVtYmVyKTsKCQlmb3IgKGkgPSAxOyBpIDwgY3QtPm5udW1zOyArK2kpIHsKCQkJc3dpdGNoIChjdC0+bG9jYXRpb25baV0ubmV4dG9wKSB7CgkJCWNhc2UgWFRfVTMyX0FORDoKCQkJCXByaW50ZigiJiIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgWFRfVTMyX0xFRlRTSDoKCQkJCXByaW50ZigiPDwiKTsKCQkJCWJyZWFrOwoJCQljYXNlIFhUX1UzMl9SSUdIVFNIOgoJCQkJcHJpbnRmKCI+PiIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgWFRfVTMyX0FUOgoJCQkJcHJpbnRmKCJAIik7CgkJCQlicmVhazsKCQkJfQoJCQlwcmludGYoIjB4JXgiLCBjdC0+bG9jYXRpb25baV0ubnVtYmVyKTsKCQl9CgoJCXByaW50ZigiPSIpOwoJCWZvciAoaSA9IDA7IGkgPCBjdC0+bnZhbHVlczsgKytpKSB7CgkJCWlmIChpID4gMCkKCQkJCXByaW50ZigiLCIpOwoJCQlpZiAoY3QtPnZhbHVlW2ldLm1pbiA9PSBjdC0+dmFsdWVbaV0ubWF4KQoJCQkJcHJpbnRmKCIweCV4IiwgY3QtPnZhbHVlW2ldLm1pbik7CgkJCWVsc2UKCQkJCXByaW50ZigiMHgleDoweCV4IiwgY3QtPnZhbHVlW2ldLm1pbiwKCQkJCSAgICAgICBjdC0+dmFsdWVbaV0ubWF4KTsKCQl9Cgl9CglwcmludGYoIiAiKTsKfQoKLyogc3RyaW5nX3RvX251bWJlcigpIGlzIG5vdCBxdWl0ZSB3aGF0IHdlIG5lZWQgaGVyZSAuLi4gKi8Kc3RhdGljIHVfaW50MzJfdCBwYXJzZV9udW1iZXIoY2hhciAqKnMsIGludCBwb3MpCnsKCXVfaW50MzJfdCBudW1iZXI7CgljaGFyICplbmQ7CgoJZXJybm8gID0gMDsKCW51bWJlciA9IHN0cnRvdWwoKnMsICZlbmQsIDApOwoJaWYgKGVuZCA9PSAqcykKCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkgICAidTMyOiBhdCBjaGFyICVkOiBleHBlY3RlZCBudW1iZXIiLCBwb3MpOwoJaWYgKGVycm5vICE9IDApCgkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJICAgInUzMjogYXQgY2hhciAlZDogZXJyb3IgcmVhZGluZyBudW1iZXIiLCBwb3MpOwoJKnMgPSBlbmQ7CglyZXR1cm4gbnVtYmVyOwp9CgovKiBGdW5jdGlvbiB3aGljaCBwYXJzZXMgY29tbWFuZCBvcHRpb25zOyByZXR1cm5zIHRydWUgaWYgaXQgYXRlIGFuIG9wdGlvbiAqLwpzdGF0aWMgaW50IHUzMl9wYXJzZShpbnQgYywgY2hhciAqKmFyZ3YsIGludCBpbnZlcnQsIHVuc2lnbmVkIGludCAqZmxhZ3MsCgkJICAgICBjb25zdCB2b2lkICplbnRyeSwgc3RydWN0IHh0X2VudHJ5X21hdGNoICoqbWF0Y2gpCnsKCXN0cnVjdCB4dF91MzIgKmRhdGEgPSAodm9pZCAqKSgqbWF0Y2gpLT5kYXRhOwoJdW5zaWduZWQgaW50IHRlc3RpbmQgPSAwLCBsb2NpbmQgPSAwLCB2YWxpbmQgPSAwOwoJc3RydWN0IHh0X3UzMl90ZXN0ICpjdCA9ICZkYXRhLT50ZXN0c1t0ZXN0aW5kXTsgLyogY3VycmVudCB0ZXN0ICovCgljaGFyICphcmcgPSBhcmd2W29wdGluZC0xXTsgLyogdGhlIGFyZ3VtZW50IHN0cmluZyAqLwoJY2hhciAqc3RhcnQgPSBhcmc7CglpbnQgc3RhdGUgPSAwOwoKCWlmIChjICE9ICd1JykKCQlyZXR1cm4gMDsKCglkYXRhLT5pbnZlcnQgPSBpbnZlcnQ7CgoJLyoKCSAqIHN0YXRlczoKCSAqIDAgPSBsb29raW5nIGZvciBudW1iZXJzIGFuZCBvcGVyYXRpb25zLAoJICogMSA9IGxvb2tpbmcgZm9yIHJhbmdlcwoJICovCgl3aGlsZSAoMSkgewoJCS8qIHJlYWQgbmV4dCBvcGVyYW5kL251bWJlciBvciByYW5nZSAqLwoJCXdoaWxlIChpc3NwYWNlKCphcmcpKQoJCQkrK2FyZzsKCgkJaWYgKCphcmcgPT0gJ1wwJykgewoJCQkvKiBlbmQgb2YgYXJndW1lbnQgZm91bmQgKi8KCQkJaWYgKHN0YXRlID09IDApCgkJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJCSAgICJ1MzI6IGFicnVwdCBlbmQgb2YgaW5wdXQgYWZ0ZXIgbG9jYXRpb24gc3BlY2lmaWVyIik7CgkJCWlmICh2YWxpbmQgPT0gMCkKCQkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkJICAgInUzMjogdGVzdCBlbmRlZCB3aXRoIG5vIHZhbHVlIHNwZWNpZmllZCIpOwoKCQkJY3QtPm5udW1zICAgID0gbG9jaW5kOwoJCQljdC0+bnZhbHVlcyAgPSB2YWxpbmQ7CgkJCWRhdGEtPm50ZXN0cyA9ICsrdGVzdGluZDsKCgkJCWlmICh0ZXN0aW5kID4gWFRfVTMyX01BWFNJWkUpCgkJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJICAgICAgICAgICAidTMyOiBhdCBjaGFyICV1OiB0b28gbWFueSBcIiYmXCJzIiwKCQkJCSAgICAgICAgICAgKHVuc2lnbmVkIGludCkoYXJnIC0gc3RhcnQpKTsKCQkJcmV0dXJuIDE7CgkJfQoKCQlpZiAoc3RhdGUgPT0gMCkgewoJCQkvKgoJCQkgKiByZWFkaW5nIGxvY2F0aW9uOiByZWFkIGEgbnVtYmVyIGlmIG5vdGhpbmcgcmVhZCB5ZXQsCgkJCSAqIG90aGVyd2lzZSBlaXRoZXIgb3AgbnVtYmVyIG9yID0gdG8gZW5kIGxvY2F0aW9uIHNwZWMKCQkJICovCgkJCWlmICgqYXJnID09ICc9JykgewoJCQkJaWYgKGxvY2luZCA9PSAwKSB7CgkJCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCQkgICAgICAgICAgICJ1MzI6IGF0IGNoYXIgJXU6ICIKCQkJCQkgICAgICAgICAgICJsb2NhdGlvbiBzcGVjIG1pc3NpbmciLAoJCQkJCSAgICAgICAgICAgKHVuc2lnbmVkIGludCkoYXJnIC0gc3RhcnQpKTsKCQkJCX0gZWxzZSB7CgkJCQkJKythcmc7CgkJCQkJc3RhdGUgPSAxOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJaWYgKGxvY2luZCAhPSAwKSB7CgkJCQkJLyogbmVlZCBvcCBiZWZvcmUgbnVtYmVyICovCgkJCQkJaWYgKCphcmcgPT0gJyYnKSB7CgkJCQkJCWN0LT5sb2NhdGlvbltsb2NpbmRdLm5leHRvcCA9IFhUX1UzMl9BTkQ7CgkJCQkJfSBlbHNlIGlmICgqYXJnID09ICc8JykgewoJCQkJCQlpZiAoKisrYXJnICE9ICc8JykKCQkJCQkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkJCQkJICAgInUzMjogYXQgY2hhciAldTogYSBzZWNvbmQgJzwnIHdhcyBleHBlY3RlZCIsICh1bnNpZ25lZCBpbnQpKGFyZyAtIHN0YXJ0KSk7CgkJCQkJCWN0LT5sb2NhdGlvbltsb2NpbmRdLm5leHRvcCA9IFhUX1UzMl9MRUZUU0g7CgkJCQkJfSBlbHNlIGlmICgqYXJnID09ICc+JykgewoJCQkJCQlpZiAoKisrYXJnICE9ICc+JykKCQkJCQkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkJCQkJICAgInUzMjogYXQgY2hhciAldTogYSBzZWNvbmQgJz4nIHdhcyBleHBlY3RlZCIsICh1bnNpZ25lZCBpbnQpKGFyZyAtIHN0YXJ0KSk7CgkJCQkJCWN0LT5sb2NhdGlvbltsb2NpbmRdLm5leHRvcCA9IFhUX1UzMl9SSUdIVFNIOwoJCQkJCX0gZWxzZSBpZiAoKmFyZyA9PSAnQCcpIHsKCQkJCQkJY3QtPmxvY2F0aW9uW2xvY2luZF0ubmV4dG9wID0gWFRfVTMyX0FUOwoJCQkJCX0gZWxzZSB7CgkJCQkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkJCQkidTMyOiBhdCBjaGFyICV1OiBvcGVyYXRvciBleHBlY3RlZCIsICh1bnNpZ25lZCBpbnQpKGFyZyAtIHN0YXJ0KSk7CgkJCQkJfQoJCQkJCSsrYXJnOwoJCQkJfQoJCQkJLyogbm93IGEgbnVtYmVyOyBzdHJpbmdfdG9fbnVtYmVyIHNraXBzIHdoaXRlIHNwYWNlPyAqLwoJCQkJY3QtPmxvY2F0aW9uW2xvY2luZF0ubnVtYmVyID0KCQkJCQlwYXJzZV9udW1iZXIoJmFyZywgYXJnIC0gc3RhcnQpOwoJCQkJaWYgKCsrbG9jaW5kID4gWFRfVTMyX01BWFNJWkUpCgkJCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCQkJICAgInUzMjogYXQgY2hhciAldTogdG9vIG1hbnkgb3BlcmF0b3JzIiwgKHVuc2lnbmVkIGludCkoYXJnIC0gc3RhcnQpKTsKCQkJfQoJCX0gZWxzZSB7CgkJCS8qCgkJCSAqIHN0YXRlIDEgLSByZWFkaW5nIHZhbHVlczogcmVhZCBhIHJhbmdlIGlmIG5vdGhpbmcKCQkJICogcmVhZCB5ZXQsIG90aGVyd2lzZSBlaXRoZXIgLHJhbmdlIG9yICYmIHRvIGVuZAoJCQkgKiB0ZXN0IHNwZWMKCQkJICovCgkJCWlmICgqYXJnID09ICcmJykgewoJCQkJaWYgKCorK2FyZyAhPSAnJicpCgkJCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCQkJICAgInUzMjogYXQgY2hhciAldTogYSBzZWNvbmQgJyYnIHdhcyBleHBlY3RlZCIsICh1bnNpZ25lZCBpbnQpKGFyZyAtIHN0YXJ0KSk7CgkJCQlpZiAodmFsaW5kID09IDApIHsKCQkJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJCQkgICAidTMyOiBhdCBjaGFyICV1OiB2YWx1ZSBzcGVjIG1pc3NpbmciLCAodW5zaWduZWQgaW50KShhcmcgLSBzdGFydCkpOwoJCQkJfSBlbHNlIHsKCQkJCQljdC0+bm51bXMgICA9IGxvY2luZDsKCQkJCQljdC0+bnZhbHVlcyA9IHZhbGluZDsKCQkJCQljdCA9ICZkYXRhLT50ZXN0c1srK3Rlc3RpbmRdOwoJCQkJCWlmICh0ZXN0aW5kID4gWFRfVTMyX01BWFNJWkUpCgkJCQkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkJCQkgICAidTMyOiBhdCBjaGFyICV1OiB0b28gbWFueSBcIiYmXCJzIiwgKHVuc2lnbmVkIGludCkoYXJnIC0gc3RhcnQpKTsKCQkJCQkrK2FyZzsKCQkJCQlzdGF0ZSAgPSAwOwoJCQkJCWxvY2luZCA9IDA7CgkJCQkJdmFsaW5kID0gMDsKCQkJCX0KCQkJfSBlbHNlIHsgLyogcmVhZCB2YWx1ZSByYW5nZSAqLwoJCQkJaWYgKHZhbGluZCA+IDApIHsgLyogbmVlZCAsIGJlZm9yZSBudW1iZXIgKi8KCQkJCQlpZiAoKmFyZyAhPSAnLCcpCgkJCQkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkJCQkgICAidTMyOiBhdCBjaGFyICV1OiBleHBlY3RlZCBcIixcIiBvciBcIiYmXCIiLCAodW5zaWduZWQgaW50KShhcmcgLSBzdGFydCkpOwoJCQkJCSsrYXJnOwoJCQkJfQoJCQkJY3QtPnZhbHVlW3ZhbGluZF0ubWluID0KCQkJCQlwYXJzZV9udW1iZXIoJmFyZywgYXJnIC0gc3RhcnQpOwoKCQkJCXdoaWxlIChpc3NwYWNlKCphcmcpKQoJCQkJCSsrYXJnOwoKCQkJCWlmICgqYXJnID09ICc6JykgewoJCQkJCSsrYXJnOwoJCQkJCWN0LT52YWx1ZVt2YWxpbmRdLm1heCA9CgkJCQkJCXBhcnNlX251bWJlcigmYXJnLCBhcmctc3RhcnQpOwoJCQkJfSBlbHNlIHsKCQkJCQljdC0+dmFsdWVbdmFsaW5kXS5tYXggPQoJCQkJCQljdC0+dmFsdWVbdmFsaW5kXS5taW47CgkJCQl9CgoJCQkJaWYgKCsrdmFsaW5kID4gWFRfVTMyX01BWFNJWkUpCgkJCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCQkJICAgInUzMjogYXQgY2hhciAldTogdG9vIG1hbnkgXCIsXCJzIiwgKHVuc2lnbmVkIGludCkoYXJnIC0gc3RhcnQpKTsKCQkJfQoJCX0KCX0KfQoKc3RhdGljIHZvaWQgdTMyX3ByaW50KGNvbnN0IHZvaWQgKmlwLCBjb25zdCBzdHJ1Y3QgeHRfZW50cnlfbWF0Y2ggKm1hdGNoLAogICAgICAgICAgICAgICAgICAgICAgaW50IG51bWVyaWMpCnsKCWNvbnN0IHN0cnVjdCB4dF91MzIgKmRhdGEgPSAoY29uc3Qgdm9pZCAqKW1hdGNoLT5kYXRhOwoJcHJpbnRmKCJ1MzIgIik7CglpZiAoZGF0YS0+aW52ZXJ0KQoJCXByaW50ZigiISAiKTsKCXUzMl9kdW1wKGRhdGEpOwoJcmV0dXJuOwp9CgpzdGF0aWMgdm9pZCB1MzJfc2F2ZShjb25zdCB2b2lkICppcCwgY29uc3Qgc3RydWN0IHh0X2VudHJ5X21hdGNoICptYXRjaCkKewoJY29uc3Qgc3RydWN0IHh0X3UzMiAqZGF0YSA9IChjb25zdCB2b2lkICopbWF0Y2gtPmRhdGE7CglpZiAoZGF0YS0+aW52ZXJ0KQoJCXByaW50ZigiISAiKTsKCXByaW50ZigiLS11MzIgIik7Cgl1MzJfZHVtcChkYXRhKTsKCXJldHVybjsKfQoKc3RhdGljIHN0cnVjdCB4dGFibGVzX21hdGNoIHUzMl9tYXRjaCA9IHsKCS5uYW1lICAgICAgICAgID0gInUzMiIsCgkuZmFtaWx5ICAgICAgICA9IEFGX0lORVQsCgkudmVyc2lvbiAgICAgICA9IElQVEFCTEVTX1ZFUlNJT04sCgkuc2l6ZSAgICAgICAgICA9IFhUX0FMSUdOKHNpemVvZihzdHJ1Y3QgeHRfdTMyKSksCgkudXNlcnNwYWNlc2l6ZSA9IFhUX0FMSUdOKHNpemVvZihzdHJ1Y3QgeHRfdTMyKSksCgkuaGVscCAgICAgICAgICA9IHUzMl9oZWxwLAoJLnBhcnNlICAgICAgICAgPSB1MzJfcGFyc2UsCgkucHJpbnQgICAgICAgICA9IHUzMl9wcmludCwKCS5zYXZlICAgICAgICAgID0gdTMyX3NhdmUsCgkuZXh0cmFfb3B0cyAgICA9IHUzMl9vcHRzLAp9OwoKc3RhdGljIHN0cnVjdCB4dGFibGVzX21hdGNoIHUzMl9tYXRjaDYgPSB7CgkubmFtZSAgICAgICAgICA9ICJ1MzIiLAoJLmZhbWlseSAgICAgICAgPSBBRl9JTkVUNiwKCS52ZXJzaW9uICAgICAgID0gSVBUQUJMRVNfVkVSU0lPTiwKCS5zaXplICAgICAgICAgID0gWFRfQUxJR04oc2l6ZW9mKHN0cnVjdCB4dF91MzIpKSwKCS51c2Vyc3BhY2VzaXplID0gWFRfQUxJR04oc2l6ZW9mKHN0cnVjdCB4dF91MzIpKSwKCS5oZWxwICAgICAgICAgID0gdTMyX2hlbHAsCgkucGFyc2UgICAgICAgICA9IHUzMl9wYXJzZSwKCS5wcmludCAgICAgICAgID0gdTMyX3ByaW50LAoJLnNhdmUgICAgICAgICAgPSB1MzJfc2F2ZSwKCS5leHRyYV9vcHRzICAgID0gdTMyX29wdHMsCn07Cgp2b2lkIF9pbml0KHZvaWQpCnsKCXh0YWJsZXNfcmVnaXN0ZXJfbWF0Y2goJnUzMl9tYXRjaCk7Cgl4dGFibGVzX3JlZ2lzdGVyX21hdGNoKCZ1MzJfbWF0Y2g2KTsKCXJldHVybjsKfQo=