diff options
Diffstat (limited to 'src/binlogcat.c')
-rw-r--r-- | src/binlogcat.c | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/src/binlogcat.c b/src/binlogcat.c index 219f78c..ee8837a 100644 --- a/src/binlogcat.c +++ b/src/binlogcat.c @@ -17,12 +17,14 @@ #include <config.h> #include <unistd.h> +#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <time.h> #include <string.h> #include "vmod-binlog.h" +#include "pack.h" char *progname; char *timefmt = "%c"; @@ -34,11 +36,16 @@ void catlog(const char *fname) { FILE *fp; - union binlog_header header; - struct binlog_record rec; + struct binlog_file_header header; + struct binlog_record *rec; char timebuf[128]; size_t i; time_t start_ts; + char *dataspec; + size_t size; + struct packenv *env; + struct packinst *inst; + char *p; if (strcmp(fname, "-") == 0) fp = stdin; @@ -57,29 +64,54 @@ catlog(const char *fname) exit(1); } - if (memcmp(header.hdr.magic, BINLOG_MAGIC_STR, BINLOG_MAGIC_LEN)) { + if (memcmp(header.magic, BINLOG_MAGIC_STR, BINLOG_MAGIC_LEN)) { fprintf(stderr, "%s: %s is not a binlog file\n", progname, fname); exit(1); } - if (header.hdr.version != BINLOG_VERSION) { + if (header.version != BINLOG_VERSION) { fprintf(stderr, "%s: %s: unknown version\n", progname, fname); exit(1); } - if (header.hdr.recsize != sizeof(struct binlog_record)) { - fprintf(stderr, "%s: %s: record length mismatch\n", - progname, fname); + size = header.hdrsize - sizeof(header); + dataspec = malloc(size); + if (!dataspec) { + fprintf(stderr, "%s: not enough memory", progname); + abort(); + } + + if (fread(dataspec, size, 1, fp) != 1) { + fprintf(stderr, "%s: error reading header of %s: %s\n", + progname, fname, strerror(errno)); exit(1); } if (verbose_option) - printf("# %s; %lu records\n", fname, header.hdr.recnum); + printf("# %s; format=%s; recsize=%lu; recnum=%lu\n", + fname, dataspec, header.recsize, header.recnum); + + inst = packcomp(dataspec, &p); + if (*p) { + fprintf(stderr, "%s: %s: bad dataspec near %s", + progname, dataspec, p); + exit(1); + } + free(dataspec); + + rec = malloc(header.recsize); + if (!rec) { + fprintf(stderr, "%s: not enough memory", progname); + abort(); + } + env = packenv_create(header.recsize - + offsetof(struct binlog_record,data)); + env->fp = stdout; - for (i = 0; i < header.hdr.recnum; i++) { - if (fread(&rec, sizeof(rec), 1, fp) != 1) { + for (i = 0; i < header.recnum; i++) { + if (fread(rec, header.recsize, 1, fp) != 1) { fprintf(stderr, "%s: %s: unexpected eof\n", progname, fname); break; @@ -87,15 +119,26 @@ catlog(const char *fname) if (timediff_option) { if (i == 0) - start_ts = rec.ts; - rec.ts -= start_ts; + start_ts = rec->ts; + rec->ts -= start_ts; } - strftime(timebuf, sizeof timebuf, timefmt, localtime(&rec.ts)); + strftime(timebuf, sizeof timebuf, timefmt, + localtime(&rec->ts)); if (number_option) printf("%lu ", (unsigned long) i); - printf("%s %ld %ld\n", timebuf, rec.nid, rec.aid); + printf("%s ", timebuf); + + memcpy(env->buf_base, rec->data, env->buf_size); + env->buf_pos = 0; + + packout(inst, env); + fputc('\n', stdout); } + + free(rec); + packenv_free(env); + packfree(inst); fclose(fp); } |