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 @@ | |||
17 | 17 | ||
18 | #include <config.h> | 18 | #include <config.h> |
19 | #include <unistd.h> | 19 | #include <unistd.h> |
20 | #include <stddef.h> | ||
20 | #include <stdio.h> | 21 | #include <stdio.h> |
21 | #include <stdlib.h> | 22 | #include <stdlib.h> |
22 | #include <errno.h> | 23 | #include <errno.h> |
23 | #include <time.h> | 24 | #include <time.h> |
24 | #include <string.h> | 25 | #include <string.h> |
25 | #include "vmod-binlog.h" | 26 | #include "vmod-binlog.h" |
27 | #include "pack.h" | ||
26 | 28 | ||
27 | char *progname; | 29 | char *progname; |
28 | char *timefmt = "%c"; | 30 | char *timefmt = "%c"; |
@@ -34,11 +36,16 @@ void | |||
34 | catlog(const char *fname) | 36 | catlog(const char *fname) |
35 | { | 37 | { |
36 | FILE *fp; | 38 | FILE *fp; |
37 | union binlog_header header; | 39 | struct binlog_file_header header; |
38 | struct binlog_record rec; | 40 | struct binlog_record *rec; |
39 | char timebuf[128]; | 41 | char timebuf[128]; |
40 | size_t i; | 42 | size_t i; |
41 | time_t start_ts; | 43 | time_t start_ts; |
44 | char *dataspec; | ||
45 | size_t size; | ||
46 | struct packenv *env; | ||
47 | struct packinst *inst; | ||
48 | char *p; | ||
42 | 49 | ||
43 | if (strcmp(fname, "-") == 0) | 50 | if (strcmp(fname, "-") == 0) |
44 | fp = stdin; | 51 | fp = stdin; |
@@ -57,29 +64,54 @@ catlog(const char *fname) | |||
57 | exit(1); | 64 | exit(1); |
58 | } | 65 | } |
59 | 66 | ||
60 | if (memcmp(header.hdr.magic, BINLOG_MAGIC_STR, BINLOG_MAGIC_LEN)) { | 67 | if (memcmp(header.magic, BINLOG_MAGIC_STR, BINLOG_MAGIC_LEN)) { |
61 | fprintf(stderr, "%s: %s is not a binlog file\n", | 68 | fprintf(stderr, "%s: %s is not a binlog file\n", |
62 | progname, fname); | 69 | progname, fname); |
63 | exit(1); | 70 | exit(1); |
64 | } | 71 | } |
65 | 72 | ||
66 | if (header.hdr.version != BINLOG_VERSION) { | 73 | if (header.version != BINLOG_VERSION) { |
67 | fprintf(stderr, "%s: %s: unknown version\n", | 74 | fprintf(stderr, "%s: %s: unknown version\n", |
68 | progname, fname); | 75 | progname, fname); |
69 | exit(1); | 76 | exit(1); |
70 | } | 77 | } |
71 | 78 | ||
72 | if (header.hdr.recsize != sizeof(struct binlog_record)) { | 79 | size = header.hdrsize - sizeof(header); |
73 | fprintf(stderr, "%s: %s: record length mismatch\n", | 80 | dataspec = malloc(size); |
74 | progname, fname); | 81 | if (!dataspec) { |
82 | fprintf(stderr, "%s: not enough memory", progname); | ||
83 | abort(); | ||
84 | } | ||
85 | |||
86 | if (fread(dataspec, size, 1, fp) != 1) { | ||
87 | fprintf(stderr, "%s: error reading header of %s: %s\n", | ||
88 | progname, fname, strerror(errno)); | ||
75 | exit(1); | 89 | exit(1); |
76 | } | 90 | } |
77 | 91 | ||
78 | if (verbose_option) | 92 | if (verbose_option) |
79 | printf("# %s; %lu records\n", fname, header.hdr.recnum); | 93 | printf("# %s; format=%s; recsize=%lu; recnum=%lu\n", |
94 | fname, dataspec, header.recsize, header.recnum); | ||
95 | |||
96 | inst = packcomp(dataspec, &p); | ||
97 | if (*p) { | ||
98 | fprintf(stderr, "%s: %s: bad dataspec near %s", | ||
99 | progname, dataspec, p); | ||
100 | exit(1); | ||
101 | } | ||
102 | free(dataspec); | ||
103 | |||
104 | rec = malloc(header.recsize); | ||
105 | if (!rec) { | ||
106 | fprintf(stderr, "%s: not enough memory", progname); | ||
107 | abort(); | ||
108 | } | ||
109 | env = packenv_create(header.recsize - | ||
110 | offsetof(struct binlog_record,data)); | ||
111 | env->fp = stdout; | ||
80 | 112 | ||
81 | for (i = 0; i < header.hdr.recnum; i++) { | 113 | for (i = 0; i < header.recnum; i++) { |
82 | if (fread(&rec, sizeof(rec), 1, fp) != 1) { | 114 | if (fread(rec, header.recsize, 1, fp) != 1) { |
83 | fprintf(stderr, "%s: %s: unexpected eof\n", | 115 | fprintf(stderr, "%s: %s: unexpected eof\n", |
84 | progname, fname); | 116 | progname, fname); |
85 | break; | 117 | break; |
@@ -87,15 +119,26 @@ catlog(const char *fname) | |||
87 | 119 | ||
88 | if (timediff_option) { | 120 | if (timediff_option) { |
89 | if (i == 0) | 121 | if (i == 0) |
90 | start_ts = rec.ts; | 122 | start_ts = rec->ts; |
91 | rec.ts -= start_ts; | 123 | rec->ts -= start_ts; |
92 | } | 124 | } |
93 | 125 | ||
94 | strftime(timebuf, sizeof timebuf, timefmt, localtime(&rec.ts)); | 126 | strftime(timebuf, sizeof timebuf, timefmt, |
127 | localtime(&rec->ts)); | ||
95 | if (number_option) | 128 | if (number_option) |
96 | printf("%lu ", (unsigned long) i); | 129 | printf("%lu ", (unsigned long) i); |
97 | printf("%s %ld %ld\n", timebuf, rec.nid, rec.aid); | 130 | printf("%s ", timebuf); |
131 | |||
132 | memcpy(env->buf_base, rec->data, env->buf_size); | ||
133 | env->buf_pos = 0; | ||
134 | |||
135 | packout(inst, env); | ||
136 | fputc('\n', stdout); | ||
98 | } | 137 | } |
138 | |||
139 | free(rec); | ||
140 | packenv_free(env); | ||
141 | packfree(inst); | ||
99 | 142 | ||
100 | fclose(fp); | 143 | fclose(fp); |
101 | } | 144 | } |