diff options
Diffstat (limited to 'support')
-rw-r--r-- | support/rotatelogs.c | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/support/rotatelogs.c b/support/rotatelogs.c index 7c203e59df..63869ae34a 100644 --- a/support/rotatelogs.c +++ b/support/rotatelogs.c @@ -63,7 +63,7 @@ struct rotate_config { int force_open; int verbose; int echo; - const char *szLogRoot; + char *szLogRoot; int truncate; const char *linkfile; const char *postrotate_prog; @@ -71,6 +71,7 @@ struct rotate_config { int create_empty; #endif int num_files; + int create_path; }; typedef struct rotate_status rotate_status_t; @@ -103,9 +104,9 @@ static void usage(const char *argv0, const char *reason) } fprintf(stderr, #if APR_FILES_AS_SOCKETS - "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-t] [-e] [-c] [-n number] <logfile> " + "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-d] [-t] [-e] [-c] [-n number] <logfile> " #else - "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-t] [-e] [-n number] <logfile> " + "Usage: %s [-v] [-l] [-L linkname] [-p prog] [-f] [-d] [-t] [-e] [-n number] <logfile> " #endif "{<rotation time in seconds>|<rotation size>(B|K|M|G)} " "[offset minutes from UTC]\n\n", @@ -137,6 +138,7 @@ static void usage(const char *argv0, const char *reason) " -L path Create hard link from current log to specified path.\n" " -p prog Run specified program after opening a new log file. See below.\n" " -f Force opening of log on program start.\n" + " -d Create parent directories of log file.\n" " -t Truncate logfile instead of rotating, tail friendly.\n" " -e Echo log to stdout for further processing.\n" #if APR_FILES_AS_SOCKETS @@ -200,6 +202,7 @@ static void dumpConfig (rotate_config_t *config) fprintf(stderr, "Rotation based on localtime: %12s\n", config->use_localtime ? "yes" : "no"); fprintf(stderr, "Rotation file date pattern: %12s\n", config->use_strftime ? "yes" : "no"); fprintf(stderr, "Rotation file forced open: %12s\n", config->force_open ? "yes" : "no"); + fprintf(stderr, "Create parent directories: %12s\n", config->create_path ? "yes" : "no"); fprintf(stderr, "Rotation verbose: %12s\n", config->verbose ? "yes" : "no"); #if APR_FILES_AS_SOCKETS fprintf(stderr, "Rotation create empty logs: %12s\n", config->create_empty ? "yes" : "no"); @@ -430,6 +433,23 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status) } } apr_pool_create(&newlog.pool, status->pool); + if (config->create_path) { + char *ptr = strrchr(newlog.name, '/'); + if (ptr && ptr > newlog.name) { + char *path = apr_pstrmemdup(newlog.pool, newlog.name, ptr - newlog.name); + if (config->verbose) { + fprintf(stderr, "Creating directory tree %s\n", path); + } + rv = apr_dir_make_recursive(path, APR_FPROT_OS_DEFAULT, newlog.pool); + if (rv != APR_SUCCESS) { + char error[120]; + + apr_strerror(rv, error, sizeof error); + fprintf(stderr, "Could not create directory '%s' (%s)\n", path, error); + exit(2); + } + } + } if (config->verbose) { fprintf(stderr, "Opening file %s\n", newlog.name); } @@ -560,9 +580,9 @@ int main (int argc, const char * const argv[]) apr_pool_create(&status.pool, NULL); apr_getopt_init(&opt, status.pool, argc, argv); #if APR_FILES_AS_SOCKETS - while ((rv = apr_getopt(opt, "lL:p:ftvecn:", &c, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(opt, "lL:p:fdtvecn:", &c, &opt_arg)) == APR_SUCCESS) { #else - while ((rv = apr_getopt(opt, "lL:p:ftven:", &c, &opt_arg)) == APR_SUCCESS) { + while ((rv = apr_getopt(opt, "lL:p:fdtven:", &c, &opt_arg)) == APR_SUCCESS) { #endif switch (c) { case 'l': @@ -577,6 +597,9 @@ int main (int argc, const char * const argv[]) case 'f': config.force_open = 1; break; + case 'd': + config.create_path = 1; + break; case 't': config.truncate = 1; break; @@ -611,7 +634,11 @@ int main (int argc, const char * const argv[]) usage(argv[0], "Incorrect number of arguments"); } - config.szLogRoot = argv[opt->ind++]; + rv = apr_filepath_merge(&config.szLogRoot, "", argv[opt->ind++], + APR_FILEPATH_TRUENAME, status.pool); + if (rv != APR_SUCCESS && rv != APR_EPATHWILD) { + usage(argv[0], "Invalid filename given"); + } /* Read in the remaining flags, namely time, size and UTC offset. */ for(; opt->ind < argc; opt->ind++) { |