forked from kernelslacker/trinity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.c
208 lines (176 loc) · 4.08 KB
/
log.c
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include <stdio.h>
#include <stdarg.h>
#include "log.h"
#include "params.h" // logging, monochrome, quiet_level
#include "pids.h"
#include "shm.h"
#include "trinity.h"
#define BUFSIZE 1024 // decoded syscall args are fprintf'd directly, this is for everything else.
char ANSI_RED[] = "[1;31m";
char ANSI_GREEN[] = "[1;32m";
char ANSI_YELLOW[] = "[1;33m";
char ANSI_BLUE[] = "[1;34m";
char ANSI_MAGENTA[] = "[1;35m";
char ANSI_CYAN[] = "[1;36m";
char ANSI_WHITE[] = "[1;37m";
char ANSI_RESET[] = "[0m";
void strip_ansi(char *ansibuf)
{
char *from = ansibuf, *to = ansibuf;
unsigned int len, i;
/* If we've specified monochrome, we won't have any ANSI codes
* in the buffer to be stripped out. */
if (monochrome == TRUE)
return;
/* because we look ahead two bytes as we scan the buffer,
* we only want to scan a maximum of buffer len - 2 bytes
* to avoid reading past the end.
*/
len = strlen(ansibuf) - 2;
for (i = 0; i < len; i++) {
*to = from[i];
if (from[i] == '') {
if (from[i + 2] == '1')
i += 6; // ANSI_COLOUR
else
i += 3; // ANSI_RESET
} else {
to++;
}
}
/* copy the trailing 2 bytes */
*to++ = from[i++];
*to++ = from[i];
*to = 0;
}
/*
* level defines whether it gets displayed to the screen with printf.
* (it always logs).
* 0 = everything, even all the registers
* 1 = prints syscall count
* 2 = Just the reseed values
*
*/
void output(unsigned char level, const char *fmt, ...)
{
va_list args;
int n;
FILE *handle;
pid_t pid;
char outputbuf[BUFSIZE];
char *prefix = NULL;
char main_prefix[]="[main]";
char child_prefix[32];
if (logging == LOGGING_DISABLED && level >= quiet_level)
return;
/* prefix preparation */
pid = getpid();
if (pid == mainpid)
prefix = main_prefix;
else if (prefix == NULL) {
unsigned int childno;
childno = find_childno(pid);
snprintf(child_prefix, sizeof(child_prefix), "[child%u:%u]", childno, pid);
prefix = child_prefix;
shm->children[childno]->logdirty = TRUE;
}
/* formatting output */
va_start(args, fmt);
n = vsnprintf(outputbuf, sizeof(outputbuf), fmt, args);
va_end(args);
if (n < 0) {
outputerr("## Something went wrong in output() [%d]\n", n);
exit(EXIT_FAILURE);
}
/* stdout output if needed */
if (quiet_level >= level) {
printf("%s %s", prefix, outputbuf);
(void)fflush(stdout);
}
/* go on with file logs only if enabled */
if (logging == LOGGING_DISABLED)
return;
handle = find_logfile_handle();
if (!handle)
return;
strip_ansi(outputbuf);
fprintf(handle, "%s %s", prefix, outputbuf);
(void)fflush(handle);
}
/*
* Used as a way to consolidated all printf calls if someones one to redirect it to somewhere else.
* note: this function ignores quiet_level since it main purpose is error output.
*/
void outputerr(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
void outputstd(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
}
// TODO: combine the below with output()
void output_rendered_buffer(char *buffer)
{
FILE *log_handle;
/* Output to stdout only if -q param is not specified */
if (quiet_level == MAX_LOGLEVEL) {
fprintf(stdout, "%s", buffer);
fflush(stdout);
}
/* Exit if should not continue at all. */
if (logging == LOGGING_DISABLED)
return;
log_handle = find_logfile_handle();
if (log_handle != NULL) {
strip_ansi(buffer);
fprintf(log_handle, "%s", buffer);
fflush(log_handle);
}
}
void init_logging(void)
{
switch (logging) {
case LOGGING_DISABLED:
return;
case LOGGING_FILES:
open_main_logfile();
return;
}
}
void shutdown_logging(void)
{
switch (logging) {
case LOGGING_DISABLED:
return;
case LOGGING_FILES:
close_logfile(&mainlogfile);
return;
}
}
void init_child_logging(struct childdata *child)
{
switch (logging) {
case LOGGING_DISABLED:
return;
case LOGGING_FILES:
open_child_logfile(child);
return;
}
}
void shutdown_child_logging(struct childdata *child)
{
switch (logging) {
case LOGGING_DISABLED:
return;
case LOGGING_FILES:
close_logfile(&child->logfile);
return;
}
}