diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-17 22:27:16 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-17 22:27:16 +0300 |
commit | 803128db75e3efea8cd7be29732a7b4315205d13 (patch) | |
tree | 713699a3724f905ca3dd740c386c9ffdb75e94a7 /src/binlogsel.c | |
parent | aad0ead6ae1bb56953642eac584d9a5f1dc6d72e (diff) | |
download | vmod-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.c | 202 |
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; | |||
42 | char *pattern; | 43 | char *pattern; |
43 | enum binlog_index_type index_type = index_year; | 44 | enum binlog_index_type index_type = index_year; |
44 | 45 | ||
46 | char *module_name; | ||
47 | char *module_args; | ||
48 | void (*module_init)(char *, void (*)(const char *, const char *, const char *)); | ||
49 | int (*module_open)(const char *, size_t, const char *); | ||
50 | void (*module_close)(void); | ||
51 | void (*module_done)(void); | ||
52 | void (*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 | ||
98 | void | 107 | void |
108 | interval_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 | |||
137 | void | ||
99 | help() | 138 | help() |
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 | ||
303 | static int | 369 | static 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 | |||
751 | struct libdir { | ||
752 | struct libdir *next; | ||
753 | struct libdir *prev; | ||
754 | const char *dir; | ||
755 | }; | ||
756 | |||
757 | struct libdir *libdir_head, *libdir_mid, *libdir_tail; | ||
758 | |||
759 | void | ||
760 | add_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 | |||
783 | void | ||
784 | loader_init(void) | ||
785 | { | ||
786 | struct libdir *ld; | ||
787 | lt_dlhandle handle = NULL; | ||