Browse Source

Add basic function to process attachment

tags/v0.1.0
Damien Goutte-Gattat 9 years ago
parent
commit
02e76c43b0
1 changed files with 83 additions and 4 deletions
  1. +83
    -4
      src/fmail.c

+ 83
- 4
src/fmail.c View File

@@ -24,10 +24,12 @@
#include <stdlib.h>
#include <getopt.h>
#include <locale.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

#include <gpgme.h>
#include <magic.h>

#include <sbuffer.h>
#include <xmem.h>
@@ -80,16 +82,17 @@ See the COPYING file or <http://www.gnu.org/licenses/gpl.html>.\n\
/* Helper functions. */

const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

static char *
generate_boundary(char *buffer, size_t len)
{
static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
int i;

for ( i = 0; i < len - 1; i++ )
buffer[i] = chars[rand() % (sizeof(chars) - 1)];
buffer[i] = base64_chars[rand() % (sizeof(base64_chars) - 1)];
buffer[i] = '\0';

return buffer;
@@ -143,6 +146,35 @@ qp_encode_stream(FILE *in, FILE *out)
}
}

static void
base64_encode_stream(FILE *in, FILE *out)
{
unsigned char buffer[3];
int n, j;

j = 0;
while ( (n = fread(buffer, 1, 3, in)) > 0 ) {
char quartet[4];

if ( n < 3 )
buffer[2] = 0;
if ( n < 2 )
buffer[1] = 0;

quartet[0] = base64_chars[buffer[0] >> 2];
quartet[1] = base64_chars[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xf0) >> 4)];
quartet[2] = (unsigned char) (n > 1 ? base64_chars[((buffer[1] & 0x0f) << 2) | ((buffer[2] & 0x0c) >> 6)] : '=' );
quartet[3] = (unsigned char) (n > 2 ? base64_chars[buffer[2] & 0x3f] : '=');

j += 1;
fwrite(quartet, 1, 4, out);
if ( j == 16 ) {
fprintf(out, "\r\n");
j = 0;
}
}
}

static char *
rfc2822_date(void)
{
@@ -269,6 +301,49 @@ sign_stream(gpgme_ctx_t ctx, FILE *in, FILE *out)


/* Attachments stuff. */

static magic_t
initialize_magic(void)
{
magic_t ctx;

if ( ! (ctx = magic_open(MAGIC_SYMLINK | MAGIC_MIME)) )
err(EXIT_FAILURE, "cannot obtain libmagic cookie");

if ( magic_load(ctx, NULL) == -1 )
err(EXIT_FAILURE, "cannot load default magic database");

return ctx;
}

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

mime = magic_file(ctx, filename);
last_eq = strrchr(mime, '=');
binary = strcmp(last_eq, "=binary") ? 0 : 1;

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

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

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


/* Main function. */

int
@@ -277,6 +352,7 @@ main(int argc, char *argv[])
char c, **attachments;
string_buffer_t *headers;
gpgme_ctx_t sign_ctx;
magic_t mgc_ctx;
int att_count;

struct option options[] = {
@@ -293,6 +369,7 @@ main(int argc, char *argv[])

headers = sb_new(0);
sign_ctx = NULL;
mgc_ctx = initialize_magic();
attachments = NULL;
att_count = 0;

@@ -349,5 +426,7 @@ main(int argc, char *argv[])
if ( attachments )
free(attachments);

magic_close(mgc_ctx);

return EXIT_SUCCESS;
}

Loading…
Cancel
Save