165 |
|
|
166 |
#define MAX_QUOTE 75 |
#define MAX_QUOTE 75 |
167 |
|
|
168 |
/* Be more conservative in what we quote. This is never a problem for |
/* Be more conservative in what we quote than in RFC2045, as in some |
169 |
the recipient, except for the extra overhead in the message size */ |
circumstances, additional symbols (like parenthesis) must be quoted |
170 |
|
in headers. This is never a problem for the recipient, except for |
171 |
|
the extra overhead in the message size */ |
172 |
static int |
static int |
173 |
must_quote (char c) |
must_quote (char c) |
174 |
{ |
{ |
179 |
return 1; |
return 1; |
180 |
} |
} |
181 |
|
|
182 |
|
|
183 |
|
/* State of the encoder */ |
184 |
typedef struct _encoder rfc2047_encoder; |
typedef struct _encoder rfc2047_encoder; |
185 |
|
|
186 |
struct _encoder { |
struct _encoder { |
187 |
char encoding; |
/* Name of the encoding (either B or Q) */ |
188 |
|
char encoding; |
189 |
|
|
190 |
|
/* Charset of the encoded data */ |
191 |
const char * charset; |
const char * charset; |
192 |
|
|
193 |
|
/* TRUE if we need to open a quoted-word at the next byte */ |
194 |
int must_open; |
int must_open; |
195 |
|
|
196 |
|
/* Pointer on the current input byte */ |
197 |
const unsigned char * src; |
const unsigned char * src; |
198 |
|
|
199 |
|
/* Pointer on the current output byte and on the complete output */ |
200 |
char * dst, * result; |
char * dst, * result; |
201 |
|
|
202 |
|
/* todo: number of bytes remaining in the input, done: number of |
203 |
|
bytes written in the output, quotesize: number of bytes in the |
204 |
|
current quoted-word */ |
205 |
int todo, done, quotesize; |
int todo, done, quotesize; |
206 |
|
|
207 |
|
/* Virtual methods implemented for the encoders: |
208 |
|
|
209 |
|
count: return how many bytes would be used by inserting the |
210 |
|
current input |
211 |
|
next: quote the current input byte on the output |
212 |
|
flush: output any pending byte and close the quoted-word |
213 |
|
*/ |
214 |
int (* count) (rfc2047_encoder * enc); |
int (* count) (rfc2047_encoder * enc); |
215 |
void (* next) (rfc2047_encoder * enc); |
void (* next) (rfc2047_encoder * enc); |
216 |
void (* flush) (rfc2047_encoder * enc); |
void (* flush) (rfc2047_encoder * enc); |
217 |
|
|
218 |
|
/* Extra data for the Base64 encoder */ |
219 |
unsigned char buffer [4]; |
unsigned char buffer [4]; |
|
|
|
220 |
int state; |
int state; |
|
|
|
221 |
}; |
}; |
222 |
|
|
223 |
|
|
224 |
|
/* Write the opening of a quoted-word and return the minimum number of |
225 |
|
bytes it will use */ |
226 |
static int |
static int |
227 |
_open_quote (const char * charset, |
_open_quote (const char * charset, |
228 |
char encoding, |
char encoding, |
242 |
return len + 2; |
return len + 2; |
243 |
} |
} |
244 |
|
|
245 |
|
/* Terminate a quoted-word */ |
246 |
static void |
static void |
247 |
_close_quote (char ** dst, int * done) |
_close_quote (char ** dst, int * done) |
248 |
{ |
{ |
255 |
} |
} |
256 |
} |
} |
257 |
|
|
258 |
|
|
259 |
|
/* Call this function before the beginning of a quoted-word */ |
260 |
static void |
static void |
261 |
init_quoted (rfc2047_encoder * enc) |
init_quoted (rfc2047_encoder * enc) |
262 |
{ |
{ |
263 |
enc->must_open = 1; |
enc->must_open = 1; |
264 |
} |
} |
265 |
|
|
266 |
|
/* Insert the current byte in the quoted-word (handling maximum |
267 |
|
quoted-word sizes,...) */ |
268 |
static void |
static void |
269 |
insert_quoted (rfc2047_encoder * enc) |
insert_quoted (rfc2047_encoder * enc) |
270 |
{ |
{ |
295 |
enc->next (enc); |
enc->next (enc); |
296 |
} |
} |
297 |
|
|
298 |
|
/* Flush the current quoted-word */ |
299 |
static void |
static void |
300 |
flush_quoted (rfc2047_encoder * enc) |
flush_quoted (rfc2047_encoder * enc) |
301 |
{ |
{ |
306 |
} |
} |
307 |
|
|
308 |
|
|
309 |
|
/* Insert the current byte unquoted */ |
310 |
static void |
static void |
311 |
insert_unquoted (rfc2047_encoder * enc) |
insert_unquoted (rfc2047_encoder * enc) |
312 |
{ |
{ |
317 |
} |
} |
318 |
|
|
319 |
|
|
320 |
|
/* Check if the next word will need to be quoted */ |
321 |
static int |
static int |
322 |
is_next_quoted (const char * src) |
is_next_quoted (const char * src) |
323 |
{ |
{ |
335 |
} |
} |
336 |
|
|
337 |
|
|
338 |
/* Quoted-printable encoder */ |
/* -------------------------------------------------- |
339 |
|
Quoted-printable encoder |
340 |
|
-------------------------------------------------- */ |
341 |
|
|
342 |
static void |
static void |
343 |
qp_init (rfc2047_encoder * enc) |
qp_init (rfc2047_encoder * enc) |
356 |
static void |
static void |
357 |
qp_next (rfc2047_encoder * enc) |
qp_next (rfc2047_encoder * enc) |
358 |
{ |
{ |
359 |
if (must_quote (* enc->src)) |
if (* enc->src == '_' || must_quote (* enc->src)) |
360 |
{ |
{ |
361 |
/* special encoding of space as a '_' to increase readability */ |
/* special encoding of space as a '_' to increase readability */ |
362 |
if (* enc->src == ' ') |
if (* enc->src == ' ') |
406 |
} |
} |
407 |
|
|
408 |
|
|
409 |
/* Base64 encoder */ |
/* -------------------------------------------------- |
410 |
|
Base64 encoder |
411 |
|
-------------------------------------------------- */ |
412 |
|
|
413 |
const char *b64 = |
const char *b64 = |
414 |
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |