LyogU2hhcmVkIGxpYnJhcnkgYWRkLW9uIHRvIGlwdGFibGVzIHRvIGFkZCBST1VURSB0YXJnZXQgc3VwcG9ydC4KICogQXV0aG9yIDogQ+lkcmljIGRlIExhdW5vaXMsIDxkZWxhdW5vaXNAaW5mby51Y2wuYWMuYmU+CiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8Z2V0b3B0Lmg+CiNpbmNsdWRlIDxpcHRhYmxlcy5oPgojaW5jbHVkZSA8bmV0L2lmLmg+CiNpbmNsdWRlIDxsaW51eC9uZXRmaWx0ZXJfaXB2NC9pcF90YWJsZXMuaD4KI2luY2x1ZGUgPGxpbnV4L25ldGZpbHRlcl9pcHY0L2lwdF9ST1VURS5oPgoKLyogRnVuY3Rpb24gd2hpY2ggcHJpbnRzIG91dCB1c2FnZSBtZXNzYWdlLiAqLwpzdGF0aWMgdm9pZApoZWxwKHZvaWQpCnsKCXByaW50ZigKIlJPVVRFIHRhcmdldCB2JXMgb3B0aW9uczpcbiIKIiAgLS1pZmFjZSAgIG5hbWUgICAgICAgICAgICAgICAgU2VuZCB0aGlzIHBhY2tldCBkaXJlY3RseSB0aHJvdWdoIGlmYWNlIG5hbWUuXG4iCiIgIC0taWZpbmRleCBpbmRleCAgICAgICAgICAgICAgIFNlbmQgdGhpcyBwYWNrZXQgZGlyZWN0bHkgdGhyb3VnaCBpZmFjZSBpbmRleC5cbiIKIlxuIiwKSVBUQUJMRVNfVkVSU0lPTik7Cn0KCnN0YXRpYyBzdHJ1Y3Qgb3B0aW9uIG9wdHNbXSA9IHsKCXsgImlmYWNlIiwgMSwgMCwgJzEnIH0sCgl7ICJpZmluZGV4IiwgMSwgMCwgJzInIH0sCgl7IDAgfQp9OwoKLyogSW5pdGlhbGl6ZSB0aGUgdGFyZ2V0LiAqLwpzdGF0aWMgdm9pZAppbml0KHN0cnVjdCBpcHRfZW50cnlfdGFyZ2V0ICp0LCB1bnNpZ25lZCBpbnQgKm5mY2FjaGUpCnsKfQoKI2RlZmluZSBJUFRfUk9VVEVfT1BUX0lGICAgIDB4MDEKCi8qIEZ1bmN0aW9uIHdoaWNoIHBhcnNlcyBjb21tYW5kIG9wdGlvbnM7IHJldHVybnMgdHJ1ZSBpZiBpdAogICBhdGUgYW4gb3B0aW9uICovCnN0YXRpYyBpbnQKcGFyc2UoaW50IGMsIGNoYXIgKiphcmd2LCBpbnQgaW52ZXJ0LCB1bnNpZ25lZCBpbnQgKmZsYWdzLAogICAgICBjb25zdCBzdHJ1Y3QgaXB0X2VudHJ5ICplbnRyeSwKICAgICAgc3RydWN0IGlwdF9lbnRyeV90YXJnZXQgKip0YXJnZXQpCnsKCXN0cnVjdCBpcHRfcm91dGVfdGFyZ2V0X2luZm8gKnJvdXRlX2luZm8gPSAKCQkoc3RydWN0IGlwdF9yb3V0ZV90YXJnZXRfaW5mbyopKCp0YXJnZXQpLT5kYXRhOwoKCXN3aXRjaCAoYykgewoJCWNoYXIgKmVuZDsKCWNhc2UgJzEnOgoJCWlmICgqZmxhZ3MgJiBJUFRfUk9VVEVfT1BUX0lGKQoJCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLAoJCQkJICAgIkNhbid0IHNwZWNpZnkgLS1pZmFjZSBvciAtLWlmaW5kZXggdHdpY2UiKTsKCgkJaWYgKGNoZWNrX2ludmVyc2Uob3B0YXJnLCAmaW52ZXJ0LCBOVUxMLCAwKSkKCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCSAgICJVbmV4cGVjdGVkIGAhJyBhZnRlciAtLWlmYWNlIik7CgoJCWlmIChzdHJsZW4ob3B0YXJnKSA+IHNpemVvZihyb3V0ZV9pbmZvLT5pZl9uYW1lKSAtIDEpCgkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkgICAiTWF4aW11bSBpbnRlcmZhY2UgbmFtZSBsZW5ndGggJXUiLAoJCQkJICAgc2l6ZW9mKHJvdXRlX2luZm8tPmlmX25hbWUpIC0gMSk7CgoJCXN0cmNweShyb3V0ZV9pbmZvLT5pZl9uYW1lLCBvcHRhcmcpOwoJCXJvdXRlX2luZm8tPmlmX2luZGV4ID0gMDsKCQkqZmxhZ3MgfD0gSVBUX1JPVVRFX09QVF9JRjsKCQlicmVhazsKCgljYXNlICcyJzoKCQlpZiAoKmZsYWdzICYgSVBUX1JPVVRFX09QVF9JRikKCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkJCSAgICJDYW4ndCBzcGVjaWZ5IC0taWZhY2Ugb3IgLS1pZmluZGV4IHR3aWNlIik7CgoJCWlmIChjaGVja19pbnZlcnNlKG9wdGFyZywgJmludmVydCwgTlVMTCwgMCkpCgkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkgICAiVW5leHBlY3RlZCBgIScgYWZ0ZXIgLS1pZmluZGV4Iik7CgoJCXJvdXRlX2luZm8tPmlmX25hbWVbMF0gPSAwOwoJCXJvdXRlX2luZm8tPmlmX2luZGV4ID0gc3RydG91bChvcHRhcmcsICZlbmQsIDApOwoJCWlmICgqZW5kICE9ICdcMCcgfHwgZW5kID09IG9wdGFyZykKCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwgIkJhZCBST1VURSBpZmluZGV4IGAlcyciLAoJCQkJICAgb3B0YXJnKTsKCgkJaWYgKHJvdXRlX2luZm8tPmlmX2luZGV4ID09IDApCgkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sCgkJCQkgICAiSW50ZXJmYWNlIGluZGV4IGNhbid0IGJlIDAgISIpOwoKCQkqZmxhZ3MgfD0gSVBUX1JPVVRFX09QVF9JRjsKCQlicmVhazsKCglkZWZhdWx0OgoJCXJldHVybiAwOwoJfQoKCXJldHVybiAxOwp9CgpzdGF0aWMgdm9pZApmaW5hbF9jaGVjayh1bnNpZ25lZCBpbnQgZmxhZ3MpCnsKCWlmICghZmxhZ3MpCgkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwKCQkgICAgICAgICAgICJST1VURSB0YXJnZXQ6IFBhcmFtZXRlciAtLWlmYWNlIGlzIHJlcXVpcmVkIik7Cn0KCi8qIFByaW50cyBvdXQgdGhlIHRhcmdpbmZvLiAqLwpzdGF0aWMgdm9pZApwcmludChjb25zdCBzdHJ1Y3QgaXB0X2lwICppcCwKICAgICAgY29uc3Qgc3RydWN0IGlwdF9lbnRyeV90YXJnZXQgKnRhcmdldCwKICAgICAgaW50IG51bWVyaWMpCnsKCWNvbnN0IHN0cnVjdCBpcHRfcm91dGVfdGFyZ2V0X2luZm8gKnJvdXRlX2luZm8KCQk9IChjb25zdCBzdHJ1Y3QgaXB0X3JvdXRlX3RhcmdldF9pbmZvICopdGFyZ2V0LT5kYXRhOwoKCXByaW50ZigiUk9VVEUgIik7CgoJaWYgKHJvdXRlX2luZm8tPmlmX25hbWVbMF0gIT0gMCkKCQlwcmludGYoImlmYWNlICVzICIsIHJvdXRlX2luZm8tPmlmX25hbWUpOwoJZWxzZSAKCQlwcmludGYoImlmaW5kZXggJXUgIiwgcm91dGVfaW5mby0+aWZfaW5kZXgpOwp9CgpzdGF0aWMKc3RydWN0IGlwdGFibGVzX3RhcmdldCByb3V0ZQo9IHsgTlVMTCwKICAgICJST1VURSIsCiAgICBJUFRBQkxFU19WRVJTSU9OLAogICAgSVBUX0FMSUdOKHNpemVvZihzdHJ1Y3QgaXB0X3JvdXRlX3RhcmdldF9pbmZvKSksCiAgICBJUFRfQUxJR04oc2l6ZW9mKHN0cnVjdCBpcHRfcm91dGVfdGFyZ2V0X2luZm8pKSwKICAgICZoZWxwLAogICAgJmluaXQsCiAgICAmcGFyc2UsCiAgICAmZmluYWxfY2hlY2ssCiAgICAmcHJpbnQsCiAgICBOVUxMLCAvKiBzYXZlICovCiAgICBvcHRzCn07Cgp2b2lkIF9pbml0KHZvaWQpCnsKCXJlZ2lzdGVyX3RhcmdldCgmcm91dGUpOwp9Cg==