offline pcap reading working
[netsniff-ng.git] / src / tprintf.c
bloba721445b064fc53155dd55de8576ee81c1251d9f
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Subject to the GPL.
6 */
8 #define _BSD_SOURCE
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include <pthread.h>
12 #include <assert.h>
14 #include "tty.h"
15 #include "tprintf.h"
16 #include "die.h"
18 static char buffer[1024];
19 static size_t buffer_use = 0;
20 static pthread_spinlock_t buffer_lock;
22 static size_t lcount = 0;
25 * We want to print our stuff terminal aligned. Since we're printing packets
26 * we're in slowpath anyways. If stdin/stdout are connected to a terminal
27 * then default size = 1024; else size = 4096.
29 void tprintf_flush(void)
31 char *ptr = buffer;
32 size_t flush_len = get_tty_size() - 5;
34 while (buffer_use-- > 0) {
35 if (lcount == flush_len) {
36 fputs("\n ", stdout);
37 lcount = 3;
38 while (buffer_use > 0 && (*ptr == ' ' ||
39 *ptr == ',' || *ptr == '\n')) {
40 buffer_use--;
41 ptr++;
45 if (*ptr == '\n') {
46 flush_len = get_tty_size() - 5;
47 lcount = -1;
50 /* Collect in stream buffer. */
51 fputc(*ptr, stdout);
52 ptr++;
54 lcount++;
57 fflush(stdout);
58 buffer_use++;
59 assert(buffer_use == 0);
62 void tprintf_init(void)
64 pthread_spin_init(&buffer_lock, PTHREAD_PROCESS_SHARED);
65 memset(buffer, 0, sizeof(buffer));
68 void tprintf_cleanup(void)
70 pthread_spin_lock(&buffer_lock);
71 tprintf_flush();
72 pthread_spin_unlock(&buffer_lock);
73 pthread_spin_destroy(&buffer_lock);
76 void tprintf(char *msg, ...)
78 int ret;
79 va_list vl;
81 va_start(vl, msg);
82 pthread_spin_lock(&buffer_lock);
84 ret = vsnprintf(buffer + buffer_use,
85 sizeof(buffer) - buffer_use,
86 msg, vl);
87 if (ret < 0)
88 /* Something screwed up! Unexpected. */
89 goto out;
91 if (ret >= sizeof(buffer) - buffer_use) {
92 tprintf_flush();
94 /* Rewrite the buffer */
95 ret = vsnprintf(buffer + buffer_use,
96 sizeof(buffer) - buffer_use,
97 msg, vl);
98 /* Again, we've failed! This shouldn't happen! So
99 * switch to vfprintf temporarily :-( */
100 if (ret >= sizeof(buffer) - buffer_use) {
101 fprintf(stderr, "BUG (buffer too large) -->\n");
102 vfprintf(stdout, msg, vl);
103 fprintf(stderr, " <--\n");
104 goto out;
108 if (ret < sizeof(buffer) - buffer_use)
109 buffer_use += ret;
111 out:
112 pthread_spin_unlock(&buffer_lock);
113 va_end(vl);