Browse Source

Merge branch 'develop'

master fmail-0.2.1
Damien Goutte-Gattat 2 years ago
parent
commit
b0cb062a32
  1. 5
      NEWS
  2. 2
      configure.ac
  3. 2
      man/fmail.1.in
  4. 76
      src/fmail.c

5
NEWS

@ -1,3 +1,8 @@
Changes in fmail 0.2.1 (2019-02-13)
* Use 7bit encoding for attachments when possible.
Changes in fmail 0.2.0 (2019-01-12)
* Prune path components in an attachment’s filename.

2
configure.ac

@ -1,6 +1,6 @@
dnl Configure template for the fmail package
AC_INIT([fmail], [0.2.0],
AC_INIT([fmail], [0.2.1],
[dgouttegattat@incenp.org])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_MACRO_DIR([m4])

2
man/fmail.1.in

@ -110,7 +110,7 @@ Add a
.B User-Agent:
header.
.TP
.BR -D "; " --date
.BR -D ", " --date
Add an automatically generated
.B Date:
header with the current date.

76
src/fmail.c

@ -134,6 +134,47 @@ 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;
if ( ! (f = fopen(filename, "r")) )
return 0; /* We'll error out later. */
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 +571,50 @@ 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);
if ( ! (f = fopen(filename, "r")) )
err(EXIT_FAILURE, "cannot open attachment '%s'", filename);
encoding_funcs[encoding](f, out);
fclose(f);
fprintf(out, "\r\n");

Loading…
Cancel
Save