LyogU2hhcmVkIGxpYnJhcnkgYWRkLW9uIHRvIGlwdGFibGVzIHRvIGFkZCBsaW1pdCBzdXBwb3J0LgogKgogKiBK6XL0bWUgZGUgVml2aWUgICA8ZGV2aXZpZUBpbmZvLmVuc2VyYi51LWJvcmRlYXV4LmZyPgogKiBIZXJ26SBFeWNoZW5uZSAgICA8cnZAd2FsbGZpcmUub3JnPgogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPGdldG9wdC5oPgojaW5jbHVkZSA8aXB0YWJsZXMuaD4KI2luY2x1ZGUgPHN0ZGRlZi5oPgojaW5jbHVkZSA8bGludXgvbmV0ZmlsdGVyX2lwdjQvaXBfdGFibGVzLmg+Ci8qIEZvciA2NGJpdCBrZXJuZWwgLyAzMmJpdCB1c2Vyc3BhY2UgKi8KI2luY2x1ZGUgIi4uL2luY2x1ZGUvbGludXgvbmV0ZmlsdGVyX2lwdjQvaXB0X2xpbWl0LmgiCgojZGVmaW5lIElQVF9MSU1JVF9BVkcJIjMvaG91ciIKI2RlZmluZSBJUFRfTElNSVRfQlVSU1QJNQoKLyogRnVuY3Rpb24gd2hpY2ggcHJpbnRzIG91dCB1c2FnZSBtZXNzYWdlLiAqLwpzdGF0aWMgdm9pZApoZWxwKHZvaWQpCnsKCXByaW50ZigKImxpbWl0IHYlcyBvcHRpb25zOlxuIgoiLS1saW1pdCBhdmcJCQltYXggYXZlcmFnZSBtYXRjaCByYXRlOiBkZWZhdWx0ICJJUFRfTElNSVRfQVZHIlxuIgoiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbUGFja2V0cyBwZXIgc2Vjb25kIHVubGVzcyBmb2xsb3dlZCBieSBcbiIKIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL3NlYyAvbWludXRlIC9ob3VyIC9kYXkgcG9zdGZpeGVzXVxuIgoiLS1saW1pdC1idXJzdCBudW1iZXIJCW51bWJlciB0byBtYXRjaCBpbiBhIGJ1cnN0LCBkZWZhdWx0ICV1XG4iCiJcbiIsIElQVEFCTEVTX1ZFUlNJT04sIElQVF9MSU1JVF9CVVJTVCk7Cn0KCnN0YXRpYyBzdHJ1Y3Qgb3B0aW9uIG9wdHNbXSA9IHsKCXsgImxpbWl0IiwgMSwgMCwgJyUnIH0sCgl7ICJsaW1pdC1idXJzdCIsIDEsIDAsICckJyB9LAoJeyAwIH0KfTsKCnN0YXRpYwppbnQgcGFyc2VfcmF0ZShjb25zdCBjaGFyICpyYXRlLCB1X2ludDMyX3QgKnZhbCkKewoJY29uc3QgY2hhciAqZGVsaW07Cgl1X2ludDMyX3QgcjsKCXVfaW50MzJfdCBtdWx0ID0gMTsgIC8qIFNlY29uZHMgYnkgZGVmYXVsdC4gKi8KCglkZWxpbSA9IHN0cmNocihyYXRlLCAnLycpOwoJaWYgKGRlbGltKSB7CgkJaWYgKHN0cmxlbihkZWxpbSsxKSA9PSAwKQoJCQlyZXR1cm4gMDsKCgkJaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJzZWNvbmQiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSAxOwoJCWVsc2UgaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJtaW51dGUiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSA2MDsKCQllbHNlIGlmIChzdHJuY2FzZWNtcChkZWxpbSsxLCAiaG91ciIsIHN0cmxlbihkZWxpbSsxKSkgPT0gMCkKCQkJbXVsdCA9IDYwKjYwOwoJCWVsc2UgaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJkYXkiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSAyNCo2MCo2MDsKCQllbHNlCgkJCXJldHVybiAwOwoJfQoJciA9IGF0b2kocmF0ZSk7CglpZiAoIXIpCgkJcmV0dXJuIDA7CgoJLyogVGhpcyB3b3VsZCBnZXQgbWFwcGVkIHRvIGluZmluaXRlICgxL2RheSBpcyBtaW5pbXVtIHRoZXkKICAgICAgICAgICBjYW4gc3BlY2lmeSwgc28gd2UncmUgb2sgYXQgdGhhdCBlbmQpLiAqLwoJaWYgKHIgLyBtdWx0ID4gSVBUX0xJTUlUX1NDQUxFKQoJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sICJSYXRlIHRvbyBmYXN0IGAlcydcbiIsIHJhdGUpOwoKCSp2YWwgPSBJUFRfTElNSVRfU0NBTEUgKiBtdWx0IC8gcjsKCXJldHVybiAxOwp9CgovKiBJbml0aWFsaXplIHRoZSBtYXRjaC4gKi8Kc3RhdGljIHZvaWQKaW5pdChzdHJ1Y3QgaXB0X2VudHJ5X21hdGNoICptLCB1bnNpZ25lZCBpbnQgKm5mY2FjaGUpCnsKCXN0cnVjdCBpcHRfcmF0ZWluZm8gKnIgPSAoc3RydWN0IGlwdF9yYXRlaW5mbyAqKW0tPmRhdGE7CgoJcGFyc2VfcmF0ZShJUFRfTElNSVRfQVZHLCAmci0+YXZnKTsKCXItPmJ1cnN0ID0gSVBUX0xJTUlUX0JVUlNUOwoKfQoKLyogRklYTUU6IGhhbmRsZSBvdmVyZmxvdzoKCWlmIChyLT5hdmcqci0+YnVyc3Qvci0+YnVyc3QgIT0gci0+YXZnKQoJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCSAgICJTb3JyeTogYnVyc3QgdG9vIGxhcmdlIGZvciB0aGF0IGF2ZyByYXRlLlxuIik7CiovCgovKiBGdW5jdGlvbiB3aGljaCBwYXJzZXMgY29tbWFuZCBvcHRpb25zOyByZXR1cm5zIHRydWUgaWYgaXQKICAgYXRlIGFuIG9wdGlvbiAqLwpzdGF0aWMgaW50CnBhcnNlKGludCBjLCBjaGFyICoqYXJndiwgaW50IGludmVydCwgdW5zaWduZWQgaW50ICpmbGFncywKICAgICAgY29uc3Qgc3RydWN0IGlwdF9lbnRyeSAqZW50cnksCiAgICAgIHVuc2lnbmVkIGludCAqbmZjYWNoZSwKICAgICAgc3RydWN0IGlwdF9lbnRyeV9tYXRjaCAqKm1hdGNoKQp7CglzdHJ1Y3QgaXB0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcHRfcmF0ZWluZm8gKikoKm1hdGNoKS0+ZGF0YTsKCXVuc2lnbmVkIGludCBudW07CgoJc3dpdGNoKGMpIHsKCWNhc2UgJyUnOgoJCWlmIChjaGVja19pbnZlcnNlKGFyZ3Zbb3B0aW5kLTFdLCAmaW52ZXJ0LCAmb3B0aW5kLCAwKSkgYnJlYWs7CgkJaWYgKCFwYXJzZV9yYXRlKG9wdGFyZywgJnItPmF2ZykpCgkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkgICAiYmFkIHJhdGUgYCVzJyIsIG9wdGFyZyk7CgkJYnJlYWs7CgoJY2FzZSAnJCc6CgkJaWYgKGNoZWNrX2ludmVyc2UoYXJndltvcHRpbmQtMV0sICZpbnZlcnQsICZvcHRpbmQsIDApKSBicmVhazsKCQlpZiAoc3RyaW5nX3RvX251bWJlcihvcHRhcmcsIDAsIDEwMDAwLCAmbnVtKSA9PSAtMSkKCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCSAgICJiYWQgLS1saW1pdC1idXJzdCBgJXMnIiwgb3B0YXJnKTsKCQlyLT5idXJzdCA9IG51bTsKCQlicmVhazsKCglkZWZhdWx0OgoJCXJldHVybiAwOwoJfQoKCWlmIChpbnZlcnQpCgkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJICAgImxpbWl0IGRvZXMgbm90IHN1cHBvcnQgaW52ZXJ0Iik7CgoJcmV0dXJuIDE7Cn0KCi8qIEZpbmFsIGNoZWNrOyBub3RoaW5nLiAqLwpzdGF0aWMgdm9pZCBmaW5hbF9jaGVjayh1bnNpZ25lZCBpbnQgZmxhZ3MpCnsKfQoKc3RhdGljIHN0cnVjdCByYXRlcwp7Cgljb25zdCBjaGFyICpuYW1lOwoJdV9pbnQzMl90IG11bHQ7Cn0gcmF0ZXNbXSA9IHsgeyAiZGF5IiwgSVBUX0xJTUlUX1NDQUxFKjI0KjYwKjYwIH0sCgkgICAgICB7ICJob3VyIiwgSVBUX0xJTUlUX1NDQUxFKjYwKjYwIH0sCgkgICAgICB7ICJtaW4iLCBJUFRfTElNSVRfU0NBTEUqNjAgfSwKCSAgICAgIHsgInNlYyIsIElQVF9MSU1JVF9TQ0FMRSB9IH07CgpzdGF0aWMgdm9pZCBwcmludF9yYXRlKHVfaW50MzJfdCBwZXJpb2QpCnsKCXVuc2lnbmVkIGludCBpOwoKCWZvciAoaSA9IDE7IGkgPCBzaXplb2YocmF0ZXMpL3NpemVvZihzdHJ1Y3QgcmF0ZXMpOyBpKyspIHsKCQlpZiAocGVyaW9kID4gcmF0ZXNbaV0ubXVsdAogICAgICAgICAgICB8fCByYXRlc1tpXS5tdWx0L3BlcmlvZCA8IHJhdGVzW2ldLm11bHQlcGVyaW9kKQoJCQlicmVhazsKCX0KCglwcmludGYoIiV1LyVzICIsIHJhdGVzW2ktMV0ubXVsdCAvIHBlcmlvZCwgcmF0ZXNbaS0xXS5uYW1lKTsKfQoKLyogUHJpbnRzIG91dCB0aGUgbWF0Y2hpbmZvLiAqLwpzdGF0aWMgdm9pZApwcmludChjb25zdCBzdHJ1Y3QgaXB0X2lwICppcCwKICAgICAgY29uc3Qgc3RydWN0IGlwdF9lbnRyeV9tYXRjaCAqbWF0Y2gsCiAgICAgIGludCBudW1lcmljKQp7CglzdHJ1Y3QgaXB0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcHRfcmF0ZWluZm8gKiltYXRjaC0+ZGF0YTsKCXByaW50ZigibGltaXQ6IGF2ZyAiKTsgcHJpbnRfcmF0ZShyLT5hdmcpOwoJcHJpbnRmKCJidXJzdCAldSAiLCByLT5idXJzdCk7Cn0KCi8qIEZJWE1FOiBNYWtlIG1pbmltYWxpc3Q6IG9ubHkgcHJpbnQgcmF0ZSBpZiBub3QgZGVmYXVsdCAtLVJSICovCnN0YXRpYyB2b2lkIHNhdmUoY29uc3Qgc3RydWN0IGlwdF9pcCAqaXAsIGNvbnN0IHN0cnVjdCBpcHRfZW50cnlfbWF0Y2ggKm1hdGNoKQp7CglzdHJ1Y3QgaXB0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcHRfcmF0ZWluZm8gKiltYXRjaC0+ZGF0YTsKCglwcmludGYoIi0tbGltaXQgIik7IHByaW50X3JhdGUoci0+YXZnKTsKCWlmIChyLT5idXJzdCAhPSBJUFRfTElNSVRfQlVSU1QpCgkJcHJpbnRmKCItLWxpbWl0LWJ1cnN0ICV1ICIsIHItPmJ1cnN0KTsKfQoKc3RhdGljIHN0cnVjdCBpcHRhYmxlc19tYXRjaCBsaW1pdCA9IHsgCgkubmV4dAkJPSBOVUxMLAoJLm5hbWUJCT0gImxpbWl0IiwKCS52ZXJzaW9uCT0gSVBUQUJMRVNfVkVSU0lPTiwKCS5zaXplCQk9IElQVF9BTElHTihzaXplb2Yoc3RydWN0IGlwdF9yYXRlaW5mbykpLAoJLnVzZXJzcGFjZXNpemUJPSBvZmZzZXRvZihzdHJ1Y3QgaXB0X3JhdGVpbmZvLCBwcmV2KSwKCS5oZWxwCQk9ICZoZWxwLAoJLmluaXQJCT0gJmluaXQsCgkucGFyc2UJCT0gJnBhcnNlLAoJLmZpbmFsX2NoZWNrCT0gJmZpbmFsX2NoZWNrLAoJLnByaW50CQk9ICZwcmludCwKCS5zYXZlCQk9ICZzYXZlLAoJLmV4dHJhX29wdHMJPSBvcHRzCn07Cgp2b2lkIF9pbml0KHZvaWQpCnsKCXJlZ2lzdGVyX21hdGNoKCZsaW1pdCk7Cn0K