LyoKICogQnVpbHRpbiAiZ2l0IGJyYW5jaCIKICoKICogQ29weXJpZ2h0IChjKSAyMDA2IEtyaXN0aWFuIEj4Z3NiZXJnIDxrcmhAcmVkaGF0LmNvbT4KICogQmFzZWQgb24gZ2l0LWJyYW5jaC5zaCBieSBKdW5pbyBDIEhhbWFuby4KICovCgojaW5jbHVkZSAiY2FjaGUuaCIKI2luY2x1ZGUgImNvbG9yLmgiCiNpbmNsdWRlICJyZWZzLmgiCiNpbmNsdWRlICJjb21taXQuaCIKI2luY2x1ZGUgImJ1aWx0aW4uaCIKCnN0YXRpYyBjb25zdCBjaGFyIGJ1aWx0aW5fYnJhbmNoX3VzYWdlW10gPQogICJnaXQtYnJhbmNoIFstcl0gKC1kIHwgLUQpIDxicmFuY2huYW1lPiB8IFstLXRyYWNrIHwgLS1uby10cmFja10gWy1sXSBbLWZdIDxicmFuY2huYW1lPiBbPHN0YXJ0LXBvaW50Pl0gfCAoLW0gfCAtTSkgWzxvbGRicmFuY2g+XSA8bmV3YnJhbmNoPiB8IFstLWNvbG9yIHwgLS1uby1jb2xvcl0gWy1yIHwgLWFdIFstdiBbLS1hYmJyZXY9PGxlbmd0aD4gfCAtLW5vLWFiYnJldl1dIjsKCiNkZWZpbmUgUkVGX1VOS05PV05fVFlQRSAgICAweDAwCiNkZWZpbmUgUkVGX0xPQ0FMX0JSQU5DSCAgICAweDAxCiNkZWZpbmUgUkVGX1JFTU9URV9CUkFOQ0ggICAweDAyCiNkZWZpbmUgUkVGX1RBRyAgICAgICAgICAgICAweDA0CgpzdGF0aWMgY29uc3QgY2hhciAqaGVhZDsKc3RhdGljIHVuc2lnbmVkIGNoYXIgaGVhZF9zaGExWzIwXTsKCnN0YXRpYyBpbnQgYnJhbmNoX3RyYWNrX3JlbW90ZXM7CgpzdGF0aWMgaW50IGJyYW5jaF91c2VfY29sb3I7CnN0YXRpYyBjaGFyIGJyYW5jaF9jb2xvcnNbXVtDT0xPUl9NQVhMRU5dID0gewoJIlwwMzNbbSIsCS8qIHJlc2V0ICovCgkiIiwJCS8qIFBMQUlOIChub3JtYWwpICovCgkiXDAzM1szMW0iLAkvKiBSRU1PVEUgKHJlZCkgKi8KCSIiLAkJLyogTE9DQUwgKG5vcm1hbCkgKi8KCSJcMDMzWzMybSIsCS8qIENVUlJFTlQgKGdyZWVuKSAqLwp9OwplbnVtIGNvbG9yX2JyYW5jaCB7CglDT0xPUl9CUkFOQ0hfUkVTRVQgPSAwLAoJQ09MT1JfQlJBTkNIX1BMQUlOID0gMSwKCUNPTE9SX0JSQU5DSF9SRU1PVEUgPSAyLAoJQ09MT1JfQlJBTkNIX0xPQ0FMID0gMywKCUNPTE9SX0JSQU5DSF9DVVJSRU5UID0gNCwKfTsKCnN0YXRpYyBpbnQgcGFyc2VfYnJhbmNoX2NvbG9yX3Nsb3QoY29uc3QgY2hhciAqdmFyLCBpbnQgb2ZzKQp7CglpZiAoIXN0cmNhc2VjbXAodmFyK29mcywgInBsYWluIikpCgkJcmV0dXJuIENPTE9SX0JSQU5DSF9QTEFJTjsKCWlmICghc3RyY2FzZWNtcCh2YXIrb2ZzLCAicmVzZXQiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX1JFU0VUOwoJaWYgKCFzdHJjYXNlY21wKHZhcitvZnMsICJyZW1vdGUiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX1JFTU9URTsKCWlmICghc3RyY2FzZWNtcCh2YXIrb2ZzLCAibG9jYWwiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX0xPQ0FMOwoJaWYgKCFzdHJjYXNlY21wKHZhcitvZnMsICJjdXJyZW50IikpCgkJcmV0dXJuIENPTE9SX0JSQU5DSF9DVVJSRU5UOwoJZGllKCJiYWQgY29uZmlnIHZhcmlhYmxlICclcyciLCB2YXIpOwp9CgpzdGF0aWMgaW50IGdpdF9icmFuY2hfY29uZmlnKGNvbnN0IGNoYXIgKnZhciwgY29uc3QgY2hhciAqdmFsdWUpCnsKCWlmICghc3RyY21wKHZhciwgImNvbG9yLmJyYW5jaCIpKSB7CgkJYnJhbmNoX3VzZV9jb2xvciA9IGdpdF9jb25maWdfY29sb3Jib29sKHZhciwgdmFsdWUpOwoJCXJldHVybiAwOwoJfQoJaWYgKCFwcmVmaXhjbXAodmFyLCAiY29sb3IuYnJhbmNoLiIpKSB7CgkJaW50IHNsb3QgPSBwYXJzZV9icmFuY2hfY29sb3Jfc2xvdCh2YXIsIDEzKTsKCQljb2xvcl9wYXJzZSh2YWx1ZSwgdmFyLCBicmFuY2hfY29sb3JzW3Nsb3RdKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghc3RyY21wKHZhciwgImJyYW5jaC5hdXRvc2V0dXBtZXJnZSIpKQoJCWJyYW5jaF90cmFja19yZW1vdGVzID0gZ2l0X2NvbmZpZ19ib29sKHZhciwgdmFsdWUpOwoKCXJldHVybiBnaXRfZGVmYXVsdF9jb25maWcodmFyLCB2YWx1ZSk7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICpicmFuY2hfZ2V0X2NvbG9yKGVudW0gY29sb3JfYnJhbmNoIGl4KQp7CglpZiAoYnJhbmNoX3VzZV9jb2xvcikKCQlyZXR1cm4gYnJhbmNoX2NvbG9yc1tpeF07CglyZXR1cm4gIiI7Cn0KCnN0YXRpYyBpbnQgZGVsZXRlX2JyYW5jaGVzKGludCBhcmdjLCBjb25zdCBjaGFyICoqYXJndiwgaW50IGZvcmNlLCBpbnQga2luZHMpCnsKCXN0cnVjdCBjb21taXQgKnJldiwgKmhlYWRfcmV2ID0gaGVhZF9yZXY7Cgl1bnNpZ25lZCBjaGFyIHNoYTFbMjBdOwoJY2hhciAqbmFtZSA9IE5VTEw7Cgljb25zdCBjaGFyICpmbXQsICpyZW1vdGU7CgljaGFyIHNlY3Rpb25bUEFUSF9NQVhdOwoJaW50IGk7CglpbnQgcmV0ID0gMDsKCglzd2l0Y2ggKGtpbmRzKSB7CgljYXNlIFJFRl9SRU1PVEVfQlJBTkNIOgoJCWZtdCA9ICJyZWZzL3JlbW90ZXMvJXMiOwoJCXJlbW90ZSA9ICJyZW1vdGUgIjsKCQlmb3JjZSA9IDE7CgkJYnJlYWs7CgljYXNlIFJFRl9MT0NBTF9CUkFOQ0g6CgkJZm10ID0gInJlZnMvaGVhZHMvJXMiOwoJCXJlbW90ZSA9ICIiOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlkaWUoImNhbm5vdCB1c2UgLWEgd2l0aCAtZCIpOwoJfQoKCWlmICghZm9yY2UpIHsKCQloZWFkX3JldiA9IGxvb2t1cF9jb21taXRfcmVmZXJlbmNlKGhlYWRfc2hhMSk7CgkJaWYgKCFoZWFkX3JldikKCQkJZGllKCJDb3VsZG4ndCBsb29rIHVwIGNvbW1pdCBvYmplY3QgZm9yIEhFQUQiKTsKCX0KCWZvciAoaSA9IDA7IGkgPCBhcmdjOyBpKyspIHsKCQlpZiAoa2luZHMgPT0gUkVGX0xPQ0FMX0JSQU5DSCAmJiAhc3RyY21wKGhlYWQsIGFyZ3ZbaV0pKSB7CgkJCWVycm9yKCJDYW5ub3QgZGVsZXRlIHRoZSBicmFuY2ggJyVzJyAiCgkJCQkid2hpY2ggeW91IGFyZSBjdXJyZW50bHkgb24uIiwgYXJndltpXSk7CgkJCXJldCA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCgkJaWYgKG5hbWUpCgkJCWZyZWUobmFtZSk7CgoJCW5hbWUgPSB4c3RyZHVwKG1rcGF0aChmbXQsIGFyZ3ZbaV0pKTsKCQlpZiAoIXJlc29sdmVfcmVmKG5hbWUsIHNoYTEsIDEsIE5VTEwpKSB7CgkJCWVycm9yKCIlc2JyYW5jaCAnJXMnIG5vdCBmb3VuZC4iLAoJCQkJCXJlbW90ZSwgYXJndltpXSk7CgkJCXJldCA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCgkJcmV2ID0gbG9va3VwX2NvbW1pdF9yZWZlcmVuY2Uoc2hhMSk7CgkJaWYgKCFyZXYpIHsKCQkJZXJyb3IoIkNvdWxkbid0IGxvb2sgdXAgY29tbWl0IG9iamVjdCBmb3IgJyVzJyIsIG5hbWUpOwoJCQlyZXQgPSAxOwoJCQljb250aW51ZTsKCQl9CgoJCS8qIFRoaXMgY2hlY2tzIHdoZXRoZXIgdGhlIG1lcmdlIGJhc2VzIG9mIGJyYW5jaCBhbmQKCQkgKiBIRUFEIGNvbnRhaW5zIGJyYW5jaCAtLSB3aGljaCBtZWFucyB0aGF0IHRoZSBIRUFECgkJICogY29udGFpbnMgZXZlcnl0aGluZyBpbiBib3RoLgoJCSAqLwoKCQlpZiAoIWZvcmNlICYmCgkJICAgICFpbl9tZXJnZV9iYXNlcyhyZXYsICZoZWFkX3JldiwgMSkpIHsKCQkJZXJyb3IoIlRoZSBicmFuY2ggJyVzJyBpcyBub3QgYSBzdHJpY3Qgc3Vic2V0IG9mICIKCQkJCSJ5b3VyIGN1cnJlbnQgSEVBRC5cbiIKCQkJCSJJZiB5b3UgYXJlIHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIGl0LCAiCgkJCQkicnVuICdnaXQgYnJhbmNoIC1EICVzJy4iLCBhcmd2W2ldLCBhcmd2W2ldKTsKCQkJcmV0ID0gMTsKCQkJY29udGludWU7CgkJfQoKCQlpZiAoZGVsZXRlX3JlZihuYW1lLCBzaGExKSkgewoJCQllcnJvcigiRXJyb3IgZGVsZXRpbmcgJXNicmFuY2ggJyVzJyIsIHJlbW90ZSwKCQkJICAgICAgIGFyZ3ZbaV0pOwoJCQlyZXQgPSAxOwoJCX0gZWxzZSB7CgkJCXByaW50ZigiRGVsZXRlZCAlc2JyYW5jaCAlcy5cbiIsIHJlbW90ZSwgYXJndltpXSk7CgkJCXNucHJpbnRmKHNlY3Rpb24sIHNpemVvZihzZWN0aW9uKSwgImJyYW5jaC4lcyIsCgkJCQkgYXJndltpXSk7CgkJCWlmIChnaXRfY29uZmlnX3JlbmFtZV9zZWN0aW9uKHNlY3Rpb24sIE5VTEwpIDwgMCkKCQkJCXdhcm5pbmcoIlVwZGF0ZSBvZiBjb25maWctZmlsZSBmYWlsZWQiKTsKCQl9Cgl9CgoJaWYgKG5hbWUpCgkJZnJlZShuYW1lKTsKCglyZXR1cm4ocmV0KTsKfQoKc3RydWN0IHJlZl9pdGVtIHsKCWNoYXIgKm5hbWU7Cgl1bnNpZ25lZCBpbnQga2luZDsKCXVuc2lnbmVkIGNoYXIgc2hhMVsyMF07Cn07CgpzdHJ1Y3QgcmVmX2xpc3QgewoJaW50IGluZGV4LCBhbGxvYywgbWF4d2lkdGg7CglzdHJ1Y3QgcmVmX2l0ZW0gKmxpc3Q7CglpbnQga2luZHM7Cn07CgpzdGF0aWMgaW50IGFwcGVuZF9yZWYoY29uc3QgY2hhciAqcmVmbmFtZSwgY29uc3QgdW5zaWduZWQgY2hhciAqc2hhMSwgaW50IGZsYWdzLCB2b2lkICpjYl9kYXRhKQp7CglzdHJ1Y3QgcmVmX2xpc3QgKnJlZl9saXN0ID0gKHN0cnVjdCByZWZfbGlzdCopKGNiX2RhdGEpOwoJc3RydWN0IHJlZl9pdGVtICpuZXdpdGVtOwoJaW50IGtpbmQgPSBSRUZfVU5LTk9XTl9UWVBFOwoJaW50IGxlbjsKCgkvKiBEZXRlY3Qga2luZCAqLwoJaWYgKCFwcmVmaXhjbXAocmVmbmFtZSwgInJlZnMvaGVhZHMvIikpIHsKCQlraW5kID0gUkVGX0xPQ0FMX0JSQU5DSDsKCQlyZWZuYW1lICs9IDExOwoJfSBlbHNlIGlmICghcHJlZml4Y21wKHJlZm5hbWUsICJyZWZzL3JlbW90ZXMvIikpIHsKCQlraW5kID0gUkVGX1JFTU9URV9CUkFOQ0g7CgkJcmVmbmFtZSArPSAxMzsKCX0gZWxzZSBpZiAoIXByZWZpeGNtcChyZWZuYW1lLCAicmVmcy90YWdzLyIpKSB7CgkJa2luZCA9IFJFRl9UQUc7CgkJcmVmbmFtZSArPSAxMDsKCX0KCgkvKiBEb24ndCBhZGQgdHlwZXMgdGhlIGNhbGxlciBkb2Vzbid0IHdhbnQgKi8KCWlmICgoa2luZCAmIHJlZl9saXN0LT5raW5kcykgPT0gMCkKCQlyZXR1cm4gMDsKCgkvKiBSZXNpemUgYnVmZmVyICovCglpZiAocmVmX2xpc3QtPmluZGV4ID49IHJlZl9saXN0LT5hbGxvYykgewoJCXJlZl9saXN0LT5hbGxvYyA9IGFsbG9jX25yKHJlZl9saXN0LT5hbGxvYyk7CgkJcmVmX2xpc3QtPmxpc3QgPSB4cmVhbGxvYyhyZWZfbGlzdC0+bGlzdCwKCQkJCXJlZl9saXN0LT5hbGxvYyAqIHNpemVvZihzdHJ1Y3QgcmVmX2l0ZW0pKTsKCX0KCgkvKiBSZWNvcmQgdGhlIG5ldyBpdGVtICovCgluZXdpdGVtID0gJihyZWZfbGlzdC0+bGlzdFtyZWZfbGlzdC0+aW5kZXgrK10pOwoJbmV3aXRlbS0+bmFtZSA9IHhzdHJkdXAocmVmbmFtZSk7CgluZXdpdGVtLT5raW5kID0ga2luZDsKCWhhc2hjcHkobmV3aXRlbS0+c2hhMSwgc2hhMSk7CglsZW4gPSBzdHJsZW4obmV3aXRlbS0+bmFtZSk7CglpZiAobGVuID4gcmVmX2xpc3QtPm1heHdpZHRoKQoJCXJlZl9saXN0LT5tYXh3aWR0aCA9IGxlbjsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgZnJlZV9yZWZfbGlzdChzdHJ1Y3QgcmVmX2xpc3QgKnJlZl9saXN0KQp7CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgcmVmX2xpc3QtPmluZGV4OyBpKyspCgkJZnJlZShyZWZfbGlzdC0+bGlzdFtpXS5uYW1lKTsKCWZyZWUocmVmX2xpc3QtPmxpc3QpOwp9CgpzdGF0aWMgaW50IHJlZl9jbXAoY29uc3Qgdm9pZCAqcjEsIGNvbnN0IHZvaWQgKnIyKQp7CglzdHJ1Y3QgcmVmX2l0ZW0gKmMxID0gKHN0cnVjdCByZWZfaXRlbSAqKShyMSk7CglzdHJ1Y3QgcmVmX2l0ZW0gKmMyID0gKHN0cnVjdCByZWZfaXRlbSAqKShyMik7CgoJaWYgKGMxLT5raW5kICE9IGMyLT5raW5kKQoJCXJldHVybiBjMS0+a2luZCAtIGMyLT5raW5kOwoJcmV0dXJuIHN0cmNtcChjMS0+bmFtZSwgYzItPm5hbWUpOwp9CgpzdGF0aWMgdm9pZCBwcmludF9yZWZfaXRlbShzdHJ1Y3QgcmVmX2l0ZW0gKml0ZW0sIGludCBtYXh3aWR0aCwgaW50IHZlcmJvc2UsCgkJCSAgIGludCBhYmJyZXYsIGludCBjdXJyZW50KQp7CgljaGFyIGM7CglpbnQgY29sb3I7CglzdHJ1Y3QgY29tbWl0ICpjb21taXQ7CgoJc3dpdGNoIChpdGVtLT5raW5kKSB7CgljYXNlIFJFRl9MT0NBTF9CUkFOQ0g6CgkJY29sb3IgPSBDT0xPUl9CUkFOQ0hfTE9DQUw7CgkJYnJlYWs7CgljYXNlIFJFRl9SRU1PVEVfQlJBTkNIOgoJCWNvbG9yID0gQ09MT1JfQlJBTkNIX1JFTU9URTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJY29sb3IgPSBDT0xPUl9CUkFOQ0hfUExBSU47CgkJYnJlYWs7Cgl9CgoJYyA9ICcgJzsKCWlmIChjdXJyZW50KSB7CgkJYyA9ICcqJzsKCQljb2xvciA9IENPTE9SX0JSQU5DSF9DVVJSRU5UOwoJfQoKCWlmICh2ZXJib3NlKSB7CgkJY2hhciAqc3ViamVjdCA9IE5VTEw7CgkJdW5zaWduZWQgbG9uZyBzdWJqZWN0X2xlbiA9IDA7CgkJY29uc3QgY2hhciAqc3ViID0gIiAqKioqIGludmFsaWQgcmVmICoqKioiOwoKCQljb21taXQgPSBsb29rdXBfY29tbWl0KGl0ZW0tPnNoYTEpOwoJCWlmIChjb21taXQgJiYgIXBhcnNlX2NvbW1pdChjb21taXQpKSB7CgkJCXByZXR0eV9wcmludF9jb21taXQoQ01JVF9GTVRfT05FTElORSwgY29tbWl0LCB+MCwKCQkJCQkgICAgJnN1YmplY3QsICZzdWJqZWN0X2xlbiwgMCwKCQkJCQkgICAgTlVMTCwgTlVMTCwgMCk7CgkJCXN1YiA9IHN1YmplY3Q7CgkJfQoJCXByaW50ZigiJWMgJXMlLSpzJXMgJXMgJXNcbiIsIGMsIGJyYW5jaF9nZXRfY29sb3IoY29sb3IpLAoJCSAgICAgICBtYXh3aWR0aCwgaXRlbS0+bmFtZSwKCQkgICAgICAgYnJhbmNoX2dldF9jb2xvcihDT0xPUl9CUkFOQ0hfUkVTRVQpLAoJCSAgICAgICBmaW5kX3VuaXF1ZV9hYmJyZXYoaXRlbS0+c2hhMSwgYWJicmV2KSwgc3ViKTsKCQlpZiAoc3ViamVjdCkKCQkJZnJlZShzdWJqZWN0KTsKCX0gZWxzZSB7CgkJcHJpbnRmKCIlYyAlcyVzJXNcbiIsIGMsIGJyYW5jaF9nZXRfY29sb3IoY29sb3IpLCBpdGVtLT5uYW1lLAoJCSAgICAgICBicmFuY2hfZ2V0X2NvbG9yKENPTE9SX0JSQU5DSF9SRVNFVCkpOwoJfQp9CgpzdGF0aWMgdm9pZCBwcmludF9yZWZfbGlzdChpbnQga2luZHMsIGludCBkZXRhY2hlZCwgaW50IHZlcmJvc2UsIGludCBhYmJyZXYpCnsKCWludCBpOwoJc3RydWN0IHJlZl9saXN0IHJlZl9saXN0OwoKCW1lbXNldCgmcmVmX2xpc3QsIDAsIHNpemVvZihyZWZfbGlzdCkpOwoJcmVmX2xpc3Qua2luZHMgPSBraW5kczsKCWZvcl9lYWNoX3JlZihhcHBlbmRfcmVmLCAmcmVmX2xpc3QpOwoKCXFzb3J0KHJlZl9saXN0Lmxpc3QsIHJlZl9saXN0LmluZGV4LCBzaXplb2Yoc3RydWN0IHJlZl9pdGVtKSwgcmVmX2NtcCk7CgoJZGV0YWNoZWQgPSAoZGV0YWNoZWQgJiYgKGtpbmRzICYgUkVGX0xPQ0FMX0JSQU5DSCkpOwoJaWYgKGRldGFjaGVkKSB7CgkJc3RydWN0IHJlZl9pdGVtIGl0ZW07CgkJaXRlbS5uYW1lID0geHN0cmR1cCgiKG5vIGJyYW5jaCkiKTsKCQlpdGVtLmtpbmQgPSBSRUZfTE9DQUxfQlJBTkNIOwoJCWhhc2hjcHkoaXRlbS5zaGExLCBoZWFkX3NoYTEpOwoJCWlmIChzdHJsZW4oaXRlbS5uYW1lKSA+IHJlZl9saXN0Lm1heHdpZHRoKQoJCQkgICAgICByZWZfbGlzdC5tYXh3aWR0aCA9IHN0cmxlbihpdGVtLm5hbWUpOwoJCXByaW50X3JlZl9pdGVtKCZpdGVtLCByZWZfbGlzdC5tYXh3aWR0aCwgdmVyYm9zZSwgYWJicmV2LCAxKTsKCQlmcmVlKGl0ZW0ubmFtZSk7Cgl9CgoJZm9yIChpID0gMDsgaSA8IHJlZl9saXN0LmluZGV4OyBpKyspIHsKCQlpbnQgY3VycmVudCA9ICFkZXRhY2hlZCAmJgoJCQkocmVmX2xpc3QubGlzdFtpXS5raW5kID09IFJFRl9MT0NBTF9CUkFOQ0gpICYmCgkJCSFzdHJjbXAocmVmX2xpc3QubGlzdFtpXS5uYW1lLCBoZWFkKTsKCQlwcmludF9yZWZfaXRlbSgmcmVmX2xpc3QubGlzdFtpXSwgcmVmX2xpc3QubWF4d2lkdGgsIHZlcmJvc2UsCgkJCSAgICAgICBhYmJyZXYsIGN1cnJlbnQpOwoJfQoKCWZyZWVfcmVmX2xpc3QoJnJlZl9saXN0KTsKfQoKc3RhdGljIGNoYXIgKmNvbmZpZ19yZXBvOwpzdGF0aWMgY2hhciAqY29uZmlnX3JlbW90ZTsKc3RhdGljIGNvbnN0IGNoYXIgKnN0YXJ0X3JlZjsKCnN0YXRpYyBpbnQgZ2V0X3JlbW90ZV9icmFuY2hfbmFtZShjb25zdCBjaGFyICp2YWx1ZSkKewoJY29uc3QgY2hhciAqY29sb247Cgljb25zdCBjaGFyICplbmQ7CgoJaWYgKCp2YWx1ZSA9PSAnKycpCgkJdmFsdWUrKzsKCgljb2xvbiA9IHN0cmNocih2YWx1ZSwgJzonKTsKCWlmICghY29sb24pCgkJcmV0dXJuIDA7CgoJZW5kID0gdmFsdWUgKyBzdHJsZW4odmFsdWUpOwoKCS8qCgkgKiBUcnkgYW4gZXhhY3QgbWF0Y2ggZmlyc3QuICBJLmUuIGhhbmRsZSB0aGUgY2FzZSB3aGVyZSB0aGUKCSAqIHZhbHVlIGlzICIkYW55dGhpbmc6cmVmcy9mb28vYmFyL2JheiIgYW5kIHN0YXJ0X3JlZiBpcyBleGFjdGx5CgkgKiAicmVmcy9mb28vYmFyL2JheiIuIFRoZW4gdGhlIG5hbWUgYXQgdGhlIHJlbW90ZSBpcyAkYW55dGhpbmcuCgkgKi8KCWlmICghc3RyY21wKGNvbG9uICsgMSwgc3RhcnRfcmVmKSkgewoJCS8qIFRydW5jYXRlIHRoZSB2YWx1ZSBiZWZvcmUgdGhlIGNvbG9uLiAqLwoJCW5mYXNwcmludGYoJmNvbmZpZ19yZXBvLCAiJS4qcyIsIGNvbG9uIC0gdmFsdWUsIHZhbHVlKTsKCQlyZXR1cm4gMTsKCX0KCgkvKgoJICogSXMgdGhpcyBhIHdpbGRjYXJkIG1hdGNoPwoJICovCglpZiAoKGVuZCAtIDIgPD0gdmFsdWUpIHx8IGVuZFstMl0gIT0gJy8nIHx8IGVuZFstMV0gIT0gJyonIHx8CgkgICAgKGNvbG9uIC0gMiA8PSB2YWx1ZSkgfHwgY29sb25bLTJdICE9ICcvJyB8fCBjb2xvblstMV0gIT0gJyonKQoJCXJldHVybiAwOwoKCS8qCgkgKiBWYWx1ZSBpcyAicmVmcy9mb28vYmFyLzxhc3Rlcmlzaz46cmVmcy9iYXovYm9hLzxhc3Rlcmlzaz4iCgkgKiBhbmQgc3RhcnRfcmVmIGJlZ2lucyB3aXRoICJyZWZzL2Jhei9ib2EvIjsgdGhlIG5hbWUgYXQgdGhlCgkgKiByZW1vdGUgaXMgcmVmcy9mb28vYmFyLyB3aXRoIHRoZSByZW1haW5pbmcgcGFydCBvZiB0aGUKCSAqIHN0YXJ0X3JlZi4gIFRoZSBsZW5ndGggb2YgdGhlIHByZWZpeCBvbiB0aGUgUkhTIGlzIChlbmQgLQoJICogY29sb24gLSAyKSwgaW5jbHVkaW5nIHRoZSBzbGFzaCBpbW1lZGlhdGVseSBiZWZvcmUgdGhlCgkgKiBhc3Rlcmlzay4KCSAqLwoJaWYgKChzdHJsZW4oc3RhcnRfcmVmKSA8IGVuZCAtIGNvbG9uIC0gMikgfHwKCSAgICBtZW1jbXAoc3RhcnRfcmVmLCBjb2xvbiArIDEsIGVuZCAtIGNvbG9uIC0gMikpCgkJcmV0dXJuIDA7IC8qIGRvZXMgbm90IG1hdGNoIHByZWZpeCAqLwoKCS8qIFJlcGxhY2UgdGhlIGFzdGVyaXNrIHdpdGggdGhlIHJlbW90ZSBicmFuY2ggbmFtZS4gICovCgluZmFzcHJpbnRmKCZjb25maWdfcmVwbywgIiUuKnMlcyIsCgkJICAgKGNvbG9uIC0gMSkgLSB2YWx1ZSwgdmFsdWUsCgkJICAgc3RhcnRfcmVmICsgKGVuZCAtIGNvbG9uIC0gMikpOwoJcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgZ2V0X3JlbW90ZV9jb25maWcoY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSkKewoJY29uc3QgY2hhciAqdmFyOwoJaWYgKHByZWZpeGNtcChrZXksICJyZW1vdGUuIikpCgkJcmV0dXJuIDA7CgoJdmFyID0gc3RycmNocihrZXksICcuJyk7CglpZiAodmFyID09IGtleSArIDYgfHwgc3RyY21wKHZhciwgIi5mZXRjaCIpKQoJCXJldHVybiAwOwoJLyoKCSAqIE9rLCB3ZSBhcmUgbG9va2luZyBhdCBrZXkgPT0gInJlbW90ZS4kZm9vLmZldGNoIjsKCSAqLwoJaWYgKGdldF9yZW1vdGVfYnJhbmNoX25hbWUodmFsdWUpKQoJCW5mYXNwcmludGYoJmNvbmZpZ19yZW1vdGUsICIlLipzIiwgdmFyIC0gKGtleSArIDcpLCBrZXkgKyA3KTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgc2V0X2JyYW5jaF9tZXJnZShjb25zdCBjaGFyICpuYW1lLCBjb25zdCBjaGFyICpjb25maWdfcmVtb3RlLAoJCQkgICAgIGNvbnN0IGNoYXIgKmNvbmZpZ19yZXBvKQp7CgljaGFyIGtleVsxMDI0XTsKCWlmIChzaXplb2Yoa2V5KSA8PQoJICAgIHNucHJpbnRmKGtleSwgc2l6ZW9mKGtleSksICJicmFuY2guJXMucmVtb3RlIiwgbmFtZSkpCgkJZGllKCJ3aGF0IGEgbG9uZyBicmFuY2ggbmFtZSB5b3UgaGF2ZSEiKTsKCWdpdF9jb25maWdfc2V0KGtleSwgY29uZmlnX3JlbW90ZSk7CgoJLyoKCSAqIFdlIGRvIG5vdCBoYXZlIHRvIGNoZWNrIGlmIHdlIGhhdmUgZW5vdWdoIHNwYWNlIGZvcgoJICogdGhlICdtZXJnZScga2V5LCBzaW5jZSBpdCdzIHNob3J0ZXIgdGhhbiB0aGUKCSAqIHByZXZpb3VzICdyZW1vdGUnIGtleSwgd2hpY2ggd2UgYWxyZWFkeSBjaGVja2VkLgoJICovCglzbnByaW50ZihrZXksIHNpemVvZihrZXkpLCAiYnJhbmNoLiVzLm1lcmdlIiwgbmFtZSk7CglnaXRfY29uZmlnX3NldChrZXksIGNvbmZpZ19yZXBvKTsKfQoKc3RhdGljIHZvaWQgc2V0X2JyYW5jaF9kZWZhdWx0cyhjb25zdCBjaGFyICpuYW1lLCBjb25zdCBjaGFyICpyZWFsX3JlZikKewoJLyoKCSAqIG5hbWUgaXMgdGhlIG5hbWUgb2YgbmV3IGJyYW5jaCB1bmRlciByZWZzL2hlYWRzOwoJICogcmVhbF9yZWYgaXMgdHlwaWNhbGx5IHJlZnMvcmVtb3Rlcy8kZm9vLyRiYXIsIHdoZXJlCgkgKiAkZm9vIGlzIHRoZSByZW1vdGUgbmFtZSAodGhlcmUgdHlwaWNhbGx5IGFyZSBubyBzbGFzaGVzKQoJICogYW5kICRiYXIgaXMgdGhlIGJyYW5jaCBuYW1lIHdlIG1hcCBmcm9tIHRoZSByZW1vdGUKCSAqIChpdCBjb3VsZCBoYXZlIHNsYXNoZXMpLgoJICovCglzdGFydF9yZWYgPSByZWFsX3JlZjsKCWdpdF9jb25maWcoZ2V0X3JlbW90ZV9jb25maWcpOwoJaWYgKCFjb25maWdfcmVwbyAmJiAhY29uZmlnX3JlbW90ZSAmJgoJICAgICFwcmVmaXhjbXAocmVhbF9yZWYsICJyZWZzL2hlYWRzLyIpKSB7CgkJc2V0X2JyYW5jaF9tZXJnZShuYW1lLCAiLiIsIHJlYWxfcmVmKTsKCQlwcmludGYoIkJyYW5jaCAlcyBzZXQgdXAgdG8gdHJhY2sgbG9jYWwgYnJhbmNoICVzLlxuIiwKCQkgICAgICAgbmFtZSwgcmVhbF9yZWYpOwoJfQoKCWlmIChjb25maWdfcmVwbyAmJiBjb25maWdfcmVtb3RlKSB7CgkJc2V0X2JyYW5jaF9tZXJnZShuYW1lLCBjb25maWdfcmVtb3RlLCBjb25maWdfcmVwbyk7CgkJcHJpbnRmKCJCcmFuY2ggJXMgc2V0IHVwIHRvIHRyYWNrIHJlbW90ZSBicmFuY2ggJXMuXG4iLAoJCSAgICAgICBuYW1lLCByZWFsX3JlZik7Cgl9CgoJaWYgKGNvbmZpZ19yZXBvKQoJCWZyZWUoY29uZmlnX3JlcG8pOwoJaWYgKGNvbmZpZ19yZW1vdGUpCgkJZnJlZShjb25maWdfcmVtb3RlKTsKfQoKc3RhdGljIHZvaWQgY3JlYXRlX2JyYW5jaChjb25zdCBjaGFyICpuYW1lLCBjb25zdCBjaGFyICpzdGFydF9uYW1lLAoJCQkgIGludCBmb3JjZSwgaW50IHJlZmxvZywgaW50IHRyYWNrKQp7CglzdHJ1Y3QgcmVmX2xvY2sgKmxvY2s7CglzdHJ1Y3QgY29tbWl0ICpjb21taXQ7Cgl1bnNpZ25lZCBjaGFyIHNoYTFbMjBdOwoJY2hhciAqcmVhbF9yZWYsIHJlZltQQVRIX01BWF0sIG1zZ1tQQVRIX01BWCArIDIwXTsKCWludCBmb3JjaW5nID0gMDsKCglzbnByaW50ZihyZWYsIHNpemVvZiByZWYsICJyZWZzL2hlYWRzLyVzIiwgbmFtZSk7CglpZiAoY2hlY2tfcmVmX2Zvcm1hdChyZWYpKQoJCWRpZSgiJyVzJyBpcyBub3QgYSB2YWxpZCBicmFuY2ggbmFtZS4iLCBuYW1lKTsKCglpZiAocmVzb2x2ZV9yZWYocmVmLCBzaGExLCAxLCBOVUxMKSkgewoJCWlmICghZm9yY2UpCgkJCWRpZSgiQSBicmFuY2ggbmFtZWQgJyVzJyBhbHJlYWR5IGV4aXN0cy4iLCBuYW1lKTsKCQllbHNlIGlmICghaXNfYmFyZV9yZXBvc2l0b3J5KCkgJiYgIXN0cmNtcChoZWFkLCBuYW1lKSkKCQkJZGllKCJDYW5ub3QgZm9yY2UgdXBkYXRlIHRoZSBjdXJyZW50IGJyYW5jaC4iKTsKCQlmb3JjaW5nID0gMTsKCX0KCglyZWFsX3JlZiA9IE5VTEw7CglpZiAoZ2V0X3NoYTEoc3RhcnRfbmFtZSwgc2hhMSkpCgkJZGllKCJOb3QgYSB2YWxpZCBvYmplY3QgbmFtZTogJyVzJy4iLCBzdGFydF9uYW1lKTsKCglzd2l0Y2ggKGR3aW1fcmVmKHN0YXJ0X25hbWUsIHN0cmxlbihzdGFydF9uYW1lKSwgc2hhMSwgJnJlYWxfcmVmKSkgewoJY2FzZSAwOgoJCS8qIE5vdCBicmFuY2hpbmcgZnJvbSBhbnkgZXhpc3RpbmcgYnJhbmNoICovCgkJcmVhbF9yZWYgPSBOVUxMOwoJCWJyZWFrOwoJY2FzZSAxOgoJCS8qIFVuaXF1ZSBjb21wbGV0aW9uIC0tIGdvb2QgKi8KCQlicmVhazsKCWRlZmF1bHQ6CgkJZGllKCJBbWJpZ3VvdXMgb2JqZWN0IG5hbWU6ICclcycuIiwgc3RhcnRfbmFtZSk7CgkJYnJlYWs7Cgl9CgoJaWYgKChjb21taXQgPSBsb29rdXBfY29tbWl0X3JlZmVyZW5jZShzaGExKSkgPT0gTlVMTCkKCQlkaWUoIk5vdCBhIHZhbGlkIGJyYW5jaCBwb2ludDogJyVzJy4iLCBzdGFydF9uYW1lKTsKCWhhc2hjcHkoc2hhMSwgY29tbWl0LT5vYmplY3Quc2hhMSk7CgoJbG9jayA9IGxvY2tfYW55X3JlZl9mb3JfdXBkYXRlKHJlZiwgTlVMTCwgMCk7CglpZiAoIWxvY2spCgkJZGllKCJGYWlsZWQgdG8gbG9jayByZWYgZm9yIHVwZGF0ZTogJXMuIiwgc3RyZXJyb3IoZXJybm8pKTsKCglpZiAocmVmbG9nKQoJCWxvZ19hbGxfcmVmX3VwZGF0ZXMgPSAxOwoKCWlmIChmb3JjaW5nKQoJCXNucHJpbnRmKG1zZywgc2l6ZW9mIG1zZywgImJyYW5jaDogUmVzZXQgZnJvbSAlcyIsCgkJCSBzdGFydF9uYW1lKTsKCWVsc2UKCQlzbnByaW50Zihtc2csIHNpemVvZiBtc2csICJicmFuY2g6IENyZWF0ZWQgZnJvbSAlcyIsCgkJCSBzdGFydF9uYW1lKTsKCgkvKiBXaGVuIGJyYW5jaGluZyBvZmYgYSByZW1vdGUgYnJhbmNoLCBzZXQgdXAgc28gdGhhdCBnaXQtcHVsbAoJICAgYXV0b21hdGljYWxseSBtZXJnZXMgZnJvbSB0aGVyZS4gIFNvIGZhciwgdGhpcyBpcyBvbmx5IGRvbmUgZm9yCgkgICByZW1vdGVzIHJlZ2lzdGVyZWQgdmlhIC5naXQvY29uZmlnLiAgKi8KCWlmIChyZWFsX3JlZiAmJiB0cmFjaykKCQlzZXRfYnJhbmNoX2RlZmF1bHRzKG5hbWUsIHJlYWxfcmVmKTsKCglpZiAod3JpdGVfcmVmX3NoYTEobG9jaywgc2hhMSwgbXNnKSA8IDApCgkJZGllKCJGYWlsZWQgdG8gd3JpdGUgcmVmOiAlcy4iLCBzdHJlcnJvcihlcnJubykpOwoKCWlmIChyZWFsX3JlZikKCQlmcmVlKHJlYWxfcmVmKTsKfQoKc3RhdGljIHZvaWQgcmVuYW1lX2JyYW5jaChjb25zdCBjaGFyICpvbGRuYW1lLCBjb25zdCBjaGFyICpuZXduYW1lLCBpbnQgZm9yY2UpCnsKCWNoYXIgb2xkcmVmW1BBVEhfTUFYXSwgbmV3cmVmW1BBVEhfTUFYXSwgbG9nbXNnW1BBVEhfTUFYKjIgKyAxMDBdOwoJdW5zaWduZWQgY2hhciBzaGExWzIwXTsKCWNoYXIgb2xkc2VjdGlvbltQQVRIX01BWF0sIG5ld3NlY3Rpb25bUEFUSF9NQVhdOwoKCWlmICghb2xkbmFtZSkKCQlkaWUoImNhbm5vdCByZW5hbWUgdGhlIGN1cnJlbnQgYnJhbmNoIHdoaWxlIG5vdCBvbiBhbnkuIik7CgoJaWYgKHNucHJpbnRmKG9sZHJlZiwgc2l6ZW9mKG9sZHJlZiksICJyZWZzL2hlYWRzLyVzIiwgb2xkbmFtZSkgPiBzaXplb2Yob2xkcmVmKSkKCQlkaWUoIk9sZCBicmFuY2huYW1lIHRvbyBsb25nIik7CgoJaWYgKGNoZWNrX3JlZl9mb3JtYXQob2xkcmVmKSkKCQlkaWUoIkludmFsaWQgYnJhbmNoIG5hbWU6ICVzIiwgb2xkcmVmKTsKCglpZiAoc25wcmludGYobmV3cmVmLCBzaXplb2YobmV3cmVmKSwgInJlZnMvaGVhZHMvJXMiLCBuZXduYW1lKSA+IHNpemVvZihuZXdyZWYpKQoJCWRpZSgiTmV3IGJyYW5jaG5hbWUgdG9vIGxvbmciKTsKCglpZiAoY2hlY2tfcmVmX2Zvcm1hdChuZXdyZWYpKQoJCWRpZSgiSW52YWxpZCBicmFuY2ggbmFtZTogJXMiLCBuZXdyZWYpOwoKCWlmIChyZXNvbHZlX3JlZihuZXdyZWYsIHNoYTEsIDEsIE5VTEwpICYmICFmb3JjZSkKCQlkaWUoIkEgYnJhbmNoIG5hbWVkICclcycgYWxyZWFkeSBleGlzdHMuIiwgbmV3bmFtZSk7CgoJc25wcmludGYobG9nbXNnLCBzaXplb2YobG9nbXNnKSwgIkJyYW5jaDogcmVuYW1lZCAlcyB0byAlcyIsCgkJIG9sZHJlZiwgbmV3cmVmKTsKCglpZiAocmVuYW1lX3JlZihvbGRyZWYsIG5ld3JlZiwgbG9nbXNnKSkKCQlkaWUoIkJyYW5jaCByZW5hbWUgZmFpbGVkIik7CgoJLyogbm8gbmVlZCB0byBwYXNzIGxvZ21zZyBoZXJlIGFzIEhFQUQgZGlkbid0IHJlYWxseSBtb3ZlICovCglpZiAoIXN0cmNtcChvbGRuYW1lLCBoZWFkKSAmJiBjcmVhdGVfc3ltcmVmKCJIRUFEIiwgbmV3cmVmLCBOVUxMKSkKCQlkaWUoIkJyYW5jaCByZW5hbWVkIHRvICVzLCBidXQgSEVBRCBpcyBub3QgdXBkYXRlZCEiLCBuZXduYW1lKTsKCglzbnByaW50ZihvbGRzZWN0aW9uLCBzaXplb2Yob2xkc2VjdGlvbiksICJicmFuY2guJXMiLCBvbGRyZWYgKyAxMSk7CglzbnByaW50ZihuZXdzZWN0aW9uLCBzaXplb2YobmV3c2VjdGlvbiksICJicmFuY2guJXMiLCBuZXdyZWYgKyAxMSk7CglpZiAoZ2l0X2NvbmZpZ19yZW5hbWVfc2VjdGlvbihvbGRzZWN0aW9uLCBuZXdzZWN0aW9uKSA8IDApCgkJZGllKCJCcmFuY2ggaXMgcmVuYW1lZCwgYnV0IHVwZGF0ZSBvZiBjb25maWctZmlsZSBmYWlsZWQiKTsKfQoKaW50IGNtZF9icmFuY2goaW50IGFyZ2MsIGNvbnN0IGNoYXIgKiphcmd2LCBjb25zdCBjaGFyICpwcmVmaXgpCnsKCWludCBkZWxldGUgPSAwLCBmb3JjZV9kZWxldGUgPSAwLCBmb3JjZV9jcmVhdGUgPSAwOwoJaW50IHJlbmFtZSA9IDAsIGZvcmNlX3JlbmFtZSA9IDA7CglpbnQgdmVyYm9zZSA9IDAsIGFiYnJldiA9IERFRkFVTFRfQUJCUkVWLCBkZXRhY2hlZCA9IDA7CglpbnQgcmVmbG9nID0gMCwgdHJhY2s7CglpbnQga2luZHMgPSBSRUZfTE9DQUxfQlJBTkNIOwoJaW50IGk7CgoJZ2l0X2NvbmZpZyhnaXRfYnJhbmNoX2NvbmZpZyk7Cgl0cmFjayA9IGJyYW5jaF90cmFja19yZW1vdGVzOwoKCWZvciAoaSA9IDE7IGkgPCBhcmdjOyBpKyspIHsKCQljb25zdCBjaGFyICphcmcgPSBhcmd2W2ldOwoKCQlpZiAoYXJnWzBdICE9ICctJykKCQkJYnJlYWs7CgkJaWYgKCFzdHJjbXAoYXJnLCAiLS0iKSkgewoJCQlpKys7CgkJCWJyZWFrOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItLXRyYWNrIikpIHsKCQkJdHJhY2sgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLS1uby10cmFjayIpKSB7CgkJCXRyYWNrID0gMDsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1kIikpIHsKCQkJZGVsZXRlID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1EIikpIHsKCQkJZGVsZXRlID0gMTsKCQkJZm9yY2VfZGVsZXRlID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1mIikpIHsKCQkJZm9yY2VfY3JlYXRlID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1tIikpIHsKCQkJcmVuYW1lID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1NIikpIHsKCQkJcmVuYW1lID0gMTsKCQkJZm9yY2VfcmVuYW1lID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1yIikpIHsKCQkJa2luZHMgPSBSRUZfUkVNT1RFX0JSQU5DSDsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1hIikpIHsKCQkJa2luZHMgPSBSRUZfUkVNT1RFX0JSQU5DSCB8IFJFRl9MT0NBTF9CUkFOQ0g7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItbCIpKSB7CgkJCXJlZmxvZyA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXByZWZpeGNtcChhcmcsICItLW5vLWFiYnJldiIpKSB7CgkJCWFiYnJldiA9IDA7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXByZWZpeGNtcChhcmcsICItLWFiYnJldj0iKSkgewoJCQlhYmJyZXYgPSBzdHJ0b3VsKGFyZyArIDksIE5VTEwsIDEwKTsKCQkJaWYgKGFiYnJldiA8IE1JTklNVU1fQUJCUkVWKQoJCQkJYWJicmV2ID0gTUlOSU1VTV9BQkJSRVY7CgkJCWVsc2UgaWYgKGFiYnJldiA+IDQwKQoJCQkJYWJicmV2ID0gNDA7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItdiIpKSB7CgkJCXZlcmJvc2UgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLS1jb2xvciIpKSB7CgkJCWJyYW5jaF91c2VfY29sb3IgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLS1uby1jb2xvciIpKSB7CgkJCWJyYW5jaF91c2VfY29sb3IgPSAwOwoJCQljb250aW51ZTsKCQl9CgkJdXNhZ2UoYnVpbHRpbl9icmFuY2hfdXNhZ2UpOwoJfQoKCWlmICgoZGVsZXRlICYmIHJlbmFtZSkgfHwgKGRlbGV0ZSAmJiBmb3JjZV9jcmVhdGUpIHx8CgkgICAgKHJlbmFtZSAmJiBmb3JjZV9jcmVhdGUpKQoJCXVzYWdlKGJ1aWx0aW5fYnJhbmNoX3VzYWdlKTsKCgloZWFkID0gcmVzb2x2ZV9yZWYoIkhFQUQiLCBoZWFkX3NoYTEsIDAsIE5VTEwpOwoJaWYgKCFoZWFkKQoJCWRpZSgiRmFpbGVkIHRvIHJlc29sdmUgSEVBRCBhcyBhIHZhbGlkIHJlZi4iKTsKCWhlYWQgPSB4c3RyZHVwKGhlYWQpOwoJaWYgKCFzdHJjbXAoaGVhZCwgIkhFQUQiKSkgewoJCWRldGFjaGVkID0gMTsKCX0KCWVsc2UgewoJCWlmIChwcmVmaXhjbXAoaGVhZCwgInJlZnMvaGVhZHMvIikpCgkJCWRpZSgiSEVBRCBub3QgZm91bmQgYmVsb3cgcmVmcy9oZWFkcyEiKTsKCQloZWFkICs9IDExOwoJfQoKCWlmIChkZWxldGUpCgkJcmV0dXJuIGRlbGV0ZV9icmFuY2hlcyhhcmdjIC0gaSwgYXJndiArIGksIGZvcmNlX2RlbGV0ZSwga2luZHMpOwoJZWxzZSBpZiAoaSA9PSBhcmdjKQoJCXByaW50X3JlZl9saXN0KGtpbmRzLCBkZXRhY2hlZCwgdmVyYm9zZSwgYWJicmV2KTsKCWVsc2UgaWYgKHJlbmFtZSAmJiAoaSA9PSBhcmdjIC0gMSkpCgkJcmVuYW1lX2JyYW5jaChoZWFkLCBhcmd2W2ldLCBmb3JjZV9yZW5hbWUpOwoJZWxzZSBpZiAocmVuYW1lICYmIChpID09IGFyZ2MgLSAyKSkKCQlyZW5hbWVfYnJhbmNoKGFyZ3ZbaV0sIGFyZ3ZbaSArIDFdLCBmb3JjZV9yZW5hbWUpOwoJZWxzZSBpZiAoaSA9PSBhcmdjIC0gMSB8fCBpID09IGFyZ2MgLSAyKQoJCWNyZWF0ZV9icmFuY2goYXJndltpXSwgKGkgPT0gYXJnYyAtIDIpID8gYXJndltpKzFdIDogaGVhZCwKCQkJICAgICAgZm9yY2VfY3JlYXRlLCByZWZsb2csIHRyYWNrKTsKCWVsc2UKCQl1c2FnZShidWlsdGluX2JyYW5jaF91c2FnZSk7CgoJcmV0dXJuIDA7Cn0K