LyoKICogIGxpbnV4L2tlcm5lbC9zeXMuYwogKgogKiAgQ29weXJpZ2h0IChDKSAxOTkxLCAxOTkyICBMaW51cyBUb3J2YWxkcwogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21tLmg+CiNpbmNsdWRlIDxsaW51eC91dHNuYW1lLmg+CiNpbmNsdWRlIDxsaW51eC9tbWFuLmg+CiNpbmNsdWRlIDxsaW51eC9zbXBfbG9jay5oPgojaW5jbHVkZSA8bGludXgvbm90aWZpZXIuaD4KI2luY2x1ZGUgPGxpbnV4L3JlYm9vdC5oPgojaW5jbHVkZSA8bGludXgvcHJjdGwuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2hpZ2h1aWQuaD4KCiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CgojaWZuZGVmIFNFVF9VTkFMSUdOX0NUTAojIGRlZmluZSBTRVRfVU5BTElHTl9DVEwoYSxiKQkoLUVJTlZBTCkKI2VuZGlmCiNpZm5kZWYgR0VUX1VOQUxJR05fQ1RMCiMgZGVmaW5lIEdFVF9VTkFMSUdOX0NUTChhLGIpCSgtRUlOVkFMKQojZW5kaWYKI2lmbmRlZiBTRVRfRlBFTVVfQ1RMCiMgZGVmaW5lIFNFVF9GUEVNVV9DVEwoYSxiKQkoLUVJTlZBTCkKI2VuZGlmCiNpZm5kZWYgR0VUX0ZQRU1VX0NUTAojIGRlZmluZSBHRVRfRlBFTVVfQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgojaWZuZGVmIFNFVF9GUEVYQ19DVEwKIyBkZWZpbmUgU0VUX0ZQRVhDX0NUTChhLGIpCSgtRUlOVkFMKQojZW5kaWYKI2lmbmRlZiBHRVRfRlBFWENfQ1RMCiMgZGVmaW5lIEdFVF9GUEVYQ19DVEwoYSxiKQkoLUVJTlZBTCkKI2VuZGlmCgovKgogKiB0aGlzIGlzIHdoZXJlIHRoZSBzeXN0ZW0td2lkZSBvdmVyZmxvdyBVSUQgYW5kIEdJRCBhcmUgZGVmaW5lZCwgZm9yCiAqIGFyY2hpdGVjdHVyZXMgdGhhdCBub3cgaGF2ZSAzMi1iaXQgVUlEL0dJRCBidXQgZGlkbid0IGluIHRoZSBwYXN0CiAqLwoKaW50IG92ZXJmbG93dWlkID0gREVGQVVMVF9PVkVSRkxPV1VJRDsKaW50IG92ZXJmbG93Z2lkID0gREVGQVVMVF9PVkVSRkxPV0dJRDsKCi8qCiAqIHRoZSBzYW1lIGFzIGFib3ZlLCBidXQgZm9yIGZpbGVzeXN0ZW1zIHdoaWNoIGNhbiBvbmx5IHN0b3JlIGEgMTYtYml0CiAqIFVJRCBhbmQgR0lELiBhcyBzdWNoLCB0aGlzIGlzIG5lZWRlZCBvbiBhbGwgYXJjaGl0ZWN0dXJlcwogKi8KCmludCBmc19vdmVyZmxvd3VpZCA9IERFRkFVTFRfRlNfT1ZFUkZMT1dVSUQ7CmludCBmc19vdmVyZmxvd2dpZCA9IERFRkFVTFRfRlNfT1ZFUkZMT1dVSUQ7CgovKgogKiB0aGlzIGluZGljYXRlcyB3aGV0aGVyIHlvdSBjYW4gcmVib290IHdpdGggY3RybC1hbHQtZGVsOiB0aGUgZGVmYXVsdCBpcyB5ZXMKICovCgppbnQgQ19BX0QgPSAxOwppbnQgY2FkX3BpZCA9IDE7CgoKLyoKICoJTm90aWZpZXIgbGlzdCBmb3Iga2VybmVsIGNvZGUgd2hpY2ggd2FudHMgdG8gYmUgY2FsbGVkCiAqCWF0IHNodXRkb3duLiBUaGlzIGlzIHVzZWQgdG8gc3RvcCBhbnkgaWRsaW5nIERNQSBvcGVyYXRpb25zCiAqCWFuZCB0aGUgbGlrZS4gCiAqLwoKc3RhdGljIHN0cnVjdCBub3RpZmllcl9ibG9jayAqcmVib290X25vdGlmaWVyX2xpc3Q7CnJ3bG9ja190IG5vdGlmaWVyX2xvY2sgPSBSV19MT0NLX1VOTE9DS0VEOwoKLyoqCiAqCW5vdGlmaWVyX2NoYWluX3JlZ2lzdGVyCS0gQWRkIG5vdGlmaWVyIHRvIGEgbm90aWZpZXIgY2hhaW4KICoJQGxpc3Q6IFBvaW50ZXIgdG8gcm9vdCBsaXN0IHBvaW50ZXIKICoJQG46IE5ldyBlbnRyeSBpbiBub3RpZmllciBjaGFpbgogKgogKglBZGRzIGEgbm90aWZpZXIgdG8gYSBub3RpZmllciBjaGFpbi4KICoKICoJQ3VycmVudGx5IGFsd2F5cyByZXR1cm5zIHplcm8uCiAqLwogCmludCBub3RpZmllcl9jaGFpbl9yZWdpc3RlcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKipsaXN0LCBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm4pCnsKCXdyaXRlX2xvY2soJm5vdGlmaWVyX2xvY2spOwoJd2hpbGUoKmxpc3QpCgl7CgkJaWYobi0+cHJpb3JpdHkgPiAoKmxpc3QpLT5wcmlvcml0eSkKCQkJYnJlYWs7CgkJbGlzdD0gJigoKmxpc3QpLT5uZXh0KTsKCX0KCW4tPm5leHQgPSAqbGlzdDsKCSpsaXN0PW47Cgl3cml0ZV91bmxvY2soJm5vdGlmaWVyX2xvY2spOwoJcmV0dXJuIDA7Cn0KCi8qKgogKglub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyIC0gUmVtb3ZlIG5vdGlmaWVyIGZyb20gYSBub3RpZmllciBjaGFpbgogKglAbmw6IFBvaW50ZXIgdG8gcm9vdCBsaXN0IHBvaW50ZXIKICoJQG46IE5ldyBlbnRyeSBpbiBub3RpZmllciBjaGFpbgogKgogKglSZW1vdmVzIGEgbm90aWZpZXIgZnJvbSBhIG5vdGlmaWVyIGNoYWluLgogKgogKglSZXR1cm5zIHplcm8gb24gc3VjY2Vzcywgb3IgJS1FTk9FTlQgb24gZmFpbHVyZS4KICovCiAKaW50IG5vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICoqbmwsIHN0cnVjdCBub3RpZmllcl9ibG9jayAqbikKewoJd3JpdGVfbG9jaygmbm90aWZpZXJfbG9jayk7Cgl3aGlsZSgoKm5sKSE9TlVMTCkKCXsKCQlpZigoKm5sKT09bikKCQl7CgkJCSpubD1uLT5uZXh0OwoJCQl3cml0ZV91bmxvY2soJm5vdGlmaWVyX2xvY2spOwoJCQlyZXR1cm4gMDsKCQl9CgkJbmw9JigoKm5sKS0+bmV4dCk7Cgl9Cgl3cml0ZV91bmxvY2soJm5vdGlmaWVyX2xvY2spOwoJcmV0dXJuIC1FTk9FTlQ7Cn0KCi8qKgogKglub3RpZmllcl9jYWxsX2NoYWluIC0gQ2FsbCBmdW5jdGlvbnMgaW4gYSBub3RpZmllciBjaGFpbgogKglAbjogUG9pbnRlciB0byByb290IHBvaW50ZXIgb2Ygbm90aWZpZXIgY2hhaW4KICoJQHZhbDogVmFsdWUgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoJQHY6IFBvaW50ZXIgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoKICoJQ2FsbHMgZWFjaCBmdW5jdGlvbiBpbiBhIG5vdGlmaWVyIGNoYWluIGluIHR1cm4uCiAqCiAqCUlmIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIG5vdGlmaWVyIGNhbiBiZSBhbmQnZAogKgl3aXRoICVOT1RJRllfU1RPUF9NQVNLLCB0aGVuIG5vdGlmaWVyX2NhbGxfY2hhaW4KICoJd2lsbCByZXR1cm4gaW1tZWRpYXRlbHksIHdpdGggdGhlIHJldHVybiB2YWx1ZSBvZgogKgl0aGUgbm90aWZpZXIgZnVuY3Rpb24gd2hpY2ggaGFsdGVkIGV4ZWN1dGlvbi4KICoJT3RoZXJ3aXNlLCB0aGUgcmV0dXJuIHZhbHVlIGlzIHRoZSByZXR1cm4gdmFsdWUKICoJb2YgdGhlIGxhc3Qgbm90aWZpZXIgZnVuY3Rpb24gY2FsbGVkLgogKi8KIAppbnQgbm90aWZpZXJfY2FsbF9jaGFpbihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKipuLCB1bnNpZ25lZCBsb25nIHZhbCwgdm9pZCAqdikKewoJaW50IHJldD1OT1RJRllfRE9ORTsKCXN0cnVjdCBub3RpZmllcl9ibG9jayAqbmIgPSAqbjsKCgl3aGlsZShuYikKCXsKCQlyZXQ9bmItPm5vdGlmaWVyX2NhbGwobmIsdmFsLHYpOwoJCWlmKHJldCZOT1RJRllfU1RPUF9NQVNLKQoJCXsKCQkJcmV0dXJuIHJldDsKCQl9CgkJbmI9bmItPm5leHQ7Cgl9CglyZXR1cm4gcmV0Owp9CgovKioKICoJcmVnaXN0ZXJfcmVib290X25vdGlmaWVyIC0gUmVnaXN0ZXIgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIGF0IHJlYm9vdCB0aW1lCiAqCUBuYjogSW5mbyBhYm91dCBub3RpZmllciBmdW5jdGlvbiB0byBiZSBjYWxsZWQKICoKICoJUmVnaXN0ZXJzIGEgZnVuY3Rpb24gd2l0aCB0aGUgbGlzdCBvZiBmdW5jdGlvbnMKICoJdG8gYmUgY2FsbGVkIGF0IHJlYm9vdCB0aW1lLgogKgogKglDdXJyZW50bHkgYWx3YXlzIHJldHVybnMgemVybywgYXMgbm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIKICoJYWx3YXlzIHJldHVybnMgemVyby4KICovCiAKaW50IHJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKiBuYikKewoJcmV0dXJuIG5vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwgbmIpOwp9CgovKioKICoJdW5yZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIgLSBVbnJlZ2lzdGVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCByZWJvb3Qgbm90aWZpZXIKICoJQG5iOiBIb29rIHRvIGJlIHVucmVnaXN0ZXJlZAogKgogKglVbnJlZ2lzdGVycyBhIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCByZWJvb3QKICoJbm90aWZpZXIgZnVuY3Rpb24uCiAqCiAqCVJldHVybnMgemVybyBvbiBzdWNjZXNzLCBvciAlLUVOT0VOVCBvbiBmYWlsdXJlLgogKi8KIAppbnQgdW5yZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICogbmIpCnsKCXJldHVybiBub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwgbmIpOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX25pX3N5c2NhbGwodm9pZCkKewoJcmV0dXJuIC1FTk9TWVM7Cn0KCnN0YXRpYyBpbnQgcHJvY19zZWwoc3RydWN0IHRhc2tfc3RydWN0ICpwLCBpbnQgd2hpY2gsIGludCB3aG8pCnsKCWlmKHAtPnBpZCkKCXsKCQlzd2l0Y2ggKHdoaWNoKSB7CgkJCWNhc2UgUFJJT19QUk9DRVNTOgoJCQkJaWYgKCF3aG8gJiYgcCA9PSBjdXJyZW50KQoJCQkJCXJldHVybiAxOwoJCQkJcmV0dXJuKHAtPnBpZCA9PSB3aG8pOwoJCQljYXNlIFBSSU9fUEdSUDoKCQkJCWlmICghd2hvKQoJCQkJCXdobyA9IGN1cnJlbnQtPnBncnA7CgkJCQlyZXR1cm4ocC0+cGdycCA9PSB3aG8pOwoJCQljYXNlIFBSSU9fVVNFUjoKCQkJCWlmICghd2hvKQoJCQkJCXdobyA9IGN1cnJlbnQtPnVpZDsKCQkJCXJldHVybihwLT51aWQgPT0gd2hvKTsKCQl9Cgl9CglyZXR1cm4gMDsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19zZXRwcmlvcml0eShpbnQgd2hpY2gsIGludCB3aG8sIGludCBuaWNldmFsKQp7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnA7CglpbnQgZXJyb3I7CgoJaWYgKHdoaWNoID4gMiB8fCB3aGljaCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CgoJLyogbm9ybWFsaXplOiBhdm9pZCBzaWduZWQgZGl2aXNpb24gKHJvdW5kaW5nIHByb2JsZW1zKSAqLwoJZXJyb3IgPSAtRVNSQ0g7CglpZiAobmljZXZhbCA8IC0yMCkKCQluaWNldmFsID0gLTIwOwoJaWYgKG5pY2V2YWwgPiAxOSkKCQluaWNldmFsID0gMTk7CgoJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCWZvcl9lYWNoX3Rhc2socCkgewoJCWlmICghcHJvY19zZWwocCwgd2hpY2gsIHdobykpCgkJCWNvbnRpbnVlOwoJCWlmIChwLT51aWQgIT0gY3VycmVudC0+ZXVpZCAmJgoJCQlwLT51aWQgIT0gY3VycmVudC0+dWlkICYmICFjYXBhYmxlKENBUF9TWVNfTklDRSkpIHsKCQkJZXJyb3IgPSAtRVBFUk07CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoZXJyb3IgPT0gLUVTUkNIKQoJCQllcnJvciA9IDA7CgkJaWYgKG5pY2V2YWwgPCBwLT5uaWNlICYmICFjYXBhYmxlKENBUF9TWVNfTklDRSkpCgkJCWVycm9yID0gLUVBQ0NFUzsKCQllbHNlCgkJCXAtPm5pY2UgPSBuaWNldmFsOwoJfQoJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoKCXJldHVybiBlcnJvcjsKfQoKLyoKICogVWdoLiBUbyBhdm9pZCBuZWdhdGl2ZSByZXR1cm4gdmFsdWVzLCAiZ2V0cHJpb3JpdHkoKSIgd2lsbAogKiBub3QgcmV0dXJuIHRoZSBub3JtYWwgbmljZS12YWx1ZSwgYnV0IGEgbmVnYXRlZCB2YWx1ZSB0aGF0CiAqIGhhcyBiZWVuIG9mZnNldCBieSAyMCAoaWUgaXQgcmV0dXJucyA0MC4uMSBpbnN0ZWFkIG9mIC0yMC4uMTkpCiAqIHRvIHN0YXkgY29tcGF0aWJsZS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cHJpb3JpdHkoaW50IHdoaWNoLCBpbnQgd2hvKQp7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnA7Cglsb25nIHJldHZhbCA9IC1FU1JDSDsKCglpZiAod2hpY2ggPiAyIHx8IHdoaWNoIDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCglyZWFkX2xvY2soJnRhc2tsaXN0X2xvY2spOwoJZm9yX2VhY2hfdGFzayAocCkgewoJCWxvbmcgbmljZXZhbDsKCQlpZiAoIXByb2Nfc2VsKHAsIHdoaWNoLCB3aG8pKQoJCQljb250aW51ZTsKCQluaWNldmFsID0gMjAgLSBwLT5uaWNlOwoJCWlmIChuaWNldmFsID4gcmV0dmFsKQoJCQlyZXR2YWwgPSBuaWNldmFsOwoJfQoJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoKCXJldHVybiByZXR2YWw7Cn0KCgovKgogKiBSZWJvb3Qgc3lzdGVtIGNhbGw6IGZvciBvYnZpb3VzIHJlYXNvbnMgb25seSByb290IG1heSBjYWxsIGl0LAogKiBhbmQgZXZlbiByb290IG5lZWRzIHRvIHNldCB1cCBzb21lIG1hZ2ljIG51bWJlcnMgaW4gdGhlIHJlZ2lzdGVycwogKiBzbyB0aGF0IHNvbWUgbWlzdGFrZSB3b24ndCBtYWtlIHRoaXMgcmVib290IHRoZSB3aG9sZSBtYWNoaW5lLgogKiBZb3UgY2FuIGFsc28gc2V0IHRoZSBtZWFuaW5nIG9mIHRoZSBjdHJsLWFsdC1kZWwta2V5IGhlcmUuCiAqCiAqIHJlYm9vdCBkb2Vzbid0IHN5bmM6IGRvIHRoYXQgeW91cnNlbGYgYmVmb3JlIGNhbGxpbmcgdGhpcy4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfcmVib290KGludCBtYWdpYzEsIGludCBtYWdpYzIsIHVuc2lnbmVkIGludCBjbWQsIHZvaWQgKiBhcmcpCnsKCWNoYXIgYnVmZmVyWzI1Nl07CgoJLyogV2Ugb25seSB0cnVzdCB0aGUgc3VwZXJ1c2VyIHdpdGggcmVib290aW5nIHRoZSBzeXN0ZW0uICovCglpZiAoIWNhcGFibGUoQ0FQX1NZU19CT09UKSkKCQlyZXR1cm4gLUVQRVJNOwoKCS8qIEZvciBzYWZldHksIHdlIHJlcXVpcmUgIm1hZ2ljIiBhcmd1bWVudHMuICovCglpZiAobWFnaWMxICE9IExJTlVYX1JFQk9PVF9NQUdJQzEgfHwKCSAgICAobWFnaWMyICE9IExJTlVYX1JFQk9PVF9NQUdJQzIgJiYgbWFnaWMyICE9IExJTlVYX1JFQk9PVF9NQUdJQzJBICYmCgkJCW1hZ2ljMiAhPSBMSU5VWF9SRUJPT1RfTUFHSUMyQikpCgkJcmV0dXJuIC1FSU5WQUw7CgoJbG9ja19rZXJuZWwoKTsKCXN3aXRjaCAoY21kKSB7CgljYXNlIExJTlVYX1JFQk9PVF9DTURfUkVTVEFSVDoKCQlub3RpZmllcl9jYWxsX2NoYWluKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwgU1lTX1JFU1RBUlQsIE5VTEwpOwoJCXByaW50ayhLRVJOX0VNRVJHICJSZXN0YXJ0aW5nIHN5c3RlbS5cbiIpOwoJCW1hY2hpbmVfcmVzdGFydChOVUxMKTsKCQlicmVhazsKCgljYXNlIExJTlVYX1JFQk9PVF9DTURfQ0FEX09OOgoJCUNfQV9EID0gMTsKCQlicmVhazsKCgljYXNlIExJTlVYX1JFQk9PVF9DTURfQ0FEX09GRjoKCQlDX0FfRCA9IDA7CgkJYnJlYWs7CgoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX0hBTFQ6CgkJbm90aWZpZXJfY2FsbF9jaGFpbigmcmVib290X25vdGlmaWVyX2xpc3QsIFNZU19IQUxULCBOVUxMKTsKCQlwcmludGsoS0VSTl9FTUVSRyAiU3lzdGVtIGhhbHRlZC5cbiIpOwoJCW1hY2hpbmVfaGFsdCgpOwoJCWRvX2V4aXQoMCk7CgkJYnJlYWs7CgoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX1BPV0VSX09GRjoKCQlub3RpZmllcl9jYWxsX2NoYWluKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwgU1lTX1BPV0VSX09GRiwgTlVMTCk7CgkJcHJpbnRrKEtFUk5fRU1FUkcgIlBvd2VyIGRvd24uXG4iKTsKCQltYWNoaW5lX3Bvd2VyX29mZigpOwoJCWRvX2V4aXQoMCk7CgkJYnJlYWs7CgoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX1JFU1RBUlQyOgoJCWlmIChzdHJuY3B5X2Zyb21fdXNlcigmYnVmZmVyWzBdLCAoY2hhciAqKWFyZywgc2l6ZW9mKGJ1ZmZlcikgLSAxKSA8IDApIHsKCQkJdW5sb2NrX2tlcm5lbCgpOwoJCQlyZXR1cm4gLUVGQVVMVDsKCQl9CgkJYnVmZmVyW3NpemVvZihidWZmZXIpIC0gMV0gPSAnXDAnOwoKCQlub3RpZmllcl9jYWxsX2NoYWluKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwgU1lTX1JFU1RBUlQsIGJ1ZmZlcik7CgkJcHJpbnRrKEtFUk5fRU1FUkcgIlJlc3RhcnRpbmcgc3lzdGVtIHdpdGggY29tbWFuZCAnJXMnLlxuIiwgYnVmZmVyKTsKCQltYWNoaW5lX3Jlc3RhcnQoYnVmZmVyKTsKCQlicmVhazsKCglkZWZhdWx0OgoJCXVubG9ja19rZXJuZWwoKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCXVubG9ja19rZXJuZWwoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBkZWZlcnJlZF9jYWQodm9pZCAqZHVtbXkpCnsKCW5vdGlmaWVyX2NhbGxfY2hhaW4oJnJlYm9vdF9ub3RpZmllcl9saXN0LCBTWVNfUkVTVEFSVCwgTlVMTCk7CgltYWNoaW5lX3Jlc3RhcnQoTlVMTCk7Cn0KCi8qCiAqIFRoaXMgZnVuY3Rpb24gZ2V0cyBjYWxsZWQgYnkgY3RybC1hbHQtZGVsIC0gaWUgdGhlIGtleWJvYXJkIGludGVycnVwdC4KICogQXMgaXQncyBjYWxsZWQgd2l0aGluIGFuIGludGVycnVwdCwgaXQgbWF5IE5PVCBzeW5jOiB0aGUgb25seSBjaG9pY2UKICogaXMgd2hldGhlciB0byByZWJvb3QgYXQgb25jZSwgb3IganVzdCBpZ25vcmUgdGhlIGN0cmwtYWx0LWRlbC4KICovCnZvaWQgY3RybF9hbHRfZGVsKHZvaWQpCnsKCXN0YXRpYyBzdHJ1Y3QgdHFfc3RydWN0IGNhZF90cSA9IHsKCQlyb3V0aW5lOiBkZWZlcnJlZF9jYWQsCgl9OwoKCWlmIChDX0FfRCkKCQlzY2hlZHVsZV90YXNrKCZjYWRfdHEpOwoJZWxzZQoJCWtpbGxfcHJvYyhjYWRfcGlkLCBTSUdJTlQsIDEpOwp9CgkKCi8qCiAqIFVucHJpdmlsZWdlZCB1c2VycyBtYXkgY2hhbmdlIHRoZSByZWFsIGdpZCB0byB0aGUgZWZmZWN0aXZlIGdpZAogKiBvciB2aWNlIHZlcnNhLiAgKEJTRC1zdHlsZSkKICoKICogSWYgeW91IHNldCB0aGUgcmVhbCBnaWQgYXQgYWxsLCBvciBzZXQgdGhlIGVmZmVjdGl2ZSBnaWQgdG8gYSB2YWx1ZSBub3QKICogZXF1YWwgdG8gdGhlIHJlYWwgZ2lkLCB0aGVuIHRoZSBzYXZlZCBnaWQgaXMgc2V0IHRvIHRoZSBuZXcgZWZmZWN0aXZlIGdpZC4KICoKICogVGhpcyBtYWtlcyBpdCBwb3NzaWJsZSBmb3IgYSBzZXRnaWQgcHJvZ3JhbSB0byBjb21wbGV0ZWx5IGRyb3AgaXRzCiAqIHByaXZpbGVnZXMsIHdoaWNoIGlzIG9mdGVuIGEgdXNlZnVsIGFzc2VydGlvbiB0byBtYWtlIHdoZW4geW91IGFyZSBkb2luZwogKiBhIHNlY3VyaXR5IGF1ZGl0IG92ZXIgYSBwcm9ncmFtLgogKgogKiBUaGUgZ2VuZXJhbCBpZGVhIGlzIHRoYXQgYSBwcm9ncmFtIHdoaWNoIHVzZXMganVzdCBzZXRyZWdpZCgpIHdpbGwgYmUKICogMTAwJSBjb21wYXRpYmxlIHdpdGggQlNELiAgQSBwcm9ncmFtIHdoaWNoIHVzZXMganVzdCBzZXRnaWQoKSB3aWxsIGJlCiAqIDEwMCUgY29tcGF0aWJsZSB3aXRoIFBPU0lYIHdpdGggc2F2ZWQgSURzLiAKICoKICogU01QOiBUaGVyZSBhcmUgbm90IHJhY2VzLCB0aGUgR0lEcyBhcmUgY2hlY2tlZCBvbmx5IGJ5IGZpbGVzeXN0ZW0KICogICAgICBvcGVyYXRpb25zIChhcyBmYXIgYXMgc2VtYW50aWMgcHJlc2VydmF0aW9uIGlzIGNvbmNlcm5lZCkuCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldHJlZ2lkKGdpZF90IHJnaWQsIGdpZF90IGVnaWQpCnsKCWludCBvbGRfcmdpZCA9IGN1cnJlbnQtPmdpZDsKCWludCBvbGRfZWdpZCA9IGN1cnJlbnQtPmVnaWQ7CglpbnQgbmV3X3JnaWQgPSBvbGRfcmdpZDsKCWludCBuZXdfZWdpZCA9IG9sZF9lZ2lkOwoKCWlmIChyZ2lkICE9IChnaWRfdCkgLTEpIHsKCQlpZiAoKG9sZF9yZ2lkID09IHJnaWQpIHx8CgkJICAgIChjdXJyZW50LT5lZ2lkPT1yZ2lkKSB8fAoJCSAgICBjYXBhYmxlKENBUF9TRVRHSUQpKQoJCQluZXdfcmdpZCA9IHJnaWQ7CgkJZWxzZQoJCQlyZXR1cm4gLUVQRVJNOwoJfQoJaWYgKGVnaWQgIT0gKGdpZF90KSAtMSkgewoJCWlmICgob2xkX3JnaWQgPT0gZWdpZCkgfHwKCQkgICAgKGN1cnJlbnQtPmVnaWQgPT0gZWdpZCkgfHwKCQkgICAgKGN1cnJlbnQtPnNnaWQgPT0gZWdpZCkgfHwKCQkgICAgY2FwYWJsZShDQVBfU0VUR0lEKSkKCQkJbmV3X2VnaWQgPSBlZ2lkOwoJCWVsc2UgewoJCQlyZXR1cm4gLUVQRVJNOwoJCX0KCX0KCWlmIChuZXdfZWdpZCAhPSBvbGRfZWdpZCkKCXsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSAwOwoJCXdtYigpOwoJfQoJaWYgKHJnaWQgIT0gKGdpZF90KSAtMSB8fAoJICAgIChlZ2lkICE9IChnaWRfdCkgLTEgJiYgZWdpZCAhPSBvbGRfcmdpZCkpCgkJY3VycmVudC0+c2dpZCA9IG5ld19lZ2lkOwoJY3VycmVudC0+ZnNnaWQgPSBuZXdfZWdpZDsKCWN1cnJlbnQtPmVnaWQgPSBuZXdfZWdpZDsKCWN1cnJlbnQtPmdpZCA9IG5ld19yZ2lkOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIHNldGdpZCgpIGlzIGltcGxlbWVudGVkIGxpa2UgU3lzViB3LyBTQVZFRF9JRFMgCiAqCiAqIFNNUDogU2FtZSBpbXBsaWNpdCByYWNlcyBhcyBhYm92ZS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0Z2lkKGdpZF90IGdpZCkKewoJaW50IG9sZF9lZ2lkID0gY3VycmVudC0+ZWdpZDsKCglpZiAoY2FwYWJsZShDQVBfU0VUR0lEKSkKCXsKCQlpZihvbGRfZWdpZCAhPSBnaWQpCgkJewoJCQljdXJyZW50LT5tbS0+ZHVtcGFibGU9MDsKCQkJd21iKCk7CgkJfQoJCWN1cnJlbnQtPmdpZCA9IGN1cnJlbnQtPmVnaWQgPSBjdXJyZW50LT5zZ2lkID0gY3VycmVudC0+ZnNnaWQgPSBnaWQ7Cgl9CgllbHNlIGlmICgoZ2lkID09IGN1cnJlbnQtPmdpZCkgfHwgKGdpZCA9PSBjdXJyZW50LT5zZ2lkKSkKCXsKCQlpZihvbGRfZWdpZCAhPSBnaWQpCgkJewoJCQljdXJyZW50LT5tbS0+ZHVtcGFibGU9MDsKCQkJd21iKCk7CgkJfQoJCWN1cnJlbnQtPmVnaWQgPSBjdXJyZW50LT5mc2dpZCA9IGdpZDsKCX0KCWVsc2UKCQlyZXR1cm4gLUVQRVJNOwoJcmV0dXJuIDA7Cn0KICAKLyogCiAqIGNhcF9lbXVsYXRlX3NldHh1aWQoKSBmaXhlcyB0aGUgZWZmZWN0aXZlIC8gcGVybWl0dGVkIGNhcGFiaWxpdGllcyBvZgogKiBhIHByb2Nlc3MgYWZ0ZXIgYSBjYWxsIHRvIHNldHVpZCwgc2V0cmV1aWQsIG9yIHNldHJlc3VpZC4KICoKICogIDEpIFdoZW4gc2V0KnVpZGluZyBfZnJvbV8gb25lIG9mIHtyLGUsc311aWQgPT0gMCBfdG9fIGFsbCBvZgogKiAge3IsZSxzfXVpZCAhPSAwLCB0aGUgcGVybWl0dGVkIGFuZCBlZmZlY3RpdmUgY2FwYWJpbGl0aWVzIGFyZQogKiAgY2xlYXJlZC4KICoKICogIDIpIFdoZW4gc2V0KnVpZGluZyBfZnJvbV8gZXVpZCA9PSAwIF90b18gZXVpZCAhPSAwLCB0aGUgZWZmZWN0aXZlCiAqICBjYXBhYmlsaXRpZXMgb2YgdGhlIHByb2Nlc3MgYXJlIGNsZWFyZWQuCiAqCiAqICAzKSBXaGVuIHNldCp1aWRpbmcgX2Zyb21fIGV1aWQgIT0gMCBfdG9fIGV1aWQgPT0gMCwgdGhlIGVmZmVjdGl2ZQogKiAgY2FwYWJpbGl0aWVzIGFyZSBzZXQgdG8gdGhlIHBlcm1pdHRlZCBjYXBhYmlsaXRpZXMuCiAqCiAqICBmc3VpZCBpcyBoYW5kbGVkIGVsc2V3aGVyZS4gZnN1aWQgPT0gMCBhbmQge3IsZSxzfXVpZCE9IDAgc2hvdWxkIAogKiAgbmV2ZXIgaGFwcGVuLgogKgogKiAgLWFzdG9yIAogKgogKiBjZXZhbnMgLSBOZXcgYmVoYXZpb3VyLCBPY3QgJzk5CiAqIEEgcHJvY2VzcyBtYXksIHZpYSBwcmN0bCgpLCBlbGVjdCB0byBrZWVwIGl0cyBjYXBhYmlsaXRpZXMgd2hlbiBpdAogKiBjYWxscyBzZXR1aWQoKSBhbmQgc3dpdGNoZXMgYXdheSBmcm9tIHVpZD09MC4gQm90aCBwZXJtaXR0ZWQgYW5kCiAqIGVmZmVjdGl2ZSBzZXRzIHdpbGwgYmUgcmV0YWluZWQuCiAqIFdpdGhvdXQgdGhpcyBjaGFuZ2UsIGl0IHdhcyBpbXBvc3NpYmxlIGZvciBhIGRhZW1vbiB0byBkcm9wIG9ubHkgc29tZQogKiBvZiBpdHMgcHJpdmlsZWdlLiBUaGUgY2FsbCB0byBzZXR1aWQoIT0wKSB3b3VsZCBkcm9wIGFsbCBwcml2aWxlZ2VzIQogKiBLZWVwaW5nIHVpZCAwIGlzIG5vdCBhbiBvcHRpb24gYmVjYXVzZSB1aWQgMCBvd25zIHRvbyBtYW55IHZpdGFsCiAqIGZpbGVzLi4KICogVGhhbmtzIHRvIE9sYWYgS2lyY2ggYW5kIFBldGVyIEJlbmllIGZvciBzcG90dGluZyB0aGlzLgogKi8Kc3RhdGljIGlubGluZSB2b2lkIGNhcF9lbXVsYXRlX3NldHh1aWQoaW50IG9sZF9ydWlkLCBpbnQgb2xkX2V1aWQsIAoJCQkJICAgICAgIGludCBvbGRfc3VpZCkKewoJaWYgKChvbGRfcnVpZCA9PSAwIHx8IG9sZF9ldWlkID09IDAgfHwgb2xkX3N1aWQgPT0gMCkgJiYKCSAgICAoY3VycmVudC0+dWlkICE9IDAgJiYgY3VycmVudC0+ZXVpZCAhPSAwICYmIGN1cnJlbnQtPnN1aWQgIT0gMCkgJiYKCSAgICAhY3VycmVudC0+a2VlcF9jYXBhYmlsaXRpZXMpIHsKCQljYXBfY2xlYXIoY3VycmVudC0+Y2FwX3Blcm1pdHRlZCk7CgkJY2FwX2NsZWFyKGN1cnJlbnQtPmNhcF9lZmZlY3RpdmUpOwoJfQoJaWYgKG9sZF9ldWlkID09IDAgJiYgY3VycmVudC0+ZXVpZCAhPSAwKSB7CgkJY2FwX2NsZWFyKGN1cnJlbnQtPmNhcF9lZmZlY3RpdmUpOwoJfQoJaWYgKG9sZF9ldWlkICE9IDAgJiYgY3VycmVudC0+ZXVpZCA9PSAwKSB7CgkJY3VycmVudC0+Y2FwX2VmZmVjdGl2ZSA9IGN1cnJlbnQtPmNhcF9wZXJtaXR0ZWQ7Cgl9Cn0KCnN0YXRpYyBpbnQgc2V0X3VzZXIodWlkX3QgbmV3X3J1aWQsIGludCBkdW1wY2xlYXIpCnsKCXN0cnVjdCB1c2VyX3N0cnVjdCAqbmV3X3VzZXI7CgoJbmV3X3VzZXIgPSBhbGxvY191aWQobmV3X3J1aWQpOwoJaWYgKCFuZXdfdXNlcikKCQlyZXR1cm4gLUVBR0FJTjsKCXN3aXRjaF91aWQobmV3X3VzZXIpOwoKCWlmKGR1bXBjbGVhcikKCXsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSAwOwoJCXdtYigpOwoJfQoJY3VycmVudC0+dWlkID0gbmV3X3J1aWQ7CglyZXR1cm4gMDsKfQoKLyoKICogVW5wcml2aWxlZ2VkIHVzZXJzIG1heSBjaGFuZ2UgdGhlIHJlYWwgdWlkIHRvIHRoZSBlZmZlY3RpdmUgdWlkCiAqIG9yIHZpY2UgdmVyc2EuICAoQlNELXN0eWxlKQogKgogKiBJZiB5b3Ugc2V0IHRoZSByZWFsIHVpZCBhdCBhbGwsIG9yIHNldCB0aGUgZWZmZWN0aXZlIHVpZCB0byBhIHZhbHVlIG5vdAogKiBlcXVhbCB0byB0aGUgcmVhbCB1aWQsIHRoZW4gdGhlIHNhdmVkIHVpZCBpcyBzZXQgdG8gdGhlIG5ldyBlZmZlY3RpdmUgdWlkLgogKgogKiBUaGlzIG1ha2VzIGl0IHBvc3NpYmxlIGZvciBhIHNldHVpZCBwcm9ncmFtIHRvIGNvbXBsZXRlbHkgZHJvcCBpdHMKICogcHJpdmlsZWdlcywgd2hpY2ggaXMgb2Z0ZW4gYSB1c2VmdWwgYXNzZXJ0aW9uIHRvIG1ha2Ugd2hlbiB5b3UgYXJlIGRvaW5nCiAqIGEgc2VjdXJpdHkgYXVkaXQgb3ZlciBhIHByb2dyYW0uCiAqCiAqIFRoZSBnZW5lcmFsIGlkZWEgaXMgdGhhdCBhIHByb2dyYW0gd2hpY2ggdXNlcyBqdXN0IHNldHJldWlkKCkgd2lsbCBiZQogKiAxMDAlIGNvbXBhdGlibGUgd2l0aCBCU0QuICBBIHByb2dyYW0gd2hpY2ggdXNlcyBqdXN0IHNldHVpZCgpIHdpbGwgYmUKICogMTAwJSBjb21wYXRpYmxlIHdpdGggUE9TSVggd2l0aCBzYXZlZCBJRHMuIAogKi8KYXNtbGlua2FnZSBsb25nIHN5c19zZXRyZXVpZCh1aWRfdCBydWlkLCB1aWRfdCBldWlkKQp7CglpbnQgb2xkX3J1aWQsIG9sZF9ldWlkLCBvbGRfc3VpZCwgbmV3X3J1aWQsIG5ld19ldWlkOwoKCW5ld19ydWlkID0gb2xkX3J1aWQgPSBjdXJyZW50LT51aWQ7CgluZXdfZXVpZCA9IG9sZF9ldWlkID0gY3VycmVudC0+ZXVpZDsKCW9sZF9zdWlkID0gY3VycmVudC0+c3VpZDsKCglpZiAocnVpZCAhPSAodWlkX3QpIC0xKSB7CgkJbmV3X3J1aWQgPSBydWlkOwoJCWlmICgob2xkX3J1aWQgIT0gcnVpZCkgJiYKCQkgICAgKGN1cnJlbnQtPmV1aWQgIT0gcnVpZCkgJiYKCQkgICAgIWNhcGFibGUoQ0FQX1NFVFVJRCkpCgkJCXJldHVybiAtRVBFUk07Cgl9CgoJaWYgKGV1aWQgIT0gKHVpZF90KSAtMSkgewoJCW5ld19ldWlkID0gZXVpZDsKCQlpZiAoKG9sZF9ydWlkICE9IGV1aWQpICYmCgkJICAgIChjdXJyZW50LT5ldWlkICE9IGV1aWQpICYmCgkJICAgIChjdXJyZW50LT5zdWlkICE9IGV1aWQpICYmCgkJICAgICFjYXBhYmxlKENBUF9TRVRVSUQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJfQoKCWlmIChuZXdfcnVpZCAhPSBvbGRfcnVpZCAmJiBzZXRfdXNlcihuZXdfcnVpZCwgbmV3X2V1aWQgIT0gb2xkX2V1aWQpIDwgMCkKCQlyZXR1cm4gLUVBR0FJTjsKCglpZiAobmV3X2V1aWQgIT0gb2xkX2V1aWQpCgl7CgkJY3VycmVudC0+bW0tPmR1bXBhYmxlPTA7CgkJd21iKCk7Cgl9CgljdXJyZW50LT5mc3VpZCA9IGN1cnJlbnQtPmV1aWQgPSBuZXdfZXVpZDsKCWlmIChydWlkICE9ICh1aWRfdCkgLTEgfHwKCSAgICAoZXVpZCAhPSAodWlkX3QpIC0xICYmIGV1aWQgIT0gb2xkX3J1aWQpKQoJCWN1cnJlbnQtPnN1aWQgPSBjdXJyZW50LT5ldWlkOwoJY3VycmVudC0+ZnN1aWQgPSBjdXJyZW50LT5ldWlkOwoKCWlmICghaXNzZWN1cmUoU0VDVVJFX05PX1NFVFVJRF9GSVhVUCkpIHsKCQljYXBfZW11bGF0ZV9zZXR4dWlkKG9sZF9ydWlkLCBvbGRfZXVpZCwgb2xkX3N1aWQpOwoJfQoKCXJldHVybiAwOwp9CgoKCQkKLyoKICogc2V0dWlkKCkgaXMgaW1wbGVtZW50ZWQgbGlrZSBTeXNWIHdpdGggU0FWRURfSURTIAogKiAKICogTm90ZSB0aGF0IFNBVkVEX0lEJ3MgaXMgZGVmaWNpZW50IGluIHRoYXQgYSBzZXR1aWQgcm9vdCBwcm9ncmFtCiAqIGxpa2Ugc2VuZG1haWwsIGZvciBleGFtcGxlLCBjYW5ub3Qgc2V0IGl0cyB1aWQgdG8gYmUgYSBub3JtYWwgCiAqIHVzZXIgYW5kIHRoZW4gc3dpdGNoIGJhY2ssIGJlY2F1c2UgaWYgeW91J3JlIHJvb3QsIHNldHVpZCgpIHNldHMKICogdGhlIHNhdmVkIHVpZCB0b28uICBJZiB5b3UgZG9uJ3QgbGlrZSB0aGlzLCBibGFtZSB0aGUgYnJpZ2h0IHBlb3BsZQogKiBpbiB0aGUgUE9TSVggY29tbWl0dGVlIGFuZC9vciBVU0cuICBOb3RlIHRoYXQgdGhlIEJTRC1zdHlsZSBzZXRyZXVpZCgpCiAqIHdpbGwgYWxsb3cgYSByb290IHByb2dyYW0gdG8gdGVtcG9yYXJpbHkgZHJvcCBwcml2aWxlZ2VzIGFuZCBiZSBhYmxlIHRvCiAqIHJlZ2FpbiB0aGVtIGJ5IHN3YXBwaW5nIHRoZSByZWFsIGFuZCBlZmZlY3RpdmUgdWlkLiAgCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldHVpZCh1aWRfdCB1aWQpCnsKCWludCBvbGRfZXVpZCA9IGN1cnJlbnQtPmV1aWQ7CglpbnQgb2xkX3J1aWQsIG9sZF9zdWlkLCBuZXdfcnVpZCwgbmV3X3N1aWQ7CgoJb2xkX3J1aWQgPSBuZXdfcnVpZCA9IGN1cnJlbnQtPnVpZDsKCW9sZF9zdWlkID0gY3VycmVudC0+c3VpZDsKCW5ld19zdWlkID0gb2xkX3N1aWQ7CgkKCWlmIChjYXBhYmxlKENBUF9TRVRVSUQpKSB7CgkJaWYgKHVpZCAhPSBvbGRfcnVpZCAmJiBzZXRfdXNlcih1aWQsIG9sZF9ldWlkICE9IHVpZCkgPCAwKQoJCQlyZXR1cm4gLUVBR0FJTjsKCQluZXdfc3VpZCA9IHVpZDsKCX0gZWxzZSBpZiAoKHVpZCAhPSBjdXJyZW50LT51aWQpICYmICh1aWQgIT0gbmV3X3N1aWQpKQoJCXJldHVybiAtRVBFUk07CgoJaWYgKG9sZF9ldWlkICE9IHVpZCkKCXsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSAwOwoJCXdtYigpOwoJfQoJY3VycmVudC0+ZnN1aWQgPSBjdXJyZW50LT5ldWlkID0gdWlkOwoJY3VycmVudC0+c3VpZCA9IG5ld19zdWlkOwoKCWlmICghaXNzZWN1cmUoU0VDVVJFX05PX1NFVFVJRF9GSVhVUCkpIHsKCQljYXBfZW11bGF0ZV9zZXR4dWlkKG9sZF9ydWlkLCBvbGRfZXVpZCwgb2xkX3N1aWQpOwoJfQoKCXJldHVybiAwOwp9CgoKLyoKICogVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIGEgZ2VuZXJpYyBhYmlsaXR5IHRvIHVwZGF0ZSBydWlkLCBldWlkLAogKiBhbmQgc3VpZC4gIFRoaXMgYWxsb3dzIHlvdSB0byBpbXBsZW1lbnQgdGhlIDQuNCBjb21wYXRpYmxlIHNldGV1aWQoKS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmVzdWlkKHVpZF90IHJ1aWQsIHVpZF90IGV1aWQsIHVpZF90IHN1aWQpCnsKCWludCBvbGRfcnVpZCA9IGN1cnJlbnQtPnVpZDsKCWludCBvbGRfZXVpZCA9IGN1cnJlbnQtPmV1aWQ7CglpbnQgb2xkX3N1aWQgPSBjdXJyZW50LT5zdWlkOwoKCWlmICghY2FwYWJsZShDQVBfU0VUVUlEKSkgewoJCWlmICgocnVpZCAhPSAodWlkX3QpIC0xKSAmJiAocnVpZCAhPSBjdXJyZW50LT51aWQpICYmCgkJICAgIChydWlkICE9IGN1cnJlbnQtPmV1aWQpICYmIChydWlkICE9IGN1cnJlbnQtPnN1aWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJCWlmICgoZXVpZCAhPSAodWlkX3QpIC0xKSAmJiAoZXVpZCAhPSBjdXJyZW50LT51aWQpICYmCgkJICAgIChldWlkICE9IGN1cnJlbnQtPmV1aWQpICYmIChldWlkICE9IGN1cnJlbnQtPnN1aWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJCWlmICgoc3VpZCAhPSAodWlkX3QpIC0xKSAmJiAoc3VpZCAhPSBjdXJyZW50LT51aWQpICYmCgkJICAgIChzdWlkICE9IGN1cnJlbnQtPmV1aWQpICYmIChzdWlkICE9IGN1cnJlbnQtPnN1aWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJfQoJaWYgKHJ1aWQgIT0gKHVpZF90KSAtMSkgewoJCWlmIChydWlkICE9IGN1cnJlbnQtPnVpZCAmJiBzZXRfdXNlcihydWlkLCBldWlkICE9IGN1cnJlbnQtPmV1aWQpIDwgMCkKCQkJcmV0dXJuIC1FQUdBSU47Cgl9CglpZiAoZXVpZCAhPSAodWlkX3QpIC0xKSB7CgkJaWYgKGV1aWQgIT0gY3VycmVudC0+ZXVpZCkKCQl7CgkJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IDA7CgkJCXdtYigpOwoJCX0KCQljdXJyZW50LT5ldWlkID0gZXVpZDsKCX0KCWN1cnJlbnQtPmZzdWlkID0gY3VycmVudC0+ZXVpZDsKCWlmIChzdWlkICE9ICh1aWRfdCkgLTEpCgkJY3VycmVudC0+c3VpZCA9IHN1aWQ7CgoJaWYgKCFpc3NlY3VyZShTRUNVUkVfTk9fU0VUVUlEX0ZJWFVQKSkgewoJCWNhcF9lbXVsYXRlX3NldHh1aWQob2xkX3J1aWQsIG9sZF9ldWlkLCBvbGRfc3VpZCk7Cgl9CgoJcmV0dXJuIDA7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cmVzdWlkKHVpZF90ICpydWlkLCB1aWRfdCAqZXVpZCwgdWlkX3QgKnN1aWQpCnsKCWludCByZXR2YWw7CgoJaWYgKCEocmV0dmFsID0gcHV0X3VzZXIoY3VycmVudC0+dWlkLCBydWlkKSkgJiYKCSAgICAhKHJldHZhbCA9IHB1dF91c2VyKGN1cnJlbnQtPmV1aWQsIGV1aWQpKSkKCQlyZXR2YWwgPSBwdXRfdXNlcihjdXJyZW50LT5zdWlkLCBzdWlkKTsKCglyZXR1cm4gcmV0dmFsOwp9CgovKgogKiBTYW1lIGFzIGFib3ZlLCBidXQgZm9yIHJnaWQsIGVnaWQsIHNnaWQuCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldHJlc2dpZChnaWRfdCByZ2lkLCBnaWRfdCBlZ2lkLCBnaWRfdCBzZ2lkKQp7CglpZiAoIWNhcGFibGUoQ0FQX1NFVEdJRCkpIHsKCQlpZiAoKHJnaWQgIT0gKGdpZF90KSAtMSkgJiYgKHJnaWQgIT0gY3VycmVudC0+Z2lkKSAmJgoJCSAgICAocmdpZCAhPSBjdXJyZW50LT5lZ2lkKSAmJiAocmdpZCAhPSBjdXJyZW50LT5zZ2lkKSkKCQkJcmV0dXJuIC1FUEVSTTsKCQlpZiAoKGVnaWQgIT0gKGdpZF90KSAtMSkgJiYgKGVnaWQgIT0gY3VycmVudC0+Z2lkKSAmJgoJCSAgICAoZWdpZCAhPSBjdXJyZW50LT5lZ2lkKSAmJiAoZWdpZCAhPSBjdXJyZW50LT5zZ2lkKSkKCQkJcmV0dXJuIC1FUEVSTTsKCQlpZiAoKHNnaWQgIT0gKGdpZF90KSAtMSkgJiYgKHNnaWQgIT0gY3VycmVudC0+Z2lkKSAmJgoJCSAgICAoc2dpZCAhPSBjdXJyZW50LT5lZ2lkKSAmJiAoc2dpZCAhPSBjdXJyZW50LT5zZ2lkKSkKCQkJcmV0dXJuIC1FUEVSTTsKCX0KCWlmIChlZ2lkICE9IChnaWRfdCkgLTEpIHsKCQlpZiAoZWdpZCAhPSBjdXJyZW50LT5lZ2lkKQoJCXsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gMDsKCQkJd21iKCk7CgkJfQoJCWN1cnJlbnQtPmVnaWQgPSBlZ2lkOwoJfQoJY3VycmVudC0+ZnNnaWQgPSBjdXJyZW50LT5lZ2lkOwoJaWYgKHJnaWQgIT0gKGdpZF90KSAtMSkKCQljdXJyZW50LT5naWQgPSByZ2lkOwoJaWYgKHNnaWQgIT0gKGdpZF90KSAtMSkKCQljdXJyZW50LT5zZ2lkID0gc2dpZDsKCXJldHVybiAwOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldHJlc2dpZChnaWRfdCAqcmdpZCwgZ2lkX3QgKmVnaWQsIGdpZF90ICpzZ2lkKQp7CglpbnQgcmV0dmFsOwoKCWlmICghKHJldHZhbCA9IHB1dF91c2VyKGN1cnJlbnQtPmdpZCwgcmdpZCkpICYmCgkgICAgIShyZXR2YWwgPSBwdXRfdXNlcihjdXJyZW50LT5lZ2lkLCBlZ2lkKSkpCgkJcmV0dmFsID0gcHV0X3VzZXIoY3VycmVudC0+c2dpZCwgc2dpZCk7CgoJcmV0dXJuIHJldHZhbDsKfQoKCi8qCiAqICJzZXRmc3VpZCgpIiBzZXRzIHRoZSBmc3VpZCAtIHRoZSB1aWQgdXNlZCBmb3IgZmlsZXN5c3RlbSBjaGVja3MuIFRoaXMKICogaXMgdXNlZCBmb3IgImFjY2VzcygpIiBhbmQgZm9yIHRoZSBORlMgZGFlbW9uIChsZXR0aW5nIG5mc2Qgc3RheSBhdAogKiB3aGF0ZXZlciB1aWQgaXQgd2FudHMgdG8pLiBJdCBub3JtYWxseSBzaGFkb3dzICJldWlkIiwgZXhjZXB0IHdoZW4KICogZXhwbGljaXRseSBzZXQgYnkgc2V0ZnN1aWQoKSBvciBmb3IgYWNjZXNzLi4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0ZnN1aWQodWlkX3QgdWlkKQp7CglpbnQgb2xkX2ZzdWlkOwoKCW9sZF9mc3VpZCA9IGN1cnJlbnQtPmZzdWlkOwoJaWYgKHVpZCA9PSBjdXJyZW50LT51aWQgfHwgdWlkID09IGN1cnJlbnQtPmV1aWQgfHwKCSAgICB1aWQgPT0gY3VycmVudC0+c3VpZCB8fCB1aWQgPT0gY3VycmVudC0+ZnN1aWQgfHwgCgkgICAgY2FwYWJsZShDQVBfU0VUVUlEKSkKCXsKCQlpZiAodWlkICE9IG9sZF9mc3VpZCkKCQl7CgkJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IDA7CgkJCXdtYigpOwoJCX0KCQljdXJyZW50LT5mc3VpZCA9IHVpZDsKCX0KCgkvKiBXZSBlbXVsYXRlIGZzdWlkIGJ5IGVzc2VudGlhbGx5IGRvaW5nIGEgc2NhbGVkLWRvd24gdmVyc2lvbgoJICogb2Ygd2hhdCB3ZSBkaWQgaW4gc2V0cmVzdWlkIGFuZCBmcmllbmRzLiBIb3dldmVyLCB3ZSBvbmx5CgkgKiBvcGVyYXRlIG9uIHRoZSBmcy1zcGVjaWZpYyBiaXRzIG9mIHRoZSBwcm9jZXNzJyBlZmZlY3RpdmUKCSAqIGNhcGFiaWxpdGllcyAKCSAqCgkgKiBGSVhNRSAtIGlzIGZzdXNlciB1c2VkIGZvciBhbGwgQ0FQX0ZTX01BU0sgY2FwYWJpbGl0aWVzPwoJICogICAgICAgICAgaWYgbm90LCB3ZSBtaWdodCBiZSBhIGJpdCB0b28gaGFyc2ggaGVyZS4KCSAqLwoJCglpZiAoIWlzc2VjdXJlKFNFQ1VSRV9OT19TRVRVSURfRklYVVApKSB7CgkJaWYgKG9sZF9mc3VpZCA9PSAwICYmIGN1cnJlbnQtPmZzdWlkICE9IDApIHsKCQkJY2FwX3QoY3VycmVudC0+Y2FwX2VmZmVjdGl2ZSkgJj0gfkNBUF9GU19NQVNLOwoJCX0KCQlpZiAob2xkX2ZzdWlkICE9IDAgJiYgY3VycmVudC0+ZnN1aWQgPT0gMCkgewoJCQljYXBfdChjdXJyZW50LT5jYXBfZWZmZWN0aXZlKSB8PQoJCQkJKGNhcF90KGN1cnJlbnQtPmNhcF9wZXJtaXR0ZWQpICYgQ0FQX0ZTX01BU0spOwoJCX0KCX0KCglyZXR1cm4gb2xkX2ZzdWlkOwp9CgovKgogKiBTYW1tYSBw5SBzdmVuc2thLi4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0ZnNnaWQoZ2lkX3QgZ2lkKQp7CglpbnQgb2xkX2ZzZ2lkOwoKCW9sZF9mc2dpZCA9IGN1cnJlbnQtPmZzZ2lkOwoJaWYgKGdpZCA9PSBjdXJyZW50LT5naWQgfHwgZ2lkID09IGN1cnJlbnQtPmVnaWQgfHwKCSAgICBnaWQgPT0gY3VycmVudC0+c2dpZCB8fCBnaWQgPT0gY3VycmVudC0+ZnNnaWQgfHwgCgkgICAgY2FwYWJsZShDQVBfU0VUR0lEKSkKCXsKCQlpZiAoZ2lkICE9IG9sZF9mc2dpZCkKCQl7CgkJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IDA7CgkJCXdtYigpOwoJCX0KCQljdXJyZW50LT5mc2dpZCA9IGdpZDsKCX0KCXJldHVybiBvbGRfZnNnaWQ7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfdGltZXMoc3RydWN0IHRtcyAqIHRidWYpCnsKCS8qCgkgKglJbiB0aGUgU01QIHdvcmxkIHdlIG1pZ2h0IGp1c3QgYmUgdW5sdWNreSBhbmQgaGF2ZSBvbmUgb2YKCSAqCXRoZSB0aW1lcyBpbmNyZW1lbnQgYXMgd2UgdXNlIGl0LiBTaW5jZSB0aGUgdmFsdWUgaXMgYW4KCSAqCWF0b21pY2FsbHkgc2FmZSB0eXBlIHRoaXMgaXMganVzdCBmaW5lLiBDb25jZXB0dWFsbHkgaXRzCgkgKglhcyBpZiB0aGUgc3lzY2FsbCB0b29rIGFuIGluc3RhbnQgbG9uZ2VyIHRvIG9jY3VyLgoJICovCglpZiAodGJ1ZikKCQlpZiAoY29weV90b191c2VyKHRidWYsICZjdXJyZW50LT50aW1lcywgc2l6ZW9mKHN0cnVjdCB0bXMpKSkKCQkJcmV0dXJuIC1FRkFVTFQ7CglyZXR1cm4gamlmZmllczsKfQoKLyoKICogVGhpcyBuZWVkcyBzb21lIGhlYXZ5IGNoZWNraW5nIC4uLgogKiBJIGp1c3QgaGF2ZW4ndCB0aGUgc3RvbWFjaCBmb3IgaXQuIEkgYWxzbyBkb24ndCBmdWxseQogKiB1bmRlcnN0YW5kIHNlc3Npb25zL3BncnAgZXRjLiBMZXQgc29tZWJvZHkgd2hvIGRvZXMgZXhwbGFpbiBpdC4KICoKICogT0ssIEkgdGhpbmsgSSBoYXZlIHRoZSBwcm90ZWN0aW9uIHNlbWFudGljcyByaWdodC4uLi4gdGhpcyBpcyByZWFsbHkKICogb25seSBpbXBvcnRhbnQgb24gYSBtdWx0aS11c2VyIHN5c3RlbSBhbnl3YXksIHRvIG1ha2Ugc3VyZSBvbmUgdXNlcgogKiBjYW4ndCBzZW5kIGEgc2lnbmFsIHRvIGEgcHJvY2VzcyBvd25lZCBieSBhbm90aGVyLiAgLVRZVCwgMTIvMTIvOTEKICoKICogQXVjaC4gSGFkIHRvIGFkZCB0aGUgJ2RpZF9leGVjJyBmbGFnIHRvIGNvbmZvcm0gY29tcGxldGVseSB0byBQT1NJWC4KICogTEJUIDA0LjAzLjk0CiAqLwoKYXNtbGlua2FnZSBsb25nIHN5c19zZXRwZ2lkKHBpZF90IHBpZCwgcGlkX3QgcGdpZCkKewoJc3RydWN0IHRhc2tfc3RydWN0ICogcDsKCWludCBlcnIgPSAtRUlOVkFMOwoKCWlmICghcGlkKQoJCXBpZCA9IGN1cnJlbnQtPnBpZDsKCWlmICghcGdpZCkKCQlwZ2lkID0gcGlkOwoJaWYgKHBnaWQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoKCS8qIEZyb20gdGhpcyBwb2ludCBmb3J3YXJkIHdlIGtlZXAgaG9sZGluZyBvbnRvIHRoZSB0YXNrbGlzdCBsb2NrCgkgKiBzbyB0aGF0IG91ciBwYXJlbnQgZG9lcyBub3QgY2hhbmdlIGZyb20gdW5kZXIgdXMuIC1EYXZlTQoJICovCglyZWFkX2xvY2soJnRhc2tsaXN0X2xvY2spOwoKCWVyciA9IC1FU1JDSDsKCXAgPSBmaW5kX3Rhc2tfYnlfcGlkKHBpZCk7CglpZiAoIXApCgkJZ290byBvdXQ7CgoJaWYgKHAtPnBfcHB0ciA9PSBjdXJyZW50IHx8IHAtPnBfb3BwdHIgPT0gY3VycmVudCkgewoJCWVyciA9IC1FUEVSTTsKCQlpZiAocC0+c2Vzc2lvbiAhPSBjdXJyZW50LT5zZXNzaW9uKQoJCQlnb3RvIG91dDsKCQllcnIgPSAtRUFDQ0VTOwoJCWlmIChwLT5kaWRfZXhlYykKCQkJZ290byBvdXQ7Cgl9IGVsc2UgaWYgKHAgIT0gY3VycmVudCkKCQlnb3RvIG91dDsKCWVyciA9IC1FUEVSTTsKCWlmIChwLT5sZWFkZXIpCgkJZ290byBvdXQ7CglpZiAocGdpZCAhPSBwaWQpIHsKCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKiB0bXA7CgkJZm9yX2VhY2hfdGFzayAodG1wKSB7CgkJCWlmICh0bXAtPnBncnAgPT0gcGdpZCAmJgoJCQkgICAgdG1wLT5zZXNzaW9uID09IGN1cnJlbnQtPnNlc3Npb24pCgkJCQlnb3RvIG9rX3BnaWQ7CgkJfQoJCWdvdG8gb3V0OwoJfQoKb2tfcGdpZDoKCXAtPnBncnAgPSBwZ2lkOwoJZXJyID0gMDsKb3V0OgoJLyogQWxsIHBhdGhzIGxlYWQgdG8gaGVyZSwgdGh1cyB3ZSBhcmUgc2FmZS4gLURhdmVNICovCglyZWFkX3VubG9jaygmdGFza2xpc3RfbG9jayk7CglyZXR1cm4gZXJyOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldHBnaWQocGlkX3QgcGlkKQp7CglpZiAoIXBpZCkgewoJCXJldHVybiBjdXJyZW50LT5wZ3JwOwoJfSBlbHNlIHsKCQlpbnQgcmV0dmFsOwoJCXN0cnVjdCB0YXNrX3N0cnVjdCAqcDsKCgkJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQlwID0gZmluZF90YXNrX2J5X3BpZChwaWQpOwoKCQlyZXR2YWwgPSAtRVNSQ0g7CgkJaWYgKHApCgkJCXJldHZhbCA9IHAtPnBncnA7CgkJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoJCXJldHVybiByZXR2YWw7Cgl9Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cGdycCh2b2lkKQp7CgkvKiBTTVAgLSBhc3N1bWluZyB3cml0ZXMgYXJlIHdvcmQgYXRvbWljIHRoaXMgaXMgZmluZSAqLwoJcmV0dXJuIGN1cnJlbnQtPnBncnA7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0c2lkKHBpZF90IHBpZCkKewoJaWYgKCFwaWQpIHsKCQlyZXR1cm4gY3VycmVudC0+c2Vzc2lvbjsKCX0gZWxzZSB7CgkJaW50IHJldHZhbDsKCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnA7CgoJCXJlYWRfbG9jaygmdGFza2xpc3RfbG9jayk7CgkJcCA9IGZpbmRfdGFza19ieV9waWQocGlkKTsKCgkJcmV0dmFsID0gLUVTUkNIOwoJCWlmKHApCgkJCXJldHZhbCA9IHAtPnNlc3Npb247CgkJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoJCXJldHVybiByZXR2YWw7Cgl9Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0c2lkKHZvaWQpCnsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqIHA7CglpbnQgZXJyID0gLUVQRVJNOwoKCXJlYWRfbG9jaygmdGFza2xpc3RfbG9jayk7Cglmb3JfZWFjaF90YXNrKHApIHsKCQlpZiAocC0+cGdycCA9PSBjdXJyZW50LT5waWQpCgkJCWdvdG8gb3V0OwoJfQoKCWN1cnJlbnQtPmxlYWRlciA9IDE7CgljdXJyZW50LT5zZXNzaW9uID0gY3VycmVudC0+cGdycCA9IGN1cnJlbnQtPnBpZDsKCWN1cnJlbnQtPnR0eSA9IE5VTEw7CgljdXJyZW50LT50dHlfb2xkX3BncnAgPSAwOwoJZXJyID0gY3VycmVudC0+cGdycDsKb3V0OgoJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoJcmV0dXJuIGVycjsKfQoKLyoKICogU3VwcGxlbWVudGFyeSBncm91cCBJRHMKICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0Z3JvdXBzKGludCBnaWRzZXRzaXplLCBnaWRfdCAqZ3JvdXBsaXN0KQp7CglpbnQgaTsKCQoJLyoKCSAqCVNNUDogTm9ib2R5IGVsc2UgY2FuIGNoYW5nZSBvdXIgZ3JvdXBsaXN0LiBUaHVzIHdlIGFyZQoJICoJc2FmZS4KCSAqLwoKCWlmIChnaWRzZXRzaXplIDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWkgPSBjdXJyZW50LT5uZ3JvdXBzOwoJaWYgKGdpZHNldHNpemUpIHsKCQlpZiAoaSA+IGdpZHNldHNpemUpCgkJCXJldHVybiAtRUlOVkFMOwoJCWlmIChjb3B5X3RvX3VzZXIoZ3JvdXBsaXN0LCBjdXJyZW50LT5ncm91cHMsIHNpemVvZihnaWRfdCkqaSkpCgkJCXJldHVybiAtRUZBVUxUOwoJfQoJcmV0dXJuIGk7Cn0KCi8qCiAqCVNNUDogT3VyIGdyb3VwcyBhcmUgbm90IHNoYXJlZC4gV2UgY2FuIGNvcHkgdG8vZnJvbSB0aGVtIHNhZmVseQogKgl3aXRob3V0IGFub3RoZXIgdGFzayBpbnRlcmZlcmluZy4KICovCiAKYXNtbGlua2FnZSBsb25nIHN5c19zZXRncm91cHMoaW50IGdpZHNldHNpemUsIGdpZF90ICpncm91cGxpc3QpCnsKCWlmICghY2FwYWJsZShDQVBfU0VUR0lEKSkKCQlyZXR1cm4gLUVQRVJNOwoJaWYgKCh1bnNpZ25lZCkgZ2lkc2V0c2l6ZSA+IE5HUk9VUFMpCgkJcmV0dXJuIC1FSU5WQUw7CglpZihjb3B5X2Zyb21fdXNlcihjdXJyZW50LT5ncm91cHMsIGdyb3VwbGlzdCwgZ2lkc2V0c2l6ZSAqIHNpemVvZihnaWRfdCkpKQoJCXJldHVybiAtRUZBVUxUOwoJY3VycmVudC0+bmdyb3VwcyA9IGdpZHNldHNpemU7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBzdXBwbGVtZW50YWxfZ3JvdXBfbWVtYmVyKGdpZF90IGdycCkKewoJaW50IGkgPSBjdXJyZW50LT5uZ3JvdXBzOwoKCWlmIChpKSB7CgkJZ2lkX3QgKmdyb3VwcyA9IGN1cnJlbnQtPmdyb3VwczsKCQlkbyB7CgkJCWlmICgqZ3JvdXBzID09IGdycCkKCQkJCXJldHVybiAxOwoJCQlncm91cHMrKzsKCQkJaS0tOwoJCX0gd2hpbGUgKGkpOwoJfQoJcmV0dXJuIDA7Cn0KCi8qCiAqIENoZWNrIHdoZXRoZXIgd2UncmUgZnNnaWQvZWdpZCBvciBpbiB0aGUgc3VwcGxlbWVudGFsIGdyb3VwLi4KICovCmludCBpbl9ncm91cF9wKGdpZF90IGdycCkKewoJaW50IHJldHZhbCA9IDE7CglpZiAoZ3JwICE9IGN1cnJlbnQtPmZzZ2lkKQoJCXJldHZhbCA9IHN1cHBsZW1lbnRhbF9ncm91cF9tZW1iZXIoZ3JwKTsKCXJldHVybiByZXR2YWw7Cn0KCmludCBpbl9lZ3JvdXBfcChnaWRfdCBncnApCnsKCWludCByZXR2YWwgPSAxOwoJaWYgKGdycCAhPSBjdXJyZW50LT5lZ2lkKQoJCXJldHZhbCA9IHN1cHBsZW1lbnRhbF9ncm91cF9tZW1iZXIoZ3JwKTsKCXJldHVybiByZXR2YWw7Cn0KCkRFQ0xBUkVfUldTRU0odXRzX3NlbSk7Cgphc21saW5rYWdlIGxvbmcgc3lzX25ld3VuYW1lKHN0cnVjdCBuZXdfdXRzbmFtZSAqIG5hbWUpCnsKCWludCBlcnJubyA9IDA7CgoJZG93bl9yZWFkKCZ1dHNfc2VtKTsKCWlmIChjb3B5X3RvX3VzZXIobmFtZSwmc3lzdGVtX3V0c25hbWUsc2l6ZW9mICpuYW1lKSkKCQllcnJubyA9IC1FRkFVTFQ7Cgl1cF9yZWFkKCZ1dHNfc2VtKTsKCXJldHVybiBlcnJubzsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19zZXRob3N0bmFtZShjaGFyICpuYW1lLCBpbnQgbGVuKQp7CglpbnQgZXJybm87CgljaGFyIHRtcFtfX05FV19VVFNfTEVOXTsKCglpZiAoIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJcmV0dXJuIC1FUEVSTTsKCWlmIChsZW4gPCAwIHx8IGxlbiA+IF9fTkVXX1VUU19MRU4pCgkJcmV0dXJuIC1FSU5WQUw7Cglkb3duX3dyaXRlKCZ1dHNfc2VtKTsKCWVycm5vID0gLUVGQVVMVDsKCWlmICghY29weV9mcm9tX3VzZXIodG1wLCBuYW1lLCBsZW4pKSB7CgkJbWVtY3B5KHN5c3RlbV91dHNuYW1lLm5vZGVuYW1lLCB0bXAsIGxlbik7CgkJc3lzdGVtX3V0c25hbWUubm9kZW5hbWVbbGVuXSA9IDA7CgkJZXJybm8gPSAwOwoJfQoJdXBfd3JpdGUoJnV0c19zZW0pOwoJcmV0dXJuIGVycm5vOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldGhvc3RuYW1lKGNoYXIgKm5hbWUsIGludCBsZW4pCnsKCWludCBpLCBlcnJubzsKCglpZiAobGVuIDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWRvd25fcmVhZCgmdXRzX3NlbSk7CglpID0gMSArIHN0cmxlbihzeXN0ZW1fdXRzbmFtZS5ub2RlbmFtZSk7CglpZiAoaSA+IGxlbikKCQlpID0gbGVuOwoJZXJybm8gPSAwOwoJaWYgKGNvcHlfdG9fdXNlcihuYW1lLCBzeXN0ZW1fdXRzbmFtZS5ub2RlbmFtZSwgaSkpCgkJZXJybm8gPSAtRUZBVUxUOwoJdXBfcmVhZCgmdXRzX3NlbSk7CglyZXR1cm4gZXJybm87Cn0KCi8qCiAqIE9ubHkgc2V0ZG9tYWlubmFtZTsgZ2V0ZG9tYWlubmFtZSBjYW4gYmUgaW1wbGVtZW50ZWQgYnkgY2FsbGluZwogKiB1bmFtZSgpCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldGRvbWFpbm5hbWUoY2hhciAqbmFtZSwgaW50IGxlbikKewoJaW50IGVycm5vOwoJY2hhciB0bXBbX19ORVdfVVRTX0xFTl07CgoJaWYgKCFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCXJldHVybiAtRVBFUk07CglpZiAobGVuIDwgMCB8fCBsZW4gPiBfX05FV19VVFNfTEVOKQoJCXJldHVybiAtRUlOVkFMOwoKCWRvd25fd3JpdGUoJnV0c19zZW0pOwoJZXJybm8gPSAtRUZBVUxUOwoJaWYgKCFjb3B5X2Zyb21fdXNlcih0bXAsIG5hbWUsIGxlbikpIHsKCQltZW1jcHkoc3lzdGVtX3V0c25hbWUuZG9tYWlubmFtZSwgdG1wLCBsZW4pOwoJCXN5c3RlbV91dHNuYW1lLmRvbWFpbm5hbWVbbGVuXSA9IDA7CgkJZXJybm8gPSAwOwoJfQoJdXBfd3JpdGUoJnV0c19zZW0pOwoJcmV0dXJuIGVycm5vOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldHJsaW1pdCh1bnNpZ25lZCBpbnQgcmVzb3VyY2UsIHN0cnVjdCBybGltaXQgKnJsaW0pCnsKCWlmIChyZXNvdXJjZSA+PSBSTElNX05MSU1JVFMpCgkJcmV0dXJuIC1FSU5WQUw7CgllbHNlCgkJcmV0dXJuIGNvcHlfdG9fdXNlcihybGltLCBjdXJyZW50LT5ybGltICsgcmVzb3VyY2UsIHNpemVvZigqcmxpbSkpCgkJCT8gLUVGQVVMVCA6IDA7Cn0KCiNpZiAhZGVmaW5lZChfX2lhNjRfXykgCgovKgogKglCYWNrIGNvbXBhdGliaWxpdHkgZm9yIGdldHJsaW1pdC4gTmVlZGVkIGZvciBzb21lIGFwcHMuCiAqLwogCmFzbWxpbmthZ2UgbG9uZyBzeXNfb2xkX2dldHJsaW1pdCh1bnNpZ25lZCBpbnQgcmVzb3VyY2UsIHN0cnVjdCBybGltaXQgKnJsaW0pCnsKCXN0cnVjdCBybGltaXQgeDsKCWlmIChyZXNvdXJjZSA+PSBSTElNX05MSU1JVFMpCgkJcmV0dXJuIC1FSU5WQUw7CgoJbWVtY3B5KCZ4LCBjdXJyZW50LT5ybGltICsgcmVzb3VyY2UsIHNpemVvZigqcmxpbSkpOwoJaWYoeC5ybGltX2N1ciA+IDB4N0ZGRkZGRkYpCgkJeC5ybGltX2N1ciA9IDB4N0ZGRkZGRkY7CglpZih4LnJsaW1fbWF4ID4gMHg3RkZGRkZGRikKCQl4LnJsaW1fbWF4ID0gMHg3RkZGRkZGRjsKCXJldHVybiBjb3B5X3RvX3VzZXIocmxpbSwgJngsIHNpemVvZih4KSk/LUVGQVVMVDowOwp9CgojZW5kaWYKCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmxpbWl0KHVuc2lnbmVkIGludCByZXNvdXJjZSwgc3RydWN0IHJsaW1pdCAqcmxpbSkKewoJc3RydWN0IHJsaW1pdCBuZXdfcmxpbSwgKm9sZF9ybGltOwoKCWlmIChyZXNvdXJjZSA+PSBSTElNX05MSU1JVFMpCgkJcmV0dXJuIC1FSU5WQUw7CglpZihjb3B5X2Zyb21fdXNlcigmbmV3X3JsaW0sIHJsaW0sIHNpemVvZigqcmxpbSkpKQoJCXJldHVybiAtRUZBVUxUOwogICAgICAgaWYgKG5ld19ybGltLnJsaW1fY3VyID4gbmV3X3JsaW0ucmxpbV9tYXgpCiAgICAgICAgICAgICAgIHJldHVybiAtRUlOVkFMOwoJb2xkX3JsaW0gPSBjdXJyZW50LT5ybGltICsgcmVzb3VyY2U7CglpZiAoKChuZXdfcmxpbS5ybGltX2N1ciA+IG9sZF9ybGltLT5ybGltX21heCkgfHwKCSAgICAgKG5ld19ybGltLnJsaW1fbWF4ID4gb2xkX3JsaW0tPnJsaW1fbWF4KSkgJiYKCSAgICAhY2FwYWJsZShDQVBfU1lTX1JFU09VUkNFKSkKCQlyZXR1cm4gLUVQRVJNOwoJaWYgKHJlc291cmNlID09IFJMSU1JVF9OT0ZJTEUpIHsKCQlpZiAobmV3X3JsaW0ucmxpbV9jdXIgPiBOUl9PUEVOIHx8IG5ld19ybGltLnJsaW1fbWF4ID4gTlJfT1BFTikKCQkJcmV0dXJuIC1FUEVSTTsKCX0KCSpvbGRfcmxpbSA9IG5ld19ybGltOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIEl0IHdvdWxkIG1ha2Ugc2Vuc2UgdG8gcHV0IHN0cnVjdCBydXNhZ2UgaW4gdGhlIHRhc2tfc3RydWN0LAogKiBleGNlcHQgdGhhdCB3b3VsZCBtYWtlIHRoZSB0YXNrX3N0cnVjdCBiZSAqcmVhbGx5IGJpZyouICBBZnRlcgogKiB0YXNrX3N0cnVjdCBnZXRzIG1vdmVkIGludG8gbWFsbG9jJ2VkIG1lbW9yeSwgaXQgd291bGQKICogbWFrZSBzZW5zZSB0byBkbyB0aGlzLiAgSXQgd2lsbCBtYWtlIG1vdmluZyB0aGUgcmVzdCBvZiB0aGUgaW5mb3JtYXRpb24KICogYSBsb3Qgc2ltcGxlciEgIChXaGljaCB3ZSdyZSBub3QgZG9pbmcgcmlnaHQgbm93IGJlY2F1c2Ugd2UncmUgbm90CiAqIG1lYXN1cmluZyB0aGVtIHlldCkuCiAqCiAqIFRoaXMgaXMgU01QIHNhZmUuICBFaXRoZXIgd2UgYXJlIGNhbGxlZCBmcm9tIHN5c19nZXRydXNhZ2Ugb24gb3Vyc2VsdmVzCiAqIGJlbG93ICh3ZSBrbm93IHdlIGFyZW4ndCBnb2luZyB0byBleGl0L2Rpc2FwcGVhciBhbmQgb25seSB3ZSBjaGFuZ2Ugb3VyCiAqIHJ1c2FnZSBjb3VudGVycyksIG9yIHdlIGFyZSBjYWxsZWQgZnJvbSB3YWl0NCgpIG9uIGEgcHJvY2VzcyB3aGljaCBpcwogKiBlaXRoZXIgc3RvcHBlZCBvciB6b21iaWVkLiAgSW4gdGhlIHpvbWJpZWQgY2FzZSB0aGUgdGFzayB3b24ndCBnZXQKICogcmVhcGVkIHRpbGwgc2hvcnRseSBhZnRlciB0aGUgY2FsbCB0byBnZXRydXNhZ2UoKSwgaW4gYm90aCBjYXNlcyB0aGUKICogdGFzayBiZWluZyBleGFtaW5lZCBpcyBpbiBhIGZyb3plbiBzdGF0ZSBzbyB0aGUgY291bnRlcnMgd29uJ3QgY2hhbmdlLgogKgogKiBGSVhNRSEgR2V0IHRoZSBmYXVsdCBjb3VudHMgcHJvcGVybHkhCiAqLwppbnQgZ2V0cnVzYWdlKHN0cnVjdCB0YXNrX3N0cnVjdCAqcCwgaW50IHdobywgc3RydWN0IHJ1c2FnZSAqcnUpCnsKCXN0cnVjdCBydXNhZ2UgcjsKCgltZW1zZXQoKGNoYXIgKikgJnIsIDAsIHNpemVvZihyKSk7Cglzd2l0Y2ggKHdobykgewoJCWNhc2UgUlVTQUdFX1NFTEY6CgkJCXIucnVfdXRpbWUudHZfc2VjID0gQ1RfVE9fU0VDUyhwLT50aW1lcy50bXNfdXRpbWUpOwoJCQlyLnJ1X3V0aW1lLnR2X3VzZWMgPSBDVF9UT19VU0VDUyhwLT50aW1lcy50bXNfdXRpbWUpOwoJCQlyLnJ1X3N0aW1lLnR2X3NlYyA9IENUX1RPX1NFQ1MocC0+dGltZXMudG1zX3N0aW1lKTsKCQkJci5ydV9zdGltZS50dl91c2VjID0gQ1RfVE9fVVNFQ1MocC0+dGltZXMudG1zX3N0aW1lKTsKCQkJci5ydV9taW5mbHQgPSBwLT5taW5fZmx0OwoJCQlyLnJ1X21hamZsdCA9IHAtPm1hal9mbHQ7CgkJCXIucnVfbnN3YXAgPSBwLT5uc3dhcDsKCQkJYnJlYWs7CgkJY2FzZSBSVVNBR0VfQ0hJTERSRU46CgkJCXIucnVfdXRpbWUudHZfc2VjID0gQ1RfVE9fU0VDUyhwLT50aW1lcy50bXNfY3V0aW1lKTsKCQkJci5ydV91dGltZS50dl91c2VjID0gQ1RfVE9fVVNFQ1MocC0+dGltZXMudG1zX2N1dGltZSk7CgkJCXIucnVfc3RpbWUudHZfc2VjID0gQ1RfVE9fU0VDUyhwLT50aW1lcy50bXNfY3N0aW1lKTsKCQkJci5ydV9zdGltZS50dl91c2VjID0gQ1RfVE9fVVNFQ1MocC0+dGltZXMudG1zX2NzdGltZSk7CgkJCXIucnVfbWluZmx0ID0gcC0+Y21pbl9mbHQ7CgkJCXIucnVfbWFqZmx0ID0gcC0+Y21hal9mbHQ7CgkJCXIucnVfbnN3YXAgPSBwLT5jbnN3YXA7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCXIucnVfdXRpbWUudHZfc2VjID0gQ1RfVE9fU0VDUyhwLT50aW1lcy50bXNfdXRpbWUgKyBwLT50aW1lcy50bXNfY3V0aW1lKTsKCQkJci5ydV91dGltZS50dl91c2VjID0gQ1RfVE9fVVNFQ1MocC0+dGltZXMudG1zX3V0aW1lICsgcC0+dGltZXMudG1zX2N1dGltZSk7CgkJCXIucnVfc3RpbWUudHZfc2VjID0gQ1RfVE9fU0VDUyhwLT50aW1lcy50bXNfc3RpbWUgKyBwLT50aW1lcy50bXNfY3N0aW1lKTsKCQkJci5ydV9zdGltZS50dl91c2VjID0gQ1RfVE9fVVNFQ1MocC0+dGltZXMudG1zX3N0aW1lICsgcC0+dGltZXMudG1zX2NzdGltZSk7CgkJCXIucnVfbWluZmx0ID0gcC0+bWluX2ZsdCArIHAtPmNtaW5fZmx0OwoJCQlyLnJ1X21hamZsdCA9IHAtPm1hal9mbHQgKyBwLT5jbWFqX2ZsdDsKCQkJci5ydV9uc3dhcCA9IHAtPm5zd2FwICsgcC0+Y25zd2FwOwoJCQlicmVhazsKCX0KCXJldHVybiBjb3B5X3RvX3VzZXIocnUsICZyLCBzaXplb2YocikpID8gLUVGQVVMVCA6IDA7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cnVzYWdlKGludCB3aG8sIHN0cnVjdCBydXNhZ2UgKnJ1KQp7CglpZiAod2hvICE9IFJVU0FHRV9TRUxGICYmIHdobyAhPSBSVVNBR0VfQ0hJTERSRU4pCgkJcmV0dXJuIC1FSU5WQUw7CglyZXR1cm4gZ2V0cnVzYWdlKGN1cnJlbnQsIHdobywgcnUpOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX3VtYXNrKGludCBtYXNrKQp7CgltYXNrID0geGNoZygmY3VycmVudC0+ZnMtPnVtYXNrLCBtYXNrICYgU19JUldYVUdPKTsKCXJldHVybiBtYXNrOwp9CiAgICAKYXNtbGlua2FnZSBsb25nIHN5c19wcmN0bChpbnQgb3B0aW9uLCB1bnNpZ25lZCBsb25nIGFyZzIsIHVuc2lnbmVkIGxvbmcgYXJnMywKCQkJICB1bnNpZ25lZCBsb25nIGFyZzQsIHVuc2lnbmVkIGxvbmcgYXJnNSkKewoJaW50IGVycm9yID0gMDsKCWludCBzaWc7CgoJc3dpdGNoIChvcHRpb24pIHsKCQljYXNlIFBSX1NFVF9QREVBVEhTSUc6CgkJCXNpZyA9IGFyZzI7CgkJCWlmIChzaWcgPCAwIHx8IHNpZyA+IF9OU0lHKSB7CgkJCQllcnJvciA9IC1FSU5WQUw7CgkJCQlicmVhazsKCQkJfQoJCQljdXJyZW50LT5wZGVhdGhfc2lnbmFsID0gc2lnOwoJCQlicmVhazsKCQljYXNlIFBSX0dFVF9QREVBVEhTSUc6CgkJCWVycm9yID0gcHV0X3VzZXIoY3VycmVudC0+cGRlYXRoX3NpZ25hbCwgKGludCAqKWFyZzIpOwoJCQlicmVhazsKCQljYXNlIFBSX0dFVF9EVU1QQUJMRToKCQkJaWYgKGlzX2R1bXBhYmxlKGN1cnJlbnQpKQoJCQkJZXJyb3IgPSAxOwoJCQlicmVhazsKCQljYXNlIFBSX1NFVF9EVU1QQUJMRToKCQkJaWYgKGFyZzIgIT0gMCAmJiBhcmcyICE9IDEpIHsKCQkJCWVycm9yID0gLUVJTlZBTDsKCQkJCWJyZWFrOwoJCQl9CgkJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IGFyZzI7CgkJCWJyZWFrOwoKCSAgICAgICAgY2FzZSBQUl9TRVRfVU5BTElHTjoKCQkJZXJyb3IgPSBTRVRfVU5BTElHTl9DVEwoY3VycmVudCwgYXJnMik7CgkJCWJyZWFrOwoJICAgICAgICBjYXNlIFBSX0dFVF9VTkFMSUdOOgoJCQllcnJvciA9IEdFVF9VTkFMSUdOX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkgICAgICAgIGNhc2UgUFJfU0VUX0ZQRU1VOgoJCQllcnJvciA9IFNFVF9GUEVNVV9DVEwoY3VycmVudCwgYXJnMik7CgkJCWJyZWFrOwoJICAgICAgICBjYXNlIFBSX0dFVF9GUEVNVToKCQkJZXJyb3IgPSBHRVRfRlBFTVVfQ1RMKGN1cnJlbnQsIGFyZzIpOwoJCQlicmVhazsKCQljYXNlIFBSX1NFVF9GUEVYQzoKCQkJZXJyb3IgPSBTRVRfRlBFWENfQ1RMKGN1cnJlbnQsIGFyZzIpOwoJCQlicmVhazsKCQljYXNlIFBSX0dFVF9GUEVYQzoKCQkJZXJyb3IgPSBHRVRfRlBFWENfQ1RMKGN1cnJlbnQsIGFyZzIpOwoJCQlicmVhazsKCgkJY2FzZSBQUl9HRVRfS0VFUENBUFM6CgkJCWlmIChjdXJyZW50LT5rZWVwX2NhcGFiaWxpdGllcykKCQkJCWVycm9yID0gMTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfS0VFUENBUFM6CgkJCWlmIChhcmcyICE9IDAgJiYgYXJnMiAhPSAxKSB7CgkJCQllcnJvciA9IC1FSU5WQUw7CgkJCQlicmVhazsKCQkJfQoJCQljdXJyZW50LT5rZWVwX2NhcGFiaWxpdGllcyA9IGFyZzI7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCWVycm9yID0gLUVJTlZBTDsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gZXJyb3I7Cn0KCkVYUE9SVF9TWU1CT0wobm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIpOwpFWFBPUlRfU1lNQk9MKG5vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIpOwpFWFBPUlRfU1lNQk9MKG5vdGlmaWVyX2NhbGxfY2hhaW4pOwpFWFBPUlRfU1lNQk9MKHJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllcik7CkVYUE9SVF9TWU1CT0wodW5yZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIpOwpFWFBPUlRfU1lNQk9MKGluX2dyb3VwX3ApOwpFWFBPUlRfU1lNQk9MKGluX2Vncm91cF9wKTsK