diff --git a/mms-lib/src/mms_attachment.c b/mms-lib/src/mms_attachment.c index f9e07ea..d1b36a2 100644 --- a/mms-lib/src/mms_attachment.c +++ b/mms-lib/src/mms_attachment.c @@ -28,6 +28,7 @@ MMS_LOG_MODULE_DEFINE("mms-attachment"); #define MMS_ATTACHMENT_DEFAULT_TYPE "application/octet-stream" +#define CONTENT_TYPE_PARAM_NAME "name" G_DEFINE_TYPE(MMSAttachment, mms_attachment, G_TYPE_OBJECT); @@ -250,6 +251,8 @@ mms_attachment_new( GMappedFile* map = g_mapped_file_new(path, FALSE, error); if (map) { unsigned int flags = 0; + char* media_type = NULL; + char* name = g_path_get_basename(path); char* content_type = NULL; GType type; MMSAttachment* at; @@ -257,43 +260,61 @@ mms_attachment_new( if (info->content_type && info->content_type[0]) { char** ct = mms_parse_http_content_type(info->content_type); if (ct) { - content_type = mms_unparse_http_content_type(ct); + char** ptr; + gboolean append_name = TRUE; if (!strcmp(ct[0], SMIL_CONTENT_TYPE)) { flags |= MMS_ATTACHMENT_SMIL; } + for (ptr = ct+1; *ptr; ptr+=2) { + if (!g_ascii_strcasecmp(ptr[0], CONTENT_TYPE_PARAM_NAME)) { + g_free(ptr[1]); + ptr[1] = g_strdup(name); + append_name = FALSE; + } + } + if (append_name) { + const guint len = g_strv_length(ct); + ct = g_renew(gchar*, ct, len+3); + ct[len] = g_strdup(CONTENT_TYPE_PARAM_NAME); + ct[len+1] = g_strdup(name); + ct[len+2] = NULL; + } + content_type = mms_unparse_http_content_type(ct); + media_type = g_strdup(ct[0]); g_strfreev(ct); } } if (!content_type) { - char* detected_type = mms_attachment_guess_content_type(path); const char* default_charset = "utf-8"; const char* charset = NULL; - const char* ct[4]; + const char* ct[6]; int n = 0; - if (!strcmp(detected_type, SMIL_CONTENT_TYPE)) { + media_type = mms_attachment_guess_content_type(path); + if (!strcmp(media_type, SMIL_CONTENT_TYPE)) { flags |= MMS_ATTACHMENT_SMIL; charset = default_charset; - } else if (g_str_has_prefix(detected_type, "text/")) { + } else if (g_str_has_prefix(media_type, "text/")) { charset = default_charset; } - ct[n++] = detected_type; + ct[n++] = media_type; if (charset) { ct[n++] = "charset"; ct[n++] = charset; } + ct[n++] = CONTENT_TYPE_PARAM_NAME; + ct[n++] = name; ct[n++] = NULL; content_type = mms_unparse_http_content_type((char**)ct); - g_free(detected_type); } MMS_DEBUG("%s: %s", path, content_type); - if (!strcmp(content_type, "image/jpeg")) { + if (!strcmp(media_type, "image/jpeg")) { type = MMS_TYPE_ATTACHMENT_JPEG; - } else if (g_str_has_prefix(content_type, "image/")) { + } else if (g_str_has_prefix(media_type, "image/")) { type = MMS_TYPE_ATTACHMENT_IMAGE; } else { type = MMS_TYPE_ATTACHMENT; @@ -305,10 +326,12 @@ mms_attachment_new( at->flags |= flags; at->file_name = at->original_file = path; at->content_type = content_type; - at->content_location = g_path_get_basename(path); + at->content_location = name; at->content_id = (info->content_id && info->content_id[0]) ? g_strdup(info->content_id) : g_strdup(at->content_location); + + g_free(media_type); return at; } g_free(path); diff --git a/mms-lib/src/mms_codec.c b/mms-lib/src/mms_codec.c index 930c256..6a0d834 100644 --- a/mms-lib/src/mms_codec.c +++ b/mms-lib/src/mms_codec.c @@ -32,10 +32,8 @@ # define ssize_t int # define write _write # include -# define uninitialized_var(x) x #else # include -# define uninitialized_var(x) x = x #endif #include @@ -1853,6 +1851,25 @@ static gboolean encode_quoted_string(struct file_buffer *fb, { char *ptr; char **text = user; + + if (!*text) + return TRUE; + + ptr = fb_request_field(fb, header, strlen(*text) + 2); + if (ptr == NULL) + return FALSE; + + ptr[0] = '"'; + strcpy(ptr + 1, *text); + + return TRUE; +} + +static gboolean encode_content_id(struct file_buffer *fb, + enum mms_header header, void *user) +{ + char *ptr; + char **text = user; unsigned int len; if (!*text) @@ -2067,7 +2084,7 @@ static gboolean mms_encode_send_req_part_header(struct mms_attachment *part, unsigned int ct_len; unsigned int cs_len; const char *ct_str; - const char *uninitialized_var(cs_str); + char *name = NULL; unsigned int ctp_len; unsigned int cid_len; unsigned int cloc_len; @@ -2099,7 +2116,7 @@ static gboolean mms_encode_send_req_part_header(struct mms_attachment *part, const char *key = parsed[i]; if (g_ascii_strcasecmp("charset", key) == 0) { - cs_str = parsed[i+1]; + const char *cs_str = parsed[i+1]; len += 1; @@ -2111,6 +2128,10 @@ static gboolean mms_encode_send_req_part_header(struct mms_attachment *part, goto done; len += cs_len; + + } else if (g_ascii_strcasecmp("name", key) == 0) { + name = parsed[i+1]; + len += 2 + strlen(name) + 1; } } @@ -2179,9 +2200,16 @@ static gboolean mms_encode_send_req_part_header(struct mms_attachment *part, memcpy(ptr, &cs_val, cs_len); } + /* Encode "name" param */ + if (name) { + if (encode_quoted_string(fb, WSP_PARAMETER_TYPE_NAME_DEFUNCT, + &name) == FALSE) + goto done; + } + /* Encode content-id */ if (part->content_id != NULL) { - if (encode_quoted_string(fb, MMS_PART_HEADER_CONTENT_ID, + if (encode_content_id(fb, MMS_PART_HEADER_CONTENT_ID, &part->content_id) == FALSE) goto done; } diff --git a/mms-lib/test/send/test_send.c b/mms-lib/test/send/test_send.c index 07bf486..0086246 100644 --- a/mms-lib/test/send/test_send.c +++ b/mms-lib/test/send/test_send.c @@ -80,9 +80,9 @@ typedef struct test { } Test; static const MMSAttachmentInfo test_files_accept [] = { - { "smil", NULL, NULL }, - { "0001.jpg", "image/jpeg", "image" }, - { "test.txt", "text/plain;charset=utf-8", "text" } + { "smil", "application/smil;charset=us-ascii", NULL }, + { "0001.jpg", "image/jpeg;name=0001.jpg", "image" }, + { "test.txt", "text/plain;charset=utf-8;name=wrong.name", "text" } }; static const MMSAttachmentInfo test_files_accept_no_ext [] = {