LyogU2hhcmVkIGxpYnJhcnkgYWRkLW9uIHRvIGlwdGFibGVzIHRvIGFkZCBsaW1pdCBzdXBwb3J0LgogKgogKiBK6XL0bWUgZGUgVml2aWUgICA8ZGV2aXZpZUBpbmZvLmVuc2VyYi51LWJvcmRlYXV4LmZyPgogKiBIZXJ26SBFeWNoZW5uZSAgICA8cnZAd2FsbGZpcmUub3JnPgogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPGdldG9wdC5oPgojaW5jbHVkZSA8aXA2dGFibGVzLmg+CiNpbmNsdWRlIDxzdGRkZWYuaD4KI2luY2x1ZGUgPGxpbnV4L25ldGZpbHRlcl9pcHY2L2lwNl90YWJsZXMuaD4KI2luY2x1ZGUgPGxpbnV4L25ldGZpbHRlcl9pcHY2L2lwNnRfbGltaXQuaD4KCiNkZWZpbmUgSVA2VF9MSU1JVF9BVkcJIjMvaG91ciIKI2RlZmluZSBJUDZUX0xJTUlUX0JVUlNUCTUKCi8qIEZ1bmN0aW9uIHdoaWNoIHByaW50cyBvdXQgdXNhZ2UgbWVzc2FnZS4gKi8Kc3RhdGljIHZvaWQKaGVscCh2b2lkKQp7CglwcmludGYoCiJsaW1pdCB2JXMgb3B0aW9uczpcbiIKIi0tbGltaXQgYXZnCQkJbWF4IGF2ZXJhZ2UgbWF0Y2ggcmF0ZTogZGVmYXVsdCAiSVA2VF9MSU1JVF9BVkciXG4iCiIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtQYWNrZXRzIHBlciBzZWNvbmQgdW5sZXNzIGZvbGxvd2VkIGJ5IFxuIgoiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvc2VjIC9taW51dGUgL2hvdXIgL2RheSBwb3N0Zml4ZXNdXG4iCiItLWxpbWl0LWJ1cnN0IG51bWJlcgkJbnVtYmVyIHRvIG1hdGNoIGluIGEgYnVyc3QsIGRlZmF1bHQgJXVcbiIKIlxuIiwgSVBUQUJMRVNfVkVSU0lPTiwgSVA2VF9MSU1JVF9CVVJTVCk7Cn0KCnN0YXRpYyBzdHJ1Y3Qgb3B0aW9uIG9wdHNbXSA9IHsKCXsgImxpbWl0IiwgMSwgMCwgJyUnIH0sCgl7ICJsaW1pdC1idXJzdCIsIDEsIDAsICckJyB9LAoJeyAwIH0KfTsKCnN0YXRpYwppbnQgcGFyc2VfcmF0ZShjb25zdCBjaGFyICpyYXRlLCB1X2ludDMyX3QgKnZhbCkKewoJY29uc3QgY2hhciAqZGVsaW07Cgl1X2ludDMyX3QgcjsKCXVfaW50MzJfdCBtdWx0ID0gMTsgIC8qIFNlY29uZHMgYnkgZGVmYXVsdC4gKi8KCglkZWxpbSA9IHN0cmNocihyYXRlLCAnLycpOwoJaWYgKGRlbGltKSB7CgkJaWYgKHN0cmxlbihkZWxpbSsxKSA9PSAwKQoJCQlyZXR1cm4gMDsKCgkJaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJzZWNvbmQiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSAxOwoJCWVsc2UgaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJtaW51dGUiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSA2MDsKCQllbHNlIGlmIChzdHJuY2FzZWNtcChkZWxpbSsxLCAiaG91ciIsIHN0cmxlbihkZWxpbSsxKSkgPT0gMCkKCQkJbXVsdCA9IDYwKjYwOwoJCWVsc2UgaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJkYXkiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSAyNCo2MCo2MDsKCQllbHNlCgkJCXJldHVybiAwOwoJfQoJciA9IGF0b2kocmF0ZSk7CglpZiAoIXIpCgkJcmV0dXJuIDA7CgoJLyogVGhpcyB3b3VsZCBnZXQgbWFwcGVkIHRvIGluZmluaXRlICgxL2RheSBpcyBtaW5pbXVtIHRoZXkKICAgICAgICAgICBjYW4gc3BlY2lmeSwgc28gd2UncmUgb2sgYXQgdGhhdCBlbmQpLiAqLwoJaWYgKHIgLyBtdWx0ID4gSVA2VF9MSU1JVF9TQ0FMRSkKCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLCAiUmF0ZSB0b28gZmFzdCBgJXMnXG4iLCByYXRlKTsKCgkqdmFsID0gSVA2VF9MSU1JVF9TQ0FMRSAqIG11bHQgLyByOwoJcmV0dXJuIDE7Cn0KCi8qIEluaXRpYWxpemUgdGhlIG1hdGNoLiAqLwpzdGF0aWMgdm9pZAppbml0KHN0cnVjdCBpcDZ0X2VudHJ5X21hdGNoICptLCB1bnNpZ25lZCBpbnQgKm5mY2FjaGUpCnsKCXN0cnVjdCBpcDZ0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcDZ0X3JhdGVpbmZvICopbS0+ZGF0YTsKCglwYXJzZV9yYXRlKElQNlRfTElNSVRfQVZHLCAmci0+YXZnKTsKCXItPmJ1cnN0ID0gSVA2VF9MSU1JVF9CVVJTVDsKCgkvKiBDYW4ndCBjYWNoZSB0aGlzICovCgkqbmZjYWNoZSB8PSBORkNfVU5LTk9XTjsKfQoKLyogRklYTUU6IGhhbmRsZSBvdmVyZmxvdzoKCWlmIChyLT5hdmcqci0+YnVyc3Qvci0+YnVyc3QgIT0gci0+YXZnKQoJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCSAgICJTb3JyeTogYnVyc3QgdG9vIGxhcmdlIGZvciB0aGF0IGF2ZyByYXRlLlxuIik7CiovCgovKiBGdW5jdGlvbiB3aGljaCBwYXJzZXMgY29tbWFuZCBvcHRpb25zOyByZXR1cm5zIHRydWUgaWYgaXQKICAgYXRlIGFuIG9wdGlvbiAqLwpzdGF0aWMgaW50CnBhcnNlKGludCBjLCBjaGFyICoqYXJndiwgaW50IGludmVydCwgdW5zaWduZWQgaW50ICpmbGFncywKICAgICAgY29uc3Qgc3RydWN0IGlwNnRfZW50cnkgKmVudHJ5LAogICAgICB1bnNpZ25lZCBpbnQgKm5mY2FjaGUsCiAgICAgIHN0cnVjdCBpcDZ0X2VudHJ5X21hdGNoICoqbWF0Y2gpCnsKCXN0cnVjdCBpcDZ0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcDZ0X3JhdGVpbmZvICopKCptYXRjaCktPmRhdGE7Cgl1bnNpZ25lZCBpbnQgbnVtOwoKCXN3aXRjaChjKSB7CgljYXNlICclJzoKCQlpZiAoY2hlY2tfaW52ZXJzZShvcHRhcmcsICZpbnZlcnQsIE5VTEwsIDApKQoJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJICAgIlVuZXhwZWN0ZWQgYCEnIGFmdGVyIC0tbGltaXQiKTsKCQlpZiAoIXBhcnNlX3JhdGUob3B0YXJnLCAmci0+YXZnKSkKCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCSAgICJiYWQgcmF0ZSBgJXMnIiwgb3B0YXJnKTsKCQlicmVhazsKCgljYXNlICckJzoKCQlpZiAoY2hlY2tfaW52ZXJzZShvcHRhcmcsICZpbnZlcnQsIE5VTEwsIDApKQoJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJICAgIlVuZXhwZWN0ZWQgYCEnIGFmdGVyIC0tbGltaXQtYnVyc3QiKTsKCgkJaWYgKHN0cmluZ190b19udW1iZXIob3B0YXJnLCAwLCAxMDAwMCwgJm51bSkgPT0gLTEpCgkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkgICAiYmFkIC0tbGltaXQtYnVyc3QgYCVzJyIsIG9wdGFyZyk7CgkJci0+YnVyc3QgPSBudW07CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlyZXR1cm4gMDsKCX0KCglyZXR1cm4gMTsKfQoKLyogRmluYWwgY2hlY2s7IG5vdGhpbmcuICovCnN0YXRpYyB2b2lkIGZpbmFsX2NoZWNrKHVuc2lnbmVkIGludCBmbGFncykKewp9CgpzdGF0aWMgc3RydWN0IHJhdGVzCnsKCWNvbnN0IGNoYXIgKm5hbWU7Cgl1X2ludDMyX3QgbXVsdDsKfSByYXRlc1tdID0geyB7ICJkYXkiLCBJUDZUX0xJTUlUX1NDQUxFKjI0KjYwKjYwIH0sCgkgICAgICB7ICJob3VyIiwgSVA2VF9MSU1JVF9TQ0FMRSo2MCo2MCB9LAoJICAgICAgeyAibWluIiwgSVA2VF9MSU1JVF9TQ0FMRSo2MCB9LAoJICAgICAgeyAic2VjIiwgSVA2VF9MSU1JVF9TQ0FMRSB9IH07CgpzdGF0aWMgdm9pZCBwcmludF9yYXRlKHVfaW50MzJfdCBwZXJpb2QpCnsKCXVuc2lnbmVkIGludCBpOwoKCWZvciAoaSA9IDE7IGkgPCBzaXplb2YocmF0ZXMpL3NpemVvZihzdHJ1Y3QgcmF0ZXMpOyBpKyspIHsKCQlpZiAocGVyaW9kID4gcmF0ZXNbaV0ubXVsdAoJCSAgICB8fCByYXRlc1tpXS5tdWx0ICUgcGVyaW9kICE9IDApCgkJCWJyZWFrOwoJfQoKCXByaW50ZigiJXUvJXMgIiwgcmF0ZXNbaS0xXS5tdWx0IC8gcGVyaW9kLCByYXRlc1tpLTFdLm5hbWUpOwp9CgovKiBQcmludHMgb3V0IHRoZSBtYXRjaGluZm8uICovCnN0YXRpYyB2b2lkCnByaW50KGNvbnN0IHN0cnVjdCBpcDZ0X2lwNiAqaXAsCiAgICAgIGNvbnN0IHN0cnVjdCBpcDZ0X2VudHJ5X21hdGNoICptYXRjaCwKICAgICAgaW50IG51bWVyaWMpCnsKCXN0cnVjdCBpcDZ0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcDZ0X3JhdGVpbmZvICopbWF0Y2gtPmRhdGE7CglwcmludGYoImxpbWl0OiBhdmcgIik7IHByaW50X3JhdGUoci0+YXZnKTsKCXByaW50ZigiYnVyc3QgJXUgIiwgci0+YnVyc3QpOwp9CgovKiBGSVhNRTogTWFrZSBtaW5pbWFsaXN0OiBvbmx5IHByaW50IHJhdGUgaWYgbm90IGRlZmF1bHQgLS1SUiAqLwpzdGF0aWMgdm9pZCBzYXZlKGNvbnN0IHN0cnVjdCBpcDZ0X2lwNiAqaXAsIGNvbnN0IHN0cnVjdCBpcDZ0X2VudHJ5X21hdGNoICptYXRjaCkKewoJc3RydWN0IGlwNnRfcmF0ZWluZm8gKnIgPSAoc3RydWN0IGlwNnRfcmF0ZWluZm8gKiltYXRjaC0+ZGF0YTsKCglwcmludGYoIi0tbGltaXQgIik7IHByaW50X3JhdGUoci0+YXZnKTsKCWlmIChyLT5idXJzdCAhPSBJUDZUX0xJTUlUX0JVUlNUKQoJCXByaW50ZigiLS1saW1pdC1idXJzdCAldSAiLCByLT5idXJzdCk7Cn0KCnN0YXRpYwpzdHJ1Y3QgaXA2dGFibGVzX21hdGNoIGxpbWl0Cj0geyBOVUxMLAogICAgImxpbWl0IiwKICAgIElQVEFCTEVTX1ZFUlNJT04sCiAgICBJUDZUX0FMSUdOKHNpemVvZihzdHJ1Y3QgaXA2dF9yYXRlaW5mbykpLAogICAgb2Zmc2V0b2Yoc3RydWN0IGlwNnRfcmF0ZWluZm8sIHByZXYpLAogICAgJmhlbHAsCiAgICAmaW5pdCwKICAgICZwYXJzZSwKICAgICZmaW5hbF9jaGVjaywKICAgICZwcmludCwKICAgICZzYXZlLAogICAgb3B0cwp9OwoKdm9pZCBfaW5pdCh2b2lkKQp7CglyZWdpc3Rlcl9tYXRjaDYoJmxpbWl0KTsKfQo=