LyoKICogQnVpbHRpbiAiZ2l0IGJyYW5jaCIKICoKICogQ29weXJpZ2h0IChjKSAyMDA2IEtyaXN0aWFuIEj4Z3NiZXJnIDxrcmhAcmVkaGF0LmNvbT4KICogQmFzZWQgb24gZ2l0LWJyYW5jaC5zaCBieSBKdW5pbyBDIEhhbWFuby4KICovCgojaW5jbHVkZSAiY2FjaGUuaCIKI2luY2x1ZGUgInJlZnMuaCIKI2luY2x1ZGUgImNvbW1pdC5oIgojaW5jbHVkZSAiYnVpbHRpbi5oIgoKc3RhdGljIGNvbnN0IGNoYXIgYnVpbHRpbl9icmFuY2hfdXNhZ2VbXSA9CiJnaXQtYnJhbmNoICgtZCB8IC1EKSA8YnJhbmNobmFtZT4gfCBbLWxdIFstZl0gPGJyYW5jaG5hbWU+IFs8c3RhcnQtcG9pbnQ+XSB8IFstcl0iOwoKCnN0YXRpYyBjb25zdCBjaGFyICpoZWFkOwpzdGF0aWMgdW5zaWduZWQgY2hhciBoZWFkX3NoYTFbMjBdOwoKc3RhdGljIGludCBpbl9tZXJnZV9iYXNlcyhjb25zdCB1bnNpZ25lZCBjaGFyICpzaGExLAoJCQkgIHN0cnVjdCBjb21taXQgKnJldjEsCgkJCSAgc3RydWN0IGNvbW1pdCAqcmV2MikKewoJc3RydWN0IGNvbW1pdF9saXN0ICpiYXNlcywgKmI7CglpbnQgcmV0ID0gMDsKCgliYXNlcyA9IGdldF9tZXJnZV9iYXNlcyhyZXYxLCByZXYyLCAxKTsKCWZvciAoYiA9IGJhc2VzOyBiOyBiID0gYi0+bmV4dCkgewoJCWlmICghaGFzaGNtcChzaGExLCBiLT5pdGVtLT5vYmplY3Quc2hhMSkpIHsKCQkJcmV0ID0gMTsKCQkJYnJlYWs7CgkJfQoJfQoKCWZyZWVfY29tbWl0X2xpc3QoYmFzZXMpOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgZGVsZXRlX2JyYW5jaGVzKGludCBhcmdjLCBjb25zdCBjaGFyICoqYXJndiwgaW50IGZvcmNlKQp7CglzdHJ1Y3QgY29tbWl0ICpyZXYsICpoZWFkX3JldjsKCXVuc2lnbmVkIGNoYXIgc2hhMVsyMF07CgljaGFyICpuYW1lOwoJaW50IGk7CgoJaGVhZF9yZXYgPSBsb29rdXBfY29tbWl0X3JlZmVyZW5jZShoZWFkX3NoYTEpOwoJZm9yIChpID0gMDsgaSA8IGFyZ2M7IGkrKykgewoJCWlmICghc3RyY21wKGhlYWQsIGFyZ3ZbaV0pKQoJCQlkaWUoIkNhbm5vdCBkZWxldGUgdGhlIGJyYW5jaCB5b3UgYXJlIGN1cnJlbnRseSBvbi4iKTsKCgkJbmFtZSA9IHhzdHJkdXAobWtwYXRoKCJyZWZzL2hlYWRzLyVzIiwgYXJndltpXSkpOwoJCWlmICghcmVzb2x2ZV9yZWYobmFtZSwgc2hhMSwgMSwgTlVMTCkpCgkJCWRpZSgiQnJhbmNoICclcycgbm90IGZvdW5kLiIsIGFyZ3ZbaV0pOwoKCQlyZXYgPSBsb29rdXBfY29tbWl0X3JlZmVyZW5jZShzaGExKTsKCQlpZiAoIXJldiB8fCAhaGVhZF9yZXYpCgkJCWRpZSgiQ291bGRuJ3QgbG9vayB1cCBjb21taXQgb2JqZWN0cy4iKTsKCgkJLyogVGhpcyBjaGVja3Mgd2hldGhlciB0aGUgbWVyZ2UgYmFzZXMgb2YgYnJhbmNoIGFuZAoJCSAqIEhFQUQgY29udGFpbnMgYnJhbmNoIC0tIHdoaWNoIG1lYW5zIHRoYXQgdGhlIEhFQUQKCQkgKiBjb250YWlucyBldmVyeXRoaW5nIGluIGJvdGguCgkJICovCgoJCWlmICghZm9yY2UgJiYKCQkgICAgIWluX21lcmdlX2Jhc2VzKHNoYTEsIHJldiwgaGVhZF9yZXYpKSB7CgkJCWZwcmludGYoc3RkZXJyLAoJCQkJIlRoZSBicmFuY2ggJyVzJyBpcyBub3QgYSBzdHJpY3Qgc3Vic2V0IG9mIHlvdXIgY3VycmVudCBIRUFELlxuIgoJCQkJIklmIHlvdSBhcmUgc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgaXQsIHJ1biAnZ2l0IGJyYW5jaCAtRCAlcycuXG4iLAoJCQkJYXJndltpXSwgYXJndltpXSk7CgkJCWV4aXQoMSk7CgkJfQoKCQlpZiAoZGVsZXRlX3JlZihuYW1lLCBzaGExKSkKCQkJcHJpbnRmKCJFcnJvciBkZWxldGluZyBicmFuY2ggJyVzJ1xuIiwgYXJndltpXSk7CgkJZWxzZQoJCQlwcmludGYoIkRlbGV0ZWQgYnJhbmNoICVzLlxuIiwgYXJndltpXSk7CgoJCWZyZWUobmFtZSk7Cgl9Cn0KCnN0YXRpYyBpbnQgcmVmX2luZGV4LCByZWZfYWxsb2M7CnN0YXRpYyBjaGFyICoqcmVmX2xpc3Q7CgpzdGF0aWMgaW50IGFwcGVuZF9yZWYoY29uc3QgY2hhciAqcmVmbmFtZSwgY29uc3QgdW5zaWduZWQgY2hhciAqc2hhMSwgaW50IGZsYWdzLAoJCXZvaWQgKmNiX2RhdGEpCnsKCWlmIChyZWZfaW5kZXggPj0gcmVmX2FsbG9jKSB7CgkJcmVmX2FsbG9jID0gYWxsb2NfbnIocmVmX2FsbG9jKTsKCQlyZWZfbGlzdCA9IHhyZWFsbG9jKHJlZl9saXN0LCByZWZfYWxsb2MgKiBzaXplb2YoY2hhciAqKSk7Cgl9CgoJcmVmX2xpc3RbcmVmX2luZGV4KytdID0geHN0cmR1cChyZWZuYW1lKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCByZWZfY21wKGNvbnN0IHZvaWQgKnIxLCBjb25zdCB2b2lkICpyMikKewoJcmV0dXJuIHN0cmNtcCgqKGNoYXIgKiopcjEsICooY2hhciAqKilyMik7Cn0KCnN0YXRpYyB2b2lkIHByaW50X3JlZl9saXN0KGludCByZW1vdGVfb25seSkKewoJaW50IGk7CgljaGFyIGM7CgoJaWYgKHJlbW90ZV9vbmx5KQoJCWZvcl9lYWNoX3JlbW90ZV9yZWYoYXBwZW5kX3JlZiwgTlVMTCk7CgllbHNlCgkJZm9yX2VhY2hfYnJhbmNoX3JlZihhcHBlbmRfcmVmLCBOVUxMKTsKCglxc29ydChyZWZfbGlzdCwgcmVmX2luZGV4LCBzaXplb2YoY2hhciAqKSwgcmVmX2NtcCk7CgoJZm9yIChpID0gMDsgaSA8IHJlZl9pbmRleDsgaSsrKSB7CgkJYyA9ICcgJzsKCQlpZiAoIXN0cmNtcChyZWZfbGlzdFtpXSwgaGVhZCkpCgkJCWMgPSAnKic7CgoJCXByaW50ZigiJWMgJXNcbiIsIGMsIHJlZl9saXN0W2ldKTsKCX0KfQoKc3RhdGljIHZvaWQgY3JlYXRlX2JyYW5jaChjb25zdCBjaGFyICpuYW1lLCBjb25zdCBjaGFyICpzdGFydCwKCQkJICBpbnQgZm9yY2UsIGludCByZWZsb2cpCnsKCXN0cnVjdCByZWZfbG9jayAqbG9jazsKCXN0cnVjdCBjb21taXQgKmNvbW1pdDsKCXVuc2lnbmVkIGNoYXIgc2hhMVsyMF07CgljaGFyIHJlZltQQVRIX01BWF0sIG1zZ1tQQVRIX01BWCArIDIwXTsKCglzbnByaW50ZihyZWYsIHNpemVvZiByZWYsICJyZWZzL2hlYWRzLyVzIiwgbmFtZSk7CglpZiAoY2hlY2tfcmVmX2Zvcm1hdChyZWYpKQoJCWRpZSgiJyVzJyBpcyBub3QgYSB2YWxpZCBicmFuY2ggbmFtZS4iLCBuYW1lKTsKCglpZiAocmVzb2x2ZV9yZWYocmVmLCBzaGExLCAxLCBOVUxMKSkgewoJCWlmICghZm9yY2UpCgkJCWRpZSgiQSBicmFuY2ggbmFtZWQgJyVzJyBhbHJlYWR5IGV4aXN0cy4iLCBuYW1lKTsKCQllbHNlIGlmICghc3RyY21wKGhlYWQsIG5hbWUpKQoJCQlkaWUoIkNhbm5vdCBmb3JjZSB1cGRhdGUgdGhlIGN1cnJlbnQgYnJhbmNoLiIpOwoJfQoKCWlmIChnZXRfc2hhMShzdGFydCwgc2hhMSkgfHwKCSAgICAoY29tbWl0ID0gbG9va3VwX2NvbW1pdF9yZWZlcmVuY2Uoc2hhMSkpID09IE5VTEwpCgkJZGllKCJOb3QgYSB2YWxpZCBicmFuY2ggcG9pbnQ6ICclcycuIiwgc3RhcnQpOwoJaGFzaGNweShzaGExLCBjb21taXQtPm9iamVjdC5zaGExKTsKCglsb2NrID0gbG9ja19hbnlfcmVmX2Zvcl91cGRhdGUocmVmLCBOVUxMKTsKCWlmICghbG9jaykKCQlkaWUoIkZhaWxlZCB0byBsb2NrIHJlZiBmb3IgdXBkYXRlOiAlcy4iLCBzdHJlcnJvcihlcnJubykpOwoKCWlmIChyZWZsb2cpIHsKCQlsb2dfYWxsX3JlZl91cGRhdGVzID0gMTsKCQlzbnByaW50Zihtc2csIHNpemVvZiBtc2csICJicmFuY2g6IENyZWF0ZWQgZnJvbSAlcyIsIHN0YXJ0KTsKCX0KCglpZiAod3JpdGVfcmVmX3NoYTEobG9jaywgc2hhMSwgbXNnKSA8IDApCgkJZGllKCJGYWlsZWQgdG8gd3JpdGUgcmVmOiAlcy4iLCBzdHJlcnJvcihlcnJubykpOwp9CgppbnQgY21kX2JyYW5jaChpbnQgYXJnYywgY29uc3QgY2hhciAqKmFyZ3YsIGNvbnN0IGNoYXIgKnByZWZpeCkKewoJaW50IGRlbGV0ZSA9IDAsIGZvcmNlX2RlbGV0ZSA9IDAsIGZvcmNlX2NyZWF0ZSA9IDAsIHJlbW90ZV9vbmx5ID0gMDsKCWludCByZWZsb2cgPSAwOwoJaW50IGk7CgoJZ2l0X2NvbmZpZyhnaXRfZGVmYXVsdF9jb25maWcpOwoKCWZvciAoaSA9IDE7IGkgPCBhcmdjOyBpKyspIHsKCQljb25zdCBjaGFyICphcmcgPSBhcmd2W2ldOwoKCQlpZiAoYXJnWzBdICE9ICctJykKCQkJYnJlYWs7CgkJaWYgKCFzdHJjbXAoYXJnLCAiLS0iKSkgewoJCQlpKys7CgkJCWJyZWFrOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItZCIpKSB7CgkJCWRlbGV0ZSA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItRCIpKSB7CgkJCWRlbGV0ZSA9IDE7CgkJCWZvcmNlX2RlbGV0ZSA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItZiIpKSB7CgkJCWZvcmNlX2NyZWF0ZSA9IDE7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIXN0cmNtcChhcmcsICItciIpKSB7CgkJCXJlbW90ZV9vbmx5ID0gMTsKCQkJY29udGludWU7CgkJfQoJCWlmICghc3RyY21wKGFyZywgIi1sIikpIHsKCQkJcmVmbG9nID0gMTsKCQkJY29udGludWU7CgkJfQoJCXVzYWdlKGJ1aWx0aW5fYnJhbmNoX3VzYWdlKTsKCX0KCgloZWFkID0geHN0cmR1cChyZXNvbHZlX3JlZigiSEVBRCIsIGhlYWRfc2hhMSwgMCwgTlVMTCkpOwoJaWYgKCFoZWFkKQoJCWRpZSgiRmFpbGVkIHRvIHJlc29sdmUgSEVBRCBhcyBhIHZhbGlkIHJlZi4iKTsKCWlmIChzdHJuY21wKGhlYWQsICJyZWZzL2hlYWRzLyIsIDExKSkKCQlkaWUoIkhFQUQgbm90IGZvdW5kIGJlbG93IHJlZnMvaGVhZHMhIik7CgloZWFkICs9IDExOwoKCWlmIChkZWxldGUpCgkJZGVsZXRlX2JyYW5jaGVzKGFyZ2MgLSBpLCBhcmd2ICsgaSwgZm9yY2VfZGVsZXRlKTsKCWVsc2UgaWYgKGkgPT0gYXJnYykKCQlwcmludF9yZWZfbGlzdChyZW1vdGVfb25seSk7CgllbHNlIGlmIChpID09IGFyZ2MgLSAxKQoJCWNyZWF0ZV9icmFuY2goYXJndltpXSwgaGVhZCwgZm9yY2VfY3JlYXRlLCByZWZsb2cpOwoJZWxzZSBpZiAoaSA9PSBhcmdjIC0gMikKCQljcmVhdGVfYnJhbmNoKGFyZ3ZbaV0sIGFyZ3ZbaSArIDFdLCBmb3JjZV9jcmVhdGUsIHJlZmxvZyk7CgllbHNlCgkJdXNhZ2UoYnVpbHRpbl9icmFuY2hfdXNhZ2UpOwoKCXJldHVybiAwOwp9Cg==