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
|
/*
* Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include "libbb.h"
#define BUF_CHUNK 256
struct buf
{
size_t offset;
size_t size;
size_t maxsize;
unsigned char *buf;
int fd;
};
void buf_init(struct buf *buf, int fd)
{
buf->maxsize= 0;
buf->size= 0;
buf->offset= 0;
buf->buf= NULL;
buf->fd= fd;
}
int buf_add(struct buf *buf, const void *data, size_t len )
{
size_t maxsize;
void *newbuf;
if (buf->size+len <= buf->maxsize)
{
/* Easy case, just add data */
memcpy(buf->buf+buf->size, data, len);
buf->size += len;
return 0;
}
/* Just get a new buffer */
maxsize= buf->size-buf->offset + len + BUF_CHUNK;
newbuf= malloc(maxsize);
if (!newbuf)
{
fprintf(stderr, "unable to allocate %ld bytes\n", maxsize);
return (1);
}
if (buf->offset < buf->size)
{
/* Copy existing data */
memcpy(newbuf, buf->buf+buf->offset, buf->size-buf->offset);
buf->size -= buf->offset;
buf->offset= 0;
}
else
{
buf->size= buf->offset= 0;
}
buf->maxsize= maxsize;
free(buf->buf);
buf->buf= newbuf;
memcpy(buf->buf+buf->size, data, len);
buf->size += len;
return 0;
}
int buf_add_b64(struct buf *buf, void *data, size_t len, int mime_nl)
{
char b64[]=
"ABCDEFGHIJKLMNOP"
"QRSTUVWXYZabcdef"
"ghijklmnopqrstuv"
"wxyz0123456789+/";
int i;
uint8_t *p;
uint32_t v;
char str[4];
p= data;
for (i= 0; i+3 <= len; i += 3, p += 3)
{
v= (p[0] << 16) + (p[1] << 8) + p[2];
str[0]= b64[(v >> 18) & 63];
str[1]= b64[(v >> 12) & 63];
str[2]= b64[(v >> 6) & 63];
str[3]= b64[(v >> 0) & 63];
buf_add(buf, str, 4);
if(mime_nl)
if (i % 48 == 45)
buf_add(buf, "\n", 1);
}
switch(len-i)
{
case 0: break; /* Nothing to do */
case 1:
v= (p[0] << 16);
str[0]= b64[(v >> 18) & 63];
str[1]= b64[(v >> 12) & 63];
str[2]= '=';
str[3]= '=';
buf_add(buf, str, 4);
break;
case 2:
v= (p[0] << 16) + (p[1] << 8);
str[0]= b64[(v >> 18) & 63];
str[1]= b64[(v >> 12) & 63];
str[2]= b64[(v >> 6) & 63];
str[3]= '=';
buf_add(buf, str, 4);
break;
default:
fprintf(stderr, "bad state in buf_add_b64");
}
}
void buf_cleanup(struct buf *buf)
{
if(buf->maxsize)
free(buf->buf);
buf->buf = NULL;
buf->offset= buf->size= buf->maxsize= 0;
}
|