diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-15 18:38:49 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-15 18:56:22 +0300 |
commit | ef3f928cc712f6774e19f8cb8f880cbeac15e8ff (patch) | |
tree | 88f59a4c8d1867bfadb924ee547b4b74a97c5ce0 /src/binlogsel.c | |
parent | f035194d7d1b6cc0846ad7a5d86e0d6fa9463c67 (diff) | |
download | vmod-binlog-ef3f928cc712f6774e19f8cb8f880cbeac15e8ff.tar.gz vmod-binlog-ef3f928cc712f6774e19f8cb8f880cbeac15e8ff.tar.bz2 |
Change default log naming.
* configure.ac: Call AM_PROG_CC_C_O
* src/binlog.c (BLF_TRUNCATE): New flag.
(vmod_init): Change pattern initialization.
New parameter "reuselog".
(createfile): Remove O_TRUNC.
(checkheader): New function.
(newfile): Reuse existing file, if it is the first file
to be opened after varnish startup and its header matches
exactly our data.
* src/binlogsel.c: Use indexed directory structure to speed up
searches.
* src/vmod-binlog.h (BINLOG_PATTERN): Change pattern.
(BINLOG_GLOB_PATTERN,BINLOG_INDEX): New defines.
Diffstat (limited to 'src/binlogsel.c')
-rw-r--r-- | src/binlogsel.c | 245 |
1 files changed, 228 insertions, 17 deletions
diff --git a/src/binlogsel.c b/src/binlogsel.c index 62299e5..8f1cfce 100644 --- a/src/binlogsel.c +++ b/src/binlogsel.c @@ -40,3 +40,5 @@ int verbose_option; int timediff_option; +char *directory; char *pattern; +enum binlog_index_type index_type = index_year; @@ -47,2 +49,5 @@ time_t from_time, to_time; +static int matchnames(const char *dir, const char *pat, glob_t *gl); +void selglob(const char *dir, const char *pattern); + void @@ -52,5 +57,5 @@ help() } - + /* Convert strftime-like pattern into globbing pattern */ -void +char * convpattern(const char *dir) @@ -75,3 +80,4 @@ convpattern(const char *dir) if (*q == '%') { - *p++ = '*'; + if (p > newpat && p[-1] != '*') + *p++ = '*'; q += 2; @@ -81,3 +87,3 @@ convpattern(const char *dir) *p = 0; - pattern = newpat; + return newpat; } @@ -334,3 +340,177 @@ selfilelist(char **argv) } + +static char * +mkfilename(const char *dir, const char *file) +{ + size_t dirlen, size; + char *ret; + + dirlen = strlen(dir); + while (dirlen > 0 && dir[dirlen-1] == '/') + --dirlen; + size = dirlen + 1 + strlen(file) + 1; + ret = xmalloc(size); + memcpy(ret, dir, dirlen); + ret[dirlen++] = '/'; + strcpy(ret + dirlen, file); + return ret; +} + +int +filename_to_int(char *name) +{ + char *p = strrchr(name, '/'); + if (!p) + abort(); + return atoi(p + 1); +} + +void +selidx_day(const char *dir) +{ + int from_day, to_day; + struct tm *tm; + glob_t gl; + int glinit = 0; + char *dirbuf; + size_t dirlen; + + if (index_type == index_month) { + selglob(dir, BINLOG_GLOB_PATTERN); + return; + } + + if (timemask & FROM_TIME) + from_day = gmtime(&from_time)->tm_mday; + else { + glinit = matchnames(dir, "[0-9][0-9]", &gl); + if (glinit) + from_day = filename_to_int(gl.gl_pathv[0]); + else { + error("no matching files"); + exit(1); + } + } + + if (timemask & TO_TIME) + to_day = gmtime(&to_time)->tm_mday; + else { + if (!glinit) { + glinit = matchnames(dir, "[0-9][0-9]", &gl); + if (!glinit) { + error("no matching files"); + exit(1); + } + } + to_day = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]); + } + + dirlen = strlen(dir) + 4; + dirbuf = xmalloc(dirlen); + for (;from_day <= to_day; from_day++) { + snprintf(dirbuf, dirlen, "%s/%02d", dir, from_day); + selglob(dirbuf, BINLOG_GLOB_PATTERN); + } + free(dirbuf); + if (glinit) + globfree(&gl); +} + +void +selidx_month(const char *dir) +{ + int from_month, to_month; + struct tm *tm; + glob_t gl; + int glinit = 0; + char *dirbuf; + size_t dirlen; + + if (index_type == index_year) { + selglob(dir, BINLOG_GLOB_PATTERN); + return; + } + + if (timemask & FROM_TIME) + from_month = 1 + gmtime(&from_time)->tm_mon; + else { + glinit = matchnames(dir, "[0-9][0-9]", &gl); + if (glinit) + from_month = filename_to_int(gl.gl_pathv[0]); + else { + error("no matching files"); + exit(1); + } + } + + if (timemask & TO_TIME) + to_month = 1 + gmtime(&to_time)->tm_mon; + else { + if (!glinit) { + glinit = matchnames(dir, "[0-9][0-9]", &gl); + if (!glinit) { + error("no matching files"); + exit(1); + } + } + to_month = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]); + } + + dirlen = strlen(dir) + 4; + dirbuf = xmalloc(dirlen); + for (;from_month <= to_month; from_month++) { + snprintf(dirbuf, dirlen, "%s/%02d", dir, from_month); + selidx_day(dirbuf); + } + free(dirbuf); + if (glinit) + globfree(&gl); +} + +void +selidx_year(const char *dir) +{ + int from_year, to_year; + struct tm *tm; + glob_t gl; + int glinit = 0; + char *dirbuf; + size_t dirlen; + + if (timemask & FROM_TIME) + from_year = 1900 + gmtime(&from_time)->tm_year; + else { + glinit = matchnames(dir, "[0-9][0-9][0-9][0-9]", &gl); + if (glinit) + from_year = filename_to_int(gl.gl_pathv[0]); + else { + error("no matching files"); + exit(1); + } + } + if (timemask & TO_TIME) + to_year = 1900 + gmtime(&to_time)->tm_year; + else { + if (!glinit) { + glinit = matchnames(dir, "[0-9][0-9][0-9][0-9]", &gl); + if (!glinit) { + error("no matching files"); + exit(1); + } + } + to_year = filename_to_int(gl.gl_pathv[gl.gl_pathc - 1]); + } + + dirlen = strlen(dir) + 6; + dirbuf = xmalloc(dirlen); + for (;from_year <= to_year; from_year++) { + snprintf(dirbuf, dirlen, "%s/%04d", dir, from_year); + selidx_month(dirbuf); + } + free(dirbuf); + if (glinit) + globfree(&gl); +} + int @@ -338,3 +518,3 @@ globerrfunc (const char *epath, int eerrno) { - error("%s: %s", strerror(eerrno)); + error("%s: %s", epath, strerror(eerrno)); return 0; @@ -342,2 +522,26 @@ globerrfunc (const char *epath, int eerrno) +static int +matchnames(const char *dir, const char *pat, glob_t *gl) +{ + char *p = mkfilename(dir, pat); + int rc = glob(p, GLOB_ERR, globerrfunc, gl); + free(p); + switch (rc) { + case 0: + break; + case GLOB_NOSPACE: + error("out of memory"); + exit(1); + + case GLOB_ABORTED: + error("read error"); + exit(1); + + case GLOB_NOMATCH: + return 0; + } + return 1; +} + + struct logfile { @@ -360,3 +564,3 @@ tsort(const void *a, const void *b) void -selpattern(void) +selglob(const char *dir, const char *pattern) { @@ -365,4 +569,5 @@ selpattern(void) struct logfile *logfiles; - - switch (glob(pattern, GLOB_ERR|GLOB_NOSORT, globerrfunc, &gl)) { + char *p = mkfilename(dir, pattern); + + switch (glob(p, GLOB_ERR|GLOB_NOSORT, globerrfunc, &gl)) { case 0: @@ -381,3 +586,4 @@ selpattern(void) } - + free(p); + logfiles = xcalloc(gl.gl_pathc, sizeof(*logfiles)); @@ -402,3 +608,3 @@ selpattern(void) } - + int @@ -408,6 +614,5 @@ main(int argc, char **argv) struct timespec ts; - char *directory; setprogname(argv[0]); - while ((c = getopt(argc, argv, "D:dF:hp:T:t:nv")) != EOF) + while ((c = getopt(argc, argv, "D:dF:hi:p:T:t:nv")) != EOF) switch (c) { @@ -431,2 +636,9 @@ main(int argc, char **argv) return 0; + case 'i': + index_type = atoi(optarg); + if (index_type < 0 || index_type > index_last) { + error("invalid index type: %s", optarg); + exit(1); + } + break; case 'p': @@ -459,3 +671,3 @@ main(int argc, char **argv) if (argc) { - if (pattern) { + if (pattern || directory) { error("either files or pattern (-p) must be given, " @@ -465,7 +677,6 @@ main(int argc, char **argv) selfilelist(argv); + } else if (pattern) { + selglob(directory, convpattern(pattern)); } else { - if (!pattern) - pattern = BINLOG_PATTERN; - convpattern(directory); - selpattern(); + selidx_year(directory); } |