libetpan - fdik
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

773 lines
18 KiB

/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - DINH Viet Hoa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the libEtPan! project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* $Id: mailmime_types.c,v 1.21 2011/01/06 00:09:52 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailmime_types.h"
#include "mmapstring.h"
#include <string.h>
#include <stdlib.h>
void mailmime_attribute_free(char * attribute)
{
mailmime_token_free(attribute);
}
struct mailmime_composite_type *
mailmime_composite_type_new(int ct_type, char * ct_token)
{
struct mailmime_composite_type * ct;
ct = malloc(sizeof(* ct));
if (ct == NULL)
return NULL;
ct->ct_type = ct_type;
ct->ct_token = ct_token;
return ct;
}
void mailmime_composite_type_free(struct mailmime_composite_type * ct)
{
if (ct->ct_token != NULL)
mailmime_extension_token_free(ct->ct_token);
free(ct);
}
struct mailmime_content *
mailmime_content_new(struct mailmime_type * ct_type,
char * ct_subtype,
clist * ct_parameters)
{
struct mailmime_content * content;
content = malloc(sizeof(* content));
if (content == NULL)
return NULL;
content->ct_type = ct_type;
content->ct_subtype = ct_subtype;
content->ct_parameters = ct_parameters;
return content;
}
void mailmime_content_free(struct mailmime_content * content)
{
mailmime_type_free(content->ct_type);
mailmime_subtype_free(content->ct_subtype);
if (content->ct_parameters != NULL) {
clist_foreach(content->ct_parameters,
(clist_func) mailmime_parameter_free, NULL);
clist_free(content->ct_parameters);
}
free(content);
}
void mailmime_description_free(char * description)
{
free(description);
}
void mailmime_location_free(char * location)
{
free(location);
}
struct mailmime_discrete_type *
mailmime_discrete_type_new(int dt_type, char * dt_extension)
{
struct mailmime_discrete_type * discrete_type;
discrete_type = malloc(sizeof(* discrete_type));
if (discrete_type == NULL)
return NULL;
discrete_type->dt_type = dt_type;
discrete_type->dt_extension = dt_extension;
return discrete_type;
}
void mailmime_discrete_type_free(struct mailmime_discrete_type * discrete_type)
{
if (discrete_type->dt_extension != NULL)
mailmime_extension_token_free(discrete_type->dt_extension);
free(discrete_type);
}
void mailmime_encoding_free(struct mailmime_mechanism * encoding)
{
mailmime_mechanism_free(encoding);
}
void mailmime_extension_token_free(char * extension)
{
mailmime_token_free(extension);
}
void mailmime_id_free(char * id)
{
mailimf_msg_id_free(id);
}
struct mailmime_mechanism * mailmime_mechanism_new(int enc_type, char * enc_token)
{
struct mailmime_mechanism * mechanism;
mechanism = malloc(sizeof(* mechanism));
if (mechanism == NULL)
return NULL;
mechanism->enc_type = enc_type;
mechanism->enc_token = enc_token;
return mechanism;
}
void mailmime_mechanism_free(struct mailmime_mechanism * mechanism)
{
if (mechanism->enc_token != NULL)
mailmime_token_free(mechanism->enc_token);
free(mechanism);
}
struct mailmime_parameter *
mailmime_parameter_new(char * pa_name, char * pa_value)
{
struct mailmime_parameter * parameter;
parameter = malloc(sizeof(* parameter));
if (parameter == NULL)
return NULL;
parameter->pa_name = pa_name;
parameter->pa_value = pa_value;
return parameter;
}
void mailmime_parameter_free(struct mailmime_parameter * parameter)
{
mailmime_attribute_free(parameter->pa_name);
mailmime_value_free(parameter->pa_value);
free(parameter);
}
void mailmime_subtype_free(char * subtype)
{
mailmime_extension_token_free(subtype);
}
void mailmime_token_free(char * token)
{
free(token);
}
struct mailmime_type *
mailmime_type_new(int tp_type,
struct mailmime_discrete_type * tp_discrete_type,
struct mailmime_composite_type * tp_composite_type)
{
struct mailmime_type * mime_type;
mime_type = malloc(sizeof(* mime_type));
if (mime_type == NULL)
return NULL;
mime_type->tp_type = tp_type;
switch (tp_type) {
case MAILMIME_TYPE_DISCRETE_TYPE:
mime_type->tp_data.tp_discrete_type = tp_discrete_type;
break;
case MAILMIME_TYPE_COMPOSITE_TYPE:
mime_type->tp_data.tp_composite_type = tp_composite_type;
break;
}
return mime_type;
}
void mailmime_type_free(struct mailmime_type * type)
{
switch (type->tp_type) {
case MAILMIME_TYPE_DISCRETE_TYPE:
mailmime_discrete_type_free(type->tp_data.tp_discrete_type);
break;
case MAILMIME_TYPE_COMPOSITE_TYPE:
mailmime_composite_type_free(type->tp_data.tp_composite_type);
break;
}
free(type);
}
void mailmime_value_free(char * value)
{
free(value);
}
/*
void mailmime_x_token_free(gchar * x_token)
{
g_free(x_token);
}
*/
struct mailmime_field *
mailmime_field_new(int fld_type,
struct mailmime_content * fld_content,
struct mailmime_mechanism * fld_encoding,
char * fld_id,
char * fld_description,
uint32_t fld_version,
struct mailmime_disposition * fld_disposition,
struct mailmime_language * fld_language,
char * fld_location)
{
struct mailmime_field * field;
field = malloc(sizeof(* field));
if (field == NULL)
return NULL;
field->fld_type = fld_type;
switch (fld_type) {
case MAILMIME_FIELD_TYPE:
field->fld_data.fld_content = fld_content;
break;
case MAILMIME_FIELD_TRANSFER_ENCODING:
field->fld_data.fld_encoding = fld_encoding;
break;
case MAILMIME_FIELD_ID:
field->fld_data.fld_id = fld_id;
break;
case MAILMIME_FIELD_DESCRIPTION:
field->fld_data.fld_description = fld_description;
break;
case MAILMIME_FIELD_VERSION:
field->fld_data.fld_version = fld_version;
break;
case MAILMIME_FIELD_DISPOSITION:
field->fld_data.fld_disposition = fld_disposition;
break;
case MAILMIME_FIELD_LANGUAGE:
field->fld_data.fld_language = fld_language;
break;
case MAILMIME_FIELD_LOCATION:
field->fld_data.fld_location = fld_location;
break;
}
return field;
}
void mailmime_field_free(struct mailmime_field * field)
{
switch (field->fld_type) {
case MAILMIME_FIELD_TYPE:
if (field->fld_data.fld_content != NULL)
mailmime_content_free(field->fld_data.fld_content);
break;
case MAILMIME_FIELD_TRANSFER_ENCODING:
if (field->fld_data.fld_encoding != NULL)
mailmime_encoding_free(field->fld_data.fld_encoding);
break;
case MAILMIME_FIELD_ID:
if (field->fld_data.fld_id != NULL)
mailmime_id_free(field->fld_data.fld_id);
break;
case MAILMIME_FIELD_DESCRIPTION:
if (field->fld_data.fld_description != NULL)
mailmime_description_free(field->fld_data.fld_description);
break;
case MAILMIME_FIELD_DISPOSITION:
if (field->fld_data.fld_disposition != NULL)
mailmime_disposition_free(field->fld_data.fld_disposition);
break;
case MAILMIME_FIELD_LANGUAGE:
if (field->fld_data.fld_language != NULL)
mailmime_language_free(field->fld_data.fld_language);
break;
case MAILMIME_FIELD_LOCATION:
if (field->fld_data.fld_location != NULL)
mailmime_location_free(field->fld_data.fld_location);
break;
}
free(field);
}
struct mailmime_fields * mailmime_fields_new(clist * fld_list)
{
struct mailmime_fields * fields;
fields = malloc(sizeof(* fields));
if (fields == NULL)
return NULL;
fields->fld_list = fld_list;
return fields;
}
void mailmime_fields_free(struct mailmime_fields * fields)
{
clist_foreach(fields->fld_list, (clist_func) mailmime_field_free, NULL);
clist_free(fields->fld_list);
free(fields);
}
/*
struct mailmime_body_part *
mailmime_body_part_new(gchar * text, guint32 size)
{
struct mailmime_body_part * body_part;
body_part = g_new(struct mailmime_body_part, 1);
if (body_part == NULL)
return NULL;
body_part->text = text;
body_part->size = size;
return body_part;
}
void mailmime_body_part_free(struct mailmime_body_part * body_part)
{
g_free(body_part);
}
*/
struct mailmime_multipart_body *
mailmime_multipart_body_new(clist * bd_list)
{
struct mailmime_multipart_body * mp_body;
mp_body = malloc(sizeof(* mp_body));
if (mp_body == NULL)
return NULL;
mp_body->bd_list = bd_list;
return mp_body;
}
void mailmime_multipart_body_free(struct mailmime_multipart_body * mp_body)
{
clist_foreach(mp_body->bd_list, (clist_func) mailimf_body_free, NULL);
clist_free(mp_body->bd_list);
free(mp_body);
}
struct mailmime * mailmime_new(int mm_type,
const char * mm_mime_start, size_t mm_length,
struct mailmime_fields * mm_mime_fields,
struct mailmime_content * mm_content_type,
struct mailmime_data * mm_body,
struct mailmime_data * mm_preamble,
struct mailmime_data * mm_epilogue,
clist * mm_mp_list,
struct mailimf_fields * mm_fields,
struct mailmime * mm_msg_mime)
{
struct mailmime * mime;
clistiter * cur;
mime = malloc(sizeof(* mime));
if (mime == NULL)
return NULL;
mime->mm_parent = NULL;
mime->mm_parent_type = MAILMIME_NONE;
mime->mm_multipart_pos = NULL;
mime->mm_type = mm_type;
mime->mm_mime_start = mm_mime_start;
mime->mm_length = mm_length;
mime->mm_mime_fields = mm_mime_fields;
mime->mm_content_type = mm_content_type;
mime->mm_imf_fields = NULL;
mime->mm_body = mm_body;
switch (mm_type) {
case MAILMIME_SINGLE:
mime->mm_data.mm_single = mm_body;
break;
case MAILMIME_MULTIPLE:
mime->mm_data.mm_multipart.mm_preamble = mm_preamble;
mime->mm_data.mm_multipart.mm_epilogue = mm_epilogue;
mime->mm_data.mm_multipart.mm_mp_list = mm_mp_list;
for(cur = clist_begin(mm_mp_list) ; cur != NULL ;
cur = clist_next(cur)) {
struct mailmime * submime;
submime = clist_content(cur);
submime->mm_parent = mime;
submime->mm_parent_type = MAILMIME_MULTIPLE;
submime->mm_multipart_pos = cur;
}
break;
case MAILMIME_MESSAGE:
mime->mm_data.mm_message.mm_fields = mm_fields;
mime->mm_data.mm_message.mm_msg_mime = mm_msg_mime;
if (mm_msg_mime != NULL) {
mm_msg_mime->mm_parent = mime;
mm_msg_mime->mm_parent_type = MAILMIME_MESSAGE;
}
break;
}
return mime;
}
void mailmime_free(struct mailmime * mime)
{
switch (mime->mm_type) {
case MAILMIME_SINGLE:
if ((mime->mm_body == NULL) && (mime->mm_data.mm_single != NULL))
mailmime_data_free(mime->mm_data.mm_single);
/* do nothing */
break;
case MAILMIME_MULTIPLE:
if (mime->mm_data.mm_multipart.mm_preamble != NULL)
mailmime_data_free(mime->mm_data.mm_multipart.mm_preamble);
if (mime->mm_data.mm_multipart.mm_epilogue != NULL)
mailmime_data_free(mime->mm_data.mm_multipart.mm_epilogue);
clist_foreach(mime->mm_data.mm_multipart.mm_mp_list,
(clist_func) mailmime_free, NULL);
clist_free(mime->mm_data.mm_multipart.mm_mp_list);
break;
case MAILMIME_MESSAGE:
if (mime->mm_data.mm_message.mm_fields != NULL)
mailimf_fields_free(mime->mm_data.mm_message.mm_fields);
if (mime->mm_data.mm_message.mm_msg_mime != NULL)
mailmime_free(mime->mm_data.mm_message.mm_msg_mime);
break;
}
if (mime->mm_body != NULL)
mailmime_data_free(mime->mm_body);
if (mime->mm_mime_fields != NULL)
mailmime_fields_free(mime->mm_mime_fields);
if (mime->mm_imf_fields != NULL)
mailimf_fields_free(mime->mm_imf_fields);
if (mime->mm_content_type != NULL)
mailmime_content_free(mime->mm_content_type);
free(mime);
}
struct mailmime_encoded_word *
mailmime_encoded_word_new(char * wd_charset, char * wd_text)
{
struct mailmime_encoded_word * ew;
ew = malloc(sizeof(* ew));
if (ew == NULL)
return NULL;
ew->wd_charset = wd_charset;
ew->wd_text = wd_text;
return ew;
}
void mailmime_charset_free(char * charset)
{
free(charset);
}
void mailmime_encoded_text_free(char * text)
{
free(text);
}
void mailmime_encoded_word_free(struct mailmime_encoded_word * ew)
{
mailmime_charset_free(ew->wd_charset);
mailmime_encoded_text_free(ew->wd_text);
free(ew);
}
/* mailmime_disposition */
struct mailmime_disposition *
mailmime_disposition_new(struct mailmime_disposition_type * dsp_type,
clist * dsp_parms)
{
struct mailmime_disposition * dsp;
dsp = malloc(sizeof(* dsp));
if (dsp == NULL)
return NULL;
dsp->dsp_type = dsp_type;
dsp->dsp_parms = dsp_parms;
return dsp;
}
void mailmime_disposition_free(struct mailmime_disposition * dsp)
{
mailmime_disposition_type_free(dsp->dsp_type);
clist_foreach(dsp->dsp_parms,
(clist_func) mailmime_disposition_parm_free, NULL);
clist_free(dsp->dsp_parms);
free(dsp);
}
struct mailmime_disposition_type *
mailmime_disposition_type_new(int dsp_type, char * dsp_extension)
{
struct mailmime_disposition_type * m_dsp_type;
m_dsp_type = malloc(sizeof(* m_dsp_type));
if (m_dsp_type == NULL)
return NULL;
m_dsp_type->dsp_type = dsp_type;
m_dsp_type->dsp_extension = dsp_extension;
return m_dsp_type;
}
void mailmime_disposition_type_free(struct mailmime_disposition_type * dsp_type)
{
if (dsp_type->dsp_extension != NULL)
free(dsp_type->dsp_extension);
free(dsp_type);
}
struct mailmime_disposition_parm *
mailmime_disposition_parm_new(int pa_type,
char * pa_filename,
char * pa_creation_date,
char * pa_modification_date,
char * pa_read_date,
size_t pa_size,
struct mailmime_parameter * pa_parameter)
{
struct mailmime_disposition_parm * dsp_parm;
dsp_parm = malloc(sizeof(* dsp_parm));
if (dsp_parm == NULL)
return NULL;
dsp_parm->pa_type = pa_type;
switch (pa_type) {
case MAILMIME_DISPOSITION_PARM_FILENAME:
dsp_parm->pa_data.pa_filename = pa_filename;
break;
case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
dsp_parm->pa_data.pa_creation_date = pa_creation_date;
break;
case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
dsp_parm->pa_data.pa_modification_date = pa_modification_date;
break;
case MAILMIME_DISPOSITION_PARM_READ_DATE:
dsp_parm->pa_data.pa_read_date = pa_read_date;
break;
case MAILMIME_DISPOSITION_PARM_SIZE:
dsp_parm->pa_data.pa_size = pa_size;
break;
case MAILMIME_DISPOSITION_PARM_PARAMETER:
dsp_parm->pa_data.pa_parameter = pa_parameter;
break;
}
return dsp_parm;
}
void mailmime_disposition_parm_free(struct mailmime_disposition_parm *
dsp_parm)
{
switch (dsp_parm->pa_type) {
case MAILMIME_DISPOSITION_PARM_FILENAME:
mailmime_filename_parm_free(dsp_parm->pa_data.pa_filename);
break;
case MAILMIME_DISPOSITION_PARM_CREATION_DATE:
mailmime_creation_date_parm_free(dsp_parm->pa_data.pa_creation_date);
break;
case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE:
mailmime_modification_date_parm_free(dsp_parm->pa_data.pa_modification_date);
break;
case MAILMIME_DISPOSITION_PARM_READ_DATE:
mailmime_read_date_parm_free(dsp_parm->pa_data.pa_read_date);
break;
case MAILMIME_DISPOSITION_PARM_PARAMETER:
mailmime_parameter_free(dsp_parm->pa_data.pa_parameter);
break;
}
free(dsp_parm);
}
void mailmime_filename_parm_free(char * filename)
{
mailmime_value_free(filename);
}
void mailmime_creation_date_parm_free(char * date)
{
mailmime_quoted_date_time_free(date);
}
void mailmime_modification_date_parm_free(char * date)
{
mailmime_quoted_date_time_free(date);
}
void mailmime_read_date_parm_free(char * date)
{
mailmime_quoted_date_time_free(date);
}
void mailmime_quoted_date_time_free(char * date)
{
mailimf_quoted_string_free(date);
}
struct mailmime_section * mailmime_section_new(clist * sec_list)
{
struct mailmime_section * section;
section = malloc(sizeof(* section));
if (section == NULL)
return NULL;
section->sec_list = sec_list;
return section;
}
void mailmime_section_free(struct mailmime_section * section)
{
clist_foreach(section->sec_list, (clist_func) free, NULL);
clist_free(section->sec_list);
free(section);
}
struct mailmime_language * mailmime_language_new(clist * lg_list)
{
struct mailmime_language * lang;
lang = malloc(sizeof(* lang));
if (lang == NULL)
return NULL;
lang->lg_list = lg_list;
return lang;
}
void mailmime_language_free(struct mailmime_language * lang)
{
clist_foreach(lang->lg_list, (clist_func) mailimf_atom_free, NULL);
clist_free(lang->lg_list);
free(lang);
}
void mailmime_decoded_part_free(char * part)
{
mmap_string_unref(part);
}
struct mailmime_data * mailmime_data_new(int dt_type, int dt_encoding,
int dt_encoded, const char * dt_data, size_t dt_length, char * dt_filename)
{
struct mailmime_data * mime_data;
mime_data = malloc(sizeof(* mime_data));
if (mime_data == NULL)
return NULL;
mime_data->dt_type = dt_type;
mime_data->dt_encoding = dt_encoding;
mime_data->dt_encoded = dt_encoded;
switch (dt_type) {
case MAILMIME_DATA_TEXT:
mime_data->dt_data.dt_text.dt_data = dt_data;
mime_data->dt_data.dt_text.dt_length = dt_length;
break;
case MAILMIME_DATA_FILE:
mime_data->dt_data.dt_filename = dt_filename;
break;
}
return mime_data;
}
void mailmime_data_free(struct mailmime_data * mime_data)
{
switch (mime_data->dt_type) {
case MAILMIME_DATA_FILE:
free(mime_data->dt_data.dt_filename);
break;
}
free(mime_data);
}