LyogU2hhcmVkIGxpYnJhcnkgYWRkLW9uIHRvIGlwdGFibGVzIHRvIGFkZCBsaW1pdCBzdXBwb3J0LgogKgogKiBK6XL0bWUgZGUgVml2aWUgICA8ZGV2aXZpZUBpbmZvLmVuc2VyYi51LWJvcmRlYXV4LmZyPgogKiBIZXJ26SBFeWNoZW5uZSAgIDxleWNoZW5uZUBpbmZvLmVuc2VyYi51LWJvcmRlYXV4LmZyPgogKi8KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8Z2V0b3B0Lmg+CiNpbmNsdWRlIDxpcDZ0YWJsZXMuaD4KI2luY2x1ZGUgPHN0ZGRlZi5oPgojaW5jbHVkZSA8bGludXgvbmV0ZmlsdGVyX2lwdjYvaXA2X3RhYmxlcy5oPgojaW5jbHVkZSA8bGludXgvbmV0ZmlsdGVyX2lwdjYvaXA2dF9saW1pdC5oPgoKI2RlZmluZSBJUDZUX0xJTUlUX0FWRwkiMy9ob3VyIgojZGVmaW5lIElQNlRfTElNSVRfQlVSU1QJNQoKLyogRnVuY3Rpb24gd2hpY2ggcHJpbnRzIG91dCB1c2FnZSBtZXNzYWdlLiAqLwpzdGF0aWMgdm9pZApoZWxwKHZvaWQpCnsKCXByaW50ZigKImxpbWl0IHYlcyBvcHRpb25zOlxuIgoiLS1saW1pdCBhdmcJCQltYXggYXZlcmFnZSBtYXRjaCByYXRlOiBkZWZhdWx0ICJJUDZUX0xJTUlUX0FWRyJcbiIKIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1BhY2tldHMgcGVyIHNlY29uZCB1bmxlc3MgZm9sbG93ZWQgYnkgXG4iCiIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC9zZWMgL21pbnV0ZSAvaG91ciAvZGF5IHBvc3RmaXhlc11cbiIKIi0tbGltaXQtYnVyc3QgbnVtYmVyCQludW1iZXIgdG8gbWF0Y2ggaW4gYSBidXJzdCwgZGVmYXVsdCAldVxuIgoiXG4iLCBORVRGSUxURVJfVkVSU0lPTiwgSVA2VF9MSU1JVF9CVVJTVCk7Cn0KCnN0YXRpYyBzdHJ1Y3Qgb3B0aW9uIG9wdHNbXSA9IHsKCXsgImxpbWl0IiwgMSwgMCwgJyUnIH0sCgl7ICJsaW1pdC1idXJzdCIsIDEsIDAsICckJyB9LAoJeyAwIH0KfTsKCnN0YXRpYwppbnQgcGFyc2VfcmF0ZShjb25zdCBjaGFyICpyYXRlLCB1X2ludDMyX3QgKnZhbCkKewoJY29uc3QgY2hhciAqZGVsaW07Cgl1X2ludDMyX3QgcjsKCXVfaW50MzJfdCBtdWx0ID0gMTsgIC8qIFNlY29uZHMgYnkgZGVmYXVsdC4gKi8KCglkZWxpbSA9IHN0cmNocihyYXRlLCAnLycpOwoJaWYgKGRlbGltKSB7CgkJaWYgKHN0cmxlbihkZWxpbSsxKSA9PSAwKQoJCQlyZXR1cm4gMDsKCgkJaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJzZWNvbmQiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSAxOwoJCWVsc2UgaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJtaW51dGUiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSA2MDsKCQllbHNlIGlmIChzdHJuY2FzZWNtcChkZWxpbSsxLCAiaG91ciIsIHN0cmxlbihkZWxpbSsxKSkgPT0gMCkKCQkJbXVsdCA9IDYwKjYwOwoJCWVsc2UgaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJkYXkiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSAyNCo2MCo2MDsKCQllbHNlCgkJCXJldHVybiAwOwoJfQoJciA9IGF0b2kocmF0ZSk7CglpZiAoIXIpCgkJcmV0dXJuIDA7CgoJLyogVGhpcyB3b3VsZCBnZXQgbWFwcGVkIHRvIGluZmluaXRlICgxL2RheSBpcyBtaW5pbXVtIHRoZXkKICAgICAgICAgICBjYW4gc3BlY2lmeSwgc28gd2UncmUgb2sgYXQgdGhhdCBlbmQpLiAqLwoJaWYgKHIgLyBtdWx0ID4gSVA2VF9MSU1JVF9TQ0FMRSkKCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLCAiUmF0ZSB0b28gZmFzdCBgJXMnXG4iLCByYXRlKTsKCgkqdmFsID0gSVA2VF9MSU1JVF9TQ0FMRSAqIG11bHQgLyByOwoJcmV0dXJuIDE7Cn0KCi8qIEluaXRpYWxpemUgdGhlIG1hdGNoLiAqLwpzdGF0aWMgdm9pZAppbml0KHN0cnVjdCBpcDZ0X2VudHJ5X21hdGNoICptLCB1bnNpZ25lZCBpbnQgKm5mY2FjaGUpCnsKCXN0cnVjdCBpcDZ0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcDZ0X3JhdGVpbmZvICopbS0+ZGF0YTsKCglwYXJzZV9yYXRlKElQNlRfTElNSVRfQVZHLCAmci0+YXZnKTsKCXItPmJ1cnN0ID0gSVA2VF9MSU1JVF9CVVJTVDsKCgkvKiBDYW4ndCBjYWNoZSB0aGlzICovCgkqbmZjYWNoZSB8PSBORkNfVU5LTk9XTjsKfQoKLyogRklYTUU6IGhhbmRsZSBvdmVyZmxvdzoKCWlmIChyLT5hdmcqci0+YnVyc3Qvci0+YnVyc3QgIT0gci0+YXZnKQoJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCSAgICJTb3JyeTogYnVyc3QgdG9vIGxhcmdlIGZvciB0aGF0IGF2ZyByYXRlLlxuIik7CiovCgovKiBGdW5jdGlvbiB3aGljaCBwYXJzZXMgY29tbWFuZCBvcHRpb25zOyByZXR1cm5zIHRydWUgaWYgaXQKICAgYXRlIGFuIG9wdGlvbiAqLwpzdGF0aWMgaW50CnBhcnNlKGludCBjLCBjaGFyICoqYXJndiwgaW50IGludmVydCwgdW5zaWduZWQgaW50ICpmbGFncywKICAgICAgY29uc3Qgc3RydWN0IGlwNnRfZW50cnkgKmVudHJ5LAogICAgICB1bnNpZ25lZCBpbnQgKm5mY2FjaGUsCiAgICAgIHN0cnVjdCBpcDZ0X2VudHJ5X21hdGNoICoqbWF0Y2gpCnsKCXN0cnVjdCBpcDZ0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcDZ0X3JhdGVpbmZvICopKCptYXRjaCktPmRhdGE7CglpbnQgbnVtOwoKCXN3aXRjaChjKSB7CgljYXNlICclJzoKCQlpZiAoY2hlY2tfaW52ZXJzZShvcHRhcmcsICZpbnZlcnQpKQoJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJICAgIlVuZXhwZWN0ZWQgYCEnIGFmdGVyIC0tbGltaXQiKTsKCQlpZiAoIXBhcnNlX3JhdGUob3B0YXJnLCAmci0+YXZnKSkKCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCSAgICJiYWQgcmF0ZSBgJXMnIiwgb3B0YXJnKTsKCQlicmVhazsKCgljYXNlICckJzoKCQlpZiAoY2hlY2tfaW52ZXJzZShvcHRhcmcsICZpbnZlcnQpKQoJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJICAgIlVuZXhwZWN0ZWQgYCEnIGFmdGVyIC0tbGltaXQtYnVyc3QiKTsKCgkJbnVtID0gc3RyaW5nX3RvX251bWJlcihvcHRhcmcsIDAsIDEwMDAwKTsKCQlpZiAobnVtIDw9IDApCgkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkgICAiYmFkIC0tbGltaXQtYnVyc3QgYCVzJyIsIG9wdGFyZyk7CgkJci0+YnVyc3QgPSBudW07CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlyZXR1cm4gMDsKCX0KCglyZXR1cm4gMTsKfQoKLyogRmluYWwgY2hlY2s7IG5vdGhpbmcuICovCnN0YXRpYyB2b2lkIGZpbmFsX2NoZWNrKHVuc2lnbmVkIGludCBmbGFncykKewp9CgpzdGF0aWMgc3RydWN0IHJhdGVzCnsKCWNvbnN0IGNoYXIgKm5hbWU7Cgl1X2ludDMyX3QgbXVsdDsKfSByYXRlc1tdID0geyB7ICJkYXkiLCBJUDZUX0xJTUlUX1NDQUxFKjI0KjYwKjYwIH0sCgkgICAgICB7ICJob3VyIiwgSVA2VF9MSU1JVF9TQ0FMRSo2MCo2MCB9LAoJICAgICAgeyAibWluIiwgSVA2VF9MSU1JVF9TQ0FMRSo2MCB9LAoJICAgICAgeyAic2VjIiwgSVA2VF9MSU1JVF9TQ0FMRSB9IH07CgpzdGF0aWMgdm9pZCBwcmludF9yYXRlKHVfaW50MzJfdCBwZXJpb2QpCnsKCXVuc2lnbmVkIGludCBpOwoKCWZvciAoaSA9IDE7IGkgPCBzaXplb2YocmF0ZXMpL3NpemVvZihzdHJ1Y3QgcmF0ZXMpOyBpKyspIHsKCQlpZiAocGVyaW9kID4gcmF0ZXNbaV0ubXVsdAoJCSAgICB8fCByYXRlc1tpXS5tdWx0ICUgcGVyaW9kICE9IDApCgkJCWJyZWFrOwoJfQoKCXByaW50ZigiJXUvJXMgIiwgcmF0ZXNbaS0xXS5tdWx0IC8gcGVyaW9kLCByYXRlc1tpLTFdLm5hbWUpOwp9CgovKiBQcmludHMgb3V0IHRoZSBtYXRjaGluZm8uICovCnN0YXRpYyB2b2lkCnByaW50KGNvbnN0IHN0cnVjdCBpcDZ0X2lwNiAqaXAsCiAgICAgIGNvbnN0IHN0cnVjdCBpcDZ0X2VudHJ5X21hdGNoICptYXRjaCwKICAgICAgaW50IG51bWVyaWMpCnsKCXN0cnVjdCBpcDZ0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcDZ0X3JhdGVpbmZvICopbWF0Y2gtPmRhdGE7CglwcmludGYoImxpbWl0OiBhdmcgIik7IHByaW50X3JhdGUoci0+YXZnKTsKCXByaW50ZigiYnVyc3QgJXUgIiwgci0+YnVyc3QpOwp9CgovKiBGSVhNRTogTWFrZSBtaW5pbWFsaXN0OiBvbmx5IHByaW50IHJhdGUgaWYgbm90IGRlZmF1bHQgLS1SUiAqLwpzdGF0aWMgdm9pZCBzYXZlKGNvbnN0IHN0cnVjdCBpcDZ0X2lwNiAqaXAsIGNvbnN0IHN0cnVjdCBpcDZ0X2VudHJ5X21hdGNoICptYXRjaCkKewoJc3RydWN0IGlwNnRfcmF0ZWluZm8gKnIgPSAoc3RydWN0IGlwNnRfcmF0ZWluZm8gKiltYXRjaC0+ZGF0YTsKCglwcmludGYoIi0tbGltaXQgIik7IHByaW50X3JhdGUoci0+YXZnKTsKCWlmIChyLT5idXJzdCAhPSBJUDZUX0xJTUlUX0JVUlNUKQoJCXByaW50ZigiLS1saW1pdC1idXJzdCAldSAiLCByLT5idXJzdCk7Cn0KCnN0cnVjdCBpcDZ0YWJsZXNfbWF0Y2ggbGltaXQKPSB7IE5VTEwsCiAgICAibGltaXQiLAogICAgTkVURklMVEVSX1ZFUlNJT04sCiAgICBJUDZUX0FMSUdOKHNpemVvZihzdHJ1Y3QgaXA2dF9yYXRlaW5mbykpLAogICAgb2Zmc2V0b2Yoc3RydWN0IGlwNnRfcmF0ZWluZm8sIHByZXYpLAogICAgJmhlbHAsCiAgICAmaW5pdCwKICAgICZwYXJzZSwKICAgICZmaW5hbF9jaGVjaywKICAgICZwcmludCwKICAgICZzYXZlLAogICAgb3B0cwp9OwoKdm9pZCBfaW5pdCh2b2lkKQp7CglyZWdpc3Rlcl9tYXRjaDYoJmxpbWl0KTsKfQo=