Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #60 from monich/transfer-encoding
Handle content transfer encoding
  • Loading branch information
monich committed Jan 20, 2015
2 parents 3e93d0f + 557912a commit 918026f
Show file tree
Hide file tree
Showing 34 changed files with 357 additions and 50 deletions.
2 changes: 1 addition & 1 deletion mms-engine/Makefile
Expand Up @@ -17,7 +17,7 @@ include ../mms-lib/Config.mak
#

PKGS = gio-unix-2.0 gio-2.0
LIB_PKGS = libwspcodec libsoup-2.4 dconf $(RESIZE_PKG) $(PKGS)
LIB_PKGS = libwspcodec gmime-2.6 libsoup-2.4 dconf $(RESIZE_PKG) $(PKGS)

#
# Default target
Expand Down
2 changes: 1 addition & 1 deletion mms-engine/mms-engine.pro
@@ -1,6 +1,6 @@
TEMPLATE = app
CONFIG += link_pkgconfig
PKGCONFIG += gio-unix-2.0 gio-2.0 glib-2.0 libsoup-2.4 dconf libwspcodec ImageMagick
PKGCONFIG += gmime-2.6 gio-unix-2.0 gio-2.0 glib-2.0 libsoup-2.4 dconf libwspcodec ImageMagick
DBUS_INTERFACE_DIR = $$_PRO_FILE_PWD_
MMS_LIB_DIR = $$_PRO_FILE_PWD_/../mms-lib
MMS_OFONO_DIR = $$_PRO_FILE_PWD_/../mms-ofono
Expand Down
2 changes: 1 addition & 1 deletion mms-lib/Makefile
Expand Up @@ -12,7 +12,7 @@ include Config.mak
# Required packages
#

PKGS = glib-2.0 libsoup-2.4 libwspcodec
PKGS = gmime-2.6 glib-2.0 libsoup-2.4 libwspcodec

#
# Default target
Expand Down
4 changes: 3 additions & 1 deletion mms-lib/include/mms_message.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013-2014 Jolla Ltd.
* Copyright (C) 2013-2015 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -48,6 +49,7 @@ typedef struct _mms_message_part {
char* content_type; /* Content-Type */
char* content_id; /* Content-ID */
char* file; /* File name */
char* orig; /* File prior to decoding */
} MMSMessagePart;

MMSMessage*
Expand Down
2 changes: 1 addition & 1 deletion mms-lib/mms-lib.pro
@@ -1,7 +1,7 @@
TEMPLATE = lib
CONFIG += staticlib
CONFIG += link_pkgconfig
PKGCONFIG += glib-2.0 libsoup-2.4 libwspcodec
PKGCONFIG += gmime-2.6 glib-2.0 libsoup-2.4 libwspcodec
INCLUDEPATH += include
QMAKE_CFLAGS += -Wno-unused

Expand Down
43 changes: 25 additions & 18 deletions mms-lib/src/mms_codec.c
Expand Up @@ -3,7 +3,7 @@
* Multimedia Messaging Service
*
* Copyright (C) 2010-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013-2014 Jolla Ltd.
* Copyright (C) 2013-2015 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -501,6 +501,7 @@ static gboolean extract_text(struct wsp_header_iter *iter, void *user)
if (text == NULL)
return FALSE;

g_free(*out);
*out = g_strdup(text);

