summaryrefslogtreecommitdiffabout
path: root/src/binlogcat.c
authorSergey Poznyakoff <gray@gnu.org.ua>2013-10-12 09:19:32 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2013-10-12 09:28:12 (GMT)
commitb6678bb65fce1f64e82cc049aae3d7ba6f8aa19c (patch) (side-by-side diff)
tree55c1959713e8f37f5958afb4c0cdb4d751406fe6 /src/binlogcat.c
parent791cdf412f5fb66a056aa28b27507fdc9af86507 (diff)
downloadvmod-binlog-b6678bb65fce1f64e82cc049aae3d7ba6f8aa19c.tar.gz
vmod-binlog-b6678bb65fce1f64e82cc049aae3d7ba6f8aa19c.tar.bz2
Rewrite using opaque record data.
Records can carry arbitrary data, whose format is defined using teplate strings similar to those of Perl's pack() function. The teplate string is stored in the logfile header and is used by binlogcat to render a human-readable representation. * src/.gitignore: New file. * pack.c: New file. * pack.h: New file. * src/Makefile.am: Add pack.c, pack.h * src/binlog.c: Rewrite. Use pack routines to construct each record. * src/binlogcat.c: Likewise. Use packout to unpack each record. * src/vmod-binlog.h (struct binlog_record): Remove nid,aid. (struct binlog_file_header): Add hdrsize. (BINLOG_HEADER_SIZE,union binlog_header): Remove (binlog_recnum): Remove. (binlog_size): Rewrite. * src/vmod.vcc (append,sappend): Remove. (init): Change signature. (start,commit,pack): New functions. * tests/test01.at: Rewrite. * tests/test02.at: Rewrite.
Diffstat (limited to 'src/binlogcat.c') (more/less context) (ignore whitespace changes)
-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 @@
#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);
}

Return to:

Send suggestions and report system problems to the System administrator.