Commit message: Fixed crash #274
CVE: CVE-2017-8825
CWE: CWE-476
Vulnerability description: A null dereference vulnerability has been found in the MIME handling component of LibEtPan before 1.8, as used in MailCore and MailCore 2. A crash can occur in low-level/imf/mailimf.c during a failed parse of a Cc header containing multiple e-mail addresses.

Project: libetpan
File: mailimf.c

static int guess_header_type(const char * message, size_t length, size_t indx)
{
  int state;
  int r;

  state = HEADER_START;
  
  while (1) {

    if (indx >= length)
      return MAILIMF_FIELD_NONE;

    switch(state) {
    case HEADER_START:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'B':
	return MAILIMF_FIELD_BCC;
      case 'C':
	state = HEADER_C;
	break;
      case 'D':
	return MAILIMF_FIELD_ORIG_DATE;
      case 'F':
	return MAILIMF_FIELD_FROM;
      case 'I':
	return MAILIMF_FIELD_IN_REPLY_TO;
      case 'K':
	return MAILIMF_FIELD_KEYWORDS;
      case 'M':
	return MAILIMF_FIELD_MESSAGE_ID;
      case 'R':
	state = HEADER_R;
	break;
      case 'T':
	return MAILIMF_FIELD_TO;
	break;
      case 'S':
	state = HEADER_S;
	break;
      default:
	return MAILIMF_FIELD_NONE;
      }
      break;
    case HEADER_C:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'O':
	return MAILIMF_FIELD_COMMENTS;
      case 'C':
	return MAILIMF_FIELD_CC;
      default:
	return MAILIMF_FIELD_NONE;
      }
      break;
    case HEADER_R:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'E':
	state = HEADER_RE;
	break;
      default:
	return MAILIMF_FIELD_NONE;
      }
      break;
    case HEADER_RE:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'F':
	return MAILIMF_FIELD_REFERENCES;
      case 'P':
	return MAILIMF_FIELD_REPLY_TO;
      case 'S':
        state = HEADER_RES;
        break;
      case 'T':
        return MAILIMF_FIELD_RETURN_PATH;
      default:
	return MAILIMF_FIELD_NONE;
      }
      break;
    case HEADER_S:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'E':
	return MAILIMF_FIELD_SENDER;
      case 'U':
	return MAILIMF_FIELD_SUBJECT;
      default:
	return MAILIMF_FIELD_NONE;
      }
      break;

    case HEADER_RES:
      r = mailimf_token_case_insensitive_parse(message,
          length, &indx, "ent-");
      if (r != MAILIMF_NO_ERROR)
        return MAILIMF_FIELD_NONE;
      
      if (indx >= length)
        return MAILIMF_FIELD_NONE;
      
      switch((char) toupper((unsigned char) message[indx])) {
      case 'D':
        return MAILIMF_FIELD_RESENT_DATE;
      case 'F':
        return MAILIMF_FIELD_RESENT_FROM;
      case 'S':
        return MAILIMF_FIELD_RESENT_SENDER;
      case 'T':
        return MAILIMF_FIELD_RESENT_TO;
      case 'C':
        return MAILIMF_FIELD_RESENT_CC;
      case 'B':
        return MAILIMF_FIELD_RESENT_BCC;
      case 'M':
        return MAILIMF_FIELD_RESENT_MSG_ID;
      default:
        return MAILIMF_FIELD_NONE;
      }
      break;
    }
    indx ++;
  }
}

Project: libetpan
File: mailimf.c

static int guess_month(const char * message, size_t length, size_t indx)
{
  int state;

  state = MONTH_START;

  while (1) {

    if (indx >= length)
      return -1;

    switch(state) {
    case MONTH_START:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'J': /* Jan Jun Jul */
	state = MONTH_J;
	break;
      case 'F': /* Feb */
	return 2;
      case 'M': /* Mar May */
	state = MONTH_M;
	break;
      case 'A': /* Apr Aug */
	state = MONTH_A;
	break;
      case 'S': /* Sep */
	return 9;
      case 'O': /* Oct */
	return 10;
      case 'N': /* Nov */
	return 11;
      case 'D': /* Dec */
	return 12;
      default:
	return -1;
      }
      break;
    case MONTH_J:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'A':
	return 1;
      case 'U':
	state = MONTH_JU;
	break;
      default:
	return -1;
      }
      break;
    case MONTH_JU:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'N':
	return 6;
      case 'L':
	return 7;
      default:
	return -1;
      }
      break;
    case MONTH_M:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'A':
	state = MONTH_MA;
	break;
      default:
	return -1;
      }
      break;
    case MONTH_MA:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'Y':
	return 5;
      case 'R':
	return 3;
      default:
	return -1;
      }
      break;
    case MONTH_A:
      switch((char) toupper((unsigned char) message[indx])) {
      case 'P':
	return 4;
      case 'U':
	return 8;
      default:
	return -1;
      }
      break;
    }

    indx ++;
  }
}

Project: libetpan
File: mailimf.c

static inline int is_atext(char ch)
{
  switch (ch) {
  case ' ':
  case '\t':
  case '\n':
  case '\r':
#if 0
  case '(':
  case ')':
#endif
  case '<':
  case '>':
#if 0
  case '@':
#endif
  case ',':
  case '"':
  case ':':
  case ';':
    return FALSE;
  default:
    return TRUE;
  }
}

Project: libetpan
File: mailimf.c

static inline int is_digit(char ch)
{
  return (ch >= '0') && (ch <= '9');
}

Project: libetpan
File: mailimf.c

static inline int is_dtext(char ch)
{
  unsigned char uch = (unsigned char) ch;

  if (is_no_ws_ctl(ch))
    return TRUE;

  if (uch < 33)
    return FALSE;

  if ((uch >= 91) && (uch <= 93))
    return FALSE;

  if (uch == 127)
    return FALSE;

  return TRUE;
}

Project: libetpan
File: mailimf.c

static inline int is_ftext(char ch)
{
  unsigned char uch = (unsigned char) ch;

  if (uch < 33)
    return FALSE;

  if (uch == 58)
    return FALSE;

  return TRUE;
}

Project: libetpan
File: mailimf.c

static inline int is_no_ws_ctl(char ch)
{
  if ((ch == 9) || (ch == 10) || (ch == 13))
    return FALSE;

  if (ch == 127)
     return TRUE;

  return (ch >= 1) && (ch <= 31);
}

Project: libetpan
File: mailimf.c

static inline int is_qtext(char ch)
{
  unsigned char uch = (unsigned char) ch;

  if (is_no_ws_ctl(ch))
    return TRUE;

  if (uch < 33)
    return FALSE;

  if (uch == 34)
    return FALSE;

  if (uch == 92)
    return FALSE;

  if (uch == 127)
    return FALSE;

  return TRUE;
}

Project: libetpan
File: mailimf.c

static int mailimf_addr_spec_msg_id_parse(const char * message, size_t length,
                                          size_t * indx,
                                          char ** result)
{
    size_t cur_token;
    char * addr_spec;
    int r;
    int res;
    size_t begin;
    size_t end;
    int final;
    size_t count;
    const char * src;
    char * dest;
    size_t i;
    
    cur_token = * indx;
    
    r = mailimf_cfws_parse(message, length, &cur_token);
    if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
        res = r;
        goto err;
    }
    
    end = cur_token;
    if (end >= length) {
        res = MAILIMF_ERROR_PARSE;
        goto err;
    }
    
    begin = cur_token;
    
    final = FALSE;
    while (1) {
        switch (message[end]) {
            case '>':
            case '\r':
            case '\n':
                final = TRUE;
                break;
        }
        
        if (final)
            break;
        
        end ++;
        if (end >= length)
            break;
    }
    
    if (end == begin) {
        res = MAILIMF_ERROR_PARSE;
        goto err;
    }
    
    addr_spec = malloc(end - cur_token + 1);
    if (addr_spec == NULL) {
        res = MAILIMF_ERROR_MEMORY;
        goto err;
    }
    
    count = end - cur_token;
    src = message + cur_token;
    dest = addr_spec;
    for(i = 0 ; i < count ; i ++) {
        if ((* src != ' ') && (* src != '\t')) {
            * dest = * src;
            dest ++;
        }
        src ++;
    }
    * dest = '\0';
    
    cur_token = end;
    
    * result = addr_spec;
    * indx = cur_token;
    
    return MAILIMF_NO_ERROR;
    
err:
    return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_addr_spec_parse(const char * message, size_t length,
				   size_t * indx,
				   char ** result)
{
  size_t cur_token;
#if 0
  char * local_part;
  char * domain;
#endif
  char * addr_spec;
  int r;
  int res;
  size_t begin;
  size_t end;
  int final;
  size_t count;
  const char * src;
  char * dest;
  size_t i;
  
  cur_token = * indx;
  
  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }

  end = cur_token;
  if (end >= length) {
    res = MAILIMF_ERROR_PARSE;
    goto err;
  }

  begin = cur_token;

  final = FALSE;
  while (1) {
    switch (message[end]) {
    case '>':
    case ',':
    case '\r':
    case '\n':
    case '(':
    case ')':
    case ':':
    case ';':
      final = TRUE;
      break;
    }

    if (final)
      break;

    end ++;
    if (end >= length)
      break;
  }

  if (end == begin) {
    res = MAILIMF_ERROR_PARSE;
    goto err;
  }
  
  addr_spec = malloc(end - cur_token + 1);
  if (addr_spec == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }
  
  count = end - cur_token;
  src = message + cur_token;
  dest = addr_spec;
  for(i = 0 ; i < count ; i ++) {
    if ((* src != ' ') && (* src != '\t')) {
      * dest = * src;
      dest ++;
    }
    src ++;
  }
  * dest = '\0';
  
#if 0
  strncpy(addr_spec, message + cur_token, end - cur_token);
  addr_spec[end - cur_token] = '\0';
#endif

  cur_token = end;

#if 0
  r = mailimf_local_part_parse(message, length, &cur_token, &local_part);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_at_sign_parse(message, length, &cur_token);
  switch (r) {
  case MAILIMF_NO_ERROR:
    r = mailimf_domain_parse(message, length, &cur_token, &domain);
    if (r != MAILIMF_NO_ERROR) {
      res = r;
      goto free_local_part;
    }
    break;

  case MAILIMF_ERROR_PARSE:
    domain = NULL;
    break;

  default:
    res = r;
    goto free_local_part;
  }

  if (domain) {
    addr_spec = malloc(strlen(local_part) + strlen(domain) + 2);
    if (addr_spec == NULL) {
      res = MAILIMF_ERROR_MEMORY;
      goto free_domain;
    }
    
    strcpy(addr_spec, local_part);
    strcat(addr_spec, "@");
    strcat(addr_spec, domain);

    mailimf_domain_free(domain);
    mailimf_local_part_free(local_part);
  }
  else {
    addr_spec = local_part;
  }