return TRUE;
Expand Down Expand Up @@ -1261,24 +1262,29 @@ static gboolean attachment_parse_headers(struct wsp_header_iter *iter,
{
while (wsp_header_iter_next(iter)) {
const unsigned char *hdr = wsp_header_iter_get_hdr(iter);
unsigned char h;

/* Skip application headers */
if (wsp_header_iter_get_hdr_type(iter) !=
WSP_HEADER_TYPE_WELL_KNOWN)
continue;

h = hdr[0] & 0x7f;

switch (h) {
case MMS_PART_HEADER_CONTENT_ID:
if (!extract_quoted_string(iter, &part->content_id))
return FALSE;
break;
case MMS_PART_HEADER_CONTENT_LOCATION:
if (!extract_text(iter, &part->content_location))
return FALSE;
break;
if (wsp_header_iter_get_hdr_type(iter) ==
WSP_HEADER_TYPE_WELL_KNOWN) {
switch (hdr[0] & 0x7f) {
case MMS_PART_HEADER_CONTENT_ID:
if (!extract_quoted_string(iter,
&part->content_id))
return FALSE;
break;
case MMS_PART_HEADER_CONTENT_LOCATION:
if (!extract_text(iter,
&part->content_location))
return FALSE;
break;
}
} else {
/* Application (textual) header */
if (g_ascii_strcasecmp((char*)hdr,
"content-transfer-encoding") == 0) {
if (!extract_text(iter,
&part->transfer_encoding))
return FALSE;
}
}
}

Expand All @@ -1292,6 +1298,7 @@ static void free_attachment(gpointer data, gpointer user_data)
g_free(attach->content_type);
g_free(attach->content_id);
g_free(attach->content_location);
g_free(attach->transfer_encoding);

g_free(attach);
}
Expand Down
2 changes: 2 additions & 0 deletions mms-lib/src/mms_codec.h
Expand Up @@ -3,6 +3,7 @@
* Multimedia Messaging Service
*
* Copyright (C) 2010-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2013-2015 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -185,6 +186,7 @@ struct mms_attachment {
char *content_type;
char *content_id;
char *content_location;
char *transfer_encoding;
};

struct mms_message {
Expand Down
120 changes: 119 additions & 1 deletion mms-lib/src/mms_file_util.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013-2014 Jolla Ltd.
* Copyright (C) 2013-2015 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -222,6 +223,123 @@ mms_file_copy(
return ok;
}

/*
* MIME decoding
*/
typedef struct mms_mime_decode {
int out;
const char* dest;
size_t outbytes;
size_t outbuflen;
void* outbuf;
GMimeEncoding state;
} MMSMimeDecode;

static
gboolean
mms_file_decode_init(
MMSMimeDecode* dec,
const char* dest,
GMimeContentEncoding enc,
GError** error)
{
memset(dec, 0, sizeof(*dec));
dec->out = open(dest, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, MMS_FILE_PERM);
if (dec->out >= 0) {
dec->dest = dest;
g_mime_encoding_init_decode(&dec->state, enc);
return TRUE;
} else {
MMS_ERROR(error, MMS_LIB_ERROR_IO, "Failed to create file %s: %s",
dest, strerror(errno));
return FALSE;
}
}

static
void
mms_file_decode_deinit(
MMSMimeDecode* dec)
{
g_free(dec->outbuf);
close(dec->out);
}

gboolean
mms_file_decode_step(
MMSMimeDecode* dec,
const void* inbuf,
size_t inlen,
size_t (*step)(GMimeEncoding*, const char*, size_t, char*),
GError** error)
{
ssize_t nbytes;
size_t need = g_mime_encoding_outlen(&dec->state, inlen);
if (need > dec->outbuflen) {
g_free(dec->outbuf);
dec->outbuf = g_malloc(need);
dec->outbuflen = need;
}
nbytes = step(&dec->state, inbuf, inlen, dec->outbuf);
if (write(dec->out, dec->outbuf, nbytes) == nbytes) {
dec->outbytes += nbytes;
return TRUE;
} else {
MMS_ERROR(error, MMS_LIB_ERROR_IO, "Failed to write %s: %s",
dec->dest, strerror(errno));
return FALSE;
}
}

gboolean
mms_file_decode(
const char* src,
const char* dest,
GMimeContentEncoding enc,
GError** error)
{
gboolean ok = FALSE;
int in = open(src, O_RDONLY | O_BINARY);
if (in >= 0) {
MMSMimeDecode dec;
if (mms_file_decode_init(&dec, dest, enc, error)) {
int nbytes;
size_t inbytes = 0;
const size_t buflen = 1024;
void* inbuf = g_malloc(buflen);
ok = TRUE;
while ((nbytes = read(in, inbuf, buflen)) > 0) {
inbytes += nbytes;
if (!mms_file_decode_step(&dec, inbuf, nbytes,
g_mime_encoding_step, error)) {
ok = FALSE;
break;
}
}
if (nbytes < 0) {
ok = FALSE;
MMS_ERROR(error, MMS_LIB_ERROR_IO,
"Failed to read %s: %s", src, strerror(errno));
} else if (ok) {
if (mms_file_decode_step(&dec, NULL, 0,
g_mime_encoding_flush, error)) {
MMS_DEBUG("Decoded %s (%d bytes) -> %s (%d bytes)",
src, (int)inbytes, dest, (int)dec.outbytes);
} else {
ok = FALSE;
}
}
mms_file_decode_deinit(&dec);
g_free(inbuf);
}
close(in);
} else {
MMS_ERROR(error, MMS_LIB_ERROR_IO,
"Failed to open file %s: %s", src, strerror(errno));
}
return ok;
}

/*
* Local Variables:
* mode: C
Expand Down
12 changes: 11 additions & 1 deletion mms-lib/src/mms_file_util.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013-2014 Jolla Ltd.
* Copyright (C) 2013-2015 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand All @@ -17,6 +18,8 @@

#include "mms_lib_types.h"

#include <gmime/gmime-encodings.h>

/* Permissions for MMS files and directories */
#define MMS_DIR_PERM (0755)
#define MMS_FILE_PERM (0644)
Expand Down Expand Up @@ -75,6 +78,13 @@ mms_file_copy(
const char* dest,
GError** error);

gboolean
mms_file_decode(
const char* src,
const char* dest,
GMimeContentEncoding enc,
GError** error);

#define mms_message_dir(config,id) \
(g_strconcat((config)->root_dir, "/" MMS_MESSAGE_DIR "/" , id, NULL))
#define mms_task_dir(task) \
Expand Down
7 changes: 6 additions & 1 deletion mms-lib/src/mms_message.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013-2014 Jolla Ltd.
* Copyright (C) 2013-2015 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
Expand Down Expand Up @@ -33,6 +34,10 @@ mms_message_part_free(
if (!(msg->flags & MMS_MESSAGE_FLAG_KEEP_FILES)) remove(part->file);
g_free(part->file);
}
if (part->orig) {
if (!(msg->flags & MMS_MESSAGE_FLAG_KEEP_FILES)) remove(part->orig);
g_free(part->orig);
}
g_free(part);
}

Expand Down

0 comments on commit 918026f

Please sign in to comment.