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