LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAKICogRmlsZW5hbWU6ICAgICAgaXJsYW5fY2xpZW50LmMKICogVmVyc2lvbjogICAgICAgMC45CiAqIERlc2NyaXB0aW9uOiAgIElyREEgTEFOIEFjY2VzcyBQcm90b2NvbCAoSXJMQU4pIENsaWVudAogKiBTdGF0dXM6ICAgICAgICBFeHBlcmltZW50YWwuCiAqIEF1dGhvcjogICAgICAgIERhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4KICogQ3JlYXRlZCBhdDogICAgU3VuIEF1ZyAzMSAyMDoxNDozNyAxOTk3CiAqIE1vZGlmaWVkIGF0OiAgIFR1ZSBEZWMgMTQgMTU6NDc6MDIgMTk5OQogKiBNb2RpZmllZCBieTogICBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+CiAqIFNvdXJjZXM6ICAgICAgIHNrZWxldG9uLmMgYnkgRG9uYWxkIEJlY2tlciA8YmVja2VyQENFU0RJUy5nc2ZjLm5hc2EuZ292PgogKiAgICAgICAgICAgICAgICBzbGlwLmMgYnkgTGF1cmVuY2UgQ3VsaGFuZSwgPGxvekBob2xtZXMuZGVtb24uY28udWs+CiAqICAgICAgICAgICAgICAgICAgICAgICAgICBGcmVkIE4uIHZhbiBLZW1wZW4sIDx3YWx0amVAdXdhbHQubmwubXVnbmV0Lm9yZz4KICogCiAqICAgICBDb3B5cmlnaHQgKGMpIDE5OTgtMTk5OSBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+LCAKICogICAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqICAgICAKICogICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgCiAqICAgICBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyAKICogICAgIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIAogKiAgICAgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqICAgICBOZWl0aGVyIERhZyBCcmF0dGxpIG5vciBVbml2ZXJzaXR5IG9mIFRyb21z+CBhZG1pdCBsaWFiaWxpdHkgbm9yCiAqICAgICBwcm92aWRlIHdhcnJhbnR5IGZvciBhbnkgb2YgdGhpcyBzb2Z0d2FyZS4gVGhpcyBtYXRlcmlhbCBpcyAKICogICAgIHByb3ZpZGVkICJBUy1JUyIgYW5kIGF0IG5vIGNoYXJnZS4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvbmV0ZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9ldGhlcmRldmljZS5oPgojaW5jbHVkZSA8bGludXgvaWZfYXJwLmg+CiNpbmNsdWRlIDxsaW51eC9iaXRvcHMuaD4KI2luY2x1ZGUgPG5ldC9hcnAuaD4KCiNpbmNsdWRlIDxhc20vc3lzdGVtLmg+CiNpbmNsdWRlIDxhc20vYnl0ZW9yZGVyLmg+CgojaW5jbHVkZSA8bmV0L2lyZGEvaXJkYS5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJ0dHAuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybG1wLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9pcmlhc19vYmplY3QuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lyaWFwLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS90aW1lci5oPgoKI2luY2x1ZGUgPG5ldC9pcmRhL2lybGFuX2NvbW1vbi5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJsYW5fZXZlbnQuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybGFuX2V0aC5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJsYW5fcHJvdmlkZXIuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybGFuX2NsaWVudC5oPgoKI3VuZGVmIENPTkZJR19JUkxBTl9HUkFUVUlUT1VTX0FSUAoKc3RhdGljIHZvaWQgaXJsYW5fY2xpZW50X2N0cmxfZGlzY29ubmVjdF9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIAoJCQkJCQkgICAgTE1fUkVBU09OIHJlYXNvbiwgCgkJCQkJCSAgICBzdHJ1Y3Qgc2tfYnVmZiAqKTsKc3RhdGljIGludCBpcmxhbl9jbGllbnRfY3RybF9kYXRhX2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgCgkJCQkJICAgICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKTsKc3RhdGljIHZvaWQgaXJsYW5fY2xpZW50X2N0cmxfY29ubmVjdF9jb25maXJtKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIAoJCQkJCSAgICAgIHN0cnVjdCBxb3NfaW5mbyAqcW9zLCAKCQkJCQkgICAgICBfX3UzMiBtYXhfc2R1X3NpemUsCgkJCQkJICAgICAgX191OCBtYXhfaGVhZGVyX3NpemUsCgkJCQkJICAgICAgc3RydWN0IHNrX2J1ZmYgKik7CnN0YXRpYyB2b2lkIGlybGFuX2NoZWNrX3Jlc3BvbnNlX3BhcmFtKHN0cnVjdCBpcmxhbl9jYiAqc2VsZiwgY2hhciAqcGFyYW0sIAoJCQkJICAgICAgIGNoYXIgKnZhbHVlLCBpbnQgdmFsX2xlbik7CnN0YXRpYyB2b2lkIGlybGFuX2NsaWVudF9vcGVuX2N0cmxfdHNhcChzdHJ1Y3QgaXJsYW5fY2IgKnNlbGYpOwoKc3RhdGljIHZvaWQgaXJsYW5fY2xpZW50X2tpY2tfdGltZXJfZXhwaXJlZCh2b2lkICpkYXRhKQp7CglzdHJ1Y3QgaXJsYW5fY2IgKnNlbGYgPSAoc3RydWN0IGlybGFuX2NiICopIGRhdGE7CgkKCUlSREFfREVCVUcoMiwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyApOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJUkxBTl9NQUdJQywgcmV0dXJuOyk7CgkKCS8qICAKCSAqIElmIHdlIGFyZSBpbiBwZWVyIG1vZGUsIHRoZSBjbGllbnQgbWF5IG5vdCBoYXZlIGdvdCB0aGUgZGlzY292ZXJ5CgkgKiBpbmRpY2F0aW9uIGl0IG5lZWRzIHRvIG1ha2UgcHJvZ3Jlc3MuIElmIHRoZSBjbGllbnQgaXMgc3RpbGwgaW4gCgkgKiBJRExFIHN0YXRlLCB3ZSBtdXN0IGtpY2sgaXQgdG8sIGJ1dCBvbmx5IGlmIHRoZSBwcm92aWRlciBpcyBub3QgSURMRQogCSAqLwoJaWYgKChzZWxmLT5wcm92aWRlci5hY2Nlc3NfdHlwZSA9PSBBQ0NFU1NfUEVFUikgJiYgCgkgICAgKHNlbGYtPmNsaWVudC5zdGF0ZSA9PSBJUkxBTl9JRExFKSAmJgoJICAgIChzZWxmLT5wcm92aWRlci5zdGF0ZSAhPSBJUkxBTl9JRExFKSkgewoJCWlybGFuX2NsaWVudF93YWtldXAoc2VsZiwgc2VsZi0+c2FkZHIsIHNlbGYtPmRhZGRyKTsKCX0KfQoKc3RhdGljIHZvaWQgaXJsYW5fY2xpZW50X3N0YXJ0X2tpY2tfdGltZXIoc3RydWN0IGlybGFuX2NiICpzZWxmLCBpbnQgdGltZW91dCkKewoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fICk7CgkKCWlyZGFfc3RhcnRfdGltZXIoJnNlbGYtPmNsaWVudC5raWNrX3RpbWVyLCB0aW1lb3V0LCAodm9pZCAqKSBzZWxmLCAKCQkJIGlybGFuX2NsaWVudF9raWNrX3RpbWVyX2V4cGlyZWQpOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhbl9jbGllbnRfd2FrZXVwIChzZWxmLCBzYWRkciwgZGFkZHIpCiAqCiAqICAgIFdha2UgdXAgY2xpZW50CiAqCiAqLwp2b2lkIGlybGFuX2NsaWVudF93YWtldXAoc3RydWN0IGlybGFuX2NiICpzZWxmLCBfX3UzMiBzYWRkciwgX191MzIgZGFkZHIpCnsKCUlSREFfREVCVUcoMSwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyApOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJUkxBTl9NQUdJQywgcmV0dXJuOyk7CgoJLyogCgkgKiBDaGVjayBpZiB3ZSBhcmUgYWxyZWFkeSBhd2FrZSwgb3IgaWYgd2UgYXJlIGEgcHJvdmlkZXIgaW4gZGlyZWN0CgkgKiBtb2RlIChpbiB0aGF0IGNhc2Ugd2UgbXVzdCBsZWF2ZSB0aGUgY2xpZW50IGlkbGUKCSAqLwoJaWYgKChzZWxmLT5jbGllbnQuc3RhdGUgIT0gSVJMQU5fSURMRSkgfHwgCgkgICAgKHNlbGYtPnByb3ZpZGVyLmFjY2Vzc190eXBlID09IEFDQ0VTU19ESVJFQ1QpKQoJewoJCQlJUkRBX0RFQlVHKDAsICIlcygpLCBhbHJlYWR5IGF3YWtlIVxuIiwgX19GVU5DVElPTl9fICk7CgkJCXJldHVybjsKCX0KCgkvKiBBZGRyZXNzZXMgbWF5IGhhdmUgY2hhbmdlZCEgKi8KCXNlbGYtPnNhZGRyID0gc2FkZHI7CglzZWxmLT5kYWRkciA9IGRhZGRyOwoKCWlmIChzZWxmLT5kaXNjb25uZWN0X3JlYXNvbiA9PSBMTV9VU0VSX1JFUVVFU1QpIHsKCQkJSVJEQV9ERUJVRygwLCAiJXMoKSwgc3RpbGwgc3RvcHBlZCBieSB1c2VyXG4iLCBfX0ZVTkNUSU9OX18gKTsKCQkJcmV0dXJuOwoJfQoKCS8qIE9wZW4gVFNBUHMgKi8KCWlybGFuX2NsaWVudF9vcGVuX2N0cmxfdHNhcChzZWxmKTsKCWlybGFuX29wZW5fZGF0YV90c2FwKHNlbGYpOwoKCWlybGFuX2RvX2NsaWVudF9ldmVudChzZWxmLCBJUkxBTl9ESVNDT1ZFUllfSU5ESUNBVElPTiwgTlVMTCk7CgkKCS8qIFN0YXJ0IGtpY2sgdGltZXIgKi8KCWlybGFuX2NsaWVudF9zdGFydF9raWNrX3RpbWVyKHNlbGYsIDIqSFopOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhbl9kaXNjb3ZlcnlfaW5kaWNhdGlvbiAoZGFkZHIpCiAqCiAqICAgIFJlbW90ZSBkZXZpY2Ugd2l0aCBJckxBTiBzZXJ2ZXIgc3VwcG9ydCBkaXNjb3ZlcmVkCiAqCiAqLwp2b2lkIGlybGFuX2NsaWVudF9kaXNjb3ZlcnlfaW5kaWNhdGlvbihkaXNjaW5mb190ICpkaXNjb3ZlcnksCgkJCQkgICAgICAgRElTQ09WRVJZX01PREUgbW9kZSwKCQkJCSAgICAgICB2b2lkICpwcml2KSAKewoJc3RydWN0IGlybGFuX2NiICpzZWxmOwoJX191MzIgc2FkZHIsIGRhZGRyOwoJCglJUkRBX0RFQlVHKDEsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18gKTsKCglJUkRBX0FTU0VSVChkaXNjb3ZlcnkgIT0gTlVMTCwgcmV0dXJuOyk7CgoJLyoKCSAqIEkgZGlkbid0IGNoZWNrIGl0LCBidXQgSSBiZXQgdGhhdCBJckxBTiBzdWZmZXIgZnJvbSB0aGUgc2FtZQoJICogZGVmaWNpZW5jeSBhcyBJckNvbW0gYW5kIGRvZXNuJ3QgaGFuZGxlIHR3byBpbnN0YW5jZXMKCSAqIHNpbXVsdGFuZW91c2x5IGNvbm5lY3RpbmcgdG8gZWFjaCBvdGhlci4KCSAqIFNhbWUgd29ya2Fyb3VuZCwgZHJvcCBwYXNzaXZlIGRpc2NvdmVyaWVzLgoJICogSmVhbiBJSSAqLwoJaWYobW9kZSA9PSBESVNDT1ZFUllfUEFTU0lWRSkKCQlyZXR1cm47CgoJc2FkZHIgPSBkaXNjb3ZlcnktPnNhZGRyOwoJZGFkZHIgPSBkaXNjb3ZlcnktPmRhZGRyOwoKCS8qIEZpbmQgaW5zdGFuY2UgKi8KCXJjdV9yZWFkX2xvY2soKTsKCXNlbGYgPSBpcmxhbl9nZXRfYW55KCk7CglpZiAoc2VsZikgewoJCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElSTEFOX01BR0lDLCBnb3RvIG91dDspOwoKCQlJUkRBX0RFQlVHKDEsICIlcygpLCBGb3VuZCBpbnN0YW5jZSAoJTA4eCkhXG4iLCBfX0ZVTkNUSU9OX18gLAoJCSAgICAgIGRhZGRyKTsKCQkKCQlpcmxhbl9jbGllbnRfd2FrZXVwKHNlbGYsIHNhZGRyLCBkYWRkcik7Cgl9CklSREFfQVNTRVJUX0xBQkVMKG91dDopCglyY3VfcmVhZF91bmxvY2soKTsKfQoJCi8qCiAqIEZ1bmN0aW9uIGlybGFuX2NsaWVudF9kYXRhX2luZGljYXRpb24gKGhhbmRsZSwgc2tiKQogKgogKiAgICBUaGlzIGZ1bmN0aW9uIGdldHMgdGhlIGRhdGEgdGhhdCBpcyByZWNlaXZlZCBvbiB0aGUgY29udHJvbCBjaGFubmVsCiAqCiAqLwpzdGF0aWMgaW50IGlybGFuX2NsaWVudF9jdHJsX2RhdGFfaW5kaWNhdGlvbih2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLCAKCQkJCQkgICAgIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCBpcmxhbl9jYiAqc2VsZjsKCQoJSVJEQV9ERUJVRygyLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fICk7CgkKCXNlbGYgPSAoc3RydWN0IGlybGFuX2NiICopIGluc3RhbmNlOwoJCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSVJMQU5fTUFHSUMsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2tiICE9IE5VTEwsIHJldHVybiAtMTspOwoJCglpcmxhbl9kb19jbGllbnRfZXZlbnQoc2VsZiwgSVJMQU5fREFUQV9JTkRJQ0FUSU9OLCBza2IpOyAKCgkvKiBSZWFkeSBmb3IgYSBuZXcgY29tbWFuZCAqLwkKCUlSREFfREVCVUcoMiwgIiVzKCksIGNsZWFyaW5nIHR4X2J1c3lcbiIsIF9fRlVOQ1RJT05fXyApOwoJc2VsZi0+Y2xpZW50LnR4X2J1c3kgPSBGQUxTRTsKCgkvKiBDaGVjayBpZiB3ZSBoYXZlIHNvbWUgcXVldWVkIGNvbW1hbmRzIHdhaXRpbmcgdG8gYmUgc2VudCAqLwoJaXJsYW5fcnVuX2N0cmxfdHhfcXVldWUoc2VsZik7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGlybGFuX2NsaWVudF9jdHJsX2Rpc2Nvbm5lY3RfaW5kaWNhdGlvbih2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLCAKCQkJCQkJICAgIExNX1JFQVNPTiByZWFzb24sIAoJCQkJCQkgICAgc3RydWN0IHNrX2J1ZmYgKnVzZXJkYXRhKSAKewoJc3RydWN0IGlybGFuX2NiICpzZWxmOwoJc3RydWN0IHRzYXBfY2IgKnRzYXA7CglzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwoKCUlSREFfREVCVUcoNCwgIiVzKCksIHJlYXNvbj0lZFxuIiwgX19GVU5DVElPTl9fICwgcmVhc29uKTsKCQoJc2VsZiA9IChzdHJ1Y3QgaXJsYW5fY2IgKikgaW5zdGFuY2U7Cgl0c2FwID0gKHN0cnVjdCB0c2FwX2NiICopIHNhcDsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSVJMQU5fTUFHSUMsIHJldHVybjspOwkKCUlSREFfQVNTRVJUKHRzYXAgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVCh0c2FwLT5tYWdpYyA9PSBUVFBfVFNBUF9NQUdJQywgcmV0dXJuOyk7CgkKCUlSREFfQVNTRVJUKHRzYXAgPT0gc2VsZi0+Y2xpZW50LnRzYXBfY3RybCwgcmV0dXJuOyk7CgogICAgICAgCS8qIFJlbW92ZSBmcmFtZXMgcXVldWVkIG9uIHRoZSBjb250cm9sIGNoYW5uZWwgKi8KCXdoaWxlICgoc2tiID0gc2tiX2RlcXVldWUoJnNlbGYtPmNsaWVudC50eHEpKSAhPSBOVUxMKSB7CgkJZGV2X2tmcmVlX3NrYihza2IpOwoJfQoJc2VsZi0+Y2xpZW50LnR4X2J1c3kgPSBGQUxTRTsKCglpcmxhbl9kb19jbGllbnRfZXZlbnQoc2VsZiwgSVJMQU5fTE1QX0RJU0NPTk5FQ1QsIE5VTEwpOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhbl9jbGllbnRfb3Blbl90c2FwcyAoc2VsZikKICoKICogICAgSW5pdGlhbGl6ZSBjYWxsYmFja3MgYW5kIG9wZW4gSXJUVFAgVFNBUHMKICoKICovCnN0YXRpYyB2b2lkIGlybGFuX2NsaWVudF9vcGVuX2N0cmxfdHNhcChzdHJ1Y3QgaXJsYW5fY2IgKnNlbGYpCnsKCXN0cnVjdCB0c2FwX2NiICp0c2FwOwoJbm90aWZ5X3Qgbm90aWZ5OwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyApOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJUkxBTl9NQUdJQywgcmV0dXJuOyk7CgoJLyogQ2hlY2sgaWYgYWxyZWFkeSBvcGVuICovCglpZiAoc2VsZi0+Y2xpZW50LnRzYXBfY3RybCkKCQlyZXR1cm47CgoJaXJkYV9ub3RpZnlfaW5pdCgmbm90aWZ5KTsKCgkvKiBTZXQgdXAgY2FsbGJhY2tzICovCglub3RpZnkuZGF0YV9pbmRpY2F0aW9uICAgICAgID0gaXJsYW5fY2xpZW50X2N0cmxfZGF0YV9pbmRpY2F0aW9uOwoJbm90aWZ5LmNvbm5lY3RfY29uZmlybSAgICAgICA9IGlybGFuX2NsaWVudF9jdHJsX2Nvbm5lY3RfY29uZmlybTsKCW5vdGlmeS5kaXNjb25uZWN0X2luZGljYXRpb24gPSBpcmxhbl9jbGllbnRfY3RybF9kaXNjb25uZWN0X2luZGljYXRpb247Cglub3RpZnkuaW5zdGFuY2UgPSBzZWxmOwoJc3RybGNweShub3RpZnkubmFtZSwgIklyTEFOIGN0cmwgKGMpIiwgc2l6ZW9mKG5vdGlmeS5uYW1lKSk7CgkKCXRzYXAgPSBpcnR0cF9vcGVuX3RzYXAoTFNBUF9BTlksIERFRkFVTFRfSU5JVElBTF9DUkVESVQsICZub3RpZnkpOwoJaWYgKCF0c2FwKSB7CgkJSVJEQV9ERUJVRygyLCAiJXMoKSwgR290IG5vIHRzYXAhXG4iLCBfX0ZVTkNUSU9OX18gKTsKCQlyZXR1cm47Cgl9CglzZWxmLT5jbGllbnQudHNhcF9jdHJsID0gdHNhcDsKfQoKLyoKICogRnVuY3Rpb24gaXJsYW5fY2xpZW50X2Nvbm5lY3RfY29uZmlybSAoaGFuZGxlLCBza2IpCiAqCiAqICAgIENvbm5lY3Rpb24gdG8gcGVlciBJckxBTiBsYXllIGNvbmZpcm1lZAogKgogKi8Kc3RhdGljIHZvaWQgaXJsYW5fY2xpZW50X2N0cmxfY29ubmVjdF9jb25maXJtKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIAoJCQkJCSAgICAgIHN0cnVjdCBxb3NfaW5mbyAqcW9zLCAKCQkJCQkgICAgICBfX3UzMiBtYXhfc2R1X3NpemUsCgkJCQkJICAgICAgX191OCBtYXhfaGVhZGVyX3NpemUsCgkJCQkJICAgICAgc3RydWN0IHNrX2J1ZmYgKnNrYikgCnsKCXN0cnVjdCBpcmxhbl9jYiAqc2VsZjsKCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18gKTsKCglzZWxmID0gKHN0cnVjdCBpcmxhbl9jYiAqKSBpbnN0YW5jZTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSVJMQU5fTUFHSUMsIHJldHVybjspOwoKCXNlbGYtPmNsaWVudC5tYXhfc2R1X3NpemUgPSBtYXhfc2R1X3NpemU7CglzZWxmLT5jbGllbnQubWF4X2hlYWRlcl9zaXplID0gbWF4X2hlYWRlcl9zaXplOwoKCS8qIFRPRE86IHdlIGNvdWxkIHNldCB0aGUgTVRVIGRlcGVuZGluZyBvbiB0aGUgbWF4X3NkdV9zaXplICovCgoJaXJsYW5fZG9fY2xpZW50X2V2ZW50KHNlbGYsIElSTEFOX0NPTk5FQ1RfQ09NUExFVEUsIE5VTEwpOwp9CgovKgogKiBGdW5jdGlvbiBwcmludF9yZXRfY29kZSAoY29kZSkKICoKICogICAgUHJpbnQgcmV0dXJuIGNvZGUgb2YgcmVxdWVzdCB0byBwZWVyIElyTEFOIGxheWVyLgogKgogKi8Kc3RhdGljIHZvaWQgcHJpbnRfcmV0X2NvZGUoX191OCBjb2RlKSAKewoJc3dpdGNoKGNvZGUpIHsKCWNhc2UgMDoKCQlwcmludGsoS0VSTl9JTkZPICJTdWNjZXNzXG4iKTsKCQlicmVhazsKCWNhc2UgMToKCQlJUkRBX1dBUk5JTkcoIklyTEFOOiBJbnN1ZmZpY2llbnQgcmVzb3VyY2VzXG4iKTsKCQlicmVhazsKCWNhc2UgMjoKCQlJUkRBX1dBUk5JTkcoIklyTEFOOiBJbnZhbGlkIGNvbW1hbmQgZm9ybWF0XG4iKTsKCQlicmVhazsKCWNhc2UgMzoKCQlJUkRBX1dBUk5JTkcoIklyTEFOOiBDb21tYW5kIG5vdCBzdXBwb3J0ZWRcbiIpOwoJCWJyZWFrOwoJY2FzZSA0OgoJCUlSREFfV0FSTklORygiSXJMQU46IFBhcmFtZXRlciBub3Qgc3VwcG9ydGVkXG4iKTsKCQlicmVhazsKCWNhc2UgNToKCQlJUkRBX1dBUk5JTkcoIklyTEFOOiBWYWx1ZSBub3Qgc3VwcG9ydGVkXG4iKTsKCQlicmVhazsKCWNhc2UgNjoKCQlJUkRBX1dBUk5JTkcoIklyTEFOOiBOb3Qgb3BlblxuIik7CgkJYnJlYWs7CgljYXNlIDc6CgkJSVJEQV9XQVJOSU5HKCJJckxBTjogQXV0aGVudGljYXRpb24gcmVxdWlyZWRcbiIpOwoJCWJyZWFrOwoJY2FzZSA4OgoJCUlSREFfV0FSTklORygiSXJMQU46IEludmFsaWQgcGFzc3dvcmRcbiIpOwoJCWJyZWFrOwoJY2FzZSA5OgoJCUlSREFfV0FSTklORygiSXJMQU46IFByb3RvY29sIGVycm9yXG4iKTsKCQlicmVhazsKCWNhc2UgMjU1OgoJCUlSREFfV0FSTklORygiSXJMQU46IEFzeW5jaHJvbm91cyBzdGF0dXNcbiIpOwoJCWJyZWFrOwoJfQp9CgovKgogKiBGdW5jdGlvbiBpcmxhbl9jbGllbnRfcGFyc2VfcmVzcG9uc2UgKHNlbGYsIHNrYikKICoKICogICAgRXh0cmFjdCBhbGwgcGFyYW1ldGVycyBmcm9tIHJlY2VpdmVkIGJ1ZmZlciwgdGhlbiBmZWVkIHRoZW0gdG8gCiAqICAgIGNoZWNrX3BhcmFtcyBmb3IgcGFyc2luZwogKi8Kdm9pZCBpcmxhbl9jbGllbnRfcGFyc2VfcmVzcG9uc2Uoc3RydWN0IGlybGFuX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglfX3U4ICpmcmFtZTsKCV9fdTggKnB0cjsKCWludCBjb3VudDsKCWludCByZXQ7CglfX3UxNiB2YWxfbGVuOwoJaW50IGk7CiAgICAgICAgY2hhciAqbmFtZTsKICAgICAgICBjaGFyICp2YWx1ZTsKCglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuOyk7CQoJCglJUkRBX0RFQlVHKDQsICIlcygpIHNrYi0+bGVuPSVkXG4iLCBfX0ZVTkNUSU9OX18gLCAoaW50KSBza2ItPmxlbik7CgkKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJUkxBTl9NQUdJQywgcmV0dXJuOyk7CgkKCWlmICghc2tiKSB7CgkJSVJEQV9FUlJPUigiJXMoKSwgR290IE5VTEwgc2tiIVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm47Cgl9CglmcmFtZSA9IHNrYi0+ZGF0YTsKCQoJLyogCgkgKiAgQ2hlY2sgcmV0dXJuIGNvZGUgYW5kIHByaW50IGl0IGlmIG5vdCBzdWNjZXNzIAoJICovCglpZiAoZnJhbWVbMF0pIHsKCQlwcmludF9yZXRfY29kZShmcmFtZVswXSk7CgkJcmV0dXJuOwoJfQoJCgluYW1lID0ga21hbGxvYygyNTUsIEdGUF9BVE9NSUMpOwoJaWYgKCFuYW1lKQoJCXJldHVybjsKCXZhbHVlID0ga21hbGxvYygxMDE2LCBHRlBfQVRPTUlDKTsKCWlmICghdmFsdWUpIHsKCQlrZnJlZShuYW1lKTsKCQlyZXR1cm47Cgl9CgoJLyogSG93IG1hbnkgcGFyYW1ldGVycz8gKi8KCWNvdW50ID0gZnJhbWVbMV07CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgZ290ICVkIHBhcmFtZXRlcnNcbiIsIF9fRlVOQ1RJT05fXyAsIGNvdW50KTsKCQoJcHRyID0gZnJhbWUrMjsKCgkvKiBGb3IgYWxsIHBhcmFtZXRlcnMgKi8KIAlmb3IgKGk9MDsgaTxjb3VudDtpKyspIHsKCQlyZXQgPSBpcmxhbl9leHRyYWN0X3BhcmFtKHB0ciwgbmFtZSwgdmFsdWUsICZ2YWxfbGVuKTsKCQlpZiAocmV0IDwgMCkgewoJCQlJUkRBX0RFQlVHKDIsICIlcygpLCBJckxBTiwgRXJyb3IhXG4iLCBfX0ZVTkNUSU9OX18gKTsKCQkJYnJlYWs7CgkJfQoJCXB0ciArPSByZXQ7CgkJaXJsYW5fY2hlY2tfcmVzcG9uc2VfcGFyYW0oc2VsZiwgbmFtZSwgdmFsdWUsIHZhbF9sZW4pOwogCX0KCS8qIENsZWFudXAgKi8KCWtmcmVlKG5hbWUpOwoJa2ZyZWUodmFsdWUpOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhbl9jaGVja19yZXNwb25zZV9wYXJhbSAoc2VsZiwgcGFyYW0sIHZhbHVlLCB2YWxfbGVuKQogKgogKiAgICAgQ2hlY2sgd2hpY2ggcGFyYW1ldGVyIGlzIHJlY2VpdmVkIGFuZCB1cGRhdGUgbG9jYWwgdmFyaWFibGVzCiAqCiAqLwpzdGF0aWMgdm9pZCBpcmxhbl9jaGVja19yZXNwb25zZV9wYXJhbShzdHJ1Y3QgaXJsYW5fY2IgKnNlbGYsIGNoYXIgKnBhcmFtLCAKCQkJCSAgICAgICBjaGFyICp2YWx1ZSwgaW50IHZhbF9sZW4pIAp7CglfX3UxNiB0bXBfY3B1OyAvKiBUZW1wb3JhcnkgdmFsdWUgaW4gaG9zdCBvcmRlciAqLwoJX191OCAqYnl0ZXM7CglpbnQgaTsKCglJUkRBX0RFQlVHKDQsICIlcygpLCBwYXJtPSVzXG4iLCBfX0ZVTkNUSU9OX18gLCBwYXJhbSk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElSTEFOX01BR0lDLCByZXR1cm47KTsKCgkvKiBNZWRpYSB0eXBlICovCglpZiAoc3RyY21wKHBhcmFtLCAiTUVESUEiKSA9PSAwKSB7CgkJaWYgKHN0cmNtcCh2YWx1ZSwgIjgwMi4zIikgPT0gMCkKCQkJc2VsZi0+bWVkaWEgPSBNRURJQV84MDJfMzsKCQllbHNlCgkJCXNlbGYtPm1lZGlhID0gTUVESUFfODAyXzU7CgkJcmV0dXJuOwoJfQoJaWYgKHN0cmNtcChwYXJhbSwgIkZJTFRFUl9UWVBFIikgPT0gMCkgewoJCWlmIChzdHJjbXAodmFsdWUsICJESVJFQ1RFRCIpID09IDApCgkJCXNlbGYtPmNsaWVudC5maWx0ZXJfdHlwZSB8PSBJUkxBTl9ESVJFQ1RFRDsKCQllbHNlIGlmIChzdHJjbXAodmFsdWUsICJGVU5DVElPTkFMIikgPT0gMCkKCQkJc2VsZi0+Y2xpZW50LmZpbHRlcl90eXBlIHw9IElSTEFOX0ZVTkNUSU9OQUw7CgkJZWxzZSBpZiAoc3RyY21wKHZhbHVlLCAiR1JPVVAiKSA9PSAwKQoJCQlzZWxmLT5jbGllbnQuZmlsdGVyX3R5cGUgfD0gSVJMQU5fR1JPVVA7CgkJZWxzZSBpZiAoc3RyY21wKHZhbHVlLCAiTUFDX0ZSQU1FIikgPT0gMCkKCQkJc2VsZi0+Y2xpZW50LmZpbHRlcl90eXBlIHw9IElSTEFOX01BQ19GUkFNRTsKCQllbHNlIGlmIChzdHJjbXAodmFsdWUsICJNVUxUSUNBU1QiKSA9PSAwKQoJCQlzZWxmLT5jbGllbnQuZmlsdGVyX3R5cGUgfD0gSVJMQU5fTVVMVElDQVNUOwoJCWVsc2UgaWYgKHN0cmNtcCh2YWx1ZSwgIkJST0FEQ0FTVCIpID09IDApCgkJCXNlbGYtPmNsaWVudC5maWx0ZXJfdHlwZSB8PSBJUkxBTl9CUk9BRENBU1Q7CgkJZWxzZSBpZiAoc3RyY21wKHZhbHVlLCAiSVBYX1NPQ0tFVCIpID09IDApCgkJCXNlbGYtPmNsaWVudC5maWx0ZXJfdHlwZSB8PSBJUkxBTl9JUFhfU09DS0VUOwoJCQoJfQoJaWYgKHN0cmNtcChwYXJhbSwgIkFDQ0VTU19UWVBFIikgPT0gMCkgewoJCWlmIChzdHJjbXAodmFsdWUsICJESVJFQ1QiKSA9PSAwKQoJCQlzZWxmLT5jbGllbnQuYWNjZXNzX3R5cGUgPSBBQ0NFU1NfRElSRUNUOwoJCWVsc2UgaWYgKHN0cmNtcCh2YWx1ZSwgIlBFRVIiKSA9PSAwKQoJCQlzZWxmLT5jbGllbnQuYWNjZXNzX3R5cGUgPSBBQ0NFU1NfUEVFUjsKCQllbHNlIGlmIChzdHJjbXAodmFsdWUsICJIT1NURUQiKSA9PSAwKQoJCQlzZWxmLT5jbGllbnQuYWNjZXNzX3R5cGUgPSBBQ0NFU1NfSE9TVEVEOwoJCWVsc2UgewoJCQlJUkRBX0RFQlVHKDIsICIlcygpLCB1bmtub3duIGFjY2VzcyB0eXBlIVxuIiwgX19GVU5DVElPTl9fICk7CgkJfQoJfQoJLyogSVJMQU4gdmVyc2lvbiAqLwoJaWYgKHN0cmNtcChwYXJhbSwgIklSTEFOX1ZFUiIpID09IDApIHsKCQlJUkRBX0RFQlVHKDQsICJJckxBTiB2ZXJzaW9uICVkLiVkXG4iLCAoX191OCkgdmFsdWVbMF0sIAoJCSAgICAgIChfX3U4KSB2YWx1ZVsxXSk7CgoJCXNlbGYtPnZlcnNpb25bMF0gPSB2YWx1ZVswXTsKCQlzZWxmLT52ZXJzaW9uWzFdID0gdmFsdWVbMV07CgkJcmV0dXJuOwoJfQoJLyogV2hpY2ggcmVtb3RlIFRTQVAgdG8gdXNlIGZvciBkYXRhIGNoYW5uZWwgKi8KCWlmIChzdHJjbXAocGFyYW0sICJEQVRBX0NIQU4iKSA9PSAwKSB7CgkJc2VsZi0+ZHRzYXBfc2VsX2RhdGEgPSB2YWx1ZVswXTsKCQlJUkRBX0RFQlVHKDQsICJEYXRhIFRTQVAgPSAlMDJ4XG4iLCBzZWxmLT5kdHNhcF9zZWxfZGF0YSk7CgkJcmV0dXJuOwoJfQoJaWYgKHN0cmNtcChwYXJhbSwgIkNPTl9BUkIiKSA9PSAwKSB7CgkJbWVtY3B5KCZ0bXBfY3B1LCB2YWx1ZSwgMik7IC8qIEFsaWduIHZhbHVlICovCgkJbGUxNl90b19jcHVzKCZ0bXBfY3B1KTsgICAgIC8qIENvbnZlcnQgdG8gaG9zdCBvcmRlciAqLwoJCXNlbGYtPmNsaWVudC5yZWN2X2FyYl92YWwgPSB0bXBfY3B1OwoJCUlSREFfREVCVUcoMiwgIiVzKCksIHJlY2VpdmUgYXJiIHZhbD0lZFxuIiwgX19GVU5DVElPTl9fICwgCgkJCSAgIHNlbGYtPmNsaWVudC5yZWN2X2FyYl92YWwpOwoJfQoJaWYgKHN0cmNtcChwYXJhbSwgIk1BWF9GUkFNRSIpID09IDApIHsKCQltZW1jcHkoJnRtcF9jcHUsIHZhbHVlLCAyKTsgLyogQWxpZ24gdmFsdWUgKi8KCQlsZTE2X3RvX2NwdXMoJnRtcF9jcHUpOyAgICAgLyogQ29udmVydCB0byBob3N0IG9yZGVyICovCgkJc2VsZi0+Y2xpZW50Lm1heF9mcmFtZSA9IHRtcF9jcHU7CgkJSVJEQV9ERUJVRyg0LCAiJXMoKSwgbWF4IGZyYW1lPSVkXG4iLCBfX0ZVTkNUSU9OX18gLCAKCQkJICAgc2VsZi0+Y2xpZW50Lm1heF9mcmFtZSk7Cgl9CgkgCgkvKiBSRUNPTk5FQ1RfS0VZLCBpbiBjYXNlIHRoZSBsaW5rIGdvZXMgZG93biEgKi8KCWlmIChzdHJjbXAocGFyYW0sICJSRUNPTk5FQ1RfS0VZIikgPT0gMCkgewoJCUlSREFfREVCVUcoNCwgIkdvdCByZWNvbm5lY3Qga2V5OiAiKTsKCQkvKiBmb3IgKGkgPSAwOyBpIDwgdmFsX2xlbjsgaSsrKSAqLwovKiAJCQlwcmludGsoIiUwMngiLCB2YWx1ZVtpXSk7ICovCgkJbWVtY3B5KHNlbGYtPmNsaWVudC5yZWNvbm5lY3Rfa2V5LCB2YWx1ZSwgdmFsX2xlbik7CgkJc2VsZi0+Y2xpZW50LmtleV9sZW4gPSB2YWxfbGVuOwoJCUlSREFfREVCVUcoNCwgIlxuIik7Cgl9CgkvKiBGSUxURVJfRU5UUlksIGhhdmUgd2UgZ290IGFuIGV0aGVybmV0IGFkZHJlc3M/ICovCglpZiAoc3RyY21wKHBhcmFtLCAiRklMVEVSX0VOVFJZIikgPT0gMCkgewoJCWJ5dGVzID0gdmFsdWU7CgkJSVJEQV9ERUJVRyg0LCAiRXRoZXJuZXQgYWRkcmVzcyA9ICUwMng6JTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4XG4iLAoJCSAgICAgIGJ5dGVzWzBdLCBieXRlc1sxXSwgYnl0ZXNbMl0sIGJ5dGVzWzNdLCBieXRlc1s0XSwgCgkJICAgICAgYnl0ZXNbNV0pOwoJCWZvciAoaSA9IDA7IGkgPCA2OyBpKyspIAoJCQlzZWxmLT5kZXYtPmRldl9hZGRyW2ldID0gYnl0ZXNbaV07Cgl9Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybGFuX2NsaWVudF9nZXRfdmFsdWVfY29uZmlybSAob2JqX2lkLCB2YWx1ZSkKICoKICogICAgR290IHJlc3VsdHMgZnJvbSByZW1vdGUgTE0tSUFTCiAqCiAqLwp2b2lkIGlybGFuX2NsaWVudF9nZXRfdmFsdWVfY29uZmlybShpbnQgcmVzdWx0LCBfX3UxNiBvYmpfaWQsIAoJCQkJICAgIHN0cnVjdCBpYXNfdmFsdWUgKnZhbHVlLCB2b2lkICpwcml2KSAKewoJc3RydWN0IGlybGFuX2NiICpzZWxmOwoJCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18gKTsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybjspOwoKCXNlbGYgPSAoc3RydWN0IGlybGFuX2NiICopIHByaXY7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJUkxBTl9NQUdJQywgcmV0dXJuOyk7CgoJLyogV2UgcHJvYmFibHkgZG9uJ3QgbmVlZCB0byBtYWtlIGFueSBtb3JlIHF1ZXJpZXMgKi8KCWlyaWFwX2Nsb3NlKHNlbGYtPmNsaWVudC5pcmlhcCk7CglzZWxmLT5jbGllbnQuaXJpYXAgPSBOVUxMOwoKCS8qIENoZWNrIGlmIHJlcXVlc3Qgc3VjY2VlZGVkICovCglpZiAocmVzdWx0ICE9IElBU19TVUNDRVNTKSB7CgkJSVJEQV9ERUJVRygyLCAiJXMoKSwgZ290IE5VTEwgdmFsdWUhXG4iLCBfX0ZVTkNUSU9OX18gKTsKCQlpcmxhbl9kb19jbGllbnRfZXZlbnQoc2VsZiwgSVJMQU5fSUFTX1BST1ZJREVSX05PVF9BVkFJTCwgCgkJCQkgICAgICBOVUxMKTsKCQlyZXR1cm47Cgl9CgoJc3dpdGNoICh2YWx1ZS0+dHlwZSkgewoJY2FzZSBJQVNfSU5URUdFUjoKCQlzZWxmLT5kdHNhcF9zZWxfY3RybCA9IHZhbHVlLT50LmludGVnZXI7CgoJCWlmICh2YWx1ZS0+dC5pbnRlZ2VyICE9IC0xKSB7CgkJCWlybGFuX2RvX2NsaWVudF9ldmVudChzZWxmLCBJUkxBTl9JQVNfUFJPVklERVJfQVZBSUwsCgkJCQkJICAgICAgTlVMTCk7CgkJCXJldHVybjsKCQl9CgkJaXJpYXNfZGVsZXRlX3ZhbHVlKHZhbHVlKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJSVJEQV9ERUJVRygyLCAiJXMoKSwgdW5rbm93biB0eXBlIVxuIiwgX19GVU5DVElPTl9fICk7CgkJYnJlYWs7Cgl9Cglpcmxhbl9kb19jbGllbnRfZXZlbnQoc2VsZiwgSVJMQU5fSUFTX1BST1ZJREVSX05PVF9BVkFJTCwgTlVMTCk7Cn0K