LyogU2hhcmVkIGxpYnJhcnkgYWRkLW9uIHRvIGlwdGFibGVzIHRvIGFkZCBsaW1pdCBzdXBwb3J0LgogKgogKiBK6XL0bWUgZGUgVml2aWUgICA8ZGV2aXZpZUBpbmZvLmVuc2VyYi51LWJvcmRlYXV4LmZyPgogKiBIZXJ26SBFeWNoZW5uZSAgICA8cnZAd2FsbGZpcmUub3JnPgogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPGdldG9wdC5oPgojaW5jbHVkZSA8aXA2dGFibGVzLmg+CiNpbmNsdWRlIDxzdGRkZWYuaD4KI2luY2x1ZGUgPGxpbnV4L25ldGZpbHRlcl9pcHY2L2lwNl90YWJsZXMuaD4KI2luY2x1ZGUgPGxpbnV4L25ldGZpbHRlcl9pcHY2L2lwNnRfbGltaXQuaD4KCiNkZWZpbmUgSVA2VF9MSU1JVF9BVkcJIjMvaG91ciIKI2RlZmluZSBJUDZUX0xJTUlUX0JVUlNUCTUKCi8qIEZ1bmN0aW9uIHdoaWNoIHByaW50cyBvdXQgdXNhZ2UgbWVzc2FnZS4gKi8Kc3RhdGljIHZvaWQKaGVscCh2b2lkKQp7CglwcmludGYoCiJsaW1pdCB2JXMgb3B0aW9uczpcbiIKIi0tbGltaXQgYXZnCQkJbWF4IGF2ZXJhZ2UgbWF0Y2ggcmF0ZTogZGVmYXVsdCAiSVA2VF9MSU1JVF9BVkciXG4iCiIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtQYWNrZXRzIHBlciBzZWNvbmQgdW5sZXNzIGZvbGxvd2VkIGJ5IFxuIgoiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvc2VjIC9taW51dGUgL2hvdXIgL2RheSBwb3N0Zml4ZXNdXG4iCiItLWxpbWl0LWJ1cnN0IG51bWJlcgkJbnVtYmVyIHRvIG1hdGNoIGluIGEgYnVyc3QsIGRlZmF1bHQgJXVcbiIKIlxuIiwgTkVURklMVEVSX1ZFUlNJT04sIElQNlRfTElNSVRfQlVSU1QpOwp9CgpzdGF0aWMgc3RydWN0IG9wdGlvbiBvcHRzW10gPSB7Cgl7ICJsaW1pdCIsIDEsIDAsICclJyB9LAoJeyAibGltaXQtYnVyc3QiLCAxLCAwLCAnJCcgfSwKCXsgMCB9Cn07CgpzdGF0aWMKaW50IHBhcnNlX3JhdGUoY29uc3QgY2hhciAqcmF0ZSwgdV9pbnQzMl90ICp2YWwpCnsKCWNvbnN0IGNoYXIgKmRlbGltOwoJdV9pbnQzMl90IHI7Cgl1X2ludDMyX3QgbXVsdCA9IDE7ICAvKiBTZWNvbmRzIGJ5IGRlZmF1bHQuICovCgoJZGVsaW0gPSBzdHJjaHIocmF0ZSwgJy8nKTsKCWlmIChkZWxpbSkgewoJCWlmIChzdHJsZW4oZGVsaW0rMSkgPT0gMCkKCQkJcmV0dXJuIDA7CgoJCWlmIChzdHJuY2FzZWNtcChkZWxpbSsxLCAic2Vjb25kIiwgc3RybGVuKGRlbGltKzEpKSA9PSAwKQoJCQltdWx0ID0gMTsKCQllbHNlIGlmIChzdHJuY2FzZWNtcChkZWxpbSsxLCAibWludXRlIiwgc3RybGVuKGRlbGltKzEpKSA9PSAwKQoJCQltdWx0ID0gNjA7CgkJZWxzZSBpZiAoc3RybmNhc2VjbXAoZGVsaW0rMSwgImhvdXIiLCBzdHJsZW4oZGVsaW0rMSkpID09IDApCgkJCW11bHQgPSA2MCo2MDsKCQllbHNlIGlmIChzdHJuY2FzZWNtcChkZWxpbSsxLCAiZGF5Iiwgc3RybGVuKGRlbGltKzEpKSA9PSAwKQoJCQltdWx0ID0gMjQqNjAqNjA7CgkJZWxzZQoJCQlyZXR1cm4gMDsKCX0KCXIgPSBhdG9pKHJhdGUpOwoJaWYgKCFyKQoJCXJldHVybiAwOwoKCS8qIFRoaXMgd291bGQgZ2V0IG1hcHBlZCB0byBpbmZpbml0ZSAoMS9kYXkgaXMgbWluaW11bSB0aGV5CiAgICAgICAgICAgY2FuIHNwZWNpZnksIHNvIHdlJ3JlIG9rIGF0IHRoYXQgZW5kKS4gKi8KCWlmIChyIC8gbXVsdCA+IElQNlRfTElNSVRfU0NBTEUpCgkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwgIlJhdGUgdG9vIGZhc3QgYCVzJ1xuIiwgcmF0ZSk7CgoJKnZhbCA9IElQNlRfTElNSVRfU0NBTEUgKiBtdWx0IC8gcjsKCXJldHVybiAxOwp9CgovKiBJbml0aWFsaXplIHRoZSBtYXRjaC4gKi8Kc3RhdGljIHZvaWQKaW5pdChzdHJ1Y3QgaXA2dF9lbnRyeV9tYXRjaCAqbSwgdW5zaWduZWQgaW50ICpuZmNhY2hlKQp7CglzdHJ1Y3QgaXA2dF9yYXRlaW5mbyAqciA9IChzdHJ1Y3QgaXA2dF9yYXRlaW5mbyAqKW0tPmRhdGE7CgoJcGFyc2VfcmF0ZShJUDZUX0xJTUlUX0FWRywgJnItPmF2Zyk7CglyLT5idXJzdCA9IElQNlRfTElNSVRfQlVSU1Q7CgoJLyogQ2FuJ3QgY2FjaGUgdGhpcyAqLwoJKm5mY2FjaGUgfD0gTkZDX1VOS05PV047Cn0KCi8qIEZJWE1FOiBoYW5kbGUgb3ZlcmZsb3c6CglpZiAoci0+YXZnKnItPmJ1cnN0L3ItPmJ1cnN0ICE9IHItPmF2ZykKCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkgICAiU29ycnk6IGJ1cnN0IHRvbyBsYXJnZSBmb3IgdGhhdCBhdmcgcmF0ZS5cbiIpOwoqLwoKLyogRnVuY3Rpb24gd2hpY2ggcGFyc2VzIGNvbW1hbmQgb3B0aW9uczsgcmV0dXJucyB0cnVlIGlmIGl0CiAgIGF0ZSBhbiBvcHRpb24gKi8Kc3RhdGljIGludApwYXJzZShpbnQgYywgY2hhciAqKmFyZ3YsIGludCBpbnZlcnQsIHVuc2lnbmVkIGludCAqZmxhZ3MsCiAgICAgIGNvbnN0IHN0cnVjdCBpcDZ0X2VudHJ5ICplbnRyeSwKICAgICAgdW5zaWduZWQgaW50ICpuZmNhY2hlLAogICAgICBzdHJ1Y3QgaXA2dF9lbnRyeV9tYXRjaCAqKm1hdGNoKQp7CglzdHJ1Y3QgaXA2dF9yYXRlaW5mbyAqciA9IChzdHJ1Y3QgaXA2dF9yYXRlaW5mbyAqKSgqbWF0Y2gpLT5kYXRhOwoJdW5zaWduZWQgaW50IG51bTsKCglzd2l0Y2goYykgewoJY2FzZSAnJSc6CgkJaWYgKGNoZWNrX2ludmVyc2Uob3B0YXJnLCAmaW52ZXJ0LCBOVUxMLCAwKSkKCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCSAgICJVbmV4cGVjdGVkIGAhJyBhZnRlciAtLWxpbWl0Iik7CgkJaWYgKCFwYXJzZV9yYXRlKG9wdGFyZywgJnItPmF2ZykpCgkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkgICAiYmFkIHJhdGUgYCVzJyIsIG9wdGFyZyk7CgkJYnJlYWs7CgoJY2FzZSAnJCc6CgkJaWYgKGNoZWNrX2ludmVyc2Uob3B0YXJnLCAmaW52ZXJ0LCBOVUxMLCAwKSkKCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCSAgICJVbmV4cGVjdGVkIGAhJyBhZnRlciAtLWxpbWl0LWJ1cnN0Iik7CgoJCWlmIChzdHJpbmdfdG9fbnVtYmVyKG9wdGFyZywgMCwgMTAwMDAsICZudW0pID09IC0xKQoJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJICAgImJhZCAtLWxpbWl0LWJ1cnN0IGAlcyciLCBvcHRhcmcpOwoJCXItPmJ1cnN0ID0gbnVtOwoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJcmV0dXJuIDA7Cgl9CgoJcmV0dXJuIDE7Cn0KCi8qIEZpbmFsIGNoZWNrOyBub3RoaW5nLiAqLwpzdGF0aWMgdm9pZCBmaW5hbF9jaGVjayh1bnNpZ25lZCBpbnQgZmxhZ3MpCnsKfQoKc3RhdGljIHN0cnVjdCByYXRlcwp7Cgljb25zdCBjaGFyICpuYW1lOwoJdV9pbnQzMl90IG11bHQ7Cn0gcmF0ZXNbXSA9IHsgeyAiZGF5IiwgSVA2VF9MSU1JVF9TQ0FMRSoyNCo2MCo2MCB9LAoJICAgICAgeyAiaG91ciIsIElQNlRfTElNSVRfU0NBTEUqNjAqNjAgfSwKCSAgICAgIHsgIm1pbiIsIElQNlRfTElNSVRfU0NBTEUqNjAgfSwKCSAgICAgIHsgInNlYyIsIElQNlRfTElNSVRfU0NBTEUgfSB9OwoKc3RhdGljIHZvaWQgcHJpbnRfcmF0ZSh1X2ludDMyX3QgcGVyaW9kKQp7Cgl1bnNpZ25lZCBpbnQgaTsKCglmb3IgKGkgPSAxOyBpIDwgc2l6ZW9mKHJhdGVzKS9zaXplb2Yoc3RydWN0IHJhdGVzKTsgaSsrKSB7CgkJaWYgKHBlcmlvZCA+IHJhdGVzW2ldLm11bHQKCQkgICAgfHwgcmF0ZXNbaV0ubXVsdCAlIHBlcmlvZCAhPSAwKQoJCQlicmVhazsKCX0KCglwcmludGYoIiV1LyVzICIsIHJhdGVzW2ktMV0ubXVsdCAvIHBlcmlvZCwgcmF0ZXNbaS0xXS5uYW1lKTsKfQoKLyogUHJpbnRzIG91dCB0aGUgbWF0Y2hpbmZvLiAqLwpzdGF0aWMgdm9pZApwcmludChjb25zdCBzdHJ1Y3QgaXA2dF9pcDYgKmlwLAogICAgICBjb25zdCBzdHJ1Y3QgaXA2dF9lbnRyeV9tYXRjaCAqbWF0Y2gsCiAgICAgIGludCBudW1lcmljKQp7CglzdHJ1Y3QgaXA2dF9yYXRlaW5mbyAqciA9IChzdHJ1Y3QgaXA2dF9yYXRlaW5mbyAqKW1hdGNoLT5kYXRhOwoJcHJpbnRmKCJsaW1pdDogYXZnICIpOyBwcmludF9yYXRlKHItPmF2Zyk7CglwcmludGYoImJ1cnN0ICV1ICIsIHItPmJ1cnN0KTsKfQoKLyogRklYTUU6IE1ha2UgbWluaW1hbGlzdDogb25seSBwcmludCByYXRlIGlmIG5vdCBkZWZhdWx0IC0tUlIgKi8Kc3RhdGljIHZvaWQgc2F2ZShjb25zdCBzdHJ1Y3QgaXA2dF9pcDYgKmlwLCBjb25zdCBzdHJ1Y3QgaXA2dF9lbnRyeV9tYXRjaCAqbWF0Y2gpCnsKCXN0cnVjdCBpcDZ0X3JhdGVpbmZvICpyID0gKHN0cnVjdCBpcDZ0X3JhdGVpbmZvICopbWF0Y2gtPmRhdGE7CgoJcHJpbnRmKCItLWxpbWl0ICIpOyBwcmludF9yYXRlKHItPmF2Zyk7CglpZiAoci0+YnVyc3QgIT0gSVA2VF9MSU1JVF9CVVJTVCkKCQlwcmludGYoIi0tbGltaXQtYnVyc3QgJXUgIiwgci0+YnVyc3QpOwp9CgpzdGF0aWMKc3RydWN0IGlwNnRhYmxlc19tYXRjaCBsaW1pdAo9IHsgTlVMTCwKICAgICJsaW1pdCIsCiAgICBORVRGSUxURVJfVkVSU0lPTiwKICAgIElQNlRfQUxJR04oc2l6ZW9mKHN0cnVjdCBpcDZ0X3JhdGVpbmZvKSksCiAgICBvZmZzZXRvZihzdHJ1Y3QgaXA2dF9yYXRlaW5mbywgcHJldiksCiAgICAmaGVscCwKICAgICZpbml0LAogICAgJnBhcnNlLAogICAgJmZpbmFsX2NoZWNrLAogICAgJnByaW50LAogICAgJnNhdmUsCiAgICBvcHRzCn07Cgp2b2lkIF9pbml0KHZvaWQpCnsKCXJlZ2lzdGVyX21hdGNoNigmbGltaXQpOwp9Cg==