Browse Source

Use 7bit-encoding for attachments when possible.

Avoid Quoted-Printable encoding for attachment when possible
(if the attachment appears to be US-ASCII and does not contain any
line longer than 998 characters).

Some mail clients (Gnus?) seem to have problems extracting
attached OpenPGP keys if they are encoded in Quoted-Printable.
tags/fmail-0.2.1^2
parent
commit
0686642b01
1 changed files with 62 additions and 8 deletions
  1. +62
    -8
      src/fmail.c

+ 62
- 8
src/fmail.c View File

@@ -134,6 +134,45 @@ generate_boundary(char *buffer, size_t len)
return buffer;
}

static int
check_7bit_encoding(const char *filename)
{
FILE *f;
int c, ok = 1;
unsigned n;

f = fopen(filename, "r");
while ( ! feof(f) && ! ok ) {
c = fgetc(f);

if ( c == 0 || c == '\r' || c > 127 )
ok = 0;
else if ( c == '\n' )
n = 0;
else
n += 1;

if ( n > 998 )
ok = 0;
}

fclose(f);

return ok;
}

static void
mime7bit_encode_stream(FILE *in, FILE *out)
{
int c;

while ( (c = fgetc(in)) != EOF ) {
if ( c == '\n' )
fputc('\r', out);
fputc(c, out);
}
}

static void
qp_encode_stream(FILE *in, FILE *out)
{
@@ -530,33 +569,48 @@ get_basename(const char *filename)
return last_slash ? last_slash + 1 : filename;
}

typedef enum {
ENCODING_7BIT = 0,
ENCODING_QP,
ENCODING_BASE64
} encoding_t;

const char *encoding_names[] = { "7bit", "quoted-printable", "base64" };
void (*encoding_funcs[])(FILE *, FILE *) = {
mime7bit_encode_stream,
qp_encode_stream,
base64_encode_stream
};

static void
process_attachment(const char *filename, magic_t ctx, FILE *out)
{
const char *mime;
int binary;
encoding_t encoding;
FILE *f;

if ( (mime = magic_file(ctx, filename)) ) {
const char *last_eq;

last_eq = strrchr(mime, '=');
binary = strcmp(last_eq, "=binary") ? 0 : 1;
if ( strcmp(last_eq, "=binary") == 0 )
encoding = ENCODING_BASE64;
else if ( strcmp(last_eq, "=us-ascii") == 0 && check_7bit_encoding(filename) )
encoding = ENCODING_7BIT;
else
encoding = ENCODING_QP;
}
else {
mime = "application/octet-stream";
binary = 1;
encoding = ENCODING_BASE64;
}

fprintf(out, "Content-Type: %s\r\n", mime);
fprintf(out, "Content-Transfer-Encoding: %s\r\n", binary ? "base64" : "quoted-printable");
fprintf(out, "Content-Transfer-Encoding: %s\r\n", encoding_names[encoding]);
fprintf(out, "Content-Disposition: attachment; filename=%s\r\n\r\n", get_basename(filename));

f = fopen(filename, "r");
if ( binary )
base64_encode_stream(f, out);
else
qp_encode_stream(f, out);
encoding_funcs[encoding](f, out);
fclose(f);

fprintf(out, "\r\n");


Loading…
Cancel
Save