aboutsummaryrefslogtreecommitdiff
path: root/src/binlogsel.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-10-17 22:27:16 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2013-10-17 22:27:16 +0300
commit803128db75e3efea8cd7be29732a7b4315205d13 (patch)
tree713699a3724f905ca3dd740c386c9ffdb75e94a7 /src/binlogsel.c
parentaad0ead6ae1bb56953642eac584d9a5f1dc6d72e (diff)
downloadvmod-binlog-803128db75e3efea8cd7be29732a7b4315205d13.tar.gz
vmod-binlog-803128db75e3efea8cd7be29732a7b4315205d13.tar.bz2
binlogsel: add loadable module support
* Makefile.am (SUBDIRS): Add libltdl * configure.ac: Configure ltdl * src/Makefile.am (binlogsel_LDADD): Add LIBLTDL. (binlogsel_CPPFLAGS): New variable. * src/binlogcat.c (catlog): Bugfix. * src/binlogsel.c: Allow for multiple intervals. Support loadable modules. * doc/binlogcat.1: Update. * doc/binlogsel.1: Update. * doc/vmod-binlog.3: Update.
Diffstat (limited to 'src/binlogsel.c')
-rw-r--r--src/binlogsel.c202
1 files changed, 183 insertions, 19 deletions
diff --git a/src/binlogsel.c b/src/binlogsel.c
index 5238215..10630e6 100644
--- a/src/binlogsel.c
+++ b/src/binlogsel.c
@@ -28,6 +28,7 @@
28#include <time.h> 28#include <time.h>
29#include <string.h> 29#include <string.h>
30#include <glob.h> 30#include <glob.h>
31#include <ltdl.h>
31#include "vmod-binlog.h" 32#include "vmod-binlog.h"
32#include "pack.h" 33#include "pack.h"
33#include "err.h" 34#include "err.h"
@@ -42,6 +43,14 @@ char *directory;
42char *pattern; 43char *pattern;
43enum binlog_index_type index_type = index_year; 44enum binlog_index_type index_type = index_year;
44 45
46char *module_name;
47char *module_args;
48void (*module_init)(char *, void (*)(const char *, const char *, const char *));
49int (*module_open)(const char *, size_t, const char *);
50void (*module_close)(void);
51void (*module_done)(void);
52void (*module_record)(const char *, time_t, void *);
53
45/* Time mask flags indicate which timestamp is set. */ 54/* Time mask flags indicate which timestamp is set. */
46#define START_TIME 0x01 /* start time is set */ 55#define START_TIME 0x01 /* start time is set */
47#define STOP_TIME 0x02 /* stop time is set */ 56#define STOP_TIME 0x02 /* stop time is set */
@@ -96,22 +105,65 @@ interval_add(const char *name, int tmask, time_t start, time_t end)
96} 105}
97 106
98void 107void
108interval_add_str(const char *id, const char *from, const char *to)
109{
110 struct timespec ts;
111 time_t start, end;
112 int tmask = 0;
113
114 if (from) {
115 if (!parse_datetime(&ts, from, NULL)) {
116 error("invalid timespec: %s", from);
117 exit(1);
118 }
119 start = ts.tv_sec;
120 tmask |= START_TIME;
121 }
122
123 if (to) {
124 if (!parse_datetime(&ts, to, NULL)) {
125 error("invalid timespec: %s", to);
126 exit(1);
127 }
128 end = ts.tv_sec;
129 tmask |= STOP_TIME;
130 }
131
132 if (tmask)
133 interval_add(id, tmask, start, end);
134}
135
136
137void
99help() 138help()
100{ 139{
101 printf("usage: %s [-dhnVv] [-t FORMAT] [-F TIME] [-T TIME] [-p PATTERN] [-D DIR] [-i 0|1|2] [FILE...]\n", progname); 140 printf("usage: %s [OPTIONS] [FILE...]\n", progname);
102 printf("Select records from binary logs\n"); 141 printf("Select records from binary logs\n");
103 printf("\nOptions are:\n\n"); 142 printf("\nOPTIONS are:\n\n");
143 printf("File selection:\n");
104 printf(" -D DIR log file storage directory\n"); 144 printf(" -D DIR log file storage directory\n");
105 printf(" -i 0|1|2 select directory indexing level\n"); 145 printf(" -i 0|1|2 select directory indexing level\n");
146 printf(" -p PATTERN select files matching PATTERN\n");
147 printf("\n");
148 printf("Time intervals:\n");
149 printf(" -I TAG set tag for the subsequent -F and -T option pair\n");
106 printf(" -F TIME print records starting from TIME\n"); 150 printf(" -F TIME print records starting from TIME\n");
107 printf(" -T TIME print records starting up to TIME\n"); 151 printf(" -T TIME print records starting up to TIME\n");
108 printf(" -p PATTERN select files matching PATTERN\n");
109 printf("\n"); 152 printf("\n");
153 printf("Loadable module control\n");
154 printf(" -L DIR append DIR to the loadable module search path\n");
155 printf(" -P DIR add DIR to the loadable module search path before\n");
156 printf(" the default module directory\n");
157 printf(" -m 'MODULE[ ARGS]'\n");
158 printf(" load given MODULE\n");
159 printf("\n");
160 printf("Output control:\n");
110 printf(" -d print timestamps relative to first record in the file\n"); 161 printf(" -d print timestamps relative to first record in the file\n");
111 printf(" -n output record numbers\n"); 162 printf(" -n output record numbers\n");
112 printf(" -v print information about each file\n"); 163 printf(" -v print information about each file\n");
113 printf(" -t FMT format timestamps according to FMT\n"); 164 printf(" -t FMT format timestamps according to FMT\n");
114 printf("\n"); 165 printf("\n");
166 printf("Informational options:\n");
115 printf(" -h print this help summary\n"); 167 printf(" -h print this help summary\n");
116 printf(" -V show program version\n"); 168 printf(" -V show program version\n");
117 printf("\n"); 169 printf("\n");
@@ -208,6 +260,7 @@ selmem(const char *name, void *base)
208 char timebuf[128]; 260 char timebuf[128];
209 char *format; 261 char *format;
210 struct interval *ip; 262 struct interval *ip;
263 size_t datasize;
211 264
212 hdr = base; 265 hdr = base;
213 266
@@ -228,6 +281,13 @@ selmem(const char *name, void *base)
228 name, format, (unsigned long) hdr->recsize, 281 name, format, (unsigned long) hdr->recsize,
229 (unsigned long) hdr->recnum); 282 (unsigned long) hdr->recnum);
230 283
284 datasize = hdr->recsize - offsetof(struct binlog_record,data);
285
286 if (module_open && module_open(name, datasize, format)) {
287 error("%s: rejected by module %s", name, module_name);
288 return;
289 }
290
231 inst = packcomp(format, &p); 291 inst = packcomp(format, &p);
232 if (!inst) { 292 if (!inst) {
233 if (errno == EINVAL) { 293 if (errno == EINVAL) {
@@ -240,8 +300,7 @@ selmem(const char *name, void *base)
240 return; 300 return;
241 } 301 }
242 302
243 env = packenv_create(hdr->recsize - 303 env = packenv_create(datasize);
244 offsetof(struct binlog_record,data));
245 env->fp = stdout; 304 env->fp = stdout;
246 305
247 base = (char*)base + hdr->hdrsize; 306 base = (char*)base + hdr->hdrsize;
@@ -286,18 +345,25 @@ selmem(const char *name, void *base)
286 continue; 345 continue;
287 if ((ip->timemask & STOP_TIME) && ip->end < rec->ts) 346 if ((ip->timemask & STOP_TIME) && ip->end < rec->ts)
288 continue; 347 continue;
289 if (ip->name) 348 if (module_record)
290 printf("%s ", ip->name); 349 module_record(ip->name, rec->ts, env->buf_base);
291 else if (ip == interval_head && ip->next) 350 else {
292 printf("default "); 351 if (ip->name)
293 if (number_option) 352 printf("%s ", ip->name);
294 printf("%lu ", (unsigned long) start); 353 else if (ip == interval_head && ip->next)
295 printf("%s ", timebuf); 354 printf("default ");
296 env->buf_pos = 0; 355 if (number_option)
297 packout(inst, env); 356 printf("%lu ", (unsigned long) start);
298 fputc('\n', stdout); 357 printf("%s ", timebuf);
358 env->buf_pos = 0;
359 packout(inst, env);
360 fputc('\n', stdout);
361 }
299 } 362 }
300 } 363 }
364
365 if (module_close)
366 module_close();
301} 367}
302 368
303static int 369static int
@@ -679,6 +745,78 @@ selglob(const char *dir, const char *pattern)
679 globfree(&gl); 745 globfree(&gl);
680} 746}
681 747
748#define LP_PREPEND 0
749#define LP_APPEND 1
750
751struct libdir {
752 struct libdir *next;
753 struct libdir *prev;
754 const char *dir;
755};
756
757struct libdir *libdir_head, *libdir_mid, *libdir_tail;
758
759void
760add_load_path(const char *dir, int where)
761{
762 struct libdir *ld = xmalloc(sizeof(ld[0]));
763 ld->dir = dir;
764 if (!libdir_mid) {
765 ld->next = ld->prev = NULL;
766 libdir_mid = libdir_head = libdir_tail = ld;
767 } else if (where == LP_PREPEND) {
768 ld->next = libdir_mid;
769 ld->prev = libdir_mid->prev;
770 if (ld->prev)
771 ld->prev->next = libdir_mid;
772 else
773 libdir_head = ld;
774 libdir_mid->prev = ld;
775 } else /* if (where == LT_APPEND) */ {
776 ld->next = NULL;
777 ld->prev = libdir_tail;
778 libdir_tail->next = ld;
779 libdir_tail = ld;
780 }
781}
782
783void
784loader_init(void)
785{
786 struct libdir *ld;
787 lt_dlhandle handle = NULL;