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