LyoKICogQnVpbHRpbiAiZ2l0IGJyYW5jaCIKICoKICogQ29weXJpZ2h0IChjKSAyMDA2IEtyaXN0aWFuIEj4Z3NiZXJnIDxrcmhAcmVkaGF0LmNvbT4KICogQmFzZWQgb24gZ2l0LWJyYW5jaC5zaCBieSBKdW5pbyBDIEhhbWFuby4KICovCgojaW5jbHVkZSAiY2FjaGUuaCIKI2luY2x1ZGUgImNvbG9yLmgiCiNpbmNsdWRlICJyZWZzLmgiCiNpbmNsdWRlICJjb21taXQuaCIKI2luY2x1ZGUgImJ1aWx0aW4uaCIKCnN0YXRpYyBjb25zdCBjaGFyIGJ1aWx0aW5fYnJhbmNoX3VzYWdlW10gPQogICJnaXQtYnJhbmNoIFstcl0gKC1kIHwgLUQpIDxicmFuY2huYW1lPiB8IFstbF0gWy1mXSA8YnJhbmNobmFtZT4gWzxzdGFydC1wb2ludD5dIHwgKC1tIHwgLU0pIFs8b2xkYnJhbmNoPl0gPG5ld2JyYW5jaD4gfCBbLXIgfCAtYV0gWy12IFstLWFiYnJldj08bGVuZ3RoPl1dIjsKCiNkZWZpbmUgUkVGX1VOS05PV05fVFlQRSAgICAweDAwCiNkZWZpbmUgUkVGX0xPQ0FMX0JSQU5DSCAgICAweDAxCiNkZWZpbmUgUkVGX1JFTU9URV9CUkFOQ0ggICAweDAyCiNkZWZpbmUgUkVGX1RBRyAgICAgICAgICAgICAweDA0CgpzdGF0aWMgY29uc3QgY2hhciAqaGVhZDsKc3RhdGljIHVuc2lnbmVkIGNoYXIgaGVhZF9zaGExWzIwXTsKCnN0YXRpYyBpbnQgYnJhbmNoX3VzZV9jb2xvcjsKc3RhdGljIGNoYXIgYnJhbmNoX2NvbG9yc1tdW0NPTE9SX01BWExFTl0gPSB7CgkiXDAzM1ttIiwJLyogcmVzZXQgKi8KCSIiLAkJLyogUExBSU4gKG5vcm1hbCkgKi8KCSJcMDMzWzMxbSIsCS8qIFJFTU9URSAocmVkKSAqLwoJIiIsCQkvKiBMT0NBTCAobm9ybWFsKSAqLwoJIlwwMzNbMzJtIiwJLyogQ1VSUkVOVCAoZ3JlZW4pICovCn07CmVudW0gY29sb3JfYnJhbmNoIHsKCUNPTE9SX0JSQU5DSF9SRVNFVCA9IDAsCglDT0xPUl9CUkFOQ0hfUExBSU4gPSAxLAoJQ09MT1JfQlJBTkNIX1JFTU9URSA9IDIsCglDT0xPUl9CUkFOQ0hfTE9DQUwgPSAzLAoJQ09MT1JfQlJBTkNIX0NVUlJFTlQgPSA0LAp9OwoKc3RhdGljIGludCBwYXJzZV9icmFuY2hfY29sb3Jfc2xvdChjb25zdCBjaGFyICp2YXIsIGludCBvZnMpCnsKCWlmICghc3RyY2FzZWNtcCh2YXIrb2ZzLCAicGxhaW4iKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX1BMQUlOOwoJaWYgKCFzdHJjYXNlY21wKHZhcitvZnMsICJyZXNldCIpKQoJCXJldHVybiBDT0xPUl9CUkFOQ0hfUkVTRVQ7CglpZiAoIXN0cmNhc2VjbXAodmFyK29mcywgInJlbW90ZSIpKQoJCXJldHVybiBDT0xPUl9CUkFOQ0hfUkVNT1RFOwoJaWYgKCFzdHJjYXNlY21wKHZhcitvZnMsICJsb2NhbCIpKQoJCXJldHVybiBDT0xPUl9CUkFOQ0hfTE9DQUw7CglpZiAoIXN0cmNhc2VjbXAodmFyK29mcywgImN1cnJlbnQiKSkKCQlyZXR1cm4gQ09MT1JfQlJBTkNIX0NVUlJFTlQ7CglkaWUoImJhZCBjb25maWcgdmFyaWFibGUgJyVzJyIsIHZhcik7Cn0KCmludCBnaXRfYnJhbmNoX2NvbmZpZyhjb25zdCBjaGFyICp2YXIsIGNvbnN0IGNoYXIgKnZhbHVlKQp7CglpZiAoIXN0cmNtcCh2YXIsICJjb2xvci5icmFuY2giKSkgewoJCWJyYW5jaF91c2VfY29sb3IgPSBnaXRfY29uZmlnX2NvbG9yYm9vbCh2YXIsIHZhbHVlKTsKCQlyZXR1cm4gMDsKCX0KCWlmICghc3RybmNtcCh2YXIsICJjb2xvci5icmFuY2guIiwgMTMpKSB7CgkJaW50IHNsb3QgPSBwYXJzZV9icmFuY2hfY29sb3Jfc2xvdCh2YXIsIDEzKTsKCQljb2xvcl9wYXJzZSh2YWx1ZSwgdmFyLCBicmFuY2hfY29sb3JzW3Nsb3RdKTsKCQlyZXR1cm4gMDsKCX0KCXJldHVybiBnaXRfZGVmYXVsdF9jb25maWcodmFyLCB2YWx1ZSk7Cn0KCmNvbnN0IGNoYXIgKmJyYW5jaF9nZXRfY29sb3IoZW51bSBjb2xvcl9icmFuY2ggaXgpCnsKCWlmIChicmFuY2hfdXNlX2NvbG9yKQoJCXJldHVybiBicmFuY2hfY29sb3JzW2l4XTsKCXJldHVybiAiIjsKfQoKc3RhdGljIGludCBpbl9tZXJnZV9iYXNlcyhjb25zdCB1bnNpZ25lZCBjaGFyICpzaGExLAoJCQkgIHN0cnVjdCBjb21taXQgKnJldjEsCgkJCSAgc3RydWN0IGNvbW1pdCAqcmV2MikKewoJc3RydWN0IGNvbW1pdF9saXN0ICpiYXNlcywgKmI7CglpbnQgcmV0ID0gMDsKCgliYXNlcyA9IGdldF9tZXJnZV9iYXNlcyhyZXYxLCByZXYyLCAxKTsKCWZvciAoYiA9IGJhc2VzOyBiOyBiID0gYi0+bmV4dCkgewoJCWlmICghaGFzaGNtcChzaGExLCBiLT5pdGVtLT5vYmplY3Quc2hhMSkpIHsKCQkJcmV0ID0gMTsKCQkJYnJlYWs7CgkJfQoJfQoKCWZyZWVfY29tbWl0X2xpc3QoYmFzZXMpOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBkZWxldGVfYnJhbmNoZXMoaW50IGFyZ2MsIGNvbnN0IGNoYXIgKiphcmd2LCBpbnQgZm9yY2UsIGludCBraW5kcykKewoJc3RydWN0IGNvbW1pdCAqcmV2LCAqaGVhZF9yZXYgPSBoZWFkX3JldjsKCXVuc2lnbmVkIGNoYXIgc2hhMVsyMF07CgljaGFyICpuYW1lID0gTlVMTDsKCWNvbnN0IGNoYXIgKmZtdCwgKnJlbW90ZTsKCWludCBpOwoJaW50IHJldCA9IDA7CgoJc3dpdGNoIChraW5kcykgewoJY2FzZSBSRUZfUkVNT1RFX0JSQU5DSDoKCQlmbXQgPSAicmVmcy9yZW1vdGVzLyVzIjsKCQlyZW1vdGUgPSAicmVtb3RlICI7CgkJZm9yY2UgPSAxOwoJCWJyZWFrOwoJY2FzZSBSRUZfTE9DQUxfQlJBTkNIOgoJCWZtdCA9ICJyZWZzL2hlYWRzLyVzIjsKCQlyZW1vdGUgPSAiIjsKCQlicmVhazsKCWRlZmF1bHQ6CgkJZGllKCJjYW5ub3QgdXNlIC1hIHdpdGggLWQiKTsKCX0KCglpZiAoIWZvcmNlKSB7CgkJaGVhZF9yZXYgPSBsb29rdXBfY29tbWl0X3JlZmVyZW5jZShoZWFkX3NoYTEpOwoJCWlmICghaGVhZF9yZXYpCgkJCWRpZSgiQ291bGRuJ3QgbG9vayB1cCBjb21taXQgb2JqZWN0IGZvciBIRUFEIik7Cgl9Cglmb3IgKGkgPSAwOyBpIDwgYXJnYzsgaSsrKSB7CgkJaWYgKGtpbmRzID09IFJFRl9MT0NBTF9CUkFOQ0ggJiYgIXN0cmNtcChoZWFkLCBhcmd2W2ldKSkgewoJCQllcnJvcigiQ2Fubm90IGRlbGV0ZSB0aGUgYnJhbmNoICclcycgIgoJCQkJIndoaWNoIHlvdSBhcmUgY3VycmVudGx5IG9uLiIsIGFyZ3ZbaV0pOwoJCQlyZXQgPSAxOwoJCQljb250aW51ZTsKCQl9CgoJCWlmIChuYW1lKQoJCQlmcmVlKG5hbWUpOwoKCQluYW1lID0geHN0cmR1cChta3BhdGgoZm10LCBhcmd2W2ldKSk7CgkJaWYgKCFyZXNvbHZlX3JlZihuYW1lLCBzaGExLCAxLCBOVUxMKSkgewoJCQllcnJvcigiJXNicmFuY2ggJyVzJyBub3QgZm91bmQuIiwKCQkJCQlyZW1vdGUsIGFyZ3ZbaV0pOwoJCQlyZXQgPSAxOwoJCQljb250aW51ZTsKCQl9CgoJCXJldiA9IGxvb2t1cF9jb21taXRfcmVmZXJlbmNlKHNoYTEpOwoJCWlmICghcmV2KSB7CgkJCWVycm9yKCJDb3VsZG4ndCBsb29rIHVwIGNvbW1pdCBvYmplY3QgZm9yICclcyciLCBuYW1lKTsKCQkJcmV0ID0gMTsKCQkJY29udGludWU7CgkJfQoKCQkvKiBUaGlzIGNoZWNrcyB3aGV0aGVyIHRoZSBtZXJnZSBiYXNlcyBvZiBicmFuY2ggYW5kCgkJICogSEVBRCBjb250YWlucyBicmFuY2ggLS0gd2hpY2ggbWVhbnMgdGhhdCB0aGUgSEVBRAoJCSAqIGNvbnRhaW5zIGV2ZXJ5dGhpbmcgaW4gYm90aC4KCQkgKi8KCgkJaWYgKCFmb3JjZSAmJgoJCSAgICAhaW5fbWVyZ2VfYmFzZXMoc2hhMSwgcmV2LCBoZWFkX3JldikpIHsKCQkJZXJyb3IoIlRoZSBicmFuY2ggJyVzJyBpcyBub3QgYSBzdHJpY3Qgc3Vic2V0IG9mICIKCQkJCSJ5b3VyIGN1cnJlbnQgSEVBRC5cbiIKCQkJCSJJZiB5b3UgYXJlIHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIGl0LCAiCgkJCQkicnVuICdnaXQgYnJhbmNoIC1EICVzJy4iLCBhcmd2W2ldLCBhcmd2W2ldKTsKCQkJcmV0ID0gMTsKCQkJY29udGludWU7CgkJfQoKCQlpZiAoZGVsZXRlX3JlZihuYW1lLCBzaGExKSkgewoJCQllcnJvcigiRXJyb3IgZGVsZXRpbmcgJXNicmFuY2ggJyVzJyIsIHJlbW90ZSwKCQkJICAgICAgIGFyZ3ZbaV0pOwoJCQlyZXQgPSAxOwoJCX0gZWxzZQoJCQlwcmludGYoIkRlbGV0ZWQgJXNicmFuY2ggJXMuXG4iLCByZW1vdGUsIGFyZ3ZbaV0pOwoKCX0KCglpZiAobmFtZSkKCQlmcmVlKG5hbWUpOwoKCXJldHVybihyZXQpOwp9CgpzdHJ1Y3QgcmVmX2l0ZW0gewoJY2hhciAqbmFtZTsKCXVuc2lnbmVkIGludCBraW5kOwoJdW5zaWduZWQgY2hhciBzaGExWzIwXTsKfTsKCnN0cnVjdCByZWZfbGlzdCB7CglpbnQgaW5kZXgsIGFsbG9jLCBtYXh3aWR0aDsKCXN0cnVjdCByZWZfaXRlbSAqbGlzdDsKCWludCBraW5kczsKfTsKCnN0YXRpYyBpbnQgYXBwZW5kX3JlZihjb25zdCBjaGFyICpyZWZuYW1lLCBjb25zdCB1bnNpZ25lZCBjaGFyICpzaGExLCBpbnQgZmxhZ3MsIHZvaWQgKmNiX2RhdGEpCnsKCXN0cnVjdCByZWZfbGlzdCAqcmVmX2xpc3QgPSAoc3RydWN0IHJlZl9saXN0KikoY2JfZGF0YSk7CglzdHJ1Y3QgcmVmX2l0ZW0gKm5ld2l0ZW07CglpbnQga2luZCA9IFJFRl9VTktOT1dOX1RZUEU7CglpbnQgbGVuOwoKCS8qIERldGVjdCBraW5kICovCglpZiAoIXN0cm5jbXAocmVmbmFtZSwgInJlZnMvaGVhZHMvIiwgMTEpKSB7CgkJa2luZCA9IFJFRl9MT0NBTF9CUkFOQ0g7CgkJcmVmbmFtZSArPSAxMTsKCX0gZWxzZSBpZiAoIXN0cm5jbXAocmVmbmFtZSwgInJlZnMvcmVtb3Rlcy8iLCAxMykpIHsKCQlraW5kID0gUkVGX1JFTU9URV9CUkFOQ0g7CgkJcmVmbmFtZSArPSAxMzsKCX0gZWxzZSBpZiAoIXN0cm5jbXAocmVmbmFtZSwgInJlZnMvdGFncy8iLCAxMCkpIHsKCQlraW5kID0gUkVGX1RBRzsKCQlyZWZuYW1lICs9IDEwOwoJfQoKCS8qIERvbid0IGFkZCB0eXBlcyB0aGUgY2FsbGVyIGRvZXNuJ3Qgd2FudCAqLwoJaWYgKChraW5kICYgcmVmX2xpc3QtPmtpbmRzKSA9PSAwKQoJCXJldHVybiAwOwoKCS8qIFJlc2l6ZSBidWZmZXIgKi8KCWlmIChyZWZfbGlzdC0+aW5kZXggPj0gcmVmX2xpc3QtPmFsbG9jKSB7CgkJcmVmX2xpc3QtPmFsbG9jID0gYWxsb2NfbnIocmVmX2xpc3QtPmFsbG9jKTsKCQlyZWZfbGlzdC0+bGlzdCA9IHhyZWFsbG9jKHJlZl9saXN0LT5saXN0LAoJCQkJcmVmX2xpc3QtPmFsbG9jICogc2l6ZW9mKHN0cnVjdCByZWZfaXRlbSkpOwoJfQoKCS8qIFJlY29yZCB0aGUgbmV3IGl0ZW0gKi8KCW5ld2l0ZW0gPSAmKHJlZl9saXN0LT5saXN0W3JlZl9saXN0LT5pbmRleCsrXSk7CgluZXdpdGVtLT5uYW1lID0geHN0cmR1cChyZWZuYW1lKTsKCW5ld2l0ZW0tPmtpbmQgPSBraW5kOwoJaGFzaGNweShuZXdpdGVtLT5zaGExLCBzaGExKTsKCWxlbiA9IHN0cmxlbihuZXdpdGVtLT5uYW1lKTsKCWlmIChsZW4gPiByZWZfbGlzdC0+bWF4d2lkdGgpCgkJcmVmX2xpc3QtPm1heHdpZHRoID0gbGVuOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBmcmVlX3JlZl9saXN0KHN0cnVjdCByZWZfbGlzdCAqcmVmX2xpc3QpCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCByZWZfbGlzdC0+aW5kZXg7IGkrKykKCQlmcmVlKHJlZl9saXN0LT5saXN0W2ldLm5hbWUpOwoJZnJlZShyZWZfbGlzdC0+bGlzdCk7Cn0KCnN0YXRpYyBpbnQgcmVmX2NtcChjb25zdCB2b2lkICpyMSwgY29uc3Qgdm9pZCAqcjIpCnsKCXN0cnVjdCByZWZfaXRlbSAqYzEgPSAoc3RydWN0IHJlZl9pdGVtICopKHIxKTsKCXN0cnVjdCByZWZfaXRlbSAqYzIgPSAoc3RydWN0IHJlZl9pdGVtICopKHIyKTsKCglpZiAoYzEtPmtpbmQgIT0gYzItPmtpbmQpCgkJcmV0dXJuIGMxLT5raW5kIC0gYzItPmtpbmQ7CglyZXR1cm4gc3RyY21wKGMxLT5uYW1lLCBjMi0+bmFtZSk7Cn0KCnN0YXRpYyB2b2lkIHByaW50X3JlZl9pbmZvKGNvbnN0IHVuc2lnbmVkIGNoYXIgKnNoYTEsIGludCBhYmJyZXYpCnsKCXN0cnVjdCBjb21taXQgKmNvbW1pdDsKCWNoYXIgc3ViamVjdFsyNTZdOwoKCgljb21taXQgPSBsb29rdXBfY29tbWl0KHNoYTEpOwoJaWYgKGNvbW1pdCAmJiAhcGFyc2VfY29tbWl0KGNvbW1pdCkpCgkJcHJldHR5X3ByaW50X2NvbW1pdChDTUlUX0ZNVF9PTkVMSU5FLCBjb21taXQsIH4wLAoJCQkJICAgIHN1YmplY3QsIHNpemVvZihzdWJqZWN0KSwgMCwKCQkJCSAgICBOVUxMLCBOVUxMLCAwKTsKCWVsc2UKCQlzdHJjcHkoc3ViamVjdCwgIiAqKioqIGludmFsaWQgcmVmICoqKioiKTsKCglwcmludGYoIiAlcyAlc1xuIiwgZmluZF91bmlxdWVfYWJicmV2KHNoYTEsIGFiYnJldiksIHN1YmplY3QpOwp9CgpzdGF0aWMgdm9pZCBwcmludF9yZWZfbGlzdChpbnQga2luZHMsIGludCB2ZXJib3NlLCBpbnQgYWJicmV2KQp7CglpbnQgaTsKCWNoYXIgYzsKCXN0cnVjdCByZWZfbGlzdCByZWZfbGlzdDsKCWludCBjb2xvcjsKCgltZW1zZXQoJnJlZl9saXN0LCAwLCBzaXplb2YocmVmX2xpc3QpKTsKCXJlZl9saXN0LmtpbmRzID0ga2luZHM7Cglmb3JfZWFjaF9yZWYoYXBwZW5kX3JlZiwgJnJlZl9saXN0KTsKCglxc29ydChyZWZfbGlzdC5saXN0LCByZWZfbGlzdC5pbmRleCwgc2l6ZW9mKHN0cnVjdCByZWZfaXRlbSksIHJlZl9jbXApOwoKCWZvciAoaSA9IDA7IGkgPCByZWZfbGlzdC5pbmRleDsgaSsrKSB7CgkJc3dpdGNoKCByZWZfbGlzdC5saXN0W2ldLmtpbmQgKSB7CgkJCWNhc2UgUkVGX0xPQ0FMX0JSQU5DSDoKCQkJCWNvbG9yID0gQ09MT1JfQlJBTkNIX0xPQ0FMOwoJCQkJYnJlYWs7CgkJCWNhc2UgUkVGX1JFTU9URV9CUkFOQ0g6CgkJCQljb2xvciA9IENPTE9SX0JSQU5DSF9SRU1PVEU7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWNvbG9yID0gQ09MT1JfQlJBTkNIX1BMQUlOOwoJCQkJYnJlYWs7CgkJfQoKCQljID0gJyAnOwoJCWlmIChyZWZfbGlzdC5saXN0W2ldLmtpbmQgPT0gUkVGX0xPQ0FMX0JSQU5DSCAmJgoJCQkJIXN0cmNtcChyZWZfbGlzdC5saXN0W2ldLm5hbWUsIGhlYWQpKSB7CgkJCWMgPSAnKic7CgkJCWNvbG9yID0gQ09MT1JfQlJBTkNIX0NVUlJFTlQ7CgkJfQoKCQlpZiAodmVyYm9zZSkgewoJCQlwcmludGYoIiVjICVzJS0qcyVzIiwgYywKCQkJCQlicmFuY2hfZ2V0X2NvbG9yKGNvbG9yKSwKCQkJCQlyZWZfbGlzdC5tYXh3aWR0aCwKCQkJCQlyZWZfbGlzdC5saXN0W2ldLm5hbWUsCgkJCQkJYnJhbmNoX2dldF9jb2xvcihDT0xPUl9CUkFOQ0hfUkVTRVQpKTsKCQkJcHJpbnRfcmVmX2luZm8ocmVmX2xpc3QubGlzdFtpXS5zaGExLCBhYmJyZXYpOwoJCX0KCQllbHNlCgkJCXByaW50ZigiJWMgJXMlcyVzXG4iLCBjLAoJCQkJCWJyYW5jaF9nZXRfY29sb3IoY29sb3IpLAoJCQkJCXJlZl9saXN0Lmxpc3RbaV0ubmFtZSwKCQkJCQlicmFuY2hfZ2V0X2NvbG9yKENPTE9SX0JSQU5DSF9SRVNFVCkpOwoJfQoKCWZyZWVfcmVmX2xpc3QoJnJlZl9saXN0KTsKfQoKc3RhdGljIHZvaWQgY3JlYXRlX2JyYW5jaChjb25zdCBjaGFyICpuYW1lLCBjb25zdCBjaGFyICpzdGFydCwKCQkJICBpbnQgZm9yY2UsIGludCByZWZsb2cpCnsKCXN0cnVjdCByZWZfbG9jayAqbG9jazsKCXN0cnVjdCBjb21taXQgKmNvbW1pdDsKCXVuc2lnbmVkIGNoYXIgc2hhMVsyMF07CgljaGFyIHJlZltQQVRIX01BWF0sIG1zZ1tQQVRIX01BWCArIDIwXTsKCglzbnByaW50ZihyZWYsIHNpemVvZiByZWYsICJyZWZzL2hlYWRzLyVzIiwgbmFtZSk7CglpZiAoY2hlY2tfcmVmX2Zvcm1hdChyZWYpKQoJCWRpZSgiJyVzJyBpcyBub3QgYSB2YWxpZCBicmFuY2ggbmFtZS4iLCBuYW1lKTsKCglpZiAocmVzb2x2ZV9yZWYocmVmLCBzaGExLCAxLCBOVUxMKSkgewoJCWlmICghZm9yY2UpCgkJCWRpZSgiQSBicmFuY2ggbmFtZWQgJyVzJyBhbHJlYWR5IGV4aXN0cy4iLCBuYW1lKTsKCQllbHNlIGlmICghc3RyY21wKGhlYWQsIG5hbWUpKQoJCQlkaWUoIkNhbm5vdCBmb3JjZSB1cGRhdGUgdGhlIGN1cnJlbnQgYnJhbmNoLiIpOwoJfQoKCWlmIChnZXRfc2hhMShzdGFydCwgc2hhMSkgfHwKCSAgICAoY29tbWl0ID0gbG9va3VwX2NvbW1pdF9yZWZlcmVuY2Uoc2hhMSkpID09IE5VTEwpCgkJZGllKCJOb3QgYSB2YWxpZCBicmFuY2ggcG9pbnQ6ICclcycuIiwgc3RhcnQpOwoJaGFzaGNweShzaGExLCBjb21taXQtPm9iamVjdC5zaGExKTsKCglsb2NrID0gbG9ja19hbnlfcmVmX2Zvcl91cGRhdGUocmVmLCBOVUxMKTsKCWlmICghbG9jaykKCQlkaWUoIkZhaWxlZCB0byBsb2NrIHJlZiBmb3IgdXBkYXRlOiAlcy4iLCBzdHJlcnJvcihlcnJubykpOwoKCWlmIChyZWZsb2cpIHsKCQlsb2dfYWxsX3JlZl91cGRhdGVzID0gMTsKCQlzbnByaW50Zihtc2csIHNpemVvZiBtc2csICJicmFuY2g6IENyZWF0ZWQgZnJvbSAlcyIsIHN0YXJ0KTsKCX0KCglpZiAod3JpdGVfcmVmX3NoYTEobG9jaywgc2hhMSwgbXNnKSA8IDApCgkJZGllKCJGYWlsZWQgdG8gd3JpdGUgcmVmOiAlcy4iLCBzdHJlcnJvcihlcnJubykpOwp9CgpzdGF0aWMgdm9pZCByZW5hbWVfYnJhbmNoKGNvbnN0IGNoYXIgKm9sZG5hbWUsIGNvbnN0IGNoYXIgKm5ld25hbWUsIGludCBmb3JjZSkKewoJY2hhciBvbGRyZWZbUEFUSF9NQVhdLCBuZXdyZWZbUEFUSF9NQVhdLCBsb2dtc2dbUEFUSF9NQVgqMiArIDEwMF07Cgl1bnNpZ25lZCBjaGFyIHNoYTFbMjBdOwoKCWlmIChzbnByaW50ZihvbGRyZWYsIHNpemVvZihvbGRyZWYpLCAicmVmcy9oZWFkcy8lcyIsIG9sZG5hbWUpID4gc2l6ZW9mKG9sZHJlZikpCgkJZGllKCJPbGQgYnJhbmNobmFtZSB0b28gbG9uZyIpOwoKCWlmIChjaGVja19yZWZfZm9ybWF0KG9sZHJlZikpCgkJZGllKCJJbnZhbGlkIGJyYW5jaCBuYW1lOiAlcyIsIG9sZHJlZik7CgoJaWYgKHNucHJpbnRmKG5ld3JlZiwgc2l6ZW9mKG5ld3JlZiksICJyZWZzL2hlYWRzLyVzIiwgbmV3bmFtZSkgPiBzaXplb2YobmV3cmVmKSkKCQlkaWUoIk5ldyBicmFuY2huYW1lIHRvbyBsb25nIik7CgoJaWYgKGNoZWNrX3JlZl9mb3JtYXQobmV3cmVmKSkKCQlkaWUoIkludmFsaWQgYnJhbmNoIG5hbWU6ICVzIiwgbmV3cmVmKTsKCglpZiAocmVzb2x2ZV9yZWYobmV3cmVmLCBzaGExLCAxLCBOVUxMKSAmJiAhZm9yY2UpCgkJZGllKCJBIGJyYW5jaCBuYW1lZCAnJXMnIGFscmVhZHkgZXhpc3RzLiIsIG5ld25hbWUpOwoKCXNucHJpbnRmKGxvZ21zZywgc2l6ZW9mKGxvZ21zZyksICJCcmFuY2g6IHJlbmFtZWQgJXMgdG8gJXMiLAoJCSBvbGRyZWYsIG5ld3JlZik7CgoJaWYgKHJlbmFtZV9yZWYob2xkcmVmLCBuZXdyZWYsIGxvZ21zZykpCgkJZGllKCJCcmFuY2ggcmVuYW1lIGZhaWxlZCIpOwoKCWlmICghc3RyY21wKG9sZG5hbWUsIGhlYWQpICYmIGNyZWF0ZV9zeW1yZWYoIkhFQUQiLCBuZXdyZWYpKQoJCWRpZSgiQnJhbmNoIHJlbmFtZWQgdG8gJXMsIGJ1dCBIRUFEIGlzIG5vdCB1cGRhdGVkISIsIG5ld25hbWUpOwp9CgppbnQgY21kX2JyYW5jaChpbnQgYXJnYywgY29uc3QgY2hhciAqKmFyZ3YsIGNvbnN0IGNoYXIgKnByZWZpeCkKewoJaW50IGRlbGV0ZSA9IDAsIGZvcmNlX2RlbGV0ZSA9IDAsIGZvcmNlX2NyZWF0ZSA9IDA7CglpbnQgcmVuYW1lID0gMCwgZm9yY2VfcmVuYW1lID0gMDsKCWludCB2ZXJib3NlID0gMCwgYWJicmV2ID0gREVGQVVMVF9BQkJSRVY7CglpbnQgcmVmbG9nID0gMDsKCWludCBraW5kcyA9IFJFRl9MT0NBTF9CUkFOQ0g7CglpbnQgaTsKCglzZXR1cF9pZGVudCgpOwoJZ2l0X2NvbmZpZyhnaXRfYnJhbmNoX2NvbmZpZyk7CgoJZm9yIChpID0gMTsgaSA8IGFyZ2M7IGkrKykgewoJCWNvbnN0IGNoYXIgKmFyZyA9IGFyZ3ZbaV07CgoJCWlmIChhcmdbMF0gIT0gJy0nKQoJCQlicmVhazsKCQlpZiAoIXN0cmNtcChhcmcsICItLSIpKSB7CgkJCWkrKzsKCQkJYnJlYWs7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1kIikpIHsKCQkJZGVsZXRlID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1EIikpIHsKCQkJZGVsZXRlID0gMTsKCQkJZm9yY2VfZGVsZXRlID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1mIikpIHsKCQkJZm9yY2VfY3JlYXRlID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1tIikpIHsKCQkJcmVuYW1lID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1NIikpIHsKCQkJcmVuYW1lID0gMTsKCQkJZm9yY2VfcmVuYW1lID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1yIikpIHsKCQkJa2luZHMgPSBSRUZfUkVNT1RFX0JSQU5DSDsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1hIikpIHsKCQkJa2luZHMgPSBSRUZfUkVNT1RFX0JSQU5DSCB8IFJFRl9MT0NBTF9CUkFOQ0g7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItbCIpKSB7CgkJCXJlZmxvZyA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cm5jbXAoYXJnLCAiLS1hYmJyZXY9IiwgOSkpIHsKCQkJYWJicmV2ID0gYXRvaShhcmcrOSk7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItdiIpKSB7CgkJCXZlcmJvc2UgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLS1jb2xvciIpKSB7CgkJCWJyYW5jaF91c2VfY29sb3IgPSAxOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFzdHJjbXAoYXJnLCAiLS1uby1jb2xvciIpKSB7CgkJCWJyYW5jaF91c2VfY29sb3IgPSAwOwoJCQljb250aW51ZTsKCQl9CgkJdXNhZ2UoYnVpbHRpbl9icmFuY2hfdXNhZ2UpOwoJfQoKCWlmICgoZGVsZXRlICYmIHJlbmFtZSkgfHwgKGRlbGV0ZSAmJiBmb3JjZV9jcmVhdGUpIHx8CgkgICAgKHJlbmFtZSAmJiBmb3JjZV9jcmVhdGUpKQoJCXVzYWdlKGJ1aWx0aW5fYnJhbmNoX3VzYWdlKTsKCgloZWFkID0geHN0cmR1cChyZXNvbHZlX3JlZigiSEVBRCIsIGhlYWRfc2hhMSwgMCwgTlVMTCkpOwoJaWYgKCFoZWFkKQoJCWRpZSgiRmFpbGVkIHRvIHJlc29sdmUgSEVBRCBhcyBhIHZhbGlkIHJlZi4iKTsKCWlmIChzdHJuY21wKGhlYWQsICJyZWZzL2hlYWRzLyIsIDExKSkKCQlkaWUoIkhFQUQgbm90IGZvdW5kIGJlbG93IHJlZnMvaGVhZHMhIik7CgloZWFkICs9IDExOwoKCWlmIChkZWxldGUpCgkJcmV0dXJuIGRlbGV0ZV9icmFuY2hlcyhhcmdjIC0gaSwgYXJndiArIGksIGZvcmNlX2RlbGV0ZSwga2luZHMpOwoJZWxzZSBpZiAoaSA9PSBhcmdjKQoJCXByaW50X3JlZl9saXN0KGtpbmRzLCB2ZXJib3NlLCBhYmJyZXYpOwoJZWxzZSBpZiAocmVuYW1lICYmIChpID09IGFyZ2MgLSAxKSkKCQlyZW5hbWVfYnJhbmNoKGhlYWQsIGFyZ3ZbaV0sIGZvcmNlX3JlbmFtZSk7CgllbHNlIGlmIChyZW5hbWUgJiYgKGkgPT0gYXJnYyAtIDIpKQoJCXJlbmFtZV9icmFuY2goYXJndltpXSwgYXJndltpICsgMV0sIGZvcmNlX3JlbmFtZSk7CgllbHNlIGlmIChpID09IGFyZ2MgLSAxKQoJCWNyZWF0ZV9icmFuY2goYXJndltpXSwgaGVhZCwgZm9yY2VfY3JlYXRlLCByZWZsb2cpOwoJZWxzZSBpZiAoaSA9PSBhcmdjIC0gMikKCQljcmVhdGVfYnJhbmNoKGFyZ3ZbaV0sIGFyZ3ZbaSArIDFdLCBmb3JjZV9jcmVhdGUsIHJlZmxvZyk7CgllbHNlCgkJdXNhZ2UoYnVpbHRpbl9icmFuY2hfdXNhZ2UpOwoKCXJldHVybiAwOwp9Cg==