LyoKICogQnVpbHRpbiAiZ2l0IGJyYW5jaCIKICoKICogQ29weXJpZ2h0IChjKSAyMDA2IEtyaXN0aWFuIEj4Z3NiZXJnIDxrcmhAcmVkaGF0LmNvbT4KICogQmFzZWQgb24gZ2l0LWJyYW5jaC5zaCBieSBKdW5pbyBDIEhhbWFuby4KICovCgojaW5jbHVkZSAiY2FjaGUuaCIKI2luY2x1ZGUgImNvbG9yLmgiCiNpbmNsdWRlICJyZWZzLmgiCiNpbmNsdWRlICJjb21taXQuaCIKI2luY2x1ZGUgImJ1aWx0aW4uaCIKCnN0YXRpYyBjb25zdCBjaGFyIGJ1aWx0aW5fYnJhbmNoX3VzYWdlW10gPQogICJnaXQtYnJhbmNoIFstcl0gKC1kIHwgLUQpIDxicmFuY2huYW1lPiB8IFstLXRyYWNrIHwgLS1uby10cmFja10gWy1sXSBbLWZdIDxicmFuY2huYW1lPiBbPHN0YXJ0LXBvaW50Pl0gfCAoLW0gfCAtTSkgWzxvbGRicmFuY2g+XSA8bmV3YnJhbmNoPiB8IFstLWNvbG9yIHwgLS1uby1jb2xvcl0gWy1yIHwgLWFdIFstdiBbLS1hYmJyZXY9PGxlbmd0aD4gfCAtLW5vLWFiYnJldl1dIjsKCiNkZWZpbmUgUkVGX1VOS05PV05fVFlQRSAgICAweDAwCiNkZWZpbmUgUkVGX0xPQ0FMX0JSQU5DSCAgICAweDAxCiNkZWZpbmUgUkVGX1JFTU9URV9CUkFOQ0ggICAweDAyCiNkZWZpbmUgUkVGX1RBRyAgICAgICAgICAgICAweDA0CgpzdGF0aWMgY29uc3QgY2hhciAqaGVhZDsKc3RhdGljIHVuc2lnbmVkIGNoYXIgaGVhZF9zaGExWzIwXTsKCnN0YXRpYyBpbnQgYnJhbmNoX3RyYWNrX3JlbW90ZXM7CgpzdGF0aWMgaW50IGJyYW5jaF91c2VfY29sb3I7CnN0YXRpYyBjaGFyIGJyYW5jaF9jb2xvcnNbXVtDT0xPUl9NQVhMRU5dID0gewoJIlwwMzNbbSIsCS8qIHJlc2V0ICovCgkiIiwJCS8qIFBMQUlOIChub3JtYWwpICovCgkiXDAzM1szMW0iLAkvKiBSRU1PVEUgKHJlZCkgKi8KCSIiLAkJLyogTE9DQUwgKG5vcm1hbCkgKi8KCSJcMDMzWzMybSIsCS8qIENVUlJFTlQgKGdyZWVuKSAqLwp9OwplbnVtIGNvbG9yX2JyYW5jaCB7CglDT0xPUl9CUkFOQ0hfUkVTRVQgPSAwLAoJQ09MT1JfQlJBTkNIX1BMQUlOID0gMSwKCUNPTE9SX0JSQU5DSF9SRU1PVEUgPSAyLAoJQ09MT1JfQlJBTkNIX0xPQ0FMID0gMywKCUNPTE9SX0JSQU5DSF9DVVJSRU5UID0gNCwKfTsKCnN0YXRpYyBpbnQgcGFyc2VfYnJhbmNoX2NvbG9yX3Nsb3QoY29uc3QgY2hhciAqdmFyLCBpbnQgb2ZzKQp7CglpZiAoIXN0cmNhc2VjbXAodmFyK29mcywgInBsYWluIikpCgkJcmV0dXJuIENPTE9SX0JSQU5DSF9QTEFJTjsKCWlmICghc3RyY2FzZWNtcCh2YXIrb2ZzLCAicmVzZXQiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX1JFU0VUOwoJaWYgKCFzdHJjYXNlY21wKHZhcitvZnMsICJyZW1vdGUiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX1JFTU9URTsKCWlmICghc3RyY2FzZWNtcCh2YXIrb2ZzLCAibG9jYWwiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX0xPQ0FMOwoJaWYgKCFzdHJjYXNlY21wKHZhcitvZnMsICJjdXJyZW50IikpCgkJcmV0dXJuIENPTE9SX0JSQU5DSF9DVVJSRU5UOwoJZGllKCJiYWQgY29uZmlnIHZhcmlhYmxlICclcyciLCB2YXIpOwp9CgppbnQgZ2l0X2JyYW5jaF9jb25maWcoY29uc3QgY2hhciAqdmFyLCBjb25zdCBjaGFyICp2YWx1ZSkKewoJaWYgKCFzdHJjbXAodmFyLCAiY29sb3IuYnJhbmNoIikpIHsKCQlicmFuY2hfdXNlX2NvbG9yID0gZ2l0X2NvbmZpZ19jb2xvcmJvb2wodmFyLCB2YWx1ZSk7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXByZWZpeGNtcCh2YXIsICJjb2xvci5icmFuY2guIikpIHsKCQlpbnQgc2xvdCA9IHBhcnNlX2JyYW5jaF9jb2xvcl9zbG90KHZhciwgMTMpOwoJCWNvbG9yX3BhcnNlKHZhbHVlLCB2YXIsIGJyYW5jaF9jb2xvcnNbc2xvdF0pOwoJCXJldHVybiAwOwoJfQoJaWYgKCFzdHJjbXAodmFyLCAiYnJhbmNoLmF1dG9zZXR1cG1lcmdlIikpCgkJYnJhbmNoX3RyYWNrX3JlbW90ZXMgPSBnaXRfY29uZmlnX2Jvb2wodmFyLCB2YWx1ZSk7CgoJcmV0dXJuIGdpdF9kZWZhdWx0X2NvbmZpZyh2YXIsIHZhbHVlKTsKfQoKY29uc3QgY2hhciAqYnJhbmNoX2dldF9jb2xvcihlbnVtIGNvbG9yX2JyYW5jaCBpeCkKewoJaWYgKGJyYW5jaF91c2VfY29sb3IpCgkJcmV0dXJuIGJyYW5jaF9jb2xvcnNbaXhdOwoJcmV0dXJuICIiOwp9CgpzdGF0aWMgaW50IGRlbGV0ZV9icmFuY2hlcyhpbnQgYXJnYywgY29uc3QgY2hhciAqKmFyZ3YsIGludCBmb3JjZSwgaW50IGtpbmRzKQp7CglzdHJ1Y3QgY29tbWl0ICpyZXYsICpoZWFkX3JldiA9IGhlYWRfcmV2OwoJdW5zaWduZWQgY2hhciBzaGExWzIwXTsKCWNoYXIgKm5hbWUgPSBOVUxMOwoJY29uc3QgY2hhciAqZm10LCAqcmVtb3RlOwoJaW50IGk7CglpbnQgcmV0ID0gMDsKCglzd2l0Y2ggKGtpbmRzKSB7CgljYXNlIFJFRl9SRU1PVEVfQlJBTkNIOgoJCWZtdCA9ICJyZWZzL3JlbW90ZXMvJXMiOwoJCXJlbW90ZSA9ICJyZW1vdGUgIjsKCQlmb3JjZSA9IDE7CgkJYnJlYWs7CgljYXNlIFJFRl9MT0NBTF9CUkFOQ0g6CgkJZm10ID0gInJlZnMvaGVhZHMvJXMiOwoJCXJlbW90ZSA9ICIiOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlkaWUoImNhbm5vdCB1c2UgLWEgd2l0aCAtZCIpOwoJfQoKCWlmICghZm9yY2UpIHsKCQloZWFkX3JldiA9IGxvb2t1cF9jb21taXRfcmVmZXJlbmNlKGhlYWRfc2hhMSk7CgkJaWYgKCFoZWFkX3JldikKCQkJZGllKCJDb3VsZG4ndCBsb29rIHVwIGNvbW1pdCBvYmplY3QgZm9yIEhFQUQiKTsKCX0KCWZvciAoaSA9IDA7IGkgPCBhcmdjOyBpKyspIHsKCQlpZiAoa2luZHMgPT0gUkVGX0xPQ0FMX0JSQU5DSCAmJiAhc3RyY21wKGhlYWQsIGFyZ3ZbaV0pKSB7CgkJCWVycm9yKCJDYW5ub3QgZGVsZXRlIHRoZSBicmFuY2ggJyVzJyAiCgkJCQkid2hpY2ggeW91IGFyZSBjdXJyZW50bHkgb24uIiwgYXJndltpXSk7CgkJCXJldCA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCgkJaWYgKG5hbWUpCgkJCWZyZWUobmFtZSk7CgoJCW5hbWUgPSB4c3RyZHVwKG1rcGF0aChmbXQsIGFyZ3ZbaV0pKTsKCQlpZiAoIXJlc29sdmVfcmVmKG5hbWUsIHNoYTEsIDEsIE5VTEwpKSB7CgkJCWVycm9yKCIlc2JyYW5jaCAnJXMnIG5vdCBmb3VuZC4iLAoJCQkJCXJlbW90ZSwgYXJndltpXSk7CgkJCXJldCA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCgkJcmV2ID0gbG9va3VwX2NvbW1pdF9yZWZlcmVuY2Uoc2hhMSk7CgkJaWYgKCFyZXYpIHsKCQkJZXJyb3IoIkNvdWxkbid0IGxvb2sgdXAgY29tbWl0IG9iamVjdCBmb3IgJyVzJyIsIG5hbWUpOwoJCQlyZXQgPSAxOwoJCQljb250aW51ZTsKCQl9CgoJCS8qIFRoaXMgY2hlY2tzIHdoZXRoZXIgdGhlIG1lcmdlIGJhc2VzIG9mIGJyYW5jaCBhbmQKCQkgKiBIRUFEIGNvbnRhaW5zIGJyYW5jaCAtLSB3aGljaCBtZWFucyB0aGF0IHRoZSBIRUFECgkJICogY29udGFpbnMgZXZlcnl0aGluZyBpbiBib3RoLgoJCSAqLwoKCQlpZiAoIWZvcmNlICYmCgkJICAgICFpbl9tZXJnZV9iYXNlcyhyZXYsICZoZWFkX3JldiwgMSkpIHsKCQkJZXJyb3IoIlRoZSBicmFuY2ggJyVzJyBpcyBub3QgYSBzdHJpY3Qgc3Vic2V0IG9mICIKCQkJCSJ5b3VyIGN1cnJlbnQgSEVBRC5cbiIKCQkJCSJJZiB5b3UgYXJlIHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIGl0LCAiCgkJCQkicnVuICdnaXQgYnJhbmNoIC1EICVzJy4iLCBhcmd2W2ldLCBhcmd2W2ldKTsKCQkJcmV0ID0gMTsKCQkJY29udGludWU7CgkJfQoKCQlpZiAoZGVsZXRlX3JlZihuYW1lLCBzaGExKSkgewoJCQllcnJvcigiRXJyb3IgZGVsZXRpbmcgJXNicmFuY2ggJyVzJyIsIHJlbW90ZSwKCQkJICAgICAgIGFyZ3ZbaV0pOwoJCQlyZXQgPSAxOwoJCX0gZWxzZQoJCQlwcmludGYoIkRlbGV0ZWQgJXNicmFuY2ggJXMuXG4iLCByZW1vdGUsIGFyZ3ZbaV0pOwoKCX0KCglpZiAobmFtZSkKCQlmcmVlKG5hbWUpOwoKCXJldHVybihyZXQpOwp9CgpzdHJ1Y3QgcmVmX2l0ZW0gewoJY2hhciAqbmFtZTsKCXVuc2lnbmVkIGludCBraW5kOwoJdW5zaWduZWQgY2hhciBzaGExWzIwXTsKfTsKCnN0cnVjdCByZWZfbGlzdCB7CglpbnQgaW5kZXgsIGFsbG9jLCBtYXh3aWR0aDsKCXN0cnVjdCByZWZfaXRlbSAqbGlzdDsKCWludCBraW5kczsKfTsKCnN0YXRpYyBpbnQgYXBwZW5kX3JlZihjb25zdCBjaGFyICpyZWZuYW1lLCBjb25zdCB1bnNpZ25lZCBjaGFyICpzaGExLCBpbnQgZmxhZ3MsIHZvaWQgKmNiX2RhdGEpCnsKCXN0cnVjdCByZWZfbGlzdCAqcmVmX2xpc3QgPSAoc3RydWN0IHJlZl9saXN0KikoY2JfZGF0YSk7CglzdHJ1Y3QgcmVmX2l0ZW0gKm5ld2l0ZW07CglpbnQga2luZCA9IFJFRl9VTktOT1dOX1RZUEU7CglpbnQgbGVuOwoKCS8qIERldGVjdCBraW5kICovCglpZiAoIXByZWZpeGNtcChyZWZuYW1lLCAicmVmcy9oZWFkcy8iKSkgewoJCWtpbmQgPSBSRUZfTE9DQUxfQlJBTkNIOwoJCXJlZm5hbWUgKz0gMTE7Cgl9IGVsc2UgaWYgKCFwcmVmaXhjbXAocmVmbmFtZSwgInJlZnMvcmVtb3Rlcy8iKSkgewoJCWtpbmQgPSBSRUZfUkVNT1RFX0JSQU5DSDsKCQlyZWZuYW1lICs9IDEzOwoJfSBlbHNlIGlmICghcHJlZml4Y21wKHJlZm5hbWUsICJyZWZzL3RhZ3MvIikpIHsKCQlraW5kID0gUkVGX1RBRzsKCQlyZWZuYW1lICs9IDEwOwoJfQoKCS8qIERvbid0IGFkZCB0eXBlcyB0aGUgY2FsbGVyIGRvZXNuJ3Qgd2FudCAqLwoJaWYgKChraW5kICYgcmVmX2xpc3QtPmtpbmRzKSA9PSAwKQoJCXJldHVybiAwOwoKCS8qIFJlc2l6ZSBidWZmZXIgKi8KCWlmIChyZWZfbGlzdC0+aW5kZXggPj0gcmVmX2xpc3QtPmFsbG9jKSB7CgkJcmVmX2xpc3QtPmFsbG9jID0gYWxsb2NfbnIocmVmX2xpc3QtPmFsbG9jKTsKCQlyZWZfbGlzdC0+bGlzdCA9IHhyZWFsbG9jKHJlZl9saXN0LT5saXN0LAoJCQkJcmVmX2xpc3QtPmFsbG9jICogc2l6ZW9mKHN0cnVjdCByZWZfaXRlbSkpOwoJfQoKCS8qIFJlY29yZCB0aGUgbmV3IGl0ZW0gKi8KCW5ld2l0ZW0gPSAmKHJlZl9saXN0LT5saXN0W3JlZl9saXN0LT5pbmRleCsrXSk7CgluZXdpdGVtLT5uYW1lID0geHN0cmR1cChyZWZuYW1lKTsKCW5ld2l0ZW0tPmtpbmQgPSBraW5kOwoJaGFzaGNweShuZXdpdGVtLT5zaGExLCBzaGExKTsKCWxlbiA9IHN0cmxlbihuZXdpdGVtLT5uYW1lKTsKCWlmIChsZW4gPiByZWZfbGlzdC0+bWF4d2lkdGgpCgkJcmVmX2xpc3QtPm1heHdpZHRoID0gbGVuOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBmcmVlX3JlZl9saXN0KHN0cnVjdCByZWZfbGlzdCAqcmVmX2xpc3QpCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCByZWZfbGlzdC0+aW5kZXg7IGkrKykKCQlmcmVlKHJlZl9saXN0LT5saXN0W2ldLm5hbWUpOwoJZnJlZShyZWZfbGlzdC0+bGlzdCk7Cn0KCnN0YXRpYyBpbnQgcmVmX2NtcChjb25zdCB2b2lkICpyMSwgY29uc3Qgdm9pZCAqcjIpCnsKCXN0cnVjdCByZWZfaXRlbSAqYzEgPSAoc3RydWN0IHJlZl9pdGVtICopKHIxKTsKCXN0cnVjdCByZWZfaXRlbSAqYzIgPSAoc3RydWN0IHJlZl9pdGVtICopKHIyKTsKCglpZiAoYzEtPmtpbmQgIT0gYzItPmtpbmQpCgkJcmV0dXJuIGMxLT5raW5kIC0gYzItPmtpbmQ7CglyZXR1cm4gc3RyY21wKGMxLT5uYW1lLCBjMi0+bmFtZSk7Cn0KCnN0YXRpYyB2b2lkIHByaW50X3JlZl9pdGVtKHN0cnVjdCByZWZfaXRlbSAqaXRlbSwgaW50IG1heHdpZHRoLCBpbnQgdmVyYm9zZSwKCQkJICAgaW50IGFiYnJldiwgaW50IGN1cnJlbnQpCnsKCWNoYXIgYzsKCWludCBjb2xvcjsKCXN0cnVjdCBjb21taXQgKmNvbW1pdDsKCWNoYXIgc3ViamVjdFsyNTZdOwoKCXN3aXRjaCAoaXRlbS0+a2luZCkgewoJY2FzZSBSRUZfTE9DQUxfQlJBTkNIOgoJCWNvbG9yID0gQ09MT1JfQlJBTkNIX0xPQ0FMOwoJCWJyZWFrOwoJY2FzZSBSRUZfUkVNT1RFX0JSQU5DSDoKCQljb2xvciA9IENPTE9SX0JSQU5DSF9SRU1PVEU7CgkJYnJlYWs7CglkZWZhdWx0OgoJCWNvbG9yID0gQ09MT1JfQlJBTkNIX1BMQUlOOwoJCWJyZWFrOwoJfQoKCWMgPSAnICc7CglpZiAoY3VycmVudCkgewoJCWMgPSAnKic7CgkJY29sb3IgPSBDT0xPUl9CUkFOQ0hfQ1VSUkVOVDsKCX0KCglpZiAodmVyYm9zZSkgewoJCWNvbW1pdCA9IGxvb2t1cF9jb21taXQoaXRlbS0+c2hhMSk7CgkJaWYgKGNvbW1pdCAmJiAhcGFyc2VfY29tbWl0KGNvbW1pdCkpCgkJCXByZXR0eV9wcmludF9jb21taXQoQ01JVF9GTVRfT05FTElORSwgY29tbWl0LCB+MCwKCQkJCQkgICAgc3ViamVjdCwgc2l6ZW9mKHN1YmplY3QpLCAwLAoJCQkJCSAgICBOVUxMLCBOVUxMLCAwKTsKCQllbHNlCgkJCXN0cmNweShzdWJqZWN0LCAiICoqKiogaW52YWxpZCByZWYgKioqKiIpOwoJCXByaW50ZigiJWMgJXMlLSpzJXMgJXMgJXNcbiIsIGMsIGJyYW5jaF9nZXRfY29sb3IoY29sb3IpLAoJCSAgICAgICBtYXh3aWR0aCwgaXRlbS0+bmFtZSwKCQkgICAgICAgYnJhbmNoX2dldF9jb2xvcihDT0xPUl9CUkFOQ0hfUkVTRVQpLAoJCSAgICAgICBmaW5kX3VuaXF1ZV9hYmJyZXYoaXRlbS0+c2hhMSwgYWJicmV2KSwgc3ViamVjdCk7Cgl9IGVsc2UgewoJCXByaW50ZigiJWMgJXMlcyVzXG4iLCBjLCBicmFuY2hfZ2V0X2NvbG9yKGNvbG9yKSwgaXRlbS0+bmFtZSwKCQkgICAgICAgYnJhbmNoX2dldF9jb2xvcihDT0xPUl9CUkFOQ0hfUkVTRVQpKTsKCX0KfQoKc3RhdGljIHZvaWQgcHJpbnRfcmVmX2xpc3QoaW50IGtpbmRzLCBpbnQgZGV0YWNoZWQsIGludCB2ZXJib3NlLCBpbnQgYWJicmV2KQp7CglpbnQgaTsKCXN0cnVjdCByZWZfbGlzdCByZWZfbGlzdDsKCgltZW1zZXQoJnJlZl9saXN0LCAwLCBzaXplb2YocmVmX2xpc3QpKTsKCXJlZl9saXN0LmtpbmRzID0ga2luZHM7Cglmb3JfZWFjaF9yZWYoYXBwZW5kX3JlZiwgJnJlZl9saXN0KTsKCglxc29ydChyZWZfbGlzdC5saXN0LCByZWZfbGlzdC5pbmRleCwgc2l6ZW9mKHN0cnVjdCByZWZfaXRlbSksIHJlZl9jbXApOwoKCWRldGFjaGVkID0gKGRldGFjaGVkICYmIChraW5kcyAmIFJFRl9MT0NBTF9CUkFOQ0gpKTsKCWlmIChkZXRhY2hlZCkgewoJCXN0cnVjdCByZWZfaXRlbSBpdGVtOwoJCWl0ZW0ubmFtZSA9IHhzdHJkdXAoIihubyBicmFuY2gpIik7CgkJaXRlbS5raW5kID0gUkVGX0xPQ0FMX0JSQU5DSDsKCQloYXNoY3B5KGl0ZW0uc2hhMSwgaGVhZF9zaGExKTsKCQlpZiAoc3RybGVuKGl0ZW0ubmFtZSkgPiByZWZfbGlzdC5tYXh3aWR0aCkKCQkJICAgICAgcmVmX2xpc3QubWF4d2lkdGggPSBzdHJsZW4oaXRlbS5uYW1lKTsKCQlwcmludF9yZWZfaXRlbSgmaXRlbSwgcmVmX2xpc3QubWF4d2lkdGgsIHZlcmJvc2UsIGFiYnJldiwgMSk7CgkJZnJlZShpdGVtLm5hbWUpOwoJfQoKCWZvciAoaSA9IDA7IGkgPCByZWZfbGlzdC5pbmRleDsgaSsrKSB7CgkJaW50IGN1cnJlbnQgPSAhZGV0YWNoZWQgJiYKCQkJKHJlZl9saXN0Lmxpc3RbaV0ua2luZCA9PSBSRUZfTE9DQUxfQlJBTkNIKSAmJgoJCQkhc3RyY21wKHJlZl9saXN0Lmxpc3RbaV0ubmFtZSwgaGVhZCk7CgkJcHJpbnRfcmVmX2l0ZW0oJnJlZl9saXN0Lmxpc3RbaV0sIHJlZl9saXN0Lm1heHdpZHRoLCB2ZXJib3NlLAoJCQkgICAgICAgYWJicmV2LCBjdXJyZW50KTsKCX0KCglmcmVlX3JlZl9saXN0KCZyZWZfbGlzdCk7Cn0KCnN0YXRpYyBjaGFyICpjb25maWdfcmVwbzsKc3RhdGljIGNoYXIgKmNvbmZpZ19yZW1vdGU7CnN0YXRpYyBjb25zdCBjaGFyICpzdGFydF9yZWY7CgpzdGF0aWMgaW50IGdldF9yZW1vdGVfYnJhbmNoX25hbWUoY29uc3QgY2hhciAqdmFsdWUpCnsKCWNvbnN0IGNoYXIgKmNvbG9uOwoJY29uc3QgY2hhciAqZW5kOwoKCWlmICgqdmFsdWUgPT0gJysnKQoJCXZhbHVlKys7CgoJY29sb24gPSBzdHJjaHIodmFsdWUsICc6Jyk7CglpZiAoIWNvbG9uKQoJCXJldHVybiAwOwoKCWVuZCA9IHZhbHVlICsgc3RybGVuKHZhbHVlKTsKCgkvKgoJICogVHJ5IGFuIGV4YWN0IG1hdGNoIGZpcnN0LiAgSS5lLiBoYW5kbGUgdGhlIGNhc2Ugd2hlcmUgdGhlCgkgKiB2YWx1ZSBpcyAiJGFueXRoaW5nOnJlZnMvZm9vL2Jhci9iYXoiIGFuZCBzdGFydF9yZWYgaXMgZXhhY3RseQoJICogInJlZnMvZm9vL2Jhci9iYXoiLiBUaGVuIHRoZSBuYW1lIGF0IHRoZSByZW1vdGUgaXMgJGFueXRoaW5nLgoJICovCglpZiAoIXN0cmNtcChjb2xvbiArIDEsIHN0YXJ0X3JlZikpIHsKCQkvKiBUcnVuY2F0ZSB0aGUgdmFsdWUgYmVmb3JlIHRoZSBjb2xvbi4gKi8KCQluZmFzcHJpbnRmKCZjb25maWdfcmVwbywgIiUuKnMiLCBjb2xvbiAtIHZhbHVlLCB2YWx1ZSk7CgkJcmV0dXJuIDE7Cgl9CgoJLyoKCSAqIElzIHRoaXMgYSB3aWxkY2FyZCBtYXRjaD8KCSAqLwoJaWYgKChlbmQgLSAyIDw9IHZhbHVlKSB8fCBlbmRbLTJdICE9ICcvJyB8fCBlbmRbLTFdICE9ICcqJyB8fAoJICAgIChjb2xvbiAtIDIgPD0gdmFsdWUpIHx8IGNvbG9uWy0yXSAhPSAnLycgfHwgY29sb25bLTFdICE9ICcqJykKCQlyZXR1cm4gMDsKCgkvKgoJICogVmFsdWUgaXMgInJlZnMvZm9vL2Jhci88YXN0ZXJpc2s+OnJlZnMvYmF6L2JvYS88YXN0ZXJpc2s+IgoJICogYW5kIHN0YXJ0X3JlZiBiZWdpbnMgd2l0aCAicmVmcy9iYXovYm9hLyI7IHRoZSBuYW1lIGF0IHRoZQoJICogcmVtb3RlIGlzIHJlZnMvZm9vL2Jhci8gd2l0aCB0aGUgcmVtYWluaW5nIHBhcnQgb2YgdGhlCgkgKiBzdGFydF9yZWYuICBUaGUgbGVuZ3RoIG9mIHRoZSBwcmVmaXggb24gdGhlIFJIUyBpcyAoZW5kIC0KCSAqIGNvbG9uIC0gMiksIGluY2x1ZGluZyB0aGUgc2xhc2ggaW1tZWRpYXRlbHkgYmVmb3JlIHRoZQoJICogYXN0ZXJpc2suCgkgKi8KCWlmICgoc3RybGVuKHN0YXJ0X3JlZikgPCBlbmQgLSBjb2xvbiAtIDIpIHx8CgkgICAgbWVtY21wKHN0YXJ0X3JlZiwgY29sb24gKyAxLCBlbmQgLSBjb2xvbiAtIDIpKQoJCXJldHVybiAwOyAvKiBkb2VzIG5vdCBtYXRjaCBwcmVmaXggKi8KCgkvKiBSZXBsYWNlIHRoZSBhc3RlcmlzayB3aXRoIHRoZSByZW1vdGUgYnJhbmNoIG5hbWUuICAqLwoJbmZhc3ByaW50ZigmY29uZmlnX3JlcG8sICIlLipzJXMiLAoJCSAgIChjb2xvbiAtIDEpIC0gdmFsdWUsIHZhbHVlLAoJCSAgIHN0YXJ0X3JlZiArIChlbmQgLSBjb2xvbiAtIDIpKTsKCXJldHVybiAxOwp9CgpzdGF0aWMgaW50IGdldF9yZW1vdGVfY29uZmlnKGNvbnN0IGNoYXIgKmtleSwgY29uc3QgY2hhciAqdmFsdWUpCnsKCWNvbnN0IGNoYXIgKnZhcjsKCWlmIChwcmVmaXhjbXAoa2V5LCAicmVtb3RlLiIpKQoJCXJldHVybiAwOwoKCXZhciA9IHN0cnJjaHIoa2V5LCAnLicpOwoJaWYgKHZhciA9PSBrZXkgKyA2IHx8IHN0cmNtcCh2YXIsICIuZmV0Y2giKSkKCQlyZXR1cm4gMDsKCS8qCgkgKiBPaywgd2UgYXJlIGxvb2tpbmcgYXQga2V5ID09ICJyZW1vdGUuJGZvby5mZXRjaCI7CgkgKi8KCWlmIChnZXRfcmVtb3RlX2JyYW5jaF9uYW1lKHZhbHVlKSkKCQluZmFzcHJpbnRmKCZjb25maWdfcmVtb3RlLCAiJS4qcyIsIHZhciAtIChrZXkgKyA3KSwga2V5ICsgNyk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHNldF9icmFuY2hfbWVyZ2UoY29uc3QgY2hhciAqbmFtZSwgY29uc3QgY2hhciAqY29uZmlnX3JlbW90ZSwKCQkJICAgICBjb25zdCBjaGFyICpjb25maWdfcmVwbykKewoJY2hhciBrZXlbMTAyNF07CglpZiAoc2l6ZW9mKGtleSkgPD0KCSAgICBzbnByaW50ZihrZXksIHNpemVvZihrZXkpLCAiYnJhbmNoLiVzLnJlbW90ZSIsIG5hbWUpKQoJCWRpZSgid2hhdCBhIGxvbmcgYnJhbmNoIG5hbWUgeW91IGhhdmUhIik7CglnaXRfY29uZmlnX3NldChrZXksIGNvbmZpZ19yZW1vdGUpOwoKCS8qCgkgKiBXZSBkbyBub3QgaGF2ZSB0byBjaGVjayBpZiB3ZSBoYXZlIGVub3VnaCBzcGFjZSBmb3IKCSAqIHRoZSAnbWVyZ2UnIGtleSwgc2luY2UgaXQncyBzaG9ydGVyIHRoYW4gdGhlCgkgKiBwcmV2aW91cyAncmVtb3RlJyBrZXksIHdoaWNoIHdlIGFscmVhZHkgY2hlY2tlZC4KCSAqLwoJc25wcmludGYoa2V5LCBzaXplb2Yoa2V5KSwgImJyYW5jaC4lcy5tZXJnZSIsIG5hbWUpOwoJZ2l0X2NvbmZpZ19zZXQoa2V5LCBjb25maWdfcmVwbyk7Cn0KCnN0YXRpYyB2b2lkIHNldF9icmFuY2hfZGVmYXVsdHMoY29uc3QgY2hhciAqbmFtZSwgY29uc3QgY2hhciAqcmVhbF9yZWYpCnsKCS8qCgkgKiBuYW1lIGlzIHRoZSBuYW1lIG9mIG5ldyBicmFuY2ggdW5kZXIgcmVmcy9oZWFkczsKCSAqIHJlYWxfcmVmIGlzIHR5cGljYWxseSByZWZzL3JlbW90ZXMvJGZvby8kYmFyLCB3aGVyZQoJICogJGZvbyBpcyB0aGUgcmVtb3RlIG5hbWUgKHRoZXJlIHR5cGljYWxseSBhcmUgbm8gc2xhc2hlcykKCSAqIGFuZCAkYmFyIGlzIHRoZSBicmFuY2ggbmFtZSB3ZSBtYXAgZnJvbSB0aGUgcmVtb3RlCgkgKiAoaXQgY291bGQgaGF2ZSBzbGFzaGVzKS4KCSAqLwoJc3RhcnRfcmVmID0gcmVhbF9yZWY7CglnaXRfY29uZmlnKGdldF9yZW1vdGVfY29uZmlnKTsKCWlmICghY29uZmlnX3JlcG8gJiYgIWNvbmZpZ19yZW1vdGUgJiYKCSAgICAhcHJlZml4Y21wKHJlYWxfcmVmLCAicmVmcy9oZWFkcy8iKSkgewoJCXNldF9icmFuY2hfbWVyZ2UobmFtZSwgIi4iLCByZWFsX3JlZik7CgkJcHJpbnRmKCJCcmFuY2ggJXMgc2V0IHVwIHRvIHRyYWNrIGxvY2FsIGJyYW5jaCAlcy5cbiIsCgkJICAgICAgIG5hbWUsIHJlYWxfcmVmKTsKCX0KCglpZiAoY29uZmlnX3JlcG8gJiYgY29uZmlnX3JlbW90ZSkgewoJCXNldF9icmFuY2hfbWVyZ2UobmFtZSwgY29uZmlnX3JlbW90ZSwgY29uZmlnX3JlcG8pOwoJCXByaW50ZigiQnJhbmNoICVzIHNldCB1cCB0byB0cmFjayByZW1vdGUgYnJhbmNoICVzLlxuIiwKCQkgICAgICAgbmFtZSwgcmVhbF9yZWYpOwoJfQoKCWlmIChjb25maWdfcmVwbykKCQlmcmVlKGNvbmZpZ19yZXBvKTsKCWlmIChjb25maWdfcmVtb3RlKQoJCWZyZWUoY29uZmlnX3JlbW90ZSk7Cn0KCnN0YXRpYyB2b2lkIGNyZWF0ZV9icmFuY2goY29uc3QgY2hhciAqbmFtZSwgY29uc3QgY2hhciAqc3RhcnRfbmFtZSwKCQkJICBpbnQgZm9yY2UsIGludCByZWZsb2csIGludCB0cmFjaykKewoJc3RydWN0IHJlZl9sb2NrICpsb2NrOwoJc3RydWN0IGNvbW1pdCAqY29tbWl0OwoJdW5zaWduZWQgY2hhciBzaGExWzIwXTsKCWNoYXIgKnJlYWxfcmVmLCByZWZbUEFUSF9NQVhdLCBtc2dbUEFUSF9NQVggKyAyMF07CglpbnQgZm9yY2luZyA9IDA7CgoJc25wcmludGYocmVmLCBzaXplb2YgcmVmLCAicmVmcy9oZWFkcy8lcyIsIG5hbWUpOwoJaWYgKGNoZWNrX3JlZl9mb3JtYXQocmVmKSkKCQlkaWUoIiclcycgaXMgbm90IGEgdmFsaWQgYnJhbmNoIG5hbWUuIiwgbmFtZSk7CgoJaWYgKHJlc29sdmVfcmVmKHJlZiwgc2hhMSwgMSwgTlVMTCkpIHsKCQlpZiAoIWZvcmNlKQoJCQlkaWUoIkEgYnJhbmNoIG5hbWVkICclcycgYWxyZWFkeSBleGlzdHMuIiwgbmFtZSk7CgkJZWxzZSBpZiAoIWlzX2JhcmVfcmVwb3NpdG9yeSgpICYmICFzdHJjbXAoaGVhZCwgbmFtZSkpCgkJCWRpZSgiQ2Fubm90IGZvcmNlIHVwZGF0ZSB0aGUgY3VycmVudCBicmFuY2guIik7CgkJZm9yY2luZyA9IDE7Cgl9CgoJcmVhbF9yZWYgPSBOVUxMOwoJaWYgKGdldF9zaGExKHN0YXJ0X25hbWUsIHNoYTEpKQoJCWRpZSgiTm90IGEgdmFsaWQgb2JqZWN0IG5hbWU6ICclcycuIiwgc3RhcnRfbmFtZSk7CgoJc3dpdGNoIChkd2ltX3JlZihzdGFydF9uYW1lLCBzdHJsZW4oc3RhcnRfbmFtZSksIHNoYTEsICZyZWFsX3JlZikpIHsKCWNhc2UgMDoKCQkvKiBOb3QgYnJhbmNoaW5nIGZyb20gYW55IGV4aXN0aW5nIGJyYW5jaCAqLwoJCXJlYWxfcmVmID0gTlVMTDsKCQlicmVhazsKCWNhc2UgMToKCQkvKiBVbmlxdWUgY29tcGxldGlvbiAtLSBnb29kICovCgkJYnJlYWs7CglkZWZhdWx0OgoJCWRpZSgiQW1iaWd1b3VzIG9iamVjdCBuYW1lOiAnJXMnLiIsIHN0YXJ0X25hbWUpOwoJCWJyZWFrOwoJfQoKCWlmICgoY29tbWl0ID0gbG9va3VwX2NvbW1pdF9yZWZlcmVuY2Uoc2hhMSkpID09IE5VTEwpCgkJZGllKCJOb3QgYSB2YWxpZCBicmFuY2ggcG9pbnQ6ICclcycuIiwgc3RhcnRfbmFtZSk7CgloYXNoY3B5KHNoYTEsIGNvbW1pdC0+b2JqZWN0LnNoYTEpOwoKCWxvY2sgPSBsb2NrX2FueV9yZWZfZm9yX3VwZGF0ZShyZWYsIE5VTEwpOwoJaWYgKCFsb2NrKQoJCWRpZSgiRmFpbGVkIHRvIGxvY2sgcmVmIGZvciB1cGRhdGU6ICVzLiIsIHN0cmVycm9yKGVycm5vKSk7CgoJaWYgKHJlZmxvZykKCQlsb2dfYWxsX3JlZl91cGRhdGVzID0gMTsKCglpZiAoZm9yY2luZykKCQlzbnByaW50Zihtc2csIHNpemVvZiBtc2csICJicmFuY2g6IFJlc2V0IGZyb20gJXMiLAoJCQkgc3RhcnRfbmFtZSk7CgllbHNlCgkJc25wcmludGYobXNnLCBzaXplb2YgbXNnLCAiYnJhbmNoOiBDcmVhdGVkIGZyb20gJXMiLAoJCQkgc3RhcnRfbmFtZSk7CgoJLyogV2hlbiBicmFuY2hpbmcgb2ZmIGEgcmVtb3RlIGJyYW5jaCwgc2V0IHVwIHNvIHRoYXQgZ2l0LXB1bGwKCSAgIGF1dG9tYXRpY2FsbHkgbWVyZ2VzIGZyb20gdGhlcmUuICBTbyBmYXIsIHRoaXMgaXMgb25seSBkb25lIGZvcgoJICAgcmVtb3RlcyByZWdpc3RlcmVkIHZpYSAuZ2l0L2NvbmZpZy4gICovCglpZiAocmVhbF9yZWYgJiYgdHJhY2spCgkJc2V0X2JyYW5jaF9kZWZhdWx0cyhuYW1lLCByZWFsX3JlZik7CgoJaWYgKHdyaXRlX3JlZl9zaGExKGxvY2ssIHNoYTEsIG1zZykgPCAwKQoJCWRpZSgiRmFpbGVkIHRvIHdyaXRlIHJlZjogJXMuIiwgc3RyZXJyb3IoZXJybm8pKTsKCglpZiAocmVhbF9yZWYpCgkJZnJlZShyZWFsX3JlZik7Cn0KCnN0YXRpYyB2b2lkIHJlbmFtZV9icmFuY2goY29uc3QgY2hhciAqb2xkbmFtZSwgY29uc3QgY2hhciAqbmV3bmFtZSwgaW50IGZvcmNlKQp7CgljaGFyIG9sZHJlZltQQVRIX01BWF0sIG5ld3JlZltQQVRIX01BWF0sIGxvZ21zZ1tQQVRIX01BWCoyICsgMTAwXTsKCXVuc2lnbmVkIGNoYXIgc2hhMVsyMF07CgljaGFyIG9sZHNlY3Rpb25bUEFUSF9NQVhdLCBuZXdzZWN0aW9uW1BBVEhfTUFYXTsKCglpZiAoIW9sZG5hbWUpCgkJZGllKCJjYW5ub3QgcmVuYW1lIHRoZSBjdXJyZW50IGJyYW5jaCB3aGlsZSBub3Qgb24gYW55LiIpOwoKCWlmIChzbnByaW50ZihvbGRyZWYsIHNpemVvZihvbGRyZWYpLCAicmVmcy9oZWFkcy8lcyIsIG9sZG5hbWUpID4gc2l6ZW9mKG9sZHJlZikpCgkJZGllKCJPbGQgYnJhbmNobmFtZSB0b28gbG9uZyIpOwoKCWlmIChjaGVja19yZWZfZm9ybWF0KG9sZHJlZikpCgkJZGllKCJJbnZhbGlkIGJyYW5jaCBuYW1lOiAlcyIsIG9sZHJlZik7CgoJaWYgKHNucHJpbnRmKG5ld3JlZiwgc2l6ZW9mKG5ld3JlZiksICJyZWZzL2hlYWRzLyVzIiwgbmV3bmFtZSkgPiBzaXplb2YobmV3cmVmKSkKCQlkaWUoIk5ldyBicmFuY2huYW1lIHRvbyBsb25nIik7CgoJaWYgKGNoZWNrX3JlZl9mb3JtYXQobmV3cmVmKSkKCQlkaWUoIkludmFsaWQgYnJhbmNoIG5hbWU6ICVzIiwgbmV3cmVmKTsKCglpZiAocmVzb2x2ZV9yZWYobmV3cmVmLCBzaGExLCAxLCBOVUxMKSAmJiAhZm9yY2UpCgkJZGllKCJBIGJyYW5jaCBuYW1lZCAnJXMnIGFscmVhZHkgZXhpc3RzLiIsIG5ld25hbWUpOwoKCXNucHJpbnRmKGxvZ21zZywgc2l6ZW9mKGxvZ21zZyksICJCcmFuY2g6IHJlbmFtZWQgJXMgdG8gJXMiLAoJCSBvbGRyZWYsIG5ld3JlZik7CgoJaWYgKHJlbmFtZV9yZWYob2xkcmVmLCBuZXdyZWYsIGxvZ21zZykpCgkJZGllKCJCcmFuY2ggcmVuYW1lIGZhaWxlZCIpOwoKCS8qIG5vIG5lZWQgdG8gcGFzcyBsb2dtc2cgaGVyZSBhcyBIRUFEIGRpZG4ndCByZWFsbHkgbW92ZSAqLwoJaWYgKCFzdHJjbXAob2xkbmFtZSwgaGVhZCkgJiYgY3JlYXRlX3N5bXJlZigiSEVBRCIsIG5ld3JlZiwgTlVMTCkpCgkJZGllKCJCcmFuY2ggcmVuYW1lZCB0byAlcywgYnV0IEhFQUQgaXMgbm90IHVwZGF0ZWQhIiwgbmV3bmFtZSk7CgoJc25wcmludGYob2xkc2VjdGlvbiwgc2l6ZW9mKG9sZHNlY3Rpb24pLCAiYnJhbmNoLiVzIiwgb2xkcmVmICsgMTEpOwoJc25wcmludGYobmV3c2VjdGlvbiwgc2l6ZW9mKG5ld3NlY3Rpb24pLCAiYnJhbmNoLiVzIiwgbmV3cmVmICsgMTEpOwoJaWYgKGdpdF9jb25maWdfcmVuYW1lX3NlY3Rpb24ob2xkc2VjdGlvbiwgbmV3c2VjdGlvbikgPCAwKQoJCWRpZSgiQnJhbmNoIGlzIHJlbmFtZWQsIGJ1dCB1cGRhdGUgb2YgY29uZmlnLWZpbGUgZmFpbGVkIik7Cn0KCmludCBjbWRfYnJhbmNoKGludCBhcmdjLCBjb25zdCBjaGFyICoqYXJndiwgY29uc3QgY2hhciAqcHJlZml4KQp7CglpbnQgZGVsZXRlID0gMCwgZm9yY2VfZGVsZXRlID0gMCwgZm9yY2VfY3JlYXRlID0gMDsKCWludCByZW5hbWUgPSAwLCBmb3JjZV9yZW5hbWUgPSAwOwoJaW50IHZlcmJvc2UgPSAwLCBhYmJyZXYgPSBERUZBVUxUX0FCQlJFViwgZGV0YWNoZWQgPSAwOwoJaW50IHJlZmxvZyA9IDAsIHRyYWNrOwoJaW50IGtpbmRzID0gUkVGX0xPQ0FMX0JSQU5DSDsKCWludCBpOwoKCWdpdF9jb25maWcoZ2l0X2JyYW5jaF9jb25maWcpOwoJdHJhY2sgPSBicmFuY2hfdHJhY2tfcmVtb3RlczsKCglmb3IgKGkgPSAxOyBpIDwgYXJnYzsgaSsrKSB7CgkJY29uc3QgY2hhciAqYXJnID0gYXJndltpXTsKCgkJaWYgKGFyZ1swXSAhPSAnLScpCgkJCWJyZWFrOwoJCWlmICghc3RyY21wKGFyZywgIi0tIikpIHsKCQkJaSsrOwoJCQlicmVhazsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLS10cmFjayIpKSB7CgkJCXRyYWNrID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi0tbm8tdHJhY2siKSkgewoJCQl0cmFjayA9IDA7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItZCIpKSB7CgkJCWRlbGV0ZSA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItRCIpKSB7CgkJCWRlbGV0ZSA9IDE7CgkJCWZvcmNlX2RlbGV0ZSA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItZiIpKSB7CgkJCWZvcmNlX2NyZWF0ZSA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItbSIpKSB7CgkJCXJlbmFtZSA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItTSIpKSB7CgkJCXJlbmFtZSA9IDE7CgkJCWZvcmNlX3JlbmFtZSA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItciIpKSB7CgkJCWtpbmRzID0gUkVGX1JFTU9URV9CUkFOQ0g7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItYSIpKSB7CgkJCWtpbmRzID0gUkVGX1JFTU9URV9CUkFOQ0ggfCBSRUZfTE9DQUxfQlJBTkNIOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLWwiKSkgewoJCQlyZWZsb2cgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFwcmVmaXhjbXAoYXJnLCAiLS1uby1hYmJyZXYiKSkgewoJCQlhYmJyZXYgPSAwOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFwcmVmaXhjbXAoYXJnLCAiLS1hYmJyZXY9IikpIHsKCQkJYWJicmV2ID0gc3RydG91bChhcmcgKyA5LCBOVUxMLCAxMCk7CgkJCWlmIChhYmJyZXYgPCBNSU5JTVVNX0FCQlJFVikKCQkJCWFiYnJldiA9IE1JTklNVU1fQUJCUkVWOwoJCQllbHNlIGlmIChhYmJyZXYgPiA0MCkKCQkJCWFiYnJldiA9IDQwOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLXYiKSkgewoJCQl2ZXJib3NlID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi0tY29sb3IiKSkgewoJCQlicmFuY2hfdXNlX2NvbG9yID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi0tbm8tY29sb3IiKSkgewoJCQlicmFuY2hfdXNlX2NvbG9yID0gMDsKCQkJY29udGludWU7CgkJfQoJCXVzYWdlKGJ1aWx0aW5fYnJhbmNoX3VzYWdlKTsKCX0KCglpZiAoKGRlbGV0ZSAmJiByZW5hbWUpIHx8IChkZWxldGUgJiYgZm9yY2VfY3JlYXRlKSB8fAoJICAgIChyZW5hbWUgJiYgZm9yY2VfY3JlYXRlKSkKCQl1c2FnZShidWlsdGluX2JyYW5jaF91c2FnZSk7CgoJaGVhZCA9IHJlc29sdmVfcmVmKCJIRUFEIiwgaGVhZF9zaGExLCAwLCBOVUxMKTsKCWlmICghaGVhZCkKCQlkaWUoIkZhaWxlZCB0byByZXNvbHZlIEhFQUQgYXMgYSB2YWxpZCByZWYuIik7CgloZWFkID0geHN0cmR1cChoZWFkKTsKCWlmICghc3RyY21wKGhlYWQsICJIRUFEIikpIHsKCQlkZXRhY2hlZCA9IDE7Cgl9CgllbHNlIHsKCQlpZiAocHJlZml4Y21wKGhlYWQsICJyZWZzL2hlYWRzLyIpKQoJCQlkaWUoIkhFQUQgbm90IGZvdW5kIGJlbG93IHJlZnMvaGVhZHMhIik7CgkJaGVhZCArPSAxMTsKCX0KCglpZiAoZGVsZXRlKQoJCXJldHVybiBkZWxldGVfYnJhbmNoZXMoYXJnYyAtIGksIGFyZ3YgKyBpLCBmb3JjZV9kZWxldGUsIGtpbmRzKTsKCWVsc2UgaWYgKGkgPT0gYXJnYykKCQlwcmludF9yZWZfbGlzdChraW5kcywgZGV0YWNoZWQsIHZlcmJvc2UsIGFiYnJldik7CgllbHNlIGlmIChyZW5hbWUgJiYgKGkgPT0gYXJnYyAtIDEpKQoJCXJlbmFtZV9icmFuY2goaGVhZCwgYXJndltpXSwgZm9yY2VfcmVuYW1lKTsKCWVsc2UgaWYgKHJlbmFtZSAmJiAoaSA9PSBhcmdjIC0gMikpCgkJcmVuYW1lX2JyYW5jaChhcmd2W2ldLCBhcmd2W2kgKyAxXSwgZm9yY2VfcmVuYW1lKTsKCWVsc2UgaWYgKGkgPT0gYXJnYyAtIDEgfHwgaSA9PSBhcmdjIC0gMikKCQljcmVhdGVfYnJhbmNoKGFyZ3ZbaV0sIChpID09IGFyZ2MgLSAyKSA/IGFyZ3ZbaSsxXSA6IGhlYWQsCgkJCSAgICAgIGZvcmNlX2NyZWF0ZSwgcmVmbG9nLCB0cmFjayk7CgllbHNlCgkJdXNhZ2UoYnVpbHRpbl9icmFuY2hfdXNhZ2UpOwoKCXJldHVybiAwOwp9Cg==