LyoKICogU3VwcG9ydCBmdW5jdGlvbnMuICBFeHBvcnRlZCBmdW5jdGlvbnMgYXJlIHByb3RvdHlwZWQgaW4gc3VuZHJpZXMuaC4KICoKICogYWRkZWQgZmNudGwgbG9ja2luZyBieSBLamV0aWwgVC4gKGtqZXRpbGhvQG1hdGgudWlvLm5vKSAtIGFlYiwgOTUwOTI3CiAqCiAqIDE5OTktMDItMjIgQXJrYWRpdXN6IE1ptmtpZXdpY3ogPG1pc2lla0BwbGQuT1JHLlBMPgogKiAtIGFkZGVkIE5hdGl2ZSBMYW5ndWFnZSBTdXBwb3J0CiAqCiAqLwojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxtbnRlbnQuaD4JCS8qIGZvciBNTlRUWVBFX1NXQVAgKi8KCiNpbmNsdWRlICJjYW5vbmljYWxpemUuaCIKCiNpbmNsdWRlICJmc3RhYi5oIgojaW5jbHVkZSAic3VuZHJpZXMuaCIKI2luY2x1ZGUgInhtYWxsb2MuaCIKI2luY2x1ZGUgIm5scy5oIgoKaW50IG1vdW50X3F1aWV0OwppbnQgdmVyYm9zZTsKaW50IG5vY2Fub25pY2FsaXplOwpjaGFyICpwcm9nbmFtZTsKCmNoYXIgKgp4c3RybmR1cCAoY29uc3QgY2hhciAqcywgaW50IG4pIHsKICAgICBjaGFyICp0OwoKICAgICBpZiAocyA9PSBOVUxMKQoJICBkaWUgKEVYX1NPRlRXQVJFLCBfKCJidWcgaW4geHN0cm5kdXAgY2FsbCIpKTsKCiAgICAgdCA9IHhtYWxsb2MobisxKTsKICAgICBzdHJuY3B5KHQscyxuKTsKICAgICB0W25dID0gMDsKCiAgICAgcmV0dXJuIHQ7Cn0KCi8qIHJlYWxsb2NhdGVzIGl0cyBmaXJzdCBhcmcgLSB0eXBpY2FsIHVzZTogcyA9IHhzdHJjb25jYXQzKHMsdCx1KTsgKi8KY2hhciAqCnhzdHJjb25jYXQzIChjaGFyICpzLCBjb25zdCBjaGFyICp0LCBjb25zdCBjaGFyICp1KSB7CiAgICAgc2l6ZV90IGxlbiA9IDA7CgogICAgIGxlbiA9IChzID8gc3RybGVuKHMpIDogMCkgKyAodCA/IHN0cmxlbih0KSA6IDApICsgKHUgPyBzdHJsZW4odSkgOiAwKTsKCiAgICAgaWYgKCFsZW4pCgkgICAgIHJldHVybiBOVUxMOwogICAgIGlmICghcykgewoJICAgICBzID0geG1hbGxvYyhsZW4gKyAxKTsKCSAgICAgKnMgPSAnXDAnOwogICAgIH0KICAgICBlbHNlCgkgICAgIHMgPSB4cmVhbGxvYyhzLCBsZW4gKyAxKTsKICAgICBpZiAodCkKCSAgICAgc3RyY2F0KHMsIHQpOwogICAgIGlmICh1KQoJICAgICBzdHJjYXQocywgdSk7CiAgICAgcmV0dXJuIHM7Cn0KCi8qIGZyZWVzIGl0cyBmaXJzdCBhcmcgLSB0eXBpY2FsIHVzZTogcyA9IHhzdHJjb25jYXQ0KHMsdCx1LHYpOyAqLwpjaGFyICoKeHN0cmNvbmNhdDQgKGNoYXIgKnMsIGNvbnN0IGNoYXIgKnQsIGNvbnN0IGNoYXIgKnUsIGNvbnN0IGNoYXIgKnYpIHsKICAgICBzaXplX3QgbGVuID0gMDsKCiAgICAgbGVuID0gKHMgPyBzdHJsZW4ocykgOiAwKSArICh0ID8gc3RybGVuKHQpIDogMCkgKwoJCSh1ID8gc3RybGVuKHUpIDogMCkgKyAodiA/IHN0cmxlbih2KSA6IDApOwoKICAgICBpZiAoIWxlbikKCSAgICAgcmV0dXJuIE5VTEw7CiAgICAgaWYgKCFzKSB7CgkgICAgIHMgPSB4bWFsbG9jKGxlbiArIDEpOwoJICAgICAqcyA9ICdcMCc7CiAgICAgfQogICAgIGVsc2UKCSAgICAgcyA9IHhyZWFsbG9jKHMsIGxlbiArIDEpOwogICAgIGlmICh0KQoJICAgICBzdHJjYXQocywgdCk7CiAgICAgaWYgKHUpCgkgICAgIHN0cmNhdChzLCB1KTsKICAgICBpZiAodikKCSAgICAgc3RyY2F0KHMsIHYpOwogICAgIHJldHVybiBzOwoKCn0KCi8qIENhbGwgdGhpcyB3aXRoIFNJR19CTE9DSyB0byBibG9jayBhbmQgU0lHX1VOQkxPQ0sgdG8gdW5ibG9jay4gICovCnZvaWQKYmxvY2tfc2lnbmFscyAoaW50IGhvdykgewogICAgIHNpZ3NldF90IHNpZ3M7CgogICAgIHNpZ2ZpbGxzZXQgKCZzaWdzKTsKICAgICBzaWdkZWxzZXQoJnNpZ3MsIFNJR1RSQVApOwogICAgIHNpZ2RlbHNldCgmc2lncywgU0lHU0VHVik7CiAgICAgc2lncHJvY21hc2sgKGhvdywgJnNpZ3MsIChzaWdzZXRfdCAqKSAwKTsKfQoKCi8qIE5vbi1mYXRhbCBlcnJvci4gIFByaW50IG1lc3NhZ2UgYW5kIHJldHVybi4gICovCi8qIChwcmludCB0aGUgbWVzc2FnZSBpbiBhIHNpbmdsZSBwcmludGYsIGluIGFuIGF0dGVtcHQKICAgIHRvIGF2b2lkIG1peGluZyBvdXRwdXQgb2Ygc2V2ZXJhbCB0aHJlYWRzKSAqLwp2b2lkCmVycm9yIChjb25zdCBjaGFyICpmbXQsIC4uLikgewogICAgIHZhX2xpc3QgYXJnczsKCiAgICAgaWYgKG1vdW50X3F1aWV0KQoJICByZXR1cm47CiAgICAgdmFfc3RhcnQgKGFyZ3MsIGZtdCk7CiAgICAgdmZwcmludGYgKHN0ZGVyciwgZm10LCBhcmdzKTsKICAgICB2YV9lbmQgKGFyZ3MpOwogICAgIGZwdXRjKCdcbicsIHN0ZGVycik7Cn0KCi8qIEZhdGFsIGVycm9yLiAgUHJpbnQgbWVzc2FnZSBhbmQgZXhpdC4gICovCnZvaWQKZGllKGludCBlcnIsIGNvbnN0IGNoYXIgKmZtdCwgLi4uKSB7Cgl2YV9saXN0IGFyZ3M7CgoJdmFfc3RhcnQoYXJncywgZm10KTsKCXZmcHJpbnRmKHN0ZGVyciwgZm10LCBhcmdzKTsKCWZwcmludGYoc3RkZXJyLCAiXG4iKTsKCXZhX2VuZChhcmdzKTsKCglleGl0KGVycik7Cn0KCi8qIFRydWUgaWYgZnN0eXBlcyBtYXRjaC4gIE51bGwgKlRZUEVTIG1lYW5zIG1hdGNoIGFueXRoaW5nLAogICBleGNlcHQgdGhhdCBzd2FwIHR5cGVzIGFsd2F5cyByZXR1cm4gZmFsc2UuICovCi8qIEFjY2VwdCBub25mcyxwcm9jLGRldnB0cyBhbmQgbm9uZnMsbm9wcm9jLG5vZGV2cHRzCiAgIHdpdGggdGhlIHNhbWUgbWVhbmluZy4gKi8KaW50Cm1hdGNoaW5nX3R5cGUgKGNvbnN0IGNoYXIgKnR5cGUsIGNvbnN0IGNoYXIgKnR5cGVzKSB7CiAgICAgaW50IG5vOwkJCS8qIG5lZ2F0ZWQgdHlwZXMgbGlzdCAqLwogICAgIGludCBsZW47CiAgICAgY29uc3QgY2hhciAqcDsKCiAgICAgaWYgKHN0cmVxICh0eXBlLCBNTlRUWVBFX1NXQVApKQoJICByZXR1cm4gMDsKICAgICBpZiAodHlwZXMgPT0gTlVMTCkKCSAgcmV0dXJuIDE7CgogICAgIG5vID0gMDsKICAgICBpZiAoIXN0cm5jbXAodHlwZXMsICJubyIsIDIpKSB7CgkgIG5vID0gMTsKCSAgdHlwZXMgKz0gMjsKICAgICB9CgogICAgIC8qIERvZXMgdHlwZSBvY2N1ciBpbiB0eXBlcywgc2VwYXJhdGVkIGJ5IGNvbW1hcz8gKi8KICAgICBsZW4gPSBzdHJsZW4odHlwZSk7CiAgICAgcCA9IHR5cGVzOwogICAgIHdoaWxlKDEpIHsKCSAgICAgaWYgKCFzdHJuY21wKHAsICJubyIsIDIpICYmICFzdHJuY21wKHArMiwgdHlwZSwgbGVuKSAmJgoJCSAocFtsZW4rMl0gPT0gMCB8fCBwW2xlbisyXSA9PSAnLCcpKQoJCSAgICAgcmV0dXJuIDA7CgkgICAgIGlmIChzdHJuY21wKHAsIHR5cGUsIGxlbikgPT0gMCAmJgoJCSAocFtsZW5dID09IDAgfHwgcFtsZW5dID09ICcsJykpCgkJICAgICByZXR1cm4gIW5vOwoJICAgICBwID0gc3RyY2hyKHAsJywnKTsKCSAgICAgaWYgKCFwKQoJCSAgICAgYnJlYWs7CgkgICAgIHArKzsKICAgICB9CiAgICAgcmV0dXJuIG5vOwp9CgovKiBSZXR1cm5zIDEgaWYgbmVlZGxlIGZvdW5kIG9yIG5vbmVlZGxlIG5vdCBmb3VuZCBpbiBoYXlzdGFjawogKiBPdGhlcndpc2UgcmV0dXJucyAwCiAqLwpzdGF0aWMgaW50CmNoZWNrX29wdGlvbihjb25zdCBjaGFyICpoYXlzdGFjaywgY29uc3QgY2hhciAqbmVlZGxlKSB7CiAgICAgY29uc3QgY2hhciAqcCwgKnI7CiAgICAgaW50IGxlbiwgbmVlZGxlX2xlbiwgdGhpc19sZW47CiAgICAgaW50IG5vOwoKICAgICBubyA9IDA7CiAgICAgaWYgKCFzdHJuY21wKG5lZWRsZSwgIm5vIiwgMikpIHsKCSAgbm8gPSAxOwoJICBuZWVkbGUgKz0gMjsKICAgICB9CiAgICAgbmVlZGxlX2xlbiA9IHN0cmxlbihuZWVkbGUpOwogICAgIGxlbiA9IHN0cmxlbihoYXlzdGFjayk7CgogICAgIGZvciAocCA9IGhheXN0YWNrOyBwIDwgaGF5c3RhY2srbGVuOyBwKyspIHsKCSAgciA9IHN0cmNocihwLCAnLCcpOwoJICBpZiAocikgewoJICAgICAgIHRoaXNfbGVuID0gci1wOwoJICB9IGVsc2UgewoJICAgICAgIHRoaXNfbGVuID0gc3RybGVuKHApOwoJICB9CgkgIGlmICh0aGlzX2xlbiAhPSBuZWVkbGVfbGVuKSB7CgkgICAgICAgcCArPSB0aGlzX2xlbjsKCSAgICAgICBjb250aW51ZTsKCSAgfQoJICBpZiAoc3RybmNtcChwLCBuZWVkbGUsIHRoaXNfbGVuKSA9PSAwKQoJICAgICAgIHJldHVybiAhbm87IC8qIGZvbyBvciBub2ZvbyB3YXMgZm91bmQgKi8KCSAgcCArPSB0aGlzX2xlbjsKICAgICB9CgogICAgIHJldHVybiBubzsgIC8qIGZvbyBvciBub2ZvbyB3YXMgbm90IGZvdW5kICovCn0KCgovKiBSZXR1cm5zIDEgaWYgZWFjaCBvZiB0aGUgdGVzdF9vcHRzIG9wdGlvbnMgYWdyZWVzIHdpdGggdGhlIGVudGlyZQogKiBsaXN0IG9mIG9wdGlvbnMuCiAqIFJldHVybnMgMCBpZiBhbnkgbm9vcHQgaXMgZm91bmQgaW4gdGVzdF9vcHRzIGFuZCBvcHQgaXMgZm91bmQgaW4gb3B0aW9ucy4KICogUmV0dXJucyAwIGlmIGFueSBvcHQgaXMgZm91bmQgaW4gdGVzdF9vcHRzIGJ1dCBpcyBub3QgZm91bmQgaW4gb3B0aW9ucy4KICogVW5saWtlIGZzIHR5cGUgbWF0Y2hpbmcsIG5vbmV0ZGV2LHVzZXIgYW5kIG5vbmV0ZGV2LG5vdXNlciBoYXZlCiAqIERJRkZFUkVOVCBtZWFuaW5nczsgZWFjaCBvcHRpb24gaXMgbWF0Y2hlZCBleHBsaWNpdGx5IGFzIHNwZWNpZmllZC4KICovCmludAptYXRjaGluZ19vcHRzIChjb25zdCBjaGFyICpvcHRpb25zLCBjb25zdCBjaGFyICp0ZXN0X29wdHMpIHsKICAgICBjb25zdCBjaGFyICpwLCAqcjsKICAgICBjaGFyICpxOwogICAgIGludCBsZW4sIHRoaXNfbGVuOwoKICAgICBpZiAodGVzdF9vcHRzID09IE5VTEwpCgkgIHJldHVybiAxOwoKICAgICBsZW4gPSBzdHJsZW4odGVzdF9vcHRzKTsKICAgICBxID0gYWxsb2NhKGxlbisxKTsKICAgICBpZiAocSA9PSBOVUxMKQogICAgICAgICAgZGllIChFWF9TWVNFUlIsIF8oIm5vdCBlbm91Z2ggbWVtb3J5IikpOwogICAgIAogICAgIGZvciAocCA9IHRlc3Rfb3B0czsgcCA8IHRlc3Rfb3B0cytsZW47IHArKykgewoJICByID0gc3RyY2hyKHAsICcsJyk7CgkgIGlmIChyKSB7CgkgICAgICAgdGhpc19sZW4gPSByLXA7CgkgIH0gZWxzZSB7CgkgICAgICAgdGhpc19sZW4gPSBzdHJsZW4ocCk7CgkgIH0KCSAgaWYgKCF0aGlzX2xlbikgY29udGludWU7IC8qIGlmIHR3byAnLCcgYXBwZWFyIGluIGEgcm93ICovCgkgIHN0cm5jcHkocSwgcCwgdGhpc19sZW4pOwoJICBxW3RoaXNfbGVuXSA9ICdcMCc7CgkgIGlmICghY2hlY2tfb3B0aW9uKG9wdGlvbnMsIHEpKQoJICAgICAgIHJldHVybiAwOyAvKiBhbnkgbWF0Y2ggZmFpbHVyZSBtZWFucyBmYWlsdXJlICovCgkgIHAgKz0gdGhpc19sZW47CiAgICAgfQoKICAgICAvKiBubyBtYXRjaCBmYWlsdXJlcyBpbiBsaXN0IG1lYW5zIHN1Y2Nlc3MgKi8KICAgICByZXR1cm4gMTsKfQoKaW50CmlzX3BzZXVkb19mcyhjb25zdCBjaGFyICp0eXBlKQp7CglpZiAodHlwZSA9PSBOVUxMIHx8ICp0eXBlID09ICcvJykKCQlyZXR1cm4gMDsKCWlmIChzdHJlcSh0eXBlLCAibm9uZSIpIHx8CgkgICAgc3RyZXEodHlwZSwgInByb2MiKSB8fAoJICAgIHN0cmVxKHR5cGUsICJ0bXBmcyIpIHx8CgkgICAgc3RyZXEodHlwZSwgInN5c2ZzIikgfHwKCSAgICBzdHJlcSh0eXBlLCAidXNiZnMiKSB8fAoJICAgIHN0cmVxKHR5cGUsICJjZ3JvdXAiKSB8fAoJICAgIHN0cmVxKHR5cGUsICJjcHVzZXQiKSB8fAoJICAgIHN0cmVxKHR5cGUsICJycGNfcGlwZWZzIikgfHwKCSAgICBzdHJlcSh0eXBlLCAiZGV2cHRzIikpCgkJcmV0dXJuIDE7CglyZXR1cm4gMDsKfQoKLyogTWFrZSBhIGNhbm9uaWNhbCBwYXRobmFtZSBmcm9tIFBBVEguICBSZXR1cm5zIGEgZnJlc2hseSBtYWxsb2NlZCBzdHJpbmcuCiAgIEl0IGlzIHVwIHRoZSAqY2FsbGVyKiB0byBlbnN1cmUgdGhhdCB0aGUgUEFUSCBpcyBzZW5zaWJsZS4gIGkuZS4KICAgY2Fub25pY2FsaXplICgiL2Rldi9mZDAvLiIpIHJldHVybnMgIi9kZXYvZmQwIiBldmVuIHRob3VnaCBgYC9kZXYvZmQwLy4nJwogICBpcyBub3QgYSBsZWdhbCBwYXRobmFtZSBmb3IgYGAvZGV2L2ZkMCcnLiAgQW55dGhpbmcgd2UgY2Fubm90IHBhcnNlCiAgIHdlIHJldHVybiB1bm1vZGlmaWVkLiAgICovCmNoYXIgKgpjYW5vbmljYWxpemVfc3BlYyAoY29uc3QgY2hhciAqcGF0aCkKewoJY2hhciAqcmVzOwoKCWlmICghcGF0aCkKCQlyZXR1cm4gTlVMTDsKCWlmIChub2Nhbm9uaWNhbGl6ZSB8fCBpc19wc2V1ZG9fZnMocGF0aCkpCgkJcmV0dXJuIHhzdHJkdXAocGF0aCk7CgoJcmVzID0gY2Fub25pY2FsaXplX3BhdGgocGF0aCk7CglpZiAoIXJlcykKCQlkaWUoRVhfU1lTRVJSLCBfKCJub3QgZW5vdWdoIG1lbW9yeSIpKTsKCXJldHVybiByZXM7Cn0KCmNoYXIgKmNhbm9uaWNhbGl6ZSAoY29uc3QgY2hhciAqcGF0aCkKewoJY2hhciAqcmVzOwoKCWlmICghcGF0aCkKCQlyZXR1cm4gTlVMTDsKCWVsc2UgaWYgKG5vY2Fub25pY2FsaXplKQoJCXJldHVybiB4c3RyZHVwKHBhdGgpOwoKCXJlcyA9IGNhbm9uaWNhbGl6ZV9wYXRoKHBhdGgpOwoJaWYgKCFyZXMpCgkJZGllKEVYX1NZU0VSUiwgXygibm90IGVub3VnaCBtZW1vcnkiKSk7CglyZXR1cm4gcmVzOwp9Cgo=