LyoKICogJElkJAogKgogKiBDb3B5cmlnaHQgqSAyMDAzIEtlaXRoIFBhY2thcmQKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJmY2ludC5oIgoKc3RhdGljIGludApyYXdpbmRleCAoRmNHbHlwaE5hbWUgKmduKTsKCnN0YXRpYyB2b2lkCnNjYW4gKEZJTEUgKmYsIGNoYXIgKmZpbGVuYW1lKTsKCnN0YXRpYyBpbnQKaXNwcmltZSAoaW50IGkpOwoKc3RhdGljIHZvaWQKZmluZF9oYXNoICh2b2lkKTsKCnN0YXRpYyBGY0NoYXIzMgpGY0hhc2hHbHlwaE5hbWUgKGNvbnN0IEZjQ2hhcjggKm5hbWUpOwoKc3RhdGljIHZvaWQKaW5zZXJ0IChGY0dseXBoTmFtZSAqZ24sIEZjR2x5cGhOYW1lICoqdGFibGUsIEZjQ2hhcjMyIGgpOwoKc3RhdGljIHZvaWQKZHVtcCAoRmNHbHlwaE5hbWUgKip0YWJsZSwgY2hhciAqbmFtZSk7CgpzdGF0aWMgRmNHbHlwaE5hbWUgKgpGY0FsbG9jR2x5cGhOYW1lIChGY0NoYXIzMiB1Y3MsIEZjQ2hhcjggKm5hbWUpCnsKICAgIEZjR2x5cGhOYW1lCSpnbjsKCiAgICBnbiA9IG1hbGxvYyAoc2l6ZW9mIChGY0dseXBoTmFtZSkgKyBzdHJsZW4gKChjaGFyICopIG5hbWUpKTsKICAgIGlmICghZ24pCglyZXR1cm4gMDsKICAgIGduLT51Y3MgPSB1Y3M7CiAgICBzdHJjcHkgKChjaGFyICopIGduLT5uYW1lLCAoY2hhciAqKSBuYW1lKTsKICAgIHJldHVybiBnbjsKfQoKc3RhdGljIHZvaWQgCmZhdGFsIChjaGFyICpmaWxlLCBpbnQgbGluZW5vLCBjaGFyICptc2cpCnsKICAgIGZwcmludGYgKHN0ZGVyciwgIiVzOiVkOiAlc1xuIiwgZmlsZSwgbGluZW5vLCBtc2cpOwogICAgZXhpdCAoMSk7Cn0KCiNkZWZpbmUgTUFYX0dMWVBIRklMRQkgICAgMjU2CiNkZWZpbmUgTUFYX0dMWVBITkFNRQkgICAgMTAyNDAKI2RlZmluZSBNQVhfTkFNRUxFTgkgICAgMTAyNAoKRmNHbHlwaE5hbWUgKnJhd1tNQVhfR0xZUEhOQU1FXTsKaW50CSAgICBucmF3OwppbnQJICAgIG1heF9uYW1lX2xlbjsKRmNHbHlwaE5hbWUgKm5hbWVfdG9fdWNzW01BWF9HTFlQSE5BTUUqMl07CkZjR2x5cGhOYW1lICp1Y3NfdG9fbmFtZVtNQVhfR0xZUEhOQU1FKjJdOwppbnQJICAgIGhhc2gsIHJlaGFzaDsKCnN0YXRpYyBpbnQKcmF3aW5kZXggKEZjR2x5cGhOYW1lICpnbikKewogICAgaW50CWk7CgogICAgZm9yIChpID0gMDsgaSA8IG5yYXc7IGkrKykKCWlmIChyYXdbaV0gPT0gZ24pCgkgICAgcmV0dXJuIGk7CiAgICByZXR1cm4gLTE7Cn0KCnN0YXRpYyB2b2lkCnNjYW4gKEZJTEUgKmYsIGNoYXIgKmZpbGVuYW1lKQp7CiAgICBjaGFyCSAgICBidWZbTUFYX05BTUVMRU5dOwogICAgY2hhcgkgICAgbmFtZVtNQVhfTkFNRUxFTl07CiAgICB1bnNpZ25lZCBsb25nICAgdWNzOwogICAgRmNHbHlwaE5hbWUJICAgICpnbjsKICAgIGludAkJICAgIGxpbmVubyA9IDA7CiAgICBpbnQJCSAgICBsZW47CiAgICAKICAgIHdoaWxlIChmZ2V0cyAoYnVmLCBzaXplb2YgKGJ1ZiksIGYpKQogICAgewoJbGluZW5vKys7CglpZiAoc3NjYW5mIChidWYsICIlW147XTslbHhcbiIsIG5hbWUsICZ1Y3MpICE9IDIpCgkgICAgY29udGludWU7CglnbiA9IEZjQWxsb2NHbHlwaE5hbWUgKChGY0NoYXIzMikgdWNzLCAoRmNDaGFyOCAqKSBuYW1lKTsKCWlmICghZ24pCgkgICAgZmF0YWwgKGZpbGVuYW1lLCBsaW5lbm8sICJvdXQgb2YgbWVtb3J5Iik7CglsZW4gPSBzdHJsZW4gKChGY0NoYXI4ICopIG5hbWUpOwoJaWYgKGxlbiA+IG1heF9uYW1lX2xlbikKCSAgICBtYXhfbmFtZV9sZW4gPSBsZW47CglyYXdbbnJhdysrXSA9IGduOwogICAgfQp9CgpzdGF0aWMgaW50IGNvbXBhcmVfc3RyaW5nIChjb25zdCB2b2lkICphLCBjb25zdCB2b2lkICpiKQp7CiAgICBjb25zdCBjaGFyICAgICpjb25zdCAqYXMgPSBhLCAqY29uc3QgKmJzID0gYjsKICAgIHJldHVybiBzdHJjbXAgKCphcywgKmJzKTsKfQoKc3RhdGljIGludCBjb21wYXJlX2dseXBobmFtZSAoY29uc3Qgdm9pZCAqYSwgY29uc3Qgdm9pZCAqYikKewogICAgY29uc3QgRmNHbHlwaE5hbWUJKmNvbnN0ICphZyA9IGEsICpjb25zdCAqYmcgPSBiOwoKICAgIHJldHVybiBzdHJjbXAgKChjaGFyICopICgqYWcpLT5uYW1lLCAoY2hhciAqKSAoKmJnKS0+bmFtZSk7Cn0KCnN0YXRpYyBpbnQKaXNxcnQgKGludCBhKQp7CiAgICBpbnQJICAgIGwsIGgsIG07CgogICAgbCA9IDI7CiAgICBoID0gYS8yOwogICAgd2hpbGUgKChoLWwpID4gMSkKICAgIHsKCW0gPSAoaCtsKSA+PiAxOwoJaWYgKG0gKiBtIDwgYSkKCSAgICBsID0gbTsKCWVsc2UKCSAgICBoID0gbTsKICAgIH0KICAgIHJldHVybiBoOwp9CgpzdGF0aWMgaW50CmlzcHJpbWUgKGludCBpKQp7CiAgICBpbnQJbCwgdDsKCiAgICBpZiAoaSA8IDIpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmICgoaSAmIDEpID09IDApCiAgICB7CglpZiAoaSA9PSAyKQoJICAgIHJldHVybiBGY1RydWU7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGwgPSBpc3FydCAoaSkgKyAxOwogICAgZm9yICh0ID0gMzsgdCA8PSBsOyB0ICs9IDIpCglpZiAoaSAlIHQgPT0gMCkKCSAgICByZXR1cm4gMDsKICAgIHJldHVybiAxOwp9CgovKgogKiBGaW5kIGEgcHJpbWUgcGFpciB0aGF0IGxlYXZlcyBhdCBsZWFzdCAyNSUgb2YgdGhlIGhhc2ggdGFibGUgZW1wdHkKICovCgpzdGF0aWMgdm9pZApmaW5kX2hhc2ggKHZvaWQpCnsKICAgIGludAloOwoKICAgIGggPSBucmF3ICsgbnJhdyAvIDQ7CiAgICBpZiAoKGggJiAxKSA9PSAwKSAKCWgrKzsKICAgIHdoaWxlICghaXNwcmltZShoLTIpIHx8ICFpc3ByaW1lKGgpKQoJaCArPSAyOwogICAgaGFzaCA9IGg7CiAgICByZWhhc2ggPSBoLTI7Cn0KCnN0YXRpYyBGY0NoYXIzMgpGY0hhc2hHbHlwaE5hbWUgKGNvbnN0IEZjQ2hhcjggKm5hbWUpCnsKICAgIEZjQ2hhcjMyCWggPSAwOwogICAgRmNDaGFyOAljOwoKICAgIHdoaWxlICgoYyA9ICpuYW1lKyspKQogICAgewoJaCA9ICgoaCA8PCAxKSB8IChoID4+IDMxKSkgXiBjOwogICAgfQogICAgcmV0dXJuIGg7Cn0KCnN0YXRpYyB2b2lkCmluc2VydCAoRmNHbHlwaE5hbWUgKmduLCBGY0dseXBoTmFtZSAqKnRhYmxlLCBGY0NoYXIzMiBoKQp7CiAgICBpbnQJCWksIHIgPSAwOwoKICAgIGkgPSAoaW50KSAoaCAlIGhhc2gpOwogICAgd2hpbGUgKHRhYmxlW2ldKQogICAgewoJaWYgKCFyKSByID0gKGludCkgKGggJSByZWhhc2gpOwoJaSArPSByOwoJaWYgKGkgPj0gaGFzaCkKCSAgICBpIC09IGhhc2g7CiAgICB9CiAgICB0YWJsZVtpXSA9IGduOwp9CgpzdGF0aWMgdm9pZApkdW1wIChGY0dseXBoTmFtZSAqKnRhYmxlLCBjaGFyICpuYW1lKQp7CiAgICBpbnQJaTsKICAgIAogICAgcHJpbnRmICgic3RhdGljIEZjR2x5cGhOYW1lCSolc1slZF0gPSB7XG4iLCBuYW1lLCBoYXNoKTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgaGFzaDsgaSsrKQoJaWYgKHRhYmxlW2ldKQoJICAgIHByaW50ZiAoIihGY0dseXBoTmFtZSAqKSAmZ2x5cGglZCxcbiIsIHJhd2luZGV4KHRhYmxlW2ldKSk7CgllbHNlCgkgICAgcHJpbnRmICgiMCxcbiIpOwogICAgCiAgICBwcmludGYgKCJ9O1xuIik7Cn0KCmludAptYWluIChpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKICAgIGNoYXIJKmZpbGVzW01BWF9HTFlQSEZJTEVdOwogICAgY2hhcglsaW5lWzEwMjRdOwogICAgRklMRQkqZjsKICAgIGludAkJaTsKICAgIAogICAgaSA9IDA7CiAgICB3aGlsZSAoKisrYXJndikKICAgIHsKCWlmIChpID09IE1BWF9HTFlQSEZJTEUpCgkgICAgZmF0YWwgKCphcmd2LCAwLCAiVG9vIG1hbnkgZ2x5cGhuYW1lIGZpbGVzIik7CglmaWxlc1tpKytdID0gKmFyZ3Y7CiAgICB9CiAgICBmaWxlc1tpXSA9IDA7CiAgICBxc29ydCAoZmlsZXMsIGksIHNpemVvZiAoY2hhciAqKSwgY29tcGFyZV9zdHJpbmcpOwogICAgZm9yIChpID0gMDsgZmlsZXNbaV07IGkrKykgCiAgICB7CglmID0gZm9wZW4gKGZpbGVzW2ldLCAiciIpOwoJaWYgKCFmKQoJICAgIGZhdGFsIChmaWxlc1tpXSwgMCwgc3RyZXJyb3IgKGVycm5vKSk7CglzY2FuIChmLCBmaWxlc1tpXSk7CglmY2xvc2UgKGYpOwogICAgfQogICAgcXNvcnQgKHJhdywgbnJhdywgc2l6ZW9mIChGY0dseXBoTmFtZSAqKSwgY29tcGFyZV9nbHlwaG5hbWUpOwoKICAgIGZpbmRfaGFzaCAoKTsKICAgIAogICAgZm9yIChpID0gMDsgaSA8IG5yYXc7IGkrKykKICAgIHsKCWluc2VydCAocmF3W2ldLCBuYW1lX3RvX3VjcywgRmNIYXNoR2x5cGhOYW1lIChyYXdbaV0tPm5hbWUpKTsKCWluc2VydCAocmF3W2ldLCB1Y3NfdG9fbmFtZSwgcmF3W2ldLT51Y3MpOwogICAgfQogICAgCiAgICAvKgogICAgICogU2NhbiB0aGUgaW5wdXQgdW50aWwgdGhlIG1hcmtlciBpcyBmb3VuZAogICAgICovCiAgICAKICAgIHdoaWxlIChmZ2V0cyAobGluZSwgc2l6ZW9mIChsaW5lKSwgc3RkaW4pKQogICAgewoJaWYgKCFzdHJuY21wIChsaW5lLCAiQEBAIiwgMykpCgkgICAgYnJlYWs7CglmcHV0cyAobGluZSwgc3Rkb3V0KTsKICAgIH0KICAgIAogICAgcHJpbnRmICgiLyogJWQgZ2x5cGhuYW1lcyBpbiAlZCBlbnRyaWVzLCAlZCUlIG9jY3VwYW5jeSAqL1xuXG4iLAoJICAgIG5yYXcsIGhhc2gsIG5yYXcgKiAxMDAgLyBoYXNoKTsKCSAgICAgIAogICAgcHJpbnRmICgiI2RlZmluZSBGQ19HTFlQSE5BTUVfSEFTSCAldVxuIiwgaGFzaCk7CiAgICBwcmludGYgKCIjZGVmaW5lIEZDX0dMWVBITkFNRV9SRUhBU0ggJXVcbiIsIHJlaGFzaCk7CiAgICBwcmludGYgKCIjZGVmaW5lIEZDX0dMWVBITkFNRV9NQVhMRU4gJWRcblxuIiwgbWF4X25hbWVfbGVuKTsKICAgIAogICAgLyoKICAgICAqIER1bXAgb3V0IGVudHJpZXMKICAgICAqLwogICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgbnJhdzsgaSsrKQoJcHJpbnRmICgic3RhdGljIHN0cnVjdCB7IEZjQ2hhcjMyIHVjczsgRmNDaGFyOCBuYW1lWyVkXTsgfSIKCSAgICAgICAgIiBnbHlwaCVkID0geyAweCVseCwgXCIlc1wiIH07XG4iLAoJICAgICAgICAoaW50KSBzdHJsZW4gKHJhd1tpXS0+bmFtZSkgKyAxLAoJCWksICh1bnNpZ25lZCBsb25nKSByYXdbaV0tPnVjcywgcmF3W2ldLT5uYW1lKTsKCiAgICAvKgogICAgICogRHVtcCBvdXQgbmFtZV90b191Y3MgdGFibGUKICAgICAqLwoKICAgIGR1bXAgKG5hbWVfdG9fdWNzLCAibmFtZV90b191Y3MiKTsKICAgIAogICAgLyoKICAgICAqIER1bXAgb3V0IHVjc190b19uYW1lIHRhYmxlCiAgICAgKi8KICAgIGR1bXAgKHVjc190b19uYW1lLCAidWNzX3RvX25hbWUiKTsKCiAgICB3aGlsZSAoZmdldHMgKGxpbmUsIHNpemVvZiAobGluZSksIHN0ZGluKSkKCWZwdXRzIChsaW5lLCBzdGRvdXQpOwogICAgCiAgICBmZmx1c2ggKHN0ZG91dCk7CiAgICBleGl0IChmZXJyb3IgKHN0ZG91dCkpOwp9Cg==