1 /*
2  * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 50    Log file handling */
10 
11 #include "squid.h"
12 #include "fatal.h"
13 #include "fde.h"
14 #include "log/File.h"
15 #include "log/ModDaemon.h"
16 #include "log/ModStdio.h"
17 #include "log/ModSyslog.h"
18 #include "log/ModUdp.h"
19 #include "log/TcpLogger.h"
20 
21 CBDATA_CLASS_INIT(Logfile);
22 
Logfile(const char * aPath)23 Logfile::Logfile(const char *aPath) :
24     sequence_number(0),
25     data(NULL),
26     f_linestart(NULL),
27     f_linewrite(NULL),
28     f_lineend(NULL),
29     f_flush(NULL),
30     f_rotate(NULL),
31     f_close(NULL)
32 {
33     xstrncpy(path, aPath, sizeof(path));
34     flags.fatal = 0;
35 }
36 
37 Logfile *
logfileOpen(const char * path,size_t bufsz,int fatal_flag)38 logfileOpen(const char *path, size_t bufsz, int fatal_flag)
39 {
40     int ret;
41     const char *patharg;
42 
43     debugs(50, DBG_IMPORTANT, "Logfile: opening log " << path);
44 
45     Logfile *lf = new Logfile(path);
46     patharg = path;
47     /* need to call the per-logfile-type code */
48     if (strncmp(path, "stdio:", 6) == 0) {
49         patharg = path + 6;
50         ret = logfile_mod_stdio_open(lf, patharg, bufsz, fatal_flag);
51     } else if (strncmp(path, "daemon:", 7) == 0) {
52         patharg = path + 7;
53         ret = logfile_mod_daemon_open(lf, patharg, bufsz, fatal_flag);
54     } else if (strncmp(path, "tcp:", 4) == 0) {
55         patharg = path + 4;
56         ret = Log::TcpLogger::Open(lf, patharg, bufsz, fatal_flag);
57     } else if (strncmp(path, "udp:", 4) == 0) {
58         patharg = path + 4;
59         ret = logfile_mod_udp_open(lf, patharg, bufsz, fatal_flag);
60 #if HAVE_SYSLOG
61     } else if (strncmp(path, "syslog:", 7) == 0) {
62         patharg = path + 7;
63         ret = logfile_mod_syslog_open(lf, patharg, bufsz, fatal_flag);
64 #endif
65     } else {
66         debugs(50, DBG_IMPORTANT, "WARNING: log name now starts with a module name. Use 'stdio:" << patharg << "'");
67         snprintf(lf->path, MAXPATHLEN, "stdio:%s", patharg);
68         ret = logfile_mod_stdio_open(lf, patharg, bufsz, fatal_flag);
69     }
70     if (!ret) {
71         if (fatal_flag)
72             fatalf("logfileOpen: %s: couldn't open!\n", path);
73         else
74             debugs(50, DBG_IMPORTANT, "logfileOpen: " << path << ": couldn't open!");
75         lf->f_close(lf);
76         delete lf;
77         return NULL;
78     }
79     assert(lf->data != NULL);
80 
81     if (fatal_flag)
82         lf->flags.fatal = 1;
83 
84     lf->sequence_number = 0;
85 
86     return lf;
87 }
88 
89 void
logfileClose(Logfile * lf)90 logfileClose(Logfile * lf)
91 {
92     debugs(50, DBG_IMPORTANT, "Logfile: closing log " << lf->path);
93     lf->f_flush(lf);
94     lf->f_close(lf);
95     delete lf;
96 }
97 
98 void
logfileRotate(Logfile * lf,int16_t rotateCount)99 logfileRotate(Logfile * lf, int16_t rotateCount)
100 {
101     debugs(50, DBG_IMPORTANT, "logfileRotate: " << lf->path);
102     lf->f_rotate(lf, rotateCount);
103 }
104 
105 void
logfileWrite(Logfile * lf,char * buf,size_t len)106 logfileWrite(Logfile * lf, char *buf, size_t len)
107 {
108     lf->f_linewrite(lf, buf, len);
109 }
110 
111 void
logfilePrintf(Logfile * lf,const char * fmt,...)112 logfilePrintf(Logfile * lf, const char *fmt,...)
113 {
114     va_list args;
115     char buf[8192];
116     int s;
117 
118     va_start(args, fmt);
119 
120     s = vsnprintf(buf, 8192, fmt, args);
121 
122     if (s > 8192) {
123         s = 8192;
124 
125         if (fmt[strlen(fmt) - 1] == '\n')
126             buf[8191] = '\n';
127     }
128 
129     logfileWrite(lf, buf, (size_t) s);
130     va_end(args);
131 }
132 
133 void
logfileLineStart(Logfile * lf)134 logfileLineStart(Logfile * lf)
135 {
136     lf->f_linestart(lf);
137 }
138 
139 void
logfileLineEnd(Logfile * lf)140 logfileLineEnd(Logfile * lf)
141 {
142     lf->f_lineend(lf);
143     ++ lf->sequence_number;
144 }
145 
146 void
logfileFlush(Logfile * lf)147 logfileFlush(Logfile * lf)
148 {
149     lf->f_flush(lf);
150 }
151 
152