LyogCiAqIEltcGxlbWVudGF0aW9uIG9mIFZFUi5ETEwKICogCiAqIENvcHlyaWdodCAxOTk2IE1hcmN1cyBNZWlzc25lcgogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW4uaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ2ZXIuaCIKI2luY2x1ZGUgImx6ZXhwYW5kLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAic3RyaW5nMzIuaCIKCiNkZWZpbmUgTFpSRUFEKHdoYXQpCWlmIChzaXplb2YoKndoYXQpIT1MWlJlYWQzMihsemZkLHdoYXQsc2l6ZW9mKCp3aGF0KSkpIHJldHVybiAwOwoKI2RlZmluZSBzdHJkdXBXMkEoeCkJU1RSSU5HMzJfRHVwVW5pVG9BbnNpKHgpCiNkZWZpbmUgc3RyZHVwQTJXKHgpCVNUUklORzMyX0R1cEFuc2lUb1VuaSh4KQoKaW50CnJlYWRfbmVfaGVhZGVyKEhGSUxFIGx6ZmQsc3RydWN0IG5lX2hlYWRlcl9zICpuZWhkKSB7CglzdHJ1Y3QJbXpfaGVhZGVyX3MJbXpoOwoKCUxaU2VlayhsemZkLDAsU0VFS19TRVQpOwoJaWYgKHNpemVvZihtemgpIT1MWlJlYWQzMihsemZkLCZtemgsc2l6ZW9mKG16aCkpKQoJCXJldHVybiAwOwoJaWYgKG16aC5tel9tYWdpYyE9TVpfU0lHTkFUVVJFKQoJCXJldHVybiAwOwoJTFpTZWVrKGx6ZmQsbXpoLm5lX29mZnNldCxTRUVLX1NFVCk7CglMWlJFQUQobmVoZCk7CglpZiAobmVoZC0+bmVfbWFnaWMgPT0gTkVfU0lHTkFUVVJFKSB7CgkJTFpTZWVrKGx6ZmQsbXpoLm5lX29mZnNldCxTRUVLX1NFVCk7CgkJcmV0dXJuIDE7Cgl9CgkvKiBtdXN0IGhhbmRsZSBQRSBmaWxlcyB0b28uIExhdGVyLiAqLwoJcmV0dXJuIDA7Cn0KCgppbnQKZmluZF9uZV9yZXNvdXJjZSgKCUhGSUxFIGx6ZmQsc3RydWN0IG5lX2hlYWRlcl9zICpuZWhkLFNFR1BUUiB0eXBlaWQsU0VHUFRSIHJlc2lkLAoJQllURSAqKnJlc2RhdGEsaW50ICpyZXNsZW4sRFdPUkQgKm9mZgopIHsKCU5FX1RZUEVJTkZPCXRpOwoJTkVfTkFNRUlORk8Jbmk7CglpbnQJCWk7CglXT1JECQlzaGlmdGNvdW50OwoJRFdPUkQJCW5laGRvZmZzZXQ7CgoJbmVoZG9mZnNldD1MWlNlZWsobHpmZCxuZWhkLT5yZXNvdXJjZV90YWJfb2Zmc2V0LFNFRUtfQ1VSKTsKCUxaUkVBRCgmc2hpZnRjb3VudCk7CglkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwic2hpZnRjb3VudCBpcyAlZFxuIixzaGlmdGNvdW50KTsKCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCJyZWFkaW5nIHJlc291cmNlIHR5cGVpbmZvIGRpci5cbiIpOwoKCWlmICghSElXT1JEKHR5cGVpZCkpIHR5cGVpZCA9IChTRUdQVFIpKExPV09SRCh0eXBlaWQpIHwgMHg4MDAwKTsKCWlmICghSElXT1JEKHJlc2lkKSkgIHJlc2lkICA9IChTRUdQVFIpKExPV09SRChyZXNpZCkgfCAweDgwMDApOwoJd2hpbGUgKDEpIHsKCQlpbnQJc2tpcGZsYWc7CgoJCUxaUkVBRCgmdGkpOwoJCWlmICghdGkudHlwZV9pZCkKCQkJcmV0dXJuIDA7CgkJZHByaW50Zl9yZXNvdXJjZShzdGRlcnIsIiAgICB0aS50eXBlaWQgPSUwNHgsY291bnQ9JWRcbiIsdGkudHlwZV9pZCx0aS5jb3VudCk7CgkJc2tpcGZsYWc9MDsKCQlpZiAoIUhJV09SRCh0eXBlaWQpKSB7CgkJCWlmICgodGkudHlwZV9pZCYweDgwMDApJiYodHlwZWlkIT10aS50eXBlX2lkKSkKCQkJCXNraXBmbGFnPTE7CgkJfSBlbHNlIHsKCQkJaWYgKHRpLnR5cGVfaWQgJiAweDgwMDApIHsKCQkJCXNraXBmbGFnPTE7IAoJCQl9IGVsc2UgewoJCQkJQllURQlsZW47CgkJCQljaGFyCSpzdHI7CgkJCQlEV09SRAl3aGVyZWxlZnQ7CgoJCQkJd2hlcmVsZWZ0PUxaU2VlaygKCQkJCQlsemZkLAoJCQkJCW5laGRvZmZzZXQrbmVoZC0+cmVzb3VyY2VfdGFiX29mZnNldCt0aS50eXBlX2lkLAoJCQkJCVNFRUtfU0VUCgkJCQkpOwoJCQkJTFpSRUFEKCZsZW4pOwoJCQkJc3RyPXhtYWxsb2MobGVuKTsKCQkJCWlmIChsZW4hPUxaUmVhZDMyKGx6ZmQsc3RyLGxlbikpCgkJCQkJcmV0dXJuIDA7CgkJCQlkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwicmVhZCAlcyB0byBjb21wYXJlIGl0IHdpdGggJXNcbiIsCgkJCQkJc3RyLChjaGFyKilQVFJfU0VHX1RPX0xJTih0eXBlaWQpCgkJCQkpOwoJCQkJaWYgKGxzdHJjbXBpMzJBKHN0ciwoY2hhciopUFRSX1NFR19UT19MSU4odHlwZWlkKSkpCgkJCQkJc2tpcGZsYWc9MTsKCQkJCWZyZWUoc3RyKTsKCQkJCUxaU2VlayhsemZkLHdoZXJlbGVmdCxTRUVLX1NFVCk7CgkJCX0KCQl9CgkJaWYgKHNraXBmbGFnKSB7CgkJCUxaU2VlayhsemZkLHRpLmNvdW50KnNpemVvZihuaSksU0VFS19DVVIpOwoJCQljb250aW51ZTsKCQl9CgkJZm9yIChpPTA7aTx0aS5jb3VudDtpKyspIHsKCQkJV09SRAkqcmRhdGE7CgkJCWludAlsZW47CgoJCQlMWlJFQUQoJm5pKTsKCQkJZHByaW50Zl9yZXNvdXJjZShzdGRlcnIsIgluaS5pZD0lNHgsb2Zmc2V0PSVkLGxlbmd0aD0lZFxuIiwKCQkJCW5pLmlkLG5pLm9mZnNldCxuaS5sZW5ndGgKCQkJKTsKCQkJc2tpcGZsYWc9MTsKCQkJaWYgKCFISVdPUkQocmVzaWQpKSB7CgkJCQlpZiAobmkuaWQgPT0gcmVzaWQpCgkJCQkJc2tpcGZsYWc9MDsKCQkJfSBlbHNlIHsKCQkJCWlmICghKG5pLmlkICYgMHg4MDAwKSkgewoJCQkJCUJZVEUJbGVuOwoJCQkJCWNoYXIJKnN0cjsKCQkJCQlEV09SRAl3aGVyZWxlZnQ7CgoJCQkJCXdoZXJlbGVmdD1MWlNlZWsoCgkJCQkJCWx6ZmQsCgkJCQkJCW5laGRvZmZzZXQrbmVoZC0+cmVzb3VyY2VfdGFiX29mZnNldCtuaS5pZCwKCQkJCQkJU0VFS19TRVQKCQkJCQkpOwoJCQkJCUxaUkVBRCgmbGVuKTsKCQkJCQlzdHI9eG1hbGxvYyhsZW4pOwoJCQkJCWlmIChsZW4hPUxaUmVhZDMyKGx6ZmQsc3RyLGxlbikpCgkJCQkJCXJldHVybiAwOwoJCQkJCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCJyZWFkICVzIHRvIGNvbXBhcmUgaXQgd2l0aCAlc1xuIiwKCQkJCQkJc3RyLChjaGFyKilQVFJfU0VHX1RPX0xJTih0eXBlaWQpCgkJCQkJKTsKCQkJCQlpZiAoIWxzdHJjbXBpMzJBKHN0ciwoY2hhciopUFRSX1NFR19UT19MSU4odHlwZWlkKSkpCgkJCQkJCXNraXBmbGFnPTA7CgkJCQkJZnJlZShzdHIpOwoJCQkJCUxaU2VlayhsemZkLHdoZXJlbGVmdCxTRUVLX1NFVCk7CgkJCQl9CgkJCX0KCQkJaWYgKHNraXBmbGFnKQoJCQkJY29udGludWU7CgkJCUxaU2VlayhsemZkLCgoaW50KW5pLm9mZnNldDw8c2hpZnRjb3VudCksU0VFS19TRVQpOwoJCQkqb2ZmCT0gKGludCluaS5vZmZzZXQ8PHNoaWZ0Y291bnQ7CgkJCWxlbgk9IG5pLmxlbmd0aDw8c2hpZnRjb3VudDsKCQkJcmRhdGE9KFdPUkQqKXhtYWxsb2MobGVuKTsKCQkJaWYgKGxlbiE9TFpSZWFkMzIobHpmZCxyZGF0YSxsZW4pKSB7CgkJCQlmcmVlKHJkYXRhKTsKCQkJCXJldHVybiAwOwoJCQl9CgkJCWRwcmludGZfcmVzb3VyY2Uoc3RkZXJyLCJyZXNvdXJjZSBmb3VuZC5cbiIpOwoJCQkqcmVzZGF0YT0gKEJZVEUqKXJkYXRhOwoJCQkqcmVzbGVuCT0gbGVuOwoJCQlyZXR1cm4gMTsKCQl9Cgl9Cn0KCi8qIEdldEZpbGVSZXNvdXJjZVNpemUJCQkJW1ZFUi4yXSAqLwpEV09SRApHZXRGaWxlUmVzb3VyY2VTaXplKExQQ1NUUiBmaWxlbmFtZSxTRUdQVFIgcmVzdHlwZSxTRUdQVFIgcmVzaWQsTFBEV09SRCBvZmYpIHsKCUhGSUxFCWx6ZmQ7CglPRlNUUlVDVAlvZnM7CglCWVRFCSpyZXNkYXRhOwoJaW50CXJlc2xlbjsKCXN0cnVjdAluZV9oZWFkZXJfcwluZWhkOwoKCWZwcmludGYoc3RkZXJyLCJHZXRGaWxlUmVzb3VyY2VTaXplKCVzLCVseCwlbHgsJXApXG4iLAoJCWZpbGVuYW1lLChMT05HKXJlc3R5cGUsKExPTkcpcmVzaWQsb2ZmCgkpOwoJbHpmZD1MWk9wZW5GaWxlMTYoZmlsZW5hbWUsJm9mcyxPRl9SRUFEKTsKCWlmIChsemZkPT0wKQoJCXJldHVybiAwOwoJaWYgKCFyZWFkX25lX2hlYWRlcihsemZkLCZuZWhkKSkgewoJCUxaQ2xvc2UobHpmZCk7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIWZpbmRfbmVfcmVzb3VyY2UobHpmZCwmbmVoZCxyZXN0eXBlLHJlc2lkLCZyZXNkYXRhLCZyZXNsZW4sb2ZmKSkgewoJCUxaQ2xvc2UobHpmZCk7CgkJcmV0dXJuIDA7Cgl9CglmcmVlKHJlc2RhdGEpOwoJTFpDbG9zZShsemZkKTsKCXJldHVybiByZXNsZW47Cn0KCi8qIEdldEZpbGVSZXNvdXJjZVNpemUJCQkJW1ZFUi4zXSAqLwpEV09SRApHZXRGaWxlUmVzb3VyY2UoTFBDU1RSIGZpbGVuYW1lLFNFR1BUUiByZXN0eXBlLFNFR1BUUiByZXNpZCwKCQlEV09SRCBvZmYsRFdPUkQgZGF0YWxlbixMUFZPSUQgZGF0YQopIHsKCUhGSUxFCWx6ZmQ7CglPRlNUUlVDVAlvZnM7CglCWVRFCSpyZXNkYXRhOwoJaW50CXJlc2xlbjsKCXN0cnVjdAluZV9oZWFkZXJfcwluZWhkOwoJZnByaW50ZihzdGRlcnIsIkdldEZpbGVSZXNvdXJjZSglcywlbHgsJWx4LCVsZCwlbGQsJXApXG4iLAoJCWZpbGVuYW1lLChMT05HKXJlc3R5cGUsKExPTkcpcmVzaWQsb2ZmLGRhdGFsZW4sZGF0YQoJKTsKCglsemZkPUxaT3BlbkZpbGUxNihmaWxlbmFtZSwmb2ZzLE9GX1JFQUQpOwoJaWYgKGx6ZmQ9PTApCgkJcmV0dXJuIDA7CglpZiAoIW9mZikgewoJCWlmICghcmVhZF9uZV9oZWFkZXIobHpmZCwmbmVoZCkpIHsKCQkJTFpDbG9zZShsemZkKTsKCQkJcmV0dXJuIDA7CgkJfQoJCWlmICghZmluZF9uZV9yZXNvdXJjZShsemZkLCZuZWhkLHJlc3R5cGUscmVzaWQsJnJlc2RhdGEsJnJlc2xlbiwmb2ZmKSkgewoJCQlMWkNsb3NlKGx6ZmQpOwoJCQlyZXR1cm4gMDsKCQl9CgkJZnJlZShyZXNkYXRhKTsKCX0KCUxaU2VlayhsemZkLG9mZixTRUVLX1NFVCk7CglpZiAocmVzbGVuPmRhdGFsZW4pCgkJcmVzbGVuPWRhdGFsZW47CglMWlJlYWQzMihsemZkLGRhdGEscmVzbGVuKTsKCUxaQ2xvc2UobHpmZCk7CglyZXR1cm4gcmVzbGVuOwp9CgovKiBHZXRGaWxlVmVyc2lvbkluZm9TaXplCQkJW1ZFUi42XSAqLwpEV09SRApHZXRGaWxlVmVyc2lvbkluZm9TaXplMTYoTFBDU1RSIGZpbGVuYW1lLExQRFdPUkQgaGFuZGxlKSB7CglEV09SRAlsZW4scmV0OwoJQllURQlidWZbNzJdOwoJVlNfRklYRURGSUxFSU5GTyAqdmZmaTsKCglkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwiR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTE2KCVzLCVwKVxuIixmaWxlbmFtZSxoYW5kbGUpOwoJbGVuPUdldEZpbGVSZXNvdXJjZVNpemUoZmlsZW5hbWUsVlNfRklMRV9JTkZPLFZTX1ZFUlNJT05fSU5GTyxoYW5kbGUpOwoJaWYgKCFsZW4pCgkJcmV0dXJuIDA7CglyZXQ9R2V0RmlsZVJlc291cmNlKAoJCWZpbGVuYW1lLFZTX0ZJTEVfSU5GTyxWU19WRVJTSU9OX0lORk8sKmhhbmRsZSxzaXplb2YoYnVmKSxidWYKCSk7CglpZiAoIXJldCkKCQlyZXR1cm4gMDsKCgl2ZmZpPShWU19GSVhFREZJTEVJTkZPKikoYnVmKzB4MTQpOwoJaWYgKHZmZmktPmR3U2lnbmF0dXJlICE9IFZTX0ZGSV9TSUdOQVRVUkUpCgkJcmV0dXJuIDA7CglpZiAoKihXT1JEKilidWYgPCBsZW4pCgkJbGVuID0gKihXT1JEKilidWY7CglmcHJpbnRmKHN0ZGVyciwiLT5zdHJ1Y3Zlcj0lbGQuJWxkLGZpbGV2ZXI9JWxkLiVsZCxwcm9kdWN0dmVyPSVsZC4lbGQsZmxhZ21hc2s9JWx4LGZsYWdzPSVseCxPUz0iLAoJCSh2ZmZpLT5kd1N0cnVjVmVyc2lvbj4+MTYpLHZmZmktPmR3U3RydWNWZXJzaW9uJjB4RkZGRiwKCQl2ZmZpLT5kd0ZpbGVWZXJzaW9uTVMsdmZmaS0+ZHdGaWxlVmVyc2lvbkxTLAoJCXZmZmktPmR3UHJvZHVjdFZlcnNpb25NUyx2ZmZpLT5kd1Byb2R1Y3RWZXJzaW9uTFMsCgkJdmZmaS0+ZHdGaWxlRmxhZ3NNYXNrLHZmZmktPmR3RmlsZUZsYWdzCgkpOwoJc3dpdGNoICh2ZmZpLT5kd0ZpbGVPUyYweEZGRkYwMDAwKSB7CgljYXNlIFZPU19ET1M6ZnByaW50ZihzdGRlcnIsIkRPUywiKTticmVhazsKCWNhc2UgVk9TX09TMjE2OmZwcmludGYoc3RkZXJyLCJPUy8yLTE2LCIpO2JyZWFrOwoJY2FzZSBWT1NfT1MyMzI6ZnByaW50ZihzdGRlcnIsIk9TLzItMzIsIik7YnJlYWs7CgljYXNlIFZPU19OVDpmcHJpbnRmKHN0ZGVyciwiTlQsIik7YnJlYWs7CgljYXNlIFZPU19VTktOT1dOOgoJZGVmYXVsdDoKCQlmcHJpbnRmKHN0ZGVyciwiVU5LTk9XTiglbGQpLCIsdmZmaS0+ZHdGaWxlT1MmMHhGRkZGMDAwMCk7YnJlYWs7Cgl9Cglzd2l0Y2ggKHZmZmktPmR3RmlsZU9TICYgMHhGRkZGKSB7CgljYXNlIFZPU19fQkFTRTpmcHJpbnRmKHN0ZGVyciwiQkFTRSIpO2JyZWFrOwoJY2FzZSBWT1NfX1dJTkRPV1MxNjpmcHJpbnRmKHN0ZGVyciwiV0lOMTYiKTticmVhazsKCWNhc2UgVk9TX19XSU5ET1dTMzI6ZnByaW50ZihzdGRlcnIsIldJTjMyIik7YnJlYWs7CgljYXNlIFZPU19fUE0xNjpmcHJpbnRmKHN0ZGVyciwiUE0xNiIpO2JyZWFrOwoJY2FzZSBWT1NfX1BNMzI6ZnByaW50ZihzdGRlcnIsIlBNMzIiKTticmVhazsKCWRlZmF1bHQ6ZnByaW50ZihzdGRlcnIsIlVOS05PV04oJWxkKSIsdmZmaS0+ZHdGaWxlT1MmMHhGRkZGKTticmVhazsKCX0KCXN3aXRjaCAodmZmaS0+ZHdGaWxlVHlwZSkgewoJZGVmYXVsdDoKCWNhc2UgVkZUX1VOS05PV046CgkJZnByaW50ZihzdGRlcnIsImZpbGV0eXBlPVVua25vd24oJWxkKSIsdmZmaS0+ZHdGaWxlVHlwZSk7CgkJYnJlYWs7CgljYXNlIFZGVF9BUFA6ZnByaW50ZihzdGRlcnIsImZpbGV0eXBlPUFQUCIpO2JyZWFrOwoJY2FzZSBWRlRfRExMOmZwcmludGYoc3RkZXJyLCJmaWxldHlwZT1ETEwiKTticmVhazsKCWNhc2UgVkZUX0RSVjoKCQlmcHJpbnRmKHN0ZGVyciwiZmlsZXR5cGU9RFJWLCIpOwoJCXN3aXRjaCh2ZmZpLT5kd0ZpbGVTdWJ0eXBlKSB7CgkJZGVmYXVsdDoKCQljYXNlIFZGVDJfVU5LTk9XTjoKCQkJZnByaW50ZihzdGRlcnIsIlVOS05PV04oJWxkKSIsdmZmaS0+ZHdGaWxlU3VidHlwZSk7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfUFJJTlRFUjoKCQkJZnByaW50ZihzdGRlcnIsIlBSSU5URVIiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9LRVlCT0FSRDoKCQkJZnByaW50ZihzdGRlcnIsIktFWUJPQVJEIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfTEFOR1VBR0U6CgkJCWZwcmludGYoc3RkZXJyLCJMQU5HVUFHRSIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0RJU1BMQVk6CgkJCWZwcmludGYoc3RkZXJyLCJESVNQTEFZIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfTU9VU0U6CgkJCWZwcmludGYoc3RkZXJyLCJNT1VTRSIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX05FVFdPUks6CgkJCWZwcmludGYoc3RkZXJyLCJORVRXT1JLIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfU1lTVEVNOgoJCQlmcHJpbnRmKHN0ZGVyciwiU1lTVEVNIik7CgkJCWJyZWFrOwoJCWNhc2UgVkZUMl9EUlZfSU5TVEFMTEFCTEU6CgkJCWZwcmludGYoc3RkZXJyLCJJTlNUQUxMQUJMRSIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX1NPVU5EOgoJCQlmcHJpbnRmKHN0ZGVyciwiU09VTkQiKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0RSVl9DT01NOgoJCQlmcHJpbnRmKHN0ZGVyciwiQ09NTSIpOwoJCQlicmVhazsKCQljYXNlIFZGVDJfRFJWX0lOUFVUTUVUSE9EOgoJCQlmcHJpbnRmKHN0ZGVyciwiSU5QVVRNRVRIT0QiKTsKCQkJYnJlYWs7CgkJfQoJCWJyZWFrOwoJY2FzZSBWRlRfRk9OVDoKCQlmcHJpbnRmKHN0ZGVyciwiZmlsZXR5cGU9Rk9OVC4iKTsKCQlzd2l0Y2ggKHZmZmktPmR3RmlsZVN1YnR5cGUpIHsKCQlkZWZhdWx0OgoJCQlmcHJpbnRmKHN0ZGVyciwiVU5LTk9XTiglbGQpIix2ZmZpLT5kd0ZpbGVTdWJ0eXBlKTsKCQkJYnJlYWs7CgkJY2FzZSBWRlQyX0ZPTlRfUkFTVEVSOmZwcmludGYoc3RkZXJyLCJSQVNURVIiKTticmVhazsKCQljYXNlIFZGVDJfRk9OVF9WRUNUT1I6ZnByaW50ZihzdGRlcnIsIlZFQ1RPUiIpO2JyZWFrOwoJCWNhc2UgVkZUMl9GT05UX1RSVUVUWVBFOmZwcmludGYoc3RkZXJyLCJUUlVFVFlQRSIpO2JyZWFrOwoJCX0KCQlicmVhazsKCWNhc2UgVkZUX1ZYRDpmcHJpbnRmKHN0ZGVyciwiZmlsZXR5cGU9VlhEIik7YnJlYWs7CgljYXNlIFZGVF9TVEFUSUNfTElCOmZwcmludGYoc3RkZXJyLCJmaWxldHlwZT1TVEFUSUNfTElCIik7YnJlYWs7Cgl9CglmcHJpbnRmKHN0ZGVyciwiZmlsZWRhdGE9JWx4LiVseFxuIix2ZmZpLT5kd0ZpbGVEYXRlTVMsdmZmaS0+ZHdGaWxlRGF0ZUxTKTsKCXJldHVybiBsZW47Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mb1NpemUzMkEJCQlbVkVSU0lPTi4xXSAqLwpEV09SRApHZXRGaWxlVmVyc2lvbkluZm9TaXplMzJBKExQQ1NUUiBmaWxlbmFtZSxMUERXT1JEIGhhbmRsZSkgewoJZHByaW50Zl9yZXNvdXJjZShzdGRlcnIsIkdldEZpbGVWZXJzaW9uSW5mb1NpemUzMkEoJXMsJXApXG4iLGZpbGVuYW1lLGhhbmRsZSk7CglyZXR1cm4gR2V0RmlsZVZlcnNpb25JbmZvU2l6ZTE2KGZpbGVuYW1lLGhhbmRsZSk7Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mb1NpemUzMlcJCQlbVkVSU0lPTi4yXSAqLwpEV09SRApHZXRGaWxlVmVyc2lvbkluZm9TaXplMzJXKExQQ1dTVFIgZmlsZW5hbWUsTFBEV09SRCBoYW5kbGUpIHsKCUxQU1RSCXhmbjsKCURXT1JECXJldDsKCgl4Zm4JPSBzdHJkdXBXMkEoZmlsZW5hbWUpOwoJcmV0PUdldEZpbGVWZXJzaW9uSW5mb1NpemUxNih4Zm4saGFuZGxlKTsKCWZyZWUoeGZuKTsKCXJldHVybglyZXQ7Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mbwkJCQlbVkVSLjddICovCkRXT1JEIApHZXRGaWxlVmVyc2lvbkluZm8xNihMUENTVFIgZmlsZW5hbWUsRFdPUkQgaGFuZGxlLERXT1JEIGRhdGFzaXplLExQVk9JRCBkYXRhKSB7CglkcHJpbnRmX3Jlc291cmNlKHN0ZGVyciwiR2V0RmlsZVZlcnNpb25JbmZvMTYoJXMsJWxkLCVsZCwlcClcbi0+IiwKCQlmaWxlbmFtZSxoYW5kbGUsZGF0YXNpemUsZGF0YQoJKTsKCXJldHVybiBHZXRGaWxlUmVzb3VyY2UoCgkJZmlsZW5hbWUsVlNfRklMRV9JTkZPLFZTX1ZFUlNJT05fSU5GTyxoYW5kbGUsZGF0YXNpemUsZGF0YQoJKTsKfQoKLyogR2V0RmlsZVZlcnNpb25JbmZvQQkJCQlbVkVSU0lPTi4wXSAqLwpEV09SRCAKR2V0RmlsZVZlcnNpb25JbmZvMzJBKExQQ1NUUiBmaWxlbmFtZSxEV09SRCBoYW5kbGUsRFdPUkQgZGF0YXNpemUsTFBWT0lEIGRhdGEpIHsKCXJldHVybiBHZXRGaWxlVmVyc2lvbkluZm8xNihmaWxlbmFtZSxoYW5kbGUsZGF0YXNpemUsZGF0YSk7Cn0KCi8qIEdldEZpbGVWZXJzaW9uSW5mb1cJCQkJW1ZFUlNJT04uM10gKi8KRFdPUkQgCkdldEZpbGVWZXJzaW9uSW5mbzMyVyhMUENXU1RSIGZpbGVuYW1lLERXT1JEIGhhbmRsZSxEV09SRCBkYXRhc2l6ZSxMUFZPSUQgZGF0YSl7CglEV09SRAlyZXQ7CglMUFNUUglmbjsKCglmbgk9IHN0cmR1cFcyQShmaWxlbmFtZSk7CglyZXQJPSBHZXRGaWxlVmVyc2lvbkluZm8xNihmbixoYW5kbGUsZGF0YXNpemUsZGF0YSk7CglmcmVlKGZuKTsKCXJldHVybglyZXQ7Cn0KCi8qIFZlckZpbmRGaWxlCQkJCVtWRVIuOF0gKi8KRFdPUkQKVmVyRmluZEZpbGUxNigKCVVJTlQxNiBmbGFncyxMUENTVFIgZmlsZW5hbWUsTFBDU1RSIHdpbmRpcixMUENTVFIgYXBwZGlyLAoJTFBTVFIgY3VyZGlyLFVJTlQxNiAqY3VyZGlybGVuLExQU1RSIGRlc3RkaXIsVUlOVDE2ICpkZXN0ZGlybGVuCikgewoJZnByaW50ZihzdGRlcnIsIlZlckZpbmRGaWxlKCV4LCVzLCVzLCVzLCVwLCVkLCVwLCVkKVxuIiwKCQlmbGFncyxmaWxlbmFtZSx3aW5kaXIsYXBwZGlyLGN1cmRpciwqY3VyZGlybGVuLGRlc3RkaXIsKmRlc3RkaXJsZW4KCSk7CglzdHJjcHkoY3VyZGlyLCJaOlxcUk9PVFxcLldJTkVcXCIpOy8qRklYTUUqLwoJKmN1cmRpcmxlbj1zdHJsZW4oY3VyZGlyKTsKCXN0cmNweShkZXN0ZGlyLCJaOlxcUk9PVFxcLldJTkVcXCIpOy8qRklYTUUqLwoJKmRlc3RkaXJsZW49c3RybGVuKGRlc3RkaXIpOwoJcmV0dXJuIDA7Cn0KCi8qIFZlckZpbmRGaWxlQQkJCQkJCVtWRVJTSU9OLjVdICovCkRXT1JEClZlckZpbmRGaWxlMzJBKAoJVUlOVDMyIGZsYWdzLExQQ1NUUiBmaWxlbmFtZSxMUENTVFIgd2luZGlyLExQQ1NUUiBhcHBkaXIsCglMUFNUUiBjdXJkaXIsVUlOVDMyICpjdXJkaXJsZW4sTFBTVFIgZGVzdGRpcixVSU5UMzIgKmRlc3RkaXJsZW4KKSB7CglyZXR1cm4gVmVyRmluZEZpbGUxNihmbGFncyxmaWxlbmFtZSx3aW5kaXIsYXBwZGlyLGN1cmRpcixjdXJkaXJsZW4sZGVzdGRpcixkZXN0ZGlybGVuKTsKfQoKLyogVmVyRmluZEZpbGVXCQkJCQkJW1ZFUlNJT04uNl0gKi8KRFdPUkQKVmVyRmluZEZpbGUzMlcoCglVSU5UMzIgZmxhZ3MsTFBDV1NUUiBmaWxlbmFtZSxMUENXU1RSIHdpbmRpcixMUENXU1RSIGFwcGRpciwKCUxQV1NUUiBjdXJkaXIsVUlOVDMyICpjdXJkaXJsZW4sTFBXU1RSIGRlc3RkaXIsVUlOVDMyICpkZXN0ZGlybGVuCikgewoJTFBTVFIJd2ZuLHd3ZCx3YWQsd2RkLHdjZDsKCURXT1JECXJldDsKCgl3Zm4gPSBzdHJkdXBXMkEoZmlsZW5hbWUpOwoJd3dkID0gc3RyZHVwVzJBKHdpbmRpcik7Cgl3YWQgPSBzdHJkdXBXMkEoYXBwZGlyKTsKCXdjZCA9IChMUFNUUiltYWxsb2MoKmN1cmRpcmxlbik7Cgl3ZGQgPSAoTFBTVFIpbWFsbG9jKCpkZXN0ZGlybGVuKTsKCXJldD1WZXJGaW5kRmlsZTE2KGZsYWdzLHdmbix3d2Qsd2FkLHdjZCxjdXJkaXJsZW4sd2RkLGRlc3RkaXJsZW4pOwoJU1RSSU5HMzJfQW5zaVRvVW5pKGN1cmRpcix3Y2QpOwoJU1RSSU5HMzJfQW5zaVRvVW5pKGRlc3RkaXIsd2RkKTsKCSpjdXJkaXJsZW4JPSBzdHJsZW4od2NkKTsKCSpkZXN0ZGlybGVuCT0gc3RybGVuKHdkZCk7CglyZXR1cm4gcmV0Owp9CgovKiBWZXJJbnN0YWxsRmlsZQkJCQkJW1ZFUi45XSAqLwpEV09SRApWZXJJbnN0YWxsRmlsZTE2KAoJVUlOVDE2IGZsYWdzLExQQ1NUUiBzcmNmaWxlbmFtZSxMUENTVFIgZGVzdGZpbGVuYW1lLExQQ1NUUiBzcmNkaXIsCglMUENTVFIgZGVzdGRpcixMUFNUUiB0bXBmaWxlLFVJTlQxNiAqdG1wZmlsZWxlbgopIHsKCWZwcmludGYoc3RkZXJyLCJWZXJJbnN0YWxsRmlsZSgleCwlcywlcywlcywlcywlcCwlZClcbiIsCgkJZmxhZ3Msc3JjZmlsZW5hbWUsZGVzdGZpbGVuYW1lLHNyY2RpcixkZXN0ZGlyLHRtcGZpbGUsKnRtcGZpbGVsZW4KCSk7CgoJLyogRklYTUU6IEltcGxlbWVudGF0aW9uIHN0aWxsIG1pc3NpbmcgLi4uLiAqLwoKCXJldHVybiBWSUZfU1JDT0xEOwp9CgovKiBWZXJGaW5kRmlsZUEJCQkJCVtWRVJTSU9OLjVdICovCkRXT1JEClZlckluc3RhbGxGaWxlMzJBKAoJVUlOVDMyIGZsYWdzLExQQ1NUUiBzcmNmaWxlbmFtZSxMUENTVFIgZGVzdGZpbGVuYW1lLExQQ1NUUiBzcmNkaXIsCglMUENTVFIgZGVzdGRpcixMUFNUUiB0bXBmaWxlLFVJTlQzMiAqdG1wZmlsZWxlbgopIHsKCXJldHVybiBWZXJJbnN0YWxsRmlsZTE2KGZsYWdzLHNyY2ZpbGVuYW1lLGRlc3RmaWxlbmFtZSxzcmNkaXIsZGVzdGRpcix0bXBmaWxlLHRtcGZpbGVsZW4pOwp9CgovKiBWZXJGaW5kRmlsZVcJCQkJCVtWRVJTSU9OLjZdICovCkRXT1JEClZlckluc3RhbGxGaWxlMzJXKAoJVUlOVDMyIGZsYWdzLExQQ1dTVFIgc3JjZmlsZW5hbWUsTFBDV1NUUiBkZXN0ZmlsZW5hbWUsTFBDV1NUUiBzcmNkaXIsCglMUENXU1RSIGRlc3RkaXIsTFBXU1RSIHRtcGZpbGUsVUlOVDMyICp0bXBmaWxlbGVuCikgewoJTFBTVFIJd3NyY2Ysd3NyY2Qsd2Rlc3RmLHdkZXN0ZCx3dG1wZjsKCURXT1JECXJldDsKCgl3c3JjZgk9IHN0cmR1cFcyQShzcmNmaWxlbmFtZSk7Cgl3c3JjZAk9IHN0cmR1cFcyQShzcmNkaXIpOwoJd2Rlc3RmCT0gc3RyZHVwVzJBKGRlc3RmaWxlbmFtZSk7Cgl3ZGVzdGQJPSBzdHJkdXBXMkEoZGVzdGRpcik7Cgl3dG1wZgk9IHN0cmR1cFcyQSh0bXBmaWxlKTsKCXJldD1WZXJJbnN0YWxsRmlsZTMyQShmbGFncyx3c3JjZix3ZGVzdGYsd3NyY2Qsd2Rlc3RkLHd0bXBmLHRtcGZpbGVsZW4pOwoJZnJlZSh3c3JjZik7CglmcmVlKHdzcmNkKTsKCWZyZWUod2Rlc3RmKTsKCWZyZWUod2Rlc3RkKTsKCWZyZWUod3RtcGYpOwoJcmV0dXJuIHJldDsKfQoKLyogRklYTUU6IFRoaXMgdGFibGUgc2hvdWxkLCBvZiBjb3Vyc2UsIGJlIGxhbmd1YWdlIGRlcGVuZGVuZCAqLwpzdGF0aWMgY29uc3Qgc3RydWN0IG1hcF9pZDJzdHIgewoJVUlOVAlsYW5naWQ7Cgljb25zdCBjaGFyICpsYW5nbmFtZTsKfSBsYW5ndWFnZXNbXT17Cgl7MHgwNDAxLCJBcmFiaXNjaCJ9LAoJezB4MDQwMiwiQnVsZ2FyaXNjaCJ9LAoJezB4MDQwMywiS2F0YWxhbmlzY2gifSwKCXsweDA0MDQsIlRyYWRpdGlvbmFsZXMgQ2hpbmVzaXNjaCJ9LAoJezB4MDQwNSwiVHNjaGVjaXNjaCJ9LAoJezB4MDQwNiwiRORuaXNjaCJ9LAoJezB4MDQwNywiRGV1dHNjaCJ9LAoJezB4MDQwOCwiR3JpZWNoaXNjaCJ9LAoJezB4MDQwOSwiQW1lcmlrYW5pc2NoZXMgRW5nbGlzY2gifSwKCXsweDA0MEEsIkthc3RpbGlzY2hlcyBTcGFuaXNjaCJ9LAoJezB4MDQwQiwiRmlubmlzY2gifSwKCXsweDA0MEMsIkZyYW569nNpc2NoIn0sCgl7MHgwNDBELCJIZWJy5GlzY2gifSwKCXsweDA0MEUsIlVuZ2FyaXNjaCJ9LAoJezB4MDQwRiwiSXNs5G5kaXNjaCJ9LAoJezB4MDQxMCwiSXRhbGllbmlzY2gifSwKCXsweDA0MTEsIkphcGFuaXNjaCJ9LAoJezB4MDQxMiwiS29yZWFuaXNjaCJ9LAoJezB4MDQxMywiTmllZGVybORuZGlzY2gifSwKCXsweDA0MTQsIk5vcndlZ2lzY2gtQm9rbWFsIn0sCgl7MHgwNDE1LCJQb2xuaXNjaCJ9LAoJezB4MDQxNiwiQnJhc2lsaWFuaXNjaGVzIFBvcnR1Z2llc2lzY2gifSwKCXsweDA0MTcsIlLkdG9yb21hbmlzY2gifSwKCXsweDA0MTgsIlJ1beRuaXNjaCJ9LAoJezB4MDQxOSwiUnVzc2lzY2gifSwKCXsweDA0MUEsIktyb2F0b3NlcmJpc2NoIChsYXRlaW5pc2NoKSJ9LAoJezB4MDQxQiwiU2xvd2VuaXNjaCJ9LAoJezB4MDQxQywiQWxiYW5pc2NoIn0sCgl7MHgwNDFELCJTY2h3ZWRpc2NoIn0sCgl7MHgwNDFFLCJUaGFpIn0sCgl7MHgwNDFGLCJU/HJraXNjaCJ9LAoJezB4MDQyMCwiVXJkdSJ9LAoJezB4MDQyMSwiQmFoYXNhIn0sCgl7MHgwODA0LCJWZXJlaW5mYWNodGVzIENoaW5lc2lzY2gifSwKCXsweDA4MDcsIlNjaHdlaXplcmRldXRzY2gifSwKCXsweDA4MDksIkJyaXRpc2NoZXMgRW5nbGlzY2gifSwKCXsweDA4MEEsIk1leGlrYW5pc2NoZXMgU3BhbmlzY2gifSwKCXsweDA4MEMsIkJlbGdpc2NoZXMgRnJhbnr2c2lzY2gifSwKCXsweDA4MTAsIlNjaHdlaXplcmlzY2hlcyBJdGFsaWVuaXNjaCJ9LAoJezB4MDgxMywiQmVsZ2lzY2hlcyBOaWVkZXJs5G5kaXNjaCJ9LAoJezB4MDgxNCwiTm9yZ3dlZ2lzY2gtTnlub3JzayJ9LAoJezB4MDgxNiwiUG9ydHVnaWVzaXNjaCJ9LAoJezB4MDgxQSwiU2VyYm9rcmF0aXNjaCAoa3lyaWxsaXNjaCkifSwKCXsweDBDMUMsIkthbmFkaXNjaGVzIEZyYW569nNpc2NoIn0sCgl7MHgxMDBDLCJTY2h3ZWl6ZXJpc2NoZXMgRnJhbnr2c2lzY2gifSwKCXsweDAwMDAsIlVuYmVrYW5udCJ9LAp9OwoKLyogVmVyTGFuZ3VhZ2VOYW1lCQkJCVtWRVIuMTBdICovCkRXT1JEClZlckxhbmd1YWdlTmFtZTE2KFVJTlQxNiBsYW5naWQsTFBTVFIgbGFuZ25hbWUsVUlOVDE2IGxhbmduYW1lbGVuKSB7CglpbnQJaTsKCWNoYXIJKmJ1ZjsKCglmcHJpbnRmKHN0ZGVyciwiVmVyTGFuZ3VhZ2VOYW1lKCVkLCVwLCVkKVxuIixsYW5naWQsbGFuZ25hbWUsbGFuZ25hbWVsZW4pOwoJLyogRmlyc3QsIGNoZWNrIFxTeXN0ZW1cQ3VycmVudENvbnRyb2xTZXRcY29udHJvbFxObHNcTG9jYWxlXDxsYW5naWQ+CgkgKiBmcm9tIHRoZSByZWdpc3RyeS4gCgkgKi8KCWJ1Zj0oY2hhciopbWFsbG9jKHN0cmxlbigiXFxTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxjb250cm9sXFxObHNcXExvY2FsZVxcIikrOSk7CglzcHJpbnRmKGJ1ZiwiXFxTeXN0ZW1cXEN1cnJlbnRDb250cm9sU2V0XFxjb250cm9sXFxObHNcXExvY2FsZVxcJTA4eCIsbGFuZ2lkKTsKCWlmIChFUlJPUl9TVUNDRVNTPT1SZWdRdWVyeVZhbHVlMTYoSEtFWV9MT0NBTF9NQUNISU5FLGJ1ZixsYW5nbmFtZSwoTFBEV09SRCkmbGFuZ25hbWVsZW4pKSB7CgkJbGFuZ25hbWVbbGFuZ25hbWVsZW4tMV09J1wwJzsKCQlyZXR1cm4gbGFuZ25hbWVsZW47Cgl9CgkvKiBpZiB0aGF0IGZhaWxzLCB1c2UgdGhlIGludGVyYWwgdGFibGUgKi8KCWZvciAoaT0wO2xhbmd1YWdlc1tpXS5sYW5naWQhPTA7aSsrKQoJCWlmIChsYW5naWQ9PWxhbmd1YWdlc1tpXS5sYW5naWQpCgkJCWJyZWFrOwoJc3RybmNweShsYW5nbmFtZSxsYW5ndWFnZXNbaV0ubGFuZ25hbWUsbGFuZ25hbWVsZW4pOwoJbGFuZ25hbWVbbGFuZ25hbWVsZW4tMV09J1wwJzsKCXJldHVybiBzdHJsZW4obGFuZ3VhZ2VzW2ldLmxhbmduYW1lKTsKfQoKLyogVmVyTGFuZ3VhZ2VOYW1lQQkJCQlbVkVSU0lPTi45XSAqLwpEV09SRApWZXJMYW5ndWFnZU5hbWUzMkEoVUlOVDMyIGxhbmdpZCxMUFNUUiBsYW5nbmFtZSxVSU5UMzIgbGFuZ25hbWVsZW4pIHsKCXJldHVybiBWZXJMYW5ndWFnZU5hbWUxNihsYW5naWQsbGFuZ25hbWUsbGFuZ25hbWVsZW4pOwp9CgovKiBWZXJMYW5ndWFnZU5hbWVXCQkJCVtWRVJTSU9OLjEwXSAqLwpEV09SRApWZXJMYW5ndWFnZU5hbWUzMlcoVUlOVDMyIGxhbmdpZCxMUFdTVFIgbGFuZ25hbWUsVUlOVDMyIGxhbmduYW1lbGVuKSB7CglpbnQJaTsKCWNoYXIJKmJ1ZjsKCUxQV1NUUglrZXluYW1lLHJlc3VsdDsKCgkvKiBGaXJzdCwgY2hlY2sgXFN5c3RlbVxDdXJyZW50Q29udHJvbFNldFxjb250cm9sXE5sc1xMb2NhbGVcPGxhbmdpZD4KCSAqIGZyb20gdGhlIHJlZ2lzdHJ5LiAKCSAqLwoJYnVmPShjaGFyKiltYWxsb2Moc3RybGVuKCJcXFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXGNvbnRyb2xcXE5sc1xcTG9jYWxlXFwiKSs5KTsKCXNwcmludGYoYnVmLCJcXFN5c3RlbVxcQ3VycmVudENvbnRyb2xTZXRcXGNvbnRyb2xcXE5sc1xcTG9jYWxlXFwlMDh4IixsYW5naWQpOwoJa2V5bmFtZT1zdHJkdXBBMlcoYnVmKTtmcmVlKGJ1Zik7CglpZiAoRVJST1JfU1VDQ0VTUz09UmVnUXVlcnlWYWx1ZTMyVyhIS0VZX0xPQ0FMX01BQ0hJTkUsa2V5bmFtZSxsYW5nbmFtZSwoTFBEV09SRCkmbGFuZ25hbWVsZW4pKSB7CgkJZnJlZShrZXluYW1lKTsKCQlyZXR1cm4gbGFuZ25hbWVsZW47Cgl9CglmcmVlKGtleW5hbWUpOwoJLyogaWYgdGhhdCBmYWlscywgdXNlIHRoZSBpbnRlcmFsIHRhYmxlICovCglmb3IgKGk9MDtsYW5ndWFnZXNbaV0ubGFuZ2lkIT0wO2krKykKCQlpZiAobGFuZ2lkPT1sYW5ndWFnZXNbaV0ubGFuZ2lkKQoJCQlicmVhazsKCXJlc3VsdD1zdHJkdXBBMlcobGFuZ3VhZ2VzW2ldLmxhbmduYW1lKTsKCWk9bHN0cmxlbjMyVyhyZXN1bHQpKnNpemVvZihXQ0hBUik7CglpZiAoaT5sYW5nbmFtZWxlbikKCQlpPWxhbmduYW1lbGVuOwoJbWVtY3B5KGxhbmduYW1lLHJlc3VsdCxpKTsKCWxhbmduYW1lW2xhbmduYW1lbGVuLTFdPSdcMCc7CglmcmVlKHJlc3VsdCk7CglyZXR1cm4gc3RybGVuKGxhbmd1YWdlc1tpXS5sYW5nbmFtZSk7IC8qIHNhbWUgYXMgc3RybGVuVyhyZXN1bHQpOyAqLwp9CgovKiBGSVhNRTogVU5JQ09ERT8gKi8Kc3RydWN0IGRiIHsKCVdPUkQJbmV4dG9mZjsKCVdPUkQJZGF0YWxlbjsKLyogaW4gbWVtb3J5IHN0cnVjdHVyZS4uLiAqLwoJY2hhcgluYW1lWzFdOyAJLyogcGFkZGVkIHRvIGR3b3JkIGFsaWdubWVudCAqLwovKiAuLi4uIAoJY2hhcglkYXRhW2RhdGFsZW5dOyAgICAgcGFkZGVkIHRvIGR3b3JkIGFsaWduZW1udAoJQllURQlzdWJkaXJkYXRhW107ICAgICAgdW50aWwgbmV4dG9mZgogKi8KfTsKCnN0YXRpYyBCWVRFKgpfZmluZF9kYXRhKEJZVEUgKmJsb2NrLExQQ1NUUiBzdHIpIHsKCWNoYXIJKm5leHRzbGFzaDsKCWludAlzdWJzdHJsZW47CglzdHJ1Y3QJZGIJKmRiOwoKCXdoaWxlICgqc3RyICYmICpzdHI9PSdcXCcpCgkJc3RyKys7CglpZiAoTlVMTCE9KG5leHRzbGFzaD1zdHJjaHIoc3RyLCdcXCcpKSkKCQlzdWJzdHJsZW49bmV4dHNsYXNoLXN0cjsKCWVsc2UKCQlzdWJzdHJsZW49c3RybGVuKHN0cik7CglpZiAobmV4dHNsYXNoIT1OVUxMKSB7CgkJd2hpbGUgKCpuZXh0c2xhc2ggJiYgKm5leHRzbGFzaD09J1xcJykKCQkJbmV4dHNsYXNoKys7CgkJaWYgKCEqbmV4dHNsYXNoKQoJCQluZXh0c2xhc2g9TlVMTDsKCX0KCgoJd2hpbGUgKDEpIHsKCQlkYj0oc3RydWN0IGRiKilibG9jazsKCQlmcHJpbnRmKHN0ZGVyciwiZGI9JXAsZGItPm5leHRvZmY9JWQsZGItPmRhdGFsZW49JWQsZGItPm5hbWU9JXMsZGItPmRhdGE9JXNcbiIsCgkJCWRiLGRiLT5uZXh0b2ZmLGRiLT5kYXRhbGVuLGRiLT5uYW1lLChjaGFyKikoKGNoYXIqKWRiKzQrKChzdHJsZW4oZGItPm5hbWUpKzQpJn4zKSkKCQkpOwoJCWlmICghZGItPm5leHRvZmYpCgkJCXJldHVybiBOVUxMOwoKCQlmcHJpbnRmKHN0ZGVyciwiY29tcGFyaW5nIHdpdGggJXNcbiIsZGItPm5hbWUpOwoJCWlmICghc3RybmNtcChkYi0+bmFtZSxzdHIsc3Vic3RybGVuKSkgewoJCQlpZiAobmV4dHNsYXNoKQoJCQkJcmV0dXJuIF9maW5kX2RhdGEoCgkJCQkJYmxvY2srNCsoKHN0cmxlbihkYi0+bmFtZSkrNCkmfjMpKygoZGItPmRhdGFsZW4rMykmfjMpCgkJCQkJLG5leHRzbGFzaAoJCQkJKTsKCQkJZWxzZQoJCQkJcmV0dXJuIGJsb2NrOwoJCX0KCQlibG9jaz1ibG9jaysoKGRiLT5uZXh0b2ZmKzMpJn4zKTsKCX0KfQoKLyogVmVyUXVlcnlWYWx1ZSAJCQlbVkVSLjExXSAqLwovKiB0YWtlIGNhcmUsICdidWZmZXInIGlzIE5PVCBhIFNFR1BUUiwgaXQganVzdCBwb2ludHMgdG8gb25lICovCkRXT1JEClZlclF1ZXJ5VmFsdWUxNihTRUdQVFIgc2VnYmxvY2ssTFBDU1RSIHN1YmJsb2NrLFNFR1BUUiAqYnVmZmVyLFVJTlQxNiAqYnVmbGVuKQp7CglCWVRFCSpibG9jaz1QVFJfU0VHX1RPX0xJTihzZWdibG9jayksKmI7CglzdHJ1Y3QJZGIJKmRiOwoJY2hhcgkqczsKCglmcHJpbnRmKHN0ZGVyciwiVmVyUXVlcnlWYWx1ZTE2KCVwLCVzLCVwLCVkKVxuIiwKCQlibG9jayxzdWJibG9jayxidWZmZXIsKmJ1ZmxlbgoJKTsKCXM9KGNoYXIqKXhtYWxsb2Moc3RybGVuKCJWU19WRVJTSU9OX0lORk8iKStzdHJsZW4oc3ViYmxvY2spKzEpOwoJc3RyY3B5KHMsIlZTX1ZFUlNJT05fSU5GTyIpO3N0cmNhdChzLHN1YmJsb2NrKTsKCWI9X2ZpbmRfZGF0YShibG9jayxzKTsKCWlmIChiPT1OVUxMKSB7CgkJKmJ1Zmxlbj0wOwoJCXJldHVybiAwOwoJfQoJZGI9KHN0cnVjdCBkYiopYjsKCSpidWZsZW4JPSBkYi0+ZGF0YWxlbjsKCS8qIGxldCBiIHBvaW50IHRvIGRhdGEgYXJlYSAqLwoJYgk9IGIrNCsoKHN0cmxlbihkYi0+bmFtZSkrNCkmMyk7CgkvKiBub3cgbG9vayB1cCB3aGF0IHRoZSByZXNwLiBTRUdQVFIgd291bGQgYmUgLi4uIAoJICogd2UgY291bGQgdXNlIE1BS0VfU0VHUFRSICwgYnV0IHdlIGRvbid0IG5lZWQgdG8KCSAqLwoJKmJ1ZmZlcgk9IChiLWJsb2NrKStzZWdibG9jazsKCWZwcmludGYoc3RkZXJyLCIJLT4gJXM9JXNcbiIsc3ViYmxvY2ssYik7CglyZXR1cm4gMTsKfQoKRFdPUkQKVmVyUXVlcnlWYWx1ZTMyQShMUFZPSUQgdmJsb2NrLExQQ1NUUiBzdWJibG9jayxMUFZPSUQgKnZidWZmZXIsVUlOVDMyICpidWZsZW4pCnsKCUJZVEUJKmIsKmJsb2NrPShMUEJZVEUpdmJsb2NrLCoqYnVmZmVyPShMUEJZVEUqKXZidWZmZXI7CglzdHJ1Y3QJZGIJKmRiOwoJY2hhcgkqczsKCglmcHJpbnRmKHN0ZGVyciwiVmVyUXVlcnlWYWx1ZTMyQSglcCwlcywlcCwlZClcbiIsCgkJYmxvY2ssc3ViYmxvY2ssYnVmZmVyLCpidWZsZW4KCSk7CglzPShjaGFyKil4bWFsbG9jKHN0cmxlbigiVlNfVkVSU0lPTl9JTkZPIikrc3RybGVuKHN1YmJsb2NrKSsxKTsKCXN0cmNweShzLCJWU19WRVJTSU9OX0lORk8iKTtzdHJjYXQocyxzdWJibG9jayk7CgliPV9maW5kX2RhdGEoYmxvY2sscyk7CglpZiAoYj09TlVMTCkgewoJCSpidWZsZW49MDsKCQlyZXR1cm4gMDsKCX0KCWRiPShzdHJ1Y3QgZGIqKWI7CgkqYnVmbGVuCT0gZGItPmRhdGFsZW47CgkvKiBsZXQgYiBwb2ludCB0byBkYXRhIGFyZWEgKi8KCWIJPSBiKzQrKChzdHJsZW4oZGItPm5hbWUpKzQpJjMpOwoJKmJ1ZmZlcgk9IGI7CglmcHJpbnRmKHN0ZGVyciwiCS0+ICVzPSVzXG4iLHN1YmJsb2NrLGIpOwoJcmV0dXJuIDE7Cn0KCkRXT1JEClZlclF1ZXJ5VmFsdWUzMlcoTFBWT0lEIHZibG9jayxMUENXU1RSIHN1YmJsb2NrLExQVk9JRCAqdmJ1ZmZlcixVSU5UMzIgKmJ1ZmxlbikKewoJLyogRklYTUU6IGhtbSwgd2Ugbm90IG9ubHkgbmVlZCB0byBjb252ZXJ0IHN1YmJsb2NrLCBidXQgYWxzbyAKCSAqICAgICAgICB0aGUgY29udGVudC4uLm9yPwoJICogQW5kIHdoYXQgYWJvdXQgVU5JQ09ERSB2ZXJzaW9uIGluZm8/CgkgKiBBbmQgdGhlIE5BTUVTIG9mIHRoZSB2YWx1ZXM/CgkgKi8KCUJZVEUJCSpiLCoqYnVmZmVyPShMUEJZVEUqKXZidWZmZXIsKmJsb2NrPShMUEJZVEUpdmJsb2NrOwoJc3RydWN0CWRiCSpkYjsKCWNoYXIJCSpzLCpzYjsKCglzYj1zdHJkdXBXMkEoc3ViYmxvY2spOwoJcz0oY2hhciopeG1hbGxvYyhzdHJsZW4oIlZTX1ZFUlNJT05fSU5GTyIpK3N0cmxlbihzYikrMSk7CglzdHJjcHkocywiVlNfVkVSU0lPTl9JTkZPIik7c3RyY2F0KHMsc2IpOwoJYj1fZmluZF9kYXRhKGJsb2NrLHMpOwoJaWYgKGI9PU5VTEwpIHsKCQkqYnVmbGVuPTA7CgkJZnJlZShzYik7CgkJcmV0dXJuIDA7Cgl9CglkYj0oc3RydWN0IGRiKiliOwoJKmJ1Zmxlbgk9IGRiLT5kYXRhbGVuOwoJLyogbGV0IGIgcG9pbnQgdG8gZGF0YSBhcmVhICovCgliCT0gYis0Kygoc3RybGVuKGRiLT5uYW1lKSs0KSYzKTsKCSpidWZmZXIJPSBiOwoJZnByaW50ZihzdGRlcnIsIgktPiAlcz0lc1xuIixzYixiKTsKCWZyZWUoc2IpOwoJcmV0dXJuIDE7Cn0KLyogMjAgR0VURklMRVZFUlNJT05JTkZPUkFXICovCg==