writeBuffer.c
3.51 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
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
#include <stdio.h> /* for ferror() */
#include <string.h> /* for memset and stuff */
#include <errno.h> /* for errno */
#include <ctype.h> /* for isprint */
#include "include/client.h"
#include "include/monitor.h"
int
_handleIoError(FILE * wHandle)
{
if (ferror(wHandle)) {
switch (errno) {
case EIO:
/* FALLTHROUGHT */
case ENOSPC:
syslogMonitor(LOG_ERR, MON_CRITICAL, "io.fatal",
"fatal IO error [%s]",
strerror(errno));
syslogMonitor(LOG_ERR, MON_FAILURE, "io.fatal",
"fatal IO error [%s] - service terminated",
strerror(errno));
break;
}
return 1;
}
return 0;
}
int
_isPrintableBuffer(const char * buffer, size_t size, char * found)
{
while (isprint(*(buffer++)) && 1 < size--);
if (0 == size) {
return 1;
} else {
*found = *(buffer-1);
return 0;
}
}
int
_doWrite(tClient * client, size_t size, FILE * wHandle)
{
char found = '\0';
if (NULL != client->buffer) {
if (!_isPrintableBuffer(client->buffer, size, &found)) {
syslogMonitor(LOG_ERR, MON_WARNING, "data.binary",
"got non printable character[0x%02x] from client[%s] - connection closed",
found,
client->remoteAddr);
return WRITE_ERR_NOPRINT;
}
/* write remaining stuff to file */
fwrite(client->buffer, size, 1, wHandle);
if (_handleIoError(wHandle)) {
return WRITE_ERR_IO;
}
fputc('\n', wHandle);
if (_handleIoError(wHandle)) {
return WRITE_ERR_IO;
}
fflush(wHandle);
if (_handleIoError(wHandle)) {
return WRITE_ERR_IO;
}
return size + 1;
} else {
return 0;
}
}
/*
* write all data that remains in buffer, even if its not terminated by
* a newline. Anyway ignore trailing newlines.
*/
int
writeRemaining(tClient * client, FILE * wHandle)
{
int written = writeBuffer(client, wHandle);
if (0 < client->readPos) {
unsigned int wLen = client->readPos;
/* ignore trailing newlines */
while (0 < client->readPos && '\n' == client->buffer[wLen]) {
wLen--;
}
written += _doWrite(client, wLen, wHandle);
}
memset(client->buffer, 0, client->readPos);
client->readPos = 0;
return written;
}
/*
* write buffer till last newline is reached.
* If no newline is in buffer, nothing is written.
*/
int
writeBuffer(tClient * client, FILE * wHandle)
{
char * nlpos = memchr(client->buffer, '\n', client->readPos);
int written = 0;
while (NULL != nlpos) {
unsigned int moveSize, clearSize;
char * actAddr;
if (nlpos > client->buffer) {
unsigned int wLen = nlpos - client->buffer;
int wTemp = _doWrite(client, wLen, wHandle);
if (0 > wTemp) {
return wTemp;
}
written += wTemp;
}
actAddr = client->buffer + client->readPos;
moveSize = actAddr - nlpos - 1;
clearSize = actAddr - client->buffer - moveSize;
memmove(client->buffer, nlpos+1, moveSize);
memset(client->buffer + moveSize, 0, clearSize);
client->readPos = moveSize;
nlpos = memchr(client->buffer, '\n', client->readPos);
}
return written;
}