aboutsummaryrefslogtreecommitdiff
path: root/src/binlogsel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/binlogsel.c')
-rw-r--r--src/binlogsel.c235
1 files changed, 223 insertions, 12 deletions
diff --git a/src/binlogsel.c b/src/binlogsel.c
index 62299e5..8f1cfce 100644
--- a/src/binlogsel.c
+++ b/src/binlogsel.c
@@ -35,27 +35,32 @@
35#include "parse-datetime.h" 35#include "parse-datetime.h"
36 36
37char *timefmt = "%c"; 37char *timefmt = "%c";
38int number_option; 38int number_option;
39int verbose_option; 39int verbose_option;
40int timediff_option; 40int timediff_option;
41char *directory;
41char *pattern; 42char *pattern;
43enum binlog_index_type index_type = index_year;
42 44
43#define FROM_TIME 0x01 45#define FROM_TIME 0x01
44#define TO_TIME 0x02 46#define TO_TIME 0x02
45int timemask; 47int timemask;
46time_t from_time, to_time; 48time_t from_time, to_time;
47 49
50static int matchnames(const char *dir, const char *pat, glob_t *gl);
51void selglob(const char *dir, const char *pattern);
52
48void 53void
49help() 54help()
50{ 55{
51 printf("usage: %s [-dhnv] [-t FORMAT] [-F FROMTIME] [-T TOTIME] [-p PATTERN] [-D DIR] [FILE...]\n", progname); 56 printf("usage: %s [-dhnv] [-t FORMAT] [-F FROMTIME] [-T TOTIME] [-p PATTERN] [-D DIR] [FILE...]\n", progname);
52} 57}
53 58
54/* Convert strftime-like pattern into globbing pattern */ 59/* Convert strftime-like pattern into globbing pattern */
55void 60char *
56convpattern(const char *dir) 61convpattern(const char *dir)
57{ 62{
58 char *p, *q; 63 char *p, *q;
59 char *newpat; 64 char *newpat;
60 size_t size = strlen(pattern) + 1; 65 size_t size = strlen(pattern) + 1;
61 66
@@ -70,19 +75,20 @@ convpattern(const char *dir)
70 p += strlen(dir); 75 p += strlen(dir);
71 *p++ = '/'; 76 *p++ = '/';
72 } 77 }
73 78
74 for (q = pattern; *q; ) { 79 for (q = pattern; *q; ) {
75 if (*q == '%') { 80 if (*q == '%') {
81 if (p > newpat && p[-1] != '*')
76 *p++ = '*'; 82 *p++ = '*';
77 q += 2; 83 q += 2;
78 } else 84 } else
79 *p++ = *q++; 85 *p++ = *q++;
80 } 86 }
81 *p = 0; 87 *p = 0;
82 pattern = newpat; 88 return newpat;
83} 89}
84 90
85#define getrec(base, recsize, n) \ 91#define getrec(base, recsize, n) \
86 ((struct binlog_record*)((char *)(base) + (n) * (recsize))) 92 ((struct binlog_record*)((char *)(base) + (n) * (recsize)))
87 93
88int 94int
@@ -330,19 +336,217 @@ void
330selfilelist(char **argv) 336selfilelist(char **argv)
331{ 337{
332 for (;*argv;++argv) 338 for (;*argv;++argv)
333 selfile(*argv); 339 selfile(*argv);
334} 340}
335 341
342static char *
343mkfilename(const char *dir, const char *file)
344{
345 size_t dirlen, size;
346 char *ret;
347
348 dirlen = strlen(dir);
349 while (dirlen > 0 && dir[dirlen-1] == '/')
350 --dirlen;
351 size = dirlen + 1 + strlen(file) + 1;
352 ret = xmalloc(size);
353 memcpy(ret, dir, dirlen);
354 ret[dirlen++] = '/';
355 strcpy(ret + dirlen, file);
356 return ret;
357}
358
359int
360filename_to_int(char *name)
361{
362 char *p = strrchr(name, '/');
363 if (!p)
364 abort();
365 return atoi(p + 1);
366}
367
368void
369selidx_day(const char *dir)
370{
371 int from_day, to_day;
372 struct tm *tm;
373 glob_t gl;
374 int glinit = 0;
375 char *dirbuf;
376 size_t dirlen;
377
378 if (index_type == index_month) {
379 selglob(dir, BINLOG_GLOB_PATTERN);
380 return;
381 }
382
383 if (timemask & FROM_TIME)
384 from_day = gmtime(&from_time)->tm_mday;
385 else {
386 glinit = matchnames(dir, "[0-9][0-9]", &gl);
387 if (glinit)
388 from_day = filename_to_int(gl.gl_pathv[0]);
389 else {
390 error("no matching files");
391 exit(1);
392 }
393 }
394
395 if (timemask & TO_TIME)
396 to_day = gmtime(&to_time)->tm_mday;
397 else {
398 if (!glinit) {
399 glinit = matchnames(dir, "[0-9][0-9]", &gl);
400 if (!glinit) {
401 error("no matching files");
402 exit(1);
403 }
404 }
405 to_day = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]);
406 }
407
408 dirlen = strlen(dir) + 4;
409 dirbuf = xmalloc(dirlen);
410 for (;from_day <= to_day; from_day++) {
411 snprintf(dirbuf, dirlen, "%s/%02d", dir, from_day);
412 selglob(dirbuf, BINLOG_GLOB_PATTERN);
413 }
414 free(dirbuf);
415 if (glinit)
416 globfree(&gl);
417}
418
419void
420selidx_month(const char *dir)
421{
422 int from_month, to_month;
423 struct tm *tm;
424 glob_t gl;
425 int glinit = 0;
426 char *dirbuf;
427 size_t dirlen;
428
429 if (index_type == index_year) {
430 selglob(dir, BINLOG_GLOB_PATTERN);
431 return;
432 }
433
434 if (timemask & FROM_TIME)
435 from_month = 1 + gmtime(&from_time)->tm_mon;
436 else {
437 glinit = matchnames(dir, "[0-9][0-9]", &gl);
438 if (glinit)
439 from_month = filename_to_int(gl.gl_pathv[0]);
440 else {
441 error("no matching files");
442 exit(1);
443 }
444 }
445
446 if (timemask & TO_TIME)
447 to_month = 1 + gmtime(&to_time)->tm_mon;
448 else {
449 if (!glinit) {
450 glinit = matchnames(dir, "[0-9][0-9]", &gl);
451 if (!glinit) {
452 error("no matching files");
453 exit(1);
454 }
455 }
456 to_month = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]);
457 }
458
459 dirlen = strlen(dir) + 4;
460 dirbuf = xmalloc(dirlen);
461 for (;from_month <= to_month; from_month++) {
462 snprintf(dirbuf, dirlen, "%s/%02d", dir, from_month);
463 selidx_day(dirbuf);
464 }
465 free(dirbuf);
466 if (glinit)
467 globfree(&gl);
468}
469
470void
471selidx_year(const char *dir)
472{
473 int from_year, to_year;
474 struct tm *tm;
475 glob_t gl;
476 int glinit = 0;
477 char *dirbuf;
478 size_t dirlen;
479
480 if (timemask & FROM_TIME)
481 from_year = 1900 + gmtime(&from_time)->tm_year;
482 else {
483 glinit = matchnames(dir, "[0-9][0-9][0-9][0-9]", &gl);
484 if (glinit)
485 from_year = filename_to_int(gl.gl_pathv[0]);
486 else {
487 error("no matching files");
488 exit(1);
489 }
490 }
491
492 if (timemask & TO_TIME)
493 to_year = 1900 + gmtime(&to_time)->tm_year;
494 else {
495 if (!glinit) {
496 glinit = matchnames(dir, "[0-9][0-9][0-9][0-9]", &gl);
497 if (!glinit) {