LyogCiAqIEltcGxlbWVudGF0aW9uIG9mIFZFUi5ETEwKICogCiAqIENvcHlyaWdodCAxOTk2IE1hcmN1cyBNZWlzc25lcgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ2ZXIuaCIKI2luY2x1ZGUgImx6ZXhwYW5kLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJzdGFja2ZyYW1lLmgiCS8qIE1BS0VfU0VHUFRSICovCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2RlZmluZSBMWlJFQUQod2hhdCkJaWYgKHNpemVvZigqd2hhdCkhPUxaUmVhZChsemZkLE1BS0VfU0VHUFRSKHdoYXQpLHNpemVvZigqd2hhdCkpKSByZXR1cm4gMDsKCmludApyZWFkX25lX2hlYWRlcihIRklMRSBsemZkLHN0cnVjdCBuZV9oZWFkZXJfcyAqbmVoZCkgewoJc3RydWN0CW16X2hlYWRlcl9zCW16aDsKCglMWlNlZWsobHpmZCwwLFNFRUtfU0VUKTsKCWlmIChzaXplb2YobXpoKSE9TFpSZWFkKGx6ZmQsTUFLRV9TRUdQVFIoJm16aCksc2l6ZW9mKG16aCkpKQoJCXJldHVybiAwOwoJaWYgKG16aC5tel9tYWdpYyE9TVpfU0lHTkFUVVJFKQoJCXJldHVybiAwOwoJTFpTZWVrKGx6ZmQsbXpoLm5lX29mZnNldCxTRUVLX1NFVCk7CglMWlJFQUQobmVoZCk7CglpZiAobmVoZC0+bmVfbWFnaWMgPT0gTkVfU0lHTkFUVVJFKSB7CgkJTFpTZWVrKGx6ZmQsbXpoLm5lX29mZnNldCxTRUVLX1NFVCk7CgkJcmV0dXJuIDE7Cgl9CgkvKiBtdXN0IGhhbmRsZSBQRSBmaWxlcyB0b28uIExhdGVyLiAqLwoJcmV0dXJuIDA7Cn0KCgppbnQKZmluZF9uZV9yZXNvdXJjZSgKCUhGSUxFIGx6ZmQsc3RydWN0IG5lX2hlYWRlcl9zICpuZWhkLFNFR1BUUiB0eXBlaWQsU0VHUFRSIHJlc2lkLAoJQllURSAqKnJlc2RhdGEsaW50ICpyZXNsZW4sRFdPUkQgKm9mZgopIHsKCU5FX1RZUEVJTkZPCXRpOwoJTkVfTkFNRUlORk8Jbmk7CglpbnQJCWk7CglXT1JECQlzaGlmdGNvdW50OwoJRFdPUkQJCW5laGRvZmZzZXQ7CgoJbmVoZG9mZnNldD1MWlNlZWsobHpmZCxuZWhkLT5yZXNvdXJjZV90YWJfb2Zmc2V0LFNFRUtfQ1VSKTsKCUxaUkVBRCgmc2hpZnRjb3VudCk7CglkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwic2hpZnRjb3VudCBpcyAlZFxuIixzaGlmdGNvdW50KTsKCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCJyZWFkaW5nIHJlc291cmNlIHR5cGVpbmZvIGRpci5cbiIpOwoKCWlmICghSElXT1JEKHR5cGVpZCkpIHR5cGVpZCA9IChTRUdQVFIpKChXT1JEKXR5cGVpZCB8IDB4ODAwMCk7CglpZiAoIUhJV09SRChyZXNpZCkpICByZXNpZCAgPSAoU0VHUFRSKSgoV09SRClyZXNpZCB8IDB4ODAwMCk7Cgl3aGlsZSAoMSkgewoJCWludAlza2lwZmxhZzsKCgkJTFpSRUFEKCZ0aSk7CgkJaWYgKCF0aS50eXBlX2lkKQoJCQlyZXR1cm4gMDsKCQlkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwiICAgIHRpLnR5cGVpZCA9JTA0eCxjb3VudD0lZFxuIix0aS50eXBlX2lkLHRpLmNvdW50KTsKCQlza2lwZmxhZz0wOwoJCWlmICghSElXT1JEKHR5cGVpZCkpIHsKCQkJaWYgKCh0aS50eXBlX2lkJjB4ODAwMCkmJih0eXBlaWQhPXRpLnR5cGVfaWQpKQoJCQkJc2tpcGZsYWc9MTsKCQl9IGVsc2UgewoJCQlpZiAodGkudHlwZV9pZCAmIDB4ODAwMCkgewoJCQkJc2tpcGZsYWc9MTsgCgkJCX0gZWxzZSB7CgkJCQlCWVRFCWxlbjsKCQkJCWNoYXIJKnN0cjsKCQkJCURXT1JECXdoZXJlbGVmdDsKCgkJCQl3aGVyZWxlZnQ9TFpTZWVrKAoJCQkJCWx6ZmQsCgkJCQkJbmVoZG9mZnNldCtuZWhkLT5yZXNvdXJjZV90YWJfb2Zmc2V0K3RpLnR5cGVfaWQsCgkJCQkJU0VFS19TRVQKCQkJCSk7CgkJCQlMWlJFQUQoJmxlbik7CgkJCQlzdHI9eG1hbGxvYyhsZW4pOwoJCQkJaWYgKGxlbiE9TFpSZWFkKGx6ZmQsTUFLRV9TRUdQVFIoc3RyKSxsZW4pKQoJCQkJCXJldHVybiAwOwoJCQkJZHByaW50Zl9yZXNvdXJjZShzdGRlcnIsInJlYWQgJXMgdG8gY29tcGFyZSBpdCB3aXRoICVzXG4iLAoJCQkJCXN0ciwoY2hhciopUFRSX1NFR19UT19MSU4odHlwZWlkKQoJCQkJKTsKCQkJCWlmIChsc3RyY21waShzdHIsKGNoYXIqKVBUUl9TRUdfVE9fTElOKHR5cGVpZCkpKQoJCQkJCXNraXBmbGFnPTE7CgkJCQlmcmVlKHN0cik7CgkJCQlMWlNlZWsobHpmZCx3aGVyZWxlZnQsU0VFS19TRVQpOwoJCQl9CgkJfQoJCWlmIChza2lwZmxhZykgewoJCQlMWlNlZWsobHpmZCx0aS5jb3VudCpzaXplb2YobmkpLFNFRUtfQ1VSKTsKCQkJY29udGludWU7CgkJfQoJCWZvciAoaT0wO2k8dGkuY291bnQ7aSsrKSB7CgkJCVdPUkQJKnJkYXRhOwoJCQlpbnQJbGVuOwoKCQkJTFpSRUFEKCZuaSk7CgkJCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCIJbmkuaWQ9JTR4LG9mZnNldD0lZCxsZW5ndGg9JWRcbiIsCgkJCQluaS5pZCxuaS5vZmZzZXQsbmkubGVuZ3RoCgkJCSk7CgkJCXNraXBmbGFnPTE7CgkJCWlmICghSElXT1JEKHJlc2lkKSkgewoJCQkJaWYgKG5pLmlkID09IHJlc2lkKQoJCQkJCXNraXBmbGFnPTA7CgkJCX0gZWxzZSB7CgkJCQlpZiAoIShuaS5pZCAmIDB4ODAwMCkpIHsKCQkJCQlCWVRFCWxlbjsKCQkJCQljaGFyCSpzdHI7CgkJCQkJRFdPUkQJd2hlcmVsZWZ0OwoKCQkJCQl3aGVyZWxlZnQ9TFpTZWVrKAoJCQkJCQlsemZkLAoJCQkJCQluZWhkb2Zmc2V0K25laGQtPnJlc291cmNlX3RhYl9vZmZzZXQrbmkuaWQsCgkJCQkJCVNFRUtfU0VUCgkJCQkJKTsKCQkJCQlMWlJFQUQoJmxlbik7CgkJCQkJc3RyPXhtYWxsb2MobGVuKTsKCQkJCQlpZiAobGVuIT1MWlJlYWQobHpmZCxNQUtFX1NFR1BUUihzdHIpLGxlbikpCgkJCQkJCXJldHVybiAwOwoJCQkJCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCJyZWFkICVzIHRvIGNvbXBhcmUgaXQgd2l0aCAlc1xuIiwKCQkJCQkJc3RyLChjaGFyKilQVFJfU0VHX1RPX0xJTih0eXBlaWQpCgkJCQkJKTsKCQkJCQlpZiAoIWxzdHJjbXBpKHN0ciwoY2hhciopUFRSX1NFR19UT19MSU4odHlwZWlkKSkpCgkJCQkJCXNraXBmbGFnPTA7CgkJCQkJZnJlZShzdHIpOwoJCQkJCUxaU2VlayhsemZkLHdoZXJlbGVmdCxTRUVLX1NFVCk7CgkJCQl9CgkJCX0KCQkJaWYgKHNraXBmbGFnKQoJCQkJY29udGludWU7CgkJCUxaU2VlayhsemZkLCgoaW50KW5pLm9mZnNldDw8c2hpZnRjb3VudCksU0VFS19TRVQpOwoJCQkqb2ZmCT0gKGludCluaS5vZmZzZXQ8PHNoaWZ0Y291bnQ7CgkJCWxlbgk9IG5pLmxlbmd0aDw8c2hpZnRjb3VudDsKCQkJcmRhdGE9KFdPUkQqKXhtYWxsb2MobGVuKTsKCQkJaWYgKGxlbiE9TFpSZWFkKGx6ZmQsTUFLRV9TRUdQVFIocmRhdGEpLGxlbikpIHsKCQkJCWZyZWUocmRhdGEpOwoJCQkJcmV0dXJuIDA7CgkJCX0KCQkJZHByaW50Zl9yZXNvdXJjZShzdGRlcnIsInJlc291cmNlIGZvdW5kLlxuIik7CgkJCSpyZXNkYXRhPSAoQllURSopcmRhdGE7CgkJCSpyZXNsZW4JPSBsZW47CgkJCXJldHVybiAxOwoJCX0KCX0KfQoKRFdPUkQKR2V0RmlsZVJlc291cmNlU2l6ZShMUENTVFIgZmlsZW5hbWUsU0VHUFRSIHJlc3R5cGUsU0VHUFRSIHJlc2lkLExQRFdPUkQgb2ZmKSB7CglIRklMRQlsemZkOwoJT0ZTVFJVQ1QJb2ZzOwoJQllURQkqcmVzZGF0YTsKCWludAlyZXNsZW47CglzdHJ1Y3QJbmVfaGVhZGVyX3MJbmVoZDsKCglmcHJpbnRmKHN0ZGVyciwiR2V0RmlsZVJlc291cmNlU2l6ZSglcywlbHgsJWx4LCVwKVxuIiwKCQlmaWxlbmFtZSwoTE9ORylyZXN0eXBlLChMT05HKXJlc2lkLG9mZgoJKTsKCWx6ZmQ9TFpPcGVuRmlsZShmaWxlbmFtZSwmb2ZzLE9GX1JFQUQpOwoJaWYgKGx6ZmQ9PTApCgkJcmV0dXJuIDA7CglpZiAoIXJlYWRfbmVfaGVhZGVyKGx6ZmQsJm5laGQpKSB7CgkJTFpDbG9zZShsemZkKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghZmluZF9uZV9yZXNvdXJjZShsemZkLCZuZWhkLHJlc3R5cGUscmVzaWQsJnJlc2RhdGEsJnJlc2xlbixvZmYpKSB7CgkJTFpDbG9zZShsemZkKTsKCQlyZXR1cm4gMDsKCX0KCWZyZWUocmVzZGF0YSk7CglMWkNsb3NlKGx6ZmQpOwoJcmV0dXJuIHJlc2xlbjsKfQoKRFdPUkQKR2V0RmlsZVJlc291cmNlKExQQ1NUUiBmaWxlbmFtZSxTRUdQVFIgcmVzdHlwZSxTRUdQVFIgcmVzaWQsCgkJRFdPUkQgb2ZmLERXT1JEIGRhdGFsZW4sTFBWT0lEIGRhdGEKKSB7CglIRklMRQlsemZkOwoJT0ZTVFJVQ1QJb2ZzOwoJQllURQkqcmVzZGF0YTsKCWludAlyZXNsZW47CglzdHJ1Y3QJbmVfaGVhZGVyX3MJbmVoZDsKCWZwcmludGYoc3RkZXJyLCJHZXRGaWxlUmVzb3VyY2UoJXMsJWx4LCVseCwlbGQsJWxkLCVwKVxuIiwKCQlmaWxlbmFtZSwoTE9ORylyZXN0eXBlLChMT05HKXJlc2lkLG9mZixkYXRhbGVuLGRhdGEKCSk7CgoJbHpmZD1MWk9wZW5GaWxlKGZpbGVuYW1lLCZvZnMsT0ZfUkVBRCk7CglpZiAobHpmZD09MCkKCQlyZXR1cm4gMDsKCWlmICghb2ZmKSB7CgkJaWYgKCFyZWFkX25lX2hlYWRlcihsemZkLCZuZWhkKSkgewoJCQlMWkNsb3NlKGx6ZmQpOwoJCQlyZXR1cm4gMDsKCQl9CgkJaWYgKCFmaW5kX25lX3Jlc291cmNlKGx6ZmQsJm5laGQscmVzdHlwZSxyZXNpZCwmcmVzZGF0YSwmcmVzbGVuLCZvZmYpKSB7CgkJCUxaQ2xvc2UobHpmZCk7CgkJCXJldHVybiAwOwoJCX0KCQlmcmVlKHJlc2RhdGEpOwoJfQoJTFpTZWVrKGx6ZmQsb2ZmLFNFRUtfU0VUKTsKCWlmIChyZXNsZW4+ZGF0YWxlbikKCQlyZXNsZW49ZGF0YWxlbjsKCUxaUmVhZChsemZkLE1BS0VfU0VHUFRSKGRhdGEpLHJlc2xlbik7CglMWkNsb3NlKGx6ZmQpOwoJcmV0dXJuIHJlc2xlbjsKfQoKRFdPUkQKR2V0RmlsZVZlcnNpb25JbmZvU2l6ZShMUENTVFIgZmlsZW5hbWUsTFBEV09SRCBoYW5kbGUpIHsKCURXT1JECWxlbixyZXQ7CglCWVRFCWJ1Zls3Ml07CglWU19GSVhFREZJTEVJTkZPICp2ZmZpOwoKCWZwcmludGYoc3RkZXJyLCJHZXRGaWxlVmVyc2lvbkluZm9TaXplKCVzLCVwKVxuIixmaWxlbmFtZSxoYW5kbGUpOwoKCWxlbj1HZXRGaWxlUmVzb3VyY2VTaXplKGZpbGVuYW1lLFZTX0ZJTEVfSU5GTyxWU19WRVJTSU9OX0lORk8saGFuZGxlKTsKCWlmICghbGVuKQoJCXJldHVybiAwOwoJcmV0PUdldEZpbGVSZXNvdXJjZSgKCQlmaWxlbmFtZSxWU19GSUxFX0lORk8sVlNfVkVSU0lPTl9JTkZPLCpoYW5kbGUsc2l6ZW9mKGJ1ZiksYnVmCgkpOwoJaWYgKCFyZXQpCgkJcmV0dXJuIDA7CgoJdmZmaT0oVlNfRklYRURGSUxFSU5GTyopKGJ1ZisweDE0KTsKCWlmICh2ZmZpLT5kd1NpZ25hdHVyZSAhPSBWU19GRklfU0lHTkFUVVJFKQoJCXJldHVybiAwOwoJaWYgKCooV09SRCopYnVmIDwgbGVuKQoJCWxlbiA9ICooV09SRCopYnVmOwoJZnByaW50ZihzdGRlcnIsIi0+c3RydWN2ZXI9JWxkLiVsZCxmaWxldmVyPSVsZC4lbGQscHJvZHVjdHZlcj0lbGQuJWxkLGZsYWdtYXNrPSVseCxmbGFncz0lbHgsT1M9IiwKCQkodmZmaS0+ZHdTdHJ1Y1ZlcnNpb24+PjE2KSx2ZmZpLT5kd1N0cnVjVmVyc2lvbiYweEZGRkYsCgkJdmZmaS0+ZHdGaWxlVmVyc2lvbk1TLHZmZmktPmR3RmlsZVZlcnNpb25MUywKCQl2ZmZpLT5kd1Byb2R1Y3RWZXJzaW9uTVMsdmZmaS0+ZHdQcm9kdWN0VmVyc2lvbkxTLAoJCXZmZmktPmR3RmlsZUZsYWdzTWFzayx2ZmZpLT5kd0ZpbGVGbGFncwoJKTsKCXN3aXRjaCAodmZmaS0+ZHdGaWxlT1MmMHhGRkZGMDAwMCkgewoJY2FzZSBWT1NfRE9TOmZwcmludGYoc3RkZXJyLCJET1MsIik7YnJlYWs7CgljYXNlIFZPU19PUzIxNjpmcHJpbnRmKHN0ZGVyciwiT1MvMi0xNiwiKTticmVhazsKCWNhc2UgVk9TX09TMjMyOmZwcmludGYoc3RkZXJyLCJPUy8yLTMyLCIpO2JyZWFrOwoJY2FzZSBWT1NfTlQ6ZnByaW50ZihzdGRlcnIsIk5ULCIpO2JyZWFrOwoJY2FzZSBWT1NfVU5LTk9XTjoKCWRlZmF1bHQ6CgkJZnByaW50ZihzdGRlcnIsIlVOS05PV04oJWxkKSwiLHZmZmktPmR3RmlsZU9TJjB4RkZGRjAwMDApO2JyZWFrOwoJfQoJc3dpdGNoICh2ZmZpLT5kd0ZpbGVPUyAmIDB4RkZGRikgewoJY2FzZSBWT1NfX0JBU0U6ZnByaW50ZihzdGRlcnIsIkJBU0UiKTticmVhazsKCWNhc2UgVk9TX19XSU5ET1dTMTY6ZnByaW50ZihzdGRlcnIsIldJTjE2Iik7YnJlYWs7CgljYXNlIFZPU19fV0lORE9XUzMyOmZwcmludGYoc3RkZXJyLCJXSU4zMiIpO2JyZWFrOwoJY2FzZSBWT1NfX1BNMTY6ZnByaW50ZihzdGRlcnIsIlBNMTYiKTticmVhazsKCWNhc2UgVk9TX19QTTMyOmZwcmludGYoc3RkZXJyLCJQTTMyIik7YnJlYWs7CglkZWZhdWx0OmZwcmludGYoc3RkZXJyLCJVTktOT1dOKCVsZCkiLHZmZmktPmR3RmlsZU9TJjB4RkZGRik7YnJlYWs7Cgl9Cglzd2l0Y2ggKHZmZmktPmR3RmlsZVR5cGUpIHsKCWRlZmF1bHQ6CgljYXNlIFZGVF9VTktOT1dOOgoJCWZwcmludGYoc3RkZXJyLCJmaWxldHlwZT1Vbmtub3duKCVsZCkiLHZmZmktPmR3RmlsZVR5cGUpOwoJCWJyZWFrOwoJY2FzZSBWRlRfQVBQOmZwcmludGYoc3RkZXJyLCJmaWxldHlwZT1BUFAiKTticmVhazsKCWNhc2UgVkZUX0RMTDpmcHJpbnRmKHN0ZGVyciwiZmlsZXR5cGU9RExMIik7YnJlYWs7CgljYXNlIFZGVF9EUlY6CgkJZnByaW50ZihzdGRlcnIsImZpbGV0eXBlPURSViwiKTsKCQlzd2l0Y2godmZmaS0+ZHdGaWxlU3VidHlwZSkgewoJCWRlZmF1bHQ6CgkJY2FzZSBWRlQyX1VOS05PV046CgkJCWZwcmludGYoc3RkZXJyLCJVTktOT1dOKCVsZCkiLHZmZmktPmR3RmlsZVN1YnR5cGUpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX1BSSU5URVI6CgkJCWZwcmludGYoc3RkZXJyLCJQUklOVEVSIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfS0VZQk9BUkQ6CgkJCWZwcmludGYoc3RkZXJyLCJLRVlCT0FSRCIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0xBTkdVQUdFOgoJCQlmcHJpbnRmKHN0ZGVyciwiTEFOR1VBR0UiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9ESVNQTEFZOgoJCQlmcHJpbnRmKHN0ZGVyciwiRElTUExBWSIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX01PVVNFOgoJCQlmcHJpbnRmKHN0ZGVyciwiTU9VU0UiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9ORVRXT1JLOgoJCQlmcHJpbnRmKHN0ZGVyciwiTkVUV09SSyIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX1NZU1RFTToKCQkJZnByaW50ZihzdGRlcnIsIlNZU1RFTSIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0lOU1RBTExBQkxFOgoJCQlmcHJpbnRmKHN0ZGVyciwiSU5TVEFMTEFCTEUiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9TT1VORDoKCQkJZnByaW50ZihzdGRlcnIsIlNPVU5EIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfQ09NTToKCQkJZnByaW50ZihzdGRlcnIsIkNPTU0iKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9JTlBVVE1FVEhPRDoKCQkJZnByaW50ZihzdGRlcnIsIklOUFVUTUVUSE9EIik7CgkJCWJyZWFrOwoJCX0KCQlicmVhazsKCWNhc2UgVkZUX0ZPTlQ6CgkJZnByaW50ZihzdGRlcnIsImZpbGV0eXBlPUZPTlQuIik7CgkJc3dpdGNoICh2ZmZpLT5kd0ZpbGVTdWJ0eXBlKSB7CgkJZGVmYXVsdDoKCQkJZnByaW50ZihzdGRlcnIsIlVOS05PV04oJWxkKSIsdmZmaS0+ZHdGaWxlU3VidHlwZSk7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9GT05UX1JBU1RFUjpmcHJpbnRmKHN0ZGVyciwiUkFTVEVSIik7YnJlYWs7CgkJY2FzZSBWRlQyX0ZPTlRfVkVDVE9SOmZwcmludGYoc3RkZXJyLCJWRUNUT1IiKTticmVhazsKCQljYXNlIFZGVDJfRk9OVF9UUlVFVFlQRTpmcHJpbnRmKHN0ZGVyciwiVFJVRVRZUEUiKTticmVhazsKCQl9CgkJYnJlYWs7CgljYXNlIFZGVF9WWEQ6ZnByaW50ZihzdGRlcnIsImZpbGV0eXBlPVZYRCIpO2JyZWFrOwoJY2FzZSBWRlRfU1RBVElDX0xJQjpmcHJpbnRmKHN0ZGVyciwiZmlsZXR5cGU9U1RBVElDX0xJQiIpO2JyZWFrOwoJfQoJZnByaW50ZihzdGRlcnIsImZpbGVkYXRhPSVseC4lbHhcbiIsdmZmaS0+ZHdGaWxlRGF0ZU1TLHZmZmktPmR3RmlsZURhdGVMUyk7CglyZXR1cm4gbGVuOwp9CgpEV09SRCAKR2V0RmlsZVZlcnNpb25JbmZvKExQQ1NUUiBmaWxlbmFtZSxEV09SRCBoYW5kbGUsRFdPUkQgZGF0YXNpemUsTFBWT0lEIGRhdGEpIHsKCWZwcmludGYoc3RkZXJyLCJHZXRGaWxlVmVyc2lvbkluZm8oJXMsJWxkLCVsZCwlcClcbi0+IiwKCQlmaWxlbmFtZSxoYW5kbGUsZGF0YXNpemUsZGF0YQoJKTsKCXJldHVybiBHZXRGaWxlUmVzb3VyY2UoCgkJZmlsZW5hbWUsVlNfRklMRV9JTkZPLFZTX1ZFUlNJT05fSU5GTyxoYW5kbGUsZGF0YXNpemUsZGF0YQoJKTsKfQoKRFdPUkQgClZlckZpbmRGaWxlKAoJVUlOVCBmbGFncyxMUENTVFIgZmlsZW5hbWUsTFBDU1RSIHdpbmRpcixMUENTVFIgYXBwZGlyLAoJTFBTVFIgY3VyZGlyLFVJTlQgKmN1cmRpcmxlbixMUFNUUiBkZXN0ZGlyLFVJTlQqZGVzdGRpcmxlbgopIHsKCWZwcmludGYoc3RkZXJyLCJWZXJGaW5kRmlsZSgleCwlcywlcywlcywlcCwlZCwlcCwlZClcbiIsCgkJZmxhZ3MsZmlsZW5hbWUsd2luZGlyLGFwcGRpcixjdXJkaXIsKmN1cmRpcmxlbixkZXN0ZGlyLCpkZXN0ZGlybGVuCgkpOwoJc3RyY3B5KGN1cmRpciwiWjpcXFJPT1RcXC5XSU5FXFwiKTsvKkZJWE1FKi8KCSpjdXJkaXJsZW49c3RybGVuKGN1cmRpcik7CglzdHJjcHkoZGVzdGRpciwiWjpcXFJPT1RcXC5XSU5FXFwiKTsvKkZJWE1FKi8KCSpkZXN0ZGlybGVuPXN0cmxlbihkZXN0ZGlyKTsKCXJldHVybiAwOwp9CgpEV09SRApWZXJJbnN0YWxsRmlsZSgKCVVJTlQgZmxhZ3MsTFBDU1RSIHNyY2ZpbGVuYW1lLExQQ1NUUiBkZXN0ZmlsZW5hbWUsTFBDU1RSIHNyY2RpciwKCUxQQ1NUUiBkZXN0ZGlyLExQU1RSIHRtcGZpbGUsVUlOVCp0bXBmaWxlbGVuCikgewoJZnByaW50ZihzdGRlcnIsIlZlckluc3RhbGxGaWxlKCV4LCVzLCVzLCVzLCVzLCVwLCVkKVxuIiwKCQlmbGFncyxzcmNmaWxlbmFtZSxkZXN0ZmlsZW5hbWUsc3JjZGlyLGRlc3RkaXIsdG1wZmlsZSwqdG1wZmlsZWxlbgoJKTsKCXJldHVybiBWSUZfU1JDT0xEOwp9CgovKiBGSVhNRTogVGhpcyB0YWJsZSBzaG91bGQsIG9mIGNvdXJzZSwgYmUgbGFuZ3VhZ2UgZGVwZW5kZW5kICovCnN0YXRpYyBzdHJ1Y3QgbWFwX2lkMnN0ciB7CglVSU5UCWxhbmdpZDsKCWNoYXIJKmxhbmduYW1lOwp9IGxhbmd1YWdlc1tdPXsKCXsweDA0MDEsIkFyYWJpc2NoIn0sCgl7MHgwNDAyLCJCdWxnYXJpc2NoIn0sCgl7MHgwNDAzLCJLYXRhbGFuaXNjaCJ9LAoJezB4MDQwNCwiVHJhZGl0aW9uYWxlcyBDaGluZXNpc2NoIn0sCgl7MHgwNDA1LCJUc2NoZWNpc2NoIn0sCgl7MHgwNDA2LCJE5G5pc2NoIn0sCgl7MHgwNDA3LCJEZXV0c2NoIn0sCgl7MHgwNDA4LCJHcmllY2hpc2NoIn0sCgl7MHgwNDA5LCJBbWVyaWthbmlzY2hlcyBFbmdsaXNjaCJ9LAoJezB4MDQwQSwiS2FzdGlsaXNjaGVzIFNwYW5pc2NoIn0sCgl7MHgwNDBCLCJGaW5uaXNjaCJ9LAoJezB4MDQwQywiRnJhbnr2c2lzY2gifSwKCXsweDA0MEQsIkhlYnLkaXNjaCJ9LAoJezB4MDQwRSwiVW5nYXJpc2NoIn0sCgl7MHgwNDBGLCJJc2zkbmRpc2NoIn0sCgl7MHgwNDEwLCJJdGFsaWVuaXNjaCJ9LAoJezB4MDQxMSwiSmFwYW5pc2NoIn0sCgl7MHgwNDEyLCJLb3JlYW5pc2NoIn0sCgl7MHgwNDEzLCJOaWVkZXJs5G5kaXNjaCJ9LAoJezB4MDQxNCwiTm9yd2VnaXNjaC1Cb2ttYWwifSwKCXsweDA0MTUsIlBvbG5pc2NoIn0sCgl7MHgwNDE2LCJCcmFzaWxpYW5pc2NoZXMgUG9ydHVnaWVzaXNjaCJ9LAoJezB4MDQxNywiUuR0b3JvbWFuaXNjaCJ9LAoJezB4MDQxOCwiUnVt5G5pc2NoIn0sCgl7MHgwNDE5LCJSdXNzaXNjaCJ9LAoJezB4MDQxQSwiS3JvYXRvc2VyYmlzY2ggKGxhdGVpbmlzY2gpIn0sCgl7MHgwNDFCLCJTbG93ZW5pc2NoIn0sCgl7MHgwNDFDLCJBbGJhbmlzY2gifSwKCXsweDA0MUQsIlNjaHdlZGlzY2gifSwKCXsweDA0MUUsIlRoYWkifSwKCXsweDA0MUYsIlT8cmtpc2NoIn0sCgl7MHgwNDIwLCJVcmR1In0sCgl7MHgwNDIxLCJCYWhhc2EifSwKCXsweDA4MDQsIlZlcmVpbmZhY2h0ZXMgQ2hpbmVzaXNjaCJ9LAoJezB4MDgwNywiU2Nod2VpemVyZGV1dHNjaCJ9LAoJezB4MDgwOSwiQnJpdGlzY2hlcyBFbmdsaXNjaCJ9LAoJezB4MDgwQSwiTWV4aWthbmlzY2hlcyBTcGFuaXNjaCJ9LAoJezB4MDgwQywiQmVsZ2lzY2hlcyBGcmFuevZzaXNjaCJ9LAoJezB4MDgxMCwiU2Nod2VpemVyaXNjaGVzIEl0YWxpZW5pc2NoIn0sCgl7MHgwODEzLCJCZWxnaXNjaGVzIE5pZWRlcmzkbmRpc2NoIn0sCgl7MHgwODE0LCJOb3Jnd2VnaXNjaC1OeW5vcnNrIn0sCgl7MHgwODE2LCJQb3J0dWdpZXNpc2NoIn0sCgl7MHgwODFBLCJTZXJib2tyYXRpc2NoIChreXJpbGxpc2NoKSJ9LAoJezB4MEMxQywiS2FuYWRpc2NoZXMgRnJhbnr2c2lzY2gifSwKCXsweDEwMEMsIlNjaHdlaXplcmlzY2hlcyBGcmFuevZzaXNjaCJ9LAoJezB4MDAwMCwiVW5iZWthbm50In0sCn07CgoKRFdPUkQKVmVyTGFuZ3VhZ2VOYW1lKFVJTlQgbGFuZ2lkLExQU1RSIGxhbmduYW1lLFVJTlQgbGFuZ25hbWVsZW4pIHsKCWludAlpOwoKCWZwcmludGYoc3RkZXJyLCJWZXJMYW5ndWFnZU5hbWUoJWQsJXAsJWQpXG4iLGxhbmdpZCxsYW5nbmFtZSxsYW5nbmFtZWxlbik7Cglmb3IgKGk9MDtsYW5ndWFnZXNbaV0ubGFuZ2lkIT0wO2krKykKCQlpZiAobGFuZ2lkPT1sYW5ndWFnZXNbaV0ubGFuZ2lkKQoJCQlicmVhazsKCXN0cm5jcHkobGFuZ25hbWUsbGFuZ3VhZ2VzW2ldLmxhbmduYW1lLGxhbmduYW1lbGVuKTsKCWxhbmduYW1lW2xhbmduYW1lbGVuLTFdPSdcMCc7CglyZXR1cm4gc3RybGVuKGxhbmd1YWdlc1tpXS5sYW5nbmFtZSk7Cn0KCnN0cnVjdCBkYiB7CglXT1JECW5leHRvZmY7CglXT1JECWRhdGFsZW47Ci8qIGluIG1lbW9yeSBzdHJ1Y3R1cmUuLi4gKi8KCWNoYXIJbmFtZVsxXTsgCS8qIHBhZGRlZCB0byBkd29yZCBhbGlnbm1lbnQgKi8KLyogLi4uLiAKCWNoYXIJZGF0YVtkYXRhbGVuXTsgICAgIHBhZGRlZCB0byBkd29yZCBhbGlnbmVtbnQKCUJZVEUJc3ViZGlyZGF0YVtdOyAgICAgIHVudGlsIG5leHRvZmYKICovCn07CgpzdGF0aWMgQllURSoKX2ZpbmRfZGF0YShCWVRFICpibG9jayxMUENTVFIgc3RyKSB7CgljaGFyCSpuZXh0c2xhc2g7CglpbnQJc3Vic3RybGVuOwoJc3RydWN0CWRiCSpkYjsKCgl3aGlsZSAoKnN0ciAmJiAqc3RyPT0nXFwnKQoJCXN0cisrOwoJaWYgKE5VTEwhPShuZXh0c2xhc2g9c3RyY2hyKHN0ciwnXFwnKSkpCgkJc3Vic3RybGVuPW5leHRzbGFzaC1zdHI7CgllbHNlCgkJc3Vic3RybGVuPXN0cmxlbihzdHIpOwoJaWYgKG5leHRzbGFzaCE9TlVMTCkgewoJCXdoaWxlICgqbmV4dHNsYXNoICYmICpuZXh0c2xhc2g9PSdcXCcpCgkJCW5leHRzbGFzaCsrOwoJCWlmICghKm5leHRzbGFzaCkKCQkJbmV4dHNsYXNoPU5VTEw7Cgl9CgoKCXdoaWxlICgxKSB7CgkJZGI9KHN0cnVjdCBkYiopYmxvY2s7CgkJZnByaW50ZihzdGRlcnIsImRiPSVwLGRiLT5uZXh0b2ZmPSVkLGRiLT5kYXRhbGVuPSVkLGRiLT5uYW1lPSVzLGRiLT5kYXRhPSVzXG4iLAoJCQlkYixkYi0+bmV4dG9mZixkYi0+ZGF0YWxlbixkYi0+bmFtZSwoY2hhciopKChjaGFyKilkYis0Kygoc3RybGVuKGRiLT5uYW1lKSs0KSZ+MykpCgkJKTsKCQlpZiAoIWRiLT5uZXh0b2ZmKQoJCQlyZXR1cm4gTlVMTDsKCgkJZnByaW50ZihzdGRlcnIsImNvbXBhcmluZyB3aXRoICVzXG4iLGRiLT5uYW1lKTsKCQlpZiAoIXN0cm5jbXAoZGItPm5hbWUsc3RyLHN1YnN0cmxlbikpIHsKCQkJaWYgKG5leHRzbGFzaCkKCQkJCXJldHVybiBfZmluZF9kYXRhKAoJCQkJCWJsb2NrKzQrKChzdHJsZW4oZGItPm5hbWUpKzQpJn4zKSsoKGRiLT5kYXRhbGVuKzMpJn4zKQoJCQkJCSxuZXh0c2xhc2gKCQkJCSk7CgkJCWVsc2UKCQkJCXJldHVybiBibG9jazsKCQl9CgkJYmxvY2s9YmxvY2srKChkYi0+bmV4dG9mZiszKSZ+Myk7Cgl9Cgp9CgovKiB0YWtlIGNhcmUsICdidWZmZXInIGlzIE5PVCBhIFNFR1BUUiwgaXQganVzdCBwb2ludHMgdG8gb25lICovCkRXT1JEClZlclF1ZXJ5VmFsdWUoU0VHUFRSIHNlZ2Jsb2NrLExQQ1NUUiBzdWJibG9jayxTRUdQVFIgKmJ1ZmZlcixVSU5UICpidWZsZW4pIHsKCUJZVEUJKmJsb2NrPVBUUl9TRUdfVE9fTElOKHNlZ2Jsb2NrKSwqYjsKCXN0cnVjdAlkYgkqZGI7CgljaGFyCSpzOwoKCWZwcmludGYoc3RkZXJyLCJWZXJRdWVyeVZhbHVlKCVwLCVzLCVwLCVkKVxuIiwKCQlibG9jayxzdWJibG9jayxidWZmZXIsKmJ1ZmxlbgoJKTsKCXM9KGNoYXIqKXhtYWxsb2Moc3RybGVuKCJWU19WRVJTSU9OX0lORk8iKStzdHJsZW4oc3ViYmxvY2spKzEpOwoJc3RyY3B5KHMsIlZTX1ZFUlNJT05fSU5GTyIpO3N0cmNhdChzLHN1YmJsb2NrKTsKCWI9X2ZpbmRfZGF0YShibG9jayxzKTsKCWlmIChiPT1OVUxMKSB7CgkJKmJ1Zmxlbj0wOwoJCXJldHVybiAwOwoJfQoJZGI9KHN0cnVjdCBkYiopYjsKCSpidWZsZW4JPSBkYi0+ZGF0YWxlbjsKCS8qIGxldCBiIHBvaW50IHRvIGRhdGEgYXJlYSAqLwoJYgk9IGIrNCsoKHN0cmxlbihkYi0+bmFtZSkrNCkmMyk7CgkvKiBub3cgbG9vayB1cCB3aGF0IHRoZSByZXNwLiBTRUdQVFIgd291bGQgYmUgLi4uIAoJICogd2UgY291bGQgdXNlIE1BS0VfU0VHUFRSICwgYnV0IHdlIGRvbid0IG5lZWQgdG8KCSAqLwoJKmJ1ZmZlcgk9IChiLWJsb2NrKStzZWdibG9jazsKCWZwcmludGYoc3RkZXJyLCIJLT4gJXM9JXNcbiIsc3ViYmxvY2ssYik7CglyZXR1cm4gMTsKfQoKLyoKICAgMjAgR0VURklMRVZFUlNJT05JTkZPUkFXCiAgIDIxIFZFUkZUSEtfVEhVTktEQVRBMTYKICAgMjIgVkVSVEhLU0xfVEhVTktEQVRBMTYKKi8K