Browse Source

Add basic function to process attachment

master
Damien Goutte-Gattat 10 years ago
parent
commit
02e76c43b0
  1. 87
      src/fmail.c

87
src/fmail.c

@ -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