diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2014-05-30 16:45:49 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2014-05-30 16:45:49 +0300 |
commit | b425cc797090c46c3c9ab7b3052d322c4224bd76 (patch) | |
tree | 4a613bd71502b12851ddfb69fc1d442a09c3ecf5 /src/binlogsel.c | |
parent | 2035536f831b0ce54c28c2a0b405febb113e0fab (diff) | |
download | vmod-binlog-b425cc797090c46c3c9ab7b3052d322c4224bd76.tar.gz vmod-binlog-b425cc797090c46c3c9ab7b3052d322c4224bd76.tar.bz2 |
binlogsel: dry-run and incremental mode.
* src/binlogsel.c (last_ts): New variable.
(module_init): Change signature (incompatible change!)
(interval) <descr>: New member.
(interval_count): New variable.
(interval_add): Take descr as argument. Fill in interval->descr.
(interval_add): Increment interval_count.
(interval_add_str): Construct descr.
(selmem): Update last_ts
(selidx_day,selidx_month,selidx_year): Silently ignore non-existing
directories. Don't bail out if no matching file was found.
(selidx_year): Clear the START_TIME flag after the first iteration.
(read_status_fp,read_status_file)
(write_status_file): New functions.
(main): New option -n.
Use interval_add_str to parse intervals.
Pass flags to module_init.
Process status file, if requested.
Diffstat (limited to 'src/binlogsel.c')
-rw-r--r-- | src/binlogsel.c | 216 |
1 files changed, 182 insertions, 34 deletions
diff --git a/src/binlogsel.c b/src/binlogsel.c index da04636..c448bd5 100644 --- a/src/binlogsel.c +++ b/src/binlogsel.c | |||
@@ -43,9 +43,11 @@ char *directory; | |||
43 | char *pattern; | 43 | char *pattern; |
44 | enum binlog_index_type index_type = index_year; | 44 | enum binlog_index_type index_type = index_year; |
45 | 45 | ||
46 | time_t last_ts; | ||
47 | |||
46 | char *module_name; | 48 | char *module_name; |
47 | char *module_args; | 49 | char *module_args; |
48 | void (*module_init)(char *, void (*)(const char *, const char *, const char *)); | 50 | void (*module_init)(int, char *, void (*)(const char *, const char *, const char *)); |
49 | int (*module_open)(const char *, size_t, const char *); | 51 | int (*module_open)(const char *, size_t, const char *); |
50 | void (*module_close)(void); | 52 | void (*module_close)(void); |
51 | void (*module_done)(void); | 53 | void (*module_done)(void); |
@@ -69,19 +71,23 @@ void selglob(const char *dir, const char *pattern); | |||
69 | struct interval { | 71 | struct interval { |
70 | struct interval *next; | 72 | struct interval *next; |
71 | char *name; | 73 | char *name; |
74 | char *descr; | ||
72 | int timemask; | 75 | int timemask; |
73 | time_t start; | 76 | time_t start; |
74 | time_t end; | 77 | time_t end; |
75 | }; | 78 | }; |
76 | 79 | ||
77 | static struct interval *interval_head, *interval_tail; | 80 | static struct interval *interval_head, *interval_tail; |
81 | size_t interval_count; | ||
78 | 82 | ||
79 | void | 83 | void |
80 | interval_add(const char *name, int tmask, time_t start, time_t end) | 84 | interval_add(const char *name, const char *descr, |
85 | int tmask, time_t start, time_t end) | ||
81 | { | 86 | { |
82 | struct interval *p = xmalloc(sizeof(*p)); | 87 | struct interval *p = xmalloc(sizeof(*p)); |
83 | p->next = NULL; | 88 | p->next = NULL; |
84 | p->name = xstrdup(name); | 89 | p->name = xstrdup(name); |
90 | p->descr = xstrdup(descr); | ||
85 | p->timemask = tmask; | 91 | p->timemask = tmask; |
86 | p->start = start; | 92 | p->start = start; |
87 | p->end = end; | 93 | p->end = end; |
@@ -90,7 +96,8 @@ interval_add(const char *name, int tmask, time_t start, time_t end) | |||
90 | else | 96 | else |
91 | interval_head = p; | 97 | interval_head = p; |
92 | interval_tail = p; | 98 | interval_tail = p; |
93 | 99 | ++interval_count; | |
100 | |||
94 | if (tmask & START_TIME) { | 101 | if (tmask & START_TIME) { |
95 | if (!(timemask & START_TIME) || start_time > start) { | 102 | if (!(timemask & START_TIME) || start_time > start) { |
96 | start_time = start; | 103 | start_time = start; |
@@ -133,8 +140,20 @@ interval_add_str(const char *id, const char *from, const char *to) | |||
133 | tmask |= STOP_TIME; | 140 | tmask |= STOP_TIME; |
134 | } | 141 | } |
135 | 142 | ||
136 | if (tmask) | 143 | if (tmask) { |
137 | interval_add(id, tmask, start, end); | 144 | char *descr = xmalloc((from ? strlen(from) : 0) |
145 | + (from ? strlen(from) : 0) + 1); | ||
146 | descr[0] = 0; | ||
147 | if (from) | ||
148 | strcat(descr, from); | ||
149 | strcat(descr, ":"); | ||
150 | if (to) | ||
151 | strcat(descr, to); | ||
152 | |||
153 | interval_add(id, descr, tmask, start, end); | ||
154 | |||
155 | free(descr); | ||
156 | } | ||
138 | } | 157 | } |
139 | 158 | ||
140 | 159 | ||
@@ -349,6 +368,9 @@ selmem(const char *name, void *base) | |||
349 | continue; | 368 | continue; |
350 | if ((ip->timemask & STOP_TIME) && ip->end < rec->ts) | 369 | if ((ip->timemask & STOP_TIME) && ip->end < rec->ts) |
351 | continue; | 370 | continue; |
371 | |||
372 | last_ts = rec->ts; | ||
373 | |||
352 | if (module_record) | 374 | if (module_record) |
353 | module_record(ip->name, rec->ts, env->buf_base); | 375 | module_record(ip->name, rec->ts, env->buf_base); |
354 | else { | 376 | else { |
@@ -519,6 +541,13 @@ selidx_day(const char *dir) | |||
519 | char *dirbuf; | 541 | char *dirbuf; |
520 | size_t dirlen; | 542 | size_t dirlen; |
521 | 543 | ||
544 | if (access(dir, F_OK)) { | ||
545 | if (errno == ENOENT) | ||
546 | return; | ||
547 | else | ||
548 | error("can't access %s: %s", dir, strerror(errno)); | ||
549 | } | ||
550 | |||
522 | if (index_type == index_month) { | 551 | if (index_type == index_month) { |
523 | selglob(dir, BINLOG_GLOB_PATTERN); | 552 | selglob(dir, BINLOG_GLOB_PATTERN); |
524 | return; | 553 | return; |
@@ -532,7 +561,7 @@ selidx_day(const char *dir) | |||
532 | from_day = filename_to_int(gl.gl_pathv[0]); | 561 | from_day = filename_to_int(gl.gl_pathv[0]); |
533 | else { | 562 | else { |
534 | error("no matching files"); | 563 | error("no matching files"); |
535 | exit(1); | 564 | return; |
536 | } | 565 | } |
537 | } | 566 | } |
538 | 567 | ||
@@ -543,7 +572,7 @@ selidx_day(const char *dir) | |||
543 | glinit = matchnames(dir, "[0-9][0-9]", &gl); | 572 | glinit = matchnames(dir, "[0-9][0-9]", &gl); |
544 | if (!glinit) { | 573 | if (!glinit) { |
545 | error("no matching files"); | 574 | error("no matching files"); |
546 | exit(1); | 575 | return; |
547 | } | 576 | } |
548 | } | 577 | } |
549 | to_day = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]); | 578 | to_day = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]); |
@@ -569,6 +598,13 @@ selidx_month(const char *dir) | |||
569 | char *dirbuf; | 598 | char *dirbuf; |
570 | size_t dirlen; | 599 | size_t dirlen; |
571 | 600 | ||
601 | if (access(dir, F_OK)) { | ||
602 | if (errno == ENOENT) | ||
603 | return; | ||
604 | else | ||
605 | error("can't access %s: %s", dir, strerror(errno)); | ||
606 | } | ||
607 | |||
572 | if (index_type == index_year) { | 608 | if (index_type == index_year) { |
573 | selglob(dir, BINLOG_GLOB_PATTERN); | 609 | selglob(dir, BINLOG_GLOB_PATTERN); |
574 | return; | 610 | return; |
@@ -582,7 +618,7 @@ selidx_month(const char *dir) | |||
582 | from_month = filename_to_int(gl.gl_pathv[0]); | 618 | from_month = filename_to_int(gl.gl_pathv[0]); |
583 | else { | 619 | else { |
584 | error("no matching files"); | 620 | error("no matching files"); |
585 | exit(1); | 621 | return; |
586 | } | 622 | } |
587 | } | 623 | } |
588 | 624 | ||
@@ -593,7 +629,7 @@ selidx_month(const char *dir) | |||
593 | glinit = matchnames(dir, "[0-9][0-9]", &gl); | 629 | glinit = matchnames(dir, "[0-9][0-9]", &gl); |
594 | if (!glinit) { | 630 | if (!glinit) { |
595 | error("no matching files"); | 631 | error("no matching files"); |
596 | exit(1); | 632 | return; |
597 | } | 633 | } |
598 | } | 634 | } |
599 | to_month = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]); | 635 | to_month = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]); |
@@ -619,6 +655,13 @@ selidx_year(const char *dir) | |||
619 | char *dirbuf; | 655 | char *dirbuf; |
620 | size_t dirlen; | 656 | size_t dirlen; |
621 | 657 | ||
658 | if (access(dir, F_OK)) { | ||
659 | if (errno == ENOENT) | ||
660 | return; | ||
661 | else | ||
662 | error("can't access %s: %s", dir, strerror(errno)); | ||
663 | } | ||
664 | |||
622 | if (timemask & START_TIME) | 665 | if (timemask & START_TIME) |
623 | from_year = 1900 + gmtime(&start_time)->tm_year; | 666 | from_year = 1900 + gmtime(&start_time)->tm_year; |
624 | else { | 667 | else { |
@@ -627,7 +670,7 @@ selidx_year(const char *dir) | |||
627 | from_year = filename_to_int(gl.gl_pathv[0]); | 670 | from_year = filename_to_int(gl.gl_pathv[0]); |
628 | else { | 671 | else { |
629 | error("no matching files"); | 672 | error("no matching files"); |
630 | exit(1); | 673 | return; |
631 | } | 674 | } |
632 | } | 675 | } |
633 | 676 | ||
@@ -638,7 +681,7 @@ selidx_year(const char *dir) | |||
638 | glinit = matchnames(dir, "[0-9][0-9][0-9][0-9]", &gl); | 681 | glinit = matchnames(dir, "[0-9][0-9][0-9][0-9]", &gl); |
639 | if (!glinit) { | 682 | if (!glinit) { |
640 | error("no matching files"); | 683 | error("no matching files"); |
641 | exit(1); | 684 | return; |
642 | } | 685 | } |
643 | } | 686 | } |
644 | to_year = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]); | 687 | to_year = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]); |
@@ -649,6 +692,7 @@ selidx_year(const char *dir) | |||
649 | for (; from_year <= to_year; from_year++) { | 692 | for (; from_year <= to_year; from_year++) { |
650 | snprintf(dirbuf, dirlen, "%s/%04d", dir, from_year); | 693 | snprintf(dirbuf, dirlen, "%s/%04d", dir, from_year); |
651 | selidx_month(dirbuf); | 694 | selidx_month(dirbuf); |
695 | timemask &= ~START_TIME; | ||
652 | } |