LyoKICogQ29weXJpZ2h0IChjKSAyMDExIFJvZ2VyIFBhdSBNb25u6SA8cm9nZXIucGF1QGVudGVsLnVwYy5lZHU+CiAqIENvcHlyaWdodCAoYykgMjAxMSBTdGVmYW5vIFNhYmF0aW5pCiAqIENvcHlyaWdodCAoYykgMjAxMyBQYXVsIEIgTWFob2wKICoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgRkZtcGVnLgogKgogKiBGRm1wZWcgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBGRm1wZWcgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggRkZtcGVnOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EKICovCgovKioKICogQGZpbGUKICogQ2FjdWxhdGUgdGhlIFBTTlIgYmV0d2VlbiB0d28gaW5wdXQgdmlkZW9zLgogKi8KCiNpbmNsdWRlICJsaWJhdnV0aWwvb3B0LmgiCiNpbmNsdWRlICJsaWJhdnV0aWwvcGl4ZGVzYy5oIgojaW5jbHVkZSAiYXZmaWx0ZXIuaCIKI2luY2x1ZGUgImR1YWxpbnB1dC5oIgojaW5jbHVkZSAiZHJhd3V0aWxzLmgiCiNpbmNsdWRlICJmb3JtYXRzLmgiCiNpbmNsdWRlICJpbnRlcm5hbC5oIgojaW5jbHVkZSAidmlkZW8uaCIKCnR5cGVkZWYgc3RydWN0IFBTTlJDb250ZXh0IHsKICAgIGNvbnN0IEFWQ2xhc3MgKmNsYXNzOwogICAgRkZEdWFsSW5wdXRDb250ZXh0IGRpbnB1dDsKICAgIGRvdWJsZSBtc2UsIG1pbl9tc2UsIG1heF9tc2U7CiAgICB1aW50NjRfdCBuYl9mcmFtZXM7CiAgICBGSUxFICpzdGF0c19maWxlOwogICAgY2hhciAqc3RhdHNfZmlsZV9zdHI7CiAgICBpbnQgbWF4WzRdLCBhdmVyYWdlX21heDsKICAgIGludCBpc19yZ2I7CiAgICB1aW50OF90IHJnYmFfbWFwWzRdOwogICAgY2hhciBjb21wc1s0XTsKICAgIGludCBuYl9jb21wb25lbnRzOwogICAgaW50IHBsYW5ld2lkdGhbNF07CiAgICBpbnQgcGxhbmVoZWlnaHRbNF07CgogICAgdm9pZCAoKmNvbXB1dGVfbXNlKShzdHJ1Y3QgUFNOUkNvbnRleHQgKnMsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQ4X3QgKm1bNF0sIGNvbnN0IGludCBtbFs0XSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDhfdCAqcls0XSwgY29uc3QgaW50IHJsWzRdLAogICAgICAgICAgICAgICAgICAgICAgICBpbnQgdywgaW50IGgsIGRvdWJsZSBtc2VbNF0pOwp9IFBTTlJDb250ZXh0OwoKI2RlZmluZSBPRkZTRVQoeCkgb2Zmc2V0b2YoUFNOUkNvbnRleHQsIHgpCiNkZWZpbmUgRkxBR1MgQVZfT1BUX0ZMQUdfRklMVEVSSU5HX1BBUkFNfEFWX09QVF9GTEFHX1ZJREVPX1BBUkFNCgpzdGF0aWMgY29uc3QgQVZPcHRpb24gcHNucl9vcHRpb25zW10gPSB7CiAgICB7InN0YXRzX2ZpbGUiLCAiU2V0IGZpbGUgd2hlcmUgdG8gc3RvcmUgcGVyLWZyYW1lIGRpZmZlcmVuY2UgaW5mb3JtYXRpb24iLCBPRkZTRVQoc3RhdHNfZmlsZV9zdHIpLCBBVl9PUFRfVFlQRV9TVFJJTkcsIHsuc3RyPU5VTEx9LCAwLCAwLCBGTEFHUyB9LAogICAgeyJmIiwgICAgICAgICAgIlNldCBmaWxlIHdoZXJlIHRvIHN0b3JlIHBlci1mcmFtZSBkaWZmZXJlbmNlIGluZm9ybWF0aW9uIiwgT0ZGU0VUKHN0YXRzX2ZpbGVfc3RyKSwgQVZfT1BUX1RZUEVfU1RSSU5HLCB7LnN0cj1OVUxMfSwgMCwgMCwgRkxBR1MgfSwKICAgIHsgTlVMTCB9Cn07CgpBVkZJTFRFUl9ERUZJTkVfQ0xBU1MocHNucik7CgpzdGF0aWMgaW5saW5lIHVuc2lnbmVkIHBvdzIodW5zaWduZWQgYmFzZSkKewogICAgcmV0dXJuIGJhc2UqYmFzZTsKfQoKc3RhdGljIGlubGluZSBkb3VibGUgZ2V0X3BzbnIoZG91YmxlIG1zZSwgdWludDY0X3QgbmJfZnJhbWVzLCBpbnQgbWF4KQp7CiAgICByZXR1cm4gMTAuMCAqIGxvZyhwb3cyKG1heCkgLyAobXNlIC8gbmJfZnJhbWVzKSkgLyBsb2coMTAuMCk7Cn0KCnN0YXRpYyBpbmxpbmUKdm9pZCBjb21wdXRlX2ltYWdlc19tc2UoUFNOUkNvbnRleHQgKnMsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQ4X3QgKm1haW5fZGF0YVs0XSwgY29uc3QgaW50IG1haW5fbGluZXNpemVzWzRdLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50OF90ICpyZWZfZGF0YVs0XSwgY29uc3QgaW50IHJlZl9saW5lc2l6ZXNbNF0sCiAgICAgICAgICAgICAgICAgICAgICAgIGludCB3LCBpbnQgaCwgZG91YmxlIG1zZVs0XSkKewogICAgaW50IGksIGMsIGo7CgogICAgZm9yIChjID0gMDsgYyA8IHMtPm5iX2NvbXBvbmVudHM7IGMrKykgewogICAgICAgIGNvbnN0IGludCBvdXR3ID0gcy0+cGxhbmV3aWR0aFtjXTsKICAgICAgICBjb25zdCBpbnQgb3V0aCA9IHMtPnBsYW5laGVpZ2h0W2NdOwogICAgICAgIGNvbnN0IHVpbnQ4X3QgKm1haW5fbGluZSA9IG1haW5fZGF0YVtjXTsKICAgICAgICBjb25zdCB1aW50OF90ICpyZWZfbGluZSA9IHJlZl9kYXRhW2NdOwogICAgICAgIGNvbnN0IGludCByZWZfbGluZXNpemUgPSByZWZfbGluZXNpemVzW2NdOwogICAgICAgIGNvbnN0IGludCBtYWluX2xpbmVzaXplID0gbWFpbl9saW5lc2l6ZXNbY107CiAgICAgICAgdWludDY0X3QgbSA9IDA7CgogICAgICAgIGZvciAoaSA9IDA7IGkgPCBvdXRoOyBpKyspIHsKICAgICAgICAgICAgaW50IG0yID0gMDsKICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IG91dHc7IGorKykKICAgICAgICAgICAgICAgIG0yICs9IHBvdzIobWFpbl9saW5lW2pdIC0gcmVmX2xpbmVbal0pOwogICAgICAgICAgICBtICs9IG0yOwogICAgICAgICAgICByZWZfbGluZSArPSByZWZfbGluZXNpemU7CiAgICAgICAgICAgIG1haW5fbGluZSArPSBtYWluX2xpbmVzaXplOwogICAgICAgIH0KICAgICAgICBtc2VbY10gPSBtIC8gKGRvdWJsZSkob3V0dyAqIG91dGgpOwogICAgfQp9CgpzdGF0aWMgaW5saW5lCnZvaWQgY29tcHV0ZV9pbWFnZXNfbXNlXzE2Yml0KFBTTlJDb250ZXh0ICpzLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50OF90ICptYWluX2RhdGFbNF0sIGNvbnN0IGludCBtYWluX2xpbmVzaXplc1s0XSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDhfdCAqcmVmX2RhdGFbNF0sIGNvbnN0IGludCByZWZfbGluZXNpemVzWzRdLAogICAgICAgICAgICAgICAgICAgICAgICBpbnQgdywgaW50IGgsIGRvdWJsZSBtc2VbNF0pCnsKICAgIGludCBpLCBjLCBqOwoKICAgIGZvciAoYyA9IDA7IGMgPCBzLT5uYl9jb21wb25lbnRzOyBjKyspIHsKICAgICAgICBjb25zdCBpbnQgb3V0dyA9IHMtPnBsYW5ld2lkdGhbY107CiAgICAgICAgY29uc3QgaW50IG91dGggPSBzLT5wbGFuZWhlaWdodFtjXTsKICAgICAgICBjb25zdCB1aW50MTZfdCAqbWFpbl9saW5lID0gKHVpbnQxNl90ICopbWFpbl9kYXRhW2NdOwogICAgICAgIGNvbnN0IHVpbnQxNl90ICpyZWZfbGluZSA9ICh1aW50MTZfdCAqKXJlZl9kYXRhW2NdOwogICAgICAgIGNvbnN0IGludCByZWZfbGluZXNpemUgPSByZWZfbGluZXNpemVzW2NdIC8gMjsKICAgICAgICBjb25zdCBpbnQgbWFpbl9saW5lc2l6ZSA9IG1haW5fbGluZXNpemVzW2NdIC8gMjsKICAgICAgICB1aW50NjRfdCBtID0gMDsKCiAgICAgICAgZm9yIChpID0gMDsgaSA8IG91dGg7IGkrKykgewogICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgb3V0dzsgaisrKQogICAgICAgICAgICAgICAgbSArPSBwb3cyKG1haW5fbGluZVtqXSAtIHJlZl9saW5lW2pdKTsKICAgICAgICAgICAgcmVmX2xpbmUgKz0gcmVmX2xpbmVzaXplOwogICAgICAgICAgICBtYWluX2xpbmUgKz0gbWFpbl9saW5lc2l6ZTsKICAgICAgICB9CiAgICAgICAgbXNlW2NdID0gbSAvIChkb3VibGUpKG91dHcgKiBvdXRoKTsKICAgIH0KfQoKc3RhdGljIHZvaWQgc2V0X21ldGEoQVZEaWN0aW9uYXJ5ICoqbWV0YWRhdGEsIGNvbnN0IGNoYXIgKmtleSwgY2hhciBjb21wLCBmbG9hdCBkKQp7CiAgICBjaGFyIHZhbHVlWzEyOF07CiAgICBzbnByaW50Zih2YWx1ZSwgc2l6ZW9mKHZhbHVlKSwgIiUwLjJmIiwgZCk7CiAgICBpZiAoY29tcCkgewogICAgICAgIGNoYXIga2V5MlsxMjhdOwogICAgICAgIHNucHJpbnRmKGtleTIsIHNpemVvZihrZXkyKSwgIiVzJWMiLCBrZXksIGNvbXApOwogICAgICAgIGF2X2RpY3Rfc2V0KG1ldGFkYXRhLCBrZXkyLCB2YWx1ZSwgMCk7CiAgICB9IGVsc2UgewogICAgICAgIGF2X2RpY3Rfc2V0KG1ldGFkYXRhLCBrZXksIHZhbHVlLCAwKTsKICAgIH0KfQoKc3RhdGljIEFWRnJhbWUgKmRvX3BzbnIoQVZGaWx0ZXJDb250ZXh0ICpjdHgsIEFWRnJhbWUgKm1haW4sCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFWRnJhbWUgKnJlZikKewogICAgUFNOUkNvbnRleHQgKnMgPSBjdHgtPnByaXY7CiAgICBkb3VibGUgY29tcF9tc2VbNF0sIG1zZSA9IDA7CiAgICBpbnQgaiwgYzsKICAgIEFWRGljdGlvbmFyeSAqKm1ldGFkYXRhID0gYXZwcml2X2ZyYW1lX2dldF9tZXRhZGF0YXAobWFpbik7CgogICAgcy0+Y29tcHV0ZV9tc2UocywgKGNvbnN0IHVpbnQ4X3QgKiopbWFpbi0+ZGF0YSwgbWFpbi0+bGluZXNpemUsCiAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgdWludDhfdCAqKilyZWYtPmRhdGEsIHJlZi0+bGluZXNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgbWFpbi0+d2lkdGgsIG1haW4tPmhlaWdodCwgY29tcF9tc2UpOwoKICAgIGZvciAoaiA9IDA7IGogPCBzLT5uYl9jb21wb25lbnRzOyBqKyspCiAgICAgICAgbXNlICs9IGNvbXBfbXNlW2pdOwogICAgbXNlIC89IHMtPm5iX2NvbXBvbmVudHM7CgogICAgcy0+bWluX21zZSA9IEZGTUlOKHMtPm1pbl9tc2UsIG1zZSk7CiAgICBzLT5tYXhfbXNlID0gRkZNQVgocy0+bWF4X21zZSwgbXNlKTsKCiAgICBzLT5tc2UgKz0gbXNlOwogICAgcy0+bmJfZnJhbWVzKys7CgogICAgZm9yIChqID0gMDsgaiA8IHMtPm5iX2NvbXBvbmVudHM7IGorKykgewogICAgICAgIGMgPSBzLT5pc19yZ2IgPyBzLT5yZ2JhX21hcFtqXSA6IGo7CiAgICAgICAgc2V0X21ldGEobWV0YWRhdGEsICJsYXZmaS5wc25yLm1zZS4iLCBzLT5jb21wc1tqXSwgY29tcF9tc2VbY10pOwogICAgICAgIHNldF9tZXRhKG1ldGFkYXRhLCAibGF2ZmkucHNuci5tc2VfYXZnIiwgMCwgbXNlKTsKICAgICAgICBzZXRfbWV0YShtZXRhZGF0YSwgImxhdmZpLnBzbnIucHNuci4iLCBzLT5jb21wc1tqXSwgZ2V0X3BzbnIoY29tcF9tc2VbY10sIDEsIHMtPm1heFtjXSkpOwogICAgICAgIHNldF9tZXRhKG1ldGFkYXRhLCAibGF2ZmkucHNuci5wc25yX2F2ZyIsIDAsIGdldF9wc25yKG1zZSwgMSwgcy0+YXZlcmFnZV9tYXgpKTsKICAgIH0KCiAgICBpZiAocy0+c3RhdHNfZmlsZSkgewogICAgICAgIGZwcmludGYocy0+c3RhdHNfZmlsZSwgIm46JSJQUklkNjQiIG1zZV9hdmc6JTAuMmYgIiwgcy0+bmJfZnJhbWVzLCBtc2UpOwogICAgICAgIGZvciAoaiA9IDA7IGogPCBzLT5uYl9jb21wb25lbnRzOyBqKyspIHsKICAgICAgICAgICAgYyA9IHMtPmlzX3JnYiA/IHMtPnJnYmFfbWFwW2pdIDogajsKICAgICAgICAgICAgZnByaW50ZihzLT5zdGF0c19maWxlLCAibXNlXyVjOiUwLjJmICIsIHMtPmNvbXBzW2pdLCBjb21wX21zZVtjXSk7CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDA7IGogPCBzLT5uYl9jb21wb25lbnRzOyBqKyspIHsKICAgICAgICAgICAgYyA9IHMtPmlzX3JnYiA/IHMtPnJnYmFfbWFwW2pdIDogajsKICAgICAgICAgICAgZnByaW50ZihzLT5zdGF0c19maWxlLCAicHNucl8lYzolMC4yZiAiLCBzLT5jb21wc1tqXSwKICAgICAgICAgICAgICAgICAgICBnZXRfcHNucihjb21wX21zZVtjXSwgMSwgcy0+bWF4W2NdKSk7CiAgICAgICAgfQogICAgICAgIGZwcmludGYocy0+c3RhdHNfZmlsZSwgIlxuIik7CiAgICB9CgogICAgcmV0dXJuIG1haW47Cn0KCnN0YXRpYyBhdl9jb2xkIGludCBpbml0KEFWRmlsdGVyQ29udGV4dCAqY3R4KQp7CiAgICBQU05SQ29udGV4dCAqcyA9IGN0eC0+cHJpdjsKCiAgICBzLT5taW5fbXNlID0gK0lORklOSVRZOwogICAgcy0+bWF4X21zZSA9IC1JTkZJTklUWTsKCiAgICBpZiAocy0+c3RhdHNfZmlsZV9zdHIpIHsKICAgICAgICBzLT5zdGF0c19maWxlID0gZm9wZW4ocy0+c3RhdHNfZmlsZV9zdHIsICJ3Iik7CiAgICAgICAgaWYgKCFzLT5zdGF0c19maWxlKSB7CiAgICAgICAgICAgIGludCBlcnIgPSBBVkVSUk9SKGVycm5vKTsKICAgICAgICAgICAgY2hhciBidWZbMTI4XTsKICAgICAgICAgICAgYXZfc3RyZXJyb3IoZXJyLCBidWYsIHNpemVvZihidWYpKTsKICAgICAgICAgICAgYXZfbG9nKGN0eCwgQVZfTE9HX0VSUk9SLCAiQ291bGQgbm90IG9wZW4gc3RhdHMgZmlsZSAlczogJXNcbiIsCiAgICAgICAgICAgICAgICAgICBzLT5zdGF0c19maWxlX3N0ciwgYnVmKTsKICAgICAgICAgICAgcmV0dXJuIGVycjsKICAgICAgICB9CiAgICB9CgogICAgcy0+ZGlucHV0LnByb2Nlc3MgPSBkb19wc25yOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcXVlcnlfZm9ybWF0cyhBVkZpbHRlckNvbnRleHQgKmN0eCkKewogICAgc3RhdGljIGNvbnN0IGVudW0gQVZQaXhlbEZvcm1hdCBwaXhfZm10c1tdID0gewogICAgICAgIEFWX1BJWF9GTVRfR1JBWTgsIEFWX1BJWF9GTVRfR1JBWTE2LAojZGVmaW5lIFBGX05PQUxQSEEoc3VmKSBBVl9QSVhfRk1UX1lVVjQyMCMjc3VmLCAgQVZfUElYX0ZNVF9ZVVY0MjIjI3N1ZiwgIEFWX1BJWF9GTVRfWVVWNDQ0IyNzdWYKI2RlZmluZSBQRl9BTFBIQShzdWYpICAgQVZfUElYX0ZNVF9ZVVZBNDIwIyNzdWYsIEFWX1BJWF9GTVRfWVVWQTQyMiMjc3VmLCBBVl9QSVhfRk1UX1lVVkE0NDQjI3N1ZgojZGVmaW5lIFBGKHN1ZikgICAgICAgICBQRl9OT0FMUEhBKHN1ZiksIFBGX0FMUEhBKHN1ZikKICAgICAgICBQRihQKSwgUEYoUDkpLCBQRihQMTApLCBQRl9OT0FMUEhBKFAxMiksIFBGX05PQUxQSEEoUDE0KSwgUEYoUDE2KSwKICAgICAgICBBVl9QSVhfRk1UX1lVVjQ0MFAsIEFWX1BJWF9GTVRfWVVWNDExUCwgQVZfUElYX0ZNVF9ZVVY0MTBQLAogICAgICAgIEFWX1BJWF9GTVRfWVVWSjQxMVAsIEFWX1BJWF9GTVRfWVVWSjQyMFAsIEFWX1BJWF9GTVRfWVVWSjQyMlAsCiAgICAgICAgQVZfUElYX0ZNVF9ZVVZKNDQwUCwgQVZfUElYX0ZNVF9ZVVZKNDQ0UCwKICAgICAgICBBVl9QSVhfRk1UX0dCUlAsIEFWX1BJWF9GTVRfR0JSUDksIEFWX1BJWF9GTVRfR0JSUDEwLAogICAgICAgIEFWX1BJWF9GTVRfR0JSUDEyLCBBVl9QSVhfRk1UX0dCUlAxNCwgQVZfUElYX0ZNVF9HQlJQMTYsCiAgICAgICAgQVZfUElYX0ZNVF9HQlJBUCwgQVZfUElYX0ZNVF9HQlJBUDE2LAogICAgICAgIEFWX1BJWF9GTVRfTk9ORQogICAgfTsKCiAgICBBVkZpbHRlckZvcm1hdHMgKmZtdHNfbGlzdCA9IGZmX21ha2VfZm9ybWF0X2xpc3QocGl4X2ZtdHMpOwogICAgaWYgKCFmbXRzX2xpc3QpCiAgICAgICAgcmV0dXJuIEFWRVJST1IoRU5PTUVNKTsKICAgIHJldHVybiBmZl9zZXRfY29tbW9uX2Zvcm1hdHMoY3R4LCBmbXRzX2xpc3QpOwp9CgpzdGF0aWMgaW50IGNvbmZpZ19pbnB1dF9yZWYoQVZGaWx0ZXJMaW5rICppbmxpbmspCnsKICAgIGNvbnN0IEFWUGl4Rm10RGVzY3JpcHRvciAqZGVzYyA9IGF2X3BpeF9mbXRfZGVzY19nZXQoaW5saW5rLT5mb3JtYXQpOwogICAgQVZGaWx0ZXJDb250ZXh0ICpjdHggID0gaW5saW5rLT5kc3Q7CiAgICBQU05SQ29udGV4dCAqcyA9IGN0eC0+cHJpdjsKICAgIGludCBqOwoKICAgIHMtPm5iX2NvbXBvbmVudHMgPSBkZXNjLT5uYl9jb21wb25lbnRzOwogICAgaWYgKGN0eC0+aW5wdXRzWzBdLT53ICE9IGN0eC0+aW5wdXRzWzFdLT53IHx8CiAgICAgICAgY3R4LT5pbnB1dHNbMF0tPmggIT0gY3R4LT5pbnB1dHNbMV0tPmgpIHsKICAgICAgICBhdl9sb2coY3R4LCBBVl9MT0dfRVJST1IsICJXaWR0aCBhbmQgaGVpZ2h0IG9mIGlucHV0IHZpZGVvcyBtdXN0IGJlIHNhbWUuXG4iKTsKICAgICAgICByZXR1cm4gQVZFUlJPUihFSU5WQUwpOwogICAgfQogICAgaWYgKGN0eC0+aW5wdXRzWzBdLT5mb3JtYXQgIT0gY3R4LT5pbnB1dHNbMV0tPmZvcm1hdCkgewogICAgICAgIGF2X2xvZyhjdHgsIEFWX0xPR19FUlJPUiwgIklucHV0cyBtdXN0IGJlIG9mIHNhbWUgcGl4ZWwgZm9ybWF0LlxuIik7CiAgICAgICAgcmV0dXJuIEFWRVJST1IoRUlOVkFMKTsKICAgIH0KCiAgICBzd2l0Y2ggKGlubGluay0+Zm9ybWF0KSB7CiAgICBjYXNlIEFWX1BJWF9GTVRfR1JBWTg6CiAgICBjYXNlIEFWX1BJWF9GTVRfR1JBWTE2OgogICAgY2FzZSBBVl9QSVhfRk1UX0dCUlA6CiAgICBjYXNlIEFWX1BJWF9GTVRfR0JSUDk6CiAgICBjYXNlIEFWX1BJWF9GTVRfR0JSUDEwOgogICAgY2FzZSBBVl9QSVhfRk1UX0dCUlAxMjoKICAgIGNhc2UgQVZfUElYX0ZNVF9HQlJQMTQ6CiAgICBjYXNlIEFWX1BJWF9GTVRfR0JSUDE2OgogICAgY2FzZSBBVl9QSVhfRk1UX0dCUkFQOgogICAgY2FzZSBBVl9QSVhfRk1UX0dCUkFQMTY6CiAgICBjYXNlIEFWX1BJWF9GTVRfWVVWSjQxMVA6CiAgICBjYXNlIEFWX1BJWF9GTVRfWVVWSjQyMFA6CiAgICBjYXNlIEFWX1BJWF9GTVRfWVVWSjQyMlA6CiAgICBjYXNlIEFWX1BJWF9GTVRfWVVWSjQ0MFA6CiAgICBjYXNlIEFWX1BJWF9GTVRfWVVWSjQ0NFA6CiAgICAgICAgcy0+bWF4WzBdID0gKDEgPDwgKGRlc2MtPmNvbXBbMF0uZGVwdGhfbWludXMxICsgMSkpIC0gMTsKICAgICAgICBzLT5tYXhbMV0gPSAoMSA8PCAoZGVzYy0+Y29tcFsxXS5kZXB0aF9taW51czEgKyAxKSkgLSAxOwogICAgICAgIHMtPm1heFsyXSA9ICgxIDw8IChkZXNjLT5jb21wWzJdLmRlcHRoX21pbnVzMSArIDEpKSAtIDE7CiAgICAgICAgcy0+bWF4WzNdID0gKDEgPDwgKGRlc2MtPmNvbXBbM10uZGVwdGhfbWludXMxICsgMSkpIC0gMTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgcy0+bWF4WzBdID0gMjM1ICogKDEgPDwgKGRlc2MtPmNvbXBbMF0uZGVwdGhfbWludXMxIC0gNykpOwogICAgICAgIHMtPm1heFsxXSA9IDI0MCAqICgxIDw8IChkZXNjLT5jb21wWzFdLmRlcHRoX21pbnVzMSAtIDcpKTsKICAgICAgICBzLT5tYXhbMl0gPSAyNDAgKiAoMSA8PCAoZGVzYy0+Y29tcFsyXS5kZXB0aF9taW51czEgLSA3KSk7CiAgICAgICAgcy0+bWF4WzNdID0gKDEgPDwgKGRlc2MtPmNvbXBbM10uZGVwdGhfbWludXMxICsgMSkpIC0gMTsKICAgIH0KCiAgICBzLT5pc19yZ2IgPSBmZl9maWxsX3JnYmFfbWFwKHMtPnJnYmFfbWFwLCBpbmxpbmstPmZvcm1hdCkgPj0gMDsKICAgIHMtPmNvbXBzWzBdID0gcy0+aXNfcmdiID8gJ3InIDogJ3knIDsKICAgIHMtPmNvbXBzWzFdID0gcy0+aXNfcmdiID8gJ2cnIDogJ3UnIDsKICAgIHMtPmNvbXBzWzJdID0gcy0+aXNfcmdiID8gJ2InIDogJ3YnIDsKICAgIHMtPmNvbXBzWzNdID0gJ2EnOwoKICAgIGZvciAoaiA9IDA7IGogPCBzLT5uYl9jb21wb25lbnRzOyBqKyspCiAgICAgICAgcy0+YXZlcmFnZV9tYXggKz0gcy0+bWF4W2pdOwogICAgcy0+YXZlcmFnZV9tYXggLz0gcy0+bmJfY29tcG9uZW50czsKCiAgICBzLT5wbGFuZWhlaWdodFsxXSA9IHMtPnBsYW5laGVpZ2h0WzJdID0gRkZfQ0VJTF9SU0hJRlQoaW5saW5rLT5oLCBkZXNjLT5sb2cyX2Nocm9tYV9oKTsKICAgIHMtPnBsYW5laGVpZ2h0WzBdID0gcy0+cGxhbmVoZWlnaHRbM10gPSBpbmxpbmstPmg7CiAgICBzLT5wbGFuZXdpZHRoWzFdICA9IHMtPnBsYW5ld2lkdGhbMl0gID0gRkZfQ0VJTF9SU0hJRlQoaW5saW5rLT53LCBkZXNjLT5sb2cyX2Nocm9tYV93KTsKICAgIHMtPnBsYW5ld2lkdGhbMF0gID0gcy0+cGxhbmV3aWR0aFszXSAgPSBpbmxpbmstPnc7CgogICAgcy0+Y29tcHV0ZV9tc2UgPSBkZXNjLT5jb21wWzBdLmRlcHRoX21pbnVzMSA+IDcgPyBjb21wdXRlX2ltYWdlc19tc2VfMTZiaXQgOiBjb21wdXRlX2ltYWdlc19tc2U7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgY29uZmlnX291dHB1dChBVkZpbHRlckxpbmsgKm91dGxpbmspCnsKICAgIEFWRmlsdGVyQ29udGV4dCAqY3R4ID0gb3V0bGluay0+c3JjOwogICAgUFNOUkNvbnRleHQgKnMgPSBjdHgtPnByaXY7CiAgICBBVkZpbHRlckxpbmsgKm1haW5saW5rID0gY3R4LT5pbnB1dHNbMF07CiAgICBpbnQgcmV0OwoKICAgIG91dGxpbmstPncgPSBtYWlubGluay0+dzsKICAgIG91dGxpbmstPmggPSBtYWlubGluay0+aDsKICAgIG91dGxpbmstPnRpbWVfYmFzZSA9IG1haW5saW5rLT50aW1lX2Jhc2U7CiAgICBvdXRsaW5rLT5zYW1wbGVfYXNwZWN0X3JhdGlvID0gbWFpbmxpbmstPnNhbXBsZV9hc3BlY3RfcmF0aW87CiAgICBvdXRsaW5rLT5mcmFtZV9yYXRlID0gbWFpbmxpbmstPmZyYW1lX3JhdGU7CiAgICBpZiAoKHJldCA9IGZmX2R1YWxpbnB1dF9pbml0KGN0eCwgJnMtPmRpbnB1dCkpIDwgMCkKICAgICAgICByZXR1cm4gcmV0OwoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50IGZpbHRlcl9mcmFtZShBVkZpbHRlckxpbmsgKmlubGluaywgQVZGcmFtZSAqaW5waWNyZWYpCnsKICAgIFBTTlJDb250ZXh0ICpzID0gaW5saW5rLT5kc3QtPnByaXY7CiAgICByZXR1cm4gZmZfZHVhbGlucHV0X2ZpbHRlcl9mcmFtZSgmcy0+ZGlucHV0LCBpbmxpbmssIGlucGljcmVmKTsKfQoKc3RhdGljIGludCByZXF1ZXN0X2ZyYW1lKEFWRmlsdGVyTGluayAqb3V0bGluaykKewogICAgUFNOUkNvbnRleHQgKnMgPSBvdXRsaW5rLT5zcmMtPnByaXY7CiAgICByZXR1cm4gZmZfZHVhbGlucHV0X3JlcXVlc3RfZnJhbWUoJnMtPmRpbnB1dCwgb3V0bGluayk7Cn0KCnN0YXRpYyBhdl9jb2xkIHZvaWQgdW5pbml0KEFWRmlsdGVyQ29udGV4dCAqY3R4KQp7CiAgICBQU05SQ29udGV4dCAqcyA9IGN0eC0+cHJpdjsKCiAgICBpZiAocy0+bmJfZnJhbWVzID4gMCkgewogICAgICAgIGF2X2xvZyhjdHgsIEFWX0xPR19JTkZPLCAiUFNOUiBhdmVyYWdlOiUwLjJmIG1pbjolMC4yZiBtYXg6JTAuMmZcbiIsCiAgICAgICAgICAgICAgIGdldF9wc25yKHMtPm1zZSwgcy0+bmJfZnJhbWVzLCBzLT5hdmVyYWdlX21heCksCiAgICAgICAgICAgICAgIGdldF9wc25yKHMtPm1heF9tc2UsIDEsIHMtPmF2ZXJhZ2VfbWF4KSwKICAgICAgICAgICAgICAgZ2V0X3BzbnIocy0+bWluX21zZSwgMSwgcy0+YXZlcmFnZV9tYXgpKTsKICAgIH0KCiAgICBmZl9kdWFsaW5wdXRfdW5pbml0KCZzLT5kaW5wdXQpOwoKICAgIGlmIChzLT5zdGF0c19maWxlKQogICAgICAgIGZjbG9zZShzLT5zdGF0c19maWxlKTsKfQoKc3RhdGljIGNvbnN0IEFWRmlsdGVyUGFkIHBzbnJfaW5wdXRzW10gPSB7CiAgICB7CiAgICAgICAgLm5hbWUgICAgICAgICA9ICJtYWluIiwKICAgICAgICAudHlwZSAgICAgICAgID0gQVZNRURJQV9UWVBFX1ZJREVPLAogICAgICAgIC5maWx0ZXJfZnJhbWUgPSBmaWx0ZXJfZnJhbWUsCiAgICB9LHsKICAgICAgICAubmFtZSAgICAgICAgID0gInJlZmVyZW5jZSIsCiAgICAgICAgLnR5cGUgICAgICAgICA9IEFWTUVESUFfVFlQRV9WSURFTywKICAgICAgICAuZmlsdGVyX2ZyYW1lID0gZmlsdGVyX2ZyYW1lLAogICAgICAgIC5jb25maWdfcHJvcHMgPSBjb25maWdfaW5wdXRfcmVmLAogICAgfSwKICAgIHsgTlVMTCB9Cn07CgpzdGF0aWMgY29uc3QgQVZGaWx0ZXJQYWQgcHNucl9vdXRwdXRzW10gPSB7CiAgICB7CiAgICAgICAgLm5hbWUgICAgICAgICAgPSAiZGVmYXVsdCIsCiAgICAgICAgLnR5cGUgICAgICAgICAgPSBBVk1FRElBX1RZUEVfVklERU8sCiAgICAgICAgLmNvbmZpZ19wcm9wcyAgPSBjb25maWdfb3V0cHV0LAogICAgICAgIC5yZXF1ZXN0X2ZyYW1lID0gcmVxdWVzdF9mcmFtZSwKICAgIH0sCiAgICB7IE5VTEwgfQp9OwoKQVZGaWx0ZXIgZmZfdmZfcHNuciA9IHsKICAgIC5uYW1lICAgICAgICAgID0gInBzbnIiLAogICAgLmRlc2NyaXB0aW9uICAgPSBOVUxMX0lGX0NPTkZJR19TTUFMTCgiQ2FsY3VsYXRlIHRoZSBQU05SIGJldHdlZW4gdHdvIHZpZGVvIHN0cmVhbXMuIiksCiAgICAuaW5pdCAgICAgICAgICA9IGluaXQsCiAgICAudW5pbml0ICAgICAgICA9IHVuaW5pdCwKICAgIC5xdWVyeV9mb3JtYXRzID0gcXVlcnlfZm9ybWF0cywKICAgIC5wcml2X3NpemUgICAgID0gc2l6ZW9mKFBTTlJDb250ZXh0KSwKICAgIC5wcml2X2NsYXNzICAgID0gJnBzbnJfY2xhc3MsCiAgICAuaW5wdXRzICAgICAgICA9IHBzbnJfaW5wdXRzLAogICAgLm91dHB1dHMgICAgICAgPSBwc25yX291dHB1dHMsCn07Cg==