#endif

  * result = addr_spec;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

#if 0
 free_domain:
  mailimf_domain_free(domain);
 free_local_part:
  mailimf_local_part_free(local_part);
#endif
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_address_list_parse(const char * message, size_t length,
			   size_t * indx,
			   struct mailimf_address_list ** result)
{
  size_t cur_token;
  clist * list;
  struct mailimf_address_list * address_list;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_struct_list_parse(message, length,
				&cur_token, &list, ',',
				(mailimf_struct_parser *)
				mailimf_address_parse,
				(mailimf_struct_destructor *)
				mailimf_address_free);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  address_list = mailimf_address_list_new(list);
  if (address_list == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_list;
  }

  * result = address_list;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_list:
  clist_foreach(list, (clist_func) mailimf_address_free, NULL);
  clist_free(list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

int mailimf_address_parse(const char * message, size_t length,
			  size_t * indx,
			  struct mailimf_address ** result)
{
  int type;
  size_t cur_token;
  struct mailimf_mailbox * mailbox;
  struct mailimf_group * group;
  struct mailimf_address * address;
  int r;
  int res;

  cur_token = * indx;

  mailbox = NULL;
  group = NULL;

  type = MAILIMF_ADDRESS_ERROR; /* XXX - removes a gcc warning */
  r = mailimf_group_parse(message, length, &cur_token, &group);
  if (r == MAILIMF_NO_ERROR)
    type = MAILIMF_ADDRESS_GROUP;
  
  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_mailbox_parse(message, length, &cur_token, &mailbox);
    if (r == MAILIMF_NO_ERROR)
      type = MAILIMF_ADDRESS_MAILBOX;
  }

  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  address = mailimf_address_new(type, mailbox, group);
  if (address == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  * result = address;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
  
 free:
  if (mailbox != NULL)
    mailimf_mailbox_free(mailbox);
  if (group != NULL)
    mailimf_group_free(group);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_angle_addr_parse(const char * message, size_t length,
				    size_t * indx, char ** result)
{
  size_t cur_token;
  char * addr_spec;
  int r;
  
  cur_token = * indx;
  
  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;
  
  r = mailimf_lower_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR)
    return r;
  
  r = mailimf_addr_spec_parse(message, length, &cur_token, &addr_spec);
  if (r != MAILIMF_NO_ERROR)
    return r;
  
  r = mailimf_greater_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    free(addr_spec);
    return r;
  }

  * result = addr_spec;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_at_sign_parse(const char * message, size_t length,
				      size_t * indx)
{
  return mailimf_unstrict_char_parse(message, length, indx, '@');
}

Project: libetpan
File: mailimf.c

int mailimf_atom_parse(const char * message, size_t length,
		       size_t * indx, char ** result)
{
  size_t cur_token;
  int r;
  int res;
  char * atom;
  size_t end;

  cur_token = * indx;

  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }
  
  end = cur_token;
  if (end >= length) {
    res = MAILIMF_ERROR_PARSE;
    goto err;
  }

  while (is_atext(message[end])) {
    end ++;
    if (end >= length)
      break;
  }
  if (end == cur_token) {
    res = MAILIMF_ERROR_PARSE;
    goto err;
  }

  atom = malloc(end - cur_token + 1);
  if (atom == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }
  strncpy(atom, message + cur_token, end - cur_token);
  atom[end - cur_token] = '\0';

  cur_token = end;

  * indx = cur_token;
  * result = atom;

  return MAILIMF_NO_ERROR;

 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_bcc_parse(const char * message, size_t length,
		  size_t * indx, struct mailimf_bcc ** result)
{
  struct mailimf_address_list * addr_list;
  struct mailimf_bcc * bcc;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;
  addr_list = NULL;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Bcc");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
  switch (r) {
  case MAILIMF_NO_ERROR:
    /* do nothing */
    break;
  case MAILIMF_ERROR_PARSE:
    r = mailimf_cfws_parse(message, length, &cur_token);
    if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
      res = r;
      goto err;
    }
    break;
  default:
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  bcc = mailimf_bcc_new(addr_list);
  if (bcc == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }

  * result = bcc;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 err:
  if (addr_list != NULL)
    mailimf_address_list_free(addr_list);
  return res;
}

Project: libetpan
File: mailimf.c

int mailimf_body_parse(const char * message, size_t length,
		       size_t * indx,
		       struct mailimf_body ** result)
{
  size_t cur_token;
  struct mailimf_body * body;

  cur_token = * indx;

  body = mailimf_body_new(message + cur_token, length - cur_token);
  if (body == NULL)
    return MAILIMF_ERROR_MEMORY;

  cur_token = length;

  * result = body;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_broken_date_parse(const char * message, size_t length,
                                     size_t * indx,
                                     int * pday, int * pmonth, int * pyear)
{
  size_t cur_token;
  int day;
  int month;
  int year;
  int r;

  cur_token = * indx;

  month = 1;
  r = mailimf_month_parse(message, length, &cur_token, &month);
  if (r != MAILIMF_NO_ERROR)
    return r;

  day = 1;
  r = mailimf_day_parse(message, length, &cur_token, &day);
  if (r != MAILIMF_NO_ERROR)
    return r;

  year = 2001;
  r = mailimf_year_parse(message, length, &cur_token, &year);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * pday = day;
  * pmonth = month;
  * pyear = year;

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

mailimf_cc_parse(const char * message, size_t length,
		 size_t * indx, struct mailimf_cc ** result)
{
  struct mailimf_address_list * addr_list;
  struct mailimf_cc * cc;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Cc");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_addr_list;
  }

  cc = mailimf_cc_new(addr_list);
  if (cc == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_addr_list;
  }

  * result = cc;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_addr_list:
  mailimf_address_list_free(addr_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static inline int mailimf_ccontent_parse(const char * message, size_t length,
					 size_t * indx)
{
  size_t cur_token;
  char ch;
  int r;
  
  cur_token = * indx;

  if (cur_token >= length)
    return MAILIMF_ERROR_PARSE;

  if (is_ctext(message[cur_token])) {
    cur_token ++;
  }
  else {
    r = mailimf_quoted_pair_parse(message, length, &cur_token, &ch);
    
    if (r == MAILIMF_ERROR_PARSE)
      r = mailimf_comment_parse(message, length, &cur_token);
    
    if (r == MAILIMF_ERROR_PARSE)
      return r;
  }

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static inline int mailimf_cfws_fws_comment_parse(const char * message, size_t length,
						 size_t * indx)
{
  size_t cur_token;
  int r;

  cur_token = * indx;

  r = mailimf_fws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_comment_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

int mailimf_cfws_parse(const char * message, size_t length,
		       size_t * indx)
{
  size_t cur_token;
  int has_comment;
  int r;

  cur_token = * indx;

  has_comment = FALSE;
  while (1) {
    r = mailimf_cfws_fws_comment_parse(message, length, &cur_token);
    if (r != MAILIMF_NO_ERROR) {
      if (r == MAILIMF_ERROR_PARSE)
	break;
      else
	return r;
    }
    has_comment = TRUE;
  }

  if (!has_comment) {
    r = mailimf_fws_parse(message, length, &cur_token);
    if (r != MAILIMF_NO_ERROR)
      return r;
  }

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

int mailimf_char_parse(const char * message, size_t length,
		       size_t * indx, char token)
{
  size_t cur_token;

  cur_token = * indx;

  if (cur_token >= length)
    return MAILIMF_ERROR_PARSE;

  if (message[cur_token] == token) {
    cur_token ++;
    * indx = cur_token;
    return MAILIMF_NO_ERROR;
  }
  else
    return MAILIMF_ERROR_PARSE;
}

Project: libetpan
File: mailimf.c

static int mailimf_colon_parse(const char * message, size_t length,
			       size_t * indx)
{
  return mailimf_unstrict_char_parse(message, length, indx, ':');
}

Project: libetpan
File: mailimf.c

static int mailimf_comma_parse(const char * message, size_t length,
			       size_t * indx)
{
  return mailimf_unstrict_char_parse(message, length, indx, ',');
}

Project: libetpan
File: mailimf.c

mailimf_comment_fws_ccontent_parse(const char * message, size_t length,
				   size_t * indx)
{
  size_t cur_token;
  int r;

  cur_token = * indx;

  r = mailimf_fws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_ccontent_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static inline int mailimf_comment_parse(const char * message, size_t length,
				 size_t * indx)
{
  size_t cur_token;
  int r;

  cur_token = * indx;

  r = mailimf_oparenth_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR)
    return r;

  while (1) {
    r = mailimf_comment_fws_ccontent_parse(message, length, &cur_token);
    if (r != MAILIMF_NO_ERROR) {
      if (r == MAILIMF_ERROR_PARSE)
	break;
      else
	return r;
    }
  }

  r = mailimf_fws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_cparenth_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_comments_parse(const char * message, size_t length,
				  size_t * indx,
				  struct mailimf_comments ** result)
{
  struct mailimf_comments * comments;
  char * value;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Comments");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }
  
  r = mailimf_unstructured_parse(message, length, &cur_token, &value);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_value;
  }
  
  comments = mailimf_comments_new(value);
  if (comments == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_value;
  }

  * result = comments;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_value:
  mailimf_unstructured_free(value);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_cparenth_parse(const char * message, size_t length,
				  size_t * indx)
{
  return mailimf_char_parse(message, length, indx, ')');
}

Project: libetpan
File: mailimf.c

int mailimf_crlf_parse(const char * message, size_t length, size_t * indx)
{
  size_t cur_token;
  int r;

  cur_token = * indx;

  r = mailimf_char_parse(message, length, &cur_token, '\r');
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_char_parse(message, length, &cur_token, '\n');
  if (r != MAILIMF_NO_ERROR)
    return r;

  * indx = cur_token;
  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

mailimf_custom_string_parse(const char * message, size_t length,
			    size_t * indx, char ** result,
			    int (* is_custom_char)(char))
{
  size_t begin;
  size_t end;
  char * gstr;

  begin = * indx;

  end = begin;

  if (end >= length)
    return MAILIMF_ERROR_PARSE;

  while (is_custom_char(message[end])) {
    end ++;
    if (end >= length)
      break;
  }

  if (end != begin) {
    /*
    gstr = strndup(message + begin, end - begin);
    */
    gstr = malloc(end - begin + 1);
    if (gstr == NULL)
      return MAILIMF_ERROR_MEMORY;
    strncpy(gstr, message + begin, end - begin);
    gstr[end - begin] = '\0';

    * indx = end;
    * result = gstr;
    return MAILIMF_NO_ERROR;
  }
  else
    return MAILIMF_ERROR_PARSE;
}

Project: libetpan
File: mailimf.c

static int mailimf_date_parse(const char * message, size_t length,
			      size_t * indx,
			      int * pday, int * pmonth, int * pyear)
{
  size_t cur_token;
  int day;
  int month;
  int year;
  int r;

  cur_token = * indx;

  day = 1;
  r = mailimf_day_parse(message, length, &cur_token, &day);
  if (r != MAILIMF_NO_ERROR)
    return r;

  month = 1;
  r = mailimf_month_parse(message, length, &cur_token, &month);
  if (r != MAILIMF_NO_ERROR)
    return r;

  year = 2001;
  r = mailimf_year_parse(message, length, &cur_token, &year);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * pday = day;
  * pmonth = month;
  * pyear = year;

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan

int mailimf_date_time_parse(const char * message, size_t length,
			    size_t * indx,
			    struct mailimf_date_time ** result)
{
  size_t cur_token;
  int day_of_week;
  struct mailimf_date_time * date_time;
  int day;
  int month;
  int year;
  int hour;
  int min;
  int sec;
  int zone;
  int r;

  cur_token = * indx;

  day_of_week = -1;
  r = mailimf_day_of_week_parse(message, length, &cur_token, &day_of_week);
  if (r == MAILIMF_NO_ERROR) {
    r = mailimf_comma_parse(message, length, &cur_token);
    if (r == MAILIMF_ERROR_PARSE) {
    }
    else if (r != MAILIMF_NO_ERROR) {
      return r;
    }
  }
  else if (r != MAILIMF_ERROR_PARSE)
    return r;

  day = 0;
  month = 0;
  year = 0;
  r = mailimf_date_parse(message, length, &cur_token, &day, &month, &year);
  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_broken_date_parse(message, length, &cur_token, &day, &month, &year);
  }
  else if (r != MAILIMF_NO_ERROR) {
    return r;
  }

  r = mailimf_fws_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR)
    return r;
  
  hour = 0;
  min = 0;
  sec = 0;
  zone = 0;
  r = mailimf_time_parse(message, length, &cur_token,
			 &hour, &min, &sec, &zone);
  if (r != MAILIMF_NO_ERROR)
    return r;

  date_time = mailimf_date_time_new(day, month, year, hour, min, sec, zone);
  if (date_time == NULL)
    return MAILIMF_ERROR_MEMORY;

  * indx = cur_token;
  * result = date_time;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_day_name_parse(const char * message, size_t length,
				  size_t * indx, int * result)
{
  size_t cur_token;
  int day_of_week;
  int guessed_day;
  int r;

  cur_token = * indx;

  guessed_day = guess_day_name(message, length, cur_token);
  if (guessed_day == -1)
    return MAILIMF_ERROR_PARSE;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token,
					   day_names[guessed_day - 1].str);
  if (r != MAILIMF_NO_ERROR)
    return r;

  day_of_week = guessed_day;

  * result = day_of_week;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_day_of_week_parse(const char * message, size_t length,
				     size_t * indx, int * result)
{
  size_t cur_token;
  int day_of_week;
  int r;

  cur_token = * indx;

  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_day_name_parse(message, length, &cur_token, &day_of_week);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * indx = cur_token;
  * result = day_of_week;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_day_parse(const char * message, size_t length,
			     size_t * indx, int * result)
{
  size_t cur_token;
  uint32_t day;
  int r;

  cur_token = * indx;

  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_number_parse(message, length, &cur_token, &day);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * result = day;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_digit_parse(const char * message, size_t length,
			       size_t * indx, int * result)
{
  size_t cur_token;

  cur_token = * indx;
  
  if (cur_token >= length)
    return MAILIMF_ERROR_PARSE;

  if (is_digit(message[cur_token])) {
    * result = message[cur_token] - '0';
    cur_token ++;
    * indx = cur_token;
    return MAILIMF_NO_ERROR;
  }
  else
    return MAILIMF_ERROR_PARSE;
}

Project: libetpan
File: mailimf.c

static int mailimf_display_name_parse(const char * message, size_t length,
				      size_t * indx, char ** result)
{
  return mailimf_phrase_parse(message, length, indx, result);
}

Project: libetpan
File: mailimf.c

static int mailimf_dquote_parse(const char * message, size_t length,
				size_t * indx)
{
  return mailimf_char_parse(message, length, indx, '\"');
}

Project: libetpan
File: mailimf.c

mailimf_envelope_and_optional_fields_parse(const char * message, size_t length,
					   size_t * indx,
					   struct mailimf_fields ** result)
{
  size_t cur_token;
  clist * list;
  struct mailimf_fields * fields;
  int r;
  int res;

  cur_token = * indx;

  list = NULL;

  r = mailimf_struct_multiple_parse(message, length, &cur_token,
				    &list,
				    (mailimf_struct_parser *)
				    mailimf_envelope_or_optional_field_parse,
				    (mailimf_struct_destructor *)
				    mailimf_field_free);
  switch (r) {
  case MAILIMF_NO_ERROR:
    /* do nothing */
    break;

  case MAILIMF_ERROR_PARSE:
    list = clist_new();
    if (list == NULL) {
      res = MAILIMF_ERROR_MEMORY;
      goto err;
    }
    break;

  default:
    res = r;
    goto err;
  }

  fields = mailimf_fields_new(list);
  if (fields == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  * result = fields;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free:
  if (list != NULL) {
    clist_foreach(list, (clist_func) mailimf_field_free, NULL);
    clist_free(list);
  }
 err:
  return res;
}

Project: libetpan
File: mailimf.c

int mailimf_envelope_fields_parse(const char * message, size_t length,
				  size_t * indx,
				  struct mailimf_fields ** result)
{
  size_t cur_token;
  clist * list;
  struct mailimf_fields * fields;
  int r;
  int res;

  cur_token = * indx;

  list = clist_new();
  if (list == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }

  while (1) {
    struct mailimf_field * elt;

    r = mailimf_envelope_field_parse(message, length, &cur_token, &elt);
    if (r == MAILIMF_NO_ERROR) {
      r = clist_append(list, elt);
      if (r < 0) {
	res = MAILIMF_ERROR_MEMORY;
	goto free;
      }
    }
    else if (r == MAILIMF_ERROR_PARSE) {
      r = mailimf_ignore_field_parse(message, length, &cur_token);
      if (r == MAILIMF_NO_ERROR) {
	/* do nothing */
      }
      else if (r == MAILIMF_ERROR_PARSE) {
	break;
      }
      else {
	res = r;
	goto free;
      }
    }
    else {
      res = r;
      goto free;
    }
  }

  fields = mailimf_fields_new(list);
  if (fields == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  * result = fields;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free:
  if (list != NULL) {
    clist_foreach(list, (clist_func) mailimf_field_free, NULL);
    clist_free(list);
  }
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_envelope_or_optional_field_parse(const char * message,
					 size_t length,
					 size_t * indx,
					 struct mailimf_field ** result)
{
  int r;
  size_t cur_token;
  struct mailimf_optional_field * optional_field;
  struct mailimf_field * field;

  r = mailimf_envelope_field_parse(message, length, indx, result);
  if (r == MAILIMF_NO_ERROR)
    return MAILIMF_NO_ERROR;

  cur_token = * indx;

  r = mailimf_optional_field_parse(message, length, &cur_token,
				   &optional_field);
  if (r != MAILIMF_NO_ERROR)
    return r;

  field = mailimf_field_new(MAILIMF_FIELD_OPTIONAL_FIELD, NULL,
      NULL, NULL, NULL,
      NULL, NULL, NULL,
      NULL, NULL, NULL,
      NULL, NULL, NULL,
      NULL, NULL, NULL, NULL, NULL,
      NULL, NULL, NULL, optional_field);
  if (field == NULL) {
    mailimf_optional_field_free(optional_field);
    return MAILIMF_ERROR_MEMORY;
  }

  * result = field;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_field_name_parse(const char * message, size_t length,
				    size_t * indx, char ** result)
{
  char * field_name;
  size_t cur_token;
  size_t end;
  
  cur_token = * indx;

  end = cur_token;
  if (end >= length) {
    return MAILIMF_ERROR_PARSE;
  }

  while (is_ftext(message[end])) {
    end ++;
    if (end >= length)
      break;
  }
  if (end == cur_token) {
    return MAILIMF_ERROR_PARSE;
  }

  /*  field_name = strndup(message + cur_token, end - cur_token); */
  field_name = malloc(end - cur_token + 1);
  if (field_name == NULL) {
    return MAILIMF_ERROR_MEMORY;
  }
  strncpy(field_name, message + cur_token, end - cur_token);
  field_name[end - cur_token] = '\0';

  cur_token = end;
  
  * indx = cur_token;
  * result = field_name;
  
  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_field_parse(const char * message, size_t length,
			       size_t * indx,
			       struct mailimf_field ** result)
{
  size_t cur_token;
  int type;
  struct mailimf_return * return_path;
  struct mailimf_orig_date * resent_date;
  struct mailimf_from * resent_from;
  struct mailimf_sender * resent_sender;
  struct mailimf_to* resent_to;
  struct mailimf_cc * resent_cc;
  struct mailimf_bcc * resent_bcc;
  struct mailimf_message_id * resent_msg_id;
  struct mailimf_orig_date * orig_date;
  struct mailimf_from * from;
  struct mailimf_sender * sender;
  struct mailimf_reply_to * reply_to;
  struct mailimf_to * to;
  struct mailimf_cc * cc;
  struct mailimf_bcc * bcc;
  struct mailimf_message_id * message_id;
  struct mailimf_in_reply_to * in_reply_to;
  struct mailimf_references * references;
  struct mailimf_subject * subject;
  struct mailimf_comments * comments;
  struct mailimf_keywords * keywords;
  struct mailimf_optional_field * optional_field;
  struct mailimf_field * field;
  int guessed_type;
  int r;
  int res;
  
  cur_token = * indx;

  return_path = NULL;
  resent_date = NULL;
  resent_from = NULL;
  resent_sender = NULL;
  resent_to = NULL;
  resent_cc = NULL;
  resent_bcc = NULL;
  resent_msg_id = NULL;
  orig_date = NULL;
  from = NULL;
  sender = NULL;
  reply_to = NULL;
  to = NULL;
  cc = NULL;
  bcc = NULL;
  message_id = NULL;
  in_reply_to = NULL;
  references = NULL;
  subject = NULL;
  comments = NULL;
  keywords = NULL;
  optional_field = NULL;

  guessed_type = guess_header_type(message, length, cur_token);
  type = MAILIMF_FIELD_NONE;

  switch (guessed_type) {
  case MAILIMF_FIELD_ORIG_DATE:
    r = mailimf_orig_date_parse(message, length, &cur_token,
				&orig_date);
    if (r == MAILIMF_NO_ERROR)
      type = MAILIMF_FIELD_ORIG_DATE;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_FROM:
    r = mailimf_from_parse(message, length, &cur_token,
			   &from);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_SENDER:
    r = mailimf_sender_parse(message, length, &cur_token,
			     &sender);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_REPLY_TO:
    r = mailimf_reply_to_parse(message, length, &cur_token,
			       &reply_to);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_TO:
    r = mailimf_to_parse(message, length, &cur_token,
			 &to);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_CC:
    r = mailimf_cc_parse(message, length, &cur_token,
			 &cc);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_BCC:
    r = mailimf_bcc_parse(message, length, &cur_token,
			  &bcc);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_MESSAGE_ID:
    r = mailimf_message_id_parse(message, length, &cur_token,
				 &message_id);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_IN_REPLY_TO:
    r = mailimf_in_reply_to_parse(message, length, &cur_token,
				  &in_reply_to);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_REFERENCES:
    r = mailimf_references_parse(message, length, &cur_token,
				 &references);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_SUBJECT:
    r = mailimf_subject_parse(message, length, &cur_token,
			      &subject);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_COMMENTS:
    r = mailimf_comments_parse(message, length, &cur_token,
			       &comments);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_KEYWORDS:
    r = mailimf_keywords_parse(message, length, &cur_token,
			       &keywords);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_RETURN_PATH:
    r = mailimf_return_parse(message, length, &cur_token,
        &return_path);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_RESENT_DATE:
    r = mailimf_resent_date_parse(message, length, &cur_token,
				  &resent_date);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_RESENT_FROM:
    r = mailimf_resent_from_parse(message, length, &cur_token,
				  &resent_from);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_RESENT_SENDER:
    r = mailimf_resent_sender_parse(message, length, &cur_token,
				    &resent_sender);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_RESENT_TO:
    r = mailimf_resent_to_parse(message, length, &cur_token,
				&resent_to);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_RESENT_CC:
    r= mailimf_resent_cc_parse(message, length, &cur_token,
			       &resent_cc);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_RESENT_BCC:
    r = mailimf_resent_bcc_parse(message, length, &cur_token,
				 &resent_bcc);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  case MAILIMF_FIELD_RESENT_MSG_ID:
    r = mailimf_resent_msg_id_parse(message, length, &cur_token,
				    &resent_msg_id);
    if (r == MAILIMF_NO_ERROR)
      type = guessed_type;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else {
      res = r;
      goto err;
    }
    break;
  }

  if (type == MAILIMF_FIELD_NONE) {
    r = mailimf_optional_field_parse(message, length, &cur_token,
        &optional_field);
    if (r != MAILIMF_NO_ERROR) {
      res = r;
      goto err;
    }

    type = MAILIMF_FIELD_OPTIONAL_FIELD;
  }

  field = mailimf_field_new(type, return_path, resent_date,
      resent_from, resent_sender, resent_to, resent_cc, resent_bcc,
      resent_msg_id, orig_date, from, sender, reply_to, to,
      cc, bcc, message_id, in_reply_to, references,
      subject, comments, keywords, optional_field);
  if (field == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_field;
  }

  * result = field;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_field:
  if (return_path != NULL)
    mailimf_return_free(return_path);
  if (resent_date != NULL)
    mailimf_orig_date_free(resent_date);
  if (resent_from != NULL)
    mailimf_from_free(resent_from);
  if (resent_sender != NULL)
    mailimf_sender_free(resent_sender);
  if (resent_to != NULL)
    mailimf_to_free(resent_to);
  if (resent_cc != NULL)
    mailimf_cc_free(resent_cc);
  if (resent_bcc != NULL)
    mailimf_bcc_free(resent_bcc);
  if (resent_msg_id != NULL)
    mailimf_message_id_free(resent_msg_id);
  if (orig_date != NULL)
    mailimf_orig_date_free(orig_date);
  if (from != NULL)
    mailimf_from_free(from);
  if (sender != NULL)
    mailimf_sender_free(sender);
  if (reply_to != NULL)
    mailimf_reply_to_free(reply_to);
  if (to != NULL)
    mailimf_to_free(to);
  if (cc != NULL)
    mailimf_cc_free(cc);
  if (bcc != NULL)
    mailimf_bcc_free(bcc);
  if (message_id != NULL)
    mailimf_message_id_free(message_id);
  if (in_reply_to != NULL)
    mailimf_in_reply_to_free(in_reply_to);
  if (references != NULL)
    mailimf_references_free(references);
  if (subject != NULL)
    mailimf_subject_free(subject);
  if (comments != NULL)
    mailimf_comments_free(comments);
  if (keywords != NULL)
    mailimf_keywords_free(keywords);
  if (optional_field != NULL)
    mailimf_optional_field_free(optional_field);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

int mailimf_fields_parse(const char * message, size_t length,
			 size_t * indx,
			 struct mailimf_fields ** result)
{
  size_t cur_token;
  clist * list;
  struct mailimf_fields * fields;
  int r;
  int res;

  cur_token = * indx;

  list = NULL;

  r = mailimf_struct_multiple_parse(message, length, &cur_token,
				    &list,
				    (mailimf_struct_parser *)
				    mailimf_field_parse,
				    (mailimf_struct_destructor *)
				    mailimf_field_free);
  /*
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }
  */

  switch (r) {
  case MAILIMF_NO_ERROR:
    /* do nothing */
    break;

  case MAILIMF_ERROR_PARSE:
    list = clist_new();
    if (list == NULL) {
      res = MAILIMF_ERROR_MEMORY;
      goto err;
    }
    break;

  default:
    res = r;
    goto err;
  }

  fields = mailimf_fields_new(list);
  if (fields == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  * result = fields;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free:
  if (list != NULL) {
    clist_foreach(list, (clist_func) mailimf_field_free, NULL);
    clist_free(list);
  }
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_fws_atom_for_word_parse(const char * message, size_t length,
                                           size_t * indx, char ** result, int * p_missing_closing_quote)
{
  size_t end;
  size_t cur_token;
  int r;
  int res;
  struct mailmime_encoded_word * word;
  int has_fwd;
  int missing_closing_quote;
  char * atom;
  
  cur_token = * indx;
  missing_closing_quote = 0;
  
  r = mailimf_fws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }
  
  end = cur_token;
  
  r = mailmime_encoded_word_parse(message, length, &cur_token, &word, &has_fwd, &missing_closing_quote);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }
  
  if (r == MAILIMF_ERROR_PARSE) {
    return mailimf_fws_atom_parse(message, length, indx, result);
  }
  
  mailmime_encoded_word_free(word);
  
  atom = malloc(cur_token - end + 1);
  if (atom == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }
  strncpy(atom, message + end, cur_token - end);
  atom[cur_token - end] = '\0';
  
  * result = atom;
  * indx = cur_token;
  * p_missing_closing_quote = missing_closing_quote;
  
  return MAILIMF_NO_ERROR;
  
err:
  return res;
}

Project: libetpan
File: mailimf.c

int mailimf_fws_atom_parse(const char * message, size_t length,
			   size_t * indx, char ** result)
{
  size_t cur_token;
  int r;
  int res;
  char * atom;
  size_t end;

  cur_token = * indx;

  r = mailimf_fws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }

  end = cur_token;
  if (end >= length) {
    res = MAILIMF_ERROR_PARSE;
    goto err;
  }

  while (is_atext(message[end])) {
    end ++;
    if (end >= length)
      break;
  }
  if (end == cur_token) {
    res = MAILIMF_ERROR_PARSE;
    goto err;
  }

  atom = malloc(end - cur_token + 1);
  if (atom == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }
  strncpy(atom, message + cur_token, end - cur_token);
  atom[end - cur_token] = '\0';

  cur_token = end;

  * indx = cur_token;
  * result = atom;

  return MAILIMF_NO_ERROR;

 err:
  return res;
}

Project: libetpan
File: mailimf.c

int mailimf_fws_parse(const char * message, size_t length, size_t * indx)
{
  size_t cur_token;
  size_t final_token;
  int fws_1;
  int fws_2;
  int fws_3;
  int r;
  
  cur_token = * indx;

  fws_1 = FALSE;
  while (1) {
    r = mailimf_wsp_parse(message, length, &cur_token);
    if (r != MAILIMF_NO_ERROR) {
      if (r == MAILIMF_ERROR_PARSE)
	break;
      else
	return r;
    }
    fws_1 = TRUE;
  }
  final_token = cur_token;

  r = mailimf_crlf_parse(message, length, &cur_token);
  switch (r) {
  case MAILIMF_NO_ERROR:
    fws_2 = TRUE;
    break;
  case MAILIMF_ERROR_PARSE:
    fws_2 = FALSE;
    break;
  default:
      return r;
  }
  
  fws_3 = FALSE;
  if (fws_2) {
    while (1) {
      r = mailimf_wsp_parse(message, length, &cur_token);
      if (r != MAILIMF_NO_ERROR) {
	if (r == MAILIMF_ERROR_PARSE)
	  break;
	else
	  return r;
      }
      fws_3 = TRUE;
    }
  }

  if ((!fws_1) && (!fws_3))
    return MAILIMF_ERROR_PARSE;

  if (!fws_3)
    cur_token = final_token;

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

int mailimf_fws_quoted_string_parse(const char * message, size_t length,
				    size_t * indx, char ** result)
{
  size_t cur_token;
  MMAPString * gstr;
  char ch;
  char * str;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_fws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }

  r = mailimf_dquote_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  gstr = mmap_string_new("");
  if (gstr == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }

#if 0
  if (mmap_string_append_c(gstr, '\"') == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_gstr;
  }
#endif

  while (1) {
    r = mailimf_fws_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR) {
      if (mmap_string_append_c(gstr, ' ') == NULL) {
	res = MAILIMF_ERROR_MEMORY;
	goto free_gstr;
      }
    }
    else if (r != MAILIMF_ERROR_PARSE) {
      res = r;
      goto free_gstr;
    }

    r = mailimf_qcontent_parse(message, length, &cur_token, &ch);
    if (r == MAILIMF_NO_ERROR) {
      if (mmap_string_append_c(gstr, ch) == NULL) {
	res = MAILIMF_ERROR_MEMORY;
	goto free_gstr;
      }
    }
    else if (r == MAILIMF_ERROR_PARSE)
      break;
    else {
      res = r;
      goto free_gstr;
    }
  }

  r = mailimf_dquote_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_gstr;
  }

#if 0
  if (mmap_string_append_c(gstr, '\"') == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_gstr;
  }
#endif

  str = strdup(gstr->str);
  if (str == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_gstr;
  }
  mmap_string_free(gstr);

  * indx = cur_token;
  * result = str;

  return MAILIMF_NO_ERROR;

 free_gstr:
  mmap_string_free(gstr);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

int mailimf_fws_word_parse(const char * message, size_t length,
			   size_t * indx, char ** result, int * p_missing_closing_quote)
{
  size_t cur_token;
  char * word;
  int r;
  int missing_closing_quote;

  cur_token = * indx;
  missing_closing_quote = 0;

  r = mailimf_fws_atom_for_word_parse(message, length, &cur_token, &word, &missing_closing_quote);

  if (r == MAILIMF_ERROR_PARSE)
    r = mailimf_fws_quoted_string_parse(message, length, &cur_token, &word);

  if (r != MAILIMF_NO_ERROR)
    return r;

  * result = word;
  * indx = cur_token;
  * p_missing_closing_quote = missing_closing_quote;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_greater_parse(const char * message, size_t length,
				      size_t * indx)
{
  return mailimf_unstrict_char_parse(message, length, indx, '>');
}

Project: libetpan
File: mailimf.c

int mailimf_ignore_field_parse(const char * message, size_t length,
			       size_t * indx)
{
  int has_field;
  size_t cur_token;
  int state;
  size_t terminal;

  has_field = FALSE;
  cur_token = * indx;

  terminal = cur_token;
  state = UNSTRUCTURED_START;

  /* check if this is not a beginning CRLF */

  if (cur_token >= length)
    return MAILIMF_ERROR_PARSE;

  switch (message[cur_token]) {
  case '\r':
    return MAILIMF_ERROR_PARSE;
  case '\n':
    return MAILIMF_ERROR_PARSE;
  }

  while (state != UNSTRUCTURED_OUT) {

    switch(state) {
    case UNSTRUCTURED_START:
      if (cur_token >= length)
	return MAILIMF_ERROR_PARSE;

      switch(message[cur_token]) {
      case '\r':
	state = UNSTRUCTURED_CR;
	break;
      case '\n':
	state = UNSTRUCTURED_LF;
	break;
      case ':':
	has_field = TRUE;
	state = UNSTRUCTURED_START;
	break;
      default:
	state = UNSTRUCTURED_START;
	break;
      }
      break;
    case UNSTRUCTURED_CR:
      if (cur_token >= length)
	return MAILIMF_ERROR_PARSE;

      switch(message[cur_token]) {
      case '\n':
	state = UNSTRUCTURED_LF;
	break;
      case ':':
	has_field = TRUE;
	state = UNSTRUCTURED_START;
	break;
      default:
	state = UNSTRUCTURED_START;
	break;
      }
      break;
    case UNSTRUCTURED_LF:
      if (cur_token >= length) {
	terminal = cur_token;
	state = UNSTRUCTURED_OUT;
	break;
      }

      switch(message[cur_token]) {
      case '\t':
      case ' ':
	state = UNSTRUCTURED_WSP;
	break;
      default:
	terminal = cur_token;
	state = UNSTRUCTURED_OUT;
	break;
      }
      break;
    case UNSTRUCTURED_WSP:
      if (cur_token >= length)
	return MAILIMF_ERROR_PARSE;

      switch(message[cur_token]) {
      case '\r':
	state = UNSTRUCTURED_CR;
	break;
      case '\n':
	state = UNSTRUCTURED_LF;
	break;
      case ':':
	has_field = TRUE;
	state = UNSTRUCTURED_START;
	break;
      default:
	state = UNSTRUCTURED_START;
	break;
      }
      break;
    }

    cur_token ++;
  }

  if (!has_field)
    return MAILIMF_ERROR_PARSE;

  * indx = terminal;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_ignore_unstructured_parse(const char * message, size_t length,
					     size_t * indx)
{
  size_t cur_token;
  int state;
  size_t terminal;

  cur_token = * indx;

  state = UNSTRUCTURED_START;
  terminal = cur_token;

  while (state != UNSTRUCTURED_OUT) {

    switch(state) {
    case UNSTRUCTURED_START:
      if (cur_token >= length)
	return MAILIMF_ERROR_PARSE;
      terminal = cur_token;
      switch(message[cur_token]) {
      case '\r':
	state = UNSTRUCTURED_CR;
	break;
      case '\n':
	state = UNSTRUCTURED_LF;
	break;
      default:
	state = UNSTRUCTURED_START;
	break;
      }
      break;
    case UNSTRUCTURED_CR:
      if (cur_token >= length)
	return MAILIMF_ERROR_PARSE;
      switch(message[cur_token]) {
      case '\n':
	state = UNSTRUCTURED_LF;
	break;
      default:
	state = UNSTRUCTURED_START;
	break;
      }
      break;
    case UNSTRUCTURED_LF:
      if (cur_token >= length) {
	state = UNSTRUCTURED_OUT;
	break;
      }
      switch(message[cur_token]) {
      case '\t':
      case ' ':
	state = UNSTRUCTURED_WSP;
	break;
      default:
	state = UNSTRUCTURED_OUT;
	break;
      }
      break;
    case UNSTRUCTURED_WSP:
      if (cur_token >= length)
	return MAILIMF_ERROR_PARSE;
      switch(message[cur_token]) {
      case '\r':
	state = UNSTRUCTURED_CR;
	break;
      case '\n':
	state = UNSTRUCTURED_LF;
	break;
      default:
	state = UNSTRUCTURED_START;
	break;
      }
      break;
    }

    cur_token ++;
  }

  * indx = terminal;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_in_reply_to_parse(const char * message, size_t length,
				     size_t * indx,
				     struct mailimf_in_reply_to ** result)
{
  struct mailimf_in_reply_to * in_reply_to;
  size_t cur_token;
  clist * msg_id_list;
  int res;
  int r;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "In-Reply-To");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_msg_id_list_parse(message, length, &cur_token, &msg_id_list);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_list;
  }

  in_reply_to = mailimf_in_reply_to_new(msg_id_list);
  if (in_reply_to == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_list;
  }

  * result = in_reply_to;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_list:
  clist_foreach(msg_id_list, (clist_func) mailimf_msg_id_free, NULL);
  clist_free(msg_id_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_keywords_parse(const char * message, size_t length,
				  size_t * indx,
				  struct mailimf_keywords ** result)
{
  struct mailimf_keywords * keywords;
  clist * list;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Keywords");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }
  
  r = mailimf_struct_list_parse(message, length, &cur_token,
				&list, ',',
				(mailimf_struct_parser *)
				mailimf_phrase_parse,
				(mailimf_struct_destructor *)
				mailimf_phrase_free);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_list;
  }
  
  keywords = mailimf_keywords_new(list);
  if (keywords == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_list;
  }

  * result = keywords;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_list:
  clist_foreach(list, (clist_func) mailimf_phrase_free, NULL);
  clist_free(list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_lower_parse(const char * message, size_t length,
			       size_t * indx)
{
  return mailimf_unstrict_char_parse(message, length, indx, '<');
}

Project: libetpan
File: mailimf.c

int mailimf_mailbox_parse(const char * message, size_t length,
			  size_t * indx,
			  struct mailimf_mailbox ** result)
{
  size_t cur_token;
  char * display_name;
  struct mailimf_mailbox * mailbox;
  char * addr_spec;
  int r;
  int res;

  cur_token = * indx;
  display_name = NULL;
  addr_spec = NULL;

  r = mailimf_name_addr_parse(message, length, &cur_token,
			      &display_name, &addr_spec);
  if (r == MAILIMF_ERROR_PARSE)
    r = mailimf_addr_spec_parse(message, length, &cur_token, &addr_spec);

  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  mailbox = mailimf_mailbox_new(display_name, addr_spec);
  if (mailbox == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  * result = mailbox;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free:
  if (display_name != NULL)
    mailimf_display_name_free(display_name);
  if (addr_spec != NULL)
    mailimf_addr_spec_free(addr_spec);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_message_id_parse(const char * message, size_t length,
				    size_t * indx,
				    struct mailimf_message_id ** result)
{
  char * value;
  size_t cur_token;
  struct mailimf_message_id * message_id;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Message-ID");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_msg_id_parse(message, length, &cur_token, &value);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_value;
  }

  message_id = mailimf_message_id_new(value);
  if (message_id == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_value;
  }

  * result = message_id;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_value:
  mailimf_msg_id_free(value);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

int mailimf_message_parse(const char * message, size_t length,
			  size_t * indx,
			  struct mailimf_message ** result)
{
  struct mailimf_fields * fields;
  struct mailimf_body * body;
  struct mailimf_message * msg;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_fields_parse(message, length, &cur_token, &fields);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_crlf_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }

  r = mailimf_body_parse(message, length, &cur_token, &body);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_fields;
  }

  msg = mailimf_message_new(fields, body);
  if (msg == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_body;
  }

  * indx = cur_token;
  * result = msg;

  return MAILIMF_NO_ERROR;

 free_body:
  mailimf_body_free(body);
 free_fields:
  mailimf_fields_free(fields);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_minus_parse(const char * message, size_t length,
			       size_t * indx)
{
  return mailimf_unstrict_char_parse(message, length, indx, '-');
}

Project: libetpan
File: mailimf.c

static int mailimf_month_name_parse(const char * message, size_t length,
				    size_t * indx, int * result)
{
  size_t cur_token;
  int month;
  int guessed_month;
  int r;

  cur_token = * indx;

  guessed_month = guess_month(message, length, cur_token);
  if (guessed_month == -1)
    return MAILIMF_ERROR_PARSE;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token,
					   month_names[guessed_month - 1].str);
  if (r != MAILIMF_NO_ERROR)
    return r;

  month = guessed_month;

  * result = month;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

int mailimf_msg_id_list_parse(const char * message, size_t length,
			      size_t * indx, clist ** result)
{
  return mailimf_struct_multiple_parse(message, length, indx,
				       result,
				       (mailimf_struct_parser *)
				       mailimf_unstrict_msg_id_parse,
				       (mailimf_struct_destructor *)
				       mailimf_msg_id_free);
}

Project: libetpan

int mailimf_msg_id_parse(const char * message, size_t length,
			 size_t * indx,
			 char ** result)
{
  size_t cur_token;
#if 0
  char * id_left;
  char * id_right;
#endif
  char * msg_id;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_lower_parse(message, length, &cur_token);
  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_addr_spec_msg_id_parse(message, length, &cur_token, &msg_id);
    if (r != MAILIMF_NO_ERROR) {
      res = r;
      goto err;
    }
    
    * result = msg_id;
    * indx = cur_token;
    
    return MAILIMF_NO_ERROR;
  }
  else if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_lower_parse(message, length, &cur_token);
  if (r == MAILIMF_NO_ERROR) {
  }
  else if (r == MAILIMF_ERROR_PARSE) {
  }
  else {
    res = r;
    goto err;
  }
  r = mailimf_addr_spec_msg_id_parse(message, length, &cur_token, &msg_id);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }
  
  r = mailimf_greater_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    free(msg_id);
    res = r;
    goto err;
  }
  r = mailimf_greater_parse(message, length, &cur_token);
  if (r == MAILIMF_NO_ERROR) {
  }
  else if (r == MAILIMF_ERROR_PARSE) {
  }
  else {
    free(msg_id);
    res = r;
    goto err;
  }
  
#if 0
  r = mailimf_id_left_parse(message, length, &cur_token, &id_left);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_at_sign_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_id_left;
  }

  r = mailimf_id_right_parse(message, length, &cur_token, &id_right);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_id_left;
  }

  r = mailimf_greater_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_id_right;
  }

  msg_id = malloc(strlen(id_left) + strlen(id_right) + 2);
  if (msg_id == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_id_right;
  }
  strcpy(msg_id, id_left);
  strcat(msg_id, "@");
  strcat(msg_id, id_right);

  mailimf_id_left_free(id_left);
  mailimf_id_right_free(id_right);
#endif

  * result = msg_id;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

#if 0
 free_id_right:
  mailimf_id_right_free(id_right);
 free_id_left:
  mailimf_id_left_free(id_left);
#endif
  /*
 free:
  mailimf_atom_free(msg_id);
  */
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_name_addr_parse(const char * message, size_t length,
				   size_t * indx,
				   char ** pdisplay_name,
				   char ** pangle_addr)
{
  char * display_name;
  char * angle_addr;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  display_name = NULL;
  angle_addr = NULL;

  r = mailimf_display_name_parse(message, length, &cur_token, &display_name);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }

  r = mailimf_angle_addr_parse(message, length, &cur_token, &angle_addr);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_display_name;
  }

  * pdisplay_name = display_name;
  * pangle_addr = angle_addr;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_display_name:
  if (display_name != NULL)
    mailimf_display_name_free(display_name);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_number_parse(const char * message, size_t length,
		     size_t * indx, uint32_t * result)
{
  size_t cur_token;
  int digit;
  uint32_t number;
  int parsed;
  int r;

  cur_token = * indx;
  parsed = FALSE;

  number = 0;
  while (1) {
    r = mailimf_digit_parse(message, length, &cur_token, &digit);
    if (r != MAILIMF_NO_ERROR) {
      if (r == MAILIMF_ERROR_PARSE)
	break;
      else
	return r;
    }
    number *= 10;
    number += digit;
    parsed = TRUE;
  }

  if (!parsed)
    return MAILIMF_ERROR_PARSE;

  * result = number;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

mailimf_only_optional_field_parse(const char * message,
				  size_t length,
				  size_t * indx,
				  struct mailimf_field ** result)
{
  int r;
  size_t cur_token;
  struct mailimf_optional_field * optional_field;
  struct mailimf_field * field;

  cur_token = * indx;

  r = mailimf_optional_field_parse(message, length, &cur_token,
				   &optional_field);
  if (r != MAILIMF_NO_ERROR)
    return r;

  field = mailimf_field_new(MAILIMF_FIELD_OPTIONAL_FIELD, NULL, NULL, NULL,
      NULL, NULL, NULL, NULL, NULL,
      NULL, NULL, NULL, NULL, NULL,
      NULL, NULL, NULL, NULL, NULL,
      NULL, NULL, NULL, optional_field);
  if (field == NULL) {
    mailimf_optional_field_free(optional_field);
    return MAILIMF_ERROR_MEMORY;
  }

  * result = field;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_oparenth_parse(const char * message, size_t length,
				  size_t * indx)
{
  return mailimf_char_parse(message, length, indx, '(');
}

Project: libetpan
File: mailimf.c

mailimf_optional_field_parse(const char * message, size_t length,
			     size_t * indx,
			     struct mailimf_optional_field ** result)
{
  char * name;
  char * value;
  struct mailimf_optional_field * optional_field;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_field_name_parse(message, length, &cur_token, &name);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_name;
  }

  r = mailimf_unstructured_parse(message, length, &cur_token, &value);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_name;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_value;
  }

  optional_field = mailimf_optional_field_new(name, value);
  if (optional_field == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_value;
  }

  * result = optional_field;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_value:
  mailimf_unstructured_free(value);
 free_name:
  mailimf_field_name_free(name);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_optional_fields_parse(const char * message, size_t length,
			      size_t * indx,
			      struct mailimf_fields ** result)
{
  size_t cur_token;
  clist * list;
  struct mailimf_fields * fields;
  int r;
  int res;

  cur_token = * indx;

  list = NULL;

  r = mailimf_struct_multiple_parse(message, length, &cur_token,
				    &list,
				    (mailimf_struct_parser *)
				    mailimf_only_optional_field_parse,
				    (mailimf_struct_destructor *)
				    mailimf_field_free);
  switch (r) {
  case MAILIMF_NO_ERROR:
    /* do nothing */
    break;

  case MAILIMF_ERROR_PARSE:
    list = clist_new();
    if (list == NULL) {
      res = MAILIMF_ERROR_MEMORY;
      goto err;
    }
    break;

  default:
    res = r;
    goto err;
  }

  fields = mailimf_fields_new(list);
  if (fields == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  * result = fields;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free:
  if (list != NULL) {
    clist_foreach(list, (clist_func) mailimf_field_free, NULL);
    clist_free(list);
  }
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_orig_date_parse(const char * message, size_t length,
			size_t * indx, struct mailimf_orig_date ** result)
{
  struct mailimf_date_time * date_time;
  struct mailimf_orig_date * orig_date;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Date:");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_date_time_parse(message, length, &cur_token, &date_time);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_ignore_unstructured_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_date_time;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_date_time;
  }

  orig_date = mailimf_orig_date_new(date_time);
  if (orig_date == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_date_time;
  }

  * result = orig_date;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_date_time:
  mailimf_date_time_free(date_time);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_parse_unwanted_msg_id(const char * message, size_t length,
					 size_t * indx)
{
  size_t cur_token;
  int r;
  char * word;
  int token_parsed;

  cur_token = * indx;

  token_parsed = TRUE;
  while (token_parsed) {
    token_parsed = FALSE;
    r = mailimf_word_parse(message, length, &cur_token, &word);
    if (r == MAILIMF_NO_ERROR) {
      mailimf_word_free(word);
      token_parsed = TRUE;
    }
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else
      return r;
    r = mailimf_semi_colon_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR)
      token_parsed = TRUE;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else
      return r;
    r = mailimf_comma_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR)
      token_parsed = TRUE;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else
      return r;
    r = mailimf_plus_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR)
      token_parsed = TRUE;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else
      return r;
    r = mailimf_colon_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR)
      token_parsed = TRUE;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else
      return r;
    r = mailimf_point_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR)
      token_parsed = TRUE;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else
      return r;
    r = mailimf_at_sign_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR)
      token_parsed = TRUE;
    else if (r == MAILIMF_ERROR_PARSE) {
      /* do nothing */
    }
    else
      return r;
  }

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_phrase_parse(const char * message, size_t length,
				size_t * indx, char ** result)
{
  MMAPString * gphrase;
  char * word;
  int first;
  size_t cur_token;
  int r;
  int res;
  char * str;
  int has_missing_closing_quote;

  cur_token = * indx;
  has_missing_closing_quote = 0;

  gphrase = mmap_string_new("");
  if (gphrase == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }

  first = TRUE;

  while (1) {
    int missing_quote = 0;
    r = mailimf_fws_word_parse(message, length, &cur_token, &word, &missing_quote);
    if (missing_quote) {
      has_missing_closing_quote = 1;
    }
    if (r == MAILIMF_NO_ERROR) {
      if (!first) {
	if (mmap_string_append_c(gphrase, ' ') == NULL) {
	  mailimf_word_free(word);
	  res = MAILIMF_ERROR_MEMORY;
	  goto free;
	}
      }
      if (mmap_string_append(gphrase, word) == NULL) {
	mailimf_word_free(word);
	res = MAILIMF_ERROR_MEMORY;
	goto free;
      }
      mailimf_word_free(word);
      first = FALSE;
    }
    else if (r == MAILIMF_ERROR_PARSE)
      break;
    else {
      res = r;
      goto free;
    }
  }

  if (first) {
    res = MAILIMF_ERROR_PARSE;
    goto free;
  }

  if (has_missing_closing_quote) {
    r = mailimf_char_parse(message, length, &cur_token, '\"');
  }

  str = strdup(gphrase->str);
  if (str == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }
  mmap_string_free(gphrase);

  * result = str;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free:
  mmap_string_free(gphrase);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_plus_parse(const char * message, size_t length,
			      size_t * indx)
{
  return mailimf_unstrict_char_parse(message, length, indx, '+');
}

Project: libetpan
File: mailimf.c

static int mailimf_point_parse(const char * message, size_t length,
				      size_t * indx)
{
  return mailimf_unstrict_char_parse(message, length, indx, '.');
}

Project: libetpan
File: mailimf.c

static int mailimf_qcontent_parse(const char * message, size_t length,
				  size_t * indx, char * result)
{
  size_t cur_token;
  char ch;
  int r;

  cur_token = * indx;

  if (cur_token >= length)
    return MAILIMF_ERROR_PARSE;

  if (is_qtext(message[cur_token])) {
    ch = message[cur_token];
    cur_token ++;
  }
  else {
    r = mailimf_quoted_pair_parse(message, length, &cur_token, &ch);
    
    if (r != MAILIMF_NO_ERROR)
      return r;
  }
  
  * result = ch;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static inline int mailimf_quoted_pair_parse(const char * message, size_t length,
					    size_t * indx, char * result)
{
  size_t cur_token;

  cur_token = * indx;
  
  if (cur_token + 1 >= length)
    return MAILIMF_ERROR_PARSE;

  if (message[cur_token] != '\\')
    return MAILIMF_ERROR_PARSE;

  cur_token ++;
  * result = message[cur_token];
  cur_token ++;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

int mailimf_references_parse(const char * message, size_t length,
			     size_t * indx,
			     struct mailimf_references ** result)
{
  struct mailimf_references * references;
  size_t cur_token;
  clist * msg_id_list;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "References");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_msg_id_list_parse(message, length, &cur_token, &msg_id_list);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_list;
  }

  references = mailimf_references_new(msg_id_list);
  if (references == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_list;
  }

  * result = references;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_list:
  clist_foreach(msg_id_list, (clist_func) mailimf_msg_id_free, NULL);
  clist_free(msg_id_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_reply_to_parse(const char * message, size_t length,
		       size_t * indx, struct mailimf_reply_to ** result)
{
  struct mailimf_address_list * addr_list;
  struct mailimf_reply_to * reply_to;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Reply-To");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_addr_list;
  }

  reply_to = mailimf_reply_to_new(addr_list);
  if (reply_to == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_addr_list;
  }

  * result = reply_to;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_addr_list:
  mailimf_address_list_free(addr_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_resent_bcc_parse(const char * message, size_t length,
			 size_t * indx, struct mailimf_bcc ** result)
{
  struct mailimf_address_list * addr_list;
  struct mailimf_bcc * bcc;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;
  bcc = NULL;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Resent-Bcc");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  addr_list = NULL;
  r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE)) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_addr_list;
  }

  bcc = mailimf_bcc_new(addr_list);
  if (bcc == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_addr_list;
  }

  * result = bcc;
  * indx = cur_token;

  return TRUE;

 free_addr_list:
  mailimf_address_list_free(addr_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_resent_cc_parse(const char * message, size_t length,
			size_t * indx, struct mailimf_cc ** result)
{
  struct mailimf_address_list * addr_list;
  struct mailimf_cc * cc;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Resent-Cc");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_addr_list;
  }

  cc = mailimf_cc_new(addr_list);
  if (cc == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_addr_list;
  }

  * result = cc;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_addr_list:
  mailimf_address_list_free(addr_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_resent_date_parse(const char * message, size_t length,
			  size_t * indx, struct mailimf_orig_date ** result)
{
  struct mailimf_orig_date * orig_date;
  struct mailimf_date_time * date_time;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Resent-Date");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_date_time_parse(message, length, &cur_token, &date_time);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_date_time;
  }

  orig_date = mailimf_orig_date_new(date_time);
  if (orig_date == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_date_time;
  }

  * result = orig_date;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_date_time:
  mailimf_date_time_free(date_time);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_resent_from_parse(const char * message, size_t length,
			  size_t * indx, struct mailimf_from ** result)
{
  struct mailimf_mailbox_list * mb_list;
  struct mailimf_from * from;
  size_t cur_token;
  int r;
  int res;

  cur_token =  * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Resent-From");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_mailbox_list_parse(message, length, &cur_token, &mb_list);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_mb_list;
  }

  from = mailimf_from_new(mb_list);
  if (from == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_mb_list;
  }

  * result = from;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_mb_list:
  mailimf_mailbox_list_free(mb_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_resent_msg_id_parse(const char * message, size_t length,
			    size_t * indx,
			    struct mailimf_message_id ** result)
{
  char * value;
  size_t cur_token;
  struct mailimf_message_id * message_id;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Resent-Message-ID");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_msg_id_parse(message, length, &cur_token, &value);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_value;
  }

  message_id = mailimf_message_id_new(value);
  if (message_id == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_value;
  }

  * result = message_id;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_value:
  mailimf_msg_id_free(value);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_resent_sender_parse(const char * message, size_t length,
			    size_t * indx, struct mailimf_sender ** result)
{
  struct mailimf_mailbox * mb;
  struct mailimf_sender * sender;
  size_t cur_token;
  int r;
  int res;

  cur_token = length;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Resent-Sender");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_mailbox_parse(message, length, &cur_token, &mb);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_mb;
  }

  sender = mailimf_sender_new(mb);
  if (sender == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_mb;
  }

  * result = sender;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_mb:
  mailimf_mailbox_free(mb);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_resent_to_parse(const char * message, size_t length,
			size_t * indx, struct mailimf_to ** result)
{
  struct mailimf_address_list * addr_list;
  struct mailimf_to * to;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Resent-To");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_addr_list;
  }

  to = mailimf_to_new(addr_list);
  if (to == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_addr_list;
  }

  * result = to;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_addr_list:
  mailimf_address_list_free(addr_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_return_parse(const char * message, size_t length,
				size_t * indx,
				struct mailimf_return ** result)
{
  struct mailimf_path * path;
  struct mailimf_return * return_path;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Return-Path");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  path = NULL;
  r = mailimf_path_parse(message, length, &cur_token, &path);
  if ( r!= MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_path;
  }

  return_path = mailimf_return_new(path);
  if (return_path == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_path;
  }

  * result = return_path;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_path:
  mailimf_path_free(path);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_second_parse(const char * message, size_t length,
				size_t * indx, int * result)
{
  uint32_t second;
  int r;

  r = mailimf_number_parse(message, length, indx, &second);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * result = second;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_semi_colon_parse(const char * message, size_t length,
				    size_t * indx)
{
  return mailimf_unstrict_char_parse(message, length, indx, ';');
}

Project: libetpan
File: mailimf.c

mailimf_struct_list_parse(const char * message, size_t length,
			  size_t * indx, clist ** result,
			  char symbol,
			  mailimf_struct_parser * parser,
			  mailimf_struct_destructor * destructor)
{
  clist * struct_list;
  size_t cur_token;
  void * value;
  size_t final_token;
  int r;
  int res;

  cur_token = * indx;

  r = parser(message, length, &cur_token, &value);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  struct_list = clist_new();
  if (struct_list == NULL) {
    destructor(value);
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }

  r = clist_append(struct_list, value);
  if (r < 0) {
    destructor(value);
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  final_token = cur_token;

  while (1) {
    r = mailimf_unstrict_char_parse(message, length, &cur_token, symbol);
    if (r != MAILIMF_NO_ERROR) {
      if (r == MAILIMF_ERROR_PARSE)
	break;
      else {
	res = r;
	goto free;
      }
    }

    r = parser(message, length, &cur_token, &value);
    if (r != MAILIMF_NO_ERROR) {
      if (r == MAILIMF_ERROR_PARSE)
	break;
      else {
	res = r;
	goto free;
      }
    }

    r = clist_append(struct_list, value);
    if (r < 0) {
      destructor(value);
      res = MAILIMF_ERROR_MEMORY;
      goto free;
    }

    final_token = cur_token;
  }
  
  * result = struct_list;
  * indx = final_token;
  
  return MAILIMF_NO_ERROR;
  
 free:
  clist_foreach(struct_list, (clist_func) destructor, NULL);
  clist_free(struct_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_struct_multiple_parse(const char * message, size_t length,
			      size_t * indx, clist ** result,
			      mailimf_struct_parser * parser,
			      mailimf_struct_destructor * destructor)
{
  clist * struct_list;
  size_t cur_token;
  void * value;
  int r;
  int res;

  cur_token = * indx;

  r = parser(message, length, &cur_token, &value);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  struct_list = clist_new();
  if (struct_list == NULL) {
    destructor(value);
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }

  r = clist_append(struct_list, value);
  if (r < 0) {
    destructor(value);
    res = MAILIMF_ERROR_MEMORY;
    goto free;
  }

  while (1) {
    r = parser(message, length, &cur_token, &value);
    if (r != MAILIMF_NO_ERROR) {
      if (r == MAILIMF_ERROR_PARSE)
	break;
      else {
	res = r;
	goto free;
      }
    }
    r = clist_append(struct_list, value);
    if (r < 0) {
      (* destructor)(value);
      res = MAILIMF_ERROR_MEMORY;
      goto free;
    }
  }

  * result = struct_list;
  * indx = cur_token;
  
  return MAILIMF_NO_ERROR;

 free:
  clist_foreach(struct_list, (clist_func) destructor, NULL);
  clist_free(struct_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_subject_parse(const char * message, size_t length,
				 size_t * indx,
				 struct mailimf_subject ** result)
{
  struct mailimf_subject * subject;
  char * value;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "Subject");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }
  
  r = mailimf_unstructured_parse(message, length, &cur_token, &value);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_value;
  }
  
  subject = mailimf_subject_new(value);
  if (subject == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_value;
  }

  * result = subject;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_value:
  mailimf_unstructured_free(value);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

static int mailimf_time_of_day_parse(const char * message, size_t length,
				     size_t * indx,
				     int * phour, int * pmin,
				     int * psec)
{
  int hour;
  int min;
  int sec;
  size_t cur_token;
  int r;

  cur_token = * indx;

  r = mailimf_hour_parse(message, length, &cur_token, &hour);
  if (r != MAILIMF_NO_ERROR)
    return r;

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR)
    return r;

  r = mailimf_minute_parse(message, length, &cur_token, &min);
  if (r != MAILIMF_NO_ERROR)
    return r;

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r == MAILIMF_NO_ERROR) {
    r = mailimf_second_parse(message, length, &cur_token, &sec);
    if (r != MAILIMF_NO_ERROR)
      return r;
  }
  else if (r == MAILIMF_ERROR_PARSE)
    sec = 0;
  else
    return r;

  * phour = hour;
  * pmin = min;
  * psec = sec;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_time_parse(const char * message, size_t length,
			      size_t * indx, 
			      int * phour, int * pmin,
			      int * psec,
			      int * pzone)
{
  size_t cur_token;
  int hour;
  int min;
  int sec;
  int zone;
  int r;

  cur_token = * indx;

  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_time_of_day_parse(message, length, &cur_token,
				&hour, &min, &sec);
  if (r != MAILIMF_NO_ERROR)
    return r;

  r = mailimf_fws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_zone_parse(message, length, &cur_token, &zone);
  if (r == MAILIMF_NO_ERROR) {
    /* do nothing */
  }
  else if (r == MAILIMF_ERROR_PARSE) {
    zone = 0;
  }
  else {
    return r;
  }

  * phour = hour;
  * pmin = min;
  * psec = sec;
  * pzone = zone;

  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

mailimf_to_parse(const char * message, size_t length,
		 size_t * indx, struct mailimf_to ** result)
{
  struct mailimf_address_list * addr_list;
  struct mailimf_to * to;
  size_t cur_token;
  int r;
  int res;

  cur_token = * indx;

  r = mailimf_token_case_insensitive_parse(message, length,
					   &cur_token, "To");
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_colon_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_address_list_parse(message, length, &cur_token, &addr_list);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailimf_unstrict_crlf_parse(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    res = r;
    goto free_addr_list;
  }

  to = mailimf_to_new(addr_list);
  if (to == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_addr_list;
  }

  * result = to;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;

 free_addr_list:
  mailimf_address_list_free(addr_list);
 err:
  return res;
}

Project: libetpan
File: mailimf.c

mailimf_token_case_insensitive_len_parse(const char * message, size_t length,
					 size_t * indx, char * token,
					 size_t token_length)
{
  size_t cur_token;

  cur_token = * indx;

  if (cur_token + token_length - 1 >= length)
    return MAILIMF_ERROR_PARSE;

  if (strncasecmp(message + cur_token, token, token_length) == 0) {
    cur_token += token_length;
    * indx = cur_token;
    return MAILIMF_NO_ERROR;
  }
  else
    return MAILIMF_ERROR_PARSE;
}

Project: libetpan
File: mailimf.c

int mailimf_unstrict_char_parse(const char * message, size_t length,
				size_t * indx, char token)
{
  size_t cur_token;
  int r;

  cur_token = * indx;

  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_char_parse(message, length, &cur_token, token);
  if (r != MAILIMF_NO_ERROR)
    return r;
  
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_unstrict_crlf_parse(const char * message,
				       size_t length, size_t * indx)
{
  size_t cur_token;
  int r;

  cur_token = * indx;

  mailimf_cfws_parse(message, length, &cur_token);

  r = mailimf_char_parse(message, length, &cur_token, '\r');
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_char_parse(message, length, &cur_token, '\n');
  if (r != MAILIMF_NO_ERROR)
    return r;

  * indx = cur_token;
  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_unstrict_msg_id_parse(const char * message, size_t length,
					 size_t * indx,
					 char ** result)
{
  char * msgid;
  size_t cur_token;
  int r;

  cur_token = * indx;

  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_parse_unwanted_msg_id(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR)
    return r;

  r = mailimf_msg_id_parse(message, length, &cur_token, &msgid);
  if (r != MAILIMF_NO_ERROR)
    return r;

  r = mailimf_parse_unwanted_msg_id(message, length, &cur_token);
  if (r != MAILIMF_NO_ERROR) {
    free(msgid);
    return r;
  }

  * result = msgid;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_unstructured_parse(const char * message, size_t length,
				      size_t * indx, char ** result)
{
  size_t cur_token;
  int state;
  size_t begin;
  size_t terminal;
  char * str;

  cur_token = * indx;


  while (1) {
    int r;

    r = mailimf_wsp_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR) {
      /* do nothing */
    }
    else if (r == MAILIMF_ERROR_PARSE)
      break;
    else {
      return r;
    }
  }

  state = UNSTRUCTURED_START;
  begin = cur_token;
  terminal = cur_token;

  while (state != UNSTRUCTURED_OUT) {

    switch(state) {
    case UNSTRUCTURED_START:
      if (cur_token >= length)
	return MAILIMF_ERROR_PARSE;

      terminal = cur_token;
      switch(message[cur_token]) {
      case '\r':
	state = UNSTRUCTURED_CR;
	break;
      case '\n':
	state = UNSTRUCTURED_LF;
	break;
      default:
	state = UNSTRUCTURED_START;
	break;
      }
      break;
    case UNSTRUCTURED_CR:
      if (cur_token >= length)
	return MAILIMF_ERROR_PARSE;

      switch(message[cur_token]) {
      case '\n':
	state = UNSTRUCTURED_LF;
	break;
      default:
	state = UNSTRUCTURED_START;
	break;
      }
      break;

    case UNSTRUCTURED_LF:
      if (cur_token >= length) {
	state = UNSTRUCTURED_OUT;
	break;
      }

      switch(message[cur_token]) {
      case '\t':
      case ' ':
	state = UNSTRUCTURED_WSP;
	break;
      default:
	state = UNSTRUCTURED_OUT;
	break;
      }
      break;
    case UNSTRUCTURED_WSP:
      if (cur_token >= length)
	return MAILIMF_ERROR_PARSE;

      switch(message[cur_token]) {
      case '\r':
	state = UNSTRUCTURED_CR;
	break;
      case '\n':
	state = UNSTRUCTURED_LF;
	break;
      default:
	state = UNSTRUCTURED_START;
	break;
      }
      break;
    }

    cur_token ++;
  }

  str = malloc(terminal - begin + 1);
  if (str == NULL)
    return MAILIMF_ERROR_MEMORY;
  strncpy(str, message + begin,  terminal - begin);
  str[terminal - begin] = '\0';

  * indx = terminal;
  * result = str;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

int mailimf_word_parse(const char * message, size_t length,
		       size_t * indx, char ** result)
{
  size_t cur_token;
  char * word;
  int r;

  cur_token = * indx;

  r = mailimf_atom_parse(message, length, &cur_token, &word);

  if (r == MAILIMF_ERROR_PARSE)
    r = mailimf_quoted_string_parse(message, length, &cur_token, &word);

  if (r != MAILIMF_NO_ERROR)
    return r;

  * result = word;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static inline int mailimf_wsp_parse(const char * message, size_t length,
				    size_t * indx)
{
  size_t cur_token;

  cur_token = * indx;

  if (cur_token >= length)
    return MAILIMF_ERROR_PARSE;

  if ((message[cur_token] != ' ') && (message[cur_token] != '\t'))
    return MAILIMF_ERROR_PARSE;

  cur_token ++;
  * indx = cur_token;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_year_parse(const char * message, size_t length,
			      size_t * indx, int * result)
{
  uint32_t number;
  size_t cur_token;
  int r;

  cur_token = * indx;

  r = mailimf_cfws_parse(message, length, &cur_token);
  if ((r != MAILIMF_NO_ERROR) && (r != MAILIMF_ERROR_PARSE))
    return r;

  r = mailimf_number_parse(message, length, &cur_token, &number);
  if (r != MAILIMF_NO_ERROR)
    return r;

  * indx = cur_token;
  * result = number;

  return MAILIMF_NO_ERROR;
}

Project: libetpan
File: mailimf.c

static int mailimf_zone_parse(const char * message, size_t length,
                              size_t * indx, int * result)
{
  int zone;
  int sign;
  size_t cur_token;
  int r;
  uint32_t value;

  cur_token = * indx;

  if (cur_token + 1 < length) {
    if ((message[cur_token] == 'U') && (message[cur_token + 1] == 'T')) {
      * result = TRUE;
      * indx = cur_token + 2;

      return MAILIMF_NO_ERROR;
    }
  }

  zone = 0;
  if (cur_token + 2 < length) {
    int state;

    state = STATE_ZONE_1;

    while (state <= 2) {
      switch (state) {
        case STATE_ZONE_1:
          switch (message[cur_token]) {
            case 'G':
              if (message[cur_token + 1] == 'M' && message[cur_token + 2] == 'T') {
                if ((cur_token + 3 < length) && ((message[cur_token + 3] == '+') || (message[cur_token + 3] == '-'))) {
                  cur_token += 3;
                  state = STATE_ZONE_CONT;
                }
                else {
                  zone = 0;
                  state = STATE_ZONE_OK;
                }
              }
              else {
                state = STATE_ZONE_ERR;
              }
              break;
            case 'E':
              zone = -5;
              state = STATE_ZONE_2;
              break;
            case 'C':
              zone = -6;
              state = STATE_ZONE_2;
              break;
            case 'M':
              zone = -7;
              state = STATE_ZONE_2;
              break;
            case 'P':
              zone = -8;
              state = STATE_ZONE_2;
              break;
            default:
              state = STATE_ZONE_CONT;
              break;
          }
          break;
        case STATE_ZONE_2:
          switch (message[cur_token + 1]) {
            case 'S':
              state = STATE_ZONE_3;
              break;
            case 'D':
              zone ++;
              state = STATE_ZONE_3;
              break;
            default:
              state = STATE_ZONE_ERR;
              break;
          }
          break;
        case STATE_ZONE_3:
          if (message[cur_token + 2] == 'T') {
            zone *= 100;
            state = STATE_ZONE_OK;
          }
          else
            state = STATE_ZONE_ERR;
          break;
      }
    }

    switch (state) {
      case STATE_ZONE_OK:
        * result = zone;
        * indx = cur_token + 3;
        return MAILIMF_NO_ERROR;

      case STATE_ZONE_ERR:
        return MAILIMF_ERROR_PARSE;
    }
  }

  sign = 1;
  r = mailimf_plus_parse(message, length, &cur_token);
  if (r == MAILIMF_NO_ERROR)
    sign = 1;

  if (r == MAILIMF_ERROR_PARSE) {
    r = mailimf_minus_parse(message, length, &cur_token);
    if (r == MAILIMF_NO_ERROR)
      sign = -1;
  }

  if (r == MAILIMF_NO_ERROR) {
    /* do nothing */
  }
  else if (r == MAILIMF_ERROR_PARSE)
    sign = 1;
  else
    return r;

  r = mailimf_number_parse(message, length, &cur_token, &value);
  if (r != MAILIMF_NO_ERROR)
    return r;

  zone = value * sign;

  * indx = cur_token;
  * result = zone;

  return MAILIMF_NO_ERROR;
}