summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2013-10-17 07:21:56 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2013-10-17 07:21:56 (GMT)
commitaad0ead6ae1bb56953642eac584d9a5f1dc6d72e (patch) (side-by-side diff)
treefb943138c9612c0036860e9991420a1ea5433c05
parent57d1cbccf5bfb96831501519825e462580b0affe (diff)
downloadvmod-binlog-aad0ead6ae1bb56953642eac584d9a5f1dc6d72e.tar.gz
vmod-binlog-aad0ead6ae1bb56953642eac584d9a5f1dc6d72e.tar.bz2
Add multiple interval support to binlogsel.
* src/binlogsel.c (FROM_TIME,TO_TIME): Rename to START_TIME, STOP_TIME. (from_time,to_time): Rename to start_time,to_time. (CLEAR_START_TIME,CLEAR_STOP_TIME): New macros. (interval): New struct. (interval_head, interval_tail): New variables. (interval_add): New function. (selmem): Iterate over available intervals and output records for those that match the time limits. (main): New option -I. Build interval list from multiple -I,-F,-T options.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--src/binlogsel.c138
1 files changed, 105 insertions, 33 deletions
diff --git a/src/binlogsel.c b/src/binlogsel.c
index 550724c..5238215 100644
--- a/src/binlogsel.c
+++ b/src/binlogsel.c
@@ -42,14 +42,59 @@ char *directory;
char *pattern;
enum binlog_index_type index_type = index_year;
-#define FROM_TIME 0x01
-#define TO_TIME 0x02
+/* Time mask flags indicate which timestamp is set. */
+#define START_TIME 0x01 /* start time is set */
+#define STOP_TIME 0x02 /* stop time is set */
+/* The two flags below are valid only for global timemask. They
+ are set when building interval list and are then used in main to
+ reset the START_TIME and STOP_TIME bits. */
+#define CLEAR_START_TIME 0x04 /* Reset start time */
+#define CLEAR_STOP_TIME 0x08 /* Reset stop time */
+
int timemask;
-time_t from_time, to_time;
+time_t start_time, to_time;
static int matchnames(const char *dir, const char *pat, glob_t *gl);
void selglob(const char *dir, const char *pattern);
+struct interval {
+ struct interval *next;
+ const char *name;
+ int timemask;
+ time_t start;
+ time_t end;
+};
+
+static struct interval *interval_head, *interval_tail;
+
+void
+interval_add(const char *name, int tmask, time_t start, time_t end)
+{
+ struct interval *p = xmalloc(sizeof(*p));
+ p->next = NULL;
+ p->name = name;
+ p->timemask = tmask;
+ p->start = start;
+ p->end = end;
+ if (interval_tail)
+ interval_tail->next = p;
+ else
+ interval_head = p;
+ interval_tail = p;
+
+ if (tmask & START_TIME) {
+ if (!(timemask & START_TIME) || start_time > start)
+ start_time = start;
+ } else
+ timemask |= CLEAR_START_TIME;
+
+ if (tmask & STOP_TIME) {
+ if (!(timemask & STOP_TIME) || to_time < end)
+ to_time = end;
+ } else
+ timemask |= CLEAR_STOP_TIME;
+}
+
void
help()
{
@@ -162,6 +207,7 @@ selmem(const char *name, void *base)
time_t start_ts;
char timebuf[128];
char *format;
+ struct interval *ip;
hdr = base;
@@ -200,20 +246,20 @@ selmem(const char *name, void *base)
base = (char*)base + hdr->hdrsize;
- if (timemask & FROM_TIME) {
+ if (timemask & START_TIME) {
switch (searchts(base, hdr->recsize, 0, hdr->recnum - 1,
- from_time, &start)) {
+ start_time, &start)) {
case 0:
break;
case -1:
for (; start < hdr->recnum; start++) {
- if (getrec(base, hdr->recsize, start)->ts > from_time)
+ if (getrec(base, hdr->recsize, start)->ts > start_time)
break;
}
break;
case 1:
for (; start + 1 >= 0; start--) {
- if (from_time < getrec(base, hdr->recsize, start)->ts)
+ if (start_time < getrec(base, hdr->recsize, start)->ts)
break;
}
++start;
@@ -224,7 +270,7 @@ selmem(const char *name, void *base)
for (i = 0; start < hdr->recnum; i++, start++) {
rec = getrec(base, hdr->recsize, start);
- if ((timemask & TO_TIME) && rec->ts > to_time)
+ if ((timemask & STOP_TIME) && rec->ts > to_time)
break;
if (timediff_option) {
@@ -234,14 +280,23 @@ selmem(const char *name, void *base)
}
strftime(timebuf, sizeof timebuf, timefmt,
localtime(&rec->ts));
- if (number_option)
- printf("%lu ", (unsigned long) start);
- printf("%s ", timebuf);
memcpy(env->buf_base, rec->data, env->buf_size);
- env->buf_pos = 0;
-
- packout(inst, env);
- fputc('\n', stdout);
+ for (ip = interval_head; ip; ip = ip->next) {
+ if ((ip->timemask & START_TIME) && ip->start > rec->ts)
+ continue;
+ if ((ip->timemask & STOP_TIME) && ip->end < rec->ts)
+ continue;
+ if (ip->name)
+ printf("%s ", ip->name);
+ else if (ip == interval_head && ip->next)
+ printf("default ");
+ if (number_option)
+ printf("%lu ", (unsigned long) start);
+ printf("%s ", timebuf);
+ env->buf_pos = 0;
+ packout(inst, env);
+ fputc('\n', stdout);
+ }
}
}
@@ -291,15 +346,15 @@ fchecktime(FILE *fp, const char *fname, time_t *ts)
}
end = rec.ts;
- if ((timemask & TO_TIME) && header.recnum > 1) {
+ if ((timemask & STOP_TIME) && header.recnum > 1) {
if (to_time < start)
return 1;
- if (timemask & FROM_TIME) {
- if (from_time > end)
+ if (timemask & START_TIME) {
+ if (start_time > end)
return 1;
}
- } else if ((timemask & FROM_TIME) && from_time > end)
+ } else if ((timemask & START_TIME) && start_time > end)
return 1;
*ts = start;
@@ -399,8 +454,8 @@ selidx_day(const char *dir)
return;
}
- if (timemask & FROM_TIME)
- from_day = gmtime(&from_time)->tm_mday;
+ if (timemask & START_TIME)
+ from_day = gmtime(&start_time)->tm_mday;
else {
glinit = matchnames(dir, "[0-9][0-9]", &gl);
if (glinit)
@@ -411,7 +466,7 @@ selidx_day(const char *dir)
}
}
- if (timemask & TO_TIME)
+ if (timemask & STOP_TIME)
to_day = gmtime(&to_time)->tm_mday;
else {
if (!glinit) {
@@ -449,8 +504,8 @@ selidx_month(const char *dir)
return;
}
- if (timemask & FROM_TIME)
- from_month = 1 + gmtime(&from_time)->tm_mon;
+ if (timemask & START_TIME)
+ from_month = 1 + gmtime(&start_time)->tm_mon;
else {
glinit = matchnames(dir, "[0-9][0-9]", &gl);
if (glinit)
@@ -461,7 +516,7 @@ selidx_month(const char *dir)
}
}
- if (timemask & TO_TIME)
+ if (timemask & STOP_TIME)
to_month = 1 + gmtime(&to_time)->tm_mon;
else {
if (!glinit) {
@@ -494,8 +549,8 @@ selidx_year(const char *dir)
char *dirbuf;
size_t dirlen;
- if (timemask & FROM_TIME)
- from_year = 1900 + gmtime(&from_time)->tm_year;
+ if (timemask & START_TIME)
+ from_year = 1900 + gmtime(&start_time)->tm_year;
else {
glinit = matchnames(dir, "[0-9][0-9][0-9][0-9]", &gl);
if (glinit)
@@ -506,7 +561,7 @@ selidx_year(const char *dir)
}
}
- if (timemask & TO_TIME)
+ if (timemask & STOP_TIME)
to_year = 1900 + gmtime(&to_time)->tm_year;
else {
if (!glinit) {
@@ -629,9 +684,12 @@ main(int argc, char **argv)
{
int c;
struct timespec ts;
+ const char *id;
+ int tmask = 0;
+ time_t start, stop;
setprogname(argv[0]);
- while ((c = getopt(argc, argv, "D:dF:hi:p:T:t:nV")) != EOF)
+ while ((c = getopt(argc, argv, "D:dF:hi:I:p:T:t:nV")) != EOF)
switch (c) {
case 'D':
directory = optarg;
@@ -645,12 +703,18 @@ main(int argc, char **argv)
error("invalid timespec: %s", optarg);
exit(1);
}
- from_time = ts.tv_sec;
- timemask |= FROM_TIME;
+ start = ts.tv_sec;
+ tmask |= START_TIME;
break;
case 'h':
help();
return 0;
+ case 'I':
+ if (tmask)
+ interval_add(id, tmask, start, stop);
+ tmask = 0;
+ id = optarg;
+ break;
case 'i':
index_type = atoi(optarg);
if (index_type < 0 || index_type > index_last) {
@@ -666,8 +730,8 @@ main(int argc, char **argv)
error("invalid timespec: %s", optarg);
exit(1);
}
- to_time = ts.tv_sec;
- timemask |= TO_TIME;
+ stop = ts.tv_sec;
+ tmask |= STOP_TIME;
break;
case 't':
timefmt = optarg;
@@ -685,6 +749,14 @@ main(int argc, char **argv)
exit(1);
}
+ if (tmask)
+ interval_add(id, tmask, start, stop);
+
+ if (timemask & CLEAR_START_TIME)
+ timemask &= ~START_TIME;
+ if (timemask & CLEAR_STOP_TIME)
+ timemask &= ~STOP_TIME;
+
argc -= optind;
argv += optind;

Return to:

Send suggestions and report system problems to the System administrator.