EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
logsys.cpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------
3  * LICENSE:
4  * ------------------------------------------------------------------------------------
5  * This file is part of EVEmu: EVE Online Server Emulator
6  * Copyright 2006 - 2021 The EVEmu Team
7  * For the latest information visit https://evemu.dev
8  * ------------------------------------------------------------------------------------
9  * This program is free software; you can redistribute it and/or modify it under
10  * the terms of the GNU Lesser General Public License as published by the Free Software
11  * Foundation; either version 2 of the License, or (at your option) any later
12  * version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License along with
19  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  * Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  * http://www.gnu.org/copyleft/lesser.txt.
22  * ------------------------------------------------------------------------------------
23  * Author: Zhur
24  */
25 
26 #include "eve-core.h"
27 
28 #include "log/logsys.h"
29 #include "utils/utils_hex.h"
30 #include "threading/Mutex.h"
31 
33 
34 FILE *logsys_log_file(nullptr);
35 
36 #define LOG_CATEGORY(category) #category ,
38  #include "log/logtypes.h"
39 };
40 
41 //this array is private to this file, only a const version of it is exposed
42 #define LOG_TYPE(category, type, enabled, str) { enabled, LOG_ ##category, #category "__" #type, str },
44  #include "log/logtypes.h"
45  #include "utils/Lock.h"
46  { false, NUMBER_OF_LOG_CATEGORIES, "BAD TYPE", "Bad Name" } /* dummy trailing record */
47 };
48 
50 
51 void log_hex(LogType type, const void *data, unsigned long length, unsigned char padding) {
52  char buffer[80];
53  uint32 offset;
54  for(offset=0;offset<length;offset+=16) {
55  build_hex_line((const uint8 *)data,length,offset,buffer,padding);
56  log_message(type, "%s", buffer); //%s is to prevent % escapes in the ascii
57  }
58 }
59 
60 void log_phex(LogType type, const void *data, unsigned long length, unsigned char padding) {
61  if (length <= 1024)
62  log_hex(type, data, length, padding);
63  else {
64  char buffer[80];
65  log_hex(type, data, 1024-32, padding);
66  log_message(type, " ... truncated ...");
67  build_hex_line((const uint8 *)data,length,length-16,buffer,padding);
68  log_message(type, "%s", buffer);
69  }
70 }
71 
72 void log_message(LogType type, const char *fmt, ...) {
73  va_list args;
74  va_start(args, fmt);
75  log_messageVA(type, 0, fmt, args);
76  va_end(args);
77 }
78 
79 void log_messageVA(LogType type, const char *fmt, va_list args) {
80 
81  log_messageVA(type, 0, fmt, args);
82 }
83 
84 extern void log_messageVA( LogType type, uint32 iden, const char *fmt, va_list args )
85 {
86  /* allocate enough room for a med message (changed from 4k to 1k) */
87  size_t log_msg_size = 0x400;
88  size_t log_msg_index = 0;
89  char* log_msg = (char*)malloc(log_msg_size);
90 
91  /* handle the time part.. cross platform */
92  tm t;
93  time_t tTime;
94  time(&tTime);
95  localtime_r( &tTime, &t );
96  int va_size = snprintf(&log_msg[log_msg_index], log_msg_size, "%02u:%02u:%02u [%s] ", t.tm_hour, t.tm_min, t.tm_sec, log_type_info[type].display_name );
97 
98  /* store the resulting size */
99  log_msg_size-=va_size;
100  log_msg_index+=va_size;
101 
102  /* add the required spaces */
103  for (uint32 i = 0; i < iden; i++)
104  log_msg[log_msg_index++] = ' ';
105 
106  /* make sure the resulting size is corrected */
107  log_msg_size-=iden;
108 
109  /* put in the rest of the va stuff */
110  va_size = vsnprintf(&log_msg[log_msg_index], log_msg_size, fmt, args);
111  log_msg_index+=va_size;
112 
113  /* make sure that there is a new line at the end */
114  log_msg[log_msg_index++] = '\n';
115  log_msg[log_msg_index++] = '\0';
116 
117  MutexLock lock(mLogSys);
118 
119  fputs(log_msg, stdout);
120 
121  //print into the logfile (if any)
122  if (logsys_log_file != nullptr) {
123  //fprintf(logsys_log_file, "%s\n", message.c_str());
124  fputs(log_msg, logsys_log_file);
125  //keep the logfile updated
126  fflush(logsys_log_file);
127  }
128 
129  lock.Unlock();
130 
131  free(log_msg);
132 }
133 
135 {
136  real_log_type_info[t].enabled = true;
137 }
138 
140 {
141  real_log_type_info[t].enabled = false;
142 }
143 
145 {
146  real_log_type_info[t].enabled = !real_log_type_info[t].enabled;
147 }
148 
149 bool log_open_logfile( const char* filename )
150 {
151  MutexLock lock(mLogSys);
152  if (logsys_log_file)
153  if (!log_close_logfile())
154  return false;
155 
156  logsys_log_file = fopen(filename, "w");
157  return ( nullptr != logsys_log_file);
158 }
159 
161 {
162  MutexLock lock(mLogSys);
163  if (!logsys_log_file)
164  return true;
165  return ( 0 == fclose( logsys_log_file ) );
166 }
167 
168 bool load_log_settings(const char *filename) {
169  //this is a terrible algorithm, but im lazy today
170  FILE *f = fopen(filename, "r");
171  if (!f)
172  return false;
173  char linebuf[512], type_name[256], value[256];
174  uint16 i(0);
175  while(!feof(f)) {
176  ++i;
177  if (fgets(linebuf, 512, f) == nullptr)
178  continue;
179  if (sscanf(linebuf, "%[^=]=%[^\r\n]\n", type_name, value) != 2)
180  continue;
181 
182  if (type_name[0] == '\0' || type_name[0] == '#')
183  continue;
184 
185  //first make sure we understand the value
186  bool enabled;
187  if (!strcasecmp(value, "on") || !strcasecmp(value, "yes") || !strcasecmp(value, "enabled") || !strcmp(value, "1"))
188  enabled = true;
189  else if (!strcasecmp(value, "off") || !strcasecmp(value, "no") || !strcasecmp(value, "disabled") || !strcmp(value, "0"))
190  enabled = false;
191  else {
192  printf("Unable to parse value '%s' from %s around line %u. Skipping.\n", value, filename, i);
193  continue;
194  }
195 
196  int r;
197  //first see if it is a category name
198  for(r = 0; r < NUMBER_OF_LOG_CATEGORIES; r++) {
199  if (!strcasecmp(log_category_names[r], type_name))
200  break;
201  }
202  if (r != NUMBER_OF_LOG_CATEGORIES) {
203  //matched a category.
204  int k;
205  for(k = 0; k < NUMBER_OF_LOG_TYPES; k++) {
206  if (log_type_info[k].category != r)
207  continue; //does not match this category.
208  if (enabled)
209  log_enable(LogType(k));
210  else
211  log_disable(LogType(k));
212  }
213  continue;
214  }
215 
216  for(r = 0; r < NUMBER_OF_LOG_TYPES; r++) {
217  if (!strcasecmp(log_type_info[r].name, type_name))
218  break;
219  }
220  if (r == NUMBER_OF_LOG_TYPES) {
221  printf("Unable to locate log type %s from file %s around line %u. Skipping.\n", type_name, filename, i);
222  continue;
223  }
224 
225  //got it all figured out, do something now...
226  if (enabled)
227  log_enable(LogType(r));
228  else
229  log_disable(LogType(r));
230  }
231  fclose(f);
232  return true;
233 }
#define vsnprintf
Definition: eve-compat.h:188
unsigned __int8 uint8
Definition: eve-compat.h:46
tm * localtime_r(const time_t *timep, tm *result)
Definition: eve-compat.cpp:184
bool load_log_settings(const char *filename)
Definition: logsys.cpp:168
A lock for a Lockable object.
Definition: Lock.h:70
void build_hex_line(const uint8 *buffer, size_t length, size_t offset, char *ret, unsigned int padding)
Build a printable line suitable for hex dump.
Definition: utils_hex.cpp:33
bool log_open_logfile(const char *filename)
Definition: logsys.cpp:149
Common wrapper for platform-specific mutexes.
Definition: Mutex.h:36
* args
void log_hex(LogType type, const void *data, unsigned long length, unsigned char padding)
Definition: logsys.cpp:51
#define snprintf
Definition: eve-compat.h:184
const char * display_name
Definition: logsys.h:72
const LogTypeStatus * log_type_info
Definition: logsys.cpp:49
static LogTypeStatus real_log_type_info[NUMBER_OF_LOG_TYPES+1]
Definition: logsys.cpp:43
void log_toggle(LogType t)
Definition: logsys.cpp:144
bool enabled
Definition: logsys.h:69
void log_enable(LogType t)
Definition: logsys.cpp:134
void log_disable(LogType t)
Definition: logsys.cpp:139
unsigned __int32 uint32
Definition: eve-compat.h:50
void log_phex(LogType type, const void *data, unsigned long length, unsigned char padding)
Definition: logsys.cpp:60
void Unlock()
Unlocks the object.
Definition: Lock.h:115
void log_message(LogType type, const char *fmt,...)
Definition: logsys.cpp:72
Mutex mLogSys
Definition: logsys.cpp:32
LogType
Definition: logsys.h:59
FILE * logsys_log_file(nullptr)
void log_messageVA(LogType type, const char *fmt, va_list args)
Definition: logsys.cpp:79
unsigned __int16 uint16
Definition: eve-compat.h:48
bool log_close_logfile()
Definition: logsys.cpp:160
const char * log_category_names[NUMBER_OF_LOG_CATEGORIES]
Definition: logsys.cpp:37
#define strcasecmp
Definition: eve-compat.h:262