LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNzdHIuYyx2IDEuMTAgMjAwMi8wOC8zMSAyMjoxNzozMiBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJmY2ludC5oIgoKRmNDaGFyOCAqCkZjU3RyQ29weSAoY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNDaGFyOAkqcjsKCiAgICBpZiAoIXMpCglyZXR1cm4gMDsKICAgIHIgPSAoRmNDaGFyOCAqKSBtYWxsb2MgKHN0cmxlbiAoKGNoYXIgKikgcykgKyAxKTsKICAgIGlmICghcikKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1NUUklORywgc3RybGVuICgoY2hhciAqKSBzKSArIDEpOwogICAgc3RyY3B5ICgoY2hhciAqKSByLCAoY2hhciAqKSBzKTsKICAgIHJldHVybiByOwp9CgpGY0NoYXI4ICoKRmNTdHJQbHVzIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIGludAkgICAgbCA9IHN0cmxlbiAoKGNoYXIgKilzMSkgKyBzdHJsZW4gKChjaGFyICopIHMyKSArIDE7CiAgICBGY0NoYXI4ICpzID0gbWFsbG9jIChsKTsKCiAgICBpZiAoIXMpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9TVFJJTkcsIGwpOwogICAgc3RyY3B5ICgoY2hhciAqKSBzLCAoY2hhciAqKSBzMSk7CiAgICBzdHJjYXQgKChjaGFyICopIHMsIChjaGFyICopIHMyKTsKICAgIHJldHVybiBzOwp9Cgp2b2lkCkZjU3RyRnJlZSAoRmNDaGFyOCAqcykKewogICAgRmNNZW1GcmVlIChGQ19NRU1fU1RSSU5HLCBzdHJsZW4gKChjaGFyICopIHMpICsgMSk7CiAgICBmcmVlIChzKTsKfQoKaW50CkZjU3RyQ21wSWdub3JlQ2FzZSAoY29uc3QgRmNDaGFyOCAqczEsIGNvbnN0IEZjQ2hhcjggKnMyKQp7CiAgICBGY0NoYXI4IGMxLCBjMjsKICAgIAogICAgZm9yICg7OykgCiAgICB7CgljMSA9ICpzMSsrOwoJYzIgPSAqczIrKzsKCWlmICghYzEgfHwgKGMxICE9IGMyICYmIChjMSA9IEZjVG9Mb3dlcihjMSkpICE9IChjMiA9IEZjVG9Mb3dlcihjMikpKSkKCSAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAoaW50KSBjMSAtIChpbnQpIGMyOwp9CgppbnQKRmNTdHJDbXBJZ25vcmVCbGFua3NBbmRDYXNlIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIEZjQ2hhcjggYzEsIGMyOwogICAgCiAgICBmb3IgKDs7KSAKICAgIHsKCWRvCgkgICAgYzEgPSAqczErKzsKCXdoaWxlIChjMSA9PSAnICcpOwoJZG8KCSAgICBjMiA9ICpzMisrOwoJd2hpbGUgKGMyID09ICcgJyk7CglpZiAoIWMxIHx8IChjMSAhPSBjMiAmJiAoYzEgPSBGY1RvTG93ZXIoYzEpKSAhPSAoYzIgPSBGY1RvTG93ZXIoYzIpKSkpCgkgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKGludCkgYzEgLSAoaW50KSBjMjsKfQoKaW50CkZjU3RyQ21wIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIEZjQ2hhcjggYzEsIGMyOwogICAgCiAgICBpZiAoczEgPT0gczIpCglyZXR1cm4gMDsKICAgIGZvciAoOzspIAogICAgewoJYzEgPSAqczErKzsKCWMyID0gKnMyKys7CglpZiAoIWMxIHx8IGMxICE9IGMyKQoJICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIChpbnQpIGMxIC0gKGludCkgYzI7Cn0KCmludApGY1V0ZjhUb1VjczQgKGNvbnN0IEZjQ2hhcjggKnNyY19vcmlnLAoJICAgICAgRmNDaGFyMzIJICAgICpkc3QsCgkgICAgICBpbnQJICAgIGxlbikKewogICAgY29uc3QgRmNDaGFyOCAgICpzcmMgPSBzcmNfb3JpZzsKICAgIEZjQ2hhcjgJICAgIHM7CiAgICBpbnQJCSAgICBleHRyYTsKICAgIEZjQ2hhcjMyCSAgICByZXN1bHQ7CgogICAgaWYgKGxlbiA9PSAwKQoJcmV0dXJuIDA7CiAgICAKICAgIHMgPSAqc3JjKys7CiAgICBsZW4tLTsKICAgIAogICAgaWYgKCEocyAmIDB4ODApKQogICAgewoJcmVzdWx0ID0gczsKCWV4dHJhID0gMDsKICAgIH0gCiAgICBlbHNlIGlmICghKHMgJiAweDQwKSkKICAgIHsKCXJldHVybiAtMTsKICAgIH0KICAgIGVsc2UgaWYgKCEocyAmIDB4MjApKQogICAgewoJcmVzdWx0ID0gcyAmIDB4MWY7CglleHRyYSA9IDE7CiAgICB9CiAgICBlbHNlIGlmICghKHMgJiAweDEwKSkKICAgIHsKCXJlc3VsdCA9IHMgJiAweGY7CglleHRyYSA9IDI7CiAgICB9CiAgICBlbHNlIGlmICghKHMgJiAweDA4KSkKICAgIHsKCXJlc3VsdCA9IHMgJiAweDA3OwoJZXh0cmEgPSAzOwogICAgfQogICAgZWxzZSBpZiAoIShzICYgMHgwNCkpCiAgICB7CglyZXN1bHQgPSBzICYgMHgwMzsKCWV4dHJhID0gNDsKICAgIH0KICAgIGVsc2UgaWYgKCAhIChzICYgMHgwMikpCiAgICB7CglyZXN1bHQgPSBzICYgMHgwMTsKCWV4dHJhID0gNTsKICAgIH0KICAgIGVsc2UKICAgIHsKCXJldHVybiAtMTsKICAgIH0KICAgIGlmIChleHRyYSA+IGxlbikKCXJldHVybiAtMTsKICAgIAogICAgd2hpbGUgKGV4dHJhLS0pCiAgICB7CglyZXN1bHQgPDw9IDY7CglzID0gKnNyYysrOwoJCglpZiAoKHMgJiAweGMwKSAhPSAweDgwKQoJICAgIHJldHVybiAtMTsKCQoJcmVzdWx0IHw9IHMgJiAweDNmOwogICAgfQogICAgKmRzdCA9IHJlc3VsdDsKICAgIHJldHVybiBzcmMgLSBzcmNfb3JpZzsKfQoKRmNCb29sCkZjVXRmOExlbiAoY29uc3QgRmNDaGFyOCAgICAqc3RyaW5nLAoJICAgaW50CQkgICAgbGVuLAoJICAgaW50CQkgICAgKm5jaGFyLAoJICAgaW50CQkgICAgKndjaGFyKQp7CiAgICBpbnQJCW47CiAgICBpbnQJCWNsZW47CiAgICBGY0NoYXIzMgljOwogICAgRmNDaGFyMzIJbWF4OwogICAgCiAgICBuID0gMDsKICAgIG1heCA9IDA7CiAgICB3aGlsZSAobGVuKQogICAgewoJY2xlbiA9IEZjVXRmOFRvVWNzNCAoc3RyaW5nLCAmYywgbGVuKTsKCWlmIChjbGVuIDw9IDApCS8qIG1hbGZvcm1lZCBVVEY4IHN0cmluZyAqLwoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKGMgPiBtYXgpCgkgICAgbWF4ID0gYzsKCXN0cmluZyArPSBjbGVuOwoJbGVuIC09IGNsZW47CgluKys7CiAgICB9CiAgICAqbmNoYXIgPSBuOwogICAgaWYgKG1heCA+PSAweDEwMDAwKQoJKndjaGFyID0gNDsKICAgIGVsc2UgaWYgKG1heCA+IDB4MTAwKQoJKndjaGFyID0gMjsKICAgIGVsc2UKCSp3Y2hhciA9IDE7CiAgICByZXR1cm4gRmNUcnVlOwp9CgppbnQKRmNVY3M0VG9VdGY4IChGY0NoYXIzMgl1Y3M0LAoJICAgICAgRmNDaGFyOAlkZXN0W0ZDX1VURjhfTUFYX0xFTl0pCnsKICAgIGludAliaXRzOwogICAgRmNDaGFyOCAqZCA9IGRlc3Q7CiAgICAKICAgIGlmICAgICAgKHVjczQgPCAgICAgICAweDgwKSB7ICAqZCsrPSAgdWNzNDsgICAgICAgICAgICAgICAgICAgICAgICAgYml0cz0gLTY7IH0KICAgIGVsc2UgaWYgKHVjczQgPCAgICAgIDB4ODAwKSB7ICAqZCsrPSAoKHVjczQgPj4gIDYpICYgMHgxRikgfCAweEMwOyAgYml0cz0gIDA7IH0KICAgIGVsc2UgaWYgKHVjczQgPCAgICAweDEwMDAwKSB7ICAqZCsrPSAoKHVjczQgPj4gMTIpICYgMHgwRikgfCAweEUwOyAgYml0cz0gIDY7IH0KICAgIGVsc2UgaWYgKHVjczQgPCAgIDB4MjAwMDAwKSB7ICAqZCsrPSAoKHVjczQgPj4gMTgpICYgMHgwNykgfCAweEYwOyAgYml0cz0gMTI7IH0KICAgIGVsc2UgaWYgKHVjczQgPCAgMHg0MDAwMDAwKSB7ICAqZCsrPSAoKHVjczQgPj4gMjQpICYgMHgwMykgfCAweEY4OyAgYml0cz0gMTg7IH0KICAgIGVsc2UgaWYgKHVjczQgPCAweDgwMDAwMDAwKSB7ICAqZCsrPSAoKHVjczQgPj4gMzApICYgMHgwMSkgfCAweEZDOyAgYml0cz0gMjQ7IH0KICAgIGVsc2UgcmV0dXJuIDA7CgogICAgZm9yICggOyBiaXRzID49IDA7IGJpdHMtPSA2KSB7CgkqZCsrPSAoKHVjczQgPj4gYml0cykgJiAweDNGKSB8IDB4ODA7CiAgICB9CiAgICByZXR1cm4gZCAtIGRlc3Q7Cn0KCiNkZWZpbmUgR2V0VXRmMTYoc3JjLGVuZGlhbikgXAogICAgKChGY0NoYXIxNikgKChzcmMpW2VuZGlhbiA9PSBGY0VuZGlhbkJpZyA/IDAgOiAxXSA8PCA4KSB8IFwKICAgICAoRmNDaGFyMTYpICgoc3JjKVtlbmRpYW4gPT0gRmNFbmRpYW5CaWcgPyAxIDogMF0pKQoKaW50CkZjVXRmMTZUb1VjczQgKGNvbnN0IEZjQ2hhcjgJKnNyY19vcmlnLAoJICAgICAgIEZjRW5kaWFuCQllbmRpYW4sCgkgICAgICAgRmNDaGFyMzIJCSpkc3QsCgkgICAgICAgaW50CQlsZW4pCS8qIGluIGJ5dGVzICovCnsKICAgIGNvbnN0IEZjQ2hhcjggICAqc3JjID0gc3JjX29yaWc7CiAgICBGY0NoYXIxNgkgICAgYSwgYjsKICAgIEZjQ2hhcjMyCSAgICByZXN1bHQ7CgogICAgaWYgKGxlbiA8IDIpCglyZXR1cm4gMDsKICAgIAogICAgYSA9IEdldFV0ZjE2IChzcmMsIGVuZGlhbik7IHNyYyArPSAyOyBsZW4gLT0gMjsKICAgIAogICAgLyogCiAgICAgKiBDaGVjayBmb3Igc3Vycm9nYXRlIAogICAgICovCiAgICBpZiAoKGEgJiAweGZjMDApID09IDB4ZDgwMCkKICAgIHsKCWlmIChsZW4gPCAyKQoJICAgIHJldHVybiAwOwoJYiA9IEdldFV0ZjE2IChzcmMsIGVuZGlhbik7IHNyYyArPSAyOyBsZW4gLT0gMjsKCS8qCgkgKiBDaGVjayBmb3IgaW52YWxpZCBzdXJyb2dhdGUgc2VxdWVuY2UKCSAqLwoJaWYgKChiICYgMHhmYzAwKSAhPSAweGRjMDApCgkgICAgcmV0dXJuIDA7CglyZXN1bHQgPSAoKCgoRmNDaGFyMzIpIGEgJiAweDNmZikgPDwgMTApIHwKCQkgICgoRmNDaGFyMzIpIGIgJiAweDNmZikpICsgMHgxMDAwMDsKICAgIH0KICAgIGVsc2UKCXJlc3VsdCA9IGE7CiAgICAqZHN0ID0gcmVzdWx0OwogICAgcmV0dXJuIHNyYyAtIHNyY19vcmlnOwp9CgpGY0Jvb2wKRmNVdGYxNkxlbiAoY29uc3QgRmNDaGFyOCAgICpzdHJpbmcsCgkgICAgRmNFbmRpYW4JICAgIGVuZGlhbiwKCSAgICBpbnQJCSAgICBsZW4sCS8qIGluIGJ5dGVzICovCgkgICAgaW50CQkgICAgKm5jaGFyLAoJICAgIGludAkJICAgICp3Y2hhcikKewogICAgaW50CQluOwogICAgaW50CQljbGVuOwogICAgRmNDaGFyMzIJYzsKICAgIEZjQ2hhcjMyCW1heDsKICAgIAogICAgbiA9IDA7CiAgICBtYXggPSAwOwogICAgd2hpbGUgKGxlbikKICAgIHsKCWNsZW4gPSBGY1V0ZjE2VG9VY3M0IChzdHJpbmcsIGVuZGlhbiwgJmMsIGxlbik7CglpZiAoY2xlbiA8PSAwKQkvKiBtYWxmb3JtZWQgVVRGOCBzdHJpbmcgKi8KCSAgICByZXR1cm4gRmNGYWxzZTsKCWlmIChjID4gbWF4KQoJICAgIG1heCA9IGM7CglzdHJpbmcgKz0gY2xlbjsKCWxlbiAtPSBjbGVuOwoJbisrOwogICAgfQogICAgKm5jaGFyID0gbjsKICAgIGlmIChtYXggPj0gMHgxMDAwMCkKCSp3Y2hhciA9IDQ7CiAgICBlbHNlIGlmIChtYXggPiAweDEwMCkKCSp3Y2hhciA9IDI7CiAgICBlbHNlCgkqd2NoYXIgPSAxOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKdm9pZApGY1N0ckJ1ZkluaXQgKEZjU3RyQnVmICpidWYsIEZjQ2hhcjggKmluaXQsIGludCBzaXplKQp7CiAgICBidWYtPmJ1ZiA9IGluaXQ7CiAgICBidWYtPmFsbG9jYXRlZCA9IEZjRmFsc2U7CiAgICBidWYtPmZhaWxlZCA9IEZjRmFsc2U7CiAgICBidWYtPmxlbiA9IDA7CiAgICBidWYtPnNpemUgPSBzaXplOwp9Cgp2b2lkCkZjU3RyQnVmRGVzdHJveSAoRmNTdHJCdWYgKmJ1ZikKewogICAgaWYgKGJ1Zi0+YWxsb2NhdGVkKQogICAgewoJRmNNZW1GcmVlIChGQ19NRU1fU1RSQlVGLCBidWYtPnNpemUpOwoJZnJlZSAoYnVmLT5idWYpOwoJRmNTdHJCdWZJbml0IChidWYsIDAsIDApOwogICAgfQp9CgpGY0NoYXI4ICoKRmNTdHJCdWZEb25lIChGY1N0ckJ1ZiAqYnVmKQp7CiAgICBGY0NoYXI4ICpyZXQ7CgogICAgcmV0ID0gbWFsbG9jIChidWYtPmxlbiArIDEpOwogICAgaWYgKHJldCkKICAgIHsKCUZjTWVtQWxsb2MgKEZDX01FTV9TVFJJTkcsIGJ1Zi0+bGVuICsgMSk7CgltZW1jcHkgKHJldCwgYnVmLT5idWYsIGJ1Zi0+bGVuKTsKCXJldFtidWYtPmxlbl0gPSAnXDAnOwogICAgfQogICAgRmNTdHJCdWZEZXN0cm95IChidWYpOwogICAgcmV0dXJuIHJldDsKfQoKRmNCb29sCkZjU3RyQnVmQ2hhciAoRmNTdHJCdWYgKmJ1ZiwgRmNDaGFyOCBjKQp7CiAgICBpZiAoYnVmLT5sZW4gPT0gYnVmLT5zaXplKQogICAgewoJRmNDaGFyOAkgICAgKm5ldzsKCWludAkgICAgc2l6ZTsKCglpZiAoYnVmLT5hbGxvY2F0ZWQpCgl7CgkgICAgc2l6ZSA9IGJ1Zi0+c2l6ZSAqIDI7CgkgICAgbmV3ID0gcmVhbGxvYyAoYnVmLT5idWYsIHNpemUpOwoJfQoJZWxzZQoJewoJICAgIHNpemUgPSBidWYtPnNpemUgKyAxMDI0OwoJICAgIG5ldyA9IG1hbGxvYyAoc2l6ZSk7CgkgICAgaWYgKG5ldykKCSAgICB7CgkJYnVmLT5hbGxvY2F0ZWQgPSBGY1RydWU7CgkJbWVtY3B5IChuZXcsIGJ1Zi0+YnVmLCBidWYtPmxlbik7CgkgICAgfQoJfQoJaWYgKCFuZXcpCgl7CgkgICAgYnVmLT5mYWlsZWQgPSBGY1RydWU7CgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl9CglpZiAoYnVmLT5zaXplKQoJICAgIEZjTWVtRnJlZSAoRkNfTUVNX1NUUkJVRiwgYnVmLT5zaXplKTsKCUZjTWVtQWxsb2MgKEZDX01FTV9TVFJCVUYsIHNpemUpOwoJYnVmLT5zaXplID0gc2l6ZTsKCWJ1Zi0+YnVmID0gbmV3OwogICAgfQogICAgYnVmLT5idWZbYnVmLT5sZW4rK10gPSBjOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjU3RyQnVmU3RyaW5nIChGY1N0ckJ1ZiAqYnVmLCBjb25zdCBGY0NoYXI4ICpzKQp7CiAgICBGY0NoYXI4IGM7CiAgICB3aGlsZSAoKGMgPSAqcysrKSkKCWlmICghRmNTdHJCdWZDaGFyIChidWYsIGMpKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjU3RyQnVmRGF0YSAoRmNTdHJCdWYgKmJ1ZiwgY29uc3QgRmNDaGFyOCAqcywgaW50IGxlbikKewogICAgd2hpbGUgKGxlbi0tID4gMCkKCWlmICghRmNTdHJCdWZDaGFyIChidWYsICpzKyspKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjU3RyVXNlc0hvbWUgKGNvbnN0IEZjQ2hhcjggKnMpCnsKICAgIHJldHVybiAqcyA9PSAnfic7Cn0KCkZjQ2hhcjggKgpGY1N0ckNvcHlGaWxlbmFtZSAoY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNDaGFyOCAqbmV3OwogICAgCiAgICBpZiAoKnMgPT0gJ34nKQogICAgewoJRmNDaGFyOAkqaG9tZSA9IEZjQ29uZmlnSG9tZSAoKTsKCWludAlzaXplOwoJaWYgKCFob21lKQoJICAgIHJldHVybiAwOwoJc2l6ZSA9IHN0cmxlbiAoKGNoYXIgKikgaG9tZSkgKyBzdHJsZW4gKChjaGFyICopIHMpOwoJbmV3ID0gKEZjQ2hhcjggKikgbWFsbG9jIChzaXplKTsKCWlmICghbmV3KQoJICAgIHJldHVybiAwOwoJRmNNZW1BbGxvYyAoRkNfTUVNX1NUUklORywgc2l6ZSk7CglzdHJjcHkgKChjaGFyICopIG5ldywgKGNoYXIgKikgaG9tZSk7CglzdHJjYXQgKChjaGFyICopIG5ldywgKGNoYXIgKikgcyArIDEpOwogICAgfQogICAgZWxzZQogICAgewoJaW50CXNpemUgPSBzdHJsZW4gKChjaGFyICopIHMpICsgMTsKCW5ldyA9IChGY0NoYXI4ICopIG1hbGxvYyAoc2l6ZSk7CglpZiAoIW5ldykKCSAgICByZXR1cm4gMDsKCUZjTWVtQWxsb2MgKEZDX01FTV9TVFJJTkcsIHNpemUpOwoJc3RyY3B5ICgoY2hhciAqKSBuZXcsIChjb25zdCBjaGFyICopIHMpOwogICAgfQogICAgcmV0dXJuIG5ldzsKfQoKRmNDaGFyOCAqCkZjU3RyTGFzdFNsYXNoIChjb25zdCBGY0NoYXI4ICAqcGF0aCkKewogICAgRmNDaGFyOAkgICAgKnNsYXNoOwoKICAgIHNsYXNoID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNvbnN0IGNoYXIgKikgcGF0aCwgJy8nKTsKI2lmZGVmIF9XSU4zMgogICAgewogICAgICAgIEZjQ2hhcjggICAgICpiYWNrc2xhc2g7CgoJYmFja3NsYXNoID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNvbnN0IGNoYXIgKikgcGF0aCwgJ1xcJyk7CglpZiAoIXNsYXNoIHx8IChiYWNrc2xhc2ggJiYgYmFja3NsYXNoID4gc2xhc2gpKQoJICAgIHNsYXNoID0gYmFja3NsYXNoOwogICAgfQojZW5kaWYKCiAgICByZXR1cm4gc2xhc2g7Cn0KICAKRmNDaGFyOCAqCkZjU3RyRGlybmFtZSAoY29uc3QgRmNDaGFyOCAqZmlsZSkKewogICAgRmNDaGFyOCAqc2xhc2g7CiAgICBGY0NoYXI4ICpkaXI7CgogICAgc2xhc2ggPSBGY1N0ckxhc3RTbGFzaCAoZmlsZSk7CiAgICBpZiAoIXNsYXNoKQoJcmV0dXJuIEZjU3RyQ29weSAoKEZjQ2hhcjggKikgIi4iKTsKICAgIGRpciA9IG1hbGxvYyAoKHNsYXNoIC0gZmlsZSkgKyAxKTsKICAgIGlmICghZGlyKQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fU1RSSU5HLCAoc2xhc2ggLSBmaWxlKSArIDEpOwogICAgc3RybmNweSAoKGNoYXIgKikgZGlyLCAoY29uc3QgY2hhciAqKSBmaWxlLCBzbGFzaCAtIGZpbGUpOwogICAgZGlyW3NsYXNoIC0gZmlsZV0gPSAnXDAnOwogICAgcmV0dXJuIGRpcjsKfQoKRmNDaGFyOCAqCkZjU3RyQmFzZW5hbWUgKGNvbnN0IEZjQ2hhcjggKmZpbGUpCnsKICAgIEZjQ2hhcjggKnNsYXNoOwoKICAgIHNsYXNoID0gRmNTdHJMYXN0U2xhc2ggKGZpbGUpOwogICAgaWYgKCFzbGFzaCkKCXJldHVybiBGY1N0ckNvcHkgKGZpbGUpOwogICAgcmV0dXJuIEZjU3RyQ29weSAoc2xhc2ggKyAxKTsKfQoKRmNTdHJTZXQgKgpGY1N0clNldENyZWF0ZSAodm9pZCkKewogICAgRmNTdHJTZXQJKnNldCA9IG1hbGxvYyAoc2l6ZW9mIChGY1N0clNldCkpOwogICAgaWYgKCFzZXQpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9TVFJTRVQsIHNpemVvZiAoRmNTdHJTZXQpKTsKICAgIHNldC0+cmVmID0gMTsKICAgIHNldC0+bnVtID0gMDsKICAgIHNldC0+c2l6ZSA9IDA7CiAgICBzZXQtPnN0cnMgPSAwOwogICAgcmV0dXJuIHNldDsKfQoKc3RhdGljIEZjQm9vbApfRmNTdHJTZXRBcHBlbmQgKEZjU3RyU2V0ICpzZXQsIEZjQ2hhcjggKnMpCnsKICAgIGlmIChGY1N0clNldE1lbWJlciAoc2V0LCBzKSkKICAgIHsKCUZjU3RyRnJlZSAocyk7CglyZXR1cm4gRmNUcnVlOwogICAgfQogICAgaWYgKHNldC0+bnVtID09IHNldC0+c2l6ZSkKICAgIHsKCUZjQ2hhcjgJKipzdHJzID0gbWFsbG9jICgoc2V0LT5zaXplICsgMikgKiBzaXplb2YgKEZjQ2hhcjggKikpOwoKCWlmICghc3RycykKCSAgICByZXR1cm4gRmNGYWxzZTsKCUZjTWVtQWxsb2MgKEZDX01FTV9TVFJTRVQsIChzZXQtPnNpemUgKyAyKSAqIHNpemVvZiAoRmNDaGFyOCAqKSk7CglzZXQtPnNpemUgPSBzZXQtPnNpemUgKyAxOwoJaWYgKHNldC0+bnVtKQoJICAgIG1lbWNweSAoc3Rycywgc2V0LT5zdHJzLCBzZXQtPm51bSAqIHNpemVvZiAoRmNDaGFyOCAqKSk7CglpZiAoc2V0LT5zdHJzKQoJICAgIGZyZWUgKHNldC0+c3Rycyk7CglzZXQtPnN0cnMgPSBzdHJzOwogICAgfQogICAgc2V0LT5zdHJzW3NldC0+bnVtKytdID0gczsKICAgIHNldC0+c3Ryc1tzZXQtPm51bV0gPSAwOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjU3RyU2V0TWVtYmVyIChGY1N0clNldCAqc2V0LCBjb25zdCBGY0NoYXI4ICpzKQp7CiAgICBpbnQJaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgc2V0LT5udW07IGkrKykKCWlmICghRmNTdHJDbXAgKHNldC0+c3Ryc1tpXSwgcykpCgkgICAgcmV0dXJuIEZjVHJ1ZTsKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpGY0Jvb2wKRmNTdHJTZXRFcXVhbCAoRmNTdHJTZXQgKnNhLCBGY1N0clNldCAqc2IpCnsKICAgIGludAlpOwogICAgaWYgKHNhLT5udW0gIT0gc2ItPm51bSkKCXJldHVybiBGY0ZhbHNlOwogICAgZm9yIChpID0gMDsgaSA8IHNhLT5udW07IGkrKykKCWlmICghRmNTdHJTZXRNZW1iZXIgKHNiLCBzYS0+c3Ryc1tpXSkpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJTZXRBZGQgKEZjU3RyU2V0ICpzZXQsIGNvbnN0IEZjQ2hhcjggKnMpCnsKICAgIEZjQ2hhcjggKm5ldyA9IEZjU3RyQ29weSAocyk7CiAgICBpZiAoIW5ldykKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKCFfRmNTdHJTZXRBcHBlbmQgKHNldCwgbmV3KSkKICAgIHsKCUZjU3RyRnJlZSAobmV3KTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjU3RyU2V0QWRkRmlsZW5hbWUgKEZjU3RyU2V0ICpzZXQsIGNvbnN0IEZjQ2hhcjggKnMpCnsKICAgIEZjQ2hhcjggKm5ldyA9IEZjU3RyQ29weUZpbGVuYW1lIChzKTsKICAgIGlmICghbmV3KQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoIV9GY1N0clNldEFwcGVuZCAoc2V0LCBuZXcpKQogICAgewoJRmNTdHJGcmVlIChuZXcpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJTZXREZWwgKEZjU3RyU2V0ICpzZXQsIGNvbnN0IEZjQ2hhcjggKnMpCnsKICAgIGludAlpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBzZXQtPm51bTsgaSsrKQoJaWYgKCFGY1N0ckNtcCAoc2V0LT5zdHJzW2ldLCBzKSkKCXsKCSAgICBGY1N0ckZyZWUgKHNldC0+c3Ryc1tpXSk7CgkgICAgLyoKCSAgICAgKiBjb3B5IHJlbWFpbmluZyBzdHJpbmcgcG9pbnRlcnMgYW5kIHRyYWlsaW5nCgkgICAgICogTlVMTAoJICAgICAqLwoJICAgIG1lbW1vdmUgKCZzZXQtPnN0cnNbaV0sICZzZXQtPnN0cnNbaSsxXSwgCgkJICAgICAoc2V0LT5udW0gLSBpKSAqIHNpemVvZiAoRmNDaGFyOCAqKSk7CgkgICAgc2V0LT5udW0tLTsKCSAgICByZXR1cm4gRmNUcnVlOwoJfQogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCnZvaWQKRmNTdHJTZXREZXN0cm95IChGY1N0clNldCAqc2V0KQp7CiAgICBpZiAoLS1zZXQtPnJlZiA9PSAwKQogICAgewoJaW50CWk7CiAgICAKCWZvciAoaSA9IDA7IGkgPCBzZXQtPm51bTsgaSsrKQoJICAgIEZjU3RyRnJlZSAoc2V0LT5zdHJzW2ldKTsKCUZjTWVtRnJlZSAoRkNfTUVNX1NUUlNFVCwgKHNldC0+c2l6ZSkgKiBzaXplb2YgKEZjQ2hhcjggKikpOwoJaWYgKHNldC0+c3RycykKCSAgICBmcmVlIChzZXQtPnN0cnMpOwoJRmNNZW1GcmVlIChGQ19NRU1fU1RSU0VULCBzaXplb2YgKEZjU3RyU2V0KSk7CglmcmVlIChzZXQpOwogICAgfQp9CgpGY1N0ckxpc3QgKgpGY1N0ckxpc3RDcmVhdGUgKEZjU3RyU2V0ICpzZXQpCnsKICAgIEZjU3RyTGlzdAkqbGlzdDsKCiAgICBsaXN0ID0gbWFsbG9jIChzaXplb2YgKEZjU3RyTGlzdCkpOwogICAgaWYgKCFsaXN0KQoJcmV0dXJuIDA7CiAgICBGY01lbUFsbG9jIChGQ19NRU1fU1RSTElTVCwgc2l6ZW9mIChGY1N0ckxpc3QpKTsKICAgIGxpc3QtPnNldCA9IHNldDsKICAgIHNldC0+cmVmKys7CiAgICBsaXN0LT5uID0gMDsKICAgIHJldHVybiBsaXN0Owp9CgpGY0NoYXI4ICoKRmNTdHJMaXN0TmV4dCAoRmNTdHJMaXN0ICpsaXN0KQp7CiAgICBpZiAobGlzdC0+biA+PSBsaXN0LT5zZXQtPm51bSkKCXJldHVybiAwOwogICAgcmV0dXJuIGxpc3QtPnNldC0+c3Ryc1tsaXN0LT5uKytdOwp9Cgp2b2lkCkZjU3RyTGlzdERvbmUgKEZjU3RyTGlzdCAqbGlzdCkKewogICAgRmNTdHJTZXREZXN0cm95IChsaXN0LT5zZXQpOwogICAgRmNNZW1GcmVlIChGQ19NRU1fU1RSTElTVCwgc2l6ZW9mIChGY1N0ckxpc3QpKTsKICAgIGZyZWUgKGxpc3QpOwp9Cg==