Index: logrotate.c =================================================================== --- logrotate.c (revision 314) +++ logrotate.c (working copy) @@ -45,6 +45,12 @@ #define GLOB_ABORTED GLOB_ABEND #endif +#ifdef PATH_MAX +#define STATEFILE_BUFFER_SIZE 2 * PATH_MAX + 16 +#else +#define STATEFILE_BUFFER_SIZE 4096 +#endif + struct logState { char *fn; struct tm lastRotated; /* only tm.mon, tm_mday, tm_year are good! */ @@ -82,6 +88,34 @@ return 1; } +static void unescape(char *arg) +{ + char *p = arg; + char *next; + char escaped; + while ((next = strchr(p, '\\')) != NULL) { + + p = next; + + switch (p[1]) { + case 'n': + escaped = '\n'; + break; + case '\\': + escaped = '\\'; + break; + default: + ++p; + continue; + } + + /* Overwrite the backslash with the intended character, + * and shift everything down one */ + *p++ = escaped; + memmove(p, p+1, 1 + strlen(p+1)); + } +} + #define HASH_SIZE_MIN 64 static int allocateHash(void) { @@ -1546,7 +1580,13 @@ for (chptr = p->fn; *chptr; chptr++) { switch (*chptr) { case '"': + case '\\': fputc('\\', f); + break; + case '\n': + fputc('\\', f); + fputc('n', f); + continue; } fputc(*chptr, f); @@ -1567,7 +1607,8 @@ static int readState(char *stateFilename) { FILE *f; - char buf[1024]; + char buf[STATEFILE_BUFFER_SIZE]; + char *filename; const char **argv; int argc; int year, month, day; @@ -1678,7 +1719,10 @@ year -= 1900, month -= 1; - if ((st = findState(argv[0])) == NULL) + filename = strdup(argv[0]); + unescape(filename); + + if ((st = findState(filename)) == NULL) return 1; st->lastRotated.tm_mon = month; @@ -1690,6 +1734,7 @@ st->lastRotated = *localtime(&lr_time); free(argv); + free(filename); } fclose(f);