]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - helpers/log_daemon/file/log_file_daemon.cc
Boilerplate: update copyright blurbs on Squid helpers
[thirdparty/squid.git] / helpers / log_daemon / file / log_file_daemon.cc
index aaa4e488a7822ab76cc8d27e6c1cb40cdf304dcf..e6445e63888c86e65e7d9d2f93cdb632ddefc51b 100644 (file)
@@ -1,35 +1,29 @@
-#include "config.h"
+/*
+ * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
 
-#if HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
+#include "squid.h"
+
+#include <cassert>
+#include <cerrno>
+#include <csignal>
+#include <cstring>
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #if HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
-#if HAVE_ASSERT_H
-#include <assert.h>
-#endif
 #if HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
-#if HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#if HAVE_STRING_H
-#include <string.h>
-#endif
 #if HAVE_PATHS_H
 #include <paths.h>
 #endif
@@ -51,25 +45,33 @@ rotate(const char *path, int rotate_count)
     assert(path);
 #ifdef S_ISREG
     if (stat(path, &sb) == 0)
-       if (S_ISREG(sb.st_mode) == 0)
-           return;
+        if (S_ISREG(sb.st_mode) == 0)
+            return;
 #endif
     /* Rotate numbers 0 through N up one */
     for (i = rotate_count; i > 1;) {
-       i--;
-       snprintf(from, MAXPATHLEN, "%s.%d", path, i - 1);
-       snprintf(to, MAXPATHLEN, "%s.%d", path, i);
-#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_)
-       remove(to);
+        --i;
+        snprintf(from, MAXPATHLEN, "%s.%d", path, i - 1);
+        snprintf(to, MAXPATHLEN, "%s.%d", path, i);
+#if _SQUID_OS2_ || _SQUID_WINDOWS_
+        if (remove(to) < 0) {
+            fprintf(stderr, "WARNING: remove '%s' failure: %s\n", to, xstrerror());
+        }
 #endif
-       rename(from, to);
+        if (rename(from, to) < 0 && errno != ENOENT) {
+            fprintf(stderr, "WARNING: rename '%s' to '%s' failure: %s\n", from, to, xstrerror());
+        }
     }
     if (rotate_count > 0) {
-       snprintf(to, MAXPATHLEN, "%s.%d", path, 0);
-#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_)
-       remove(to);
+        snprintf(to, MAXPATHLEN, "%s.%d", path, 0);
+#if _SQUID_OS2_ || _SQUID_WINDOWS_
+        if (remove(to) < 0) {
+            fprintf(stderr, "WARNING: remove '%s' failure: %s\n", to, xstrerror());
+        }
 #endif
-       rename(path, to);
+        if (rename(path, to) < 0 && errno != ENOENT) {
+            fprintf(stderr, "WARNING: rename %s to %s failure: %s\n", path, to, xstrerror());
+        }
     }
 }
 
@@ -94,13 +96,13 @@ main(int argc, char *argv[])
     int do_buffer = 1;
 
     if (argc < 2) {
-       printf("Error: usage: %s <logfile>\n", argv[0]);
-       exit(1);
+        printf("Error: usage: %s <logfile>\n", argv[0]);
+        exit(1);
     }
     fp = fopen(argv[1], "a");
     if (fp == NULL) {
-       perror("fopen");
-       exit(1);
+        perror("fopen");
+        exit(1);
     }
     setbuf(stdout, NULL);
     close(2);
@@ -109,44 +111,66 @@ main(int argc, char *argv[])
     dup2(t, 2);
 
     while (fgets(buf, LOGFILE_BUF_LEN, stdin)) {
-       /* First byte indicates what we're logging! */
-       switch (buf[0]) {
-       case 'L':
-           if (buf[1] != '\0') {
-               fprintf(fp, "%s", buf + 1);
-           }
-           if (!do_buffer)
-               fflush(fp);
-           break;
-       case 'R':
-           fclose(fp);
-           rotate(argv[1], rotate_count);
-           fp = fopen(argv[1], "a");
-           if (fp == NULL) {
-               perror("fopen");
-               exit(1);
-           }
-           break;
-       case 'T':
-           break;
-       case 'O':
-           break;
-       case 'r':
-           //fprintf(fp, "SET ROTATE: %s\n", buf + 1);
-           rotate_count = atoi(buf + 1);
-           break;
-       case 'b':
-           //fprintf(fp, "SET BUFFERED: %s\n", buf + 1);
-           do_buffer = (buf[1] == '1');
-           break;
-       case 'F':
-           fflush(fp);
-           break;
-       default:
-           /* Just in case .. */
-           fprintf(fp, "%s", buf);
-           break;
-       }
+        /* First byte indicates what we're logging! */
+        switch (buf[0]) {
+        case 'L':
+            if (buf[1] != '\0') {
+                fprintf(fp, "%s", buf + 1);
+                /* try to detect the 32-bit file too big write error and rotate */
+                int err = ferror(fp);
+                clearerr(fp);
+                if (err < 0) {
+                    /* file too big - recover by rotating the logs and starting a new one.
+                     * out of device space - recover by rotating and hoping that rotation count drops a big one.
+                     */
+                    if (err == EFBIG || err == ENOSPC) {
+                        fprintf(stderr, "WARNING: %s writing %s. Attempting to recover via a log rotation.\n",xstrerr(err),argv[1]);
+                        fclose(fp);
+                        rotate(argv[1], rotate_count);
+                        fp = fopen(argv[1], "a");
+                        if (fp == NULL) {
+                            perror("fopen");
+                            exit(1);
+                        }
+                        fprintf(fp, "%s", buf + 1);
+                    } else {
+                        perror("fprintf");
+                        exit(1);
+                    }
+                }
+            }
+            if (!do_buffer)
+                fflush(fp);
+            break;
+        case 'R':
+            fclose(fp);
+            rotate(argv[1], rotate_count);
+            fp = fopen(argv[1], "a");
+            if (fp == NULL) {
+                perror("fopen");
+                exit(1);
+            }
+            break;
+        case 'T':
+            break;
+        case 'O':
+            break;
+        case 'r':
+            //fprintf(fp, "SET ROTATE: %s\n", buf + 1);
+            rotate_count = atoi(buf + 1);
+            break;
+        case 'b':
+            //fprintf(fp, "SET BUFFERED: %s\n", buf + 1);
+            do_buffer = (buf[1] == '1');
+            break;
+        case 'F':
+            fflush(fp);
+            break;
+        default:
+            /* Just in case .. */
+            fprintf(fp, "%s", buf);
+            break;
+        }
     }
     fclose(fp);
     fp = NULL;