LyogU2hhcmVkIGxpYnJhcnkgYWRkLW9uIHRvIGlwdGFibGVzIHRvIGFkZCBsaW1pdCBzdXBwb3J0LgogKgogKiBK6XL0bWUgZGUgVml2aWUgICA8ZGV2aXZpZUBpbmZvLmVuc2VyYi51LWJvcmRlYXV4LmZyPgogKiBIZXJ26SBFeWNoZW5uZSAgICA8cnZAd2FsbGZpcmUub3JnPgogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPGdldG9wdC5oPgojaW5jbHVkZSA8aXB0YWJsZXMuaD4KI2luY2x1ZGUgPHN0ZGRlZi5oPgojaW5jbHVkZSA8bGludXgvbmV0ZmlsdGVyX2lwdjQvaXBfdGFibGVzLmg+CiNpbmNsdWRlIDxsaW51eC9uZXRmaWx0ZXJfaXB2NC9pcHRfbGltaXQuaD4KCiNkZWZpbmUgSVBUX0xJTUlUX0FWRwkiMy9ob3VyIgojZGVmaW5lIElQVF9MSU1JVF9CVVJTVAk1CgovKiBGdW5jdGlvbiB3aGljaCBwcmludHMgb3V0IHVzYWdlIG1lc3NhZ2UuICovCnN0YXRpYyB2b2lkCmhlbHAodm9pZCkKewoJcHJpbnRmKAoibGltaXQgdiVzIG9wdGlvbnM6XG4iCiItLWxpbWl0IGF2ZwkJCW1heCBhdmVyYWdlIG1hdGNoIHJhdGU6IGRlZmF1bHQgIklQVF9MSU1JVF9BVkciXG4iCiIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtQYWNrZXRzIHBlciBzZWNvbmQgdW5sZXNzIGZvbGxvd2VkIGJ5IFxuIgoiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvc2VjIC9taW51dGUgL2hvdXIgL2RheSBwb3N0Zml4ZXNdXG4iCiItLWxpbWl0LWJ1cnN0IG51bWJlcgkJbnVtYmVyIHRvIG1hdGNoIGluIGEgYnVyc3QsIGRlZmF1bHQgJXVcbiIKIlxuIiwgSVBUQUJMRVNfVkVSU0lPTiwgSVBUX0xJTUlUX0JVUlNUKTsKfQoKc3RhdGljIHN0cnVjdCBvcHRpb24gb3B0c1tdID0gewoJeyAibGltaXQiLCAxLCAwLCAnJScgfSwKCXsgImxpbWl0LWJ1cnN0IiwgMSwgMCwgJyQnIH0sCgl7IDAgfQp9OwoKc3RhdGljCmludCBwYXJzZV9yYXRlKGNvbnN0IGNoYXIgKnJhdGUsIHVfaW50MzJfdCAqdmFsKQp7Cgljb25zdCBjaGFyICpkZWxpbTsKCXVfaW50MzJfdCByOwoJdV9pbnQzMl90IG11bHQgPSAxOyAgLyogU2Vjb25kcyBieSBkZWZhdWx0LiAqLwoKCWRlbGltID0gc3RyY2hyKHJhdGUsICcvJyk7CglpZiAoZGVsaW0pIHsKCQlpZiAoc3RybGVuKGRlbGltKzEpID09IDApCgkJCXJldHVybiAwOwoKCQlpZiAoc3RybmNhc2VjbXAoZGVsaW0rMSwgInNlY29uZCIsIHN0cmxlbihkZWxpbSsxKSkgPT0gMCkKCQkJbXVsdCA9IDE7CgkJZWxzZSBpZiAoc3RybmNhc2VjbXAoZGVsaW0rMSwgIm1pbnV0ZSIsIHN0cmxlbihkZWxpbSsxKSkgPT0gMCkKCQkJbXVsdCA9IDYwOwoJCWVsc2UgaWYgKHN0cm5jYXNlY21wKGRlbGltKzEsICJob3VyIiwgc3RybGVuKGRlbGltKzEpKSA9PSAwKQoJCQltdWx0ID0gNjAqNjA7CgkJZWxzZSBpZiAoc3RybmNhc2VjbXAoZGVsaW0rMSwgImRheSIsIHN0cmxlbihkZWxpbSsxKSkgPT0gMCkKCQkJbXVsdCA9IDI0KjYwKjYwOwoJCWVsc2UKCQkJcmV0dXJuIDA7Cgl9CglyID0gYXRvaShyYXRlKTsKCWlmICghcikKCQlyZXR1cm4gMDsKCgkvKiBUaGlzIHdvdWxkIGdldCBtYXBwZWQgdG8gaW5maW5pdGUgKDEvZGF5IGlzIG1pbmltdW0gdGhleQogICAgICAgICAgIGNhbiBzcGVjaWZ5LCBzbyB3ZSdyZSBvayBhdCB0aGF0IGVuZCkuICovCglpZiAociAvIG11bHQgPiBJUFRfTElNSVRfU0NBTEUpCgkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwgIlJhdGUgdG9vIGZhc3QgYCVzJ1xuIiwgcmF0ZSk7CgoJKnZhbCA9IElQVF9MSU1JVF9TQ0FMRSAqIG11bHQgLyByOwoJcmV0dXJuIDE7Cn0KCi8qIEluaXRpYWxpemUgdGhlIG1hdGNoLiAqLwpzdGF0aWMgdm9pZAppbml0KHN0cnVjdCBpcHRfZW50cnlfbWF0Y2ggKm0sIHVuc2lnbmVkIGludCAqbmZjYWNoZSkKewoJc3RydWN0IGlwdF9yYXRlaW5mbyAqciA9IChzdHJ1Y3QgaXB0X3JhdGVpbmZvICopbS0+ZGF0YTsKCglwYXJzZV9yYXRlKElQVF9MSU1JVF9BVkcsICZyLT5hdmcpOwoJci0+YnVyc3QgPSBJUFRfTElNSVRfQlVSU1Q7CgoJLyogQ2FuJ3QgY2FjaGUgdGhpcyAqLwoJKm5mY2FjaGUgfD0gTkZDX1VOS05PV047Cn0KCi8qIEZJWE1FOiBoYW5kbGUgb3ZlcmZsb3c6CglpZiAoci0+YXZnKnItPmJ1cnN0L3ItPmJ1cnN0ICE9IHItPmF2ZykKCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkgICAiU29ycnk6IGJ1cnN0IHRvbyBsYXJnZSBmb3IgdGhhdCBhdmcgcmF0ZS5cbiIpOwoqLwoKLyogRnVuY3Rpb24gd2hpY2ggcGFyc2VzIGNvbW1hbmQgb3B0aW9uczsgcmV0dXJucyB0cnVlIGlmIGl0CiAgIGF0ZSBhbiBvcHRpb24gKi8Kc3RhdGljIGludApwYXJzZShpbnQgYywgY2hhciAqKmFyZ3YsIGludCBpbnZlcnQsIHVuc2lnbmVkIGludCAqZmxhZ3MsCiAgICAgIGNvbnN0IHN0cnVjdCBpcHRfZW50cnkgKmVudHJ5LAogICAgICB1bnNpZ25lZCBpbnQgKm5mY2FjaGUsCiAgICAgIHN0cnVjdCBpcHRfZW50cnlfbWF0Y2ggKiptYXRjaCkKewoJc3RydWN0IGlwdF9yYXRlaW5mbyAqciA9IChzdHJ1Y3QgaXB0X3JhdGVpbmZvICopKCptYXRjaCktPmRhdGE7Cgl1bnNpZ25lZCBpbnQgbnVtOwoKCXN3aXRjaChjKSB7CgljYXNlICclJzoKCQlpZiAoY2hlY2tfaW52ZXJzZShvcHRhcmcsICZpbnZlcnQsIE5VTEwsIDApKQoJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJICAgIlVuZXhwZWN0ZWQgYCEnIGFmdGVyIC0tbGltaXQiKTsKCQlpZiAoIXBhcnNlX3JhdGUob3B0YXJnLCAmci0+YXZnKSkKCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCSAgICJiYWQgcmF0ZSBgJXMnIiwgb3B0YXJnKTsKCQlicmVhazsKCgljYXNlICckJzoKCQlpZiAoY2hlY2tfaW52ZXJzZShvcHRhcmcsICZpbnZlcnQsIE5VTEwsIDApKQoJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJICAgIlVuZXhwZWN0ZWQgYCEnIGFmdGVyIC0tbGltaXQtYnVyc3QiKTsKCgkJaWYgKHN0cmluZ190b19udW1iZXIob3B0YXJnLCAwLCAxMDAwMCwgJm51bSkgPT0gLTEpCgkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkgICAiYmFkIC0tbGltaXQtYnVyc3QgYCVzJyIsIG9wdGFyZyk7CgkJci0+YnVyc3QgPSBudW07CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlyZXR1cm4gMDsKCX0KCglyZXR1cm4gMTsKfQoKLyogRmluYWwgY2hlY2s7IG5vdGhpbmcuICovCnN0YXRpYyB2b2lkIGZpbmFsX2NoZWNrKHVuc2lnbmVkIGludCBmbGFncykKewp9CgpzdGF0aWMgc3RydWN0IHJhdGVzCnsKCWNvbnN0IGNoYXIgKm5hbWU7Cgl1X2ludDMyX3QgbXVsdDsKfSByYXRlc1tdID0geyB7ICJkYXkiLCBJUFRfTElNSVRfU0NBTEUqMjQqNjAqNjAgfSwKCSAgICAgIHsgImhvdXIiLCBJUFRfTElNSVRfU0NBTEUqNjAqNjAgfSwKCSAgICAgIHsgIm1pbiIsIElQVF9MSU1JVF9TQ0FMRSo2MCB9LAoJICAgICAgeyAic2VjIiwgSVBUX0xJTUlUX1NDQUxFIH0gfTsKCnN0YXRpYyB2b2lkIHByaW50X3JhdGUodV9pbnQzMl90IHBlcmlvZCkKewoJdW5zaWduZWQgaW50IGk7CgoJZm9yIChpID0gMTsgaSA8IHNpemVvZihyYXRlcykvc2l6ZW9mKHN0cnVjdCByYXRlcyk7IGkrKykgewoJCWlmIChwZXJpb2QgPiByYXRlc1tpXS5tdWx0CiAgICAgICAgICAgIHx8IHJhdGVzW2ldLm11bHQvcGVyaW9kIDwgcmF0ZXNbaV0ubXVsdCVwZXJpb2QpCgkJCWJyZWFrOwoJfQoKCXByaW50ZigiJXUvJXMgIiwgcmF0ZXNbaS0xXS5tdWx0IC8gcGVyaW9kLCByYXRlc1tpLTFdLm5hbWUpOwp9CgovKiBQcmludHMgb3V0IHRoZSBtYXRjaGluZm8uICovCnN0YXRpYyB2b2lkCnByaW50KGNvbnN0IHN0cnVjdCBpcHRfaXAgKmlwLAogICAgICBjb25zdCBzdHJ1Y3QgaXB0X2VudHJ5X21hdGNoICptYXRjaCwKICAgICAgaW50IG51bWVyaWMpCnsKCXN0cnVjdCBpcHRfcmF0ZWluZm8gKnIgPSAoc3RydWN0IGlwdF9yYXRlaW5mbyAqKW1hdGNoLT5kYXRhOwoJcHJpbnRmKCJsaW1pdDogYXZnICIpOyBwcmludF9yYXRlKHItPmF2Zyk7CglwcmludGYoImJ1cnN0ICV1ICIsIHItPmJ1cnN0KTsKfQoKLyogRklYTUU6IE1ha2UgbWluaW1hbGlzdDogb25seSBwcmludCByYXRlIGlmIG5vdCBkZWZhdWx0IC0tUlIgKi8Kc3RhdGljIHZvaWQgc2F2ZShjb25zdCBzdHJ1Y3QgaXB0X2lwICppcCwgY29uc3Qgc3RydWN0IGlwdF9lbnRyeV9tYXRjaCAqbWF0Y2gpCnsKCXN0cnVjdCBpcHRfcmF0ZWluZm8gKnIgPSAoc3RydWN0IGlwdF9yYXRlaW5mbyAqKW1hdGNoLT5kYXRhOwoKCXByaW50ZigiLS1saW1pdCAiKTsgcHJpbnRfcmF0ZShyLT5hdmcpOwoJaWYgKHItPmJ1cnN0ICE9IElQVF9MSU1JVF9CVVJTVCkKCQlwcmludGYoIi0tbGltaXQtYnVyc3QgJXUgIiwgci0+YnVyc3QpOwp9CgpzdGF0aWMKc3RydWN0IGlwdGFibGVzX21hdGNoIGxpbWl0Cj0geyBOVUxMLAogICAgImxpbWl0IiwKICAgIElQVEFCTEVTX1ZFUlNJT04sCiAgICBJUFRfQUxJR04oc2l6ZW9mKHN0cnVjdCBpcHRfcmF0ZWluZm8pKSwKICAgIG9mZnNldG9mKHN0cnVjdCBpcHRfcmF0ZWluZm8sIHByZXYpLAogICAgJmhlbHAsCiAgICAmaW5pdCwKICAgICZwYXJzZSwKICAgICZmaW5hbF9jaGVjaywKICAgICZwcmludCwKICAgICZzYXZlLAogICAgb3B0cwp9OwoKdm9pZCBfaW5pdCh2b2lkKQp7CglyZWdpc3Rlcl9tYXRjaCgmbGltaXQpOwp9Cg==