Skip to content

Commit d78a704

Browse files
feat: Write log to local file
1 parent 471c538 commit d78a704

1 file changed

Lines changed: 51 additions & 9 deletions

File tree

src/fakehttp.c

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@
4343
#endif /* VERSION */
4444

4545
#define E(...) logger(__func__, __FILE__, __LINE__, __VA_ARGS__)
46+
#define E_RAW(...) logger_raw(__VA_ARGS__)
4647

48+
static FILE *g_logfp = NULL;
4749
static int g_sockfd = 0;
4850
static int g_exit = 0;
4951
static int g_repeat = 3;
@@ -67,6 +69,7 @@ static void print_usage(const char *name)
6769
" -r <repeat> duplicate generated packets for <repeat> "
6870
"times\n"
6971
" -t <ttl> TTL for generated packets\n"
72+
" -w <file> write log to <file> instead of stderr\n"
7073
" -x <mask> set the mask for fwmark\n"
7174
"\n"
7275
"FakeHTTP version " VERSION "\n",
@@ -77,23 +80,38 @@ static void print_usage(const char *name)
7780
static void logger(const char *funcname, const char *filename,
7881
unsigned long line, const char *fmt, ...)
7982
{
83+
FILE *fp;
8084
va_list args;
8185
time_t t;
8286
char *stime;
8387

88+
fp = g_logfp ? g_logfp : stderr;
8489
t = time(NULL);
8590
stime = ctime(&t);
8691
if (stime) {
8792
stime[strlen(stime) - 1] = '\0';
88-
fprintf(stderr, "%s ", stime);
93+
fprintf(fp, "%s ", stime);
8994
}
9095

91-
fprintf(stderr, "[%s() - %s:%lu] ", funcname, filename, line);
96+
fprintf(fp, "[%s() - %s:%lu] ", funcname, filename, line);
9297
va_start(args, fmt);
93-
vfprintf(stderr, fmt, args);
98+
vfprintf(fp, fmt, args);
9499
va_end(args);
95-
fputc('\n', stderr);
96-
fflush(stderr);
100+
fputc('\n', fp);
101+
fflush(fp);
102+
}
103+
104+
105+
static void logger_raw(const char *fmt, ...)
106+
{
107+
FILE *fp;
108+
va_list args;
109+
110+
fp = g_logfp ? g_logfp : stderr;
111+
va_start(args, fmt);
112+
vfprintf(fp, fmt, args);
113+
va_end(args);
114+
fflush(fp);
97115
}
98116

99117

@@ -160,12 +178,23 @@ static int execute_command(char **argv, int silent)
160178
}
161179

162180
if (!pid) {
181+
fd = -1;
182+
163183
if (silent) {
164184
fd = open("/dev/null", O_WRONLY);
165185
if (fd < 0) {
166186
E("ERROR: open(): %s", strerror(errno));
167187
_exit(EXIT_FAILURE);
168188
}
189+
} else if (g_logfp) {
190+
fd = fileno(g_logfp);
191+
if (fd < 0) {
192+
E("ERROR: fileno(): %s", strerror(errno));
193+
_exit(EXIT_FAILURE);
194+
}
195+
}
196+
197+
if (fd >= 0) {
169198
res = dup2(fd, STDOUT_FILENO);
170199
if (res < 0) {
171200
E("ERROR: dup2(): %s", strerror(errno));
@@ -197,11 +226,11 @@ static int execute_command(char **argv, int silent)
197226

198227
child_failed:
199228
if (!silent) {
200-
fprintf(stderr, "failed command is: %s", argv[0]);
229+
E_RAW("[*] failed command is: %s", argv[0]);
201230
for (i = 1; argv[i]; i++) {
202-
fprintf(stderr, " %s", argv[i]);
231+
E_RAW(" %s", argv[i]);
203232
}
204-
fputc('\n', stderr);
233+
E_RAW("\n");
205234
}
206235

207236
return -1;
@@ -676,7 +705,7 @@ int main(int argc, char *argv[])
676705
return EXIT_FAILURE;
677706
}
678707

679-
while ((opt = getopt(argc, argv, "h:i:m:n:r:t:x:")) != -1) {
708+
while ((opt = getopt(argc, argv, "h:i:m:n:r:t:w:x:")) != -1) {
680709
switch (opt) {
681710
case 'h':
682711
if (strlen(optarg) > _POSIX_HOST_NAME_MAX) {
@@ -731,6 +760,15 @@ int main(int argc, char *argv[])
731760
}
732761
g_ttl = tmp;
733762
break;
763+
case 'w':
764+
g_logfp = fopen(optarg, "a");
765+
if (!g_logfp) {
766+
fprintf(stderr, "%s: invalid value for -w: %s\n", argv[0],
767+
strerror(errno));
768+
print_usage(argv[0]);
769+
return EXIT_FAILURE;
770+
}
771+
break;
734772
case 'x':
735773
tmp = strtoull(optarg, NULL, 0);
736774
if (!tmp || tmp > UINT32_MAX) {
@@ -973,5 +1011,9 @@ int main(int argc, char *argv[])
9731011
free_buff:
9741012
free(buff);
9751013

1014+
if (g_logfp) {
1015+
fclose(g_logfp);
1016+
}
1017+
9761018
return exitcode;
9771019
}

0 commit comments

Comments
 (0)