logf argument names changed.
[swftools.git] / lib / log.c
1 /* log.c 
2    Logging facilities for displaying information on screen, as well as
3    (optional) storing it to a file and transmitting it over the network.
4
5    Part of the swftools package.
6    
7    Copyright (c) 2001 Matthias Kramm <kramm@quiss.org> 
8
9    This file is distributed under the GPL, see file COPYING for details */
10
11 #ifdef __NT__
12 #include "stdafx.h"
13 #include <string.h>
14 #include <winsock2.h>
15 #include <stdlib.h>
16 #include <malloc.h>
17 #if _MSC_VER > 1000
18 #pragma once
19 #endif // _MSC_VER > 1000
20 #else
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <unistd.h>
26 #endif
27
28 #include "log.h"
29
30 #define LOGLEVEL_FATAL 0
31 #define LOGLEVEL_ERROR 1
32 #define LOGLEVEL_WARNING 2
33 #define LOGLEVEL_NOTICE 3
34 #define LOGLEVEL_VERBOSE 4
35 #define LOGLEVEL_DEBUG 5
36
37 int screenloglevel;
38 int fileloglevel;
39 int socketloglevel;
40 FILE *logFile = 0;
41 #ifdef __NT__
42 SOCKET logSocket;
43 #else
44 int logSocket = 0;
45 #endif
46
47 char bLogToSock = 0;
48
49 void initlogSocket(char* servAddr, char* logPort);
50
51 void initLog(char* pLogName, int fileloglevel, char* servAddr, char* logPort, int serverlevel, int screenlevel)
52 {
53    screenloglevel = screenlevel;
54    fileloglevel = fileloglevel;
55    socketloglevel = screenlevel;
56    logFile = NULL;
57    bLogToSock = 0;
58
59    if (pLogName && fileloglevel>=0)
60    logFile = fopen(pLogName, "a+");
61    bLogToSock = (servAddr && logPort && (serverlevel>=0));
62    if(bLogToSock)
63        initlogSocket(servAddr, logPort);
64 }
65
66 void initlogSocket(char* servAddr, char* logPort)
67 {
68 #ifndef __NT__
69    bLogToSock = 0;
70 #else
71    // init winsock
72    // check and prepare WinSock DLL
73    WORD wVersionRequested = MAKEWORD( 2, 2 );
74    WSADATA wsaData;
75    if ( WSAStartup(wVersionRequested, &wsaData) != 0 )
76    {
77       bLogToSock = false;
78       return;
79    }
80    // Confirm that the WinSock DLL supports 2.2.
81    // Note that if the DLL supports versions greater
82    // than 2.2 in addition to 2.2, it will still return
83    // 2.2 in wVersion since that is the version we
84    // requested.
85
86    if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
87    {
88       bLogToSock = false;
89       return;
90    }
91
92    struct hostent *hp;
93    hp = gethostbyname(servAddr);
94    if (hp == NULL) // we don't know who this host is
95    {
96       bLogToSock = false;
97       return;
98    }
99
100    // connect socket
101    sockaddr_in SocketAddress;
102
103    memset(&SocketAddress, 0, sizeof(SocketAddress));
104    memcpy((char*)&SocketAddress.sin_addr, hp->h_addr, hp->h_length); // set address
105    SocketAddress.sin_family = hp->h_addrtype;
106    SocketAddress.sin_port = htons((u_short)atoi(logPort));
107
108    logSocket = socket(hp->h_addrtype, SOCK_STREAM, 0);
109    if (logSocket == INVALID_SOCKET)
110    {
111       bLogToSock = false;
112       return;
113    }
114
115    // try to connect to the specified socket
116    if ( connect(logSocket, (struct sockaddr*)&SocketAddress, sizeof (SocketAddress)) == SOCKET_ERROR) {
117       bLogToSock = false;
118       return;
119    }
120    bLogToSock = true;
121 #endif
122 }
123
124 void exitLog()
125 {
126    // close socket communication
127    if(bLogToSock)
128 #ifndef __NT__
129      close(logSocket);
130 #else
131      closesocket(logSocket);
132 #endif
133    // close file
134    if(logFile != NULL)
135      fclose(logFile);
136 }
137
138
139 static char * logimportance[]= {"Fatal","Error","Warning","Notice","Verbose","Debug"};
140 static int loglevels=6;
141 static char * logimportance2[]= {"       ","FATAL  ","ERROR  ","WARNING","NOTICE ","VERBOSE","DEBUG  "};
142 void log(char* logString)
143 {
144    char timebuffer[32];
145    char* logBuffer;
146    char dbuffer[9];
147    char tbuffer[9];
148    int level;
149    char*lt;
150    char*gt;
151    int l;
152
153    logBuffer = (char*)malloc (strlen(logString) + 24 + 15);
154 #ifndef __NT__
155    {
156      /*time_t t = time(0);
157      tm*t2 = localtime(t);
158      strftime(dbuffer, 8, "%m %d", t2);
159      strftime(tbuffer, 8, "%m %d", t2);
160      dbuffer[0]=0; //FIXME
161      tbuffer[0]=0;*/
162      time_t t = time(0);
163      char* a = ctime(&t);
164      int l = strlen(a);
165      while(a[l-1] == 13 || a[l-1] == 10)
166        l--;
167      a[l]=0;
168      sprintf(timebuffer, "%s", a);
169    }
170 #else
171    _strdate( dbuffer );
172    _strtime( tbuffer );
173    sprintf(timebuffer, "%s - %s",dbuffer,tbuffer);
174 #endif
175
176    // search for <level> field
177    level = -1;
178    lt=strchr(logString, '<');
179    gt=strchr(logString, '>');
180    if(lt && gt && lt<gt)
181    {
182        int t;
183        for(t=0;t<loglevels;t++)
184        {
185 #ifndef __NT__
186            if(!strncasecmp(lt+1,logimportance[t],strlen(logimportance[t])))
187 #else
188            if(!strnicmp(lt+1,logimportance[t],strlen(logimportance[t])))
189 #endif
190            {
191                logString = gt+1;
192                while(logString[0]==' ') logString ++;
193                level = t;
194                break;
195            }
196        }
197    }
198    
199 //   sprintf(logBuffer, "%s: %s %s", timebuffer, logimportance2[level + 1],logString);
200    sprintf(logBuffer, "%s %s", logimportance2[level + 1],logString);
201
202    // we always do exactly one newline.
203    
204    l=strlen(logBuffer)-1;
205    while((logBuffer[l]==13 || logBuffer[l]==10) && l>=0)
206    {
207        logBuffer[l]=0;
208        l--;
209    }
210
211    if (level <= screenloglevel)
212    {
213        printf("%s\n", logBuffer); 
214        fflush(stdout);
215    }
216
217    if (level <= fileloglevel)
218    {
219        if (logFile != NULL)
220        {
221           fprintf(logFile, "%s\n", logBuffer); 
222           fflush(logFile);
223        }
224    }
225
226    if (level <= socketloglevel)
227    {
228        if (bLogToSock)
229        {
230           // send data
231 #ifndef __NT__
232           write(logSocket, logBuffer, strlen(logBuffer));
233 #else
234           send(logSocket, logBuffer, strlen(logBuffer), 0);
235 #endif
236        }
237    }
238    free (logBuffer);
239 }
240
241 void logf(const char* format, ...)
242 {
243     char buf[1024];
244         va_list arglist;
245         va_start(arglist, format);
246     buf[0] = 0;
247     vsprintf(&buf[strlen(buf)], format, arglist);
248         va_end(arglist);
249     strcat(buf, "\n");
250     log(buf);
251 }
252