コード例 #1
0
ファイル: mailmime.c プロジェクト: WARA45542/libetpan
LIBETPAN_EXPORT
int
mailmime_field_parse(struct mailimf_optional_field * field,
		     struct mailmime_field ** result)
{
  char * name;
  char * value;
  int guessed_type;
  size_t cur_token;
  struct mailmime_content * content;
  struct mailmime_mechanism * encoding;
  char * id;
  char * description;
  uint32_t version;
  struct mailmime_field * mime_field;
  struct mailmime_language * language;
  struct mailmime_disposition * disposition;
  char * location;
  int res;
  int r;

  name = field->fld_name;
  value = field->fld_value;
  cur_token = 0;

  content = NULL;
  encoding = NULL;
  id = NULL;
  description = NULL;
  version = 0;
  disposition = NULL;
  language = NULL;
  location = NULL;

  guessed_type = guess_field_type(name);

  switch (guessed_type) {
  case MAILMIME_FIELD_TYPE:
    if (strcasecmp(name, "Content-Type") != 0)
      return MAILIMF_ERROR_PARSE;
    {
      size_t cur_token = 0;
      char * decoded_value;
      r = mailmime_encoded_phrase_parse("us-ascii",
          value, strlen(value),
          &cur_token, "utf-8", &decoded_value);
      if (r != MAILIMF_NO_ERROR) {
        cur_token = 0;
        r = mailmime_content_parse(value, strlen(value), &cur_token, &content);
      }
      else {
        cur_token = 0;
        r = mailmime_content_parse(decoded_value, strlen(decoded_value), &cur_token, &content);
        free(decoded_value);
      }
      if (r != MAILIMF_NO_ERROR)
        return r;
    }
    break;

  case MAILMIME_FIELD_TRANSFER_ENCODING:
    if (strcasecmp(name, "Content-Transfer-Encoding") != 0)
      return MAILIMF_ERROR_PARSE;
    r = mailmime_encoding_parse(value, strlen(value), &cur_token, &encoding);
    if (r != MAILIMF_NO_ERROR)
      return r;
    break;

  case MAILMIME_FIELD_ID:
    if (strcasecmp(name, "Content-ID") != 0)
      return MAILIMF_ERROR_PARSE;
    r = mailmime_id_parse(value, strlen(value), &cur_token, &id);
    if (r != MAILIMF_NO_ERROR)
      return r;
    break;

  case MAILMIME_FIELD_DESCRIPTION:
    if (strcasecmp(name, "Content-Description") != 0)
      return MAILIMF_ERROR_PARSE;
    r = mailmime_description_parse(value, strlen(value),
				   &cur_token, &description);
    if (r != MAILIMF_NO_ERROR)
      return r;
    break;

  case MAILMIME_FIELD_VERSION:
    if (strcasecmp(name, "MIME-Version") != 0)
      return MAILIMF_ERROR_PARSE;
    r = mailmime_version_parse(value, strlen(value), &cur_token, &version);
    if (r != MAILIMF_NO_ERROR)
      return r;
    break;

  case MAILMIME_FIELD_DISPOSITION:
    if (strcasecmp(name, "Content-Disposition") != 0)
      return MAILIMF_ERROR_PARSE;
    r = mailmime_disposition_parse(value, strlen(value),
				   &cur_token, &disposition);
    if (r != MAILIMF_NO_ERROR)
      return r;
    break;

  case MAILMIME_FIELD_LANGUAGE:
    if (strcasecmp(name, "Content-Language") != 0)
      return MAILIMF_ERROR_PARSE;
    r = mailmime_language_parse(value, strlen(value), &cur_token, &language);
    if (r != MAILIMF_NO_ERROR)
      return r;
    break;

  case MAILMIME_FIELD_LOCATION:
    if (strcasecmp(name, "Content-Location") != 0)
      return MAILIMF_ERROR_PARSE;
    r = mailmime_location_parse(value, strlen(value), &cur_token, &location);
    if (r != MAILIMF_NO_ERROR)
      return r;
    break;
      
  default:
    return MAILIMF_ERROR_PARSE;
  }

  mime_field = mailmime_field_new(guessed_type, content, encoding,
				  id, description, version, disposition,
				  language, location);
  if (mime_field == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }
  
  * result = mime_field;

  return MAILIMF_NO_ERROR;

