aboutsummaryrefslogtreecommitdiff
path: root/src/binlogcat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/binlogcat.c')
-rw-r--r--src/binlogcat.c71
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
27char *progname; 29char *progname;
28char *timefmt = "%c"; 30char *timefmt = "%c";
@@ -34,11 +36,16 @@ void
34catlog(const char *fname) 36catlog(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}

Return to:

Send suggestions and report system problems to the System administrator.