]> granicus.if.org Git - apache/blobdiff - support/rotatelogs.c
More splitting as suggested by minfrin.
[apache] / support / rotatelogs.c
index a295ad0a7bcb8f267407eb4e8c1663c31bbeb35f..37f11096767a493250ac01a6906364c33e2eac6f 100644 (file)
@@ -89,6 +89,7 @@ struct rotate_config {
     int verbose;
     const char *szLogRoot;
     int truncate;
+    const char *linkfile;
 };
 
 typedef struct rotate_status rotate_status_t;
@@ -115,7 +116,7 @@ static void usage(const char *argv0, const char *reason)
         fprintf(stderr, "%s\n", reason);
     }
     fprintf(stderr,
-            "Usage: %s [-v] [-l] [-f] [-t] <logfile> "
+            "Usage: %s [-v] [-l] [-L linkname] [-f] [-t] <logfile> "
             "{<rotation time in seconds>|<rotation size>(B|K|M|G)} "
             "[offset minutes from UTC]\n\n",
             argv0);
@@ -139,7 +140,9 @@ static void usage(const char *argv0, const char *reason)
             "when the file size\nis reached a new log is started. If the "
             "-t option is specified, the specified\nfile will be truncated "
             "instead of rotated, and is useful where tail is used to\n"
-            "process logs in real time.\n");
+            "process logs in real time.  If the -L option is specified, "
+            "a hard link will be\nmade from the current log file to the "
+            "specified filename.\n");
     exit(1);
 }
 
@@ -172,8 +175,13 @@ static void closeFile(rotate_config_t *config, apr_pool_t *pool, apr_file_t *fil
         if (config->verbose) {
             apr_finfo_t finfo;
             apr_int32_t wanted = APR_FINFO_NAME;
-            if (apr_file_info_get(&finfo, wanted, file) == APR_SUCCESS) {
-                fprintf(stderr, "Closing file %s (%s)\n", finfo.name, finfo.fname);
+            apr_status_t rv = apr_file_info_get(&finfo, wanted, file);
+            if ((rv == APR_SUCCESS) || (rv == APR_INCOMPLETE)) {
+                if (finfo.valid & APR_FINFO_NAME) {
+                    fprintf(stderr, "Closing file %s (%s)\n", finfo.name, finfo.fname);
+                } else {
+                    fprintf(stderr, "Closing file %s\n", finfo.fname);
+                }
             }
         }
         apr_file_close(file);
@@ -301,10 +309,10 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status)
     }
     else {
         if (config->truncate) {
-            snprintf(status->filename, sizeof(status->filename), "%s", config->szLogRoot);
+            apr_snprintf(status->filename, sizeof(status->filename), "%s", config->szLogRoot);
         }
         else {
-            snprintf(status->filename, sizeof(status->filename), "%s.%010d", config->szLogRoot,
+            apr_snprintf(status->filename, sizeof(status->filename), "%s.%010d", config->szLogRoot,
                     tLogStart);
         }
     }
@@ -351,6 +359,20 @@ static void doRotate(rotate_config_t *config, rotate_status_t *status)
         status->pfile_prev = NULL;
     }
     status->nMessCount = 0;
+    if (config->linkfile) {
+        apr_file_remove(config->linkfile, status->pfile);
+        if (config->verbose) {
+            fprintf(stderr,"Linking %s to %s\n", status->filename, config->linkfile);
+        }
+        rv = apr_file_link(status->filename, config->linkfile);
+        if (rv != APR_SUCCESS) {
+            char error[120];
+            apr_strerror(rv, error, sizeof error);
+            fprintf(stderr, "Error linking file %s to %s (%s)\n",
+                    status->filename, config->linkfile, error);
+            exit(2);
+        }
+    }
 }
 
 /*
@@ -416,7 +438,7 @@ int main (int argc, const char * const argv[])
     apr_getopt_t *opt;
     apr_status_t rv;
     char c;
-    const char *optarg;
+    const char *opt_arg;
     const char *err = NULL;
 
     apr_app_initialize(&argc, &argv, NULL);
@@ -440,11 +462,14 @@ int main (int argc, const char * const argv[])
 
     apr_pool_create(&status.pool, NULL);
     apr_getopt_init(&opt, status.pool, argc, argv);
-    while ((rv = apr_getopt(opt, "lftv", &c, &optarg)) == APR_SUCCESS) {
+    while ((rv = apr_getopt(opt, "lL:ftv", &c, &opt_arg)) == APR_SUCCESS) {
         switch (c) {
         case 'l':
             config.use_localtime = 1;
             break;
+        case 'L':
+            config.linkfile = opt_arg;
+            break;
         case 'f':
             config.force_open = 1;
             break;