]> git.ipfire.org Git - thirdparty/squid.git/blame - helpers/log_daemon/file/log_file_daemon.cc
TestBed: Typo remaining from old flags mistake
[thirdparty/squid.git] / helpers / log_daemon / file / log_file_daemon.cc
CommitLineData
82b7abe3
AJ
1#include "config.h"
2
3#if HAVE_STDIO_H
4#include <stdio.h>
5#endif
82b7abe3
AJ
6#if HAVE_UNISTD_H
7#include <unistd.h>
8#endif
9#if HAVE_FCNTL_H
10#include <fcntl.h>
11#endif
12#if HAVE_ASSERT_H
13#include <assert.h>
14#endif
15#if HAVE_SYS_PARAM_H
16#include <sys/param.h>
17#endif
18#if HAVE_SYS_STAT_H
19#include <sys/stat.h>
20#endif
21#if HAVE_SIGNAL_H
22#include <signal.h>
23#endif
24#if HAVE_ERRNO_H
25#include <errno.h>
26#endif
27#if HAVE_STRING_H
28#include <string.h>
29#endif
30#if HAVE_PATHS_H
31#include <paths.h>
32#endif
33
34#include "defines.h"
35
36/* parse buffer - ie, length of longest expected line */
37#define LOGFILE_BUF_LEN 65536
38
39static void
40rotate(const char *path, int rotate_count)
41{
42#ifdef S_ISREG
43 struct stat sb;
44#endif
45 int i;
46 char from[MAXPATHLEN];
47 char to[MAXPATHLEN];
48 assert(path);
49#ifdef S_ISREG
50 if (stat(path, &sb) == 0)
9d65168e
A
51 if (S_ISREG(sb.st_mode) == 0)
52 return;
82b7abe3
AJ
53#endif
54 /* Rotate numbers 0 through N up one */
55 for (i = rotate_count; i > 1;) {
9d65168e
A
56 i--;
57 snprintf(from, MAXPATHLEN, "%s.%d", path, i - 1);
58 snprintf(to, MAXPATHLEN, "%s.%d", path, i);
82b7abe3 59#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_)
9d65168e 60 remove(to);
82b7abe3 61#endif
9d65168e 62 rename(from, to);
82b7abe3
AJ
63 }
64 if (rotate_count > 0) {
9d65168e 65 snprintf(to, MAXPATHLEN, "%s.%d", path, 0);
82b7abe3 66#if defined(_SQUID_OS2_) || defined(_SQUID_WIN32_)
9d65168e 67 remove(to);
82b7abe3 68#endif
9d65168e 69 rename(path, to);
82b7abe3
AJ
70 }
71}
72
73/**
74 * The commands:
75 *
76 * L<data>\n - logfile data
77 * R\n - rotate file
78 * T\n - truncate file
79 * O\n - repoen file
80 * F\n - flush file
81 * r<n>\n - set rotate count to <n>
82 * b<n>\n - 1 = buffer output, 0 = don't buffer output
83 */
84int
85main(int argc, char *argv[])
86{
87 int t;
88 FILE *fp;
89 char buf[LOGFILE_BUF_LEN];
90 int rotate_count = 10;
91 int do_buffer = 1;
92
93 if (argc < 2) {
9d65168e
A
94 printf("Error: usage: %s <logfile>\n", argv[0]);
95 exit(1);
82b7abe3
AJ
96 }
97 fp = fopen(argv[1], "a");
98 if (fp == NULL) {
9d65168e
A
99 perror("fopen");
100 exit(1);
82b7abe3
AJ
101 }
102 setbuf(stdout, NULL);
103 close(2);
104 t = open(_PATH_DEVNULL, O_RDWR);
105 assert(t > -1);
106 dup2(t, 2);
107
108 while (fgets(buf, LOGFILE_BUF_LEN, stdin)) {
9d65168e
A
109 /* First byte indicates what we're logging! */
110 switch (buf[0]) {
111 case 'L':
112 if (buf[1] != '\0') {
113 fprintf(fp, "%s", buf + 1);
48d54e4d
AJ
114 /* try to detect the 32-bit file too big write error and rotate */
115 int err = ferror(fp);
116 clearerr(fp);
117 if (err < 0) {
118 /* file too big - recover by rotating the logs and starting a new one.
119 * out of device space - recover by rotating and hoping that rotation count drops a big one.
120 */
121 if (err == EFBIG || err == ENOSPC) {
122 fprintf(stderr, "WARNING: %s writing %s. Attempting to recover via a log rotation.\n",strerror(err),argv[1]);
123 fclose(fp);
124 rotate(argv[1], rotate_count);
125 fp = fopen(argv[1], "a");
126 if (fp == NULL) {
127 perror("fopen");
128 exit(1);
129 }
130 fprintf(fp, "%s", buf + 1);
131 } else {
132 perror("fprintf");
133 exit(1);
134 }
135 }
9d65168e
A
136 }
137 if (!do_buffer)
138 fflush(fp);
139 break;
140 case 'R':
141 fclose(fp);
142 rotate(argv[1], rotate_count);
143 fp = fopen(argv[1], "a");
144 if (fp == NULL) {
145 perror("fopen");
146 exit(1);
147 }
148 break;
149 case 'T':
150 break;
151 case 'O':
152 break;
153 case 'r':
154 //fprintf(fp, "SET ROTATE: %s\n", buf + 1);
155 rotate_count = atoi(buf + 1);
156 break;
157 case 'b':
158 //fprintf(fp, "SET BUFFERED: %s\n", buf + 1);
159 do_buffer = (buf[1] == '1');
160 break;
161 case 'F':
162 fflush(fp);
163 break;
164 default:
165 /* Just in case .. */
166 fprintf(fp, "%s", buf);
167 break;
168 }
82b7abe3
AJ
169 }
170 fclose(fp);
171 fp = NULL;
172 exit(0);
173}