From e3b89230f065c48c84b48c88edb6eb088374c487 Mon Sep 17 00:00:00 2001 From: zautrix Date: Sat, 03 Jul 2004 16:33:12 +0000 Subject: Initial revision --- (limited to 'kmicromail/libetpan/mime/mailmime_disposition.c') diff --git a/kmicromail/libetpan/mime/mailmime_disposition.c b/kmicromail/libetpan/mime/mailmime_disposition.c new file mode 100644 index 0000000..9d8dfec --- a/dev/null +++ b/kmicromail/libetpan/mime/mailmime_disposition.c @@ -0,0 +1,595 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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$ + */ + +#include "mailmime_disposition.h" +#include "mailmime.h" + +#include +#include + +static int +mailmime_disposition_parm_parse(const char * message, size_t length, + size_t * index, + struct mailmime_disposition_parm ** + result); + +static int +mailmime_creation_date_parm_parse(const char * message, size_t length, + size_t * index, char ** result); + +static int +mailmime_filename_parm_parse(const char * message, size_t length, + size_t * index, char ** result); + +static int +mailmime_modification_date_parm_parse(const char * message, size_t length, + size_t * index, char ** result); + +static int +mailmime_read_date_parm_parse(const char * message, size_t length, + size_t * index, char ** result); + +static int +mailmime_size_parm_parse(const char * message, size_t length, + size_t * index, size_t * result); + +static int +mailmime_quoted_date_time_parse(const char * message, size_t length, + size_t * index, char ** result); + +/* + disposition := "Content-Disposition" ":" + disposition-type + *(";" disposition-parm) + +*/ + + +int mailmime_disposition_parse(const char * message, size_t length, + size_t * index, + struct mailmime_disposition ** result) +{ + size_t final_token; + size_t cur_token; + struct mailmime_disposition_type * dsp_type; + clist * list; + struct mailmime_disposition * dsp; + int r; + int res; + + cur_token = * index; + + r = mailmime_disposition_type_parse(message, length, &cur_token, + &dsp_type); + if (r != MAILIMF_NO_ERROR) { + res = r; + goto err; + } + + list = clist_new(); + if (list == NULL) { + res = MAILIMF_ERROR_MEMORY; + goto free_type; + } + + while (1) { + struct mailmime_disposition_parm * param; + + final_token = cur_token; + r = mailimf_unstrict_char_parse(message, length, &cur_token, ';'); + if (r == MAILIMF_NO_ERROR) { + /* do nothing */ + } + else if (r == MAILIMF_ERROR_PARSE) { + break; + } + else { + res = r; + goto free_list; + } + + r = mailmime_disposition_parm_parse(message, length, &cur_token, ¶m); + if (r == MAILIMF_NO_ERROR) { + /* do nothing */ + } + else if (r == MAILIMF_ERROR_PARSE) { + cur_token = final_token; + break; + } + else { + res = r; + goto free_list; + } + + r = clist_append(list, param); + if (r < 0) { + res = MAILIMF_ERROR_MEMORY; + goto free_list; + } + } + + dsp = mailmime_disposition_new(dsp_type, list); + if (dsp == NULL) { + res = MAILIMF_ERROR_MEMORY; + goto free_list; + } + + * result = dsp; + * index = cur_token; + + return MAILIMF_NO_ERROR; + + free_list: + clist_foreach(list, (clist_func) mailmime_disposition_parm_free, NULL); + clist_free(list); + free_type: + mailmime_disposition_type_free(dsp_type); + err: + return res; +} + +/* + disposition-type := "inline" + / "attachment" + / extension-token + ; values are not case-sensitive + +*/ + + + +int +mailmime_disposition_type_parse(const char * message, size_t length, + size_t * index, + struct mailmime_disposition_type ** result) +{ + size_t cur_token; + int type; + char * extension; + struct mailmime_disposition_type * dsp_type; + int r; + int res; + + cur_token = * index; + + r = mailimf_cfws_parse(message, length, &cur_token); + if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) { + res = r; + goto err; + } + + type = MAILMIME_DISPOSITION_TYPE_ERROR; /* XXX - removes a gcc warning */ + + extension = NULL; + r = mailimf_token_case_insensitive_parse(message, length, + &cur_token, "inline"); + if (r == MAILIMF_NO_ERROR) + type = MAILMIME_DISPOSITION_TYPE_INLINE; + + if (r == MAILIMF_ERROR_PARSE) { + r = mailimf_token_case_insensitive_parse(message, length, + &cur_token, "attachment"); + if (r == MAILIMF_NO_ERROR) + type = MAILMIME_DISPOSITION_TYPE_ATTACHMENT; + } + + if (r == MAILIMF_ERROR_PARSE) { + r = mailmime_extension_token_parse(message, length, &cur_token, + &extension); + if (r == MAILIMF_NO_ERROR) + type = MAILMIME_DISPOSITION_TYPE_EXTENSION; + } + + if (r != MAILIMF_NO_ERROR) { + res = r; + goto err; + } + + dsp_type = mailmime_disposition_type_new(type, extension); + if (dsp_type == NULL) { + res = MAILIMF_ERROR_MEMORY; + goto free; + } + + * result = dsp_type; + * index = cur_token; + + return MAILIMF_NO_ERROR; + + free: + if (extension != NULL) + free(extension); + err: + return res; +} + +/* + disposition-parm := filename-parm + / creation-date-parm + / modification-date-parm + / read-date-parm + / size-parm + / parameter +*/ + + +int mailmime_disposition_guess_type(const char * message, size_t length, + size_t index) +{ + if (index >= length) + return MAILMIME_DISPOSITION_PARM_PARAMETER; + + switch ((char) toupper((unsigned char) message[index])) { + case 'F': + return MAILMIME_DISPOSITION_PARM_FILENAME; + case 'C': + return MAILMIME_DISPOSITION_PARM_CREATION_DATE; + case 'M': + return MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE; + case 'R': + return MAILMIME_DISPOSITION_PARM_READ_DATE; + case 'S': + return MAILMIME_DISPOSITION_PARM_SIZE; + default: + return MAILMIME_DISPOSITION_PARM_PARAMETER; + } +} + +static int +mailmime_disposition_parm_parse(const char * message, size_t length, + size_t * index, + struct mailmime_disposition_parm ** + result) +{ + char * filename; + char * creation_date; + char * modification_date; + char * read_date; + size_t size; + struct mailmime_parameter * parameter; + size_t cur_token; + struct mailmime_disposition_parm * dsp_parm; + int type; + int guessed_type; + int r; + int res; + + cur_token = * index; + + filename = NULL; + creation_date = NULL; + modification_date = NULL; + read_date = NULL; + size = 0; + parameter = NULL; + + r = mailimf_cfws_parse(message, length, &cur_token); + if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) { + res = r; + goto err; + } + + guessed_type = mailmime_disposition_guess_type(message, length, cur_token); + + type = MAILMIME_DISPOSITION_PARM_PARAMETER; + + switch (guessed_type) { + case MAILMIME_DISPOSITION_PARM_FILENAME: + r = mailmime_filename_parm_parse(message, length, &cur_token, + &filename); + if (r == MAILIMF_NO_ERROR) + type = guessed_type; + else if (r == MAILIMF_ERROR_PARSE) { + /* do nothing */ + } + else { + res = r; + goto err; + } + break; + + case MAILMIME_DISPOSITION_PARM_CREATION_DATE: + r = mailmime_creation_date_parm_parse(message, length, &cur_token, + &creation_date); + if (r == MAILIMF_NO_ERROR) + type = guessed_type; + else if (r == MAILIMF_ERROR_PARSE) { + /* do nothing */ + } + else { + res = r; + goto err; + } + break; + + case MAILMIME_DISPOSITION_PARM_MODIFICATION_DATE: + r = mailmime_modification_date_parm_parse(message, length, &cur_token, + &modification_date); + if (r == MAILIMF_NO_ERROR) + type = guessed_type; + else if (r == MAILIMF_ERROR_PARSE) { + /* do nothing */ + } + else { + res = r; + goto err; + } + break; + + case MAILMIME_DISPOSITION_PARM_READ_DATE: + r = mailmime_read_date_parm_parse(message, length, &cur_token, + &read_date); + if (r == MAILIMF_NO_ERROR) + type = guessed_type; + else if (r == MAILIMF_ERROR_PARSE) { + /* do nothing */ + } + else { + res = r; + goto err; + } + break; + + case MAILMIME_DISPOSITION_PARM_SIZE: + r = mailmime_size_parm_parse(message, length, &cur_token, + &size); + if (r == MAILIMF_NO_ERROR) + type = guessed_type; + else if (r == MAILIMF_ERROR_PARSE) { + /* do nothing */ + } + else { + res = r; + goto err; + } + break; + } + + if (type == MAILMIME_DISPOSITION_PARM_PARAMETER) { + r = mailmime_parameter_parse(message, length, &cur_token, + ¶meter); + if (r != MAILIMF_NO_ERROR) { + type = guessed_type; + res = r; + goto err; + } + } + + dsp_parm = mailmime_disposition_parm_new(type, filename, creation_date, + modification_date, read_date, + size, parameter); + + if (dsp_parm == NULL) { + res = MAILIMF_ERROR_MEMORY; + goto free; + } + + * result = dsp_parm; + * index = cur_token; + + return MAILIMF_NO_ERROR; + + free: + if (filename != NULL) + mailmime_filename_parm_free(dsp_parm->pa_data.pa_filename); + if (creation_date != NULL) + mailmime_creation_date_parm_free(dsp_parm->pa_data.pa_creation_date); + if (modification_date != NULL) + mailmime_modification_date_parm_free(dsp_parm->pa_data.pa_modification_date); + if (read_date != NULL) + mailmime_read_date_parm_free(dsp_parm->pa_data.pa_read_date); + if (parameter != NULL) + mailmime_parameter_free(dsp_parm->pa_data.pa_parameter); + err: + return res; +} + +/* + filename-parm := "filename" "=" value +*/ + +static int +mailmime_filename_parm_parse(const char * message, size_t length, + size_t * index, char ** result) +{ + char * value; + int r; + size_t cur_token; + + cur_token = * index; + + r = mailimf_token_case_insensitive_parse(message, length, + &cur_token, "filename"); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailimf_unstrict_char_parse(message, length, &cur_token, '='); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailmime_value_parse(message, length, &cur_token, &value); + if (r != MAILIMF_NO_ERROR) + return r; + + * index = cur_token; + * result = value; + + return MAILIMF_NO_ERROR; +} + +/* + creation-date-parm := "creation-date" "=" quoted-date-time +*/ + +static int +mailmime_creation_date_parm_parse(const char * message, size_t length, + size_t * index, char ** result) +{ + char * value; + int r; + size_t cur_token; + + cur_token = * index; + + r = mailimf_token_case_insensitive_parse(message, length, + &cur_token, "creation-date"); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailimf_unstrict_char_parse(message, length, &cur_token, '='); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailmime_quoted_date_time_parse(message, length, &cur_token, &value); + if (r != MAILIMF_NO_ERROR) + return r; + + * index = cur_token; + * result = value; + + return MAILIMF_NO_ERROR; +} + +/* + modification-date-parm := "modification-date" "=" quoted-date-time +*/ + +static int +mailmime_modification_date_parm_parse(const char * message, size_t length, + size_t * index, char ** result) +{ + char * value; + size_t cur_token; + int r; + + cur_token = * index; + + r = mailimf_token_case_insensitive_parse(message, length, + &cur_token, "modification-date"); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailimf_unstrict_char_parse(message, length, &cur_token, '='); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailmime_quoted_date_time_parse(message, length, &cur_token, &value); + if (r != MAILIMF_NO_ERROR) + return r; + + * index = cur_token; + * result = value; + + return MAILIMF_NO_ERROR; +} + +/* + read-date-parm := "read-date" "=" quoted-date-time +*/ + +static int +mailmime_read_date_parm_parse(const char * message, size_t length, + size_t * index, char ** result) +{ + char * value; + size_t cur_token; + int r; + + cur_token = * index; + + r = mailimf_token_case_insensitive_parse(message, length, + &cur_token, "read-date"); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailimf_unstrict_char_parse(message, length, &cur_token, '='); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailmime_quoted_date_time_parse(message, length, &cur_token, &value); + if (r != MAILIMF_NO_ERROR) + return r; + + * index = cur_token; + * result = value; + + return MAILIMF_NO_ERROR; +} + +/* + size-parm := "size" "=" 1*DIGIT +*/ + +static int +mailmime_size_parm_parse(const char * message, size_t length, + size_t * index, size_t * result) +{ + uint32_t value; + size_t cur_token; + int r; + + cur_token = * index; + + r = mailimf_token_case_insensitive_parse(message, length, + &cur_token, "size"); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailimf_unstrict_char_parse(message, length, &cur_token, '='); + if (r != MAILIMF_NO_ERROR) + return r; + + r = mailimf_number_parse(message, length, &cur_token, &value); + if (r != MAILIMF_NO_ERROR) + return r; + + * index = cur_token; + * result = value; + + return MAILIMF_NO_ERROR; +} + +/* + quoted-date-time := quoted-string + ; contents MUST be an RFC 822 `date-time' + ; numeric timezones (+HHMM or -HHMM) MUST be used +*/ + +static int +mailmime_quoted_date_time_parse(const char * message, size_t length, + size_t * index, char ** result) +{ + return mailimf_quoted_string_parse(message, length, index, result); +} -- cgit v0.9.0.2