LyoKICogQnVpbHRpbiAiZ2l0IGJyYW5jaCIKICoKICogQ29weXJpZ2h0IChjKSAyMDA2IEtyaXN0aWFuIEj4Z3NiZXJnIDxrcmhAcmVkaGF0LmNvbT4KICogQmFzZWQgb24gZ2l0LWJyYW5jaC5zaCBieSBKdW5pbyBDIEhhbWFuby4KICovCgojaW5jbHVkZSAiY2FjaGUuaCIKI2luY2x1ZGUgImNvbG9yLmgiCiNpbmNsdWRlICJyZWZzLmgiCiNpbmNsdWRlICJjb21taXQuaCIKI2luY2x1ZGUgImJ1aWx0aW4uaCIKCnN0YXRpYyBjb25zdCBjaGFyIGJ1aWx0aW5fYnJhbmNoX3VzYWdlW10gPQogICJnaXQtYnJhbmNoIFstcl0gKC1kIHwgLUQpIDxicmFuY2huYW1lPiB8IFstLXRyYWNrIHwgLS1uby10cmFja10gWy1sXSBbLWZdIDxicmFuY2huYW1lPiBbPHN0YXJ0LXBvaW50Pl0gfCAoLW0gfCAtTSkgWzxvbGRicmFuY2g+XSA8bmV3YnJhbmNoPiB8IFstLWNvbG9yIHwgLS1uby1jb2xvcl0gWy1yIHwgLWFdIFstdiBbLS1hYmJyZXY9PGxlbmd0aD4gfCAtLW5vLWFiYnJldl1dIjsKCiNkZWZpbmUgUkVGX1VOS05PV05fVFlQRSAgICAweDAwCiNkZWZpbmUgUkVGX0xPQ0FMX0JSQU5DSCAgICAweDAxCiNkZWZpbmUgUkVGX1JFTU9URV9CUkFOQ0ggICAweDAyCiNkZWZpbmUgUkVGX1RBRyAgICAgICAgICAgICAweDA0CgpzdGF0aWMgY29uc3QgY2hhciAqaGVhZDsKc3RhdGljIHVuc2lnbmVkIGNoYXIgaGVhZF9zaGExWzIwXTsKCnN0YXRpYyBpbnQgYnJhbmNoX3RyYWNrX3JlbW90ZXM7CgpzdGF0aWMgaW50IGJyYW5jaF91c2VfY29sb3I7CnN0YXRpYyBjaGFyIGJyYW5jaF9jb2xvcnNbXVtDT0xPUl9NQVhMRU5dID0gewoJIlwwMzNbbSIsCS8qIHJlc2V0ICovCgkiIiwJCS8qIFBMQUlOIChub3JtYWwpICovCgkiXDAzM1szMW0iLAkvKiBSRU1PVEUgKHJlZCkgKi8KCSIiLAkJLyogTE9DQUwgKG5vcm1hbCkgKi8KCSJcMDMzWzMybSIsCS8qIENVUlJFTlQgKGdyZWVuKSAqLwp9OwplbnVtIGNvbG9yX2JyYW5jaCB7CglDT0xPUl9CUkFOQ0hfUkVTRVQgPSAwLAoJQ09MT1JfQlJBTkNIX1BMQUlOID0gMSwKCUNPTE9SX0JSQU5DSF9SRU1PVEUgPSAyLAoJQ09MT1JfQlJBTkNIX0xPQ0FMID0gMywKCUNPTE9SX0JSQU5DSF9DVVJSRU5UID0gNCwKfTsKCnN0YXRpYyBpbnQgcGFyc2VfYnJhbmNoX2NvbG9yX3Nsb3QoY29uc3QgY2hhciAqdmFyLCBpbnQgb2ZzKQp7CglpZiAoIXN0cmNhc2VjbXAodmFyK29mcywgInBsYWluIikpCgkJcmV0dXJuIENPTE9SX0JSQU5DSF9QTEFJTjsKCWlmICghc3RyY2FzZWNtcCh2YXIrb2ZzLCAicmVzZXQiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX1JFU0VUOwoJaWYgKCFzdHJjYXNlY21wKHZhcitvZnMsICJyZW1vdGUiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX1JFTU9URTsKCWlmICghc3RyY2FzZWNtcCh2YXIrb2ZzLCAibG9jYWwiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX0xPQ0FMOwoJaWYgKCFzdHJjYXNlY21wKHZhcitvZnMsICJjdXJyZW50IikpCgkJcmV0dXJuIENPTE9SX0JSQU5DSF9DVVJSRU5UOwoJZGllKCJiYWQgY29uZmlnIHZhcmlhYmxlICclcyciLCB2YXIpOwp9CgppbnQgZ2l0X2JyYW5jaF9jb25maWcoY29uc3QgY2hhciAqdmFyLCBjb25zdCBjaGFyICp2YWx1ZSkKewoJaWYgKCFzdHJjbXAodmFyLCAiY29sb3IuYnJhbmNoIikpIHsKCQlicmFuY2hfdXNlX2NvbG9yID0gZ2l0X2NvbmZpZ19jb2xvcmJvb2wodmFyLCB2YWx1ZSk7CgkJcmV0dXJuIDA7Cgl9CglpZiAoIXByZWZpeGNtcCh2YXIsICJjb2xvci5icmFuY2guIikpIHsKCQlpbnQgc2xvdCA9IHBhcnNlX2JyYW5jaF9jb2xvcl9zbG90KHZhciwgMTMpOwoJCWNvbG9yX3BhcnNlKHZhbHVlLCB2YXIsIGJyYW5jaF9jb2xvcnNbc2xvdF0pOwoJCXJldHVybiAwOwoJfQoJaWYgKCFzdHJjbXAodmFyLCAiYnJhbmNoLmF1dG9zZXR1cG1lcmdlIikpCgkJYnJhbmNoX3RyYWNrX3JlbW90ZXMgPSBnaXRfY29uZmlnX2Jvb2wodmFyLCB2YWx1ZSk7CgoJcmV0dXJuIGdpdF9kZWZhdWx0X2NvbmZpZyh2YXIsIHZhbHVlKTsKfQoKY29uc3QgY2hhciAqYnJhbmNoX2dldF9jb2xvcihlbnVtIGNvbG9yX2JyYW5jaCBpeCkKewoJaWYgKGJyYW5jaF91c2VfY29sb3IpCgkJcmV0dXJuIGJyYW5jaF9jb2xvcnNbaXhdOwoJcmV0dXJuICIiOwp9CgpzdGF0aWMgaW50IGRlbGV0ZV9icmFuY2hlcyhpbnQgYXJnYywgY29uc3QgY2hhciAqKmFyZ3YsIGludCBmb3JjZSwgaW50IGtpbmRzKQp7CglzdHJ1Y3QgY29tbWl0ICpyZXYsICpoZWFkX3JldiA9IGhlYWRfcmV2OwoJdW5zaWduZWQgY2hhciBzaGExWzIwXTsKCWNoYXIgKm5hbWUgPSBOVUxMOwoJY29uc3QgY2hhciAqZm10LCAqcmVtb3RlOwoJaW50IGk7CglpbnQgcmV0ID0gMDsKCglzd2l0Y2ggKGtpbmRzKSB7CgljYXNlIFJFRl9SRU1PVEVfQlJBTkNIOgoJCWZtdCA9ICJyZWZzL3JlbW90ZXMvJXMiOwoJCXJlbW90ZSA9ICJyZW1vdGUgIjsKCQlmb3JjZSA9IDE7CgkJYnJlYWs7CgljYXNlIFJFRl9MT0NBTF9CUkFOQ0g6CgkJZm10ID0gInJlZnMvaGVhZHMvJXMiOwoJCXJlbW90ZSA9ICIiOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlkaWUoImNhbm5vdCB1c2UgLWEgd2l0aCAtZCIpOwoJfQoKCWlmICghZm9yY2UpIHsKCQloZWFkX3JldiA9IGxvb2t1cF9jb21taXRfcmVmZXJlbmNlKGhlYWRfc2hhMSk7CgkJaWYgKCFoZWFkX3JldikKCQkJZGllKCJDb3VsZG4ndCBsb29rIHVwIGNvbW1pdCBvYmplY3QgZm9yIEhFQUQiKTsKCX0KCWZvciAoaSA9IDA7IGkgPCBhcmdjOyBpKyspIHsKCQlpZiAoa2luZHMgPT0gUkVGX0xPQ0FMX0JSQU5DSCAmJiAhc3RyY21wKGhlYWQsIGFyZ3ZbaV0pKSB7CgkJCWVycm9yKCJDYW5ub3QgZGVsZXRlIHRoZSBicmFuY2ggJyVzJyAiCgkJCQkid2hpY2ggeW91IGFyZSBjdXJyZW50bHkgb24uIiwgYXJndltpXSk7CgkJCXJldCA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCgkJaWYgKG5hbWUpCgkJCWZyZWUobmFtZSk7CgoJCW5hbWUgPSB4c3RyZHVwKG1rcGF0aChmbXQsIGFyZ3ZbaV0pKTsKCQlpZiAoIXJlc29sdmVfcmVmKG5hbWUsIHNoYTEsIDEsIE5VTEwpKSB7CgkJCWVycm9yKCIlc2JyYW5jaCAnJXMnIG5vdCBmb3VuZC4iLAoJCQkJCXJlbW90ZSwgYXJndltpXSk7CgkJCXJldCA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCgkJcmV2ID0gbG9va3VwX2NvbW1pdF9yZWZlcmVuY2Uoc2hhMSk7CgkJaWYgKCFyZXYpIHsKCQkJZXJyb3IoIkNvdWxkbid0IGxvb2sgdXAgY29tbWl0IG9iamVjdCBmb3IgJyVzJyIsIG5hbWUpOwoJCQlyZXQgPSAxOwoJCQljb250aW51ZTsKCQl9CgoJCS8qIFRoaXMgY2hlY2tzIHdoZXRoZXIgdGhlIG1lcmdlIGJhc2VzIG9mIGJyYW5jaCBhbmQKCQkgKiBIRUFEIGNvbnRhaW5zIGJyYW5jaCAtLSB3aGljaCBtZWFucyB0aGF0IHRoZSBIRUFECgkJICogY29udGFpbnMgZXZlcnl0aGluZyBpbiBib3RoLgoJCSAqLwoKCQlpZiAoIWZvcmNlICYmCgkJICAgICFpbl9tZXJnZV9iYXNlcyhyZXYsICZoZWFkX3JldiwgMSkpIHsKCQkJZXJyb3IoIlRoZSBicmFuY2ggJyVzJyBpcyBub3QgYSBzdHJpY3Qgc3Vic2V0IG9mICIKCQkJCSJ5b3VyIGN1cnJlbnQgSEVBRC5cbiIKCQkJCSJJZiB5b3UgYXJlIHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIGl0LCAiCgkJCQkicnVuICdnaXQgYnJhbmNoIC1EICVzJy4iLCBhcmd2W2ldLCBhcmd2W2ldKTsKCQkJcmV0ID0gMTsKCQkJY29udGludWU7CgkJfQoKCQlpZiAoZGVsZXRlX3JlZihuYW1lLCBzaGExKSkgewoJCQllcnJvcigiRXJyb3IgZGVsZXRpbmcgJXNicmFuY2ggJyVzJyIsIHJlbW90ZSwKCQkJICAgICAgIGFyZ3ZbaV0pOwoJCQlyZXQgPSAxOwoJCX0gZWxzZQoJCQlwcmludGYoIkRlbGV0ZWQgJXNicmFuY2ggJXMuXG4iLCByZW1vdGUsIGFyZ3ZbaV0pOwoKCX0KCglpZiAobmFtZSkKCQlmcmVlKG5hbWUpOwoKCXJldHVybihyZXQpOwp9CgpzdHJ1Y3QgcmVmX2l0ZW0gewoJY2hhciAqbmFtZTsKCXVuc2lnbmVkIGludCBraW5kOwoJdW5zaWduZWQgY2hhciBzaGExWzIwXTsKfTsKCnN0cnVjdCByZWZfbGlzdCB7CglpbnQgaW5kZXgsIGFsbG9jLCBtYXh3aWR0aDsKCXN0cnVjdCByZWZfaXRlbSAqbGlzdDsKCWludCBraW5kczsKfTsKCnN0YXRpYyBpbnQgYXBwZW5kX3JlZihjb25zdCBjaGFyICpyZWZuYW1lLCBjb25zdCB1bnNpZ25lZCBjaGFyICpzaGExLCBpbnQgZmxhZ3MsIHZvaWQgKmNiX2RhdGEpCnsKCXN0cnVjdCByZWZfbGlzdCAqcmVmX2xpc3QgPSAoc3RydWN0IHJlZl9saXN0KikoY2JfZGF0YSk7CglzdHJ1Y3QgcmVmX2l0ZW0gKm5ld2l0ZW07CglpbnQga2luZCA9IFJFRl9VTktOT1dOX1RZUEU7CglpbnQgbGVuOwoKCS8qIERldGVjdCBraW5kICovCglpZiAoIXByZWZpeGNtcChyZWZuYW1lLCAicmVmcy9oZWFkcy8iKSkgewoJCWtpbmQgPSBSRUZfTE9DQUxfQlJBTkNIOwoJCXJlZm5hbWUgKz0gMTE7Cgl9IGVsc2UgaWYgKCFwcmVmaXhjbXAocmVmbmFtZSwgInJlZnMvcmVtb3Rlcy8iKSkgewoJCWtpbmQgPSBSRUZfUkVNT1RFX0JSQU5DSDsKCQlyZWZuYW1lICs9IDEzOwoJfSBlbHNlIGlmICghcHJlZml4Y21wKHJlZm5hbWUsICJyZWZzL3RhZ3MvIikpIHsKCQlraW5kID0gUkVGX1RBRzsKCQlyZWZuYW1lICs9IDEwOwoJfQoKCS8qIERvbid0IGFkZCB0eXBlcyB0aGUgY2FsbGVyIGRvZXNuJ3Qgd2FudCAqLwoJaWYgKChraW5kICYgcmVmX2xpc3QtPmtpbmRzKSA9PSAwKQoJCXJldHVybiAwOwoKCS8qIFJlc2l6ZSBidWZmZXIgKi8KCWlmIChyZWZfbGlzdC0+aW5kZXggPj0gcmVmX2xpc3QtPmFsbG9jKSB7CgkJcmVmX2xpc3QtPmFsbG9jID0gYWxsb2NfbnIocmVmX2xpc3QtPmFsbG9jKTsKCQlyZWZfbGlzdC0+bGlzdCA9IHhyZWFsbG9jKHJlZl9saXN0LT5saXN0LAoJCQkJcmVmX2xpc3QtPmFsbG9jICogc2l6ZW9mKHN0cnVjdCByZWZfaXRlbSkpOwoJfQoKCS8qIFJlY29yZCB0aGUgbmV3IGl0ZW0gKi8KCW5ld2l0ZW0gPSAmKHJlZl9saXN0LT5saXN0W3JlZl9saXN0LT5pbmRleCsrXSk7CgluZXdpdGVtLT5uYW1lID0geHN0cmR1cChyZWZuYW1lKTsKCW5ld2l0ZW0tPmtpbmQgPSBraW5kOwoJaGFzaGNweShuZXdpdGVtLT5zaGExLCBzaGExKTsKCWxlbiA9IHN0cmxlbihuZXdpdGVtLT5uYW1lKTsKCWlmIChsZW4gPiByZWZfbGlzdC0+bWF4d2lkdGgpCgkJcmVmX2xpc3QtPm1heHdpZHRoID0gbGVuOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBmcmVlX3JlZl9saXN0KHN0cnVjdCByZWZfbGlzdCAqcmVmX2xpc3QpCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCByZWZfbGlzdC0+aW5kZXg7IGkrKykKCQlmcmVlKHJlZl9saXN0LT5saXN0W2ldLm5hbWUpOwoJZnJlZShyZWZfbGlzdC0+bGlzdCk7Cn0KCnN0YXRpYyBpbnQgcmVmX2NtcChjb25zdCB2b2lkICpyMSwgY29uc3Qgdm9pZCAqcjIpCnsKCXN0cnVjdCByZWZfaXRlbSAqYzEgPSAoc3RydWN0IHJlZl9pdGVtICopKHIxKTsKCXN0cnVjdCByZWZfaXRlbSAqYzIgPSAoc3RydWN0IHJlZl9pdGVtICopKHIyKTsKCglpZiAoYzEtPmtpbmQgIT0gYzItPmtpbmQpCgkJcmV0dXJuIGMxLT5raW5kIC0gYzItPmtpbmQ7CglyZXR1cm4gc3RyY21wKGMxLT5uYW1lLCBjMi0+bmFtZSk7Cn0KCnN0YXRpYyB2b2lkIHByaW50X3JlZl9pdGVtKHN0cnVjdCByZWZfaXRlbSAqaXRlbSwgaW50IG1heHdpZHRoLCBpbnQgdmVyYm9zZSwKCQkJICAgaW50IGFiYnJldiwgaW50IGN1cnJlbnQpCnsKCWNoYXIgYzsKCWludCBjb2xvcjsKCXN0cnVjdCBjb21taXQgKmNvbW1pdDsKCWNoYXIgc3ViamVjdFsyNTZdOwoKCXN3aXRjaCAoaXRlbS0+a2luZCkgewoJY2FzZSBSRUZfTE9DQUxfQlJBTkNIOgoJCWNvbG9yID0gQ09MT1JfQlJBTkNIX0xPQ0FMOwoJCWJyZWFrOwoJY2FzZSBSRUZfUkVNT1RFX0JSQU5DSDoKCQljb2xvciA9IENPTE9SX0JSQU5DSF9SRU1PVEU7CgkJYnJlYWs7CglkZWZhdWx0OgoJCWNvbG9yID0gQ09MT1JfQlJBTkNIX1BMQUlOOwoJCWJyZWFrOwoJfQoKCWMgPSAnICc7CglpZiAoY3VycmVudCkgewoJCWMgPSAnKic7CgkJY29sb3IgPSBDT0xPUl9CUkFOQ0hfQ1VSUkVOVDsKCX0KCglpZiAodmVyYm9zZSkgewoJCWNvbW1pdCA9IGxvb2t1cF9jb21taXQoaXRlbS0+c2hhMSk7CgkJaWYgKGNvbW1pdCAmJiAhcGFyc2VfY29tbWl0KGNvbW1pdCkpCgkJCXByZXR0eV9wcmludF9jb21taXQoQ01JVF9GTVRfT05FTElORSwgY29tbWl0LCB+MCwKCQkJCQkgICAgc3ViamVjdCwgc2l6ZW9mKHN1YmplY3QpLCAwLAoJCQkJCSAgICBOVUxMLCBOVUxMLCAwKTsKCQllbHNlCgkJCXN0cmNweShzdWJqZWN0LCAiICoqKiogaW52YWxpZCByZWYgKioqKiIpOwoJCXByaW50ZigiJWMgJXMlLSpzJXMgJXMgJXNcbiIsIGMsIGJyYW5jaF9nZXRfY29sb3IoY29sb3IpLAoJCSAgICAgICBtYXh3aWR0aCwgaXRlbS0+bmFtZSwKCQkgICAgICAgYnJhbmNoX2dldF9jb2xvcihDT0xPUl9CUkFOQ0hfUkVTRVQpLAoJCSAgICAgICBmaW5kX3VuaXF1ZV9hYmJyZXYoaXRlbS0+c2hhMSwgYWJicmV2KSwgc3ViamVjdCk7Cgl9IGVsc2UgewoJCXByaW50ZigiJWMgJXMlcyVzXG4iLCBjLCBicmFuY2hfZ2V0X2NvbG9yKGNvbG9yKSwgaXRlbS0+bmFtZSwKCQkgICAgICAgYnJhbmNoX2dldF9jb2xvcihDT0xPUl9CUkFOQ0hfUkVTRVQpKTsKCX0KfQoKc3RhdGljIHZvaWQgcHJpbnRfcmVmX2xpc3QoaW50IGtpbmRzLCBpbnQgZGV0YWNoZWQsIGludCB2ZXJib3NlLCBpbnQgYWJicmV2KQp7CglpbnQgaTsKCXN0cnVjdCByZWZfbGlzdCByZWZfbGlzdDsKCgltZW1zZXQoJnJlZl9saXN0LCAwLCBzaXplb2YocmVmX2xpc3QpKTsKCXJlZl9saXN0LmtpbmRzID0ga2luZHM7Cglmb3JfZWFjaF9yZWYoYXBwZW5kX3JlZiwgJnJlZl9saXN0KTsKCglxc29ydChyZWZfbGlzdC5saXN0LCByZWZfbGlzdC5pbmRleCwgc2l6ZW9mKHN0cnVjdCByZWZfaXRlbSksIHJlZl9jbXApOwoKCWRldGFjaGVkID0gKGRldGFjaGVkICYmIChraW5kcyAmIFJFRl9MT0NBTF9CUkFOQ0gpKTsKCWlmIChkZXRhY2hlZCkgewoJCXN0cnVjdCByZWZfaXRlbSBpdGVtOwoJCWl0ZW0ubmFtZSA9IHhzdHJkdXAoIihubyBicmFuY2gpIik7CgkJaXRlbS5raW5kID0gUkVGX0xPQ0FMX0JSQU5DSDsKCQloYXNoY3B5KGl0ZW0uc2hhMSwgaGVhZF9zaGExKTsKCQlpZiAoc3RybGVuKGl0ZW0ubmFtZSkgPiByZWZfbGlzdC5tYXh3aWR0aCkKCQkJICAgICAgcmVmX2xpc3QubWF4d2lkdGggPSBzdHJsZW4oaXRlbS5uYW1lKTsKCQlwcmludF9yZWZfaXRlbSgmaXRlbSwgcmVmX2xpc3QubWF4d2lkdGgsIHZlcmJvc2UsIGFiYnJldiwgMSk7CgkJZnJlZShpdGVtLm5hbWUpOwoJfQoKCWZvciAoaSA9IDA7IGkgPCByZWZfbGlzdC5pbmRleDsgaSsrKSB7CgkJaW50IGN1cnJlbnQgPSAhZGV0YWNoZWQgJiYKCQkJKHJlZl9saXN0Lmxpc3RbaV0ua2luZCA9PSBSRUZfTE9DQUxfQlJBTkNIKSAmJgoJCQkhc3RyY21wKHJlZl9saXN0Lmxpc3RbaV0ubmFtZSwgaGVhZCk7CgkJcHJpbnRfcmVmX2l0ZW0oJnJlZl9saXN0Lmxpc3RbaV0sIHJlZl9saXN0Lm1heHdpZHRoLCB2ZXJib3NlLAoJCQkgICAgICAgYWJicmV2LCBjdXJyZW50KTsKCX0KCglmcmVlX3JlZl9saXN0KCZyZWZfbGlzdCk7Cn0KCnN0YXRpYyBjaGFyICpjb25maWdfcmVwbzsKc3RhdGljIGNoYXIgKmNvbmZpZ19yZW1vdGU7CnN0YXRpYyBjb25zdCBjaGFyICpzdGFydF9yZWY7CnN0YXRpYyBpbnQgc3RhcnRfbGVuOwpzdGF0aWMgaW50IGJhc2VfbGVuOwoKc3RhdGljIGludCBnZXRfcmVtb3RlX2JyYW5jaF9uYW1lKGNvbnN0IGNoYXIgKnZhbHVlKQp7Cgljb25zdCBjaGFyICpjb2xvbjsKCWNvbnN0IGNoYXIgKmVuZDsKCglpZiAoKnZhbHVlID09ICcrJykKCQl2YWx1ZSsrOwoKCWNvbG9uID0gc3RyY2hyKHZhbHVlLCAnOicpOwoJaWYgKCFjb2xvbikKCQlyZXR1cm4gMDsKCgllbmQgPSB2YWx1ZSArIHN0cmxlbih2YWx1ZSk7CgoJLyogVHJ5IGFuIGV4YWN0IG1hdGNoIGZpcnN0LiAgKi8KCWlmICghc3RyY21wKGNvbG9uICsgMSwgc3RhcnRfcmVmKSkgewoJCS8qIFRydW5jYXRlIHRoZSB2YWx1ZSBiZWZvcmUgdGhlIGNvbG9uLiAgKi8KCQluZmFzcHJpbnRmKCZjb25maWdfcmVwbywgIiUuKnMiLCBjb2xvbiAtIHZhbHVlLCB2YWx1ZSk7CgkJcmV0dXJuIDE7Cgl9CgoJLyogVHJ5IHdpdGggYSB3aWxkY2FyZCBtYXRjaCBub3cuICAqLwoJaWYgKGVuZCAtIHZhbHVlID4gMiAmJiBlbmRbLTJdID09ICcvJyAmJiBlbmRbLTFdID09ICcqJyAmJgoJICAgIGNvbG9uIC0gdmFsdWUgPiAyICYmIGNvbG9uWy0yXSA9PSAnLycgJiYgY29sb25bLTFdID09ICcqJyAmJgoJICAgIChlbmQgLSAyKSAtIChjb2xvbiArIDEpID09IGJhc2VfbGVuICYmCgkgICAgIXN0cm5jbXAoY29sb24gKyAxLCBzdGFydF9yZWYsIGJhc2VfbGVuKSkgewoJCS8qIFJlcGxhY2UgdGhlIHN0YXIgd2l0aCB0aGUgcmVtb3RlIGJyYW5jaCBuYW1lLiAgKi8KCQluZmFzcHJpbnRmKCZjb25maWdfcmVwbywgIiUuKnMlcyIsCgkJCSAgIChjb2xvbiAtIDIpIC0gdmFsdWUsIHZhbHVlLAoJCQkgICBzdGFydF9yZWYgKyBiYXNlX2xlbik7CgkJcmV0dXJuIDE7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgZ2V0X3JlbW90ZV9jb25maWcoY29uc3QgY2hhciAqa2V5LCBjb25zdCBjaGFyICp2YWx1ZSkKewoJY29uc3QgY2hhciAqdmFyOwoJaWYgKHByZWZpeGNtcChrZXksICJyZW1vdGUuIikpCgkJcmV0dXJuIDA7CgoJdmFyID0gc3RycmNocihrZXksICcuJyk7CglpZiAodmFyID09IGtleSArIDYpCgkJcmV0dXJuIDA7CgoJaWYgKCFzdHJjbXAodmFyLCAiLmZldGNoIikgJiYgZ2V0X3JlbW90ZV9icmFuY2hfbmFtZSh2YWx1ZSkpCgkJbmZhc3ByaW50ZigmY29uZmlnX3JlbW90ZSwgIiUuKnMiLCB2YXIgLSAoa2V5ICsgNyksIGtleSArIDcpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBzZXRfYnJhbmNoX21lcmdlKGNvbnN0IGNoYXIgKm5hbWUsIGNvbnN0IGNoYXIgKmNvbmZpZ19yZW1vdGUsCgkJCSAgICAgY29uc3QgY2hhciAqY29uZmlnX3JlcG8pCnsKCWNoYXIga2V5WzEwMjRdOwoJaWYgKHNpemVvZihrZXkpIDw9CgkgICAgc25wcmludGYoa2V5LCBzaXplb2Yoa2V5KSwgImJyYW5jaC4lcy5yZW1vdGUiLCBuYW1lKSkKCQlkaWUoIndoYXQgYSBsb25nIGJyYW5jaCBuYW1lIHlvdSBoYXZlISIpOwoJZ2l0X2NvbmZpZ19zZXQoa2V5LCBjb25maWdfcmVtb3RlKTsKCgkvKgoJICogV2UgZG8gbm90IGhhdmUgdG8gY2hlY2sgaWYgd2UgaGF2ZSBlbm91Z2ggc3BhY2UgZm9yCgkgKiB0aGUgJ21lcmdlJyBrZXksIHNpbmNlIGl0J3Mgc2hvcnRlciB0aGFuIHRoZQoJICogcHJldmlvdXMgJ3JlbW90ZScga2V5LCB3aGljaCB3ZSBhbHJlYWR5IGNoZWNrZWQuCgkgKi8KCXNucHJpbnRmKGtleSwgc2l6ZW9mKGtleSksICJicmFuY2guJXMubWVyZ2UiLCBuYW1lKTsKCWdpdF9jb25maWdfc2V0KGtleSwgY29uZmlnX3JlcG8pOwp9CgpzdGF0aWMgdm9pZCBzZXRfYnJhbmNoX2RlZmF1bHRzKGNvbnN0IGNoYXIgKm5hbWUsIGNvbnN0IGNoYXIgKnJlYWxfcmVmKQp7Cgljb25zdCBjaGFyICpzbGFzaCA9IHN0cnJjaHIocmVhbF9yZWYsICcvJyk7CgoJaWYgKCFzbGFzaCkKCQlyZXR1cm47CgoJc3RhcnRfcmVmID0gcmVhbF9yZWY7CglzdGFydF9sZW4gPSBzdHJsZW4ocmVhbF9yZWYpOwoJYmFzZV9sZW4gPSBzbGFzaCAtIHJlYWxfcmVmOwoJZ2l0X2NvbmZpZyhnZXRfcmVtb3RlX2NvbmZpZyk7CglpZiAoIWNvbmZpZ19yZXBvICYmICFjb25maWdfcmVtb3RlICYmCgkgICAgIXByZWZpeGNtcChyZWFsX3JlZiwgInJlZnMvaGVhZHMvIikpIHsKCQlzZXRfYnJhbmNoX21lcmdlKG5hbWUsICIuIiwgcmVhbF9yZWYpOwoJCXByaW50ZigiQnJhbmNoICVzIHNldCB1cCB0byB0cmFjayBsb2NhbCBicmFuY2ggJXMuXG4iLAoJCSAgICAgICBuYW1lLCByZWFsX3JlZik7Cgl9CgoJaWYgKGNvbmZpZ19yZXBvICYmIGNvbmZpZ19yZW1vdGUpIHsKCQlzZXRfYnJhbmNoX21lcmdlKG5hbWUsIGNvbmZpZ19yZW1vdGUsIGNvbmZpZ19yZXBvKTsKCQlwcmludGYoIkJyYW5jaCAlcyBzZXQgdXAgdG8gdHJhY2sgcmVtb3RlIGJyYW5jaCAlcy5cbiIsCgkJICAgICAgIG5hbWUsIHJlYWxfcmVmKTsKCX0KCglpZiAoY29uZmlnX3JlcG8pCgkJZnJlZShjb25maWdfcmVwbyk7CglpZiAoY29uZmlnX3JlbW90ZSkKCQlmcmVlKGNvbmZpZ19yZW1vdGUpOwp9CgpzdGF0aWMgdm9pZCBjcmVhdGVfYnJhbmNoKGNvbnN0IGNoYXIgKm5hbWUsIGNvbnN0IGNoYXIgKnN0YXJ0X25hbWUsCgkJCSAgaW50IGZvcmNlLCBpbnQgcmVmbG9nLCBpbnQgdHJhY2spCnsKCXN0cnVjdCByZWZfbG9jayAqbG9jazsKCXN0cnVjdCBjb21taXQgKmNvbW1pdDsKCXVuc2lnbmVkIGNoYXIgc2hhMVsyMF07CgljaGFyICpyZWFsX3JlZiwgcmVmW1BBVEhfTUFYXSwgbXNnW1BBVEhfTUFYICsgMjBdOwoJaW50IGZvcmNpbmcgPSAwOwoKCXNucHJpbnRmKHJlZiwgc2l6ZW9mIHJlZiwgInJlZnMvaGVhZHMvJXMiLCBuYW1lKTsKCWlmIChjaGVja19yZWZfZm9ybWF0KHJlZikpCgkJZGllKCInJXMnIGlzIG5vdCBhIHZhbGlkIGJyYW5jaCBuYW1lLiIsIG5hbWUpOwoKCWlmIChyZXNvbHZlX3JlZihyZWYsIHNoYTEsIDEsIE5VTEwpKSB7CgkJaWYgKCFmb3JjZSkKCQkJZGllKCJBIGJyYW5jaCBuYW1lZCAnJXMnIGFscmVhZHkgZXhpc3RzLiIsIG5hbWUpOwoJCWVsc2UgaWYgKCFpc19iYXJlX3JlcG9zaXRvcnkoKSAmJiAhc3RyY21wKGhlYWQsIG5hbWUpKQoJCQlkaWUoIkNhbm5vdCBmb3JjZSB1cGRhdGUgdGhlIGN1cnJlbnQgYnJhbmNoLiIpOwoJCWZvcmNpbmcgPSAxOwoJfQoKCXJlYWxfcmVmID0gTlVMTDsKCWlmIChnZXRfc2hhMShzdGFydF9uYW1lLCBzaGExKSkKCQlkaWUoIk5vdCBhIHZhbGlkIG9iamVjdCBuYW1lOiAnJXMnLiIsIHN0YXJ0X25hbWUpOwoKCXN3aXRjaCAoZHdpbV9yZWYoc3RhcnRfbmFtZSwgc3RybGVuKHN0YXJ0X25hbWUpLCBzaGExLCAmcmVhbF9yZWYpKSB7CgljYXNlIDA6CgkJLyogTm90IGJyYW5jaGluZyBmcm9tIGFueSBleGlzdGluZyBicmFuY2ggKi8KCQlyZWFsX3JlZiA9IE5VTEw7CgkJYnJlYWs7CgljYXNlIDE6CgkJLyogVW5pcXVlIGNvbXBsZXRpb24gLS0gZ29vZCAqLwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlkaWUoIkFtYmlndW91cyBvYmplY3QgbmFtZTogJyVzJy4iLCBzdGFydF9uYW1lKTsKCQlicmVhazsKCX0KCglpZiAoKGNvbW1pdCA9IGxvb2t1cF9jb21taXRfcmVmZXJlbmNlKHNoYTEpKSA9PSBOVUxMKQoJCWRpZSgiTm90IGEgdmFsaWQgYnJhbmNoIHBvaW50OiAnJXMnLiIsIHN0YXJ0X25hbWUpOwoJaGFzaGNweShzaGExLCBjb21taXQtPm9iamVjdC5zaGExKTsKCglsb2NrID0gbG9ja19hbnlfcmVmX2Zvcl91cGRhdGUocmVmLCBOVUxMKTsKCWlmICghbG9jaykKCQlkaWUoIkZhaWxlZCB0byBsb2NrIHJlZiBmb3IgdXBkYXRlOiAlcy4iLCBzdHJlcnJvcihlcnJubykpOwoKCWlmIChyZWZsb2cpCgkJbG9nX2FsbF9yZWZfdXBkYXRlcyA9IDE7CgoJaWYgKGZvcmNpbmcpCgkJc25wcmludGYobXNnLCBzaXplb2YgbXNnLCAiYnJhbmNoOiBSZXNldCBmcm9tICVzIiwKCQkJIHN0YXJ0X25hbWUpOwoJZWxzZQoJCXNucHJpbnRmKG1zZywgc2l6ZW9mIG1zZywgImJyYW5jaDogQ3JlYXRlZCBmcm9tICVzIiwKCQkJIHN0YXJ0X25hbWUpOwoKCS8qIFdoZW4gYnJhbmNoaW5nIG9mZiBhIHJlbW90ZSBicmFuY2gsIHNldCB1cCBzbyB0aGF0IGdpdC1wdWxsCgkgICBhdXRvbWF0aWNhbGx5IG1lcmdlcyBmcm9tIHRoZXJlLiAgU28gZmFyLCB0aGlzIGlzIG9ubHkgZG9uZSBmb3IKCSAgIHJlbW90ZXMgcmVnaXN0ZXJlZCB2aWEgLmdpdC9jb25maWcuICAqLwoJaWYgKHJlYWxfcmVmICYmIHRyYWNrKQoJCXNldF9icmFuY2hfZGVmYXVsdHMobmFtZSwgcmVhbF9yZWYpOwoKCWlmICh3cml0ZV9yZWZfc2hhMShsb2NrLCBzaGExLCBtc2cpIDwgMCkKCQlkaWUoIkZhaWxlZCB0byB3cml0ZSByZWY6ICVzLiIsIHN0cmVycm9yKGVycm5vKSk7CgoJaWYgKHJlYWxfcmVmKQoJCWZyZWUocmVhbF9yZWYpOwp9CgpzdGF0aWMgdm9pZCByZW5hbWVfYnJhbmNoKGNvbnN0IGNoYXIgKm9sZG5hbWUsIGNvbnN0IGNoYXIgKm5ld25hbWUsIGludCBmb3JjZSkKewoJY2hhciBvbGRyZWZbUEFUSF9NQVhdLCBuZXdyZWZbUEFUSF9NQVhdLCBsb2dtc2dbUEFUSF9NQVgqMiArIDEwMF07Cgl1bnNpZ25lZCBjaGFyIHNoYTFbMjBdOwoJY2hhciBvbGRzZWN0aW9uW1BBVEhfTUFYXSwgbmV3c2VjdGlvbltQQVRIX01BWF07CgoJaWYgKCFvbGRuYW1lKQoJCWRpZSgiY2Fubm90IHJlbmFtZSB0aGUgY3VycmVudCBicmFuY2ggd2hpbGUgbm90IG9uIGFueS4iKTsKCglpZiAoc25wcmludGYob2xkcmVmLCBzaXplb2Yob2xkcmVmKSwgInJlZnMvaGVhZHMvJXMiLCBvbGRuYW1lKSA+IHNpemVvZihvbGRyZWYpKQoJCWRpZSgiT2xkIGJyYW5jaG5hbWUgdG9vIGxvbmciKTsKCglpZiAoY2hlY2tfcmVmX2Zvcm1hdChvbGRyZWYpKQoJCWRpZSgiSW52YWxpZCBicmFuY2ggbmFtZTogJXMiLCBvbGRyZWYpOwoKCWlmIChzbnByaW50ZihuZXdyZWYsIHNpemVvZihuZXdyZWYpLCAicmVmcy9oZWFkcy8lcyIsIG5ld25hbWUpID4gc2l6ZW9mKG5ld3JlZikpCgkJZGllKCJOZXcgYnJhbmNobmFtZSB0b28gbG9uZyIpOwoKCWlmIChjaGVja19yZWZfZm9ybWF0KG5ld3JlZikpCgkJZGllKCJJbnZhbGlkIGJyYW5jaCBuYW1lOiAlcyIsIG5ld3JlZik7CgoJaWYgKHJlc29sdmVfcmVmKG5ld3JlZiwgc2hhMSwgMSwgTlVMTCkgJiYgIWZvcmNlKQoJCWRpZSgiQSBicmFuY2ggbmFtZWQgJyVzJyBhbHJlYWR5IGV4aXN0cy4iLCBuZXduYW1lKTsKCglzbnByaW50Zihsb2dtc2csIHNpemVvZihsb2dtc2cpLCAiQnJhbmNoOiByZW5hbWVkICVzIHRvICVzIiwKCQkgb2xkcmVmLCBuZXdyZWYpOwoKCWlmIChyZW5hbWVfcmVmKG9sZHJlZiwgbmV3cmVmLCBsb2dtc2cpKQoJCWRpZSgiQnJhbmNoIHJlbmFtZSBmYWlsZWQiKTsKCgkvKiBubyBuZWVkIHRvIHBhc3MgbG9nbXNnIGhlcmUgYXMgSEVBRCBkaWRuJ3QgcmVhbGx5IG1vdmUgKi8KCWlmICghc3RyY21wKG9sZG5hbWUsIGhlYWQpICYmIGNyZWF0ZV9zeW1yZWYoIkhFQUQiLCBuZXdyZWYsIE5VTEwpKQoJCWRpZSgiQnJhbmNoIHJlbmFtZWQgdG8gJXMsIGJ1dCBIRUFEIGlzIG5vdCB1cGRhdGVkISIsIG5ld25hbWUpOwoKCXNucHJpbnRmKG9sZHNlY3Rpb24sIHNpemVvZihvbGRzZWN0aW9uKSwgImJyYW5jaC4lcyIsIG9sZHJlZiArIDExKTsKCXNucHJpbnRmKG5ld3NlY3Rpb24sIHNpemVvZihuZXdzZWN0aW9uKSwgImJyYW5jaC4lcyIsIG5ld3JlZiArIDExKTsKCWlmIChnaXRfY29uZmlnX3JlbmFtZV9zZWN0aW9uKG9sZHNlY3Rpb24sIG5ld3NlY3Rpb24pIDwgMCkKCQlkaWUoIkJyYW5jaCBpcyByZW5hbWVkLCBidXQgdXBkYXRlIG9mIGNvbmZpZy1maWxlIGZhaWxlZCIpOwp9CgppbnQgY21kX2JyYW5jaChpbnQgYXJnYywgY29uc3QgY2hhciAqKmFyZ3YsIGNvbnN0IGNoYXIgKnByZWZpeCkKewoJaW50IGRlbGV0ZSA9IDAsIGZvcmNlX2RlbGV0ZSA9IDAsIGZvcmNlX2NyZWF0ZSA9IDA7CglpbnQgcmVuYW1lID0gMCwgZm9yY2VfcmVuYW1lID0gMDsKCWludCB2ZXJib3NlID0gMCwgYWJicmV2ID0gREVGQVVMVF9BQkJSRVYsIGRldGFjaGVkID0gMDsKCWludCByZWZsb2cgPSAwLCB0cmFjazsKCWludCBraW5kcyA9IFJFRl9MT0NBTF9CUkFOQ0g7CglpbnQgaTsKCglnaXRfY29uZmlnKGdpdF9icmFuY2hfY29uZmlnKTsKCXRyYWNrID0gYnJhbmNoX3RyYWNrX3JlbW90ZXM7CgoJZm9yIChpID0gMTsgaSA8IGFyZ2M7IGkrKykgewoJCWNvbnN0IGNoYXIgKmFyZyA9IGFyZ3ZbaV07CgoJCWlmIChhcmdbMF0gIT0gJy0nKQoJCQlicmVhazsKCQlpZiAoIXN0cmNtcChhcmcsICItLSIpKSB7CgkJCWkrKzsKCQkJYnJlYWs7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi0tdHJhY2siKSkgewoJCQl0cmFjayA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItLW5vLXRyYWNrIikpIHsKCQkJdHJhY2sgPSAwOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLWQiKSkgewoJCQlkZWxldGUgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLUQiKSkgewoJCQlkZWxldGUgPSAxOwoJCQlmb3JjZV9kZWxldGUgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLWYiKSkgewoJCQlmb3JjZV9jcmVhdGUgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLW0iKSkgewoJCQlyZW5hbWUgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLU0iKSkgewoJCQlyZW5hbWUgPSAxOwoJCQlmb3JjZV9yZW5hbWUgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLXIiKSkgewoJCQlraW5kcyA9IFJFRl9SRU1PVEVfQlJBTkNIOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLWEiKSkgewoJCQlraW5kcyA9IFJFRl9SRU1PVEVfQlJBTkNIIHwgUkVGX0xPQ0FMX0JSQU5DSDsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1sIikpIHsKCQkJcmVmbG9nID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghcHJlZml4Y21wKGFyZywgIi0tbm8tYWJicmV2IikpIHsKCQkJYWJicmV2ID0gMDsKCQkJY29udGludWU7CgkJfQoJCWlmICghcHJlZml4Y21wKGFyZywgIi0tYWJicmV2PSIpKSB7CgkJCWFiYnJldiA9IHN0cnRvdWwoYXJnICsgOSwgTlVMTCwgMTApOwoJCQlpZiAoYWJicmV2IDwgTUlOSU1VTV9BQkJSRVYpCgkJCQlhYmJyZXYgPSBNSU5JTVVNX0FCQlJFVjsKCQkJZWxzZSBpZiAoYWJicmV2ID4gNDApCgkJCQlhYmJyZXYgPSA0MDsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi12IikpIHsKCQkJdmVyYm9zZSA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItLWNvbG9yIikpIHsKCQkJYnJhbmNoX3VzZV9jb2xvciA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItLW5vLWNvbG9yIikpIHsKCQkJYnJhbmNoX3VzZV9jb2xvciA9IDA7CgkJCWNvbnRpbnVlOwoJCX0KCQl1c2FnZShidWlsdGluX2JyYW5jaF91c2FnZSk7Cgl9CgoJaWYgKChkZWxldGUgJiYgcmVuYW1lKSB8fCAoZGVsZXRlICYmIGZvcmNlX2NyZWF0ZSkgfHwKCSAgICAocmVuYW1lICYmIGZvcmNlX2NyZWF0ZSkpCgkJdXNhZ2UoYnVpbHRpbl9icmFuY2hfdXNhZ2UpOwoKCWhlYWQgPSB4c3RyZHVwKHJlc29sdmVfcmVmKCJIRUFEIiwgaGVhZF9zaGExLCAwLCBOVUxMKSk7CglpZiAoIWhlYWQpCgkJZGllKCJGYWlsZWQgdG8gcmVzb2x2ZSBIRUFEIGFzIGEgdmFsaWQgcmVmLiIpOwoJaWYgKCFzdHJjbXAoaGVhZCwgIkhFQUQiKSkgewoJCWRldGFjaGVkID0gMTsKCX0KCWVsc2UgewoJCWlmIChwcmVmaXhjbXAoaGVhZCwgInJlZnMvaGVhZHMvIikpCgkJCWRpZSgiSEVBRCBub3QgZm91bmQgYmVsb3cgcmVmcy9oZWFkcyEiKTsKCQloZWFkICs9IDExOwoJfQoKCWlmIChkZWxldGUpCgkJcmV0dXJuIGRlbGV0ZV9icmFuY2hlcyhhcmdjIC0gaSwgYXJndiArIGksIGZvcmNlX2RlbGV0ZSwga2luZHMpOwoJZWxzZSBpZiAoaSA9PSBhcmdjKQoJCXByaW50X3JlZl9saXN0KGtpbmRzLCBkZXRhY2hlZCwgdmVyYm9zZSwgYWJicmV2KTsKCWVsc2UgaWYgKHJlbmFtZSAmJiAoaSA9PSBhcmdjIC0gMSkpCgkJcmVuYW1lX2JyYW5jaChoZWFkLCBhcmd2W2ldLCBmb3JjZV9yZW5hbWUpOwoJZWxzZSBpZiAocmVuYW1lICYmIChpID09IGFyZ2MgLSAyKSkKCQlyZW5hbWVfYnJhbmNoKGFyZ3ZbaV0sIGFyZ3ZbaSArIDFdLCBmb3JjZV9yZW5hbWUpOwoJZWxzZSBpZiAoaSA9PSBhcmdjIC0gMSB8fCBpID09IGFyZ2MgLSAyKQoJCWNyZWF0ZV9icmFuY2goYXJndltpXSwgKGkgPT0gYXJnYyAtIDIpID8gYXJndltpKzFdIDogaGVhZCwKCQkJICAgICAgZm9yY2VfY3JlYXRlLCByZWZsb2csIHRyYWNrKTsKCWVsc2UKCQl1c2FnZShidWlsdGluX2JyYW5jaF91c2FnZSk7CgoJcmV0dXJuIDA7Cn0K