Ly89PT0tLS0tLS0tLS0tLS0tLS0tIGdjYWxsb2MuaCAtIE12bSBhbGxvY2F0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KLy8KLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdm0KLy8KLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCi8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KLy8KLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KCiNpZm5kZWYgX0dDX0FMTE9DX0hfCiNkZWZpbmUgX0dDX0FMTE9DX0hfCgojaW5jbHVkZSA8c3RyaW5nLmg+IC8qIG1lbXNldCAqLwoKI2luY2x1ZGUgImdjY2h1bmsuaCIKI2luY2x1ZGUgInR5cGVzLmgiCgpjbGFzcyBHQ0ZyZWVMaXN0IHsKIAlHQ0NodW5rTm9kZSAJICpfbGlzdDsKIAl1aW50cHRyX3QJCQkJCV9jaHVua19uYmI7CiAJdWludHB0cl90CQkJCQlfYXJlYV9uYmI7CiAJdWludHB0cl90CQkJCQlfbmJfY2h1bmtzOwogCXVpbnRwdHJfdAkJCQkJX2hlYWRlcnNfbmJiOwogCXVpbnRwdHJfdCAgICAgICAgICBfZmlsbGVkOwpwdWJsaWM6CiAJaW5saW5lIEdDRnJlZUxpc3QoKSB7IF9jaHVua19uYmIgPSAwOyBfbmJfY2h1bmtzID0gMTsgfQoKIAlpbmxpbmUgdm9pZAkJCWluaXRpYWxpc2UodWludHB0cl90IG4sIHVpbnRwdHJfdCBhcmVhKSB7CiAJCV9saXN0CQkJCQk9IDA7CiAJCV9jaHVua19uYmIJCT0gbjsgCiAJCV9hcmVhX25iYgkJCT0gR0NNYXBwZWRBcmVhOjpyb3VuZChhcmVhKTsgLyogdGFpbGxlIGVuIHBhZ2VzIHV0aWxpc+llIHBvdXIgdW5lIGZyZWUtbGlzdCAqLwogCQlfbmJfY2h1bmtzCQk9IF9hcmVhX25iYi9fY2h1bmtfbmJiOyAgICAgIC8qIG5vbWJyZSBkZSB0eXBlIHF1ZSBqZSBwZXV4IGNhc2VyIGxhIGRlZGFucyAgKi8KIAkJLyogZXN0LWNlIHF1J2lsIHJlc3RlIGRlIGxhIHBsYWNlIGRlcmnocmUgPyAqLwogCQlfZmlsbGVkID0gKF9uYl9jaHVua3MgKiBfY2h1bmtfbmJiKSA9PSBfYXJlYV9uYmIgPyAwIDogMTsKIAkJLyogaid1dGlsaXNlIHVuICJmYXV4IGhlYWRlciIg4CAwIHBvdXIgY29tcGxldGVyIGNlIHRydWMgKi8KIAkJX2hlYWRlcnNfbmJiCT0gKF9uYl9jaHVua3MgKyBfZmlsbGVkKSpzaXplb2YoR0NDaHVua05vZGUpOwogCX0KCiAJaW5saW5lIEdDQ2h1bmtOb2RlICAgICpsaXN0KCkgeyByZXR1cm4gX2xpc3Q7IH0KIAlpbmxpbmUgdm9pZAkJCQkJCWxpc3QoR0NDaHVua05vZGUgKmwpIHsgX2xpc3QgPSBsOyB9CiAJaW5saW5lIHVpbnRwdHJfdAkJCQkJbmJfY2h1bmtzKCkJCXsgcmV0dXJuIF9uYl9jaHVua3M7IH0KIAlpbmxpbmUgdWludHB0cl90CQkJCQljaHVua19uYmIoKQkJeyByZXR1cm4gX2NodW5rX25iYjsgfQogCWlubGluZSB1aW50cHRyX3QJCQkJCWFyZWFfbmJiKCkJCXsgcmV0dXJuIF9hcmVhX25iYjsgfQogCWlubGluZSB1aW50cHRyX3QJCQkJCWhlYWRlcnNfbmJiKCkgeyByZXR1cm4gX2hlYWRlcnNfbmJiOyB9CiAJaW5saW5lIHVpbnRwdHJfdCAgICAgICAgIGZpbGxlZCgpICAgICAgeyByZXR1cm4gX2ZpbGxlZDsgfQoKIAlpbmxpbmUgdm9pZCByZWplY3QoR0NDaHVua05vZGUgKmhlYWRlcikgewogCQloZWFkZXItPm5leHQoX2xpc3QpOwogCQlfbGlzdCA9IGhlYWRlcjsKIAl9Cn07CgpjbGFzcyBHQ0ZyZWVMaXN0RmluZGVyIHsKIAkvKiB0cm9pcyB6b25lcyBkaXN0aW5jdGVzOiBleHBvbmVudGllbGxlL2xpbmVhaXJlL21tYXAgKi8KIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IG1pbl9leHBfbG9nID0gMDsJCQkJCQkvKiAwICAtPiA0ID0+IDQgKi8KIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IG1heF9leHBfbG9nID0gNTsJCQkJCQkvKiA0ICAtPiAzMiBlbiBleHBvbmVudGllbGxlICovCiAJc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCBtYXhfbGluX2xvZyA9IDEzOwkJCQkJCS8qIDMyIC0+IDEyOCBlbiBsaW7pYWlyZSAqLwogCXN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgbGluX3N0ZXBfbG9nID0gNDsJCQkJCQkvKiBwYXIgcGFzIGRlIDQgKi8KIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IG1pbl9leHAgPSAxIDw8IG1pbl9leHBfbG9nOwogCXN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgbWF4X2V4cCA9IDEgPDwgbWF4X2V4cF9sb2c7CiAJc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCBtYXhfbGluID0gMSA8PCBtYXhfbGluX2xvZzsKIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50CW5iX2V4cCA9IG1heF9leHBfbG9nIC0gbWluX2V4cF9sb2cgKyAxOwogCXN0YXRpYyBjb25zdCB1bnNpZ25lZCBpbnQgbmJfbGluID0gKG1heF9saW4gLSBtYXhfZXhwKT4+bGluX3N0ZXBfbG9nOwoKIAlHQ0ZyZWVMaXN0CQlfZXhwX2xpc3RzW25iX2V4cF07CiAJR0NGcmVlTGlzdAkJKmV4cF9saXN0c1ttYXhfZXhwKzFdOwogCUdDRnJlZUxpc3QJCWxpbl9saXN0c1tuYl9saW5dOwogCUdDRnJlZUxpc3QJCW1tYXBfbGlzdDsKCiAJaW5saW5lIHVpbnRwdHJfdCBsaW5FbnRyeSh1aW50cHRyX3QgbikgeyByZXR1cm4gKG4gLSBtYXhfZXhwIC0gMSk+Pmxpbl9zdGVwX2xvZzsgfQpwdWJsaWM6CiAJR0NGcmVlTGlzdEZpbmRlcigpOwoKIAlzdGF0aWMgaW5saW5lIGJvb2wJCWlzTW1hcGVkKHVpbnRwdHJfdCBuKSB7IHJldHVybiBuPm1heF9saW47IH0KCiAJaW5saW5lIEdDRnJlZUxpc3QgKmZpbmQodWludHB0cl90IG4pIHsKIAkJcmV0dXJuIGlzTW1hcGVkKG4pID8gJm1tYXBfbGlzdCA6IChuPm1heF9leHApID8gbGluX2xpc3RzICsgbGluRW50cnkobikgOiBleHBfbGlzdHNbbl07IAogCX0KfTsKCmNsYXNzIEdDQWxsb2NhdG9yIHsKIAlzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50CQl1c2VkX2hlYWRlcnNfbmJiID0gKFBBR0VfU0laRSArICg0MDk2KnNpemVvZihHQ0NodW5rTm9kZSkpIC0gMSkgJiAtUEFHRV9TSVpFOwoKCXVpbnRwdHJfdCAgICBteV9zaXplOwogCUdDRnJlZUxpc3RGaW5kZXIJdW5kZWZpbmVkX2ZpbmRlcjsKIAlHQ0ZyZWVMaXN0RmluZGVyCXplcm9fZmlsbGVkX2ZpbmRlcjsKCglHQ01hcHBlZEFyZWEJCW5vcm1hbF9hcmVhOyAgICAvKiBhcmVhIHBvdXIgbGVzIHBldGl0IGNodW5rICovCglHQ01hcHBlZEFyZWEJCW1hcHBlZF9hcmVhOyAgICAvKiBwb3VyIGxlcyBncm9zICovCglHQ01hcHBlZEFyZWEJCWhlYWRlcnNfYXJlYTsgICAvKiBsaXN0ZSBkZXMgbW1hcCBkZXMgaGVhZGVycyAqLwoJR0NDaHVua05vZGUJCSAgKnVzZWRfaGVhZGVyczsgIC8qIHVuZSBsaXN0ZSBkZSBoZWFkZXJzIHBvdXIgbGVzIHByb2NoYWluZXMgYWxsb2NfbGlzdCAqLwoJR0NDaHVua05vZGUJCSAgKm1heF9oZWFkZXJzOyAgIC8qIGxhIGxpbWl0ZSAqLwoKCUdDQ2h1bmtOb2RlICAgICAqYWxsb2NfaGVhZGVycyh1aW50cHRyX3QsIHZvaWQgKiwgdWludHB0cl90LCB1aW50cHRyX3QpOwoJR0NDaHVua05vZGUgICAgICphbGxvY19saXN0KEdDRnJlZUxpc3QgKiwgdWludHB0cl90KTsKcHVibGljOgoJR0NBbGxvY2F0b3IoKTsKIAl+R0NBbGxvY2F0b3IoKTsKCgl2b2lkICpvcGVyYXRvciBuZXcodWludHB0cl90KTsKCXZvaWQgb3BlcmF0b3IgZGVsZXRlKHZvaWQgKik7CgogCWlubGluZSBHQ1BhZ2UgICAgICAgICpvMnBhZ2Uodm9pZCAqcHRyKSB7IHJldHVybiBHQ0hhc2g6OmdldChwdHIpOyB9CgogCWlubGluZSBHQ0NodW5rTm9kZSAqYWxsb2NfY2h1bmsodWludHB0cl90IG4sIGJvb2wgaXNDb2wsIHVuc2lnbmVkIGludCBtKSB7CgkJR0NGcmVlTGlzdAkJCSAgICAgKmZsID0gdW5kZWZpbmVkX2ZpbmRlci5maW5kKG4pOwoJCXJlZ2lzdGVyIEdDQ2h1bmtOb2RlICpyZXMgPSBmbC0+bGlzdCgpOwoJCQoJCWlmKCFyZXMpCgkJCXJlcyA9IGFsbG9jX2xpc3QoZmwsIG4pOwoJCQoJCWZsLT5saXN0KHJlcy0+bmV4dCgpKTsKCQlyZXMtPm5iYihuLCBpc0NvbCwgbSk7CgoJCXJldHVybiByZXM7CiAJfQoJCiAJaW5saW5lIHZvaWQgcmVqZWN0X2NodW5rKEdDUGFnZSAqcGFnZSwgR0NDaHVua05vZGUgKmhlYWRlcikgewogCQlHQ0ZyZWVMaXN0ICpmbCA9IHVuZGVmaW5lZF9maW5kZXIuZmluZChwYWdlLT5jaHVua19uYmIoKSk7CgkJCiAJCWlmKGZsLT5jaHVua19uYmIoKSkgewoJCQkvLwkJCXByaW50ZigiMCBGaWxsZWQgJXAgd2l0aCAlZCBieXRlc1xuIiwgaGVhZGVyLT5jaHVuaygpLCBoZWFkZXItPm5iYigpKTsKCQkJbWVtc2V0KGhlYWRlci0+Y2h1bmsoKSwgMCwgaGVhZGVyLT5uYmIoKSk7CgkJCWhlYWRlci0+ZnJlZSgpOwogCQkJZmwtPnJlamVjdChoZWFkZXIpOwoJCX0gZWxzZSB7CgkJCUdDSGFzaDo6aGFzaF91bnByb3RlY3RlZChwYWdlLCBwYWdlLT5hcmVhKCksIHBhZ2UtPm5iYigpLCAwKTsKCQkJcGFnZS0+cmVqZWN0KCk7CgkJCWRlbGV0ZSAoR0NQYWdlICopKHBhZ2UtPm11bm1hcCgpKTsKIAkJfQogCX0KCQogCWlubGluZSB2b2lkIHJlamVjdF9jaHVuayhHQ0NodW5rTm9kZSAqaGVhZGVyKSB7CiAJCXJlamVjdF9jaHVuayhvMnBhZ2UoaGVhZGVyLT5jaHVuaygpKSwgaGVhZGVyKTsKIAl9CgkKIAlpbmxpbmUgR0NDaHVua05vZGUgKnN0dXBpZF9yZWFsbG9jX2NodW5rKEdDQ2h1bmtOb2RlICpvbGRfaGVhZGVyLCB1aW50cHRyX3QgbmV3X25iYikgewogCQlHQ0NodW5rTm9kZSAqbmV3X2hlYWRlciA9IGFsbG9jX2NodW5rKG5ld19uYmIsIG9sZF9oZWFkZXItPmlzQ29sbGVjdGFibGUoKSwgb2xkX2hlYWRlci0+bWFyaygpKTsKIAkJdWludHB0cl90IG9sZCA9IG9sZF9oZWFkZXItPm5iYigpOwogCQl1aW50cHRyX3QgbmJiID0gb2xkIDwgbmV3X25iYiA/IG9sZCA6IG5ld19uYmI7CiAJCW1lbWNweShuZXdfaGVhZGVyLT5jaHVuaygpLCBvbGRfaGVhZGVyLT5jaHVuaygpLCBuYmIpOwogCQlyZXR1cm4gbmV3X2hlYWRlcjsKIAl9CgkKIAlpbmxpbmUgR0NDaHVua05vZGUgKnJlYWxsb2NfY2h1bmsoR0NQYWdlICpwYWdlLCBHQ0NodW5rTm9kZSAqb2xkX2hlYWRlciwgdWludHB0cl90IG5ld19uYmIpIHsKIAkJR0NDaHVua05vZGUgKm5ld19oZWFkZXIgPSBvbGRfaGVhZGVyOwogCQl1aW50cHRyX3QJICAgICBtYXhfbmJiID0gcGFnZS0+Y2h1bmtfbmJiKCk7CgkJCiAJCWlmKEdDRnJlZUxpc3RGaW5kZXI6OmlzTW1hcGVkKG1heF9uYmIpKQogCQkJaWYoR0NGcmVlTGlzdEZpbmRlcjo6aXNNbWFwZWQobmV3X25iYikpIHsKIAkJCQkvKiBsZSBwbHVzIGNvbXBsaXF16Swgb24gZXNzYXllIGRlIGZhaXJlIHVuIG1yZW1hcCBkJ3VuIHBldGl0IGJvdXQuLi4gKi8KIAkJCQl1aW50cHRyX3QJCQkJCQkJcm91bmRlZCA9IEdDTWFwcGVkQXJlYTo6cm91bmQobmV3X25iYik7CgkJCQl1aW50cHRyX3QgICAgICAgICAgICAgIG9sZF9uYmIgPSBwYWdlLT5uYmIoKTsKIAkJCQlzaWduZWQgaW50CQkJCQlkZXBsID0gcm91bmRlZCAtIHBhZ2UtPm5iYigpOwogCQkJCWlmKGRlcGwpIHsKIAkJCQkJaWYocGFnZS0+bXJlbWFwKHJvdW5kZWQpID09IC0xKSAvKiBwZXJkdSAqLwogCQkJCQkJcmV0dXJuIG5ld19oZWFkZXIgPSBzdHVwaWRfcmVhbGxvY19jaHVuayhvbGRfaGVhZGVyLCBuZXdfbmJiKTsKIAkJCQkJZWxzZSB7CiAJCQkJCQlpZihkZXBsID4gMCkKIAkJCQkJCQlHQ0hhc2g6Omhhc2hfdW5wcm90ZWN0ZWQocGFnZSwgKHZvaWQgKikoKHVpbnRwdHJfdClwYWdlLT5hcmVhKCkgKyBvbGRfbmJiKSwgZGVwbCwgZGVwbCk7CiAJCQkJCQllbHNlCiAJCQkJCQkJR0NIYXNoOjpoYXNoX3VucHJvdGVjdGVkKHBhZ2UsICh2b2lkICopKCh1aW50cHRyX3QpcGFnZS0+YXJlYSgpICsgcm91bmRlZCksIC1kZXBsLCAwKTsKIAkJCQkJfQogCQkJCX0KCQkJCXBhZ2UtPmNodW5rX25iYihyb3VuZGVkKTsKIAkJCQlvbGRfaGVhZGVyLT5uYmIobmV3X25iYik7CiAJCQl9IGVsc2UKIAkJCQluZXdfaGVhZGVyID0gc3R1cGlkX3JlYWxsb2NfY2h1bmsob2xkX2hlYWRlciwgbmV3X25iYik7CiAJCWVsc2UKIAkJCWlmKG5ld19uYmIgPD0gbWF4X25iYikKIAkJCQlvbGRfaGVhZGVyLT5uYmIobmV3X25iYik7CiAJCQllbHNlCiAJCQkJbmV3X2hlYWRlciA9IHN0dXBpZF9yZWFsbG9jX2NodW5rKG9sZF9oZWFkZXIsIG5ld19uYmIpOwogCQlyZXR1cm4gbmV3X2hlYWRlcjsKIAl9CgogCWlubGluZSB2b2lkICphbGxvYyh1aW50cHRyX3Qgc3opIHsgcmV0dXJuIGFsbG9jX2NodW5rKHN6LCAwLCAwKS0+Y2h1bmsoKTsgfQoJCiAJaW5saW5lIHZvaWQgZnJlZSh2b2lkICpwdHIpIHsKIAkJR0NQYWdlICAgICAJKnBhZ2UgPSBvMnBhZ2UocHRyKTsKIAkJR0NDaHVua05vZGUJKmhlYWRlciA9IHBhZ2UtPm8ybm9kZShwdHIsIEdDQ2h1bmtOb2RlOjptYXNrTm90Q29sbGVjdGFibGUpOwoKIAkJaWYoIWhlYWRlcikKIAkJCWdjZmF0YWwoIiVwIGlzbid0IGFuIG9iamVjdCIsIHB0cik7CgkJCiAJCXJlamVjdF9jaHVuayhwYWdlLCBoZWFkZXIpOwogCX0KCiAJaW5saW5lIHZvaWQgKnJlYWxsb2Modm9pZCAqcHRyLCB1aW50cHRyX3QgbmJiKSB7CiAJCUdDUGFnZSAgICAgIAkqcGFnZSA9IG8ycGFnZShwdHIpOwogCQlHQ0NodW5rTm9kZSAgICpoZWFkZXIgPSBwYWdlLT5vMm5vZGUocHRyLCBHQ0NodW5rTm9kZTo6bWFza05vdENvbGxlY3RhYmxlKTsKCQkKIAkJaWYoIWhlYWRlcikKIAkJCWdjZmF0YWwoIiVwIGlzbid0IGFuIG9iamVjdCIsIGhlYWRlcik7CgkJCiAJCXJlZ2lzdGVyIEdDQ2h1bmtOb2RlICpuZXdfaGVhZGVyID0gcmVhbGxvY19jaHVuayhwYWdlLCBoZWFkZXIsIG5iYik7CiAJCWlmKG5ld19oZWFkZXIgIT0gaGVhZGVyKQogCQkJcmVqZWN0X2NodW5rKHBhZ2UsIGhlYWRlcik7CgogCQlyZXR1cm4gbmV3X2hlYWRlci0+Y2h1bmsoKTsKIAl9Cn07CgojZW5kaWYK