/[LeafOK_CVS]/lbbs/src/log.c
ViewVC logotype

Contents of /lbbs/src/log.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.37 - (show annotations)
Thu Dec 18 14:47:00 2025 UTC (2 months, 4 weeks ago) by sysadm
Branch: MAIN
Changes since 1.36: +79 -26 lines
Content type: text/x-csrc
Refine and bug fix

1 /* SPDX-License-Identifier: GPL-3.0-or-later */
2 /*
3 * log
4 * - logger
5 *
6 * Copyright (C) 2004-2025 Leaflet <leaflet@leafok.com>
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include "common.h"
14 #include "io.h"
15 #include "log.h"
16 #include <errno.h>
17 #include <stdarg.h>
18 #include <string.h>
19 #include <time.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22
23 enum _log_constant_t
24 {
25 STR_LOG_TIME_MAX_LEN = 50,
26 };
27
28 static char path_common_log[FILE_PATH_LEN];
29 static char path_error_log[FILE_PATH_LEN];
30 static FILE *fp_common_log = NULL;
31 static FILE *fp_error_log = NULL;
32 static int redir_common_log = 0;
33 static int redir_error_log = 0;
34
35 int log_begin(const char *common_log_file, const char *error_log_file)
36 {
37 strncpy(path_common_log, common_log_file, sizeof(path_common_log) - 1);
38 path_common_log[sizeof(path_common_log) - 1] = '\0';
39 strncpy(path_error_log, error_log_file, sizeof(path_error_log) - 1);
40 path_error_log[sizeof(path_error_log) - 1] = '\0';
41
42 fp_common_log = fopen(path_common_log, "a");
43 if (fp_common_log == NULL)
44 {
45 fprintf(stderr, "fopen(%s) error: %s\n", path_common_log, strerror(errno));
46 return -1;
47 }
48
49 fp_error_log = fopen(path_error_log, "a");
50 if (fp_error_log == NULL)
51 {
52 fprintf(stderr, "fopen(%s) error: %s\n", path_error_log, strerror(errno));
53 fclose(fp_common_log);
54 fp_common_log = NULL;
55 return -2;
56 }
57
58 redir_common_log = 0;
59 redir_error_log = 0;
60
61 return 0;
62 }
63
64 void log_end()
65 {
66 if (fp_common_log)
67 {
68 fclose(fp_common_log);
69 fp_common_log = NULL;
70 }
71 if (fp_error_log)
72 {
73 fclose(fp_error_log);
74 fp_error_log = NULL;
75 }
76 }
77
78 inline static int log_head(char *buf, size_t len, int log_level, const char *app_file, int app_line)
79 {
80 time_t t;
81 struct tm gm_tm;
82 char s_time[STR_LOG_TIME_MAX_LEN + 1];
83 int ret;
84
85 time(&t);
86 gmtime_r(&t, &gm_tm);
87 strftime(s_time, sizeof(s_time), "%Y-%m-%d %H:%M:%S", &gm_tm);
88
89 if (log_level == LOG_LEVEL_COMMON)
90 {
91 ret = snprintf(buf, len, "[%s] [%d] [INFO] ", s_time, getpid());
92 }
93 else if (log_level == LOG_LEVEL_ERROR)
94 {
95 ret = snprintf(buf, len, "[%s] [%d] [ERROR] [%s:%d] ", s_time, getpid(), app_file, app_line);
96 }
97 else // if (log_level == LOG_LEVEL_DEBUG)
98 {
99 ret = snprintf(buf, len, "[%s] [%d] [DEBUG] [%s:%d] ", s_time, getpid(), app_file, app_line);
100 }
101
102 return ret;
103 }
104
105 int log_printf(enum log_level_t log_level, const char *app_file, int app_line, const char *format, ...)
106 {
107 va_list args;
108 char buf[LINE_BUFFER_LEN];
109 FILE *fp_log;
110 int offset;
111 int ret;
112
113 fp_log = (log_level == LOG_LEVEL_COMMON ? fp_common_log : fp_error_log);
114
115 offset = log_head(buf, sizeof(buf), log_level, app_file, app_line);
116
117 va_start(args, format);
118 ret = vsnprintf(buf + offset, sizeof(buf) - (size_t)offset, format, args);
119 va_end(args);
120
121 if (ret < 0)
122 {
123 // Encoding error
124 return -1;
125 }
126 else if (offset + ret >= sizeof(buf))
127 {
128 buf[sizeof(buf) - 2] = '\n'; // Add newline for truncated messages
129 buf[sizeof(buf) - 1] = '\0'; // Ensure null termination
130 if (fputs(buf, fp_log) == EOF)
131 {
132 return -3; // Write error
133 }
134 ret = -2; // Indicate truncation
135 }
136 else
137 {
138 if (fputs(buf, fp_log) == EOF)
139 {
140 return -3; // Write error
141 }
142 ret = offset + ret;
143 }
144
145 if (fflush(fp_log) == EOF)
146 {
147 return -4; // Flush error
148 }
149
150 return ret;
151 }
152
153 int log_common_redir(int fd)
154 {
155 redir_common_log = 1;
156 return dup2(fd, fileno(fp_common_log));
157 }
158
159 int log_error_redir(int fd)
160 {
161 redir_error_log = 1;
162 return dup2(fd, fileno(fp_error_log));
163 }
164
165 int log_restart(void)
166 {
167 FILE *fp_common = NULL;
168 FILE *fp_error = NULL;
169
170 if (!redir_common_log)
171 {
172 fp_common = fopen(path_common_log, "a");
173 if (fp_common == NULL)
174 {
175 log_error("fopen(%s) error: %s\n", path_common_log, strerror(errno));
176 return -1;
177 }
178 }
179
180 if (!redir_error_log)
181 {
182 fp_error = fopen(path_error_log, "a");
183 if (fp_error == NULL)
184 {
185 log_error("fopen(%s) error: %s\n", path_error_log, strerror(errno));
186 if (fp_common)
187 {
188 fclose(fp_common);
189 }
190 return -2;
191 }
192 }
193
194 // Apply new file pointers
195 if (fp_common)
196 {
197 fclose(fp_common_log);
198 fp_common_log = fp_common;
199 }
200 if (fp_error)
201 {
202 fclose(fp_error_log);
203 fp_error_log = fp_error;
204 }
205
206 return 0;
207 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1