aboutsummaryrefslogtreecommitdiff
path: root/src/binlogsel.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-10-15 18:38:49 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2013-10-15 18:56:22 +0300
commitef3f928cc712f6774e19f8cb8f880cbeac15e8ff (patch)
tree88f59a4c8d1867bfadb924ee547b4b74a97c5ce0 /src/binlogsel.c
parentf035194d7d1b6cc0846ad7a5d86e0d6fa9463c67 (diff)
downloadvmod-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.c245
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);
}

Return to:

Send suggestions and report system problems to the System administrator.