 free:
  if (location != NULL)
    mailmime_location_free(location);
  if (language != NULL)
    mailmime_language_free(language);
  if (content != NULL)
    mailmime_content_free(content);
  if (encoding != NULL)
    mailmime_encoding_free(encoding);
  if (id != NULL)
    mailmime_id_free(id);
  if (description != NULL)
    mailmime_description_free(description);
  return res;
}
コード例 #2
0
ファイル: mailthread.c プロジェクト: mralexgray/etPanKit
static char * extract_subject(char * default_from,
    struct mailmessage_tree * tree,
    char * str)
{
  char * subj;
  char * cur;
  char * write_pos;
  size_t len;
  size_t begin;

  char * decoded;
  size_t cur_token;

  int do_repeat_5;
  int do_repeat_6;
  int r;

  /*
    (1) Convert any RFC 2047 encoded-words in the subject to
    UTF-8.
  */

  decoded = NULL;

  cur_token = 0;
  r = mailmime_encoded_phrase_parse(default_from, str, strlen(str),
				    &cur_token, "utf-8",
				    &decoded);

  if (r == MAILIMF_NO_ERROR) {
    subj = decoded;
  }
  else
    subj = strdup(str);

  len = strlen(subj);

  /*
    Convert all tabs and continuations to space.
    Convert all multiple spaces to a single space.
  */

  cur = subj;
  write_pos = subj;
  while (* cur != '\0') {
    int cont;

    switch (* cur) {
    case '\t':
    case '\r':
    case '\n':
      cont = TRUE;

      cur ++;
      while (* cur && cont) {
	switch (* cur) {
	case '\t':
	case '\r':
	case '\n':
	  cont = TRUE;
	  break;
	default:
	  cont = FALSE;
	  break;
	}
	cur ++;
      }
      
      * write_pos = ' ';
      write_pos ++;

      break;
      
    default:
      * write_pos = * cur;
      write_pos ++;

      cur ++;

      break;
    }
  }
  * write_pos = '\0';

  begin = 0;

  do {
    do_repeat_6 = FALSE;

    /*
      (2) Remove all trailing text of the subject that matches
      the subj-trailer ABNF, repeat until no more matches are
      possible.
    */

    while (len > 0) {
      int chg;

      chg = FALSE;

      /* subj-trailer    = "(fwd)" / WSP */
      if (subj[len - 1] == ' ') {
	subj[len - 1] = '\0';
	len --;
      }
      else {
	if (len < 5)
	  break;

	if (strncasecmp(subj + len - 5, "(fwd)", 5) != 0)
	  break;

	subj[len - 5] = '\0';
	len -= 5;
	tree->node_is_reply = TRUE;
      }
    }

    do {
      size_t saved_begin;

      do_repeat_5 = FALSE;

      /*
	(3) Remove all prefix text of the subject that matches the
	subj-leader ABNF.
      */
    
      if (skip_subj_leader(tree, subj, &begin, len))
	do_repeat_5 = TRUE;

      /*
	(4) If there is prefix text of the subject that matches the
	subj-blob ABNF, and removing that prefix leaves a non-empty
	subj-base, then remove the prefix text.
      */
    
      saved_begin = begin;
      if (skip_subj_blob(subj, &begin, len)) {
	if (begin == len) {
	  /* this will leave a empty subject base */
	  begin = saved_begin;
	}
	else
	  do_repeat_5 = TRUE;
      }

      /*
	(5) Repeat (3) and (4) until no matches remain.
	Note: it is possible to defer step (2) until step (6),
	but this requires checking for subj-trailer in step (4).
      */
    
    }
    while (do_repeat_5);

    /*
      (6) If the resulting text begins with the subj-fwd-hdr ABNF
      and ends with the subj-fwd-trl ABNF, remove the
      subj-fwd-hdr and subj-fwd-trl and repeat from step (2).
    */

    if (len >= 5) {
      size_t saved_begin;

      saved_begin = begin;
      if (strncasecmp(subj + begin, "[fwd:", 5) == 0) {
	begin += 5;
	
	if (subj[len - 1] != ']')
	  saved_begin = begin;
	else {
	  tree->node_is_reply = TRUE;

	  subj[len - 1] = '\0';
	  len --;
	  do_repeat_6 = TRUE;
	}
      }
    }

  }
  while (do_repeat_6);

  /*
    (7) The resulting text is the "base subject" used in
    threading.
  */

  /* convert to upper case */

  cur = subj + begin;
  write_pos = subj;

  while (* cur != '\0') {
    * write_pos = (char) toupper((unsigned char) * cur);
    cur ++;
    write_pos ++;
  }
  * write_pos = '\0';

  return subj;
}