1 #include <stdio.h>
2 #include <string.h>
3 #include <stdarg.h>
4 #include "logs.h"
5 #include "utils.h"
6 #include "dnsparser.h"
7
8 #define MAX_PATH_BUFFER 256
9
10 static BOOL PrintConsole = FALSE;
11 static BOOL DebugOn = FALSE;
12
13 static FILE *LogFile = NULL;
14
15 static int ThresholdLength = 0;
16 static int CurrentLength = 0;
17 static char FilePath[MAX_PATH_BUFFER];
18
19 static EFFECTIVE_LOCK PrintLock;
20
Log_Init(ConfigFileInfo * ConfigInfo,BOOL PrintScreen,BOOL Debug)21 int Log_Init(ConfigFileInfo *ConfigInfo, BOOL PrintScreen, BOOL Debug)
22 {
23 PrintConsole = PrintScreen;
24 DebugOn = Debug;
25
26 EFFECTIVE_LOCK_INIT(PrintLock);
27
28 if( ConfigGetBoolean(ConfigInfo, "LogOn") == FALSE )
29 {
30 return 0;
31 }
32
33 if( snprintf(FilePath,
34 sizeof(FilePath),
35 "%s%cdnsforwarder.log",
36 ConfigGetRawString(ConfigInfo, "LogFileFolder"),
37 PATH_SLASH_CH
38 )
39 >= sizeof(FilePath)
40 )
41 {
42 return -36;
43 }
44
45 LogFile = fopen(FilePath, "r+");
46 if( LogFile == NULL )
47 {
48 /* File does not exist */
49 LogFile = fopen(FilePath, "w");
50 if( LogFile == NULL )
51 {
52 printf("ERROR: Log file %s is unwritable. Try run `dnsforwarder -p'.\n", FilePath);
53 return -44;
54 }
55
56 CurrentLength = 0;
57 } else {
58 fseek(LogFile, 0, SEEK_END);
59 CurrentLength = ftell(LogFile);
60 }
61
62 ThresholdLength = ConfigGetInt32(ConfigInfo, "LogFileThresholdLength");
63 if( ThresholdLength <= 0 )
64 {
65 return -60;
66 }
67
68 return 0;
69 }
70
Log_Inited(void)71 BOOL Log_Inited(void)
72 {
73 return LogFile != NULL || PrintConsole;
74 }
75
Log_DebugOn(void)76 BOOL Log_DebugOn(void)
77 {
78 return DebugOn;
79 }
80
CheckLength(void)81 static void CheckLength(void)
82 {
83 static int CurrentNumber = 0;
84
85 if( CurrentLength >= ThresholdLength )
86 {
87 char FileRenamed[MAX_PATH_BUFFER + 8];
88
89 fclose(LogFile);
90
91 while( TRUE )
92 {
93 ++CurrentNumber;
94
95 if( snprintf(FileRenamed,
96 sizeof(FileRenamed),
97 "%s.%d",
98 FilePath,
99 CurrentNumber
100 )
101 >= sizeof(FileRenamed)
102 )
103 {
104 return;
105 }
106
107 if( FileIsReadable(FileRenamed) == FALSE )
108 {
109 /* If path to `FileRenamed' does not exist */
110 if( rename(FilePath, FileRenamed) != 0 )
111 {
112 return;
113 }
114
115 LogFile = fopen(FilePath, "w");
116 if( LogFile == NULL )
117 {
118 return;
119 }
120
121 CurrentLength = 0;
122
123 break;
124 }
125 }
126 }
127 }
128
Log_Print(const char * Type,const char * format,...)129 void Log_Print(const char *Type, const char *format, ...)
130 {
131 va_list ap;
132 char DateAndTime[32];
133
134 if( !Log_Inited() )
135 {
136 return;
137 }
138
139 GetCurDateAndTime(DateAndTime, sizeof(DateAndTime));
140
141 va_start(ap, format);
142
143 EFFECTIVE_LOCK_GET(PrintLock);
144 if( LogFile != NULL )
145 {
146 CheckLength();
147
148 CurrentLength += fprintf(LogFile,
149 Type == NULL ? "%s " : "%s [%s] ",
150 DateAndTime,
151 Type == NULL ? "" : Type
152 );
153 CurrentLength += vfprintf(LogFile, format, ap);
154
155 fflush(LogFile);
156
157 va_start(ap, format);
158 }
159
160 if( PrintConsole )
161 {
162 printf(Type == NULL ? "%s " : "%s [%s] ",
163 DateAndTime,
164 Type == NULL ? "" : Type
165 );
166 vprintf(format, ap);
167 }
168
169 EFFECTIVE_LOCK_RELEASE(PrintLock);
170
171 va_end(ap);
172 }
173
ShowRefusingMessage(IHeader * h,const char * Message)174 void ShowRefusingMessage(IHeader *h, const char *Message)
175 {
176 Log_Print(NULL,
177 "[R][%s][%s][%s] %s.\n",
178 h->Agent,
179 DNSGetTypeName(h->Type),
180 h->Domain,
181 Message
182 );
183 }
184
ShowTimeOutMessage(const IHeader * h,char Protocol)185 void ShowTimeOutMessage(const IHeader *h, char Protocol)
186 {
187 Log_Print(NULL,
188 "[%c][%s][%s][%s] Timed out.\n",
189 Protocol,
190 h->Agent,
191 DNSGetTypeName(h->Type),
192 h->Domain
193 );
194 }
195
ShowErrorMessage(IHeader * h,char Protocol)196 void ShowErrorMessage(IHeader *h, char Protocol)
197 {
198 if( PRINTON )
199 {
200 int ErrorNum;
201 char ErrorMessage[320];
202
203 ErrorNum = GET_LAST_ERROR();
204 ErrorMessage[0] ='\0';
205 GetErrorMsg(ErrorNum, ErrorMessage, sizeof(ErrorMessage));
206
207 Log_Print(NULL,
208 "[%c][%s][%s][%s] An error occured : %d : %s .\n",
209 Protocol,
210 h->Agent,
211 DNSGetTypeName(h->Type),
212 h->Domain,
213 ErrorNum,
214 ErrorMessage
215 );
216 }
217 }
218
ShowNormalMessage(IHeader * h,char Protocol)219 void ShowNormalMessage(IHeader *h, char Protocol)
220 {
221 if( PRINTON )
222 {
223 char *Package = (char *)(h + 1);
224 char InfoBuffer[1024];
225
226 InfoBuffer[0] = '\0';
227 GetAllAnswers(Package, h->EntityLength, InfoBuffer, sizeof(InfoBuffer));
228
229 Log_Print(NULL,
230 "[%c][%s][%s][%s] : %d bytes\n%s",
231 Protocol,
232 h->Agent,
233 DNSGetTypeName(h->Type),
234 h->Domain,
235 h->EntityLength,
236 InfoBuffer
237 );
238 }
239 }
240
ShowBlockedMessage(IHeader * h,const char * Message)241 void ShowBlockedMessage(IHeader *h, const char *Message)
242 {
243 if( PRINTON )
244 {
245 char *Package = (char *)(h + 1);
246 char InfoBuffer[1024];
247
248 InfoBuffer[0] = '\0';
249 GetAllAnswers(Package, h->EntityLength, InfoBuffer, sizeof(InfoBuffer));
250
251 Log_Print(NULL,
252 "[B][%s][%s] %s :\n%s",
253 DNSGetTypeName(h->Type),
254 h->Domain,
255 Message == NULL ? "" : Message,
256 InfoBuffer
257 );
258 }
259 }
260
ShowSocketError(const char * Prompts,int ErrorNum)261 void ShowSocketError(const char *Prompts, int ErrorNum)
262 {
263 if( PRINTON )
264 {
265 char ErrorMessage[320];
266 GetErrorMsg(ErrorNum, ErrorMessage, sizeof(ErrorMessage));
267 ERRORMSG("%s : %d : %s\n", Prompts, ErrorNum, ErrorMessage);
268 }
269 }
270