LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2NhY2hlLmMsdiAxLjExIDIwMDIvMDgvMTkgMTk6MzI6MDUga2VpdGhwIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDAgS2VpdGggUGFja2FyZCwgbWVtYmVyIG9mIFRoZSBYRnJlZTg2IFByb2plY3QsIEluYy4KICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJmY2ludC5oIgoKLyoKICogUE9TSVggaGFzIGJyb2tlbiBzdGRpbyBzbyB0aGF0IGdldGMgbXVzdCBkbyB0aHJlYWQtc2FmZSBsb2NraW5nLAogKiB0aGlzIGlzIGEgc2VyaW91cyBwZXJmb3JtYW5jZSBwcm9ibGVtIGZvciBhcHBsaWNhdGlvbnMgZG9pbmcgbGFyZ2UKICogYW1vdW50cyBvZiBJTyB3aXRoIGdldGMgKGFzIGlzIGRvbmUgaGVyZSkuICBJZiBhdmFpbGFibGUsIHVzZQogKiB0aGUgZ2V0Y191bmxvY2tlZCB2YXJpZW50IGluc3RlYWQuCiAqLwogCiNpZiBkZWZpbmVkKGdldGNfdW5sb2NrZWQpIHx8IGRlZmluZWQoX0lPX2dldGNfdW5sb2NrZWQpCiNkZWZpbmUgR0VUQyhmKSBnZXRjX3VubG9ja2VkKGYpCiNkZWZpbmUgUFVUQyhjLGYpIHB1dGNfdW5sb2NrZWQoYyxmKQojZWxzZQojZGVmaW5lIEdFVEMoZikgZ2V0YyhmKQojZGVmaW5lIFBVVEMoYyxmKSBwdXRjKGMsZikKI2VuZGlmCgojZGVmaW5lIEZDX0RCR19DQUNIRV9SRUYgICAgMTAyNAoKc3RhdGljIEZjQ2hhcjggKgpGY0NhY2hlUmVhZFN0cmluZyAoRklMRSAqZiwgRmNDaGFyOCAqZGVzdCwgaW50IGxlbikKewogICAgaW50CQljOwogICAgRmNCb29sCWVzY2FwZTsKICAgIEZjQ2hhcjgJKmQ7CiAgICBpbnQJCXNpemU7CiAgICBpbnQJCWk7CgogICAgd2hpbGUgKChjID0gR0VUQyAoZikpICE9IEVPRikKCWlmIChjID09ICciJykKCSAgICBicmVhazsKICAgIGlmIChjID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKGxlbiA9PSAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICAKICAgIHNpemUgPSBsZW47CiAgICBpID0gMDsKICAgIGQgPSBkZXN0OwogICAgZXNjYXBlID0gRmNGYWxzZTsKICAgIHdoaWxlICgoYyA9IEdFVEMgKGYpKSAhPSBFT0YpCiAgICB7CglpZiAoIWVzY2FwZSkKCXsKCSAgICBzd2l0Y2ggKGMpIHsKCSAgICBjYXNlICciJzoKCQljID0gJ1wwJzsKCQlicmVhazsKCSAgICBjYXNlICdcXCc6CgkJZXNjYXBlID0gRmNUcnVlOwoJCWNvbnRpbnVlOwoJICAgIH0KCX0KCWlmIChpID09IHNpemUpCgl7CgkgICAgRmNDaGFyOCAqbmV3ID0gbWFsbG9jIChzaXplICogMik7CgkgICAgaWYgKCFuZXcpCgkJYnJlYWs7CgkgICAgbWVtY3B5IChuZXcsIGQsIHNpemUpOwoJICAgIHNpemUgKj0gMjsKCSAgICBpZiAoZCAhPSBkZXN0KQoJCWZyZWUgKGQpOwoJICAgIGQgPSBuZXc7Cgl9CglkW2krK10gPSBjOwoJaWYgKGMgPT0gJ1wwJykKCSAgICByZXR1cm4gZDsKCWVzY2FwZSA9IEZjRmFsc2U7CiAgICB9CiAgICBpZiAoZCAhPSBkZXN0KQoJZnJlZSAoZCk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlUmVhZFVsb25nIChGSUxFICpmLCB1bnNpZ25lZCBsb25nICpkZXN0KQp7CiAgICB1bnNpZ25lZCBsb25nICAgdDsKICAgIGludAkJICAgIGM7CgogICAgd2hpbGUgKChjID0gR0VUQyAoZikpICE9IEVPRikKICAgIHsKCWlmICghaXNzcGFjZSAoYykpCgkgICAgYnJlYWs7CiAgICB9CiAgICBpZiAoYyA9PSBFT0YpCglyZXR1cm4gRmNGYWxzZTsKICAgIHQgPSAwOwogICAgZm9yICg7OykKICAgIHsKCWlmIChjID09IEVPRiB8fCBpc3NwYWNlIChjKSkKCSAgICBicmVhazsKCWlmICghaXNkaWdpdCAoYykpCgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl0ID0gdCAqIDEwICsgKGMgLSAnMCcpOwoJYyA9IEdFVEMgKGYpOwogICAgfQogICAgKmRlc3QgPSB0OwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlUmVhZEludCAoRklMRSAqZiwgaW50ICpkZXN0KQp7CiAgICB1bnNpZ25lZCBsb25nICAgdDsKICAgIEZjQm9vbAkgICAgcmV0OwoKICAgIHJldCA9IEZjQ2FjaGVSZWFkVWxvbmcgKGYsICZ0KTsKICAgIGlmIChyZXQpCgkqZGVzdCA9IChpbnQpIHQ7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVSZWFkVGltZSAoRklMRSAqZiwgdGltZV90ICpkZXN0KQp7CiAgICB1bnNpZ25lZCBsb25nICAgdDsKICAgIEZjQm9vbAkgICAgcmV0OwoKICAgIHJldCA9IEZjQ2FjaGVSZWFkVWxvbmcgKGYsICZ0KTsKICAgIGlmIChyZXQpCgkqZGVzdCA9ICh0aW1lX3QpIHQ7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZUNoYXJzIChGSUxFICpmLCBjb25zdCBGY0NoYXI4ICpjaGFycykKewogICAgRmNDaGFyOCAgICBjOwogICAgd2hpbGUgKChjID0gKmNoYXJzKyspKQogICAgewoJc3dpdGNoIChjKSB7CgljYXNlICciJzoKCWNhc2UgJ1xcJzoKCSAgICBpZiAoUFVUQyAoJ1xcJywgZikgPT0gRU9GKQoJCXJldHVybiBGY0ZhbHNlOwoJICAgIC8qIGZhbGwgdGhyb3VnaCAqLwoJZGVmYXVsdDoKCSAgICBpZiAoUFVUQyAoYywgZikgPT0gRU9GKQoJCXJldHVybiBGY0ZhbHNlOwoJfQogICAgfQogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVTdHJpbmcgKEZJTEUgKmYsIGNvbnN0IEZjQ2hhcjggKnN0cmluZykKewoKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKCFGY0NhY2hlV3JpdGVDaGFycyAoZiwgc3RyaW5nKSkKCXJldHVybiBGY0ZhbHNlOwogICAgaWYgKFBVVEMgKCciJywgZikgPT0gRU9GKQoJcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZVBhdGggKEZJTEUgKmYsIGNvbnN0IEZjQ2hhcjggKmRpciwgY29uc3QgRmNDaGFyOCAqZmlsZSkKewogICAgaWYgKFBVVEMgKCciJywgZikgPT0gRU9GKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoZGlyKQoJaWYgKCFGY0NhY2hlV3JpdGVDaGFycyAoZiwgZGlyKSkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIGlmIChkaXIgJiYgZGlyW3N0cmxlbigoY29uc3QgY2hhciAqKSBkaXIpIC0gMV0gIT0gJy8nKQoJaWYgKFBVVEMgKCcvJywgZikgPT0gRU9GKQoJICAgIHJldHVybiBGY0ZhbHNlOwogICAgaWYgKCFGY0NhY2hlV3JpdGVDaGFycyAoZiwgZmlsZSkpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChQVVRDICgnIicsIGYpID09IEVPRikKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlV3JpdGVVbG9uZyAoRklMRSAqZiwgdW5zaWduZWQgbG9uZyB0KQp7CiAgICBpbnQJICAgIHBvdzsKICAgIHVuc2lnbmVkIGxvbmcgICB0ZW1wLCBkaWdpdDsKCiAgICB0ZW1wID0gdDsKICAgIHBvdyA9IDE7CiAgICB3aGlsZSAodGVtcCA+PSAxMCkKICAgIHsKCXRlbXAgLz0gMTA7Cglwb3cgKj0gMTA7CiAgICB9CiAgICB0ZW1wID0gdDsKICAgIHdoaWxlIChwb3cpCiAgICB7CglkaWdpdCA9IHRlbXAgLyBwb3c7CglpZiAoUFVUQyAoKGNoYXIpIGRpZ2l0ICsgJzAnLCBmKSA9PSBFT0YpCgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl0ZW1wID0gdGVtcCAtIHBvdyAqIGRpZ2l0OwoJcG93ID0gcG93IC8gMTA7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZUludCAoRklMRSAqZiwgaW50IGkpCnsKICAgIHJldHVybiBGY0NhY2hlV3JpdGVVbG9uZyAoZiwgKHVuc2lnbmVkIGxvbmcpIGkpOwp9CgpzdGF0aWMgRmNCb29sCkZjQ2FjaGVXcml0ZVRpbWUgKEZJTEUgKmYsIHRpbWVfdCB0KQp7CiAgICByZXR1cm4gRmNDYWNoZVdyaXRlVWxvbmcgKGYsICh1bnNpZ25lZCBsb25nKSB0KTsKfQoKc3RhdGljIEZjQm9vbApGY0NhY2hlRm9udFNldEFkZCAoRmNGb250U2V0CSAgICAqc2V0LAoJCSAgIEZjU3RyU2V0CSAgICAqZGlycywKCQkgICBjb25zdCBGY0NoYXI4ICAgICpkaXIsCgkJICAgaW50CQkgICAgZGlyX2xlbiwKCQkgICBjb25zdCBGY0NoYXI4ICAgICpmaWxlLAoJCSAgIGNvbnN0IEZjQ2hhcjggICAgKm5hbWUpCnsKICAgIEZjQ2hhcjgJcGF0aF9idWZbODE5Ml0sICpwYXRoOwogICAgaW50CQlsZW47CiAgICBGY0Jvb2wJcmV0ID0gRmNGYWxzZTsKICAgIEZjUGF0dGVybgkqZm9udDsKICAgIEZjUGF0dGVybgkqZnJvemVuOwoKICAgIHBhdGggPSBwYXRoX2J1ZjsKICAgIGxlbiA9IChkaXJfbGVuICsgMSArIHN0cmxlbiAoKGNvbnN0IGNoYXIgKikgZmlsZSkgKyAxKTsKICAgIGlmIChsZW4gPiBzaXplb2YgKHBhdGhfYnVmKSkKICAgIHsKCXBhdGggPSBtYWxsb2MgKGxlbik7CglpZiAoIXBhdGgpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBzdHJuY3B5ICgoY2hhciAqKSBwYXRoLCAoY29uc3QgY2hhciAqKSBkaXIsIGRpcl9sZW4pOwogICAgaWYgKGRpcltkaXJfbGVuIC0gMV0gIT0gJy8nKQoJcGF0aFtkaXJfbGVuKytdID0gJy8nOwogICAgc3RyY3B5ICgoY2hhciAqKSBwYXRoICsgZGlyX2xlbiwgKGNvbnN0IGNoYXIgKikgZmlsZSk7CiAgICBpZiAoIUZjU3RyQ21wIChuYW1lLCBGQ19GT05UX0ZJTEVfRElSKSkKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFVikKCSAgICBwcmludGYgKCIgZGlyIGNhY2hlIGRpciBcIiVzXCJcbiIsIHBhdGgpOwoJcmV0ID0gRmNTdHJTZXRBZGQgKGRpcnMsIHBhdGgpOwogICAgfQogICAgZWxzZSBpZiAoIUZjU3RyQ21wIChuYW1lLCBGQ19GT05UX0ZJTEVfSU5WQUxJRCkpCiAgICB7CglyZXQgPSBGY1RydWU7CiAgICB9CiAgICBlbHNlCiAgICB7Cglmb250ID0gRmNOYW1lUGFyc2UgKG5hbWUpOwoJaWYgKGZvbnQpCgl7CgkgICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJCXByaW50ZiAoIiBkaXIgY2FjaGUgZmlsZSBcIiVzXCJcbiIsIGZpbGUpOwoJICAgIHJldCA9IEZjUGF0dGVybkFkZFN0cmluZyAoZm9udCwgRkNfRklMRSwgcGF0aCk7CgkgICAgaWYgKHJldCkKCSAgICB7CgkJZnJvemVuID0gRmNQYXR0ZXJuRnJlZXplIChmb250KTsKCQlyZXQgPSAoZnJvemVuICE9IDApOwoJCWlmIChyZXQpCgkJICAgcmV0ID0gRmNGb250U2V0QWRkIChzZXQsIGZyb3plbik7CgkgICAgfQoJICAgIEZjUGF0dGVybkRlc3Ryb3kgKGZvbnQpOwoJfQogICAgfQogICAgaWYgKHBhdGggIT0gcGF0aF9idWYpIGZyZWUgKHBhdGgpOwogICAgcmV0dXJuIHJldDsKICAgIAp9CgpzdGF0aWMgdW5zaWduZWQgaW50CkZjQ2FjaGVIYXNoIChjb25zdCBGY0NoYXI4ICpzdHJpbmcpCnsKICAgIHVuc2lnbmVkIGludCAgICBoID0gMDsKICAgIEZjQ2hhcjgJICAgIGM7CgogICAgd2hpbGUgKChjID0gKnN0cmluZysrKSkKCWggPSAoaCA8PCAxKSBeIGM7CiAgICByZXR1cm4gMDsKfQoKLyoKICogVmVyaWZ5IHRoZSBzYXZlZCB0aW1lc3RhbXAgZm9yIGEgZmlsZQogKi8KRmNCb29sCkZjR2xvYmFsQ2FjaGVDaGVja1RpbWUgKEZjR2xvYmFsQ2FjaGVJbmZvICppbmZvKQp7CiAgICBzdHJ1Y3Qgc3RhdAkgICAgc3RhdGI7CgogICAgaWYgKHN0YXQgKChjaGFyICopIGluZm8tPmZpbGUsICZzdGF0YikgPCAwKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIGZpbGUgbWlzc2luZ1xuIik7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIGlmIChzdGF0Yi5zdF9tdGltZSAhPSBpbmZvLT50aW1lKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIHRpbWVzdGFtcCBtaXNtYXRjaCAod2FzICVkIGlzICVkKVxuIiwKCQkgICAgKGludCkgaW5mby0+dGltZSwgKGludCkgc3RhdGIuc3RfbXRpbWUpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp2b2lkCkZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChGY0dsb2JhbENhY2hlCSAgICAqY2FjaGUsCgkJCSBGY0dsb2JhbENhY2hlSW5mbyAgKmluZm8pCnsKICAgIGlmICghaW5mby0+cmVmZXJlbmNlZCkKICAgIHsKCWluZm8tPnJlZmVyZW5jZWQgPSBGY1RydWU7CgljYWNoZS0+cmVmZXJlbmNlZCsrOwoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVfUkVGKQoJICAgIHByaW50ZiAoIlJlZmVyZW5jZSAlZCAlc1xuIiwgY2FjaGUtPnJlZmVyZW5jZWQsIGluZm8tPmZpbGUpOwogICAgfQp9CgovKgogKiBCcmVhayBhIHBhdGggaW50byBkaXIvYmFzZSBlbGVtZW50cyBhbmQgY29tcHV0ZSB0aGUgYmFzZSBoYXNoCiAqIGFuZCB0aGUgZGlyIGxlbmd0aC4gIFRoaXMgaXMgc2hhcmVkIGJldHdlZW4gdGhlIGZ1bmN0aW9ucwogKiB3aGljaCB3YWxrIHRoZSBmaWxlIGNhY2hlcwogKi8KCnR5cGVkZWYgc3RydWN0IF9GY0ZpbGVQYXRoSW5mbyB7CiAgICBjb25zdCBGY0NoYXI4ICAgKmRpcjsKICAgIGludAkJICAgIGRpcl9sZW47CiAgICBjb25zdCBGY0NoYXI4ICAgKmJhc2U7CiAgICB1bnNpZ25lZCBpbnQgICAgYmFzZV9oYXNoOwp9IEZjRmlsZVBhdGhJbmZvOwoKc3RhdGljIEZjRmlsZVBhdGhJbmZvCkZjRmlsZVBhdGhJbmZvR2V0IChjb25zdCBGY0NoYXI4ICAgICpwYXRoKQp7CiAgICBGY0ZpbGVQYXRoSW5mbyAgaTsKICAgIEZjQ2hhcjgJICAgICpzbGFzaDsKCiAgICBzbGFzaCA9IChGY0NoYXI4ICopIHN0cnJjaHIgKChjb25zdCBjaGFyICopIHBhdGgsICcvJyk7CiAgICBpZiAoc2xhc2gpCiAgICB7CiAgICAgICAgaS5kaXIgPSBwYXRoOwogICAgICAgIGkuZGlyX2xlbiA9IHNsYXNoIC0gcGF0aDsKCWlmICghaS5kaXJfbGVuKQoJICAgIGkuZGlyX2xlbiA9IDE7CglpLmJhc2UgPSBzbGFzaCArIDE7CiAgICB9CiAgICBlbHNlCiAgICB7CglpLmRpciA9IChjb25zdCBGY0NoYXI4ICopICIuIjsKCWkuZGlyX2xlbiA9IDE7CglpLmJhc2UgPSBwYXRoOwogICAgfQogICAgaS5iYXNlX2hhc2ggPSBGY0NhY2hlSGFzaCAoaS5iYXNlKTsKICAgIHJldHVybiBpOwp9CgpGY0dsb2JhbENhY2hlRGlyICoKRmNHbG9iYWxDYWNoZURpckdldCAoRmNHbG9iYWxDYWNoZSAgKmNhY2hlLAoJCSAgICAgY29uc3QgRmNDaGFyOCAgKmRpciwKCQkgICAgIGludAkgICAgbGVuLAoJCSAgICAgRmNCb29sCSAgICBjcmVhdGVfbWlzc2luZykKewogICAgdW5zaWduZWQgaW50CWhhc2ggPSBGY0NhY2hlSGFzaCAoZGlyKTsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQsICoqcHJldjsKCiAgICBmb3IgKHByZXYgPSAmY2FjaGUtPmVudHNbaGFzaCAlIEZDX0dMT0JBTF9DQUNIRV9ESVJfSEFTSF9TSVpFXTsKCSAoZCA9ICpwcmV2KTsKCSBwcmV2ID0gJigqcHJldiktPm5leHQpCiAgICB7CglpZiAoZC0+aW5mby5oYXNoID09IGhhc2ggJiYgZC0+bGVuID09IGxlbiAmJgoJICAgICFzdHJuY21wICgoY29uc3QgY2hhciAqKSBkLT5pbmZvLmZpbGUsCgkJICAgICAgKGNvbnN0IGNoYXIgKikgZGlyLCBsZW4pKQoJICAgIGJyZWFrOwogICAgfQogICAgaWYgKCEoZCA9ICpwcmV2KSkKICAgIHsKCWludAlpOwoJaWYgKCFjcmVhdGVfbWlzc2luZykKCSAgICByZXR1cm4gMDsKCWQgPSBtYWxsb2MgKHNpemVvZiAoRmNHbG9iYWxDYWNoZURpcikgKyBsZW4gKyAxKTsKCWlmICghZCkKCSAgICByZXR1cm4gMDsKCWQtPm5leHQgPSAqcHJldjsKCSpwcmV2ID0gZDsKCWQtPmluZm8uaGFzaCA9IGhhc2g7CglkLT5pbmZvLmZpbGUgPSAoRmNDaGFyOCAqKSAoZCArIDEpOwoJc3RybmNweSAoKGNoYXIgKikgZC0+aW5mby5maWxlLCAoY29uc3QgY2hhciAqKSBkaXIsIGxlbik7CglkLT5pbmZvLmZpbGVbbGVuXSA9ICdcMCc7CglkLT5pbmZvLnRpbWUgPSAwOwoJZC0+aW5mby5yZWZlcmVuY2VkID0gRmNGYWxzZTsKCWQtPmxlbiA9IGxlbjsKCWZvciAoaSA9IDA7IGkgPCBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkU7IGkrKykKCSAgICBkLT5lbnRzW2ldID0gMDsKCWQtPnN1YmRpcnMgPSAwOwogICAgfQogICAgcmV0dXJuIGQ7Cn0KCnN0YXRpYyBGY0dsb2JhbENhY2hlSW5mbyAqCkZjR2xvYmFsQ2FjaGVEaXJBZGQgKEZjR2xvYmFsQ2FjaGUgICpjYWNoZSwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpkaXIsCgkJICAgICB0aW1lX3QJICAgIHRpbWUsCgkJICAgICBGY0Jvb2wJICAgIHJlcGxhY2UpCnsKICAgIEZjR2xvYmFsQ2FjaGVEaXIJKmQ7CiAgICBGY0ZpbGVQYXRoSW5mbwlpOwogICAgRmNHbG9iYWxDYWNoZVN1YmRpcgkqc3ViZGlyOwogICAgRmNHbG9iYWxDYWNoZURpcgkqcGFyZW50OwoKICAgIC8qCiAgICAgKiBBZGQgdGhpcyBkaXJlY3RvcnkgdG8gdGhlIGNhY2hlCiAgICAgKi8KICAgIGQgPSBGY0dsb2JhbENhY2hlRGlyR2V0IChjYWNoZSwgZGlyLCBzdHJsZW4gKChjb25zdCBjaGFyICopIGRpciksIEZjVHJ1ZSk7CiAgICBpZiAoIWQpCglyZXR1cm4gMDsKICAgIGQtPmluZm8udGltZSA9IHRpbWU7CiAgICBpID0gRmNGaWxlUGF0aEluZm9HZXQgKGRpcik7CiAgICAvKgogICAgICogQWRkIHRoaXMgZGlyZWN0b3J5IHRvIHRoZSBzdWJkaXJlY3RvcnkgbGlzdCBvZiB0aGUgcGFyZW50CiAgICAgKi8KICAgIHBhcmVudCA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBpLmRpciwgaS5kaXJfbGVuLCBGY1RydWUpOwogICAgaWYgKCFwYXJlbnQpCglyZXR1cm4gMDsKICAgIHN1YmRpciA9IG1hbGxvYyAoc2l6ZW9mIChGY0dsb2JhbENhY2hlU3ViZGlyKSArIAoJCSAgICAgc3RybGVuICgoY29uc3QgY2hhciAqKSBpLmJhc2UpICsgMSk7CiAgICBpZiAoIXN1YmRpcikKCXJldHVybiAwOwogICAgc3ViZGlyLT5maWxlID0gKEZjQ2hhcjggKikgKHN1YmRpciArIDEpOwogICAgc3RyY3B5ICgoY2hhciAqKSBzdWJkaXItPmZpbGUsIChjb25zdCBjaGFyICopIGkuYmFzZSk7CiAgICBzdWJkaXItPm5leHQgPSBwYXJlbnQtPnN1YmRpcnM7CiAgICBwYXJlbnQtPnN1YmRpcnMgPSBzdWJkaXI7CiAgICByZXR1cm4gJmQtPmluZm87Cn0KCnN0YXRpYyB2b2lkCkZjR2xvYmFsQ2FjaGVEaXJEZXN0cm95IChGY0dsb2JhbENhY2hlRGlyICpkKQp7CiAgICBGY0dsb2JhbENhY2hlRmlsZQkqZiwgKm5leHQ7CiAgICBpbnQJCQloOwogICAgRmNHbG9iYWxDYWNoZVN1YmRpcgkqcywgKm5leHRzOwoKICAgIGZvciAoaCA9IDA7IGggPCBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkU7IGgrKykKCWZvciAoZiA9IGQtPmVudHNbaF07IGY7IGYgPSBuZXh0KQoJewoJICAgIG5leHQgPSBmLT5uZXh0OwoJICAgIGZyZWUgKGYpOwoJfQogICAgZm9yIChzID0gZC0+c3ViZGlyczsgczsgcyA9IG5leHRzKQogICAgewoJbmV4dHMgPSBzLT5uZXh0OwoJZnJlZSAocyk7CiAgICB9CiAgICBmcmVlIChkKTsKfQoKRmNCb29sCkZjR2xvYmFsQ2FjaGVTY2FuRGlyIChGY0ZvbnRTZXQJCSpzZXQsCgkJICAgICAgRmNTdHJTZXQJCSpkaXJzLAoJCSAgICAgIEZjR2xvYmFsQ2FjaGUJKmNhY2hlLAoJCSAgICAgIGNvbnN0IEZjQ2hhcjgJKmRpcikKewogICAgRmNHbG9iYWxDYWNoZURpcgkqZCA9IEZjR2xvYmFsQ2FjaGVEaXJHZXQgKGNhY2hlLCBkaXIsCgkJCQkJCSAgc3RybGVuICgoY29uc3QgY2hhciAqKSBkaXIpLAoJCQkJCQkgIEZjRmFsc2UpOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmY7CiAgICBpbnQJCQloOwogICAgaW50CQkJZGlyX2xlbjsKICAgIEZjR2xvYmFsQ2FjaGVTdWJkaXIJKnN1YmRpcjsKCiAgICBpZiAoRmNEZWJ1ZygpICYgRkNfREJHX0NBQ0hFKQoJcHJpbnRmICgiRmNHbG9iYWxDYWNoZVNjYW5EaXIgJXNcbiIsIGRpcik7CiAgICAKICAgIGlmICghZCkKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJICAgIHByaW50ZiAoIlx0Tm8gZGlyIGNhY2hlIGVudHJ5XG4iKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQoKICAgIGlmICghRmNHbG9iYWxDYWNoZUNoZWNrVGltZSAoJmQtPmluZm8pKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiXHRkaXIgY2FjaGUgZW50cnkgdGltZSBtaXNtYXRjaFxuIik7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KCiAgICBkaXJfbGVuID0gc3RybGVuICgoY29uc3QgY2hhciAqKSBkaXIpOwogICAgZm9yIChoID0gMDsgaCA8IEZDX0dMT0JBTF9DQUNIRV9GSUxFX0hBU0hfU0laRTsgaCsrKQoJZm9yIChmID0gZC0+ZW50c1toXTsgZjsgZiA9IGYtPm5leHQpCgl7CgkgICAgaWYgKEZjRGVidWcoKSAmIEZDX0RCR19DQUNIRVYpCgkJcHJpbnRmICgiRmNHbG9iYWxDYWNoZVNjYW5EaXIgYWRkIGZpbGUgJXNcbiIsIGYtPmluZm8uZmlsZSk7CgkgICAgaWYgKCFGY0NhY2hlRm9udFNldEFkZCAoc2V0LCBkaXJzLCBkaXIsIGRpcl9sZW4sCgkJCQkgICAgZi0+aW5mby5maWxlLCBmLT5uYW1lKSkKCSAgICB7CgkJY2FjaGUtPmJyb2tlbiA9IEZjVHJ1ZTsKCQlyZXR1cm4gRmNGYWxzZTsKCSAgICB9CgkgICAgRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKGNhY2hlLCAmZi0+aW5mbyk7Cgl9CiAgICBmb3IgKHN1YmRpciA9IGQtPnN1YmRpcnM7IHN1YmRpcjsgc3ViZGlyID0gc3ViZGlyLT5uZXh0KQogICAgewoJaWYgKCFGY0NhY2hlRm9udFNldEFkZCAoc2V0LCBkaXJzLCBkaXIsIGRpcl9sZW4sCgkJCQlzdWJkaXItPmZpbGUsIEZDX0ZPTlRfRklMRV9ESVIpKQoJewoJICAgIGNhY2hlLT5icm9rZW4gPSBGY1RydWU7CgkgICAgcmV0dXJuIEZjRmFsc2U7Cgl9CiAgICB9CiAgICAKICAgIEZjR2xvYmFsQ2FjaGVSZWZlcmVuY2VkIChjYWNoZSwgJmQtPmluZm8pOwoKICAgIHJldHVybiBGY1RydWU7Cn0KCi8qCiAqIExvY2F0ZSB0aGUgY2FjaGUgZW50cnkgZm9yIGEgcGFydGljdWxhciBmaWxlCiAqLwpGY0dsb2JhbENhY2hlRmlsZSAqCkZjR2xvYmFsQ2FjaGVGaWxlR2V0IChGY0dsb2JhbENhY2hlICpjYWNoZSwKCQkgICAgICBjb25zdCBGY0NoYXI4ICpmaWxlLAoJCSAgICAgIGludAkgICAgaWQsCgkJICAgICAgaW50CSAgICAqY291bnQpCnsKICAgIEZjRmlsZVBhdGhJbmZvCWkgPSBGY0ZpbGVQYXRoSW5mb0dldCAoZmlsZSk7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkID0gRmNHbG9iYWxDYWNoZURpckdldCAoY2FjaGUsIGkuZGlyLCAKCQkJCQkJICBpLmRpcl9sZW4sIEZjRmFsc2UpOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmYsICptYXRjaCA9IDA7CiAgICBpbnQJCQltYXggPSAtMTsKCiAgICBpZiAoIWQpCglyZXR1cm4gMDsKICAgIGZvciAoZiA9IGQtPmVudHNbaS5iYXNlX2hhc2ggJSBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkVdOyBmOyBmID0gZi0+bmV4dCkKICAgIHsKCWlmIChmLT5pbmZvLmhhc2ggPT0gaS5iYXNlX2hhc2ggJiYKCSAgICAhc3RyY21wICgoY29uc3QgY2hhciAqKSBmLT5pbmZvLmZpbGUsIChjb25zdCBjaGFyICopIGkuYmFzZSkpCgl7CgkgICAgaWYgKGYtPmlkID09IGlkKQoJCW1hdGNoID0gZjsKCSAgICBpZiAoZi0+aWQgPiBtYXgpCgkJbWF4ID0gZi0+aWQ7Cgl9CiAgICB9CiAgICBpZiAoY291bnQpCgkqY291bnQgPSBtYXg7CiAgICByZXR1cm4gbWF0Y2g7Cn0KICAgIAovKgogKiBBZGQgYSBmaWxlIGVudHJ5IHRvIHRoZSBjYWNoZQogKi8Kc3RhdGljIEZjR2xvYmFsQ2FjaGVJbmZvICoKRmNHbG9iYWxDYWNoZUZpbGVBZGQgKEZjR2xvYmFsQ2FjaGUgKmNhY2hlLAoJCSAgICAgIGNvbnN0IEZjQ2hhcjggKnBhdGgsCgkJICAgICAgaW50CSAgICBpZCwKCQkgICAgICB0aW1lX3QJICAgIHRpbWUsCgkJICAgICAgY29uc3QgRmNDaGFyOCAqbmFtZSwKCQkgICAgICBGY0Jvb2wJICAgIHJlcGxhY2UpCnsKICAgIEZjRmlsZVBhdGhJbmZvCWkgPSBGY0ZpbGVQYXRoSW5mb0dldCAocGF0aCk7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkID0gRmNHbG9iYWxDYWNoZURpckdldCAoY2FjaGUsIGkuZGlyLCAKCQkJCQkJICBpLmRpcl9sZW4sIEZjVHJ1ZSk7CiAgICBGY0dsb2JhbENhY2hlRmlsZQkqZiwgKipwcmV2OwoKICAgIGlmICghZCkKCXJldHVybiAwOwogICAgZm9yIChwcmV2ID0gJmQtPmVudHNbaS5iYXNlX2hhc2ggJSBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkVdOwoJIChmID0gKnByZXYpOwoJIHByZXYgPSAmKCpwcmV2KS0+bmV4dCkKICAgIHsKCWlmIChmLT5pbmZvLmhhc2ggPT0gaS5iYXNlX2hhc2ggJiYgCgkgICAgZi0+aWQgPT0gaWQgJiYKCSAgICAhc3RyY21wICgoY29uc3QgY2hhciAqKSBmLT5pbmZvLmZpbGUsIChjb25zdCBjaGFyICopIGkuYmFzZSkpCgl7CgkgICAgYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAoKnByZXYpCiAgICB7CglpZiAoIXJlcGxhY2UpCgkgICAgcmV0dXJuIDA7CgoJZiA9ICpwcmV2OwoJaWYgKGYtPmluZm8ucmVmZXJlbmNlZCkKCSAgICBjYWNoZS0+cmVmZXJlbmNlZC0tOwoJKnByZXYgPSBmLT5uZXh0OwoJZnJlZSAoZik7CiAgICB9CiAgICBmID0gbWFsbG9jIChzaXplb2YgKEZjR2xvYmFsQ2FjaGVGaWxlKSArCgkJc3RybGVuICgoY2hhciAqKSBpLmJhc2UpICsgMSArCgkJc3RybGVuICgoY2hhciAqKSBuYW1lKSArIDEpOwogICAgaWYgKCFmKQoJcmV0dXJuIDA7CiAgICBmLT5uZXh0ID0gKnByZXY7CiAgICAqcHJldiA9IGY7CiAgICBmLT5pbmZvLmhhc2ggPSBpLmJhc2VfaGFzaDsKICAgIGYtPmluZm8uZmlsZSA9IChGY0NoYXI4ICopIChmICsgMSk7CiAgICBmLT5pbmZvLnRpbWUgPSB0aW1lOwogICAgZi0+aW5mby5yZWZlcmVuY2VkID0gRmNGYWxzZTsKICAgIGYtPmlkID0gaWQ7CiAgICBmLT5uYW1lID0gZi0+aW5mby5maWxlICsgc3RybGVuICgoY2hhciAqKSBpLmJhc2UpICsgMTsKICAgIHN0cmNweSAoKGNoYXIgKikgZi0+aW5mby5maWxlLCAoY29uc3QgY2hhciAqKSBpLmJhc2UpOwogICAgc3RyY3B5ICgoY2hhciAqKSBmLT5uYW1lLCAoY29uc3QgY2hhciAqKSBuYW1lKTsKICAgIHJldHVybiAmZi0+aW5mbzsKfQoKRmNHbG9iYWxDYWNoZSAqCkZjR2xvYmFsQ2FjaGVDcmVhdGUgKHZvaWQpCnsKICAgIEZjR2xvYmFsQ2FjaGUgICAqY2FjaGU7CiAgICBpbnQJCSAgICBoOwoKICAgIGNhY2hlID0gbWFsbG9jIChzaXplb2YgKEZjR2xvYmFsQ2FjaGUpKTsKICAgIGlmICghY2FjaGUpCglyZXR1cm4gMDsKICAgIGZvciAoaCA9IDA7IGggPCBGQ19HTE9CQUxfQ0FDSEVfRElSX0hBU0hfU0laRTsgaCsrKQoJY2FjaGUtPmVudHNbaF0gPSAwOwogICAgY2FjaGUtPmVudHJpZXMgPSAwOwogICAgY2FjaGUtPnJlZmVyZW5jZWQgPSAwOwogICAgY2FjaGUtPnVwZGF0ZWQgPSBGY0ZhbHNlOwogICAgY2FjaGUtPmJyb2tlbiA9IEZjRmFsc2U7CiAgICByZXR1cm4gY2FjaGU7Cn0KCnZvaWQKRmNHbG9iYWxDYWNoZURlc3Ryb3kgKEZjR2xvYmFsQ2FjaGUgKmNhY2hlKQp7CiAgICBGY0dsb2JhbENhY2hlRGlyCSpkLCAqbmV4dDsKICAgIGludAkJCWg7CgogICAgZm9yIChoID0gMDsgaCA8IEZDX0dMT0JBTF9DQUNIRV9ESVJfSEFTSF9TSVpFOyBoKyspCiAgICB7Cglmb3IgKGQgPSBjYWNoZS0+ZW50c1toXTsgZDsgZCA9IG5leHQpCgl7CgkgICAgbmV4dCA9IGQtPm5leHQ7CgkgICAgRmNHbG9iYWxDYWNoZURpckRlc3Ryb3kgKGQpOwoJfQogICAgfQogICAgZnJlZSAoY2FjaGUpOwp9CgovKgogKiBDYWNoZSBmaWxlIHN5bnRheCBpcyBxdWl0ZSBzaW1wbGU6CiAqCiAqICJmaWxlX25hbWUiIGlkIHRpbWUgImZvbnRfbmFtZSIgXG4KICovCiAKdm9pZApGY0dsb2JhbENhY2hlTG9hZCAoRmNHbG9iYWxDYWNoZSAgICAqY2FjaGUsCgkJICAgY29uc3QgRmNDaGFyOCAgICAqY2FjaGVfZmlsZSkKewogICAgRklMRQkJKmY7CiAgICBGY0NoYXI4CQlmaWxlX2J1Zls4MTkyXSwgKmZpbGU7CiAgICBpbnQJCQlpZDsKICAgIHRpbWVfdAkJdGltZTsKICAgIEZjQ2hhcjgJCW5hbWVfYnVmWzgxOTJdLCAqbmFtZTsKICAgIEZjR2xvYmFsQ2FjaGVJbmZvCSppbmZvOwoKICAgIGYgPSBmb3BlbiAoKGNoYXIgKikgY2FjaGVfZmlsZSwgInIiKTsKICAgIGlmICghZikKCXJldHVybjsKCiAgICBjYWNoZS0+dXBkYXRlZCA9IEZjRmFsc2U7CiAgICBmaWxlID0gMDsKICAgIG5hbWUgPSAwOwogICAgd2hpbGUgKChmaWxlID0gRmNDYWNoZVJlYWRTdHJpbmcgKGYsIGZpbGVfYnVmLCBzaXplb2YgKGZpbGVfYnVmKSkpICYmCgkgICBGY0NhY2hlUmVhZEludCAoZiwgJmlkKSAmJgoJICAgRmNDYWNoZVJlYWRUaW1lIChmLCAmdGltZSkgJiYKCSAgIChuYW1lID0gRmNDYWNoZVJlYWRTdHJpbmcgKGYsIG5hbWVfYnVmLCBzaXplb2YgKG5hbWVfYnVmKSkpKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIkZjR2xvYmFsQ2FjaGVMb2FkIFwiJXNcIiBcIiUyMC4yMHNcIlxuIiwgZmlsZSwgbmFtZSk7CglpZiAoIUZjU3RyQ21wIChuYW1lLCBGQ19GT05UX0ZJTEVfRElSKSkKCSAgICBpbmZvID0gRmNHbG9iYWxDYWNoZURpckFkZCAoY2FjaGUsIGZpbGUsIHRpbWUsIEZjRmFsc2UpOwoJZWxzZQoJICAgIGluZm8gPSBGY0dsb2JhbENhY2hlRmlsZUFkZCAoY2FjaGUsIGZpbGUsIGlkLCB0aW1lLCBuYW1lLCBGY0ZhbHNlKTsKCWlmICghaW5mbykKCSAgICBjYWNoZS0+YnJva2VuID0gRmNUcnVlOwoJZWxzZQoJICAgIGNhY2hlLT5lbnRyaWVzKys7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRV9SRUYpCgkgICAgcHJpbnRmICgiRmNHbG9iYWxDYWNoZUxvYWQgZW50cnkgJWQgJXNcbiIsCgkJICAgIGNhY2hlLT5lbnRyaWVzLCBmaWxlKTsKCWlmIChmaWxlICE9IGZpbGVfYnVmKQoJICAgIGZyZWUgKGZpbGUpOwoJaWYgKG5hbWUgIT0gbmFtZV9idWYpCgkgICAgZnJlZSAobmFtZSk7CglmaWxlID0gMDsKCW5hbWUgPSAwOwogICAgfQogICAgaWYgKGZpbGUgJiYgZmlsZSAhPSBmaWxlX2J1ZikKCWZyZWUgKGZpbGUpOwogICAgaWYgKG5hbWUgJiYgbmFtZSAhPSBuYW1lX2J1ZikKCWZyZWUgKG5hbWUpOwogICAgZmNsb3NlIChmKTsKfQoKRmNCb29sCkZjR2xvYmFsQ2FjaGVVcGRhdGUgKEZjR2xvYmFsQ2FjaGUgICpjYWNoZSwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpmaWxlLAoJCSAgICAgaW50CSAgICBpZCwKCQkgICAgIGNvbnN0IEZjQ2hhcjggICpuYW1lKQp7CiAgICBjb25zdCBGY0NoYXI4CSptYXRjaDsKICAgIHN0cnVjdCBzdGF0CQlzdGF0YjsKICAgIEZjR2xvYmFsQ2FjaGVJbmZvCSppbmZvOwoKICAgIG1hdGNoID0gZmlsZTsKCiAgICBpZiAoc3RhdCAoKGNoYXIgKikgZmlsZSwgJnN0YXRiKSA8IDApCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmIChTX0lTRElSIChzdGF0Yi5zdF9tb2RlKSkKCWluZm8gPSBGY0dsb2JhbENhY2hlRGlyQWRkIChjYWNoZSwgZmlsZSwgc3RhdGIuc3RfbXRpbWUsIAoJCQkJICAgRmNUcnVlKTsKICAgIGVsc2UKCWluZm8gPSBGY0dsb2JhbENhY2hlRmlsZUFkZCAoY2FjaGUsIGZpbGUsIGlkLCBzdGF0Yi5zdF9tdGltZSwgCgkJCQkgICAgbmFtZSwgRmNUcnVlKTsKICAgIGlmIChpbmZvKQogICAgewoJRmNHbG9iYWxDYWNoZVJlZmVyZW5jZWQgKGNhY2hlLCBpbmZvKTsKCWNhY2hlLT51cGRhdGVkID0gRmNUcnVlOwogICAgfQogICAgZWxzZQoJY2FjaGUtPmJyb2tlbiA9IEZjVHJ1ZTsKICAgIHJldHVybiBpbmZvICE9IDA7Cn0KCkZjQm9vbApGY0dsb2JhbENhY2hlU2F2ZSAoRmNHbG9iYWxDYWNoZSAgICAqY2FjaGUsCgkJICAgY29uc3QgRmNDaGFyOCAgICAqY2FjaGVfZmlsZSkKewogICAgRklMRQkJKmY7CiAgICBpbnQJCQlkaXJfaGFzaCwgZmlsZV9oYXNoOwogICAgRmNHbG9iYWxDYWNoZURpcgkqZGlyOwogICAgRmNHbG9iYWxDYWNoZUZpbGUJKmZpbGU7CiAgICBGY0F0b21pYwkJKmF0b21pYzsKCiAgICBpZiAoIWNhY2hlLT51cGRhdGVkICYmIGNhY2hlLT5yZWZlcmVuY2VkID09IGNhY2hlLT5lbnRyaWVzKQoJcmV0dXJuIEZjVHJ1ZTsKICAgIAogICAgaWYgKGNhY2hlLT5icm9rZW4pCglyZXR1cm4gRmNGYWxzZTsKCiAgICAvKiBTZXQtVUlEIHByb2dyYW1zIGNhbid0IHNhZmVseSB1cGRhdGUgdGhlIGNhY2hlICovCiAgICBpZiAoZ2V0dWlkICgpICE9IGdldGV1aWQgKCkpCglyZXR1cm4gRmNGYWxzZTsKICAgIAogICAgYXRvbWljID0gRmNBdG9taWNDcmVhdGUgKGNhY2hlX2ZpbGUpOwogICAgaWYgKCFhdG9taWMpCglnb3RvIGJhaWwwOwogICAgaWYgKCFGY0F0b21pY0xvY2sgKGF0b21pYykpCglnb3RvIGJhaWwxOwogICAgZiA9IGZvcGVuICgoY2hhciAqKSBGY0F0b21pY05ld0ZpbGUoYXRvbWljKSwgInciKTsKICAgIGlmICghZikKCWdvdG8gYmFpbDI7CgogICAgZm9yIChkaXJfaGFzaCA9IDA7IGRpcl9oYXNoIDwgRkNfR0xPQkFMX0NBQ0hFX0RJUl9IQVNIX1NJWkU7IGRpcl9oYXNoKyspCiAgICB7Cglmb3IgKGRpciA9IGNhY2hlLT5lbnRzW2Rpcl9oYXNoXTsgZGlyOyBkaXIgPSBkaXItPm5leHQpCgl7CgkgICAgaWYgKCFkaXItPmluZm8ucmVmZXJlbmNlZCkKCQljb250aW51ZTsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgZGlyLT5pbmZvLmZpbGUpKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIDApKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgaWYgKCFGY0NhY2hlV3JpdGVUaW1lIChmLCBkaXItPmluZm8udGltZSkpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgKEZjQ2hhcjggKikgRkNfRk9OVF9GSUxFX0RJUikpCgkJZ290byBiYWlsNDsKCSAgICBpZiAoUFVUQyAoJ1xuJywgZikgPT0gRU9GKQoJCWdvdG8gYmFpbDQ7CgkgICAgCgkgICAgZm9yIChmaWxlX2hhc2ggPSAwOyBmaWxlX2hhc2ggPCBGQ19HTE9CQUxfQ0FDSEVfRklMRV9IQVNIX1NJWkU7IGZpbGVfaGFzaCsrKQoJICAgIHsKCQlmb3IgKGZpbGUgPSBkaXItPmVudHNbZmlsZV9oYXNoXTsgZmlsZTsgZmlsZSA9IGZpbGUtPm5leHQpCgkJewoJCSAgICBpZiAoIWZpbGUtPmluZm8ucmVmZXJlbmNlZCkKCQkJY29udGludWU7CgkJICAgIGlmICghRmNDYWNoZVdyaXRlUGF0aCAoZiwgZGlyLT5pbmZvLmZpbGUsIGZpbGUtPmluZm8uZmlsZSkpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIGZpbGUtPmlkIDwgMCA/IDAgOiBmaWxlLT5pZCkpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKCFGY0NhY2hlV3JpdGVUaW1lIChmLCBmaWxlLT5pbmZvLnRpbWUpKQoJCQlnb3RvIGJhaWw0OwoJCSAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkJCWdvdG8gYmFpbDQ7CgkJICAgIGlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBmaWxlLT5uYW1lKSkKCQkJZ290byBiYWlsNDsKCQkgICAgaWYgKFBVVEMgKCdcbicsIGYpID09IEVPRikKCQkJZ290byBiYWlsNDsKCQl9CgkgICAgfQoJfQogICAgfQoKICAgIGlmIChmY2xvc2UgKGYpID09IEVPRikKCWdvdG8gYmFpbDM7CiAgICAKICAgIGlmICghRmNBdG9taWNSZXBsYWNlT3JpZyAoYXRvbWljKSkKCWdvdG8gYmFpbDM7CiAgICAKICAgIEZjQXRvbWljVW5sb2NrIChhdG9taWMpOwogICAgRmNBdG9taWNEZXN0cm95IChhdG9taWMpOwoKICAgIGNhY2hlLT51cGRhdGVkID0gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7CgpiYWlsNDoKICAgIGZjbG9zZSAoZik7CmJhaWwzOgogICAgRmNBdG9taWNEZWxldGVOZXcgKGF0b21pYyk7CmJhaWwyOgogICAgRmNBdG9taWNVbmxvY2sgKGF0b21pYyk7CmJhaWwxOgogICAgRmNBdG9taWNEZXN0cm95IChhdG9taWMpOwpiYWlsMDoKICAgIHJldHVybiBGY0ZhbHNlOwp9CgpGY0Jvb2wKRmNEaXJDYWNoZVZhbGlkIChjb25zdCBGY0NoYXI4ICpkaXIpCnsKICAgIEZjQ2hhcjgJKmNhY2hlX2ZpbGUgPSBGY1N0clBsdXMgKGRpciwgKEZjQ2hhcjggKikgIi8iIEZDX0RJUl9DQUNIRV9GSUxFKTsKICAgIHN0cnVjdCBzdGF0CWZpbGVfc3RhdCwgZGlyX3N0YXQ7CgogICAgaWYgKHN0YXQgKChjaGFyICopIGRpciwgJmRpcl9zdGF0KSA8IDApCiAgICB7CglGY1N0ckZyZWUgKGNhY2hlX2ZpbGUpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICBpZiAoc3RhdCAoKGNoYXIgKikgY2FjaGVfZmlsZSwgJmZpbGVfc3RhdCkgPCAwKQogICAgewoJRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgRmNTdHJGcmVlIChjYWNoZV9maWxlKTsKICAgIC8qCiAgICAgKiBJZiB0aGUgZGlyZWN0b3J5IGhhcyBiZWVuIG1vZGlmaWVkIG1vcmUgcmVjZW50bHkgdGhhbgogICAgICogdGhlIGNhY2hlIGZpbGUsIHRoZSBjYWNoZSBpcyBub3QgdmFsaWQKICAgICAqLwogICAgaWYgKGRpcl9zdGF0LnN0X210aW1lIC0gZmlsZV9zdGF0LnN0X210aW1lID4gMCkKCXJldHVybiBGY0ZhbHNlOwogICAgcmV0dXJuIEZjVHJ1ZTsKfQoKRmNCb29sCkZjRGlyQ2FjaGVSZWFkRGlyIChGY0ZvbnRTZXQgKnNldCwgRmNTdHJTZXQgKmRpcnMsIGNvbnN0IEZjQ2hhcjggKmRpcikKewogICAgRmNDaGFyOAkgICAgKmNhY2hlX2ZpbGUgPSBGY1N0clBsdXMgKGRpciwgKEZjQ2hhcjggKikgIi8iIEZDX0RJUl9DQUNIRV9GSUxFKTsKICAgIEZJTEUJICAgICpmOwogICAgRmNDaGFyOAkgICAgKmJhc2U7CiAgICBpbnQJCSAgICBpZDsKICAgIGludAkJICAgIGRpcl9sZW47CiAgICBGY0NoYXI4CSAgICBmaWxlX2J1Zls4MTkyXSwgKmZpbGU7CiAgICBGY0NoYXI4CSAgICBuYW1lX2J1Zls4MTkyXSwgKm5hbWU7CiAgICBGY0Jvb2wJICAgIHJldCA9IEZjRmFsc2U7CgogICAgaWYgKCFjYWNoZV9maWxlKQoJZ290byBiYWlsMDsKICAgIAogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCJGY0RpckNhY2hlUmVhZERpciBjYWNoZV9maWxlIFwiJXNcIlxuIiwgY2FjaGVfZmlsZSk7CiAgICAKICAgIGYgPSBmb3BlbiAoKGNoYXIgKikgY2FjaGVfZmlsZSwgInIiKTsKICAgIGlmICghZikKICAgIHsKCWlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJICAgIHByaW50ZiAoIiBubyBjYWNoZSBmaWxlXG4iKTsKCWdvdG8gYmFpbDE7CiAgICB9CgogICAgaWYgKCFGY0RpckNhY2hlVmFsaWQgKGRpcikpCiAgICB7CglpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCSAgICBwcmludGYgKCIgY2FjaGUgZmlsZSBvbGRlciB0aGFuIGRpcmVjdG9yeVxuIik7Cglnb3RvIGJhaWwyOwogICAgfQogICAgCiAgICBiYXNlID0gKEZjQ2hhcjggKikgc3RycmNociAoKGNoYXIgKikgY2FjaGVfZmlsZSwgJy8nKTsKICAgIGlmICghYmFzZSkKCWdvdG8gYmFpbDI7CiAgICBiYXNlKys7CiAgICBkaXJfbGVuID0gYmFzZSAtIGNhY2hlX2ZpbGU7CiAgICAKICAgIGZpbGUgPSAwOwogICAgbmFtZSA9IDA7CiAgICB3aGlsZSAoKGZpbGUgPSBGY0NhY2hlUmVhZFN0cmluZyAoZiwgZmlsZV9idWYsIHNpemVvZiAoZmlsZV9idWYpKSkgJiYKCSAgIEZjQ2FjaGVSZWFkSW50IChmLCAmaWQpICYmCgkgICAobmFtZSA9IEZjQ2FjaGVSZWFkU3RyaW5nIChmLCBuYW1lX2J1Ziwgc2l6ZW9mIChuYW1lX2J1ZikpKSkKICAgIHsKCWlmICghRmNDYWNoZUZvbnRTZXRBZGQgKHNldCwgZGlycywgY2FjaGVfZmlsZSwgZGlyX2xlbiwKCQkJCWZpbGUsIG5hbWUpKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoZmlsZSAhPSBmaWxlX2J1ZikKCSAgICBmcmVlIChmaWxlKTsKCWlmIChuYW1lICE9IG5hbWVfYnVmKQoJICAgIGZyZWUgKG5hbWUpOwoJZmlsZSA9IG5hbWUgPSAwOwogICAgfQogICAgaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCglwcmludGYgKCIgY2FjaGUgbG9hZGVkXG4iKTsKICAgIAogICAgcmV0ID0gRmNUcnVlOwpiYWlsMzoKICAgIGlmIChmaWxlICYmIGZpbGUgIT0gZmlsZV9idWYpCglmcmVlIChmaWxlKTsKICAgIGlmIChuYW1lICYmIG5hbWUgIT0gbmFtZV9idWYpCglmcmVlIChuYW1lKTsKYmFpbDI6CiAgICBmY2xvc2UgKGYpOwpiYWlsMToKICAgIGZyZWUgKGNhY2hlX2ZpbGUpOwpiYWlsMDoKICAgIHJldHVybiByZXQ7Cn0KCi8qCiAqIHJldHVybiB0aGUgcGF0aCBmcm9tIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyAnY2FjaGUnIHRvICdmaWxlJwogKi8KCnN0YXRpYyBjb25zdCBGY0NoYXI4ICoKRmNGaWxlQmFzZU5hbWUgKGNvbnN0IEZjQ2hhcjggKmNhY2hlLCBjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBjb25zdCBGY0NoYXI4ICAgKmNhY2hlX3NsYXNoOwoKICAgIGNhY2hlX3NsYXNoID0gKGNvbnN0IEZjQ2hhcjggKikgc3RycmNociAoKGNvbnN0IGNoYXIgKikgY2FjaGUsICcvJyk7CiAgICBpZiAoY2FjaGVfc2xhc2ggJiYgIXN0cm5jbXAgKChjb25zdCBjaGFyICopIGNhY2hlLCAoY29uc3QgY2hhciAqKSBmaWxlLAoJCQkJIChjYWNoZV9zbGFzaCArIDEpIC0gY2FjaGUpKQoJcmV0dXJuIGZpbGUgKyAoKGNhY2hlX3NsYXNoICsgMSkgLSBjYWNoZSk7CiAgICByZXR1cm4gZmlsZTsKfQoKRmNCb29sCkZjRGlyQ2FjaGVXcml0ZURpciAoRmNGb250U2V0ICpzZXQsIEZjU3RyU2V0ICpkaXJzLCBjb25zdCBGY0NoYXI4ICpkaXIpCnsKICAgIEZjQ2hhcjgJICAgICpjYWNoZV9maWxlID0gRmNTdHJQbHVzIChkaXIsIChGY0NoYXI4ICopICIvIiBGQ19ESVJfQ0FDSEVfRklMRSk7CiAgICBGY1BhdHRlcm4JICAgICpmb250OwogICAgRklMRQkgICAgKmY7CiAgICBGY0NoYXI4CSAgICAqbmFtZTsKICAgIGNvbnN0IEZjQ2hhcjggICAqZmlsZSwgKmJhc2U7CiAgICBpbnQJCSAgICBuOwogICAgaW50CQkgICAgaWQ7CiAgICBGY0Jvb2wJICAgIHJldDsKICAgIEZjU3RyTGlzdAkgICAgKmxpc3Q7CgogICAgaWYgKCFjYWNoZV9maWxlKQoJZ290byBiYWlsMDsKICAgIGlmIChGY0RlYnVnICgpICYgRkNfREJHX0NBQ0hFKQoJcHJpbnRmICgiRmNEaXJDYWNoZVdyaXRlRGlyIGNhY2hlX2ZpbGUgXCIlc1wiXG4iLCBjYWNoZV9maWxlKTsKICAgIAogICAgZiA9IGZvcGVuICgoY2hhciAqKSBjYWNoZV9maWxlLCAidyIpOwogICAgaWYgKCFmKQogICAgewoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEUpCgkgICAgcHJpbnRmICgiIGNhbid0IGNyZWF0ZSBcIiVzXCJcbiIsIGNhY2hlX2ZpbGUpOwoJZ290byBiYWlsMTsKICAgIH0KICAgIAogICAgbGlzdCA9IEZjU3RyTGlzdENyZWF0ZSAoZGlycyk7CiAgICBpZiAoIWxpc3QpCglnb3RvIGJhaWwyOwogICAgCiAgICB3aGlsZSAoKGRpciA9IEZjU3RyTGlzdE5leHQgKGxpc3QpKSkKICAgIHsKCWJhc2UgPSBGY0ZpbGVCYXNlTmFtZSAoY2FjaGVfZmlsZSwgZGlyKTsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBiYXNlKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKFBVVEMgKCcgJywgZikgPT0gRU9GKQoJICAgIGdvdG8gYmFpbDM7CglpZiAoIUZjQ2FjaGVXcml0ZUludCAoZiwgMCkpCgkgICAgZ290byBiYWlsMzsKICAgICAgICBpZiAoUFVUQyAoJyAnLCBmKSA9PSBFT0YpCgkgICAgZ290byBiYWlsMzsKCWlmICghRmNDYWNoZVdyaXRlU3RyaW5nIChmLCBGQ19GT05UX0ZJTEVfRElSKSkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKFBVVEMgKCdcbicsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwogICAgfQogICAgCiAgICBmb3IgKG4gPSAwOyBuIDwgc2V0LT5uZm9udDsgbisrKQogICAgewoJZm9udCA9IHNldC0+Zm9udHNbbl07CglpZiAoRmNQYXR0ZXJuR2V0U3RyaW5nIChmb250LCBGQ19GSUxFLCAwLCAoRmNDaGFyOCAqKikgJmZpbGUpICE9IEZjUmVzdWx0TWF0Y2gpCgkgICAgZ290byBiYWlsMzsKCWJhc2UgPSBGY0ZpbGVCYXNlTmFtZSAoY2FjaGVfZmlsZSwgZmlsZSk7CglpZiAoRmNQYXR0ZXJuR2V0SW50ZWdlciAoZm9udCwgRkNfSU5ERVgsIDAsICZpZCkgIT0gRmNSZXN1bHRNYXRjaCkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKEZjRGVidWcgKCkgJiBGQ19EQkdfQ0FDSEVWKQoJICAgIHByaW50ZiAoIiB3cml0ZSBmaWxlIFwiJXNcIlxuIiwgYmFzZSk7CglpZiAoIUZjQ2FjaGVXcml0ZVN0cmluZyAoZiwgYmFzZSkpCgkgICAgZ290byBiYWlsMzsKCWlmIChQVVRDICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJaWYgKCFGY0NhY2hlV3JpdGVJbnQgKGYsIGlkKSkKCSAgICBnb3RvIGJhaWwzOwogICAgICAgIGlmIChQVVRDICgnICcsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwoJbmFtZSA9IEZjTmFtZVVucGFyc2UgKGZvbnQpOwoJaWYgKCFuYW1lKQoJICAgIGdvdG8gYmFpbDM7CglyZXQgPSBGY0NhY2hlV3JpdGVTdHJpbmcgKGYsIG5hbWUpOwoJZnJlZSAobmFtZSk7CglpZiAoIXJldCkKCSAgICBnb3RvIGJhaWwzOwoJaWYgKFBVVEMgKCdcbicsIGYpID09IEVPRikKCSAgICBnb3RvIGJhaWwzOwogICAgfQogICAgCiAgICBGY1N0ckxpc3REb25lIChsaXN0KTsKCiAgICBpZiAoZmNsb3NlIChmKSA9PSBFT0YpCglnb3RvIGJhaWwxOwogICAgCiAgICBmcmVlIChjYWNoZV9maWxlKTsKCiAgICBpZiAoRmNEZWJ1ZyAoKSAmIEZDX0RCR19DQUNIRSkKCXByaW50ZiAoIiBjYWNoZSB3cml0dGVuXG4iKTsKICAgIHJldHVybiBGY1RydWU7CiAgICAKYmFpbDM6CiAgICBGY1N0ckxpc3REb25lIChsaXN0KTsKYmFpbDI6CiAgICBmY2xvc2UgKGYpOwpiYWlsMToKICAgIHVubGluayAoKGNoYXIgKikgY2FjaGVfZmlsZSk7CiAgICBmcmVlIChjYWNoZV9maWxlKTsKYmFpbDA6CiAgICByZXR1cm4gRmNGYWxzZTsKfQo=