-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathlog.c
More file actions
113 lines (91 loc) · 2.64 KB
/
log.c
File metadata and controls
113 lines (91 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* ipxwrapper - Logging functions
* Copyright (C) 2011-2024 Daniel Collins <solemnwarning@solemnwarning.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "ipxwrapper.h"
#include "common.h"
static HANDLE log_fh = NULL;
static HANDLE log_mutex = NULL;
void log_init()
{
if(!(log_mutex = CreateMutex(NULL, FALSE, NULL))) {
abort();
}
}
void log_open(const char *file) {
log_fh = CreateFile(
file,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
NULL
);
if(log_fh == INVALID_HANDLE_VALUE) {
log_fh = NULL;
}
}
void log_close() {
if(log_fh) {
CloseHandle(log_fh);
log_fh = NULL;
}
if(log_mutex) {
CloseHandle(log_mutex);
log_mutex = NULL;
}
}
void log_printf(enum ipx_log_level level, const char *fmt, ...) {
DWORD called = GetTickCount();
if(level < min_log_level) {
return;
}
WaitForSingleObject(log_mutex, INFINITE);
if(!log_fh) {
log_open("ipxwrapper.log");
}
if(!log_fh) {
ReleaseMutex(log_mutex);
return;
}
va_list argv;
char msg[1024], tstr[64];
va_start(argv, fmt);
vsnprintf(msg, 1024, fmt, argv);
va_end(argv);
snprintf(tstr, 64, "[%u.%02u, thread %u] ", (unsigned int)(called/1000), (unsigned int)((called % 1000) / 10), (unsigned int)GetCurrentThreadId());
OVERLAPPED off;
off.Offset = 0;
off.OffsetHigh = 0;
off.hEvent = 0;
if(!LockFileEx(log_fh, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &off)) {
ReleaseMutex(log_mutex);
return;
}
if(SetFilePointer(log_fh, 0, NULL, FILE_END) != INVALID_SET_FILE_POINTER) {
DWORD written;
WriteFile(log_fh, tstr, strlen(tstr), &written, NULL);
WriteFile(log_fh, msg, strlen(msg), &written, NULL);
WriteFile(log_fh, "\r\n", 2, &written, NULL);
}
UnlockFile(log_fh, 0, 0, 1, 0);
ReleaseMutex(log_mutex);
}