LyogCiAqIEltcGxlbWVudGF0aW9uIG9mIFZFUi5ETEwKICogCiAqIENvcHlyaWdodCAxOTk2IE1hcmN1cyBNZWlzc25lcgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ2ZXIuaCIKI2luY2x1ZGUgImx6ZXhwYW5kLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAic3RyaW5nMzIuaCIKCiNkZWZpbmUgTFpSRUFEKHdoYXQpIFwKICBpZiAoc2l6ZW9mKCp3aGF0KSE9TFpSZWFkMzIobHpmZCx3aGF0LHNpemVvZigqd2hhdCkpKSByZXR1cm4gMDsKI2RlZmluZSBMWlRFTEwobHpmZCkgTFpTZWVrKGx6ZmQsIDAsIFNFRUtfQ1VSKTsKCiNkZWZpbmUgc3RyZHVwVzJBKHgpCVNUUklORzMyX0R1cFVuaVRvQW5zaSh4KQojZGVmaW5lIHN0cmR1cEEyVyh4KQlTVFJJTkczMl9EdXBBbnNpVG9VbmkoeCkKCmludApyZWFkX25lX2hlYWRlcihIRklMRSBsemZkLHN0cnVjdCBuZV9oZWFkZXJfcyAqbmVoZCkgewoJc3RydWN0CW16X2hlYWRlcl9zCW16aDsKCglMWlNlZWsobHpmZCwwLFNFRUtfU0VUKTsKCWlmIChzaXplb2YobXpoKSE9TFpSZWFkMzIobHpmZCwmbXpoLHNpemVvZihtemgpKSkKCQlyZXR1cm4gMDsKCWlmIChtemgubXpfbWFnaWMhPU1aX1NJR05BVFVSRSkKCQlyZXR1cm4gMDsKCUxaU2VlayhsemZkLG16aC5uZV9vZmZzZXQsU0VFS19TRVQpOwoJTFpSRUFEKG5laGQpOwoJaWYgKG5laGQtPm5lX21hZ2ljID09IE5FX1NJR05BVFVSRSkgewoJCUxaU2VlayhsemZkLG16aC5uZV9vZmZzZXQsU0VFS19TRVQpOwoJCXJldHVybiAxOwoJfQoJLyogbXVzdCBoYW5kbGUgUEUgZmlsZXMgdG9vLiBMYXRlci4gKi8KCXJldHVybiAwOwp9CgoKaW50CmZpbmRfbmVfcmVzb3VyY2UoCglIRklMRSBsemZkLHN0cnVjdCBuZV9oZWFkZXJfcyAqbmVoZCxTRUdQVFIgdHlwZWlkLFNFR1BUUiByZXNpZCwKCUJZVEUgKipyZXNkYXRhLGludCAqcmVzbGVuLERXT1JEICpvZmYKKSB7CglORV9UWVBFSU5GTwl0aTsKCU5FX05BTUVJTkZPCW5pOwoJaW50CQlpOwoJV09SRAkJc2hpZnRjb3VudDsKCURXT1JECQluZWhkb2Zmc2V0OwoKCW5laGRvZmZzZXQgPSBMWlRFTEwobHpmZCk7CglMWlNlZWsobHpmZCxuZWhkLT5yZXNvdXJjZV90YWJfb2Zmc2V0LFNFRUtfQ1VSKTsKCUxaUkVBRCgmc2hpZnRjb3VudCk7CglkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwic2hpZnRjb3VudCBpcyAlZFxuIixzaGlmdGNvdW50KTsKCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCJyZWFkaW5nIHJlc291cmNlIHR5cGVpbmZvIGRpci5cbiIpOwoKCWlmICghSElXT1JEKHR5cGVpZCkpIHR5cGVpZCA9IChTRUdQVFIpKExPV09SRCh0eXBlaWQpIHwgMHg4MDAwKTsKCWlmICghSElXT1JEKHJlc2lkKSkgIHJlc2lkICA9IChTRUdQVFIpKExPV09SRChyZXNpZCkgfCAweDgwMDApOwoJd2hpbGUgKDEpIHsKCQlpbnQJc2tpcGZsYWc7CgoJCUxaUkVBRCgmdGkpOwoJCWlmICghdGkudHlwZV9pZCkKCQkJcmV0dXJuIDA7CgkJZHByaW50Zl9yZXNvdXJjZShzdGRlcnIsIiAgICB0aS50eXBlaWQgPSUwNHgsY291bnQ9JWRcbiIsdGkudHlwZV9pZCx0aS5jb3VudCk7CgkJc2tpcGZsYWc9MDsKCQlpZiAoIUhJV09SRCh0eXBlaWQpKSB7CgkJCWlmICgodGkudHlwZV9pZCYweDgwMDApJiYodHlwZWlkIT10aS50eXBlX2lkKSkKCQkJCXNraXBmbGFnPTE7CgkJfSBlbHNlIHsKCQkJaWYgKHRpLnR5cGVfaWQgJiAweDgwMDApIHsKCQkJCXNraXBmbGFnPTE7IAoJCQl9IGVsc2UgewoJCQkJQllURQlsZW47CgkJCQljaGFyCSpzdHI7CgkJCQlEV09SRAl3aGVyZWxlZnQ7CgoJCQkJd2hlcmVsZWZ0ID0gTFpURUxMKGx6ZmQpOwoJCQkJTFpTZWVrKAoJCQkJCWx6ZmQsCgkJCQkJbmVoZG9mZnNldCtuZWhkLT5yZXNvdXJjZV90YWJfb2Zmc2V0K3RpLnR5cGVfaWQsCgkJCQkJU0VFS19TRVQKCQkJCSk7CgkJCQlMWlJFQUQoJmxlbik7CgkJCQlzdHI9eG1hbGxvYyhsZW4pOwoJCQkJaWYgKGxlbiE9TFpSZWFkMzIobHpmZCxzdHIsbGVuKSkKCQkJCQlyZXR1cm4gMDsKCQkJCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCJyZWFkICVzIHRvIGNvbXBhcmUgaXQgd2l0aCAlc1xuIiwKCQkJCQlzdHIsKGNoYXIqKVBUUl9TRUdfVE9fTElOKHR5cGVpZCkKCQkJCSk7CgkJCQlpZiAobHN0cmNtcGkzMkEoc3RyLChjaGFyKilQVFJfU0VHX1RPX0xJTih0eXBlaWQpKSkKCQkJCQlza2lwZmxhZz0xOwoJCQkJZnJlZShzdHIpOwoJCQkJTFpTZWVrKGx6ZmQsd2hlcmVsZWZ0LFNFRUtfU0VUKTsKCQkJfQoJCX0KCQlpZiAoc2tpcGZsYWcpIHsKCQkJTFpTZWVrKGx6ZmQsdGkuY291bnQqc2l6ZW9mKG5pKSxTRUVLX0NVUik7CgkJCWNvbnRpbnVlOwoJCX0KCQlmb3IgKGk9MDtpPHRpLmNvdW50O2krKykgewoJCQlXT1JECSpyZGF0YTsKCQkJaW50CWxlbjsKCgkJCUxaUkVBRCgmbmkpOwoJCQlkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwiCW5pLmlkPSU0eCxvZmZzZXQ9JWQsbGVuZ3RoPSVkXG4iLAoJCQkJbmkuaWQsbmkub2Zmc2V0LG5pLmxlbmd0aAoJCQkpOwoJCQlza2lwZmxhZz0xOwoJCQlpZiAoIUhJV09SRChyZXNpZCkpIHsKCQkJCWlmIChuaS5pZCA9PSByZXNpZCkKCQkJCQlza2lwZmxhZz0wOwoJCQl9IGVsc2UgewoJCQkJaWYgKCEobmkuaWQgJiAweDgwMDApKSB7CgkJCQkJQllURQlsZW47CgkJCQkJY2hhcgkqc3RyOwoJCQkJCURXT1JECXdoZXJlbGVmdDsKCgkJCQkJd2hlcmVsZWZ0ID0gTFpURUxMKGx6ZmQpOwoJCQkJCSAgTFpTZWVrKAoJCQkJCQlsemZkLAoJCQkJCQluZWhkb2Zmc2V0K25laGQtPnJlc291cmNlX3RhYl9vZmZzZXQrbmkuaWQsCgkJCQkJCVNFRUtfU0VUCgkJCQkJKTsKCQkJCQlMWlJFQUQoJmxlbik7CgkJCQkJc3RyPXhtYWxsb2MobGVuKTsKCQkJCQlpZiAobGVuIT1MWlJlYWQzMihsemZkLHN0cixsZW4pKQoJCQkJCQlyZXR1cm4gMDsKCQkJCQlkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwicmVhZCAlcyB0byBjb21wYXJlIGl0IHdpdGggJXNcbiIsCgkJCQkJCXN0ciwoY2hhciopUFRSX1NFR19UT19MSU4odHlwZWlkKQoJCQkJCSk7CgkJCQkJaWYgKCFsc3RyY21waTMyQShzdHIsKGNoYXIqKVBUUl9TRUdfVE9fTElOKHR5cGVpZCkpKQoJCQkJCQlza2lwZmxhZz0wOwoJCQkJCWZyZWUoc3RyKTsKCQkJCQlMWlNlZWsobHpmZCx3aGVyZWxlZnQsU0VFS19TRVQpOwoJCQkJfQoJCQl9CgkJCWlmIChza2lwZmxhZykKCQkJCWNvbnRpbnVlOwoJCQlMWlNlZWsobHpmZCwoKGludCluaS5vZmZzZXQ8PHNoaWZ0Y291bnQpLFNFRUtfU0VUKTsKCQkJKm9mZgk9IChpbnQpbmkub2Zmc2V0PDxzaGlmdGNvdW50OwoJCQlsZW4JPSBuaS5sZW5ndGg8PHNoaWZ0Y291bnQ7CgkJCXJkYXRhPShXT1JEKil4bWFsbG9jKGxlbik7CgkJCWlmIChsZW4hPUxaUmVhZDMyKGx6ZmQscmRhdGEsbGVuKSkgewoJCQkJZnJlZShyZGF0YSk7CgkJCQlyZXR1cm4gMDsKCQkJfQoJCQlkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwicmVzb3VyY2UgZm91bmQuXG4iKTsKCQkJKnJlc2RhdGE9IChCWVRFKilyZGF0YTsKCQkJKnJlc2xlbgk9IGxlbjsKCQkJcmV0dXJuIDE7CgkJfQoJfQp9CgovKiBHZXRGaWxlUmVzb3VyY2VTaXplCQkJCVtWRVIuMl0gKi8KRFdPUkQKR2V0RmlsZVJlc291cmNlU2l6ZShMUENTVFIgZmlsZW5hbWUsU0VHUFRSIHJlc3R5cGUsU0VHUFRSIHJlc2lkLExQRFdPUkQgb2ZmKSB7CglIRklMRQlsemZkOwoJT0ZTVFJVQ1QJb2ZzOwoJQllURQkqcmVzZGF0YTsKCWludAlyZXNsZW47CglzdHJ1Y3QJbmVfaGVhZGVyX3MJbmVoZDsKCglmcHJpbnRmKHN0ZGVyciwiR2V0RmlsZVJlc291cmNlU2l6ZSglcywlbHgsJWx4LCVwKVxuIiwKCQlmaWxlbmFtZSwoTE9ORylyZXN0eXBlLChMT05HKXJlc2lkLG9mZgoJKTsKCWx6ZmQ9TFpPcGVuRmlsZTE2KGZpbGVuYW1lLCZvZnMsT0ZfUkVBRCk7CglpZiAobHpmZD09MCkKCQlyZXR1cm4gMDsKCWlmICghcmVhZF9uZV9oZWFkZXIobHpmZCwmbmVoZCkpIHsKCQlMWkNsb3NlKGx6ZmQpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFmaW5kX25lX3Jlc291cmNlKGx6ZmQsJm5laGQscmVzdHlwZSxyZXNpZCwmcmVzZGF0YSwmcmVzbGVuLG9mZikpIHsKCQlMWkNsb3NlKGx6ZmQpOwoJCXJldHVybiAwOwoJfQoJZnJlZShyZXNkYXRhKTsKCUxaQ2xvc2UobHpmZCk7CglyZXR1cm4gcmVzbGVuOwp9CgovKiBHZXRGaWxlUmVzb3VyY2UJCQkJW1ZFUi4zXSAqLwpEV09SRApHZXRGaWxlUmVzb3VyY2UoTFBDU1RSIGZpbGVuYW1lLFNFR1BUUiByZXN0eXBlLFNFR1BUUiByZXNpZCwKCQlEV09SRCBvZmYsRFdPUkQgZGF0YWxlbixMUFZPSUQgZGF0YQopIHsKCUhGSUxFCWx6ZmQ7CglPRlNUUlVDVAlvZnM7CglCWVRFCSpyZXNkYXRhOwoJaW50CXJlc2xlbj1kYXRhbGVuOwoJc3RydWN0CW5lX2hlYWRlcl9zCW5laGQ7CglmcHJpbnRmKHN0ZGVyciwiR2V0RmlsZVJlc291cmNlKCVzLCVseCwlbHgsJWxkLCVsZCwlcClcbiIsCgkJZmlsZW5hbWUsKExPTkcpcmVzdHlwZSwoTE9ORylyZXNpZCxvZmYsZGF0YWxlbixkYXRhCgkpOwoKCWx6ZmQ9TFpPcGVuRmlsZTE2KGZpbGVuYW1lLCZvZnMsT0ZfUkVBRCk7CglpZiAobHpmZD09MCkKCQlyZXR1cm4gMDsKCWlmICghb2ZmKSB7CgkJaWYgKCFyZWFkX25lX2hlYWRlcihsemZkLCZuZWhkKSkgewoJCQlMWkNsb3NlKGx6ZmQpOwoJCQlyZXR1cm4gMDsKCQl9CgkJaWYgKCFmaW5kX25lX3Jlc291cmNlKGx6ZmQsJm5laGQscmVzdHlwZSxyZXNpZCwmcmVzZGF0YSwmcmVzbGVuLCZvZmYpKSB7CgkJCUxaQ2xvc2UobHpmZCk7CgkJCXJldHVybiAwOwoJCX0KCQlmcmVlKHJlc2RhdGEpOwoJfQoJTFpTZWVrKGx6ZmQsb2ZmLFNFRUtfU0VUKTsKCWlmIChyZXNsZW4+ZGF0YWxlbikKCQlyZXNsZW49ZGF0YWxlbjsKCUxaUmVhZDMyKGx6ZmQsZGF0YSxyZXNsZW4pOwoJTFpDbG9zZShsemZkKTsKCXJldHVybiByZXNsZW47Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mb1NpemUJCQlbVkVSLjZdICovCkRXT1JECkdldEZpbGVWZXJzaW9uSW5mb1NpemUxNihMUENTVFIgZmlsZW5hbWUsTFBEV09SRCBoYW5kbGUpIHsKCURXT1JECWxlbixyZXQ7CglCWVRFCWJ1Zls3Ml07CglWU19GSVhFREZJTEVJTkZPICp2ZmZpOwoKCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCJHZXRGaWxlVmVyc2lvbkluZm9TaXplMTYoJXMsJXApXG4iLGZpbGVuYW1lLGhhbmRsZSk7CglsZW49R2V0RmlsZVJlc291cmNlU2l6ZShmaWxlbmFtZSxWU19GSUxFX0lORk8sVlNfVkVSU0lPTl9JTkZPLGhhbmRsZSk7CglpZiAoIWxlbikKCQlyZXR1cm4gMDsKCXJldD1HZXRGaWxlUmVzb3VyY2UoCgkJZmlsZW5hbWUsVlNfRklMRV9JTkZPLFZTX1ZFUlNJT05fSU5GTywqaGFuZGxlLHNpemVvZihidWYpLGJ1ZgoJKTsKCWlmICghcmV0KQoJCXJldHVybiAwOwoKCXZmZmk9KFZTX0ZJWEVERklMRUlORk8qKShidWYrMHgxNCk7CglpZiAodmZmaS0+ZHdTaWduYXR1cmUgIT0gVlNfRkZJX1NJR05BVFVSRSkKCQlyZXR1cm4gMDsKCWlmICgqKFdPUkQqKWJ1ZiA8IGxlbikKCQlsZW4gPSAqKFdPUkQqKWJ1ZjsKCWZwcmludGYoc3RkZXJyLCItPnN0cnVjdmVyPSVsZC4lbGQsZmlsZXZlcj0lbGQuJWxkLHByb2R1Y3R2ZXI9JWxkLiVsZCxmbGFnbWFzaz0lbHgsZmxhZ3M9JWx4LE9TPSIsCgkJKHZmZmktPmR3U3RydWNWZXJzaW9uPj4xNiksdmZmaS0+ZHdTdHJ1Y1ZlcnNpb24mMHhGRkZGLAoJCXZmZmktPmR3RmlsZVZlcnNpb25NUyx2ZmZpLT5kd0ZpbGVWZXJzaW9uTFMsCgkJdmZmaS0+ZHdQcm9kdWN0VmVyc2lvbk1TLHZmZmktPmR3UHJvZHVjdFZlcnNpb25MUywKCQl2ZmZpLT5kd0ZpbGVGbGFnc01hc2ssdmZmaS0+ZHdGaWxlRmxhZ3MKCSk7Cglzd2l0Y2ggKHZmZmktPmR3RmlsZU9TJjB4RkZGRjAwMDApIHsKCWNhc2UgVk9TX0RPUzpmcHJpbnRmKHN0ZGVyciwiRE9TLCIpO2JyZWFrOwoJY2FzZSBWT1NfT1MyMTY6ZnByaW50ZihzdGRlcnIsIk9TLzItMTYsIik7YnJlYWs7CgljYXNlIFZPU19PUzIzMjpmcHJpbnRmKHN0ZGVyciwiT1MvMi0zMiwiKTticmVhazsKCWNhc2UgVk9TX05UOmZwcmludGYoc3RkZXJyLCJOVCwiKTticmVhazsKCWNhc2UgVk9TX1VOS05PV046CglkZWZhdWx0OgoJCWZwcmludGYoc3RkZXJyLCJVTktOT1dOKCVsZCksIix2ZmZpLT5kd0ZpbGVPUyYweEZGRkYwMDAwKTticmVhazsKCX0KCXN3aXRjaCAodmZmaS0+ZHdGaWxlT1MgJiAweEZGRkYpIHsKCWNhc2UgVk9TX19CQVNFOmZwcmludGYoc3RkZXJyLCJCQVNFIik7YnJlYWs7CgljYXNlIFZPU19fV0lORE9XUzE2OmZwcmludGYoc3RkZXJyLCJXSU4xNiIpO2JyZWFrOwoJY2FzZSBWT1NfX1dJTkRPV1MzMjpmcHJpbnRmKHN0ZGVyciwiV0lOMzIiKTticmVhazsKCWNhc2UgVk9TX19QTTE2OmZwcmludGYoc3RkZXJyLCJQTTE2Iik7YnJlYWs7CgljYXNlIFZPU19fUE0zMjpmcHJpbnRmKHN0ZGVyciwiUE0zMiIpO2JyZWFrOwoJZGVmYXVsdDpmcHJpbnRmKHN0ZGVyciwiVU5LTk9XTiglbGQpIix2ZmZpLT5kd0ZpbGVPUyYweEZGRkYpO2JyZWFrOwoJfQoJc3dpdGNoICh2ZmZpLT5kd0ZpbGVUeXBlKSB7CglkZWZhdWx0OgoJY2FzZSBWRlRfVU5LTk9XTjoKCQlmcHJpbnRmKHN0ZGVyciwiZmlsZXR5cGU9VW5rbm93biglbGQpIix2ZmZpLT5kd0ZpbGVUeXBlKTsKCQlicmVhazsKCWNhc2UgVkZUX0FQUDpmcHJpbnRmKHN0ZGVyciwiZmlsZXR5cGU9QVBQIik7YnJlYWs7CgljYXNlIFZGVF9ETEw6ZnByaW50ZihzdGRlcnIsImZpbGV0eXBlPURMTCIpO2JyZWFrOwoJY2FzZSBWRlRfRFJWOgoJCWZwcmludGYoc3RkZXJyLCJmaWxldHlwZT1EUlYsIik7CgkJc3dpdGNoKHZmZmktPmR3RmlsZVN1YnR5cGUpIHsKCQlkZWZhdWx0OgoJCWNhc2UgVkZUMl9VTktOT1dOOgoJCQlmcHJpbnRmKHN0ZGVyciwiVU5LTk9XTiglbGQpIix2ZmZpLT5kd0ZpbGVTdWJ0eXBlKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9QUklOVEVSOgoJCQlmcHJpbnRmKHN0ZGVyciwiUFJJTlRFUiIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0tFWUJPQVJEOgoJCQlmcHJpbnRmKHN0ZGVyciwiS0VZQk9BUkQiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9MQU5HVUFHRToKCQkJZnByaW50ZihzdGRlcnIsIkxBTkdVQUdFIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfRElTUExBWToKCQkJZnByaW50ZihzdGRlcnIsIkRJU1BMQVkiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9NT1VTRToKCQkJZnByaW50ZihzdGRlcnIsIk1PVVNFIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfTkVUV09SSzoKCQkJZnByaW50ZihzdGRlcnIsIk5FVFdPUksiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9TWVNURU06CgkJCWZwcmludGYoc3RkZXJyLCJTWVNURU0iKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9JTlNUQUxMQUJMRToKCQkJZnByaW50ZihzdGRlcnIsIklOU1RBTExBQkxFIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfU09VTkQ6CgkJCWZwcmludGYoc3RkZXJyLCJTT1VORCIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0NPTU06CgkJCWZwcmludGYoc3RkZXJyLCJDT01NIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfSU5QVVRNRVRIT0Q6CgkJCWZwcmludGYoc3RkZXJyLCJJTlBVVE1FVEhPRCIpOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7CgljYXNlIFZGVF9GT05UOgoJCWZwcmludGYoc3RkZXJyLCJmaWxldHlwZT1GT05ULiIpOwoJCXN3aXRjaCAodmZmaS0+ZHdGaWxlU3VidHlwZSkgewoJCWRlZmF1bHQ6CgkJCWZwcmludGYoc3RkZXJyLCJVTktOT1dOKCVsZCkiLHZmZmktPmR3RmlsZVN1YnR5cGUpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRk9OVF9SQVNURVI6ZnByaW50ZihzdGRlcnIsIlJBU1RFUiIpO2JyZWFrOwoJCWNhc2UgVkZUMl9GT05UX1ZFQ1RPUjpmcHJpbnRmKHN0ZGVyciwiVkVDVE9SIik7YnJlYWs7CgkJY2FzZSBWRlQyX0ZPTlRfVFJVRVRZUEU6ZnByaW50ZihzdGRlcnIsIlRSVUVUWVBFIik7YnJlYWs7CgkJfQoJCWJyZWFrOwoJY2FzZSBWRlRfVlhEOmZwcmludGYoc3RkZXJyLCJmaWxldHlwZT1WWEQiKTticmVhazsKCWNhc2UgVkZUX1NUQVRJQ19MSUI6ZnByaW50ZihzdGRlcnIsImZpbGV0eXBlPVNUQVRJQ19MSUIiKTticmVhazsKCX0KCWZwcmludGYoc3RkZXJyLCJmaWxlZGF0YT0lbHguJWx4XG4iLHZmZmktPmR3RmlsZURhdGVNUyx2ZmZpLT5kd0ZpbGVEYXRlTFMpOwoJcmV0dXJuIGxlbjsKfQoKLyogR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTMyQQkJCVtWRVJTSU9OLjFdICovCkRXT1JECkdldEZpbGVWZXJzaW9uSW5mb1NpemUzMkEoTFBDU1RSIGZpbGVuYW1lLExQRFdPUkQgaGFuZGxlKSB7CglkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwiR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTMyQSglcywlcClcbiIsZmlsZW5hbWUsaGFuZGxlKTsKCXJldHVybiBHZXRGaWxlVmVyc2lvbkluZm9TaXplMTYoZmlsZW5hbWUsaGFuZGxlKTsKfQoKLyogR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTMyVwkJCVtWRVJTSU9OLjJdICovCkRXT1JECkdldEZpbGVWZXJzaW9uSW5mb1NpemUzMlcoTFBDV1NUUiBmaWxlbmFtZSxMUERXT1JEIGhhbmRsZSkgewoJTFBTVFIJeGZuOwoJRFdPUkQJcmV0OwoKCXhmbgk9IHN0cmR1cFcyQShmaWxlbmFtZSk7CglyZXQ9R2V0RmlsZVZlcnNpb25JbmZvU2l6ZTE2KHhmbixoYW5kbGUpOwoJZnJlZSh4Zm4pOwoJcmV0dXJuCXJldDsKfQoKLyogR2V0RmlsZVZlcnNpb25JbmZvCQkJCVtWRVIuN10gKi8KRFdPUkQgCkdldEZpbGVWZXJzaW9uSW5mbzE2KExQQ1NUUiBmaWxlbmFtZSxEV09SRCBoYW5kbGUsRFdPUkQgZGF0YXNpemUsTFBWT0lEIGRhdGEpIHsKCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCJHZXRGaWxlVmVyc2lvbkluZm8xNiglcywlbGQsJWxkLCVwKVxuLT4iLAoJCWZpbGVuYW1lLGhhbmRsZSxkYXRhc2l6ZSxkYXRhCgkpOwoJcmV0dXJuIEdldEZpbGVSZXNvdXJjZSgKCQlmaWxlbmFtZSxWU19GSUxFX0lORk8sVlNfVkVSU0lPTl9JTkZPLGhhbmRsZSxkYXRhc2l6ZSxkYXRhCgkpOwp9CgovKiBHZXRGaWxlVmVyc2lvbkluZm9BCQkJCVtWRVJTSU9OLjBdICovCkRXT1JEIApHZXRGaWxlVmVyc2lvbkluZm8zMkEoTFBDU1RSIGZpbGVuYW1lLERXT1JEIGhhbmRsZSxEV09SRCBkYXRhc2l6ZSxMUFZPSUQgZGF0YSkgewoJcmV0dXJuIEdldEZpbGVWZXJzaW9uSW5mbzE2KGZpbGVuYW1lLGhhbmRsZSxkYXRhc2l6ZSxkYXRhKTsKfQoKLyogR2V0RmlsZVZlcnNpb25JbmZvVwkJCQlbVkVSU0lPTi4zXSAqLwpEV09SRCAKR2V0RmlsZVZlcnNpb25JbmZvMzJXKExQQ1dTVFIgZmlsZW5hbWUsRFdPUkQgaGFuZGxlLERXT1JEIGRhdGFzaXplLExQVk9JRCBkYXRhKXsKCURXT1JECXJldDsKCUxQU1RSCWZuOwoKCWZuCT0gc3RyZHVwVzJBKGZpbGVuYW1lKTsKCXJldAk9IEdldEZpbGVWZXJzaW9uSW5mbzE2KGZuLGhhbmRsZSxkYXRhc2l6ZSxkYXRhKTsKCWZyZWUoZm4pOwoJcmV0dXJuCXJldDsKfQoKLyogVmVyRmluZEZpbGUJCQkJW1ZFUi44XSAqLwpEV09SRApWZXJGaW5kRmlsZTE2KAoJVUlOVDE2IGZsYWdzLExQQ1NUUiBmaWxlbmFtZSxMUENTVFIgd2luZGlyLExQQ1NUUiBhcHBkaXIsCglMUFNUUiBjdXJkaXIsVUlOVDE2ICpjdXJkaXJsZW4sTFBTVFIgZGVzdGRpcixVSU5UMTYgKmRlc3RkaXJsZW4KKSB7CglmcHJpbnRmKHN0ZGVyciwiVmVyRmluZEZpbGUoJXgsJXMsJXMsJXMsJXAsJWQsJXAsJWQpXG4iLAoJCWZsYWdzLGZpbGVuYW1lLHdpbmRpcixhcHBkaXIsY3VyZGlyLCpjdXJkaXJsZW4sZGVzdGRpciwqZGVzdGRpcmxlbgoJKTsKCXN0cmNweShjdXJkaXIsIlo6XFxST09UXFwuV0lORVxcIik7LypGSVhNRSovCgkqY3VyZGlybGVuPXN0cmxlbihjdXJkaXIpOwoJc3RyY3B5KGRlc3RkaXIsIlo6XFxST09UXFwuV0lORVxcIik7LypGSVhNRSovCgkqZGVzdGRpcmxlbj1zdHJsZW4oZGVzdGRpcik7CglyZXR1cm4gMDsKfQoKLyogVmVyRmluZEZpbGVBCQkJCQkJW1ZFUlNJT04uNV0gKi8KRFdPUkQKVmVyRmluZEZpbGUzMkEoCglVSU5UMzIgZmxhZ3MsTFBDU1RSIGZpbGVuYW1lLExQQ1NUUiB3aW5kaXIsTFBDU1RSIGFwcGRpciwKCUxQU1RSIGN1cmRpcixVSU5UMzIgKmN1cmRpcmxlbixMUFNUUiBkZXN0ZGlyLFVJTlQzMiAqZGVzdGRpcmxlbgopIHsKCXJldHVybiBWZXJGaW5kRmlsZTE2KGZsYWdzLGZpbGVuYW1lLHdpbmRpcixhcHBkaXIsY3VyZGlyLGN1cmRpcmxlbixkZXN0ZGlyLGRlc3RkaXJsZW4pOwp9CgovKiBWZXJGaW5kRmlsZVcJCQkJCQlbVkVSU0lPTi42XSAqLwpEV09SRApWZXJGaW5kRmlsZTMyVygKCVVJTlQzMiBmbGFncyxMUENXU1RSIGZpbGVuYW1lLExQQ1dTVFIgd2luZGlyLExQQ1dTVFIgYXBwZGlyLAoJTFBXU1RSIGN1cmRpcixVSU5UMzIgKmN1cmRpcmxlbixMUFdTVFIgZGVzdGRpcixVSU5UMzIgKmRlc3RkaXJsZW4KKSB7CglMUFNUUgl3Zm4sd3dkLHdhZCx3ZGQsd2NkOwoJRFdPUkQJcmV0OwoKCXdmbiA9IHN0cmR1cFcyQShmaWxlbmFtZSk7Cgl3d2QgPSBzdHJkdXBXMkEod2luZGlyKTsKCXdhZCA9IHN0cmR1cFcyQShhcHBkaXIpOwoJd2NkID0gKExQU1RSKW1hbGxvYygqY3VyZGlybGVuKTsKCXdkZCA9IChMUFNUUiltYWxsb2MoKmRlc3RkaXJsZW4pOwoJcmV0PVZlckZpbmRGaWxlMTYoZmxhZ3Msd2ZuLHd3ZCx3YWQsd2NkLGN1cmRpcmxlbix3ZGQsZGVzdGRpcmxlbik7CglTVFJJTkczMl9BbnNpVG9VbmkoY3VyZGlyLHdjZCk7CglTVFJJTkczMl9BbnNpVG9VbmkoZGVzdGRpcix3ZGQpOwoJKmN1cmRpcmxlbgk9IHN0cmxlbih3Y2QpOwoJKmRlc3RkaXJsZW4JPSBzdHJsZW4od2RkKTsKCXJldHVybiByZXQ7Cn0KCi8qIFZlckluc3RhbGxGaWxlCQkJCQlbVkVSLjldICovCkRXT1JEClZlckluc3RhbGxGaWxlMTYoCglVSU5UMTYgZmxhZ3MsTFBDU1RSIHNyY2ZpbGVuYW1lLExQQ1NUUiBkZXN0ZmlsZW5hbWUsTFBDU1RSIHNyY2RpciwKCUxQQ1NUUiBkZXN0ZGlyLExQU1RSIHRtcGZpbGUsVUlOVDE2ICp0bXBmaWxlbGVuCikgewoJZnByaW50ZihzdGRlcnIsIlZlckluc3RhbGxGaWxlKCV4LCVzLCVzLCVzLCVzLCVwLCVkKVxuIiwKCQlmbGFncyxzcmNmaWxlbmFtZSxkZXN0ZmlsZW5hbWUsc3JjZGlyLGRlc3RkaXIsdG1wZmlsZSwqdG1wZmlsZWxlbgoJKTsKCgkvKiBGSVhNRTogSW1wbGVtZW50YXRpb24gc3RpbGwgbWlzc2luZyAuLi4uICovCgoJcmV0dXJuIFZJRl9TUkNPTEQ7Cn0KCi8qIFZlckZpbmRGaWxlQQkJCQkJW1ZFUlNJT04uNV0gKi8KRFdPUkQKVmVySW5zdGFsbEZpbGUzMkEoCglVSU5UMzIgZmxhZ3MsTFBDU1RSIHNyY2ZpbGVuYW1lLExQQ1NUUiBkZXN0ZmlsZW5hbWUsTFBDU1RSIHNyY2RpciwKCUxQQ1NUUiBkZXN0ZGlyLExQU1RSIHRtcGZpbGUsVUlOVDMyICp0bXBmaWxlbGVuCikgewoJcmV0dXJuIFZlckluc3RhbGxGaWxlMTYoZmxhZ3Msc3JjZmlsZW5hbWUsZGVzdGZpbGVuYW1lLHNyY2RpcixkZXN0ZGlyLHRtcGZpbGUsdG1wZmlsZWxlbik7Cn0KCi8qIFZlckZpbmRGaWxlVwkJCQkJW1ZFUlNJT04uNl0gKi8KRFdPUkQKVmVySW5zdGFsbEZpbGUzMlcoCglVSU5UMzIgZmxhZ3MsTFBDV1NUUiBzcmNmaWxlbmFtZSxMUENXU1RSIGRlc3RmaWxlbmFtZSxMUENXU1RSIHNyY2RpciwKCUxQQ1dTVFIgZGVzdGRpcixMUFdTVFIgdG1wZmlsZSxVSU5UMzIgKnRtcGZpbGVsZW4KKSB7CglMUFNUUgl3c3JjZix3c3JjZCx3ZGVzdGYsd2Rlc3RkLHd0bXBmOwoJRFdPUkQJcmV0OwoKCXdzcmNmCT0gc3RyZHVwVzJBKHNyY2ZpbGVuYW1lKTsKCXdzcmNkCT0gc3RyZHVwVzJBKHNyY2Rpcik7Cgl3ZGVzdGYJPSBzdHJkdXBXMkEoZGVzdGZpbGVuYW1lKTsKCXdkZXN0ZAk9IHN0cmR1cFcyQShkZXN0ZGlyKTsKCXd0bXBmCT0gc3RyZHVwVzJBKHRtcGZpbGUpOwoJcmV0PVZlckluc3RhbGxGaWxlMzJBKGZsYWdzLHdzcmNmLHdkZXN0Zix3c3JjZCx3ZGVzdGQsd3RtcGYsdG1wZmlsZWxlbik7CglmcmVlKHdzcmNmKTsKCWZyZWUod3NyY2QpOwoJZnJlZSh3ZGVzdGYpOwoJZnJlZSh3ZGVzdGQpOwoJZnJlZSh3dG1wZik7CglyZXR1cm4gcmV0Owp9CgovKiBGSVhNRTogVGhpcyB0YWJsZSBzaG91bGQsIG9mIGNvdXJzZSwgYmUgbGFuZ3VhZ2UgZGVwZW5kZW5kICovCnN0YXRpYyBjb25zdCBzdHJ1Y3QgbWFwX2lkMnN0ciB7CglVSU5UCWxhbmdpZDsKCWNvbnN0IGNoYXIgKmxhbmduYW1lOwp9IGxhbmd1YWdlc1tdPXsKCXsweDA0MDEsIkFyYWJpc2NoIn0sCgl7MHgwNDAyLCJCdWxnYXJpc2NoIn0sCgl7MHgwNDAzLCJLYXRhbGFuaXNjaCJ9LAoJezB4MDQwNCwiVHJhZGl0aW9uYWxlcyBDaGluZXNpc2NoIn0sCgl7MHgwNDA1LCJUc2NoZWNpc2NoIn0sCgl7MHgwNDA2LCJE5G5pc2NoIn0sCgl7MHgwNDA3LCJEZXV0c2NoIn0sCgl7MHgwNDA4LCJHcmllY2hpc2NoIn0sCgl7MHgwNDA5LCJBbWVyaWthbmlzY2hlcyBFbmdsaXNjaCJ9LAoJezB4MDQwQSwiS2FzdGlsaXNjaGVzIFNwYW5pc2NoIn0sCgl7MHgwNDBCLCJGaW5uaXNjaCJ9LAoJezB4MDQwQywiRnJhbnr2c2lzY2gifSwKCXsweDA0MEQsIkhlYnLkaXNjaCJ9LAoJezB4MDQwRSwiVW5nYXJpc2NoIn0sCgl7MHgwNDBGLCJJc2zkbmRpc2NoIn0sCgl7MHgwNDEwLCJJdGFsaWVuaXNjaCJ9LAoJezB4MDQxMSwiSmFwYW5pc2NoIn0sCgl7MHgwNDEyLCJLb3JlYW5pc2NoIn0sCgl7MHgwNDEzLCJOaWVkZXJs5G5kaXNjaCJ9LAoJezB4MDQxNCwiTm9yd2VnaXNjaC1Cb2ttYWwifSwKCXsweDA0MTUsIlBvbG5pc2NoIn0sCgl7MHgwNDE2LCJCcmFzaWxpYW5pc2NoZXMgUG9ydHVnaWVzaXNjaCJ9LAoJezB4MDQxNywiUuR0b3JvbWFuaXNjaCJ9LAoJezB4MDQxOCwiUnVt5G5pc2NoIn0sCgl7MHgwNDE5LCJSdXNzaXNjaCJ9LAoJezB4MDQxQSwiS3JvYXRvc2VyYmlzY2ggKGxhdGVpbmlzY2gpIn0sCgl7MHgwNDFCLCJTbG93ZW5pc2NoIn0sCgl7MHgwNDFDLCJBbGJhbmlzY2gifSwKCXsweDA0MUQsIlNjaHdlZGlzY2gifSwKCXsweDA0MUUsIlRoYWkifSwKCXsweDA0MUYsIlT8cmtpc2NoIn0sCgl7MHgwNDIwLCJVcmR1In0sCgl7MHgwNDIxLCJCYWhhc2EifSwKCXsweDA4MDQsIlZlcmVpbmZhY2h0ZXMgQ2hpbmVzaXNjaCJ9LAoJezB4MDgwNywiU2Nod2VpemVyZGV1dHNjaCJ9LAoJezB4MDgwOSwiQnJpdGlzY2hlcyBFbmdsaXNjaCJ9LAoJezB4MDgwQSwiTWV4aWthbmlzY2hlcyBTcGFuaXNjaCJ9LAoJezB4MDgwQywiQmVsZ2lzY2hlcyBGcmFuevZzaXNjaCJ9LAoJezB4MDgxMCwiU2Nod2VpemVyaXNjaGVzIEl0YWxpZW5pc2NoIn0sCgl7MHgwODEzLCJCZWxnaXNjaGVzIE5pZWRlcmzkbmRpc2NoIn0sCgl7MHgwODE0LCJOb3Jnd2VnaXNjaC1OeW5vcnNrIn0sCgl7MHgwODE2LCJQb3J0dWdpZXNpc2NoIn0sCgl7MHgwODFBLCJTZXJib2tyYXRpc2NoIChreXJpbGxpc2NoKSJ9LAoJezB4MEMxQywiS2FuYWRpc2NoZXMgRnJhbnr2c2lzY2gifSwKCXsweDEwMEMsIlNjaHdlaXplcmlzY2hlcyBGcmFuevZzaXNjaCJ9LAoJezB4MDAwMCwiVW5iZWthbm50In0sCn07CgovKiBWZXJMYW5ndWFnZU5hbWUJCQkJW1ZFUi4xMF0gKi8KRFdPUkQKVmVyTGFuZ3VhZ2VOYW1lMTYoVUlOVDE2IGxhbmdpZCxMUFNUUiBsYW5nbmFtZSxVSU5UMTYgbGFuZ25hbWVsZW4pIHsKCWludAlpOwoJY2hhcgkqYnVmOwoKCWZwcmludGYoc3RkZXJyLCJWZXJMYW5ndWFnZU5hbWUoJWQsJXAsJWQpXG4iLGxhbmdpZCxsYW5nbmFtZSxsYW5nbmFtZWxlbik7CgkvKiBGaXJzdCwgY2hlY2sgXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldFxjb250cm9sXE5sc1xMb2NhbGVcPGxhbmdpZD4KCSAqIGZyb20gdGhlIHJlZ2lzdHJ5LiAKCSAqLwoJYnVmPShjaGFyKiltYWxsb2Moc3RybGVuKCJcXFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXGNvbnRyb2xcXE5sc1xcTG9jYWxlXFwiKSs5KTsKCXNwcmludGYoYnVmLCJcXFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXGNvbnRyb2xcXE5sc1xcTG9jYWxlXFwlMDh4IixsYW5naWQpOwoJaWYgKEVSUk9SX1NVQ0NFU1M9PVJlZ1F1ZXJ5VmFsdWUxNihIS0VZX0xPQ0FMX01BQ0hJTkUsYnVmLGxhbmduYW1lLChMUERXT1JEKSZsYW5nbmFtZWxlbikpIHsKCQlsYW5nbmFtZVtsYW5nbmFtZWxlbi0xXT0nXDAnOwoJCXJldHVybiBsYW5nbmFtZWxlbjsKCX0KCS8qIGlmIHRoYXQgZmFpbHMsIHVzZSB0aGUgaW50ZXJhbCB0YWJsZSAqLwoJZm9yIChpPTA7bGFuZ3VhZ2VzW2ldLmxhbmdpZCE9MDtpKyspCgkJaWYgKGxhbmdpZD09bGFuZ3VhZ2VzW2ldLmxhbmdpZCkKCQkJYnJlYWs7CglzdHJuY3B5KGxhbmduYW1lLGxhbmd1YWdlc1tpXS5sYW5nbmFtZSxsYW5nbmFtZWxlbik7CglsYW5nbmFtZVtsYW5nbmFtZWxlbi0xXT0nXDAnOwoJcmV0dXJuIHN0cmxlbihsYW5ndWFnZXNbaV0ubGFuZ25hbWUpOwp9CgovKiBWZXJMYW5ndWFnZU5hbWVBCQkJCVtWRVJTSU9OLjldICovCkRXT1JEClZlckxhbmd1YWdlTmFtZTMyQShVSU5UMzIgbGFuZ2lkLExQU1RSIGxhbmduYW1lLFVJTlQzMiBsYW5nbmFtZWxlbikgewoJcmV0dXJuIFZlckxhbmd1YWdlTmFtZTE2KGxhbmdpZCxsYW5nbmFtZSxsYW5nbmFtZWxlbik7Cn0KCi8qIFZlckxhbmd1YWdlTmFtZVcJCQkJW1ZFUlNJT04uMTBdICovCkRXT1JEClZlckxhbmd1YWdlTmFtZTMyVyhVSU5UMzIgbGFuZ2lkLExQV1NUUiBsYW5nbmFtZSxVSU5UMzIgbGFuZ25hbWVsZW4pIHsKCWludAlpOwoJY2hhcgkqYnVmOwoJTFBXU1RSCWtleW5hbWUscmVzdWx0OwoKCS8qIEZpcnN0LCBjaGVjayBcU3lzdGVtXEN1cnJlbnRDb250cm9sU2V0XGNvbnRyb2xcTmxzXExvY2FsZVw8bGFuZ2lkPgoJICogZnJvbSB0aGUgcmVnaXN0cnkuIAoJICovCglidWY9KGNoYXIqKW1hbGxvYyhzdHJsZW4oIlxcU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcY29udHJvbFxcTmxzXFxMb2NhbGVcXCIpKzkpOwoJc3ByaW50ZihidWYsIlxcU3lzdGVtXFxDdXJyZW50Q29udHJvbFNldFxcY29udHJvbFxcTmxzXFxMb2NhbGVcXCUwOHgiLGxhbmdpZCk7CglrZXluYW1lPXN0cmR1cEEyVyhidWYpO2ZyZWUoYnVmKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdRdWVyeVZhbHVlMzJXKEhLRVlfTE9DQUxfTUFDSElORSxrZXluYW1lLGxhbmduYW1lLChMUERXT1JEKSZsYW5nbmFtZWxlbikpIHsKCQlmcmVlKGtleW5hbWUpOwoJCXJldHVybiBsYW5nbmFtZWxlbjsKCX0KCWZyZWUoa2V5bmFtZSk7CgkvKiBpZiB0aGF0IGZhaWxzLCB1c2UgdGhlIGludGVyYWwgdGFibGUgKi8KCWZvciAoaT0wO2xhbmd1YWdlc1tpXS5sYW5naWQhPTA7aSsrKQoJCWlmIChsYW5naWQ9PWxhbmd1YWdlc1tpXS5sYW5naWQpCgkJCWJyZWFrOwoJcmVzdWx0PXN0cmR1cEEyVyhsYW5ndWFnZXNbaV0ubGFuZ25hbWUpOwoJaT1sc3RybGVuMzJXKHJlc3VsdCkqc2l6ZW9mKFdDSEFSKTsKCWlmIChpPmxhbmduYW1lbGVuKQoJCWk9bGFuZ25hbWVsZW47CgltZW1jcHkobGFuZ25hbWUscmVzdWx0LGkpOwoJbGFuZ25hbWVbbGFuZ25hbWVsZW4tMV09J1wwJzsKCWZyZWUocmVzdWx0KTsKCXJldHVybiBzdHJsZW4obGFuZ3VhZ2VzW2ldLmxhbmduYW1lKTsgLyogc2FtZSBhcyBzdHJsZW5XKHJlc3VsdCk7ICovCn0KCi8qIEZJWE1FOiBVTklDT0RFPyAqLwpzdHJ1Y3QgZGIgewoJV09SRAluZXh0b2ZmOwoJV09SRAlkYXRhbGVuOwovKiBpbiBtZW1vcnkgc3RydWN0dXJlLi4uICovCgljaGFyCW5hbWVbMV07IAkvKiBwYWRkZWQgdG8gZHdvcmQgYWxpZ25tZW50ICovCi8qIC4uLi4gCgljaGFyCWRhdGFbZGF0YWxlbl07ICAgICBwYWRkZWQgdG8gZHdvcmQgYWxpZ25lbW50CglCWVRFCXN1YmRpcmRhdGFbXTsgICAgICB1bnRpbCBuZXh0b2ZmCiAqLwp9OwoKc3RhdGljIEJZVEUqCl9maW5kX2RhdGEoQllURSAqYmxvY2ssTFBDU1RSIHN0cikgewoJY2hhcgkqbmV4dHNsYXNoOwoJaW50CXN1YnN0cmxlbjsKCXN0cnVjdAlkYgkqZGI7CgoJd2hpbGUgKCpzdHIgJiYgKnN0cj09J1xcJykKCQlzdHIrKzsKCWlmIChOVUxMIT0obmV4dHNsYXNoPXN0cmNocihzdHIsJ1xcJykpKQoJCXN1YnN0cmxlbj1uZXh0c2xhc2gtc3RyOwoJZWxzZQoJCXN1YnN0cmxlbj1zdHJsZW4oc3RyKTsKCWlmIChuZXh0c2xhc2ghPU5VTEwpIHsKCQl3aGlsZSAoKm5leHRzbGFzaCAmJiAqbmV4dHNsYXNoPT0nXFwnKQoJCQluZXh0c2xhc2grKzsKCQlpZiAoISpuZXh0c2xhc2gpCgkJCW5leHRzbGFzaD1OVUxMOwoJfQoKCgl3aGlsZSAoMSkgewoJCWRiPShzdHJ1Y3QgZGIqKWJsb2NrOwoJCWZwcmludGYoc3RkZXJyLCJkYj0lcCxkYi0+bmV4dG9mZj0lZCxkYi0+ZGF0YWxlbj0lZCxkYi0+bmFtZT0lcyxkYi0+ZGF0YT0lc1xuIiwKCQkJZGIsZGItPm5leHRvZmYsZGItPmRhdGFsZW4sZGItPm5hbWUsKGNoYXIqKSgoY2hhciopZGIrNCsoKHN0cmxlbihkYi0+bmFtZSkrNCkmfjMpKQoJCSk7CgkJaWYgKCFkYi0+bmV4dG9mZikKCQkJcmV0dXJuIE5VTEw7CgoJCWZwcmludGYoc3RkZXJyLCJjb21wYXJpbmcgd2l0aCAlc1xuIixkYi0+bmFtZSk7CgkJaWYgKCFzdHJuY21wKGRiLT5uYW1lLHN0cixzdWJzdHJsZW4pKSB7CgkJCWlmIChuZXh0c2xhc2gpCgkJCQlyZXR1cm4gX2ZpbmRfZGF0YSgKCQkJCQlibG9jays0Kygoc3RybGVuKGRiLT5uYW1lKSs0KSZ+MykrKChkYi0+ZGF0YWxlbiszKSZ+MykKCQkJCQksbmV4dHNsYXNoCgkJCQkpOwoJCQllbHNlCgkJCQlyZXR1cm4gYmxvY2s7CgkJfQoJCWJsb2NrPWJsb2NrKygoZGItPm5leHRvZmYrMykmfjMpOwoJfQp9CgovKiBWZXJRdWVyeVZhbHVlIAkJCVtWRVIuMTFdICovCi8qIHRha2UgY2FyZSwgJ2J1ZmZlcicgaXMgTk9UIGEgU0VHUFRSLCBpdCBqdXN0IHBvaW50cyB0byBvbmUgKi8KRFdPUkQKVmVyUXVlcnlWYWx1ZTE2KFNFR1BUUiBzZWdibG9jayxMUENTVFIgc3ViYmxvY2ssU0VHUFRSICpidWZmZXIsVUlOVDE2ICpidWZsZW4pCnsKCUJZVEUJKmJsb2NrPVBUUl9TRUdfVE9fTElOKHNlZ2Jsb2NrKSwqYjsKCXN0cnVjdAlkYgkqZGI7CgljaGFyCSpzOwoKCWZwcmludGYoc3RkZXJyLCJWZXJRdWVyeVZhbHVlMTYoJXAsJXMsJXAsJWQpXG4iLAoJCWJsb2NrLHN1YmJsb2NrLGJ1ZmZlciwqYnVmbGVuCgkpOwoJcz0oY2hhciopeG1hbGxvYyhzdHJsZW4oIlZTX1ZFUlNJT05fSU5GTyIpK3N0cmxlbihzdWJibG9jaykrMSk7CglzdHJjcHkocywiVlNfVkVSU0lPTl9JTkZPIik7c3RyY2F0KHMsc3ViYmxvY2spOwoJYj1fZmluZF9kYXRhKGJsb2NrLHMpOwoJaWYgKGI9PU5VTEwpIHsKCQkqYnVmbGVuPTA7CgkJcmV0dXJuIDA7Cgl9CglkYj0oc3RydWN0IGRiKiliOwoJKmJ1Zmxlbgk9IGRiLT5kYXRhbGVuOwoJLyogbGV0IGIgcG9pbnQgdG8gZGF0YSBhcmVhICovCgliCT0gYis0Kygoc3RybGVuKGRiLT5uYW1lKSs0KSZ+Myk7CgkvKiBub3cgbG9vayB1cCB3aGF0IHRoZSByZXNwLiBTRUdQVFIgd291bGQgYmUgLi4uICovCgkqYnVmZmVyCT0gKGItYmxvY2spK3NlZ2Jsb2NrOwoJZnByaW50ZihzdGRlcnIsIgktPiAlcz0lc1xuIixzdWJibG9jayxiKTsKCXJldHVybiAxOwp9CgpEV09SRApWZXJRdWVyeVZhbHVlMzJBKExQVk9JRCB2YmxvY2ssTFBDU1RSIHN1YmJsb2NrLExQVk9JRCAqdmJ1ZmZlcixVSU5UMzIgKmJ1ZmxlbikKewoJQllURQkqYiwqYmxvY2s9KExQQllURSl2YmxvY2ssKipidWZmZXI9KExQQllURSopdmJ1ZmZlcjsKCXN0cnVjdAlkYgkqZGI7CgljaGFyCSpzOwoKCWZwcmludGYoc3RkZXJyLCJWZXJRdWVyeVZhbHVlMzJBKCVwLCVzLCVwLCVkKVxuIiwKCQlibG9jayxzdWJibG9jayxidWZmZXIsKmJ1ZmxlbgoJKTsKCXM9KGNoYXIqKXhtYWxsb2Moc3RybGVuKCJWU19WRVJTSU9OX0lORk8iKStzdHJsZW4oc3ViYmxvY2spKzEpOwoJc3RyY3B5KHMsIlZTX1ZFUlNJT05fSU5GTyIpO3N0cmNhdChzLHN1YmJsb2NrKTsKCWI9X2ZpbmRfZGF0YShibG9jayxzKTsKCWlmIChiPT1OVUxMKSB7CgkJKmJ1Zmxlbj0wOwoJCXJldHVybiAwOwoJfQoJZGI9KHN0cnVjdCBkYiopYjsKCSpidWZsZW4JPSBkYi0+ZGF0YWxlbjsKCS8qIGxldCBiIHBvaW50IHRvIGRhdGEgYXJlYSAqLwoJYgk9IGIrNCsoKHN0cmxlbihkYi0+bmFtZSkrNCkmfjMpOwoJKmJ1ZmZlcgk9IGI7CglmcHJpbnRmKHN0ZGVyciwiCS0+ICVzPSVzXG4iLHN1YmJsb2NrLGIpOwoJcmV0dXJuIDE7Cn0KCkRXT1JEClZlclF1ZXJ5VmFsdWUzMlcoTFBWT0lEIHZibG9jayxMUENXU1RSIHN1YmJsb2NrLExQVk9JRCAqdmJ1ZmZlcixVSU5UMzIgKmJ1ZmxlbikKewoJLyogRklYTUU6IGhtbSwgd2Ugbm90IG9ubHkgbmVlZCB0byBjb252ZXJ0IHN1YmJsb2NrLCBidXQgYWxzbyAKCSAqICAgICAgICB0aGUgY29udGVudC4uLm9yPwoJICogQW5kIHdoYXQgYWJvdXQgVU5JQ09ERSB2ZXJzaW9uIGluZm8/CgkgKiBBbmQgdGhlIE5BTUVTIG9mIHRoZSB2YWx1ZXM/CgkgKi8KCUJZVEUJCSpiLCoqYnVmZmVyPShMUEJZVEUqKXZidWZmZXIsKmJsb2NrPShMUEJZVEUpdmJsb2NrOwoJc3RydWN0CWRiCSpkYjsKCWNoYXIJCSpzLCpzYjsKCglzYj1zdHJkdXBXMkEoc3ViYmxvY2spOwoJcz0oY2hhciopeG1hbGxvYyhzdHJsZW4oIlZTX1ZFUlNJT05fSU5GTyIpK3N0cmxlbihzYikrMSk7CglzdHJjcHkocywiVlNfVkVSU0lPTl9JTkZPIik7c3RyY2F0KHMsc2IpOwoJYj1fZmluZF9kYXRhKGJsb2NrLHMpOwoJaWYgKGI9PU5VTEwpIHsKCQkqYnVmbGVuPTA7CgkJZnJlZShzYik7CgkJcmV0dXJuIDA7Cgl9CglkYj0oc3RydWN0IGRiKiliOwoJKmJ1Zmxlbgk9IGRiLT5kYXRhbGVuOwoJLyogbGV0IGIgcG9pbnQgdG8gZGF0YSBhcmVhICovCgliCT0gYis0Kygoc3RybGVuKGRiLT5uYW1lKSs0KSZ+Myk7CgkqYnVmZmVyCT0gYjsKCWZwcmludGYoc3RkZXJyLCIJLT4gJXM9JXNcbiIsc2IsYik7CglmcmVlKHNiKTsKCXJldHVybiAxOwp9Ci8qIDIwIEdFVEZJTEVWRVJTSU9OSU5GT1JBVyAqLwo=